# HG changeset patch # User Medo # Date 1344803877 -7200 # Node ID d70a5b0d11902313910efd1f9078d4953627048c # Parent c8c552ee3acb59d5c600e0613fff340de2f5c3b9 frontlib improvements: - Added README with overview documentation - Improved code documentation/comments - Added flib_gameconn_send_quit to gracefully exit a running game - Changed the type of some size variables to size_t - Fixed starting a mission/training sending the mission script like a multiplayer script - Removed reference counters from flib_scheme and flib_map - Removed INGAME state from netconn (there is no useful difference to ROOM state) - Added extras/jnacontrol.c to warn when functions signatures used by Hedgeroid change - Other small code improvements diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/Android.mk --- a/project_files/frontlib/Android.mk Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/Android.mk Sun Aug 12 22:37:57 2012 +0200 @@ -14,7 +14,7 @@ net/netbase.c net/netconn_callbacks.c net/netconn_send.c \ net/netconn.c net/netprotocol.c util/buffer.c util/inihelper.c \ util/logging.c util/refcounter.c util/util.c frontlib.c \ - hwconsts.c socket.c + hwconsts.c socket.c extra/jnacontrol.c LOCAL_SHARED_LIBRARIES += SDL_net LOCAL_LDLIBS += -lz diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/extra/jnacontrol.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/frontlib/extra/jnacontrol.c Sun Aug 12 22:37:57 2012 +0200 @@ -0,0 +1,235 @@ +/* + * 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. + */ + +/* + * This file is not directly part of the frontlib and is not required to build it. + * However, it is recommended to include it in compilation when building for Android. The purpose of this file + * is to ensure consistency between the function signatures of the JNA Java bindings of the Android port and the + * frontlib functions. + * + * This file, in essence, consists only of function declarations. They are duplicates of function declarations + * from the frontlib headers that are referenced from JNA bindings. If the signature of one of these functions + * changes in the frontlib, it will no longer match the signature in this file, and the compiler will show an error. + * If that happens, you need to update the JNA bindings in Hedgeroid to match the new function signature, and then + * update this file. + * + * The reason for all this is that JNA does not actually know the function signatures of the functions it binds, + * it derives them from Java method declarations. If those do not match the actual function signatures, you will + * only notice when you suddenly get strange (and possibly hard to track down) problems at runtime. This file is + * an attempt to detect these problems at compile time instead. Notice that it will NOT detect changes to structs + * or constants though, which also require updates to the JNA bindings. + */ + +/* + * Before we include the frontlib headers, we define away the const keyword. This is necessary because there is no + * distinction between const and non-const types on the JNA side, and we don't want the compiler to complain because + * of bad constness. + * + * This is so evil, but it works... + */ +#define const + +#include "../frontlib.h" + +/* + * Now we map the Java types to the corresponding C types... + */ +typedef flib_netconn *NetconnPtr; +typedef flib_gameconn *GameconnPtr; +typedef flib_mapconn *MapconnPtr; +typedef flib_metascheme *MetaschemePtr; +typedef flib_room **RoomArrayPtr; +typedef flib_weaponset *WeaponsetPtr; +typedef flib_weaponsetlist *WeaponsetListPtr; +typedef flib_map *MapRecipePtr; +typedef flib_scheme *SchemePtr; +typedef flib_schemelist *SchemelistPtr; + +typedef flib_room *RoomPtr; +typedef flib_team *TeamPtr; +typedef flib_gamesetup *GameSetupPtr; +typedef bool boolean; +typedef size_t NativeLong; +typedef void *Pointer; +typedef char *String; +typedef uint8_t *Buffer; + +/* + * Mapping callback types + */ +typedef void (*VoidCallback)(Pointer context); +typedef void (*StrCallback)(Pointer context, String arg1); +typedef void (*IntCallback)(Pointer context, int arg1); +typedef void (*IntStrCallback)(Pointer context, int arg1, String arg2); +typedef void (*StrIntCallback)(Pointer context, String arg1, int arg2); +typedef void (*StrStrCallback)(Pointer context, String arg1, String arg2); +typedef void (*RoomCallback)(Pointer context, RoomPtr arg1); +typedef void (*RoomListCallback)(Pointer context, RoomArrayPtr arg1, int arg2); +typedef void (*StrRoomCallback)(Pointer context, String arg1, RoomPtr arg2); +typedef void (*BoolCallback)(Pointer context, boolean arg1); +typedef void (*StrBoolCallback)(Pointer context, String arg1, boolean arg2); +typedef void (*TeamCallback)(Pointer context, TeamPtr arg1); +typedef void (*BytesCallback)(Pointer context, const uint8_t *buffer, NativeLong size); +typedef void (*BytesBoolCallback)(Pointer context, const uint8_t *buffer, NativeLong size, boolean arg3); +typedef void (*SchemeCallback)(Pointer context, SchemePtr arg1); +typedef void (*MapIntCallback)(Pointer context, MapRecipePtr arg1, int arg2); +typedef void (*WeaponsetCallback)(Pointer context, WeaponsetPtr arg1); +typedef void (*MapimageCallback)(Pointer context, const uint8_t *mapimage, int hogs); +typedef void (*LogCallback)(int arg1, String arg2); + +/* + * Below here are the copypasted method declarations from the JNA bindings + */ + +// frontlib.h +int flib_init(); +void flib_quit(); + +// net/netconn.h +NetconnPtr flib_netconn_create(String playerName, MetaschemePtr meta, String dataDirPath, String host, int port); +void flib_netconn_destroy(NetconnPtr conn); + +void flib_netconn_tick(NetconnPtr conn); +boolean flib_netconn_is_chief(NetconnPtr conn); +String flib_netconn_get_playername(NetconnPtr conn); +GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn); +int flib_netconn_send_quit(NetconnPtr conn, String quitmsg); +int flib_netconn_send_chat(NetconnPtr conn, String chat); +int flib_netconn_send_teamchat(NetconnPtr conn, String msg); +int flib_netconn_send_password(NetconnPtr conn, String passwd); +int flib_netconn_send_nick(NetconnPtr conn, String nick); +int flib_netconn_send_request_roomlist(NetconnPtr conn); +int flib_netconn_send_joinRoom(NetconnPtr conn, String room); +int flib_netconn_send_createRoom(NetconnPtr conn, String room); +int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName); +int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg); +int flib_netconn_send_toggleReady(NetconnPtr conn); +int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team); +int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname); +int flib_netconn_send_engineMessage(NetconnPtr conn, Buffer message, NativeLong size); +int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount); +int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex); +int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset); +int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map); +int flib_netconn_send_mapName(NetconnPtr conn, String mapName); +int flib_netconn_send_mapGen(NetconnPtr conn, int mapGen); +int flib_netconn_send_mapTemplate(NetconnPtr conn, int templateFilter); +int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize); +int flib_netconn_send_mapSeed(NetconnPtr conn, String seed); +int flib_netconn_send_mapTheme(NetconnPtr conn, String theme); +int flib_netconn_send_mapDrawdata(NetconnPtr conn, Buffer drawData, NativeLong size); +int flib_netconn_send_script(NetconnPtr conn, String scriptName); +int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme); +int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError); +int flib_netconn_send_ban(NetconnPtr conn, String playerName); +int flib_netconn_send_kick(NetconnPtr conn, String playerName); +int flib_netconn_send_playerInfo(NetconnPtr conn, String playerName); +int flib_netconn_send_playerFollow(NetconnPtr conn, String playerName); +int flib_netconn_send_startGame(NetconnPtr conn); +int flib_netconn_send_toggleRestrictJoins(NetconnPtr conn); +int flib_netconn_send_toggleRestrictTeams(NetconnPtr conn); +int flib_netconn_send_clearAccountsCache(NetconnPtr conn); +int flib_netconn_send_setServerVar(NetconnPtr conn, String name, String value); +int flib_netconn_send_getServerVars(NetconnPtr conn); + +void flib_netconn_onMessage(NetconnPtr conn, IntStrCallback callback, Pointer context); +void flib_netconn_onChat(NetconnPtr conn, StrStrCallback callback, Pointer context); +void flib_netconn_onConnected(NetconnPtr conn, VoidCallback callback, Pointer context); +void flib_netconn_onDisconnected(NetconnPtr conn, IntStrCallback callback, Pointer context); +void flib_netconn_onRoomlist(NetconnPtr conn, RoomListCallback callback, Pointer context); +void flib_netconn_onRoomAdd(NetconnPtr conn, RoomCallback callback, Pointer context); +void flib_netconn_onRoomDelete(NetconnPtr conn, StrCallback callback, Pointer context); +void flib_netconn_onRoomUpdate(NetconnPtr conn, StrRoomCallback callback, Pointer context); +void flib_netconn_onLobbyJoin(NetconnPtr conn, StrCallback callback, Pointer context); +void flib_netconn_onLobbyLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); +void flib_netconn_onNickTaken(NetconnPtr conn, StrCallback callback, Pointer context); +void flib_netconn_onPasswordRequest(NetconnPtr conn, StrCallback callback, Pointer context); +void flib_netconn_onEnterRoom(NetconnPtr conn, BoolCallback callback, Pointer context); +void flib_netconn_onRoomChiefStatus(NetconnPtr conn, BoolCallback callback, Pointer context); +void flib_netconn_onReadyState(NetconnPtr conn, StrBoolCallback callback, Pointer context); +void flib_netconn_onLeaveRoom(NetconnPtr conn, IntStrCallback callback, Pointer context); +void flib_netconn_onTeamAdd(NetconnPtr conn, TeamCallback callback, Pointer context); +void flib_netconn_onTeamDelete(NetconnPtr conn, StrCallback callback, Pointer context); +void flib_netconn_onRoomJoin(NetconnPtr conn, StrCallback callback, Pointer context); +void flib_netconn_onRoomLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); +void flib_netconn_onRunGame(NetconnPtr conn, VoidCallback callback, Pointer context); +void flib_netconn_onTeamAccepted(NetconnPtr conn, StrCallback callback, Pointer context); +void flib_netconn_onHogCountChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); +void flib_netconn_onTeamColorChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); +void flib_netconn_onEngineMessage(NetconnPtr conn, BytesCallback callback, Pointer context); +void flib_netconn_onCfgScheme(NetconnPtr conn, SchemeCallback callback, Pointer context); +void flib_netconn_onMapChanged(NetconnPtr conn, MapIntCallback callback, Pointer context); +void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context); +void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context); +void flib_netconn_onAdminAccess(NetconnPtr conn, VoidCallback callback, Pointer context); +void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context); + +// ipc/gameconn.h +GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame); +GameconnPtr flib_gameconn_create_playdemo(Buffer demo, NativeLong size); +GameconnPtr flib_gameconn_create_loadgame(String playerName, Buffer save, NativeLong size); +GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script); + +void flib_gameconn_destroy(GameconnPtr conn); +int flib_gameconn_getport(GameconnPtr conn); +void flib_gameconn_tick(GameconnPtr conn); + +int flib_gameconn_send_enginemsg(GameconnPtr conn, Buffer data, NativeLong len); +int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg); +int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg); +int flib_gameconn_send_quit(GameconnPtr conn); + +void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context); +void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context); +void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context); +void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context); +void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context); +void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context); + +// ipc/mapconn.h +MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc); +void flib_mapconn_destroy(MapconnPtr conn); +int flib_mapconn_getport(MapconnPtr conn); +void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context); +void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context); +void flib_mapconn_tick(MapconnPtr conn); + +// model/scheme.h +MetaschemePtr flib_metascheme_from_ini(String filename); +MetaschemePtr flib_metascheme_retain(MetaschemePtr metainfo); +void flib_metascheme_release(MetaschemePtr metainfo); + +// model/schemelist.h +SchemelistPtr flib_schemelist_from_ini(MetaschemePtr meta, String filename); +int flib_schemelist_to_ini(String filename, SchemelistPtr list); +void flib_schemelist_destroy(SchemelistPtr list); + +// model/team.h +TeamPtr flib_team_from_ini(String filename); +int flib_team_to_ini(String filename, TeamPtr team); +void flib_team_destroy(TeamPtr team); + +// model/weapon.h +WeaponsetListPtr flib_weaponsetlist_from_ini(String filename); +int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets); +void flib_weaponsetlist_destroy(WeaponsetListPtr list); + +// util/logging.h +void flib_log_setLevel(int level); +void flib_log_setCallback(LogCallback callback); diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/frontlib.h --- a/project_files/frontlib/frontlib.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/frontlib.h Sun Aug 12 22:37:57 2012 +0200 @@ -30,6 +30,7 @@ #include "ipc/mapconn.h" #include "net/netconn.h" #include "util/logging.h" +#include "model/schemelist.h" /** * Call this function before anything else in this library. diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/ipc/gameconn.c --- a/project_files/frontlib/ipc/gameconn.c Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/ipc/gameconn.c Sun Aug 12 22:37:57 2012 +0200 @@ -117,14 +117,14 @@ return result; } -flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demo, size_t size) { - if(log_badargs_if(demo==NULL && size>0)) { +flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demoFileContent, size_t size) { + if(log_badargs_if(demoFileContent==NULL && size>0)) { return NULL; } flib_gameconn *result = NULL; flib_gameconn *tempConn = flib_gameconn_create_partial(false, "Player", false); if(tempConn) { - if(!flib_vector_append(tempConn->configBuffer, demo, size)) { + if(!flib_vector_append(tempConn->configBuffer, demoFileContent, size)) { result = tempConn; tempConn = NULL; } @@ -133,14 +133,14 @@ return result; } -flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *save, size_t size) { - if(log_badargs_if(save==NULL && size>0)) { +flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *saveFileContent, size_t size) { + if(log_badargs_if(saveFileContent==NULL && size>0)) { return NULL; } flib_gameconn *result = NULL; flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, false); if(tempConn) { - if(!flib_vector_append(tempConn->configBuffer, save, size)) { + if(!flib_vector_append(tempConn->configBuffer, saveFileContent, size)) { result = tempConn; tempConn = NULL; } @@ -280,6 +280,18 @@ return -1; } +int flib_gameconn_send_quit(flib_gameconn *conn) { + if(log_badargs_if(conn==NULL)) { + return -1; + } + const char *msg = "\x07""efinish"; + if(!flib_ipcbase_send_raw(conn->ipcBase, msg, msg[0]+1)) { + demo_append(conn, msg, msg[0]+1); + return 0; + } + return -1; +} + /** * This macro generates a callback setter function. It uses the name of the callback to * automatically generate the function name and the fields to set, so a consistent naming diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/ipc/gameconn.h --- a/project_files/frontlib/ipc/gameconn.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/ipc/gameconn.h Sun Aug 12 22:37:57 2012 +0200 @@ -17,6 +17,26 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +/** + * This file contains functions for starting and interacting with a game run by the engine. + * The general usage is to first create a gameconn object by calling one of the flib_gameconn_create + * functions. That will cause the frontlib to listen on a random port which can be queried using + * flib_gameconn_getport(). You should also register your callback functions right at the start + * to ensure you don't miss any callbacks. + * + * Next, start the engine (that part is up to you) with the appropriate command line arguments + * for starting a game. + * + * In order to allow the gameconn to run, you should regularly call flib_gameconn_tick(), which + * performs network I/O and calls your callbacks on interesting events. + * + * Once the engine connects, the gameconn will send it the required commands for starting the + * game you requested in your flib_gameconn_create call. + * + * When the game is finished (or the connection is lost), you will receive the onDisconnect + * message. This is the signal to destroy the gameconn and stop calling tick(). + */ + #ifndef GAMECONN_H_ #define GAMECONN_H_ @@ -26,6 +46,9 @@ #include #include +/* + * Different reasons for a disconnect. Only GAME_END_FINISHED signals a correctly completed game. + */ #define GAME_END_FINISHED 0 #define GAME_END_INTERRUPTED 1 #define GAME_END_HALTED 2 @@ -33,11 +56,33 @@ typedef struct _flib_gameconn flib_gameconn; +/** + * Create a gameconn that will start a local or network game with the indicated configuration. + */ flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame); -flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demo, size_t size); -flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *save, size_t size); + +/** + * Create a gameconn that will play back a demo. + */ +flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demoFileContent, size_t size); + +/** + * Create a gameconn that will continue from a saved game. + */ +flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *saveFileContent, size_t size); + +/** + * Create a gameconn that will start a campaign or training mission with the indicated script. + * seed is the random seed to use as entropy source (any string). + * script is the path and filename of a Campaign or Training script, relative to the Data directory + * (e.g. "Missions/Training/Basic_Training_-_Bazooka.lua") + */ flib_gameconn *flib_gameconn_create_campaign(const char *playerName, const char *seed, const char *script); +/** + * Release all resources of this gameconn, including the network connection, and free its memory. + * It is safe to call this function from a callback. + */ void flib_gameconn_destroy(flib_gameconn *conn); /** @@ -52,48 +97,76 @@ */ void flib_gameconn_tick(flib_gameconn *conn); +/** + * Send an engine message to the engine. Only needed in net games, where you receive engine + * messages from the server and have to pass them here. + */ int flib_gameconn_send_enginemsg(flib_gameconn *conn, const uint8_t *data, size_t len); + +/** + * Send an info message to the engine that will be displayed in the game's chatlog. + * The msgtype determines the color of the message; in the QTFrontend, info messages and + * normal chat messages use 1, emote-messages (those starting with /me) use 2, and + * join/leave messages use 3. You should use flib_gameconn_send_chatmsg for chat messages + * though because it automatically formats /me messages. + * + * Generally only needed in net games. + */ int flib_gameconn_send_textmsg(flib_gameconn *conn, int msgtype, const char *msg); + +/** + * Send a chat message to be displayed in the game's chatlog. Messages starting with /me are + * automatically formatted correctly. + * + * Generally only needed in net games. + */ int flib_gameconn_send_chatmsg(flib_gameconn *conn, const char *playername, const char *msg); /** - * handleConnect(void *context) + * Request the engine to stop the game. + * You can use this to shut down a game early without directly killing the engine process. + */ +int flib_gameconn_send_quit(flib_gameconn *conn); + +/** + * Expected callback signature: void handleConnect(void *context) + * The engine has successfully connected. You don't have to react to this in any way. */ void flib_gameconn_onConnect(flib_gameconn *conn, void (*callback)(void* context), void* context); /** - * handleDisconnect(void *context, int reason) + * Expected callback signature: void handleDisconnect(void *context, int reason) + * The connection to the engine was closed, either because the game has ended normally, or + * because it was interrupted/halted, or because of an error. The reason is provided as one + * of the GAME_END_xxx constants. + * + * You should destroy the gameconn and - in a netgame - notify the server that the game has ended. */ void flib_gameconn_onDisconnect(flib_gameconn *conn, void (*callback)(void* context, int reason), void* context); /** - * Receives error messages sent by the engine - * handleErrorMessage(void* context, const char *msg) + * Expected callback signature: void handleErrorMessage(void* context, const char *msg) + * The engine sent an error message, you should probably display it to the user or at least log it. */ void flib_gameconn_onErrorMessage(flib_gameconn *conn, void (*callback)(void* context, const char *msg), void* context); /** - * handleChat(void* context, const char *msg, bool teamchat) + * Expected callback signature: void handleChat(void* context, const char *msg, bool teamchat) + * The player entered a chat or teamchat message. In a netgame, you should send it on to the server. */ void flib_gameconn_onChat(flib_gameconn *conn, void (*callback)(void* context, const char *msg, bool teamchat), void* context); /** - * Called when the game ends - * handleGameRecorded(void *context, const uint8_t *record, int size, bool isSavegame) + * Expected callback signature: void handleGameRecorded(void *context, const uint8_t *record, size_t size, bool isSavegame) + * The game has stopped, and a demo or savegame is available. You can store it in a file and later pass it back + * to the engine to either watch a replay (if it's a demo) or to continue playing (if it's a savegame). */ void flib_gameconn_onGameRecorded(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *record, size_t size, bool isSavegame), void* context); /** - * Called when the game ends - * TODO handleStats(???) - */ - -/** - * ...needs to be passed on to the server in a net game - * handleEngineMessage(void *context, const uint8_t *em, size_t size) + * Expected callback signature: void handleEngineMessage(void *context, const uint8_t *em, size_t size) + * The engine has generated a message with player input. In a netgame, you should send it on to the server. */ void flib_gameconn_onEngineMessage(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *em, size_t size), void* context); -// TODO efinish - #endif diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/ipc/ipcprotocol.c --- a/project_files/frontlib/ipc/ipcprotocol.c Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/ipc/ipcprotocol.c Sun Aug 12 22:37:57 2012 +0200 @@ -80,8 +80,8 @@ */ const char *edraw = "edraw "; int edrawlen = strlen(edraw); - for(int offset=0; offsetdrawDataSize; offset+=200) { - int bytesRemaining = map->drawDataSize-offset; + for(size_t offset=0; offsetdrawDataSize; offset+=200) { + size_t bytesRemaining = map->drawDataSize-offset; int fragmentsize = bytesRemaining < 200 ? bytesRemaining : 200; uint8_t messagesize = edrawlen + fragmentsize; error |= flib_vector_append(tempvector, &messagesize, 1); @@ -111,10 +111,19 @@ int flib_ipc_append_script(flib_vector *vec, const char *script) { int result = -1; - char *copy = flib_strdupnull(script); + if(!log_badargs_if2(vec==NULL, script==NULL)) { + result = flib_ipc_append_message(vec, "escript %s", script); + } + return result; +} + +int flib_ipc_append_style(flib_vector *vec, const char *style) { + int result = -1; + char *copy = flib_strdupnull(style); if(!log_badargs_if(vec==NULL) && copy) { if(!strcmp("Normal", copy)) { // "Normal" means no gametype script + // TODO if an empty script called "Normal" is added to the scripts directory this can be removed result = 0; } else { size_t len = strlen(copy); @@ -192,7 +201,7 @@ } } -int flib_ipc_append_addteam(flib_vector *vec, const flib_team *team, bool perHogAmmo, bool noAmmoStore) { +static int flib_ipc_append_addteam(flib_vector *vec, const flib_team *team, bool perHogAmmo, bool noAmmoStore) { int result = -1; flib_vector *tempvector = flib_vector_create(); if(!log_badargs_if2(vec==NULL, team==NULL) && tempvector) { @@ -206,11 +215,11 @@ char md5Hex[33]; calculateMd5Hex(team->ownerName ? team->ownerName : "", md5Hex); - if(team->colorIndex<0 || team->colorIndex>=flib_teamcolor_defaults_len) { + if(team->colorIndex<0 || team->colorIndex>=flib_teamcolor_count) { flib_log_e("Color index out of bounds for team %s: %i", team->name, team->colorIndex); error = true; } else { - error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", md5Hex, flib_teamcolor_defaults[team->colorIndex], team->name); + error |= flib_ipc_append_message(tempvector, "eaddteam %s %"PRIu32" %s", md5Hex, flib_teamcolors[team->colorIndex], team->name); } if(team->remoteDriven) { @@ -258,8 +267,8 @@ if(setup->map) { error |= flib_ipc_append_mapconf(tempvector, setup->map, false); } - if(setup->script) { - error |= flib_ipc_append_script(tempvector, setup->script); + if(setup->style) { + error |= flib_ipc_append_style(tempvector, setup->style); } if(setup->gamescheme) { error |= flib_ipc_append_gamescheme(tempvector, setup->gamescheme); diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/ipc/ipcprotocol.h --- a/project_files/frontlib/ipc/ipcprotocol.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/ipc/ipcprotocol.h Sun Aug 12 22:37:57 2012 +0200 @@ -58,7 +58,7 @@ int flib_ipc_append_seed(flib_vector *vec, const char *seed); /** - * Append a script message to the buffer. + * Append a script to the buffer (e.g. "Missions/Training/Basic_Training_-_Bazooka.lua") * * Returns nonzero if something goes wrong. In that case the buffer * contents are unaffected. @@ -66,15 +66,28 @@ int flib_ipc_append_script(flib_vector *vec, const char *script); /** + * Append a game style to the buffer. (e.g. "Capture the Flag") + * + * Returns nonzero if something goes wrong. In that case the buffer + * contents are unaffected. + */ +int flib_ipc_append_style(flib_vector *vec, const char *style); + +/** * Append the game scheme to the buffer. * * Returns nonzero if something goes wrong. In that case the buffer * contents are unaffected. */ -int flib_ipc_append_gamescheme(flib_vector *vec, const flib_scheme *cfg); +int flib_ipc_append_gamescheme(flib_vector *vec, const flib_scheme *scheme); -int flib_ipc_append_addteam(flib_vector *vec, const flib_team *team, bool perHogAmmo, bool noAmmoStore); - +/** + * Append the entire game config to the buffer (including the final "!" that marks the + * end of configuration data for the engine) + * + * Returns nonzero if something goes wrong. In that case the buffer + * contents are unaffected. + */ int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame); #endif /* IPCPROTOCOL_H_ */ diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/ipc/mapconn.h --- a/project_files/frontlib/ipc/mapconn.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/ipc/mapconn.h Sun Aug 12 22:37:57 2012 +0200 @@ -17,6 +17,24 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +/** + * Functions for querying a map preview from the engine, which includes both a two-color image + * and the number of hogs this map is suitable for. + * + * The general usage is to first create a mapconn object by calling flib_mapconn_create. + * That will cause the frontlib to listen on a random port which can be queried using + * flib_mapconn_getport(). You should also register your callback functions right at the start + * to ensure you don't miss any callbacks. + * + * Next, start the engine (that part is up to you) with the appropriate command line arguments + * for a map preview request. + * + * In order to allow the mapconn to run, you should regularly call flib_mapconn_tick(), which + * performs network I/O and calls your callbacks if the map has been generated or an error + * has occurred. Once either the onSuccess or onFailure callback is called, you should destroy + * the mapconn and stop calling tick(). + */ + #ifndef IPC_MAPCONN_H_ #define IPC_MAPCONN_H_ @@ -38,7 +56,7 @@ * * The map must be a regular, maze or drawn map - for a preview of a named map, * use the preview images in the map's directory, and for the hog count read the - * map information (flib_mapcfg_read). + * map information (e.g. using flib_mapcfg_read). * * No NULL parameters allowed, returns NULL on failure. * Use flib_mapconn_destroy to free the returned object. @@ -59,7 +77,6 @@ /** * Set a callback which will receive the rendered map if the rendering succeeds. - * You can pass callback=NULL to unset a callback. * * Expected callback signature: * void handleSuccess(void *context, const uint8_t *bitmap, int numHedgehogs) @@ -77,7 +94,6 @@ /** * Set a callback which will receive an error message if rendering fails. - * You can pass callback=NULL to unset a callback. * * Expected callback signature: * void handleFailure(void *context, const char *errormessage) diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/model/gamesetup.c --- a/project_files/frontlib/model/gamesetup.c Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/model/gamesetup.c Sun Aug 12 22:37:57 2012 +0200 @@ -24,9 +24,9 @@ void flib_gamesetup_destroy(flib_gamesetup *gamesetup) { if(gamesetup) { - free(gamesetup->script); - flib_scheme_release(gamesetup->gamescheme); - flib_map_release(gamesetup->map); + free(gamesetup->style); + flib_scheme_destroy(gamesetup->gamescheme); + flib_map_destroy(gamesetup->map); flib_teamlist_destroy(gamesetup->teamlist); free(gamesetup); } @@ -39,11 +39,11 @@ flib_gamesetup *result = flib_calloc(1, sizeof(flib_gamesetup)); if(result) { - result->script = flib_strdupnull(setup->script); + result->style = flib_strdupnull(setup->style); result->gamescheme = flib_scheme_copy(setup->gamescheme); result->map = flib_map_copy(setup->map); result->teamlist = flib_teamlist_copy(setup->teamlist); - if((setup->script && !result->script) + if((setup->style && !result->style) || (setup->gamescheme && !result->gamescheme) || (setup->map && !result->map) || (setup->teamlist && !result->teamlist)) { diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/model/gamesetup.h --- a/project_files/frontlib/model/gamesetup.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/model/gamesetup.h Sun Aug 12 22:37:57 2012 +0200 @@ -18,7 +18,7 @@ */ /** - * A complete game configuration that contains all settings for a + * A complete game configuration that contains all settings the engine needs to start a * local or networked game. */ @@ -31,7 +31,7 @@ #include "teamlist.h" typedef struct { - char *script; + char *style; // e.g. "Capture the Flag" flib_scheme *gamescheme; flib_map *map; flib_teamlist *teamlist; diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/model/map.c --- a/project_files/frontlib/model/map.c Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/model/map.c Sun Aug 12 22:37:57 2012 +0200 @@ -26,16 +26,6 @@ #include -static void flib_map_destroy(flib_map *map) { - if(map) { - free(map->seed); - free(map->drawData); - free(map->name); - free(map->theme); - free(map); - } -} - flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter) { if(log_badargs_if2(seed==NULL, theme==NULL)) { return NULL; @@ -74,7 +64,7 @@ } flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize) { - if(log_badargs_if3(seed==NULL, theme==NULL, drawData==NULL && drawDataSize>0)) { + if(log_badargs_if3(seed==NULL, theme==NULL, drawData==NULL)) { return NULL; } flib_map newmap = {0}; @@ -90,7 +80,7 @@ flib_map *flib_map_copy(const flib_map *map) { flib_map *result = NULL; if(map) { - flib_map *newmap = flib_map_retain(flib_calloc(1, sizeof(flib_map))); + flib_map *newmap = flib_calloc(1, sizeof(flib_map)); if(newmap) { newmap->mapgen = map->mapgen; newmap->drawDataSize = map->drawDataSize; @@ -105,20 +95,17 @@ newmap = NULL; } } - flib_map_release(newmap); + flib_map_destroy(newmap); } return result; } -flib_map *flib_map_retain(flib_map *map) { +void flib_map_destroy(flib_map *map) { if(map) { - flib_retain(&map->_referenceCount, "flib_map"); - } - return map; -} - -void flib_map_release(flib_map *map) { - if(map && flib_release(&map->_referenceCount, "flib_map")) { - flib_map_destroy(map); + free(map->seed); + free(map->drawData); + free(map->name); + free(map->theme); + free(map); } } diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/model/map.h --- a/project_files/frontlib/model/map.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/model/map.h Sun Aug 12 22:37:57 2012 +0200 @@ -45,22 +45,20 @@ /** * Data structure for defining a map. This contains the whole recipe to - * exactly recreate a particular map. For named maps, you also need the - * corresponding files. + * exactly recreate a particular map. * * The required fields depend on the map generator, see the comments * at the struct for details. */ typedef struct { - int _referenceCount; int mapgen; // Always one of the MAPGEN_ constants - char *name; // The name of the map for MAPGEN_NAMED, otherwise one of "+rnd+", "+maze+" or "+drawn+". - char *seed; // Used for all maps - char *theme; // Used for all maps + char *name; // The name of the map for MAPGEN_NAMED (e.g. "Cogs"), otherwise one of "+rnd+", "+maze+" or "+drawn+". + char *seed; // Used for all maps. This is a random seed for all (non-AI) entropy in the round. Typically a random UUID, but can be any string. + char *theme; // Used for all maps. This is the name of a directory in Data/Themes (e.g. "Beach") uint8_t *drawData; // Used for MAPGEN_DRAWN - int drawDataSize; // Used for MAPGEN_DRAWN TODO size_t - int templateFilter; // Used for MAPGEN_REGULAR - int mazeSize; // Used for MAPGEN_MAZE + size_t drawDataSize; // Used for MAPGEN_DRAWN + int templateFilter; // Used for MAPGEN_REGULAR. One of the TEMPLATEFILTER_xxx constants. + int mazeSize; // Used for MAPGEN_MAZE. One of the MAZE_SIZE_xxx constants. } flib_map; /** @@ -108,15 +106,9 @@ flib_map *flib_map_copy(const flib_map *map); /** - * Increase the reference count of the object. Call this if you store a pointer to it somewhere. - * Returns the parameter. - */ -flib_map *flib_map_retain(flib_map *map); - -/** * Decrease the reference count of the object and free it if this was the last reference. */ -void flib_map_release(flib_map *map); +void flib_map_destroy(flib_map *map); #endif diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/model/scheme.c --- a/project_files/frontlib/model/scheme.c Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/model/scheme.c Sun Aug 12 22:37:57 2012 +0200 @@ -48,16 +48,6 @@ } } -static void flib_scheme_destroy(flib_scheme* scheme) { - if(scheme) { - flib_metascheme_release(scheme->meta); - free(scheme->mods); - free(scheme->settings); - free(scheme->name); - free(scheme); - } -} - static flib_metascheme *flib_metascheme_from_ini_handleError(flib_metascheme *result, flib_ini *ini) { flib_metascheme_destroy(result); flib_ini_destroy(ini); @@ -166,7 +156,7 @@ } flib_scheme *flib_scheme_create(flib_metascheme *meta, const char *schemeName) { - flib_scheme *result = flib_scheme_retain(flib_calloc(1, sizeof(flib_scheme))); + flib_scheme *result = flib_calloc(1, sizeof(flib_scheme)); if(log_badargs_if2(meta==NULL, schemeName==NULL) || result==NULL) { return NULL; } @@ -199,16 +189,13 @@ return result; } -flib_scheme *flib_scheme_retain(flib_scheme *scheme) { +void flib_scheme_destroy(flib_scheme* scheme) { if(scheme) { - flib_retain(&scheme->_referenceCount, "flib_scheme"); - } - return scheme; -} - -void flib_scheme_release(flib_scheme *scheme) { - if(scheme && flib_release(&scheme->_referenceCount, "flib_scheme")) { - flib_scheme_destroy(scheme); + flib_metascheme_release(scheme->meta); + free(scheme->mods); + free(scheme->settings); + free(scheme->name); + free(scheme); } } diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/model/scheme.h --- a/project_files/frontlib/model/scheme.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/model/scheme.h Sun Aug 12 22:37:57 2012 +0200 @@ -19,6 +19,10 @@ /** * Data structures for game scheme information. + * + * The scheme consists of settings (integers) and mods (booleans). These are not fixed, but + * described in a "metascheme" file, which describes how each setting and mod is sent to the + * engine, and in which order they appear in the network protocol. */ #ifndef SCHEME_H_ @@ -27,18 +31,19 @@ #include typedef struct { - char *name; - char *engineCommand; - bool maxMeansInfinity; - bool times1000; - int min; - int max; - int def; + char *name; // A name identifying this setting (used as key in the schemes file) + char *engineCommand; // The command needed to send the setting to the engine. May be null if the setting is not sent to the engine (for the "health" setting) + bool maxMeansInfinity; // If true, send a very high number to the engine if the setting is equal to its maximum + bool times1000; // If true (for time-based settings), multiply the setting by 1000 before sending it to the engine. + int min; // The smallest allowed value + int max; // The highest allowed value + int def; // The default value } flib_metascheme_setting; typedef struct { - char *name; - int bitmaskIndex; + char *name; // A name identifying this mod (used as key in the schemes file) + int bitmaskIndex; // Mods are sent to the engine in a single integer, this field describes which bit of that integer is used + // for this particular mod. } flib_metascheme_mod; /** @@ -53,8 +58,11 @@ flib_metascheme_mod *mods; } flib_metascheme; +/** + * The settings and mods arrays have the same number and order of elements + * as the corresponding arrays in the metascheme. + */ typedef struct { - int _referenceCount; flib_metascheme *meta; char *name; @@ -93,15 +101,9 @@ flib_scheme *flib_scheme_copy(const flib_scheme *scheme); /** - * Increase the reference count of the object. Call this if you store a pointer to it somewhere. - * Returns the parameter. - */ -flib_scheme *flib_scheme_retain(flib_scheme *scheme); - -/** * Decrease the reference count of the object and free it if this was the last reference. */ -void flib_scheme_release(flib_scheme* scheme); +void flib_scheme_destroy(flib_scheme* scheme); /** * Retrieve a mod setting by its name. If the mod is not found, logs an error and returns false. diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/model/schemelist.c --- a/project_files/frontlib/model/schemelist.c Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/model/schemelist.c Sun Aug 12 22:37:57 2012 +0200 @@ -72,13 +72,14 @@ if(schemeNameKey) { char *schemeName = NULL; if(!flib_ini_get_str_opt(ini, &schemeName, schemeNameKey, "Unnamed")) { - flib_scheme *scheme = flib_scheme_create(meta, schemeName); - if(scheme) { - if(!readSettingsFromIni(ini, scheme, index) && !readModsFromIni(ini, scheme, index)) { - result = flib_scheme_retain(scheme); + flib_scheme *tmpScheme = flib_scheme_create(meta, schemeName); + if(tmpScheme) { + if(!readSettingsFromIni(ini, tmpScheme, index) && !readModsFromIni(ini, tmpScheme, index)) { + result = tmpScheme; + tmpScheme = NULL; } } - flib_scheme_release(scheme); + flib_scheme_destroy(tmpScheme); } free(schemeName); } @@ -118,11 +119,10 @@ for(int i=0; imeta; bool error = false; @@ -179,7 +179,7 @@ void flib_schemelist_destroy(flib_schemelist *list) { if(list) { for(int i=0; ischemeCount; i++) { - flib_scheme_release(list->schemes[i]); + flib_scheme_destroy(list->schemes[i]); } free(list->schemes); free(list); @@ -203,7 +203,6 @@ int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos) { if(!log_badargs_if2(list==NULL, cfg==NULL) && !insertScheme(&list->schemes, &list->schemeCount, cfg, pos)) { - flib_scheme_retain(cfg); return 0; } return -1; @@ -213,7 +212,7 @@ if(!log_badargs_if(list==NULL)) { flib_scheme *elem = list->schemes[pos]; if(!deleteScheme(&list->schemes, &list->schemeCount, pos)) { - flib_scheme_release(elem); + flib_scheme_destroy(elem); return 0; } } diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/model/schemelist.h --- a/project_files/frontlib/model/schemelist.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/model/schemelist.h Sun Aug 12 22:37:57 2012 +0200 @@ -19,7 +19,7 @@ /** * Functions for managing a list of schemes. - * This is in here because the scheme config file of the QtFrontend (which we are staying compatble with) contains + * This is in here because the scheme config file of the QtFrontend (which we are staying compatible with) contains * all the schemes at once, so we need functions to work with a list like that. */ @@ -53,14 +53,14 @@ /** * Insert a new scheme into the list at position pos, moving all higher schemes to make place. * pos must be at least 0 (insert at the start) and at most list->schemeCount (insert at the end). - * The scheme is retained automatically. + * Ownership of the scheme is transferred to the list. * Returns 0 on success. */ int flib_schemelist_insert(flib_schemelist *list, flib_scheme *cfg, int pos); /** * Delete a scheme from the list at position pos, moving down all higher schemes. - * The scheme is released automatically. + * The scheme is destroyed. * Returns 0 on success. */ int flib_schemelist_delete(flib_schemelist *list, int pos); @@ -71,7 +71,7 @@ flib_scheme *flib_schemelist_find(flib_schemelist *list, const char *name); /** - * Free this schemelist. + * Free this schemelist and all contained schemes */ void flib_schemelist_destroy(flib_schemelist *list); diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/model/team.h --- a/project_files/frontlib/model/team.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/model/team.h Sun Aug 12 22:37:57 2012 +0200 @@ -24,7 +24,7 @@ * extra information about teams. For example, the weaponset is important * to the engine, but not for ini reading/writing, and with the team statistics it is the * other way around. To keep things simple, the data structure can hold all information - * used in any context. On the downside, tat means we can't use static typing to ensure + * used in any context. On the downside, that means we can't use static typing to ensure * that team information is "complete" for a particular purpose. */ #ifndef TEAM_H_ @@ -39,6 +39,9 @@ #define TEAM_DEFAULT_HEALTH 100 +/** + * Struct representing a single keybinding. + */ typedef struct { char *action; char *binding; @@ -46,7 +49,7 @@ typedef struct { char *name; - char *hat; + char *hat; // e.g. hair_yellow; References a .png file in Data/Graphics/Hats // Statistics. They are irrelevant for the engine or server, // but provided for ini reading/writing by the frontend. @@ -55,7 +58,7 @@ int deaths; int suicides; - int difficulty; + int difficulty; // 0 = human, 1 = most difficult bot ... 5 = least difficult bot (somewhat counterintuitive) // Transient setting used in game setup int initialHealth; @@ -65,10 +68,10 @@ typedef struct { flib_hog hogs[HEDGEHOGS_PER_TEAM]; char *name; - char *grave; - char *fort; - char *voicepack; - char *flag; + char *grave; // e.g. "Bone"; References a .png file in Data/Graphics/Graves + char *fort; // e.g. "Castle"; References a series of files in Data/Forts + char *voicepack; // e.g. "Classic"; References a directory in Data/Sounds/voices + char *flag; // e.g. "hedgewars"; References a .png file in Data/Graphics/Flags flib_binding *bindings; int bindingCount; @@ -81,9 +84,9 @@ // Transient settings used in game setup int colorIndex; // Index into a color table - int hogsInGame; - bool remoteDriven; - char *ownerName; + int hogsInGame; // The number of hogs that will actually play + bool remoteDriven; // true for non-local teams in a network game + char *ownerName; // Username of the owner of a team in a network game } flib_team; /** diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/model/weapon.h --- a/project_files/frontlib/model/weapon.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/model/weapon.h Sun Aug 12 22:37:57 2012 +0200 @@ -23,10 +23,12 @@ #include "../hwconsts.h" /** - * These values are all in the range 0..9 + * These values are all ASCII characters in the range '0'..'9' + * The fields are zero-terminated so they can easily be used as strings. * * For loadout, 9 means inifinite ammo. * For the other setting, 9 is invalid. + * TODO stop reference counting, it complects everything */ typedef struct { int _referenceCount; diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/net/netconn.c --- a/project_files/frontlib/net/netconn.c Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/net/netconn.c Sun Aug 12 22:37:57 2012 +0200 @@ -18,8 +18,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -// TODO: Check the state transitions. Document with a diagram or something - #include "netconn_internal.h" #include "netprotocol.h" #include "../util/logging.h" @@ -53,7 +51,7 @@ newConn->teamlist.teamCount = 0; newConn->teamlist.teams = NULL; newConn->scheme = NULL; - newConn->script = NULL; + newConn->style = NULL; newConn->weaponset = NULL; newConn->running = false; @@ -86,11 +84,11 @@ flib_metascheme_release(conn->metaCfg); - flib_map_release(conn->map); + flib_map_destroy(conn->map); flib_teamlist_clear(&conn->pendingTeamlist); flib_teamlist_clear(&conn->teamlist); - flib_scheme_release(conn->scheme); - free(conn->script); + flib_scheme_destroy(conn->scheme); + free(conn->style); flib_weaponset_release(conn->weaponset); free(conn); @@ -99,7 +97,7 @@ } bool flib_netconn_is_chief(flib_netconn *conn) { - if(!log_badargs_if(conn==NULL) && flib_netconn_is_in_room_context(conn)) { + if(!log_badargs_if(conn==NULL) && conn->netconnState==NETCONN_STATE_ROOM) { return conn->isChief; } return false; @@ -115,26 +113,22 @@ void netconn_leaveRoom(flib_netconn *conn) { conn->netconnState = NETCONN_STATE_LOBBY; conn->isChief = false; - flib_map_release(conn->map); + flib_map_destroy(conn->map); conn->map = flib_map_create_named("", "NoSuchMap"); flib_teamlist_clear(&conn->pendingTeamlist); flib_teamlist_clear(&conn->teamlist); - flib_scheme_release(conn->scheme); + flib_scheme_destroy(conn->scheme); conn->scheme = NULL; - free(conn->script); - conn->script = NULL; + free(conn->style); + conn->style = NULL; flib_weaponset_release(conn->weaponset); conn->weaponset = NULL; } -bool flib_netconn_is_in_room_context(flib_netconn *conn) { - return conn && (conn->netconnState == NETCONN_STATE_ROOM || conn->netconnState == NETCONN_STATE_INGAME); -} - void netconn_setMap(flib_netconn *conn, const flib_map *map) { flib_map *copy = flib_map_copy(map); if(copy) { - flib_map_release(conn->map); + flib_map_destroy(conn->map); conn->map = copy; } } @@ -150,15 +144,15 @@ void netconn_setScript(flib_netconn *conn, const char *script) { char *copy = flib_strdupnull(script); if(copy) { - free(conn->script); - conn->script = copy; + free(conn->style); + conn->style = copy; } } void netconn_setScheme(flib_netconn *conn, const flib_scheme *scheme) { flib_scheme *copy = flib_scheme_copy(scheme); if(copy) { - flib_scheme_release(conn->scheme); + flib_scheme_destroy(conn->scheme); conn->scheme = copy; } } @@ -172,7 +166,7 @@ flib_gamesetup stackSetup = {0}; stackSetup.gamescheme = conn->scheme; stackSetup.map = conn->map; - stackSetup.script = conn->script; + stackSetup.style = conn->style; stackSetup.teamlist = &conn->teamlist; flib_gamesetup *tmpSetup = flib_gamesetup_copy(&stackSetup); if(tmpSetup) { @@ -322,7 +316,7 @@ } } } else if (!strcmp(cmd, "ADD_TEAM")) { - if(netmsg->partCount != 24 || !flib_netconn_is_in_room_context(conn)) { + if(netmsg->partCount != 24 || conn->netconnState!=NETCONN_STATE_ROOM) { flib_log_w("Net: Bad ADD_TEAM message"); } else { flib_team *team = flib_team_from_netmsg(netmsg->parts+1); @@ -337,7 +331,7 @@ } } } else if (!strcmp(cmd, "REMOVE_TEAM")) { - if(netmsg->partCount != 2 || !flib_netconn_is_in_room_context(conn)) { + if(netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) { flib_log_w("Net: Bad REMOVETEAM message"); } else { flib_teamlist_delete(&conn->teamlist, netmsg->parts[1]); @@ -410,8 +404,6 @@ conn->onLobbyLeaveCb(conn->onLobbyLeaveCtx, netmsg->parts[1], netmsg->partCount>2 ? netmsg->parts[2] : NULL); } } else if (!strcmp(cmd, "RUN_GAME")) { - conn->netconnState = NETCONN_STATE_INGAME; - // TODO send along the config conn->onRunGameCb(conn->onRunGameCtx); } else if (!strcmp(cmd, "ASKPASSWORD")) { conn->onPasswordRequestCb(conn->onPasswordRequestCtx, conn->playerName); @@ -430,10 +422,10 @@ } } } else if (!strcmp(cmd, "TEAM_ACCEPTED")) { - if (netmsg->partCount != 2 || !flib_netconn_is_in_room_context(conn)) { + if (netmsg->partCount != 2 || conn->netconnState!=NETCONN_STATE_ROOM) { flib_log_w("Net: Bad TEAM_ACCEPTED message"); } else { - flib_team *team = flib_teamlist_find(&conn->pendingTeamlist, netmsg->parts[1]); + flib_team *team = flib_team_copy(flib_teamlist_find(&conn->pendingTeamlist, netmsg->parts[1])); if(team) { flib_teamlist_insert(&conn->teamlist, team, conn->teamlist.teamCount); flib_teamlist_delete(&conn->pendingTeamlist, netmsg->parts[1]); @@ -443,28 +435,28 @@ conn->onTeamAcceptedCb(conn->onTeamAcceptedCtx, netmsg->parts[1]); } } else if (!strcmp(cmd, "CFG")) { - if(netmsg->partCount < 3 || !flib_netconn_is_in_room_context(conn)) { + if(netmsg->partCount < 3 || conn->netconnState!=NETCONN_STATE_ROOM) { flib_log_w("Net: Bad CFG message"); } else { const char *subcmd = netmsg->parts[1]; if(!strcmp(subcmd, "SCHEME") && netmsg->partCount == conn->metaCfg->modCount + conn->metaCfg->settingCount + 3) { - flib_scheme *cfg = flib_netmsg_to_cfg(conn->metaCfg, netmsg->parts+2); + flib_scheme *cfg = flib_scheme_from_netmsg(conn->metaCfg, netmsg->parts+2); if(cfg) { - netconn_setScheme(conn, cfg); + flib_scheme_destroy(conn->scheme); + conn->scheme = cfg; conn->onCfgSchemeCb(conn->onCfgSchemeCtx, cfg); } else { flib_log_e("Error processing CFG SCHEME message"); } - flib_scheme_release(cfg); } else if(!strcmp(subcmd, "FULLMAPCONFIG") && netmsg->partCount == 7) { - flib_map *map = flib_netmsg_to_map(netmsg->parts+2); + flib_map *map = flib_map_from_netmsg(netmsg->parts+2); if(map) { - netconn_setMap(conn, map); + flib_map_destroy(conn->map); + conn->map = map; conn->onMapChangedCb(conn->onMapChangedCtx, conn->map, NETCONN_MAPCHANGE_FULL); } else { flib_log_e("Error processing CFG FULLMAPCONFIG message"); } - flib_map_release(map); } else if(!strcmp(subcmd, "MAP") && netmsg->partCount == 3) { char *mapname = flib_strdupnull(netmsg->parts[2]); if(mapname) { @@ -504,7 +496,7 @@ } else if(!strcmp(subcmd, "DRAWNMAP") && netmsg->partCount == 3) { size_t drawnMapSize = 0; uint8_t *drawnMapData = NULL; - if(!flib_netmsg_to_drawnmapdata(netmsg->parts[2], &drawnMapData, &drawnMapSize)) { + if(!flib_drawnmapdata_from_netmsg(netmsg->parts[2], &drawnMapData, &drawnMapSize)) { free(conn->map->drawData); conn->map->drawData = drawnMapData; conn->map->drawDataSize = drawnMapSize; @@ -529,7 +521,7 @@ } } } else if (!strcmp(cmd, "HH_NUM")) { - if (netmsg->partCount != 3 || !flib_netconn_is_in_room_context(conn)) { + if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) { flib_log_w("Net: Bad HH_NUM message"); } else { int hogs = atoi(netmsg->parts[2]); @@ -546,11 +538,11 @@ } } } else if (!strcmp(cmd, "TEAM_COLOR")) { - if (netmsg->partCount != 3 || !flib_netconn_is_in_room_context(conn)) { + if (netmsg->partCount != 3 || conn->netconnState!=NETCONN_STATE_ROOM) { flib_log_w("Net: Bad TEAM_COLOR message"); } else { long color; - if(sscanf(netmsg->parts[2], "%lu", &color) && color>=0 && colorparts[2], "%lu", &color) && color>=0 && colorteamlist, netmsg->parts[1]); if(team) { team->colorIndex = color; diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/net/netconn.h --- a/project_files/frontlib/net/netconn.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/net/netconn.h Sun Aug 12 22:37:57 2012 +0200 @@ -17,6 +17,42 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +/** + * This file contains functions for communicating with a Hedgewars server to chat, prepare + * and play rounds of Hedgewars. + * + * To use this, first create a netconn object by calling flib_netconn_create. This will + * start the connection to the game server (which might fail right away, the function + * returns null then). You should also register your callback functions right at the start + * to ensure you don't miss any callbacks. + * + * In order to allow the netconn to run, you should regularly call flib_netconn_tick(), which + * performs network I/O and calls your callbacks on interesting events. + * + * When the connection is closed, you will receive the onDisconnect callback. This is the + * signal to destroy the netconn and stop calling tick(). + * + * The connection process lasts from the time you create the netconn until you receive the + * onConnected callback (or onDisconnected in case something goes wrong). During that time, + * you might receive the onNickTaken and onPasswordRequest callbacks; see their description + * for more information on how to handle them. You could also receive other callbacks during + * connecting (e.g. about the room list), but it should be safe to ignore them. + * + * Once you are connected, you are in the lobby, and you can enter rooms and leave them again. + * The room and lobby states have different protocols, so many commands only work in either + * one or the other. If you are in a room you might also be in a game, but that does not + * change the protocol. The functions below are grouped by the states in which they make + * sense, or (for the callbacks) the states in which you would typically receive them. + * + * The state changes from lobby to room when the server tells you that you just entered one, + * which will also trigger the onEnterRoom callback. This usually happens in reply to either + * a joinRoom, createRoom or playerFollow command. + * + * The state changes back to lobby when the room is dissolved, when you are kicked from the + * room, or when you actively leave the room using flib_netconn_send_leaveRoom. The first + * two events will trigger the onLeaveRoom callback. + */ + #ifndef NETCONN_H_ #define NETCONN_H_ @@ -31,22 +67,21 @@ #define NETCONN_STATE_CONNECTING 0 #define NETCONN_STATE_LOBBY 1 #define NETCONN_STATE_ROOM 2 -#define NETCONN_STATE_INGAME 3 #define NETCONN_STATE_DISCONNECTED 10 -#define NETCONN_DISCONNECT_NORMAL 0 -#define NETCONN_DISCONNECT_SERVER_TOO_OLD 1 -#define NETCONN_DISCONNECT_AUTH_FAILED 2 // TODO can you retry instead? -#define NETCONN_DISCONNECT_CONNLOST 3 -#define NETCONN_DISCONNECT_INTERNAL_ERROR 100 +#define NETCONN_DISCONNECT_NORMAL 0 // The connection was closed normally +#define NETCONN_DISCONNECT_SERVER_TOO_OLD 1 // The server has a lower protocol version than we do +#define NETCONN_DISCONNECT_AUTH_FAILED 2 // You sent a password with flib_netconn_send_password that was not accepted +#define NETCONN_DISCONNECT_CONNLOST 3 // The network connection was lost +#define NETCONN_DISCONNECT_INTERNAL_ERROR 100 // Something went wrong in frontlib itself -#define NETCONN_ROOMLEAVE_ABANDONED 0 -#define NETCONN_ROOMLEAVE_KICKED 1 +#define NETCONN_ROOMLEAVE_ABANDONED 0 // The room was closed because the chief left +#define NETCONN_ROOMLEAVE_KICKED 1 // You have been kicked from the room -#define NETCONN_MSG_TYPE_PLAYERINFO 0 -#define NETCONN_MSG_TYPE_SERVERMESSAGE 1 -#define NETCONN_MSG_TYPE_WARNING 2 -#define NETCONN_MSG_TYPE_ERROR 3 +#define NETCONN_MSG_TYPE_PLAYERINFO 0 // A response to flib_netconn_send_playerInfo +#define NETCONN_MSG_TYPE_SERVERMESSAGE 1 // The welcome message when connecting to the lobby +#define NETCONN_MSG_TYPE_WARNING 2 // A general warning message +#define NETCONN_MSG_TYPE_ERROR 3 // A general error message #define NETCONN_MAPCHANGE_FULL 0 #define NETCONN_MAPCHANGE_MAP 1 @@ -80,11 +115,6 @@ bool flib_netconn_is_chief(flib_netconn *conn); /** - * Are you in the context of a room, i.e. either in room or ingame state? - */ -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. @@ -116,6 +146,7 @@ /** * Send the password in reply to a password request. + * If the server does not accept the password, you will be disconnected (NETCONN_DISCONNECT_AUTH_FAILED) */ int flib_netconn_send_password(flib_netconn *conn, const char *passwd); @@ -165,9 +196,9 @@ int flib_netconn_send_toggleReady(flib_netconn *conn); /** - * Add a team to the current room. The message includes the team color, but not - * the number of hogs. Only makes sense when in room state. If the action succeeds, you will - * receive an onTeamAccepted callback with the name of the team. + * Add a team to the current room. Apart from the "fixed" team information, this also includes + * the color, but not the number of hogs. Only makes sense when in room state. If the action + * succeeds, you will receive an onTeamAccepted callback with the name of the team. */ int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team); @@ -269,12 +300,14 @@ int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError); /** - * Ban a player. TODO: Figure out details + * Ban a player. You need to be in the lobby and a server admin for this to work. */ int flib_netconn_send_ban(flib_netconn *conn, const char *playerName); /** - * Kick a player. TODO: Figure out details + * Kick a player. This has different meanings in the lobby and in a room; + * In the lobby, it will kick the player from the server, and you need to be a server admin to do it. + * In a room, it will kick the player from the room, and you need to be room chief. */ int flib_netconn_send_kick(flib_netconn *conn, const char *playerName); @@ -286,13 +319,17 @@ int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName); /** - * Follow a player. TODO figure out details + * Follow a player. Only valid in the lobby. If the player is in a room (or in a game), + * this command is analogous to calling flib_netconn_send_joinRoom with that room. */ int flib_netconn_send_playerFollow(flib_netconn *conn, const char *playerName); /** * Signal that you want to start the game. Only makes sense in room state and if you are chief. - * TODO details + * The server will check whether all players are ready and whether it believes the setup makes + * sense (e.g. more than one clan). If the server is satisfied, you will receive an onRunGame + * callback (all other clients in the room are notified the same way). Otherwise the server + * might answer with a warning, or might not answer at all. */ int flib_netconn_send_startGame(flib_netconn *conn); @@ -309,19 +346,19 @@ int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn); /** - * Probably does something administrator-y. + * Does something administrator-y. At any rate you need to be an administrator and in the lobby + * to use this command. */ int flib_netconn_send_clearAccountsCache(flib_netconn *conn); /** * Sets a server variable to the indicated value. Only makes sense if you are server admin. * Known variables are MOTD_NEW, MOTD_OLD and LATEST_PROTO. - * TODO reply? */ int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value); /** - * Queries all server variables. Only makes sense if you are server admin. (TODO: try) + * Queries all server variables. Only makes sense if you are server admin. * If the action succeeds, you will receive several onServerVar callbacks with the * current values of all server variables. */ @@ -435,6 +472,9 @@ /** * A new team was added to the room. The person who adds a team does NOT receive this callback (he gets onTeamAccepted instead). * The team does not contain bindings, stats, weaponset, color or the number of hogs. + * + * If you receive this message and you are the room chief, you are expected to provide a color and hog count for this team using + * flib_netconn_send_teamHogCount / teamColor. */ void flib_netconn_onTeamAdd(flib_netconn *conn, void (*callback)(void *context, const flib_team *team), void *context); @@ -456,8 +496,12 @@ * When you ask for a team to be added, the server might reject it for several reasons, e.g. because it has the same name * as an existing team, or because the room chief restricted adding new teams. If the team is accepted by the server, * this callback is fired. + * + * If you are the room chief, you are expected to provide the hog count for your own team now using flib_netconn_send_teamHogCount. + * The color of the team is already set to the one you provided in addTeam, but the QtFrontend apparently always uses 0 there and + * instead sets the color after the team is accepted. */ -void flib_netconn_onTeamAccepted(flib_netconn *conn, void (*callback)(void *context, const char *teamName), void *context); +void flib_netconn_onTeamAccepted(flib_netconn *conn, void (*callback)(void *context, const char *team), void *context); /** * The number of hogs in a team has been changed by the room chief. If you are the chief and change the number of hogs yourself, @@ -505,7 +549,7 @@ void flib_netconn_onAdminAccess(flib_netconn *conn, void (*callback)(void *context), void *context); /** - * When you query the server vars with GET_SERVER_VAR (TODO probably only works as admin), the server + * When you query the server vars with flib_netconn_send_getServerVars (only works as admin), the server * replies with a list of them. This callback is called for each entry in that list. */ void flib_netconn_onServerVar(flib_netconn *conn, void (*callback)(void *context, const char *name, const char *value), void *context); diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/net/netconn_callbacks.c --- a/project_files/frontlib/net/netconn_callbacks.c Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/net/netconn_callbacks.c Sun Aug 12 22:37:57 2012 +0200 @@ -117,7 +117,6 @@ static void _noop_callback_##cbName cbParameterTypes {} \ GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName) -// TODO Disallow transfer of ownership? 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)); diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/net/netconn_internal.h --- a/project_files/frontlib/net/netconn_internal.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/net/netconn_internal.h Sun Aug 12 22:37:57 2012 +0200 @@ -50,7 +50,7 @@ flib_teamlist pendingTeamlist; flib_teamlist teamlist; flib_scheme *scheme; - char *script; + char *style; flib_weaponset *weaponset; void (*onMessageCb)(void *context, int msgtype, const char *msg); diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/net/netconn_send.c --- a/project_files/frontlib/net/netconn_send.c Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/net/netconn_send.c Sun Aug 12 22:37:57 2012 +0200 @@ -133,7 +133,7 @@ int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *str) { int result = -1; - if(flib_netconn_is_in_room_context(conn)) { + if(conn->netconnState==NETCONN_STATE_ROOM) { result = (str && *str) ? sendStr(conn, "PART", str) : sendVoid(conn, "PART"); if(!result) { netconn_leaveRoom(conn); @@ -190,11 +190,9 @@ } int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname) { - if(!sendStr(conn, "REMOVE_TEAM", teamname)) { - flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); - if(team && !team->remoteDriven) { - flib_teamlist_delete(&conn->teamlist, teamname); - } + flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); + if(team && !team->remoteDriven && !sendStr(conn, "REMOVE_TEAM", teamname)) { + flib_teamlist_delete(&conn->teamlist, teamname); return 0; } return -1; @@ -214,13 +212,11 @@ } int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount) { - if(!log_badargs_if4(conn==NULL, flib_strempty(teamname), hogcount<1, hogcount>HEDGEHOGS_PER_TEAM) + if(!log_badargs_if5(conn==NULL, flib_strempty(teamname), hogcount<1, hogcount>HEDGEHOGS_PER_TEAM, !conn->isChief) && !flib_netbase_sendf(conn->netBase, "HH_NUM\n%s\n%i\n\n", teamname, hogcount)) { - if(conn->isChief) { - flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); - if(team) { - team->hogsInGame = hogcount; - } + flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); + if(team) { + team->hogsInGame = hogcount; } return 0; } @@ -228,13 +224,11 @@ } int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex) { - if(!log_badargs_if2(conn==NULL, flib_strempty(teamname)) + if(!log_badargs_if3(conn==NULL, flib_strempty(teamname), !conn->isChief) && !flib_netbase_sendf(conn->netBase, "TEAM_COLOR\n%s\n%i\n\n", teamname, colorIndex)) { - if(conn->isChief) { - flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); - if(team) { - team->colorIndex = colorIndex; - } + flib_team *team = flib_teamlist_find(&conn->teamlist, teamname); + if(team) { + team->colorIndex = colorIndex; } return 0; } @@ -431,13 +425,7 @@ } int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError) { - if(!sendInt(conn, "ROUNDFINISHED", withoutError ? 1 : 0)) { - if(conn->netconnState == NETCONN_STATE_INGAME) { - conn->netconnState = NETCONN_STATE_ROOM; - } - return 0; - } - return -1; + return sendInt(conn, "ROUNDFINISHED", withoutError ? 1 : 0); } int flib_netconn_send_ban(flib_netconn *conn, const char *playerName) { diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/net/netprotocol.c --- a/project_files/frontlib/net/netprotocol.c Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/net/netprotocol.c Sun Aug 12 22:37:57 2012 +0200 @@ -75,7 +75,7 @@ return result; } -flib_scheme *flib_netmsg_to_cfg(flib_metascheme *meta, char **parts) { +flib_scheme *flib_scheme_from_netmsg(flib_metascheme *meta, char **parts) { flib_scheme *result = flib_scheme_create(meta, parts[0]); if(result) { for(int i=0; imodCount; i++) { @@ -88,7 +88,7 @@ return result; } -flib_map *flib_netmsg_to_map(char **parts) { +flib_map *flib_map_from_netmsg(char **parts) { flib_map *result = flib_map_create_named(parts[3], parts[0]); if(result) { result->mapgen = atoi(parts[1]); @@ -98,7 +98,7 @@ return result; } -int flib_netmsg_to_drawnmapdata(char *netmsg, uint8_t** outbuf, size_t *outlen) { +int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t** outbuf, size_t *outlen) { int result = -1; // First step: base64 decoding diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/net/netprotocol.h --- a/project_files/frontlib/net/netprotocol.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/net/netprotocol.h Sun Aug 12 22:37:57 2012 +0200 @@ -27,8 +27,6 @@ #include -// TODO unify naming - /** * Create a new team from this 23-part net message */ @@ -38,12 +36,12 @@ * Create a new scheme from this net message, which must have * meta->modCount+meta->settingCount+1 parts. */ -flib_scheme *flib_netmsg_to_cfg(flib_metascheme *meta, char **parts); +flib_scheme *flib_scheme_from_netmsg(flib_metascheme *meta, char **parts); /** * Create a new map from this five-part netmsg */ -flib_map *flib_netmsg_to_map(char **parts); +flib_map *flib_map_from_netmsg(char **parts); /** * Decode the drawn map data from this netmessage line. @@ -53,7 +51,7 @@ * is written to the variable pointed to by outlen. * Returns NULL on error. */ -int flib_netmsg_to_drawnmapdata(char *netmsg, uint8_t **outbuf, size_t *outlen); +int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t **outbuf, size_t *outlen); /** * Create a new room from this 8-part net message diff -r c8c552ee3acb -r d70a5b0d1190 project_files/frontlib/util/logging.h --- a/project_files/frontlib/util/logging.h Sun Aug 12 22:21:09 2012 +0200 +++ b/project_files/frontlib/util/logging.h Sun Aug 12 22:37:57 2012 +0200 @@ -39,6 +39,7 @@ /** * Evaluates the expression cond. If it is true, a formatted error will be logged. * Returns true if an error is logged, false otherwise (i.e. the boolean value of the argument) + * Usage: log_e_if(errorHasHappened, "Format string", formatArg, ...); */ #define log_e_if(cond, ...) _flib_fassert(__func__, FLIB_LOGLEVEL_ERROR, !(bool)(cond), __VA_ARGS__) #define log_w_if(cond, ...) _flib_fassert(__func__, FLIB_LOGLEVEL_WARNING, !(bool)(cond), __VA_ARGS__) @@ -79,9 +80,21 @@ bool _flib_fassert(const char *func, int level, bool cond, const char *fmt, ...); void _flib_flog(const char *func, int level, const char *fmt, ...); -int flib_log_getLevel(); +/** + * Only log messages that are at least the indicated level + */ void flib_log_setLevel(int level); +int flib_log_getLevel(); + +/** + * Log to the indicated file. You can pass NULL to log to stdout. + * This overrides setCallback and vice versa. + */ void flib_log_setFile(FILE *logfile); + +/** + * Returns whether messages of this level are logged at the moment. + */ bool flib_log_isActive(int level); /**