Netplay: Added password protected servers

This commit is contained in:
Sour 2018-06-16 14:02:12 -04:00
parent c0c0fa606b
commit 7619b93cfe
34 changed files with 215 additions and 174 deletions

View file

@ -7,13 +7,14 @@ class ClientConnectionData
public:
string Host;
uint16_t Port;
string Password;
string PlayerName;
bool Spectator;
ClientConnectionData(string host, uint16_t port, string playerName, bool spectator) :
Host(host), Port(port), PlayerName(playerName), Spectator(spectator)
ClientConnectionData() {}
ClientConnectionData(string host, uint16_t port, string password, string playerName, bool spectator) :
Host(host), Port(port), Password(password), PlayerName(playerName), Spectator(spectator)
{
}

View file

@ -531,6 +531,7 @@
<ClInclude Include="MovieRecorder.h" />
<ClInclude Include="AsciiTurboFile.h" />
<ClInclude Include="RawVideoFilter.h" />
<ClInclude Include="ServerInformationMessage.h" />
<ClInclude Include="SystemActionManager.h" />
<ClInclude Include="DatachBarcodeReader.h" />
<ClInclude Include="DebugHud.h" />

View file

@ -1372,6 +1372,9 @@
<ClInclude Include="BaseSoundManager.h">
<Filter>Misc</Filter>
</ClInclude>
<ClInclude Include="ServerInformationMessage.h">
<Filter>NetPlay\Messages</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">

View file

