project_files/cmdlineClient/cmdlineClient.c
changeset 10017 de822cd3df3a
parent 7488 7e09947b6aa5
equal deleted inserted replaced
10015:4feced261c68 10017:de822cd3df3a
    41 static flib_metascheme *metacfg;
    41 static flib_metascheme *metacfg;
    42 static bool netConnected = false;
    42 static bool netConnected = false;
    43 
    43 
    44 // Callback function that will be called when the map is rendered
    44 // Callback function that will be called when the map is rendered
    45 static void handleMapGenerated(void *context, const uint8_t *bitmap, int numHedgehogs) {
    45 static void handleMapGenerated(void *context, const uint8_t *bitmap, int numHedgehogs) {
    46 	printf("Drawing map for %i brave little hogs...", numHedgehogs);
    46     printf("Drawing map for %i brave little hogs...", numHedgehogs);
    47 
    47 
    48 	// Draw the map as ASCII art
    48     // Draw the map as ASCII art
    49 	for(int y=0; y<MAPIMAGE_HEIGHT; y+=8) {
    49     for(int y=0; y<MAPIMAGE_HEIGHT; y+=8) {
    50 		for(int x=0; x<MAPIMAGE_WIDTH; x+=6) {
    50         for(int x=0; x<MAPIMAGE_WIDTH; x+=6) {
    51 			int pixelnum = x + y*MAPIMAGE_WIDTH;
    51             int pixelnum = x + y*MAPIMAGE_WIDTH;
    52 			bool pixel = bitmap[pixelnum>>3] & (1<<(7-(pixelnum&7)));
    52             bool pixel = bitmap[pixelnum>>3] & (1<<(7-(pixelnum&7)));
    53 			printf(pixel ? "#" : " ");
    53             printf(pixel ? "#" : " ");
    54 		}
    54         }
    55 		printf("\n");
    55         printf("\n");
    56 	}
    56     }
    57 
    57 
    58 	flib_mapconn_destroy(mapconn);
    58     flib_mapconn_destroy(mapconn);
    59 	mapconn = NULL;
    59     mapconn = NULL;
    60 }
    60 }
    61 
    61 
    62 static void onGameDisconnect(void *context, int reason) {
    62 static void onGameDisconnect(void *context, int reason) {
    63 	flib_log_i("Connection closed. Reason: %i", reason);
    63     flib_log_i("Connection closed. Reason: %i", reason);
    64 	flib_gameconn_destroy(gameconn);
    64     flib_gameconn_destroy(gameconn);
    65 	gameconn = NULL;
    65     gameconn = NULL;
    66 	if(netconn) {
    66     if(netconn) {
    67 		flib_netconn_send_roundfinished(netconn, reason==GAME_END_FINISHED);
    67         flib_netconn_send_roundfinished(netconn, reason==GAME_END_FINISHED);
    68 	}
    68     }
    69 }
    69 }
    70 
    70 
    71 // Callback function that will be called on error
    71 // Callback function that will be called on error
    72 static void handleMapFailure(void *context, const char *errormessage) {
    72 static void handleMapFailure(void *context, const char *errormessage) {
    73 	flib_log_e("Map rendering failed: %s", errormessage);
    73     flib_log_e("Map rendering failed: %s", errormessage);
    74 	flib_mapconn_destroy(mapconn);
    74     flib_mapconn_destroy(mapconn);
    75 	mapconn = NULL;
    75     mapconn = NULL;
    76 }
    76 }
    77 
    77 
    78 static void startEngineMap(int port) {
    78 static void startEngineMap(int port) {
    79 	char cmdbuffer[255];
    79     char cmdbuffer[255];
    80 	char argbuffer[255];
    80     char argbuffer[255];
    81 	snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR);
    81     snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR);
    82 	snprintf(argbuffer, 255, "%s %i landpreview", CONFIG_DIR, port);
    82     snprintf(argbuffer, 255, "%s %i landpreview", CONFIG_DIR, port);
    83 	ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE);
    83     ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE);
    84 }
    84 }
    85 
    85 
    86 static void startEngineGame(int port) {
    86 static void startEngineGame(int port) {
    87 	char cmdbuffer[255];
    87     char cmdbuffer[255];
    88 	char argbuffer[255];
    88     char argbuffer[255];
    89 	char base64PlayerName[255];
    89     char base64PlayerName[255];
    90 	base64_encode(nickname, strlen(nickname), base64PlayerName, sizeof(base64PlayerName));
    90     base64_encode(nickname, strlen(nickname), base64PlayerName, sizeof(base64PlayerName));
    91 	snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR);
    91     snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR);
    92 	snprintf(argbuffer, 255, "%s 1024 768 32 %i 0 0 0 10 10 %s 0 0 %s 0 0 en.txt", CONFIG_DIR, port, DATA_DIR, base64PlayerName);
    92     snprintf(argbuffer, 255, "%s 1024 768 32 %i 0 0 0 10 10 %s 0 0 %s 0 0 en.txt", CONFIG_DIR, port, DATA_DIR, base64PlayerName);
    93 	ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE);
    93     ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE);
    94 }
    94 }
    95 
    95 
    96 void handleNetDisconnect(void *context, int reason, const char *message) {
    96 void handleNetDisconnect(void *context, int reason, const char *message) {
    97 	printf("Disconnected: %s", message);
    97     printf("Disconnected: %s", message);
    98 	flib_netconn_destroy(netconn);
    98     flib_netconn_destroy(netconn);
    99 	netconn = NULL;
    99     netconn = NULL;
   100 }
   100 }
   101 
   101 
   102 /*void printRoomList() {
   102 /*void printRoomList() {
   103 	const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn);
   103     const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn);
   104 	if(roomlist) {
   104     if(roomlist) {
   105 		if(roomlist->roomCount>0) {
   105         if(roomlist->roomCount>0) {
   106 			for(int i=0; i<roomlist->roomCount; i++) {
   106             for(int i=0; i<roomlist->roomCount; i++) {
   107 				if(i>0) {
   107                 if(i>0) {
   108 					printf(", ");
   108                     printf(", ");
   109 				}
   109                 }
   110 				flib_room *room = roomlist->rooms[i];
   110                 flib_room *room = roomlist->rooms[i];
   111 				printf("%s", room->name);
   111                 printf("%s", room->name);
   112 			}
   112             }
   113 		} else {
   113         } else {
   114 			puts("Unfortunately, there are no rooms at the moment.");
   114             puts("Unfortunately, there are no rooms at the moment.");
   115 		}
   115         }
   116 	} else {
   116     } else {
   117 		puts("Sorry, due to an error the room list is not available.");
   117         puts("Sorry, due to an error the room list is not available.");
   118 	}
   118     }
   119 	puts("\n");
   119     puts("\n");
   120 }*/
   120 }*/
   121 
   121 
   122 void printTeamList() {
   122 void printTeamList() {
   123 	flib_gamesetup *setup = flib_netconn_create_gamesetup(netconn);
   123     flib_gamesetup *setup = flib_netconn_create_gamesetup(netconn);
   124 	if(setup) {
   124     if(setup) {
   125 		puts("The following teams are in this room:");
   125         puts("The following teams are in this room:");
   126 		for(int i=0; i<setup->teamlist->teamCount; i++) {
   126         for(int i=0; i<setup->teamlist->teamCount; i++) {
   127 			if(i>0) {
   127             if(i>0) {
   128 				printf(", ");
   128                 printf(", ");
   129 			}
   129             }
   130 			printf("%s", setup->teamlist->teams[i]->name);
   130             printf("%s", setup->teamlist->teams[i]->name);
   131 		}
   131         }
   132 		puts("\n");
   132         puts("\n");
   133 	} else {
   133     } else {
   134 		puts("Sorry, due to an error the team list is not available.");
   134         puts("Sorry, due to an error the team list is not available.");
   135 	}
   135     }
   136 	flib_gamesetup_destroy(setup);
   136     flib_gamesetup_destroy(setup);
   137 }
   137 }
   138 
   138 
   139 void handleNetConnected(void *context) {
   139 void handleNetConnected(void *context) {
   140 	printf("You enter the lobby of a strange house inhabited by hedgehogs. Looking around, you see hallways branching off to these rooms:\n");
   140     printf("You enter the lobby of a strange house inhabited by hedgehogs. Looking around, you see hallways branching off to these rooms:\n");
   141 	//printRoomList();
   141     //printRoomList();
   142 	printf("\n\nNow, you can chat by just entering text, or join a room with /join <roomname>.");
   142     printf("\n\nNow, you can chat by just entering text, or join a room with /join <roomname>.");
   143 	printf(" You can also /quit or let me /describe <roomname>. Once in a room, you can /add <teamname> and set yourself /ready. You can also /list the available rooms (in the lobby) or the teams (in a room).\n");
   143     printf(" You can also /quit or let me /describe <roomname>. Once in a room, you can /add <teamname> and set yourself /ready. You can also /list the available rooms (in the lobby) or the teams (in a room).\n");
   144 	netConnected = true;
   144     netConnected = true;
   145 }
   145 }
   146 
   146 
   147 void handleChat(void *context, const char *nick, const char *msg) {
   147 void handleChat(void *context, const char *nick, const char *msg) {
   148 	if(gameconn) {
   148     if(gameconn) {
   149 		flib_gameconn_send_chatmsg(gameconn, nick, msg);
   149         flib_gameconn_send_chatmsg(gameconn, nick, msg);
   150 	}
   150     }
   151 	printf("%s: %s\n", nick, msg);
   151     printf("%s: %s\n", nick, msg);
   152 }
   152 }
   153 
   153 
   154 void handleEnterRoom(void *context, bool isChief) {
   154 void handleEnterRoom(void *context, bool isChief) {
   155 	puts("You have entered the room.");
   155     puts("You have entered the room.");
   156 }
   156 }
   157 
   157 
   158 void handleRoomJoin(void *context, const char *nick) {
   158 void handleRoomJoin(void *context, const char *nick) {
   159 	if(strcmp(nick, nickname)) {
   159     if(strcmp(nick, nickname)) {
   160 		printf("%s is here.\n", nick);
   160         printf("%s is here.\n", nick);
   161 	}
   161     }
   162 }
   162 }
   163 
   163 
   164 void handleRoomLeave(void *context, const char *nick, const char *partmsg) {
   164 void handleRoomLeave(void *context, const char *nick, const char *partmsg) {
   165 	if(strcmp(nick, nickname)) {
   165     if(strcmp(nick, nickname)) {
   166 		printf("%s leaves.\n", nick);
   166         printf("%s leaves.\n", nick);
   167 	}
   167     }
   168 }
   168 }
   169 
   169 
   170 void handleReady(void *context, const char *nick, bool ready) {
   170 void handleReady(void *context, const char *nick, bool ready) {
   171 	if(strcmp(nick, nickname)) {
   171     if(strcmp(nick, nickname)) {
   172 		if(ready) {
   172         if(ready) {
   173 			printf("%s is ready to go.\n", nick);
   173             printf("%s is ready to go.\n", nick);
   174 		} else {
   174         } else {
   175 			printf("%s is not ready.\n", nick);
   175             printf("%s is not ready.\n", nick);
   176 		}
   176         }
   177 	} else {
   177     } else {
   178 		if(ready) {
   178         if(ready) {
   179 			printf("You are ready to go.\n");
   179             printf("You are ready to go.\n");
   180 		} else {
   180         } else {
   181 			printf("You are not ready.\n");
   181             printf("You are not ready.\n");
   182 		}
   182         }
   183 	}
   183     }
   184 }
   184 }
   185 
   185 
   186 void handleEmFromNet(void *context, const uint8_t *em, size_t size) {
   186 void handleEmFromNet(void *context, const uint8_t *em, size_t size) {
   187 	if(gameconn) {
   187     if(gameconn) {
   188 		flib_gameconn_send_enginemsg(gameconn, em, size);
   188         flib_gameconn_send_enginemsg(gameconn, em, size);
   189 	}
   189     }
   190 }
   190 }
   191 
   191 
   192 void handleEmFromEngine(void *context, const uint8_t *em, size_t size) {
   192 void handleEmFromEngine(void *context, const uint8_t *em, size_t size) {
   193 	if(netconn) {
   193     if(netconn) {
   194 		flib_netconn_send_engineMessage(netconn, em, size);
   194         flib_netconn_send_engineMessage(netconn, em, size);
   195 	}
   195     }
   196 }
   196 }
   197 
   197 
   198 void handleChatFromGame(void *context, const char *message, bool teamchat) {
   198 void handleChatFromGame(void *context, const char *message, bool teamchat) {
   199 	if(netconn) {
   199     if(netconn) {
   200 		if(teamchat) {
   200         if(teamchat) {
   201 			flib_netconn_send_teamchat(netconn, message);
   201             flib_netconn_send_teamchat(netconn, message);
   202 		} else {
   202         } else {
   203 			flib_netconn_send_chat(netconn, message);
   203             flib_netconn_send_chat(netconn, message);
   204 		}
   204         }
   205 	}
   205     }
   206 }
   206 }
   207 
   207 
   208 void handleRunGame(void *context) {
   208 void handleRunGame(void *context) {
   209 	flib_gamesetup *gamesetup = flib_netconn_create_gamesetup(netconn);
   209     flib_gamesetup *gamesetup = flib_netconn_create_gamesetup(netconn);
   210 	if(gameconn) {
   210     if(gameconn) {
   211 		flib_log_e("Request to start game, but a game is already running.");
   211         flib_log_e("Request to start game, but a game is already running.");
   212 	} else if(gamesetup) {
   212     } else if(gamesetup) {
   213 		gameconn = flib_gameconn_create(nickname, gamesetup, true);
   213         gameconn = flib_gameconn_create(nickname, gamesetup, true);
   214 		flib_gameconn_onEngineMessage(gameconn, handleEmFromEngine, NULL);
   214         flib_gameconn_onEngineMessage(gameconn, handleEmFromEngine, NULL);
   215 		flib_gameconn_onDisconnect(gameconn, onGameDisconnect, NULL);
   215         flib_gameconn_onDisconnect(gameconn, onGameDisconnect, NULL);
   216 		flib_gameconn_onChat(gameconn, handleChatFromGame, NULL);
   216         flib_gameconn_onChat(gameconn, handleChatFromGame, NULL);
   217 		startEngineGame(flib_gameconn_getport(gameconn));
   217         startEngineGame(flib_gameconn_getport(gameconn));
   218 	}
   218     }
   219 	flib_gamesetup_destroy(gamesetup);
   219     flib_gamesetup_destroy(gamesetup);
   220 }
   220 }
   221 
   221 
   222 void handleNickTaken(void *context, const char *nick) {
   222 void handleNickTaken(void *context, const char *nick) {
   223 	printf("The nickname %s is already in use, please choose a different one:\n", nick);
   223     printf("The nickname %s is already in use, please choose a different one:\n", nick);
   224 	flib_gets(nickname, sizeof(nickname));
   224     flib_gets(nickname, sizeof(nickname));
   225 	flib_netconn_send_nick(netconn, nickname);
   225     flib_netconn_send_nick(netconn, nickname);
   226 }
   226 }
   227 
   227 
   228 void handlePwRequest(void *context, const char *nick) {
   228 void handlePwRequest(void *context, const char *nick) {
   229 	printf("A password is required to log in as %s, please enter (warning: shown in cleartext):\n", nick);
   229     printf("A password is required to log in as %s, please enter (warning: shown in cleartext):\n", nick);
   230 	char password[256];
   230     char password[256];
   231 	flib_gets(password, sizeof(password));
   231     flib_gets(password, sizeof(password));
   232 	flib_netconn_send_password(netconn, password);
   232     flib_netconn_send_password(netconn, password);
   233 }
   233 }
   234 
   234 
   235 void handleMessage(void *context, int type, const char *msg) {
   235 void handleMessage(void *context, int type, const char *msg) {
   236 	if(gameconn) {
   236     if(gameconn) {
   237 		flib_gameconn_send_textmsg(gameconn, 1, msg);
   237         flib_gameconn_send_textmsg(gameconn, 1, msg);
   238 	}
   238     }
   239 	printf("*** %s\n", msg);
   239     printf("*** %s\n", msg);
   240 }
   240 }
   241 
   241 
   242 void handleTeamAccepted(void *context, const char *teamname) {
   242 void handleTeamAccepted(void *context, const char *teamname) {
   243 	printf("The team %s has been accepted.\n", teamname);
   243     printf("The team %s has been accepted.\n", teamname);
   244 }
   244 }
   245 
   245 
   246 void handleMapChanged(void *context, const flib_map *map, int changetype) {
   246 void handleMapChanged(void *context, const flib_map *map, int changetype) {
   247 	if(map->mapgen != MAPGEN_NAMED && changetype != NETCONN_MAPCHANGE_THEME) {
   247     if(map->mapgen != MAPGEN_NAMED && changetype != NETCONN_MAPCHANGE_THEME) {
   248 		if(mapconn) {
   248         if(mapconn) {
   249 			flib_mapconn_destroy(mapconn);
   249             flib_mapconn_destroy(mapconn);
   250 			mapconn = NULL;
   250             mapconn = NULL;
   251 		}
   251         }
   252 		mapconn = flib_mapconn_create(map);
   252         mapconn = flib_mapconn_create(map);
   253 		if(mapconn) {
   253         if(mapconn) {
   254 			flib_mapconn_onSuccess(mapconn, handleMapGenerated, NULL);
   254             flib_mapconn_onSuccess(mapconn, handleMapGenerated, NULL);
   255 			flib_mapconn_onFailure(mapconn, handleMapFailure, NULL);
   255             flib_mapconn_onFailure(mapconn, handleMapFailure, NULL);
   256 			startEngineMap(flib_mapconn_getport(mapconn));
   256             startEngineMap(flib_mapconn_getport(mapconn));
   257 		}
   257         }
   258 	} else if(map->mapgen == MAPGEN_NAMED) {
   258     } else if(map->mapgen == MAPGEN_NAMED) {
   259 		printf("The map %s has been selected.\n", map->name);
   259         printf("The map %s has been selected.\n", map->name);
   260 	}
   260     }
   261 }
   261 }
   262 
   262 
   263 void handleLeaveRoom(void *context, int reason, const char *msg) {
   263 void handleLeaveRoom(void *context, int reason, const char *msg) {
   264 	if(reason == NETCONN_ROOMLEAVE_ABANDONED) {
   264     if(reason == NETCONN_ROOMLEAVE_ABANDONED) {
   265 		printf("The chief has abandoned the room.");
   265         printf("The chief has abandoned the room.");
   266 	} else if(reason == NETCONN_ROOMLEAVE_KICKED) {
   266     } else if(reason == NETCONN_ROOMLEAVE_KICKED) {
   267 		printf("You have been kicked from the room.");
   267         printf("You have been kicked from the room.");
   268 	}
   268     }
   269 	if(msg) {
   269     if(msg) {
   270 		printf(" (%s)", msg);
   270         printf(" (%s)", msg);
   271 	}
   271     }
   272 	puts(" You are back in the lobby.");
   272     puts(" You are back in the lobby.");
   273 }
   273 }
   274 
   274 
   275 void handleSchemeChanged(void *context, const flib_scheme *scheme) {
   275 void handleSchemeChanged(void *context, const flib_scheme *scheme) {
   276 	printf("Game scheme: %s.\n", scheme->name);
   276     printf("Game scheme: %s.\n", scheme->name);
   277 }
   277 }
   278 
   278 
   279 void handleWeaponsetChanged(void *context, const flib_weaponset *weaponset) {
   279 void handleWeaponsetChanged(void *context, const flib_weaponset *weaponset) {
   280 	printf("Weaponset: %s.\n", weaponset->name);
   280     printf("Weaponset: %s.\n", weaponset->name);
   281 }
   281 }
   282 
   282 
   283 void handleHogcountChanged(void *context, const char *team, int count) {
   283 void handleHogcountChanged(void *context, const char *team, int count) {
   284 	printf("Team %s will send %i hogs into the fight.\n", team, count);
   284     printf("Team %s will send %i hogs into the fight.\n", team, count);
   285 }
   285 }
   286 
   286 
   287 void handleRoomAdd(void *context, const flib_room *room) {
   287 void handleRoomAdd(void *context, const flib_room *room) {
   288 	printf("%s created a new room called %s.\n", room->owner, room->name);
   288     printf("%s created a new room called %s.\n", room->owner, room->name);
   289 }
   289 }
   290 
   290 
   291 void handleRoomDelete(void *context, const char *roomName) {
   291 void handleRoomDelete(void *context, const char *roomName) {
   292 	printf("The room %s has collapsed.\n", roomName);
   292     printf("The room %s has collapsed.\n", roomName);
   293 }
   293 }
   294 
   294 
   295 void handleScriptChanged(void *context, const char *script) {
   295 void handleScriptChanged(void *context, const char *script) {
   296 	printf("Game Type: %s\n", script);
   296     printf("Game Type: %s\n", script);
   297 }
   297 }
   298 
   298 
   299 void handleTeamAdd(void *context, const flib_team *team) {
   299 void handleTeamAdd(void *context, const flib_team *team) {
   300 	printf("%s puts the team %s to the planning board.\n", team->ownerName, team->name);
   300     printf("%s puts the team %s to the planning board.\n", team->ownerName, team->name);
   301 }
   301 }
   302 
   302 
   303 void handleTeamDelete(void *context, const char *teamName) {
   303 void handleTeamDelete(void *context, const char *teamName) {
   304 	printf("The team %s decided not to fight this battle after all.\n", teamName);
   304     printf("The team %s decided not to fight this battle after all.\n", teamName);
   305 }
   305 }
   306 
   306 
   307 void handleTeamColorChanged(void *context, const char *name, int colorIndex) {
   307 void handleTeamColorChanged(void *context, const char *name, int colorIndex) {
   308 	static const char* colorNames[] = {"red", "blue", "teal", "purple", "pink", "green", "orange", "brown", "yellow"};
   308     static const char* colorNames[] = {"red", "blue", "teal", "purple", "pink", "green", "orange", "brown", "yellow"};
   309 	const char *colorName = "strange";
   309     const char *colorName = "strange";
   310 	if(colorIndex>=0 && colorIndex < 9) {
   310     if(colorIndex>=0 && colorIndex < 9) {
   311 		colorName = colorNames[colorIndex];
   311         colorName = colorNames[colorIndex];
   312 	}
   312     }
   313 	printf("The team %s will wear %s uniforms today.\n", name, colorName);
   313     printf("The team %s will wear %s uniforms today.\n", name, colorName);
   314 }
   314 }
   315 
   315 
   316 void tick() {
   316 void tick() {
   317 	if(gameconn) {
   317     if(gameconn) {
   318 		flib_gameconn_tick(gameconn);
   318         flib_gameconn_tick(gameconn);
   319 	}
   319     }
   320 	if(netconn) {
   320     if(netconn) {
   321 		flib_netconn_tick(netconn);
   321         flib_netconn_tick(netconn);
   322 	}
   322     }
   323 	if(mapconn) {
   323     if(mapconn) {
   324 		flib_mapconn_tick(mapconn);
   324         flib_mapconn_tick(mapconn);
   325 	}
   325     }
   326 }
   326 }
   327 
   327 
   328 static HANDLE hStdin;
   328 static HANDLE hStdin;
   329 
   329 
   330 static int init() {
   330 static int init() {
   331 	hStdin = GetStdHandle(STD_INPUT_HANDLE);
   331     hStdin = GetStdHandle(STD_INPUT_HANDLE);
   332 	if(hStdin == INVALID_HANDLE_VALUE) {
   332     if(hStdin == INVALID_HANDLE_VALUE) {
   333 		flib_log_e("Unable to get stdin handle");
   333         flib_log_e("Unable to get stdin handle");
   334 		return 1;
   334         return 1;
   335 	}
   335     }
   336 	if(!flib_init(0)) {
   336     if(!flib_init(0)) {
   337 		flib_log_setLevel(FLIB_LOGLEVEL_WARNING);
   337         flib_log_setLevel(FLIB_LOGLEVEL_WARNING);
   338 		freopen( "CON", "w", stdout );
   338         freopen( "CON", "w", stdout );
   339 		freopen( "CON", "w", stderr );
   339         freopen( "CON", "w", stderr );
   340 		metacfg = flib_metascheme_from_ini("metasettings.ini");
   340         metacfg = flib_metascheme_from_ini("metasettings.ini");
   341 		if(!metacfg) {
   341         if(!metacfg) {
   342 			flib_quit();
   342             flib_quit();
   343 			return -1;
   343             return -1;
   344 		} else {
   344         } else {
   345 			return 0;
   345             return 0;
   346 		}
   346         }
   347 	}
   347     }
   348 	return -1;
   348     return -1;
   349 }
   349 }
   350 
   350 
   351 int main(int argc, char *argv[]) {
   351 int main(int argc, char *argv[]) {
   352 	if(init()) {
   352     if(init()) {
   353 		return -1;
   353         return -1;
   354 	}
   354     }
   355 
   355 
   356 	puts("Please enter a nickname:");
   356     puts("Please enter a nickname:");
   357 	flib_gets(nickname, sizeof(nickname));
   357     flib_gets(nickname, sizeof(nickname));
   358 
   358 
   359 	netconn = flib_netconn_create(nickname, metacfg, DATA_DIR"\\", "140.247.62.101", 46631);
   359     netconn = flib_netconn_create(nickname, metacfg, DATA_DIR"\\", "140.247.62.101", 46631);
   360 	if(!netconn) {
   360     if(!netconn) {
   361 		flib_quit();
   361         flib_quit();
   362 		return -1;
   362         return -1;
   363 	}
   363     }
   364 
   364 
   365 	flib_netconn_onConnected(netconn, handleNetConnected, NULL);
   365     flib_netconn_onConnected(netconn, handleNetConnected, NULL);
   366 	flib_netconn_onDisconnected(netconn, handleNetDisconnect, NULL);
   366     flib_netconn_onDisconnected(netconn, handleNetDisconnect, NULL);
   367 	flib_netconn_onChat(netconn, handleChat, NULL);
   367     flib_netconn_onChat(netconn, handleChat, NULL);
   368 	flib_netconn_onEnterRoom(netconn, handleEnterRoom, NULL);
   368     flib_netconn_onEnterRoom(netconn, handleEnterRoom, NULL);
   369 	flib_netconn_onRunGame(netconn, handleRunGame, NULL);
   369     flib_netconn_onRunGame(netconn, handleRunGame, NULL);
   370 	flib_netconn_onEngineMessage(netconn, handleEmFromNet, NULL);
   370     flib_netconn_onEngineMessage(netconn, handleEmFromNet, NULL);
   371 	flib_netconn_onRoomJoin(netconn, handleRoomJoin, NULL);
   371     flib_netconn_onRoomJoin(netconn, handleRoomJoin, NULL);
   372 	flib_netconn_onRoomLeave(netconn, handleRoomLeave, NULL);
   372     flib_netconn_onRoomLeave(netconn, handleRoomLeave, NULL);
   373 	flib_netconn_onReadyState(netconn, handleReady, NULL);
   373     flib_netconn_onReadyState(netconn, handleReady, NULL);
   374 	flib_netconn_onNickTaken(netconn, handleNickTaken, NULL);
   374     flib_netconn_onNickTaken(netconn, handleNickTaken, NULL);
   375 	flib_netconn_onPasswordRequest(netconn, handlePwRequest, NULL);
   375     flib_netconn_onPasswordRequest(netconn, handlePwRequest, NULL);
   376 	flib_netconn_onMessage(netconn, handleMessage, NULL);
   376     flib_netconn_onMessage(netconn, handleMessage, NULL);
   377 	flib_netconn_onTeamAccepted(netconn, handleTeamAccepted, NULL);
   377     flib_netconn_onTeamAccepted(netconn, handleTeamAccepted, NULL);
   378 	flib_netconn_onMapChanged(netconn, handleMapChanged, NULL);
   378     flib_netconn_onMapChanged(netconn, handleMapChanged, NULL);
   379 	flib_netconn_onLeaveRoom(netconn, handleLeaveRoom, NULL);
   379     flib_netconn_onLeaveRoom(netconn, handleLeaveRoom, NULL);
   380 	flib_netconn_onCfgScheme(netconn, handleSchemeChanged, NULL);
   380     flib_netconn_onCfgScheme(netconn, handleSchemeChanged, NULL);
   381 	flib_netconn_onWeaponsetChanged(netconn, handleWeaponsetChanged, NULL);
   381     flib_netconn_onWeaponsetChanged(netconn, handleWeaponsetChanged, NULL);
   382 	flib_netconn_onHogCountChanged(netconn, handleHogcountChanged, NULL);
   382     flib_netconn_onHogCountChanged(netconn, handleHogcountChanged, NULL);
   383 	flib_netconn_onRoomAdd(netconn, handleRoomAdd, NULL);
   383     flib_netconn_onRoomAdd(netconn, handleRoomAdd, NULL);
   384 	flib_netconn_onRoomDelete(netconn, handleRoomDelete, NULL);
   384     flib_netconn_onRoomDelete(netconn, handleRoomDelete, NULL);
   385 	flib_netconn_onScriptChanged(netconn, handleScriptChanged, NULL);
   385     flib_netconn_onScriptChanged(netconn, handleScriptChanged, NULL);
   386 	flib_netconn_onTeamAdd(netconn, handleTeamAdd, NULL);
   386     flib_netconn_onTeamAdd(netconn, handleTeamAdd, NULL);
   387 	flib_netconn_onTeamDelete(netconn, handleTeamDelete, NULL);
   387     flib_netconn_onTeamDelete(netconn, handleTeamDelete, NULL);
   388 	flib_netconn_onTeamColorChanged(netconn, handleTeamColorChanged, NULL);
   388     flib_netconn_onTeamColorChanged(netconn, handleTeamColorChanged, NULL);
   389 
   389 
   390 	INPUT_RECORD inputRecord;
   390     INPUT_RECORD inputRecord;
   391 	DWORD eventCount = 0;
   391     DWORD eventCount = 0;
   392 
   392 
   393 	while(netconn || gameconn) {
   393     while(netconn || gameconn) {
   394 		tick();
   394         tick();
   395 		if(netconn && netConnected) {
   395         if(netconn && netConnected) {
   396 			while(PeekConsoleInput(hStdin, &inputRecord, 1, &eventCount) && eventCount>0) {
   396             while(PeekConsoleInput(hStdin, &inputRecord, 1, &eventCount) && eventCount>0) {
   397 				if(inputRecord.EventType != KEY_EVENT) {
   397                 if(inputRecord.EventType != KEY_EVENT) {
   398 					ReadConsoleInput(hStdin, &inputRecord, 1, &eventCount);
   398                     ReadConsoleInput(hStdin, &inputRecord, 1, &eventCount);
   399 				} else {
   399                 } else {
   400 					printf("%s: ", nickname);
   400                     printf("%s: ", nickname);
   401 					char input[256];
   401                     char input[256];
   402 					if(!flib_gets(input, sizeof(input))) {
   402                     if(!flib_gets(input, sizeof(input))) {
   403 						if(!memcmp("/quit", input, strlen("/quit"))) {
   403                         if(!memcmp("/quit", input, strlen("/quit"))) {
   404 							flib_netconn_send_quit(netconn, "Player quit.");
   404                             flib_netconn_send_quit(netconn, "Player quit.");
   405 						} else if(!memcmp("/describe ", input, strlen("/describe "))) {
   405                         } else if(!memcmp("/describe ", input, strlen("/describe "))) {
   406 							const char *roomname = input+strlen("/describe ");
   406                             const char *roomname = input+strlen("/describe ");
   407 							/*const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn);
   407                             /*const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn);
   408 							flib_room *room = flib_roomlist_find(roomlist, roomname);
   408                             flib_room *room = flib_roomlist_find(roomlist, roomname);
   409 							if(!room) {
   409                             if(!room) {
   410 								puts("Unknown room.");
   410                                 puts("Unknown room.");
   411 							} else {
   411                             } else {
   412 								char *text = flib_asprintf(
   412                                 char *text = flib_asprintf(
   413 										"%s is a room created by %s, where %i players (%i teams) are %s on %s%s, using the %s scheme and %s weaponset.",
   413                                         "%s is a room created by %s, where %i players (%i teams) are %s on %s%s, using the %s scheme and %s weaponset.",
   414 										room->name,
   414                                         room->name,
   415 										room->owner,
   415                                         room->owner,
   416 										room->playerCount,
   416                                         room->playerCount,
   417 										room->teamCount,
   417                                         room->teamCount,
   418 										room->inProgress ? "fighting" : "preparing to fight",
   418                                         room->inProgress ? "fighting" : "preparing to fight",
   419 										room->map[0]=='+' ? "" : "the map ",
   419                                         room->map[0]=='+' ? "" : "the map ",
   420 										!strcmp("+rnd+", room->map) ? "a random map" :
   420                                         !strcmp("+rnd+", room->map) ? "a random map" :
   421 												!strcmp("+maze+", room->map) ? "a random maze" :
   421                                                 !strcmp("+maze+", room->map) ? "a random maze" :
   422 												!strcmp("+drawn+", room->map) ? "a hand-drawn map" :
   422                                                 !strcmp("+drawn+", room->map) ? "a hand-drawn map" :
   423 												room->map,
   423                                                 room->map,
   424 										room->scheme,
   424                                         room->scheme,
   425 										room->weapons);
   425                                         room->weapons);
   426 								if(text) {
   426                                 if(text) {
   427 									puts(text);
   427                                     puts(text);
   428 								}
   428                                 }
   429 								free(text);
   429                                 free(text);
   430 							}*/
   430                             }*/
   431 						} else if(!memcmp("/join ", input, strlen("/join "))) {
   431                         } else if(!memcmp("/join ", input, strlen("/join "))) {
   432 							const char *roomname = input+strlen("/join ");
   432                             const char *roomname = input+strlen("/join ");
   433 							flib_netconn_send_joinRoom(netconn, roomname);
   433                             flib_netconn_send_joinRoom(netconn, roomname);
   434 						} else if(!memcmp("/ready", input, strlen("/ready"))) {
   434                         } else if(!memcmp("/ready", input, strlen("/ready"))) {
   435 							flib_netconn_send_toggleReady(netconn);
   435                             flib_netconn_send_toggleReady(netconn);
   436 						} else if(!memcmp("/loglevel ", input, strlen("/loglevel "))) {
   436                         } else if(!memcmp("/loglevel ", input, strlen("/loglevel "))) {
   437 							int loglevel = atoi(input+strlen("/loglevel "));
   437                             int loglevel = atoi(input+strlen("/loglevel "));
   438 							flib_log_setLevel(loglevel);
   438                             flib_log_setLevel(loglevel);
   439 						} else if(!memcmp("/list", input, strlen("/list"))) {
   439                         } else if(!memcmp("/list", input, strlen("/list"))) {
   440 							if(flib_netconn_is_in_room_context(netconn)) {
   440                             if(flib_netconn_is_in_room_context(netconn)) {
   441 								printTeamList();
   441                                 printTeamList();
   442 							} else {
   442                             } else {
   443 								puts("From this big and expansive lobby, hallways branch off to these rooms:");
   443                                 puts("From this big and expansive lobby, hallways branch off to these rooms:");
   444 								//printRoomList();
   444                                 //printRoomList();
   445 							}
   445                             }
   446 						} else if(!memcmp("/addteam ", input, strlen("/addteam "))) {
   446                         } else if(!memcmp("/addteam ", input, strlen("/addteam "))) {
   447 							const char *teamname = input+strlen("/addteam ");
   447                             const char *teamname = input+strlen("/addteam ");
   448 							if(!flib_contains_dir_separator(teamname)) {
   448                             if(!flib_contains_dir_separator(teamname)) {
   449 								char *teamfilename = flib_asprintf("%s.hwt", teamname);
   449                                 char *teamfilename = flib_asprintf("%s.hwt", teamname);
   450 								if(teamfilename) {
   450                                 if(teamfilename) {
   451 									flib_team *team = flib_team_from_ini(teamfilename);
   451                                     flib_team *team = flib_team_from_ini(teamfilename);
   452 									if(team) {
   452                                     if(team) {
   453 										flib_netconn_send_addTeam(netconn, team);
   453                                         flib_netconn_send_addTeam(netconn, team);
   454 									} else {
   454                                     } else {
   455 										printf("Teamfile %s not found.\n", teamfilename);
   455                                         printf("Teamfile %s not found.\n", teamfilename);
   456 									}
   456                                     }
   457 									flib_team_destroy(team);
   457                                     flib_team_destroy(team);
   458 								}
   458                                 }
   459 								free(teamfilename);
   459                                 free(teamfilename);
   460 							}
   460                             }
   461 						} else if(strlen(input)>0) {
   461                         } else if(strlen(input)>0) {
   462 							flib_netconn_send_chat(netconn, input);
   462                             flib_netconn_send_chat(netconn, input);
   463 						}
   463                         }
   464 					}
   464                     }
   465 				}
   465                 }
   466 			}
   466             }
   467 		}
   467         }
   468 		fflush(stdout);
   468         fflush(stdout);
   469 		Sleep(10);
   469         Sleep(10);
   470 	}
   470     }
   471 
   471 
   472 
   472 
   473 	flib_metascheme_release(metacfg);
   473     flib_metascheme_release(metacfg);
   474 	return 0;
   474     return 0;
   475 }
   475 }