From 168a41f0f691ba1eb739fa534513f7680059384a Mon Sep 17 00:00:00 2001 From: MysterD Date: Sat, 26 Sep 2020 15:52:00 -0700 Subject: [PATCH] Drop various types of packets if level/area doesn't match --- src/pc/network/network.h | 3 ++ src/pc/network/packets/packet.c | 9 +++-- src/pc/network/packets/packet.h | 6 ++-- src/pc/network/packets/packet_chat.c | 2 +- src/pc/network/packets/packet_collect_coin.c | 2 +- src/pc/network/packets/packet_collect_item.c | 2 +- src/pc/network/packets/packet_collect_star.c | 2 +- src/pc/network/packets/packet_custom.c | 4 +-- .../network/packets/packet_inside_painting.c | 2 +- src/pc/network/packets/packet_join.c | 4 +-- src/pc/network/packets/packet_keep_alive.c | 2 +- src/pc/network/packets/packet_kick.c | 2 +- src/pc/network/packets/packet_leaving.c | 2 +- src/pc/network/packets/packet_level_warp.c | 6 ++-- src/pc/network/packets/packet_object.c | 2 +- src/pc/network/packets/packet_player.c | 5 +-- src/pc/network/packets/packet_read_write.c | 35 ++++++++++++++++++- src/pc/network/packets/packet_reliable.c | 2 +- src/pc/network/packets/packet_reservation.c | 4 +-- src/pc/network/packets/packet_save_file.c | 2 +- src/pc/network/packets/packet_spawn_objects.c | 2 +- src/pc/network/packets/packet_spawn_star.c | 2 +- 22 files changed, 70 insertions(+), 32 deletions(-) diff --git a/src/pc/network/network.h b/src/pc/network/network.h index a44b86db..24d73d02 100644 --- a/src/pc/network/network.h +++ b/src/pc/network/network.h @@ -9,6 +9,9 @@ #include "packets/packet.h" #include "../cliopts.h" +#define SET_BIT(val, num) ((((u8)(val)) & 0x01) << (num)); +#define GET_BIT(val, num) (((val) >> (num)) & 0x01) + // Mario 64 specific externs extern struct MarioState gMarioStates[]; diff --git a/src/pc/network/packets/packet.c b/src/pc/network/packets/packet.c index bc98073e..56b2da76 100644 --- a/src/pc/network/packets/packet.c +++ b/src/pc/network/packets/packet.c @@ -11,6 +11,12 @@ void packet_receive(struct Packet* p) { return; } + // send an ACK if requested + network_send_ack(p); + + // check if we should drop packet + if (!packet_initial_read(p)) { return; } + switch (packetType) { case PACKET_ACK: network_receive_ack(p); break; case PACKET_PLAYER: network_receive_player(p); break; @@ -35,7 +41,4 @@ void packet_receive(struct Packet* p) { case PACKET_CUSTOM: network_receive_custom(p); break; default: LOG_ERROR("received unknown packet: %d", p->buffer[0]); } - - // send an ACK if requested - network_send_ack(p); } \ No newline at end of file diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h index bfb34659..ff0a73dc 100644 --- a/src/pc/network/packets/packet.h +++ b/src/pc/network/packets/packet.h @@ -39,6 +39,7 @@ struct Packet { u16 cursor; bool error; bool reliable; + bool levelAreaMustMatch; u16 seqId; bool sent; u8 buffer[PACKET_LENGTH]; @@ -53,8 +54,9 @@ enum KickReasonType { void packet_receive(struct Packet* packet); // packet_read_write.c -void packet_init(struct Packet* packet, enum PacketType packetType, bool reliable); +void packet_init(struct Packet* packet, enum PacketType packetType, bool reliable, bool levelAreaMustMatch); 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); u32 packet_hash(struct Packet* packet); bool packet_check_hash(struct Packet* packet); @@ -125,7 +127,7 @@ void network_receive_join(struct Packet* p); // packet_custom.c u8 network_register_custom_packet(void (*send_callback)(struct Packet* p, void* params), void (*receive_callback)(struct Packet* p)); -void network_send_custom(u8 customId, bool reliable, void* params); +void network_send_custom(u8 customId, bool reliable, bool levelAreaMustMatch, void* params); void network_receive_custom(struct Packet* p); // packet_chat.c diff --git a/src/pc/network/packets/packet_chat.c b/src/pc/network/packets/packet_chat.c index cbbb9932..bba05876 100644 --- a/src/pc/network/packets/packet_chat.c +++ b/src/pc/network/packets/packet_chat.c @@ -13,7 +13,7 @@ static u8 onRemoteChatId = 0; void network_send_chat(char* message) { u16 messageLength = strlen(message); struct Packet p; - packet_init(&p, PACKET_CHAT, true); + 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)); diff --git a/src/pc/network/packets/packet_collect_coin.c b/src/pc/network/packets/packet_collect_coin.c index a081f26a..49e11f2a 100644 --- a/src/pc/network/packets/packet_collect_coin.c +++ b/src/pc/network/packets/packet_collect_coin.c @@ -55,7 +55,7 @@ void network_send_collect_coin(struct Object* o) { enum BehaviorId behaviorId = get_id_from_behavior(o->behavior); struct Packet p; - packet_init(&p, PACKET_COLLECT_COIN, true); + 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); diff --git a/src/pc/network/packets/packet_collect_item.c b/src/pc/network/packets/packet_collect_item.c index 350fadb9..a277847e 100644 --- a/src/pc/network/packets/packet_collect_item.c +++ b/src/pc/network/packets/packet_collect_item.c @@ -52,7 +52,7 @@ void network_send_collect_item(struct Object* o) { enum BehaviorId behaviorId = get_id_from_behavior(o->behavior); struct Packet p; - packet_init(&p, PACKET_COLLECT_ITEM, true); + 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); diff --git a/src/pc/network/packets/packet_collect_star.c b/src/pc/network/packets/packet_collect_star.c index 80caf6a5..19ce155c 100644 --- a/src/pc/network/packets/packet_collect_star.c +++ b/src/pc/network/packets/packet_collect_star.c @@ -47,7 +47,7 @@ void network_send_collect_star(struct Object* o, s16 coinScore, s16 starIndex) { enum BehaviorId behaviorId = get_id_from_behavior(o->behavior); struct Packet p; - packet_init(&p, PACKET_COLLECT_STAR, true); + packet_init(&p, PACKET_COLLECT_STAR, true, false); packet_write(&p, &gCurrSaveFileNum, sizeof(s16)); packet_write(&p, &gCurrCourseNum, sizeof(s16)); diff --git a/src/pc/network/packets/packet_custom.c b/src/pc/network/packets/packet_custom.c index 4a076335..3088c3d4 100644 --- a/src/pc/network/packets/packet_custom.c +++ b/src/pc/network/packets/packet_custom.c @@ -22,11 +22,11 @@ u8 network_register_custom_packet(void (*send_callback)(struct Packet* p, void* return i; } -void network_send_custom(u8 customId, bool reliable, void* params) { +void network_send_custom(u8 customId, bool reliable, bool levelAreaMustMatch, void* params) { if (customPackets[customId].send_callback == NULL) { return; } struct Packet p; - packet_init(&p, PACKET_CUSTOM, reliable); + packet_init(&p, PACKET_CUSTOM, reliable, levelAreaMustMatch); packet_write(&p, &customId, sizeof(u8)); customPackets[customId].send_callback(&p, params); network_send(&p); diff --git a/src/pc/network/packets/packet_inside_painting.c b/src/pc/network/packets/packet_inside_painting.c index d032ee06..4d5cd0bb 100644 --- a/src/pc/network/packets/packet_inside_painting.c +++ b/src/pc/network/packets/packet_inside_painting.c @@ -35,7 +35,7 @@ void network_send_inside_painting(void) { populate_packet_data(&data); struct Packet p; - packet_init(&p, PACKET_INSIDE_PAINTING, true); + packet_init(&p, PACKET_INSIDE_PAINTING, true, false); packet_write(&p, &data, sizeof(struct PacketInsidePaintingData)); network_send(&p); seqId++; diff --git a/src/pc/network/packets/packet_join.c b/src/pc/network/packets/packet_join.c index 5fa94e7e..17165896 100644 --- a/src/pc/network/packets/packet_join.c +++ b/src/pc/network/packets/packet_join.c @@ -22,7 +22,7 @@ void network_send_join_request(void) { gOverrideEeprom = eeprom; struct Packet p; - packet_init(&p, PACKET_JOIN_REQUEST, true); + packet_init(&p, PACKET_JOIN_REQUEST, true, false); network_send_to(0, &p); LOG_INFO("sending join request"); } @@ -52,7 +52,7 @@ void network_send_join(struct Packet* joinRequestPacket) { char hash[HASH_LENGTH] = GIT_HASH; struct Packet p; - packet_init(&p, PACKET_JOIN, true); + packet_init(&p, PACKET_JOIN, true, false); packet_write(&p, &hash, sizeof(u8) * HASH_LENGTH); packet_write(&p, &joinRequestPacket->localIndex, sizeof(u8)); packet_write(&p, &gCurrSaveFileNum, sizeof(s16)); diff --git a/src/pc/network/packets/packet_keep_alive.c b/src/pc/network/packets/packet_keep_alive.c index 862edc20..089a62be 100644 --- a/src/pc/network/packets/packet_keep_alive.c +++ b/src/pc/network/packets/packet_keep_alive.c @@ -4,7 +4,7 @@ void network_send_keep_alive(void) { struct Packet p; - packet_init(&p, PACKET_KEEP_ALIVE, FALSE); + packet_init(&p, PACKET_KEEP_ALIVE, false, false); network_send(&p); gLastNetworkSend = clock(); LOG_INFO("sending keep alive"); diff --git a/src/pc/network/packets/packet_kick.c b/src/pc/network/packets/packet_kick.c index 706aa1d3..682c586e 100644 --- a/src/pc/network/packets/packet_kick.c +++ b/src/pc/network/packets/packet_kick.c @@ -5,7 +5,7 @@ void network_send_kick(enum KickReasonType kickReason) { struct Packet p; - packet_init(&p, PACKET_KICK, FALSE); + packet_init(&p, PACKET_KICK, false, false); packet_write(&p, &kickReason, sizeof(enum KickReasonType)); network_send_to(0, &p); } diff --git a/src/pc/network/packets/packet_leaving.c b/src/pc/network/packets/packet_leaving.c index 1b2c7bcd..5d067b43 100644 --- a/src/pc/network/packets/packet_leaving.c +++ b/src/pc/network/packets/packet_leaving.c @@ -19,7 +19,7 @@ void network_send_leaving(u8 globalIndex) { } struct Packet p; - packet_init(&p, PACKET_LEAVING, TRUE); + packet_init(&p, PACKET_LEAVING, true, false); packet_write(&p, &globalIndex, sizeof(u8)); if (gNetworkType == NT_SERVER) { network_send(&p); diff --git a/src/pc/network/packets/packet_level_warp.c b/src/pc/network/packets/packet_level_warp.c index ecc737ec..015d1238 100644 --- a/src/pc/network/packets/packet_level_warp.c +++ b/src/pc/network/packets/packet_level_warp.c @@ -70,7 +70,7 @@ void network_send_level_warp_begin(void) { populate_packet_data(&data, false, eventId); struct Packet p; - packet_init(&p, PACKET_LEVEL_WARP, true); + packet_init(&p, PACKET_LEVEL_WARP, true, false); packet_write(&p, &data, sizeof(struct PacketLevelWarpData)); network_send(&p); @@ -88,7 +88,7 @@ void network_send_level_warp_repeat(void) { populate_packet_data(&data, false, eventId); struct Packet p; - packet_init(&p, PACKET_LEVEL_WARP, false); + packet_init(&p, PACKET_LEVEL_WARP, false, false); packet_write(&p, &data, sizeof(struct PacketLevelWarpData)); network_send(&p); @@ -103,7 +103,7 @@ static void network_send_level_warp_done(u8 remoteEventId) { populate_packet_data(&data, true, remoteEventId); struct Packet p; - packet_init(&p, PACKET_LEVEL_WARP, true); + packet_init(&p, PACKET_LEVEL_WARP, true, false); packet_write(&p, &data, sizeof(struct PacketLevelWarpData)); network_send(&p); diff --git a/src/pc/network/packets/packet_object.c b/src/pc/network/packets/packet_object.c index 7047e796..8bb7e373 100644 --- a/src/pc/network/packets/packet_object.c +++ b/src/pc/network/packets/packet_object.c @@ -356,7 +356,7 @@ void network_send_object_reliability(struct Object* o, bool reliable) { // write the packet data struct Packet p; - packet_init(&p, PACKET_OBJECT, reliable); + packet_init(&p, PACKET_OBJECT, reliable, true); packet_write_object_header(&p, o); packet_write_object_full_sync(&p, o); packet_write_object_standard_fields(&p, o); diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 752f95be..59ce6885 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -8,9 +8,6 @@ #include "game/area.h" #include "audio/external.h" -#define SET_BIT(val, num) ((((u8)(val)) & 0x01) << (num)); -#define GET_BIT(val, num) (((val) >> (num)) & 0x01) - #pragma pack(1) struct PacketPlayerData { u32 rawData[80]; @@ -147,7 +144,7 @@ void network_send_player(void) { read_packet_data(&data, &gMarioStates[0]); struct Packet p; - packet_init(&p, PACKET_PLAYER, false); + packet_init(&p, PACKET_PLAYER, false, false); packet_write(&p, &data, sizeof(struct PacketPlayerData)); network_send(&p); } diff --git a/src/pc/network/packets/packet_read_write.c b/src/pc/network/packets/packet_read_write.c index 89e163e7..56ffb3a4 100644 --- a/src/pc/network/packets/packet_read_write.c +++ b/src/pc/network/packets/packet_read_write.c @@ -1,7 +1,8 @@ #include "../network.h" +#include "game/area.h" static u16 nextSeqNum = 1; -void packet_init(struct Packet* packet, enum PacketType packetType, bool reliable) { +void packet_init(struct Packet* packet, enum PacketType packetType, bool reliable, bool levelAreaMustMatch) { memset(packet->buffer, 0, PACKET_LENGTH); packet->buffer[0] = (char)packetType; if (reliable) { @@ -14,7 +15,18 @@ void packet_init(struct Packet* packet, enum PacketType packetType, bool reliabl packet->cursor = 3; packet->error = false; packet->reliable = reliable; + packet->levelAreaMustMatch = levelAreaMustMatch; packet->sent = false; + + // write packet flags + u8 flags; + flags |= SET_BIT(packet->levelAreaMustMatch, 0); + packet_write(packet, &flags, sizeof(u8)); + + if (levelAreaMustMatch) { + packet_write(packet, &gCurrLevelNum, sizeof(s16)); + packet_write(packet, &gCurrAreaIndex, sizeof(s16)); + } } void packet_write(struct Packet* packet, void* data, u16 length) { @@ -24,6 +36,27 @@ void packet_write(struct Packet* packet, void* data, u16 length) { packet->cursor += length; } +u8 packet_initial_read(struct Packet* packet) { + // read packet flags + u8 flags = 0; + packet_read(packet, &flags, sizeof(u8)); + packet->levelAreaMustMatch = GET_BIT(flags, 0); + + if (packet->levelAreaMustMatch) { + s16 currLevelNum; + s16 currAreaIndex; + packet_read(packet, &currLevelNum, sizeof(s16)); + packet_read(packet, &currAreaIndex, sizeof(s16)); + if (currLevelNum != gCurrLevelNum || currAreaIndex != gCurrAreaIndex) { + // drop packet + return FALSE; + } + } + + // don't drop packet + return TRUE; +} + void packet_read(struct Packet* packet, void* data, u16 length) { if (data == NULL) { packet->error = true; return; } u16 cursor = packet->cursor; diff --git a/src/pc/network/packets/packet_reliable.c b/src/pc/network/packets/packet_reliable.c index 2daf9d75..e32eff13 100644 --- a/src/pc/network/packets/packet_reliable.c +++ b/src/pc/network/packets/packet_reliable.c @@ -41,7 +41,7 @@ void network_send_ack(struct Packet* p) { // send back the ACK struct Packet ack = { 0 }; - packet_init(&ack, PACKET_ACK, false); + packet_init(&ack, PACKET_ACK, false, false); packet_write(&ack, &seqId, sizeof(u16)); network_send_to(0, &ack); } diff --git a/src/pc/network/packets/packet_reservation.c b/src/pc/network/packets/packet_reservation.c index 4193ec56..7857f5b1 100644 --- a/src/pc/network/packets/packet_reservation.c +++ b/src/pc/network/packets/packet_reservation.c @@ -13,7 +13,7 @@ void network_send_reservation_request(void) { assert(gNetworkType == NT_CLIENT); struct Packet p; - packet_init(&p, PACKET_RESERVATION_REQUEST, true); + packet_init(&p, PACKET_RESERVATION_REQUEST, true, false); network_send(&p); } @@ -48,7 +48,7 @@ void network_send_reservation(void) { } struct Packet p; - packet_init(&p, PACKET_RESERVATION, true); + packet_init(&p, PACKET_RESERVATION, true, false); packet_write(&p, reservedObjs, sizeof(u8) * RESERVATION_COUNT); network_send(&p); } diff --git a/src/pc/network/packets/packet_save_file.c b/src/pc/network/packets/packet_save_file.c index 61152869..986a297c 100644 --- a/src/pc/network/packets/packet_save_file.c +++ b/src/pc/network/packets/packet_save_file.c @@ -5,7 +5,7 @@ void network_send_save_file(s32 fileIndex) { assert(gNetworkType == NT_CLIENT); struct Packet p; - packet_init(&p, PACKET_SAVE_FILE, true); + packet_init(&p, PACKET_SAVE_FILE, true, false); packet_write(&p, &fileIndex, sizeof(s32)); network_send_to(gNetworkPlayerServer->localIndex, &p); } diff --git a/src/pc/network/packets/packet_spawn_objects.c b/src/pc/network/packets/packet_spawn_objects.c index 67a3c87c..c465eb73 100644 --- a/src/pc/network/packets/packet_spawn_objects.c +++ b/src/pc/network/packets/packet_spawn_objects.c @@ -46,7 +46,7 @@ void network_send_spawn_objects(struct Object* objects[], u32 models[], u8 objec assert(objectCount < MAX_SPAWN_OBJECTS_PER_PACKET); struct Packet p; - packet_init(&p, PACKET_SPAWN_OBJECTS, true); + packet_init(&p, PACKET_SPAWN_OBJECTS, true, true); packet_write(&p, &localSpawnId, sizeof(u8)); packet_write(&p, &objectCount, sizeof(u8)); diff --git a/src/pc/network/packets/packet_spawn_star.c b/src/pc/network/packets/packet_spawn_star.c index 4f4f2f08..71697f67 100644 --- a/src/pc/network/packets/packet_spawn_star.c +++ b/src/pc/network/packets/packet_spawn_star.c @@ -7,7 +7,7 @@ extern struct Object* gCurrentObject; 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); + packet_init(&p, PACKET_SPAWN_STAR, true, true); packet_write(&p, &starType, sizeof(u8)); packet_write(&p, &x, sizeof(f32)); packet_write(&p, &y, sizeof(f32));