Drop various types of packets if level/area doesn't match

This commit is contained in:
MysterD 2020-09-26 15:52:00 -07:00
parent e0bdaa1229
commit 168a41f0f6
22 changed files with 70 additions and 32 deletions

View file

@ -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[];

View file

@ -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);
}

View file

@ -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

View file

@ -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));

View file

@ -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);

View file

@ -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);

View file

@ -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));

View file

@ -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);

View file

@ -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++;

View file

@ -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));

View file

@ -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");

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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));

View file

@ -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));