mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-29 07:32:02 +00:00
Obliterate resynch
Okay, more precisely this substitutes the old resynch with the newly added gamestate resend code.
This commit is contained in:
parent
29d8389461
commit
846560910d
3 changed files with 31 additions and 848 deletions
706
src/d_clisrv.c
706
src/d_clisrv.c
|
@ -83,6 +83,7 @@ char playeraddress[MAXPLAYERS][64];
|
|||
// The actual timeout will be longer depending on the savegame length
|
||||
tic_t jointimeout = (10*TICRATE);
|
||||
static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame?
|
||||
static boolean resendingsavegame[MAXNETNODES]; // Are we resending the savegame?
|
||||
static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout?
|
||||
|
||||
UINT16 pingmeasurecount = 1;
|
||||
|
@ -102,15 +103,8 @@ static tic_t maketic;
|
|||
|
||||
static INT16 consistancy[BACKUPTICS];
|
||||
|
||||
// Resynching shit!
|
||||
static UINT32 resynch_score[MAXNETNODES]; // "score" for kicking -- if this gets too high then cfail kick
|
||||
static UINT16 resynch_delay[MAXNETNODES]; // delay time before the player can be considered to have desynched
|
||||
static UINT32 resynch_status[MAXNETNODES]; // 0 bit means synched for that player, 1 means possibly desynched
|
||||
static UINT8 resynch_sent[MAXNETNODES][MAXPLAYERS]; // what synch packets have we attempted to send to the player
|
||||
static UINT8 resynch_inprogress[MAXNETNODES];
|
||||
static UINT8 resynch_local_inprogress = false; // WE are desynched and getting packets to fix it.
|
||||
static UINT8 player_joining = false;
|
||||
UINT8 hu_resynching = 0;
|
||||
UINT8 hu_redownloadinggamestate = 0;
|
||||
|
||||
UINT8 adminpassmd5[16];
|
||||
boolean adminpasswordset = false;
|
||||
|
@ -504,597 +498,6 @@ void ReadLmpExtraData(UINT8 **demo_pointer, INT32 playernum)
|
|||
// end extra data function for lmps
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// resynch player data
|
||||
// -----------------------------------------------------------------
|
||||
static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
|
||||
{
|
||||
size_t j;
|
||||
|
||||
rsp->playernum = (UINT8)i;
|
||||
|
||||
// Do not send anything visual related.
|
||||
// Only send data that we need to know for physics.
|
||||
rsp->playerstate = (UINT8)players[i].playerstate; //playerstate_t
|
||||
rsp->pflags = (UINT32)LONG(players[i].pflags); //pflags_t
|
||||
rsp->panim = (UINT8)players[i].panim; //panim_t
|
||||
|
||||
rsp->aiming = (angle_t)LONG(players[i].aiming);
|
||||
rsp->currentweapon = LONG(players[i].currentweapon);
|
||||
rsp->ringweapons = LONG(players[i].ringweapons);
|
||||
|
||||
rsp->ammoremoval = (UINT16)SHORT(players[i].ammoremoval);
|
||||
rsp->ammoremovaltimer = (tic_t)LONG(players[i].ammoremovaltimer);
|
||||
rsp->ammoremovalweapon = LONG(players[i].ammoremovalweapon);
|
||||
|
||||
for (j = 0; j < NUMPOWERS; ++j)
|
||||
rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]);
|
||||
|
||||
// Score is resynched in the rspfirm resync packet
|
||||
rsp->rings = SHORT(players[i].rings);
|
||||
rsp->spheres = SHORT(players[i].spheres);
|
||||
rsp->lives = players[i].lives;
|
||||
rsp->continues = players[i].continues;
|
||||
rsp->scoreadd = players[i].scoreadd;
|
||||
rsp->xtralife = players[i].xtralife;
|
||||
rsp->pity = players[i].pity;
|
||||
|
||||
rsp->skincolor = players[i].skincolor;
|
||||
rsp->skin = LONG(players[i].skin);
|
||||
rsp->availabilities = LONG(players[i].availabilities);
|
||||
// Just in case Lua does something like
|
||||
// modify these at runtime
|
||||
rsp->camerascale = (fixed_t)LONG(players[i].camerascale);
|
||||
rsp->shieldscale = (fixed_t)LONG(players[i].shieldscale);
|
||||
rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed);
|
||||
rsp->runspeed = (fixed_t)LONG(players[i].runspeed);
|
||||
rsp->thrustfactor = players[i].thrustfactor;
|
||||
rsp->accelstart = players[i].accelstart;
|
||||
rsp->acceleration = players[i].acceleration;
|
||||
rsp->charability = players[i].charability;
|
||||
rsp->charability2 = players[i].charability2;
|
||||
rsp->charflags = (UINT32)LONG(players[i].charflags);
|
||||
rsp->thokitem = (UINT32)LONG(players[i].thokitem); //mobjtype_t
|
||||
rsp->spinitem = (UINT32)LONG(players[i].spinitem); //mobjtype_t
|
||||
rsp->revitem = (UINT32)LONG(players[i].revitem); //mobjtype_t
|
||||
rsp->followitem = (UINT32)LONG(players[i].followitem); //mobjtype_t
|
||||
rsp->actionspd = (fixed_t)LONG(players[i].actionspd);
|
||||
rsp->mindash = (fixed_t)LONG(players[i].mindash);
|
||||
rsp->maxdash = (fixed_t)LONG(players[i].maxdash);
|
||||
rsp->jumpfactor = (fixed_t)LONG(players[i].jumpfactor);
|
||||
rsp->playerheight = (fixed_t)LONG(players[i].height);
|
||||
rsp->playerspinheight = (fixed_t)LONG(players[i].spinheight);
|
||||
|
||||
rsp->speed = (fixed_t)LONG(players[i].speed);
|
||||
rsp->secondjump = players[i].secondjump;
|
||||
rsp->fly1 = players[i].fly1;
|
||||
rsp->glidetime = (tic_t)LONG(players[i].glidetime);
|
||||
rsp->climbing = players[i].climbing;
|
||||
rsp->deadtimer = players[i].deadtimer;
|
||||
rsp->exiting = (tic_t)LONG(players[i].exiting);
|
||||
rsp->homing = players[i].homing;
|
||||
rsp->dashmode = (tic_t)LONG(players[i].dashmode);
|
||||
rsp->skidtime = (tic_t)LONG(players[i].skidtime);
|
||||
rsp->cmomx = (fixed_t)LONG(players[i].cmomx);
|
||||
rsp->cmomy = (fixed_t)LONG(players[i].cmomy);
|
||||
rsp->rmomx = (fixed_t)LONG(players[i].rmomx);
|
||||
rsp->rmomy = (fixed_t)LONG(players[i].rmomy);
|
||||
|
||||
rsp->weapondelay = LONG(players[i].weapondelay);
|
||||
rsp->tossdelay = LONG(players[i].tossdelay);
|
||||
|
||||
rsp->starpostx = SHORT(players[i].starpostx);
|
||||
rsp->starposty = SHORT(players[i].starposty);
|
||||
rsp->starpostz = SHORT(players[i].starpostz);
|
||||
rsp->starpostnum = LONG(players[i].starpostnum);
|
||||
rsp->starposttime = (tic_t)LONG(players[i].starposttime);
|
||||
rsp->starpostangle = (angle_t)LONG(players[i].starpostangle);
|
||||
rsp->starpostscale = (fixed_t)LONG(players[i].starpostscale);
|
||||
|
||||
rsp->maxlink = LONG(players[i].maxlink);
|
||||
rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed);
|
||||
rsp->angle_pos = (angle_t)LONG(players[i].angle_pos);
|
||||
rsp->old_angle_pos = (angle_t)LONG(players[i].old_angle_pos);
|
||||
rsp->bumpertime = (tic_t)LONG(players[i].bumpertime);
|
||||
rsp->flyangle = LONG(players[i].flyangle);
|
||||
rsp->drilltimer = (tic_t)LONG(players[i].drilltimer);
|
||||
rsp->linkcount = LONG(players[i].linkcount);
|
||||
rsp->linktimer = (tic_t)LONG(players[i].linktimer);
|
||||
rsp->anotherflyangle = LONG(players[i].anotherflyangle);
|
||||
rsp->nightstime = (tic_t)LONG(players[i].nightstime);
|
||||
rsp->drillmeter = LONG(players[i].drillmeter);
|
||||
rsp->drilldelay = players[i].drilldelay;
|
||||
rsp->bonustime = players[i].bonustime;
|
||||
rsp->mare = players[i].mare;
|
||||
rsp->lastsidehit = SHORT(players[i].lastsidehit);
|
||||
rsp->lastlinehit = SHORT(players[i].lastlinehit);
|
||||
|
||||
rsp->losstime = (tic_t)LONG(players[i].losstime);
|
||||
rsp->timeshit = players[i].timeshit;
|
||||
rsp->onconveyor = LONG(players[i].onconveyor);
|
||||
|
||||
rsp->hasmo = false;
|
||||
//Transfer important mo information if the player has a body.
|
||||
//This lets us resync players even if they are dead.
|
||||
if (!players[i].mo)
|
||||
return;
|
||||
rsp->hasmo = true;
|
||||
|
||||
rsp->health = LONG(players[i].mo->health);
|
||||
rsp->angle = (angle_t)LONG(players[i].mo->angle);
|
||||
rsp->rollangle = (angle_t)LONG(players[i].mo->rollangle);
|
||||
rsp->x = LONG(players[i].mo->x);
|
||||
rsp->y = LONG(players[i].mo->y);
|
||||
rsp->z = LONG(players[i].mo->z);
|
||||
rsp->momx = LONG(players[i].mo->momx);
|
||||
rsp->momy = LONG(players[i].mo->momy);
|
||||
rsp->momz = LONG(players[i].mo->momz);
|
||||
rsp->friction = LONG(players[i].mo->friction);
|
||||
rsp->movefactor = LONG(players[i].mo->movefactor);
|
||||
|
||||
rsp->sprite = (spritenum_t)LONG(players[i].mo->sprite);
|
||||
rsp->frame = LONG(players[i].mo->frame);
|
||||
rsp->sprite2 = players[i].mo->sprite2;
|
||||
rsp->anim_duration = SHORT(players[i].mo->anim_duration);
|
||||
rsp->tics = LONG(players[i].mo->tics);
|
||||
rsp->statenum = (statenum_t)LONG(players[i].mo->state-states); // :(
|
||||
rsp->eflags = (UINT16)SHORT(players[i].mo->eflags);
|
||||
rsp->flags = LONG(players[i].mo->flags);
|
||||
rsp->flags2 = LONG(players[i].mo->flags2);
|
||||
|
||||
rsp->radius = LONG(players[i].mo->radius);
|
||||
rsp->height = LONG(players[i].mo->height);
|
||||
rsp->scale = LONG(players[i].mo->scale);
|
||||
rsp->destscale = LONG(players[i].mo->destscale);
|
||||
rsp->scalespeed = LONG(players[i].mo->scalespeed);
|
||||
}
|
||||
|
||||
static void resynch_read_player(resynch_pak *rsp)
|
||||
{
|
||||
INT32 i = rsp->playernum, j;
|
||||
mobj_t *savedmo = players[i].mo;
|
||||
|
||||
// Do not send anything visual related.
|
||||
// Only send data that we need to know for physics.
|
||||
players[i].playerstate = (UINT8)rsp->playerstate; //playerstate_t
|
||||
players[i].pflags = (UINT32)LONG(rsp->pflags); //pflags_t
|
||||
players[i].panim = (UINT8)rsp->panim; //panim_t
|
||||
|
||||
players[i].aiming = (angle_t)LONG(rsp->aiming);
|
||||
players[i].currentweapon = LONG(rsp->currentweapon);
|
||||
players[i].ringweapons = LONG(rsp->ringweapons);
|
||||
|
||||
players[i].ammoremoval = (UINT16)SHORT(rsp->ammoremoval);
|
||||
players[i].ammoremovaltimer = (tic_t)LONG(rsp->ammoremovaltimer);
|
||||
players[i].ammoremovalweapon = LONG(rsp->ammoremovalweapon);
|
||||
|
||||
for (j = 0; j < NUMPOWERS; ++j)
|
||||
players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]);
|
||||
|
||||
// Score is resynched in the rspfirm resync packet
|
||||
players[i].rings = SHORT(rsp->rings);
|
||||
players[i].spheres = SHORT(rsp->spheres);
|
||||
players[i].lives = rsp->lives;
|
||||
players[i].continues = rsp->continues;
|
||||
players[i].scoreadd = rsp->scoreadd;
|
||||
players[i].xtralife = rsp->xtralife;
|
||||
players[i].pity = rsp->pity;
|
||||
|
||||
players[i].skincolor = rsp->skincolor;
|
||||
players[i].skin = LONG(rsp->skin);
|
||||
players[i].availabilities = LONG(rsp->availabilities);
|
||||
// Just in case Lua does something like
|
||||
// modify these at runtime
|
||||
players[i].camerascale = (fixed_t)LONG(rsp->camerascale);
|
||||
players[i].shieldscale = (fixed_t)LONG(rsp->shieldscale);
|
||||
players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed);
|
||||
players[i].runspeed = (fixed_t)LONG(rsp->runspeed);
|
||||
players[i].thrustfactor = rsp->thrustfactor;
|
||||
players[i].accelstart = rsp->accelstart;
|
||||
players[i].acceleration = rsp->acceleration;
|
||||
players[i].charability = rsp->charability;
|
||||
players[i].charability2 = rsp->charability2;
|
||||
players[i].charflags = (UINT32)LONG(rsp->charflags);
|
||||
players[i].thokitem = (UINT32)LONG(rsp->thokitem); //mobjtype_t
|
||||
players[i].spinitem = (UINT32)LONG(rsp->spinitem); //mobjtype_t
|
||||
players[i].revitem = (UINT32)LONG(rsp->revitem); //mobjtype_t
|
||||
players[i].followitem = (UINT32)LONG(rsp->followitem); //mobjtype_t
|
||||
players[i].actionspd = (fixed_t)LONG(rsp->actionspd);
|
||||
players[i].mindash = (fixed_t)LONG(rsp->mindash);
|
||||
players[i].maxdash = (fixed_t)LONG(rsp->maxdash);
|
||||
players[i].jumpfactor = (fixed_t)LONG(rsp->jumpfactor);
|
||||
players[i].height = (fixed_t)LONG(rsp->playerheight);
|
||||
players[i].spinheight = (fixed_t)LONG(rsp->playerspinheight);
|
||||
|
||||
players[i].speed = (fixed_t)LONG(rsp->speed);
|
||||
players[i].secondjump = rsp->secondjump;
|
||||
players[i].fly1 = rsp->fly1;
|
||||
players[i].glidetime = (tic_t)LONG(rsp->glidetime);
|
||||
players[i].climbing = rsp->climbing;
|
||||
players[i].deadtimer = rsp->deadtimer;
|
||||
players[i].exiting = (tic_t)LONG(rsp->exiting);
|
||||
players[i].homing = rsp->homing;
|
||||
players[i].dashmode = (tic_t)LONG(rsp->dashmode);
|
||||
players[i].skidtime = (tic_t)LONG(rsp->skidtime);
|
||||
players[i].cmomx = (fixed_t)LONG(rsp->cmomx);
|
||||
players[i].cmomy = (fixed_t)LONG(rsp->cmomy);
|
||||
players[i].rmomx = (fixed_t)LONG(rsp->rmomx);
|
||||
players[i].rmomy = (fixed_t)LONG(rsp->rmomy);
|
||||
|
||||
players[i].weapondelay = LONG(rsp->weapondelay);
|
||||
players[i].tossdelay = LONG(rsp->tossdelay);
|
||||
|
||||
players[i].starpostx = SHORT(rsp->starpostx);
|
||||
players[i].starposty = SHORT(rsp->starposty);
|
||||
players[i].starpostz = SHORT(rsp->starpostz);
|
||||
players[i].starpostnum = LONG(rsp->starpostnum);
|
||||
players[i].starposttime = (tic_t)LONG(rsp->starposttime);
|
||||
players[i].starpostangle = (angle_t)LONG(rsp->starpostangle);
|
||||
players[i].starpostscale = (fixed_t)LONG(rsp->starpostscale);
|
||||
|
||||
players[i].maxlink = LONG(rsp->maxlink);
|
||||
players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed);
|
||||
players[i].angle_pos = (angle_t)LONG(rsp->angle_pos);
|
||||
players[i].old_angle_pos = (angle_t)LONG(rsp->old_angle_pos);
|
||||
players[i].bumpertime = (tic_t)LONG(rsp->bumpertime);
|
||||
players[i].flyangle = LONG(rsp->flyangle);
|
||||
players[i].drilltimer = (tic_t)LONG(rsp->drilltimer);
|
||||
players[i].linkcount = LONG(rsp->linkcount);
|
||||
players[i].linktimer = (tic_t)LONG(rsp->linktimer);
|
||||
players[i].anotherflyangle = LONG(rsp->anotherflyangle);
|
||||
players[i].nightstime = (tic_t)LONG(rsp->nightstime);
|
||||
players[i].drillmeter = LONG(rsp->drillmeter);
|
||||
players[i].drilldelay = rsp->drilldelay;
|
||||
players[i].bonustime = rsp->bonustime;
|
||||
players[i].mare = rsp->mare;
|
||||
players[i].lastsidehit = SHORT(rsp->lastsidehit);
|
||||
players[i].lastlinehit = SHORT(rsp->lastlinehit);
|
||||
|
||||
players[i].losstime = (tic_t)LONG(rsp->losstime);
|
||||
players[i].timeshit = rsp->timeshit;
|
||||
players[i].onconveyor = LONG(rsp->onconveyor);
|
||||
|
||||
//We get a packet for each player in game.
|
||||
if (!playeringame[i])
|
||||
return;
|
||||
|
||||
//...but keep old mo even if it is corrupt or null!
|
||||
players[i].mo = savedmo;
|
||||
|
||||
//Transfer important mo information if they have a valid mo.
|
||||
if (!rsp->hasmo)
|
||||
return;
|
||||
|
||||
//server thinks player has a body.
|
||||
//Give them a new body that can be then manipulated by the server's info.
|
||||
if (!players[i].mo) //client thinks it has no body.
|
||||
P_SpawnPlayer(i);
|
||||
|
||||
//At this point, the player should have a body, whether they were respawned or not.
|
||||
P_UnsetThingPosition(players[i].mo);
|
||||
players[i].mo->angle = (angle_t)LONG(rsp->angle);
|
||||
players[i].mo->rollangle = (angle_t)LONG(rsp->rollangle);
|
||||
players[i].mo->eflags = (UINT16)SHORT(rsp->eflags);
|
||||
players[i].mo->flags = LONG(rsp->flags);
|
||||
players[i].mo->flags2 = LONG(rsp->flags2);
|
||||
players[i].mo->friction = LONG(rsp->friction);
|
||||
players[i].mo->health = LONG(rsp->health);
|
||||
players[i].mo->momx = LONG(rsp->momx);
|
||||
players[i].mo->momy = LONG(rsp->momy);
|
||||
players[i].mo->momz = LONG(rsp->momz);
|
||||
players[i].mo->movefactor = LONG(rsp->movefactor);
|
||||
|
||||
// Don't use P_SetMobjStateNF to restore state, write/read all the values manually!
|
||||
// This should stop those stupid console errors, hopefully.
|
||||
// -- Monster Iestyn
|
||||
players[i].mo->sprite = (spritenum_t)LONG(rsp->sprite);
|
||||
players[i].mo->frame = LONG(rsp->frame);
|
||||
players[i].mo->sprite2 = rsp->sprite2;
|
||||
players[i].mo->anim_duration = SHORT(rsp->anim_duration);
|
||||
players[i].mo->tics = LONG(rsp->tics);
|
||||
players[i].mo->state = &states[LONG(rsp->statenum)];
|
||||
|
||||
players[i].mo->x = LONG(rsp->x);
|
||||
players[i].mo->y = LONG(rsp->y);
|
||||
players[i].mo->z = LONG(rsp->z);
|
||||
players[i].mo->radius = LONG(rsp->radius);
|
||||
players[i].mo->height = LONG(rsp->height);
|
||||
// P_SetScale is redundant for this, as all related variables are already restored properly.
|
||||
players[i].mo->scale = LONG(rsp->scale);
|
||||
players[i].mo->destscale = LONG(rsp->destscale);
|
||||
players[i].mo->scalespeed = LONG(rsp->scalespeed);
|
||||
|
||||
// And finally, SET THE MOBJ SKIN damn it.
|
||||
if ((players[i].powers[pw_carry] == CR_NIGHTSMODE) && (skins[players[i].skin].sprites[SPR2_NFLY].numframes == 0))
|
||||
{
|
||||
players[i].mo->skin = &skins[DEFAULTNIGHTSSKIN];
|
||||
players[i].mo->color = skins[DEFAULTNIGHTSSKIN].prefcolor; // this will be corrected by thinker to super flash
|
||||
}
|
||||
else
|
||||
{
|
||||
players[i].mo->skin = &skins[players[i].skin];
|
||||
players[i].mo->color = players[i].skincolor; // this will be corrected by thinker to super flash/mario star
|
||||
}
|
||||
|
||||
P_SetThingPosition(players[i].mo);
|
||||
}
|
||||
|
||||
static inline void resynch_write_ctf(resynchend_pak *rst)
|
||||
{
|
||||
mobj_t *mflag;
|
||||
UINT8 i, j;
|
||||
|
||||
for (i = 0, mflag = redflag; i < 2; ++i, mflag = blueflag)
|
||||
{
|
||||
rst->flagx[i] = rst->flagy[i] = rst->flagz[i] = 0;
|
||||
rst->flagloose[i] = rst->flagflags[i] = 0;
|
||||
rst->flagplayer[i] = -1;
|
||||
|
||||
if (!mflag)
|
||||
{
|
||||
// Should be held by a player
|
||||
for (j = 0; j < MAXPLAYERS; ++j)
|
||||
{
|
||||
// GF_REDFLAG is 1, GF_BLUEFLAG is 2
|
||||
// redflag handling is i=0, blueflag is i=1
|
||||
// so check for gotflag == (i+1)
|
||||
if (!playeringame[j] || players[j].gotflag != (i+1))
|
||||
continue;
|
||||
rst->flagplayer[i] = (SINT8)j;
|
||||
break;
|
||||
}
|
||||
if (j == MAXPLAYERS) // fine, no I_Error
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "One of the flags has gone completely missing...\n");
|
||||
rst->flagplayer[i] = -2;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
rst->flagx[i] = (fixed_t)LONG(mflag->x);
|
||||
rst->flagy[i] = (fixed_t)LONG(mflag->y);
|
||||
rst->flagz[i] = (fixed_t)LONG(mflag->z);
|
||||
rst->flagflags[i] = LONG(mflag->flags2);
|
||||
rst->flagloose[i] = LONG(mflag->fuse); // Dropped or not?
|
||||
}
|
||||
}
|
||||
|
||||
static inline void resynch_read_ctf(resynchend_pak *p)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
players[i].gotflag = 0;
|
||||
|
||||
// Red flag
|
||||
if (p->flagplayer[0] == -2)
|
||||
; // The server doesn't even know what happened to it...
|
||||
else if (p->flagplayer[0] != -1) // Held by a player
|
||||
{
|
||||
if (!playeringame[p->flagplayer[0]])
|
||||
I_Error("Invalid red flag player %d who isn't in the game!", (INT32)p->flagplayer[0]);
|
||||
players[p->flagplayer[0]].gotflag = GF_REDFLAG;
|
||||
if (redflag)
|
||||
{
|
||||
P_RemoveMobj(redflag);
|
||||
redflag = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!redflag)
|
||||
redflag = P_SpawnMobj(0,0,0,MT_REDFLAG);
|
||||
|
||||
P_UnsetThingPosition(redflag);
|
||||
redflag->x = (fixed_t)LONG(p->flagx[0]);
|
||||
redflag->y = (fixed_t)LONG(p->flagy[0]);
|
||||
redflag->z = (fixed_t)LONG(p->flagz[0]);
|
||||
redflag->flags2 = LONG(p->flagflags[0]);
|
||||
redflag->fuse = LONG(p->flagloose[0]);
|
||||
P_SetThingPosition(redflag);
|
||||
}
|
||||
|
||||
// Blue flag
|
||||
if (p->flagplayer[1] == -2)
|
||||
; // The server doesn't even know what happened to it...
|
||||
else if (p->flagplayer[1] != -1) // Held by a player
|
||||
{
|
||||
if (!playeringame[p->flagplayer[1]])
|
||||
I_Error("Invalid blue flag player %d who isn't in the game!", (INT32)p->flagplayer[1]);
|
||||
players[p->flagplayer[1]].gotflag = GF_BLUEFLAG;
|
||||
if (blueflag)
|
||||
{
|
||||
P_RemoveMobj(blueflag);
|
||||
blueflag = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!blueflag)
|
||||
blueflag = P_SpawnMobj(0,0,0,MT_BLUEFLAG);
|
||||
|
||||
P_UnsetThingPosition(blueflag);
|
||||
blueflag->x = (fixed_t)LONG(p->flagx[1]);
|
||||
blueflag->y = (fixed_t)LONG(p->flagy[1]);
|
||||
blueflag->z = (fixed_t)LONG(p->flagz[1]);
|
||||
blueflag->flags2 = LONG(p->flagflags[1]);
|
||||
blueflag->fuse = LONG(p->flagloose[1]);
|
||||
P_SetThingPosition(blueflag);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void resynch_write_others(resynchend_pak *rst)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
rst->ingame = 0;
|
||||
rst->outofcoop = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
{
|
||||
rst->ctfteam[i] = 0;
|
||||
rst->score[i] = 0;
|
||||
rst->numboxes[i] = 0;
|
||||
rst->totalring[i] = 0;
|
||||
rst->realtime[i] = 0;
|
||||
rst->laps[i] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!players[i].spectator)
|
||||
rst->ingame |= (1<<i);
|
||||
if (players[i].outofcoop)
|
||||
rst->outofcoop |= (1<<i);
|
||||
rst->ctfteam[i] = (INT32)LONG(players[i].ctfteam);
|
||||
rst->score[i] = (UINT32)LONG(players[i].score);
|
||||
rst->numboxes[i] = SHORT(players[i].numboxes);
|
||||
rst->totalring[i] = SHORT(players[i].totalring);
|
||||
rst->realtime[i] = (tic_t)LONG(players[i].realtime);
|
||||
rst->laps[i] = players[i].laps;
|
||||
}
|
||||
|
||||
// endian safeness
|
||||
rst->ingame = (UINT32)LONG(rst->ingame);
|
||||
}
|
||||
|
||||
static inline void resynch_read_others(resynchend_pak *p)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT32 loc_ingame = (UINT32)LONG(p->ingame);
|
||||
UINT32 loc_outofcoop = (UINT32)LONG(p->outofcoop);
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
// We don't care if they're in the game or not, just write all the data.
|
||||
players[i].spectator = !(loc_ingame & (1<<i));
|
||||
players[i].outofcoop = (loc_outofcoop & (1<<i));
|
||||
players[i].ctfteam = (INT32)LONG(p->ctfteam[i]); // no, 0 does not mean spectator, at least not in Match
|
||||
players[i].score = (UINT32)LONG(p->score[i]);
|
||||
players[i].numboxes = SHORT(p->numboxes[i]);
|
||||
players[i].totalring = SHORT(p->totalring[i]);
|
||||
players[i].realtime = (tic_t)LONG(p->realtime[i]);
|
||||
players[i].laps = p->laps[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void SV_InitResynchVars(INT32 node)
|
||||
{
|
||||
resynch_delay[node] = TICRATE; // initial one second delay
|
||||
resynch_score[node] = 0; // clean slate
|
||||
resynch_status[node] = 0x00;
|
||||
resynch_inprogress[node] = false;
|
||||
memset(resynch_sent[node], 0, MAXPLAYERS);
|
||||
}
|
||||
|
||||
static void SV_RequireResynch(INT32 node)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
resynch_delay[node] = 10; // Delay before you can fail sync again
|
||||
resynch_score[node] += 200; // Add score for initial desynch
|
||||
resynch_status[node] = 0xFFFFFFFF; // No players assumed synched
|
||||
resynch_inprogress[node] = true; // so we know to send a PT_RESYNCHEND after sync
|
||||
|
||||
// Initial setup
|
||||
memset(resynch_sent[node], 0, MAXPLAYERS);
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (!playeringame[i]) // Player not in game so just drop it from required synch
|
||||
resynch_status[node] &= ~(1<<i);
|
||||
else if (playernode[i] == node); // instantly update THEIR position
|
||||
else // Send at random times based on num players
|
||||
resynch_sent[node][i] = M_RandomKey(D_NumPlayers()>>1)+1;
|
||||
}
|
||||
}
|
||||
|
||||
static void SV_SendResynch(INT32 node)
|
||||
{
|
||||
INT32 i, j;
|
||||
|
||||
if (!nodeingame[node])
|
||||
{
|
||||
// player left during resynch
|
||||
// so obviously we don't need to do any of this anymore
|
||||
resynch_inprogress[node] = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// resynched?
|
||||
if (!resynch_status[node])
|
||||
{
|
||||
// you are now synched
|
||||
resynch_inprogress[node] = false;
|
||||
|
||||
netbuffer->packettype = PT_RESYNCHEND;
|
||||
|
||||
netbuffer->u.resynchend.randomseed = P_GetRandSeed();
|
||||
if (gametyperules & GTR_TEAMFLAGS)
|
||||
resynch_write_ctf(&netbuffer->u.resynchend);
|
||||
resynch_write_others(&netbuffer->u.resynchend);
|
||||
|
||||
HSendPacket(node, true, 0, (sizeof(resynchend_pak)));
|
||||
return;
|
||||
}
|
||||
|
||||
netbuffer->packettype = PT_RESYNCHING;
|
||||
for (i = 0, j = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
// if already synched don't bother
|
||||
if (!(resynch_status[node] & 1<<i))
|
||||
continue;
|
||||
|
||||
// waiting for a reply or just waiting in general
|
||||
if (resynch_sent[node][i])
|
||||
{
|
||||
--resynch_sent[node][i];
|
||||
continue;
|
||||
}
|
||||
|
||||
resynch_write_player(&netbuffer->u.resynchpak, i);
|
||||
HSendPacket(node, false, 0, (sizeof(resynch_pak)));
|
||||
|
||||
resynch_sent[node][i] = TICRATE;
|
||||
resynch_score[node] += 2; // penalty for send
|
||||
|
||||
if (++j > 3)
|
||||
break;
|
||||
}
|
||||
|
||||
if (resynch_score[node] > (unsigned)cv_resynchattempts.value*250)
|
||||
{
|
||||
SendKick(nodetoplayer[node], KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
resynch_score[node] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void CL_AcknowledgeResynch(resynch_pak *rsp)
|
||||
{
|
||||
resynch_read_player(rsp);
|
||||
|
||||
netbuffer->packettype = PT_RESYNCHGET;
|
||||
netbuffer->u.resynchgot = rsp->playernum;
|
||||
HSendPacket(servernode, true, 0, sizeof(UINT8));
|
||||
}
|
||||
|
||||
static void SV_AcknowledgeResynchAck(INT32 node, UINT8 rsg)
|
||||
{
|
||||
if (rsg >= MAXPLAYERS)
|
||||
resynch_score[node] += 16384; // lol.
|
||||
else
|
||||
{
|
||||
resynch_status[node] &= ~(1<<rsg);
|
||||
--resynch_score[node]; // unpenalize
|
||||
}
|
||||
|
||||
// Don't let resynch cause a timeout
|
||||
freezetimeout[node] = I_GetTime() + connectiontimeout;
|
||||
}
|
||||
// -----------------------------------------------------------------
|
||||
// end resynch
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
static INT16 Consistancy(void);
|
||||
|
||||
#ifndef NONET
|
||||
|
@ -1617,6 +1020,11 @@ static void CL_LoadReceivedSavegame(boolean reloading)
|
|||
CONS_Alert(CONS_ERROR, M_GetText("Can't delete %s\n"), tmpsave);
|
||||
consistancy[gametic%BACKUPTICS] = Consistancy();
|
||||
CON_ToggleOff();
|
||||
|
||||
// Tell the server we have received and reloaded the gamestate
|
||||
// so they know they can resume the game
|
||||
netbuffer->packettype = PT_RECEIVEDGAMESTATE;
|
||||
HSendPacket(servernode, true, 0, 0);
|
||||
}
|
||||
|
||||
static void CL_ReloadReceivedSavegame(void)
|
||||
|
@ -2535,7 +1943,6 @@ void CL_Reset(void)
|
|||
multiplayer = false;
|
||||
servernode = 0;
|
||||
server = true;
|
||||
resynch_local_inprogress = false;
|
||||
doomcom->numnodes = 1;
|
||||
doomcom->numslots = 1;
|
||||
SV_StopServer();
|
||||
|
@ -3112,7 +2519,7 @@ static void ResetNode(INT32 node)
|
|||
nodewaiting[node] = 0;
|
||||
playerpernode[node] = 0;
|
||||
sendingsavegame[node] = false;
|
||||
SV_InitResynchVars(node);
|
||||
resendingsavegame[node] = false;
|
||||
}
|
||||
|
||||
void SV_ResetServer(void)
|
||||
|
@ -3634,12 +3041,6 @@ static void HandleConnect(SINT8 node)
|
|||
#endif
|
||||
SV_AddNode(node);
|
||||
|
||||
/// \note Wait what???
|
||||
/// What if the gamestate takes more than one second to get downloaded?
|
||||
/// Or if a lagspike happens?
|
||||
// you get a free second before desynch checks. use it wisely.
|
||||
SV_InitResynchVars(node);
|
||||
|
||||
if (cv_joinnextround.value && gameaction == ga_nothing)
|
||||
G_SetGamestate(GS_WAITINGPLAYERS);
|
||||
if (!SV_SendServerConfig(node))
|
||||
|
@ -3762,6 +3163,7 @@ static void PT_CanReceiveGamestate(SINT8 node)
|
|||
CONS_Printf(M_GetText("Resending game state to %s...\n"), player_names[nodetoplayer[node]]);
|
||||
|
||||
SV_SendSaveGame(node, true); // Resend a complete game state
|
||||
resendingsavegame[node] = true;
|
||||
}
|
||||
|
||||
/** Handles a packet received from a node that isn't in game
|
||||
|
@ -3976,11 +3378,6 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
switch (netbuffer->packettype)
|
||||
{
|
||||
// -------------------------------------------- SERVER RECEIVE ----------
|
||||
case PT_RESYNCHGET:
|
||||
if (client)
|
||||
break;
|
||||
SV_AcknowledgeResynchAck(netconsole, netbuffer->u.resynchgot);
|
||||
break;
|
||||
case PT_CLIENTCMD:
|
||||
case PT_CLIENT2CMD:
|
||||
case PT_CLIENTMIS:
|
||||
|
@ -3990,10 +3387,6 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
if (client)
|
||||
break;
|
||||
|
||||
// Ignore tics from those not synched
|
||||
if (resynch_inprogress[node] && nettics[node] == gametic)
|
||||
break;
|
||||
|
||||
// To save bytes, only the low byte of tic numbers are sent
|
||||
// Use ExpandTics to figure out what the rest of the bytes are
|
||||
realstart = ExpandTics(netbuffer->u.clientpak.client_tic);
|
||||
|
@ -4020,9 +3413,6 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS)
|
||||
break;
|
||||
|
||||
// If a client sends a ticcmd it should mean they are done receiving the savegame
|
||||
sendingsavegame[node] = false;
|
||||
|
||||
// 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?
|
||||
freezetimeout[node] = I_GetTime() + connectiontimeout;
|
||||
|
@ -4047,21 +3437,19 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
|
||||
&netbuffer->u.client2pak.cmd2, 1);
|
||||
|
||||
// A delay before we check resynching
|
||||
// Used on join or just after a synch fail
|
||||
if (resynch_delay[node])
|
||||
{
|
||||
--resynch_delay[node];
|
||||
break;
|
||||
}
|
||||
// Check player consistancy during the level
|
||||
if (realstart <= gametic && realstart > gametic - BACKUPTICS+1 && gamestate == GS_LEVEL
|
||||
&& consistancy[realstart%BACKUPTICS] != SHORT(netbuffer->u.clientpak.consistancy))
|
||||
&& consistancy[realstart%BACKUPTICS] != SHORT(netbuffer->u.clientpak.consistancy)
|
||||
&& !resendingsavegame[node])
|
||||
{
|
||||
SV_RequireResynch(node);
|
||||
if (cv_resynchattempts.value)
|
||||
{
|
||||
// Tell the client we are about to resend them the gamestate
|
||||
netbuffer->packettype = PT_WILLRESENDGAMESTATE;
|
||||
HSendPacket(node, true, 0, 0);
|
||||
|
||||
resendingsavegame[node] = true;
|
||||
|
||||
if (cv_resynchattempts.value && resynch_score[node] <= (unsigned)cv_resynchattempts.value*250)
|
||||
{
|
||||
if (cv_blamecfail.value)
|
||||
CONS_Printf(M_GetText("Synch failure for player %d (%s); expected %hd, got %hd\n"),
|
||||
netconsole+1, player_names[netconsole],
|
||||
|
@ -4081,8 +3469,6 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (resynch_score[node])
|
||||
--resynch_score[node];
|
||||
break;
|
||||
case PT_TEXTCMD2: // splitscreen special
|
||||
netconsole = nodetoplayer2[node];
|
||||
|
@ -4211,25 +3597,11 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
case PT_CANRECEIVEGAMESTATE:
|
||||
PT_CanReceiveGamestate(node);
|
||||
break;
|
||||
case PT_RECEIVEDGAMESTATE:
|
||||
sendingsavegame[node] = false;
|
||||
resendingsavegame[node] = false;
|
||||
break;
|
||||
// -------------------------------------------- CLIENT RECEIVE ----------
|
||||
case PT_RESYNCHEND:
|
||||
// Only accept PT_RESYNCHEND from the server.
|
||||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHEND", node);
|
||||
if (server)
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
break;
|
||||
}
|
||||
resynch_local_inprogress = false;
|
||||
|
||||
P_SetRandSeed(netbuffer->u.resynchend.randomseed);
|
||||
|
||||
if (gametyperules & GTR_TEAMFLAGS)
|
||||
resynch_read_ctf(&netbuffer->u.resynchend);
|
||||
resynch_read_others(&netbuffer->u.resynchend);
|
||||
|
||||
break;
|
||||
case PT_SERVERTICS:
|
||||
// Only accept PT_SERVERTICS from the server.
|
||||
if (node != servernode)
|
||||
|
@ -4293,18 +3665,6 @@ static void HandlePacketFromPlayer(SINT8 node)
|
|||
"IRC or Discord so it can be fixed.\n", (INT32)realstart, (INT32)realend, (INT32)neededtic);*/
|
||||
}
|
||||
break;
|
||||
case PT_RESYNCHING:
|
||||
// Only accept PT_RESYNCHING from the server.
|
||||
if (node != servernode)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_RESYNCHING", node);
|
||||
if (server)
|
||||
SendKick(netconsole, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
|
||||
break;
|
||||
}
|
||||
resynch_local_inprogress = true;
|
||||
CL_AcknowledgeResynch(&netbuffer->u.resynchpak);
|
||||
break;
|
||||
case PT_PING:
|
||||
// Only accept PT_PING from the server.
|
||||
if (node != servernode)
|
||||
|
@ -4832,7 +4192,7 @@ void TryRunTics(tic_t realtics)
|
|||
if (player_joining)
|
||||
return;
|
||||
|
||||
if (neededtic > gametic && !resynch_local_inprogress)
|
||||
if (neededtic > gametic)
|
||||
{
|
||||
if (advancedemo)
|
||||
{
|
||||
|
@ -4991,9 +4351,9 @@ void NetUpdate(void)
|
|||
if (cl_redownloadinggamestate && fileneeded[0].status == FS_FOUND)
|
||||
CL_ReloadReceivedSavegame();
|
||||
|
||||
if (!(resynch_local_inprogress || cl_redownloadinggamestate))
|
||||
if (!cl_redownloadinggamestate)
|
||||
CL_SendClientCmd(); // Send tic cmd
|
||||
hu_resynching = resynch_local_inprogress;
|
||||
hu_redownloadinggamestate = cl_redownloadinggamestate;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5001,7 +4361,7 @@ void NetUpdate(void)
|
|||
{
|
||||
INT32 counts;
|
||||
|
||||
hu_resynching = false;
|
||||
hu_redownloadinggamestate = false;
|
||||
|
||||
firstticstosend = gametic;
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
|
@ -5011,18 +4371,6 @@ void NetUpdate(void)
|
|||
// Don't erase tics not acknowledged
|
||||
counts = realtics;
|
||||
|
||||
for (i = 0; i < MAXNETNODES; ++i)
|
||||
if (resynch_inprogress[i])
|
||||
{
|
||||
if (!nodeingame[i] || nettics[i] == gametic)
|
||||
{
|
||||
SV_SendResynch(i);
|
||||
counts = -666;
|
||||
}
|
||||
else
|
||||
counts = 0; // Let the client catch up with the server
|
||||
}
|
||||
|
||||
// Do not make tics while resynching
|
||||
if (counts != -666)
|
||||
{
|
||||
|
@ -5040,7 +4388,7 @@ void NetUpdate(void)
|
|||
neededtic = maketic; // The server is a client too
|
||||
}
|
||||
else
|
||||
hu_resynching = true;
|
||||
hu_redownloadinggamestate = true;
|
||||
}
|
||||
}
|
||||
Net_AckTicker();
|
||||
|
|
169
src/d_clisrv.h
169
src/d_clisrv.h
|
@ -64,11 +64,10 @@ typedef enum
|
|||
PT_REQUESTFILE, // Client requests a file transfer
|
||||
PT_ASKINFOVIAMS, // Packet from the MS requesting info be sent to new client.
|
||||
// If this ID changes, update masterserver definition.
|
||||
PT_RESYNCHEND, // Player is now resynched and is being requested to remake the gametic
|
||||
PT_RESYNCHGET, // Player got resynch packet
|
||||
|
||||
PT_WILLRESENDGAMESTATE, // Hey Client, I am about to resend you the gamestate!
|
||||
PT_CANRECEIVEGAMESTATE, // Okay Server, I'm ready to receive it, you can go ahead.
|
||||
PT_RECEIVEDGAMESTATE, // Thank you Server, I am ready to play again!
|
||||
|
||||
// Add non-PT_CANFAIL packet types here to avoid breaking MS compatibility.
|
||||
|
||||
|
@ -82,8 +81,6 @@ typedef enum
|
|||
PT_TEXTCMD2, // Splitscreen text commands.
|
||||
PT_CLIENTJOIN, // Client wants to join; used in start game.
|
||||
PT_NODETIMEOUT, // Packet sent to self if the connection times out.
|
||||
PT_RESYNCHING, // Packet sent to resync players.
|
||||
// Blocks game advance until synched.
|
||||
|
||||
PT_LOGIN, // Login attempt from the client.
|
||||
|
||||
|
@ -136,165 +133,6 @@ typedef struct
|
|||
ticcmd_t cmds[45]; // Normally [BACKUPTIC][MAXPLAYERS] but too large
|
||||
} ATTRPACK servertics_pak;
|
||||
|
||||
// Sent to client when all consistency data
|
||||
// for players has been restored
|
||||
typedef struct
|
||||
{
|
||||
UINT32 randomseed;
|
||||
|
||||
// CTF flag stuff
|
||||
SINT8 flagplayer[2];
|
||||
INT32 flagloose[2];
|
||||
INT32 flagflags[2];
|
||||
fixed_t flagx[2];
|
||||
fixed_t flagy[2];
|
||||
fixed_t flagz[2];
|
||||
|
||||
UINT32 ingame; // Spectator bit for each player
|
||||
UINT32 outofcoop; // outofcoop bit for each player
|
||||
INT32 ctfteam[MAXPLAYERS]; // Which team? (can't be 1 bit, since in regular Match there are no teams)
|
||||
|
||||
// Resynch game scores and the like all at once
|
||||
UINT32 score[MAXPLAYERS]; // Everyone's score
|
||||
INT16 numboxes[MAXPLAYERS];
|
||||
INT16 totalring[MAXPLAYERS];
|
||||
tic_t realtime[MAXPLAYERS];
|
||||
UINT8 laps[MAXPLAYERS];
|
||||
} ATTRPACK resynchend_pak;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Player stuff
|
||||
UINT8 playernum;
|
||||
|
||||
// Do not send anything visual related.
|
||||
// Only send data that we need to know for physics.
|
||||
UINT8 playerstate; // playerstate_t
|
||||
UINT32 pflags; // pflags_t
|
||||
UINT8 panim; // panim_t
|
||||
|
||||
angle_t aiming;
|
||||
INT32 currentweapon;
|
||||
INT32 ringweapons;
|
||||
UINT16 ammoremoval;
|
||||
tic_t ammoremovaltimer;
|
||||
INT32 ammoremovalweapon;
|
||||
UINT16 powers[NUMPOWERS];
|
||||
|
||||
// Score is resynched in the confirm resync packet
|
||||
INT16 rings;
|
||||
INT16 spheres;
|
||||
SINT8 lives;
|
||||
SINT8 continues;
|
||||
UINT8 scoreadd;
|
||||
SINT8 xtralife;
|
||||
SINT8 pity;
|
||||
|
||||
UINT8 skincolor;
|
||||
INT32 skin;
|
||||
UINT32 availabilities;
|
||||
// Just in case Lua does something like
|
||||
// modify these at runtime
|
||||
fixed_t camerascale;
|
||||
fixed_t shieldscale;
|
||||
fixed_t normalspeed;
|
||||
fixed_t runspeed;
|
||||
UINT8 thrustfactor;
|
||||
UINT8 accelstart;
|
||||
UINT8 acceleration;
|
||||
UINT8 charability;
|
||||
UINT8 charability2;
|
||||
UINT32 charflags;
|
||||
UINT32 thokitem; // mobjtype_t
|
||||
UINT32 spinitem; // mobjtype_t
|
||||
UINT32 revitem; // mobjtype_t
|
||||
UINT32 followitem; // mobjtype_t
|
||||
fixed_t actionspd;
|
||||
fixed_t mindash;
|
||||
fixed_t maxdash;
|
||||
fixed_t jumpfactor;
|
||||
fixed_t playerheight;
|
||||
fixed_t playerspinheight;
|
||||
|
||||
fixed_t speed;
|
||||
UINT8 secondjump;
|
||||
UINT8 fly1;
|
||||
tic_t glidetime;
|
||||
UINT8 climbing;
|
||||
INT32 deadtimer;
|
||||
tic_t exiting;
|
||||
UINT8 homing;
|
||||
tic_t dashmode;
|
||||
tic_t skidtime;
|
||||
fixed_t cmomx;
|
||||
fixed_t cmomy;
|
||||
fixed_t rmomx;
|
||||
fixed_t rmomy;
|
||||
|
||||
INT32 weapondelay;
|
||||
INT32 tossdelay;
|
||||
|
||||
INT16 starpostx;
|
||||
INT16 starposty;
|
||||
INT16 starpostz;
|
||||
INT32 starpostnum;
|
||||
tic_t starposttime;
|
||||
angle_t starpostangle;
|
||||
fixed_t starpostscale;
|
||||
|
||||
INT32 maxlink;
|
||||
fixed_t dashspeed;
|
||||
angle_t angle_pos;
|
||||
angle_t old_angle_pos;
|
||||
tic_t bumpertime;
|
||||
INT32 flyangle;
|
||||
tic_t drilltimer;
|
||||
INT32 linkcount;
|
||||
tic_t linktimer;
|
||||
INT32 anotherflyangle;
|
||||
tic_t nightstime;
|
||||
INT32 drillmeter;
|
||||
UINT8 drilldelay;
|
||||
UINT8 bonustime;
|
||||
UINT8 mare;
|
||||
INT16 lastsidehit, lastlinehit;
|
||||
|
||||
tic_t losstime;
|
||||
UINT8 timeshit;
|
||||
INT32 onconveyor;
|
||||
|
||||
//player->mo stuff
|
||||
UINT8 hasmo; // Boolean
|
||||
|
||||
INT32 health;
|
||||
angle_t angle;
|
||||
angle_t rollangle;
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t z;
|
||||
fixed_t momx;
|
||||
fixed_t momy;
|
||||
fixed_t momz;
|
||||
fixed_t friction;
|
||||
fixed_t movefactor;
|
||||
|
||||
spritenum_t sprite;
|
||||
UINT32 frame;
|
||||
UINT8 sprite2;
|
||||
UINT16 anim_duration;
|
||||
INT32 tics;
|
||||
statenum_t statenum;
|
||||
UINT32 flags;
|
||||
UINT32 flags2;
|
||||
UINT16 eflags;
|
||||
|
||||
fixed_t radius;
|
||||
fixed_t height;
|
||||
fixed_t scale;
|
||||
fixed_t destscale;
|
||||
fixed_t scalespeed;
|
||||
} ATTRPACK resynch_pak;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 version; // Different versions don't work
|
||||
|
@ -430,9 +268,6 @@ typedef struct
|
|||
client2cmd_pak client2pak; // 200 bytes
|
||||
servertics_pak serverpak; // 132495 bytes (more around 360, no?)
|
||||
serverconfig_pak servercfg; // 773 bytes
|
||||
resynchend_pak resynchend; //
|
||||
resynch_pak resynchpak; //
|
||||
UINT8 resynchgot; //
|
||||
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
|
||||
filetx_pak filetxpak; // 139 bytes
|
||||
clientconfig_pak clientcfg; // 136 bytes
|
||||
|
@ -567,7 +402,7 @@ UINT8 GetFreeXCmdSize(void);
|
|||
|
||||
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest);
|
||||
|
||||
extern UINT8 hu_resynching;
|
||||
extern UINT8 hu_redownloadinggamestate;
|
||||
|
||||
extern UINT8 adminpassmd5[16];
|
||||
extern boolean adminpasswordset;
|
||||
|
|
|
@ -2206,7 +2206,7 @@ void HU_Drawer(void)
|
|||
HU_DrawCrosshair2();
|
||||
|
||||
// draw desynch text
|
||||
if (hu_resynching)
|
||||
if (hu_redownloadinggamestate)
|
||||
{
|
||||
static UINT32 resynch_ticker = 0;
|
||||
char resynch_text[14];
|
||||
|
|
Loading…
Reference in a new issue