Skip to content

Commit

Permalink
Merge pull request #56 from MikeIsAStar/fix-item-negotiation-bug
Browse files Browse the repository at this point in the history
[MKW] Fix a bug that leads to the rejection of one's item request without justification
  • Loading branch information
mkwcat authored Feb 22, 2024
2 parents 4a8f3d1 + aee7ed4 commit 35d845d
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 64 deletions.
19 changes: 16 additions & 3 deletions payload/import/mkw/net/itemHandler.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include <wwfcUtil.h>
#include "import/mkw/item.hpp"

namespace mkw::Net
{
Expand Down Expand Up @@ -98,7 +98,7 @@ class ItemHandler
}
}

/* 0x00 */ u8 _00;
/* 0x00 */ u8 receivedTime;
/* 0x01 */ u8 heldItem;
/* 0x02 */ u8 trailedItem;
/* 0x03 */ HeldPhase heldPhase;
Expand All @@ -108,13 +108,26 @@ class ItemHandler

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

Packet& sendPacket(u32 localPlayerIndex)
{
return m_sendPacket[localPlayerIndex];
}

void setReceivedTime(u32 receivedTime, u32 playerIndex)
{
m_receivedTime[playerIndex] = receivedTime;
}

static ItemHandler* Instance()
{
return s_instance;
}

private:
/* 0x000 */ u8 _000[0x184 - 0x000];
/* 0x000 */ Packet m_sendPacket[2];
/* 0x010 */ u8 _010[0x0A0 - 0x010];
/* 0x0A0 */ u32 m_receivedTime[12];
/* 0x0D0 */ u8 _0D0[0x184 - 0x0D0];

static ItemHandler* s_instance
AT(RMCXD_PORT(0x809C20F8, 0x809BD950, 0x809C1158, 0x809B0738));
Expand Down
55 changes: 48 additions & 7 deletions payload/import/mkw/net/net.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct __attribute__((packed)) RacePacket {
static_assert(sizeof(RacePacket) == 0x10);

// https://github.com/SeekyCt/mkw-structures/blob/master/rknetcontroller.h
class RKNetController
class NetController
{
public:
enum JoinType {
Expand Down Expand Up @@ -58,14 +58,14 @@ class RKNetController
processRacePacket(u32 playerAid, RacePacket* racePacket, u32 packetSize)
{
LONGCALL void processRacePacket(
RKNetController * rkNetController, u32 playerAid,
NetController * netController, u32 playerAid,
RacePacket * racePacket, u32 packetSize
) AT(RMCXD_PORT(0x80659A84, 0x806555FC, 0x806590F0, 0x80647D9C));

processRacePacket(this, playerAid, racePacket, packetSize);
}

ConnectionInfo& currentConnectionInfo()
const ConnectionInfo& currentConnectionInfo() const
{
return m_connectionInfo[m_currentConnectionInfoIndex];
}
Expand All @@ -75,6 +75,21 @@ class RKNetController
return m_joinType;
}

u8 myAid() const
{
return currentConnectionInfo().myAid;
}

bool isAidTheServer(u8 playerAid) const
{
return playerAid == currentConnectionInfo().serverAid;
}

bool amITheServer() const
{
return isAidTheServer(myAid());
}

bool inVanillaMatch() const
{
switch (m_joinType) {
Expand Down Expand Up @@ -113,7 +128,7 @@ class RKNetController
}
}

bool inVanillaRaceScene()
bool inVanillaRaceScene() const
{
using namespace mkw::System;

Expand All @@ -125,7 +140,7 @@ class RKNetController
return inVanillaMatch();
}

static RKNetController* Instance()
static NetController* Instance()
{
return s_instance;
}
Expand All @@ -138,11 +153,37 @@ class RKNetController
/* 0x291C */ int m_currentConnectionInfoIndex;
/* 0x2920 */ u8 _2920[0x29C8 - 0x2920];

static RKNetController* s_instance
static NetController* s_instance
AT(RMCXD_PORT(0x809C20D8, 0x809BD918, 0x809C1138, 0x809B0718));
};

static_assert(sizeof(RKNetController) == 0x29C8);
static_assert(sizeof(NetController) == 0x29C8);

class RacePacketHandler
{
public:
u32 playerIdToLocalPlayerIndex(u32 playerId)
{
LONGCALL u32 playerIdToLocalPlayerIndex(
RacePacketHandler * racePacketHandler, u32 playerId
) AT(RMCXD_PORT(0x80654918, 0x80650490, 0x80653F84, 0x80642C30));

return playerIdToLocalPlayerIndex(this, playerId);
}

static RacePacketHandler* Instance()
{
return s_instance;
}

private:
/* 0x000 */ u8 _000[0x1C8 - 0x000];

static RacePacketHandler* s_instance
AT(RMCXD_PORT(0x809C1F50, 0x809BD790, 0x809C0FB0, 0x809B0590));
};

static_assert(sizeof(RacePacketHandler) == 0x1C8);

#endif

Expand Down
36 changes: 36 additions & 0 deletions payload/import/mkw/system/raceManager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#include <wwfcUtil.h>

namespace mkw::System
{

#if RMC

class RaceManager
{
public:
u32 timer() const
{
return m_timer;
}

static RaceManager* Instance()
{
return s_instance;
}

private:
/* 0x00 */ u8 _00[0x20 - 0x00];
/* 0x20 */ u32 m_timer;
/* 0x24 */ u8 _24[0x4C - 0x24];

static RaceManager* s_instance
AT(RMCXD_PORT(0x809BD730, 0x809B8F70, 0x809BC790, 0x809ABD70));
};

static_assert(sizeof(RaceManager) == 0x4C);

#endif

} // namespace mkw::System
4 changes: 2 additions & 2 deletions payload/wwfcBugFix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ u64 IsUltraShortcutCheckEnabled(u32 r3Discard, u32 r4Save)
auto raceConfig = mkw::System::RaceConfig::Instance();
if (raceConfig->raceScenario().isOnlineVersusRace()) {
// Check if Worldwide or other vanilla match
auto rkNetController = mkw::Net::RKNetController::Instance();
if (rkNetController != nullptr && rkNetController->inVanillaMatch()) {
auto netController = mkw::Net::NetController::Instance();
if (netController && netController->inVanillaMatch()) {
enabled = true;
}
}
Expand Down
105 changes: 68 additions & 37 deletions payload/wwfcFeature.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "import/dwc.h"
#include "import/gamespy.h"
#include "import/mkw/net/itemHandler.hpp"
#include "import/mkw/net/net.hpp"
#include "import/mkw/net/selectHandler.hpp"
#include "import/mkw/system/raceManager.hpp"
#include "import/mkw/ui/page.hpp"
#include "import/mkw/util.hpp"
#include <cstring>
Expand All @@ -24,42 +27,6 @@ namespace wwfc::Feature

#if RMC

static void DecideEngineClass(
mkw::Net::SelectHandler* selectHandler, mkw::Util::Random* random
)
{
using namespace mkw::Net;

SelectHandler::Packet& sendPacket = selectHandler->sendPacket();

if (random->nextInt(100) < 65) {
sendPacket.engineClass = SelectHandler::Packet::EngineClass::e150cc;
} else {
sendPacket.engineClass =
SelectHandler::Packet::EngineClass::eMirrorMode;
}
}

// Remove the 100cc engine class from vanilla matches
WWFC_DEFINE_PATCH = {
Patch::CallWithCTR( //
WWFC_PATCH_LEVEL_PARITY, //
RMCXD_PORT(0x806613F8, 0x806594BC, 0x80660A64, 0x8064F710), //
[](mkw::Util::Random* random) -> void {
using namespace mkw::Net;

SelectHandler* selectHandler = SelectHandler::Instance();
if (RKNetController::Instance()->inVanillaMatch()) {
DecideEngineClass(selectHandler, random);
} else {
selectHandler->decideEngineClass();
}

random->dt(random, -1);
}
),
};

extern "C" {

__attribute__((__used__)) static GameSpy::GPResult
Expand Down Expand Up @@ -131,7 +98,6 @@ ShowMessageOfTheDay(mkw::UI::WifiMenuPage* wifiMenuPage)
}

wifiMenuPage->showMessageOfTheDay();

WifiMenuPage::SeenMessageOfTheDay();
}
}
Expand All @@ -156,6 +122,71 @@ WWFC_DEFINE_PATCH = {
),
};

