project_files/frontlib/net/netconn.h
branchwebgl
changeset 8330 aaefa587e277
parent 8262 f01702bfb764
child 10015 4feced261c68
--- a/project_files/frontlib/net/netconn.h	Sun Dec 02 00:03:16 2012 +0100
+++ b/project_files/frontlib/net/netconn.h	Tue Dec 25 04:45:22 2012 +0100
@@ -1,654 +1,654 @@
-/*
- * 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 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 most of the functions behave the
- * same ingame as in a room.
- *
- * 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_
-
-#include "../model/gamesetup.h"
-#include "../model/scheme.h"
-#include "../model/room.h"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#define NETCONN_STATE_CONNECTING 0
-#define NETCONN_STATE_LOBBY 1
-#define NETCONN_STATE_ROOM 2
-#define NETCONN_STATE_DISCONNECTED 10
-
-#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			// 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			// 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
-#define NETCONN_MAPCHANGE_MAPGEN 2
-#define NETCONN_MAPCHANGE_DRAWNMAP 3
-#define NETCONN_MAPCHANGE_MAZE_SIZE 4
-#define NETCONN_MAPCHANGE_TEMPLATE 5
-#define NETCONN_MAPCHANGE_THEME 6
-#define NETCONN_MAPCHANGE_SEED 7
-
-typedef struct _flib_netconn flib_netconn;
-
-/**
- * Create a new netplay connection with these parameters.
- * The path to the data directory must end with a path delimiter (e.g. C:\Games\Hedgewars\Data\)
- */
-flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port);
-void flib_netconn_destroy(flib_netconn *conn);
-
-/**
- * Perform I/O operations and call callbacks if something interesting happens.
- * Should be called regularly.
- */
-void flib_netconn_tick(flib_netconn *conn);
-
-/**
- * Are you currently the owner of this room? The return value only makes sense in
- * NETCONN_STATE_ROOM and NETCONN_STATE_INGAME states.
- */
-bool flib_netconn_is_chief(flib_netconn *conn);
-
-/**
- * Returns the playername. This is *probably* the one provided on creation, but if that name was
- * already taken, a different one could have been set by the onNickTaken callback or its default
- * implementation.
- */
-const char *flib_netconn_get_playername(flib_netconn *conn);
-
-/**
- * Generate a game setup from the current room state.
- * Returns NULL if the room state does not contain enough information for a complete game setup,
- * or if an error occurs.
- *
- * The new gamesetup must be destroyed with flib_gamesetup_destroy().
- */
-flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn);
-
-
-
-
-// Send functions needed when connecting and disconnecting
-
-	/**
-	 * Request a different nickname.
-	 * This function only makes sense in reaction to an onNickTaken callback, because the netconn
-	 * automatically requests the nickname you provide on creation, and once the server accepts the
-	 * nickname it can no longer be changed.
-	 */
-	int flib_netconn_send_nick(flib_netconn *conn, const char *nick);
-
-	/**
-	 * 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);
-
-	/**
-	 * Tell the server that you want to leave. If successful, the server will disconnect you.
-	 */
-	int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg);
-
-
-// Send functions that make sense both in the lobby and in rooms
-
-	/**
-	 * Send a chat message. This message is either sent to the lobby or the room, depending on
-	 * whether you are in a room at the moment. The message is not echoed back to you.
-	 */
-	int flib_netconn_send_chat(flib_netconn *conn, const char *chat);
-
-	/**
-	 * 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);
-
-	/**
-	 * Request information about a player (e.g. current room, version, partial IP). If the action
-	 * succeeds, you will receive an onMessage callback with NETCONN_MSG_TYPE_PLAYERINFO containing
-	 * the requested information.
-	 */
-	int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName);
-
-
-// Send functions that only make sense in the lobby
-
-	/**
-	 * Request an update of the room list. Only makes sense when in lobby state.
-	 * If the action succeeds, you will receive an onRoomlist callback containing the current room
-	 * data.
-	 */
-	int flib_netconn_send_request_roomlist(flib_netconn *conn);
-
-	/**
-	 * Join a room as guest (not chief). Only makes sense when in lobby state. If the action
-	 * succeeds, you will receive an onEnterRoom callback with chief=false followed by other
-	 * callbacks with current room information.
-	 */
-	int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room);
-
-	/**
-	 * 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);
-
-	/**
-	 * Create and join a new room. Only makes sense when in lobby state. If the action succeeds,
-	 * you will receive an onEnterRoom callback with chief=true.
-	 */
-	int flib_netconn_send_createRoom(flib_netconn *conn, const char *room);
-
-	/**
-	 * Ban a player. The scope of this ban depends on whether you are in a room or in the lobby.
-	 * In a room, you need to be the room chief, and the ban will apply to the room only. In the
-	 * lobby, you need to be server admin to ban someone, and the ban applies to the entire server.
-	 */
-	int flib_netconn_send_ban(flib_netconn *conn, const char *playerName);
-
-	/**
-	 * 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 and
-	 * in the lobby. Known variables are MOTD_NEW, MOTD_OLD and LATEST_PROTO. MOTD_OLD is shown to
-	 * players with older protocol versions, to inform them that they might want to update.
-	 */
-	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 and in the lobby.
-	 * If the action succeeds, you will receive several onServerVar callbacks with the
-	 * current values of all server variables.
-	 */
-	int flib_netconn_send_getServerVars(flib_netconn *conn);
-
-
-// Send functions that only make sense in a room
-
-	/**
-	 * Leave the room for the lobby. Only makes sense in room state. msg can be NULL if you don't
-	 * want to send a message. The server always accepts a part command, so once you send it off,
-	 * you can just assume that you are back in the lobby.
-	 */
-	int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *msg);
-
-	/**
-	 * Change your "ready" status in the room. Only makes sense when in room state. If the action
-	 * succeeds, you will receive an onClientFlags callback containing the change.
-	 */
-	int flib_netconn_send_toggleReady(flib_netconn *conn);
-
-	/**
-	 * 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.
-	 *
-	 * Notes: Technically, sending a color here is the only way for a non-chief to set the color of
-	 * her own team. The server remembers this color and even generates a separate teamColor message
-	 * to inform everyone of it. However, at the moment the frontends generally override this color
-	 * with one they choose themselves in order to deal with unfortunate behavior of the QtFrontend,
-	 * which always sends color index 0 when adding a team but thinks that the team has a random
-	 * color. The chief always sends a new color in order to bring the QtFrontend back into sync.
-	 */
-	int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team);
-
-	/**
-	 * Remove the team with the name teamname. Only makes sense when in room state.
-	 * The server does not send a reply on success.
-	 */
-	int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname);
-
-
-// Send functions that only make sense in a room and if you are room chief
-
-	/**
-	 * Rename the current room. Only makes sense in room state and if you are chief. If the action
-	 * succeeds, you (and everyone else on the server) will receive an onRoomUpdate message
-	 * containing the change.
-	 */
-	int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName);
-
-	/**
-	 * Set the number of hogs for a team. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount);
-
-	/**
-	 * Set the teamcolor of a team. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex);
-
-	/**
-	 * Set the weaponset for the room. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset);
-
-	/**
-	 * Set the map for the room. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_map(flib_netconn *conn, const flib_map *map);
-
-	/**
-	 * Set the mapname. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName);
-
-	/**
-	 * Set the map generator (regular, maze, drawn, named). Only makes sense in room state and if
-	 * you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen);
-
-	/**
-	 * Set the map template for regular maps. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter);
-
-	/**
-	 * Set the maze template (maze size) for mazes. Only makes sense in room state and if you are
-	 * chief. The server does not send a reply.
-	 */
-	int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize);
-
-	/**
-	 * Set the seed for the map. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed);
-
-	/**
-	 * Set the theme for the map. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme);
-
-	/**
-	 * Set the draw data for the drawn map. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size);
-
-	/**
-	 * Set the script (game style). Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_script(flib_netconn *conn, const char *scriptName);
-
-	/**
-	 * Set the scheme. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme);
-
-	/**
-	 * Signal that you want to start the game. Only makes sense in room state and if you are chief.
-	 * 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);
-
-	/**
-	 * Allow/forbid players to join the room. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn);
-
-	/**
-	 * Allow/forbid adding teams to the room. Only makes sense in room state and if you are chief.
-	 * The server does not send a reply.
-	 */
-	int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn);
-
-
-// Send functions that are only needed for running a game
-
-	/**
-	 * Send a teamchat message, forwarded from the engine. Only makes sense ingame.
-	 * The server does not send a reply. In contrast to a Chat message, the server
-	 * automatically converts this into an engine message and passes it on to the other
-	 * clients.
-	 */
-	int flib_netconn_send_teamchat(flib_netconn *conn, const char *msg);
-
-	/**
-	 * Send an engine message. Only makes sense when ingame. In a networked game, you have to pass
-	 * all the engine messages from the engine here, and they will be spread to all other clients
-	 * in the game to keep the game in sync.
-	 */
-	int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size);
-
-	/**
-	 * Inform the server that the round has ended. Call this when the engine has disconnected,
-	 * passing 1 if the round ended normally, 0 otherwise.
-	 */
-	int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError);
-
-
-
-
-
-// Callbacks that are important for connecting/disconnecting
-
-	/**
-	 * onNickTaken is called when connecting to the server, if it turns out that there is already a
-	 * player with the same nick.
-	 * In order to proceed, a new nickname needs to be sent to the server using
-	 * flib_netconn_send_nick() (or of course you can bail out and send a QUIT).
-	 * If you don't set a callback, the netconn will automatically react by generating a new name.
-	 */
-	void flib_netconn_onNickTaken(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
-
-	/**
-	 * When connecting with a registered nickname, the server will ask for a password before
-	 * admitting you in. This callback is called when that happens. As a reaction, you can send the
-	 * password using flib_netconn_send_password. If you don't register a callback, the default
-	 * behavior is to just quit in a way that will cause a disconnect with
-	 * NETCONN_DISCONNECT_AUTH_FAILED.
-	 *
-	 * You can't just choose a new nickname when you receive this callback, because at that point
-	 * the server has already accepted your nick.
-	 */
-	void flib_netconn_onPasswordRequest(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
-
-	/**
-	 * This is called when the server has accepted our nickname (and possibly password) and we have
-	 * entered the lobby.
-	 */
-	void flib_netconn_onConnected(flib_netconn *conn, void (*callback)(void *context), void* context);
-
-	/**
-	 * This is always the last callback (unless the netconn is destroyed early), and the netconn
-	 * should be destroyed when it is received. The reason for the disconnect is passed as one of
-	 * the NETCONN_DISCONNECT_ constants. Sometimes a message is included as well, but that
-	 * parameter might also be NULL.
-	 */
-	void flib_netconn_onDisconnected(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void* context);
-
-
-// Callbacks that make sense in most situations
-
-	/**
-	 * Callback for several informational messages that should be displayed to the user
-	 * (e.g. in the chat window), but do not require a reaction. If a game is running, you might
-	 * want to redirect some of these messages to the engine as well so the user will see them.
-	 */
-	void flib_netconn_onMessage(flib_netconn *conn, void (*callback)(void *context, int msgtype, const char *msg), void* context);
-
-	/**
-	 * We received a chat message. Where this message belongs depends on the current state
-	 * (lobby/room). If a game is running the message should be passed to the engine.
-	 */
-	void flib_netconn_onChat(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *msg), void* context);
-
-	/**
-	 * Callbacks for incremental room list updates. They will fire whenever these events occur,
-	 * even before you first query the actual roomlist - so be sure not to blindly reference your
-	 * room list in these callbacks. The server currently only sends updates when a room changes
-	 * its name, so in order to update other room information you need to query the roomlist again
-	 * (see send_request_roomlist / onRoomlist).
-	 */
-	void flib_netconn_onRoomAdd(flib_netconn *conn, void (*callback)(void *context, const flib_room *room), void* context);
-	void flib_netconn_onRoomDelete(flib_netconn *conn, void (*callback)(void *context, const char *name), void* context);
-	void flib_netconn_onRoomUpdate(flib_netconn *conn, void (*callback)(void *context, const char *oldName, const flib_room *room), void* context);
-
-	/**
-	 * Callbacks for players joining or leaving the lobby. In contrast to the roomlist updates, you
-	 * will get a JOIN callback for every player already on the server when you join (and there is
-	 * no direct way to query the current playerlist)
-	 *
-	 * NOTE: partMessage may be NULL.
-	 */
-	void flib_netconn_onLobbyJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
-	void flib_netconn_onLobbyLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context);
-
-	/**
-	 * This is called when the server informs us that one or more flags associated with a
-	 * player/client have changed.
-	 *
-	 * nick is the name of the player, flags is a string containing one character for each modified
-	 * flag (see below), and newFlagState signals whether the flags should be set to true or false.
-	 *
-	 * Some of these flags are important for protocol purposes (especially if they are set for you)
-	 * while others are just informational. Also, some flags are only relevant for players who are
-	 * in the same room as you, and the server will not inform you if they change for others.
-	 *
-	 * These are the currently known/used flags:
-	 * a: Server admin. Always updated.
-	 * h: Room chief. Updated when in the same room.
-	 * r: Ready to play. Updated when in the same room.
-	 * u: Registered user. Always updated.
-	 *
-	 * The server tells us the 'a' and 'u' flags for all players when we first join the lobby, and
-	 * also tells us the 'r' and 'h' flags when we join or create a room. It assumes that all flags
-	 * are initially false, so it will typically only tell you to set certain flags to true when
-	 * transmitting the initial states. Reset the 'h' and 'r' flags to false when leaving a room,
-	 * or when entering room state, to arrive at the right state for each player.
-	 *
-	 * The room chief state of yourself is particularly important because it determines whether you
-	 * can modify settings of the current room. Generally, when you create a room you start out
-	 * being room chief, and when you join an existing room you are not. However, if the original
-	 * chief leaves a room, the server can choose a new chief, and if that happens the chief flag
-	 * will be transferred to someone else.
-	 */
-	void flib_netconn_onClientFlags(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *flags, bool newFlagState), void *context);
-
-// Callbacks that happen only in response to specific requests
-
-	/**
-	 * Response to flib_netconn_send_request_roomlist().
-	 * The rooms array contains the current state of all rooms on the server.
-	 */
-	void flib_netconn_onRoomlist(flib_netconn *conn, void (*callback)(void *context, const flib_room **rooms, int roomCount), void* context);
-
-	/**
-	 * Response to flib_netconn_send_joinRoom, flib_netconn_send_playerFollow or
-	 * flib_netconn_send_createRoom.
-	 *
-	 * You just left the lobby and entered a room.
-	 * If chief is true, you can and should send a full configuration for the room now. This
-	 * consists of ammo, scheme, script and map, where map apparently has to come last.
-	 */
-	void flib_netconn_onEnterRoom(flib_netconn *conn, void (*callback)(void *context, bool chief), void *context);
-
-	/**
-	 * Response to flib_netconn_send_addTeam.
-	 * The server might reject your team 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.
-	 */
-	void flib_netconn_onTeamAccepted(flib_netconn *conn, void (*callback)(void *context, const char *team), void *context);
-
-	/**
-	 * 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);
-
-
-// Callbacks that are only relevant in a room
-
-	/**
-	 * You just left a room and entered the lobby again.
-	 * reason is one of the NETCONN_ROOMLEAVE_ constants (usually a kick).
-	 * This will not be called when you actively leave a room using PART.
-	 * Don't confuse with onRoomLeave, which indicates that *someone else* left the room.
-	 */
-	void flib_netconn_onLeaveRoom(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void *context);
-
-	/**
-	 * Someone joined or left the room you are currently in.
-	 * Analogous to onLobbyJoin/leave, you will receive the join callback for all players that are
-	 * already in the room when you join, including for yourself (this is actually how it is
-	 * determined that you joined a room).
-	 *
-	 * However, you will *not* receive onRoomLeave messages for everyone when you leave the room.
-	 */
-	void flib_netconn_onRoomJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
-	void flib_netconn_onRoomLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context);
-
-	/**
-	 * 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 (but it is
-	 * assumed to be the default of 4).
-	 *
-	 * If you receive this message and you are the room chief, you may want to send a color and hog
-	 * count for this team using flib_netconn_send_teamHogCount / teamColor for QtFrontend
-	 * compatibility.
-	 *
-	 * The server currently sends another message with the color of the team to the same recipients
-	 * as this teamAdd message, which will trigger an onTeamColorChanged callback. See the
-	 * description of flib_netconn_send_addTeam for more information.
-	 */
-	void flib_netconn_onTeamAdd(flib_netconn *conn, void (*callback)(void *context, const flib_team *team), void *context);
-
-	/**
-	 * A team was removed from the room. The person who removed the team will not receive this
-	 * callback.
-	 */
-	void flib_netconn_onTeamDelete(flib_netconn *conn, void (*callback)(void *context, const char *teamname), 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, you will not receive this callback.
-	 */
-	void flib_netconn_onHogCountChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int hogs), void *context);
-
-	/**
-	 * The color of a team has been set or changed. The client who set or changed the color will
-	 * not receive this callback.
-	 *
-	 * Normally, only the chief can change the color of a team. However, this message is also
-	 * generated when a team is added, so you can receive it even as chief.
-	 */
-	void flib_netconn_onTeamColorChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int colorIndex), void *context);
-
-	/**
-	 * The room chief has changed the game scheme (or you just joined a room).
-	 * You will not receive this callback if you changed the scheme yourself.
-	 */
-	void flib_netconn_onSchemeChanged(flib_netconn *conn, void (*callback)(void *context, const flib_scheme *scheme), void *context);
-
-	/**
-	 * The room chief has changed the map (or you just joined a room). Only non-chiefs receive these
-	 * messages.
-	 *
-	 * To reduce the number of callback functions, the netconn keeps track of the current map
-	 * settings and always passes the entire current map config, but informs the callee about what
-	 * has changed (see the NETCONN_MAPCHANGE_ constants).
-	 *
-	 * Caution: Due to the way the protocol works, the map might not be complete at this point if it
-	 * is a hand-drawn map, because the "full" map config does not include the drawn map data.
-	 */
-	void flib_netconn_onMapChanged(flib_netconn *conn, void (*callback)(void *context, const flib_map *map, int changetype), void *context);
-
-	/**
-	 * The room chief has changed the game style (or you just joined a room). If you are the chief
-	 * and change the style yourself, you will not receive this callback.
-	 */
-	void flib_netconn_onScriptChanged(flib_netconn *conn, void (*callback)(void *context, const char *script), void *context);
-
-	/**
-	 * The room chief has changed the weaponset (or you just joined a room). If you are the chief
-	 * and change the weaponset yourself, you will not receive this callback.
-	 */
-	void flib_netconn_onWeaponsetChanged(flib_netconn *conn, void (*callback)(void *context, const flib_weaponset *weaponset), void *context);
-
-	/**
-	 * The game is starting. Fire up the engine and join in!
-	 * You can let the netconn generate the right game setup using flib_netconn_create_gamesetup
-	 */
-	void flib_netconn_onRunGame(flib_netconn *conn, void (*callback)(void *context), void *context);
-
-	/**
-	 * You are in a room, a game is in progress, and the server is sending you the new input for the
-	 * engine to keep up to date with the current happenings. Pass it on to the engine using
-	 * flib_gameconn_send_enginemsg.
-	 */
-	void flib_netconn_onEngineMessage(flib_netconn *conn, void (*callback)(void *context, const uint8_t *message, size_t size), void *context);
-
-#endif
+/*
+ * 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 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 most of the functions behave the
+ * same ingame as in a room.
+ *
+ * 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_
+
+#include "../model/gamesetup.h"
+#include "../model/scheme.h"
+#include "../model/room.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#define NETCONN_STATE_CONNECTING 0
+#define NETCONN_STATE_LOBBY 1
+#define NETCONN_STATE_ROOM 2
+#define NETCONN_STATE_DISCONNECTED 10
+
+#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           //!< 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           //!< 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
+#define NETCONN_MAPCHANGE_MAPGEN 2
+#define NETCONN_MAPCHANGE_DRAWNMAP 3
+#define NETCONN_MAPCHANGE_MAZE_SIZE 4
+#define NETCONN_MAPCHANGE_TEMPLATE 5
+#define NETCONN_MAPCHANGE_THEME 6
+#define NETCONN_MAPCHANGE_SEED 7
+
+typedef struct _flib_netconn flib_netconn;
+
+/**
+ * Create a new netplay connection with these parameters.
+ * The path to the data directory must end with a path delimiter (e.g. C:\Games\Hedgewars\Data\)
+ */
+flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port);
+void flib_netconn_destroy(flib_netconn *conn);
+
+/**
+ * Perform I/O operations and call callbacks if something interesting happens.
+ * Should be called regularly.
+ */
+void flib_netconn_tick(flib_netconn *conn);
+
+/**
+ * Are you currently the owner of this room? The return value only makes sense in
+ * NETCONN_STATE_ROOM and NETCONN_STATE_INGAME states.
+ */
+bool flib_netconn_is_chief(flib_netconn *conn);
+
+/**
+ * Returns the playername. This is *probably* the one provided on creation, but if that name was
+ * already taken, a different one could have been set by the onNickTaken callback or its default
+ * implementation.
+ */
+const char *flib_netconn_get_playername(flib_netconn *conn);
+
+/**
+ * Generate a game setup from the current room state.
+ * Returns NULL if the room state does not contain enough information for a complete game setup,
+ * or if an error occurs.
+ *
+ * The new gamesetup must be destroyed with flib_gamesetup_destroy().
+ */
+flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn);
+
+
+
+
+// Send functions needed when connecting and disconnecting
+
+    /**
+     * Request a different nickname.
+     * This function only makes sense in reaction to an onNickTaken callback, because the netconn
+     * automatically requests the nickname you provide on creation, and once the server accepts the
+     * nickname it can no longer be changed.
+     */
+    int flib_netconn_send_nick(flib_netconn *conn, const char *nick);
+
+    /**
+     * 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);
+
+    /**
+     * Tell the server that you want to leave. If successful, the server will disconnect you.
+     */
+    int flib_netconn_send_quit(flib_netconn *conn, const char *quitmsg);
+
+
+// Send functions that make sense both in the lobby and in rooms
+
+    /**
+     * Send a chat message. This message is either sent to the lobby or the room, depending on
+     * whether you are in a room at the moment. The message is not echoed back to you.
+     */
+    int flib_netconn_send_chat(flib_netconn *conn, const char *chat);
+
+    /**
+     * 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);
+
+    /**
+     * Request information about a player (e.g. current room, version, partial IP). If the action
+     * succeeds, you will receive an onMessage callback with NETCONN_MSG_TYPE_PLAYERINFO containing
+     * the requested information.
+     */
+    int flib_netconn_send_playerInfo(flib_netconn *conn, const char *playerName);
+
+
+// Send functions that only make sense in the lobby
+
+    /**
+     * Request an update of the room list. Only makes sense when in lobby state.
+     * If the action succeeds, you will receive an onRoomlist callback containing the current room
+     * data.
+     */
+    int flib_netconn_send_request_roomlist(flib_netconn *conn);
+
+    /**
+     * Join a room as guest (not chief). Only makes sense when in lobby state. If the action
+     * succeeds, you will receive an onEnterRoom callback with chief=false followed by other
+     * callbacks with current room information.
+     */
+    int flib_netconn_send_joinRoom(flib_netconn *conn, const char *room);
+
+    /**
+     * 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);
+
+    /**
+     * Create and join a new room. Only makes sense when in lobby state. If the action succeeds,
+     * you will receive an onEnterRoom callback with chief=true.
+     */
+    int flib_netconn_send_createRoom(flib_netconn *conn, const char *room);
+
+    /**
+     * Ban a player. The scope of this ban depends on whether you are in a room or in the lobby.
+     * In a room, you need to be the room chief, and the ban will apply to the room only. In the
+     * lobby, you need to be server admin to ban someone, and the ban applies to the entire server.
+     */
+    int flib_netconn_send_ban(flib_netconn *conn, const char *playerName);
+
+    /**
+     * 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 and
+     * in the lobby. Known variables are MOTD_NEW, MOTD_OLD and LATEST_PROTO. MOTD_OLD is shown to
+     * players with older protocol versions, to inform them that they might want to update.
+     */
+    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 and in the lobby.
+     * If the action succeeds, you will receive several onServerVar callbacks with the
+     * current values of all server variables.
+     */
+    int flib_netconn_send_getServerVars(flib_netconn *conn);
+
+
+// Send functions that only make sense in a room
+
+    /**
+     * Leave the room for the lobby. Only makes sense in room state. msg can be NULL if you don't
+     * want to send a message. The server always accepts a part command, so once you send it off,
+     * you can just assume that you are back in the lobby.
+     */
+    int flib_netconn_send_leaveRoom(flib_netconn *conn, const char *msg);
+
+    /**
+     * Change your "ready" status in the room. Only makes sense when in room state. If the action
+     * succeeds, you will receive an onClientFlags callback containing the change.
+     */
+    int flib_netconn_send_toggleReady(flib_netconn *conn);
+
+    /**
+     * 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.
+     *
+     * Notes: Technically, sending a color here is the only way for a non-chief to set the color of
+     * her own team. The server remembers this color and even generates a separate teamColor message
+     * to inform everyone of it. However, at the moment the frontends generally override this color
+     * with one they choose themselves in order to deal with unfortunate behavior of the QtFrontend,
+     * which always sends color index 0 when adding a team but thinks that the team has a random
+     * color. The chief always sends a new color in order to bring the QtFrontend back into sync.
+     */
+    int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team);
+
+    /**
+     * Remove the team with the name teamname. Only makes sense when in room state.
+     * The server does not send a reply on success.
+     */
+    int flib_netconn_send_removeTeam(flib_netconn *conn, const char *teamname);
+
+
+// Send functions that only make sense in a room and if you are room chief
+
+    /**
+     * Rename the current room. Only makes sense in room state and if you are chief. If the action
+     * succeeds, you (and everyone else on the server) will receive an onRoomUpdate message
+     * containing the change.
+     */
+    int flib_netconn_send_renameRoom(flib_netconn *conn, const char *roomName);
+
+    /**
+     * Set the number of hogs for a team. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount);
+
+    /**
+     * Set the teamcolor of a team. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex);
+
+    /**
+     * Set the weaponset for the room. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset);
+
+    /**
+     * Set the map for the room. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_map(flib_netconn *conn, const flib_map *map);
+
+    /**
+     * Set the mapname. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName);
+
+    /**
+     * Set the map generator (regular, maze, drawn, named). Only makes sense in room state and if
+     * you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen);
+
+    /**
+     * Set the map template for regular maps. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter);
+
+    /**
+     * Set the maze template (maze size) for mazes. Only makes sense in room state and if you are
+     * chief. The server does not send a reply.
+     */
+    int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize);
+
+    /**
+     * Set the seed for the map. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed);
+
+    /**
+     * Set the theme for the map. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme);
+
+    /**
+     * Set the draw data for the drawn map. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size);
+
+    /**
+     * Set the script (game style). Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_script(flib_netconn *conn, const char *scriptName);
+
+    /**
+     * Set the scheme. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme);
+
+    /**
+     * Signal that you want to start the game. Only makes sense in room state and if you are chief.
+     * 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);
+
+    /**
+     * Allow/forbid players to join the room. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_toggleRestrictJoins(flib_netconn *conn);
+
+    /**
+     * Allow/forbid adding teams to the room. Only makes sense in room state and if you are chief.
+     * The server does not send a reply.
+     */
+    int flib_netconn_send_toggleRestrictTeams(flib_netconn *conn);
+
+
+// Send functions that are only needed for running a game
+
+    /**
+     * Send a teamchat message, forwarded from the engine. Only makes sense ingame.
+     * The server does not send a reply. In contrast to a Chat message, the server
+     * automatically converts this into an engine message and passes it on to the other
+     * clients.
+     */
+    int flib_netconn_send_teamchat(flib_netconn *conn, const char *msg);
+
+    /**
+     * Send an engine message. Only makes sense when ingame. In a networked game, you have to pass
+     * all the engine messages from the engine here, and they will be spread to all other clients
+     * in the game to keep the game in sync.
+     */
+    int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size);
+
+    /**
+     * Inform the server that the round has ended. Call this when the engine has disconnected,
+     * passing 1 if the round ended normally, 0 otherwise.
+     */
+    int flib_netconn_send_roundfinished(flib_netconn *conn, bool withoutError);
+
+
+
+
+
+// Callbacks that are important for connecting/disconnecting
+
+    /**
+     * onNickTaken is called when connecting to the server, if it turns out that there is already a
+     * player with the same nick.
+     * In order to proceed, a new nickname needs to be sent to the server using
+     * flib_netconn_send_nick() (or of course you can bail out and send a QUIT).
+     * If you don't set a callback, the netconn will automatically react by generating a new name.
+     */
+    void flib_netconn_onNickTaken(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+
+    /**
+     * When connecting with a registered nickname, the server will ask for a password before
+     * admitting you in. This callback is called when that happens. As a reaction, you can send the
+     * password using flib_netconn_send_password. If you don't register a callback, the default
+     * behavior is to just quit in a way that will cause a disconnect with
+     * NETCONN_DISCONNECT_AUTH_FAILED.
+     *
+     * You can't just choose a new nickname when you receive this callback, because at that point
+     * the server has already accepted your nick.
+     */
+    void flib_netconn_onPasswordRequest(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+
+    /**
+     * This is called when the server has accepted our nickname (and possibly password) and we have
+     * entered the lobby.
+     */
+    void flib_netconn_onConnected(flib_netconn *conn, void (*callback)(void *context), void* context);
+
+    /**
+     * This is always the last callback (unless the netconn is destroyed early), and the netconn
+     * should be destroyed when it is received. The reason for the disconnect is passed as one of
+     * the NETCONN_DISCONNECT_ constants. Sometimes a message is included as well, but that
+     * parameter might also be NULL.
+     */
+    void flib_netconn_onDisconnected(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void* context);
+
+
+// Callbacks that make sense in most situations
+
+    /**
+     * Callback for several informational messages that should be displayed to the user
+     * (e.g. in the chat window), but do not require a reaction. If a game is running, you might
+     * want to redirect some of these messages to the engine as well so the user will see them.
+     */
+    void flib_netconn_onMessage(flib_netconn *conn, void (*callback)(void *context, int msgtype, const char *msg), void* context);
+
+    /**
+     * We received a chat message. Where this message belongs depends on the current state
+     * (lobby/room). If a game is running the message should be passed to the engine.
+     */
+    void flib_netconn_onChat(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *msg), void* context);
+
+    /**
+     * Callbacks for incremental room list updates. They will fire whenever these events occur,
+     * even before you first query the actual roomlist - so be sure not to blindly reference your
+     * room list in these callbacks. The server currently only sends updates when a room changes
+     * its name, so in order to update other room information you need to query the roomlist again
+     * (see send_request_roomlist / onRoomlist).
+     */
+    void flib_netconn_onRoomAdd(flib_netconn *conn, void (*callback)(void *context, const flib_room *room), void* context);
+    void flib_netconn_onRoomDelete(flib_netconn *conn, void (*callback)(void *context, const char *name), void* context);
+    void flib_netconn_onRoomUpdate(flib_netconn *conn, void (*callback)(void *context, const char *oldName, const flib_room *room), void* context);
+
+    /**
+     * Callbacks for players joining or leaving the lobby. In contrast to the roomlist updates, you
+     * will get a JOIN callback for every player already on the server when you join (and there is
+     * no direct way to query the current playerlist)
+     *
+     * NOTE: partMessage may be NULL.
+     */
+    void flib_netconn_onLobbyJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+    void flib_netconn_onLobbyLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context);
+
+    /**
+     * This is called when the server informs us that one or more flags associated with a
+     * player/client have changed.
+     *
+     * nick is the name of the player, flags is a string containing one character for each modified
+     * flag (see below), and newFlagState signals whether the flags should be set to true or false.
+     *
+     * Some of these flags are important for protocol purposes (especially if they are set for you)
+     * while others are just informational. Also, some flags are only relevant for players who are
+     * in the same room as you, and the server will not inform you if they change for others.
+     *
+     * These are the currently known/used flags:
+     * a: Server admin. Always updated.
+     * h: Room chief. Updated when in the same room.
+     * r: Ready to play. Updated when in the same room.
+     * u: Registered user. Always updated.
+     *
+     * The server tells us the 'a' and 'u' flags for all players when we first join the lobby, and
+     * also tells us the 'r' and 'h' flags when we join or create a room. It assumes that all flags
+     * are initially false, so it will typically only tell you to set certain flags to true when
+     * transmitting the initial states. Reset the 'h' and 'r' flags to false when leaving a room,
+     * or when entering room state, to arrive at the right state for each player.
+     *
+     * The room chief state of yourself is particularly important because it determines whether you
+     * can modify settings of the current room. Generally, when you create a room you start out
+     * being room chief, and when you join an existing room you are not. However, if the original
+     * chief leaves a room, the server can choose a new chief, and if that happens the chief flag
+     * will be transferred to someone else.
+     */
+    void flib_netconn_onClientFlags(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *flags, bool newFlagState), void *context);
+
+// Callbacks that happen only in response to specific requests
+
+    /**
+     * Response to flib_netconn_send_request_roomlist().
+     * The rooms array contains the current state of all rooms on the server.
+     */
+    void flib_netconn_onRoomlist(flib_netconn *conn, void (*callback)(void *context, const flib_room **rooms, int roomCount), void* context);
+
+    /**
+     * Response to flib_netconn_send_joinRoom, flib_netconn_send_playerFollow or
+     * flib_netconn_send_createRoom.
+     *
+     * You just left the lobby and entered a room.
+     * If chief is true, you can and should send a full configuration for the room now. This
+     * consists of ammo, scheme, script and map, where map apparently has to come last.
+     */
+    void flib_netconn_onEnterRoom(flib_netconn *conn, void (*callback)(void *context, bool chief), void *context);
+
+    /**
+     * Response to flib_netconn_send_addTeam.
+     * The server might reject your team 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.
+     */
+    void flib_netconn_onTeamAccepted(flib_netconn *conn, void (*callback)(void *context, const char *team), void *context);
+
+    /**
+     * 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);
+
+
+// Callbacks that are only relevant in a room
+
+    /**
+     * You just left a room and entered the lobby again.
+     * reason is one of the NETCONN_ROOMLEAVE_ constants (usually a kick).
+     * This will not be called when you actively leave a room using PART.
+     * Don't confuse with onRoomLeave, which indicates that *someone else* left the room.
+     */
+    void flib_netconn_onLeaveRoom(flib_netconn *conn, void (*callback)(void *context, int reason, const char *message), void *context);
+
+    /**
+     * Someone joined or left the room you are currently in.
+     * Analogous to onLobbyJoin/leave, you will receive the join callback for all players that are
+     * already in the room when you join, including for yourself (this is actually how it is
+     * determined that you joined a room).
+     *
+     * However, you will *not* receive onRoomLeave messages for everyone when you leave the room.
+     */
+    void flib_netconn_onRoomJoin(flib_netconn *conn, void (*callback)(void *context, const char *nick), void* context);
+    void flib_netconn_onRoomLeave(flib_netconn *conn, void (*callback)(void *context, const char *nick, const char *partMessage), void* context);
+
+    /**
+     * 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 (but it is
+     * assumed to be the default of 4).
+     *
+     * If you receive this message and you are the room chief, you may want to send a color and hog
+     * count for this team using flib_netconn_send_teamHogCount / teamColor for QtFrontend
+     * compatibility.
+     *
+     * The server currently sends another message with the color of the team to the same recipients
+     * as this teamAdd message, which will trigger an onTeamColorChanged callback. See the
+     * description of flib_netconn_send_addTeam for more information.
+     */
+    void flib_netconn_onTeamAdd(flib_netconn *conn, void (*callback)(void *context, const flib_team *team), void *context);
+
+    /**
+     * A team was removed from the room. The person who removed the team will not receive this
+     * callback.
+     */
+    void flib_netconn_onTeamDelete(flib_netconn *conn, void (*callback)(void *context, const char *teamname), 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, you will not receive this callback.
+     */
+    void flib_netconn_onHogCountChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int hogs), void *context);
+
+    /**
+     * The color of a team has been set or changed. The client who set or changed the color will
+     * not receive this callback.
+     *
+     * Normally, only the chief can change the color of a team. However, this message is also
+     * generated when a team is added, so you can receive it even as chief.
+     */
+    void flib_netconn_onTeamColorChanged(flib_netconn *conn, void (*callback)(void *context, const char *teamName, int colorIndex), void *context);
+
+    /**
+     * The room chief has changed the game scheme (or you just joined a room).
+     * You will not receive this callback if you changed the scheme yourself.
+     */
+    void flib_netconn_onSchemeChanged(flib_netconn *conn, void (*callback)(void *context, const flib_scheme *scheme), void *context);
+
+    /**
+     * The room chief has changed the map (or you just joined a room). Only non-chiefs receive these
+     * messages.
+     *
+     * To reduce the number of callback functions, the netconn keeps track of the current map
+     * settings and always passes the entire current map config, but informs the callee about what
+     * has changed (see the NETCONN_MAPCHANGE_ constants).
+     *
+     * Caution: Due to the way the protocol works, the map might not be complete at this point if it
+     * is a hand-drawn map, because the "full" map config does not include the drawn map data.
+     */
+    void flib_netconn_onMapChanged(flib_netconn *conn, void (*callback)(void *context, const flib_map *map, int changetype), void *context);
+
+    /**
+     * The room chief has changed the game style (or you just joined a room). If you are the chief
+     * and change the style yourself, you will not receive this callback.
+     */
+    void flib_netconn_onScriptChanged(flib_netconn *conn, void (*callback)(void *context, const char *script), void *context);
+
+    /**
+     * The room chief has changed the weaponset (or you just joined a room). If you are the chief
+     * and change the weaponset yourself, you will not receive this callback.
+     */
+    void flib_netconn_onWeaponsetChanged(flib_netconn *conn, void (*callback)(void *context, const flib_weaponset *weaponset), void *context);
+
+    /**
+     * The game is starting. Fire up the engine and join in!
+     * You can let the netconn generate the right game setup using flib_netconn_create_gamesetup
+     */
+    void flib_netconn_onRunGame(flib_netconn *conn, void (*callback)(void *context), void *context);
+
+    /**
+     * You are in a room, a game is in progress, and the server is sending you the new input for the
+     * engine to keep up to date with the current happenings. Pass it on to the engine using
+     * flib_gameconn_send_enginemsg.
+     */
+    void flib_netconn_onEngineMessage(flib_netconn *conn, void (*callback)(void *context, const uint8_t *message, size_t size), void *context);
+
+#endif