NetPlay config and GUI improvements.

This commit is contained in:
harry 2024-02-20 06:56:26 -05:00
parent 0e4c122623
commit f04e8a5ea4
4 changed files with 203 additions and 53 deletions

View File

@ -3190,24 +3190,16 @@ void consoleWin_t::openPaletteEditorWin(void)
void consoleWin_t::openNetPlayHostWindow(void) void consoleWin_t::openNetPlayHostWindow(void)
{ {
NetPlayHostDialog *win;
//printf("Open NetPlay Host Window\n"); //printf("Open NetPlay Host Window\n");
win = new NetPlayHostDialog(this); openNetPlayHostDialog(this);
win->show();
} }
void consoleWin_t::openNetPlayJoinWindow(void) void consoleWin_t::openNetPlayJoinWindow(void)
{ {
NetPlayJoinDialog *win;
//printf("Open NetPlay Join Window\n"); //printf("Open NetPlay Join Window\n");
win = new NetPlayJoinDialog(this); openNetPlayJoinDialog(this);
win->show();
} }
void consoleWin_t::closeNetPlaySession(void) void consoleWin_t::closeNetPlaySession(void)

View File

@ -19,6 +19,7 @@
*/ */
#include <QDir> #include <QDir>
#include <QMessageBox>
#include "../../fceu.h" #include "../../fceu.h"
#include "../../state.h" #include "../../state.h"
@ -277,24 +278,46 @@ void NetPlayServer::serverProcessMessage( NetPlayClient *client, void *msgBuf, s
{ {
case NETPLAY_AUTH_RESP: case NETPLAY_AUTH_RESP:
{ {
bool authentication_passed = false;
netPlayAuthResp *msg = static_cast<netPlayAuthResp*>(msgBuf); netPlayAuthResp *msg = static_cast<netPlayAuthResp*>(msgBuf);
printf("Authorize: Player: %i Passwd: %s\n", msg->playerId, msg->pswd); printf("Authorize: Player: %i Passwd: %s\n", msg->playerId, msg->pswd);
if ( claimRole(client, msg->playerId) ) if (sessionPasswd.isEmpty())
{ {
client->userName = msg->userName; authentication_passed = true;
sendRomLoadReq( client );
sendStateSyncReq( client );
client->state = 1;
FCEU_DispMessage("%s Joined",0, client->userName.toLocal8Bit().constData());
} }
else else
{ {
netPlayErrorMsg<128> errorMsg; authentication_passed = sessionPasswd.compare(msg->pswd, Qt::CaseSensitive) == 0;
errorMsg.setDisconnectFlag();
errorMsg.printf("Player %i role is not available", msg->playerId+1); if (!authentication_passed)
sendMsg( client, &errorMsg, errorMsg.hdr.msgSize ); {
client->flushData(); netPlayErrorMsg<128> errorMsg;
errorMsg.setDisconnectFlag();
errorMsg.printf("Invalid Password");
sendMsg( client, &errorMsg, errorMsg.hdr.msgSize );
client->flushData();
}
}
if (authentication_passed)
{
if ( claimRole(client, msg->playerId) )
{
client->userName = msg->userName;
sendRomLoadReq( client );
sendStateSyncReq( client );
client->state = 1;
FCEU_DispMessage("%s Joined",0, client->userName.toLocal8Bit().constData());
}
else
{
netPlayErrorMsg<128> errorMsg;
errorMsg.setDisconnectFlag();
errorMsg.printf("Player %i role is not available", msg->playerId+1);
sendMsg( client, &errorMsg, errorMsg.hdr.msgSize );
client->flushData();
}
} }
} }
break; break;
@ -502,7 +525,7 @@ void NetPlayClient::forceDisconnect()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool NetPlayClient::isAuthenticated() bool NetPlayClient::isAuthenticated()
{ {
return state > 0; return (state > 0);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool NetPlayClient::isPlayerRole() bool NetPlayClient::isPlayerRole()
@ -532,18 +555,18 @@ void NetPlayClient::setSocket(QTcpSocket *s)
} }
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int NetPlayClient::createSocket(void) QTcpSocket* NetPlayClient::createSocket(void)
{ {
if (sock == nullptr) if (sock == nullptr)
{ {
sock = new QTcpSocket(this); sock = new QTcpSocket(this);
connect(sock, SIGNAL(connected(void)) , this, SLOT(onConnect(void)));
connect(sock, SIGNAL(disconnected(void)), this, SLOT(onDisconnect(void)));
connect(sock, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
} }
connect(sock, SIGNAL(connected(void)) , this, SLOT(onConnect(void))); return sock;
connect(sock, SIGNAL(disconnected(void)), this, SLOT(onDisconnect(void)));
connect(sock, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
return 0;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int NetPlayClient::connectToHost( const QString host, int port ) int NetPlayClient::connectToHost( const QString host, int port )
@ -569,7 +592,9 @@ void NetPlayClient::onConnect(void)
{ {
printf("Client Connected!!!\n"); printf("Client Connected!!!\n");
FCEU_DispMessage("Joined Host",0); FCEU_DispMessage("Joined Host",0);
connected = true; _connected = true;
emit connected();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void NetPlayClient::onDisconnect(void) void NetPlayClient::onDisconnect(void)
@ -597,6 +622,8 @@ void NetPlayClient::onSocketError(QAbstractSocket::SocketError error)
printf("Error: %s\n", errorMsg.toLocal8Bit().constData()); printf("Error: %s\n", errorMsg.toLocal8Bit().constData());
FCEU_DispMessage("%s", 0, errorMsg.toLocal8Bit().constData()); FCEU_DispMessage("%s", 0, errorMsg.toLocal8Bit().constData());
emit errorOccurred(errorMsg);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void clientMessageCallback( void *userData, void *msgBuf, size_t msgSize ) static void clientMessageCallback( void *userData, void *msgBuf, size_t msgSize )
@ -610,7 +637,7 @@ void NetPlayClient::update(void)
{ {
readMessages( clientMessageCallback, this ); readMessages( clientMessageCallback, this );
if (connected) if (_connected)
{ {
uint32_t ctlrData = GetGamepadPressedImmediate(); uint32_t ctlrData = GetGamepadPressedImmediate();
uint32_t currFrame = static_cast<uint32_t>(currFrameCounter); uint32_t currFrame = static_cast<uint32_t>(currFrameCounter);
@ -787,6 +814,8 @@ void NetPlayClient::clientProcessMessage( void *msgBuf, size_t msgSize )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//--- NetPlayHostDialog //--- NetPlayHostDialog
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
NetPlayHostDialog* NetPlayHostDialog::instance = nullptr;
//-----------------------------------------------------------------------------
NetPlayHostDialog::NetPlayHostDialog(QWidget *parent) NetPlayHostDialog::NetPlayHostDialog(QWidget *parent)
: QDialog(parent) : QDialog(parent)
{ {
@ -796,6 +825,8 @@ NetPlayHostDialog::NetPlayHostDialog(QWidget *parent)
QPushButton *cancelButton, *startButton; QPushButton *cancelButton, *startButton;
QLabel *lbl; QLabel *lbl;
instance = this;
setWindowTitle("NetPlay Host Game"); setWindowTitle("NetPlay Host Game");
mainLayout = new QVBoxLayout(); mainLayout = new QVBoxLayout();
@ -804,15 +835,18 @@ NetPlayHostDialog::NetPlayHostDialog(QWidget *parent)
lbl = new QLabel( tr("Server Name:") ); lbl = new QLabel( tr("Server Name:") );
grid->addWidget( lbl, 0, 0 ); grid->addWidget( lbl, 0, 0 );
serverNameEntry = new QLineEdit(); sessionNameEntry = new QLineEdit();
grid->addWidget( serverNameEntry, 0, 1 ); sessionNameEntry->setText("My Game");
grid->addWidget( sessionNameEntry, 0, 1 );
lbl = new QLabel( tr("Port:") ); lbl = new QLabel( tr("Port:") );
grid->addWidget( lbl, 1, 0 ); grid->addWidget( lbl, 1, 0 );
int netPort = NetPlayServer::DefaultPort;
g_config->getOption("SDL.NetworkPort", &netPort);
portEntry = new QSpinBox(); portEntry = new QSpinBox();
portEntry->setRange(0,65535); portEntry->setRange(0,65535);
portEntry->setValue(5050); portEntry->setValue(netPort);
grid->addWidget( portEntry, 1, 1 ); grid->addWidget( portEntry, 1, 1 );
lbl = new QLabel( tr("Role:") ); lbl = new QLabel( tr("Role:") );
@ -827,6 +861,15 @@ NetPlayHostDialog::NetPlayHostDialog(QWidget *parent)
playerRoleBox->setCurrentIndex(1); playerRoleBox->setCurrentIndex(1);
grid->addWidget( playerRoleBox, 2, 1 ); grid->addWidget( playerRoleBox, 2, 1 );
passwordRequiredCBox = new QCheckBox(tr("Password Required"));
grid->addWidget( passwordRequiredCBox, 3, 0, 1, 2 );
lbl = new QLabel( tr("Password:") );
grid->addWidget( lbl, 4, 0 );
passwordEntry = new QLineEdit();
grid->addWidget( passwordEntry, 4, 1 );
mainLayout->addLayout(grid); mainLayout->addLayout(grid);
startButton = new QPushButton( tr("Start") ); startButton = new QPushButton( tr("Start") );
@ -848,6 +891,7 @@ NetPlayHostDialog::NetPlayHostDialog(QWidget *parent)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
NetPlayHostDialog::~NetPlayHostDialog(void) NetPlayHostDialog::~NetPlayHostDialog(void)
{ {
instance = nullptr;
//printf("Destroy NetPlay Host Window\n"); //printf("Destroy NetPlay Host Window\n");
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -877,20 +921,41 @@ void NetPlayHostDialog::onStartClicked(void)
} }
NetPlayServer::Create(consoleWindow); NetPlayServer::Create(consoleWindow);
const int netPort = portEntry->value();
server = NetPlayServer::GetInstance(); server = NetPlayServer::GetInstance();
server->setRole( playerRoleBox->currentData().toInt() ); server->setRole( playerRoleBox->currentData().toInt() );
server->sessionName = sessionNameEntry->text();
server->sessionPasswd = passwordEntry->text();
if (server->listen( QHostAddress::Any, portEntry->value() ) == false) bool listenSucceeded = server->listen( QHostAddress::Any, netPort );
if (listenSucceeded)
{ {
printf("Error: TCP server failed to listen\n"); g_config->setOption("SDL.NetworkPort", netPort);
done(0);
deleteLater();
} }
else
{
QString msg = "Failed to start TCP server on port ";
msg += QString::number(netPort);
msg += "\n\nReason: ";
msg += server->errorString();
QMessageBox::warning( this, tr("TCP Server Error"), msg, QMessageBox::Ok );
done(0); // Server init failed, destruct server
deleteLater(); if (server != nullptr)
{
delete server;
server = nullptr;
}
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//--- NetPlayJoinDialog //--- NetPlayJoinDialog
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
NetPlayJoinDialog* NetPlayJoinDialog::instance = nullptr;
//-----------------------------------------------------------------------------
NetPlayJoinDialog::NetPlayJoinDialog(QWidget *parent) NetPlayJoinDialog::NetPlayJoinDialog(QWidget *parent)
: QDialog(parent) : QDialog(parent)
{ {
@ -900,6 +965,8 @@ NetPlayJoinDialog::NetPlayJoinDialog(QWidget *parent)
QPushButton *cancelButton, *startButton; QPushButton *cancelButton, *startButton;
QLabel *lbl; QLabel *lbl;
instance = this;
setWindowTitle("NetPlay Join Game"); setWindowTitle("NetPlay Join Game");
mainLayout = new QVBoxLayout(); mainLayout = new QVBoxLayout();
@ -908,16 +975,20 @@ NetPlayJoinDialog::NetPlayJoinDialog(QWidget *parent)
lbl = new QLabel( tr("Host:") ); lbl = new QLabel( tr("Host:") );
grid->addWidget( lbl, 0, 0 ); grid->addWidget( lbl, 0, 0 );
QString hostAddress = "localhost";
g_config->getOption("SDL.NetworkIP", &hostAddress);
hostEntry = new QLineEdit(); hostEntry = new QLineEdit();
hostEntry->setText("localhost"); hostEntry->setText(hostAddress);
grid->addWidget( hostEntry, 0, 1 ); grid->addWidget( hostEntry, 0, 1 );
lbl = new QLabel( tr("Port:") ); lbl = new QLabel( tr("Port:") );
grid->addWidget( lbl, 1, 0 ); grid->addWidget( lbl, 1, 0 );
int netPort = NetPlayServer::DefaultPort;
g_config->getOption("SDL.NetworkPort", &netPort);
portEntry = new QSpinBox(); portEntry = new QSpinBox();
portEntry->setRange(0,65535); portEntry->setRange(0,65535);
portEntry->setValue(5050); portEntry->setValue(netPort);
grid->addWidget( portEntry, 1, 1 ); grid->addWidget( portEntry, 1, 1 );
lbl = new QLabel( tr("Role:") ); lbl = new QLabel( tr("Role:") );
@ -935,11 +1006,9 @@ NetPlayJoinDialog::NetPlayJoinDialog(QWidget *parent)
lbl = new QLabel( tr("User:") ); lbl = new QLabel( tr("User:") );
grid->addWidget( lbl, 3, 0 ); grid->addWidget( lbl, 3, 0 );
QString name = qgetenv("USER"); QString name;
if (name.isEmpty()) g_config->getOption("SDL.NetworkUsername", &name);
{
name = qgetenv("USERNAME");
}
userNameEntry = new QLineEdit(); userNameEntry = new QLineEdit();
userNameEntry->setMaxLength(63); userNameEntry->setMaxLength(63);
userNameEntry->setText(name); userNameEntry->setText(name);
@ -973,6 +1042,7 @@ NetPlayJoinDialog::NetPlayJoinDialog(QWidget *parent)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
NetPlayJoinDialog::~NetPlayJoinDialog(void) NetPlayJoinDialog::~NetPlayJoinDialog(void)
{ {
instance = nullptr;
//printf("Destroy NetPlay Host Window\n"); //printf("Destroy NetPlay Host Window\n");
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1002,21 +1072,49 @@ void NetPlayJoinDialog::onJoinClicked(void)
} }
NetPlayClient::Create(consoleWindow); NetPlayClient::Create(consoleWindow);
const int netPort = portEntry->value();
client = NetPlayClient::GetInstance(); client = NetPlayClient::GetInstance();
client->role = playerRoleBox->currentData().toInt(); client->role = playerRoleBox->currentData().toInt();
client->userName = userNameEntry->text(); client->userName = userNameEntry->text();
client->password = passwordEntry->text(); client->password = passwordEntry->text();
if (client->connectToHost( hostEntry->text(), portEntry->value() )) QString hostAddress = hostEntry->text();
connect(client, SIGNAL(connected(void)) , this, SLOT(onConnect(void)));
connect(client, SIGNAL(errorOccurred(const QString&)), this, SLOT(onSocketError(const QString&)));
if (client->connectToHost( hostAddress, netPort ))
{ {
FCEU_DispMessage("Host connect failed",0); FCEU_DispMessage("Host connect failed",0);
} }
g_config->setOption("SDL.NetworkIP", hostAddress);
g_config->setOption("SDL.NetworkPort", netPort);
}
//----------------------------------------------------------------------------
void NetPlayJoinDialog::onConnect()
{
//printf("Close Window\n"); //printf("Close Window\n");
done(0); done(0);
deleteLater(); deleteLater();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void NetPlayJoinDialog::onSocketError(const QString& errorMsg)
{
QString msg = "Failed to connect to server";
msg += "\n\nReason: ";
msg += errorMsg;
QMessageBox::warning( this, tr("Connection Error"), msg, QMessageBox::Ok );
NetPlayClient *client = NetPlayClient::GetInstance();
if (client != nullptr)
{
delete client;
client = nullptr;
}
}
//----------------------------------------------------------------------------
//---- Global Functions //---- Global Functions
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool NetPlayActive(void) bool NetPlayActive(void)
@ -1112,3 +1210,37 @@ void NetPlayCloseSession(void)
NetPlayServer::Destroy(); NetPlayServer::Destroy();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void openNetPlayHostDialog(QWidget* parent)
{
NetPlayHostDialog* win = NetPlayHostDialog::GetInstance();
if (win == nullptr)
{
win = new NetPlayHostDialog(parent);
win->show();
}
else
{
win->activateWindow();
win->raise();
}
}
//----------------------------------------------------------------------------
void openNetPlayJoinDialog(QWidget* parent)
{
NetPlayJoinDialog* win = NetPlayJoinDialog::GetInstance();
if (win == nullptr)
{
win = new NetPlayJoinDialog(parent);
win->show();
}
else
{
win->activateWindow();
win->raise();
}
}
//----------------------------------------------------------------------------

View File

@ -67,6 +67,7 @@ class NetPlayServer : public QTcpServer
NetPlayServer(QObject *parent = 0); NetPlayServer(QObject *parent = 0);
~NetPlayServer(void); ~NetPlayServer(void);
static constexpr int DefaultPort = 4046;
static NetPlayServer *GetInstance(void){ return instance; }; static NetPlayServer *GetInstance(void){ return instance; };
static int Create(QObject *parent = 0); static int Create(QObject *parent = 0);
@ -120,6 +121,8 @@ class NetPlayServer : public QTcpServer
void serverProcessMessage( NetPlayClient *client, void *msgBuf, size_t msgSize ); void serverProcessMessage( NetPlayClient *client, void *msgBuf, size_t msgSize );
QString sessionName;
QString sessionPasswd;
private: private:
static NetPlayServer *instance; static NetPlayServer *instance;
@ -151,11 +154,12 @@ class NetPlayClient : public QObject
int connectToHost( const QString host, int port ); int connectToHost( const QString host, int port );
bool isConnected(void); bool isConnected(void){ return _connected; }
bool disconnectRequested(){ return disconnectPending; } bool disconnectRequested(){ return disconnectPending; }
void forceDisconnect(); void forceDisconnect();
bool flushData(); bool flushData();
QTcpSocket* createSocket(void);
void setSocket(QTcpSocket *s); void setSocket(QTcpSocket *s);
QTcpSocket* getSocket(void){ return sock; }; QTcpSocket* getSocket(void){ return sock; };
@ -211,7 +215,6 @@ class NetPlayClient : public QObject
uint8_t gpData[4]; uint8_t gpData[4];
private: private:
int createSocket(void);
static NetPlayClient *instance; static NetPlayClient *instance;
@ -223,13 +226,17 @@ class NetPlayClient : public QObject
char *recvMsgBuf = nullptr; char *recvMsgBuf = nullptr;
bool disconnectPending = false; bool disconnectPending = false;
bool needsDestroy = false; bool needsDestroy = false;
bool connected = false; bool _connected = false;
std::list <NetPlayFrameInput> input; std::list <NetPlayFrameInput> input;
FCEU::mutex inputMtx; FCEU::mutex inputMtx;
static constexpr size_t recvMsgBufSize = 2 * 1024 * 1024; static constexpr size_t recvMsgBufSize = 2 * 1024 * 1024;
signals:
void connected(void);
void errorOccurred(const QString&);
public slots: public slots:
void onConnect(void); void onConnect(void);
void onDisconnect(void); void onDisconnect(void);
@ -245,12 +252,17 @@ public:
NetPlayHostDialog(QWidget *parent = 0); NetPlayHostDialog(QWidget *parent = 0);
~NetPlayHostDialog(void); ~NetPlayHostDialog(void);
static NetPlayHostDialog *GetInstance(void){ return instance; };
protected: protected:
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
QLineEdit *serverNameEntry; QLineEdit *sessionNameEntry;
QSpinBox *portEntry; QSpinBox *portEntry;
QComboBox *playerRoleBox; QComboBox *playerRoleBox;
QLineEdit *passwordEntry;
QCheckBox *passwordRequiredCBox;
static NetPlayHostDialog* instance;
public slots: public slots:
void closeWindow(void); void closeWindow(void);
@ -266,6 +278,8 @@ public:
NetPlayJoinDialog(QWidget *parent = 0); NetPlayJoinDialog(QWidget *parent = 0);
~NetPlayJoinDialog(void); ~NetPlayJoinDialog(void);
static NetPlayJoinDialog *GetInstance(void){ return instance; };
protected: protected:
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
@ -275,10 +289,13 @@ protected:
QLineEdit *userNameEntry; QLineEdit *userNameEntry;
QLineEdit *passwordEntry; QLineEdit *passwordEntry;
static NetPlayJoinDialog* instance;
public slots: public slots:
void closeWindow(void); void closeWindow(void);
void onJoinClicked(void); void onJoinClicked(void);
void onConnect(void);
void onSocketError(const QString& errorMsg);
}; };
bool NetPlayActive(void); bool NetPlayActive(void);
@ -288,3 +305,5 @@ bool NetPlaySkipWait(void);
int NetPlayFrameWait(void); int NetPlayFrameWait(void);
void NetPlayReadInputFrame(uint8_t* joy); void NetPlayReadInputFrame(uint8_t* joy);
void NetPlayCloseSession(void); void NetPlayCloseSession(void);
void openNetPlayHostDialog(QWidget* parent = nullptr);
void openNetPlayJoinDialog(QWidget* parent = nullptr);

View File

@ -35,6 +35,7 @@
#include "Qt/sdl-video.h" #include "Qt/sdl-video.h"
#include "Qt/AviRecord.h" #include "Qt/AviRecord.h"
#include "Qt/unix-netplay.h" #include "Qt/unix-netplay.h"
#include "Qt/NetPlay.h"
#include "Qt/TasEditor/taseditor_config.h" #include "Qt/TasEditor/taseditor_config.h"
#ifdef WIN32 #ifdef WIN32
@ -618,13 +619,19 @@ InitConfig()
config->addOption("SDL.winFullScreenBorder", 0); config->addOption("SDL.winFullScreenBorder", 0);
#endif #endif
QString userName = qgetenv("USER");
if (userName.isEmpty())
{
userName = qgetenv("USERNAME");
}
// network play options - netplay is broken // network play options - netplay is broken
config->addOption("server", "SDL.NetworkIsServer", 0); config->addOption("server", "SDL.NetworkIsServer", 0);
config->addOption('n', "net", "SDL.NetworkIP", ""); config->addOption('n', "net", "SDL.NetworkIP", "localhost");
config->addOption('u', "user", "SDL.NetworkUsername", ""); config->addOption('u', "user", "SDL.NetworkUsername", userName.toLocal8Bit().constData());
config->addOption('w', "pass", "SDL.NetworkPassword", ""); config->addOption('w', "pass", "SDL.NetworkPassword", "");
config->addOption('k', "netkey", "SDL.NetworkGameKey", ""); config->addOption('k', "netkey", "SDL.NetworkGameKey", "");
config->addOption("port", "SDL.NetworkPort", 4046); config->addOption("port", "SDL.NetworkPort", NetPlayServer::DefaultPort);
config->addOption("players", "SDL.NetworkPlayers", 1); config->addOption("players", "SDL.NetworkPlayers", 1);
// input configuration options // input configuration options