/********************************************************************/ /* */ /* L I QQ U U I DD W W A RR 555 */ /* L I Q Q U U I D D W W A A R R 5 */ /* L I Q Q U U I D D W W W AAA RR 55 */ /* L I Q Q U U I D D WW WW A A R R 5 */ /* LLL I Q Q U I DD W W A A R R 55 */ /* */ /* b */ /* bb y y */ /* b b yyy */ /* bb y */ /* yy */ /* */ /* U U FFF O O TTT */ /* U U F O O O O T */ /* U U TIRET FF O O O O T */ /* U U F O O O O T */ /* U F O O T */ /* */ /********************************************************************/ /*****************************************************************************/ /* Liquid War is a multiplayer wargame */ /* Copyright (C) 1998-2007 Christian Mauduit */ /* */ /* 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ /* */ /* Liquid War homepage : http://www.ufoot.org/liquidwar/v5 */ /* Contact author : ufoot@ufoot.org */ /*****************************************************************************/ /********************************************************************/ /* name : netkey.c */ /* content : functions to manipulate network key messages */ /* last update : June 20th 2001 */ /********************************************************************/ /*==================================================================*/ /* includes */ /*==================================================================*/ #include #include #include #include "netkey.h" #include "cursor.h" #include "sock2gen.h" /*==================================================================*/ /* constants */ /*==================================================================*/ #define LW_NETKEY_SERIALIZED_SIZE (NB_TEAMS+2+4) /*==================================================================*/ /* types */ /*==================================================================*/ /* * Used to store the information of a LW_NETKEY struct once it has * been serialized to be sent over the network */ typedef unsigned char LW_NETKEY_SERIALIZED[LW_NETKEY_SERIALIZED_SIZE]; /*==================================================================*/ /* static functions declaration */ /*==================================================================*/ static char int_to_ascii_hexa (int src); static int ascii_hexa_to_int (char src); static void encode (LW_NETKEY_SERIALIZED dst, LW_NETKEY * src); static void decode (LW_NETKEY * dst, LW_NETKEY_SERIALIZED src); /*==================================================================*/ /* functions */ /*==================================================================*/ /*------------------------------------------------------------------*/ /* * Creates a blank netkey struct */ void lw_netkey_reset (LW_NETKEY * netkey) { int i; for (i = 0; i < NB_TEAMS; ++i) { netkey->key_states[i] = 0; } netkey->cmd = LW_NETKEY_CMD_NONE; netkey->arg = 0; } /*------------------------------------------------------------------*/ /* * Transforms an integer into a readable hexadecimal ascii character */ static char int_to_ascii_hexa (int src) { char dst; dst = '0'; if (src >= 1 && src <= 9) { dst = '0' + src; } if (src >= 10 && src <= 15) { dst = 'A' - 10 + src; } return dst; } /*------------------------------------------------------------------*/ /* * Transforms a readable hexadecimal ascii character into an integer */ static int ascii_hexa_to_int (char src) { int dst; dst = 0; if (src >= '0' && src <= '9') { dst = src - '0'; } if (src >= 'A' && src <= 'F') { dst = src - 'A' + 10; } return dst; } /*------------------------------------------------------------------*/ /* * Serializes a LW_NETKEY struct to a buffer which is sendable over * the network. */ static void encode (LW_NETKEY_SERIALIZED dst, LW_NETKEY * src) { int i; for (i = 0; i < NB_TEAMS; ++i) { /* * we translate each key press (stored as a logical or between * 1,2,4 and 8) into a readable hexadecimal character. This * makes debugging easier. */ dst[i] = int_to_ascii_hexa (src->key_states[i]); } /* * We store the command as is since it's already a character */ dst[NB_TEAMS] = src->cmd; /* * We transform the argument since we assume it's a numeric arg */ dst[NB_TEAMS + 1] = int_to_ascii_hexa (src->arg); /* * Now we serialize the "map checksum" */ dst[NB_TEAMS + 2 + 0] = (src->checksum) & 0xFF; dst[NB_TEAMS + 2 + 1] = (src->checksum >> 8) & 0xFF; dst[NB_TEAMS + 2 + 2] = (src->checksum >> 16) & 0xFF; dst[NB_TEAMS + 2 + 3] = (src->checksum >> 24) & 0xFF; } /*------------------------------------------------------------------*/ /* * Un-serializes a LW_NETKEY struct from a buffer which has been * received from the network. */ static void decode (LW_NETKEY * dst, LW_NETKEY_SERIALIZED src) { int i; for (i = 0; i < NB_TEAMS; ++i) { /* * we translate each key press (stored as a logical or between * 1,2,4 and 8) from a readable hexadecimal character. This * makes debugging easier. */ dst->key_states[i] = ascii_hexa_to_int (src[i]); } /* * We store the command as is since it's already a character */ dst->cmd = src[NB_TEAMS]; /* * We transform the argument since we assume it's a numeric arg */ dst->arg = ascii_hexa_to_int (src[NB_TEAMS + 1]); /* * Now we serialize the "map checksum" */ dst->checksum = ((unsigned int) src[NB_TEAMS + 2 + 3]) << 24 | ((unsigned int) src[NB_TEAMS + 2 + 2]) << 16 | ((unsigned int) src[NB_TEAMS + 2 + 1]) << 8 | ((unsigned int) src[NB_TEAMS + 2 + 0]); } /*------------------------------------------------------------------*/ /* * Sends a netkey information over the network */ int lw_netkey_send (int *sock, LW_NETKEY * netkey) { int result; LW_NETKEY_SERIALIZED netkey_serialized; encode (netkey_serialized, netkey); result = lw_sock_send_buffer (sock, (char *) netkey_serialized, LW_NETKEY_SERIALIZED_SIZE); return result; } /*------------------------------------------------------------------*/ /* * Receives a netkey information from the network */ int lw_netkey_recv (int *sock, LW_NETKEY * netkey) { int result; LW_NETKEY_SERIALIZED netkey_serialized; result = lw_sock_recv_buffer (sock, (char *) netkey_serialized, LW_NETKEY_SERIALIZED_SIZE); decode (netkey, netkey_serialized); return result; } /*------------------------------------------------------------------*/ /* * Returns true if at leat "num" keys are available on the socket */ int lw_netkey_peek (int *sock, int num) { int result; result = lw_sock_peek (sock, num * LW_NETKEY_SERIALIZED_SIZE); return result; }