From ffa0b225b089333abeeb0afbdb6effa397de4303 Mon Sep 17 00:00:00 2001 From: Nick Renieris Date: Wed, 22 Jun 2022 20:16:08 +0300 Subject: [PATCH] packets: Fix struct packing related bugs - sizeof(bool) is implementation defined. The server assumes it's 4 but for me it was 1 (tested with Release too) which caused some bugs - Structs aren't guaranteed to be packed. The compiler is free to change the layout, which we wouldn't want to for the Packet structs that we deserialize on the server. --- include/packets/CaptureInf.h | 4 ++-- include/packets/ChangeStagePacket.h | 2 +- include/packets/CostumeInf.h | 2 +- include/packets/GameInf.h | 4 ++-- include/packets/HackCapInf.h | 4 ++-- include/packets/InitPacket.h | 2 +- include/packets/Packet.h | 6 ++++-- include/packets/PlayerConnect.h | 2 +- include/packets/PlayerDC.h | 2 +- include/packets/PlayerInfPacket.h | 4 ++-- include/packets/ServerCommand.h | 2 +- include/packets/ShineCollect.h | 4 ++-- include/packets/TagInf.h | 4 ++-- include/types.h | 5 +++++ 14 files changed, 27 insertions(+), 20 deletions(-) diff --git a/include/packets/CaptureInf.h b/include/packets/CaptureInf.h index dc40f23..ede4cc0 100644 --- a/include/packets/CaptureInf.h +++ b/include/packets/CaptureInf.h @@ -2,12 +2,12 @@ #include "Packet.h" -struct CaptureInf : Packet { +struct PACKED CaptureInf : Packet { CaptureInf() : Packet() { this->mType = PacketType::CAPTUREINF; mPacketSize = sizeof(CaptureInf) - sizeof(Packet); }; char hackName[0x20] = {}; - + }; \ No newline at end of file diff --git a/include/packets/ChangeStagePacket.h b/include/packets/ChangeStagePacket.h index 69d0f29..961ceef 100644 --- a/include/packets/ChangeStagePacket.h +++ b/include/packets/ChangeStagePacket.h @@ -2,7 +2,7 @@ #include "Packet.h" -struct ChangeStagePacket : Packet { +struct PACKED ChangeStagePacket : Packet { ChangeStagePacket() : Packet() { this->mType = PacketType::CHANGESTAGE; mPacketSize = sizeof(ChangeStagePacket) - sizeof(Packet); diff --git a/include/packets/CostumeInf.h b/include/packets/CostumeInf.h index bba2277..672ff79 100644 --- a/include/packets/CostumeInf.h +++ b/include/packets/CostumeInf.h @@ -2,7 +2,7 @@ #include "Packet.h" -struct CostumeInf : Packet { +struct PACKED CostumeInf : Packet { CostumeInf() : Packet() {this->mType = PacketType::COSTUMEINF; mPacketSize = sizeof(CostumeInf) - sizeof(Packet);}; CostumeInf(const char* body, const char* cap) : Packet() { this->mType = PacketType::COSTUMEINF; diff --git a/include/packets/GameInf.h b/include/packets/GameInf.h index 7b82954..0665bc8 100644 --- a/include/packets/GameInf.h +++ b/include/packets/GameInf.h @@ -3,9 +3,9 @@ #include "Packet.h" #include "al/util.hpp" -struct GameInf : Packet { +struct PACKED GameInf : Packet { GameInf() : Packet() {this->mType = PacketType::GAMEINF; mPacketSize = sizeof(GameInf) - sizeof(Packet);}; - bool is2D = false; + bool4 is2D = false; u8 scenarioNo = -1; char stageName[0x40] = {}; diff --git a/include/packets/HackCapInf.h b/include/packets/HackCapInf.h index 7434bd5..c01ea60 100644 --- a/include/packets/HackCapInf.h +++ b/include/packets/HackCapInf.h @@ -2,10 +2,10 @@ #include "Packet.h" -struct HackCapInf : Packet { +struct PACKED HackCapInf : Packet { HackCapInf() : Packet() {this->mType = PacketType::HACKCAPINF; mPacketSize = sizeof(HackCapInf) - sizeof(Packet);}; sead::Vector3f capPos; sead::Quatf capQuat; - bool isCapVisible = false; + bool4 isCapVisible = false; char capAnim[PACKBUFSIZE] = {}; }; \ No newline at end of file diff --git a/include/packets/InitPacket.h b/include/packets/InitPacket.h index 002b93d..177b932 100644 --- a/include/packets/InitPacket.h +++ b/include/packets/InitPacket.h @@ -2,7 +2,7 @@ #include "Packet.h" -struct InitPacket : Packet { +struct PACKED InitPacket : Packet { InitPacket() : Packet() {this->mType = PacketType::CLIENTINIT; mPacketSize = sizeof(InitPacket) - sizeof(Packet);}; u16 maxPlayers = 0; }; \ No newline at end of file diff --git a/include/packets/Packet.h b/include/packets/Packet.h index 9fe183c..6a98562 100644 --- a/include/packets/Packet.h +++ b/include/packets/Packet.h @@ -5,6 +5,8 @@ #include "nn/account.h" +#include "types.h" + #define PACKBUFSIZE 0x30 #define COSTUMEBUFSIZE 0x20 @@ -27,7 +29,7 @@ enum PacketType : short { }; // attribute otherwise the build log is spammed with unused warnings -__attribute((used)) static const char *packetNames[] = { +USED static const char *packetNames[] = { "Unknown", "Player Info", "Player Cap Info", @@ -59,7 +61,7 @@ static const char *senderNames[] = { }; */ -struct Packet { +struct PACKED Packet { nn::account::Uid mUserID; // User ID of the packet owner PacketType mType = PacketType::UNKNOWN; short mPacketSize = 0; // represents packet size without size of header diff --git a/include/packets/PlayerConnect.h b/include/packets/PlayerConnect.h index 24e577e..52acbea 100644 --- a/include/packets/PlayerConnect.h +++ b/include/packets/PlayerConnect.h @@ -2,7 +2,7 @@ #include "Packet.h" -struct PlayerConnect : Packet { +struct PACKED PlayerConnect : Packet { PlayerConnect() : Packet() {this->mType = PacketType::PLAYERCON; mPacketSize = sizeof(PlayerConnect) - sizeof(Packet);}; ConnectionTypes conType; u16 maxPlayerCount; diff --git a/include/packets/PlayerDC.h b/include/packets/PlayerDC.h index d88432e..1086b74 100644 --- a/include/packets/PlayerDC.h +++ b/include/packets/PlayerDC.h @@ -2,6 +2,6 @@ #include "Packet.h" -struct PlayerDC : Packet { +struct PACKED PlayerDC : Packet { PlayerDC() : Packet() {this->mType = PacketType::PLAYERDC; mPacketSize = sizeof(PlayerDC) - sizeof(Packet);}; }; \ No newline at end of file diff --git a/include/packets/PlayerInfPacket.h b/include/packets/PlayerInfPacket.h index 0b54b0a..3ff35c4 100644 --- a/include/packets/PlayerInfPacket.h +++ b/include/packets/PlayerInfPacket.h @@ -4,9 +4,9 @@ #include "al/util.hpp" #include "algorithms/PlayerAnims.h" -struct PlayerInf : Packet { +struct PACKED PlayerInf : Packet { PlayerInf() : Packet() {mType = PacketType::PLAYERINF; mPacketSize = sizeof(PlayerInf) - sizeof(Packet);}; - sead::Vector3f playerPos; + sead::Vector3f playerPos; sead::Quatf playerRot; float animBlendWeights[6]; PlayerAnims::Type actName; diff --git a/include/packets/ServerCommand.h b/include/packets/ServerCommand.h index 4edd608..a5ced3f 100644 --- a/include/packets/ServerCommand.h +++ b/include/packets/ServerCommand.h @@ -2,7 +2,7 @@ #include "Packet.h" -struct ServerCommand : Packet { +struct PACKED ServerCommand : Packet { ServerCommand(const char *command) : Packet() {this->mType = PacketType::CMD; strcpy(srvCmd, command); mPacketSize = sizeof(ServerCommand) - sizeof(Packet);}; char srvCmd[PACKBUFSIZE] = {}; }; \ No newline at end of file diff --git a/include/packets/ShineCollect.h b/include/packets/ShineCollect.h index 9f8a8c7..5153c57 100644 --- a/include/packets/ShineCollect.h +++ b/include/packets/ShineCollect.h @@ -2,8 +2,8 @@ #include "Packet.h" -struct ShineCollect : Packet { +struct PACKED ShineCollect : Packet { ShineCollect() : Packet() {this->mType = PacketType::SHINECOLL; mPacketSize = sizeof(ShineCollect) - sizeof(Packet);}; int shineId = -1; - bool isGrand = false; + bool4 isGrand = false; }; \ No newline at end of file diff --git a/include/packets/TagInf.h b/include/packets/TagInf.h index 22bcdb9..9adba20 100644 --- a/include/packets/TagInf.h +++ b/include/packets/TagInf.h @@ -8,10 +8,10 @@ enum TagUpdateType : u8 { STATE = 1 << 1 }; -struct TagInf : Packet { +struct PACKED TagInf : Packet { TagInf() : Packet() { this->mType = PacketType::TAGINF; mPacketSize = sizeof(TagInf) - sizeof(Packet);}; TagUpdateType updateType; - bool isIt = false; + bool4 isIt = false; u8 seconds; u16 minutes; }; \ No newline at end of file diff --git a/include/types.h b/include/types.h index 4937f7b..ebcbc23 100644 --- a/include/types.h +++ b/include/types.h @@ -18,6 +18,8 @@ typedef signed int s32; typedef int64_t s64; typedef __int128_t s128; +typedef u32 bool4; // guaranteed to be 4 bytes, 'bool' is impl. defined + typedef float f32; typedef double f64; @@ -76,3 +78,6 @@ struct Rect float right; float top; }; + +#define PACKED __attribute__((packed)) +#define USED __attribute__((used))