rendered paste body/* * packed.c * * Copyright 2007 Alam Arias <Alam.GBC@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */#include <stdio.h>#include <stdlib.h>#define PACKED#ifdef PACKED#define ATTRPACK __attribute__ ((packed))#else#define ATTRPACK#endif#define USHORT unsigned short#define ULONG unsigned longtypedef unsigned char byte;typedef ULONG tic_t;typedef int fixed_t;#define MAXSERVERNAME 32#define MAXTEXTCMD 256typedef struct { signed char forwardmove; // *2048 for move signed char sidemove; // *2048 for move short angleturn; // <<16 for angle delta - SAVED AS A BYTE into demos signed short aiming; // mouse aiming, see G_BuildTicCmd byte buttons;#ifdef PACKED byte dummy1[1];#endif} ATTRPACK ticcmd_t;typedef struct { byte client_tic; byte resendfrom; short consistancy; ticcmd_t cmd;} ATTRPACK clientcmd_pak;typedef struct { byte client_tic; byte resendfrom; short consistancy; ticcmd_t cmd, cmd2;} ATTRPACK client2cmd_pak;typedef struct { byte starttic; byte numtics; byte numslots; // "Slots filled": Highest player number in use plus one.#ifdef PACKED byte dummy1[1];#endif ticcmd_t cmds[45]; // normally [BACKUPTIC][MAXPLAYERS] but too large} ATTRPACK servertics_pak;typedef struct { byte version; // different versions don't work#ifdef PACKED byte dummy1[3];#endif ULONG subversion; // contains build version // server launch stuffs byte serverplayer; byte totalslotnum; // "Slots": highest player number in use plus one.#ifdef PACKED byte dummy2[2];#endif tic_t gametic; byte clientnode; byte gamestate;#ifdef PACKED byte dummy3[2];#endif ULONG playerdetected; // playeringame vector in bit field byte gametype; byte modifiedgame; char adminplayer; // needs to be signed byte netcvarstates[0];} ATTRPACK serverconfig_pak;typedef struct { char fileid;#ifdef PACKED byte dummy1[3];#endif ULONG position; USHORT size; byte data[0]; // size is variable using hardare_MAXPACKETLENGTH} ATTRPACK filetx_pak;typedef struct { byte version; // different versions don't work#ifdef PACKED byte dummy1[3];#endif ULONG subversion; // contains build version byte localplayers; byte mode;} ATTRPACK clientconfig_pak;typedef struct { byte version;#ifdef PACKED byte dummy1[3];#endif ULONG subversion; byte numberofplayer; byte maxplayer; byte gametype; byte modifiedgame; char adminplayer; // needs to be signed#ifdef PACKED byte dummy2[3];#endif tic_t time; fixed_t load; // unused for the moment char mapname[8]; char servername[MAXSERVERNAME]; byte fileneedednum; byte fileneeded[0]; // is filled with writexxx (byteptr.h)} ATTRPACK serverinfo_pak;typedef struct { char reason[255];} ATTRPACK serverrefuse_pak;typedef struct { byte version;#ifdef PACKED byte dummy1[3];#endif tic_t time; // used for ping evaluation} ATTRPACK askinfo_pak;typedef struct { ULONG checksum; byte ack; // if not null the node asks for acknowledgement, the receiver must resend the ack byte ackreturn; // the return of the ack number byte packettype; byte reserved; // padding union { clientcmd_pak clientpak; client2cmd_pak client2pak; servertics_pak serverpak; serverconfig_pak servercfg; byte textcmd[MAXTEXTCMD+1]; filetx_pak filetxpak; clientconfig_pak clientcfg; serverinfo_pak serverinfo; serverrefuse_pak serverrefuse; askinfo_pak askinfo; } u; // this is needed} ATTRPACK doomdata_t;static void packcheck(const char *str, const void *start, const void *end, const size_t wantoffset){ const size_t offset = (byte*)end-(byte*)start; printf("%s %zu = %zu\n", str, offset, wantoffset); if (offset && wantoffset && offset != wantoffset) exit(-1);}doomdata_t doombuf;int main(int argc, char** argv){ size_t i; packcheck("checksum ", &doombuf, &doombuf.checksum, 0); packcheck("ack ", &doombuf, &doombuf.ack, 4); packcheck("ackreturn ", &doombuf, &doombuf.ackreturn, 5); packcheck("packettype ", &doombuf, &doombuf.packettype, 6); packcheck("reserved ", &doombuf, &doombuf.reserved, 7); packcheck("clientpak ", &doombuf, &doombuf.u.clientpak, 8); { packcheck(" client_tic ", &doombuf.u.clientpak, &doombuf.u.clientpak.client_tic, 0); packcheck(" resendfrom ", &doombuf.u.clientpak, &doombuf.u.clientpak.resendfrom, 1); packcheck(" consistancy", &doombuf.u.clientpak, &doombuf.u.clientpak.consistancy, 2); packcheck(" cmd ", &doombuf.u.clientpak, &doombuf.u.clientpak.cmd, 4); //ticmd_t packcheck(" forwardmove", &doombuf.u.clientpak.cmd, &doombuf.u.clientpak.cmd.forwardmove, 0); packcheck(" sidemove ", &doombuf.u.clientpak.cmd, &doombuf.u.clientpak.cmd.sidemove, 1); packcheck(" angleturn ", &doombuf.u.clientpak.cmd, &doombuf.u.clientpak.cmd.angleturn, 2); packcheck(" aiming ", &doombuf.u.clientpak.cmd, &doombuf.u.clientpak.cmd.aiming, 4); packcheck(" buttons ", &doombuf.u.clientpak.cmd, &doombuf.u.clientpak.cmd.buttons, 6); } packcheck("client2pak ", &doombuf, &doombuf.u.client2pak, 8); { // no todo packcheck(" client_tic ", &doombuf.u.client2pak, &doombuf.u.client2pak.client_tic, 0); packcheck(" resendfrom ", &doombuf.u.client2pak, &doombuf.u.client2pak.resendfrom, 1); packcheck(" consistancy", &doombuf.u.client2pak, &doombuf.u.client2pak.consistancy, 2); packcheck(" cmd ", &doombuf.u.client2pak, &doombuf.u.client2pak.cmd, 4); //ticmd_t packcheck(" cmd2 ", &doombuf.u.client2pak, &doombuf.u.client2pak.cmd2, 12); //ticmd_t } packcheck("serverpak ", &doombuf, &doombuf.u.serverpak, 8); { packcheck(" starttic", &doombuf.u.serverpak, &doombuf.u.serverpak.starttic, 0); packcheck(" numtics ", &doombuf.u.serverpak, &doombuf.u.serverpak.numtics, 1); packcheck(" numslots", &doombuf.u.serverpak, &doombuf.u.serverpak.numslots, 2); packcheck(" cmds ", &doombuf.u.serverpak, &doombuf.u.serverpak.cmds, 4); //ticcmd_t[45] for (i=0; i < 45; i++) { //packcheck(" data", &doombuf.u.serverpak.cmds, &doombuf.u.serverpak.cmds[i], i*8); } } packcheck("servercfg ", &doombuf, &doombuf.u.servercfg, 8); { // done packcheck(" version ", &doombuf.u.servercfg, &doombuf.u.servercfg.version, 0); packcheck(" subversion ", &doombuf.u.servercfg, &doombuf.u.servercfg.subversion, 4); packcheck(" serverplayer ", &doombuf.u.servercfg, &doombuf.u.servercfg.serverplayer, 8); packcheck(" totalslotnum ", &doombuf.u.servercfg, &doombuf.u.servercfg.totalslotnum, 9); packcheck(" gametic ", &doombuf.u.servercfg, &doombuf.u.servercfg.gametic, 12); packcheck(" clientnode ", &doombuf.u.servercfg, &doombuf.u.servercfg.clientnode, 16); packcheck(" gamestate ", &doombuf.u.servercfg, &doombuf.u.servercfg.gamestate, 17); packcheck(" playerdetected", &doombuf.u.servercfg, &doombuf.u.servercfg.playerdetected, 20); packcheck(" gametype ", &doombuf.u.servercfg, &doombuf.u.servercfg.gametype, 24); packcheck(" modifiedgame ", &doombuf.u.servercfg, &doombuf.u.servercfg.modifiedgame, 25); packcheck(" adminplayer ", &doombuf.u.servercfg, &doombuf.u.servercfg.adminplayer, 26); packcheck(" netcvarstates ", &doombuf.u.servercfg, &doombuf.u.servercfg.netcvarstates, 27); } packcheck("textcmd ", &doombuf, &doombuf.u.textcmd, 8); { // packed? for (i=0; i < MAXTEXTCMD+1; i++) { //packcheck(" data", &doombuf.u.textcmd, &doombuf.u.textcmd[i], i); //byte textcmd[MAXTEXTCMD+1]; } } packcheck("filetxpak ", &doombuf, &doombuf.u.filetxpak, 8); { // done packcheck(" fileid ", &doombuf.u.filetxpak, &doombuf.u.filetxpak.fileid, 0); packcheck(" position", &doombuf.u.filetxpak, &doombuf.u.filetxpak.position, 4); packcheck(" size ", &doombuf.u.filetxpak, &doombuf.u.filetxpak.size, 8); packcheck(" data ", &doombuf.u.filetxpak, &doombuf.u.filetxpak.data, 10); } packcheck("clientcfg ", &doombuf, &doombuf.u.clientcfg, 8); { // done packcheck(" version ", &doombuf.u.clientcfg, &doombuf.u.clientcfg.version, 0); packcheck(" sunversion ", &doombuf.u.clientcfg, &doombuf.u.clientcfg.subversion, 4); packcheck(" localplayers", &doombuf.u.clientcfg, &doombuf.u.clientcfg.localplayers, 8); packcheck(" mode ", &doombuf.u.clientcfg, &doombuf.u.clientcfg.mode, 9); } packcheck("serverinfo ", &doombuf, &doombuf.u.serverinfo, 8); { // not done packcheck(" version ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.version, 0); packcheck(" subversion ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.subversion, 4); packcheck(" numberofplayer", &doombuf.u.serverinfo, &doombuf.u.serverinfo.numberofplayer, 8); packcheck(" maxplayer ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.maxplayer, 9); packcheck(" gametype ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.gametype, 10); packcheck(" modifiedgame ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.modifiedgame, 11); packcheck(" adminplayer ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.adminplayer, 12); packcheck(" time ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.time, 16); packcheck(" load ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.load, 20); packcheck(" mapname ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.mapname, 24); //mapname[8[ packcheck(" servername ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.servername, 32); //server[MAXSEVERNAME] packcheck(" fileneedednum ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.fileneedednum, 64); packcheck(" fileneeded ", &doombuf.u.serverinfo, &doombuf.u.serverinfo.fileneeded, 65); //fileneeded[0] } packcheck("serverrefuse", &doombuf, &doombuf.u.serverrefuse, 8); { // done size_t i; for (i=0; i < 255; i++) { //packcheck(" data", &doombuf.u.serverrefuse, &doombuf.u.serverrefuse.reason[i], i); } } packcheck("askinfo ", &doombuf, &doombuf.u.askinfo, 8); { // done packcheck(" version", &doombuf.u.askinfo, &doombuf.u.askinfo.version, 0); packcheck(" time ", &doombuf.u.askinfo, &doombuf.u.askinfo.time, 4); } return 0;}