From ce4d119c43de1f9601663379470ab5986389f9d7 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 8 Jul 2025 18:58:18 -0400 Subject: [PATCH 1/3] Progress on netcode Bulk of work is matching NetManager functions that don't call DWC functions, as those aren't defined and are not in scope of this commit Additionally, various progress has been made, both on the source and header, of other net related classes --- config/RMCP01/module/splits.txt | 18 +- config/RMCP01/module/symbols.txt | 48 ++--- configure.py | 6 +- include/rk_common.h | 2 + lib/dwc/common/dwc_error.c | 16 +- lib/dwc/common/dwc_error.h | 4 +- lib/dwc/common/dwci_error.h | 12 +- src/net/FriendInfo.hpp | 61 ++++++ src/net/MiscPacketHandler.cpp | 30 +++ src/net/MiscPacketHandler.hpp | 37 ++++ src/net/NetManager.cpp | 320 ++++++++++++++++++++++++++++++- src/net/NetManager.hpp | 129 +++++++++---- src/net/packets/EVENT.cpp | 5 + src/net/packets/EVENT.hpp | 11 ++ src/net/packets/ITEM.cpp | 5 + src/net/packets/ITEM.hpp | 10 + src/net/packets/RACEHEADER1.cpp | 58 ++++++ src/net/packets/RACEHEADER1.hpp | 27 ++- src/net/packets/SELECT.cpp | 9 + src/net/packets/SELECT.hpp | 19 +- 20 files changed, 742 insertions(+), 85 deletions(-) create mode 100644 src/net/FriendInfo.hpp create mode 100644 src/net/MiscPacketHandler.cpp create mode 100644 src/net/MiscPacketHandler.hpp create mode 100644 src/net/packets/EVENT.cpp create mode 100644 src/net/packets/ITEM.cpp create mode 100644 src/net/packets/SELECT.cpp diff --git a/config/RMCP01/module/splits.txt b/config/RMCP01/module/splits.txt index 8a134e05c..99eb9b7fb 100644 --- a/config/RMCP01/module/splits.txt +++ b/config/RMCP01/module/splits.txt @@ -164,15 +164,31 @@ ui/SectionAutogens.cpp: SectionDirector.o: .text start:0x001247CC end:0x00125B04 +net/MiscPacketHandler.cpp: + .text start:0x00142E54 end:0x00145484 + .bss start:0x00004870 end:0x00004878 + net/NetManager.cpp: .text start:0x00145770 end:0x00149E98 .data start:0x0000DD90 end:0x0000DDC8 - .bss start:0x000049F8 end:0x00004A00 + .bss start:0x00004878 end:0x00004A00 net/packets/ROOM.cpp: .text start:0x0014A6D4 end:0x0014AFA0 .bss start:0x00004A00 end:0x00004A10 +net/packets/EVENT.cpp: + .text start:0x0014B134 end:0x0014BD38 + .bss start:0x00004A10 end:0x00004A18 + +net/packets/ITEM.cpp: + .text start:0x0014BD38 end:0x0014FAD8 + .bss start:0x00004A18 end:0x00004A20 + +net/packets/SELECT.cpp: + .text start:0x0014FAD8 end:0x001523C4 + .bss start:0x00004A20 end:0x00004A28 + net/packets/USER.cpp: .text start:0x001523C4 end:0x00152DE0 .bss start:0x00004A28 end:0x00004A30 diff --git a/config/RMCP01/module/symbols.txt b/config/RMCP01/module/symbols.txt index f3fbb2692..f77214c7d 100644 --- a/config/RMCP01/module/symbols.txt +++ b/config/RMCP01/module/symbols.txt @@ -7146,8 +7146,8 @@ fn_1_143854 = .text:0x00143854; // type:function size:0xB0 fn_1_143904 = .text:0x00143904; // type:function size:0x5C fn_1_143960 = .text:0x00143960; // type:function size:0x64 fn_1_1439C4 = .text:0x001439C4; // type:function size:0x64 -fn_1_143A28 = .text:0x00143A28; // type:function size:0x18 -fn_1_143A40 = .text:0x00143A40; // type:function size:0x58 +clearAidFromUnkBitfield__Q23Net17MiscPacketHandlerFUl = .text:0x00143A28; // type:function size:0x18 +__ct__Q23Net17MiscPacketHandlerFv = .text:0x00143A40; // type:function size:0x58 fn_1_143A98 = .text:0x00143A98; // type:function size:0x40 fn_1_143AD8 = .text:0x00143AD8; // type:function size:0x40 fn_1_143B18 = .text:0x00143B18; // type:function size:0x58 @@ -7165,7 +7165,7 @@ fn_1_1443A4 = .text:0x001443A4; // type:function size:0xC fn_1_1443B0 = .text:0x001443B0; // type:function size:0xAC fn_1_14445C = .text:0x0014445C; // type:function size:0x10 MiscPacketHandler_isPlayerConnected = .text:0x0014446C; // type:function size:0x88 scope:global align:4 -MiscPacketHandler_isPlayerLocal = .text:0x001444F4; // type:function size:0x70 scope:global align:4 +isPlayerLocal__Q23Net17MiscPacketHandlerFUl = .text:0x001444F4; // type:function size:0x70 scope:global align:4 fn_1_144564 = .text:0x00144564; // type:function size:0x6C fn_1_1445D0 = .text:0x001445D0; // type:function size:0xB0 fn_1_144680 = .text:0x00144680; // type:function size:0xCC @@ -7189,8 +7189,8 @@ startWWVSSearch__Q23Net10NetManagerFUc = .text:0x00145E00; // type:function size startRegionalVSSearch__Q23Net10NetManagerFUc = .text:0x00145EBC; // type:function size:0xBC startWWBattleSearch__Q23Net10NetManagerFUc = .text:0x00145F78; // type:function size:0xBC startRegionalBattleSearch__Q23Net10NetManagerFUc = .text:0x00146034; // type:function size:0xBC -fn_1_1460F0 = .text:0x001460F0; // type:function size:0x130 -fn_1_146220 = .text:0x00146220; // type:function size:0x130 +joinFriendPublicVS__Q23Net10NetManagerFUlUc = .text:0x001460F0; // type:function size:0x130 +joinFriendPublicBT__Q23Net10NetManagerFUlUc = .text:0x00146220; // type:function size:0x130 joinFriendRoom__Q23Net10NetManagerFUlUc = .text:0x00146350; // type:function size:0xD4 createFriendRoom__Q23Net10NetManagerFUc = .text:0x00146424; // type:function size:0xC0 resetRH1andROOM__Q23Net10NetManagerFv = .text:0x001464E4; // type:function size:0x58 @@ -7204,7 +7204,7 @@ fn_1_146738 = .text:0x00146738; // type:function size:0x58 fn_1_146790 = .text:0x00146790; // type:function size:0x28 fn_1_1467B8 = .text:0x001467B8; // type:function size:0x134 fn_1_1468EC = .text:0x001468EC; // type:function size:0xCC -fn_1_1469B8 = .text:0x001469B8; // type:function size:0x30 +resetFriendData__Q23Net10NetManagerFUl = .text:0x001469B8; // type:function size:0x30 isConnectionStateIdleOrInMM__Q23Net10NetManagerCFv = .text:0x001469E8; // type:function size:0xA8 isTaskThreadIdle__Q23Net10NetManagerFv = .text:0x00146A90; // type:function size:0x2C isConnectionStateIdle__Q23Net10NetManagerCFv = .text:0x00146ABC; // type:function size:0x90 @@ -7222,8 +7222,8 @@ RKNetController_trySendNextRACEPacket = .text:0x00147A7C; // type:function size: fn_1_147C30 = .text:0x00147C30; // type:function size:0xE0 fn_1_147D10 = .text:0x00147D10; // type:function size:0x7C setConnectionState__Q23Net10NetManagerFQ33Net10NetManager15ConnectionState = .text:0x00147D8C; // type:function size:0x8 -getConnectionState__Q23Net10NetManagerFv = .text:0x00147D94; // type:function size:0x84 -RKNetController_handleError = .text:0x00147E18; // type:function size:0x160 scope:global align:4 +getConnectionState__Q23Net10NetManagerCFv = .text:0x00147D94; // type:function size:0x84 +handleError__Q23Net10NetManagerFv = .text:0x00147E18; // type:function size:0x160 scope:global align:4 alloc__Q23Net10NetManagerFUll = .text:0x00147F78; // type:function size:0x88 free__Q23Net10NetManagerFPv = .text:0x00148000; // type:function size:0x64 SOAlloc__Q23Net10NetManagerFUlUl = .text:0x00148064; // type:function size:0x80 @@ -7237,15 +7237,15 @@ fn_1_1483B4 = .text:0x001483B4; // type:function size:0xBC fn_1_148470 = .text:0x00148470; // type:function size:0xB4 fn_1_148524 = .text:0x00148524; // type:function size:0x20 fn_1_148544 = .text:0x00148544; // type:function size:0x4 -fn_1_148548 = .text:0x00148548; // type:function size:0x1C +setFriendStatusUpdatingCallback2__Q23Net10NetManagerFUlUlPQ23Net10NetManager = .text:0x00148548; // type:function size:0x1C fn_1_148564 = .text:0x00148564; // type:function size:0x4 -fn_1_148568 = .text:0x00148568; // type:function size:0xC +setFriendStatusUpdatingCallback__Q23Net10NetManagerFUlPQ23Net10NetManager = .text:0x00148568; // type:function size:0xC fn_1_148574 = .text:0x00148574; // type:function size:0x68 fn_1_1485DC = .text:0x001485DC; // type:function size:0x20C NetManager_connect = .text:0x001487E8; // type:function size:0x1A0 scope:global align:4 initMMInfos__Q23Net10NetManagerFv = .text:0x00148988; // type:function size:0xA4 fn_1_148A2C = .text:0x00148A2C; // type:function size:0x1A0 -fn_1_148BCC = .text:0x00148BCC; // type:function size:0xC4 +resetFriends__Q23Net10NetManagerFv = .text:0x00148BCC; // type:function size:0xC4 fn_1_148C90 = .text:0x00148C90; // type:function size:0x12C fn_1_148DBC = .text:0x00148DBC; // type:function size:0x448 fn_1_149204 = .text:0x00149204; // type:function size:0x64 @@ -7254,10 +7254,10 @@ fn_1_1492CC = .text:0x001492CC; // type:function size:0x244 fn_1_149510 = .text:0x00149510; // type:function size:0x178 fn_1_149688 = .text:0x00149688; // type:function size:0x48 RKNetController_processRACEPacket = .text:0x001496D0; // type:function size:0x13C scope:global align:4 -fn_1_14980C = .text:0x0014980C; // type:function size:0x160 -fn_1_14996C = .text:0x0014996C; // type:function size:0x38 -RKNetController_getLocalPlayerId = .text:0x001499A4; // type:function size:0x24C scope:global align:4 -fn_1_149BF0 = .text:0x00149BF0; // type:function size:0x110 +updateAidMapping__Q23Net10NetManagerFv = .text:0x0014980C; // type:function size:0x160 +resetPidToAidMap__Q23Net10NetManagerFv = .text:0x0014996C; // type:function size:0x38 +getLocalPlayerId__Q23Net10NetManagerFUl = .text:0x001499A4; // type:function size:0x24C scope:global align:4 +getFriendJoinableStatus__Q23Net10NetManagerCFUl = .text:0x00149BF0; // type:function size:0x110 RKNetController_updateStatusData = .text:0x00149D00; // type:function size:0x198 scope:global align:4 fn_1_149E98 = .text:0x00149E98; // type:function size:0x60 fn_1_149EF8 = .text:0x00149EF8; // type:function size:0x60 @@ -7298,7 +7298,7 @@ fn_1_14B004 = .text:0x0014B004; // type:function size:0x54 fn_1_14B058 = .text:0x0014B058; // type:function size:0x44 fn_1_14B09C = .text:0x0014B09C; // type:function size:0x40 fn_1_14B0DC = .text:0x0014B0DC; // type:function size:0x58 -fn_1_14B134 = .text:0x0014B134; // type:function size:0x118 +createStaticInstance__Q23Net12EVENTHandlerFv = .text:0x0014B134; // type:function size:0x118 fn_1_14B24C = .text:0x0014B24C; // type:function size:0x40 fn_1_14B28C = .text:0x0014B28C; // type:function size:0xEC fn_1_14B378 = .text:0x0014B378; // type:function size:0x4 @@ -7315,7 +7315,7 @@ fn_1_14BC98 = .text:0x0014BC98; // type:function size:0x2C fn_1_14BCC4 = .text:0x0014BCC4; // type:function size:0x38 fn_1_14BCFC = .text:0x0014BCFC; // type:function size:0x14 fn_1_14BD10 = .text:0x0014BD10; // type:function size:0x28 -ITEMHandler_getStaticInstance = .text:0x0014BD38; // type:function size:0x27C scope:global align:4 +createStaticInstance__Q23Net11ITEMHandlerFv = .text:0x0014BD38; // type:function size:0x27C scope:global align:4 fn_1_14BFB4 = .text:0x0014BFB4; // type:function size:0x40 ITEMHandler_construct = .text:0x0014BFF4; // type:function size:0x23C scope:global align:4 fn_1_14C230 = .text:0x0014C230; // type:function size:0x4 @@ -7367,7 +7367,7 @@ fn_1_15009C = .text:0x0015009C; // type:function size:0x20 fn_1_1500BC = .text:0x001500BC; // type:function size:0x1C fn_1_1500D8 = .text:0x001500D8; // type:function size:0x1C fn_1_1500F4 = .text:0x001500F4; // type:function size:0x24 -fn_1_150118 = .text:0x00150118; // type:function size:0x8 +getPlayerIdToAidMapping__Q23Net13SELECTHandlerCFv = .text:0x00150118; // type:function size:0x8 fn_1_150120 = .text:0x00150120; // type:function size:0x50 fn_1_150170 = .text:0x00150170; // type:function size:0x50 fn_1_1501C0 = .text:0x001501C0; // type:function size:0x50 @@ -7447,7 +7447,7 @@ setPrepared__Q23Net18RACEHEADER1HandlerFv = .text:0x001538C8; // type:function s reset__Q23Net18RACEHEADER1HandlerFv = .text:0x001538D4; // type:function size:0x14C fn_1_153A20 = .text:0x00153A20; // type:function size:0x338 fn_1_153D58 = .text:0x00153D58; // type:function size:0xA4 -fn_1_153DFC = .text:0x00153DFC; // type:function size:0x210 +courseValid__Q23Net18RACEHEADER1HandlerFv = .text:0x00153DFC; // type:function size:0x210 fn_1_15400C = .text:0x0015400C; // type:function size:0x18 fn_1_154024 = .text:0x00154024; // type:function size:0x18 fn_1_15403C = .text:0x0015403C; // type:function size:0x15C @@ -7457,7 +7457,7 @@ fn_1_154314 = .text:0x00154314; // type:function size:0x108 fn_1_15441C = .text:0x0015441C; // type:function size:0x174 fn_1_154590 = .text:0x00154590; // type:function size:0xF8 fn_1_154688 = .text:0x00154688; // type:function size:0xF8 -fn_1_154780 = .text:0x00154780; // type:function size:0xF8 +getPlayerIdToAidMapping__Q23Net18RACEHEADER1HandlerCFv = .text:0x00154780; // type:function size:0xF8 fn_1_154878 = .text:0x00154878; // type:function size:0x170 fn_1_1549E8 = .text:0x001549E8; // type:function size:0x164 fn_1_154B4C = .text:0x00154B4C; // type:function size:0xF8 @@ -24511,15 +24511,15 @@ lbl_1_bss_4854 = .bss:0x00004854; // type:object size:0x4 lbl_1_bss_4858 = .bss:0x00004858; // type:object size:0x8 lbl_1_bss_4860 = .bss:0x00004860; // type:object size:0x8 lbl_1_bss_4868 = .bss:0x00004868; // type:object size:0x8 -lbl_1_bss_4870 = .bss:0x00004870; // type:object size:0x8 data:4byte +spInstance__Q23Net17MiscPacketHandler = .bss:0x00004870; // type:object size:0x8 data:4byte lbl_1_bss_4878 = .bss:0x00004878; // type:object size:0x80 data:4byte lbl_1_bss_48F8 = .bss:0x000048F8; // type:object size:0x100 spInstance__Q23Net10NetManager = .bss:0x000049F8; // type:object size:0x8 data:4byte spInstance__Q23Net11ROOMHandler = .bss:0x00004A00; // type:object size:0x8 data:4byte lbl_1_bss_4A08 = .bss:0x00004A08; // type:object size:0x8 data:4byte -lbl_1_bss_4A10 = .bss:0x00004A10; // type:object size:0x8 data:4byte -lbl_1_bss_4A18 = .bss:0x00004A18; // type:object size:0x8 data:4byte -lbl_1_bss_4A20 = .bss:0x00004A20; // type:object size:0x8 data:4byte +spInstance__Q23Net12EVENTHandler = .bss:0x00004A10; // type:object size:0x8 data:4byte +spInstance__Q23Net11ITEMHandler = .bss:0x00004A18; // type:object size:0x8 data:4byte +spInstance__Q23Net13SELECTHandler = .bss:0x00004A20; // type:object size:0x8 data:4byte spInstance__Q23Net11USERHandler = .bss:0x00004A28; // type:object size:0x8 data:4byte lbl_1_bss_4A30 = .bss:0x00004A30; // type:object size:0x8 data:4byte spInstance__Q23Net18RACEHEADER1Handler = .bss:0x00004A38; // type:object size:0x8 data:4byte diff --git a/configure.py b/configure.py index 283f5dee6..d56d2071a 100755 --- a/configure.py +++ b/configure.py @@ -793,10 +793,14 @@ def MatchingFor(*versions): Object(Matching, "geo/BoxColManager.cpp"), Object(Matching, "geo/BoxColUnit.cpp"), + Object(NonMatching, "net/MiscPacketHandler.cpp"), Object(NonMatching, "net/NetManager.cpp"), + Object(NonMatching, "net/packets/ROOM.cpp"), + Object(NonMatching, "net/packets/EVENT.cpp"), + Object(NonMatching, "net/packets/ITEM.cpp"), + Object(NonMatching, "net/packets/SELECT.cpp"), Object(NonMatching, "net/packets/USER.cpp"), Object(NonMatching, "net/packets/RACEHEADER1.cpp"), - Object(NonMatching, "net/packets/ROOM.cpp"), ], }, { diff --git a/include/rk_common.h b/include/rk_common.h index 35f2b0a91..e7c542d28 100644 --- a/include/rk_common.h +++ b/include/rk_common.h @@ -2,3 +2,5 @@ #define MAX_PLAYER_COUNT 12 #define ARRAY_COUNT(array) (sizeof(array) / sizeof((array)[0])) + +#define MAX_FRIEND_COUNT 30 diff --git a/lib/dwc/common/dwc_error.c b/lib/dwc/common/dwc_error.c index 8e8d84442..d122522a8 100644 --- a/lib/dwc/common/dwc_error.c +++ b/lib/dwc/common/dwc_error.c @@ -1,7 +1,5 @@ #include "dwc_error.h" -#include "dwci_error.h" - //! @brief The last error code encountered. //! int stDwcErrorCode; @@ -17,7 +15,7 @@ int DWC_GetLastError(int* errorCode) { return stDwcLastError; } -s32 DWC_GetLastErrorEx(s32* errorCode, u32* errorType) { +s32 DWC_GetLastErrorEx(s32* errorCode, DWCErrorType* errorType) { if (errorCode) *errorCode = stDwcErrorCode; if (errorType) { @@ -45,7 +43,7 @@ s32 DWC_GetLastErrorEx(s32* errorCode, u32* errorType) { *errorType = 1; break; case 1: - case DWCErrorFatal: + case DWC_ERROR_FATAL: *errorType = 7; break; @@ -74,21 +72,21 @@ s32 DWC_GetLastErrorEx(s32* errorCode, u32* errorType) { } void DWC_ClearError() { - if (stDwcLastError != DWCErrorFatal) { - stDwcLastError = DWCErrorNone; + if (stDwcLastError != DWC_ERROR_FATAL) { + stDwcLastError = DWC_ERROR_NONE; stDwcErrorCode = 0; } } -int DWCi_IsError() { return stDwcLastError != DWCErrorNone; } +int DWCi_IsError() { return stDwcLastError != DWC_ERROR_NONE; } void DWCi_SetError(int lastError, int errorCode) { - if (stDwcLastError != DWCErrorFatal) { + if (stDwcLastError != DWC_ERROR_FATAL) { stDwcLastError = lastError; stDwcErrorCode = errorCode; } #ifdef DEBUG - if (stDwcLastError == DWCErrorFatal) + if (stDwcLastError == DWC_ERROR_FATAL) DWC_Printf(-1, "FATALERROR_SET\n"); #endif } diff --git a/lib/dwc/common/dwc_error.h b/lib/dwc/common/dwc_error.h index 89a1a27ff..b30686104 100644 --- a/lib/dwc/common/dwc_error.h +++ b/lib/dwc/common/dwc_error.h @@ -2,12 +2,14 @@ #include +#include "dwci_error.h" + #ifdef __cplusplus extern "C" { #endif int DWC_GetLastError(int* errorCode); -s32 DWC_GetLastErrorEx(s32* errorCode, u32* errorType); +s32 DWC_GetLastErrorEx(s32* errorCode, DWCErrorType* errorType); void DWC_ClearError(); #ifdef __cplusplus diff --git a/lib/dwc/common/dwci_error.h b/lib/dwc/common/dwci_error.h index 3cb0fb7d0..ec06bec6a 100644 --- a/lib/dwc/common/dwci_error.h +++ b/lib/dwc/common/dwci_error.h @@ -4,7 +4,17 @@ extern "C" { #endif -enum dwcError { DWCErrorNone = 0, DWCErrorFatal = 9 }; +typedef enum { + DWC_ERROR_NONE = 0, + DWC_ERROR_TYPE_1 = 1, + DWC_ERROR_TYPE_2 = 2, + DWC_ERROR_TYPE_3 = 3, + DWC_ERROR_TYPE_4 = 4, + DWC_ERROR_TYPE_5 = 5, + DWC_ERROR_TYPE_6 = 6, + DWC_ERROR_TYPE_7 = 7, + DWC_ERROR_FATAL = 9, +} DWCErrorType; //! @brief @return Return if there is an error. //! diff --git a/src/net/FriendInfo.hpp b/src/net/FriendInfo.hpp new file mode 100644 index 000000000..01582c222 --- /dev/null +++ b/src/net/FriendInfo.hpp @@ -0,0 +1,61 @@ +#pragma once + +// this maybe should go in NetManager + +namespace Net { + +enum FriendStatus { + FRIEND_STATUS_IDLE = 0x0, // Is this any different than ONLINE? + FRIEND_STATUS_ONLINE = 0x2, + FRIEND_STATUS_OPEN_ROOM = 0x3, // or hosting + FRIEND_STATUS_PLAYING_WITH_FRIENDS = 0x4, + FRIEND_STATUS_PUBLIC_VS = 0x5, + FRIEND_STATUS_PUBLIC_BT = 0x8, + FRIEND_STATUS_FROOM_VS_HOST = 0xB, + FRIEND_STATUS_FROOM_BATTLE_HOST = 0xC, + FRIEND_STATUS_FROOM_VS_NON_HOST = 0xD, + FRIEND_STATUS_FROOM_BATTLE_NON_HOST = 0xE, +}; + +// The enums here are a little confusing +// FriendJoinableStatus is SearchType in other repos. +// This particular enum determines the message you see when a friend is online +// The values of FriendStatus line up with this one, its just that this makes a +// distinction between regional rooms, whether you can join them or not +enum FriendJoinableStatus { + STATUS_ONLINE_0 = 0x0, // ??? + STATUS_OFLINE = 0x1, + STATUS_ONLINE = 0x2, + STATUS_OPEN_ROOM = 0x3, + STATUS_PLAYING_WITH_FRIEND = 0x4, + STATUS_WW_VS = 0x5, + STATUS_REGIONAL_VS = 0x6, + STATUS_UNJOINABLE_REGIONAL_VS = 0x7, + STATUS_WW_BT = 0x8, + STATUS_REGIONAL_BT = 0x9, + STATUS_UNJOINABLE_REGIONAL_BT = 0xA, + STATUS_HOSTING_GP = 0xB, + STATUS_HOSTING_BT = 0xC, + STATUS_PLAYING_WITH_FRIENDS_RACE_COUNT = 0xD, + STATUS_PLAYING_WITH_FRIEND_BATTLE_COUNT = 0xE, +}; + +struct StatusData { + u32 roomId; // note to self, this is the one used 80659680, not to be confused + // with a similar field in matchMakingInfo + s8 regionId; + u8 status; // FriendStatus + u8 playerCount; + u8 currRace; +}; +static_assert(sizeof(StatusData) == 0x8); + +struct FriendInfo { + StatusData statusData; + u8 dwcFriendStatus; // Updated in NetManager::updateStatusDatas + bool addedBack; + u8 _a[0xc - 0xa]; +}; +static_assert(sizeof(FriendInfo) == 0xc); + +} // namespace Net diff --git a/src/net/MiscPacketHandler.cpp b/src/net/MiscPacketHandler.cpp new file mode 100644 index 000000000..68f98c7a4 --- /dev/null +++ b/src/net/MiscPacketHandler.cpp @@ -0,0 +1,30 @@ +#include "MiscPacketHandler.hpp" + +#include "net/NetManager.hpp" + +#include "net/packets/EVENT.hpp" +#include "net/packets/ITEM.hpp" + +namespace Net { + +void MiscPacketHandler::clearAidFromUnkBitfield(u32 aid) { + m_unkBitfield_4 &= ~(1 << aid); +} + +MiscPacketHandler::MiscPacketHandler() + : _000(0), m_unk1(false), m_unkBitfield_4(0), m_unkBitfield_8(0), + m_unkBitfield_C(0), m_unk10(0), m_unk12(3000) { + EVENTHandler::createStaticInstance(); + ITEMHandler::createStaticInstance(); +} + +bool MiscPacketHandler::isPlayerLocal(u32 playerId) { + bool isPlayerIdLocal = false; + if (playerId == NetManager::getInstance()->getLocalPlayerId(0) || + playerId == NetManager::getInstance()->getLocalPlayerId(1)) { + isPlayerIdLocal = true; + } + return isPlayerIdLocal; +} + +} // namespace Net diff --git a/src/net/MiscPacketHandler.hpp b/src/net/MiscPacketHandler.hpp new file mode 100644 index 000000000..9dcedca7c --- /dev/null +++ b/src/net/MiscPacketHandler.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include + +#include "net/packets/RACEDATA.hpp" +#include "net/packets/EVENT.hpp" + +namespace Net { + +class MiscPacketHandler { +public: + MiscPacketHandler(); + + void clearAidFromUnkBitfield(u32 aid); + + bool isPlayerLocal(u32 playerId); + + static MiscPacketHandler* getInstance() { return spInstance; } + + static MiscPacketHandler* spInstance; + +private: + u8 _000; + bool m_unk1; + u8 _[0x003 - 0x001]; // padding, probably + u32 m_unkBitfield_4; + u32 m_unkBitfield_8; + u32 m_unkBitfield_C; + u16 m_unk10; + u16 m_unk12; + RACEDATAPacket m_sendRACEDATAPackets[2]; // 0x14 - 0x94 + EVENTPacket m_sendEVENTPackets; // 0x94 - 0x18c + u8 _18c[0x1c8 - 0x18c]; +}; +static_assert(sizeof(MiscPacketHandler) == 0x1c8); + +} // namespace Net diff --git a/src/net/NetManager.cpp b/src/net/NetManager.cpp index d985f2b9a..5cc21d466 100644 --- a/src/net/NetManager.cpp +++ b/src/net/NetManager.cpp @@ -1,8 +1,13 @@ #include "NetManager.hpp" +#include "net/MiscPacketHandler.hpp" #include "net/packets/ROOM.hpp" +#include "host_system/SystemManager.hpp" +#include "system/RaceConfig.hpp" + #include +#include namespace Net { @@ -58,13 +63,78 @@ void NetManager::startRegionalBattleSearch(u8 localPlayerCount) { } } -void NetManager::joinFriendRoom(u32 friendRosterId, u8 localPlayerCount) { +void NetManager::joinFriendPublicVS(u32 friendIdx, u8 localPlayerCount) { + ConnectionState connState = getConnectionState(); + + if (connState == CONNECTION_STATE_IDLE) { + FriendJoinableStatus status = getFriendJoinableStatus(friendIdx); + switch (status) { + case STATUS_WW_VS: + m_roomType = ROOM_TYPE_JOINING_FRIEND_VS_WW; + break; + case STATUS_REGIONAL_VS: + m_roomType = ROOM_TYPE_JOINING_FRIEND_VS_REGIONAL; + break; + default: + OSLockMutex(&m_mutex); + + if (m_disconnectInfo.type != DISCONNECT_TYPE_UNRECOVERABLE_ERROR) { + m_disconnectInfo.type = DISCONNECT_TYPE_CANT_JOIN_FRIEND; + m_disconnectInfo.code = 0; + } + + OSUnlockMutex(&m_mutex); + return; + } + initMMInfos(); + m_matchMakingInfos[0].m_hostFriendId = friendIdx; + m_matchMakingInfos[1].m_hostFriendId = friendIdx; + m_matchMakingInfos[0].m_localPlayerCount = localPlayerCount; + m_matchMakingInfos[1].m_localPlayerCount = localPlayerCount; + RACEHEADER1Handler::getInstance()->setPrepared(); + } +} + +void NetManager::joinFriendPublicBT(u32 friendIdx, u8 localPlayerCount) { ConnectionState connState = getConnectionState(); if (connState == CONNECTION_STATE_IDLE) { + FriendJoinableStatus status = getFriendJoinableStatus(friendIdx); + switch (status) { + case STATUS_WW_BT: + // hmm + m_roomType = ROOM_TYPE_JOINING_FRIEND_BT_WW; + break; + case STATUS_REGIONAL_BT: + m_roomType = ROOM_TYPE_JOINING_FRIEND_BT_REGIONAL; + break; + default: + OSLockMutex(&m_mutex); + + if (m_disconnectInfo.type != DISCONNECT_TYPE_UNRECOVERABLE_ERROR) { + m_disconnectInfo.type = DISCONNECT_TYPE_CANT_JOIN_FRIEND; + m_disconnectInfo.code = 0; + } + + OSUnlockMutex(&m_mutex); + return; + } initMMInfos(); - m_matchMakingInfos[0].m_hostFriendId = friendRosterId; - m_matchMakingInfos[1].m_hostFriendId = friendRosterId; + m_matchMakingInfos[0].m_hostFriendId = friendIdx; + m_matchMakingInfos[1].m_hostFriendId = friendIdx; + m_matchMakingInfos[0].m_localPlayerCount = localPlayerCount; + m_matchMakingInfos[1].m_localPlayerCount = localPlayerCount; + RACEHEADER1Handler::getInstance()->setPrepared(); + } +} + +void NetManager::joinFriendRoom(u32 friendIdx, u8 localPlayerCount) { + ConnectionState connState = getConnectionState(); + + if (connState == CONNECTION_STATE_IDLE) { + initMMInfos(); + m_matchMakingInfos[0].m_hostFriendId = friendIdx; + m_matchMakingInfos[1].m_hostFriendId = friendIdx; m_roomType = ROOM_TYPE_NONHOST_PRIVATE; m_matchMakingInfos[0].m_localPlayerCount = localPlayerCount; m_matchMakingInfos[1].m_localPlayerCount = localPlayerCount; @@ -167,6 +237,16 @@ s32 NetManager::matchMakingElapsedSeconds() { return OSTicksToSeconds((s32)currTime - time); } +void NetManager::resetFriendData(u32 friendIdx) { + m_friends[friendIdx].statusData.roomId = 0; + m_friends[friendIdx].statusData.regionId = 0; + m_friends[friendIdx].statusData.status = 0; + m_friends[friendIdx].statusData.playerCount = 0; + m_friends[friendIdx].statusData.currRace = 0; + m_friends[friendIdx].dwcFriendStatus = 0; + m_friends[friendIdx].addedBack = true; +} + bool NetManager::isConnectionStateIdleOrInMM() const { bool idleOrMM = false; @@ -210,7 +290,7 @@ void NetManager::setConnectionState(ConnectionState connState) { NetManager::ConnectionState NetManager::getConnectionState() const { s32 code; - u32 type; + DWCErrorType type; DWC_GetLastErrorEx(&code, &type); ConnectionState connState; @@ -225,6 +305,65 @@ NetManager::ConnectionState NetManager::getConnectionState() const { return connState; } +void NetManager::handleError() { + s32 code; + DWCErrorType type; + + if (DWC_GetLastErrorEx(&code, &type)) { + // this is functionally equal to code = -code; but this was need to match + code = code - (code << 1); + if ((code / 10000) == 4 || (code / 1000) == 98) { + + return; + } + DWC_ClearError(); + + u32 errorCode; + + switch (type) { + case DWC_ERROR_TYPE_1: + case DWC_ERROR_TYPE_2: + + errorCode = code; + OSLockMutex(&m_mutex); + if (m_disconnectInfo.type != DISCONNECT_TYPE_UNRECOVERABLE_ERROR) { + m_disconnectInfo.type = DISCONNECT_TYPE_CANT_JOIN_FRIEND; + // code getting set here is somewhat interesting since cant join + // friend errors dont bring you to the error code screen in game + // since the connection state isn't set, the user wont disconnect from + // wfc + m_disconnectInfo.code = errorCode; + } + OSUnlockMutex(&m_mutex); + break; + + case DWC_ERROR_TYPE_3: + case DWC_ERROR_TYPE_4: + case DWC_ERROR_TYPE_5: + case DWC_ERROR_TYPE_6: + errorCode = code; + OSLockMutex(&m_mutex); + if (m_disconnectInfo.type != DISCONNECT_TYPE_UNRECOVERABLE_ERROR) { + m_disconnectInfo.type = DISCONNECT_TYPE_ERROR_CODE; + m_disconnectInfo.code = errorCode; + m_connectionState = CONNECTION_STATE_ERROR; + } + OSUnlockMutex(&m_mutex); + break; + + case DWC_ERROR_TYPE_7: + OSLockMutex(&m_mutex); + if (m_disconnectInfo.type != DISCONNECT_TYPE_UNRECOVERABLE_ERROR) { + m_disconnectInfo.type = DISCONNECT_TYPE_UNRECOVERABLE_ERROR; + m_disconnectInfo.code = 0; + m_connectionState = CONNECTION_STATE_ERROR; + } + OSUnlockMutex(&m_mutex); + break; + } + } +} + void* NetManager::alloc(u32 size, s32 alignment) { void* block = nullptr; if (size != 0) { @@ -283,4 +422,177 @@ void NetManager::DWCFree(u32 unk, void* block) { } } +void NetManager::setFriendStatusUpdatingCallback2(u32 r3, u32 r4, + NetManager* netManager) { + if (r3 != 0) + return; + if (r4 == 0) + return; + netManager->m_friendStatusChanged = true; +} + +void NetManager::setFriendStatusUpdatingCallback(u32 r3, + NetManager* netManager) { + netManager->m_friendStatusChanged = true; +} + +void NetManager::initMMInfos() { + for (u32 i = 0; i < 2; i++) { + m_matchMakingInfos[i].m_MMStartTime = 0; + m_matchMakingInfos[i].m_numConnectedConsoles = 0; + m_matchMakingInfos[i].m_playerCount = 0; + m_matchMakingInfos[i].m_fullAidBitmap = 0; + m_matchMakingInfos[i].m_directConnectedAidBitmap = 0; + m_matchMakingInfos[i].m_roomId = 0; + m_matchMakingInfos[i].m_hostFriendId = -1; + m_matchMakingInfos[i].m_myAid = 0xFF; + m_matchMakingInfos[i].m_hostAid = 0xFF; + m_matchMakingInfos[i].m_matchingSuspended = false; + for (u32 j = 0; j < MAX_PLAYER_COUNT; j++) { + memset(&m_matchMakingInfos[i].m_localPlayerCounts[j], 0, 4); + } + } +} + +void NetManager::resetFriends() { + for (u32 i = 0; i < MAX_FRIEND_COUNT; i++) + resetFriendData(i); +} + +void NetManager::resetPidToAidMap() { + for (u32 i = 0; i < MAX_PLAYER_COUNT; i++) + m_playerIdToAidMapping[i] = 0xFF; +} + +void NetManager::updateAidMapping() { + m_disconnectedPlayerIds = 0; + m_disconnectedAids = 0; + + if (RACEHEADER1Handler::getInstance()) { + const u8* RH1AidMapping = + RACEHEADER1Handler::getInstance()->getPlayerIdToAidMapping(); + for (u32 i = 0; i < MAX_PLAYER_COUNT; i++) + m_playerIdToAidMapping[i] = RH1AidMapping[i]; + } else if (SELECTHandler::getInstance()) { + const u8* selectAidMapping = + SELECTHandler::getInstance()->getPlayerIdToAidMapping(); + for (u32 i = 0; i < MAX_PLAYER_COUNT; i++) + m_playerIdToAidMapping[i] = selectAidMapping[i]; + } else { + resetPidToAidMap(); + } +} + +s32 NetManager::getLocalId(u32 hudId) const { + u8 myAid = m_matchMakingInfos[m_currMMInfo].m_myAid; + s32 count = -1; + for (s32 i = 0; i < MAX_PLAYER_COUNT; i++) { + if (m_playerIdToAidMapping[i] == myAid) { + count++; + if (count == hudId) + return i; + } + } + return -1; +} + +u32 NetManager::myAidIdx() const { + return 1 << m_matchMakingInfos[m_currMMInfo].m_myAid; +} + +bool NetManager::myAidInRoom() const { + u32 fullMap = m_matchMakingInfos[m_currMMInfo].m_fullAidBitmap; + u8 myAid = m_matchMakingInfos[m_currMMInfo].m_myAid; + return (1 << myAid & fullMap) != 0; +} + +s32 NetManager::getLocalPlayerId(u32 hudId) const { + if (MiscPacketHandler::spInstance) { + System::RaceConfig::Player* players = + System::RaceConfig::spInstance->mRaceScenario.mPlayers; + s32 count = 0; + // this currently just exists to prevent regswaps + u8 playerId = 0; + // loop thru player ids, check if player[i] is local + for (s32 i = 0; i < MAX_PLAYER_COUNT; i++) { + + if (players[playerId].mPlayerType == + System::RaceConfig::Player::TYPE_REAL_LOCAL) { + + // there can be at most two local players for online and the guest's + // player id will be higher than player 1's. + if (count == hudId) { + return i; + } + count++; + } + playerId++; + } + + return -1; + } + u32 myAid = m_matchMakingInfos[m_currMMInfo].m_myAid; + if (myAidInRoom()) { + return getLocalId(hudId); + } + return -1; +} + +FriendJoinableStatus NetManager::getFriendJoinableStatus(u32 friendIdx) const { + if (!m_friends[friendIdx].addedBack || + m_friends[friendIdx].dwcFriendStatus == 0) { + return STATUS_OFLINE; + } + + FriendStatus friendStatus = + static_cast(m_friends[friendIdx].statusData.status); + + if (friendStatus != FRIEND_STATUS_IDLE) { + switch (friendStatus) { + case FRIEND_STATUS_PUBLIC_VS: + // maybe this is an inlined function? its quite repetitive + if (m_disconnectPenalty != 0) { + return STATUS_ONLINE; + } + if (m_friends[friendIdx].statusData.regionId != -1) { + s32 regionId = m_friends[friendIdx].statusData.regionId; + + s32 matchingArea = System::SystemManager::sInstance->mMatchingArea; + if (regionId == matchingArea) { + return STATUS_REGIONAL_VS; + } + return STATUS_UNJOINABLE_REGIONAL_VS; + } + return STATUS_WW_VS; + case FRIEND_STATUS_PUBLIC_BT: + if (m_disconnectPenalty != 0) { + return STATUS_ONLINE; + } + + if (m_friends[friendIdx].statusData.regionId != -1) { + s32 regionId = m_friends[friendIdx].statusData.regionId; + s32 matchingArea = System::SystemManager::sInstance->mMatchingArea; + if (regionId == matchingArea) { + return STATUS_REGIONAL_BT; + } + return STATUS_UNJOINABLE_REGIONAL_BT; + } + return STATUS_WW_BT; + + case FRIEND_STATUS_FROOM_VS_HOST: + case FRIEND_STATUS_FROOM_BATTLE_HOST: + case FRIEND_STATUS_FROOM_VS_NON_HOST: + case FRIEND_STATUS_FROOM_BATTLE_NON_HOST: + case FRIEND_STATUS_ONLINE: + case FRIEND_STATUS_OPEN_ROOM: + case FRIEND_STATUS_PLAYING_WITH_FRIENDS: + return static_cast(friendStatus); + break; + default: + return static_cast(friendStatus); + } + } + return STATUS_ONLINE; +} + } // namespace Net diff --git a/src/net/NetManager.hpp b/src/net/NetManager.hpp index fdc8039ec..f3e83aa23 100644 --- a/src/net/NetManager.hpp +++ b/src/net/NetManager.hpp @@ -1,13 +1,15 @@ +#pragma once + // Credits: Melg and CLF, used as reference for names. // See bottom of file for the licenses // https://github.com/MelgMKW/Pulsar/blob/main/GameSource/MarioKartWii/RKNet/RKNetController.hpp // https://github.com/CLF78/OpenPayload/blob/master/payload/game/net/RKNetController.hpp -#pragma once - #include +#include #include "net/DisconnectInfo.hpp" +#include "net/FriendInfo.hpp" #include "net/packets/RACEPacketHolder.hpp" #include @@ -38,8 +40,10 @@ class NetManager { ROOM_TYPE_BT_REGIONAL = 0x4, ROOM_TYPE_HOST_PRIVATE = 0x5, ROOM_TYPE_NONHOST_PRIVATE = 0x6, - ROOM_TYPE_JOINING_FRIEND_WW = 0x7, - ROOM_TYPE_JOINING_FRIEND_REGIONAL = 0x8, + ROOM_TYPE_JOINING_FRIEND_VS_WW = 0x7, + ROOM_TYPE_JOINING_FRIEND_VS_REGIONAL = 0x8, + ROOM_TYPE_JOINING_FRIEND_BT_WW = 0x9, + ROOM_TYPE_JOINING_FRIEND_BT_REGIONAL = 0xA, }; // Certainly suspending MM related, but unsure about last two values @@ -60,7 +64,11 @@ class NetManager { void startRegionalBattleSearch(u8 localPlayerCount); - void joinFriendRoom(u32 friendRosterId, u8 localPlayerCount); + void joinFriendPublicVS(u32 friendIdx, u8 localPlayerCount); + + void joinFriendPublicBT(u32 friendIdx, u8 localPlayerCount); + + void joinFriendRoom(u32 friendIdx, u8 localPlayerCount); void createFriendRoom(u8 localPlayerCount); @@ -78,7 +86,7 @@ class NetManager { s32 matchMakingElapsedSeconds(); - void initMMInfos(); + void resetFriendData(u32 friendIdx); bool isConnectionStateIdleOrInMM() const; @@ -92,7 +100,9 @@ class NetManager { void setConnectionState(ConnectionState connState); - inline ConnectionState getConnectionState() const; + ConnectionState getConnectionState() const; + + void handleError(); void* alloc(u32 size, s32 alignment); @@ -107,20 +117,54 @@ class NetManager { static void DWCFree(u32 unk, void* block); -private: + static void setFriendStatusUpdatingCallback2(u32 r3, u32 r4, + NetManager* netManager); + + static void setFriendStatusUpdatingCallback(u32 r3, NetManager* netManager); + + void initMMInfos(); + + void resetFriends(); + + void updateAidMapping(); + + void resetPidToAidMap(); + + inline s32 getLocalId(u32 hudId) const; + + inline u32 myAidIdx() const; + + inline bool myAidInRoom() const; + + s32 getLocalPlayerId(u32 hudId) const; + + FriendJoinableStatus getFriendJoinableStatus(u32 friendIdx) const; + + static NetManager* getInstance() { return spInstance; } + // reason this exists is since the local player count must be in the highest + // byte to be passed off to DWC functions + struct LocalPlayerCountDWC { + u8 localPlayerCount; + u8 _1[0x4 - 0x1]; + }; + static_assert(sizeof(LocalPlayerCountDWC) == 0x4); + struct MatchMakingInfo { - u64 m_MMStartTime; // gets set upon match making - u32 m_numConnectedConsoles; // number of non guest players - u32 m_playerCount; // players in room (includes guests) - u32 m_fullAidBitmap; // # bits is equal to num consoles, all 1 - u32 m_availableAidBitmap; // will equal the full bitmap by end of mm - u32 m_roomId; - s32 m_hostFriendId; // -1 if host isn't a friend - u8 m_localPlayerCount; - u8 m_myAid; - u8 m_hostAid; - u8 _23[0x53 - 0x23]; // some kind of localPlayerCount for each aid - bool m_matchingSuspended; // set when entering mm, cleared shortly after + u64 m_MMStartTime; // gets set upon match making 0x0 + u32 m_numConnectedConsoles; // number of non guest players 0x8 + u32 m_playerCount; // players in room (includes guests) 0xC + u32 m_fullAidBitmap; // # bits is equal to num consoles, all 1 0x10 + u32 m_directConnectedAidBitmap; // Aids I'm connected to. It will fill up to + // equal m_fullAidBitmap by the end of MM as + // I connect to other users. 0x14 + u32 m_roomId; // Also known as groupId by DWC 0x18 + s32 m_hostFriendId; // -1 if host isn't a friend. 0x1C + u8 m_localPlayerCount; // 0x20 + u8 m_myAid; // 0x21 + u8 m_hostAid; // value returned by DWC_GetServerAid() 0x22 + LocalPlayerCountDWC m_localPlayerCounts[MAX_PLAYER_COUNT]; // 0x23 + bool + m_matchingSuspended; // set when entering mm, cleared shortly after 0x53 u8 _54[0x58 - 0x54]; }; static_assert(sizeof(MatchMakingInfo) == 0x58); @@ -138,34 +182,37 @@ class NetManager { RoomType m_roomType; UnkMMSuspension m_mmSuspension; // points to RACE packets to be sent, two per aid - RACEPacketHolder* m_sendRACEPackets[2][12]; + RACEPacketHolder* m_sendRACEPackets[2][MAX_PLAYER_COUNT]; // points to RACE packets to be recieved, two per aid - RACEPacketHolder* m_recvRACEPackets[2][12]; + RACEPacketHolder* m_recvRACEPackets[2][MAX_PLAYER_COUNT]; // The RACE packet to be sent, formed from m_sendRACEPackets, one per aid - PacketHolder* m_outgoingRACEPacket[12]; - u64 m_timeOfLastSentRACE[12]; - u64 m_timeOfLastRecvRACE[12]; - u64 m_timeBetweenSendingPackets[12]; // time bewteen sent packets per aid - u64 m_timeBetweenRecvPackets[12]; // time between recieved packets per aid - u8 m_aidLastSentTo; // Aid of last player we sent to - u8 m_recvRACEPacketBuffer[12][0x2e0]; - u8 _25e1[0x25e4 - 0x25e1]; // padding - u8 _25e4[0x25ec - 0x25e4]; // Unknown struct - u8 _25ec[0x2754 - 0x25ec]; // Friend related struct - bool m_friendStatusChanged; // set when a friend adds back - bool m_shutdownScheduled; // set when logging off - bool m_shouldUpdateFriendStatus; - bool m_hasEjectedDisk; // triggers a dc screen + PacketHolder* m_outgoingRACEPacket[MAX_PLAYER_COUNT]; + u64 m_timeOfLastSentRACE[MAX_PLAYER_COUNT]; + u64 m_timeOfLastRecvRACE[MAX_PLAYER_COUNT]; + u64 m_timeBetweenSendingPackets[MAX_PLAYER_COUNT]; // time bewteen sent + // packets per aid + u64 m_timeBetweenRecvPackets[MAX_PLAYER_COUNT]; // time between recieved + // packets per aid + u8 m_aidLastSentTo; // Aid of last player we sent to + u8 m_recvRACEPacketBuffer[MAX_PLAYER_COUNT][0x2e0]; + u8 _25e1[0x25e4 - 0x25e1]; // padding + StatusData m_myStatusData; + FriendInfo m_friends[MAX_FRIEND_COUNT]; + bool m_friendStatusChanged; // set when a friend adds back 0x2753 + bool m_shutdownScheduled; // set when logging off // 0x2755 + bool m_shouldUpdateFriendStatus; // 0x2756 + bool m_hasEjectedDisk; // triggers a dc screen 0x2757 u8 _2759[0x275c - 0x2759]; - s32 m_badWordsNum; // number of bad words found in the profanity check - u8 _2760[0x2764 - 0x2760]; // unsure + s32 m_badWordsNum; // number of bad words found in the profanity check + s32 m_disconnectPenalty; s32 m_vr; s32 m_br; - u32 m_lastSendIdx[12]; // idx of m_sendRACEPackets last sent per aid + u32 m_lastSendIdx[MAX_PLAYER_COUNT]; // idx of m_sendRACEPackets last sent per + // aid // idx of m_recvRACEPackets last recvieved per packet per aid - u32 m_lastRecvIdx[12][8]; + u32 m_lastRecvIdx[MAX_PLAYER_COUNT][8]; s32 m_currMMInfo; // Current MM info used - u8 m_playerIdToAidMapping[12]; + u8 m_playerIdToAidMapping[MAX_PLAYER_COUNT]; u32 m_disconnectedAids; // disconnected if 1 << aid is 1 u32 m_disconnectedPlayerIds; // disconnected if 1 << pid is 1 u8 _2934[0x295c - 0x2934]; // elo based MM struct diff --git a/src/net/packets/EVENT.cpp b/src/net/packets/EVENT.cpp new file mode 100644 index 000000000..123496765 --- /dev/null +++ b/src/net/packets/EVENT.cpp @@ -0,0 +1,5 @@ +#include "EVENT.hpp" + +namespace Net { + +} diff --git a/src/net/packets/EVENT.hpp b/src/net/packets/EVENT.hpp index 7567fbfb9..5bf78e431 100644 --- a/src/net/packets/EVENT.hpp +++ b/src/net/packets/EVENT.hpp @@ -10,7 +10,18 @@ struct EVENTPacket { static_assert(sizeof(EVENTPacket) == 0xf8); class EVENTHandler { +public: + + static void createStaticInstance(); + + static EVENTHandler *getInstance() { + return spInstance; + } + +private: u8 _0000[0x2b88 - 0x0000]; + + static EVENTHandler *spInstance; }; static_assert(sizeof(EVENTHandler) == 0x2b88); diff --git a/src/net/packets/ITEM.cpp b/src/net/packets/ITEM.cpp new file mode 100644 index 000000000..929fa7c09 --- /dev/null +++ b/src/net/packets/ITEM.cpp @@ -0,0 +1,5 @@ +#include "ITEM.hpp" + +namespace Net { + +} diff --git a/src/net/packets/ITEM.hpp b/src/net/packets/ITEM.hpp index 3a9b85b78..bf45ace4d 100644 --- a/src/net/packets/ITEM.hpp +++ b/src/net/packets/ITEM.hpp @@ -10,7 +10,17 @@ struct ITEMPacket { static_assert(sizeof(ITEMPacket) == 0x8); class ITEMHandler { +public: + + static void createStaticInstance(); + + static ITEMHandler *getInstance() { + return spInstance; + } +private: u8 _000[0x184 - 0x000]; + + static ITEMHandler *spInstance; }; static_assert(sizeof(ITEMHandler) == 0x184); diff --git a/src/net/packets/RACEHEADER1.cpp b/src/net/packets/RACEHEADER1.cpp index efa726f99..79b72cb8a 100644 --- a/src/net/packets/RACEHEADER1.cpp +++ b/src/net/packets/RACEHEADER1.cpp @@ -1,9 +1,67 @@ #include "RACEHEADER1.hpp" +#include "net/NetManager.hpp" + +#include + namespace Net { void RACEHEADER1Handler::setPrepared() { m_prepared = true; } +s32 RACEHEADER1Handler::getCourseId() const { + s32 otherCourseId; + u32 adjustedCourseId; + s32 result; + for (u8 i = 0; i < MAX_PLAYER_COUNT; i++) { + const RACEHEADER1Data *data = &m_RH1Datas[i]; + adjustedCourseId = data->courseId; + if (adjustedCourseId <= 0x42) { + adjustedCourseId = data->courseId; + otherCourseId = data->courseId; + } + else { + otherCourseId = -1; + } + + if (otherCourseId != -1 && data->_00 != 0) { + if (adjustedCourseId <= 0x42) { + result = data->courseId; + } + else { + result = -1; + } + return result; + } + } + return -1; +} + +bool RACEHEADER1Handler::courseValid() const { + bool result; + s32 adjustedCourseId; + System::CourseId courseId; + + if (!NetManager::getInstance()->hasFoundMatch() ) { + result = false; + } + else { + if (m_unk8 != 0) { + NetManager *netManager = NetManager::getInstance(); + u32 myAidSlot = 1 << netManager->m_matchMakingInfos[netManager->m_currMMInfo].m_myAid; + u32 fullBitmap =netManager->m_matchMakingInfos[netManager->m_currMMInfo].m_fullAidBitmap; + myAidSlot = fullBitmap & (m_unk8 | myAidSlot); + result = (fullBitmap == myAidSlot); + } + else { + result = false; + } + } + if (result) { + return getCourseId() != -1; + } + return result; +} + } diff --git a/src/net/packets/RACEHEADER1.hpp b/src/net/packets/RACEHEADER1.hpp index f3584e15b..2432614f4 100644 --- a/src/net/packets/RACEHEADER1.hpp +++ b/src/net/packets/RACEHEADER1.hpp @@ -1,5 +1,7 @@ #pragma once +#include "system/ResourceManager.hpp" + #include namespace Net { @@ -9,18 +11,41 @@ struct RACEHEADER1Packet { }; static_assert(sizeof(RACEHEADER1Packet) == 0x28); +struct RACEHEADER1Data { + u32 _00; + u8 _04[0x14 - 0x04]; + // This can take on values outside of the current courseId enum, maybe they're different types? + System::CourseId courseId; + u8 _18[0x20 - 0x18]; + u8 playerIdToAidMapping[12]; + u8 _2c[0x30 - 0x2c]; +}; +static_assert(sizeof(RACEHEADER1Data) == 0x30); + +/** + * @brief RACEHEADER1Handler + */ class RACEHEADER1Handler { public: void setPrepared(); void reset(); + bool courseValid() const; + + inline s32 getCourseId() const; + + const u8 *getPlayerIdToAidMapping() const; + static RACEHEADER1Handler *getInstance() { return spInstance; } private: bool m_prepared; - u8 _004[0x260 - 0x001]; + u8 _001[0x008 - 0x001]; + u32 m_unk8; + u8 _00c[0x020 - 0x00c]; + RACEHEADER1Data m_RH1Datas[12]; static RACEHEADER1Handler *spInstance; }; diff --git a/src/net/packets/SELECT.cpp b/src/net/packets/SELECT.cpp new file mode 100644 index 000000000..929fb2796 --- /dev/null +++ b/src/net/packets/SELECT.cpp @@ -0,0 +1,9 @@ +#include "SELECT.hpp" + +namespace Net { + +const u8 *SELECTHandler::getPlayerIdToAidMapping() const { + return m_sendPacket.m_playerIdToAidMapping; +} + +} diff --git a/src/net/packets/SELECT.hpp b/src/net/packets/SELECT.hpp index bf5d2955f..54aa238a6 100644 --- a/src/net/packets/SELECT.hpp +++ b/src/net/packets/SELECT.hpp @@ -5,12 +5,27 @@ namespace Net { struct SELECTPacket { - u8 _00[0x38 - 0x00]; + u8 _00[0x28 - 0x00]; + u8 m_playerIdToAidMapping[12]; + u8 _34[0x38 - 0x34]; }; static_assert(sizeof(SELECTPacket) == 0x38); class SELECTHandler { - u8 _000[0x3f8 - 0x000]; +public: + const u8 *getPlayerIdToAidMapping() const; + + static SELECTHandler *getInstance() { + return spInstance; + } + +private: + u8 _000[0x008 - 0x000]; + SELECTPacket m_sendPacket; + SELECTPacket m_recvPackets[12]; + u8 _2e0[0x3f8 - 0x2e0]; + + static SELECTHandler *spInstance; }; static_assert(sizeof(SELECTHandler) == 0x3f8); From c6415e85d68ceda8369b396dc8467d125c1e6be0 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 8 Jul 2025 21:41:02 -0400 Subject: [PATCH 2/3] Documentation, cleanup, etc --- config/RMCP01/module/symbols.txt | 6 +-- src/net/FriendInfo.hpp | 17 +++---- src/net/NetManager.cpp | 84 ++++++++++++++++++-------------- src/net/NetManager.hpp | 12 ++--- src/net/packets/RACEHEADER1.cpp | 2 + src/net/packets/RACEHEADER1.hpp | 3 -- 6 files changed, 65 insertions(+), 59 deletions(-) diff --git a/config/RMCP01/module/symbols.txt b/config/RMCP01/module/symbols.txt index f77214c7d..f2f7af69a 100644 --- a/config/RMCP01/module/symbols.txt +++ b/config/RMCP01/module/symbols.txt @@ -7237,9 +7237,9 @@ fn_1_1483B4 = .text:0x001483B4; // type:function size:0xBC fn_1_148470 = .text:0x00148470; // type:function size:0xB4 fn_1_148524 = .text:0x00148524; // type:function size:0x20 fn_1_148544 = .text:0x00148544; // type:function size:0x4 -setFriendStatusUpdatingCallback2__Q23Net10NetManagerFUlUlPQ23Net10NetManager = .text:0x00148548; // type:function size:0x1C +updateDWCServersAsyncCallback__Q23Net10NetManagerFUlUlPQ23Net10NetManager = .text:0x00148548; // type:function size:0x1C fn_1_148564 = .text:0x00148564; // type:function size:0x4 -setFriendStatusUpdatingCallback__Q23Net10NetManagerFUlPQ23Net10NetManager = .text:0x00148568; // type:function size:0xC +DWCSetBuddyFriendCallback__Q23Net10NetManagerFUlPQ23Net10NetManager = .text:0x00148568; // type:function size:0xC fn_1_148574 = .text:0x00148574; // type:function size:0x68 fn_1_1485DC = .text:0x001485DC; // type:function size:0x20C NetManager_connect = .text:0x001487E8; // type:function size:0x1A0 scope:global align:4 @@ -7255,7 +7255,7 @@ fn_1_149510 = .text:0x00149510; // type:function size:0x178 fn_1_149688 = .text:0x00149688; // type:function size:0x48 RKNetController_processRACEPacket = .text:0x001496D0; // type:function size:0x13C scope:global align:4 updateAidMapping__Q23Net10NetManagerFv = .text:0x0014980C; // type:function size:0x160 -resetPidToAidMap__Q23Net10NetManagerFv = .text:0x0014996C; // type:function size:0x38 +resetPlayerIdToAidMap__Q23Net10NetManagerFv = .text:0x0014996C; // type:function size:0x38 getLocalPlayerId__Q23Net10NetManagerFUl = .text:0x001499A4; // type:function size:0x24C scope:global align:4 getFriendJoinableStatus__Q23Net10NetManagerCFUl = .text:0x00149BF0; // type:function size:0x110 RKNetController_updateStatusData = .text:0x00149D00; // type:function size:0x198 scope:global align:4 diff --git a/src/net/FriendInfo.hpp b/src/net/FriendInfo.hpp index 01582c222..c1ca4a703 100644 --- a/src/net/FriendInfo.hpp +++ b/src/net/FriendInfo.hpp @@ -17,22 +17,21 @@ enum FriendStatus { FRIEND_STATUS_FROOM_BATTLE_NON_HOST = 0xE, }; -// The enums here are a little confusing -// FriendJoinableStatus is SearchType in other repos. -// This particular enum determines the message you see when a friend is online -// The values of FriendStatus line up with this one, its just that this makes a -// distinction between regional rooms, whether you can join them or not +// The enums here are a little confusing and deserve some explanation +// Whereas FriendStatus only makes a destinction between public and private +// rooms, FriendJoinableStatus goes a bit further in whether you can join the +// public room or not. enum FriendJoinableStatus { - STATUS_ONLINE_0 = 0x0, // ??? - STATUS_OFLINE = 0x1, + STATUS_NONE = 0x0, + STATUS_OFFLINE = 0x1, STATUS_ONLINE = 0x2, STATUS_OPEN_ROOM = 0x3, STATUS_PLAYING_WITH_FRIEND = 0x4, STATUS_WW_VS = 0x5, - STATUS_REGIONAL_VS = 0x6, + STATUS_JOINABLE_REGIONAL_VS = 0x6, STATUS_UNJOINABLE_REGIONAL_VS = 0x7, STATUS_WW_BT = 0x8, - STATUS_REGIONAL_BT = 0x9, + STATUS_JOINABLE_REGIONAL_BT = 0x9, STATUS_UNJOINABLE_REGIONAL_BT = 0xA, STATUS_HOSTING_GP = 0xB, STATUS_HOSTING_BT = 0xC, diff --git a/src/net/NetManager.cpp b/src/net/NetManager.cpp index 5cc21d466..d9e817c15 100644 --- a/src/net/NetManager.cpp +++ b/src/net/NetManager.cpp @@ -72,7 +72,7 @@ void NetManager::joinFriendPublicVS(u32 friendIdx, u8 localPlayerCount) { case STATUS_WW_VS: m_roomType = ROOM_TYPE_JOINING_FRIEND_VS_WW; break; - case STATUS_REGIONAL_VS: + case STATUS_JOINABLE_REGIONAL_VS: m_roomType = ROOM_TYPE_JOINING_FRIEND_VS_REGIONAL; break; default: @@ -102,10 +102,9 @@ void NetManager::joinFriendPublicBT(u32 friendIdx, u8 localPlayerCount) { FriendJoinableStatus status = getFriendJoinableStatus(friendIdx); switch (status) { case STATUS_WW_BT: - // hmm m_roomType = ROOM_TYPE_JOINING_FRIEND_BT_WW; break; - case STATUS_REGIONAL_BT: + case STATUS_JOINABLE_REGIONAL_BT: m_roomType = ROOM_TYPE_JOINING_FRIEND_BT_REGIONAL; break; default: @@ -311,27 +310,29 @@ void NetManager::handleError() { if (DWC_GetLastErrorEx(&code, &type)) { // this is functionally equal to code = -code; but this was need to match + // dwc error codes are negative values, but mkw uses positive error codes. + // we just need to negate code code = code - (code << 1); - if ((code / 10000) == 4 || (code / 1000) == 98) { + if ((code / 10000) == 4 || (code / 1000) == 98) { + // return early for sake errors return; } + DWC_ClearError(); - u32 errorCode; + u32 errorCode; // this variable was needed for matching purposes switch (type) { case DWC_ERROR_TYPE_1: case DWC_ERROR_TYPE_2: - errorCode = code; + errorCode = code; // this is used for matching purposes OSLockMutex(&m_mutex); if (m_disconnectInfo.type != DISCONNECT_TYPE_UNRECOVERABLE_ERROR) { m_disconnectInfo.type = DISCONNECT_TYPE_CANT_JOIN_FRIEND; - // code getting set here is somewhat interesting since cant join - // friend errors dont bring you to the error code screen in game - // since the connection state isn't set, the user wont disconnect from - // wfc + // code getting set here is somewhat interesting since errors + // when joining friends dont bring you to the error code screen in game m_disconnectInfo.code = errorCode; } OSUnlockMutex(&m_mutex); @@ -422,8 +423,8 @@ void NetManager::DWCFree(u32 unk, void* block) { } } -void NetManager::setFriendStatusUpdatingCallback2(u32 r3, u32 r4, - NetManager* netManager) { +void NetManager::updateDWCServersAsyncCallback(u32 r3, u32 r4, + NetManager* netManager) { if (r3 != 0) return; if (r4 == 0) @@ -431,8 +432,7 @@ void NetManager::setFriendStatusUpdatingCallback2(u32 r3, u32 r4, netManager->m_friendStatusChanged = true; } -void NetManager::setFriendStatusUpdatingCallback(u32 r3, - NetManager* netManager) { +void NetManager::DWCSetBuddyFriendCallback(u32 r3, NetManager* netManager) { netManager->m_friendStatusChanged = true; } @@ -445,8 +445,8 @@ void NetManager::initMMInfos() { m_matchMakingInfos[i].m_directConnectedAidBitmap = 0; m_matchMakingInfos[i].m_roomId = 0; m_matchMakingInfos[i].m_hostFriendId = -1; - m_matchMakingInfos[i].m_myAid = 0xFF; - m_matchMakingInfos[i].m_hostAid = 0xFF; + m_matchMakingInfos[i].m_myAid = -1; + m_matchMakingInfos[i].m_hostAid = -1; m_matchMakingInfos[i].m_matchingSuspended = false; for (u32 j = 0; j < MAX_PLAYER_COUNT; j++) { memset(&m_matchMakingInfos[i].m_localPlayerCounts[j], 0, 4); @@ -459,9 +459,9 @@ void NetManager::resetFriends() { resetFriendData(i); } -void NetManager::resetPidToAidMap() { +void NetManager::resetPlayerIdToAidMap() { for (u32 i = 0; i < MAX_PLAYER_COUNT; i++) - m_playerIdToAidMapping[i] = 0xFF; + m_playerIdToAidMapping[i] = -1; } void NetManager::updateAidMapping() { @@ -479,7 +479,7 @@ void NetManager::updateAidMapping() { for (u32 i = 0; i < MAX_PLAYER_COUNT; i++) m_playerIdToAidMapping[i] = selectAidMapping[i]; } else { - resetPidToAidMap(); + resetPlayerIdToAidMap(); } } @@ -496,14 +496,10 @@ s32 NetManager::getLocalId(u32 hudId) const { return -1; } -u32 NetManager::myAidIdx() const { - return 1 << m_matchMakingInfos[m_currMMInfo].m_myAid; -} - bool NetManager::myAidInRoom() const { u32 fullMap = m_matchMakingInfos[m_currMMInfo].m_fullAidBitmap; u8 myAid = m_matchMakingInfos[m_currMMInfo].m_myAid; - return (1 << myAid & fullMap) != 0; + return (1 << myAid & fullMap); } s32 NetManager::getLocalPlayerId(u32 hudId) const { @@ -531,54 +527,68 @@ s32 NetManager::getLocalPlayerId(u32 hudId) const { return -1; } - u32 myAid = m_matchMakingInfos[m_currMMInfo].m_myAid; + if (myAidInRoom()) { return getLocalId(hudId); } return -1; } +// https://decomp.me/scratch/l8u6Q FriendJoinableStatus NetManager::getFriendJoinableStatus(u32 friendIdx) const { if (!m_friends[friendIdx].addedBack || m_friends[friendIdx].dwcFriendStatus == 0) { - return STATUS_OFLINE; + return STATUS_OFFLINE; } FriendStatus friendStatus = static_cast(m_friends[friendIdx].statusData.status); + s8 regionId; + // if the friend isn't online but not doing anything if (friendStatus != FRIEND_STATUS_IDLE) { switch (friendStatus) { + + // maybe the following two cases are an inlined function? its quite + // repetitive case FRIEND_STATUS_PUBLIC_VS: - // maybe this is an inlined function? its quite repetitive if (m_disconnectPenalty != 0) { + // if im penalized for dc-ing too much show my status as online for + // others return STATUS_ONLINE; } - if (m_friends[friendIdx].statusData.regionId != -1) { - s32 regionId = m_friends[friendIdx].statusData.regionId; - s32 matchingArea = System::SystemManager::sInstance->mMatchingArea; - if (regionId == matchingArea) { - return STATUS_REGIONAL_VS; + regionId = m_friends[friendIdx].statusData.regionId; + + if (regionId != -1) { + // i have the same region as my friend, so i can join their regional + // room + if (regionId == + static_cast(System::SystemManager::sInstance->mMatchingArea)) { + return STATUS_JOINABLE_REGIONAL_VS; } + // otherwise i cant return STATUS_UNJOINABLE_REGIONAL_VS; } return STATUS_WW_VS; + case FRIEND_STATUS_PUBLIC_BT: if (m_disconnectPenalty != 0) { return STATUS_ONLINE; } - if (m_friends[friendIdx].statusData.regionId != -1) { - s32 regionId = m_friends[friendIdx].statusData.regionId; - s32 matchingArea = System::SystemManager::sInstance->mMatchingArea; - if (regionId == matchingArea) { - return STATUS_REGIONAL_BT; + regionId = m_friends[friendIdx].statusData.regionId; + + if (regionId != -1) { + if (regionId == + static_cast(System::SystemManager::sInstance->mMatchingArea)) { + return STATUS_JOINABLE_REGIONAL_BT; } return STATUS_UNJOINABLE_REGIONAL_BT; } return STATUS_WW_BT; + // just return the friendStatus for all other cases case FRIEND_STATUS_FROOM_VS_HOST: case FRIEND_STATUS_FROOM_BATTLE_HOST: case FRIEND_STATUS_FROOM_VS_NON_HOST: diff --git a/src/net/NetManager.hpp b/src/net/NetManager.hpp index f3e83aa23..14d6baef5 100644 --- a/src/net/NetManager.hpp +++ b/src/net/NetManager.hpp @@ -117,10 +117,10 @@ class NetManager { static void DWCFree(u32 unk, void* block); - static void setFriendStatusUpdatingCallback2(u32 r3, u32 r4, - NetManager* netManager); + static void updateDWCServersAsyncCallback(u32 r3, u32 r4, + NetManager* netManager); - static void setFriendStatusUpdatingCallback(u32 r3, NetManager* netManager); + static void DWCSetBuddyFriendCallback(u32 r3, NetManager* netManager); void initMMInfos(); @@ -128,12 +128,10 @@ class NetManager { void updateAidMapping(); - void resetPidToAidMap(); + void resetPlayerIdToAidMap(); inline s32 getLocalId(u32 hudId) const; - inline u32 myAidIdx() const; - inline bool myAidInRoom() const; s32 getLocalPlayerId(u32 hudId) const; @@ -204,7 +202,7 @@ class NetManager { bool m_hasEjectedDisk; // triggers a dc screen 0x2757 u8 _2759[0x275c - 0x2759]; s32 m_badWordsNum; // number of bad words found in the profanity check - s32 m_disconnectPenalty; + u32 m_disconnectPenalty; s32 m_vr; s32 m_br; u32 m_lastSendIdx[MAX_PLAYER_COUNT]; // idx of m_sendRACEPackets last sent per diff --git a/src/net/packets/RACEHEADER1.cpp b/src/net/packets/RACEHEADER1.cpp index 79b72cb8a..f261960ef 100644 --- a/src/net/packets/RACEHEADER1.cpp +++ b/src/net/packets/RACEHEADER1.cpp @@ -7,6 +7,7 @@ namespace Net { void RACEHEADER1Handler::setPrepared() { + // setting this to true allows the main logic of this class's calc() to run() m_prepared = true; } @@ -38,6 +39,7 @@ s32 RACEHEADER1Handler::getCourseId() const { return -1; } +// https://decomp.me/scratch/zMnhg bool RACEHEADER1Handler::courseValid() const { bool result; s32 adjustedCourseId; diff --git a/src/net/packets/RACEHEADER1.hpp b/src/net/packets/RACEHEADER1.hpp index 2432614f4..468af20f2 100644 --- a/src/net/packets/RACEHEADER1.hpp +++ b/src/net/packets/RACEHEADER1.hpp @@ -22,9 +22,6 @@ struct RACEHEADER1Data { }; static_assert(sizeof(RACEHEADER1Data) == 0x30); -/** - * @brief RACEHEADER1Handler - */ class RACEHEADER1Handler { public: void setPrepared(); From 929bf50497d6bb30b47cf3f2170758ec91f5f1cf Mon Sep 17 00:00:00 2001 From: Henry Date: Fri, 11 Jul 2025 14:58:50 -0400 Subject: [PATCH 3/3] Resolved suggestions, ran clang-format on net/packets/* --- src/net/MiscPacketHandler.hpp | 1 - src/net/NetManager.cpp | 13 +++++----- src/net/packets/EVENT.cpp | 4 +-- src/net/packets/EVENT.hpp | 13 ++++------ src/net/packets/HEADER.hpp | 2 +- src/net/packets/ITEM.cpp | 4 +-- src/net/packets/ITEM.hpp | 12 ++++----- src/net/packets/PacketHolder.hpp | 12 ++++----- src/net/packets/RACEDATA.hpp | 2 +- src/net/packets/RACEHEADER1.cpp | 37 +++++++++++++--------------- src/net/packets/RACEHEADER1.hpp | 18 +++++++------- src/net/packets/RACEHEADER2.hpp | 2 +- src/net/packets/RACEPacketHolder.hpp | 18 +++++++------- src/net/packets/ROOM.cpp | 4 +-- src/net/packets/ROOM.hpp | 17 ++++++------- src/net/packets/SELECT.cpp | 4 +-- src/net/packets/SELECT.hpp | 10 +++----- src/net/packets/USER.cpp | 4 +-- src/net/packets/USER.hpp | 11 ++++----- 19 files changed, 83 insertions(+), 105 deletions(-) diff --git a/src/net/MiscPacketHandler.hpp b/src/net/MiscPacketHandler.hpp index 9dcedca7c..ceee0d04b 100644 --- a/src/net/MiscPacketHandler.hpp +++ b/src/net/MiscPacketHandler.hpp @@ -22,7 +22,6 @@ class MiscPacketHandler { private: u8 _000; bool m_unk1; - u8 _[0x003 - 0x001]; // padding, probably u32 m_unkBitfield_4; u32 m_unkBitfield_8; u32 m_unkBitfield_C; diff --git a/src/net/NetManager.cpp b/src/net/NetManager.cpp index d9e817c15..0f77f632f 100644 --- a/src/net/NetManager.cpp +++ b/src/net/NetManager.cpp @@ -437,7 +437,7 @@ void NetManager::DWCSetBuddyFriendCallback(u32 r3, NetManager* netManager) { } void NetManager::initMMInfos() { - for (u32 i = 0; i < 2; i++) { + for (u32 i = 0; i < ARRAY_SIZE(m_matchMakingInfos); i++) { m_matchMakingInfos[i].m_MMStartTime = 0; m_matchMakingInfos[i].m_numConnectedConsoles = 0; m_matchMakingInfos[i].m_playerCount = 0; @@ -455,12 +455,13 @@ void NetManager::initMMInfos() { } void NetManager::resetFriends() { - for (u32 i = 0; i < MAX_FRIEND_COUNT; i++) + for (u32 i = 0; i < ARRAY_SIZE(m_friends); i++) { resetFriendData(i); + } } void NetManager::resetPlayerIdToAidMap() { - for (u32 i = 0; i < MAX_PLAYER_COUNT; i++) + for (u32 i = 0; i < ARRAY_SIZE(m_playerIdToAidMapping); i++) m_playerIdToAidMapping[i] = -1; } @@ -471,12 +472,12 @@ void NetManager::updateAidMapping() { if (RACEHEADER1Handler::getInstance()) { const u8* RH1AidMapping = RACEHEADER1Handler::getInstance()->getPlayerIdToAidMapping(); - for (u32 i = 0; i < MAX_PLAYER_COUNT; i++) + for (u32 i = 0; i < ARRAY_SIZE(m_playerIdToAidMapping); i++) m_playerIdToAidMapping[i] = RH1AidMapping[i]; } else if (SELECTHandler::getInstance()) { const u8* selectAidMapping = SELECTHandler::getInstance()->getPlayerIdToAidMapping(); - for (u32 i = 0; i < MAX_PLAYER_COUNT; i++) + for (u32 i = 0; i < ARRAY_SIZE(m_playerIdToAidMapping); i++) m_playerIdToAidMapping[i] = selectAidMapping[i]; } else { resetPlayerIdToAidMap(); @@ -486,7 +487,7 @@ void NetManager::updateAidMapping() { s32 NetManager::getLocalId(u32 hudId) const { u8 myAid = m_matchMakingInfos[m_currMMInfo].m_myAid; s32 count = -1; - for (s32 i = 0; i < MAX_PLAYER_COUNT; i++) { + for (s32 i = 0; i < ARRAY_SIZE(m_playerIdToAidMapping); i++) { if (m_playerIdToAidMapping[i] == myAid) { count++; if (count == hudId) diff --git a/src/net/packets/EVENT.cpp b/src/net/packets/EVENT.cpp index 123496765..87c8c2331 100644 --- a/src/net/packets/EVENT.cpp +++ b/src/net/packets/EVENT.cpp @@ -1,5 +1,3 @@ #include "EVENT.hpp" -namespace Net { - -} +namespace Net {} diff --git a/src/net/packets/EVENT.hpp b/src/net/packets/EVENT.hpp index 5bf78e431..51e61faf3 100644 --- a/src/net/packets/EVENT.hpp +++ b/src/net/packets/EVENT.hpp @@ -11,18 +11,15 @@ static_assert(sizeof(EVENTPacket) == 0xf8); class EVENTHandler { public: - static void createStaticInstance(); - - static EVENTHandler *getInstance() { - return spInstance; - } + + static EVENTHandler* getInstance() { return spInstance; } private: u8 _0000[0x2b88 - 0x0000]; - static EVENTHandler *spInstance; + static EVENTHandler* spInstance; }; -static_assert(sizeof(EVENTHandler) == 0x2b88); +static_assert(sizeof(EVENTHandler) == 0x2b88); -} +} // namespace Net diff --git a/src/net/packets/HEADER.hpp b/src/net/packets/HEADER.hpp index 5a9f6d997..3346f7cdd 100644 --- a/src/net/packets/HEADER.hpp +++ b/src/net/packets/HEADER.hpp @@ -9,4 +9,4 @@ struct HEADERPacket { }; static_assert(sizeof(HEADERPacket) == 0x10); -} +} // namespace Net diff --git a/src/net/packets/ITEM.cpp b/src/net/packets/ITEM.cpp index 929fa7c09..99c51a743 100644 --- a/src/net/packets/ITEM.cpp +++ b/src/net/packets/ITEM.cpp @@ -1,5 +1,3 @@ #include "ITEM.hpp" -namespace Net { - -} +namespace Net {} diff --git a/src/net/packets/ITEM.hpp b/src/net/packets/ITEM.hpp index bf45ace4d..715f31130 100644 --- a/src/net/packets/ITEM.hpp +++ b/src/net/packets/ITEM.hpp @@ -11,17 +11,15 @@ static_assert(sizeof(ITEMPacket) == 0x8); class ITEMHandler { public: - static void createStaticInstance(); - static ITEMHandler *getInstance() { - return spInstance; - } + static ITEMHandler* getInstance() { return spInstance; } + private: u8 _000[0x184 - 0x000]; - - static ITEMHandler *spInstance; + + static ITEMHandler* spInstance; }; static_assert(sizeof(ITEMHandler) == 0x184); -} +} // namespace Net diff --git a/src/net/packets/PacketHolder.hpp b/src/net/packets/PacketHolder.hpp index 291d88e13..c57c1a5a3 100644 --- a/src/net/packets/PacketHolder.hpp +++ b/src/net/packets/PacketHolder.hpp @@ -4,21 +4,19 @@ namespace Net { -template -class PacketHolder { +template class PacketHolder { public: PacketHolder(u32 bufferSize); ~PacketHolder(); void reset(); - void copy(T *src, u32 len); - void append(T *src, u32 len); + void copy(T* src, u32 len); + void append(T* src, u32 len); private: - T *packet; + T* packet; u32 bufferSize; u32 packetSize; - }; -} +} // namespace Net diff --git a/src/net/packets/RACEDATA.hpp b/src/net/packets/RACEDATA.hpp index 497e1bd51..f89889b34 100644 --- a/src/net/packets/RACEDATA.hpp +++ b/src/net/packets/RACEDATA.hpp @@ -9,4 +9,4 @@ class RACEDATAPacket { }; static_assert(sizeof(RACEDATAPacket) == 0x40); -} +} // namespace Net diff --git a/src/net/packets/RACEHEADER1.cpp b/src/net/packets/RACEHEADER1.cpp index f261960ef..b07cf246c 100644 --- a/src/net/packets/RACEHEADER1.cpp +++ b/src/net/packets/RACEHEADER1.cpp @@ -16,24 +16,21 @@ s32 RACEHEADER1Handler::getCourseId() const { u32 adjustedCourseId; s32 result; for (u8 i = 0; i < MAX_PLAYER_COUNT; i++) { - const RACEHEADER1Data *data = &m_RH1Datas[i]; + const RACEHEADER1Data* data = &m_RH1Datas[i]; adjustedCourseId = data->courseId; - if (adjustedCourseId <= 0x42) { + if (adjustedCourseId <= 0x42) { adjustedCourseId = data->courseId; otherCourseId = data->courseId; - } - else { + } else { otherCourseId = -1; } if (otherCourseId != -1 && data->_00 != 0) { if (adjustedCourseId <= 0x42) { - result = data->courseId; - } - else { - result = -1; + return data->courseId; + } else { + return -1; } - return result; } } return -1; @@ -45,20 +42,20 @@ bool RACEHEADER1Handler::courseValid() const { s32 adjustedCourseId; System::CourseId courseId; - if (!NetManager::getInstance()->hasFoundMatch() ) { + if (!NetManager::getInstance()->hasFoundMatch()) { result = false; - } - else { - if (m_unk8 != 0) { - NetManager *netManager = NetManager::getInstance(); - u32 myAidSlot = 1 << netManager->m_matchMakingInfos[netManager->m_currMMInfo].m_myAid; - u32 fullBitmap =netManager->m_matchMakingInfos[netManager->m_currMMInfo].m_fullAidBitmap; + } else { + if (m_unk8 != 0) { + NetManager* netManager = NetManager::getInstance(); + u32 myAidSlot = + 1 << netManager->m_matchMakingInfos[netManager->m_currMMInfo].m_myAid; + u32 fullBitmap = netManager->m_matchMakingInfos[netManager->m_currMMInfo] + .m_fullAidBitmap; myAidSlot = fullBitmap & (m_unk8 | myAidSlot); result = (fullBitmap == myAidSlot); - } - else { + } else { result = false; - } + } } if (result) { return getCourseId() != -1; @@ -66,4 +63,4 @@ bool RACEHEADER1Handler::courseValid() const { return result; } -} +} // namespace Net diff --git a/src/net/packets/RACEHEADER1.hpp b/src/net/packets/RACEHEADER1.hpp index 468af20f2..7354bf877 100644 --- a/src/net/packets/RACEHEADER1.hpp +++ b/src/net/packets/RACEHEADER1.hpp @@ -14,7 +14,8 @@ static_assert(sizeof(RACEHEADER1Packet) == 0x28); struct RACEHEADER1Data { u32 _00; u8 _04[0x14 - 0x04]; - // This can take on values outside of the current courseId enum, maybe they're different types? + // This can take on values outside of the current courseId enum, maybe they're + // different types? System::CourseId courseId; u8 _18[0x20 - 0x18]; u8 playerIdToAidMapping[12]; @@ -23,7 +24,7 @@ struct RACEHEADER1Data { static_assert(sizeof(RACEHEADER1Data) == 0x30); class RACEHEADER1Handler { -public: +public: void setPrepared(); void reset(); @@ -32,20 +33,19 @@ class RACEHEADER1Handler { inline s32 getCourseId() const; - const u8 *getPlayerIdToAidMapping() const; + const u8* getPlayerIdToAidMapping() const; + + static RACEHEADER1Handler* getInstance() { return spInstance; } - static RACEHEADER1Handler *getInstance() { - return spInstance; - } private: bool m_prepared; u8 _001[0x008 - 0x001]; u32 m_unk8; - u8 _00c[0x020 - 0x00c]; + u8 _00c[0x020 - 0x00c]; RACEHEADER1Data m_RH1Datas[12]; - static RACEHEADER1Handler *spInstance; + static RACEHEADER1Handler* spInstance; }; static_assert(sizeof(RACEHEADER1Handler) == 0x260); -} +} // namespace Net diff --git a/src/net/packets/RACEHEADER2.hpp b/src/net/packets/RACEHEADER2.hpp index 53c0c95d4..942fb79a6 100644 --- a/src/net/packets/RACEHEADER2.hpp +++ b/src/net/packets/RACEHEADER2.hpp @@ -9,4 +9,4 @@ struct RACEHEADER2Packet { }; static_assert(sizeof(RACEHEADER2Packet) == 0x28); -} +} // namespace Net diff --git a/src/net/packets/RACEPacketHolder.hpp b/src/net/packets/RACEPacketHolder.hpp index 41ffc6f16..bd0f925cd 100644 --- a/src/net/packets/RACEPacketHolder.hpp +++ b/src/net/packets/RACEPacketHolder.hpp @@ -17,14 +17,14 @@ namespace Net { class RACEPacketHolder { private: // Maybe this is an array? - PacketHolder *m_headerPacket; - PacketHolder *m_raceHeader1Packet; - PacketHolder *m_raceHeader2Packet; - PacketHolder *m_selectPacket; - PacketHolder *m_raceDataPacket; - PacketHolder *m_userPacket; - PacketHolder *m_itemPacket; - PacketHolder *m_eventPacket; + PacketHolder* m_headerPacket; + PacketHolder* m_raceHeader1Packet; + PacketHolder* m_raceHeader2Packet; + PacketHolder* m_selectPacket; + PacketHolder* m_raceDataPacket; + PacketHolder* m_userPacket; + PacketHolder* m_itemPacket; + PacketHolder* m_eventPacket; // 0x8065a3dc RACEPacketHolder(); @@ -33,4 +33,4 @@ class RACEPacketHolder { }; static_assert(sizeof(RACEPacketHolder) == 0x20); -} +} // namespace Net diff --git a/src/net/packets/ROOM.cpp b/src/net/packets/ROOM.cpp index 804697d3e..4155d693f 100644 --- a/src/net/packets/ROOM.cpp +++ b/src/net/packets/ROOM.cpp @@ -1,5 +1,3 @@ #include "ROOM.hpp" -namespace Net { - -} +namespace Net {} diff --git a/src/net/packets/ROOM.hpp b/src/net/packets/ROOM.hpp index 8cf770aca..13b4c392d 100644 --- a/src/net/packets/ROOM.hpp +++ b/src/net/packets/ROOM.hpp @@ -3,14 +3,14 @@ #include namespace Net { - + enum RoomRole { ROLE_HOST = 0x0, ROLE_GUEST = 0x1, }; // Credits: https://wiki.tockdom.com/wiki/Network_Protocol/ROOM -#pragma options align=packed +#pragma options align = packed struct ROOMPacket { // Message Type: // 1: Starting room @@ -18,12 +18,12 @@ struct ROOMPacket { // 3: Someone joined room // 4: Chat u8 messageType; - + // These are parameters, but its use depends on the message type. u16 _1; u8 _3; }; -#pragma options align=reset +#pragma options align = reset static_assert(sizeof(ROOMPacket) == 0x4); class ROOMHandler { @@ -32,14 +32,13 @@ class ROOMHandler { void reset(); - static ROOMHandler *getInstance() { - return spInstance; - } + static ROOMHandler* getInstance() { return spInstance; } + private: u8 _00[0x80 - 0x00]; - static ROOMHandler *spInstance; + static ROOMHandler* spInstance; }; static_assert(sizeof(ROOMHandler) == 0x80); -} +} // namespace Net diff --git a/src/net/packets/SELECT.cpp b/src/net/packets/SELECT.cpp index 929fb2796..f02cb005a 100644 --- a/src/net/packets/SELECT.cpp +++ b/src/net/packets/SELECT.cpp @@ -2,8 +2,8 @@ namespace Net { -const u8 *SELECTHandler::getPlayerIdToAidMapping() const { +const u8* SELECTHandler::getPlayerIdToAidMapping() const { return m_sendPacket.m_playerIdToAidMapping; } -} +} // namespace Net diff --git a/src/net/packets/SELECT.hpp b/src/net/packets/SELECT.hpp index 54aa238a6..d937ade48 100644 --- a/src/net/packets/SELECT.hpp +++ b/src/net/packets/SELECT.hpp @@ -13,11 +13,9 @@ static_assert(sizeof(SELECTPacket) == 0x38); class SELECTHandler { public: - const u8 *getPlayerIdToAidMapping() const; + const u8* getPlayerIdToAidMapping() const; - static SELECTHandler *getInstance() { - return spInstance; - } + static SELECTHandler* getInstance() { return spInstance; } private: u8 _000[0x008 - 0x000]; @@ -25,8 +23,8 @@ class SELECTHandler { SELECTPacket m_recvPackets[12]; u8 _2e0[0x3f8 - 0x2e0]; - static SELECTHandler *spInstance; + static SELECTHandler* spInstance; }; static_assert(sizeof(SELECTHandler) == 0x3f8); -} +} // namespace Net diff --git a/src/net/packets/USER.cpp b/src/net/packets/USER.cpp index 03f149e17..9d99a5257 100644 --- a/src/net/packets/USER.cpp +++ b/src/net/packets/USER.cpp @@ -1,5 +1,3 @@ #include "USER.hpp" -namespace Net { - -} +namespace Net {} diff --git a/src/net/packets/USER.hpp b/src/net/packets/USER.hpp index acfdc00b5..3645033c8 100644 --- a/src/net/packets/USER.hpp +++ b/src/net/packets/USER.hpp @@ -11,16 +11,15 @@ static_assert(sizeof(USERPacket) == 0xc0); class USERHandler { public: - void update(); + void update(); + + static USERHandler* getInstance() { return spInstance; } - static USERHandler *getInstance() { - return spInstance; - } private: u8 _000[0x9f0 - 0x000]; - static USERHandler *spInstance; + static USERHandler* spInstance; }; static_assert(sizeof(USERHandler) == 0x9f0); -} +} // namespace Net