X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=common.c;h=efea48511f9f20c4e4951563c91cabd8fe37159e;hp=80bd2a4ccd36596dd78e0fa2cb3ab2bac8ca8a9f;hb=7d08a8ba9d7925d79b903a087b97357968e011de;hpb=d159736a199e4043ed98cde48f6d5716ec40845c diff --git a/common.c b/common.c index 80bd2a4c..efea4851 100644 --- a/common.c +++ b/common.c @@ -177,6 +177,65 @@ unsigned short CRC_Block(const unsigned char *data, size_t size) return crc ^ CRC_XOR_VALUE; } +// QuakeWorld +static unsigned char chktbl[1024 + 4] = +{ + 0x78,0xd2,0x94,0xe3,0x41,0xec,0xd6,0xd5,0xcb,0xfc,0xdb,0x8a,0x4b,0xcc,0x85,0x01, + 0x23,0xd2,0xe5,0xf2,0x29,0xa7,0x45,0x94,0x4a,0x62,0xe3,0xa5,0x6f,0x3f,0xe1,0x7a, + 0x64,0xed,0x5c,0x99,0x29,0x87,0xa8,0x78,0x59,0x0d,0xaa,0x0f,0x25,0x0a,0x5c,0x58, + 0xfb,0x00,0xa7,0xa8,0x8a,0x1d,0x86,0x80,0xc5,0x1f,0xd2,0x28,0x69,0x71,0x58,0xc3, + 0x51,0x90,0xe1,0xf8,0x6a,0xf3,0x8f,0xb0,0x68,0xdf,0x95,0x40,0x5c,0xe4,0x24,0x6b, + 0x29,0x19,0x71,0x3f,0x42,0x63,0x6c,0x48,0xe7,0xad,0xa8,0x4b,0x91,0x8f,0x42,0x36, + 0x34,0xe7,0x32,0x55,0x59,0x2d,0x36,0x38,0x38,0x59,0x9b,0x08,0x16,0x4d,0x8d,0xf8, + 0x0a,0xa4,0x52,0x01,0xbb,0x52,0xa9,0xfd,0x40,0x18,0x97,0x37,0xff,0xc9,0x82,0x27, + 0xb2,0x64,0x60,0xce,0x00,0xd9,0x04,0xf0,0x9e,0x99,0xbd,0xce,0x8f,0x90,0x4a,0xdd, + 0xe1,0xec,0x19,0x14,0xb1,0xfb,0xca,0x1e,0x98,0x0f,0xd4,0xcb,0x80,0xd6,0x05,0x63, + 0xfd,0xa0,0x74,0xa6,0x86,0xf6,0x19,0x98,0x76,0x27,0x68,0xf7,0xe9,0x09,0x9a,0xf2, + 0x2e,0x42,0xe1,0xbe,0x64,0x48,0x2a,0x74,0x30,0xbb,0x07,0xcc,0x1f,0xd4,0x91,0x9d, + 0xac,0x55,0x53,0x25,0xb9,0x64,0xf7,0x58,0x4c,0x34,0x16,0xbc,0xf6,0x12,0x2b,0x65, + 0x68,0x25,0x2e,0x29,0x1f,0xbb,0xb9,0xee,0x6d,0x0c,0x8e,0xbb,0xd2,0x5f,0x1d,0x8f, + 0xc1,0x39,0xf9,0x8d,0xc0,0x39,0x75,0xcf,0x25,0x17,0xbe,0x96,0xaf,0x98,0x9f,0x5f, + 0x65,0x15,0xc4,0x62,0xf8,0x55,0xfc,0xab,0x54,0xcf,0xdc,0x14,0x06,0xc8,0xfc,0x42, + 0xd3,0xf0,0xad,0x10,0x08,0xcd,0xd4,0x11,0xbb,0xca,0x67,0xc6,0x48,0x5f,0x9d,0x59, + 0xe3,0xe8,0x53,0x67,0x27,0x2d,0x34,0x9e,0x9e,0x24,0x29,0xdb,0x69,0x99,0x86,0xf9, + 0x20,0xb5,0xbb,0x5b,0xb0,0xf9,0xc3,0x67,0xad,0x1c,0x9c,0xf7,0xcc,0xef,0xce,0x69, + 0xe0,0x26,0x8f,0x79,0xbd,0xca,0x10,0x17,0xda,0xa9,0x88,0x57,0x9b,0x15,0x24,0xba, + 0x84,0xd0,0xeb,0x4d,0x14,0xf5,0xfc,0xe6,0x51,0x6c,0x6f,0x64,0x6b,0x73,0xec,0x85, + 0xf1,0x6f,0xe1,0x67,0x25,0x10,0x77,0x32,0x9e,0x85,0x6e,0x69,0xb1,0x83,0x00,0xe4, + 0x13,0xa4,0x45,0x34,0x3b,0x40,0xff,0x41,0x82,0x89,0x79,0x57,0xfd,0xd2,0x8e,0xe8, + 0xfc,0x1d,0x19,0x21,0x12,0x00,0xd7,0x66,0xe5,0xc7,0x10,0x1d,0xcb,0x75,0xe8,0xfa, + 0xb6,0xee,0x7b,0x2f,0x1a,0x25,0x24,0xb9,0x9f,0x1d,0x78,0xfb,0x84,0xd0,0x17,0x05, + 0x71,0xb3,0xc8,0x18,0xff,0x62,0xee,0xed,0x53,0xab,0x78,0xd3,0x65,0x2d,0xbb,0xc7, + 0xc1,0xe7,0x70,0xa2,0x43,0x2c,0x7c,0xc7,0x16,0x04,0xd2,0x45,0xd5,0x6b,0x6c,0x7a, + 0x5e,0xa1,0x50,0x2e,0x31,0x5b,0xcc,0xe8,0x65,0x8b,0x16,0x85,0xbf,0x82,0x83,0xfb, + 0xde,0x9f,0x36,0x48,0x32,0x79,0xd6,0x9b,0xfb,0x52,0x45,0xbf,0x43,0xf7,0x0b,0x0b, + 0x19,0x19,0x31,0xc3,0x85,0xec,0x1d,0x8c,0x20,0xf0,0x3a,0xfa,0x80,0x4d,0x2c,0x7d, + 0xac,0x60,0x09,0xc0,0x40,0xee,0xb9,0xeb,0x13,0x5b,0xe8,0x2b,0xb1,0x20,0xf0,0xce, + 0x4c,0xbd,0xc6,0x04,0x86,0x70,0xc6,0x33,0xc3,0x15,0x0f,0x65,0x19,0xfd,0xc2,0xd3, + + // map checksum goes here + 0x00,0x00,0x00,0x00 +}; + +// QuakeWorld +unsigned char COM_BlockSequenceCRCByteQW(unsigned char *base, int length, int sequence) +{ + unsigned char *p; + unsigned char chkb[60 + 4]; + + p = chktbl + (sequence % (sizeof(chktbl) - 8)); + + if (length > 60) + length = 60; + memcpy(chkb, base, length); + + chkb[length] = (sequence & 0xff) ^ p[0]; + chkb[length+1] = p[1]; + chkb[length+2] = ((sequence>>8) & 0xff) ^ p[2]; + chkb[length+3] = p[3]; + + return CRC_Block(chkb, length + 4) & 0xff; +} /* ============================================================================== @@ -279,7 +338,7 @@ void MSG_WriteCoord32f (sizebuf_t *sb, float f) void MSG_WriteCoord (sizebuf_t *sb, float f, protocolversion_t protocol) { - if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE) + if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_QUAKEWORLD) MSG_WriteCoord13i (sb, f); else if (protocol == PROTOCOL_DARKPLACES1) MSG_WriteCoord32f (sb, f); @@ -320,7 +379,7 @@ void MSG_WriteAngle32f (sizebuf_t *sb, float f) void MSG_WriteAngle (sizebuf_t *sb, float f, protocolversion_t protocol) { - if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4) + if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4 || protocol == PROTOCOL_QUAKEWORLD) MSG_WriteAngle8i (sb, f); else MSG_WriteAngle16i (sb, f); @@ -420,7 +479,7 @@ char *MSG_ReadString (void) { static char string[MAX_INPUTLINE]; int l,c; - for (l = 0;l < (int) sizeof(string) - 1 && (c = MSG_ReadChar()) != -1 && c != 0;l++) + for (l = 0;l < (int) sizeof(string) - 1 && (c = MSG_ReadByte()) != -1 && c != 0;l++) string[l] = c; string[l] = 0; return string; @@ -429,7 +488,7 @@ char *MSG_ReadString (void) int MSG_ReadBytes (int numbytes, unsigned char *out) { int l, c; - for (l = 0;l < numbytes && (c = MSG_ReadChar()) != -1;l++) + for (l = 0;l < numbytes && (c = MSG_ReadByte()) != -1;l++) out[l] = c; return l; } @@ -451,7 +510,7 @@ float MSG_ReadCoord32f (void) float MSG_ReadCoord (protocolversion_t protocol) { - if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE) + if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_QUAKEWORLD) return MSG_ReadCoord13i(); else if (protocol == PROTOCOL_DARKPLACES1) return MSG_ReadCoord32f(); @@ -486,7 +545,7 @@ float MSG_ReadAngle32f (void) float MSG_ReadAngle (protocolversion_t protocol) { - if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4) + if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4 || protocol == PROTOCOL_QUAKEWORLD) return MSG_ReadAngle8i (); else return MSG_ReadAngle16i (); @@ -1254,6 +1313,139 @@ char *SearchInfostring(const char *infostring, const char *key) } } +void InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength) +{ + int pos = 0, j; + size_t keylength; + if (!key) + key = ""; + if (!value) + value = ""; + keylength = strlen(key); + if (valuelength < 1 || !value) + { + Con_Printf("InfoString_GetValue: no room in value\n"); + return; + } + value[0] = 0; + if (strchr(key, '\\')) + { + Con_Printf("InfoString_GetValue: key name \"%s\" contains \\ which is not possible in an infostring\n", key); + return; + } + if (strchr(key, '\"')) + { + Con_Printf("InfoString_SetValue: key name \"%s\" contains \" which is not allowed in an infostring\n", key); + return; + } + if (!key[0]) + { + Con_Printf("InfoString_GetValue: can not look up a key with no name\n"); + return; + } + while (buffer[pos] == '\\') + { + if (!memcmp(buffer + pos+1, key, keylength)) + { + for (pos++;buffer[pos] && buffer[pos] != '\\';pos++); + pos++; + for (j = 0;buffer[pos+j] && buffer[pos+j] != '\\' && j < (int)valuelength - 1;j++) + value[j] = buffer[pos+j]; + value[j] = 0; + return; + } + for (pos++;buffer[pos] && buffer[pos] != '\\';pos++); + for (pos++;buffer[pos] && buffer[pos] != '\\';pos++); + } + // if we reach this point the key was not found +} + +void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, const char *value) +{ + int pos = 0, pos2; + size_t keylength; + if (!key) + key = ""; + if (!value) + value = ""; + keylength = strlen(key); + if (strchr(key, '\\') || strchr(value, '\\')) + { + Con_Printf("InfoString_SetValue: \"%s\" \"%s\" contains \\ which is not possible to store in an infostring\n", key, value); + return; + } + if (strchr(key, '\"') || strchr(value, '\"')) + { + Con_Printf("InfoString_SetValue: \"%s\" \"%s\" contains \" which is not allowed in an infostring\n", key, value); + return; + } + if (!key[0]) + { + Con_Printf("InfoString_SetValue: can not set a key with no name\n"); + return; + } + while (buffer[pos] == '\\') + { + if (!memcmp(buffer + pos+1, key, keylength)) + break; + for (pos++;buffer[pos] && buffer[pos] != '\\';pos++); + for (pos++;buffer[pos] && buffer[pos] != '\\';pos++); + } + // if we found the key, find the end of it because we will be replacing it + pos2 = pos; + if (buffer[pos] == '\\') + { + for (pos2++;buffer[pos2] && buffer[pos2] != '\\';pos2++); + for (pos2++;buffer[pos2] && buffer[pos2] != '\\';pos2++); + } + if (bufferlength <= 1 + strlen(key) + 1 + strlen(value) + strlen(buffer + pos2)) + { + Con_Printf("InfoString_SetValue: no room for \"%s\" \"%s\" in infostring\n", key, value); + return; + } + if (value && value[0]) + { + // set the key/value and append the remaining text + char tempbuffer[4096]; + strlcpy(tempbuffer, buffer + pos2, sizeof(tempbuffer)); + sprintf(buffer + pos, "\\%s\\%s%s", key, value, tempbuffer); + } + else + { + // just remove the key from the text + strcpy(buffer + pos, buffer + pos2); + } +} + +void InfoString_Print(char *buffer) +{ + int i; + char key[2048]; + char value[2048]; + while (*buffer) + { + if (*buffer != '\\') + { + Con_Printf("InfoString_Print: corrupt string\n"); + return; + } + for (buffer++, i = 0;*buffer && *buffer != '\\';buffer++) + if (i < (int)sizeof(key)-1) + key[i++] = *buffer; + key[i] = 0; + if (*buffer != '\\') + { + Con_Printf("InfoString_Print: corrupt string\n"); + return; + } + for (buffer++, i = 0;*buffer && *buffer != '\\';buffer++) + if (i < (int)sizeof(value)-1) + value[i++] = *buffer; + value[i] = 0; + // empty value is an error case + Con_Printf("%20s %s\n", key, value[0] ? value : "NO VALUE"); + } +} //======================================================== // strlcat and strlcpy, from OpenBSD