mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
Add anti-spoofing
This commit is contained in:
parent
a1dbd4b268
commit
8bfadc95f1
15 changed files with 81 additions and 41 deletions
|
|
@ -138,7 +138,7 @@ void packet_receive(struct Packet* p) {
|
||||||
struct NetworkPlayer* np = &gNetworkPlayers[p->localIndex];
|
struct NetworkPlayer* np = &gNetworkPlayers[p->localIndex];
|
||||||
for (int i = 0; i < MAX_RX_SEQ_IDS; i++) {
|
for (int i = 0; i < MAX_RX_SEQ_IDS; i++) {
|
||||||
if (np->rxSeqIds[i] == p->seqId && np->rxPacketHash[i] == packetHash) {
|
if (np->rxSeqIds[i] == p->seqId && np->rxPacketHash[i] == packetHash) {
|
||||||
LOG_INFO("received duplicate packet");
|
LOG_INFO("received duplicate packet %u", packetType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -180,3 +180,11 @@ void packet_receive(struct Packet* p) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool packet_spoofed(struct Packet* p, u8 globalIndex) {
|
||||||
|
if (gNetworkSystem->requireServerBroadcast) { return false; }
|
||||||
|
if (p->localIndex == UNKNOWN_LOCAL_INDEX) { return false; }
|
||||||
|
if (p->localIndex >= MAX_PLAYERS) { return true; }
|
||||||
|
|
||||||
|
return (gNetworkPlayers[p->localIndex].globalIndex != globalIndex);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ struct LSTNetworkType {
|
||||||
// packet.c
|
// packet.c
|
||||||
void packet_process(struct Packet* p);
|
void packet_process(struct Packet* p);
|
||||||
void packet_receive(struct Packet* packet);
|
void packet_receive(struct Packet* packet);
|
||||||
|
bool packet_spoofed(struct Packet* p, u8 globalIndex);
|
||||||
|
|
||||||
// packet_read_write.c
|
// packet_read_write.c
|
||||||
void packet_init(struct Packet* packet, enum PacketType packetType, bool reliable, enum PacketLevelMatchType levelAreaMustMatch);
|
void packet_init(struct Packet* packet, enum PacketType packetType, bool reliable, enum PacketLevelMatchType levelAreaMustMatch);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,12 @@ void network_receive_area_request(struct Packet* p) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, globalIndex)) {
|
||||||
|
LOG_ERROR("rx spoofed area request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// send area
|
// send area
|
||||||
network_send_area(toNp);
|
network_send_area(toNp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,32 +4,6 @@
|
||||||
#include "pc/djui/djui.h"
|
#include "pc/djui/djui.h"
|
||||||
#include "pc/debuglog.h"
|
#include "pc/debuglog.h"
|
||||||
|
|
||||||
#ifdef DEVELOPMENT
|
|
||||||
#include "behavior_table.h"
|
|
||||||
|
|
||||||
static void print_sync_object_table(void) {
|
|
||||||
LOG_INFO("Sync Object Table");
|
|
||||||
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
|
|
||||||
if (gSyncObjects[i].o == NULL) { continue; }
|
|
||||||
u32 behaviorId = get_id_from_behavior(gSyncObjects[i].behavior);
|
|
||||||
LOG_INFO("%03d: %08X", i, behaviorId);
|
|
||||||
behaviorId = behaviorId; // suppress warning
|
|
||||||
}
|
|
||||||
LOG_INFO(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_network_player_table(void) {
|
|
||||||
LOG_INFO("Network Player Table");
|
|
||||||
LOG_INFO("%5s %5s %8s %8s %8s %8s %8s", "gID", "lID", "course", "act", "level", "area", "valid");
|
|
||||||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
|
||||||
struct NetworkPlayer* np = &gNetworkPlayers[i];
|
|
||||||
if (!np->connected) { continue; }
|
|
||||||
LOG_INFO("%5d %5d %8d %8d %8d %8d %8d", np->globalIndex, np->localIndex, np->currCourseNum, np->currActNum, np->currLevelNum, np->currAreaIndex, np->currAreaSyncValid);
|
|
||||||
}
|
|
||||||
LOG_INFO(" ");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void network_send_chat(char* message, u8 globalIndex) {
|
void network_send_chat(char* message, u8 globalIndex) {
|
||||||
u16 messageLength = strlen(message);
|
u16 messageLength = strlen(message);
|
||||||
struct Packet p = { 0 };
|
struct Packet p = { 0 };
|
||||||
|
|
@ -38,12 +12,6 @@ void network_send_chat(char* message, u8 globalIndex) {
|
||||||
packet_write(&p, &messageLength, sizeof(u16));
|
packet_write(&p, &messageLength, sizeof(u16));
|
||||||
packet_write(&p, message, messageLength * sizeof(u8));
|
packet_write(&p, message, messageLength * sizeof(u8));
|
||||||
network_send(&p);
|
network_send(&p);
|
||||||
|
|
||||||
#ifdef DEVELOPMENT
|
|
||||||
print_network_player_table();
|
|
||||||
//reservation_area_debug();
|
|
||||||
//print_sync_object_table();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void network_receive_chat(struct Packet* p) {
|
void network_receive_chat(struct Packet* p) {
|
||||||
|
|
@ -53,15 +21,16 @@ void network_receive_chat(struct Packet* p) {
|
||||||
|
|
||||||
packet_read(p, &globalIndex, sizeof(u8));
|
packet_read(p, &globalIndex, sizeof(u8));
|
||||||
packet_read(p, &remoteMessageLength, sizeof(u16));
|
packet_read(p, &remoteMessageLength, sizeof(u16));
|
||||||
if (remoteMessageLength > 256) { remoteMessageLength = 255; }
|
if (remoteMessageLength >= 255) { remoteMessageLength = 255; }
|
||||||
packet_read(p, &remoteMessage, remoteMessageLength * sizeof(u8));
|
packet_read(p, &remoteMessage, remoteMessageLength * sizeof(u8));
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, globalIndex)) {
|
||||||
|
LOG_ERROR("rx spoofed chat");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// add the message
|
// add the message
|
||||||
djui_chat_message_create_from(globalIndex, remoteMessage);
|
djui_chat_message_create_from(globalIndex, remoteMessage);
|
||||||
LOG_INFO("rx chat: %s", remoteMessage);
|
LOG_INFO("rx chat: %s", remoteMessage);
|
||||||
/*
|
|
||||||
#ifdef DEVELOPMENT
|
|
||||||
print_network_player_table();
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,12 @@ void network_receive_leaving(struct Packet* p) {
|
||||||
u8 globalIndex = 0;
|
u8 globalIndex = 0;
|
||||||
packet_read(p, &globalIndex, sizeof(u8));
|
packet_read(p, &globalIndex, sizeof(u8));
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, globalIndex)) {
|
||||||
|
LOG_ERROR("rx spoofed leaving");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LOG_INFO("Received leaving event for %d", globalIndex);
|
LOG_INFO("Received leaving event for %d", globalIndex);
|
||||||
network_player_disconnected(globalIndex);
|
network_player_disconnected(globalIndex);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,13 @@ void network_receive_level_area_inform(struct Packet* p) {
|
||||||
LOG_INFO("Received old level area inform seq: %d vs %d", sLevelAreaInformSeq[0][globalIndex], seq);
|
LOG_INFO("Received old level area inform seq: %d vs %d", sLevelAreaInformSeq[0][globalIndex], seq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, globalIndex)) {
|
||||||
|
LOG_ERROR("rx spoofed level area inform");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sLevelAreaInformSeq[0][globalIndex] = seq;
|
sLevelAreaInformSeq[0][globalIndex] = seq;
|
||||||
|
|
||||||
network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex);
|
network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex);
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,12 @@ void network_receive_level_area_request(struct Packet* p) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, globalIndex)) {
|
||||||
|
LOG_ERROR("rx spoofed level area request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// send level area
|
// send level area
|
||||||
network_send_level(toNp, true);
|
network_send_level(toNp, true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,12 @@ void network_receive_level_request(struct Packet* p) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, globalIndex)) {
|
||||||
|
LOG_ERROR("rx spoofed level request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// send level
|
// send level
|
||||||
network_send_level(toNp, false);
|
network_send_level(toNp, false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -294,6 +294,12 @@ static struct SyncObject* packet_read_object_header(struct Packet* p, u8* fromLo
|
||||||
struct NetworkPlayer* np = network_player_from_global_index(fromGlobalIndex);
|
struct NetworkPlayer* np = network_player_from_global_index(fromGlobalIndex);
|
||||||
*fromLocalIndex = (np != NULL) ? np->localIndex : p->localIndex;
|
*fromLocalIndex = (np != NULL) ? np->localIndex : p->localIndex;
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, fromGlobalIndex)) {
|
||||||
|
LOG_ERROR("rx spoofed object");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// get sync ID, sanity check
|
// get sync ID, sanity check
|
||||||
u32 syncId = 0;
|
u32 syncId = 0;
|
||||||
packet_read(p, &syncId, sizeof(u32));
|
packet_read(p, &syncId, sizeof(u32));
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "game/mario_misc.h"
|
#include "game/mario_misc.h"
|
||||||
#include "pc/configfile.h"
|
#include "pc/configfile.h"
|
||||||
#include "pc/djui/djui.h"
|
#include "pc/djui/djui.h"
|
||||||
|
#include "pc/debuglog.h"
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
struct PacketPlayerData {
|
struct PacketPlayerData {
|
||||||
|
|
@ -206,6 +207,12 @@ void network_receive_player(struct Packet* p) {
|
||||||
struct NetworkPlayer* np = network_player_from_global_index(globalIndex);
|
struct NetworkPlayer* np = network_player_from_global_index(globalIndex);
|
||||||
if (np == NULL || np->localIndex == UNKNOWN_LOCAL_INDEX || !np->connected) { return; }
|
if (np == NULL || np->localIndex == UNKNOWN_LOCAL_INDEX || !np->connected) { return; }
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, globalIndex)) {
|
||||||
|
LOG_ERROR("rx spoofed player");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// prevent receiving a packet about our player
|
// prevent receiving a packet about our player
|
||||||
if (gNetworkPlayerLocal && globalIndex == gNetworkPlayerLocal->globalIndex) { return; }
|
if (gNetworkPlayerLocal && globalIndex == gNetworkPlayerLocal->globalIndex) { return; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,12 @@ void network_receive_player_settings(struct Packet* p) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, globalId)) {
|
||||||
|
LOG_ERROR("rx spoofed player settings");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct NetworkPlayer* np = network_player_from_global_index(globalId);
|
struct NetworkPlayer* np = network_player_from_global_index(globalId);
|
||||||
snprintf(np->name, MAX_PLAYER_STRING, "%s", playerName);
|
snprintf(np->name, MAX_PLAYER_STRING, "%s", playerName);
|
||||||
np->modelIndex = playerModel;
|
np->modelIndex = playerModel;
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,12 @@ void network_receive_spawn_star_nle(struct Packet* p) {
|
||||||
packet_read(p, &syncId, sizeof(u32));
|
packet_read(p, &syncId, sizeof(u32));
|
||||||
packet_read(p, ¶ms, sizeof(u32));
|
packet_read(p, ¶ms, sizeof(u32));
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, globalIndex)) {
|
||||||
|
LOG_ERROR("rx spoofed star");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// grab network player first
|
// grab network player first
|
||||||
struct Object* object = NULL;
|
struct Object* object = NULL;
|
||||||
if (globalIndex != UNKNOWN_GLOBAL_INDEX) {
|
if (globalIndex != UNKNOWN_GLOBAL_INDEX) {
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,12 @@ void network_receive_sync_valid(struct Packet* p) {
|
||||||
packet_read(p, &areaIndex, sizeof(s16));
|
packet_read(p, &areaIndex, sizeof(s16));
|
||||||
packet_read(p, &fromGlobalIndex, sizeof(u8));
|
packet_read(p, &fromGlobalIndex, sizeof(u8));
|
||||||
|
|
||||||
|
// anti spoof
|
||||||
|
if (packet_spoofed(p, fromGlobalIndex)) {
|
||||||
|
LOG_ERROR("rx spoofed sync valid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (gNetworkType != NT_SERVER) {
|
if (gNetworkType != NT_SERVER) {
|
||||||
extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex;
|
extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex;
|
||||||
if (courseNum != gCurrCourseNum || actNum != gCurrActStarNum || levelNum != gCurrLevelNum || (areaIndex != gCurrAreaIndex && areaIndex != -1)) {
|
if (courseNum != gCurrCourseNum || actNum != gCurrActStarNum || levelNum != gCurrLevelNum || (areaIndex != gCurrAreaIndex && areaIndex != -1)) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue