Skip to content

Commit

Permalink
Added netplay debug mode for interface debug logging.
Browse files Browse the repository at this point in the history
  • Loading branch information
thor2016 committed Apr 8, 2024
1 parent 9036dd0 commit 6e69843
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 14 deletions.
116 changes: 106 additions & 10 deletions src/drivers/Qt/NetPlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,14 @@ void NetPlayServer::processPendingConnections(void)
{
NetPlayClient *client = new NetPlayClient(this);

if (debugMode)
{
// File is owned by the server
QTemporaryFile* debugFile = new QTemporaryFile( QDir::tempPath() + QString("/NetPlayServerConnection_XXXXXX.log"), this);
debugFile->open();
client->setDebugLog( debugFile );
printf("Client Debug File: %s\n", debugFile->fileName().toLocal8Bit().constData());
}
client->setSocket(newSock);

clientList.push_back(client);
Expand Down Expand Up @@ -314,7 +322,7 @@ int NetPlayServer::closeAllConnections(void)
}

//-----------------------------------------------------------------------------
int NetPlayServer::sendMsg( NetPlayClient *client, void *msg, size_t msgSize, std::function<void(void)> netByteOrderConvertFunc)
int NetPlayServer::sendMsg( NetPlayClient *client, const void *msg, size_t msgSize, std::function<void(void)> netByteOrderConvertFunc)
{
QTcpSocket* sock;

Expand All @@ -329,7 +337,7 @@ int NetPlayServer::sendMsg( NetPlayClient *client, void *msg, size_t msgSize, st
//-----------------------------------------------------------------------------
int NetPlayServer::sendRomLoadReq( NetPlayClient *client )
{
constexpr size_t BufferSize = 8 * 1024;
constexpr size_t BufferSize = 32 * 1024;
char buf[BufferSize];
size_t bytesRead;
long fileSize = 0;
Expand Down Expand Up @@ -392,6 +400,7 @@ int NetPlayServer::sendStateSyncReq( NetPlayClient *client )
{
EMUFILE_MEMORY em;
int compressionLevel = 1;
static constexpr size_t maxBytesPerWrite = 32 * 1024;
netPlayLoadStateResp resp;

if ( GameInfo == nullptr )
Expand Down Expand Up @@ -433,7 +442,24 @@ int NetPlayServer::sendStateSyncReq( NetPlayClient *client )
printf("Sending ROM Sync Request: %zu\n", em.size());

sendMsg( client, &resp, sizeof(netPlayLoadStateResp), [&resp]{ resp.toNetworkByteOrder(); } );
sendMsg( client, em.buf(), em.size() );
//sendMsg( client, em.buf(), em.size() );

const unsigned char* bufPtr = em.buf();
size_t dataSize = em.size();

while (dataSize > 0)
{
size_t bytesToWrite = dataSize;

if (bytesToWrite > maxBytesPerWrite)
{
bytesToWrite = maxBytesPerWrite;
}
sendMsg( client, bufPtr, bytesToWrite );

bufPtr += bytesToWrite;
dataSize -= bytesToWrite;
}

client->flushData();

Expand Down Expand Up @@ -745,6 +771,11 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
client->flushData();
}
}
else
{
// If authentication failed, force disconnect client.
client->forceDisconnect();
}
}
break;
case NETPLAY_CLIENT_STATE:
Expand Down Expand Up @@ -1179,6 +1210,10 @@ NetPlayClient::NetPlayClient(QObject *parent, bool outGoing)
: role(0), state(0), currentFrame(0), sock(nullptr), recvMsgId(-1), recvMsgSize(0),
recvMsgBytesLeft(0), recvMsgByteIndex(0), recvMsgBuf(nullptr)
{
FCEU::timeStampRecord ts;
ts.readNew();
spawnTimeStampMs = ts.toMilliSeconds();

if (outGoing)
{
instance = this;
Expand Down Expand Up @@ -1242,6 +1277,11 @@ NetPlayClient::~NetPlayClient(void)
{
printf("Warning: Client has leaked message dialogs\n");
}

if (debugLog != nullptr)
{
debugLog->close();
}
printf("NetPlayClient Destructor\n");
}

Expand Down Expand Up @@ -1348,6 +1388,30 @@ void NetPlayClient::setSocket(QTcpSocket *s)

if (sock != nullptr)
{
if (debugLog != nullptr)
{
FCEU::FixedString<256> logMsg;


if (isNetPlayHost())
{
QHostAddress addr = sock->peerAddress();
int port = sock->peerPort();

logMsg.sprintf("Client Socket Connected: %s:%i\n", addr.toString().toLocal8Bit().constData(), port );
}
else
{
QHostAddress addr = sock->localAddress();
int port = sock->localPort();

logMsg.sprintf("Client Socket Connected: %s:%i\n", addr.toString().toLocal8Bit().constData(), port );
}

//printf("LogMsg: %zu : %s\n", logMsg.size(), logMsg.c_str());
debugLog->write( logMsg.c_str(), logMsg.size() );
debugLog->flush();
}
sock->setSocketOption( QAbstractSocket::QAbstractSocket::LowDelayOption, 1);
sock->setSocketOption( QAbstractSocket::SendBufferSizeSocketOption, static_cast<int>(recvMsgBufSize) );
sock->setSocketOption( QAbstractSocket::ReceiveBufferSizeSocketOption, static_cast<int>(recvMsgBufSize) );
Expand Down Expand Up @@ -1435,7 +1499,7 @@ void NetPlayClient::onSocketError(QAbstractSocket::SocketError error)
//-----------------------------------------------------------------------------
int NetPlayClient::requestRomLoad( const char *romPath )
{
constexpr size_t BufferSize = 8 * 1024;
constexpr size_t BufferSize = 32 * 1024;
char buf[BufferSize];
size_t bytesRead;
long fileSize = 0;
Expand Down Expand Up @@ -1479,7 +1543,7 @@ int NetPlayClient::requestStateLoad(EMUFILE *is)
{
size_t dataSize;
char *dataBuf;
static constexpr size_t maxBytesPerWrite = 16 * 1024;
static constexpr size_t maxBytesPerWrite = 32 * 1024;
netPlayLoadStateResp resp;

dataSize = is->size();
Expand Down Expand Up @@ -1612,6 +1676,8 @@ void NetPlayClient::update(void)
//-----------------------------------------------------------------------------
int NetPlayClient::readMessages( void (*msgCallback)( void *userData, void *msgBuf, size_t msgSize ), void *userData )
{
FCEU::FixedString<256> logMsg;

if (readMessageProcessing)
{
printf("Read Message is Processing in callstack, don't allow re-entrantancy.\n");
Expand All @@ -1624,12 +1690,18 @@ int NetPlayClient::readMessages( void (*msgCallback)( void *userData, void *msgB
bool readReq;
netPlayMsgHdr *hdr;
constexpr int netPlayMsgHdrSize = sizeof(netPlayMsgHdr);
FCEU::timeStampRecord ts;
long int ts = 0;

ts.readNew();
int bytesAvailable = sock->bytesAvailable();
readReq = bytesAvailable > 0;

if (debugLog != nullptr)
{
FCEU::timeStampRecord tsRec;
tsRec.readNew();
ts = tsRec.toMilliSeconds() - spawnTimeStampMs;
}

while (readReq)
{
//printf("Read Bytes Available: %lu %i %i\n", ts.toMilliSeconds(), bytesAvailable, recvMsgBytesLeft);
Expand All @@ -1652,6 +1724,11 @@ int NetPlayClient::readMessages( void (*msgCallback)( void *userData, void *msgB
recvMsgByteIndex += dataRead;
}
//printf(" Data: Id: %u Size: %zu Read: %i\n", recvMsgId, readSize, dataRead );
if (debugLog != nullptr)
{
logMsg.sprintf("%lu: Recv Chunk: Size:%i Left:%i\n", ts, dataRead, recvMsgBytesLeft);
debugLog->write( logMsg.c_str(), logMsg.size() );
}

if (recvMsgBytesLeft > 0)
{
Expand All @@ -1660,6 +1737,11 @@ int NetPlayClient::readMessages( void (*msgCallback)( void *userData, void *msgB
}
else
{
if (debugLog != nullptr)
{
logMsg.sprintf("%lu: Recv End: Size:%i \n", ts, recvMsgSize);
debugLog->write( logMsg.c_str(), logMsg.size() );
}
msgCallback( userData, recvMsgBuf, recvMsgSize );
bytesAvailable = sock->bytesAvailable();
readReq = (bytesAvailable > 0);
Expand All @@ -1679,12 +1761,22 @@ int NetPlayClient::readMessages( void (*msgCallback)( void *userData, void *msgB
if ( (netPlayByteSwap(hdr->magic[0]) != NETPLAY_MAGIC_NUMBER) ||
(netPlayByteSwap(hdr->magic[1]) != NETPLAY_MAGIC_NUMBER) )
{
printf("Error: Message Header Validity Check Failed: %08X\n", recvMsgId);
FCEU_printf("Netplay Error: Message Header Validity Check Failed: %08X\n", recvMsgId);
forceDisconnect();
return -1;
}

if (netPlayByteSwap(hdr->msgSize) > recvMsgBufSize)
{
printf("Error: Message size too large: %08X\n", recvMsgId);
FCEU_printf("Netplay Error: Message size too large: %08X\n", recvMsgId);
forceDisconnect();
return -1;
}

if (debugLog != nullptr)
{
logMsg.sprintf("%lu: Recv Start: HDR Info: Id:%u ExpectedSize:%i\n", ts, netPlayByteSwap(hdr->msgId), recvMsgSize );
debugLog->write( logMsg.c_str(), logMsg.size() );
}
//printf("HDR: Id: %u Size: %u\n", netPlayByteSwap(hdr->msgId), netPlayByteSwap(hdr->msgSize) );

Expand Down Expand Up @@ -1773,7 +1865,7 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )

FCEU_printf("Load ROM Request Received: %s\n", msg->fileName);

tmpFile.setFileTemplate(QString("tmpRomXXXXXX.nes"));
tmpFile.setFileTemplate(QDir::tempPath() + QString("/tmpRom_XXXXXX.nes"));
tmpFile.open();
QString filepath = tmpFile.fileName();
printf("Dumping Temp Rom to: %s\n", tmpFile.fileName().toLocal8Bit().constData());
Expand Down Expand Up @@ -2028,6 +2120,9 @@ NetPlayHostDialog::NetPlayHostDialog(QWidget *parent)
g_config->getOption("SDL.NetPlayHostAllowClientStateLoadReq", &stateLoadReqEna);
allowClientStateReqCBox->setChecked(stateLoadReqEna);

debugModeCBox = new QCheckBox(tr("Debug Network Messaging"));
grid->addWidget( debugModeCBox, 4, 0, 1, 2 );

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)));
Expand Down Expand Up @@ -2113,6 +2208,7 @@ void NetPlayHostDialog::onStartClicked(void)
server->setEnforceAppVersionCheck( enforceAppVersionChkCBox->isChecked() );
server->setAllowClientRomLoadRequest( allowClientRomReqCBox->isChecked() );
server->setAllowClientStateLoadRequest( allowClientStateReqCBox->isChecked() );
server->setDebugMode( debugModeCBox->isChecked() );

if (passwordRequiredCBox->isChecked())
{
Expand Down
12 changes: 11 additions & 1 deletion src/drivers/Qt/NetPlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <list>
#include <functional>

#include <QFile>
#include <QTemporaryFile>
#include <QWidget>
#include <QDialog>
#include <QVBoxLayout>
Expand Down Expand Up @@ -128,7 +130,7 @@ class NetPlayServer : public QTcpServer
void resyncClient( NetPlayClient *client );
void resyncAllClients();

int sendMsg( NetPlayClient *client, void *msg, size_t msgSize, std::function<void(void)> netByteOrderConvertFunc = []{});
int sendMsg( NetPlayClient *client, const void *msg, size_t msgSize, std::function<void(void)> netByteOrderConvertFunc = []{});
int sendRomLoadReq( NetPlayClient *client );
int sendStateSyncReq( NetPlayClient *client );
int sendPause( NetPlayClient *client );
Expand All @@ -146,6 +148,7 @@ class NetPlayServer : public QTcpServer
void setEnforceAppVersionCheck(bool value){ enforceAppVersionCheck = value; }
void setAllowClientRomLoadRequest(bool value){ allowClientRomLoadReq = value; }
void setAllowClientStateLoadRequest(bool value){ allowClientStateLoadReq = value; }
void setDebugMode(bool value){ debugMode = value; }

void serverProcessMessage( NetPlayClient *client, void *msgBuf, size_t msgSize );

Expand Down Expand Up @@ -173,6 +176,7 @@ class NetPlayServer : public QTcpServer
bool enforceAppVersionCheck = true;
bool allowClientRomLoadReq = false;
bool allowClientStateLoadReq = false;
bool debugMode = false;

public:
signals:
Expand Down Expand Up @@ -279,6 +283,7 @@ class NetPlayClient : public QObject
void recordPingResult( uint64_t delay_ms );
void resetPingData(void);
double getAvgPingDelay();
void setDebugLog(QFile* file){ debugLog = file; };

QString userName;
QString password;
Expand Down Expand Up @@ -334,9 +339,13 @@ class NetPlayClient : public QObject
uint32_t romCrc32 = 0;
uint32_t numMsgBoxObjs = 0;

long int spawnTimeStampMs = 0;

std::list <NetPlayFrameInput> input;
FCEU::mutex inputMtx;

QFile* debugLog = nullptr;

static constexpr size_t recvMsgBufSize = 2 * 1024 * 1024;

signals:
Expand Down Expand Up @@ -376,6 +385,7 @@ class NetPlayHostDialog : public QDialog
QCheckBox *enforceAppVersionChkCBox;
QCheckBox *allowClientRomReqCBox;
QCheckBox *allowClientStateReqCBox;
QCheckBox *debugModeCBox;

static NetPlayHostDialog* instance;

Expand Down
34 changes: 31 additions & 3 deletions src/utils/StringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,21 +154,49 @@ namespace FCEU
va_start(args, format);
retval = ::vsnprintf( buf, bufSize, format, args);
va_end(args);

if (retval > 0)
{
if ( static_cast<size_t>(retval) < bufSize)
{
end = retval;
}
else
{
end = bufSize - 1;
}
}
return retval;
}

int append_sprintf( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 2, 3 )
{
int retval;
va_list args;
va_start(args, format);
size_t sizeAvail = 0;
if (bufSize > end)
{
sizeAvail = bufSize - end;
sizeAvail = bufSize - end - 1;
}
if (sizeAvail == 0)
{
return 0;
}
va_list args;
va_start(args, format);
retval = ::vsnprintf( &buf[end], sizeAvail, format, args);
va_end(args);

if (retval > 0)
{
if ( static_cast<size_t>(retval) < sizeAvail)
{
end += retval;
}
else
{
end = bufSize - 1;
}
}
return retval;
}

Expand Down

0 comments on commit 6e69843

Please sign in to comment.