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
--- 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
--- /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 <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.
+ */
+
+/*
+ * 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);
--- 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.
--- 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
--- 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 <stdint.h>
#include <stdbool.h>
+/*
+ * 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
--- 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; offset<map->drawDataSize; offset+=200) {
- int bytesRemaining = map->drawDataSize-offset;
+ for(size_t offset=0; offset<map->drawDataSize; 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);
--- 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_ */
--- 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)
--- 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)) {
--- 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;
--- 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 <stdlib.h>
-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);
}
}
--- 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
--- 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);
}
}
--- 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 <stdbool.h>
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.
--- 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; i<schemeCount; i++) {
flib_scheme *scheme = readSchemeFromIni(meta, ini, i);
if(!scheme || flib_schemelist_insert(list, scheme, i)) {
- flib_scheme_release(scheme);
+ flib_scheme_destroy(scheme);
flib_log_e("Error reading scheme %i from config file %s.", i, filename);
return fromIniHandleError(list, ini);
}
- flib_scheme_release(scheme);
}
@@ -130,7 +130,7 @@
return list;
}
-static int writeSchemeToIni(flib_scheme *scheme, flib_ini *ini, int index) {
+static int writeSchemeToIni(const flib_scheme *scheme, flib_ini *ini, int index) {
flib_metascheme *meta = scheme->meta;
bool error = false;
@@ -179,7 +179,7 @@
void flib_schemelist_destroy(flib_schemelist *list) {
if(list) {
for(int i=0; i<list->schemeCount; 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;
}
}
--- 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);
--- 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;
/**
--- 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;
--- 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 && color<flib_teamcolor_defaults_len) {
+ if(sscanf(netmsg->parts[2], "%lu", &color) && color>=0 && color<flib_teamcolor_count) {
flib_team *team = flib_teamlist_find(&conn->teamlist, netmsg->parts[1]);
if(team) {
team->colorIndex = color;
--- 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);
--- 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));
--- 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);
--- 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) {
--- 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; i<meta->modCount; 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
--- 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 <stddef.h>
-// 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
--- 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);
/**