2014-07-09 19:05:07 -04:00
# include "stdafx.h"
2015-07-01 23:17:14 -04:00
# include "MessageManager.h"
2014-07-09 19:05:07 -04:00
# include "GameServerConnection.h"
# include "HandShakeMessage.h"
# include "InputDataMessage.h"
# include "MovieDataMessage.h"
# include "GameInformationMessage.h"
# include "SaveStateMessage.h"
# include "Console.h"
# include "ControlManager.h"
2015-07-01 23:17:14 -04:00
# include "ClientConnectionData.h"
2015-07-17 20:58:57 -04:00
# include "EmulationSettings.h"
2016-02-05 23:14:27 -05:00
# include "StandardController.h"
2016-02-06 15:33:45 -05:00
# include "SelectControllerMessage.h"
# include "PlayerListMessage.h"
# include "GameServer.h"
2016-02-10 23:07:42 -05:00
# include "ForceDisconnectMessage.h"
2017-11-19 23:08:23 -05:00
# include "BaseControlDevice.h"
2014-07-09 19:05:07 -04:00
2017-11-19 23:08:23 -05:00
GameServerConnection * GameServerConnection : : _netPlayDevices [ BaseControlDevice : : PortCount ] = { } ;
2016-02-05 23:14:27 -05:00
2016-02-06 15:33:45 -05:00
GameServerConnection : : GameServerConnection ( shared_ptr < Socket > socket ) : GameConnection ( socket , nullptr )
2014-07-09 19:05:07 -04:00
{
//Server-side connection
2016-02-06 15:33:45 -05:00
_controllerPort = GameConnection : : SpectatorPort ;
2015-07-01 23:17:14 -04:00
MessageManager : : RegisterNotificationListener ( this ) ;
2014-07-09 19:05:07 -04:00
}
GameServerConnection : : ~ GameServerConnection ( )
{
2015-07-01 23:17:14 -04:00
if ( _connectionData ) {
2016-09-03 10:44:01 -04:00
MessageManager : : DisplayMessage ( " NetPlay " , _connectionData - > PlayerName + " (Player " + std : : to_string ( _controllerPort + 1 ) + " ) disconnected. " ) ;
2015-07-01 23:17:14 -04:00
}
2014-07-09 19:05:07 -04:00
2016-02-05 23:14:27 -05:00
UnregisterNetPlayDevice ( this ) ;
2015-07-01 23:17:14 -04:00
MessageManager : : UnregisterNotificationListener ( this ) ;
2014-07-09 19:05:07 -04:00
}
void GameServerConnection : : SendGameInformation ( )
{
2016-01-23 00:52:06 -05:00
Console : : Pause ( ) ;
2017-07-30 09:03:54 -04:00
GameInformationMessage gameInfo ( Console : : GetRomName ( ) , Console : : GetHashInfo ( ) . Crc32Hash , _controllerPort , EmulationSettings : : CheckFlag ( EmulationFlags : : Paused ) ) ;
2016-01-23 00:52:06 -05:00
SendNetMessage ( gameInfo ) ;
SaveStateMessage saveState ;
SendNetMessage ( saveState ) ;
Console : : Resume ( ) ;
2014-07-09 19:05:07 -04:00
}
2017-11-19 23:08:23 -05:00
void GameServerConnection : : SendMovieData ( uint8_t port , ControlDeviceState state )
2014-07-09 19:05:07 -04:00
{
if ( _handshakeCompleted ) {
2015-08-28 21:01:18 -04:00
MovieDataMessage message ( state , port ) ;
SendNetMessage ( message ) ;
2014-07-09 19:05:07 -04:00
}
}
2016-02-10 23:07:42 -05:00
void GameServerConnection : : SendForceDisconnectMessage ( string disconnectMessage )
{
ForceDisconnectMessage message ( disconnectMessage ) ;
SendNetMessage ( message ) ;
Disconnect ( ) ;
}
2017-11-19 23:08:23 -05:00
void GameServerConnection : : PushState ( ControlDeviceState state )
2016-02-05 23:14:27 -05:00
{
if ( _inputData . size ( ) = = 0 | | state ! = _inputData . back ( ) ) {
2017-11-19 23:08:23 -05:00
_inputData . clear ( ) ;
2016-02-05 23:14:27 -05:00
_inputData . push_back ( state ) ;
}
}
2017-11-19 23:08:23 -05:00
ControlDeviceState GameServerConnection : : GetState ( )
2014-07-09 19:05:07 -04:00
{
2015-07-06 21:31:32 -04:00
size_t inputBufferSize = _inputData . size ( ) ;
2017-11-19 23:08:23 -05:00
ControlDeviceState stateData ;
2014-07-09 19:05:07 -04:00
if ( inputBufferSize > 0 ) {
stateData = _inputData . front ( ) ;
if ( inputBufferSize > 1 ) {
//Always keep the last one the client sent, it will be used until a new one is received
_inputData . pop_front ( ) ;
}
}
2016-02-05 23:14:27 -05:00
return stateData ;
2014-07-09 19:05:07 -04:00
}
2014-07-09 21:48:54 -04:00
2016-02-06 15:33:45 -05:00
void GameServerConnection : : ProcessHandshakeResponse ( HandShakeMessage * message )
{
//Send the game's current state to the client and register the controller
if ( message - > IsValid ( ) ) {
Console : : Pause ( ) ;
_controllerPort = message - > IsSpectator ( ) ? GameConnection : : SpectatorPort : GetFirstFreeControllerPort ( ) ;
2016-09-03 10:44:01 -04:00
_connectionData . reset ( new ClientConnectionData ( " " , 0 , message - > GetPlayerName ( ) , false ) ) ;
2016-02-06 15:33:45 -05:00
string playerPortMessage = _controllerPort = = GameConnection : : SpectatorPort ? " Spectator " : " Player " + std : : to_string ( _controllerPort + 1 ) ;
2016-09-03 10:44:01 -04:00
MessageManager : : DisplayMessage ( " NetPlay " , _connectionData - > PlayerName + " ( " + playerPortMessage + " ) connected. " ) ;
2016-02-06 15:33:45 -05:00
2016-06-17 20:53:05 -04:00
if ( Console : : GetRomName ( ) . size ( ) > 0 ) {
2016-02-06 15:33:45 -05:00
SendGameInformation ( ) ;
}
_handshakeCompleted = true ;
RegisterNetPlayDevice ( this , _controllerPort ) ;
GameServer : : SendPlayerList ( ) ;
Console : : Resume ( ) ;
2016-02-10 23:07:42 -05:00
} else {
SendForceDisconnectMessage ( " Server is using a different version of Mesen ( " + EmulationSettings : : GetMesenVersionString ( ) + " ) - you have been disconnected. " ) ;
2016-02-19 13:05:04 -05:00
MessageManager : : DisplayMessage ( " NetPlay " , + " NetplayVersionMismatch " , message - > GetPlayerName ( ) ) ;
2016-02-06 15:33:45 -05:00
}
}
2015-07-01 23:17:14 -04:00
void GameServerConnection : : ProcessMessage ( NetMessage * message )
{
switch ( message - > GetType ( ) ) {
case MessageType : : HandShake :
2016-02-06 15:33:45 -05:00
ProcessHandshakeResponse ( ( HandShakeMessage * ) message ) ;
2015-07-01 23:17:14 -04:00
break ;
2016-02-06 15:33:45 -05:00
2015-07-01 23:17:14 -04:00
case MessageType : : InputData :
2016-02-05 23:14:27 -05:00
PushState ( ( ( InputDataMessage * ) message ) - > GetInputState ( ) ) ;
2015-07-01 23:17:14 -04:00
break ;
2016-02-06 15:33:45 -05:00
case MessageType : : SelectController :
SelectControllerPort ( ( ( SelectControllerMessage * ) message ) - > GetPortNumber ( ) ) ;
break ;
2015-08-28 21:01:18 -04:00
default :
break ;
2015-07-01 23:17:14 -04:00
}
}
2016-02-06 15:33:45 -05:00
void GameServerConnection : : SelectControllerPort ( uint8_t port )
{
Console : : Pause ( ) ;
if ( port = = GameConnection : : SpectatorPort ) {
//Client wants to be a spectator, make sure we are not using any controller
UnregisterNetPlayDevice ( this ) ;
_controllerPort = port ;
} else {
GameServerConnection * netPlayDevice = GetNetPlayDevice ( port ) ;
if ( netPlayDevice = = this ) {
//Nothing to do, we're already this player
} else if ( netPlayDevice = = nullptr ) {
//This port is free, we can switch
UnregisterNetPlayDevice ( this ) ;
RegisterNetPlayDevice ( this , port ) ;
_controllerPort = port ;
} else {
//Another player is using this port, we can't use it
}
}
SendGameInformation ( ) ;
GameServer : : SendPlayerList ( ) ;
Console : : Resume ( ) ;
}
2015-12-26 17:11:00 -05:00
void GameServerConnection : : ProcessNotification ( ConsoleNotificationType type , void * parameter )
2014-07-09 21:48:54 -04:00
{
switch ( type ) {
case ConsoleNotificationType : : GamePaused :
2015-07-01 23:17:14 -04:00
case ConsoleNotificationType : : GameLoaded :
2014-07-09 21:48:54 -04:00
case ConsoleNotificationType : : GameResumed :
2015-07-01 23:17:14 -04:00
case ConsoleNotificationType : : GameReset :
2016-01-21 17:57:18 -05:00
case ConsoleNotificationType : : StateLoaded :
2016-01-23 00:52:06 -05:00
case ConsoleNotificationType : : CheatAdded :
2016-02-05 23:14:27 -05:00
case ConsoleNotificationType : : ConfigChanged :
2014-07-09 21:48:54 -04:00
SendGameInformation ( ) ;
break ;
2015-08-28 21:01:18 -04:00
default :
break ;
2014-07-09 21:48:54 -04:00
}
2016-02-05 23:14:27 -05:00
}
void GameServerConnection : : RegisterNetPlayDevice ( GameServerConnection * device , uint8_t port )
{
GameServerConnection : : _netPlayDevices [ port ] = device ;
}
void GameServerConnection : : UnregisterNetPlayDevice ( GameServerConnection * device )
{
if ( device ! = nullptr ) {
2017-11-19 23:08:23 -05:00
for ( int i = 0 ; i < BaseControlDevice : : PortCount ; i + + ) {
2016-02-05 23:14:27 -05:00
if ( GameServerConnection : : _netPlayDevices [ i ] = = device ) {
GameServerConnection : : _netPlayDevices [ i ] = nullptr ;
break ;
}
}
}
}
GameServerConnection * GameServerConnection : : GetNetPlayDevice ( uint8_t port )
{
return GameServerConnection : : _netPlayDevices [ port ] ;
2016-02-06 15:33:45 -05:00
}
uint8_t GameServerConnection : : GetFirstFreeControllerPort ( )
{
uint8_t hostPost = GameServer : : GetHostControllerPort ( ) ;
2017-11-19 23:08:23 -05:00
for ( int i = 0 ; i < BaseControlDevice : : PortCount ; i + + ) {
2016-02-06 15:33:45 -05:00
if ( hostPost ! = i & & GameServerConnection : : _netPlayDevices [ i ] = = nullptr ) {
return i ;
}
}
return GameConnection : : SpectatorPort ;
}
string GameServerConnection : : GetPlayerName ( )
{
if ( _connectionData ) {
return _connectionData - > PlayerName ;
} else {
return " " ;
}
}
uint8_t GameServerConnection : : GetControllerPort ( )
{
return _controllerPort ;
2014-07-09 21:48:54 -04:00
}