NetPlay: Sync host cheat codes with clients
This commit is contained in:
parent
40eac94d18
commit
a2c9122f74
6 changed files with 79 additions and 24 deletions
|
@ -156,4 +156,30 @@ void CheatManager::ApplyPrgCodes(uint8_t *prgRam, uint32_t prgSize)
|
|||
}
|
||||
}
|
||||
Console::Resume();
|
||||
}
|
||||
|
||||
vector<CodeInfo> CheatManager::GetCheats()
|
||||
{
|
||||
//Used by NetPlay
|
||||
vector<CodeInfo> cheats;
|
||||
for(unique_ptr<vector<CodeInfo>> &codes : Instance->_relativeCheatCodes) {
|
||||
if(codes) {
|
||||
std::copy(codes.get()->begin(), codes.get()->end(), std::back_inserter(cheats));
|
||||
}
|
||||
}
|
||||
std::copy(Instance->_absoluteCheatCodes.begin(), Instance->_absoluteCheatCodes.end(), std::back_inserter(cheats));
|
||||
return cheats;
|
||||
}
|
||||
|
||||
void CheatManager::SetCheats(vector<CodeInfo> &cheats)
|
||||
{
|
||||
//Used by NetPlay
|
||||
Instance->ClearCodes();
|
||||
|
||||
if(cheats.size() > 0) {
|
||||
MessageManager::DisplayMessage("NetPlay", std::to_string(cheats.size()) + " cheats applied.");
|
||||
for(CodeInfo &cheat : cheats) {
|
||||
Instance->AddCode(cheat);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,6 +29,8 @@ public:
|
|||
static void AddProActionRockyCode(uint32_t code);
|
||||
static void AddCustomCode(uint32_t address, uint8_t value, int32_t compareValue = -1, bool isRelativeAddress = true);
|
||||
static void ClearCodes();
|
||||
static vector<CodeInfo> GetCheats();
|
||||
static void SetCheats(vector<CodeInfo> &cheats);
|
||||
|
||||
static void ApplyRamCodes(uint16_t addr, uint8_t &value);
|
||||
static void ApplyPrgCodes(uint8_t *prgRam, uint32_t prgSize);
|
||||
|
|
|
@ -37,20 +37,8 @@ GameServerConnection::~GameServerConnection()
|
|||
|
||||
void GameServerConnection::SendGameState()
|
||||
{
|
||||
Console::Pause();
|
||||
stringstream state;
|
||||
Console::SaveState(state);
|
||||
_handshakeCompleted = true;
|
||||
ControlManager::RegisterControlDevice(this, _controllerPort);
|
||||
Console::Resume();
|
||||
|
||||
uint32_t size = (uint32_t)state.tellp();
|
||||
|
||||
char* buffer = new char[size];
|
||||
state.read(buffer, size);
|
||||
SaveStateMessage message(buffer, size, true);
|
||||
SaveStateMessage message;
|
||||
SendNetMessage(message);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void GameServerConnection::SendGameInformation()
|
||||
|
@ -89,11 +77,17 @@ void GameServerConnection::ProcessMessage(NetMessage* message)
|
|||
case MessageType::HandShake:
|
||||
//Send the game's current state to the client and register the controller
|
||||
if(((HandShakeMessage*)message)->IsValid()) {
|
||||
Console::Pause();
|
||||
_connectionData.reset(new ClientConnectionData("", 0, ((HandShakeMessage*)message)->GetPlayerName(), ((HandShakeMessage*)message)->GetAvatarData(), ((HandShakeMessage*)message)->GetAvatarSize()));
|
||||
|
||||
MessageManager::DisplayToast("Net Play", _connectionData->PlayerName + " (Player " + std::to_string(_controllerPort + 1) + ") connected.", _connectionData->AvatarData, _connectionData->AvatarSize);
|
||||
|
||||
SendGameInformation();
|
||||
SendGameState();
|
||||
|
||||
_handshakeCompleted = true;
|
||||
ControlManager::RegisterControlDevice(this, _controllerPort);
|
||||
Console::Resume();
|
||||
}
|
||||
break;
|
||||
case MessageType::InputData:
|
||||
|
|
|
@ -10,7 +10,8 @@ protected:
|
|||
bool _sending;
|
||||
vector<uint8_t> _buffer;
|
||||
uint32_t _position = 0;
|
||||
vector<void*> _pointersToRelease;
|
||||
vector<uint8_t*> _arraysToRelease;
|
||||
vector<char*> _stringsToRelease;
|
||||
|
||||
template<typename T>
|
||||
void Stream(T &value)
|
||||
|
@ -40,7 +41,7 @@ protected:
|
|||
Stream<uint32_t>(length);
|
||||
if(*value == nullptr) {
|
||||
*value = (void*)new uint8_t[length];
|
||||
_pointersToRelease.push_back(*value);
|
||||
_arraysToRelease.push_back((uint8_t*)*value);
|
||||
}
|
||||
uint8_t* bytes = (uint8_t*)(*value);
|
||||
for(uint32_t i = 0, len = length; i < len; i++) {
|
||||
|
@ -71,8 +72,11 @@ protected:
|
|||
public:
|
||||
virtual ~NetMessage()
|
||||
{
|
||||
for(void *pointer : _pointersToRelease) {
|
||||
delete[] pointer;
|
||||
for(uint8_t *arrayPtr: _arraysToRelease) {
|
||||
delete[] arrayPtr;
|
||||
}
|
||||
for(char *stringPtr: _stringsToRelease) {
|
||||
delete[] stringPtr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,7 +104,7 @@ public:
|
|||
length = (uint32_t)(src.length() + 1);
|
||||
*dest = new char[length];
|
||||
memcpy(*dest, src.c_str(), length);
|
||||
_pointersToRelease.push_back(*dest);
|
||||
_stringsToRelease.push_back(*dest);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -2,26 +2,54 @@
|
|||
#include "stdafx.h"
|
||||
#include "NetMessage.h"
|
||||
#include "Console.h"
|
||||
#include "CheatManager.h"
|
||||
|
||||
class SaveStateMessage : public NetMessage
|
||||
{
|
||||
private:
|
||||
void* _stateData;
|
||||
uint8_t* _stateData;
|
||||
uint32_t _dataSize;
|
||||
|
||||
CodeInfo* _cheats;
|
||||
uint32_t _cheatArraySize;
|
||||
|
||||
protected:
|
||||
virtual void ProtectedStreamState()
|
||||
{
|
||||
StreamArray(&_stateData, _dataSize);
|
||||
vector<CodeInfo> cheats;
|
||||
|
||||
StreamArray((void**)&_stateData, _dataSize);
|
||||
|
||||
if(_sending) {
|
||||
cheats = CheatManager::GetCheats();
|
||||
_cheats = &cheats[0];
|
||||
_cheatArraySize = (uint32_t)cheats.size() * sizeof(CodeInfo);
|
||||
StreamArray((void**)&_cheats, _cheatArraySize);
|
||||
delete[] _stateData;
|
||||
} else {
|
||||
StreamArray((void**)&_cheats, _cheatArraySize);
|
||||
for(uint32_t i = 0; i < _cheatArraySize / sizeof(CodeInfo); i++) {
|
||||
cheats.push_back(((CodeInfo*)_cheats)[i]);
|
||||
}
|
||||
|
||||
CheatManager::SetCheats(cheats);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
SaveStateMessage(void* buffer, uint32_t length) : NetMessage(buffer, length) { }
|
||||
|
||||
SaveStateMessage(void* stateData, uint32_t dataSize, bool forSend) : NetMessage(MessageType::SaveState)
|
||||
{
|
||||
_stateData = stateData;
|
||||
_dataSize = dataSize;
|
||||
SaveStateMessage() : NetMessage(MessageType::SaveState)
|
||||
{
|
||||
//Used when sending state to clients
|
||||
Console::Pause();
|
||||
stringstream state;
|
||||
Console::SaveState(state);
|
||||
Console::Resume();
|
||||
|
||||
_dataSize = (uint32_t)state.tellp();
|
||||
_stateData = new uint8_t[_dataSize];
|
||||
state.read((char*)_stateData, _dataSize);
|
||||
}
|
||||
|
||||
void LoadState()
|
||||
|
|
|
@ -279,6 +279,7 @@ namespace Mesen.GUI.Forms
|
|||
mnuConnect.Enabled = !netPlay;
|
||||
mnuDisconnect.Enabled = !mnuConnect.Enabled && !InteropEmu.IsServerRunning();
|
||||
|
||||
mnuCheats.Enabled = !InteropEmu.IsConnected();
|
||||
mnuEmulationSpeed.Enabled = !InteropEmu.IsConnected();
|
||||
|
||||
bool moviePlaying = InteropEmu.MoviePlaying();
|
||||
|
|
Loading…
Add table
Reference in a new issue