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
--- 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 \
--- /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 <smaxein@googlemail.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 "room.h"
+#include "../util/logging.h"
+
+#include <stdlib.h>
+
+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);
+ }
+}
--- /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 <smaxein@googlemail.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.
+ */
+
+/**
+ * Models the room information for the lobby roomlist.
+ */
+
+#ifndef ROOM_H_
+#define ROOM_H_
+
+#include <stdbool.h>
+
+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
--- 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 <smaxein@googlemail.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 "roomlist.h"
-
-#include "../util/util.h"
-#include "../util/list.h"
-#include "../util/logging.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-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; i<list->roomCount; 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; i<list->roomCount; 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; i<list->roomCount; i++) {
- flib_roomlist_room_destroy(list->rooms[i]);
- }
- free(list->rooms);
- list->rooms = NULL;
- list->roomCount = 0;
- }
-}
--- 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 <smaxein@googlemail.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.
- */
-
-/**
- * Models the list of rooms on a server for netplay.
- */
-
-#ifndef ROOMLIST_H_
-#define ROOMLIST_H_
-
-#include <stdbool.h>
-
-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
--- 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; i<netmsg->partCount; 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; i<roomCount; i++) {
+ flib_room_destroy(rooms[i]);
}
- }
- if(conn->netconnState == 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);
}
--- 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 <stddef.h>
#include <stdint.h>
@@ -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);
--- 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));
--- 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 <stdbool.h>
#include <stdint.h>
@@ -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;
--- 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;
--- 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<count; i++) {
+ array[i] = flib_room_from_netmsg(params + 8*i);
+ if(!array[i]) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+flib_room **flib_room_array_from_netmsg(char **params, int count) {
+ flib_room **result = flib_calloc(count, sizeof(flib_room*));
+ if(result) {
+ if(fillRoomArray(result, params, count)) {
+ for(int i=0; i<count; i++) {
+ flib_room_destroy(result[i]);
+ }
+ free(result);
+ result = NULL;
+ }
+ }
+ return result;
+}
--- a/project_files/frontlib/net/netprotocol.h Wed Jul 18 21:34:49 2012 +0200
+++ b/project_files/frontlib/net/netprotocol.h Thu Jul 19 17:56:38 2012 +0200
@@ -23,9 +23,12 @@
#include "../model/team.h"
#include "../model/scheme.h"
#include "../model/map.h"
+#include "../model/room.h"
#include <stddef.h>
+// 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_ */
--- 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;
+}
--- 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_ */