]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - pr_edict.c
Lots of str[n]cat, str[n]cpy, and [v]sprintf have been replaced by strlcat, strlcpy...
[xonotic/darkplaces.git] / pr_edict.c
index 83a780e602e76839d59af352f4af32170b1788cb..750c26c23d82e4829600b262508ecb70fd0e0494 100644 (file)
@@ -39,8 +39,8 @@ mempool_t             *edictstring_mempool;
 
 int            type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
 
-ddef_t *ED_FieldAtOfs (int ofs);
-qboolean ED_ParseEpair (void *base, ddef_t *key, const char *s);
+ddef_t *ED_FieldAtOfs(int ofs);
+qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s);
 
 cvar_t pr_checkextension = {0, "pr_checkextension", "1"};
 cvar_t nomonsters = {0, "nomonsters", "0"};
@@ -119,6 +119,9 @@ int eval_movement;
 int eval_pmodel;
 int eval_punchvector;
 int eval_viewzoom;
+int eval_clientcolors;
+int eval_tag_entity;
+int eval_tag_index;
 
 mfunction_t *SV_PlayerPhysicsQC;
 mfunction_t *EndFrameQC;
@@ -170,6 +173,9 @@ void FindEdictFieldOffsets(void)
        eval_pmodel = FindFieldOffset("pmodel");
        eval_punchvector = FindFieldOffset("punchvector");
        eval_viewzoom = FindFieldOffset("viewzoom");
+       eval_clientcolors = FindFieldOffset("clientcolors");
+       eval_tag_entity = FindFieldOffset("tag_entity");
+       eval_tag_index = FindFieldOffset("tag_index");
 
        // LordHavoc: allowing QuakeC to override the player movement code
        SV_PlayerPhysicsQC = ED_FindFunction ("SV_PlayerPhysics");
