Skip to content

Commit

Permalink
[MKW] Prevent clients from stalling rooms
Browse files Browse the repository at this point in the history
Closes issue #23.
  • Loading branch information
MikeIsAStar committed May 23, 2024
1 parent 7c3b8c0 commit a40046c
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 66 deletions.
64 changes: 52 additions & 12 deletions payload/import/mkw/net/net.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#pragma once

#include "import/dwc.h"
#include "import/mkw/hostSystem.hpp"
#include "import/mkw/system/system.hpp"
#include <wwfcGPReport.hpp>

namespace mkw::Net
{
Expand Down Expand Up @@ -71,14 +73,13 @@ class NetController
FriendContinentalBattle = 10,
};

struct ConnectionInfo {
/* 0x00 */ u8 _00[0x21 - 0x00];
/* 0x21 */ u8 myAid;
/* 0x22 */ u8 serverAid;
/* 0x23 */ u8 _23[0x58 - 0x23];
};
void sendRacePacket()
{
LONGCALL void sendRacePacket(NetController * netController)
AT(RMCXD_PORT(0x80657E30, 0x806539A8, 0x8065749C, 0x80646148));

static_assert(sizeof(ConnectionInfo) == 0x58);
sendRacePacket(this);
}

void
processRacePacket(u32 playerAid, RacePacket* racePacket, u32 packetSize)
Expand All @@ -91,14 +92,14 @@ class NetController
processRacePacket(this, playerAid, racePacket, packetSize);
}

const ConnectionInfo& currentConnectionInfo() const
JoinType joinType() const
{
return m_connectionInfo[m_currentConnectionInfoIndex];
return m_joinType;
}

JoinType joinType() const
u32 availableAids() const
{
return m_joinType;
return currentConnectionInfo().availableAids;
}

u8 myAid() const
Expand Down Expand Up @@ -172,18 +173,57 @@ class NetController
return inVanillaMatch();
}

void reportAndKick(const char* key, u32 playerAid) const
{
using namespace DWC;

DWCiNodeInfo* nodeInfo = DWCi_NodeInfoList_GetNodeInfoForAid(playerAid);
if (nodeInfo) {
wwfc::GPReport::ReportU32(key, nodeInfo->profileId);
}

if (amITheServer()) {
DWC_CloseConnectionHard(playerAid);
}
}

static NetController* Instance()
{
return s_instance;
}

private:
struct ConnectionInfo {
/* 0x00 */ u8 _00[0x10 - 0x00];
/* 0x10 */ u32 availableAids;
/* 0x14 */ u8 _14[0x21 - 0x14];
/* 0x21 */ u8 myAid;
/* 0x22 */ u8 serverAid;
/* 0x23 */ u8 _23[0x58 - 0x23];
};

static_assert(sizeof(ConnectionInfo) == 0x58);

const ConnectionInfo& currentConnectionInfo() const
{
return m_connectionInfo[m_currentConnectionInfoIndex];
}

/* 0x0000 */ u8 _0000[0x0038 - 0x0000];
/* 0x0038 */ ConnectionInfo m_connectionInfo[2];
/* 0x00E8 */ JoinType m_joinType;
/* 0x00EC */ u8 _00EC[0x291C - 0x00EC];
/* 0x291C */ int m_currentConnectionInfoIndex;
/* 0x2920 */ u8 _2920[0x29C8 - 0x2920];
/* 0x2920 */ u8 _2920[0x29B0 - 0x2920];

public:
/* 0x29B0 */ u32 _29B0;
/* 0x29B4 */ u32 _29B4;
/* 0x29B8 */ u32 _29B8;
/* 0x29BC */ u32 _29BC;

private:
/* 0x29C0 */ u8 _29C0[0x29C8 - 0x29C0];

static NetController* s_instance
AT(RMCXD_PORT(0x809C20D8, 0x809BD918, 0x809C1138, 0x809B0718));
Expand Down
107 changes: 92 additions & 15 deletions payload/import/mkw/net/selectHandler.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "import/mkw/util.hpp"
#include "net.hpp"

