frontlib:
authorMedo <smaxein@googlemail.com>
Wed, 15 Aug 2012 23:40:10 +0200
changeset 7497 7e1d72fc03c7
parent 7494 e65adfc99f15
child 7500 6253cae96f21
frontlib: - Removed metascheme-reading and made metascheme a constant instead - Removed reference counting in favor of copying (less confusion about ownership)
project_files/frontlib/Android.mk
project_files/frontlib/extra/jnacontrol.c
project_files/frontlib/hwconsts.c
project_files/frontlib/hwconsts.h
project_files/frontlib/ipc/ipcprotocol.c
project_files/frontlib/model/gamesetup.c
project_files/frontlib/model/gamesetup.h
project_files/frontlib/model/map.c
project_files/frontlib/model/mapcfg.c
project_files/frontlib/model/scheme.c
project_files/frontlib/model/scheme.h
project_files/frontlib/model/schemelist.c
project_files/frontlib/model/schemelist.h
project_files/frontlib/model/team.c
project_files/frontlib/model/team.h
project_files/frontlib/model/weapon.c
project_files/frontlib/model/weapon.h
project_files/frontlib/net/netbase.c
project_files/frontlib/net/netbase.h
project_files/frontlib/net/netconn.c
project_files/frontlib/net/netconn.h
project_files/frontlib/net/netconn_internal.h
project_files/frontlib/net/netconn_send.c
project_files/frontlib/net/netprotocol.c
project_files/frontlib/net/netprotocol.h
project_files/frontlib/resources/metasettings.ini
project_files/frontlib/util/refcounter.c
project_files/frontlib/util/refcounter.h
--- a/project_files/frontlib/Android.mk	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/Android.mk	Wed Aug 15 23:40:10 2012 +0200
@@ -13,8 +13,8 @@
 	model/schemelist.c model/team.c model/teamlist.c model/weapon.c \
 	net/netbase.c net/netconn_callbacks.c net/netconn_send.c \
 	net/netconn.c net/netprotocol.c util/buffer.c util/inihelper.c \
-	util/logging.c util/refcounter.c util/util.c frontlib.c \
-	hwconsts.c socket.c extra/jnacontrol.c
+	util/logging.c util/util.c frontlib.c hwconsts.c socket.c \
+	extra/jnacontrol.c
 
 LOCAL_SHARED_LIBRARIES += SDL_net
 LOCAL_LDLIBS += -lz
--- a/project_files/frontlib/extra/jnacontrol.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/extra/jnacontrol.c	Wed Aug 15 23:40:10 2012 +0200
@@ -101,8 +101,13 @@
 int flib_init();
 void flib_quit();
 
+// hwconsts.h
+int flib_get_teamcolor_count();
+int flib_get_hedgehogs_per_team();
+int flib_get_weapons_count();
+
 // net/netconn.h
-NetconnPtr flib_netconn_create(String playerName, MetaschemePtr meta, String dataDirPath, String host, int port);
+NetconnPtr flib_netconn_create(String playerName, String dataDirPath, String host, int port);
 void flib_netconn_destroy(NetconnPtr conn);
 
 void flib_netconn_tick(NetconnPtr conn);
@@ -122,7 +127,6 @@
 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);
@@ -133,7 +137,6 @@
 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);
@@ -190,7 +193,6 @@
 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);
@@ -210,13 +212,10 @@
 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);
+MetaschemePtr flib_get_metascheme();
 
 // model/schemelist.h
-SchemelistPtr flib_schemelist_from_ini(MetaschemePtr meta, String filename);
+SchemelistPtr flib_schemelist_from_ini(String filename);
 int flib_schemelist_to_ini(String filename, SchemelistPtr list);
 void flib_schemelist_destroy(SchemelistPtr list);
 
@@ -230,6 +229,9 @@
 int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets);
 void flib_weaponsetlist_destroy(WeaponsetListPtr list);
 
+// model/gamesetup.h
+void flib_gamesetup_destroy(GameSetupPtr gamesetup);
+
 // util/logging.h
 void flib_log_setLevel(int level);
 void flib_log_setCallback(LogCallback callback);
--- a/project_files/frontlib/hwconsts.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/hwconsts.c	Wed Aug 15 23:40:10 2012 +0200
@@ -22,6 +22,58 @@
 const uint32_t flib_teamcolors[] = HW_TEAMCOLOR_ARRAY;
 const size_t flib_teamcolor_count = sizeof(flib_teamcolors)/sizeof(uint32_t)-1;
 
