# HG changeset patch # User Medo # Date 1342713398 -7200 # Node ID 1ed603a54ebd4916727cae3b5a8648cae929a772 # Parent f821f7d727b7113d8f153d9330b2877da1e95548 frontlib: - Removed automatic roomlist handling, since the server doesn't inform of every change after all - Added flib_netconn_get_playername - Added a callback mechanism for logging diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/Android.mk --- a/project_files/frontlib/Android.mk Wed Jul 18 21:34:49 2012 +0200 +++ b/project_files/frontlib/Android.mk Thu Jul 19 17:56:38 2012 +0200 @@ -9,7 +9,7 @@ LOCAL_SRC_FILES := base64/base64.c iniparser/iniparser.c \ iniparser/dictionary.c ipc/gameconn.c ipc/ipcbase.c \ ipc/ipcprotocol.c ipc/mapconn.c md5/md5.c model/scheme.c \ - model/gamesetup.c model/map.c model/mapcfg.c model/roomlist.c \ + model/gamesetup.c model/map.c model/mapcfg.c model/room.c \ model/schemelist.c model/team.c model/teamlist.c model/weapon.c \ net/netbase.c net/netconn_callbacks.c net/netconn_send.c \ net/netconn.c net/netprotocol.c util/buffer.c util/inihelper.c \ diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/model/room.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/frontlib/model/room.c Thu Jul 19 17:56:38 2012 +0200 @@ -0,0 +1,34 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * 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 "room.h" +#include "../util/logging.h" + +#include + +void flib_room_destroy(flib_room *room) { + if(room) { + free(room->map); + free(room->name); + free(room->owner); + free(room->scheme); + free(room->weapons); + free(room); + } +} diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/model/room.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/frontlib/model/room.h Thu Jul 19 17:56:38 2012 +0200 @@ -0,0 +1,42 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * 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. + */ + +/** + * Models the room information for the lobby roomlist. + */ + +#ifndef ROOM_H_ +#define ROOM_H_ + +#include + +typedef struct { + bool inProgress; // true if the game is running + char *name; + int playerCount; + int teamCount; + char *owner; + char *map; // This is either a map name, or one of +rnd+, +maze+ or +drawn+. + char *scheme; + char *weapons; +} flib_room; + +void flib_room_destroy(); + +#endif diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/model/roomlist.c --- a/project_files/frontlib/model/roomlist.c Wed Jul 18 21:34:49 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * 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 "roomlist.h" - -#include "../util/util.h" -#include "../util/list.h" -#include "../util/logging.h" - -#include -#include - -flib_roomlist *flib_roomlist_create() { - return flib_calloc(1, sizeof(flib_roomlist)); -} - -static void flib_roomlist_room_destroy(flib_room *room) { - if(room) { - free(room->map); - free(room->name); - free(room->owner); - free(room->scheme); - free(room->weapons); - free(room); - } -} - -void flib_roomlist_destroy(flib_roomlist *list) { - if(list) { - for(int i=0; iroomCount; i++) { - flib_roomlist_room_destroy(list->rooms[i]); - } - free(list->rooms); - free(list); - } -} - -static flib_room *fillRoomFromParams(char **params) { - flib_room *result = NULL; - flib_room *tmpRoom = flib_calloc(1, sizeof(flib_room)); - if(tmpRoom) { - tmpRoom->inProgress = !strcmp(params[0], "True"); - tmpRoom->name = flib_strdupnull(params[1]); - tmpRoom->playerCount = atoi(params[2]); - tmpRoom->teamCount = atoi(params[3]); - tmpRoom->owner = flib_strdupnull(params[4]); - tmpRoom->map = flib_strdupnull(params[5]); - tmpRoom->scheme = flib_strdupnull(params[6]); - tmpRoom->weapons = flib_strdupnull(params[7]); - if(tmpRoom->name && tmpRoom->owner && tmpRoom->map && tmpRoom->scheme && tmpRoom->weapons) { - result = tmpRoom; - tmpRoom = NULL; - } - } - flib_roomlist_room_destroy(tmpRoom); - return result; -} - -GENERATE_STATIC_LIST_INSERT(insertRoom, flib_room*) -GENERATE_STATIC_LIST_DELETE(deleteRoom, flib_room*) - -static int findRoom(const flib_roomlist *list, const char *name) { - for(int i=0; iroomCount; i++) { - if(!strcmp(name, list->rooms[i]->name)) { - return i; - } - } - return -1; -} - -int flib_roomlist_add(flib_roomlist *list, char **params) { - int result = -1; - if(!log_badargs_if2(list==NULL, params==NULL)) { - flib_room *tmpRoom = fillRoomFromParams(params); - if(tmpRoom) { - if(!insertRoom(&list->rooms, &list->roomCount, tmpRoom, 0)) { - tmpRoom = NULL; - result = 0; - } - } - flib_roomlist_room_destroy(tmpRoom); - } - return result; -} - -int flib_roomlist_delete(flib_roomlist *list, const char *name) { - int result = -1; - if(!log_badargs_if2(list==NULL, name==NULL)) { - int roomid = findRoom(list, name); - if(roomid<0) { - flib_log_w("Attempt to delete unknown room %s", name); - } else { - flib_room *room = list->rooms[roomid]; - if(!deleteRoom(&list->rooms, &list->roomCount, roomid)) { - flib_roomlist_room_destroy(room); - result = 0; - } - } - } - return result; -} - -int flib_roomlist_update(flib_roomlist *list, const char *name, char **params) { - int result = -1; - if(!log_badargs_if3(list==NULL, name==NULL, params==NULL)) { - flib_room *tmpRoom = fillRoomFromParams(params); - int roomid = findRoom(list, name); - if(tmpRoom && roomid>=0) { - flib_roomlist_room_destroy(list->rooms[roomid]); - list->rooms[roomid] = tmpRoom; - tmpRoom = NULL; - result = 0; - } - flib_roomlist_room_destroy(tmpRoom); - } - return result; -} - -flib_room *flib_roomlist_find(const flib_roomlist *list, const char *name) { - flib_room *result = NULL; - if(!log_badargs_if2(list==NULL, name==NULL)) { - int roomid = findRoom(list, name); - if(roomid>=0) { - result = list->rooms[roomid]; - } - } - return result; -} - -void flib_roomlist_clear(flib_roomlist *list) { - if(!log_badargs_if(list==NULL)) { - for(int i=0; iroomCount; i++) { - flib_roomlist_room_destroy(list->rooms[i]); - } - free(list->rooms); - list->rooms = NULL; - list->roomCount = 0; - } -} diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/model/roomlist.h --- a/project_files/frontlib/model/roomlist.h Wed Jul 18 21:34:49 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * 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. - */ - -/** - * Models the list of rooms on a server for netplay. - */ - -#ifndef ROOMLIST_H_ -#define ROOMLIST_H_ - -#include - -typedef struct { - bool inProgress; // true if the game is running - char *name; - int playerCount; - int teamCount; - char *owner; - char *map; // This is either a map name, or one of +rnd+, +maze+ or +drawn+. - char *scheme; - char *weapons; -} flib_room; - -typedef struct { - int roomCount; - flib_room **rooms; -} flib_roomlist; - -flib_roomlist *flib_roomlist_create(); - -void flib_roomlist_destroy(flib_roomlist *list); - -/** - * Insert a new room at the start of the list. The room is defined by the params-array, - * which must consist of 8 non-null strings, as sent by the server in netplay. - * - * Returns 0 on success. - */ -int flib_roomlist_add(flib_roomlist *list, char **params); - -/** - * Update the room with the name [name] with parameters sent by the server. - * - * Returns 0 on success. - */ -int flib_roomlist_update(flib_roomlist *list, const char *name, char **params); - -/** - * Returns the room with the name [name] from the list if it exists, NULL otherwise - */ -flib_room *flib_roomlist_find(const flib_roomlist *list, const char *name); - -/** - * Removes all rooms from the list - */ -void flib_roomlist_clear(flib_roomlist *list); - -/** - * Delete the room with the name [name] from the room list. - * Returns 0 on success. - */ -int flib_roomlist_delete(flib_roomlist *list, const char *name); - -#endif diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/net/netconn.c --- a/project_files/frontlib/net/netconn.c Wed Jul 18 21:34:49 2012 +0200 +++ b/project_files/frontlib/net/netconn.c Thu Jul 19 17:56:38 2012 +0200 @@ -24,7 +24,6 @@ #include "netprotocol.h" #include "../util/logging.h" #include "../util/util.h" -#include "../model/roomlist.h" #include "../md5/md5.h" #include "../base64/base64.h" #include "../model/mapcfg.h" @@ -46,8 +45,6 @@ newConn->netconnState = NETCONN_STATE_CONNECTING; newConn->isAdmin = false; newConn->metaCfg = flib_metascheme_retain(metacfg); - newConn->roomList.roomCount = 0; - newConn->roomList.rooms = NULL; newConn->isChief = false; newConn->map = flib_map_create_named("", "NoSuchMap"); @@ -88,7 +85,6 @@ free(conn->dataDirPath); flib_metascheme_release(conn->metaCfg); - flib_roomlist_clear(&conn->roomList); flib_map_release(conn->map); flib_teamlist_clear(&conn->pendingTeamlist); @@ -102,13 +98,6 @@ } } -const flib_roomlist *flib_netconn_get_roomlist(flib_netconn *conn) { - if(!log_badargs_if(conn==NULL)) { - return &conn->roomList; - } - return NULL; -} - bool flib_netconn_is_chief(flib_netconn *conn) { if(!log_badargs_if(conn==NULL) && flib_netconn_is_in_room_context(conn)) { return conn->isChief; @@ -116,6 +105,13 @@ return false; } +const char *flib_netconn_get_playername(flib_netconn *conn) { + if(!log_badargs_if(conn==NULL)) { + return conn->playerName; + } + return NULL; +} + void netconn_leaveRoom(flib_netconn *conn) { conn->netconnState = NETCONN_STATE_LOBBY; conn->isChief = false; @@ -269,16 +265,14 @@ if(netmsg->partCount % 8 != 1) { flib_log_w("Net: Malformed ROOMS message"); } else { - flib_roomlist_clear(&conn->roomList); - for(int i=1; ipartCount; i+=8) { - if(flib_roomlist_add(&conn->roomList, netmsg->parts+i)) { - flib_log_e("Error adding room to list in ROOMS message"); + int roomCount = netmsg->partCount/8; + flib_room **rooms = flib_room_array_from_netmsg(netmsg->parts+1, roomCount); + if(rooms) { + conn->onRoomlistCb(conn->onRoomlistCtx, (const flib_room**)rooms, roomCount); + for(int i=0; inetconnState == NETCONN_STATE_CONNECTING) { - // We delay the "connected" callback until now to ensure the room list is avaliable. - conn->onConnectedCb(conn->onConnectedCtx); - conn->netconnState = NETCONN_STATE_LOBBY; + free(rooms); } } } else if (!strcmp(cmd, "SERVER_MESSAGE")) { @@ -377,14 +371,9 @@ for(int i = 1; i < netmsg->partCount; ++i) { bool isMe = !strcmp(conn->playerName, netmsg->parts[i]); - if (isMe) { - if(flib_netbase_sendf(conn->netBase, "%s\n\n", "LIST")) { - // If sending this fails, the protocol breaks (we'd be waiting infinitely for the room list) - flib_netbase_sendf(net, "%s\n%s\n\n", "QUIT", "Client error"); - conn->netconnState = NETCONN_STATE_DISCONNECTED; - conn->onDisconnectedCb(conn->onDisconnectedCtx, NETCONN_DISCONNECT_INTERNAL_ERROR, "Failed to send a critical message."); - exit = true; - } + if (isMe && conn->netconnState == NETCONN_STATE_CONNECTING) { + conn->onConnectedCb(conn->onConnectedCtx); + conn->netconnState = NETCONN_STATE_LOBBY; } conn->onLobbyJoinCb(conn->onLobbyJoinCtx, netmsg->parts[i]); } @@ -398,24 +387,19 @@ } else if(!strcmp(cmd, "ROOM") && netmsg->partCount >= 2) { const char *subcmd = netmsg->parts[1]; if(!strcmp(subcmd, "ADD") && netmsg->partCount == 10) { - if(flib_roomlist_add(&conn->roomList, netmsg->parts+2)) { - flib_log_e("Error adding new room to list"); - } else { - conn->onRoomAddCb(conn->onRoomAddCtx, conn->roomList.rooms[0]); + flib_room *room = flib_room_from_netmsg(netmsg->parts+2); + if(room) { + conn->onRoomAddCb(conn->onRoomAddCtx, room); } + flib_room_destroy(room); } else if(!strcmp(subcmd, "UPD") && netmsg->partCount == 11) { - char *newName = netmsg->parts[4]; - if(flib_roomlist_update(&conn->roomList, netmsg->parts[2], netmsg->parts+3)) { - flib_log_e("Error updating room in list"); - } else { - conn->onRoomUpdateCb(conn->onRoomUpdateCtx, netmsg->parts[2], flib_roomlist_find(&conn->roomList, newName)); + flib_room *room = flib_room_from_netmsg(netmsg->parts+3); + if(room) { + conn->onRoomUpdateCb(conn->onRoomUpdateCtx, netmsg->parts[2], room); } + flib_room_destroy(room); } else if(!strcmp(subcmd, "DEL") && netmsg->partCount == 3) { - if(flib_roomlist_delete(&conn->roomList, netmsg->parts[2])) { - flib_log_e("Error deleting room from list"); - } else { - conn->onRoomDeleteCb(conn->onRoomDeleteCtx, netmsg->parts[2]); - } + conn->onRoomDeleteCb(conn->onRoomDeleteCtx, netmsg->parts[2]); } else { flib_log_w("Net: Unknown or malformed ROOM subcommand: %s", subcmd); } diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/net/netconn.h --- a/project_files/frontlib/net/netconn.h Wed Jul 18 21:34:49 2012 +0200 +++ b/project_files/frontlib/net/netconn.h Thu Jul 19 17:56:38 2012 +0200 @@ -22,7 +22,7 @@ #include "../model/gamesetup.h" #include "../model/scheme.h" -#include "../model/roomlist.h" +#include "../model/room.h" #include #include @@ -73,12 +73,6 @@ */ void flib_netconn_tick(flib_netconn *conn); - -/** - * Return the current roomlist. Don't free or modify. - */ -const flib_roomlist *flib_netconn_get_roomlist(flib_netconn *conn); - /** * Are you currently the owner of this room? The return value only makes sense in * NETCONN_STATE_ROOM and NETCONN_STATE_INGAME states. @@ -91,6 +85,13 @@ bool flib_netconn_is_in_room_context(flib_netconn *conn); /** + * Returns the playername. This is *probably* the one provided on creation, but + * if that name was already taken, a different one could have been set by the + * onNickTaken callback or its default implementation. + */ +const char *flib_netconn_get_playername(flib_netconn *conn); + +/** * Generate a game setup from the current room state. * Returns NULL if the room state does not contain enough information * for a complete game setup, or if an error occurs. @@ -127,6 +128,12 @@ int flib_netconn_send_nick(flib_netconn *conn, const char *nick); /** + * Request an update of the room list. Only makes sense when in lobby state. + * If the action succeeds, you will receive an onRoomlist callback containing the current room data. + */ +int flib_netconn_send_request_roomlist(flib_netconn *conn); + +/** * Join a room as guest (not chief). Only makes sense when in lobby state. If the action succeeds, you will * receive an onEnterRoom callback with chief=false. */ @@ -356,10 +363,13 @@ void flib_netconn_onDisconnected(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void* context); /** - * Callbacks for room list updates. The room list is managed automatically and can be queried with - * flib_netconn_get_roomlist() as soon as the onConnected callback is fired. These callbacks - * provide notification about changes. + * Callbacks for room list updates. The roomlist can be queried with flib_netconn_send_request_roomlist(), which will + * trigger flib_netconn_onRoomlist once the server replies. Additionally, the roomAdd/delete/update callbacks will fire + * whenever the server informs about these events, which can happen *before* the roomlist is first received - so be sure + * not to blindly reference your room list in these callbacks. The server currently only sends updates when a room changes + * its name, so in order to update other room information you need to query the roomlist again. */ +void flib_netconn_onRoomlist(flib_netconn *conn, void (*callback)(void *context, const flib_room **rooms, int roomCount), void* context); void flib_netconn_onRoomAdd(flib_netconn *conn, void (*callback)(void *context, const flib_room *room), void* context); void flib_netconn_onRoomDelete(flib_netconn *conn, void (*callback)(void *context, const char *name), void* context); void flib_netconn_onRoomUpdate(flib_netconn *conn, void (*callback)(void *context, const char *oldName, const flib_room *room), void* context); diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/net/netconn_callbacks.c --- a/project_files/frontlib/net/netconn_callbacks.c Wed Jul 18 21:34:49 2012 +0200 +++ b/project_files/frontlib/net/netconn_callbacks.c Thu Jul 19 17:56:38 2012 +0200 @@ -64,6 +64,7 @@ flib_netconn_onMessage(conn, NULL, NULL); flib_netconn_onConnected(conn, NULL, NULL); flib_netconn_onDisconnected(conn, NULL, NULL); + flib_netconn_onRoomlist(conn, NULL, NULL); flib_netconn_onRoomAdd(conn, NULL, NULL); flib_netconn_onRoomDelete(conn, NULL, NULL); flib_netconn_onRoomUpdate(conn, NULL, NULL); @@ -120,6 +121,7 @@ GENERATE_CB_SETTER(onMessage, (void *context, int msgtype, const char *msg), defaultCallback_onMessage); GENERATE_CB_SETTER_AND_DEFAULT(onConnected, (void *context)); GENERATE_CB_SETTER_AND_DEFAULT(onDisconnected, (void *context, int reason, const char *message)); +GENERATE_CB_SETTER_AND_DEFAULT(onRoomlist, (void *context, const flib_room **rooms, int roomCount)); GENERATE_CB_SETTER_AND_DEFAULT(onRoomAdd, (void *context, const flib_room *room)); GENERATE_CB_SETTER_AND_DEFAULT(onRoomDelete, (void *context, const char *name)); GENERATE_CB_SETTER_AND_DEFAULT(onRoomUpdate, (void *context, const char *oldName, const flib_room *room)); diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/net/netconn_internal.h --- a/project_files/frontlib/net/netconn_internal.h Wed Jul 18 21:34:49 2012 +0200 +++ b/project_files/frontlib/net/netconn_internal.h Thu Jul 19 17:56:38 2012 +0200 @@ -26,10 +26,10 @@ #include "netconn.h" #include "netbase.h" -#include "../model/roomlist.h" #include "../model/map.h" #include "../model/team.h" #include "../model/weapon.h" +#include "../model/room.h" #include #include @@ -44,7 +44,6 @@ bool isAdmin; // Player is server administrator flib_metascheme *metaCfg; - flib_roomlist roomList; bool isChief; // Player can modify the current room flib_map *map; @@ -63,6 +62,9 @@ void (*onDisconnectedCb)(void *context, int reason, const char *message); void *onDisconnectedCtx; + void (*onRoomlistCb)(void *context, const flib_room **rooms, int roomCount); + void *onRoomlistCtx; + void (*onRoomAddCb)(void *context, const flib_room *room); void *onRoomAddCtx; diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/net/netconn_send.c --- a/project_files/frontlib/net/netconn_send.c Wed Jul 18 21:34:49 2012 +0200 +++ b/project_files/frontlib/net/netconn_send.c Thu Jul 19 17:56:38 2012 +0200 @@ -107,6 +107,10 @@ return result; } +int flib_netconn_send_request_roomlist(flib_netconn *conn) { + return sendVoid(conn, "LIST"); +} + int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room) { if(!sendStr(conn, "JOIN_ROOM", room)) { conn->isChief = false; diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/net/netprotocol.c --- a/project_files/frontlib/net/netprotocol.c Wed Jul 18 21:34:49 2012 +0200 +++ b/project_files/frontlib/net/netprotocol.c Thu Jul 19 17:56:38 2012 +0200 @@ -140,3 +140,48 @@ free(base64decout); return result; } + +flib_room *flib_room_from_netmsg(char **params) { + flib_room *result = NULL; + flib_room *tmpRoom = flib_calloc(1, sizeof(flib_room)); + if(tmpRoom) { + tmpRoom->inProgress = !strcmp(params[0], "True"); + tmpRoom->name = flib_strdupnull(params[1]); + tmpRoom->playerCount = atoi(params[2]); + tmpRoom->teamCount = atoi(params[3]); + tmpRoom->owner = flib_strdupnull(params[4]); + tmpRoom->map = flib_strdupnull(params[5]); + tmpRoom->scheme = flib_strdupnull(params[6]); + tmpRoom->weapons = flib_strdupnull(params[7]); + if(tmpRoom->name && tmpRoom->owner && tmpRoom->map && tmpRoom->scheme && tmpRoom->weapons) { + result = tmpRoom; + tmpRoom = NULL; + } + } + flib_room_destroy(tmpRoom); + return result; +} + +int fillRoomArray(flib_room **array, char **params, int count) { + for(int i=0; i +// TODO unify naming + /** * Create a new team from this 23-part net message */ @@ -52,4 +55,14 @@ */ int flib_netmsg_to_drawnmapdata(char *netmsg, uint8_t **outbuf, size_t *outlen); +/** + * Create a new room from this 8-part net message + */ +flib_room *flib_room_from_netmsg(char **params); + +/** + * Create an array of count rooms from count*8 netmessage parts + */ +flib_room **flib_room_array_from_netmsg(char **params, int count); + #endif /* NETPROTOCOL_H_ */ diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/util/logging.c --- a/project_files/frontlib/util/logging.c Wed Jul 18 21:34:49 2012 +0200 +++ b/project_files/frontlib/util/logging.c Thu Jul 19 17:56:38 2012 +0200 @@ -26,6 +26,7 @@ static int flib_loglevel = FLIB_LOGLEVEL_INFO; static FILE *flib_logfile = NULL; +void (*flib_logCallback)(int level, const char *msg) = NULL; char* flib_format_ip(uint32_t numip) { static char ip[16]; @@ -41,37 +42,66 @@ } } -static void log_time() { +static int log_time(char *buffer) { time_t timer; - char buffer[25]; struct tm* tm_info; time(&timer); tm_info = localtime(&timer); - strftime(buffer, 25, "%Y-%m-%d %H:%M:%S", tm_info); - fprintf(flib_log_getfile(), "%s", buffer); + return strftime(buffer, 25, "%Y-%m-%d %H:%M:%S", tm_info); } -static const char *getPrefix(int level) { +static char getPrefix(int level) { switch(level) { - case FLIB_LOGLEVEL_ERROR: return "E"; - case FLIB_LOGLEVEL_WARNING: return "W"; - case FLIB_LOGLEVEL_INFO: return "I"; - case FLIB_LOGLEVEL_DEBUG: return "D"; - default: return "?"; + case FLIB_LOGLEVEL_ERROR: return 'E'; + case FLIB_LOGLEVEL_WARNING: return 'W'; + case FLIB_LOGLEVEL_INFO: return 'I'; + case FLIB_LOGLEVEL_DEBUG: return 'D'; + default: return '?'; } } static void _flib_vflog(const char *func, int level, const char *fmt, va_list args) { - FILE *logfile = flib_log_getfile(); if(level >= flib_loglevel) { - fprintf(logfile, "%s ", getPrefix(level)); - log_time(logfile); - fprintf(logfile, " [%-30s] ", func); - vfprintf(logfile, fmt, args); - fprintf(logfile, "\n"); - fflush(logfile); + char logbuffer[1024]; + logbuffer[0] = getPrefix(level); + logbuffer[1] = ' '; + + int pos = 2; + + int len = log_time(logbuffer+pos); + if(len>=0) { + pos += len; + if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; + } else { + return; + } + + len = snprintf(logbuffer+pos, sizeof(logbuffer)-pos, " [%-30s] ", func); + if(len>=0) { + pos += len; + if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; + } else { + return; + } + + len = vsnprintf(logbuffer+pos, sizeof(logbuffer)-pos, fmt, args); + if(len>=0) { + pos += len; + if(pos>sizeof(logbuffer)-1) pos = sizeof(logbuffer)-1; + } else { + return; + } + + if(flib_logCallback != NULL) { + flib_logCallback(level, logbuffer); + } else { + FILE *logfile = flib_log_getfile(); + fputs(logbuffer, logfile); + fputc('\n', logfile); + fflush(logfile); + } } } @@ -102,8 +132,14 @@ void flib_log_setFile(FILE *file) { flib_logfile = file; + flib_logCallback = NULL; } bool flib_log_isActive(int level) { return level >= flib_log_getLevel(); } + +void flib_log_setCallback(void (*logCallback)(int level, const char *msg)) { + flib_logCallback = logCallback; + flib_logfile = NULL; +} diff -r f821f7d727b7 -r 1ed603a54ebd project_files/frontlib/util/logging.h --- a/project_files/frontlib/util/logging.h Wed Jul 18 21:34:49 2012 +0200 +++ b/project_files/frontlib/util/logging.h Thu Jul 19 17:56:38 2012 +0200 @@ -84,4 +84,10 @@ void flib_log_setFile(FILE *logfile); bool flib_log_isActive(int level); +/** + * Allows logging through an arbitrary callback function. Useful for integrating into an + * existing logging system. This overrides setFile and vice versa. + */ +void flib_log_setCallback(void (*logCallback)(int level, const char *msg)); + #endif /* LOGGING_H_ */