pull in project-slippi/Ishiiruka/commit/5a77120289f7542302a2eb53b9ee2bce43d490f6

enforce stage for fixed rules modes
This commit is contained in:
Nikhil Narayana 2021-12-18 17:20:42 -08:00
commit 3e48d6965a
4 changed files with 80 additions and 33 deletions

View file

@ -27,6 +27,7 @@
#include "Core/Host.h"
#include "Core/NetPlayClient.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/Slippi/SlippiMatchmaking.h"
#include "Core/Slippi/SlippiPlayback.h"
#include "Core/Slippi/SlippiReplayComm.h"
#include "Core/State.h"
@ -1508,7 +1509,6 @@ bool CEXISlippi::isDisconnected()
return status != SlippiNetplayClient::SlippiConnectStatus::NET_CONNECT_STATUS_CONNECTED;
}
static int tempTestCount = 0;
void CEXISlippi::handleOnlineInputs(u8* payload)
{
m_read_queue.clear();
@ -1829,10 +1829,23 @@ void CEXISlippi::startFindMatch(u8* payload)
// give someone an early error before they even queue so that they wont enter the queue and make
// someone else get force removed from queue and have to requeue
auto directMode = SlippiMatchmaking::OnlinePlayMode::DIRECT;
if (search.mode < directMode && localSelections.characterId >= 26)
if (SlippiMatchmaking::IsFixedRulesMode(search.mode))
{
forcedError = "The character you selected is not allowed in this mode";
return;
// Character check
if (localSelections.characterId >= 26)
{
forcedError = "The character you selected is not allowed in this mode";
return;
}
// Stage check
if (localSelections.isStageSelected &&
std::find(singlesStages.begin(), singlesStages.end(), localSelections.stageId) ==
singlesStages.end())
{
forcedError = "The stage being requested is not allowed in this mode";
return;
}
}
#ifndef LOCAL_TESTING
@ -2070,14 +2083,53 @@ void CEXISlippi::prepareOnlineMatchState()
if (rps[i].characterId >= 26)
remoteCharOk = false;
}
if (lastSearch.mode < directMode && (!localCharOk || !remoteCharOk))
// TODO: This is annoying, ideally remotePlayerSelections would just include everyone including
// the local player
// TODO: Would also simplify some logic in the Netplay class
std::vector<SlippiPlayerSelections> orderedSelections(4);
orderedSelections[lps.playerIdx] = lps;
for (int i = 0; i < remotePlayerCount; i++)
{
// If we get here, someone is doing something bad, clear the lobby
handleConnectionCleanup();
orderedSelections[rps[i].playerIdx] = rps[i];
}
// Overwrite stage information. Make sure everyone loads the same stage
u16 stageId = 0x1F; // Default to battlefield if there was no selection
for (auto selections : orderedSelections)
{
if (!selections.isStageSelected)
continue;
// Stage selected by this player, use that selection
stageId = selections.stageId;
break;
}
if (SlippiMatchmaking::IsFixedRulesMode(lastSearch.mode))
{
// If we enter one of these conditions, someone is doing something bad, clear the lobby
if (!localCharOk)
{
handleConnectionCleanup();
forcedError = "The character you selected is not allowed in this mode";
prepareOnlineMatchState();
return;
prepareOnlineMatchState();
return;
}
if (!remoteCharOk)
{
handleConnectionCleanup();
prepareOnlineMatchState();
return;
}
if (std::find(singlesStages.begin(), singlesStages.end(), stageId) == singlesStages.end())
{
handleConnectionCleanup();
prepareOnlineMatchState();
return;
}
}
// Overwrite local player character
@ -2121,20 +2173,6 @@ void CEXISlippi::prepareOnlineMatchState()
onlineMatchBlock[0x61 + 3 * 0x24] = 0;
}
// Overwrite stage
u16 stageId;
if (isDecider)
{
stageId = lps.isStageSelected ? lps.stageId : rps[0].stageId;
}
else
{
stageId = rps[0].isStageSelected ? rps[0].stageId : lps.stageId;
}
u16* stage = (u16*)&onlineMatchBlock[0xE];
*stage = Common::swap16(stageId);
// Set rng offset
rngOffset = isDecider ? lps.rngOffset : rps[0].rngOffset;
WARN_LOG(SLIPPI_ONLINE, "Rng Offset: 0x%x", rngOffset);
@ -2244,22 +2282,22 @@ void CEXISlippi::prepareOnlineMatchState()
m_read_queue.insert(m_read_queue.end(), onlineMatchBlock.begin(), onlineMatchBlock.end());
}
std::vector<u16> CEXISlippi::singlesStages = {
// 0x2, // FoD
0x3, // Pokemon
0x8, // Yoshi's Story
0x1C, // Dream Land
0x1F, // Battlefield
0x20, // Final Destination
};
u16 CEXISlippi::getRandomStage()
{
static u16 selectedStage;
static std::vector<u16> stages = {
0x2, // FoD
0x3, // Pokemon
0x8, // Yoshi's Story
0x1C, // Dream Land
0x1F, // Battlefield
0x20, // Final Destination
};
// Reset stage pool if it's empty
if (stagePool.empty())
stagePool.insert(stagePool.end(), stages.begin(), stages.end());
stagePool.insert(stagePool.end(), singlesStages.begin(), singlesStages.end());
// Get random stage
int randIndex = generator() % stagePool.size();

View file

@ -251,5 +251,7 @@ private:
std::map<s32, std::unique_ptr<SlippiSavestate>> activeSavestates;
std::deque<std::unique_ptr<SlippiSavestate>> availableSavestates;
static std::vector<u16> singlesStages;
};
} // namespace ExpansionInterface

View file

@ -85,6 +85,12 @@ std::unique_ptr<SlippiNetplayClient> SlippiMatchmaking::GetNetplayClient()
return std::move(m_netplayClient);
}
bool IsFixedRulesMode(SlippiMatchmaking::OnlinePlayMode mode)
{
return mode == SlippiMatchmaking::OnlinePlayMode::UNRANKED ||
mode == SlippiMatchmaking::OnlinePlayMode::RANKED;
}
void SlippiMatchmaking::sendMessage(json msg)
{
enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE;

View file

@ -57,6 +57,7 @@ public:
std::vector<SlippiUser::UserInfo> GetPlayerInfo();
std::string GetPlayerName(u8 port);
u8 RemotePlayerCount();
static bool IsFixedRulesMode(OnlinePlayMode mode);
protected:
const std::string MM_HOST_DEV = "35.197.121.196"; // Dev host