+static const flib_metascheme_setting metaSchemeSettings[] = {
+	{ .name = "damagefactor",      .times1000 = false, .engineCommand = "e$damagepct",   .maxMeansInfinity = false, .min = 10, .max = 300,  .def = 100 },
+	{ .name = "turntime",          .times1000 = true,  .engineCommand = "e$turntime",    .maxMeansInfinity = true,  .min = 1,  .max = 9999, .def = 45  },
+	{ .name = "health",            .times1000 = false, .engineCommand = NULL,            .maxMeansInfinity = false, .min = 50, .max = 200,  .def = 100 },
+	{ .name = "suddendeath",       .times1000 = false, .engineCommand = "e$sd_turns",    .maxMeansInfinity = true,  .min = 0,  .max = 50,   .def = 15  },
+	{ .name = "caseprobability",   .times1000 = false, .engineCommand = "e$casefreq",    .maxMeansInfinity = false, .min = 0,  .max = 9,    .def = 5   },
+	{ .name = "minestime",         .times1000 = true,  .engineCommand = "e$minestime",   .maxMeansInfinity = false, .min = -1, .max = 5,    .def = 3   },
+	{ .name = "minesnum",          .times1000 = false, .engineCommand = "e$minesnum",    .maxMeansInfinity = false, .min = 0,  .max = 80,   .def = 4   },
+	{ .name = "minedudpct",        .times1000 = false, .engineCommand = "e$minedudpct",  .maxMeansInfinity = false, .min = 0,  .max = 100,  .def = 0   },
+	{ .name = "explosives",        .times1000 = false, .engineCommand = "e$explosives",  .maxMeansInfinity = false, .min = 0,  .max = 40,   .def = 2   },
+	{ .name = "healthprobability", .times1000 = false, .engineCommand = "e$healthprob",  .maxMeansInfinity = false, .min = 0,  .max = 100,  .def = 35  },
+	{ .name = "healthcaseamount",  .times1000 = false, .engineCommand = "e$hcaseamount", .maxMeansInfinity = false, .min = 0,  .max = 200,  .def = 25  },
+	{ .name = "waterrise",         .times1000 = false, .engineCommand = "e$waterrise",   .maxMeansInfinity = false, .min = 0,  .max = 100,  .def = 47  },
+	{ .name = "healthdecrease",    .times1000 = false, .engineCommand = "e$healthdec",   .maxMeansInfinity = false, .min = 0,  .max = 100,  .def = 5   },
+	{ .name = "ropepct",           .times1000 = false, .engineCommand = "e$ropepct",     .maxMeansInfinity = false, .min = 25, .max = 999,  .def = 100 },
+	{ .name = "getawaytime",       .times1000 = false, .engineCommand = "e$getawaytime", .maxMeansInfinity = false, .min = 0,  .max = 999,  .def = 100 }
+};
+
+static const flib_metascheme_mod metaSchemeMods[] = {
+	{ .name = "fortsmode",          .bitmaskIndex = 12 },
+	{ .name = "divteams",           .bitmaskIndex = 4  },
+	{ .name = "solidland",          .bitmaskIndex = 2  },
+	{ .name = "border",             .bitmaskIndex = 3  },
+	{ .name = "lowgrav",            .bitmaskIndex = 5  },
+	{ .name = "laser",              .bitmaskIndex = 6  },
+	{ .name = "invulnerability",    .bitmaskIndex = 7  },
+	{ .name = "resethealth",        .bitmaskIndex = 8  },
+	{ .name = "vampiric",           .bitmaskIndex = 9  },
+	{ .name = "karma",              .bitmaskIndex = 10 },
+	{ .name = "artillery",          .bitmaskIndex = 11 },
+	{ .name = "randomorder",        .bitmaskIndex = 13 },
+	{ .name = "king",               .bitmaskIndex = 14 },
+	{ .name = "placehog",           .bitmaskIndex = 15 },
+	{ .name = "sharedammo",         .bitmaskIndex = 16 },
+	{ .name = "disablegirders",     .bitmaskIndex = 17 },
+	{ .name = "disablelandobjects", .bitmaskIndex = 18 },
+	{ .name = "aisurvival",         .bitmaskIndex = 19 },
+	{ .name = "infattack",          .bitmaskIndex = 20 },
+	{ .name = "resetweps",          .bitmaskIndex = 21 },
+	{ .name = "perhogammo",         .bitmaskIndex = 22 },
+	{ .name = "disablewind",        .bitmaskIndex = 23 },
+	{ .name = "morewind",           .bitmaskIndex = 24 },
+	{ .name = "tagteam",            .bitmaskIndex = 25 },
+	{ .name = "bottomborder",       .bitmaskIndex = 26 }
+};
+
+const flib_metascheme flib_meta = {
+	.settingCount = sizeof(metaSchemeSettings)/sizeof(flib_metascheme_setting),
+	.modCount = sizeof(metaSchemeMods)/sizeof(flib_metascheme_mod),
+	.settings = metaSchemeSettings,
+	.mods = metaSchemeMods
+};
 
 uint32_t flib_get_teamcolor(int colorIndex) {
 	if(colorIndex>=0 && colorIndex < flib_teamcolor_count) {
@@ -42,3 +94,7 @@
 int flib_get_weapons_count() {
 	return WEAPONS_COUNT;
 }
+
+const flib_metascheme *flib_get_metascheme() {
+	return &flib_meta;
+}
--- a/project_files/frontlib/hwconsts.h	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/hwconsts.h	Wed Aug 15 23:40:10 2012 +0200
@@ -31,6 +31,7 @@
 
 #include <inttypes.h>
 #include <stddef.h>
+#include <stdbool.h>
 
 #define HEDGEHOGS_PER_TEAM 8
 #define NETGAME_DEFAULT_PORT 46631
@@ -78,4 +79,36 @@
  */
 int flib_get_weapons_count();
 
+/*
+ * These structs define the meaning of values in the flib_scheme struct, i.e. their correspondence to
+ * ini settings, engine commands and positions in the network protocol (the last is encoded in the
+ * order of settings/mods).
+ */
+typedef struct {
+    const char *name;				// A name identifying this setting (used as key in the schemes file)
+    const 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)
+    const bool maxMeansInfinity;	// If true, send a very high number to the engine if the setting is equal to its maximum
+    const bool times1000;			// If true (for time-based settings), multiply the setting by 1000 before sending it to the engine.
+    const int min;					// The smallest allowed value
+    const int max;					// The highest allowed value
+    const int def;					// The default value
+} flib_metascheme_setting;
+
+typedef struct {
+    const char *name;				// A name identifying this mod (used as key in the schemes file)
+    const 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;
+
+typedef struct {
+	const int settingCount;
+	const int modCount;
+	const flib_metascheme_setting *settings;
+	const flib_metascheme_mod *mods;
+} flib_metascheme;
+
+extern const flib_metascheme flib_meta;
+
+const flib_metascheme *flib_get_metascheme();
+
 #endif
--- a/project_files/frontlib/ipc/ipcprotocol.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/ipc/ipcprotocol.c	Wed Aug 15 23:40:10 2012 +0200
@@ -142,9 +142,9 @@
 
 static uint32_t buildModFlags(const flib_scheme *scheme) {
 	uint32_t result = 0;
-	for(int i=0; i<scheme->meta->modCount; i++) {
+	for(int i=0; i<flib_meta.modCount; i++) {
 		if(scheme->mods[i]) {
-			int bitmaskIndex = scheme->meta->mods[i].bitmaskIndex;
+			int bitmaskIndex = flib_meta.mods[i].bitmaskIndex;
 			result |= (UINT32_C(1) << bitmaskIndex);
 		}
 	}
@@ -155,19 +155,18 @@
 	int result = -1;
 	flib_vector *tempvector = flib_vector_create();
 	if(!log_badargs_if2(vec==NULL, scheme==NULL) && tempvector) {
-		const flib_metascheme *meta = scheme->meta;
 		bool error = false;
 		error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, buildModFlags(scheme));
-		for(int i=0; i<meta->settingCount; i++) {
-			if(meta->settings[i].engineCommand) {
+		for(int i=0; i<flib_meta.settingCount; i++) {
+			if(flib_meta.settings[i].engineCommand) {
 				int value = scheme->settings[i];
-				if(meta->settings[i].maxMeansInfinity) {
-					value = value>=meta->settings[i].max ? 9999 : value;
+				if(flib_meta.settings[i].maxMeansInfinity) {
+					value = value>=flib_meta.settings[i].max ? 9999 : value;
 				}
-				if(meta->settings[i].times1000) {
+				if(flib_meta.settings[i].times1000) {
 					value *= 1000;
 				}
-				error |= flib_ipc_append_message(tempvector, "%s %i", meta->settings[i].engineCommand, value);
+				error |= flib_ipc_append_message(tempvector, "%s %i", flib_meta.settings[i].engineCommand, value);
 			}
 		}
 
--- a/project_files/frontlib/model/gamesetup.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/gamesetup.c	Wed Aug 15 23:40:10 2012 +0200
@@ -32,7 +32,7 @@
 	}
 }
 
-flib_gamesetup *flib_gamesetup_copy(flib_gamesetup *setup) {
+flib_gamesetup *flib_gamesetup_copy(const flib_gamesetup *setup) {
 	if(!setup) {
 		return NULL;
 	}
--- a/project_files/frontlib/model/gamesetup.h	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/gamesetup.h	Wed Aug 15 23:40:10 2012 +0200
@@ -40,9 +40,8 @@
 void flib_gamesetup_destroy(flib_gamesetup *gamesetup);
 
 /**
- * Deep-copy of the flib_gamesetup. Copies everything except the weaponsets
- * of the hogs; those are kept as references.
+ * Deep-copy of the flib_gamesetup.
  */
-flib_gamesetup *flib_gamesetup_copy(flib_gamesetup *gamesetup);
+flib_gamesetup *flib_gamesetup_copy(const flib_gamesetup *gamesetup);
 
 #endif
--- a/project_files/frontlib/model/map.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/map.c	Wed Aug 15 23:40:10 2012 +0200
@@ -22,7 +22,6 @@
 #include "../util/inihelper.h"
 #include "../util/util.h"
 #include "../util/logging.h"
-#include "../util/refcounter.h"
 
 #include <stdlib.h>
 
--- a/project_files/frontlib/model/mapcfg.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/mapcfg.c	Wed Aug 15 23:40:10 2012 +0200
@@ -46,11 +46,13 @@
 				if(!log_e_if(!fgets(out->theme, sizeof(out->theme), file), "Error reading theme from %s", path)) {
 					removeNewline(out->theme);
 					char buf[64];
-					if(!log_e_if(!fgets(buf, sizeof(buf), file), "Error reading hoglimit from %s", path)) {
+					if(fgets(buf, sizeof(buf), file)) {
 						removeNewline(buf);
 						errno = 0;
 						out->hogLimit = strtol(buf, NULL, 10);
 						result = !log_e_if(errno, "Invalid hoglimit in %s: %i", path, buf);
+					} else {
+						result = 0;
 					}
 				}
 				fclose(file);
--- a/project_files/frontlib/model/scheme.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/scheme.c	Wed Aug 15 23:40:10 2012 +0200
@@ -22,157 +22,29 @@
 #include "../util/inihelper.h"
 #include "../util/logging.h"
 #include "../util/util.h"
-#include "../util/refcounter.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <limits.h>
 #include <string.h>
 
-static void flib_metascheme_destroy(flib_metascheme *meta) {
-	if(meta) {
-		if(meta->settings) {
-			for(int i=0; i<meta->settingCount; i++) {
-				free(meta->settings[i].name);
-				free(meta->settings[i].engineCommand);
-			}
-			free(meta->settings);
-		}
-		if(meta->mods) {
-			for(int i=0; i<meta->modCount; i++) {
-				free(meta->mods[i].name);
-			}
-			free(meta->mods);
-		}
-		free(meta);
-	}
-}
-
-static flib_metascheme *flib_metascheme_from_ini_handleError(flib_metascheme *result, flib_ini *ini) {
-	flib_metascheme_destroy(result);
-	flib_ini_destroy(ini);
-	return NULL;
-}
-
-static int readMetaSettingSections(flib_ini *ini, flib_metascheme *result, int limit) {
-	while(result->settingCount<limit) {
-		char sectionName[32];
-		if(snprintf(sectionName, sizeof(sectionName), "setting%i", result->settingCount) <= 0) {
-			return -1;
-		}
-		if(!flib_ini_enter_section(ini, sectionName)) {
-			flib_metascheme_setting *metasetting = &result->settings[result->settingCount];
-			result->settingCount++;
-
-			bool error = false;
-			error |= flib_ini_get_str(ini, &metasetting->name, "name");
-			error |= flib_ini_get_str_opt(ini, &metasetting->engineCommand, "command", NULL);
-			error |= flib_ini_get_bool(ini, &metasetting->times1000, "times1000");
-			error |= flib_ini_get_bool(ini, &metasetting->maxMeansInfinity, "maxmeansinfinity");
-			error |= flib_ini_get_int(ini, &metasetting->min, "min");
-			error |= flib_ini_get_int(ini, &metasetting->max, "max");
-			error |= flib_ini_get_int(ini, &metasetting->def, "default");
-			if(error) {
-				flib_log_e("Missing or malformed ini parameter in metaconfig, section %s", sectionName);
-				return -1;
-			}
-		} else {
-			return 0;
-		}
-	}
-	return 0;
-}
-
-static int readMetaModSections(flib_ini *ini, flib_metascheme *result, int limit) {
-	while(result->modCount<limit) {
-		char sectionName[32];
-		if(snprintf(sectionName, sizeof(sectionName), "mod%i", result->modCount) <= 0) {
-			return -1;
-		}
-		if(!flib_ini_enter_section(ini, sectionName)) {
-			flib_metascheme_mod *metamod = &result->mods[result->modCount];
-			result->modCount++;
-
-			bool error = false;
-			error |= flib_ini_get_str(ini, &metamod->name, "name");
-			error |= flib_ini_get_int(ini, &metamod->bitmaskIndex, "bitmaskIndex");
-			if(error) {
-				flib_log_e("Missing or malformed ini parameter in metaconfig, section %s", sectionName);
-				return -1;
-			}
-		} else {
-			return 0;
-		}
-	}
-	return 0;
-}
-
-flib_metascheme *flib_metascheme_from_ini(const char *filename) {
-	if(log_badargs_if(filename==NULL)) {
-		return NULL;
-	}
-	flib_metascheme *result = flib_metascheme_retain(flib_calloc(1, sizeof(flib_metascheme)));
-	flib_ini *ini = flib_ini_load(filename);
-
-	if(!result || !ini) {
-		return flib_metascheme_from_ini_handleError(result, ini);
-	}
-
-	// We're overallocating here for simplicity
-	int sectionCount = flib_ini_get_sectioncount(ini);
-	result->settingCount = 0;
-	result->modCount = 0;
-	result->settings = flib_calloc(sectionCount, sizeof(flib_metascheme_setting));
-	result->mods = flib_calloc(sectionCount, sizeof(flib_metascheme_mod));
-
-	if(!result->settings || !result->mods) {
-		return flib_metascheme_from_ini_handleError(result, ini);
-	}
-
-	if(readMetaSettingSections(ini, result, sectionCount) || readMetaModSections(ini, result, sectionCount)) {
-		return flib_metascheme_from_ini_handleError(result, ini);
-	}
-
-	if(result->settingCount+result->modCount != sectionCount) {
-		flib_log_e("Unknown or non-contiguous sections headers in metaconfig.");
-		return flib_metascheme_from_ini_handleError(result, ini);
-	}
-
-	flib_ini_destroy(ini);
-	return result;
-}
-
-flib_metascheme *flib_metascheme_retain(flib_metascheme *metainfo) {
-	if(metainfo) {
-		flib_retain(&metainfo->_referenceCount, "flib_metascheme");
-	}
-	return metainfo;
-}
-
-void flib_metascheme_release(flib_metascheme *meta) {
-	if(meta && flib_release(&meta->_referenceCount, "flib_metascheme")) {
-		flib_metascheme_destroy(meta);
-	}
-}
-
-flib_scheme *flib_scheme_create(flib_metascheme *meta, const char *schemeName) {
+flib_scheme *flib_scheme_create(const char *schemeName) {
 	flib_scheme *result = flib_calloc(1, sizeof(flib_scheme));
-	if(log_badargs_if2(meta==NULL, schemeName==NULL) || result==NULL) {
+	if(log_badargs_if(schemeName==NULL) || result==NULL) {
 		return NULL;
 	}
 
-	result->meta = flib_metascheme_retain(meta);
 	result->name = flib_strdupnull(schemeName);
-	result->mods = flib_calloc(meta->modCount, sizeof(*result->mods));
-	result->settings = flib_calloc(meta->settingCount, sizeof(*result->settings));
+	result->mods = flib_calloc(flib_meta.modCount, sizeof(*result->mods));
+	result->settings = flib_calloc(flib_meta.settingCount, sizeof(*result->settings));
 
 	if(!result->mods || !result->settings || !result->name) {
 		flib_scheme_destroy(result);
 		return NULL;
 	}
 
-	for(int i=0; i<meta->settingCount; i++) {
-		result->settings[i] = meta->settings[i].def;
+	for(int i=0; i<flib_meta.settingCount; i++) {
+		result->settings[i] = flib_meta.settings[i].def;
 	}
 	return result;
 }
@@ -180,10 +52,10 @@
 flib_scheme *flib_scheme_copy(const flib_scheme *scheme) {
 	flib_scheme *result = NULL;
 	if(scheme) {
-		result = flib_scheme_create(scheme->meta, scheme->name);
+		result = flib_scheme_create(scheme->name);
 		if(result) {
-			memcpy(result->mods, scheme->mods, scheme->meta->modCount * sizeof(*scheme->mods));
-			memcpy(result->settings, scheme->settings, scheme->meta->settingCount * sizeof(*scheme->settings));
+			memcpy(result->mods, scheme->mods, flib_meta.modCount * sizeof(*scheme->mods));
+			memcpy(result->settings, scheme->settings, flib_meta.settingCount * sizeof(*scheme->settings));
 		}
 	}
 	return result;
@@ -191,7 +63,6 @@
 
 void flib_scheme_destroy(flib_scheme* scheme) {
 	if(scheme) {
-		flib_metascheme_release(scheme->meta);
 		free(scheme->mods);
 		free(scheme->settings);
 		free(scheme->name);
@@ -199,10 +70,10 @@
 	}
 }
 
-bool flib_scheme_get_mod(flib_scheme *scheme, const char *name) {
+bool flib_scheme_get_mod(const flib_scheme *scheme, const char *name) {
 	if(!log_badargs_if2(scheme==NULL, name==NULL)) {
-		for(int i=0; i<scheme->meta->modCount; i++) {
-			if(!strcmp(scheme->meta->mods[i].name, name)) {
+		for(int i=0; i<flib_meta.modCount; i++) {
+			if(!strcmp(flib_meta.mods[i].name, name)) {
 				return scheme->mods[i];
 			}
 		}
@@ -211,10 +82,10 @@
 	return false;
 }
 
-int flib_scheme_get_setting(flib_scheme *scheme, const char *name, int def) {
+int flib_scheme_get_setting(const flib_scheme *scheme, const char *name, int def) {
 	if(!log_badargs_if2(scheme==NULL, name==NULL)) {
-		for(int i=0; i<scheme->meta->settingCount; i++) {
-			if(!strcmp(scheme->meta->settings[i].name, name)) {
+		for(int i=0; i<flib_meta.settingCount; i++) {
+			if(!strcmp(flib_meta.settings[i].name, name)) {
 				return scheme->settings[i];
 			}
 		}
--- a/project_files/frontlib/model/scheme.h	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/scheme.h	Wed Aug 15 23:40:10 2012 +0200
@@ -21,79 +21,33 @@
  * 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.
+ * described in a "metascheme", which describes how each setting and mod is sent to the
+ * engine, and in which order they appear in the network protocol. The metascheme is defined
+ * in hwconsts.h
  */
 
 #ifndef SCHEME_H_
 #define SCHEME_H_
 
 #include <stdbool.h>
-
-typedef struct {
-    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;				// 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;
-
-/**
- * The order of the meta information in the arrays is the same as the order
- * of the mod/setting information in the net protocol messages.
- */
-typedef struct {
-	int _referenceCount;
-	int settingCount;
-	int modCount;
-	flib_metascheme_setting *settings;
-	flib_metascheme_mod *mods;
-} flib_metascheme;
+#include <stddef.h>
+#include "../hwconsts.h"
 
 /**
  * The settings and mods arrays have the same number and order of elements
  * as the corresponding arrays in the metascheme.
  */
 typedef struct {
-	flib_metascheme *meta;
-
     char *name;
     int *settings;
     bool *mods;
 } flib_scheme;
 
 /**
- * Read the meta-configuration from a .ini file (e.g. which settings exist,
- * what are their defaults etc.)
- *
- * Returns the meta-configuration or NULL.
- */
-flib_metascheme *flib_metascheme_from_ini(const char *filename);
-
-/**
- * Increase the reference count of the object. Call this if you store a pointer to it somewhere.
- * Returns the parameter.
- */
-flib_metascheme *flib_metascheme_retain(flib_metascheme *metainfo);
-
-/**
- * Decrease the reference count of the object and free it if this was the last reference.
- */
-void flib_metascheme_release(flib_metascheme *metainfo);
-
-/**
  * Create a new configuration with everything set to default or false
  * Returns NULL on error.
  */
-flib_scheme *flib_scheme_create(flib_metascheme *meta, const char *schemeName);
+flib_scheme *flib_scheme_create(const char *schemeName);
 
 /**
  * Create a copy of the scheme. Returns NULL on error or if NULL was passed.
@@ -108,11 +62,11 @@
 /**
  * Retrieve a mod setting by its name. If the mod is not found, logs an error and returns false.
  */
-bool flib_scheme_get_mod(flib_scheme *scheme, const char *name);
+bool flib_scheme_get_mod(const flib_scheme *scheme, const char *name);
 
 /**
  * Retrieve a game setting by its name. If the setting is not found, logs an error and returns def.
  */
-int flib_scheme_get_setting(flib_scheme *scheme, const char *name, int def);
+int flib_scheme_get_setting(const flib_scheme *scheme, const char *name, int def);
 
 #endif /* SCHEME_H_ */
--- a/project_files/frontlib/model/schemelist.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/schemelist.c	Wed Aug 15 23:40:10 2012 +0200
@@ -22,7 +22,6 @@
 #include "../util/inihelper.h"
 #include "../util/logging.h"
 #include "../util/util.h"
-#include "../util/refcounter.h"
 #include "../util/list.h"
 
 #include <stdio.h>
@@ -35,13 +34,12 @@
 }
 
 static int readSettingsFromIni(flib_ini *ini, flib_scheme *scheme, int index) {
-	flib_metascheme *meta = scheme->meta;
 	bool error = false;
-	for(int i=0; i<meta->settingCount && !error; i++) {
-		char *key = makePrefixedName(index, meta->settings[i].name);
+	for(int i=0; i<flib_meta.settingCount && !error; i++) {
+		char *key = makePrefixedName(index, flib_meta.settings[i].name);
 		if(!key) {
 			error = true;
-		} else if(flib_ini_get_int_opt(ini, &scheme->settings[i], key, meta->settings[i].def)) {
+		} else if(flib_ini_get_int_opt(ini, &scheme->settings[i], key, flib_meta.settings[i].def)) {
 			flib_log_e("Error reading setting %s in schemes file.", key);
 			error = true;
 		}
@@ -51,10 +49,9 @@
 }
 
 static int readModsFromIni(flib_ini *ini, flib_scheme *scheme, int index) {
-	flib_metascheme *meta = scheme->meta;
 	bool error = false;
-	for(int i=0; i<meta->modCount && !error; i++) {
-		char *key = makePrefixedName(index, meta->mods[i].name);
+	for(int i=0; i<flib_meta.modCount && !error; i++) {
+		char *key = makePrefixedName(index, flib_meta.mods[i].name);
 		if(!key) {
 			error = true;
 		} else if(flib_ini_get_bool_opt(ini, &scheme->mods[i], key, false)) {
@@ -66,13 +63,13 @@
 	return error;
 }
 
-static flib_scheme *readSchemeFromIni(flib_metascheme *meta, flib_ini *ini, int index) {
+static flib_scheme *readSchemeFromIni(flib_ini *ini, int index) {
 	flib_scheme *result = NULL;
 	char *schemeNameKey = makePrefixedName(index+1, "name");
 	if(schemeNameKey) {
 		char *schemeName = NULL;
 		if(!flib_ini_get_str_opt(ini, &schemeName, schemeNameKey, "Unnamed")) {
-			flib_scheme *tmpScheme = flib_scheme_create(meta, schemeName);
+			flib_scheme *tmpScheme = flib_scheme_create(schemeName);
 			if(tmpScheme) {
 				if(!readSettingsFromIni(ini, tmpScheme, index) && !readModsFromIni(ini, tmpScheme, index)) {
 					result = tmpScheme;
@@ -93,8 +90,8 @@
 	return NULL;
 }
 
-flib_schemelist *flib_schemelist_from_ini(flib_metascheme *meta, const char *filename) {
-	if(log_badargs_if2(meta==NULL, filename==NULL)) {
+flib_schemelist *flib_schemelist_from_ini(const char *filename) {
+	if(log_badargs_if(filename==NULL)) {
 		return NULL;
 	}
 
@@ -117,7 +114,7 @@
 	}
 
 	for(int i=0; i<schemeCount; i++) {
-		flib_scheme *scheme = readSchemeFromIni(meta, ini, i);
+		flib_scheme *scheme = readSchemeFromIni(ini, i);
 		if(!scheme || flib_schemelist_insert(list, scheme, i)) {
 			flib_scheme_destroy(scheme);
 			flib_log_e("Error reading scheme %i from config file %s.", i, filename);
@@ -131,21 +128,20 @@
 }
 
 static int writeSchemeToIni(const flib_scheme *scheme, flib_ini *ini, int index) {
-	flib_metascheme *meta = scheme->meta;
 	bool error = false;
 
 	char *key = makePrefixedName(index+1, "name");
 	error |= !key || flib_ini_set_str(ini, key, scheme->name);
 	free(key);
 
-	for(int i=0; i<meta->modCount && !error; i++) {
-		char *key = makePrefixedName(index+1, meta->mods[i].name);
+	for(int i=0; i<flib_meta.modCount && !error; i++) {
+		char *key = makePrefixedName(index+1, flib_meta.mods[i].name);
 		error |= !key || flib_ini_set_bool(ini, key, scheme->mods[i]);
 		free(key);
 	}
 
-	for(int i=0; i<meta->settingCount && !error; i++) {
-		char *key = makePrefixedName(index+1, meta->settings[i].name);
+	for(int i=0; i<flib_meta.settingCount && !error; i++) {
+		char *key = makePrefixedName(index+1, flib_meta.settings[i].name);
 		error |= !key || flib_ini_set_int(ini, key, scheme->settings[i]);
 		free(key);
 	}
--- a/project_files/frontlib/model/schemelist.h	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/schemelist.h	Wed Aug 15 23:40:10 2012 +0200
@@ -37,7 +37,7 @@
  * Load a list of configurations from the ini file.
  * Returns NULL on error.
  */
-flib_schemelist *flib_schemelist_from_ini(flib_metascheme *meta, const char *filename);
+flib_schemelist *flib_schemelist_from_ini(const char *filename);
 
 /**
  * Store the list of configurations to an ini file.
--- a/project_files/frontlib/model/team.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/team.c	Wed Aug 15 23:40:10 2012 +0200
@@ -22,7 +22,6 @@
 #include "../util/inihelper.h"
 #include "../util/util.h"
 #include "../util/logging.h"
-#include "../util/refcounter.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -135,7 +134,7 @@
 		for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
 			free(team->hogs[i].name);
 			free(team->hogs[i].hat);
-			flib_weaponset_release(team->hogs[i].weaponset);
+			flib_weaponset_destroy(team->hogs[i].weaponset);
 		}
 		free(team->name);
 		free(team->grave);
@@ -234,13 +233,17 @@
 	return result;
 }
 
-void flib_team_set_weaponset(flib_team *team, flib_weaponset *set) {
+int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set) {
 	if(team) {
 		for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
-			flib_weaponset_release(team->hogs[i].weaponset);
-			team->hogs[i].weaponset = flib_weaponset_retain(set);
+			flib_weaponset_destroy(team->hogs[i].weaponset);
+			team->hogs[i].weaponset = flib_weaponset_copy(set);
+			if(set && !team->hogs[i].weaponset) {
+				return -1;
+			}
 		}
 	}
+	return 0;
 }
 
 void flib_team_set_health(flib_team *team, int health) {
@@ -275,7 +278,10 @@
 				tmpTeam->hogs[i].suicides = team->hogs[i].suicides;
 				tmpTeam->hogs[i].difficulty = team->hogs[i].difficulty;
 				tmpTeam->hogs[i].initialHealth = team->hogs[i].initialHealth;
-				tmpTeam->hogs[i].weaponset = flib_weaponset_retain(team->hogs[i].weaponset);
+				tmpTeam->hogs[i].weaponset = flib_weaponset_copy(team->hogs[i].weaponset);
+				if(team->hogs[i].weaponset && !tmpTeam->hogs[i].weaponset) {
+					error = true;
+				}
 			}
 
 			tmpTeam->name = strdupWithError(team->name, &error);
--- a/project_files/frontlib/model/team.h	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/team.h	Wed Aug 15 23:40:10 2012 +0200
@@ -115,7 +115,7 @@
 /**
  * Set the same weaponset for every hog in the team
  */
-void flib_team_set_weaponset(flib_team *team, flib_weaponset *set);
+int flib_team_set_weaponset(flib_team *team, const flib_weaponset *set);
 
 /**
  * Set the same initial health for every hog.
@@ -124,8 +124,6 @@
 
 /**
  * Create a deep copy of a team. Returns NULL on failure.
- * The referenced weaponsets are not copied, so the new
- * team references the same weaponsets.
  */
 flib_team *flib_team_copy(const flib_team *team);
 
--- a/project_files/frontlib/model/weapon.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/weapon.c	Wed Aug 15 23:40:10 2012 +0200
@@ -22,20 +22,12 @@
 #include "../util/inihelper.h"
 #include "../util/logging.h"
 #include "../util/util.h"
-#include "../util/refcounter.h"
 #include "../util/list.h"
 
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
 
-static void flib_weaponset_destroy(flib_weaponset *cfg) {
-	if(cfg) {
-		free(cfg->name);
-		free(cfg);
-	}
-}
-
 static void setField(char field[WEAPONS_COUNT+1], const char *line, int lineLen, bool no9) {
 	if(lineLen>WEAPONS_COUNT) {
 		lineLen = WEAPONS_COUNT;
@@ -60,7 +52,7 @@
 flib_weaponset *flib_weaponset_create(const char *name) {
 	flib_weaponset *result = NULL;
 	if(!log_badargs_if(name==NULL)) {
-		flib_weaponset *newSet = flib_weaponset_retain(flib_calloc(1, sizeof(flib_weaponset)));
+		flib_weaponset *newSet = flib_calloc(1, sizeof(flib_weaponset));
 		if(newSet) {
 			newSet->name = flib_strdupnull(name);
 			if(newSet->name) {
@@ -68,24 +60,19 @@
 				setField(newSet->crateprob, "", 0, false);
 				setField(newSet->crateammo, "", 0, false);
 				setField(newSet->delay, "", 0, false);
-				result = flib_weaponset_retain(newSet);
+				result = newSet;
+				newSet = NULL;
 			}
 		}
-		flib_weaponset_release(newSet);
+		flib_weaponset_destroy(newSet);
 	}
 	return result;
 }
 
-flib_weaponset *flib_weaponset_retain(flib_weaponset *weaponset) {
-	if(weaponset) {
-		flib_retain(&weaponset->_referenceCount, "flib_weaponset");
-	}
-	return weaponset;
-}
-
-void flib_weaponset_release(flib_weaponset *weaponset) {
-	if(weaponset && flib_release(&weaponset->_referenceCount, "flib_weaponset")) {
-		flib_weaponset_destroy(weaponset);
+void flib_weaponset_destroy(flib_weaponset *cfg) {
+	if(cfg) {
+		free(cfg->name);
+		free(cfg);
 	}
 }
 
@@ -108,7 +95,7 @@
 void flib_weaponsetlist_destroy(flib_weaponsetlist *list) {
 	if(list) {
 		for(int i=0; i<list->weaponsetCount; i++) {
-			flib_weaponset_release(list->weaponsets[i]);
+			flib_weaponset_destroy(list->weaponsets[i]);
 		}
 		free(list->weaponsets);
 		free(list);
@@ -139,8 +126,10 @@
 		flib_weaponset *set = flib_weaponset_from_ammostring(decodedKeyname, ammostring);
 		if(set) {
 			result = flib_weaponsetlist_insert(list, set, list->weaponsetCount);
+			if(result) {
+				flib_weaponset_destroy(set);
+			}
 		}
-		flib_weaponset_release(set);
 	}
 	free(ammostring);
 	free(decodedKeyname);
@@ -228,7 +217,6 @@
 int flib_weaponsetlist_insert(flib_weaponsetlist *list, flib_weaponset *set, int pos) {
 	if(!log_badargs_if2(list==NULL, set==NULL)
 			&& !insertWeaponset(&list->weaponsets, &list->weaponsetCount, set, pos)) {
-		flib_weaponset_retain(set);
 		return 0;
 	}
 	return -1;
@@ -238,7 +226,7 @@
 	if(!log_badargs_if(list==NULL)) {
 		flib_weaponset *elem = list->weaponsets[pos];
 		if(!deleteWeaponset(&list->weaponsets, &list->weaponsetCount, pos)) {
-			flib_weaponset_release(elem);
+			flib_weaponset_destroy(elem);
 			return 0;
 		}
 	}
--- a/project_files/frontlib/model/weapon.h	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/model/weapon.h	Wed Aug 15 23:40:10 2012 +0200
@@ -28,10 +28,8 @@
  *
  * For loadout, 9 means inifinite ammo.
  * For the other setting, 9 is invalid.
- * TODO stop reference counting, it complects everything
  */
 typedef struct {
-	int _referenceCount;
 	char loadout[WEAPONS_COUNT+1];
 	char crateprob[WEAPONS_COUNT+1];
 	char crateammo[WEAPONS_COUNT+1];
@@ -54,15 +52,9 @@
 flib_weaponset *flib_weaponset_create(const char *name);
 
 /**
- * Increase the reference count of the object. Call this if you store a pointer to it somewhere.
- * Returns the parameter.
+ * Free the memory used by this weaponset
  */
-flib_weaponset *flib_weaponset_retain(flib_weaponset *weaponset);
-
-/**
- * Decrease the reference count of the object and free it if this was the last reference.
- */
-void flib_weaponset_release(flib_weaponset *weaponset);
+void flib_weaponset_destroy(flib_weaponset *weaponset);
 
 flib_weaponset *flib_weaponset_copy(const flib_weaponset *weaponset);
 
@@ -97,14 +89,14 @@
 /**
  * Insert a new weaponset into the list at position pos, moving all higher weaponsets to make place.
  * pos must be at least 0 (insert at the start) and at most list->weaponsetCount (insert at the end).
- * The weaponset is retained automatically.
+ * Ownership of the weaponset is transferred to the list.
  * Returns 0 on success.
  */
 int flib_weaponsetlist_insert(flib_weaponsetlist *list, flib_weaponset *weaponset, int pos);
 
 /**
  * Delete a weaponset from the list at position pos, moving down all higher weaponsets.
- * The weaponset is released automatically.
+ * The weaponset is destroyed.
  * Returns 0 on success.
  */
 int flib_weaponsetlist_delete(flib_weaponsetlist *list, int pos);
--- a/project_files/frontlib/net/netbase.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/net/netbase.c	Wed Aug 15 23:40:10 2012 +0200
@@ -178,7 +178,7 @@
 	}
 }
 
-int flib_netbase_send_message(flib_netbase *net, flib_netmsg *msg) {
+int flib_netbase_send_message(flib_netbase *net, const flib_netmsg *msg) {
 	if(log_badargs_if2(net==NULL, msg==NULL)) {
 		return -1;
 	}
--- a/project_files/frontlib/net/netbase.h	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/net/netbase.h	Wed Aug 15 23:40:10 2012 +0200
@@ -73,7 +73,7 @@
  *
  * Returns a negative value on failure.
  */
-int flib_netbase_send_message(flib_netbase *net, flib_netmsg *msg);
+int flib_netbase_send_message(flib_netbase *net, const flib_netmsg *msg);
 
 /**
  * Send a message printf-style.
--- a/project_files/frontlib/net/netconn.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/net/netconn.c	Wed Aug 15 23:40:10 2012 +0200
@@ -31,9 +31,9 @@
 #include <errno.h>
 #include <ctype.h>
 
-flib_netconn *flib_netconn_create(const char *playerName, flib_metascheme *metacfg, const char *dataDirPath, const char *host, int port) {
+flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port) {
 	flib_netconn *result = NULL;
-	if(!log_badargs_if5(playerName==NULL, metacfg==NULL, host==NULL, port<1, port>65535)) {
+	if(!log_badargs_if4(playerName==NULL, host==NULL, port<1, port>65535)) {
 		flib_netconn *newConn = flib_calloc(1, sizeof(flib_netconn));
 		if(newConn) {
 			newConn->netBase = flib_netbase_create(host, port);
@@ -42,7 +42,6 @@
 
 			newConn->netconnState = NETCONN_STATE_CONNECTING;
 			newConn->isAdmin = false;
-			newConn->metaCfg = flib_metascheme_retain(metacfg);
 
 			newConn->isChief = false;
 			newConn->map = flib_map_create_named("", "NoSuchMap");
@@ -82,14 +81,12 @@
 			free(conn->playerName);
 			free(conn->dataDirPath);
 
-			flib_metascheme_release(conn->metaCfg);
-
 			flib_map_destroy(conn->map);
 			flib_teamlist_clear(&conn->pendingTeamlist);
 			flib_teamlist_clear(&conn->teamlist);
 			flib_scheme_destroy(conn->scheme);
 			free(conn->style);
-			flib_weaponset_release(conn->weaponset);
+			flib_weaponset_destroy(conn->weaponset);
 
 			free(conn);
 		}
@@ -121,7 +118,7 @@
 	conn->scheme = NULL;
 	free(conn->style);
 	conn->style = NULL;
-	flib_weaponset_release(conn->weaponset);
+	flib_weaponset_destroy(conn->weaponset);
 	conn->weaponset = NULL;
 }
 
@@ -136,7 +133,7 @@
 void netconn_setWeaponset(flib_netconn *conn, const flib_weaponset *weaponset) {
 	flib_weaponset *copy = flib_weaponset_copy(weaponset);
 	if(copy) {
-		flib_weaponset_release(conn->weaponset);
+		flib_weaponset_destroy(conn->weaponset);
 		conn->weaponset = copy;
 	}
 }
@@ -168,21 +165,31 @@
 			stackSetup.map = conn->map;
 			stackSetup.style = conn->style;
 			stackSetup.teamlist = &conn->teamlist;
-			flib_gamesetup *tmpSetup = flib_gamesetup_copy(&stackSetup);
-			if(tmpSetup) {
-				for(int i=0; i<tmpSetup->teamlist->teamCount; i++) {
-					flib_team_set_weaponset(tmpSetup->teamlist->teams[i], conn->weaponset);
-					flib_team_set_health(tmpSetup->teamlist->teams[i], flib_scheme_get_setting(conn->scheme, "health", 100));
+			result = flib_gamesetup_copy(&stackSetup);
+			if(result) {
+				bool error = false;
+				for(int i=0; i<result->teamlist->teamCount; i++) {
+					if(flib_team_set_weaponset(result->teamlist->teams[i], conn->weaponset)) {
+						error = true;
+					}
+					flib_team_set_health(result->teamlist->teams[i], flib_scheme_get_setting(conn->scheme, "health", 100));
 				}
-				if(tmpSetup->map->mapgen == MAPGEN_NAMED && tmpSetup->map->name) {
+				if(result->map->mapgen == MAPGEN_NAMED && result->map->name) {
 					flib_mapcfg mapcfg;
-					if(!flib_mapcfg_read(conn->dataDirPath, tmpSetup->map->name, &mapcfg)) {
-						free(tmpSetup->map->theme);
-						tmpSetup->map->theme = flib_strdupnull(mapcfg.theme);
+					if(!flib_mapcfg_read(conn->dataDirPath, result->map->name, &mapcfg)) {
+						free(result->map->theme);
+						result->map->theme = flib_strdupnull(mapcfg.theme);
+						if(!result->map->theme) {
+							error = true;
+						}
 					} else {
-						flib_log_e("Unable to read map config for map %s", tmpSetup->map->name);
+						flib_log_e("Unable to read map config for map %s", result->map->name);
 					}
 				}
+				if(error) {
+					flib_gamesetup_destroy(result);
+					result = NULL;
+				}
 			}
 		}
 	}
@@ -439,8 +446,8 @@
 	            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_scheme_from_netmsg(conn->metaCfg, netmsg->parts+2);
+				if(!strcmp(subcmd, "SCHEME") && netmsg->partCount == flib_meta.modCount + flib_meta.settingCount + 3) {
+					flib_scheme *cfg = flib_scheme_from_netmsg(netmsg->parts+2);
 					if(cfg) {
 						flib_scheme_destroy(conn->scheme);
 						conn->scheme = cfg;
@@ -510,12 +517,12 @@
 				} else if(!strcmp(subcmd, "AMMO") && netmsg->partCount == 4) {
 					flib_weaponset *weapons = flib_weaponset_from_ammostring(netmsg->parts[2], netmsg->parts[3]);
 					if(weapons) {
-						netconn_setWeaponset(conn, weapons);
+						flib_weaponset_destroy(conn->weaponset);
+						conn->weaponset = weapons;
 						conn->onWeaponsetChangedCb(conn->onWeaponsetChangedCtx, weapons);
 					} else {
 						flib_log_e("Error processing CFG AMMO message");
 					}
-					flib_weaponset_release(weapons);
 				} else {
 					flib_log_w("Net: Unknown or malformed CFG subcommand: %s", subcmd);
 				}
--- a/project_files/frontlib/net/netconn.h	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/net/netconn.h	Wed Aug 15 23:40:10 2012 +0200
@@ -92,14 +92,14 @@
 #define NETCONN_MAPCHANGE_THEME 6
 #define NETCONN_MAPCHANGE_SEED 7
 
-// TODO: Order of functions, and match the order in netconn.c
+// TODO: Order these functions, and match the order in netconn.c
 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, flib_metascheme *metacfg, const char *dataDirPath, const char *host, int port);
+flib_netconn *flib_netconn_create(const char *playerName, const char *dataDirPath, const char *host, int port);
 void flib_netconn_destroy(flib_netconn *conn);
 
 /**
--- a/project_files/frontlib/net/netconn_internal.h	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/net/netconn_internal.h	Wed Aug 15 23:40:10 2012 +0200
@@ -43,8 +43,6 @@
 	int netconnState;			// One of the NETCONN_STATE constants
 	bool isAdmin;				// Player is server administrator
 
-	flib_metascheme *metaCfg;
-
 	bool isChief;				// Player can modify the current room
 	flib_map *map;
 	flib_teamlist pendingTeamlist;
--- a/project_files/frontlib/net/netconn_send.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/net/netconn_send.c	Wed Aug 15 23:40:10 2012 +0200
@@ -242,11 +242,11 @@
 		strcat(ammostring, weaponset->crateprob);
 		strcat(ammostring, weaponset->delay);
 		strcat(ammostring, weaponset->crateammo);
-		if(!flib_netbase_sendf(conn->netBase, "CFG\nAMMO\n%s\n%s\n\n", weaponset->name, ammostring)) {
-			if(conn->isChief) {
+		if(conn->isChief) {
+			if(!flib_netbase_sendf(conn->netBase, "CFG\nAMMO\n%s\n%s\n\n", weaponset->name, ammostring)) {
 				netconn_setWeaponset(conn, weaponset);
+				return 0;
 			}
-			return 0;
 		}
 	}
 	return -1;
@@ -277,80 +277,98 @@
 }
 
 int flib_netconn_send_mapName(flib_netconn *conn, const char *mapName) {
-	if(!sendStr(conn, "CFG\nMAP", mapName)) {
-		if(conn->isChief) {
+	if(log_badargs_if2(conn==NULL, mapName==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendStr(conn, "CFG\nMAP", mapName)) {
 			char *copy = flib_strdupnull(mapName);
 			if(copy) {
 				free(conn->map->name);
 				conn->map->name = copy;
+				return 0;
 			}
 		}
-		return 0;
 	}
 	return -1;
 }
 
 int flib_netconn_send_mapGen(flib_netconn *conn, int mapGen) {
-	if(!sendInt(conn, "CFG\nMAPGEN", mapGen)) {
-		if(conn->isChief) {
+	if(log_badargs_if(conn==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendInt(conn, "CFG\nMAPGEN", mapGen)) {
 			conn->map->mapgen = mapGen;
+			return 0;
 		}
-		return 0;
 	}
 	return -1;
 }
 
 int flib_netconn_send_mapTemplate(flib_netconn *conn, int templateFilter) {
-	if(!sendInt(conn, "CFG\nTEMPLATE", templateFilter)) {
-		if(conn->isChief) {
+	if(log_badargs_if(conn==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendInt(conn, "CFG\nTEMPLATE", templateFilter)) {
 			conn->map->templateFilter = templateFilter;
+			return 0;
 		}
-		return 0;
 	}
 	return -1;
 }
 
 int flib_netconn_send_mapMazeSize(flib_netconn *conn, int mazeSize) {
-	if(!sendInt(conn, "CFG\nMAZE_SIZE", mazeSize)) {
-		if(conn->isChief) {
+	if(log_badargs_if(conn==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendInt(conn, "CFG\nMAZE_SIZE", mazeSize)) {
 			conn->map->mazeSize = mazeSize;
+			return 0;
 		}
-		return 0;
 	}
 	return -1;
 }
 
 int flib_netconn_send_mapSeed(flib_netconn *conn, const char *seed) {
-	if(!sendStr(conn, "CFG\nSEED", seed)) {
-		if(conn->isChief) {
+	if(log_badargs_if2(conn==NULL, seed==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendStr(conn, "CFG\nSEED", seed)) {
 			char *copy = flib_strdupnull(seed);
 			if(copy) {
 				free(conn->map->seed);
 				conn->map->seed = copy;
+				return 0;
 			}
 		}
-		return 0;
 	}
 	return -1;
 }
 
 int flib_netconn_send_mapTheme(flib_netconn *conn, const char *theme) {
-	if(!sendStr(conn, "CFG\nTHEME", theme)) {
-		if(conn->isChief) {
+	if(log_badargs_if2(conn==NULL, theme==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendStr(conn, "CFG\nTHEME", theme)) {
 			char *copy = flib_strdupnull(theme);
 			if(copy) {
 				free(conn->map->theme);
 				conn->map->theme = copy;
+				return 0;
 			}
 		}
-		return 0;
 	}
 	return -1;
 }
 
 int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size) {
 	int result = -1;
-	if(!log_badargs_if3(conn==NULL, drawData==NULL && size>0, size>SIZE_MAX/2)) {
+	if(!log_badargs_if3(conn==NULL, drawData==NULL && size>0, size>SIZE_MAX/2) && conn->isChief) {
 		uLongf zippedSize = compressBound(size);
 		uint8_t *zipped = flib_malloc(zippedSize+4); // 4 extra bytes for header
 		if(zipped) {
@@ -376,7 +394,7 @@
 		free(zipped);
 	}
 
-	if(!result && conn->isChief) {
+	if(!result) {
 		uint8_t *copy = flib_bufdupnull(drawData, size);
 		if(copy) {
 			free(conn->map->drawData);
@@ -388,26 +406,29 @@
 }
 
 int flib_netconn_send_script(flib_netconn *conn, const char *scriptName) {
-	if(!sendStr(conn, "CFG\nSCRIPT", scriptName)) {
-		if(conn->isChief) {
+	if(log_badargs_if2(conn==NULL, scriptName==NULL)) {
+		return -1;
+	}
+	if(conn->isChief) {
+		if(!sendStr(conn, "CFG\nSCRIPT", scriptName)) {
 			netconn_setScript(conn, scriptName);
+			return 0;
 		}
-		return 0;
 	}
 	return -1;
 }
 
 int flib_netconn_send_scheme(flib_netconn *conn, const flib_scheme *scheme) {
 	int result = -1;
-	if(!log_badargs_if3(conn==NULL, scheme==NULL, flib_strempty(scheme->name))) {
+	if(!log_badargs_if3(conn==NULL, scheme==NULL, flib_strempty(scheme->name)) && conn->isChief) {
 		flib_vector *vec = flib_vector_create();
 		if(vec) {
 			bool error = false;
 			error |= flib_vector_appendf(vec, "CFG\nSCHEME\n%s\n", scheme->name);
-			for(int i=0; i<scheme->meta->modCount; i++) {
+			for(int i=0; i<flib_meta.modCount; i++) {
 				error |= flib_vector_appendf(vec, "%s\n", scheme->mods[i] ? "true" : "false");
 			}
-			for(int i=0; i<scheme->meta->settingCount; i++) {
+			for(int i=0; i<flib_meta.settingCount; i++) {
 				error |= flib_vector_appendf(vec, "%i\n", scheme->settings[i]);
 			}
 			error |= flib_vector_appendf(vec, "\n");
@@ -418,7 +439,7 @@
 		flib_vector_destroy(vec);
 	}
 
-	if(!result && conn->isChief) {
+	if(!result) {
 		netconn_setScheme(conn, scheme);
 	}
 	return result;
--- a/project_files/frontlib/net/netprotocol.c	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/net/netprotocol.c	Wed Aug 15 23:40:10 2012 +0200
@@ -75,14 +75,14 @@
 	return result;
 }
 
-flib_scheme *flib_scheme_from_netmsg(flib_metascheme *meta, char **parts) {
-	flib_scheme *result = flib_scheme_create(meta, parts[0]);
+flib_scheme *flib_scheme_from_netmsg(char **parts) {
+	flib_scheme *result = flib_scheme_create(parts[0]);
 	if(result) {
-		for(int i=0; i<meta->modCount; i++) {
+		for(int i=0; i<flib_meta.modCount; i++) {
 			result->mods[i] = !strcmp(parts[i+1], "true");
 		}
-		for(int i=0; i<meta->settingCount; i++) {
-			result->settings[i] = atoi(parts[i+meta->modCount+1]);
+		for(int i=0; i<flib_meta.settingCount; i++) {
+			result->settings[i] = atoi(parts[i+flib_meta.modCount+1]);
 		}
 	}
 	return result;
--- a/project_files/frontlib/net/netprotocol.h	Sun Aug 12 23:51:36 2012 +0200
+++ b/project_files/frontlib/net/netprotocol.h	Wed Aug 15 23:40:10 2012 +0200
@@ -36,7 +36,7 @@
  * Create a new scheme from this net message, which must have
  * meta->modCount+meta->settingCount+1 parts.
  */
-flib_scheme *flib_scheme_from_netmsg(flib_metascheme *meta, char **parts);
+flib_scheme *flib_scheme_from_netmsg(char **parts);
 
 /**
  * Create a new map from this five-part netmsg
--- a/project_files/frontlib/resources/metasettings.ini	Sun Aug 12 23:51:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,234 +0,0 @@
-[mod0]
-name=fortsmode
-bitmaskindex=12
-
-[mod1]
-name=divteams
-bitmaskindex=4
-
-[mod2]
-name=solidland
-bitmaskindex=2
-
-[mod3]
-name=border
-bitmaskindex=3
-
-[mod4]
-name=lowgrav
-bitmaskindex=5
-
-[mod5]
-name=laser
-bitmaskindex=6
-
-[mod6]
-name=invulnerability
-bitmaskindex=7
-
-[mod7]
-name=resethealth
-bitmaskindex=8
-
-[mod8]
-name=vampiric
-bitmaskindex=9
-
-[mod9]
-name=karma
-bitmaskindex=10
-
-[mod10]
-name=artillery
-bitmaskindex=11
-
-[mod11]
-name=randomorder
-bitmaskindex=13
-
-[mod12]
-name=king
-bitmaskindex=14
-
-[mod13]
-name=placehog
-bitmaskindex=15
-
-[mod14]
-name=sharedammo
-bitmaskindex=16
-
-[mod15]
-name=disablegirders
-bitmaskindex=17
-
-[mod16]
-name=disablelandobjects
-bitmaskindex=18
-
-[mod17]
-name=aisurvival
-bitmaskindex=19
-
-[mod18]
-name=infattack
-bitmaskindex=20
-
-[mod19]
-name=resetweps
-bitmaskindex=21
-
-[mod20]
-name=perhogammo
-bitmaskindex=22
-
-[mod21]
-name=disablewind
-bitmaskindex=23
-
-[mod22]
-name=morewind
-bitmaskindex=24
-
-[mod23]
-name=tagteam
-bitmaskindex=25
-
-[mod24]
-name=bottomborder
-bitmaskindex=26
-
-
-[setting0]
-name=damagefactor
-times1000=false
-command=e$damagepct
-maxmeansinfinity=false
-min=10
-max=300
-default=100
-
-[setting1]
-name=turntime
-times1000=true
-command=e$turntime
-maxmeansinfinity=true
-min=1
-max=9999
-default=45
-
-[setting2]
-name=health
-times1000=false
-maxmeansinfinity=false
-min=50
-max=200
-default=100
-
-[setting3]
-name=suddendeath
-times1000=false
-command=e$sd_turns
-maxmeansinfinity=true
-min=0
-max=50
-default=15
-
-[setting4]
-name=caseprobability
-times1000=false
-command=e$casefreq
-maxmeansinfinity=false
-min=0
-max=9
-default=5
-
-[setting5]
-name=minestime
-times1000=true
-command=e$minestime
-maxmeansinfinity=false
-min=-1
-max=5
-default=3
-
-[setting6]
-name=minesnum
-times1000=false
-command=e$minesnum
-maxmeansinfinity=false
-min=0
-max=80
-default=4
-
-[setting7]
-name=minedudpct
-times1000=false
-command=e$minedudpct
-maxmeansinfinity=false
-min=0
-max=100
-default=0
-
-[setting8]
-name=explosives
-times1000=false
-command=e$explosives
-maxmeansinfinity=false
-min=0
-max=40
-default=2
-
-[setting9]
-name=healthprobability
-times1000=false
-command=e$healthprob
-maxmeansinfinity=false
-min=0
-max=100
-default=35
-
-[setting10]
-name=healthcaseamount
-times1000=false
-command=e$hcaseamount
-maxmeansinfinity=false
-min=0
-max=200
-default=25
-
-[setting11]
-name=waterrise
-times1000=false
-command=e$waterrise
-maxmeansinfinity=false
-min=0
-max=100
-default=47
-
-[setting12]
-name=healthdecrease
-times1000=false
-command=e$healthdec
-maxmeansinfinity=false
-min=0
-max=100
-default=5
-
-[setting13]
-name=ropepct
-times1000=false
-command=e$ropepct
-maxmeansinfinity=false
-min=25
-max=999
-default=100
-
-[setting14]
-name=getawaytime
-times1000=false
-command=e$getawaytime
-maxmeansinfinity=false
-min=0
-max=999
-default=100
--- a/project_files/frontlib/util/refcounter.c	Sun Aug 12 23:51:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-#include "refcounter.h"
-
-#include "logging.h"
-
-void flib_retain(int *referenceCountPtr, const char *objName) {
-	if(!log_badargs_if2(referenceCountPtr==NULL, objName==NULL)) {
-		if((*referenceCountPtr)  >= 0) {
-			(*referenceCountPtr)++;
-			flib_log_d("retaining %s, now %i references", objName, (*referenceCountPtr));
-		}
-		if((*referenceCountPtr) < 0) {
-			flib_log_e("Memory leak: Reference count overflow in %s object!", objName);
-		}
-	}
-}
-
-/**
- * Returns true if the struct should be freed.
- */
-bool flib_release(int *referenceCountPtr, const char *objName) {
-	bool result = false;
-	if(!log_badargs_if2(referenceCountPtr==NULL, objName==NULL)) {
-		if((*referenceCountPtr) > 0) {
-			if(--(*referenceCountPtr) == 0) {
-				flib_log_d("releasing and destroying %s", objName);
-				result = true;
-			} else {
-				flib_log_d("releasing %s, now %i references", objName, *referenceCountPtr);
-			}
-		} else if((*referenceCountPtr) == 0) {
-			flib_log_e("Attempt to release a %s with zero references!", objName);
-		}
-	}
-	return result;
-}
--- a/project_files/frontlib/util/refcounter.h	Sun Aug 12 23:51:36 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-/**
- * Helper functions for reference counted structs.
- *
- * We don't have enough of them to justify going crazy with macros, but I still prefer
- * to have the logic in one place.
- *
- * In particular, these functions handle counter overflow in a sensible way
- * (log and leak).
- */
-
-#ifndef REFCOUNTER_H_
-#define REFCOUNTER_H_
-
-#include <stdbool.h>
-
-/**
- * Pass a pointer to the counter variable to be incremented, and the name of the
- * object for logging purposes. On overflow an error will be logged and the
- * counter will get "stuck" so neither retain nor release will modify it anymore.
- */
-void flib_retain(int *referenceCountPtr, const char *objName);
-
-/**
- * Pass a pointer to the counter variable to be decremented and the name
- * of the object for logging purposes.
- * Returns true if the object should be freed.
- */
-bool flib_release(int *referenceCountPtr, const char *objName);
-
-#endif /* REFCOUNTER_H_ */