@@ -188,8 +194,17 @@ Sets everything to NULL
 */
 void ED_ClearEdict (edict_t *e)
 {
+       int num;
        memset (e->v, 0, progs->entityfields * 4);
        e->e->free = false;
+       // LordHavoc: for consistency set these here
+       num = NUM_FOR_EDICT(e) - 1;
+       if (num >= 0 && num < svs.maxclients)
+       {
+               e->v->colormap = num + 1;
+               e->v->team = (svs.clients[num].colors & 15) + 1;
+               e->v->netname = PR_SetString(svs.clients[num].name);
+       }
 }
 
 /*
@@ -208,7 +223,7 @@ edict_t *ED_Alloc (void)
        int                     i;
        edict_t         *e;
 
-       for ( i=svs.maxclients+1 ; i<sv.num_edicts ; i++)
+       for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
        {
                e = EDICT_NUM(i);
                // the first couple seconds of server time can involve a lot of
@@ -509,17 +524,17 @@ char *PR_GlobalString (int ofs)
        val = (void *)&pr_globals[ofs];
        def = ED_GlobalAtOfs(ofs);
        if (!def)
-               sprintf (line,"%i(?)", ofs);
+               snprintf (line, sizeof (line), "%i(?)", ofs);
        else
        {
                s = PR_ValueString (def->type, val);
-               sprintf (line,"%i(%s)%s", ofs, PR_GetString(def->s_name), s);
+               snprintf (line, sizeof (line), "%i(%s)%s", ofs, PR_GetString(def->s_name), s);
        }
 
        i = strlen(line);
        for ( ; i<20 ; i++)
-               strcat (line," ");
-       strcat (line," ");
+               strlcat (line, " ", sizeof (line));
+       strlcat (line, " ", sizeof (line));
 
        return line;
 }
@@ -532,14 +547,14 @@ char *PR_GlobalStringNoContents (int ofs)
 
        def = ED_GlobalAtOfs(ofs);
        if (!def)
-               sprintf (line,"%i(?)", ofs);
+               snprintf (line, sizeof (line), "%i(?)", ofs);
        else
-               sprintf (line,"%i(%s)", ofs, PR_GetString(def->s_name));
+               snprintf (line, sizeof (line), "%i(%s)", ofs, PR_GetString(def->s_name));
 
        i = strlen(line);
        for ( ; i<20 ; i++)
-               strcat (line," ");
-       strcat (line," ");
+               strlcat (line, " ", sizeof (line));
+       strlcat (line, " ", sizeof (line));
 
        return line;
 }
@@ -597,7 +612,7 @@ void ED_Print (edict_t *ed)
                        tempstring2[259] = 0;
                        name = tempstring2;
                }
-               strcat(tempstring, name);
+               strlcat (tempstring, name, sizeof (tempstring));
                for (l = strlen(name);l < 14;l++)
                        strcat(tempstring, " ");
                strcat(tempstring, " ");
@@ -610,8 +625,8 @@ void ED_Print (edict_t *ed)
                        tempstring2[259] = 0;
                        name = tempstring2;
                }
-               strcat(tempstring, name);
-               strcat(tempstring, "\n");
+               strlcat (tempstring, name, sizeof (tempstring));
+               strlcat (tempstring, "\n", sizeof (tempstring));
                if (strlen(tempstring) >= 4096)
                {
                        Con_Printf("%s", tempstring);
@@ -799,7 +814,7 @@ void ED_ParseGlobals (const char *data)
        while (1)
        {
                // parse key
-               if (!COM_ParseToken (&data))
+               if (!COM_ParseToken(&data, false))
                        Host_Error ("ED_ParseEntity: EOF without closing brace");
                if (com_token[0] == '}')
                        break;
@@ -807,7 +822,7 @@ void ED_ParseGlobals (const char *data)
                strcpy (keyname, com_token);
 
                // parse value
-               if (!COM_ParseToken (&data))
+               if (!COM_ParseToken(&data, false))
                        Host_Error ("ED_ParseEntity: EOF without closing brace");
 
                if (com_token[0] == '}')
@@ -820,7 +835,7 @@ void ED_ParseGlobals (const char *data)
                        continue;
                }
 
-               if (!ED_ParseEpair ((void *)pr_globals, key, com_token))
+               if (!ED_ParseEpair(NULL, key, com_token))
                        Host_Error ("ED_ParseGlobals: parse error");
        }
 }
@@ -868,74 +883,81 @@ Can parse either fields or globals
 returns false if error
 =============
 */
