mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-24 10:40:46 +00:00
- Packet code implementation (merge from private c/s repo), world updates are now synced through snapshots. See tag SVN_SyncPoint_Dec2018 on master of the other repo.
- "Scratch pad" sprites implementation, to avoid desyncs in sprite indexes, clients will insert temporary sprites which are cleared out when they receive the next snapshot from the server. - Patches from Striker which fix player stomping frag counts, the accept button when hosting a game through the menu, and a "noffire" command line parameter. - Patches from NY00123: t_data sync optimizations to improve some jittery behavior on the client side. git-svn-id: https://svn.eduke32.com/eduke32@7242 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
7bd5fa42ee
commit
87cf4495bf
14 changed files with 5200 additions and 1964 deletions
|
@ -1240,6 +1240,7 @@ int32_t rayintersect(int32_t x1, int32_t y1, int32_t z1, int32_t vx, int32_t vy,
|
|||
#if !defined NETCODE_DISABLE
|
||||
void do_insertsprite_at_headofstat(int16_t spritenum, int16_t statnum);
|
||||
int32_t insertspritestat(int16_t statnum);
|
||||
void do_deletespritestat(int16_t deleteme);
|
||||
void do_insertsprite_at_headofsect(int16_t spritenum, int16_t sectnum);
|
||||
void do_deletespritesect(int16_t deleteme);
|
||||
#endif
|
||||
|
|
|
@ -7262,7 +7262,7 @@ LISTFN_STATIC int32_t insertspritestat(int16_t statnum)
|
|||
}
|
||||
|
||||
// remove sprite 'deleteme' from its status list
|
||||
static void do_deletespritestat(int16_t deleteme)
|
||||
LISTFN_STATIC void do_deletespritestat(int16_t deleteme)
|
||||
{
|
||||
int32_t const sectnum = sprite[deleteme].statnum;
|
||||
int32_t const prev = prevspritestat[deleteme];
|
||||
|
|
|
@ -422,6 +422,9 @@ int32_t A_MoveSpriteClipdist(int32_t spriteNum, vec3_t const * const change, uin
|
|||
int const isEnemy = A_CheckEnemySprite(pSprite);
|
||||
vec2_t const oldPos = *(vec2_t *)pSprite;
|
||||
|
||||
// check to make sure the netcode didn't leave a deleted sprite in the sprite lists.
|
||||
Bassert(pSprite->sectnum < MAXSECTORS);
|
||||
|
||||
if (pSprite->statnum == STAT_MISC || (isEnemy && pSprite->xrepeat < 4))
|
||||
{
|
||||
pSprite->x += change->x;
|
||||
|
@ -472,6 +475,9 @@ int32_t A_MoveSpriteClipdist(int32_t spriteNum, vec3_t const * const change, uin
|
|||
clipmove((vec3_t *)pSprite, &newSectnum, change->x << 13, change->y << 13, clipDist, ZOFFSET6, ZOFFSET6, clipType);
|
||||
pSprite->z = oldZ;
|
||||
|
||||
// Testing: For some reason the assert below this was tripping for clients
|
||||
EDUKE32_UNUSED int16_t dbg_ClipMoveSectnum = newSectnum;
|
||||
|
||||
if (isEnemy)
|
||||
{
|
||||
// Handle potential stayput condition (map-provided or hard-coded).
|
||||
|
@ -501,6 +507,8 @@ int32_t A_MoveSpriteClipdist(int32_t spriteNum, vec3_t const * const change, uin
|
|||
pSprite->ang += 768;
|
||||
}
|
||||
|
||||
EDUKE32_UNUSED int16_t dbg_newSectnum2 = newSectnum;
|
||||
|
||||
if (newSectnum == -1)
|
||||
{
|
||||
newSectnum = pSprite->sectnum;
|
||||
|
@ -619,19 +627,16 @@ void A_DeleteSprite(int spriteNum)
|
|||
if (sprite[spriteNum].picnum == MUSICANDSFX && actor[spriteNum].t_data[0] == 1)
|
||||
S_StopEnvSound(sprite[spriteNum].lotag, spriteNum);
|
||||
|
||||
// NetAlloc
|
||||
if (Net_IsRelevantSprite(spriteNum))
|
||||
{
|
||||
Net_DeleteSprite(spriteNum);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef NETCODE_DISABLE
|
||||
deletesprite(spriteNum);
|
||||
#else
|
||||
Net_DeleteSprite(spriteNum);
|
||||
#endif
|
||||
}
|
||||
|
||||
void A_AddToDeleteQueue(int spriteNum)
|
||||
{
|
||||
if (g_deleteQueueSize == 0)
|
||||
if (g_netClient || (g_deleteQueueSize == 0)) // [75] Clients should not use SpriteDeletionQueue[] and just set the sprites invisible immediately in A_DeleteSprite
|
||||
{
|
||||
A_DeleteSprite(spriteNum);
|
||||
return;
|
||||
|
@ -1266,11 +1271,11 @@ ACTOR_STATIC void G_MovePlayers(void)
|
|||
{
|
||||
if (otherPlayerDist < 1400 && pPlayer->knee_incs == 0)
|
||||
{
|
||||
// Don't stomp teammates.
|
||||
if (
|
||||
((g_gametypeFlags[ud.coop] & GAMETYPE_TDM) && pPlayer->team != g_player[otherp].ps->team) ||
|
||||
(!(g_gametypeFlags[ud.coop] & GAMETYPE_PLAYERSFRIENDLY) && !(g_gametypeFlags[ud.coop] & GAMETYPE_TDM))
|
||||
)
|
||||
// Don't stomp teammates.
|
||||
if (
|
||||
((g_gametypeFlags[ud.coop] & GAMETYPE_TDM) && pPlayer->team != g_player[otherp].ps->team) ||
|
||||
(!(g_gametypeFlags[ud.coop] & GAMETYPE_PLAYERSFRIENDLY) && !(g_gametypeFlags[ud.coop] & GAMETYPE_TDM))
|
||||
)
|
||||
{
|
||||
pPlayer->knee_incs = 1;
|
||||
pPlayer->weapon_pos = -1;
|
||||
|
|
|
@ -184,30 +184,167 @@ typedef struct
|
|||
#endif
|
||||
} actor_t;
|
||||
|
||||
// this struct needs to match the beginning of actor_t above
|
||||
typedef struct
|
||||
// note: fields in this struct DO NOT have to be in this order,
|
||||
// however if you add something to this struct, please make sure
|
||||
// a field gets added to ActorFields[], otherwise the field
|
||||
// won't get synced over the network!
|
||||
//
|
||||
// I don't think the ActorFields array needs to be in the same order,
|
||||
// need to verify this...
|
||||
typedef struct netactor_s
|
||||
{
|
||||
int32_t t_data[10]; // 40b sometimes used to hold offsets to con code
|
||||
// actor fields
|
||||
//--------------------------------------------
|
||||
int32_t
|
||||
t_data_0,
|
||||
t_data_1,
|
||||
t_data_2,
|
||||
t_data_3,
|
||||
t_data_4,
|
||||
t_data_5,
|
||||
t_data_6,
|
||||
t_data_7,
|
||||
t_data_8,
|
||||
t_data_9;
|
||||
|
||||
#ifdef LUNATIC
|
||||
struct move mv;
|
||||
struct action ac;
|
||||
uint16_t actiontics;
|
||||
uint16_t movflags;
|
||||
|
||||
int32_t
|
||||
hvel,
|
||||
vvel;
|
||||
|
||||
|
||||
int32_t
|
||||
startframe,
|
||||
numframes;
|
||||
|
||||
int32_t
|
||||
viewtype,
|
||||
incval,
|
||||
delay;
|
||||
|
||||
int32_t
|
||||
actiontics;
|
||||
#endif
|
||||
|
||||
int32_t flags; // 4b
|
||||
vec3_t bpos; // 12b
|
||||
int32_t floorz, ceilingz; // 8b
|
||||
vec2_t lastv; // 8b
|
||||
int16_t picnum, ang, extra, owner; // 8b
|
||||
int16_t movflag, tempang, timetosleep; // 6b
|
||||
int16_t stayput;
|
||||
int32_t
|
||||
flags;
|
||||
|
||||
uint8_t cgg, lasttransport;
|
||||
|
||||
spritetype sprite;
|
||||
int16_t netIndex;
|
||||
int32_t
|
||||
bpos_x,
|
||||
bpos_y,
|
||||
bpos_z;
|
||||
|
||||
int32_t
|
||||
floorz,
|
||||
ceilingz,
|
||||
lastvx,
|
||||
lastvy,
|
||||
|
||||
lasttransport,
|
||||
|
||||
picnum,
|
||||
ang,
|
||||
extra,
|
||||
owner,
|
||||
|
||||
movflag,
|
||||
tempang,
|
||||
timetosleep,
|
||||
|
||||
stayput,
|
||||
dispicnum;
|
||||
|
||||
|
||||
#if defined LUNATIC
|
||||
int32_t movflags;
|
||||
#endif
|
||||
|
||||
// note: lightId, lightcount, lightmaxrange are not synchronized between client and server
|
||||
|
||||
int32_t
|
||||
cgg;
|
||||
|
||||
|
||||
// sprite fields
|
||||
//-----------------------------
|
||||
|
||||
int32_t
|
||||
spr_x,
|
||||
spr_y,
|
||||
spr_z,
|
||||
|
||||
spr_cstat,
|
||||
|
||||
spr_picnum,
|
||||
|
||||
spr_shade,
|
||||
|
||||
spr_pal,
|
||||
spr_clipdist,
|
||||
spr_blend,
|
||||
|
||||
spr_xrepeat,
|
||||
spr_yrepeat,
|
||||
|
||||
spr_xoffset,
|
||||
spr_yoffset,
|
||||
|
||||
spr_sectnum,
|
||||
spr_statnum,
|
||||
|
||||
spr_ang,
|
||||
spr_owner,
|
||||
spr_xvel,
|
||||
spr_yvel,
|
||||
spr_zvel,
|
||||
|
||||
spr_lotag,
|
||||
spr_hitag,
|
||||
|
||||
spr_extra;
|
||||
|
||||
//---------------------------------------------
|
||||
//spriteext fields
|
||||
|
||||
int32_t
|
||||
ext_mdanimtims,
|
||||
|
||||
ext_mdanimcur,
|
||||
ext_angoff,
|
||||
ext_pitch,
|
||||
ext_roll,
|
||||
|
||||
ext_offset_x,
|
||||
ext_offset_y,
|
||||
ext_offset_z,
|
||||
|
||||
ext_flags,
|
||||
ext_xpanning,
|
||||
ext_ypanning;
|
||||
|
||||
float ext_alpha;
|
||||
|
||||
// DON'T send tsprites over the internet
|
||||
|
||||
//--------------------------------------------
|
||||
//spritesmooth fields
|
||||
|
||||
float sm_smoothduration;
|
||||
|
||||
int32_t
|
||||
sm_mdcurframe,
|
||||
sm_mdoldframe,
|
||||
|
||||
sm_mdsmooth;
|
||||
|
||||
//--------------------------------------------
|
||||
// SpriteProjectile fields
|
||||
|
||||
// may want to put projectile fields here
|
||||
int32_t netIndex;
|
||||
|
||||
} netactor_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ void G_ShowParameterHelp(void)
|
|||
"-mh [file.def]\tInclude an additional definitions module\n"
|
||||
"-mx [file.con]\tInclude an additional CON script module\n"
|
||||
"-m\t\tDisable enemies\n"
|
||||
"-noffire\t\tDisable friendly fire\n"
|
||||
#ifndef EDUKE32_STANDALONE
|
||||
"-nam\t\tRun in NAM compatibility mode\n"
|
||||
"-napalm\t\tRun in NAPALM compatibility mode\n"
|
||||
|
@ -176,6 +177,7 @@ void G_CheckCommandLine(int32_t argc, char const * const * argv)
|
|||
ud.m_respawn_inventory = 0;
|
||||
ud.warp_on = 0;
|
||||
ud.cashman = 0;
|
||||
ud.m_ffire = 1;
|
||||
ud.m_player_skill = ud.player_skill = 2;
|
||||
g_player[0].wchoice[0] = 3;
|
||||
g_player[0].wchoice[1] = 4;
|
||||
|
@ -420,6 +422,12 @@ void G_CheckCommandLine(int32_t argc, char const * const * argv)
|
|||
i++;
|
||||
continue;
|
||||
}
|
||||
if (!Bstrcasecmp(c+1, "noffire"))
|
||||
{
|
||||
ud.m_ffire = 0;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (!Bstrcasecmp(c+1, "rts"))
|
||||
{
|
||||
if (argc > i+1)
|
||||
|
|
|
@ -268,7 +268,6 @@ void CONFIG_SetDefaults(void)
|
|||
ud.idplayers = 1;
|
||||
ud.levelstats = 0;
|
||||
ud.lockout = 0;
|
||||
ud.m_ffire = 1;
|
||||
ud.m_marker = 1;
|
||||
ud.maxautosaves = 5;
|
||||
ud.menu_scrollbartilenum = -1;
|
||||
|
|
|
@ -1268,7 +1268,16 @@ static int32_t G_InitActor(int32_t i, int32_t tilenum, int32_t set_movflag_uncon
|
|||
int32_t A_InsertSprite(int16_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int16_t s_pn,int8_t s_s,
|
||||
uint8_t s_xr,uint8_t s_yr,int16_t s_a,int16_t s_ve,int16_t s_zv,int16_t s_ow,int16_t s_ss)
|
||||
{
|
||||
int const newSprite = Net_IsRelevantStat(s_ss) ? Net_InsertSprite(whatsect, s_ss) : insertsprite(whatsect, s_ss);
|
||||
|
||||
|
||||
int32_t newSprite;
|
||||
|
||||
#ifdef NETCODE_DISABLE
|
||||
newSprite = insertsprite(whatsect, s_ss);
|
||||
#else
|
||||
newSprite = Net_InsertSprite(whatsect, s_ss);
|
||||
|
||||
#endif
|
||||
|
||||
if (EDUKE32_PREDICT_FALSE((unsigned)newSprite >= MAXSPRITES))
|
||||
{
|
||||
|
@ -4727,9 +4736,9 @@ void G_HandleLocalKeys(void)
|
|||
tempbuf[ridiculeNum++] = myconnectindex;
|
||||
|
||||
if (g_netClient)
|
||||
enet_peer_send(g_netClientPeer, CHAN_CHAT, enet_packet_create(tempbuf, ridiculeNum, 0));
|
||||
enet_peer_send(g_netClientPeer, CHAN_CHAT, enet_packet_create(&tempbuf[0], ridiculeNum, 0));
|
||||
else if (g_netServer)
|
||||
enet_host_broadcast(g_netServer, CHAN_CHAT, enet_packet_create(tempbuf, ridiculeNum, 0));
|
||||
enet_host_broadcast(g_netServer, CHAN_CHAT, enet_packet_create(&tempbuf[0], ridiculeNum, 0));
|
||||
#endif
|
||||
pus = NUMPAGES;
|
||||
pub = NUMPAGES;
|
||||
|
@ -4748,9 +4757,9 @@ void G_HandleLocalKeys(void)
|
|||
tempbuf[2] = myconnectindex;
|
||||
|
||||
if (g_netClient)
|
||||
enet_peer_send(g_netClientPeer, CHAN_CHAT, enet_packet_create(tempbuf, 3, 0));
|
||||
enet_peer_send(g_netClientPeer, CHAN_CHAT, enet_packet_create(&tempbuf[0], 3, 0));
|
||||
else if (g_netServer)
|
||||
enet_host_broadcast(g_netServer, CHAN_CHAT, enet_packet_create(tempbuf, 3, 0));
|
||||
enet_host_broadcast(g_netServer, CHAN_CHAT, enet_packet_create(&tempbuf[0], 3, 0));
|
||||
}
|
||||
#endif
|
||||
pus = NUMPAGES;
|
||||
|
@ -6599,6 +6608,14 @@ MAIN_LOOP_RESTART:
|
|||
|
||||
Menu_Change(MENU_MAIN);
|
||||
|
||||
if(g_netClient)
|
||||
{
|
||||
OSD_Printf("Waiting for initial snapshot...");
|
||||
Net_WaitForInitialSnapshot();
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (g_networkMode != NET_DEDICATED_SERVER)
|
||||
{
|
||||
G_GetCrosshairColor();
|
||||
|
@ -6662,6 +6679,11 @@ MAIN_LOOP_RESTART:
|
|||
ud.warp_on = 0;
|
||||
KB_KeyDown[sc_Pause] = 0; // JBF: I hate the pause key
|
||||
|
||||
if(g_netClient)
|
||||
{
|
||||
ready2send = 1; // TESTING
|
||||
}
|
||||
|
||||
do //main loop
|
||||
{
|
||||
if (handleevents() && quitevent)
|
||||
|
@ -6981,9 +7003,16 @@ int G_DoMoveThings(void)
|
|||
G_AnimateWalls();
|
||||
A_MoveCyclers();
|
||||
|
||||
if (g_netServer && (everyothertime % 10) == 0)
|
||||
if ((everyothertime % 10) == 0)
|
||||
{
|
||||
Net_SendMapUpdate();
|
||||
if(g_netServer)
|
||||
{
|
||||
Net_SendMapUpdate();
|
||||
}
|
||||
else if(g_netClient)
|
||||
{
|
||||
Net_StoreClientState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1319,7 +1319,7 @@ static MenuOption_t MEO_NETOPTIONS_MAPEXITS = MAKE_MENUOPTION( &MF_Bluefont, &ME
|
|||
static MenuEntry_t ME_NETOPTIONS_MAPEXITS = MAKE_MENUENTRY( "Map Exits", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_MAPEXITS, Option );
|
||||
static MenuOption_t MEO_NETOPTIONS_FRFIRE = MAKE_MENUOPTION( &MF_Bluefont, &MEOS_OffOn, &ud.m_ffire );
|
||||
static MenuEntry_t ME_NETOPTIONS_FRFIRE = MAKE_MENUENTRY( "Fr. Fire", &MF_Redfont, &MEF_NetSetup, &MEO_NETOPTIONS_FRFIRE, Option );
|
||||
static MenuEntry_t ME_NETOPTIONS_ACCEPT = MAKE_MENUENTRY( "Accept", &MF_Redfont, &MEF_NetSetup_Confirm, &MEO_NULL, Link );
|
||||
static MenuEntry_t ME_NETOPTIONS_ACCEPT = MAKE_MENUENTRY( "Accept", &MF_Redfont, &MEF_NetSetup_Confirm, &MEO_NETWORK_HOSTGAME, Link );
|
||||
|
||||
static MenuEntry_t *MEL_NETOPTIONS[] = {
|
||||
&ME_NETOPTIONS_GAMETYPE,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
Copyright (C) 2010 EDuke32 developers and contributors
|
||||
Copyright (C) 2017 EDuke32 developers and contributors
|
||||
|
||||
This file is part of EDuke32.
|
||||
|
||||
|
@ -23,10 +23,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#ifndef netplay_h_
|
||||
#define netplay_h_
|
||||
|
||||
#ifdef _WIN32
|
||||
// include this before enet does
|
||||
# define NEED_WINSOCK2_H
|
||||
# include "windows_inc.h"
|
||||
// As of Nov. of 2018, the version of gcc that the Makefile is using is too old for [[maybe_unused]],
|
||||
// but __attribute__ is GNU C only.
|
||||
#ifdef __GNUC__
|
||||
#define EDUKE32_UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define EDUKE32_UNUSED
|
||||
#endif
|
||||
|
||||
#include "enet/enet.h"
|
||||
|
@ -41,16 +43,8 @@ extern char g_netPassword[32];
|
|||
extern int32_t g_netDisconnect;
|
||||
extern int32_t g_netPlayersWaiting;
|
||||
extern enet_uint16 g_netPort;
|
||||
#ifndef NETCODE_DISABLE
|
||||
extern int32_t g_networkMode;
|
||||
#else
|
||||
#define g_networkMode 0
|
||||
#endif
|
||||
extern int32_t g_netIndex;
|
||||
extern int32_t lastsectupdate[MAXSECTORS];
|
||||
extern int32_t lastupdate[MAXSPRITES];
|
||||
extern int32_t lastwallupdate[MAXWALLS];
|
||||
extern int16_t g_netStatnums[];
|
||||
|
||||
#define NET_REVISIONS 64
|
||||
|
||||
|
@ -63,6 +57,7 @@ enum netchan_t
|
|||
CHAN_MAX
|
||||
};
|
||||
|
||||
|
||||
enum DukePacket_t
|
||||
{
|
||||
PACKET_MASTER_TO_SLAVE,
|
||||
|
@ -77,7 +72,7 @@ enum DukePacket_t
|
|||
PACKET_AUTH,
|
||||
PACKET_PLAYER_PING,
|
||||
PACKET_PLAYER_READY,
|
||||
PACKET_MAP_STREAM,
|
||||
PACKET_WORLD_UPDATE, //[75]
|
||||
|
||||
// any packet with an ID higher than PACKET_BROADCAST is rebroadcast by server
|
||||
// so hacked clients can't create fake server packets and get the server to
|
||||
|
@ -86,7 +81,7 @@ enum DukePacket_t
|
|||
// channel the packet was broadcast on
|
||||
|
||||
PACKET_BROADCAST,
|
||||
PACKET_NEW_GAME,
|
||||
PACKET_NEW_GAME, // [S->C]
|
||||
PACKET_RTS,
|
||||
PACKET_CLIENT_INFO,
|
||||
PACKET_MESSAGE,
|
||||
|
@ -97,6 +92,8 @@ enum DukePacket_t
|
|||
PACKET_MAP_VOTE_CANCEL,
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum netdisconnect_t
|
||||
{
|
||||
DISC_BAD_PASSWORD = 1,
|
||||
|
@ -116,41 +113,101 @@ enum netmode_t
|
|||
NET_DEDICATED_SERVER
|
||||
};
|
||||
|
||||
#define NETMAXACTORS 1024
|
||||
|
||||
//[75]
|
||||
|
||||
typedef struct netWall_s
|
||||
{
|
||||
uint16_t netIndex;
|
||||
|
||||
int32_t x,
|
||||
y,
|
||||
point2,
|
||||
nextwall,
|
||||
nextsector,
|
||||
|
||||
cstat,
|
||||
picnum,
|
||||
overpicnum,
|
||||
shade,
|
||||
pal,
|
||||
|
||||
xrepeat,
|
||||
yrepeat,
|
||||
xpanning,
|
||||
ypanning,
|
||||
lotag,
|
||||
|
||||
hitag,
|
||||
extra;
|
||||
|
||||
} netWall_t;
|
||||
|
||||
// sector struct with all 32 bit entries
|
||||
typedef struct netSector_s
|
||||
{
|
||||
uint16_t netIndex;
|
||||
|
||||
int32_t wallptr,
|
||||
wallnum,
|
||||
ceilingz,
|
||||
floorz,
|
||||
ceilingstat,
|
||||
|
||||
floorstat,
|
||||
ceilingpicnum,
|
||||
ceilingheinum,
|
||||
ceilingshade,
|
||||
ceilingpal,
|
||||
|
||||
ceilingxpanning,
|
||||
ceilingypanning,
|
||||
floorpicnum,
|
||||
floorheinum,
|
||||
floorshade,
|
||||
|
||||
floorpal,
|
||||
floorxpanning,
|
||||
floorypanning,
|
||||
visibility,
|
||||
fogpal,
|
||||
|
||||
lotag,
|
||||
hitag,
|
||||
extra;
|
||||
} netSector_t;
|
||||
|
||||
const uint64_t cSnapshotMemUsage = NET_REVISIONS * (
|
||||
(sizeof(netWall_t) * MAXWALLS)
|
||||
+ (sizeof(netSector_t) * MAXSECTORS)
|
||||
+ (sizeof(netactor_t) * MAXSPRITES)
|
||||
);
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct
|
||||
typedef struct netmapstate_s
|
||||
{
|
||||
|
||||
uint32_t numActors;
|
||||
netactor_t actor[NETMAXACTORS];
|
||||
uint32_t revisionNumber;
|
||||
int32_t maxActorIndex;
|
||||
netactor_t actor[MAXSPRITES];
|
||||
netWall_t wall[MAXWALLS];
|
||||
netSector_t sector[MAXSECTORS];
|
||||
|
||||
} netmapstate_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
uint32_t numActors;
|
||||
uint32_t numToDelete;
|
||||
uint32_t fromRevision;
|
||||
uint32_t toRevision;
|
||||
char data[MAXSPRITES *sizeof(netactor_t)];
|
||||
|
||||
} netmapdiff_t;
|
||||
|
||||
extern netmapstate_t *g_multiMapState[MAXPLAYERS];
|
||||
extern netmapstate_t *g_multiMapRevisions[NET_REVISIONS];
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct
|
||||
typedef struct playerupdate_s
|
||||
{
|
||||
vec3_t pos;
|
||||
vec3_t opos;
|
||||
vec3_t vel;
|
||||
int16_t ang;
|
||||
int16_t horiz;
|
||||
int16_t horizoff;
|
||||
|
||||
fix16_t q16ang;
|
||||
fix16_t q16horiz;
|
||||
fix16_t q16horizoff;
|
||||
|
||||
int16_t ping;
|
||||
int16_t playerindex;
|
||||
int16_t deadflag;
|
||||
|
@ -159,7 +216,7 @@ typedef struct
|
|||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push,1)
|
||||
typedef struct
|
||||
typedef struct newgame_s
|
||||
{
|
||||
int8_t header;
|
||||
int8_t connection;
|
||||
|
@ -177,182 +234,120 @@ typedef struct
|
|||
} newgame_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
|
||||
extern newgame_t pendingnewgame;
|
||||
|
||||
#ifndef NETCODE_DISABLE
|
||||
|
||||
// Connect/Disconnect
|
||||
void Net_Connect(const char *srvaddr);
|
||||
void Net_Disconnect(void);
|
||||
void Net_ReceiveDisconnect(ENetEvent *event);
|
||||
|
||||
// Packet Handlers
|
||||
#endif
|
||||
void Net_GetPackets(void);
|
||||
#ifndef NETCODE_DISABLE
|
||||
void Net_HandleServerPackets(void);
|
||||
void Net_HandleClientPackets(void);
|
||||
void Net_ParseClientPacket(ENetEvent *event);
|
||||
void Net_ParseServerPacket(ENetEvent *event);
|
||||
void Net_ParsePacketCommon(uint8_t *pbuf, int32_t packbufleng, int32_t serverpacketp);
|
||||
|
||||
void Net_SendAcknowledge(ENetPeer *client);
|
||||
void Net_ReceiveAcknowledge(uint8_t *pbuf, int32_t packbufleng);
|
||||
|
||||
void Net_SendChallenge();
|
||||
void Net_ReceiveChallenge(uint8_t *pbuf, int32_t packbufleng, ENetEvent *event);
|
||||
|
||||
void Net_SendNewPlayer(int32_t newplayerindex);
|
||||
void Net_ReceiveNewPlayer(uint8_t *pbuf, int32_t packbufleng);
|
||||
|
||||
void Net_SendPlayerIndex(int32_t index, ENetPeer *peer);
|
||||
void Net_ReceivePlayerIndex(uint8_t *pbuf, int32_t packbufleng);
|
||||
|
||||
void Net_SendClientInfo(void);
|
||||
void Net_ReceiveClientInfo(uint8_t *pbuf, int32_t packbufleng, int32_t fromserver);
|
||||
|
||||
void Net_SendUserMapName(void);
|
||||
void Net_ReceiveUserMapName(uint8_t *pbuf, int32_t packbufleng);
|
||||
|
||||
netmapstate_t *Net_GetRevision(uint8_t revision, uint8_t cancreate);
|
||||
|
||||
void Net_SendMapUpdate(void);
|
||||
void Net_ReceiveMapUpdate(ENetEvent *event);
|
||||
|
||||
void Net_FillMapDiff(uint32_t fromRevision, uint32_t toRevision);
|
||||
void Net_SaveMapState(netmapstate_t *save);
|
||||
void Net_RestoreMapState();
|
||||
|
||||
void Net_CopyToNet(int32_t i, netactor_t *netactor);
|
||||
void Net_CopyFromNet(int32_t i, netactor_t *netactor);
|
||||
int32_t Net_ActorsAreDifferent(netactor_t *actor1, netactor_t *actor2);
|
||||
int32_t Net_IsRelevantSprite(int32_t i);
|
||||
int32_t Net_IsRelevantStat(int32_t stat);
|
||||
int32_t Net_InsertSprite(int32_t sect, int32_t stat);
|
||||
void Net_DeleteSprite(int32_t spritenum);
|
||||
|
||||
void Net_FillPlayerUpdate(playerupdate_t *update, int32_t player);
|
||||
void Net_ExtractPlayerUpdate(playerupdate_t *update, int32_t type);
|
||||
|
||||
void Net_SendServerUpdates(void);
|
||||
void Net_ReceiveServerUpdate(ENetEvent *event);
|
||||
|
||||
void Net_SendClientUpdate(void);
|
||||
void Net_ReceiveClientUpdate(ENetEvent *event);
|
||||
|
||||
void Net_SendMessage(void);
|
||||
void Net_ReceiveMessage(uint8_t *pbuf, int32_t packbufleng);
|
||||
|
||||
void Net_StartNewGame();
|
||||
void Net_NotifyNewGame();
|
||||
void Net_SendNewGame(int32_t frommenu, ENetPeer *peer);
|
||||
void Net_ReceiveNewGame(ENetEvent *event);
|
||||
|
||||
void Net_FillNewGame(newgame_t *newgame, int32_t frommenu);
|
||||
void Net_ExtractNewGame(newgame_t *newgame, int32_t menuonly);
|
||||
|
||||
void Net_SendMapVoteInitiate(void);
|
||||
void Net_ReceiveMapVoteInitiate(uint8_t *pbuf);
|
||||
|
||||
void Net_SendMapVote(int32_t votefor);
|
||||
void Net_ReceiveMapVote(uint8_t *pbuf);
|
||||
void Net_CheckForEnoughVotes();
|
||||
|
||||
void Net_SendMapVoteCancel(int32_t failed);
|
||||
void Net_ReceiveMapVoteCancel(uint8_t *pbuf);
|
||||
|
||||
void Net_StoreClientState(void);
|
||||
|
||||
//////////
|
||||
|
||||
void Net_ResetPrediction(void);
|
||||
void Net_SpawnPlayer(int32_t player);
|
||||
void Net_SyncPlayer(ENetEvent *event);
|
||||
void Net_WaitForServer(void);
|
||||
void faketimerhandler(void);
|
||||
|
||||
void Net_InitMapStateHistory();
|
||||
void Net_AddWorldToInitialSnapshot();
|
||||
|
||||
// Debugging
|
||||
int32_t Dbg_PacketSent(enum DukePacket_t iPacketType);
|
||||
|
||||
void DumpMapStateHistory();
|
||||
|
||||
void Net_WaitForInitialSnapshot();
|
||||
|
||||
#else
|
||||
|
||||
/* NETCODE_ENABLE is not defined */
|
||||
// note: don't include faketimerhandler in this
|
||||
|
||||
#define Net_GetPackets(...) ((void)0)
|
||||
|
||||
// Connect/Disconnect
|
||||
#define Net_Connect(...) ((void)0)
|
||||
#define Net_Disconnect(...) ((void)0)
|
||||
#define Net_ReceiveDisconnect(...) ((void)0)
|
||||
|
||||
// Packet Handlers
|
||||
#define Net_HandleServerPackets(...) ((void)0)
|
||||
#define Net_HandleClientPackets(...) ((void)0)
|
||||
#define Net_ParseClientPacket(...) ((void)0)
|
||||
#define Net_ParseServerPacket(...) ((void)0)
|
||||
#define Net_ParsePacketCommon(...) ((void)0)
|
||||
|
||||
#define Net_SendAcknowledge(...) ((void)0)
|
||||
#define Net_ReceiveAcknowledge(...) ((void)0)
|
||||
|
||||
#define Net_SendChallenge(...) ((void)0)
|
||||
#define Net_ReceiveChallenge(...) ((void)0)
|
||||
|
||||
#define Net_SendNewPlayer(...) ((void)0)
|
||||
#define Net_ReceiveNewPlayer(...) ((void)0)
|
||||
|
||||
#define Net_SendPlayerIndex(...) ((void)0)
|
||||
#define Net_ReceivePlayerIndex(...) ((void)0)
|
||||
|
||||
#define Net_SendClientInfo(...) ((void)0)
|
||||
#define Net_ReceiveClientInfo(...) ((void)0)
|
||||
|
||||
#define Net_SendUserMapName(...) ((void)0)
|
||||
#define Net_ReceiveUserMapName(...) ((void)0)
|
||||
|
||||
#define Net_SendClientSync(...) ((void)0)
|
||||
#define Net_ReceiveClientSync(...) ((void)0)
|
||||
|
||||
#define Net_SendMapUpdate(...) ((void)0)
|
||||
#define Net_SendMapUpdates(...) ((void)0)
|
||||
#define Net_ReceiveMapUpdate(...) ((void)0)
|
||||
|
||||
#define Net_FillPlayerUpdate(...) ((void)0)
|
||||
#define Net_ExtractPlayerUpdate(...) ((void)0)
|
||||
|
||||
#define Net_SendServerUpdates(...) ((void)0)
|
||||
#define Net_ReceiveServerUpdate(...) ((void)0)
|
||||
|
||||
#define Net_SendClientUpdate(...) ((void)0)
|
||||
#define Net_ReceiveClientUpdate(...) ((void)0)
|
||||
|
||||
#define Net_SendMessage(...) ((void)0)
|
||||
#define Net_ReceiveMessage(...) ((void)0)
|
||||
|
||||
#define Net_StartNewGame(...) ((void)0)
|
||||
#define Net_SendNewGame(...) ((void)0)
|
||||
#define Net_ReceiveNewGame(...) ((void)0)
|
||||
|
||||
#define Net_FillNewGame(...) ((void)0)
|
||||
#define Net_ExtractNewGame(...) ((void)0)
|
||||
|
||||
#define Net_SendMapVoteInitiate(...) ((void)0)
|
||||
#define Net_ReceiveMapVoteInitiate(...) ((void)0)
|
||||
|
||||
#define Net_SendMapVote(...) ((void)0)
|
||||
#define Net_ReceiveMapVote(...) ((void)0)
|
||||
#define Net_CheckForEnoughVotes(...) ((void)0)
|
||||
|
||||
#define Net_SendMapVoteCancel(...) ((void)0)
|
||||
#define Net_ReceiveMapVoteCancel(...) ((void)0)
|
||||
|
||||
//////////
|
||||
|
||||
#define Net_ResetPrediction(...) ((void)0)
|
||||
#define Net_RestoreMapState(...) ((void)0)
|
||||
#define Net_SyncPlayer(...) ((void)0)
|
||||
#define Net_WaitForServer(...) ((void)0)
|
||||
|
||||
#define Net_ActorsAreDifferent(...) 0
|
||||
#define Net_IsRelevantSprite(...) 0
|
||||
#define Net_IsRelevantStat(...) 0
|
||||
#define Net_InsertSprite(...) 0
|
||||
#define Net_InsertSprite(...) ((void)0)
|
||||
#define Net_DeleteSprite(...) ((void)0)
|
||||
|
||||
#define Net_NotifyNewGame(...) ((void)0)
|
||||
|
||||
#define Net_WaitForInitialSnapshot(...) ((void)0)
|
||||
#define Net_SendMapUpdate(...) ((void)0)
|
||||
#define Net_StoreClientState(...) ((void)0)
|
||||
#define Net_InitMapStateHistory(...) ((void)0)
|
||||
#define Net_AddWorldToInitialSnapshot(...) ((void)0)
|
||||
#define DumpMapStateHistory(...) ((void)0)
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif // netplay_h_
|
||||
|
|
|
@ -1502,6 +1502,36 @@ static int osdcmd_cvar_set_multi(osdcmdptr_t parm)
|
|||
return r;
|
||||
}
|
||||
|
||||
#ifndef NETCODE_DISABLE
|
||||
static int32_t osdcmd_dumpmapstate(osdfuncparm_t const * const)
|
||||
{
|
||||
// this command takes no parameters
|
||||
|
||||
DumpMapStateHistory();
|
||||
|
||||
return OSDCMD_OK;
|
||||
}
|
||||
|
||||
static int32_t osdcmd_playerinfo(osdfuncparm_t const * const)
|
||||
{
|
||||
OSD_Printf("Your player index is %d.\n", myconnectindex);
|
||||
|
||||
for(int32_t playerIndex = 0; playerIndex < MAXPLAYERS; playerIndex++)
|
||||
{
|
||||
if(g_player[playerIndex].ps == nullptr)
|
||||
{
|
||||
OSD_Printf("g_player[%d]: ps unallocated.\n", playerIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
OSD_Printf("g_player[%d]: ps->i is %d.\n", playerIndex, g_player[playerIndex].ps->i);
|
||||
}
|
||||
}
|
||||
|
||||
return OSDCMD_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t registerosdcommands(void)
|
||||
{
|
||||
static osdcvardata_t cvars_game[] =
|
||||
|
@ -1745,6 +1775,12 @@ int32_t registerosdcommands(void)
|
|||
#ifdef USE_OPENGL
|
||||
baselayer_osdcmd_vidmode_func = osdcmd_vidmode;
|
||||
#endif
|
||||
|
||||
#ifndef NETCODE_DISABLE
|
||||
OSD_RegisterFunction("dumpmapstates", "Dumps current snapshots to CL/Srv_MapStates.bin", osdcmd_dumpmapstate);
|
||||
OSD_RegisterFunction("playerinfo", "Prints information about the current player", osdcmd_playerinfo);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -3674,6 +3674,7 @@ void P_FragPlayer(int playerNum)
|
|||
#ifndef NETCODE_DISABLE
|
||||
if (g_netServer)
|
||||
{
|
||||
// this packet might not be needed anymore with the new snapshot code
|
||||
packbuf[0] = PACKET_FRAG;
|
||||
packbuf[1] = playerNum;
|
||||
packbuf[2] = pPlayer->frag_ps;
|
||||
|
@ -3681,7 +3682,7 @@ void P_FragPlayer(int playerNum)
|
|||
B_BUF32(&packbuf[4], ticrandomseed);
|
||||
packbuf[8] = myconnectindex;
|
||||
|
||||
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(packbuf, 9, ENET_PACKET_FLAG_RELIABLE));
|
||||
enet_host_broadcast(g_netServer, CHAN_GAMESTATE, enet_packet_create(&packbuf[0], 9, ENET_PACKET_FLAG_RELIABLE));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -5473,9 +5474,9 @@ HORIZONLY:;
|
|||
break;
|
||||
case APLAYER__STATIC:
|
||||
{
|
||||
int playerNum = P_Get(pPlayer->actorsqu);
|
||||
P_QuickKill(g_player[playerNum].ps);
|
||||
g_player[playerNum].ps->frag_ps = playerNum;
|
||||
const int playerSquished = P_Get(pPlayer->actorsqu);
|
||||
P_QuickKill(g_player[playerSquished].ps);
|
||||
g_player[playerSquished].ps->frag_ps = playerNum;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -223,7 +223,9 @@ typedef struct {
|
|||
// NOTE: wchoice[HANDREMOTE_WEAPON .. MAX_WEAPONS-1] unused
|
||||
uint8_t frags[MAXPLAYERS], wchoice[MAX_WEAPONS];
|
||||
|
||||
char vote, gotvote, pingcnt, playerquitflag, ready;
|
||||
|
||||
char vote, gotvote, pingcnt, playerquitflag,
|
||||
ready; // currently unused. May be used later to indicate that a player has pressed use on intermission to indicate they are ready to go on to the next map
|
||||
char user_name[32];
|
||||
uint32_t revision;
|
||||
} playerdata_t;
|
||||
|
|
|
@ -35,7 +35,9 @@ static uint8_t precachehightile[2][MAXTILES>>3];
|
|||
static int32_t g_precacheCount;
|
||||
|
||||
|
||||
static inline void flag_precache(int tile, int type)
|
||||
static int32_t NET_75_CHECK = 0;
|
||||
|
||||
static void flag_precache(int32_t tile, int32_t type)
|
||||
{
|
||||
if (!(gotpic[tile>>3] & pow2char[tile&7]))
|
||||
g_precacheCount++;
|
||||
|
@ -1906,8 +1908,10 @@ int G_EnterLevel(int gameMode)
|
|||
int16_t playerAngle;
|
||||
|
||||
char levelName[BMAX_PATH];
|
||||
NET_75_CHECK++; // a major problem with how STAT_NETALLOC works, is that loadboard loads sprites directly into the arrays and does not take from
|
||||
// STAT_NETALLOC, even though the loaded sprites are very, very likely to be relevant to the netcode.
|
||||
|
||||
if (!VOLUMEONE && Menu_HaveUserMap())
|
||||
if (!VOLUMEONE && G_HaveUserMap())
|
||||
{
|
||||
if (engineLoadBoard(boardfilename, 0, &p0.pos, &playerAngle, &p0.cursectnum) < 0)
|
||||
{
|
||||
|
@ -1934,6 +1938,12 @@ int G_EnterLevel(int gameMode)
|
|||
Bmemset(gotpic, 0, sizeof(gotpic));
|
||||
Bmemset(precachehightile, 0, sizeof(precachehightile));
|
||||
|
||||
NET_75_CHECK++; // resetpspritevars attempts to insert player 0's sprite, which isn't going to work because we don't have
|
||||
// the STAT_NETALLOC sprites allocated yet.
|
||||
|
||||
Net_NotifyNewGame();
|
||||
|
||||
|
||||
prelevel(gameMode);
|
||||
|
||||
G_AlignWarpElevators();
|
||||
|
@ -1978,7 +1988,7 @@ int G_EnterLevel(int gameMode)
|
|||
P_DoQuote(QUOTE_F1HELP,g_player[myconnectindex].ps);
|
||||
#endif
|
||||
|
||||
Net_NotifyNewGame();
|
||||
//Net_NotifyNewGame();
|
||||
Net_ResetPrediction();
|
||||
|
||||
//g_player[myconnectindex].ps->palette = palette;
|
||||
|
@ -2018,6 +2028,12 @@ int G_EnterLevel(int gameMode)
|
|||
G_DrawBackground();
|
||||
G_DrawRooms(myconnectindex,65536);
|
||||
|
||||
if (g_netClient || g_netServer) // [75] : Initialize map states after map load
|
||||
{
|
||||
Net_InitMapStateHistory();
|
||||
Net_AddWorldToInitialSnapshot();
|
||||
}
|
||||
|
||||
Net_WaitForServer();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue