Commit 8bcc2662 by James R.

Merge branch 'netid-take-2' into 'next'

Use ordered id for netvars instead of shitty hash See merge request !1010
parents df98601b d9005203
...@@ -150,15 +150,15 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr) ...@@ -150,15 +150,15 @@ FUNCINLINE static ATTRINLINE UINT32 readulong(void *ptr)
#undef DEALIGNED #undef DEALIGNED
#define WRITESTRINGN(p,s,n) { size_t tmp_i = 0; for (; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); if (tmp_i < n) WRITECHAR(p, '\0');} #define WRITESTRINGN(p,s,n) do { size_t tmp_i = 0; for (; tmp_i < n && s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); if (tmp_i < n) WRITECHAR(p, '\0');} while (0)
#define WRITESTRING(p,s) { size_t tmp_i = 0; for (; s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); WRITECHAR(p, '\0');} #define WRITESTRING(p,s) do { size_t tmp_i = 0; for (; s[tmp_i] != '\0'; tmp_i++) WRITECHAR(p, s[tmp_i]); WRITECHAR(p, '\0');} while (0)
#define WRITEMEM(p,s,n) { memcpy(p, s, n); p += n; } #define WRITEMEM(p,s,n) do { memcpy(p, s, n); p += n; } while (0)
#define SKIPSTRING(p) while (READCHAR(p) != '\0') #define SKIPSTRING(p) while (READCHAR(p) != '\0')
#define READSTRINGN(p,s,n) { size_t tmp_i = 0; for (; tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';} #define READSTRINGN(p,s,n) ({ size_t tmp_i = 0; for (; tmp_i < n && (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';})
#define READSTRING(p,s) { size_t tmp_i = 0; for (; (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';} #define READSTRING(p,s) ({ size_t tmp_i = 0; for (; (s[tmp_i] = READCHAR(p)) != '\0'; tmp_i++); s[tmp_i] = '\0';})
#define READMEM(p,s,n) { memcpy(s, p, n); p += n; } #define READMEM(p,s,n) ({ memcpy(s, p, n); p += n; })
#if 0 // old names #if 0 // old names
#define WRITEBYTE(p,b) WRITEUINT8(p,b) #define WRITEBYTE(p,b) WRITEUINT8(p,b)
......
...@@ -56,7 +56,13 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr); ...@@ -56,7 +56,13 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
static boolean CV_Command(void); static boolean CV_Command(void);
consvar_t *CV_FindVar(const char *name); consvar_t *CV_FindVar(const char *name);
static const char *CV_StringValue(const char *var_name); static const char *CV_StringValue(const char *var_name);
static consvar_t *consvar_vars; // list of registered console variables static consvar_t *consvar_vars; // list of registered console variables
static UINT16 consvar_number_of_netids = 0;
#ifdef OLD22DEMOCOMPAT
static old_demo_var_t *consvar_old_demo_vars;
#endif
static char com_token[1024]; static char com_token[1024];
static char *COM_Parse(char *data); static char *COM_Parse(char *data);
...@@ -1121,14 +1127,16 @@ consvar_t *CV_FindVar(const char *name) ...@@ -1121,14 +1127,16 @@ consvar_t *CV_FindVar(const char *name)
return NULL; return NULL;
} }
/** Builds a unique Net Variable identifier number, which is used #ifdef OLD22DEMOCOMPAT
* in network packets instead of the full name. /** Builds a unique Net Variable identifier number, which was used
* in network packets and demos instead of the full name.
*
* This function only still exists to keep compatibility with old demos.
* *
* \param s Name of the variable. * \param s Name of the variable.
* \return A new unique identifier. * \return A new unique identifier.
* \sa CV_FindNetVar
*/ */
static inline UINT16 CV_ComputeNetid(const char *s) static inline UINT16 CV_ComputeOldDemoID(const char *s)
{ {
UINT16 ret = 0, i = 0; UINT16 ret = 0, i = 0;
static UINT16 premiers[16] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53}; static UINT16 premiers[16] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};
...@@ -1142,16 +1150,47 @@ static inline UINT16 CV_ComputeNetid(const char *s) ...@@ -1142,16 +1150,47 @@ static inline UINT16 CV_ComputeNetid(const char *s)
return ret; return ret;
} }
/** Finds a net variable based on its old style hash. If a hash collides, a
* warning is printed and this function returns NULL.
*
* \param chk The variable's old style hash.
* \return A pointer to the variable itself if found, or NULL.
*/
static old_demo_var_t *CV_FindOldDemoVar(UINT16 chk)
{
old_demo_var_t *demovar;
for (demovar = consvar_old_demo_vars; demovar; demovar = demovar->next)
{
if (demovar->checksum == chk)
{
if (demovar->collides)
{
CONS_Alert(CONS_WARNING,
"Old demo netvar id %hu is a collision\n", chk);
return NULL;
}
return demovar;
}
}
return NULL;
}
#endif/*OLD22DEMOCOMPAT*/
/** Finds a net variable based on its identifier number. /** Finds a net variable based on its identifier number.
* *
* \param netid The variable's identifier number. * \param netid The variable's identifier number.
* \return A pointer to the variable itself if found, or NULL. * \return A pointer to the variable itself if found, or NULL.
* \sa CV_ComputeNetid
*/ */
static consvar_t *CV_FindNetVar(UINT16 netid) static consvar_t *CV_FindNetVar(UINT16 netid)
{ {
consvar_t *cvar; consvar_t *cvar;
if (netid >= consvar_number_of_netids)
return NULL;
for (cvar = consvar_vars; cvar; cvar = cvar->next) for (cvar = consvar_vars; cvar; cvar = cvar->next)
if (cvar->netid == netid) if (cvar->netid == netid)
return cvar; return cvar;
...@@ -1161,6 +1200,32 @@ static consvar_t *CV_FindNetVar(UINT16 netid) ...@@ -1161,6 +1200,32 @@ static consvar_t *CV_FindNetVar(UINT16 netid)
static void Setvalue(consvar_t *var, const char *valstr, boolean stealth); static void Setvalue(consvar_t *var, const char *valstr, boolean stealth);
#ifdef OLD22DEMOCOMPAT
/* Sets up a netvar for compatibility with old demos. */
static void CV_RegisterOldDemoVar(consvar_t *variable)
{
old_demo_var_t *demovar;
UINT16 old_demo_id;
old_demo_id = CV_ComputeOldDemoID(variable->name);
demovar = CV_FindOldDemoVar(old_demo_id);
if (demovar)
demovar->collides = true;
else
{
demovar = ZZ_Calloc(sizeof *demovar);
demovar->checksum = old_demo_id;
demovar->cvar = variable;
demovar->next = consvar_old_demo_vars;
consvar_old_demo_vars = demovar;
}
}
#endif
/** Registers a variable for later use from the console. /** Registers a variable for later use from the console.
* *
* \param variable The variable to register. * \param variable The variable to register.
...@@ -1184,11 +1249,15 @@ void CV_RegisterVar(consvar_t *variable) ...@@ -1184,11 +1249,15 @@ void CV_RegisterVar(consvar_t *variable)
// check net variables // check net variables
if (variable->flags & CV_NETVAR) if (variable->flags & CV_NETVAR)
{ {
const consvar_t *netvar; variable->netid = consvar_number_of_netids++;
variable->netid = CV_ComputeNetid(variable->name);
netvar = CV_FindNetVar(variable->netid); /* in case of overflow... */
if (netvar) if (variable->netid > consvar_number_of_netids)
I_Error("Variables %s and %s have same netid\n", variable->name, netvar->name); I_Error("Way too many netvars");
#ifdef OLD22DEMOCOMPAT
CV_RegisterOldDemoVar(variable);
#endif
} }
// link the variable in // link the variable in
...@@ -1448,12 +1517,100 @@ badinput: ...@@ -1448,12 +1517,100 @@ badinput:
static boolean serverloading = false; static boolean serverloading = false;
static consvar_t *
ReadNetVar (UINT8 **p, char **return_value, boolean *return_stealth)
{
UINT16 netid;
char *val;
boolean stealth;
consvar_t *cvar;
netid = READUINT16 (*p);
val = (char *)*p;
SKIPSTRING (*p);
stealth = READUINT8 (*p);
cvar = CV_FindNetVar(netid);
if (cvar)
{
(*return_value) = val;
(*return_stealth) = stealth;
DEBFILE(va("Netvar received: %s [netid=%d] value %s\n", cvar->name, netid, val));
}
else
CONS_Alert(CONS_WARNING, "Netvar not found with netid %hu\n", netid);
return cvar;
}
#ifdef OLD22DEMOCOMPAT
static consvar_t *
ReadOldDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
{
UINT16 id;
char *val;
boolean stealth;
old_demo_var_t *demovar;
id = READUINT16 (*p);
val = (char *)*p;
SKIPSTRING (*p);
stealth = READUINT8 (*p);
demovar = CV_FindOldDemoVar(id);
if (demovar)
{
(*return_value) = val;
(*return_stealth) = stealth;
return demovar->cvar;
}
else
{
CONS_Alert(CONS_WARNING, "Netvar not found with old demo id %hu\n", id);
return NULL;
}
}
#endif/*OLD22DEMOCOMPAT*/
static consvar_t *
ReadDemoVar (UINT8 **p, char **return_value, boolean *return_stealth)
{
char *name;
char *val;
boolean stealth;
consvar_t *cvar;
name = (char *)*p;
SKIPSTRING (*p);
val = (char *)*p;
SKIPSTRING (*p);
stealth = READUINT8 (*p);
cvar = CV_FindVar(name);
if (cvar)
{
(*return_value) = val;
(*return_stealth) = stealth;
}
else
CONS_Alert(CONS_WARNING, "Netvar not found with name %s\n", name);
return cvar;
}
static void Got_NetVar(UINT8 **p, INT32 playernum) static void Got_NetVar(UINT8 **p, INT32 playernum)
{ {
consvar_t *cvar; consvar_t *cvar;
UINT16 netid;
char *svalue; char *svalue;
UINT8 stealth = false; boolean stealth;
if (playernum != serverplayer && !IsPlayerAdmin(playernum) && !serverloading) if (playernum != serverplayer && !IsPlayerAdmin(playernum) && !serverloading)
{ {
...@@ -1463,23 +1620,14 @@ static void Got_NetVar(UINT8 **p, INT32 playernum) ...@@ -1463,23 +1620,14 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY); SendKick(playernum, KICK_MSG_CON_FAIL | KICK_MSG_KEEP_BODY);
return; return;
} }
netid = READUINT16(*p);
cvar = CV_FindNetVar(netid);
svalue = (char *)*p;
SKIPSTRING(*p);
stealth = READUINT8(*p);
if (!cvar) cvar = ReadNetVar(p, &svalue, &stealth);
{
CONS_Alert(CONS_WARNING, "Netvar not found with netid %hu\n", netid);
return;
}
DEBFILE(va("Netvar received: %s [netid=%d] value %s\n", cvar->name, netid, svalue));
Setvalue(cvar, svalue, stealth); if (cvar)
Setvalue(cvar, svalue, stealth);
} }
void CV_SaveNetVars(UINT8 **p) void CV_SaveVars(UINT8 **p, boolean in_demo)
{ {
consvar_t *cvar; consvar_t *cvar;
UINT8 *count_p = *p; UINT8 *count_p = *p;
...@@ -1491,7 +1639,10 @@ void CV_SaveNetVars(UINT8 **p) ...@@ -1491,7 +1639,10 @@ void CV_SaveNetVars(UINT8 **p)
for (cvar = consvar_vars; cvar; cvar = cvar->next) for (cvar = consvar_vars; cvar; cvar = cvar->next)
if ((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar)) if ((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar))
{ {
WRITEUINT16(*p, cvar->netid); if (in_demo)
WRITESTRING(*p, cvar->name);
else
WRITEUINT16(*p, cvar->netid);
WRITESTRING(*p, cvar->string); WRITESTRING(*p, cvar->string);
WRITEUINT8(*p, false); WRITEUINT8(*p, false);
++count; ++count;
...@@ -1499,11 +1650,15 @@ void CV_SaveNetVars(UINT8 **p) ...@@ -1499,11 +1650,15 @@ void CV_SaveNetVars(UINT8 **p)
WRITEUINT16(count_p, count); WRITEUINT16(count_p, count);
} }
void CV_LoadNetVars(UINT8 **p) static void CV_LoadVars(UINT8 **p,
consvar_t *(*got)(UINT8 **p, char **ret_value, boolean *ret_stealth))
{ {
consvar_t *cvar; consvar_t *cvar;
UINT16 count; UINT16 count;
char *val;
boolean stealth;
// prevent "invalid command received" // prevent "invalid command received"
serverloading = true; serverloading = true;
...@@ -1513,11 +1668,33 @@ void CV_LoadNetVars(UINT8 **p) ...@@ -1513,11 +1668,33 @@ void CV_LoadNetVars(UINT8 **p)
count = READUINT16(*p); count = READUINT16(*p);
while (count--) while (count--)
Got_NetVar(p, 0); {
cvar = (*got)(p, &val, &stealth);
if (cvar)
Setvalue(cvar, val, stealth);
}
serverloading = false; serverloading = false;
} }
void CV_LoadNetVars(UINT8 **p)
{
CV_LoadVars(p, ReadNetVar);
}
#ifdef OLD22DEMOCOMPAT
void CV_LoadOldDemoVars(UINT8 **p)
{
CV_LoadVars(p, ReadOldDemoVar);
}
#endif
void CV_LoadDemoVars(UINT8 **p)
{
CV_LoadVars(p, ReadDemoVar);
}
static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth); static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth);
void CV_ResetCheatNetVars(void) void CV_ResetCheatNetVars(void)
......
...@@ -144,6 +144,19 @@ typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NUL ...@@ -144,6 +144,19 @@ typedef struct consvar_s //NULL, NULL, 0, NULL, NULL |, 0, NULL, NULL, 0, 0, NUL
struct consvar_s *next; struct consvar_s *next;
} consvar_t; } consvar_t;
#ifdef OLD22DEMOCOMPAT
typedef struct old_demo_var old_demo_var_t;
struct old_demo_var
{
UINT16 checksum;
boolean collides;/* this var is a collision of multiple hashes */
consvar_t *cvar;
old_demo_var_t *next;
};
#endif/*OLD22DEMOCOMPAT*/
extern CV_PossibleValue_t CV_OnOff[]; extern CV_PossibleValue_t CV_OnOff[];
extern CV_PossibleValue_t CV_YesNo[]; extern CV_PossibleValue_t CV_YesNo[];
extern CV_PossibleValue_t CV_Unsigned[]; extern CV_PossibleValue_t CV_Unsigned[];
...@@ -184,9 +197,18 @@ void CV_AddValue(consvar_t *var, INT32 increment); ...@@ -184,9 +197,18 @@ void CV_AddValue(consvar_t *var, INT32 increment);
void CV_SaveVariables(FILE *f); void CV_SaveVariables(FILE *f);
// load/save gamesate (load and save option and for network join in game) // load/save gamesate (load and save option and for network join in game)
void CV_SaveNetVars(UINT8 **p); void CV_SaveVars(UINT8 **p, boolean in_demo);
#define CV_SaveNetVars(p) CV_SaveVars(p, false)
void CV_LoadNetVars(UINT8 **p); void CV_LoadNetVars(UINT8 **p);
#define CV_SaveDemoVars(p) CV_SaveVars(p, true)
void CV_LoadDemoVars(UINT8 **p);
#ifdef OLD22DEMOCOMPAT
void CV_LoadOldDemoVars(UINT8 **p);
#endif
// reset cheat netvars after cheats is deactivated // reset cheat netvars after cheats is deactivated
void CV_ResetCheatNetVars(void); void CV_ResetCheatNetVars(void);
......
...@@ -657,4 +657,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; ...@@ -657,4 +657,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Render flats on walls /// Render flats on walls
#define WALLFLATS #define WALLFLATS
/// Maintain compatibility with older 2.2 demos
#define OLD22DEMOCOMPAT
#endif // __DOOMDEF__ #endif // __DOOMDEF__
...@@ -1525,7 +1525,7 @@ void G_BeginRecording(void) ...@@ -1525,7 +1525,7 @@ void G_BeginRecording(void)
} }
// Save netvar data // Save netvar data
CV_SaveNetVars(&demo_p); CV_SaveDemoVars(&demo_p);
memset(&oldcmd,0,sizeof(oldcmd)); memset(&oldcmd,0,sizeof(oldcmd));
memset(&oldghost,0,sizeof(oldghost)); memset(&oldghost,0,sizeof(oldghost));
...@@ -1756,6 +1756,9 @@ void G_DoPlayDemo(char *defdemoname) ...@@ -1756,6 +1756,9 @@ void G_DoPlayDemo(char *defdemoname)
UINT32 randseed, followitem; UINT32 randseed, followitem;
fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight; fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight;
char msg[1024]; char msg[1024];
#ifdef OLD22DEMOCOMPAT
boolean use_old_demo_vars = false;
#endif
skin[16] = '\0'; skin[16] = '\0';
color[MAXCOLORNAME] = '\0'; color[MAXCOLORNAME] = '\0';
...@@ -1818,10 +1821,13 @@ void G_DoPlayDemo(char *defdemoname) ...@@ -1818,10 +1821,13 @@ void G_DoPlayDemo(char *defdemoname)
case DEMOVERSION: // latest always supported case DEMOVERSION: // latest always supported
cnamelen = MAXCOLORNAME; cnamelen = MAXCOLORNAME;
break; break;
#ifdef OLD22DEMOCOMPAT
// all that changed between then and now was longer color name // all that changed between then and now was longer color name
case 0x000c: case 0x000c:
cnamelen = 16; cnamelen = 16;
use_old_demo_vars = true;
break; break;
#endif
// too old, cannot support. // too old, cannot support.
default: default:
snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname); snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname);
...@@ -1923,7 +1929,13 @@ void G_DoPlayDemo(char *defdemoname) ...@@ -1923,7 +1929,13 @@ void G_DoPlayDemo(char *defdemoname)
} }
// net var data // net var data
CV_LoadNetVars(&demo_p); #ifdef OLD22DEMOCOMPAT
if (use_old_demo_vars)
CV_LoadOldDemoVars(&demo_p);
else
#else
CV_LoadDemoVars(&demo_p);
#endif
// Sigh ... it's an empty demo. // Sigh ... it's an empty demo.
if (*demo_p == DEMOMARKER) if (*demo_p == DEMOMARKER)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment