NetPlay: Automatically disconnect clients that are not running the same version of Mesen

This commit is contained in:
Souryo 2016-02-10 23:07:42 -05:00
parent eb80a443b7
commit 163c2f3eaa
12 changed files with 87 additions and 10 deletions

View file

@ -370,6 +370,7 @@
<ClInclude Include="FDS.h" />
<ClInclude Include="FdsAudio.h" />
<ClInclude Include="FdsLoader.h" />
<ClInclude Include="ForceDisconnectMessage.h" />
<ClInclude Include="HdVideoFilter.h" />
<ClInclude Include="iNesLoader.h" />
<ClInclude Include="IremH3001.h" />

View file

@ -545,6 +545,9 @@
<ClInclude Include="SelectControllerMessage.h">
<Filter>NetPlay\Messages</Filter>
</ClInclude>
<ClInclude Include="ForceDisconnectMessage.h">
<Filter>NetPlay\Messages</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">

View file

@ -17,6 +17,10 @@ uint32_t EmulationSettings::PpuPaletteArgb[64] = {
0xFFB5EBF2, 0xFFB8B8B8, 0xFF000000, 0xFF000000,
};
uint16_t EmulationSettings::_versionMajor = 0;
uint8_t EmulationSettings::_versionMinor = 1;
uint8_t EmulationSettings::_versionRevision = 0;
uint32_t EmulationSettings::_flags = 0;
uint32_t EmulationSettings::_audioLatency = 20000;

View file

@ -143,6 +143,11 @@ struct KeyMappingSet
class EmulationSettings
{
private:
//Version 0.1.0
static uint16_t _versionMajor;
static uint8_t _versionMinor;
static uint8_t _versionRevision;
static uint32_t PpuPaletteArgb[64];
static uint32_t _flags;
@ -170,12 +175,12 @@ private:
public:
static uint32_t GetMesenVersion()
{
//Version 0.1.0
uint16_t major = 0;
uint8_t minor = 1;
uint8_t revision = 0;
return (_versionMajor << 16) | (_versionMinor << 8) | _versionRevision;
}
return (major << 16) | (minor << 8) | revision;
static string GetMesenVersionString()
{
return std::to_string(_versionMajor) + "." + std::to_string(_versionMinor) + "." + std::to_string(_versionRevision);
}
static void SetFlags(EmulationFlags flags)

View file

@ -0,0 +1,33 @@
#pragma once
#include "stdafx.h"
#include "MessageManager.h"
#include "NetMessage.h"
#include "Console.h"
#include "RomLoader.h"
#include "../Utilities/FolderUtilities.h"
class ForceDisconnectMessage : public NetMessage
{
private:
char* _disconnectMessage = nullptr;
uint32_t _messageLength = 0;
protected:
virtual void ProtectedStreamState()
{
StreamArray((void**)&_disconnectMessage, _messageLength);
}
public:
ForceDisconnectMessage(void* buffer, uint32_t length) : NetMessage(buffer, length) { }
ForceDisconnectMessage(string message) : NetMessage(MessageType::ForceDisconnect)
{
CopyString(&_disconnectMessage, _messageLength, message);
}
string GetMessage()
{
return _disconnectMessage;
}
};

View file

@ -12,6 +12,7 @@
#include "StandardController.h"
#include "SelectControllerMessage.h"
#include "PlayerListMessage.h"
#include "ForceDisconnectMessage.h"
GameClientConnection::GameClientConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData) : GameConnection(socket, connectionData)
{
@ -76,6 +77,10 @@ void GameClientConnection::ProcessMessage(NetMessage* message)
}
break;
case MessageType::ForceDisconnect:
MessageManager::DisplayMessage("Net Play", ((ForceDisconnectMessage*)message)->GetMessage());
break;
case MessageType::PlayerList:
_playerList = ((PlayerListMessage*)message)->GetPlayerList();
break;

View file

@ -8,6 +8,7 @@
#include "PlayerListMessage.h"
#include "SelectControllerMessage.h"
#include "ClientConnectionData.h"
#include "ForceDisconnectMessage.h"
GameConnection::GameConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData)
{
@ -58,6 +59,7 @@ NetMessage* GameConnection::ReadMessage()
case MessageType::GameInformation: return new GameInformationMessage(_messageBuffer, messageLength);
case MessageType::PlayerList: return new PlayerListMessage(_messageBuffer, messageLength);
case MessageType::SelectController: return new SelectControllerMessage(_messageBuffer, messageLength);
case MessageType::ForceDisconnect: return new ForceDisconnectMessage(_messageBuffer, messageLength);
}
}
return nullptr;
@ -70,6 +72,11 @@ void GameConnection::SendNetMessage(NetMessage &message)
_socketLock.Release();
}
void GameConnection::Disconnect()
{
_socket->Close();
}
bool GameConnection::ConnectionError()
{
return _socket->ConnectionError();

View file

@ -31,6 +31,9 @@ private:
virtual void ProcessMessage(NetMessage* message) = 0;
protected:
void Disconnect();
public:
static const uint8_t SpectatorPort = 0xFF;
GameConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData);