@ -33,7 +33,7 @@ bool GameClient::Connected()
return instance ? instance->_connected : false;
}
void GameClient::Connect(shared_ptr<ClientConnectionData> connectionData)
void GameClient::Connect(ClientConnectionData &connectionData)
{
_instance.reset(new GameClient());
@ -55,11 +55,11 @@ shared_ptr<GameClientConnection> GameClient::GetConnection()
return instance ? instance->_connection : nullptr;
}
void GameClient::PrivateConnect(shared_ptr<ClientConnectionData> connectionData)
void GameClient::PrivateConnect(ClientConnectionData &connectionData)
{
_stop = false;
shared_ptr<Socket> socket(new Socket());
if(socket->Connect(connectionData->Host.c_str(), connectionData->Port)) {
if(socket->Connect(connectionData.Host.c_str(), connectionData.Port)) {
_connection.reset(new GameClientConnection(socket, connectionData));
_connected = true;
} else {

View file

@ -19,7 +19,7 @@ private:
static shared_ptr<GameClientConnection> GetConnection();
void PrivateConnect(shared_ptr<ClientConnectionData> connectionData);
void PrivateConnect(ClientConnectionData &connectionData);
void Exec();
public:
@ -27,7 +27,7 @@ public:
virtual ~GameClient();
static bool Connected();
static void Connect(shared_ptr<ClientConnectionData> connectionData);
static void Connect(ClientConnectionData &connectionData);
static void Disconnect();
static void SelectController(uint8_t port);

View file

@ -16,9 +16,11 @@
#include "SelectControllerMessage.h"
#include "PlayerListMessage.h"
#include "ForceDisconnectMessage.h"
#include "ServerInformationMessage.h"
GameClientConnection::GameClientConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData) : GameConnection(socket, connectionData)
GameClientConnection::GameClientConnection(shared_ptr<Socket> socket, ClientConnectionData &connectionData) : GameConnection(socket)
{
_connectionData = connectionData;
_shutdown = false;
_enableControllers = false;
_minimumQueueSize = 3;
@ -26,7 +28,6 @@ GameClientConnection::GameClientConnection(shared_ptr<Socket> socket, shared_ptr
MessageManager::RegisterNotificationListener(this);
MessageManager::DisplayMessage("NetPlay", "ConnectedToServer");
ControlManager::RegisterInputProvider(this);
SendHandshake();
}
GameClientConnection::~GameClientConnection()
@ -50,7 +51,7 @@ void GameClientConnection::Shutdown()
void GameClientConnection::SendHandshake()
{
HandShakeMessage message(_connectionData->PlayerName, _connectionData->Spectator);
HandShakeMessage message(_connectionData.PlayerName, HandShakeMessage::GetPasswordHash(_connectionData.Password, _serverSalt), _connectionData.Spectator);
SendNetMessage(message);
}
@ -74,6 +75,11 @@ void GameClientConnection::ProcessMessage(NetMessage* message)
GameInformationMessage* gameInfo;
switch(message->GetType()) {
case MessageType::ServerInformation:
_serverSalt = ((ServerInformationMessage*)message)->GetHashSalt();
SendHandshake();
break;
case MessageType::SaveState:
if(_gameLoaded) {
DisableControllers();

View file

@ -7,8 +7,7 @@
#include "BaseControlDevice.h"
#include "IInputProvider.h"
#include "ControlDeviceState.h"
class ClientConnectionData;
#include "ClientConnectionData.h"
class GameClientConnection : public GameConnection, public INotificationListener, public IInputProvider
{
@ -28,6 +27,8 @@ private:
ControlDeviceState _lastInputSent;
bool _gameLoaded = false;
uint8_t _controllerPort = GameConnection::SpectatorPort;
ClientConnectionData _connectionData;
string _serverSalt;
private:
void SendHandshake();
@ -40,7 +41,7 @@ protected:
void ProcessMessage(NetMessage* message) override;
public:
GameClientConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData);
GameClientConnection(shared_ptr<Socket> socket, ClientConnectionData &connectionData);
virtual ~GameClientConnection();
void Shutdown();

View file

@ -9,12 +9,12 @@
#include "SelectControllerMessage.h"
#include "ClientConnectionData.h"
#include "ForceDisconnectMessage.h"
#include "ServerInformationMessage.h"
const uint32_t PlayerListMessage::PlayerNameMaxLength;
GameConnection::GameConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData)
GameConnection::GameConnection(shared_ptr<Socket> socket)
{
_connectionData = connectionData;
_socket = socket;
}
@ -64,6 +64,7 @@ NetMessage* GameConnection::ReadMessage()
case MessageType::PlayerList: return new PlayerListMessage(_messageBuffer, messageLength);
case MessageType::SelectController: return new SelectControllerMessage(_messageBuffer, messageLength);
case MessageType::ForceDisconnect: return new ForceDisconnectMessage(_messageBuffer, messageLength);
case MessageType::ServerInformation: return new ServerInformationMessage(_messageBuffer, messageLength);
}
}
}

View file

@ -4,7 +4,6 @@
class Socket;
class NetMessage;
class ClientConnectionData;
struct PlayerInfo
{
@ -17,7 +16,6 @@ class GameConnection
{
protected:
shared_ptr<Socket> _socket;
shared_ptr<ClientConnectionData> _connectionData;
uint8_t _readBuffer[0x40000] = {};
uint8_t _messageBuffer[0x40000] = {};
int _readPosition = 0;
@ -36,7 +34,7 @@ protected:
public:
static const uint8_t SpectatorPort = 0xFF;
GameConnection(shared_ptr<Socket> socket, shared_ptr<ClientConnectionData> connectionData);
GameConnection(shared_ptr<Socket> socket);
bool ConnectionError();
void ProcessMessages();

View file

@ -11,10 +11,11 @@ using std::thread;
unique_ptr<GameServer> GameServer::Instance;
GameServer::GameServer(uint16_t listenPort, string hostPlayerName)
GameServer::GameServer(uint16_t listenPort, string password, string hostPlayerName)
{
_stop = false;
_port = listenPort;
_password = password;
_hostPlayerName = hostPlayerName;
_hostControllerPort = 0;
ControlManager::RegisterInputRecorder(this);
@ -37,7 +38,7 @@ void GameServer::AcceptConnections()
while(true) {
shared_ptr<Socket> socket = _listener->Accept();
if(!socket->ConnectionError()) {
_openConnections.push_back(shared_ptr<GameServerConnection>(new GameServerConnection(socket)));
_openConnections.push_back(shared_ptr<GameServerConnection>(new GameServerConnection(socket, _password)));
} else {
break;
}
@ -121,9 +122,9 @@ void GameServer::Stop()
MessageManager::DisplayMessage("NetPlay", "ServerStopped");
}
void GameServer::StartServer(uint16_t port, string hostPlayerName)
void GameServer::StartServer(uint16_t port, string password, string hostPlayerName)
{
Instance.reset(new GameServer(port, hostPlayerName));
Instance.reset(new GameServer(port, password, hostPlayerName));
Instance->_serverThread.reset(new thread(&GameServer::Exec, Instance.get()));
}

View file

@ -17,6 +17,7 @@ private:
unique_ptr<Socket> _listener;
uint16_t _port;
string _password;
list<shared_ptr<GameServerConnection>> _openConnections;
bool _initialized = false;
@ -30,10 +31,10 @@ private:
void Stop();
public:
GameServer(uint16_t port, string hostPlayerName);
GameServer(uint16_t port, string password, string hostPlayerName);
virtual ~GameServer();
static void StartServer(uint16_t port, string hostPlayerName);
static void StartServer(uint16_t port, string password, string hostPlayerName);
static void StopServer();
static bool Started();

View file

@ -1,4 +1,5 @@
#include "stdafx.h"
#include <random>
#include "MessageManager.h"
#include "GameServerConnection.h"
#include "HandShakeMessage.h"
@ -16,26 +17,46 @@
#include "GameServer.h"
#include "ForceDisconnectMessage.h"
#include "BaseControlDevice.h"
#include "ServerInformationMessage.h"
GameServerConnection* GameServerConnection::_netPlayDevices[BaseControlDevice::PortCount] = { };
GameServerConnection::GameServerConnection(shared_ptr<Socket> socket) : GameConnection(socket, nullptr)
GameServerConnection::GameServerConnection(shared_ptr<Socket> socket, string serverPassword) : GameConnection(socket)
{
//Server-side connection
_serverPassword = serverPassword;
_controllerPort = GameConnection::SpectatorPort;
MessageManager::RegisterNotificationListener(this);
SendServerInformation();
}
GameServerConnection::~GameServerConnection()
{
if(_connectionData) {
MessageManager::DisplayMessage("NetPlay", _connectionData->PlayerName + " (Player " + std::to_string(_controllerPort + 1) + ") disconnected.");
if(!_playerName.empty()) {
MessageManager::DisplayMessage("NetPlay", _playerName + " (Player " + std::to_string(_controllerPort + 1) + ") disconnected.");
}
UnregisterNetPlayDevice(this);
MessageManager::UnregisterNotificationListener(this);
}
void GameServerConnection::SendServerInformation()
{
std::random_device rd;
std::mt19937 engine(rd());
std::uniform_int_distribution<> dist((int)' ', (int)'~');
string hash(50, ' ');
for(int i = 0; i < 50; i++) {
int random = dist(engine);
hash[i] = (char)random;
}
_connectionHash = hash;
ServerInformationMessage message(hash);
SendNetMessage(message);
}
void GameServerConnection::SendGameInformation()
{
Console::Pause();
@ -88,23 +109,27 @@ void GameServerConnection::ProcessHandshakeResponse(HandShakeMessage* message)
{
//Send the game's current state to the client and register the controller
if(message->IsValid()) {
Console::Pause();
if(message->CheckPassword(_serverPassword, _connectionHash)) {
Console::Pause();
_controllerPort = message->IsSpectator() ? GameConnection::SpectatorPort : GetFirstFreeControllerPort();
_connectionData.reset(new ClientConnectionData("", 0, message->GetPlayerName(), false));
_controllerPort = message->IsSpectator() ? GameConnection::SpectatorPort : GetFirstFreeControllerPort();
_playerName = message->GetPlayerName();
string playerPortMessage = _controllerPort == GameConnection::SpectatorPort ? "Spectator" : "Player " + std::to_string(_controllerPort + 1);
string playerPortMessage = _controllerPort == GameConnection::SpectatorPort ? "Spectator" : "Player " + std::to_string(_controllerPort + 1);
MessageManager::DisplayMessage("NetPlay", _connectionData->PlayerName + " (" + playerPortMessage + ") connected.");
MessageManager::DisplayMessage("NetPlay", _playerName + " (" + playerPortMessage + ") connected.");
if(Console::GetMapperInfo().RomName.size() > 0) {
SendGameInformation();
if(Console::GetMapperInfo().RomName.size() > 0) {
SendGameInformation();
}
_handshakeCompleted = true;
RegisterNetPlayDevice(this, _controllerPort);
GameServer::SendPlayerList();
Console::Resume();
} else {
SendForceDisconnectMessage("The password you provided did not match - you have been disconnected.");
}
_handshakeCompleted = true;
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("NetPlay", + "NetplayVersionMismatch", message->GetPlayerName());
@ -119,10 +144,16 @@ void GameServerConnection::ProcessMessage(NetMessage* message)
break;
case MessageType::InputData:
if(_handshakeCompleted) {
break;
}
PushState(((InputDataMessage*)message)->GetInputState());
break;
case MessageType::SelectController:
if(_handshakeCompleted) {
break;
}
SelectControllerPort(((SelectControllerMessage*)message)->GetPortNumber());
break;
@ -208,11 +239,7 @@ uint8_t GameServerConnection::GetFirstFreeControllerPort()
string GameServerConnection::GetPlayerName()
{
if(_connectionData) {
return _connectionData->PlayerName;
} else {
return "";
}
return _playerName;
}
uint8_t GameServerConnection::GetControllerPort()

View file

@ -15,10 +15,14 @@ private:
static GameServerConnection* _netPlayDevices[BaseControlDevice::PortCount];
list<ControlDeviceState> _inputData;
string _playerName;
int _controllerPort;
string _connectionHash;
string _serverPassword;
bool _handshakeCompleted = false;
void PushState(ControlDeviceState state);
void SendServerInformation();
void SendGameInformation();
void SelectControllerPort(uint8_t port);
@ -34,7 +38,7 @@ protected:
void ProcessMessage(NetMessage* message) override;
public:
GameServerConnection(shared_ptr<Socket> socket);
GameServerConnection(shared_ptr<Socket> socket, string serverPassword);
virtual ~GameServerConnection();
ControlDeviceState GetState();

View file

@ -2,33 +2,38 @@
#include "stdafx.h"
#include "NetMessage.h"
#include "EmulationSettings.h"
#include "../Utilities/sha1.h"
class HandShakeMessage : public NetMessage
{
private:
const static int CurrentVersion = 1;
const static int CurrentVersion = 2;
uint32_t _mesenVersion = 0;
uint32_t _protocolVersion = CurrentVersion;
char* _playerName = nullptr;
uint32_t _playerNameLength = 0;
char* _hashedPassword = nullptr;
uint32_t _hashedPasswordLength = 0;
bool _spectator = false;
protected:
virtual void ProtectedStreamState()
{
Stream<uint32_t>(_mesenVersion);
Stream<uint32_t>(_protocolVersion);
StreamArray((void**)&_playerName, _playerNameLength);
StreamArray((void**)&_hashedPassword, _hashedPasswordLength);
Stream<bool>(_spectator);
}
public:
HandShakeMessage(void* buffer, uint32_t length) : NetMessage(buffer, length) { }
HandShakeMessage(string playerName, bool spectator) : NetMessage(MessageType::HandShake)
HandShakeMessage(void* buffer, uint32_t length) : NetMessage(buffer, length) {}
HandShakeMessage(string playerName, string hashedPassword, bool spectator) : NetMessage(MessageType::HandShake)
{
_mesenVersion = EmulationSettings::GetMesenVersion();
_protocolVersion = HandShakeMessage::CurrentVersion;
CopyString(&_playerName, _playerNameLength, playerName);
CopyString(&_hashedPassword, _hashedPasswordLength, hashedPassword);
_spectator = spectator;
}
@ -42,8 +47,20 @@ public:
return _protocolVersion == CurrentVersion && _mesenVersion == EmulationSettings::GetMesenVersion();
}
bool CheckPassword(string serverPassword, string connectionHash)
{
return GetPasswordHash(serverPassword, connectionHash) == string(_hashedPassword);
}
bool IsSpectator()
{
return _spectator;
}
static string GetPasswordHash(string serverPassword, string connectionHash)
{
string saltedPassword = serverPassword + connectionHash;
vector<uint8_t> dataToHash = vector<uint8_t>(saltedPassword.c_str(), saltedPassword.c_str() + saltedPassword.size());
return SHA1::GetHash(dataToHash);
}
};

View file

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

View file

@ -0,0 +1,28 @@
#pragma once
#include "stdafx.h"
#include "NetMessage.h"
class ServerInformationMessage : public NetMessage
{
private:
char* _hashSalt = nullptr;
uint32_t _hashSaltLength = 0;
protected:
virtual void ProtectedStreamState()
{
StreamArray((void**)&_hashSalt, _hashSaltLength);
}
public:
ServerInformationMessage(void* buffer, uint32_t length) : NetMessage(buffer, length) {}
ServerInformationMessage(string hashSalt) : NetMessage(MessageType::ServerInformation)
{
CopyString(&_hashSalt, _hashSaltLength, hashSalt);
}
string GetHashSalt()
{
return string(_hashSalt);
}
};

View file

@ -10,6 +10,7 @@ namespace Mesen.GUI.Config
{
public string Host = "localhost";
public UInt16 Port = 8888;
public string Password = "";
public bool Spectator = false;
}
}

View file

@ -10,9 +10,6 @@ namespace Mesen.GUI.Config
{
public string Name = "Default";
public UInt16 Port = 8888;
public string Password = null;
public int MaxPlayers = 4;
public bool AllowSpectators = true;
public bool PublicServer = false;
public string Password = "";
}
}

View file

@ -159,9 +159,9 @@ namespace Mesen.GUI.Controls
set { _minimum = value; SetValue(this.Value, true); }
}
public decimal Increment { get; set; }
public decimal Increment { get; set; } = 1;
private int _decimalPlaces = 2;
private int _decimalPlaces = 0;
public int DecimalPlaces
{
get { return _decimalPlaces; }

View file

@ -440,6 +440,7 @@
<Form ID="frmClientConfig" Title="Connexió a un servidor">
<Control ID="lblHost">Servidor:</Control>
<Control ID="lblPort">Port:</Control>
<Control ID="lblPassword">Contrasenya:</Control>
<Control ID="chkSpectator">Uneix-t'hi com a espectador</Control>
<Control ID="btnOK">D'acord</Control>
<Control ID="btnCancel">Cancel·la</Control>

View file

@ -441,6 +441,7 @@
<Form ID="frmClientConfig" Title="Connect...">
<Control ID="lblHost">Host:</Control>
<Control ID="lblPort">Port:</Control>
<Control ID="lblPassword">Password:</Control>
<Control ID="chkSpectator">Join as spectator</Control>
<Control ID="btnOK">OK</Control>
<Control ID="btnCancel">Cancel</Control>

View file

@ -438,6 +438,7 @@
<Form ID="frmClientConfig" Title="Conexión a un servidor">
<Control ID="lblHost">Servidor host:</Control>
<Control ID="lblPort">Puerto:</Control>
<Control ID="lblPassword">Contraseña:</Control>
<Control ID="chkSpectator">Unirse como espectador</Control>
<Control ID="btnOK">OK</Control>
<Control ID="btnCancel">Cancelar</Control>

View file

@ -440,6 +440,7 @@
<Form ID="frmClientConfig" Title="Connexion à un serveur">
<Control ID="lblHost">Serveur hôte:</Control>
<Control ID="lblPort">Port:</Control>
<Control ID="lblPassword">Mot de passe:</Control>
<Control ID="chkSpectator">Se joindre en tant que spectateur</Control>
<Control ID="btnOK">OK</Control>
<Control ID="btnCancel">Annuler</Control>

View file

@ -439,6 +439,7 @@
<Form ID="frmClientConfig" Title="サーバに接続">
<Control ID="lblHost">ホスト:</Control>
<Control ID="lblPort">ポート:</Control>
<Control ID="lblPassword">パスワード:</Control>
<Control ID="chkSpectator">観客として接続する</Control>
<Control ID="btnOK">OK</Control>
<Control ID="btnCancel">キャンセル</Control>

View file

@ -436,6 +436,7 @@
<Form ID="frmClientConfig" Title="Conexão a um servidor">
<Control ID="lblHost">Servidor host:</Control>
<Control ID="lblPort">Port:</Control>
<Control ID="lblPassword">Senha:</Control>
<Control ID="chkSpectator">Entrar como espectador</Control>
<Control ID="btnOK">OK</Control>
<Control ID="btnCancel">Cancelar</Control>

View file

@ -437,6 +437,7 @@
<Form ID="frmClientConfig" Title="Подключение к серверу">
<Control ID="lblHost">Имя сервера:</Control>
<Control ID="lblPort">Порт:</Control>
<Control ID="lblPassword">Пароль:</Control>
<Control ID="chkSpectator">Войти как наблюдатель</Control>
<Control ID="btnOK">OK</Control>
<Control ID="btnCancel">Отмена</Control>

View file

@ -437,6 +437,7 @@
<Form ID="frmClientConfig" Title="Підключення до сервера">
<Control ID="lblHost">Iм'я сервера:</Control>
<Control ID="lblPort">Порт:</Control>
<Control ID="lblPassword">Пароль:</Control>
<Control ID="chkSpectator">Ввійти як спостерігач</Control>
<Control ID="btnOK">OK</Control>
<Control ID="btnCancel">Вiдмiна</Control>

View file

@ -33,12 +33,14 @@
this.lblPort = new System.Windows.Forms.Label();
this.txtHost = new System.Windows.Forms.TextBox();
this.chkSpectator = new System.Windows.Forms.CheckBox();
this.lblPassword = new System.Windows.Forms.Label();
this.txtPassword = new System.Windows.Forms.TextBox();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Location = new System.Drawing.Point(0, 111);
this.baseConfigPanel.Location = new System.Drawing.Point(0, 110);
this.baseConfigPanel.Size = new System.Drawing.Size(290, 29);
//
// tableLayoutPanel1
@ -46,28 +48,31 @@
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.txtPassword, 1, 2);
this.tableLayoutPanel1.Controls.Add(this.txtPort, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.lblHost, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.lblPort, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.txtHost, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.chkSpectator, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.chkSpectator, 0, 3);
this.tableLayoutPanel1.Controls.Add(this.lblPassword, 0, 2);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 4;
this.tableLayoutPanel1.RowCount = 5;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(290, 111);
this.tableLayoutPanel1.Size = new System.Drawing.Size(290, 110);
this.tableLayoutPanel1.TabIndex = 0;
//
// txtPort
//
this.txtPort.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtPort.Location = new System.Drawing.Point(41, 29);
this.txtPort.Location = new System.Drawing.Point(65, 29);
this.txtPort.Name = "txtPort";
this.txtPort.Size = new System.Drawing.Size(246, 20);
this.txtPort.Size = new System.Drawing.Size(222, 20);
this.txtPort.TabIndex = 6;
this.txtPort.TextChanged += new System.EventHandler(this.Field_TextChanged);
//
@ -94,9 +99,9 @@
// txtHost
//
this.txtHost.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtHost.Location = new System.Drawing.Point(41, 3);
this.txtHost.Location = new System.Drawing.Point(65, 3);
this.txtHost.Name = "txtHost";
this.txtHost.Size = new System.Drawing.Size(246, 20);
this.txtHost.Size = new System.Drawing.Size(222, 20);
this.txtHost.TabIndex = 5;
this.txtHost.TextChanged += new System.EventHandler(this.Field_TextChanged);
//
@ -104,18 +109,36 @@
//
this.chkSpectator.AutoSize = true;
this.tableLayoutPanel1.SetColumnSpan(this.chkSpectator, 2);
this.chkSpectator.Location = new System.Drawing.Point(3, 55);
this.chkSpectator.Location = new System.Drawing.Point(3, 81);
this.chkSpectator.Name = "chkSpectator";
this.chkSpectator.Size = new System.Drawing.Size(106, 17);
this.chkSpectator.TabIndex = 7;
this.chkSpectator.Text = "Join as spectator";
this.chkSpectator.UseVisualStyleBackColor = true;
//
// lblPassword
//
this.lblPassword.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblPassword.AutoSize = true;
this.lblPassword.Location = new System.Drawing.Point(3, 58);
this.lblPassword.Name = "lblPassword";
this.lblPassword.Size = new System.Drawing.Size(56, 13);
this.lblPassword.TabIndex = 8;
this.lblPassword.Text = "Password:";
//
// txtPassword
//
this.txtPassword.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtPassword.Location = new System.Drawing.Point(65, 55);
this.txtPassword.Name = "txtPassword";
this.txtPassword.Size = new System.Drawing.Size(222, 20);
this.txtPassword.TabIndex = 9;
//
// frmClientConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(290, 140);
this.ClientSize = new System.Drawing.Size(290, 139);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
@ -141,5 +164,7 @@
private System.Windows.Forms.Label lblPort;
private System.Windows.Forms.TextBox txtHost;
private System.Windows.Forms.CheckBox chkSpectator;
private System.Windows.Forms.TextBox txtPassword;
private System.Windows.Forms.Label lblPassword;
}
}

View file

@ -21,6 +21,7 @@ namespace Mesen.GUI.Forms.NetPlay
Entity = ConfigManager.Config.ClientConnectionInfo;
AddBinding("Host", this.txtHost);
AddBinding("Password", this.txtPassword);
AddBinding("Spectator", chkSpectator);
this.txtPort.Text = ConfigManager.Config.ClientConnectionInfo.Port.ToString();
}

View file

@ -32,20 +32,16 @@ namespace Mesen.GUI.Forms.NetPlay
this.tlpMain = new System.Windows.Forms.TableLayoutPanel();
this.txtPort = new System.Windows.Forms.TextBox();
this.lblPort = new System.Windows.Forms.Label();
this.chkPublicServer = new System.Windows.Forms.CheckBox();
this.lblServerName = new System.Windows.Forms.Label();
this.txtServerName = new System.Windows.Forms.TextBox();
this.chkSpectator = new System.Windows.Forms.CheckBox();
this.lblMaxPlayers = new System.Windows.Forms.Label();
this.lblPassword = new System.Windows.Forms.Label();
this.txtPassword = new System.Windows.Forms.TextBox();
this.nudNbPlayers = new MesenNumericUpDown();
this.tlpMain.SuspendLayout();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Location = new System.Drawing.Point(0, 161);
this.baseConfigPanel.Location = new System.Drawing.Point(0, 98);
this.baseConfigPanel.Size = new System.Drawing.Size(302, 29);
//
// tlpMain
@ -55,34 +51,28 @@ namespace Mesen.GUI.Forms.NetPlay
this.tlpMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpMain.Controls.Add(this.txtPort, 1, 1);
this.tlpMain.Controls.Add(this.lblPort, 0, 1);
this.tlpMain.Controls.Add(this.chkPublicServer, 0, 4);
this.tlpMain.Controls.Add(this.lblServerName, 0, 0);
this.tlpMain.Controls.Add(this.txtServerName, 1, 0);
this.tlpMain.Controls.Add(this.chkSpectator, 0, 5);
this.tlpMain.Controls.Add(this.lblMaxPlayers, 0, 3);
this.tlpMain.Controls.Add(this.lblPassword, 0, 2);
this.tlpMain.Controls.Add(this.txtPassword, 1, 2);
this.tlpMain.Controls.Add(this.nudNbPlayers, 1, 3);
this.tlpMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.tlpMain.Location = new System.Drawing.Point(0, 0);
this.tlpMain.Name = "tlpMain";
this.tlpMain.RowCount = 7;
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.RowCount = 4;
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.Size = new System.Drawing.Size(302, 161);
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tlpMain.Size = new System.Drawing.Size(302, 98);
this.tlpMain.TabIndex = 1;
//
// txtPort
//
this.txtPort.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtPort.Location = new System.Drawing.Point(128, 29);
this.txtPort.Location = new System.Drawing.Point(79, 29);
this.txtPort.Name = "txtPort";
this.txtPort.Size = new System.Drawing.Size(171, 20);
this.txtPort.Size = new System.Drawing.Size(220, 20);
this.txtPort.TabIndex = 13;
this.txtPort.TextChanged += new System.EventHandler(this.Field_ValueChanged);
//
@ -96,19 +86,6 @@ namespace Mesen.GUI.Forms.NetPlay
this.lblPort.TabIndex = 12;
this.lblPort.Text = "Port:";
//
// chkPublicServer
//
this.chkPublicServer.AutoSize = true;
this.tlpMain.SetColumnSpan(this.chkPublicServer, 2);
this.chkPublicServer.Enabled = false;
this.chkPublicServer.Location = new System.Drawing.Point(3, 107);
this.chkPublicServer.Name = "chkPublicServer";
this.chkPublicServer.Size = new System.Drawing.Size(87, 17);
this.chkPublicServer.TabIndex = 11;
this.chkPublicServer.Text = "Public server";
this.chkPublicServer.UseVisualStyleBackColor = true;
this.chkPublicServer.CheckedChanged += new System.EventHandler(this.Field_ValueChanged);
//
// lblServerName
//
this.lblServerName.Anchor = System.Windows.Forms.AnchorStyles.Left;
@ -122,35 +99,12 @@ namespace Mesen.GUI.Forms.NetPlay
// txtServerName
//
this.txtServerName.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtServerName.Location = new System.Drawing.Point(128, 3);
this.txtServerName.Location = new System.Drawing.Point(79, 3);
this.txtServerName.Name = "txtServerName";
this.txtServerName.Size = new System.Drawing.Size(171, 20);
this.txtServerName.Size = new System.Drawing.Size(220, 20);
this.txtServerName.TabIndex = 5;
this.txtServerName.TextChanged += new System.EventHandler(this.Field_ValueChanged);
//
// chkSpectator
//
this.chkSpectator.AutoSize = true;
this.tlpMain.SetColumnSpan(this.chkSpectator, 2);
this.chkSpectator.Enabled = false;
this.chkSpectator.Location = new System.Drawing.Point(3, 130);
this.chkSpectator.Name = "chkSpectator";
this.chkSpectator.Size = new System.Drawing.Size(103, 17);
this.chkSpectator.TabIndex = 7;
this.chkSpectator.Text = "Allow spectators";
this.chkSpectator.UseVisualStyleBackColor = true;
this.chkSpectator.CheckedChanged += new System.EventHandler(this.Field_ValueChanged);
//
// lblMaxPlayers
//
this.lblMaxPlayers.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblMaxPlayers.AutoSize = true;
this.lblMaxPlayers.Location = new System.Drawing.Point(3, 84);
this.lblMaxPlayers.Name = "lblMaxPlayers";
this.lblMaxPlayers.Size = new System.Drawing.Size(119, 13);
this.lblMaxPlayers.TabIndex = 4;
this.lblMaxPlayers.Text = "Max. number of players:";
//
// lblPassword
//
this.lblPassword.Anchor = System.Windows.Forms.AnchorStyles.Left;
@ -164,43 +118,18 @@ namespace Mesen.GUI.Forms.NetPlay
// txtPassword
//
this.txtPassword.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtPassword.Enabled = false;
this.txtPassword.Location = new System.Drawing.Point(128, 55);
this.txtPassword.Location = new System.Drawing.Point(79, 55);
this.txtPassword.Name = "txtPassword";
this.txtPassword.Size = new System.Drawing.Size(171, 20);
this.txtPassword.Size = new System.Drawing.Size(220, 20);
this.txtPassword.TabIndex = 10;
this.txtPassword.UseSystemPasswordChar = true;
this.txtPassword.TextChanged += new System.EventHandler(this.Field_ValueChanged);
//
// nudNbPlayers
//
this.nudNbPlayers.Enabled = false;
this.nudNbPlayers.Location = new System.Drawing.Point(128, 81);
this.nudNbPlayers.Maximum = new decimal(new int[] {
4,
0,
0,
0});
this.nudNbPlayers.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudNbPlayers.Name = "nudNbPlayers";
this.nudNbPlayers.Size = new System.Drawing.Size(35, 20);
this.nudNbPlayers.TabIndex = 8;
this.nudNbPlayers.Value = new decimal(new int[] {
4,
0,
0,
0});
this.nudNbPlayers.ValueChanged += new System.EventHandler(this.Field_ValueChanged);
//
// frmServerConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(302, 190);
this.ClientSize = new System.Drawing.Size(302, 127);
this.Controls.Add(this.tlpMain);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
@ -220,11 +149,7 @@ namespace Mesen.GUI.Forms.NetPlay
private System.Windows.Forms.TableLayoutPanel tlpMain;
private System.Windows.Forms.Label lblServerName;
private System.Windows.Forms.Label lblMaxPlayers;
private System.Windows.Forms.TextBox txtServerName;
private System.Windows.Forms.CheckBox chkSpectator;
private MesenNumericUpDown nudNbPlayers;
private System.Windows.Forms.CheckBox chkPublicServer;
private System.Windows.Forms.Label lblPassword;
private System.Windows.Forms.TextBox txtPassword;
private System.Windows.Forms.Label lblPort;

View file

@ -20,9 +20,6 @@ namespace Mesen.GUI.Forms.NetPlay
this.txtServerName.Text = ConfigManager.Config.ServerInfo.Name;
this.txtPort.Text = ConfigManager.Config.ServerInfo.Port.ToString();
this.txtPassword.Text = string.Empty;
this.nudNbPlayers.Value = ConfigManager.Config.ServerInfo.MaxPlayers;
this.chkSpectator.Checked = ConfigManager.Config.ServerInfo.AllowSpectators;
this.chkPublicServer.Checked = ConfigManager.Config.ServerInfo.PublicServer;
}
protected override void UpdateConfig()
@ -30,10 +27,7 @@ namespace Mesen.GUI.Forms.NetPlay
ConfigManager.Config.ServerInfo = new ServerInfo() {
Name = this.txtServerName.Text,
Port = Convert.ToUInt16(this.txtPort.Text),
Password = BitConverter.ToString(System.Security.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(this.txtPassword.Text))).Replace("-", ""),
MaxPlayers = (int)this.nudNbPlayers.Value,
AllowSpectators = this.chkSpectator.Checked,
PublicServer = this.chkPublicServer.Checked
Password = this.txtPassword.Text
};
}