-qboolean       ED_ParseEpair (void *base, ddef_t *key, const char *s)
+qboolean ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
 {
-       int             i;
-       char    string[128];
-       ddef_t  *def;
-       char    *v, *w;
-       void    *d;
-       mfunction_t     *func;
-
-       d = (void *)((int *)base + key->ofs);
+       int i;
+       ddef_t *def;
+       eval_t *val;
+       mfunction_t *func;
 
+       if (ent)
+               val = (eval_t *)((int *)ent->v + key->ofs);
+       else
+               val = (eval_t *)((int *)pr_globals + key->ofs);
        switch (key->type & ~DEF_SAVEGLOBAL)
        {
        case ev_string:
-               *(string_t *)d = PR_SetString(ED_NewString(s));
+               val->string = PR_SetString(ED_NewString(s));
                break;
 
        case ev_float:
-               *(float *)d = atof (s);
+               while (*s && *s <= ' ')
+                       s++;
+               val->_float = atof(s);
                break;
 
        case ev_vector:
-               strcpy (string, s);
-               v = string;
-               w = string;
-               for (i=0 ; i<3 ; i++)
+               for (i = 0;i < 3;i++)
                {
-                       while (*v && *v != ' ')
-                               v++;
-                       *v = 0;
-                       ((float *)d)[i] = atof (w);
-                       w = v = v+1;
+                       while (*s && *s <= ' ')
+                               s++;
+                       if (!*s)
+                               break;
+                       val->vector[i] = atof(s);
+                       while (*s > ' ')
+                               s++;
+                       if (!*s)
+                               break;
                }
                break;
 
        case ev_entity:
-               i = atoi (s);
+               while (*s && *s <= ' ')
+                       s++;
+               i = atoi(s);
                if (i < 0 || i >= MAX_EDICTS)
-                       Con_DPrintf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
+                       Con_Printf("ED_ParseEpair: ev_entity reference too large (edict %i >= MAX_EDICTS %i)\n", i, MAX_EDICTS);
                while (i >= sv.max_edicts)
                        SV_IncreaseEdicts();
-               *(int *)d = EDICT_TO_PROG(EDICT_NUM(i));
+               // if SV_IncreaseEdicts was called the base pointer needs to be updated
+               if (ent)
+                       val = (eval_t *)((int *)ent->v + key->ofs);
+               val->edict = EDICT_TO_PROG(EDICT_NUM(i));
                break;
 
        case ev_field:
-               def = ED_FindField (s);
+               def = ED_FindField(s);
                if (!def)
                {
-                       // LordHavoc: don't warn about worldspawn sky/fog fields because they don't require mod support
-                       if (strcmp(s, "sky") && strcmp(s, "fog") && strncmp(s, "fog_", 4) && strcmp(s, "farclip"))
-                               Con_DPrintf ("Can't find field %s\n", s);
+                       Con_DPrintf("ED_ParseEpair: Can't find field %s\n", s);
                        return false;
                }
-               *(int *)d = G_INT(def->ofs);
+               val->_int = G_INT(def->ofs);
                break;
 
        case ev_function:
-               func = ED_FindFunction (s);
+               func = ED_FindFunction(s);
                if (!func)
                {
-                       Con_DPrintf ("Can't find function %s\n", s);
+                       Con_Printf ("ED_ParseEpair: Can't find function %s\n", s);
                        return false;
                }
-               *(func_t *)d = func - pr_functions;
+               val->function = func - pr_functions;
                break;
 
        default:
-               break;
+               Con_Printf("ED_ParseEpair: Unknown key->type %i for key \"%s\"\n", key->type, PR_GetString(key->s_name));
+               return false;
        }
        return true;
 }
@@ -967,7 +989,7 @@ const char *ED_ParseEdict (const char *data, edict_t *ent)
        while (1)
        {
        // parse key
-               if (!COM_ParseToken (&data))
+               if (!COM_ParseToken(&data, false))
                        Host_Error ("ED_ParseEntity: EOF without closing brace");
                if (com_token[0] == '}')
                        break;
@@ -997,7 +1019,7 @@ const char *ED_ParseEdict (const char *data, edict_t *ent)
                }
 
        // parse value
-               if (!COM_ParseToken (&data))
+               if (!COM_ParseToken(&data, false))
                        Host_Error ("ED_ParseEntity: EOF without closing brace");
 
                if (com_token[0] == '}')
@@ -1024,7 +1046,7 @@ const char *ED_ParseEdict (const char *data, edict_t *ent)
                        sprintf (com_token, "0 %s 0", temp);
                }
 
-               if (!ED_ParseEpair ((void *)ent->v, key, com_token))
+               if (!ED_ParseEpair(ent, key, com_token))
                        Host_Error ("ED_ParseEdict: parse error");
        }
 