namespace mkw::Net
{
Expand All @@ -12,30 +13,36 @@ class SelectHandler
{
public:
struct __attribute__((packed)) Packet {
enum class Character : u8 {
NotSelected = 0x30,
};

enum class Vehicle : u8 {
NotSelected = 0x24,
};

enum class CourseVote : u8 {
NotSelected = 0x43,
Random = 0xFF,
};

enum class SelectedCourse : u8 {
NotSelected = 0xFF,
};

enum class Phase : u8 {
Preparing = 0,
Voting = 1,
Lottery = 2,
};

enum class EngineClass : u8 {
e100cc = 1,
e150cc = 2,
eMirrorMode = 3,
};

struct Player {
enum class Character : u8 {
NotSelected = 0x30,
};

enum class Vehicle : u8 {
NotSelected = 0x24,
};

enum class CourseVote : u8 {
NotSelected = 0x43,
Random = 0xFF,
};

/* 0x00 */ u8 _00[0x04 - 0x00];
/* 0x04 */ Character character;
/* 0x05 */ Vehicle vehicle;
Expand All @@ -49,7 +56,8 @@ class SelectHandler
/* 0x10 */ Player player[2];
/* 0x20 */ u8 _20[0x34 - 0x20];
/* 0x34 */ SelectedCourse selectedCourse;
/* 0x35 */ u8 _35[0x37 - 0x35];
/* 0x35 */ Phase phase;
/* 0x36 */ u8 _36;
/* 0x37 */ EngineClass engineClass;
};

Expand All @@ -72,15 +80,84 @@ class SelectHandler
}
}

// https://github.com/CLF78/OpenPayload/blob/master/payload/wiimmfi/RoomStall.cpp
void processKicks()
{
NetController* netController = NetController::Instance();
if (!netController->amITheServer()) {
return;
}

if (s_kickTimerFrames < s_kickTimerThresholdFrames) {
s_kickTimerFrames++;

return;
}
s_kickTimerFrames = 0;

u32 availableAids =
netController->availableAids() & ~(1 << netController->myAid());

u32 aidsStillLoading = 0x00000000;
switch (m_sendPacket.phase) {
case Packet::Phase::Preparing: {
aidsStillLoading = (~m_aidsWithNewSelectPacket) & availableAids;
if (aidsStillLoading) {
break;
}

aidsStillLoading = (~m_aidsWithNewMatchSettings) & availableAids;
break;
}
case Packet::Phase::Voting: {
aidsStillLoading = (~m_aidsWithVote) & availableAids;
if (aidsStillLoading) {
break;
}

aidsStillLoading = (~m_aidsWithVoteData) & availableAids;
break;
}
default: {
return;
}
}

// Support modifications that allow for clients to be connected to more
// than 11 peers at once.
for (u32 n = 0; n < sizeof(aidsStillLoading) * 8; n++) {
if (((aidsStillLoading >> n) & 1) == 0) {
continue;
}

netController->reportAndKick("mkw_room_stall", n);
}
}

static SelectHandler* Instance()
{
return s_instance;
}

static void ResetKickTimer()
{
s_kickTimerFrames = 0;
}

private:
/* 0x000 */ u8 _000[0x008 - 0x000];
/* 0x008 */ Packet m_sendPacket;
/* 0x040 */ u8 _040[0x3F8 - 0x040];
/* 0x040 */ u8 _040[0x3E0 - 0x040];
/* 0x3E0 */ u32 m_aidsWithNewSelectPacket;
/* 0x3E4 */ u8 _3E4[0x3E8 - 0x3E4];
/* 0x3E8 */ u32 m_aidsWithNewMatchSettings;
/* 0x3EC */ u32 m_aidsWithVoteData;
/* 0x3F0 */ u32 m_aidsWithVote;
/* 0x3F4 */ u8 _3F4[0x3F8 - 0x3F4];

static u32 s_kickTimerFrames;

static constexpr u32 s_kickTimerThresholdFrames = 90 * 60;

static SelectHandler* s_instance
AT(RMCXD_PORT(0x809C2100, 0x809BD930, 0x809C1160, 0x809B0740));
Expand Down
8 changes: 8 additions & 0 deletions payload/import/mkw/net/userHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ class UserHandler

static_assert(sizeof(Packet) == 0xC0);

void calc()
{
LONGCALL void calc(UserHandler * userHandler)
AT(RMCXD_PORT(0x806629C0, 0x806608DC, 0x8066202C, 0x80650CD8));

calc(this);
}

static UserHandler* Instance()
{
return s_instance;
Expand Down
57 changes: 57 additions & 0 deletions payload/wwfcFeature.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
#include "import/mkw/net/itemHandler.hpp"
#include "import/mkw/net/selectHandler.hpp"
#include "import/mkw/net/userHandler.hpp"
#include "import/mkw/ui/page/friendRoomPage.hpp"
#include "import/mkw/ui/page/wifiFriendMenuPage.hpp"
#include "import/mkw/ui/page/wifiMenuPage.hpp"
#include "wwfcPatch.hpp"
#include <cstring>

namespace mkw::Net
{

#if RMC

u32 SelectHandler::s_kickTimerFrames = 0;

#endif

} // namespace mkw::Net

namespace mkw::UI
{

Expand Down Expand Up @@ -124,6 +136,28 @@ WWFC_DEFINE_PATCH = {
),
};

// Prevent clients from stalling rooms
WWFC_DEFINE_PATCH = {
Patch::CallWithCTR( //
WWFC_PATCH_LEVEL_FEATURE, //
RMCXD_PORT(0x806579A0, 0x80653518, 0x8065700C, 0x80645CB8), //
// clang-format off
[](mkw::Net::NetController* netController) -> void {
using namespace mkw::Net;

netController->sendRacePacket();

UserHandler::Instance()->calc();

SelectHandler* selectHandler = SelectHandler::Instance();
if (selectHandler) {
selectHandler->processKicks();
}
}
// clang-format on
),
};

// Fix a bug that leads to the rejection of one's item request without
// justification
WWFC_DEFINE_PATCH = {
Expand All @@ -139,6 +173,29 @@ WWFC_DEFINE_PATCH = {
),
};

// Reset the timer that is used to detect if clients are stalling the room
WWFC_DEFINE_PATCH = {
Patch::CallWithCTR( //
WWFC_PATCH_LEVEL_FEATURE, //
RMCXD_PORT(0x8065FF34, 0x80657FF8, 0x8065F5A0, 0x8064E24C), //
// clang-format off
[](mkw::Net::SelectHandler* selectHandler,
mkw::Net::NetController* netController) -> mkw::Net::SelectHandler* {
using namespace mkw::Net;

netController->_29B0 = 0;
netController->_29B4 = 0;
netController->_29B8 = 0;
netController->_29BC = 0;

SelectHandler::ResetKickTimer();

return selectHandler;
}
// clang-format on
),
};

// Remove the 100cc engine class from vanilla matches
WWFC_DEFINE_PATCH = {
Patch::CallWithCTR( //
Expand Down
2 changes: 1 addition & 1 deletion payload/wwfcGPReport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ void ReportB64Encode(const char* key, const void* data, size_t dataSize);

#endif

} // namespace wwfc::GPReport
} // namespace wwfc::GPReport
Loading

0 comments on commit a40046c

Please sign in to comment.