+static void CL_ParsePointParticles1(void)
+{
+ int effectindex;
+ vec3_t origin;
+ effectindex = (unsigned short)MSG_ReadShort(&cl_message);
+ MSG_ReadVector(&cl_message, origin, cls.protocol);
+ CL_ParticleEffect(effectindex, 1, origin, origin, vec3_origin, vec3_origin, NULL, 0);
+}
+
+typedef struct cl_iplog_item_s
+{
+ char *address;
+ char *name;
+}
+cl_iplog_item_t;
+
+static qboolean cl_iplog_loaded = false;
+static int cl_iplog_numitems = 0;
+static int cl_iplog_maxitems = 0;
+static cl_iplog_item_t *cl_iplog_items;
+
+static void CL_IPLog_Load(void);
+static void CL_IPLog_Add(const char *address, const char *name, qboolean checkexisting, qboolean addtofile)
+{
+ int i;
+ size_t sz_name, sz_address;
+ if (!address || !address[0] || !name || !name[0])
+ return;
+ if (!cl_iplog_loaded)
+ CL_IPLog_Load();
+ if (developer_extra.integer)
+ Con_DPrintf("CL_IPLog_Add(\"%s\", \"%s\", %i, %i);\n", address, name, checkexisting, addtofile);
+ // see if it already exists
+ if (checkexisting)
+ {
+ for (i = 0;i < cl_iplog_numitems;i++)
+ {
+ if (!strcmp(cl_iplog_items[i].address, address) && !strcmp(cl_iplog_items[i].name, name))
+ {
+ if (developer_extra.integer)
+ Con_DPrintf("... found existing \"%s\" \"%s\"\n", cl_iplog_items[i].address, cl_iplog_items[i].name);
+ return;
+ }
+ }
+ }
+ // it does not already exist in the iplog, so add it
+ if (cl_iplog_maxitems <= cl_iplog_numitems || !cl_iplog_items)
+ {
+ cl_iplog_item_t *olditems = cl_iplog_items;
+ cl_iplog_maxitems = max(1024, cl_iplog_maxitems + 256);
+ cl_iplog_items = (cl_iplog_item_t *) Mem_Alloc(cls.permanentmempool, cl_iplog_maxitems * sizeof(cl_iplog_item_t));
+ if (olditems)
+ {
+ if (cl_iplog_numitems)
+ memcpy(cl_iplog_items, olditems, cl_iplog_numitems * sizeof(cl_iplog_item_t));
+ Mem_Free(olditems);
+ }
+ }
+ sz_address = strlen(address) + 1;
+ sz_name = strlen(name) + 1;
+ cl_iplog_items[cl_iplog_numitems].address = (char *) Mem_Alloc(cls.permanentmempool, sz_address);
+ cl_iplog_items[cl_iplog_numitems].name = (char *) Mem_Alloc(cls.permanentmempool, sz_name);
+ strlcpy(cl_iplog_items[cl_iplog_numitems].address, address, sz_address);
+ // TODO: maybe it would be better to strip weird characters from name when
+ // copying it here rather than using a straight strcpy?
+ strlcpy(cl_iplog_items[cl_iplog_numitems].name, name, sz_name);
+ cl_iplog_numitems++;
+ if (addtofile)
+ {
+ // add it to the iplog.txt file
+ // TODO: this ought to open the one in the userpath version of the base
+ // gamedir, not the current gamedir
+// not necessary for mobile
+#ifndef DP_MOBILETOUCH
+ Log_Printf(cl_iplog_name.string, "%s %s\n", address, name);
+ if (developer_extra.integer)
+ Con_DPrintf("CL_IPLog_Add: appending this line to %s: %s %s\n", cl_iplog_name.string, address, name);
+#endif
+ }
+}
+
+static void CL_IPLog_Load(void)
+{
+ int i, len, linenumber;
+ char *text, *textend;
+ unsigned char *filedata;
+ fs_offset_t filesize;
+ char line[MAX_INPUTLINE];
+ char address[MAX_INPUTLINE];
+ cl_iplog_loaded = true;
+ // TODO: this ought to open the one in the userpath version of the base
+ // gamedir, not the current gamedir
+// not necessary for mobile
+#ifndef DP_MOBILETOUCH
+ filedata = FS_LoadFile(cl_iplog_name.string, tempmempool, true, &filesize);
+#else
+ filedata = NULL;
+#endif
+ if (!filedata)
+ return;
+ text = (char *)filedata;
+ textend = text + filesize;
+ for (linenumber = 1;text < textend;linenumber++)
+ {
+ for (len = 0;text < textend && *text != '\r' && *text != '\n';text++)
+ if (len < (int)sizeof(line) - 1)
+ line[len++] = *text;
+ line[len] = 0;
+ if (text < textend && *text == '\r' && text[1] == '\n')
+ text++;
+ if (text < textend && *text == '\n')
+ text++;
+ if (line[0] == '/' && line[1] == '/')
+ continue; // skip comments if anyone happens to add them
+ for (i = 0;i < len && !ISWHITESPACE(line[i]);i++)
+ address[i] = line[i];
+ address[i] = 0;
+ // skip exactly one space character
+ i++;
+ // address contains the address with termination,
+ // line + i contains the name with termination
+ if (address[0] && line[i])
+ CL_IPLog_Add(address, line + i, false, false);
+ else
+ Con_Printf("%s:%i: could not parse address and name:\n%s\n", cl_iplog_name.string, linenumber, line);
+ }
+}
+
+static void CL_IPLog_List_f(void)
+{
+ int i, j;
+ const char *addressprefix;
+ if (Cmd_Argc() > 2)
+ {
+ Con_Printf("usage: %s 123.456.789.\n", Cmd_Argv(0));
+ return;
+ }
+ addressprefix = "";
+ if (Cmd_Argc() >= 2)
+ addressprefix = Cmd_Argv(1);
+ if (!cl_iplog_loaded)
+ CL_IPLog_Load();
+ if (addressprefix && addressprefix[0])
+ Con_Printf("Listing iplog addresses beginning with %s\n", addressprefix);
+ else
+ Con_Printf("Listing all iplog entries\n");
+ Con_Printf("address name\n");
+ for (i = 0;i < cl_iplog_numitems;i++)
+ {
+ if (addressprefix && addressprefix[0])
+ {
+ for (j = 0;addressprefix[j];j++)
+ if (addressprefix[j] != cl_iplog_items[i].address[j])
+ break;
+ // if this address does not begin with the addressprefix string
+ // simply omit it from the output
+ if (addressprefix[j])
+ continue;
+ }
+ // if name is less than 15 characters, left justify it and pad
+ // if name is more than 15 characters, print all of it, not worrying
+ // about the fact it will misalign the columns
+ if (strlen(cl_iplog_items[i].address) < 15)
+ Con_Printf("%-15s %s\n", cl_iplog_items[i].address, cl_iplog_items[i].name);
+ else
+ Con_Printf("%5s %s\n", cl_iplog_items[i].address, cl_iplog_items[i].name);
+ }
+}
+