@@ -1067,7 +1089,7 @@ void ED_LoadFromFile (const char *data)
        while (1)
        {
 // parse the opening brace
-               if (!COM_ParseToken (&data))
+               if (!COM_ParseToken(&data, false))
                        break;
                if (com_token[0] != '{')
                        Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
@@ -1177,7 +1199,10 @@ dpfield_t dpfields[] =
        {ev_float, "ping"},
        {ev_vector, "movement"},
        {ev_float, "pmodel"},
-       {ev_vector, "punchvector"}
+       {ev_vector, "punchvector"},
+       {ev_float, "clientcolors"},
+       {ev_entity, "tag_entity"},
+       {ev_float, "tag_index"}
 };
 
 /*
@@ -1418,7 +1443,7 @@ void PR_Fields_f (void)
                return;
        }
        counts = Mem_Alloc(tempmempool, progs->numfielddefs * sizeof(int));
-       for (ednum = 0;ednum < MAX_EDICTS;ednum++)
+       for (ednum = 0;ednum < sv.max_edicts;ednum++)
        {
                ed = EDICT_NUM(ednum);
                if (ed->e->free)
@@ -1453,32 +1478,32 @@ void PR_Fields_f (void)
                switch(d->type & ~DEF_SAVEGLOBAL)
                {
                case ev_string:
-                       strcat(tempstring, "string   ");
+                       strlcat (tempstring, "string   ", sizeof (tempstring));
                        break;
                case ev_entity:
-                       strcat(tempstring, "entity   ");
+                       strlcat (tempstring, "entity   ", sizeof (tempstring));
                        break;
                case ev_function:
-                       strcat(tempstring, "function ");
+                       strlcat (tempstring, "function ", sizeof (tempstring));
                        break;
                case ev_field:
-                       strcat(tempstring, "field    ");
+                       strlcat (tempstring, "field    ", sizeof (tempstring));
                        break;
                case ev_void:
-                       strcat(tempstring, "void     ");
+                       strlcat (tempstring, "void     ", sizeof (tempstring));
                        break;
                case ev_float:
-                       strcat(tempstring, "float    ");
+                       strlcat (tempstring, "float    ", sizeof (tempstring));
                        break;
                case ev_vector:
-                       strcat(tempstring, "vector   ");
+                       strlcat (tempstring, "vector   ", sizeof (tempstring));
                        break;
                case ev_pointer:
-                       strcat(tempstring, "pointer  ");
+                       strlcat (tempstring, "pointer  ", sizeof (tempstring));
                        break;
                default:
-                       sprintf (tempstring2, "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
-                       strcat(tempstring, tempstring2);
+                       snprintf (tempstring2, sizeof (tempstring2), "bad type %i ", d->type & ~DEF_SAVEGLOBAL);
+                       strlcat (tempstring, tempstring2, sizeof (tempstring));
                        break;
                }
                if (strlen(name) > 256)
@@ -1488,12 +1513,12 @@ void PR_Fields_f (void)
                        tempstring2[259] = 0;
                        name = tempstring2;
                }
-               strcat(tempstring, name);
+               strcat (tempstring, name);
                for (j = strlen(name);j < 25;j++)
                        strcat(tempstring, " ");
-               sprintf(tempstring2, "%5d", counts[i]);
-               strcat(tempstring, tempstring2);
-               strcat(tempstring, "\n");
+               snprintf (tempstring2, sizeof (tempstring2), "%5d", counts[i]);
+               strlcat (tempstring, tempstring2, sizeof (tempstring));
+               strlcat (tempstring, "\n", sizeof (tempstring));
                if (strlen(tempstring) >= 4096)
                {
                        Con_Printf("%s", tempstring);
@@ -1506,7 +1531,7 @@ void PR_Fields_f (void)
                }
        }
        Mem_Free(counts);
-       Con_Printf("%i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts, %i bytes total spent on edict fields (%i needed)\n", progs->entityfields, used, progs->entityfields * 4, usedamount * 4, MAX_EDICTS, progs->entityfields * 4 * MAX_EDICTS, usedamount * 4 * MAX_EDICTS);
+       Con_Printf("%i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts allocated, %i bytes total spent on edict fields (%i needed)\n", progs->entityfields, used, progs->entityfields * 4, usedamount * 4, sv.max_edicts, progs->entityfields * 4 * sv.max_edicts, usedamount * 4 * sv.max_edicts);
 }
 
 void PR_Globals_f (void)