View file

@ -150,7 +150,7 @@ namespace Mesen.GUI.Forms
} else {
using(frmServerConfig frm = new frmServerConfig()) {
if(frm.ShowDialog(sender, this) == System.Windows.Forms.DialogResult.OK) {
InteropEmu.StartServer(ConfigManager.Config.ServerInfo.Port, ConfigManager.Config.Profile.PlayerName);
InteropEmu.StartServer(ConfigManager.Config.ServerInfo.Port, ConfigManager.Config.ServerInfo.Password, ConfigManager.Config.Profile.PlayerName);
}
}
}
@ -164,7 +164,13 @@ namespace Mesen.GUI.Forms
using(frmClientConfig frm = new frmClientConfig()) {
if(frm.ShowDialog(sender, this) == System.Windows.Forms.DialogResult.OK) {
Task.Run(() => {
InteropEmu.Connect(ConfigManager.Config.ClientConnectionInfo.Host, ConfigManager.Config.ClientConnectionInfo.Port, ConfigManager.Config.Profile.PlayerName, ConfigManager.Config.ClientConnectionInfo.Spectator);
InteropEmu.Connect(
ConfigManager.Config.ClientConnectionInfo.Host,
ConfigManager.Config.ClientConnectionInfo.Port,
ConfigManager.Config.ClientConnectionInfo.Password,
ConfigManager.Config.Profile.PlayerName,
ConfigManager.Config.ClientConnectionInfo.Spectator
);
});
}
}

