Added app version check between netplay host and clients to ensure interface compatibility.
This commit is contained in:
parent
cc234ae04b
commit
cc61b7b5ab
|
@ -443,6 +443,9 @@ void NetPlayServer::onRomLoad()
|
|||
//printf("New ROM Loaded!\n");
|
||||
FCEU_WRAPPER_LOCK();
|
||||
|
||||
opsCrc32 = 0;
|
||||
netPlayFrameData.reset();
|
||||
|
||||
inputClear();
|
||||
inputFrameCount = static_cast<uint32_t>(currFrameCounter);
|
||||
|
||||
|
@ -460,13 +463,16 @@ void NetPlayServer::onStateLoad()
|
|||
//printf("New State Loaded!\n");
|
||||
FCEU_WRAPPER_LOCK();
|
||||
|
||||
opsCrc32 = 0;
|
||||
netPlayFrameData.reset();
|
||||
|
||||
inputClear();
|
||||
inputFrameCount = static_cast<uint32_t>(currFrameCounter);
|
||||
|
||||
// New State has been loaded by server, signal clients to load and sync
|
||||
for (auto& client : clientList )
|
||||
{
|
||||
//sendRomLoadReq( client );
|
||||
sendRomLoadReq( client );
|
||||
sendStateSyncReq( client );
|
||||
}
|
||||
FCEU_WRAPPER_UNLOCK();
|
||||
|
@ -477,12 +483,16 @@ void NetPlayServer::onNesReset()
|
|||
//printf("NES Reset Event!\n");
|
||||
FCEU_WRAPPER_LOCK();
|
||||
|
||||
opsCrc32 = 0;
|
||||
netPlayFrameData.reset();
|
||||
|
||||
inputClear();
|
||||
inputFrameCount = static_cast<uint32_t>(currFrameCounter);
|
||||
|
||||
// NES Reset has occurred on server, signal clients sync
|
||||
for (auto& client : clientList )
|
||||
{
|
||||
sendRomLoadReq( client );
|
||||
sendStateSyncReq( client );
|
||||
}
|
||||
FCEU_WRAPPER_UNLOCK();
|
||||
|
@ -530,7 +540,27 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
|
|||
msg->toHostByteOrder();
|
||||
printf("Authorize: Player: %i Passwd: %s\n", msg->playerId, msg->pswd);
|
||||
|
||||
if (sessionPasswd.isEmpty())
|
||||
bool version_chk_ok = true;
|
||||
|
||||
if (enforceAppVersionCheck)
|
||||
{
|
||||
version_chk_ok = (msg->appVersionMajor == FCEU_VERSION_MAJOR) &&
|
||||
(msg->appVersionMinor == FCEU_VERSION_MINOR) &&
|
||||
(msg->appVersionPatch == FCEU_VERSION_PATCH);
|
||||
}
|
||||
|
||||
if (!version_chk_ok)
|
||||
{
|
||||
netPlayTextMsg<128> errorMsg(NETPLAY_ERROR_MSG);
|
||||
errorMsg.setFlag(netPlayTextMsgFlags::DISCONNECT);
|
||||
errorMsg.setFlag(netPlayTextMsgFlags::ERROR);
|
||||
errorMsg.printf("Client/Host Version Mismatch:\nHost version is %i.%i.%i\nClient version is %i.%i.%i",
|
||||
FCEU_VERSION_MAJOR, FCEU_VERSION_MINOR, FCEU_VERSION_PATCH,
|
||||
msg->appVersionMajor, msg->appVersionMinor, msg->appVersionPatch);
|
||||
sendMsg( client, &errorMsg, errorMsg.hdr.msgSize, [&errorMsg]{ errorMsg.toNetworkByteOrder(); } );
|
||||
client->flushData();
|
||||
}
|
||||
else if (sessionPasswd.isEmpty())
|
||||
{
|
||||
authentication_passed = true;
|
||||
}
|
||||
|
@ -542,6 +572,7 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
|
|||
{
|
||||
netPlayTextMsg<128> errorMsg(NETPLAY_ERROR_MSG);
|
||||
errorMsg.setFlag(netPlayTextMsgFlags::DISCONNECT);
|
||||
errorMsg.setFlag(netPlayTextMsgFlags::ERROR);
|
||||
errorMsg.printf("Invalid Password");
|
||||
sendMsg( client, &errorMsg, errorMsg.hdr.msgSize, [&errorMsg]{ errorMsg.toNetworkByteOrder(); } );
|
||||
client->flushData();
|
||||
|
@ -564,6 +595,7 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
|
|||
{
|
||||
netPlayTextMsg<128> errorMsg(NETPLAY_ERROR_MSG);
|
||||
errorMsg.setFlag(netPlayTextMsgFlags::DISCONNECT);
|
||||
errorMsg.setFlag(netPlayTextMsgFlags::ERROR);
|
||||
errorMsg.printf("Player %i role is not available", msg->playerId+1);
|
||||
sendMsg( client, &errorMsg, errorMsg.hdr.msgSize, [&errorMsg]{ errorMsg.toNetworkByteOrder(); } );
|
||||
client->flushData();
|
||||
|
@ -693,6 +725,7 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
|
|||
else
|
||||
{
|
||||
netPlayTextMsg<128> errorMsg(NETPLAY_ERROR_MSG);
|
||||
errorMsg.setFlag(netPlayTextMsgFlags::WARNING);
|
||||
errorMsg.printf("Host is rejected ROMs load request");
|
||||
sendMsg( client, &errorMsg, errorMsg.hdr.msgSize, [&errorMsg]{ errorMsg.toNetworkByteOrder(); } );
|
||||
}
|
||||
|
@ -726,14 +759,10 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
|
|||
|
||||
FCEU_WRAPPER_LOCK();
|
||||
serverRequestedStateLoad = true;
|
||||
// Clients will be resync'd during this load call.
|
||||
FCEUSS_LoadFP( &em, SSLOADPARAM_NOBACKUP );
|
||||
serverRequestedStateLoad = false;
|
||||
FCEU_WRAPPER_UNLOCK();
|
||||
|
||||
opsCrc32 = 0;
|
||||
netPlayFrameData.reset();
|
||||
inputClear();
|
||||
resyncAllClients();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1347,11 +1376,28 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
|
|||
|
||||
switch (msgId)
|
||||
{
|
||||
case NETPLAY_INFO_MSG:
|
||||
{
|
||||
auto *msg = static_cast<netPlayTextMsg<256>*>(msgBuf);
|
||||
msg->toHostByteOrder();
|
||||
FCEU_printf("NetPlay Info: %s\n", msg->getBuffer());
|
||||
|
||||
if (msg->isFlagSet(netPlayTextMsgFlags::DISCONNECT))
|
||||
{
|
||||
sock->disconnectFromHost();
|
||||
}
|
||||
FCEU_DispMessage("NetPlay Errors... check message log",0);
|
||||
}
|
||||
break;
|
||||
case NETPLAY_ERROR_MSG:
|
||||
{
|
||||
auto *msg = static_cast<netPlayTextMsg<256>*>(msgBuf);
|
||||
msg->toHostByteOrder();
|
||||
FCEU_printf("NetPlay Error: 0x%X %s\n", msg->code, msg->getBuffer());
|
||||
FCEU_printf("NetPlay Error: %s\n", msg->getBuffer());
|
||||
|
||||
QString msgBoxTxt = tr("Host has replied with an error:\n\n");
|
||||
msgBoxTxt += tr(msg->getBuffer());
|
||||
QMessageBox::critical( consoleWindow, tr("NetPlay Error"), msgBoxTxt, QMessageBox::Ok );
|
||||
|
||||
if (msg->isFlagSet(netPlayTextMsgFlags::DISCONNECT))
|
||||
{
|
||||
|
@ -1547,21 +1593,28 @@ NetPlayHostDialog::NetPlayHostDialog(QWidget *parent)
|
|||
grid->addWidget( lbl, 0, 0, 1, 1 );
|
||||
grid->addWidget( frameLeadSpinBox, 0, 1, 1, 1 );
|
||||
|
||||
bool enforceAppVersionChk = false;
|
||||
enforceAppVersionChkCBox = new QCheckBox(tr("Enforce Client Versions Match"));
|
||||
grid->addWidget( enforceAppVersionChkCBox, 1, 0, 1, 2 );
|
||||
g_config->getOption("SDL.NetPlayHostEnforceAppVersionChk", &enforceAppVersionChk);
|
||||
enforceAppVersionChkCBox->setChecked(enforceAppVersionChk);
|
||||
|
||||
bool romLoadReqEna = false;
|
||||
allowClientRomReqCBox = new QCheckBox(tr("Allow Client ROM Load Requests"));
|
||||
grid->addWidget( allowClientRomReqCBox, 1, 0, 1, 2 );
|
||||
grid->addWidget( allowClientRomReqCBox, 2, 0, 1, 2 );
|
||||
g_config->getOption("SDL.NetPlayHostAllowClientRomLoadReq", &romLoadReqEna);
|
||||
allowClientRomReqCBox->setChecked(romLoadReqEna);
|
||||
|
||||
bool stateLoadReqEna = false;
|
||||
allowClientStateReqCBox = new QCheckBox(tr("Allow Client State Load Requests"));
|
||||
grid->addWidget( allowClientStateReqCBox, 2, 0, 1, 2 );
|
||||
grid->addWidget( allowClientStateReqCBox, 3, 0, 1, 2 );
|
||||
g_config->getOption("SDL.NetPlayHostAllowClientStateLoadReq", &stateLoadReqEna);
|
||||
allowClientStateReqCBox->setChecked(stateLoadReqEna);
|
||||
|
||||
connect(passwordRequiredCBox, SIGNAL(stateChanged(int)), this, SLOT(passwordRequiredChanged(int)));
|
||||
connect(allowClientRomReqCBox, SIGNAL(stateChanged(int)), this, SLOT(allowClientRomReqChanged(int)));
|
||||
connect(allowClientStateReqCBox, SIGNAL(stateChanged(int)), this, SLOT(allowClientStateReqChanged(int)));
|
||||
connect(enforceAppVersionChkCBox, SIGNAL(stateChanged(int)), this, SLOT(enforceAppVersionChkChanged(int)));
|
||||
|
||||
startButton = new QPushButton( tr("Start") );
|
||||
startButton->setIcon(style()->standardIcon(QStyle::SP_DialogApplyButton));
|
||||
|
@ -1609,11 +1662,19 @@ void NetPlayHostDialog::passwordRequiredChanged(int state)
|
|||
void NetPlayHostDialog::allowClientRomReqChanged(int state)
|
||||
{
|
||||
g_config->setOption("SDL.NetPlayHostAllowClientRomLoadReq", state != Qt::Unchecked);
|
||||
g_config->save();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void NetPlayHostDialog::allowClientStateReqChanged(int state)
|
||||
{
|
||||
g_config->setOption("SDL.NetPlayHostAllowClientStateLoadReq", state != Qt::Unchecked);
|
||||
g_config->save();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void NetPlayHostDialog::enforceAppVersionChkChanged(int state)
|
||||
{
|
||||
g_config->setOption("SDL.NetPlayHostEnforceAppVersionChk", state != Qt::Unchecked);
|
||||
g_config->save();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void NetPlayHostDialog::onStartClicked(void)
|
||||
|
@ -1632,6 +1693,7 @@ void NetPlayHostDialog::onStartClicked(void)
|
|||
server->setRole( playerRoleBox->currentData().toInt() );
|
||||
server->sessionName = sessionNameEntry->text();
|
||||
server->setMaxLeadFrames( frameLeadSpinBox->value() );
|
||||
server->setEnforceAppVersionCheck( enforceAppVersionChkCBox->isChecked() );
|
||||
server->setAllowClientRomLoadRequest( allowClientRomReqCBox->isChecked() );
|
||||
server->setAllowClientStateLoadRequest( allowClientStateReqCBox->isChecked() );
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@ class NetPlayServer : public QTcpServer
|
|||
|
||||
uint32_t getMaxLeadFrames(){ return maxLeadFrames; }
|
||||
void setMaxLeadFrames(uint32_t value){ maxLeadFrames = value; }
|
||||
void setEnforceAppVersionCheck(bool value){ enforceAppVersionCheck = value; }
|
||||
void setAllowClientRomLoadRequest(bool value){ allowClientRomLoadReq = value; }
|
||||
void setAllowClientStateLoadRequest(bool value){ allowClientStateLoadReq = value; }
|
||||
|
||||
|
@ -164,6 +165,7 @@ class NetPlayServer : public QTcpServer
|
|||
uint32_t maxLeadFrames = 10u;
|
||||
uint32_t clientWaitCounter = 0;
|
||||
uint32_t inputFrameCount = 0;
|
||||
bool enforceAppVersionCheck = true;
|
||||
bool allowClientRomLoadReq = false;
|
||||
bool allowClientStateLoadReq = false;
|
||||
|
||||
|
@ -334,6 +336,7 @@ protected:
|
|||
QLineEdit *passwordEntry;
|
||||
QCheckBox *passwordRequiredCBox;
|
||||
QSpinBox *frameLeadSpinBox;
|
||||
QCheckBox *enforceAppVersionChkCBox;
|
||||
QCheckBox *allowClientRomReqCBox;
|
||||
QCheckBox *allowClientStateReqCBox;
|
||||
|
||||
|
@ -345,6 +348,7 @@ public slots:
|
|||
void passwordRequiredChanged(int state);
|
||||
void allowClientRomReqChanged(int state);
|
||||
void allowClientStateReqChanged(int state);
|
||||
void enforceAppVersionChkChanged(int state);
|
||||
};
|
||||
|
||||
class NetPlayJoinDialog : public QDialog
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "version.h"
|
||||
|
||||
// Network Byte Swap Functions
|
||||
uint16_t netPlayByteSwap(uint16_t);
|
||||
|
@ -92,12 +93,17 @@ struct netPlayAuthResp
|
|||
{
|
||||
netPlayMsgHdr hdr;
|
||||
|
||||
uint16_t appVersionMajor;
|
||||
uint16_t appVersionMinor;
|
||||
uint32_t appVersionPatch;
|
||||
char playerId;
|
||||
char userName[64];
|
||||
char pswd[72];
|
||||
|
||||
netPlayAuthResp(void)
|
||||
: hdr(NETPLAY_AUTH_RESP, sizeof(netPlayAuthResp)), playerId(NETPLAY_SPECTATOR)
|
||||
: hdr(NETPLAY_AUTH_RESP, sizeof(netPlayAuthResp)),
|
||||
appVersionMajor(FCEU_VERSION_MAJOR), appVersionMinor(FCEU_VERSION_MINOR), appVersionPatch(FCEU_VERSION_PATCH),
|
||||
playerId(NETPLAY_SPECTATOR)
|
||||
{
|
||||
memset(pswd, 0, sizeof(pswd));
|
||||
}
|
||||
|
@ -105,19 +111,26 @@ struct netPlayAuthResp
|
|||
void toHostByteOrder()
|
||||
{
|
||||
hdr.toHostByteOrder();
|
||||
appVersionMajor = netPlayByteSwap(appVersionMajor);
|
||||
appVersionMinor = netPlayByteSwap(appVersionMinor);
|
||||
appVersionPatch = netPlayByteSwap(appVersionPatch);
|
||||
}
|
||||
|
||||
void toNetworkByteOrder()
|
||||
{
|
||||
hdr.toNetworkByteOrder();
|
||||
appVersionMajor = netPlayByteSwap(appVersionMajor);
|
||||
appVersionMinor = netPlayByteSwap(appVersionMinor);
|
||||
appVersionPatch = netPlayByteSwap(appVersionPatch);
|
||||
}
|
||||
};
|
||||
|
||||
struct netPlayTextMsgFlags
|
||||
{
|
||||
static const uint32_t DISCONNECT = 0x00000001;
|
||||
static const uint32_t WARNING = 0x00000002;
|
||||
static const uint32_t INFO = 0x00000004;
|
||||
static const uint32_t ERROR = 0x00000002;
|
||||
static const uint32_t WARNING = 0x00000004;
|
||||
static const uint32_t INFO = 0x00000008;
|
||||
};
|
||||
|
||||
template <size_t N=8>
|
||||
|
@ -125,12 +138,11 @@ struct netPlayTextMsg
|
|||
{
|
||||
netPlayMsgHdr hdr;
|
||||
|
||||
unsigned short code;
|
||||
unsigned short flags;
|
||||
unsigned short dataSize;
|
||||
uint32_t flags;
|
||||
uint16_t dataSize;
|
||||
|
||||
netPlayTextMsg(int type)
|
||||
: hdr(type, sizeof(netPlayTextMsg)), code(0), flags(0), dataSize(0)
|
||||
: hdr(type, sizeof(netPlayTextMsg)), flags(0), dataSize(0)
|
||||
{
|
||||
hdr.msgSize = sizeof(*this) - N + 1;
|
||||
memset(data, 0, N);
|
||||
|
@ -202,7 +214,6 @@ struct netPlayTextMsg
|
|||
void toHostByteOrder()
|
||||
{
|
||||
hdr.toHostByteOrder();
|
||||
code = netPlayByteSwap(code);
|
||||
flags = netPlayByteSwap(flags);
|
||||
dataSize = netPlayByteSwap(dataSize);
|
||||
}
|
||||
|
@ -210,7 +221,6 @@ struct netPlayTextMsg
|
|||
void toNetworkByteOrder()
|
||||
{
|
||||
hdr.toNetworkByteOrder();
|
||||
code = netPlayByteSwap(code);
|
||||
flags = netPlayByteSwap(flags);
|
||||
dataSize = netPlayByteSwap(dataSize);
|
||||
}
|
||||
|
|
|
@ -635,6 +635,7 @@ InitConfig()
|
|||
config->addOption("players", "SDL.NetworkPlayers", 1);
|
||||
config->addOption("SDL.NetPlayHostAllowClientRomLoadReq", 0);
|
||||
config->addOption("SDL.NetPlayHostAllowClientStateLoadReq", 0);
|
||||
config->addOption("SDL.NetPlayHostEnforceAppVersionChk", 1);
|
||||
|
||||
// input configuration options
|
||||
config->addOption("input1", "SDL.Input.0", "GamePad.0");
|
||||
|
|
Loading…
Reference in New Issue