/* * Copyright (C) 1999 Peter Amstutz * * 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., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA */ #include #include #include #include "packets.h" /* pack and unpack functions are from Kernighan & Pike's _The Practice of Programming_ chapter 9 pg 218, modified to pack null-terminated strings as well */ int pktPack(ubyte_pkt * buf, char *fmt, ...) { va_list args; ubyte_pkt *p; ubyte_pkt *bp; ubyte_pkt *st; uint16_pkt s; uint32_pkt l; bp = buf; va_start(args, fmt); for(p = fmt; *p; p++) { switch (*p) { case 'c': *bp++ = (ubyte_pkt) va_arg(args, int); break; case 's': s = (uint16_pkt) va_arg(args, int); *bp++ = s >> 8; *bp++ = s; break; case 'l': l = (uint32_pkt) va_arg(args, int); *bp++ = l >> 24; *bp++ = l >> 16; *bp++ = l >> 8; *bp++ = l; break; case 'S': st = va_arg(args, char *); while(*st) *bp++ = *st++; *bp++ = 0; break; default: va_end(args); return -1; } } va_end(args); return (bp - buf); } int pktUnpack(ubyte_pkt * buf, char *fmt, ...) { va_list args; ubyte_pkt *p; ubyte_pkt *bp; ubyte_pkt *pc; uint16_pkt *ps; uint32_pkt *pl; ubyte_pkt *st; bp = buf; va_start(args, fmt); for(p = fmt; *p; p++) { switch (*p) { case 'c': pc = va_arg(args, ubyte_pkt *); *pc = *bp++; break; case 's': ps = va_arg(args, uint16_pkt *); *ps = *bp++ << 8; *ps |= *bp++; break; case 'l': pl = va_arg(args, uint32_pkt *); *pl = *bp++ << 24; *pl |= *bp++ << 16; *pl |= *bp++ << 8; *pl |= *bp++; break; case 'S': st = va_arg(args, ubyte_pkt *); while(*bp) *st++ = *bp++; *st = 0; break; default: va_end(args); return -1; } } va_end(args); return bp - buf; } int pktPackSetGameMode(ubyte_pkt * buf, struct SetGameMode_pkt *pkt) { return pktPack(buf, "ccc", pkt->type[0], pkt->type[1], pkt->gamemode); } int pktUnpackSetGameMode(struct SetGameMode_pkt *pkt, ubyte_pkt * buf) { return pktUnpack(buf, "ccc", &(pkt->type[0]), &(pkt->type[1]), &(pkt->gamemode)); } int pktPackPlayerID(ubyte_pkt * buf, struct PlayerID_pkt *pkt) { return pktPack(buf, "ccl", pkt->type[0], pkt->type[1], htonl(pkt->id)); } int pktUnpackPlayerID(struct PlayerID_pkt *pkt, ubyte_pkt * buf) { int ret = pktUnpack(buf, "ccl", &(pkt->type[0]), &(pkt->type[1]), &(pkt->id)); pkt->id = ntohl(pkt->id); return ret; } int pktPackSetName(ubyte_pkt * buf, struct SetName_pkt *pkt) { return pktPack(buf, "cclS", pkt->type[0], pkt->type[1], htonl(pkt->id), pkt->name); } int pktUnpackSetName(struct SetName_pkt *pkt, ubyte_pkt * buf) { int ret = pktUnpack(buf, "cclS", &(pkt->type[0]), &(pkt->type[1]), &(pkt->id), pkt->name); pkt->id = ntohl(pkt->id); return ret; } int pktPackNewPlayer(ubyte_pkt * buf, struct NewPlayer_pkt *pkt) { return pktPack(buf, "cclccS", pkt->type[0], pkt->type[1], htonl(pkt->id), pkt->color, pkt->ready, pkt->name); } int pktUnpackNewPlayer(struct NewPlayer_pkt *pkt, ubyte_pkt * buf) { int ret = pktUnpack(buf, "cclccS", &(pkt->type[0]), &(pkt->type[1]), &(pkt->id), &(pkt->color), &(pkt->ready), pkt->name); pkt->id = ntohl(pkt->id); return ret; } int pktPackTankColor(ubyte_pkt * buf, struct TankColor_pkt *pkt) { return pktPack(buf, "cclc", pkt->type[0], pkt->type[1], htonl(pkt->id), pkt->color); } int pktUnpackTankColor(struct TankColor_pkt *pkt, ubyte_pkt * buf) { int ret = pktUnpack(buf, "cclc", &(pkt->type[0]), &(pkt->type[1]), &(pkt->id), &(pkt->color)); pkt->id = ntohl(pkt->id); return ret; } int pktPackMessage(ubyte_pkt * buf, struct Message_pkt *pkt) { return pktPack(buf, "ccS", pkt->type[0], pkt->type[1], pkt->message); } int pktUnpackMessage(struct Message_pkt *pkt, ubyte_pkt * buf) { return pktUnpack(buf, "ccS", &(pkt->type[0]), &(pkt->type[1]), pkt->message); } int pktPackColoredMessage(ubyte_pkt * buf, struct ColoredMessage_pkt *pkt) { return pktPack(buf, "cccS", pkt->type[0], pkt->type[1], pkt->color, pkt->message); } int pktUnpackColoredMessage(struct ColoredMessage_pkt *pkt, ubyte_pkt * buf) { return pktUnpack(buf, "cccS", &(pkt->type[0]), &(pkt->type[1]), &(pkt->color), pkt->message); } int pktPackSetTank(ubyte_pkt * buf, struct SetTank_pkt *pkt) { return pktPack(buf, "cclllsss", pkt->type[0], pkt->type[1], htonl(pkt->id), htonl(pkt->x), htonl(pkt->y), htons(pkt->a), htons(pkt->v), htons(pkt->armor)); } int pktUnpackSetTank(struct SetTank_pkt *pkt, ubyte_pkt * buf) { int ret = pktUnpack(buf, "cclllsss", &(pkt->type[0]), &(pkt->type[1]), &(pkt->id), &(pkt->x), &(pkt->y), &(pkt->a), &(pkt->v), &(pkt->armor)); pkt->id = ntohl(pkt->id); pkt->x = ntohl(pkt->x); pkt->y = ntohl(pkt->y); pkt->a = ntohs(pkt->a); pkt->v = ntohs(pkt->v); pkt->armor = ntohs(pkt->armor); return ret; } int pktPackFireCmd(ubyte_pkt * buf, struct FireCmd_pkt *pkt) { return pktPack(buf, "ccllssS", pkt->type[0], pkt->type[1], htonl(pkt->id), htonl(pkt->gen), htons(pkt->a), htons(pkt->v), pkt->shottype); } int pktUnpackFireCmd(struct FireCmd_pkt *pkt, ubyte_pkt * buf) { int ret = pktUnpack(buf, "ccllssS", &(pkt->type[0]), &(pkt->type[1]), &(pkt->id), &(pkt->gen), &(pkt->a), &(pkt->v), pkt->shottype); pkt->id = ntohl(pkt->id); pkt->gen = ntohl(pkt->gen); pkt->a = ntohs(pkt->a); pkt->v = ntohs(pkt->v); return ret; } int pktPackChangeReady(ubyte_pkt * buf, struct ChangeReady_pkt *pkt) { return pktPack(buf, "cclc", pkt->type[0], pkt->type[1], htonl(pkt->id), pkt->r); } int pktUnpackChangeReady(struct ChangeReady_pkt *pkt, ubyte_pkt * buf) { int ret = pktUnpack(buf, "cclc", &(pkt->type[0]), &(pkt->type[1]), &(pkt->id), &(pkt->r)); pkt->id = ntohl(pkt->id); return ret; } int pktPackBuyWeapon(ubyte_pkt * buf, struct BuyWeapon_pkt *pkt) { return pktPack(buf, "ccsS", pkt->type[0], pkt->type[1], htons(pkt->count), pkt->weapontype); } int pktUnpackBuyWeapon(struct BuyWeapon_pkt *pkt, ubyte_pkt * buf) { int ret = pktUnpack(buf, "ccsS", &(pkt->type[0]), &(pkt->type[1]), &(pkt->count), pkt->weapontype); pkt->count = ntohs(pkt->count); return ret; } int pktPackTerrainInfo(ubyte_pkt * buf, struct TerrainInfo_pkt *pkt) { return pktPack(buf, "ccssll", pkt->type[0], pkt->type[1], htons(pkt->sizex), htons(pkt->sizey), htonl(pkt->lerp_tweak), htonl(pkt->grav)); } int pktUnpackTerrainInfo(struct TerrainInfo_pkt *pkt, ubyte_pkt * buf) { int ret = pktUnpack(buf, "ccssll", &(pkt->type[0]), &(pkt->type[1]), &(pkt->sizex), &(pkt->sizey), &(pkt->lerp_tweak), &(pkt->grav)); pkt->sizex = ntohs(pkt->sizex); pkt->sizey = ntohs(pkt->sizey); pkt->lerp_tweak = ntohl(pkt->lerp_tweak); pkt->grav = ntohl(pkt->grav); return ret; } int pktPackUpdateTerrain(ubyte_pkt * buf, struct UpdateTerrain_pkt *pkt) { uint16_pkt s; int i; pktPack(buf, "ccss", pkt->type[0], pkt->type[1], htons(pkt->startpos), htons(pkt->length)); for(i = 0; i < pkt->length; i++) { s = htons(pkt->ter[i]); buf[6 + i * 2] = s >> 8; buf[7 + i * 2] = s; } return (6 + i * 2); } int pktUnpackUpdateTerrain(struct UpdateTerrain_pkt *pkt, ubyte_pkt * buf) { int i; pktUnpack(buf, "ccss", &(pkt->type[0]), &(pkt->type[1]), &(pkt->startpos), &(pkt->length)); pkt->startpos = ntohs(pkt->startpos); pkt->length = ntohs(pkt->length); for(i = 0; i < pkt->length; i++) { pkt->ter[i] = buf[6 + i * 2] << 8; pkt->ter[i] |= buf[7 + i * 2]; pkt->ter[i] = ntohs(pkt->ter[i]); } return (6 + i * 2); } int pktPackWindSpeed(ubyte_pkt * buf, struct PlayerID_pkt *pkt) { return pktPack(buf, "ccl", pkt->type[0], pkt->type[1], htonl(pkt->id + 0x0FFFFFFF)); } int pktUnpackWindSpeed(struct PlayerID_pkt *pkt, ubyte_pkt * buf) { int size; size = pktUnpack(buf, "ccl", &(pkt->type[0]), &(pkt->type[1]), &(pkt->id)); pkt->id = ntohl(pkt->id); pkt->id -= 0x0FFFFFFF; return size; } int pktPackScore(ubyte_pkt * buf, struct Score_pkt *pkt) { return pktPack(buf, "cclll", pkt->type[0], pkt->type[1], htonl(pkt->id), htonl(pkt->roundScore), htonl(pkt->score)); } int pktUnpackScore(struct Score_pkt *pkt, ubyte_pkt * buf) { int ret = pktUnpack(buf, "cclll", &(pkt->type[0]), &(pkt->type[1]), &(pkt->id), &(pkt->roundScore), &(pkt->score)); pkt->id = ntohl(pkt->id); pkt->roundScore = ntohl(pkt->roundScore); pkt->score = ntohl(pkt->score); return ret; } int pktPackWallType(ubyte_pkt * buf, struct PlayerID_pkt *pkt) { return pktPack(buf, "ccl", pkt->type[0], pkt->type[1], htonl(pkt->id)); } int pktUnpackWallType(struct PlayerID_pkt *pkt, ubyte_pkt * buf) { int size; size = pktUnpack(buf, "ccl", &(pkt->type[0]), &(pkt->type[1]), &(pkt->id)); pkt->id = ntohl(pkt->id); return size; }