View file

@ -78,10 +78,10 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void Reset();
[DllImport(DLLPath)] public static extern void ResetLagCounter();
[DllImport(DLLPath)] public static extern void StartServer(UInt16 port, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string hostPlayerName);
[DllImport(DLLPath)] public static extern void StartServer(UInt16 port, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string password, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string hostPlayerName);
[DllImport(DLLPath)] public static extern void StopServer();
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsServerRunning();
[DllImport(DLLPath)] public static extern void Connect([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string host, UInt16 port, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string playerName, [MarshalAs(UnmanagedType.I1)]bool spectator);
[DllImport(DLLPath)] public static extern void Connect([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string host, UInt16 port, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string password, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string playerName, [MarshalAs(UnmanagedType.I1)]bool spectator);
[DllImport(DLLPath)] public static extern void Disconnect();
[DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsConnected();

View file

@ -262,19 +262,13 @@ namespace InteropEmu {
DllExport void __stdcall PowerCycle() { Console::Reset(false); }
DllExport void __stdcall ResetLagCounter() { Console::ResetLagCounter(); }
DllExport void __stdcall StartServer(uint16_t port, char* hostPlayerName) { GameServer::StartServer(port, hostPlayerName); }
DllExport void __stdcall StartServer(uint16_t port, char* password, char* hostPlayerName) { GameServer::StartServer(port, password, hostPlayerName); }
DllExport void __stdcall StopServer() { GameServer::StopServer(); }
DllExport bool __stdcall IsServerRunning() { return GameServer::Started(); }
DllExport void __stdcall Connect(char* host, uint16_t port, char* playerName, bool spectator)
DllExport void __stdcall Connect(char* host, uint16_t port, char* password, char* playerName, bool spectator)
{
shared_ptr<ClientConnectionData> connectionData(new ClientConnectionData(
host,
port,
playerName,
spectator
));
ClientConnectionData connectionData(host, port, password, playerName, spectator);
GameClient::Connect(connectionData);
}