diff --git a/include/types.h b/include/types.h index dd981ee7e..6c614eb12 100644 --- a/include/types.h +++ b/include/types.h @@ -389,7 +389,11 @@ struct MarioState // NOTE: this defines the maximum number of players... // HOWEVER, simply increasing this to 3 will not magically work // many things will have to be overhauled! +#ifdef DEVELOPMENT +#define MAX_PLAYERS 4 +#else #define MAX_PLAYERS 2 +#endif // are you still deciding to increase it? // networking will have to be rewritten to have more than one destination. 'reliable' messages would need to be sent per-player // things that base priority on whether they are the host or not would need priority based on player index instead diff --git a/proto-3.sh b/proto-4.sh similarity index 67% rename from proto-3.sh rename to proto-4.sh index 8f7a1bbab..5c1c5360a 100644 --- a/proto-3.sh +++ b/proto-4.sh @@ -30,12 +30,12 @@ fi # debug on client # ################### +#winpty cgdb $FILE -ex 'break debug_breakpoint_here' -ex 'run --server 27015 --configfile sm64config_p1.txt' -ex 'quit' $FILE --server 27015 --configfile sm64config_p1.txt & - $FILE --client 127.0.0.1 27015 --configfile sm64config_p2.txt & - -# debug if cgdb exists -if ! [ -x "$(command -v cgdb)" ]; then - $FILE --client 127.0.0.1 27015 --configfile sm64config_p3.txt & -else - winpty cgdb $FILE -ex 'break debug_breakpoint_here' -ex 'run --client 127.0.0.1 27015 --configfile sm64config_p3.txt' -ex 'quit' -fi +sleep 2 +$FILE --client 127.0.0.1 27015 --configfile sm64config_p2.txt & +sleep 2 +$FILE --client 127.0.0.1 27015 --configfile sm64config_p3.txt & +sleep 2 +#$FILE --client 127.0.0.1 27015 --configfile sm64config_p4.txt & +winpty cgdb $FILE -ex 'break debug_breakpoint_here' -ex 'run --client 127.0.0.1 27015 --configfile sm64config_p4.txt' -ex 'quit' diff --git a/src/pc/network/discord/discord.c b/src/pc/network/discord/discord.c index 23df02df1..0ac133483 100644 --- a/src/pc/network/discord/discord.c +++ b/src/pc/network/discord/discord.c @@ -178,11 +178,11 @@ static void ns_discord_shutdown(void) { } struct NetworkSystem gNetworkSystemDiscord = { - .initialize = ns_discord_initialize, - .save_id = ns_discord_save_id, - .clear_id = ns_discord_clear_id, - .update = ns_discord_update, - .send = ns_discord_network_send, - .shutdown = ns_discord_shutdown, - .canBroadcast = true, + .initialize = ns_discord_initialize, + .save_id = ns_discord_save_id, + .clear_id = ns_discord_clear_id, + .update = ns_discord_update, + .send = ns_discord_network_send, + .shutdown = ns_discord_shutdown, + .requireServerBroadcast = false, }; diff --git a/src/pc/network/network.c b/src/pc/network/network.c index fc17e35f7..ae0153028 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -91,10 +91,13 @@ void network_on_loaded_level(void) { void network_send_to(u8 localIndex, struct Packet* p) { // sanity checks - if (gNetworkType == NT_NONE) { return; } + if (gNetworkType == NT_NONE) { LOG_ERROR("network type error none!"); return; } if (p->error) { LOG_ERROR("packet error!"); return; } if (gNetworkSystem == NULL) { LOG_ERROR("no network system attached"); return; } + // set the flags again + packet_set_flags(p); + p->localIndex = localIndex; // remember reliable packets @@ -106,13 +109,27 @@ void network_send_to(u8 localIndex, struct Packet* p) { // send int rc = gNetworkSystem->send(localIndex, p->buffer, p->cursor + sizeof(u32)); - if (rc != NO_ERROR) { return; } + if (rc == SOCKET_ERROR) { LOG_ERROR("send error %d", rc); return; } p->sent = true; gLastNetworkSend = clock(); } void network_send(struct Packet* p) { + // set the flags again + packet_set_flags(p); + + if (gNetworkType != NT_SERVER) { + p->requestBroadcast = TRUE; + if (gNetworkSystem != NULL && gNetworkSystem->requireServerBroadcast && gNetworkPlayerServer != NULL) { + int i = gNetworkPlayerServer->localIndex; + p->localIndex = i; + network_send_to(i, p); + gLastNetworkSend = clock(); + return; + } + } + for (int i = 1; i < MAX_PLAYERS; i++) { if (!gNetworkPlayers[i].connected) { continue; } p->localIndex = i; diff --git a/src/pc/network/network.h b/src/pc/network/network.h index 5318630d9..0b5fc4741 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -38,7 +38,7 @@ struct NetworkSystem { void (*update)(void); int (*send)(u8 localIndex, u8* data, u16 dataLength); void (*shutdown)(void); - bool canBroadcast; + bool requireServerBroadcast; }; struct SyncObject { diff --git a/src/pc/network/packets/packet.c b/src/pc/network/packets/packet.c index 1ad776c7c..35e64ce41 100644 --- a/src/pc/network/packets/packet.c +++ b/src/pc/network/packets/packet.c @@ -15,7 +15,7 @@ void packet_receive(struct Packet* p) { network_send_ack(p); // check if we should drop packet - if (!packet_initial_read(p)) { return; } + if (!packet_initial_read(p)) { LOG_ERROR("initial read failed (%d - %d)", packetType, p->levelAreaMustMatch); return; } switch (packetType) { case PACKET_ACK: network_receive_ack(p); break; @@ -44,4 +44,17 @@ void packet_receive(struct Packet* p) { case PACKET_CUSTOM: network_receive_custom(p); break; default: LOG_ERROR("received unknown packet: %d", p->buffer[0]); } + + // broadcast packet + if (p->requestBroadcast) { + if (gNetworkType == NT_SERVER && gNetworkSystem->requireServerBroadcast) { + for (int i = 1; i < MAX_PLAYERS; i++) { + if (!gNetworkPlayers[i].connected) { continue; } + struct Packet p2 = { 0 }; + packet_init(&p2, packetType, p->reliable, p->levelAreaMustMatch); + packet_write(&p2, &p->buffer[p2.cursor], p->cursor - p2.cursor); + network_send_to(i, &p2); + } + } + } } \ No newline at end of file diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h index 126afd5bf..969ca941f 100644 --- a/src/pc/network/packets/packet.h +++ b/src/pc/network/packets/packet.h @@ -43,6 +43,7 @@ struct Packet { bool error; bool reliable; bool levelAreaMustMatch; + bool requestBroadcast; u16 seqId; bool sent; u8 buffer[PACKET_LENGTH]; @@ -58,6 +59,7 @@ void packet_receive(struct Packet* packet); // packet_read_write.c void packet_init(struct Packet* packet, enum PacketType packetType, bool reliable, bool levelAreaMustMatch); +void packet_set_flags(struct Packet* packet); void packet_write(struct Packet* packet, void* data, u16 length); u8 packet_initial_read(struct Packet* packet); void packet_read(struct Packet* packet, void* data, u16 length); @@ -121,8 +123,8 @@ void network_receive_collect_item(struct Packet* p); // packet_reservation.c void network_send_reservation_request(void); -void network_receive_reservation_request(UNUSED struct Packet* p); -void network_send_reservation(void); +void network_receive_reservation_request(struct Packet* p); +void network_send_reservation(u8 toLocalIndex); void network_receive_reservation(struct Packet* p); // packet_join.c diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 651c963d9..a05549184 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -335,11 +335,6 @@ void network_receive_player(struct Packet* p) { // set model m->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[(np->globalIndex == 1) ? MODEL_LUIGI : MODEL_MARIO]; - - // broadcast player packet - if (gNetworkType == NT_SERVER && !gNetworkSystem->canBroadcast) { - network_send_player(globalIndex); - } } void network_update_player(void) { diff --git a/src/pc/network/packets/packet_read_write.c b/src/pc/network/packets/packet_read_write.c index 56ffb3a4e..894891e1a 100644 --- a/src/pc/network/packets/packet_read_write.c +++ b/src/pc/network/packets/packet_read_write.c @@ -1,6 +1,8 @@ #include "../network.h" #include "game/area.h" +#define PACKET_FLAG_BUFFER_OFFSET 3 + static u16 nextSeqNum = 1; void packet_init(struct Packet* packet, enum PacketType packetType, bool reliable, bool levelAreaMustMatch) { memset(packet->buffer, 0, PACKET_LENGTH); @@ -16,12 +18,13 @@ void packet_init(struct Packet* packet, enum PacketType packetType, bool reliabl packet->error = false; packet->reliable = reliable; packet->levelAreaMustMatch = levelAreaMustMatch; + packet->requestBroadcast = false; packet->sent = false; // write packet flags - u8 flags; - flags |= SET_BIT(packet->levelAreaMustMatch, 0); - packet_write(packet, &flags, sizeof(u8)); + u8 flags = 0; + packet_write(packet, &flags, sizeof(u8)); // fill in the byte + packet_set_flags(packet); if (levelAreaMustMatch) { packet_write(packet, &gCurrLevelNum, sizeof(s16)); @@ -29,6 +32,13 @@ void packet_init(struct Packet* packet, enum PacketType packetType, bool reliabl } } +void packet_set_flags(struct Packet* packet) { + u8 flags = 0; + flags |= SET_BIT(packet->levelAreaMustMatch, 0); + flags |= SET_BIT(packet->requestBroadcast, 1); + packet->buffer[PACKET_FLAG_BUFFER_OFFSET] = flags; +} + void packet_write(struct Packet* packet, void* data, u16 length) { if (data == NULL) { packet->error = true; return; } memcpy(&packet->buffer[packet->cursor], data, length); @@ -41,6 +51,7 @@ u8 packet_initial_read(struct Packet* packet) { u8 flags = 0; packet_read(packet, &flags, sizeof(u8)); packet->levelAreaMustMatch = GET_BIT(flags, 0); + packet->requestBroadcast = GET_BIT(flags, 1); if (packet->levelAreaMustMatch) { s16 currLevelNum; diff --git a/src/pc/network/packets/packet_reliable.c b/src/pc/network/packets/packet_reliable.c index 7c89d8f03..cba4f993e 100644 --- a/src/pc/network/packets/packet_reliable.c +++ b/src/pc/network/packets/packet_reliable.c @@ -41,6 +41,7 @@ void network_send_ack(struct Packet* p) { // grab seq num u16 seqId = 0; memcpy(&seqId, &p->buffer[1], 2); + p->reliable = (seqId != 0); if (seqId == 0) { return; } // send back the ACK diff --git a/src/pc/network/packets/packet_reservation.c b/src/pc/network/packets/packet_reservation.c index 7857f5b17..25021248c 100644 --- a/src/pc/network/packets/packet_reservation.c +++ b/src/pc/network/packets/packet_reservation.c @@ -14,23 +14,23 @@ void network_send_reservation_request(void) { struct Packet p; packet_init(&p, PACKET_RESERVATION_REQUEST, true, false); - network_send(&p); + network_send_to(gNetworkPlayerServer->localIndex , &p); } -void network_receive_reservation_request(UNUSED struct Packet* p) { +void network_receive_reservation_request(struct Packet* p) { assert(gNetworkType == NT_SERVER); - network_send_reservation(); + network_send_reservation(p->localIndex); } -void network_send_reservation(void) { +void network_send_reservation(u8 toLocalIndex) { assert(gNetworkType == NT_SERVER); - u8 clientPlayerIndex = 1; // two-player hack + assert(toLocalIndex != 0); // find all reserved objects u8 reservedObjs[RESERVATION_COUNT] = { 0 }; u16 reservedIndex = 0; for (u16 i = 1; i < MAX_SYNC_OBJECTS; i++) { - if (gSyncObjects[i].reserved == clientPlayerIndex) { + if (gSyncObjects[i].reserved == toLocalIndex) { reservedObjs[reservedIndex++] = i; if (reservedIndex >= RESERVATION_COUNT) { break; } } @@ -41,7 +41,7 @@ void network_send_reservation(void) { for (u16 i = MAX_SYNC_OBJECTS - 1; i > 0; i--) { if (gSyncObjects[i].o != NULL) { continue; } if (gSyncObjects[i].reserved != 0) { continue; } - gSyncObjects[i].reserved = clientPlayerIndex; + gSyncObjects[i].reserved = toLocalIndex; reservedObjs[reservedIndex++] = i; if (reservedIndex >= RESERVATION_COUNT) { break; } } @@ -50,12 +50,11 @@ void network_send_reservation(void) { struct Packet p; packet_init(&p, PACKET_RESERVATION, true, false); packet_write(&p, reservedObjs, sizeof(u8) * RESERVATION_COUNT); - network_send(&p); + network_send_to(toLocalIndex, &p); } void network_receive_reservation(struct Packet* p) { assert(gNetworkType == NT_CLIENT); - u8 clientPlayerIndex = 1; // two-player hack // find all reserved objects u8 reservedObjs[RESERVATION_COUNT] = { 0 }; @@ -65,6 +64,6 @@ void network_receive_reservation(struct Packet* p) { u16 index = reservedObjs[i]; if (index == 0) { continue; } if (gSyncObjects[index].o != NULL) { continue; } - gSyncObjects[index].reserved = clientPlayerIndex; + gSyncObjects[index].reserved = gNetworkPlayerLocal->globalIndex; } } diff --git a/src/pc/network/packets/packet_spawn_objects.c b/src/pc/network/packets/packet_spawn_objects.c index c465eb73f..fd5ee4ddd 100644 --- a/src/pc/network/packets/packet_spawn_objects.c +++ b/src/pc/network/packets/packet_spawn_objects.c @@ -152,6 +152,6 @@ void network_receive_spawn_objects(struct Packet* p) { // update their block of reserved ids if (gNetworkType == NT_SERVER && receivedReservedSyncObject) { - network_send_reservation(); + network_send_reservation(p->localIndex); } } diff --git a/src/pc/network/socket/socket.c b/src/pc/network/socket/socket.c index 6f81165c5..737ecba67 100644 --- a/src/pc/network/socket/socket.c +++ b/src/pc/network/socket/socket.c @@ -138,11 +138,11 @@ static void ns_socket_shutdown(void) { } struct NetworkSystem gNetworkSystemSocket = { - .initialize = ns_socket_initialize, - .save_id = ns_socket_save_id, - .clear_id = ns_socket_clear_id, - .update = ns_socket_update, - .send = ns_socket_send, - .shutdown = ns_socket_shutdown, - .canBroadcast = false, + .initialize = ns_socket_initialize, + .save_id = ns_socket_save_id, + .clear_id = ns_socket_clear_id, + .update = ns_socket_update, + .send = ns_socket_send, + .shutdown = ns_socket_shutdown, + .requireServerBroadcast = true, };