mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-03 09:22:31 +00:00
Updated packet handling
Added "game in progress" message for players trying to join late. Improved "unknown host" packet logging to only log when truly unknown. Correctly abort network window so game can process fatal errors instead of hanging on waiting to connect. Unexpected disconnects in lobby now correctly update the state of the game.
This commit is contained in:
parent
ccd38afbcb
commit
3f4513c571
8 changed files with 64 additions and 11 deletions
|
@ -132,7 +132,8 @@ enum
|
||||||
PRE_CONACK, // Sent from host to guest to acknowledge PRE_CONNECT receipt
|
PRE_CONACK, // Sent from host to guest to acknowledge PRE_CONNECT receipt
|
||||||
PRE_ALLFULL, // Sent from host to an unwanted guest
|
PRE_ALLFULL, // Sent from host to an unwanted guest
|
||||||
PRE_ALLHEREACK, // Sent from guest to host to acknowledge PRE_ALLHEREACK receipt
|
PRE_ALLHEREACK, // Sent from guest to host to acknowledge PRE_ALLHEREACK receipt
|
||||||
PRE_GO // Sent from host to guest to continue game startup
|
PRE_GO, // Sent from host to guest to continue game startup
|
||||||
|
PRE_IN_PROGRESS, // Sent from host to guest if the game has already started
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set PreGamePacket.fake to this so that the game rejects any pregame packets
|
// Set PreGamePacket.fake to this so that the game rejects any pregame packets
|
||||||
|
@ -269,6 +270,8 @@ void PacketSend (void)
|
||||||
// I_Error ("SendPacket error: %s",strerror(errno));
|
// I_Error ("SendPacket error: %s",strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PreSend(const void* buffer, int bufferlen, const sockaddr_in* to);
|
||||||
|
void SendConAck(int num_connected, int num_needed);
|
||||||
|
|
||||||
//
|
//
|
||||||
// PacketGet
|
// PacketGet
|
||||||
|
@ -303,7 +306,7 @@ void PacketGet (void)
|
||||||
GetPlayerName(node).GetChars());
|
GetPlayerName(node).GetChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
doomcom.data[0] = 0x80; // NCMD_EXIT
|
doomcom.data[0] = NCMD_EXIT;
|
||||||
c = 1;
|
c = 1;
|
||||||
}
|
}
|
||||||
else if (err != WSAEWOULDBLOCK)
|
else if (err != WSAEWOULDBLOCK)
|
||||||
|
@ -342,9 +345,13 @@ void PacketGet (void)
|
||||||
else if (c > 0)
|
else if (c > 0)
|
||||||
{ //The packet is not from any in-game node, so we might as well discard it.
|
{ //The packet is not from any in-game node, so we might as well discard it.
|
||||||
// Don't show the message for disconnect notifications.
|
// Don't show the message for disconnect notifications.
|
||||||
if (c != 2 || TransmitBuffer[0] != PRE_FAKE || TransmitBuffer[1] != PRE_DISCONNECT)
|
if (TransmitBuffer[0] != NCMD_EXIT)
|
||||||
{
|
{
|
||||||
DPrintf(DMSG_WARNING, "Dropped packet: Unknown host (%s:%d)\n", inet_ntoa(fromaddress.sin_addr), fromaddress.sin_port);
|
if (TransmitBuffer[0] != PRE_FAKE)
|
||||||
|
DPrintf(DMSG_WARNING, "Dropped packet: Unknown host (%s:%d)\n", inet_ntoa(fromaddress.sin_addr), fromaddress.sin_port);
|
||||||
|
// If it's someone waiting in the lobby, let them know the game already started
|
||||||
|
uint8_t msg[] = { PRE_FAKE, PRE_IN_PROGRESS };
|
||||||
|
PreSend(msg, 2, &fromaddress);
|
||||||
}
|
}
|
||||||
doomcom.remotenode = -1;
|
doomcom.remotenode = -1;
|
||||||
return;
|
return;
|
||||||
|
@ -369,7 +376,22 @@ sockaddr_in *PreGet (void *buffer, int bufferlen, bool noabort)
|
||||||
int err = WSAGetLastError();
|
int err = WSAGetLastError();
|
||||||
if (err == WSAEWOULDBLOCK || (noabort && err == WSAECONNRESET))
|
if (err == WSAEWOULDBLOCK || (noabort && err == WSAECONNRESET))
|
||||||
return NULL; // no packet
|
return NULL; // no packet
|
||||||
I_Error ("PreGet: %s", neterror ());
|
|
||||||
|
if (doomcom.consoleplayer == 0)
|
||||||
|
{
|
||||||
|
int node = FindNode(&fromaddress);
|
||||||
|
I_NetMessage("Got unexpected disconnect.");
|
||||||
|
doomcom.numnodes--;
|
||||||
|
for (; node < doomcom.numnodes; ++node)
|
||||||
|
sendaddress[node] = sendaddress[node + 1];
|
||||||
|
|
||||||
|
// Let remaining guests know that somebody left.
|
||||||
|
SendConAck(doomcom.numnodes, doomcom.numplayers);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
I_NetError("The host disbanded the game unexpectedly");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &fromaddress;
|
return &fromaddress;
|
||||||
}
|
}
|
||||||
|
@ -708,7 +730,7 @@ bool HostGame (int i)
|
||||||
|
|
||||||
doomcom.numnodes = 1;
|
doomcom.numnodes = 1;
|
||||||
|
|
||||||
I_NetInit ("Waiting for players", numplayers);
|
I_NetInit ("Hosting game", numplayers);
|
||||||
|
|
||||||
// Wait for numplayers-1 different connections
|
// Wait for numplayers-1 different connections
|
||||||
if (!I_NetLoop (Host_CheckForConnects, (void *)(intptr_t)numplayers))
|
if (!I_NetLoop (Host_CheckForConnects, (void *)(intptr_t)numplayers))
|
||||||
|
@ -783,13 +805,15 @@ bool Guest_ContactHost (void *userdata)
|
||||||
}
|
}
|
||||||
else if (packet.Message == PRE_DISCONNECT)
|
else if (packet.Message == PRE_DISCONNECT)
|
||||||
{
|
{
|
||||||
doomcom.numnodes = 0;
|
I_NetError("The host cancelled the game.");
|
||||||
I_FatalError ("The host cancelled the game.");
|
|
||||||
}
|
}
|
||||||
else if (packet.Message == PRE_ALLFULL)
|
else if (packet.Message == PRE_ALLFULL)
|
||||||
{
|
{
|
||||||
doomcom.numnodes = 0;
|
I_NetError("The game is full.");
|
||||||
I_FatalError ("The game is full.");
|
}
|
||||||
|
else if (packet.Message == PRE_IN_PROGRESS)
|
||||||
|
{
|
||||||
|
I_NetError("The game was already started.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -850,7 +874,7 @@ bool Guest_WaitForOthers (void *userdata)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case PRE_DISCONNECT:
|
case PRE_DISCONNECT:
|
||||||
I_FatalError ("The host cancelled the game.");
|
I_NetError("The host cancelled the game.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -875,6 +899,7 @@ bool JoinGame (int i)
|
||||||
BuildAddress (&sendaddress[1], Args->GetArg(i+1));
|
BuildAddress (&sendaddress[1], Args->GetArg(i+1));
|
||||||
sendplayer[1] = 0;
|
sendplayer[1] = 0;
|
||||||
doomcom.numnodes = 2;
|
doomcom.numnodes = 2;
|
||||||
|
doomcom.consoleplayer = -1;
|
||||||
|
|
||||||
|
|
||||||
// Let host know we are here
|
// Let host know we are here
|
||||||
|
@ -1046,6 +1071,13 @@ void I_NetMessage(const char* text, ...)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I_NetError(const char* error)
|
||||||
|
{
|
||||||
|
doomcom.numnodes = 0;
|
||||||
|
StartWindow->NetClose();
|
||||||
|
I_FatalError(error);
|
||||||
|
}
|
||||||
|
|
||||||
// todo: later these must be dispatched by the main menu, not the start screen.
|
// todo: later these must be dispatched by the main menu, not the start screen.
|
||||||
void I_NetProgress(int val)
|
void I_NetProgress(int val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
int I_InitNetwork (void);
|
int I_InitNetwork (void);
|
||||||
void I_NetCmd (void);
|
void I_NetCmd (void);
|
||||||
void I_NetMessage(const char*, ...);
|
void I_NetMessage(const char*, ...);
|
||||||
|
void I_NetError(const char* error);
|
||||||
void I_NetProgress(int val);
|
void I_NetProgress(int val);
|
||||||
void I_NetInit(const char* msg, int num);
|
void I_NetInit(const char* msg, int num);
|
||||||
bool I_NetLoop(bool (*timer_callback)(void*), void* userdata);
|
bool I_NetLoop(bool (*timer_callback)(void*), void* userdata);
|
||||||
|
|
|
@ -55,6 +55,7 @@ public:
|
||||||
virtual void NetInit(const char *message, int num_players) {}
|
virtual void NetInit(const char *message, int num_players) {}
|
||||||
virtual void NetProgress(int count) {}
|
virtual void NetProgress(int count) {}
|
||||||
virtual void NetDone() {}
|
virtual void NetDone() {}
|
||||||
|
virtual void NetClose() {}
|
||||||
virtual bool NetLoop(bool (*timer_callback)(void *), void *userdata) { return false; }
|
virtual bool NetLoop(bool (*timer_callback)(void *), void *userdata) { return false; }
|
||||||
virtual void AppendStatusLine(const char* status) {}
|
virtual void AppendStatusLine(const char* status) {}
|
||||||
virtual void LoadingStatus(const char* message, int colors) {}
|
virtual void LoadingStatus(const char* message, int colors) {}
|
||||||
|
@ -74,6 +75,7 @@ public:
|
||||||
void NetProgress(int count);
|
void NetProgress(int count);
|
||||||
void NetMessage(const char* format, ...); // cover for printf
|
void NetMessage(const char* format, ...); // cover for printf
|
||||||
void NetDone();
|
void NetDone();
|
||||||
|
void NetClose();
|
||||||
bool NetLoop(bool (*timer_callback)(void*), void* userdata);
|
bool NetLoop(bool (*timer_callback)(void*), void* userdata);
|
||||||
protected:
|
protected:
|
||||||
int NetMaxPos, NetCurPos;
|
int NetMaxPos, NetCurPos;
|
||||||
|
|
|
@ -128,6 +128,11 @@ void MainWindow::HideNetStartPane()
|
||||||
NetStartWindow::HideNetStartPane();
|
NetStartWindow::HideNetStartPane();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::CloseNetStartPane()
|
||||||
|
{
|
||||||
|
NetStartWindow::NetClose();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::SetNetStartProgress(int pos)
|
void MainWindow::SetNetStartProgress(int pos)
|
||||||
{
|
{
|
||||||
NetStartWindow::SetNetStartProgress(pos);
|
NetStartWindow::SetNetStartProgress(pos);
|
||||||
|
|
|
@ -29,6 +29,7 @@ public:
|
||||||
void SetNetStartProgress(int pos);
|
void SetNetStartProgress(int pos);
|
||||||
bool RunMessageLoop(bool (*timer_callback)(void*), void* userdata);
|
bool RunMessageLoop(bool (*timer_callback)(void*), void* userdata);
|
||||||
void HideNetStartPane();
|
void HideNetStartPane();
|
||||||
|
void CloseNetStartPane();
|
||||||
|
|
||||||
void SetWindowTitle(const char* caption);
|
void SetWindowTitle(const char* caption);
|
||||||
|
|
||||||
|
|
|
@ -201,3 +201,8 @@ bool FBasicStartupScreen::NetLoop(bool (*timer_callback)(void *), void *userdata
|
||||||
{
|
{
|
||||||
return mainwindow.RunMessageLoop(timer_callback, userdata);
|
return mainwindow.RunMessageLoop(timer_callback, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FBasicStartupScreen::NetClose()
|
||||||
|
{
|
||||||
|
mainwindow.CloseNetStartPane();
|
||||||
|
}
|
||||||
|
|
|
@ -64,6 +64,12 @@ bool NetStartWindow::RunMessageLoop(bool (*newtimer_callback)(void*), void* newu
|
||||||
return Instance->exitreason;
|
return Instance->exitreason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetStartWindow::NetClose()
|
||||||
|
{
|
||||||
|
if (Instance != nullptr)
|
||||||
|
Instance->OnClose();
|
||||||
|
}
|
||||||
|
|
||||||
NetStartWindow::NetStartWindow() : Widget(nullptr, WidgetType::Window)
|
NetStartWindow::NetStartWindow() : Widget(nullptr, WidgetType::Window)
|
||||||
{
|
{
|
||||||
SetWindowBackground(Colorf::fromRgba8(51, 51, 51));
|
SetWindowBackground(Colorf::fromRgba8(51, 51, 51));
|
||||||
|
|
|
@ -14,6 +14,7 @@ public:
|
||||||
static void HideNetStartPane();
|
static void HideNetStartPane();
|
||||||
static void SetNetStartProgress(int pos);
|
static void SetNetStartProgress(int pos);
|
||||||
static bool RunMessageLoop(bool (*timer_callback)(void*), void* userdata);
|
static bool RunMessageLoop(bool (*timer_callback)(void*), void* userdata);
|
||||||
|
static void NetClose();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetStartWindow();
|
NetStartWindow();
|
||||||
|
|
Loading…
Reference in a new issue