// Fix a bug that leads to the rejection of one's item request without
// justification
WWFC_DEFINE_PATCH = {
Patch::BranchWithCTR( //
WWFC_PATCH_LEVEL_BUGFIX | WWFC_PATCH_LEVEL_PARITY, //
RMCXD_PORT(0x8065C6C0, 0x8065D348, 0x8065BD2C, 0x8064A9D8), //
// clang-format off
[](mkw::Net::ItemHandler* itemHandler, u32 playerId,
mkw::Item::ItemBox item) -> void {
using namespace mkw::Net;
using namespace mkw::System;

u32 localPlayerIndex =
RacePacketHandler::Instance()->playerIdToLocalPlayerIndex(playerId);
ItemHandler::Packet& sendPacket = itemHandler->sendPacket(localPlayerIndex);
u32 timer = RaceManager::Instance()->timer();
u8 myAid = NetController::Instance()->myAid();

sendPacket.receivedTime = (myAid << 1) + localPlayerIndex;
sendPacket.heldItem = static_cast<u8>(item);
sendPacket.heldPhase = ItemHandler::Packet::HeldPhase::Decided;
itemHandler->setReceivedTime(timer & 0xFFFFFFF8, playerId);
}
// clang-format on
),
};

static void DecideEngineClass(
mkw::Net::SelectHandler* selectHandler, mkw::Util::Random* random
)
{
using namespace mkw::Net;

SelectHandler::Packet& sendPacket = selectHandler->sendPacket();

if (random->nextInt(100) < 65) {
sendPacket.engineClass = SelectHandler::Packet::EngineClass::e150cc;
} else {
sendPacket.engineClass =
SelectHandler::Packet::EngineClass::eMirrorMode;
}
}

// Remove the 100cc engine class from vanilla matches
WWFC_DEFINE_PATCH = {
Patch::CallWithCTR( //
WWFC_PATCH_LEVEL_PARITY, //
RMCXD_PORT(0x806613F8, 0x806594BC, 0x80660A64, 0x8064F710), //
// clang-format off
[](mkw::Util::Random* random) -> void {
using namespace mkw::Net;

SelectHandler* selectHandler = SelectHandler::Instance();
if (NetController::Instance()->inVanillaMatch()) {
DecideEngineClass(selectHandler, random);
} else {
selectHandler->decideEngineClass();
}

random->dt(random, -1);
}
// clang-format on
),
};

#endif

} // namespace wwfc::Feature
Loading

0 comments on commit 35d845d

Please sign in to comment.