diff --git a/proto-4.sh b/proto-4.sh index 5c1c5360a..56124ebc4 100644 --- a/proto-4.sh +++ b/proto-4.sh @@ -37,5 +37,5 @@ $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' +$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/network_player.c b/src/pc/network/network_player.c index 2734d5096..1d2b197d4 100644 --- a/src/pc/network/network_player.c +++ b/src/pc/network/network_player.c @@ -68,6 +68,7 @@ void network_player_update(void) { u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) { if (type == NPT_LOCAL) { + memset(&gNetworkPlayers[0], 0, sizeof(struct NetworkPlayer)); gNetworkPlayers[0].connected = true; gNetworkPlayers[0].type = type; gNetworkPlayers[0].localIndex = 0; @@ -92,6 +93,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) { for (int i = 1; i < MAX_PLAYERS; i++) { struct NetworkPlayer* np = &gNetworkPlayers[i]; if (np->connected) { continue; } + memset(np, 0, sizeof(struct NetworkPlayer)); np->connected = true; np->currLevelNum = -1; np->currAreaIndex = -1; diff --git a/src/pc/network/network_player.h b/src/pc/network/network_player.h index 0eca6d601..9f268ee07 100644 --- a/src/pc/network/network_player.h +++ b/src/pc/network/network_player.h @@ -8,6 +8,7 @@ #define UNKNOWN_GLOBAL_INDEX ((u8)-1) #define UNKNOWN_NETWORK_INDEX ((u64)-1) #define NETWORK_PLAYER_TIMEOUT 10 +#define MAX_RX_SEQ_IDS 16 enum NetworkPlayerType { NPT_UNKNOWN, @@ -25,6 +26,8 @@ struct NetworkPlayer { s16 currLevelNum; s16 currAreaIndex; u8 fadeOpacity; + u16 rxSeqIds[MAX_RX_SEQ_IDS]; + u8 onRxSeqId; }; extern struct NetworkPlayer gNetworkPlayers[]; diff --git a/src/pc/network/packets/packet.c b/src/pc/network/packets/packet.c index 35e64ce41..d2e185f85 100644 --- a/src/pc/network/packets/packet.c +++ b/src/pc/network/packets/packet.c @@ -14,6 +14,21 @@ void packet_receive(struct Packet* p) { // send an ACK if requested network_send_ack(p); + // check if we've already seen this packet + if (p->localIndex != 0 && p->seqId != 0 && gNetworkPlayers[p->localIndex].connected) { + struct NetworkPlayer* np = &gNetworkPlayers[p->localIndex]; + for (int i = 0; i < MAX_RX_SEQ_IDS; i++) { + if (np->rxSeqIds[i] == p->seqId) { + LOG_INFO("received duplicate packet"); + return; + } + } + // remember seq id + np->rxSeqIds[np->onRxSeqId] = p->seqId; + np->onRxSeqId++; + if (np->onRxSeqId >= MAX_RX_SEQ_IDS) { np->onRxSeqId = 0; } + } + // check if we should drop packet if (!packet_initial_read(p)) { LOG_ERROR("initial read failed (%d - %d)", packetType, p->levelAreaMustMatch); return; } @@ -50,6 +65,7 @@ void packet_receive(struct Packet* p) { if (gNetworkType == NT_SERVER && gNetworkSystem->requireServerBroadcast) { for (int i = 1; i < MAX_PLAYERS; i++) { if (!gNetworkPlayers[i].connected) { continue; } + if (i == p->localIndex) { continue; } struct Packet p2 = { 0 }; packet_init(&p2, packetType, p->reliable, p->levelAreaMustMatch); packet_write(&p2, &p->buffer[p2.cursor], p->cursor - p2.cursor); diff --git a/src/pc/network/packets/packet_chat.c b/src/pc/network/packets/packet_chat.c index abd2e4ff4..74c74adf1 100644 --- a/src/pc/network/packets/packet_chat.c +++ b/src/pc/network/packets/packet_chat.c @@ -2,50 +2,23 @@ #include "../network.h" #include "game/chat.h" -static u8 localChatId = 1; - -// two-player hack: the remoteChatIds stuff is only valid for the one remote player -// will need to be extended if MAX_PLAYERS is ever increased -#define MAX_CHAT_IDS 16 -static u8 remoteChatIds[MAX_CHAT_IDS] = { 0 }; -static u8 onRemoteChatId = 0; - void network_send_chat(char* message) { u16 messageLength = strlen(message); struct Packet p; packet_init(&p, PACKET_CHAT, true, false); - packet_write(&p, &localChatId, sizeof(u8)); packet_write(&p, &messageLength, sizeof(u16)); packet_write(&p, message, messageLength * sizeof(u8)); - network_send(&p); - localChatId++; } void network_receive_chat(struct Packet* p) { - u8 remoteChatId = 0; u16 remoteMessageLength = 0; char remoteMessage[255] = { 0 }; - packet_read(p, &remoteChatId, sizeof(u8)); packet_read(p, &remoteMessageLength, sizeof(u16)); if (remoteMessageLength > 255) { remoteMessageLength = 254; } packet_read(p, &remoteMessage, remoteMessageLength * sizeof(u8)); - // check if remote chat id has already been seen - for (u16 i = 0; i < MAX_CHAT_IDS; i++) { - if (remoteChatIds[i] == remoteChatId) { - // we already saw this message! - return; - } - } - - // cache the seen id - remoteChatIds[onRemoteChatId] = remoteChatId; - onRemoteChatId = (onRemoteChatId + 1) % MAX_CHAT_IDS; - // add the message chat_add_message(remoteMessage, CMT_REMOTE); - - return; } diff --git a/src/pc/network/packets/packet_collect_coin.c b/src/pc/network/packets/packet_collect_coin.c index bb4cb94f3..a80cd216c 100644 --- a/src/pc/network/packets/packet_collect_coin.c +++ b/src/pc/network/packets/packet_collect_coin.c @@ -12,14 +12,6 @@ // defined in sparkle_spawn_star.inc.c void bhv_spawn_star_no_level_exit(struct Object* object, u32 sp20, u8 networkSendEvent); -static u8 localCoinId = 1; - -// two-player hack: the remoteCoinId stuff is only valid for the one remote player -// will need to be extended if MAX_PLAYERS is ever increased -#define MAX_REMOTE_COIN_IDS 16 -static u8 remoteCoinIds[MAX_REMOTE_COIN_IDS] = { 0 }; -static u8 onRemoteCoinId = 0; - static f32 dist_to_pos(struct Object* o, f32* pos) { f32 x = o->oPosX - pos[0]; x *= x; f32 y = o->oPosY - pos[1]; y *= y; @@ -56,24 +48,20 @@ void network_send_collect_coin(struct Object* o) { struct Packet p; packet_init(&p, PACKET_COLLECT_COIN, true, true); - packet_write(&p, &localCoinId, sizeof(u8)); packet_write(&p, &behaviorId, sizeof(enum BehaviorId)); packet_write(&p, &o->oPosX, sizeof(f32) * 3); packet_write(&p, &gMarioStates[0].numCoins, sizeof(s16)); packet_write(&p, &o->oDamageOrCoinValue, sizeof(s32)); network_send(&p); - localCoinId++; } void network_receive_collect_coin(struct Packet* p) { - u8 remoteCoinId = 0; enum BehaviorId behaviorId; f32 pos[3] = { 0 }; s16 numCoins = 0; s32 coinValue = 0; - packet_read(p, &remoteCoinId, sizeof(u8)); packet_read(p, &behaviorId, sizeof(enum BehaviorId)); packet_read(p, &pos, sizeof(f32) * 3); packet_read(p, &numCoins, sizeof(s16)); @@ -81,17 +69,6 @@ void network_receive_collect_coin(struct Packet* p) { const void* behavior = get_behavior_from_id(behaviorId); - // check if remote coin id has already been seen - for (u16 i = 0; i < MAX_REMOTE_COIN_IDS; i++) { - if (remoteCoinIds[i] == remoteCoinId) { - // we already saw this coin! - goto SANITY_CHECK_COINS; - } - } - // cache the seen id - remoteCoinIds[onRemoteCoinId] = remoteCoinId; - onRemoteCoinId = (onRemoteCoinId + 1) % MAX_REMOTE_COIN_IDS; - // make sure it's valid if (behavior == NULL) { goto SANITY_CHECK_COINS; } diff --git a/src/pc/network/packets/packet_collect_item.c b/src/pc/network/packets/packet_collect_item.c index a277847e6..bd81d9723 100644 --- a/src/pc/network/packets/packet_collect_item.c +++ b/src/pc/network/packets/packet_collect_item.c @@ -9,14 +9,6 @@ #include "src/game/memory.h" #include "src/game/object_helpers.h" -static u8 localItemId = 1; - -// two-player hack: the remoteItemId stuff is only valid for the one remote player -// will need to be extended if MAX_PLAYERS is ever increased -#define MAX_REMOTE_ITEM_IDS 16 -static u8 remoteItemIds[MAX_REMOTE_ITEM_IDS] = { 0 }; -static u8 onRemoteItemId = 0; - static f32 dist_to_pos(struct Object* o, f32* pos) { f32 x = o->oPosX - pos[0]; x *= x; f32 y = o->oPosY - pos[1]; y *= y; @@ -53,36 +45,21 @@ void network_send_collect_item(struct Object* o) { struct Packet p; packet_init(&p, PACKET_COLLECT_ITEM, true, true); - packet_write(&p, &localItemId, sizeof(u8)); packet_write(&p, &behaviorId, sizeof(enum BehaviorId)); packet_write(&p, &o->oPosX, sizeof(f32) * 3); network_send(&p); - localItemId++; } void network_receive_collect_item(struct Packet* p) { - u8 remoteItemId = 0; enum BehaviorId behaviorId; f32 pos[3] = { 0 }; - packet_read(p, &remoteItemId, sizeof(u8)); packet_read(p, &behaviorId, sizeof(enum BehaviorId)); packet_read(p, &pos, sizeof(f32) * 3); const void* behavior = get_behavior_from_id(behaviorId); - // check if remote item id has already been seen - for (u16 i = 0; i < MAX_REMOTE_ITEM_IDS; i++) { - if (remoteItemIds[i] == remoteItemId) { - // we already saw this item! - return; - } - } - // cache the seen id - remoteItemIds[onRemoteItemId] = remoteItemId; - onRemoteItemId = (onRemoteItemId + 1) % MAX_REMOTE_ITEM_IDS; - // make sure it's valid if (behavior == NULL) { return; } diff --git a/src/pc/network/packets/packet_inside_painting.c b/src/pc/network/packets/packet_inside_painting.c index 4d5cd0bb5..d94d3559c 100644 --- a/src/pc/network/packets/packet_inside_painting.c +++ b/src/pc/network/packets/packet_inside_painting.c @@ -14,17 +14,12 @@ extern s8 sReceivedLoadedActNum; #pragma pack(1) struct PacketInsidePaintingData { - u8 seqId; u8 starIndex; u8 actIndex; u8 loadedActNum; }; -static u8 seqId = 0; -static u8 remoteLastSeqId = (u8)-1; - static void populate_packet_data(struct PacketInsidePaintingData* data) { - data->seqId = seqId; data->starIndex = sSelectableStarIndex; data->actIndex = sSelectedActIndex; data->loadedActNum = sLoadedActNum; @@ -38,7 +33,6 @@ void network_send_inside_painting(void) { packet_init(&p, PACKET_INSIDE_PAINTING, true, false); packet_write(&p, &data, sizeof(struct PacketInsidePaintingData)); network_send(&p); - seqId++; } void network_receive_inside_painting(struct Packet* p) { @@ -48,13 +42,6 @@ void network_receive_inside_painting(struct Packet* p) { struct PacketInsidePaintingData remote = { 0 }; packet_read(p, &remote, sizeof(struct PacketInsidePaintingData)); - // de-dup - if (remote.seqId == remoteLastSeqId) { - LOG_INFO("we've seen this packet, escape!"); - return; - } - remoteLastSeqId = remote.seqId; - // two-player hack: gControlledWarp is a bool instead of an index if (gControlledWarp) { LOG_ERROR("this should never happen, received inside_painting when gControlledWarp"); diff --git a/src/pc/network/packets/packet_instant_warp.c b/src/pc/network/packets/packet_instant_warp.c index 9672aceba..c3b39bff6 100644 --- a/src/pc/network/packets/packet_instant_warp.c +++ b/src/pc/network/packets/packet_instant_warp.c @@ -11,19 +11,14 @@ extern u8 gRejectInstantWarp; -static u8 seqId = 0; -static u8 remoteLastSeqId = (u8)-1; - #pragma pack(1) struct PacketInstantWarpData { - u8 seqId; Vec3f pos; s16 areaIndex; s16 yaw; }; static void populate_packet_data(struct PacketInstantWarpData* data) { - data->seqId = seqId; data->pos[0] = gMarioStates[0].pos[0]; data->pos[1] = gMarioStates[0].pos[1]; data->pos[2] = gMarioStates[0].pos[2]; @@ -43,21 +38,12 @@ void network_send_instant_warp(void) { LOG_INFO("tx %d", data.areaIndex); gRejectInstantWarp = 120; - - seqId++; } void network_receive_instant_warp(struct Packet* p) { struct PacketInstantWarpData remote = { 0 }; packet_read(p, &remote, sizeof(struct PacketInstantWarpData)); - // de-dup - if (remote.seqId == remoteLastSeqId) { - LOG_INFO("we've seen this packet, escape!"); - return; - } - remoteLastSeqId = remote.seqId; - LOG_INFO("rx instant warp"); if (gCurrAreaIndex == remote.areaIndex) { diff --git a/src/pc/network/packets/packet_level_warp.c b/src/pc/network/packets/packet_level_warp.c index 015d12380..f36809d42 100644 --- a/src/pc/network/packets/packet_level_warp.c +++ b/src/pc/network/packets/packet_level_warp.c @@ -10,9 +10,6 @@ static u8 eventId = 0; static u8 remoteFinishedEventId[2] = { (u8)-1, (u8)-1 }; -static u8 seqId = 0; -static u8 remoteLastSeqId = (u8)-1; - extern s16 gTTCSpeedSetting; extern s16 D_80339EE0; extern float gPaintingMarioYEntry; @@ -26,7 +23,6 @@ static bool isInWarp = FALSE; #pragma pack(1) struct PacketLevelWarpData { - u8 seqId; u8 eventId; u8 done; u8 controlledWarp; @@ -38,7 +34,6 @@ struct PacketLevelWarpData { }; static void populate_packet_data(struct PacketLevelWarpData* data, bool done, u8 packetEventId) { - data->seqId = seqId; data->eventId = packetEventId; data->done = done; data->controlledWarp = gControlledWarp; @@ -73,8 +68,6 @@ void network_send_level_warp_begin(void) { packet_init(&p, PACKET_LEVEL_WARP, true, false); packet_write(&p, &data, sizeof(struct PacketLevelWarpData)); network_send(&p); - - seqId++; } void network_send_level_warp_repeat(void) { @@ -91,8 +84,6 @@ void network_send_level_warp_repeat(void) { packet_init(&p, PACKET_LEVEL_WARP, false, false); packet_write(&p, &data, sizeof(struct PacketLevelWarpData)); network_send(&p); - - seqId++; } static void network_send_level_warp_done(u8 remoteEventId) { @@ -106,8 +97,6 @@ static void network_send_level_warp_done(u8 remoteEventId) { packet_init(&p, PACKET_LEVEL_WARP, true, false); packet_write(&p, &data, sizeof(struct PacketLevelWarpData)); network_send(&p); - - seqId++; } static void do_warp(void) { @@ -124,13 +113,6 @@ void network_receive_level_warp(struct Packet* p) { struct PacketLevelWarpData remote = { 0 }; packet_read(p, &remote, sizeof(struct PacketLevelWarpData)); - // de-dup - if (remote.seqId == remoteLastSeqId) { - LOG_INFO("we've seen this packet, escape!"); - return; - } - remoteLastSeqId = remote.seqId; - LOG_INFO("rx event [%d] last [%d, %d]", remote.eventId, remoteFinishedEventId[0], remoteFinishedEventId[1]); if (remote.done && remote.eventId != eventId) { diff --git a/src/pc/network/packets/packet_reliable.c b/src/pc/network/packets/packet_reliable.c index cba4f993e..13fa3b53f 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->seqId = seqId; p->reliable = (seqId != 0); if (seqId == 0) { return; } diff --git a/src/pc/network/packets/packet_spawn_star.c b/src/pc/network/packets/packet_spawn_star.c index c6586d997..a148aebd0 100644 --- a/src/pc/network/packets/packet_spawn_star.c +++ b/src/pc/network/packets/packet_spawn_star.c @@ -7,9 +7,6 @@ extern struct Object* gCurrentObject; -static u8 txSeqId = 0; -static u8 rxLastSeqId = (u8)-1; - void network_send_spawn_star(struct Object* o, u8 starType, f32 x, f32 y, f32 z, u32 behParams) { struct Packet p; packet_init(&p, PACKET_SPAWN_STAR, true, true); @@ -62,32 +59,22 @@ void network_send_spawn_star_nle(struct Object* o, u32 params) { struct Packet p; packet_init(&p, PACKET_SPAWN_STAR_NLE, true, true); - packet_write(&p, &txSeqId, sizeof(u8)); packet_write(&p, &globalIndex, sizeof(u8)); packet_write(&p, &o->oSyncID, sizeof(u32)); packet_write(&p, ¶ms, sizeof(u32)); network_send(&p); - txSeqId++; } void network_receive_spawn_star_nle(struct Packet* p) { - u8 seqId = 0; u8 globalIndex = UNKNOWN_GLOBAL_INDEX; u32 syncId = 0; u32 params = 0; - packet_read(p, &seqId, sizeof(u8)); packet_read(p, &globalIndex, sizeof(u8)); packet_read(p, &syncId, sizeof(u32)); packet_read(p, ¶ms, sizeof(u32)); - // de-dup - if (seqId == rxLastSeqId) { - LOG_INFO("Already seen seqId %d", seqId); - return; - } - // grab network player first struct Object* object = NULL; if (globalIndex != UNKNOWN_GLOBAL_INDEX) {