View file

@ -14,6 +14,7 @@
#include "SelectControllerMessage.h"
#include "PlayerListMessage.h"
#include "GameServer.h"
#include "ForceDisconnectMessage.h"
GameServerConnection* GameServerConnection::_netPlayDevices[4] = { nullptr,nullptr,nullptr,nullptr };
@ -28,8 +29,6 @@ GameServerConnection::~GameServerConnection()
{
if(_connectionData) {
MessageManager::DisplayToast("Net Play", _connectionData->PlayerName + " (Player " + std::to_string(_controllerPort + 1) + ") disconnected.", _connectionData->AvatarData, _connectionData->AvatarSize);
} else {
MessageManager::DisplayMessage("Net Play", "Player " + std::to_string(_controllerPort + 1) + " disconnected.");
}
UnregisterNetPlayDevice(this);
@ -54,6 +53,13 @@ void GameServerConnection::SendMovieData(uint8_t state, uint8_t port)
}
}
void GameServerConnection::SendForceDisconnectMessage(string disconnectMessage)
{
ForceDisconnectMessage message(disconnectMessage);
SendNetMessage(message);
Disconnect();
}
void GameServerConnection::PushState(uint32_t state)
{
if(_inputData.size() == 0 || state != _inputData.back()) {
@ -96,6 +102,9 @@ void GameServerConnection::ProcessHandshakeResponse(HandShakeMessage* message)
RegisterNetPlayDevice(this, _controllerPort);
GameServer::SendPlayerList();
Console::Resume();
} else {
SendForceDisconnectMessage("Server is using a different version of Mesen (" + EmulationSettings::GetMesenVersionString() + ") - you have been disconnected.");
MessageManager::DisplayMessage("Net Play", message->GetPlayerName() + " is not running the same version of Mesen and has been disconnected");
}
}

View file

@ -20,6 +20,8 @@ private:
void SendGameInformation();
void SelectControllerPort(uint8_t port);
void SendForceDisconnectMessage(string disconnectMessage);
void ProcessHandshakeResponse(HandShakeMessage* message);
static void RegisterNetPlayDevice(GameServerConnection* connection, uint8_t port);

View file

@ -1,11 +1,13 @@
#pragma once
#include "stdafx.h"
#include "NetMessage.h"
#include "EmulationSettings.h"
class HandShakeMessage : public NetMessage
{
private:
const static int CurrentVersion = 1;
uint32_t _mesenVersion = 0;
uint32_t _protocolVersion = CurrentVersion;
char* _playerName = nullptr;
uint32_t _playerNameLength = 0;
@ -16,6 +18,7 @@ private:
protected:
virtual void ProtectedStreamState()
{
Stream<uint32_t>(_mesenVersion);
Stream<uint32_t>(_protocolVersion);
StreamArray((void**)&_playerName, _playerNameLength);
StreamArray(&_avatarData, _avatarSize);
@ -26,13 +29,14 @@ public:
HandShakeMessage(void* buffer, uint32_t length) : NetMessage(buffer, length) { }
HandShakeMessage(string playerName, uint8_t* avatarData, uint32_t avatarSize, bool spectator) : NetMessage(MessageType::HandShake)
{
_protocolVersion = 1;
_mesenVersion = EmulationSettings::GetMesenVersion();
_protocolVersion = HandShakeMessage::CurrentVersion;
CopyString(&_playerName, _playerNameLength, playerName);
_avatarSize = avatarSize;
_avatarData = avatarData;
_spectator = spectator;
}
string GetPlayerName()
{
return string(_playerName);
@ -50,7 +54,7 @@ public:
bool IsValid()
{
return _protocolVersion == CurrentVersion;
return _protocolVersion == CurrentVersion && _mesenVersion == EmulationSettings::GetMesenVersion();
}
bool IsSpectator()

View file

@ -10,4 +10,5 @@ enum class MessageType : uint8_t
GameInformation = 4,
PlayerList = 5,
SelectController = 6,
ForceDisconnect = 7
};