mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-21 20:11:12 +00:00
Reapply recent netcode changes
This commit is contained in:
parent
7f4e82e7d9
commit
b2441114e8
32 changed files with 846 additions and 473 deletions
|
@ -39,7 +39,7 @@
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "lua_hook.h"
|
#include "lua_hook.h"
|
||||||
#include "md5.h" // demo checksums
|
#include "md5.h" // demo checksums
|
||||||
#include "d_netfil.h" // G_CheckDemoExtraFiles
|
#include "netcode/d_netfil.h" // G_CheckDemoExtraFiles
|
||||||
|
|
||||||
boolean timingdemo; // if true, exit with report on completion
|
boolean timingdemo; // if true, exit with report on completion
|
||||||
boolean nodrawers; // for comparative timing purposes
|
boolean nodrawers; // for comparative timing purposes
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -17,11 +17,12 @@
|
||||||
#include "../d_main.h"
|
#include "../d_main.h"
|
||||||
#include "../f_finale.h"
|
#include "../f_finale.h"
|
||||||
#include "../g_game.h"
|
#include "../g_game.h"
|
||||||
#include "../i_gamepad.h"
|
#include "../g_input.h"
|
||||||
#include "i_net.h"
|
#include "i_net.h"
|
||||||
#include "../i_system.h"
|
#include "../i_system.h"
|
||||||
#include "../i_time.h"
|
#include "../i_time.h"
|
||||||
#include "../i_video.h"
|
#include "../i_video.h"
|
||||||
|
#include "../keys.h"
|
||||||
#include "../m_menu.h"
|
#include "../m_menu.h"
|
||||||
#include "../m_misc.h"
|
#include "../m_misc.h"
|
||||||
#include "../snake.h"
|
#include "../snake.h"
|
||||||
|
@ -233,6 +234,7 @@ static boolean CL_AskFileList(INT32 firstfile)
|
||||||
boolean CL_SendJoin(void)
|
boolean CL_SendJoin(void)
|
||||||
{
|
{
|
||||||
UINT8 localplayers = 1;
|
UINT8 localplayers = 1;
|
||||||
|
char const *player2name;
|
||||||
if (netgame)
|
if (netgame)
|
||||||
CONS_Printf(M_GetText("Sending join request...\n"));
|
CONS_Printf(M_GetText("Sending join request...\n"));
|
||||||
netbuffer->packettype = PT_CLIENTJOIN;
|
netbuffer->packettype = PT_CLIENTJOIN;
|
||||||
|
@ -250,8 +252,14 @@ boolean CL_SendJoin(void)
|
||||||
if (splitscreen)
|
if (splitscreen)
|
||||||
CleanupPlayerName(1, cv_playername2.zstring); // 1 is a HACK? oh no
|
CleanupPlayerName(1, cv_playername2.zstring); // 1 is a HACK? oh no
|
||||||
|
|
||||||
|
// Avoid empty string on bots to avoid softlocking in singleplayer
|
||||||
|
if (botingame)
|
||||||
|
player2name = strcmp(cv_playername.zstring, "Tails") == 0 ? "Tail" : "Tails";
|
||||||
|
else
|
||||||
|
player2name = cv_playername2.zstring;
|
||||||
|
|
||||||
strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME);
|
strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME);
|
||||||
strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME);
|
strncpy(netbuffer->u.clientcfg.names[1], player2name, MAXPLAYERNAME);
|
||||||
|
|
||||||
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
|
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
|
||||||
}
|
}
|
||||||
|
@ -470,9 +478,9 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
|
||||||
|
|
||||||
static void M_ConfirmConnect(event_t *ev)
|
static void M_ConfirmConnect(event_t *ev)
|
||||||
{
|
{
|
||||||
if (ev->type == ev_keydown || ev->type == ev_gamepad_down)
|
if (ev->type == ev_keydown)
|
||||||
{
|
{
|
||||||
if ((ev->type == ev_keydown && (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_A))
|
if (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER || ev->key == KEY_JOY1)
|
||||||
{
|
{
|
||||||
if (totalfilesrequestednum > 0)
|
if (totalfilesrequestednum > 0)
|
||||||
{
|
{
|
||||||
|
@ -487,7 +495,7 @@ static void M_ConfirmConnect(event_t *ev)
|
||||||
|
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
}
|
}
|
||||||
else if ((ev->type == ev_keydown && (ev->key == 'n' || ev->key == KEY_ESCAPE)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_B))
|
else if (ev->key == 'n' || ev->key == KEY_ESCAPE || ev->key == KEY_JOY1 + 3)
|
||||||
{
|
{
|
||||||
cl_mode = CL_ABORTED;
|
cl_mode = CL_ABORTED;
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
|
@ -663,7 +671,7 @@ static const char * InvalidServerReason (serverinfo_pak *info)
|
||||||
case REFUSE_SLOTS_FULL:
|
case REFUSE_SLOTS_FULL:
|
||||||
return va(
|
return va(
|
||||||
"Maximum players reached: %d\n" EOT,
|
"Maximum players reached: %d\n" EOT,
|
||||||
info->maxplayer);
|
info->maxplayer - D_NumBots());
|
||||||
default:
|
default:
|
||||||
if (info->refusereason)
|
if (info->refusereason)
|
||||||
{
|
{
|
||||||
|
@ -893,11 +901,12 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||||
// my hand has been forced and I am dearly sorry for this awful hack :vomit:
|
// my hand has been forced and I am dearly sorry for this awful hack :vomit:
|
||||||
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
|
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
|
||||||
{
|
{
|
||||||
|
if (!Snake_JoyGrabber(snake, &events[eventtail]))
|
||||||
G_MapEventsToControls(&events[eventtail]);
|
G_MapEventsToControls(&events[eventtail]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gamekeydown[KEY_ESCAPE] || gamepads[0].buttons[GAMEPAD_BUTTON_B] || cl_mode == CL_ABORTED)
|
if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1] || cl_mode == CL_ABORTED)
|
||||||
{
|
{
|
||||||
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
||||||
M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||||
|
@ -922,7 +931,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
||||||
{
|
{
|
||||||
if (!snake)
|
if (!snake)
|
||||||
{
|
{
|
||||||
F_MenuPresTicker(true); // title sky
|
F_MenuPresTicker(); // title sky
|
||||||
F_TitleScreenTicker(true);
|
F_TitleScreenTicker(true);
|
||||||
F_TitleScreenDrawer();
|
F_TitleScreenDrawer();
|
||||||
}
|
}
|
||||||
|
@ -1020,6 +1029,9 @@ void CL_ConnectToServer(void)
|
||||||
}
|
}
|
||||||
while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes))));
|
while (!(cl_mode == CL_CONNECTED && (client || (server && nodewaited <= pnumnodes))));
|
||||||
|
|
||||||
|
if (netgame)
|
||||||
|
F_StartWaitingPlayers();
|
||||||
|
|
||||||
DEBFILE(va("Synchronisation Finished\n"));
|
DEBFILE(va("Synchronisation Finished\n"));
|
||||||
|
|
||||||
displayplayer = consoleplayer;
|
displayplayer = consoleplayer;
|
||||||
|
@ -1136,6 +1148,8 @@ void PT_ServerCFG(SINT8 node)
|
||||||
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic);
|
||||||
G_SetGametype(netbuffer->u.servercfg.gametype);
|
G_SetGametype(netbuffer->u.servercfg.gametype);
|
||||||
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
modifiedgame = netbuffer->u.servercfg.modifiedgame;
|
||||||
|
if (netbuffer->u.servercfg.usedCheats)
|
||||||
|
G_SetUsedCheats(true);
|
||||||
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
memcpy(server_context, netbuffer->u.servercfg.server_context, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -25,8 +25,6 @@
|
||||||
#include "../st_stuff.h"
|
#include "../st_stuff.h"
|
||||||
#include "../hu_stuff.h"
|
#include "../hu_stuff.h"
|
||||||
#include "../keys.h"
|
#include "../keys.h"
|
||||||
#include "../g_input.h"
|
|
||||||
#include "../i_gamepad.h"
|
|
||||||
#include "../m_menu.h"
|
#include "../m_menu.h"
|
||||||
#include "../console.h"
|
#include "../console.h"
|
||||||
#include "d_netfil.h"
|
#include "d_netfil.h"
|
||||||
|
@ -34,7 +32,6 @@
|
||||||
#include "../p_saveg.h"
|
#include "../p_saveg.h"
|
||||||
#include "../z_zone.h"
|
#include "../z_zone.h"
|
||||||
#include "../p_local.h"
|
#include "../p_local.h"
|
||||||
#include "../p_haptic.h"
|
|
||||||
#include "../m_misc.h"
|
#include "../m_misc.h"
|
||||||
#include "../am_map.h"
|
#include "../am_map.h"
|
||||||
#include "../m_random.h"
|
#include "../m_random.h"
|
||||||
|
@ -103,6 +100,8 @@ boolean acceptnewnode = true;
|
||||||
|
|
||||||
UINT16 software_MAXPACKETLENGTH;
|
UINT16 software_MAXPACKETLENGTH;
|
||||||
|
|
||||||
|
static tic_t gametime = 0;
|
||||||
|
|
||||||
static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}};
|
||||||
consvar_t cv_netticbuffer = CVAR_INIT ("netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL);
|
consvar_t cv_netticbuffer = CVAR_INIT ("netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL);
|
||||||
|
|
||||||
|
@ -114,6 +113,8 @@ consvar_t cv_blamecfail = CVAR_INIT ("blamecfail", "Off", CV_SAVE|CV_NETVAR, CV_
|
||||||
static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}};
|
||||||
consvar_t cv_playbackspeed = CVAR_INIT ("playbackspeed", "1", 0, playbackspeed_cons_t, NULL);
|
consvar_t cv_playbackspeed = CVAR_INIT ("playbackspeed", "1", 0, playbackspeed_cons_t, NULL);
|
||||||
|
|
||||||
|
consvar_t cv_dedicatedidletime = CVAR_INIT ("dedicatedidletime", "10", CV_SAVE, CV_Unsigned, NULL);
|
||||||
|
|
||||||
void ResetNode(INT32 node)
|
void ResetNode(INT32 node)
|
||||||
{
|
{
|
||||||
memset(&netnodes[node], 0, sizeof(*netnodes));
|
memset(&netnodes[node], 0, sizeof(*netnodes));
|
||||||
|
@ -210,14 +211,13 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
|
|
||||||
if (server && I_GetNodeAddress)
|
if (server && I_GetNodeAddress)
|
||||||
{
|
{
|
||||||
|
char addressbuffer[64];
|
||||||
const char *address = I_GetNodeAddress(node);
|
const char *address = I_GetNodeAddress(node);
|
||||||
char *port = NULL;
|
|
||||||
if (address) // MI: fix msvcrt.dll!_mbscat crash?
|
if (address) // MI: fix msvcrt.dll!_mbscat crash?
|
||||||
{
|
{
|
||||||
strcpy(playeraddress[newplayernum], address);
|
strcpy(addressbuffer, address);
|
||||||
port = strchr(playeraddress[newplayernum], ':');
|
strcpy(playeraddress[newplayernum],
|
||||||
if (port)
|
I_NetSplitAddress(addressbuffer, NULL));
|
||||||
*port = '\0';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -744,6 +744,9 @@ void SV_ResetServer(void)
|
||||||
|
|
||||||
CV_RevertNetVars();
|
CV_RevertNetVars();
|
||||||
|
|
||||||
|
// Ensure synched when creating a new server
|
||||||
|
M_CopyGameData(serverGamedata, clientGamedata);
|
||||||
|
|
||||||
DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n");
|
DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -997,6 +1000,45 @@ static void PT_Ping(SINT8 node, INT32 netconsole)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void PT_BasicKeepAlive(SINT8 node, INT32 netconsole)
|
||||||
|
{
|
||||||
|
if (client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// This should probably still timeout though, as the node should always have a player 1 number
|
||||||
|
if (netconsole == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If a client sends this it should mean they are done receiving the savegame
|
||||||
|
netnodes[node].sendingsavegame = false;
|
||||||
|
|
||||||
|
// As long as clients send keep alives, the server can keep running, so reset the timeout
|
||||||
|
/// \todo Use a separate cvar for that kind of timeout?
|
||||||
|
netnodes[node].freezetimeout = I_GetTime() + connectiontimeout;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Confusing, but this DOESN'T send PT_NODEKEEPALIVE, it sends PT_BASICKEEPALIVE
|
||||||
|
// Used during wipes to tell the server that a node is still connected
|
||||||
|
static void CL_SendClientKeepAlive(void)
|
||||||
|
{
|
||||||
|
netbuffer->packettype = PT_BASICKEEPALIVE;
|
||||||
|
|
||||||
|
HSendPacket(servernode, false, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SV_SendServerKeepAlive(void)
|
||||||
|
{
|
||||||
|
for (INT32 n = 1; n < MAXNETNODES; n++)
|
||||||
|
{
|
||||||
|
if (netnodes[n].ingame)
|
||||||
|
{
|
||||||
|
netbuffer->packettype = PT_BASICKEEPALIVE;
|
||||||
|
HSendPacket(n, false, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Handles a packet received from a node that isn't in game
|
/** Handles a packet received from a node that isn't in game
|
||||||
*
|
*
|
||||||
* \param node The packet sender
|
* \param node The packet sender
|
||||||
|
@ -1052,6 +1094,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
netconsole = 0;
|
netconsole = 0;
|
||||||
else
|
else
|
||||||
netconsole = netnodes[node].player;
|
netconsole = netnodes[node].player;
|
||||||
|
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
if (netconsole >= MAXPLAYERS)
|
if (netconsole >= MAXPLAYERS)
|
||||||
I_Error("bad table nodetoplayer: node %d player %d", doomcom->remotenode, netconsole);
|
I_Error("bad table nodetoplayer: node %d player %d", doomcom->remotenode, netconsole);
|
||||||
|
@ -1068,6 +1111,7 @@ static void HandlePacketFromPlayer(SINT8 node)
|
||||||
case PT_NODEKEEPALIVEMIS:
|
case PT_NODEKEEPALIVEMIS:
|
||||||
PT_ClientCmd(node, netconsole);
|
PT_ClientCmd(node, netconsole);
|
||||||
break;
|
break;
|
||||||
|
case PT_BASICKEEPALIVE : PT_BasicKeepAlive (node, netconsole); break;
|
||||||
case PT_TEXTCMD : PT_TextCmd (node, netconsole); break;
|
case PT_TEXTCMD : PT_TextCmd (node, netconsole); break;
|
||||||
case PT_TEXTCMD2 : PT_TextCmd (node, netconsole); break;
|
case PT_TEXTCMD2 : PT_TextCmd (node, netconsole); break;
|
||||||
case PT_LOGIN : PT_Login (node, netconsole); break;
|
case PT_LOGIN : PT_Login (node, netconsole); break;
|
||||||
|
@ -1209,28 +1253,8 @@ boolean TryRunTics(tic_t realtics)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetUpdate(void)
|
static void UpdatePingTable(void)
|
||||||
{
|
{
|
||||||
static tic_t gametime = 0;
|
|
||||||
static tic_t resptime = 0;
|
|
||||||
tic_t nowtime;
|
|
||||||
INT32 realtics;
|
|
||||||
|
|
||||||
nowtime = I_GetTime();
|
|
||||||
realtics = nowtime - gametime;
|
|
||||||
|
|
||||||
if (realtics <= 0) // nothing new to update
|
|
||||||
return;
|
|
||||||
if (realtics > 5)
|
|
||||||
{
|
|
||||||
if (server)
|
|
||||||
realtics = 1;
|
|
||||||
else
|
|
||||||
realtics = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
gametime = nowtime;
|
|
||||||
|
|
||||||
if (server)
|
if (server)
|
||||||
{
|
{
|
||||||
if (netgame && !(gametime % 35)) // update once per second.
|
if (netgame && !(gametime % 35)) // update once per second.
|
||||||
|
@ -1241,6 +1265,149 @@ void NetUpdate(void)
|
||||||
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
|
||||||
pingmeasurecount++;
|
pingmeasurecount++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle timeouts to prevent definitive freezes from happenning
|
||||||
|
static void HandleNodeTimeouts(void)
|
||||||
|
{
|
||||||
|
if (server)
|
||||||
|
{
|
||||||
|
for (INT32 i = 1; i < MAXNETNODES; i++)
|
||||||
|
if (netnodes[i].ingame && netnodes[i].freezetimeout < I_GetTime())
|
||||||
|
Net_ConnectionTimeout(i);
|
||||||
|
|
||||||
|
// In case the cvar value was lowered
|
||||||
|
if (joindelay)
|
||||||
|
joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep the network alive while not advancing tics!
|
||||||
|
void NetKeepAlive(void)
|
||||||
|
{
|
||||||
|
tic_t nowtime;
|
||||||
|
INT32 realtics;
|
||||||
|
|
||||||
|
nowtime = I_GetTime();
|
||||||
|
realtics = nowtime - gametime;
|
||||||
|
|
||||||
|
// return if there's no time passed since the last call
|
||||||
|
if (realtics <= 0) // nothing new to update
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdatePingTable();
|
||||||
|
|
||||||
|
GetPackets();
|
||||||
|
|
||||||
|
#ifdef MASTERSERVER
|
||||||
|
MasterClient_Ticker();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (client)
|
||||||
|
{
|
||||||
|
// send keep alive
|
||||||
|
CL_SendClientKeepAlive();
|
||||||
|
// No need to check for resynch because we aren't running any tics
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SV_SendServerKeepAlive();
|
||||||
|
}
|
||||||
|
|
||||||
|
// No else because no tics are being run and we can't resynch during this
|
||||||
|
|
||||||
|
Net_AckTicker();
|
||||||
|
HandleNodeTimeouts();
|
||||||
|
FileSendTicker();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetUpdate(void)
|
||||||
|
{
|
||||||
|
static tic_t resptime = 0;
|
||||||
|
tic_t nowtime;
|
||||||
|
INT32 realtics;
|
||||||
|
|
||||||
|
nowtime = I_GetTime();
|
||||||
|
realtics = nowtime - gametime;
|
||||||
|
|
||||||
|
if (realtics <= 0) // nothing new to update
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (realtics > 5)
|
||||||
|
{
|
||||||
|
if (server)
|
||||||
|
realtics = 1;
|
||||||
|
else
|
||||||
|
realtics = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server && dedicated && gamestate == GS_LEVEL)
|
||||||
|
{
|
||||||
|
const tic_t dedicatedidletime = cv_dedicatedidletime.value * TICRATE;
|
||||||
|
static tic_t dedicatedidletimeprev = 0;
|
||||||
|
static tic_t dedicatedidle = 0;
|
||||||
|
|
||||||
|
if (dedicatedidletime > 0)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
|
||||||
|
for (i = 1; i < MAXNETNODES; ++i)
|
||||||
|
if (netnodes[i].ingame)
|
||||||
|
{
|
||||||
|
if (dedicatedidle >= dedicatedidletime)
|
||||||
|
{
|
||||||
|
CONS_Printf("DEDICATED: Awakening from idle (Node %d detected...)\n", i);
|
||||||
|
dedicatedidle = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == MAXNETNODES)
|
||||||
|
{
|
||||||
|
if (leveltime == 2)
|
||||||
|
{
|
||||||
|
// On next tick...
|
||||||
|
dedicatedidle = dedicatedidletime-1;
|
||||||
|
}
|
||||||
|
else if (dedicatedidle >= dedicatedidletime)
|
||||||
|
{
|
||||||
|
if (D_GetExistingTextcmd(gametic, 0) || D_GetExistingTextcmd(gametic+1, 0))
|
||||||
|
{
|
||||||
|
CONS_Printf("DEDICATED: Awakening from idle (Netxcmd detected...)\n");
|
||||||
|
dedicatedidle = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
realtics = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((dedicatedidle += realtics) >= dedicatedidletime)
|
||||||
|
{
|
||||||
|
const char *idlereason = "at round start";
|
||||||
|
if (leveltime > 3)
|
||||||
|
idlereason = va("for %d seconds", dedicatedidle/TICRATE);
|
||||||
|
|
||||||
|
CONS_Printf("DEDICATED: No nodes %s, idling...\n", idlereason);
|
||||||
|
realtics = 0;
|
||||||
|
dedicatedidle = dedicatedidletime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dedicatedidletimeprev > 0 && dedicatedidle >= dedicatedidletimeprev)
|
||||||
|
{
|
||||||
|
CONS_Printf("DEDICATED: Awakening from idle (Idle disabled...)\n");
|
||||||
|
}
|
||||||
|
dedicatedidle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dedicatedidletimeprev = dedicatedidletime;
|
||||||
|
}
|
||||||
|
|
||||||
|
gametime = nowtime;
|
||||||
|
|
||||||
|
UpdatePingTable();
|
||||||
|
|
||||||
if (client)
|
if (client)
|
||||||
maketic = neededtic;
|
maketic = neededtic;
|
||||||
|
@ -1270,17 +1437,18 @@ void NetUpdate(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!demoplayback)
|
if (!demoplayback && realtics > 0)
|
||||||
{
|
{
|
||||||
hu_redownloadinggamestate = false;
|
hu_redownloadinggamestate = false;
|
||||||
|
|
||||||
firstticstosend = gametic;
|
firstticstosend = gametic;
|
||||||
for (INT32 i = 0; i < MAXNETNODES; i++)
|
for (INT32 i = 0; i < MAXNETNODES; i++)
|
||||||
if (netnodes[i].ingame && netnodes[i].tic < firstticstosend)
|
if (netnodes[i].ingame)
|
||||||
{
|
{
|
||||||
|
if (netnodes[i].tic < firstticstosend)
|
||||||
firstticstosend = netnodes[i].tic;
|
firstticstosend = netnodes[i].tic;
|
||||||
|
|
||||||
if (maketic + 1 >= netnodes[i].tic + BACKUPTICS)
|
if (maketic + realtics >= netnodes[i].tic + BACKUPTICS - TICRATE)
|
||||||
Net_ConnectionTimeout(i);
|
Net_ConnectionTimeout(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1302,20 +1470,10 @@ void NetUpdate(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
Net_AckTicker();
|
Net_AckTicker();
|
||||||
|
HandleNodeTimeouts();
|
||||||
// Handle timeouts to prevent definitive freezes from happenning
|
|
||||||
if (server)
|
|
||||||
{
|
|
||||||
for (INT32 i = 1; i < MAXNETNODES; i++)
|
|
||||||
if (netnodes[i].ingame && netnodes[i].freezetimeout < I_GetTime())
|
|
||||||
Net_ConnectionTimeout(i);
|
|
||||||
|
|
||||||
// In case the cvar value was lowered
|
|
||||||
if (joindelay)
|
|
||||||
joindelay = min(joindelay - 1, 3 * (tic_t)cv_joindelay.value * TICRATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
nowtime /= NEWTICRATERATIO;
|
nowtime /= NEWTICRATERATIO;
|
||||||
|
|
||||||
if (nowtime > resptime)
|
if (nowtime > resptime)
|
||||||
{
|
{
|
||||||
resptime = nowtime;
|
resptime = nowtime;
|
||||||
|
@ -1338,22 +1496,22 @@ void D_ClientServerInit(void)
|
||||||
DEBFILE(va("- - -== SRB2 v%d.%.2d.%d "VERSIONSTRING" debugfile ==- - -\n",
|
DEBFILE(va("- - -== SRB2 v%d.%.2d.%d "VERSIONSTRING" debugfile ==- - -\n",
|
||||||
VERSION/100, VERSION%100, SUBVERSION));
|
VERSION/100, VERSION%100, SUBVERSION));
|
||||||
|
|
||||||
COM_AddCommand("getplayernum", Command_GetPlayerNum);
|
COM_AddCommand("getplayernum", Command_GetPlayerNum, COM_LUA);
|
||||||
COM_AddCommand("kick", Command_Kick);
|
COM_AddCommand("kick", Command_Kick, COM_LUA);
|
||||||
COM_AddCommand("ban", Command_Ban);
|
COM_AddCommand("ban", Command_Ban, COM_LUA);
|
||||||
COM_AddCommand("banip", Command_BanIP);
|
COM_AddCommand("banip", Command_BanIP, COM_LUA);
|
||||||
COM_AddCommand("clearbans", Command_ClearBans);
|
COM_AddCommand("clearbans", Command_ClearBans, COM_LUA);
|
||||||
COM_AddCommand("showbanlist", Command_ShowBan);
|
COM_AddCommand("showbanlist", Command_ShowBan, COM_LUA);
|
||||||
COM_AddCommand("reloadbans", Command_ReloadBan);
|
COM_AddCommand("reloadbans", Command_ReloadBan, COM_LUA);
|
||||||
COM_AddCommand("connect", Command_connect);
|
COM_AddCommand("connect", Command_connect, COM_LUA);
|
||||||
COM_AddCommand("nodes", Command_Nodes);
|
COM_AddCommand("nodes", Command_Nodes, COM_LUA);
|
||||||
COM_AddCommand("resendgamestate", Command_ResendGamestate);
|
COM_AddCommand("resendgamestate", Command_ResendGamestate, COM_LUA);
|
||||||
#ifdef PACKETDROP
|
#ifdef PACKETDROP
|
||||||
COM_AddCommand("drop", Command_Drop);
|
COM_AddCommand("drop", Command_Drop, COM_LUA);
|
||||||
COM_AddCommand("droprate", Command_Droprate);
|
COM_AddCommand("droprate", Command_Droprate, COM_LUA);
|
||||||
#endif
|
#endif
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
COM_AddCommand("numnodes", Command_Numnodes);
|
COM_AddCommand("numnodes", Command_Numnodes, COM_LUA);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RegisterNetXCmd(XD_KICK, Got_KickCmd);
|
RegisterNetXCmd(XD_KICK, Got_KickCmd);
|
||||||
|
@ -1422,6 +1580,20 @@ INT32 D_NumPlayers(void)
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Similar to the above, but counts only bots.
|
||||||
|
* Purpose is to remove bots from both the player count and the
|
||||||
|
* max player count on the server view
|
||||||
|
*/
|
||||||
|
INT32 D_NumBots(void)
|
||||||
|
{
|
||||||
|
INT32 num = 0, ix;
|
||||||
|
for (ix = 0; ix < MAXPLAYERS; ix++)
|
||||||
|
if (playeringame[ix] && players[ix].bot)
|
||||||
|
num++;
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Consistancy
|
// Consistancy
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -73,7 +73,7 @@ extern UINT32 realpingtable[MAXPLAYERS];
|
||||||
extern UINT32 playerpingtable[MAXPLAYERS];
|
extern UINT32 playerpingtable[MAXPLAYERS];
|
||||||
extern tic_t servermaxping;
|
extern tic_t servermaxping;
|
||||||
|
|
||||||
extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed;
|
extern consvar_t cv_netticbuffer, cv_resynchattempts, cv_blamecfail, cv_playbackspeed, cv_dedicatedidletime;
|
||||||
|
|
||||||
// Used in d_net, the only dependence
|
// Used in d_net, the only dependence
|
||||||
void D_ClientServerInit(void);
|
void D_ClientServerInit(void);
|
||||||
|
@ -81,6 +81,9 @@ void D_ClientServerInit(void);
|
||||||
// Create any new ticcmds and broadcast to other players.
|
// Create any new ticcmds and broadcast to other players.
|
||||||
void NetUpdate(void);
|
void NetUpdate(void);
|
||||||
|
|
||||||
|
// Maintain connections to nodes without timing them all out.
|
||||||
|
void NetKeepAlive(void);
|
||||||
|
|
||||||
void GetPackets(void);
|
void GetPackets(void);
|
||||||
void ResetNode(INT32 node);
|
void ResetNode(INT32 node);
|
||||||
INT16 Consistancy(void);
|
INT16 Consistancy(void);
|
||||||
|
@ -118,6 +121,7 @@ extern char motd[254], server_context[8];
|
||||||
extern UINT8 playernode[MAXPLAYERS];
|
extern UINT8 playernode[MAXPLAYERS];
|
||||||
|
|
||||||
INT32 D_NumPlayers(void);
|
INT32 D_NumPlayers(void);
|
||||||
|
INT32 D_NumBots(void);
|
||||||
|
|
||||||
tic_t GetLag(INT32 node);
|
tic_t GetLag(INT32 node);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -760,6 +760,8 @@ static const char *packettypename[NUMPACKETTYPE] =
|
||||||
"ASKLUAFILE",
|
"ASKLUAFILE",
|
||||||
"HASLUAFILE",
|
"HASLUAFILE",
|
||||||
|
|
||||||
|
"PT_BASICKEEPALIVE",
|
||||||
|
|
||||||
"FILEFRAGMENT",
|
"FILEFRAGMENT",
|
||||||
"FILEACK",
|
"FILEACK",
|
||||||
"FILERECEIVED",
|
"FILERECEIVED",
|
||||||
|
@ -818,6 +820,9 @@ static void DebugPrintpacket(const char *header)
|
||||||
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic, doomcom->remotenode),
|
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic, doomcom->remotenode),
|
||||||
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom, doomcom->remotenode));
|
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom, doomcom->remotenode));
|
||||||
break;
|
break;
|
||||||
|
case PT_BASICKEEPALIVE:
|
||||||
|
fprintf(debugfile, " wipetime\n");
|
||||||
|
break;
|
||||||
case PT_TEXTCMD:
|
case PT_TEXTCMD:
|
||||||
case PT_TEXTCMD2:
|
case PT_TEXTCMD2:
|
||||||
fprintf(debugfile, " length %d\n ", netbuffer->u.textcmd[0]);
|
fprintf(debugfile, " length %d\n ", netbuffer->u.textcmd[0]);
|
||||||
|
@ -1140,26 +1145,32 @@ static void Internal_FreeNodenum(INT32 nodenum)
|
||||||
(void)nodenum;
|
(void)nodenum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *I_NetSplitAddress(char *host, char **port)
|
||||||
|
{
|
||||||
|
boolean v4 = (strchr(host, '.') != NULL);
|
||||||
|
|
||||||
|
host = strtok(host, v4 ? ":" : "[]");
|
||||||
|
|
||||||
|
if (port)
|
||||||
|
*port = strtok(NULL, ":");
|
||||||
|
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
SINT8 I_NetMakeNode(const char *hostname)
|
SINT8 I_NetMakeNode(const char *hostname)
|
||||||
{
|
{
|
||||||
SINT8 newnode = -1;
|
SINT8 newnode = -1;
|
||||||
if (I_NetMakeNodewPort)
|
if (I_NetMakeNodewPort)
|
||||||
{
|
{
|
||||||
char *localhostname = strdup(hostname);
|
char *localhostname = strdup(hostname);
|
||||||
char *t = localhostname;
|
char *port;
|
||||||
const char *port;
|
|
||||||
if (!localhostname)
|
if (!localhostname)
|
||||||
return newnode;
|
return newnode;
|
||||||
|
|
||||||
// retrieve portnum from address!
|
// retrieve portnum from address!
|
||||||
strtok(localhostname, ":");
|
hostname = I_NetSplitAddress(localhostname, &port);
|
||||||
port = strtok(NULL, ":");
|
|
||||||
|
|
||||||
// remove the port in the hostname as we've it already
|
newnode = I_NetMakeNodewPort(hostname, port);
|
||||||
while ((*t != ':') && (*t != '\0'))
|
|
||||||
t++;
|
|
||||||
*t = '\0';
|
|
||||||
|
|
||||||
newnode = I_NetMakeNodewPort(localhostname, port);
|
|
||||||
free(localhostname);
|
free(localhostname);
|
||||||
}
|
}
|
||||||
return newnode;
|
return newnode;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -33,10 +33,14 @@ extern consvar_t cv_defaultskin2;
|
||||||
|
|
||||||
extern consvar_t cv_seenames, cv_allowseenames;
|
extern consvar_t cv_seenames, cv_allowseenames;
|
||||||
extern consvar_t cv_usemouse;
|
extern consvar_t cv_usemouse;
|
||||||
extern consvar_t cv_usegamepad[2];
|
extern consvar_t cv_usejoystick;
|
||||||
extern consvar_t cv_gamepad_scale[2];
|
extern consvar_t cv_usejoystick2;
|
||||||
extern consvar_t cv_gamepad_rumble[2];
|
#ifdef LJOYSTICK
|
||||||
extern consvar_t cv_gamepad_autopause;
|
extern consvar_t cv_joyport;
|
||||||
|
extern consvar_t cv_joyport2;
|
||||||
|
#endif
|
||||||
|
extern consvar_t cv_joyscale;
|
||||||
|
extern consvar_t cv_joyscale2;
|
||||||
|
|
||||||
// splitscreen with second mouse
|
// splitscreen with second mouse
|
||||||
extern consvar_t cv_mouse2port;
|
extern consvar_t cv_mouse2port;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -504,7 +504,7 @@ INT32 CL_CheckFiles(void)
|
||||||
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
|
||||||
|
|
||||||
// Check in already loaded files
|
// Check in already loaded files
|
||||||
for (j = mainwads; wadfiles[j]; j++)
|
for (j = mainwads; j < numwadfiles; j++)
|
||||||
{
|
{
|
||||||
nameonly(strcpy(wadfilename, wadfiles[j]->filename));
|
nameonly(strcpy(wadfilename, wadfiles[j]->filename));
|
||||||
if (!stricmp(wadfilename, fileneeded[i].filename) &&
|
if (!stricmp(wadfilename, fileneeded[i].filename) &&
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -29,7 +29,6 @@
|
||||||
#include "../lua_script.h"
|
#include "../lua_script.h"
|
||||||
#include "../lzf.h"
|
#include "../lzf.h"
|
||||||
#include "../m_misc.h"
|
#include "../m_misc.h"
|
||||||
#include "../p_haptic.h"
|
|
||||||
#include "../p_local.h"
|
#include "../p_local.h"
|
||||||
#include "../p_saveg.h"
|
#include "../p_saveg.h"
|
||||||
#include "../r_main.h"
|
#include "../r_main.h"
|
||||||
|
@ -200,8 +199,6 @@ void CL_LoadReceivedSavegame(boolean reloading)
|
||||||
titledemo = false;
|
titledemo = false;
|
||||||
automapactive = false;
|
automapactive = false;
|
||||||
|
|
||||||
P_StopRumble(NULL);
|
|
||||||
|
|
||||||
// load a base level
|
// load a base level
|
||||||
if (P_LoadNetGame(reloading))
|
if (P_LoadNetGame(reloading))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 2020-2022 by James R.
|
// Copyright (C) 2020-2023 by James R.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -66,6 +66,8 @@ static I_mutex hms_api_mutex;
|
||||||
|
|
||||||
static char *hms_server_token;
|
static char *hms_server_token;
|
||||||
|
|
||||||
|
static char hms_useragent[512];
|
||||||
|
|
||||||
struct HMS_buffer
|
struct HMS_buffer
|
||||||
{
|
{
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
|
@ -82,6 +84,22 @@ Contact_error (void)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_user_agent(char *buf, size_t len)
|
||||||
|
{
|
||||||
|
if (snprintf(buf, len, "%s/%s (%s; %s; %i; %i) SRB2BASE/%i", SRB2APPLICATION, VERSIONSTRING, compbranch, comprevision, MODID, MODVERSION, CODEBASE) < 0)
|
||||||
|
I_Error("http-mserv: get_user_agent failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_user_agent_once(void)
|
||||||
|
{
|
||||||
|
if (hms_useragent[0] != '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
get_user_agent(hms_useragent, 512);
|
||||||
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
|
HMS_on_read (char *s, size_t _1, size_t n, void *userdata)
|
||||||
{
|
{
|
||||||
|
@ -157,6 +175,8 @@ HMS_connect (const char *format, ...)
|
||||||
I_lock_mutex(&hms_api_mutex);
|
I_lock_mutex(&hms_api_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
init_user_agent_once();
|
||||||
|
|
||||||
seek = strlen(hms_api) + 1;/* + '/' */
|
seek = strlen(hms_api) + 1;/* + '/' */
|
||||||
|
|
||||||
va_start (ap, format);
|
va_start (ap, format);
|
||||||
|
@ -197,12 +217,18 @@ HMS_connect (const char *format, ...)
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||||
|
|
||||||
|
#ifndef NO_IPV6
|
||||||
|
if (M_CheckParm("-noipv6"))
|
||||||
|
#endif
|
||||||
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value);
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, cv_masterserver_timeout.value);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HMS_on_read);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, hms_useragent);
|
||||||
|
|
||||||
curl_free(quack_token);
|
curl_free(quack_token);
|
||||||
free(url);
|
free(url);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 2011-2022 by Sonic Team Junior.
|
// Copyright (C) 2011-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 2011-2022 by Sonic Team Junior.
|
// Copyright (C) 2011-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -109,6 +109,17 @@ extern boolean (*I_NetCanSend)(void);
|
||||||
*/
|
*/
|
||||||
extern void (*I_NetFreeNodenum)(INT32 nodenum);
|
extern void (*I_NetFreeNodenum)(INT32 nodenum);
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief split a string into address and port
|
||||||
|
|
||||||
|
\param address string to split
|
||||||
|
|
||||||
|
\param port double pointer to hold port component (optional)
|
||||||
|
|
||||||
|
\return address component
|
||||||
|
*/
|
||||||
|
extern char *I_NetSplitAddress(char *address, char **port);
|
||||||
|
|
||||||
/** \brief open a connection with specified address
|
/** \brief open a connection with specified address
|
||||||
|
|
||||||
\param address address to connect to
|
\param address address to connect to
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -328,8 +328,14 @@ static inline void I_UPnP_rem(const char *port, const char * servicetype)
|
||||||
|
|
||||||
static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
||||||
{
|
{
|
||||||
static char s[64]; // 255.255.255.255:65535 or IPv6:65535
|
static char s[64]; // 255.255.255.255:65535 or
|
||||||
|
// [ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535
|
||||||
#ifdef HAVE_NTOP
|
#ifdef HAVE_NTOP
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
int v6 = (sk->any.sa_family == AF_INET6);
|
||||||
|
#else
|
||||||
|
int v6 = 0;
|
||||||
|
#endif
|
||||||
void *addr;
|
void *addr;
|
||||||
|
|
||||||
if(sk->any.sa_family == AF_INET)
|
if(sk->any.sa_family == AF_INET)
|
||||||
|
@ -343,14 +349,21 @@ static const char *SOCK_AddrToStr(mysockaddr_t *sk)
|
||||||
|
|
||||||
if(addr == NULL)
|
if(addr == NULL)
|
||||||
sprintf(s, "No address");
|
sprintf(s, "No address");
|
||||||
else if(inet_ntop(sk->any.sa_family, addr, s, sizeof (s)) == NULL)
|
else if(inet_ntop(sk->any.sa_family, addr, &s[v6], sizeof (s) - v6) == NULL)
|
||||||
sprintf(s, "Unknown family type, error #%u", errno);
|
sprintf(s, "Unknown family type, error #%u", errno);
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
else if(sk->any.sa_family == AF_INET6 && sk->ip6.sin6_port != 0)
|
else if(sk->any.sa_family == AF_INET6)
|
||||||
|
{
|
||||||
|
s[0] = '[';
|
||||||
|
strcat(s, "]");
|
||||||
|
|
||||||
|
if (sk->ip6.sin6_port != 0)
|
||||||
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
|
strcat(s, va(":%d", ntohs(sk->ip6.sin6_port)));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0)
|
else if(sk->any.sa_family == AF_INET && sk->ip4.sin_port != 0)
|
||||||
strcat(s, va(":%d", ntohs(sk->ip4.sin_port)));
|
strcat(s, va(":%d", ntohs(sk->ip4.sin_port)));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if (sk->any.sa_family == AF_INET)
|
if (sk->any.sa_family == AF_INET)
|
||||||
{
|
{
|
||||||
|
@ -401,7 +414,7 @@ static boolean SOCK_cmpaddr(mysockaddr_t *a, mysockaddr_t *b, UINT8 mask)
|
||||||
&& (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port));
|
&& (b->ip4.sin_port == 0 || (a->ip4.sin_port == b->ip4.sin_port));
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
else if (b->any.sa_family == AF_INET6)
|
else if (b->any.sa_family == AF_INET6)
|
||||||
return memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr))
|
return !memcmp(&a->ip6.sin6_addr, &b->ip6.sin6_addr, sizeof(b->ip6.sin6_addr))
|
||||||
&& (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port));
|
&& (b->ip6.sin6_port == 0 || (a->ip6.sin6_port == b->ip6.sin6_port));
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
@ -692,8 +705,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
unsigned long trueval = true;
|
unsigned long trueval = true;
|
||||||
#endif
|
#endif
|
||||||
mysockaddr_t straddr;
|
mysockaddr_t straddr;
|
||||||
struct sockaddr_in sin;
|
socklen_t len = sizeof(straddr);
|
||||||
socklen_t len = sizeof(sin);
|
|
||||||
|
|
||||||
if (s == (SOCKET_TYPE)ERRSOCKET)
|
if (s == (SOCKET_TYPE)ERRSOCKET)
|
||||||
return (SOCKET_TYPE)ERRSOCKET;
|
return (SOCKET_TYPE)ERRSOCKET;
|
||||||
|
@ -711,14 +723,12 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
straddr.any = *addr;
|
memcpy(&straddr, addr, addrlen);
|
||||||
I_OutputMsg("Binding to %s\n", SOCK_AddrToStr(&straddr));
|
I_OutputMsg("Binding to %s\n", SOCK_AddrToStr(&straddr));
|
||||||
|
|
||||||
if (family == AF_INET)
|
if (family == AF_INET)
|
||||||
{
|
{
|
||||||
mysockaddr_t tmpaddr;
|
if (straddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY))
|
||||||
tmpaddr.any = *addr ;
|
|
||||||
if (tmpaddr.ip4.sin_addr.s_addr == htonl(INADDR_ANY))
|
|
||||||
{
|
{
|
||||||
opt = true;
|
opt = true;
|
||||||
opts = (socklen_t)sizeof(opt);
|
opts = (socklen_t)sizeof(opt);
|
||||||
|
@ -735,7 +745,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
else if (family == AF_INET6)
|
else if (family == AF_INET6)
|
||||||
{
|
{
|
||||||
if (memcmp(addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
|
if (memcmp(&straddr.ip6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0) //IN6_ARE_ADDR_EQUAL
|
||||||
{
|
{
|
||||||
opt = true;
|
opt = true;
|
||||||
opts = (socklen_t)sizeof(opt);
|
opts = (socklen_t)sizeof(opt);
|
||||||
|
@ -745,7 +755,7 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
// make it IPv6 ony
|
// make it IPv6 ony
|
||||||
opt = true;
|
opt = true;
|
||||||
opts = (socklen_t)sizeof(opt);
|
opts = (socklen_t)sizeof(opt);
|
||||||
if (setsockopt(s, SOL_SOCKET, IPV6_V6ONLY, (char *)&opt, opts))
|
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&opt, opts))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore
|
CONS_Alert(CONS_WARNING, M_GetText("Could not limit IPv6 bind\n")); // I do not care anymore
|
||||||
}
|
}
|
||||||
|
@ -787,10 +797,17 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
|
||||||
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
|
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getsockname(s, (struct sockaddr *)&sin, &len) == -1)
|
if (getsockname(s, &straddr.any, &len) == -1)
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n"));
|
CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n"));
|
||||||
else
|
else
|
||||||
current_port = (UINT16)ntohs(sin.sin_port);
|
{
|
||||||
|
if (family == AF_INET)
|
||||||
|
current_port = (UINT16)ntohs(straddr.ip4.sin_port);
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
current_port = (UINT16)ntohs(straddr.ip6.sin6_port);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -801,7 +818,7 @@ static boolean UDP_Socket(void)
|
||||||
struct my_addrinfo *ai, *runp, hints;
|
struct my_addrinfo *ai, *runp, hints;
|
||||||
int gaie;
|
int gaie;
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
const INT32 b_ipv6 = M_CheckParm("-ipv6");
|
const INT32 b_ipv6 = !M_CheckParm("-noipv6");
|
||||||
#endif
|
#endif
|
||||||
const char *serv;
|
const char *serv;
|
||||||
|
|
||||||
|
@ -1105,6 +1122,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||||
SINT8 newnode = -1;
|
SINT8 newnode = -1;
|
||||||
struct my_addrinfo *ai = NULL, *runp, hints;
|
struct my_addrinfo *ai = NULL, *runp, hints;
|
||||||
int gaie;
|
int gaie;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
if (!port || !port[0])
|
if (!port || !port[0])
|
||||||
port = DEFAULTPORT;
|
port = DEFAULTPORT;
|
||||||
|
@ -1132,13 +1150,24 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||||
|
|
||||||
while (runp != NULL)
|
while (runp != NULL)
|
||||||
{
|
{
|
||||||
// find ip of the server
|
// test ip address of server
|
||||||
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
|
for (i = 0; i < mysocketses; ++i)
|
||||||
|
{
|
||||||
|
/* sendto tests that there is a network to this
|
||||||
|
address */
|
||||||
|
if (runp->ai_addr->sa_family == myfamily[i] &&
|
||||||
|
sendto(mysockets[i], NULL, 0, 0,
|
||||||
|
runp->ai_addr, runp->ai_addrlen) == 0)
|
||||||
{
|
{
|
||||||
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < mysocketses)
|
||||||
runp = runp->ai_next;
|
runp = runp->ai_next;
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
I_freeaddrinfo(ai);
|
I_freeaddrinfo(ai);
|
||||||
return newnode;
|
return newnode;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
// Copyright (C) 2020-2022 by James R.
|
// Copyright (C) 2020-2023 by James R.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -61,7 +61,7 @@ static CV_PossibleValue_t masterserver_update_rate_cons_t[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://mb.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange);
|
consvar_t cv_masterserver = CVAR_INIT ("masterserver", "https://mb.srb2.org/MS/0", CV_SAVE|CV_CALL, NULL, MasterServer_OnChange);
|
||||||
consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT, NULL, Update_parameters);
|
consvar_t cv_servername = CVAR_INIT ("servername", "SRB2 server", CV_SAVE|CV_NETVAR|CV_CALL|CV_NOINIT|CV_ALLOWLUA, NULL, Update_parameters);
|
||||||
|
|
||||||
consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters);
|
consvar_t cv_masterserver_update_rate = CVAR_INIT ("masterserver_update_rate", "15", CV_SAVE|CV_CALL|CV_NOINIT, masterserver_update_rate_cons_t, Update_parameters);
|
||||||
|
|
||||||
|
@ -95,8 +95,8 @@ void AddMServCommands(void)
|
||||||
CV_RegisterVar(&cv_masterserver_token);
|
CV_RegisterVar(&cv_masterserver_token);
|
||||||
CV_RegisterVar(&cv_servername);
|
CV_RegisterVar(&cv_servername);
|
||||||
#ifdef MASTERSERVER
|
#ifdef MASTERSERVER
|
||||||
COM_AddCommand("listserv", Command_Listserv_f);
|
COM_AddCommand("listserv", Command_Listserv_f, 0);
|
||||||
COM_AddCommand("masterserver_update", Update_parameters); // allows people to updates manually in case you were delisted by accident
|
COM_AddCommand("masterserver_update", Update_parameters, COM_LUA); // allows people to updates manually in case you were delisted by accident
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
// Copyright (C) 2020-2022 by James R.
|
// Copyright (C) 2020-2023 by James R.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -33,7 +33,7 @@ typedef union
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
msg_header_t header;
|
msg_header_t header;
|
||||||
char ip[16];
|
char ip[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
|
||||||
char port[8];
|
char port[8];
|
||||||
char name[32];
|
char name[32];
|
||||||
INT32 room;
|
INT32 room;
|
||||||
|
|
|
@ -321,22 +321,18 @@ void SV_WriteNetCommandsForTic(tic_t tic, UINT8 **buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CL_CopyNetCommandsFromServerPacket(tic_t tic)
|
void CL_CopyNetCommandsFromServerPacket(tic_t tic, UINT8 **buf)
|
||||||
{
|
{
|
||||||
servertics_pak *packet = &netbuffer->u.serverpak;
|
UINT8 numcmds = *(*buf)++;
|
||||||
UINT8 *cmds = (UINT8*)&packet->cmds[packet->numslots * packet->numtics];
|
|
||||||
UINT8 numcmds;
|
|
||||||
|
|
||||||
numcmds = *cmds++;
|
|
||||||
|
|
||||||
for (UINT32 i = 0; i < numcmds; i++)
|
for (UINT32 i = 0; i < numcmds; i++)
|
||||||
{
|
{
|
||||||
INT32 playernum = *cmds++; // playernum
|
INT32 playernum = *(*buf)++; // playernum
|
||||||
size_t size = cmds[0]+1;
|
size_t size = (*buf)[0]+1;
|
||||||
|
|
||||||
if (tic >= gametic) // Don't copy old net commands
|
if (tic >= gametic) // Don't copy old net commands
|
||||||
M_Memcpy(D_GetTextcmd(tic, playernum), cmds, size);
|
M_Memcpy(D_GetTextcmd(tic, playernum), *buf, size);
|
||||||
cmds += size;
|
*buf += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ size_t TotalTextCmdPerTic(tic_t tic);
|
||||||
|
|
||||||
void PT_TextCmd(SINT8 node, INT32 netconsole);
|
void PT_TextCmd(SINT8 node, INT32 netconsole);
|
||||||
void SV_WriteNetCommandsForTic(tic_t tic, UINT8 **buf);
|
void SV_WriteNetCommandsForTic(tic_t tic, UINT8 **buf);
|
||||||
void CL_CopyNetCommandsFromServerPacket(tic_t tic);
|
void CL_CopyNetCommandsFromServerPacket(tic_t tic, UINT8 **buf);
|
||||||
void CL_SendNetCommands(void);
|
void CL_SendNetCommands(void);
|
||||||
void SendKick(UINT8 playernum, UINT8 msg);
|
void SendKick(UINT8 playernum, UINT8 msg);
|
||||||
void SendKicksForNode(SINT8 node, UINT8 msg);
|
void SendKicksForNode(SINT8 node, UINT8 msg);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -72,6 +72,8 @@ typedef enum
|
||||||
PT_ASKLUAFILE, // Client telling the server they don't have the file
|
PT_ASKLUAFILE, // Client telling the server they don't have the file
|
||||||
PT_HASLUAFILE, // Client telling the server they have the file
|
PT_HASLUAFILE, // Client telling the server they have the file
|
||||||
|
|
||||||
|
PT_BASICKEEPALIVE, // Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
|
||||||
|
|
||||||
// Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility.
|
// Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility.
|
||||||
|
|
||||||
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
|
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
|
||||||
|
@ -143,6 +145,7 @@ typedef struct
|
||||||
|
|
||||||
UINT8 gametype;
|
UINT8 gametype;
|
||||||
UINT8 modifiedgame;
|
UINT8 modifiedgame;
|
||||||
|
UINT8 usedCheats;
|
||||||
|
|
||||||
char server_context[8]; // Unique context id, generated at server startup.
|
char server_context[8]; // Unique context id, generated at server startup.
|
||||||
} ATTRPACK serverconfig_pak;
|
} ATTRPACK serverconfig_pak;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -39,10 +39,10 @@ char playeraddress[MAXPLAYERS][64];
|
||||||
|
|
||||||
consvar_t cv_showjoinaddress = CVAR_INIT ("showjoinaddress", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_showjoinaddress = CVAR_INIT ("showjoinaddress", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
|
||||||
|
|
||||||
consvar_t cv_allownewplayer = CVAR_INIT ("allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL);
|
consvar_t cv_allownewplayer = CVAR_INIT ("allowjoin", "On", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, CV_OnOff, NULL);
|
||||||
|
|
||||||
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}};
|
||||||
consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_SAVE|CV_NETVAR, maxplayers_cons_t, NULL);
|
consvar_t cv_maxplayers = CVAR_INIT ("maxplayers", "8", CV_SAVE|CV_NETVAR|CV_ALLOWLUA, maxplayers_cons_t, NULL);
|
||||||
|
|
||||||
static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}};
|
static CV_PossibleValue_t joindelay_cons_t[] = {{1, "MIN"}, {3600, "MAX"}, {0, "Off"}, {0, NULL}};
|
||||||
consvar_t cv_joindelay = CVAR_INIT ("joindelay", "10", CV_SAVE|CV_NETVAR, joindelay_cons_t, NULL);
|
consvar_t cv_joindelay = CVAR_INIT ("joindelay", "10", CV_SAVE|CV_NETVAR, joindelay_cons_t, NULL);
|
||||||
|
@ -52,9 +52,9 @@ consvar_t cv_rejointimeout = CVAR_INIT ("rejointimeout", "2", CV_SAVE|CV_NETVAR|
|
||||||
|
|
||||||
static INT32 FindRejoinerNum(SINT8 node)
|
static INT32 FindRejoinerNum(SINT8 node)
|
||||||
{
|
{
|
||||||
char strippednodeaddress[64];
|
char addressbuffer[64];
|
||||||
const char *nodeaddress;
|
const char *nodeaddress;
|
||||||
char *port;
|
const char *strippednodeaddress;
|
||||||
|
|
||||||
// Make sure there is no dead dress before proceeding to the stripping
|
// Make sure there is no dead dress before proceeding to the stripping
|
||||||
if (!I_GetNodeAddress)
|
if (!I_GetNodeAddress)
|
||||||
|
@ -64,10 +64,8 @@ static INT32 FindRejoinerNum(SINT8 node)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// Strip the address of its port
|
// Strip the address of its port
|
||||||
strcpy(strippednodeaddress, nodeaddress);
|
strcpy(addressbuffer, nodeaddress);
|
||||||
port = strchr(strippednodeaddress, ':');
|
strippednodeaddress = I_NetSplitAddress(addressbuffer, NULL);
|
||||||
if (port)
|
|
||||||
*port = '\0';
|
|
||||||
|
|
||||||
// Check if any player matches the stripped address
|
// Check if any player matches the stripped address
|
||||||
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
for (INT32 i = 0; i < MAXPLAYERS; i++)
|
||||||
|
@ -110,8 +108,9 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||||
netbuffer->u.serverinfo.time = (tic_t)LONG(servertime);
|
netbuffer->u.serverinfo.time = (tic_t)LONG(servertime);
|
||||||
netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime);
|
netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime);
|
||||||
|
|
||||||
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
|
// Exclude bots from both counts
|
||||||
netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value;
|
netbuffer->u.serverinfo.numberofplayer = (UINT8)(D_NumPlayers() - D_NumBots());
|
||||||
|
netbuffer->u.serverinfo.maxplayer = (UINT8)(cv_maxplayers.value - D_NumBots());
|
||||||
|
|
||||||
netbuffer->u.serverinfo.refusereason = GetRefuseReason(node);
|
netbuffer->u.serverinfo.refusereason = GetRefuseReason(node);
|
||||||
|
|
||||||
|
@ -237,6 +236,7 @@ static boolean SV_SendServerConfig(INT32 node)
|
||||||
netbuffer->u.servercfg.gamestate = (UINT8)gamestate;
|
netbuffer->u.servercfg.gamestate = (UINT8)gamestate;
|
||||||
netbuffer->u.servercfg.gametype = (UINT8)gametype;
|
netbuffer->u.servercfg.gametype = (UINT8)gametype;
|
||||||
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
|
netbuffer->u.servercfg.modifiedgame = (UINT8)modifiedgame;
|
||||||
|
netbuffer->u.servercfg.usedCheats = (UINT8)usedCheats;
|
||||||
|
|
||||||
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
memcpy(netbuffer->u.servercfg.server_context, server_context, 8);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
@ -100,9 +100,9 @@ void D_ResetTiccmds(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check ticcmd for "speed hacks"
|
// Check ticcmd for "speed hacks"
|
||||||
static void CheckTiccmdHacks(INT32 playernum)
|
static void CheckTiccmdHacks(INT32 playernum, tic_t tic)
|
||||||
{
|
{
|
||||||
ticcmd_t *cmd = &netcmds[maketic%BACKUPTICS][playernum];
|
ticcmd_t *cmd = &netcmds[tic%BACKUPTICS][playernum];
|
||||||
if (cmd->forwardmove > MAXPLMOVE || cmd->forwardmove < -MAXPLMOVE
|
if (cmd->forwardmove > MAXPLMOVE || cmd->forwardmove < -MAXPLMOVE
|
||||||
|| cmd->sidemove > MAXPLMOVE || cmd->sidemove < -MAXPLMOVE)
|
|| cmd->sidemove > MAXPLMOVE || cmd->sidemove < -MAXPLMOVE)
|
||||||
{
|
{
|
||||||
|
@ -177,31 +177,43 @@ void PT_ClientCmd(SINT8 nodenum, INT32 netconsole)
|
||||||
// Update the nettics
|
// Update the nettics
|
||||||
node->tic = realend;
|
node->tic = realend;
|
||||||
|
|
||||||
// Don't do anything for packets of type NODEKEEPALIVE?
|
// This should probably still timeout though, as the node should always have a player 1 number
|
||||||
if (netconsole == -1 || netbuffer->packettype == PT_NODEKEEPALIVE
|
if (netconsole == -1)
|
||||||
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// As long as clients send valid ticcmds, the server can keep running, so reset the timeout
|
// As long as clients send valid ticcmds, the server can keep running, so reset the timeout
|
||||||
/// \todo Use a separate cvar for that kind of timeout?
|
/// \todo Use a separate cvar for that kind of timeout?
|
||||||
node->freezetimeout = I_GetTime() + connectiontimeout;
|
node->freezetimeout = I_GetTime() + connectiontimeout;
|
||||||
|
|
||||||
|
// Don't do anything for packets of type NODEKEEPALIVE?
|
||||||
|
// Sryder 2018/07/01: Update the freezetimeout still!
|
||||||
|
if (netbuffer->packettype == PT_NODEKEEPALIVE
|
||||||
|
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If we've alredy received a ticcmd for this tic, just submit it for the next one.
|
||||||
|
tic_t faketic = maketic;
|
||||||
|
if ((!!(netcmds[maketic % BACKUPTICS][netconsole].angleturn & TICCMD_RECEIVED))
|
||||||
|
&& (maketic - firstticstosend < BACKUPTICS - 1))
|
||||||
|
faketic++;
|
||||||
|
|
||||||
// Copy ticcmd
|
// Copy ticcmd
|
||||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
G_MoveTiccmd(&netcmds[faketic%BACKUPTICS][netconsole], &netbuffer->u.clientpak.cmd, 1);
|
||||||
|
|
||||||
// Splitscreen cmd
|
// Splitscreen cmd
|
||||||
if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
|
if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
|
||||||
&& node->player2 >= 0)
|
&& node->player2 >= 0)
|
||||||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)node->player2],
|
G_MoveTiccmd(&netcmds[faketic%BACKUPTICS][(UINT8)node->player2],
|
||||||
&netbuffer->u.client2pak.cmd2, 1);
|
&netbuffer->u.client2pak.cmd2, 1);
|
||||||
|
|
||||||
CheckTiccmdHacks(netconsole);
|
CheckTiccmdHacks(netconsole, faketic);
|
||||||
CheckConsistancy(nodenum, realstart);
|
CheckConsistancy(nodenum, realstart);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PT_ServerTics(SINT8 node, INT32 netconsole)
|
void PT_ServerTics(SINT8 node, INT32 netconsole)
|
||||||
{
|
{
|
||||||
tic_t realend, realstart;
|
tic_t realend, realstart;
|
||||||
|
servertics_pak *packet = &netbuffer->u.serverpak;
|
||||||
|
|
||||||
if (!netnodes[node].ingame)
|
if (!netnodes[node].ingame)
|
||||||
{
|
{
|
||||||
|
@ -223,15 +235,16 @@ void PT_ServerTics(SINT8 node, INT32 netconsole)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
realstart = netbuffer->u.serverpak.starttic;
|
realstart = packet->starttic;
|
||||||
realend = realstart + netbuffer->u.serverpak.numtics;
|
realend = realstart + packet->numtics;
|
||||||
|
|
||||||
realend = min(realend, gametic + CLIENTBACKUPTICS);
|
realend = min(realend, gametic + CLIENTBACKUPTICS);
|
||||||
cl_packetmissed = realstart > neededtic;
|
cl_packetmissed = realstart > neededtic;
|
||||||
|
|
||||||
if (realstart <= neededtic && realend > neededtic)
|
if (realstart <= neededtic && realend > neededtic)
|
||||||
{
|
{
|
||||||
UINT8 *pak = (UINT8 *)&netbuffer->u.serverpak.cmds;
|
UINT8 *pak = (UINT8 *)&packet->cmds;
|
||||||
|
UINT8 *txtpak = (UINT8 *)&packet->cmds[packet->numslots * packet->numtics];
|
||||||
|
|
||||||
for (tic_t i = realstart; i < realend; i++)
|
for (tic_t i = realstart; i < realend; i++)
|
||||||
{
|
{
|
||||||
|
@ -240,9 +253,9 @@ void PT_ServerTics(SINT8 node, INT32 netconsole)
|
||||||
|
|
||||||
// copy the tics
|
// copy the tics
|
||||||
pak = G_ScpyTiccmd(netcmds[i%BACKUPTICS], pak,
|
pak = G_ScpyTiccmd(netcmds[i%BACKUPTICS], pak,
|
||||||
netbuffer->u.serverpak.numslots*sizeof (ticcmd_t));
|
packet->numslots*sizeof (ticcmd_t));
|
||||||
|
|
||||||
CL_CopyNetCommandsFromServerPacket(i);
|
CL_CopyNetCommandsFromServerPacket(i, &txtpak);
|
||||||
}
|
}
|
||||||
|
|
||||||
neededtic = realend;
|
neededtic = realend;
|
||||||
|
@ -257,35 +270,39 @@ void PT_ServerTics(SINT8 node, INT32 netconsole)
|
||||||
void CL_SendClientCmd(void)
|
void CL_SendClientCmd(void)
|
||||||
{
|
{
|
||||||
size_t packetsize = 0;
|
size_t packetsize = 0;
|
||||||
|
boolean mis = false;
|
||||||
|
|
||||||
netbuffer->packettype = PT_CLIENTCMD;
|
netbuffer->packettype = PT_CLIENTCMD;
|
||||||
|
|
||||||
if (cl_packetmissed)
|
if (cl_packetmissed)
|
||||||
netbuffer->packettype++;
|
{
|
||||||
|
netbuffer->packettype = PT_CLIENTMIS;
|
||||||
|
mis = true;
|
||||||
|
}
|
||||||
|
|
||||||
netbuffer->u.clientpak.resendfrom = (UINT8)(neededtic & UINT8_MAX);
|
netbuffer->u.clientpak.resendfrom = (UINT8)(neededtic & UINT8_MAX);
|
||||||
netbuffer->u.clientpak.client_tic = (UINT8)(gametic & UINT8_MAX);
|
netbuffer->u.clientpak.client_tic = (UINT8)(gametic & UINT8_MAX);
|
||||||
|
|
||||||
if (gamestate == GS_WAITINGPLAYERS)
|
if (gamestate == GS_WAITINGPLAYERS)
|
||||||
{
|
{
|
||||||
// Send PT_NODEKEEPALIVE packet
|
// Send PT_NODEKEEPALIVE packet
|
||||||
netbuffer->packettype += 4;
|
netbuffer->packettype = (mis ? PT_NODEKEEPALIVEMIS : PT_NODEKEEPALIVE);
|
||||||
packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16);
|
packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16);
|
||||||
HSendPacket(servernode, false, 0, packetsize);
|
HSendPacket(servernode, false, 0, packetsize);
|
||||||
}
|
}
|
||||||
else if (gamestate != GS_NULL && (addedtogame || dedicated))
|
else if (gamestate != GS_NULL && (addedtogame || dedicated))
|
||||||
{
|
{
|
||||||
|
packetsize = sizeof (clientcmd_pak);
|
||||||
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1);
|
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1);
|
||||||
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]);
|
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]);
|
||||||
|
|
||||||
// Send a special packet with 2 cmd for splitscreen
|
// Send a special packet with 2 cmd for splitscreen
|
||||||
if (splitscreen || botingame)
|
if (splitscreen || botingame)
|
||||||
{
|
{
|
||||||
netbuffer->packettype += 2;
|
netbuffer->packettype = (mis ? PT_CLIENT2MIS : PT_CLIENT2CMD);
|
||||||
G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1);
|
|
||||||
packetsize = sizeof (client2cmd_pak);
|
packetsize = sizeof (client2cmd_pak);
|
||||||
|
G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
packetsize = sizeof (clientcmd_pak);
|
|
||||||
|
|
||||||
HSendPacket(servernode, false, 0, packetsize);
|
HSendPacket(servernode, false, 0, packetsize);
|
||||||
}
|
}
|
||||||
|
@ -346,7 +363,7 @@ void SV_SendTics(void)
|
||||||
for (INT32 n = 1; n < MAXNETNODES; n++)
|
for (INT32 n = 1; n < MAXNETNODES; n++)
|
||||||
if (netnodes[n].ingame)
|
if (netnodes[n].ingame)
|
||||||
{
|
{
|
||||||
netnode_t *node = netnodes[n];
|
netnode_t *node = &netnodes[n];
|
||||||
|
|
||||||
// assert node->supposedtic>=node->tic
|
// assert node->supposedtic>=node->tic
|
||||||
realfirsttic = node->supposedtic;
|
realfirsttic = node->supposedtic;
|
||||||
|
@ -408,7 +425,7 @@ void Local_Maketic(INT32 realtics)
|
||||||
// and G_MapEventsToControls
|
// and G_MapEventsToControls
|
||||||
if (!dedicated)
|
if (!dedicated)
|
||||||
rendergametic = gametic;
|
rendergametic = gametic;
|
||||||
// translate inputs (keyboard/mouse/gamepad) into game controls
|
// translate inputs (keyboard/mouse/joystick) into game controls
|
||||||
G_BuildTiccmd(&localcmds, realtics, 1);
|
G_BuildTiccmd(&localcmds, realtics, 1);
|
||||||
if (splitscreen || botingame)
|
if (splitscreen || botingame)
|
||||||
G_BuildTiccmd(&localcmds2, realtics, 2);
|
G_BuildTiccmd(&localcmds2, realtics, 2);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SONIC ROBO BLAST 2
|
// SONIC ROBO BLAST 2
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
// Copyright (C) 1999-2023 by Sonic Team Junior.
|
||||||
//
|
//
|
||||||
// This program is free software distributed under the
|
// This program is free software distributed under the
|
||||||
// terms of the GNU General Public License, version 2.
|
// terms of the GNU General Public License, version 2.
|
||||||
|
|
70
src/snake.c
70
src/snake.c
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include "snake.h"
|
#include "snake.h"
|
||||||
#include "g_input.h"
|
#include "g_input.h"
|
||||||
|
#include "g_game.h"
|
||||||
|
#include "i_joy.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
@ -67,6 +69,9 @@ typedef struct snake_s
|
||||||
enum bonustype_s bonustype;
|
enum bonustype_s bonustype;
|
||||||
UINT8 bonusx;
|
UINT8 bonusx;
|
||||||
UINT8 bonusy;
|
UINT8 bonusy;
|
||||||
|
|
||||||
|
event_t *joyevents[MAXEVENTS];
|
||||||
|
UINT16 joyeventcount;
|
||||||
} snake_t;
|
} snake_t;
|
||||||
|
|
||||||
static const char *bonuspatches[] = {
|
static const char *bonuspatches[] = {
|
||||||
|
@ -113,6 +118,8 @@ static void Initialise(snake_t *snake)
|
||||||
snake->appley = M_RandomKey(NUM_BLOCKS_Y);
|
snake->appley = M_RandomKey(NUM_BLOCKS_Y);
|
||||||
|
|
||||||
snake->bonustype = BONUS_NONE;
|
snake->bonustype = BONUS_NONE;
|
||||||
|
|
||||||
|
snake->joyeventcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT8 GetOppositeDir(UINT8 dir)
|
static UINT8 GetOppositeDir(UINT8 dir)
|
||||||
|
@ -160,18 +167,19 @@ void Snake_Update(void *opaque)
|
||||||
UINT8 oldx, oldy;
|
UINT8 oldx, oldy;
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
UINT16 joystate = 0;
|
UINT16 joystate = 0;
|
||||||
|
static INT32 pjoyx = 0, pjoyy = 0;
|
||||||
|
|
||||||
snake_t *snake = opaque;
|
snake_t *snake = opaque;
|
||||||
|
|
||||||
// Handle retry
|
// Handle retry
|
||||||
if (snake->gameover && (G_PlayerInputDown(0, GC_JUMP) || gamekeydown[KEY_ENTER]))
|
if (snake->gameover && (PLAYER1INPUTDOWN(GC_JUMP) || gamekeydown[KEY_ENTER]))
|
||||||
{
|
{
|
||||||
Initialise(snake);
|
Initialise(snake);
|
||||||
snake->pausepressed = true; // Avoid accidental pause on respawn
|
snake->pausepressed = true; // Avoid accidental pause on respawn
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle pause
|
// Handle pause
|
||||||
if (G_PlayerInputDown(0, GC_PAUSE) || gamekeydown[KEY_ENTER])
|
if (PLAYER1INPUTDOWN(GC_PAUSE) || gamekeydown[KEY_ENTER])
|
||||||
{
|
{
|
||||||
if (!snake->pausepressed)
|
if (!snake->pausepressed)
|
||||||
snake->paused = !snake->paused;
|
snake->paused = !snake->paused;
|
||||||
|
@ -190,23 +198,58 @@ void Snake_Update(void *opaque)
|
||||||
oldx = snake->snakex[1];
|
oldx = snake->snakex[1];
|
||||||
oldy = snake->snakey[1];
|
oldy = snake->snakey[1];
|
||||||
|
|
||||||
|
// Process the input events in here dear lord
|
||||||
|
for (UINT16 j = 0; j < snake->joyeventcount; j++)
|
||||||
|
{
|
||||||
|
event_t *ev = snake->joyevents[j];
|
||||||
|
const INT32 jdeadzone = (JOYAXISRANGE * cv_digitaldeadzone.value) / FRACUNIT;
|
||||||
|
if (ev->y != INT32_MAX)
|
||||||
|
{
|
||||||
|
if (Joystick.bGamepadStyle || abs(ev->y) > jdeadzone)
|
||||||
|
{
|
||||||
|
if (ev->y < 0 && pjoyy >= 0)
|
||||||
|
joystate = 1;
|
||||||
|
else if (ev->y > 0 && pjoyy <= 0)
|
||||||
|
joystate = 2;
|
||||||
|
pjoyy = ev->y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pjoyy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev->x != INT32_MAX)
|
||||||
|
{
|
||||||
|
if (Joystick.bGamepadStyle || abs(ev->x) > jdeadzone)
|
||||||
|
{
|
||||||
|
if (ev->x < 0 && pjoyx >= 0)
|
||||||
|
joystate = 3;
|
||||||
|
else if (ev->x > 0 && pjoyx <= 0)
|
||||||
|
joystate = 4;
|
||||||
|
pjoyx = ev->x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pjoyx = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snake->joyeventcount = 0;
|
||||||
|
|
||||||
// Update direction
|
// Update direction
|
||||||
if (G_PlayerInputDown(0, GC_STRAFELEFT) || gamekeydown[KEY_LEFTARROW] || joystate == 3)
|
if (PLAYER1INPUTDOWN(GC_STRAFELEFT) || gamekeydown[KEY_LEFTARROW] || joystate == 3)
|
||||||
{
|
{
|
||||||
if (snake->snakelength < 2 || x <= oldx)
|
if (snake->snakelength < 2 || x <= oldx)
|
||||||
snake->snakedir[0] = 1;
|
snake->snakedir[0] = 1;
|
||||||
}
|
}
|
||||||
else if (G_PlayerInputDown(0, GC_STRAFERIGHT) || gamekeydown[KEY_RIGHTARROW] || joystate == 4)
|
else if (PLAYER1INPUTDOWN(GC_STRAFERIGHT) || gamekeydown[KEY_RIGHTARROW] || joystate == 4)
|
||||||
{
|
{
|
||||||
if (snake->snakelength < 2 || x >= oldx)
|
if (snake->snakelength < 2 || x >= oldx)
|
||||||
snake->snakedir[0] = 2;
|
snake->snakedir[0] = 2;
|
||||||
}
|
}
|
||||||
else if (G_PlayerInputDown(0, GC_FORWARD) || gamekeydown[KEY_UPARROW] || joystate == 1)
|
else if (PLAYER1INPUTDOWN(GC_FORWARD) || gamekeydown[KEY_UPARROW] || joystate == 1)
|
||||||
{
|
{
|
||||||
if (snake->snakelength < 2 || y <= oldy)
|
if (snake->snakelength < 2 || y <= oldy)
|
||||||
snake->snakedir[0] = 3;
|
snake->snakedir[0] = 3;
|
||||||
}
|
}
|
||||||
else if (G_PlayerInputDown(0, GC_BACKWARD) || gamekeydown[KEY_DOWNARROW] || joystate == 2)
|
else if (PLAYER1INPUTDOWN(GC_BACKWARD) || gamekeydown[KEY_DOWNARROW] || joystate == 2)
|
||||||
{
|
{
|
||||||
if (snake->snakelength < 2 || y >= oldy)
|
if (snake->snakelength < 2 || y >= oldy)
|
||||||
snake->snakedir[0] = 4;
|
snake->snakedir[0] = 4;
|
||||||
|
@ -533,3 +576,18 @@ void Snake_Free(void **opaque)
|
||||||
*opaque = NULL;
|
*opaque = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// I'm screaming the hack is clean - ashi
|
||||||
|
boolean Snake_JoyGrabber(void *opaque, event_t *ev)
|
||||||
|
{
|
||||||
|
snake_t *snake = opaque;
|
||||||
|
|
||||||
|
if (ev->type == ev_joystick && ev->key == 0)
|
||||||
|
{
|
||||||
|
snake->joyevents[snake->joyeventcount] = ev;
|
||||||
|
snake->joyeventcount++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -12,9 +12,12 @@
|
||||||
#ifndef __SNAKE__
|
#ifndef __SNAKE__
|
||||||
#define __SNAKE__
|
#define __SNAKE__
|
||||||
|
|
||||||
|
#include "d_event.h"
|
||||||
|
|
||||||
void Snake_Allocate(void **opaque);
|
void Snake_Allocate(void **opaque);
|
||||||
void Snake_Update(void *opaque);
|
void Snake_Update(void *opaque);
|
||||||
void Snake_Draw(void *opaque);
|
void Snake_Draw(void *opaque);
|
||||||
void Snake_Free(void **opaque);
|
void Snake_Free(void **opaque);
|
||||||
|
boolean Snake_JoyGrabber(void *opaque, event_t *ev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue