+ else if (old_client_nr == first_player.nr) // failed -- local player?
+ {
+ char request[100];
+
+ sprintf(request, "Sorry! Player %d already exists! You are player %d!",
+ index_nr_wanted + 1, new_index_nr + 1);
+
+ Request(request, REQ_CONFIRM);
+
+ Error(ERR_NETWORK_CLIENT, "cannot switch -- you keep client # %d",
+ new_client_nr);
+ }
+
+ if (game_status == GAME_MODE_MAIN)
+ DrawNetworkPlayers();
+}
+
+static void Handle_OP_PLAYER_NAME(void)
+{
+ int player_nr = getNetworkBuffer8BitInteger(read_buffer);
+ char *player_name = getNetworkBufferString(read_buffer);
+ struct NetworkClientPlayerInfo *player = getNetworkPlayer(player_nr);
+
+ printf("OP_PLAYER_NAME: %d\n", player_nr);
+
+ strncpy(player->name, player_name, MAX_PLAYER_NAME_LEN);
+ player->name[MAX_PLAYER_NAME_LEN] = '\0';
+
+ Error(ERR_NETWORK_CLIENT, "client %d calls itself \"%s\"",
+ player_nr, player->name);
+}
+
+static void Handle_OP_PLAYER_CONNECTED(void)
+{
+ struct NetworkClientPlayerInfo *player, *last_player = NULL;
+ int new_client_nr = getNetworkBuffer8BitInteger(read_buffer);
+ int new_index_nr = new_client_nr - 1;
+
+ printf("OP_PLAYER_CONNECTED: %d\n", new_client_nr);
+ Error(ERR_NETWORK_CLIENT, "new client %d connected", new_client_nr);
+
+ for (player = &first_player; player; player = player->next)
+ {
+ if (player->nr == new_client_nr)
+ Error(ERR_EXIT, "multiplayer server sent duplicate player id");
+
+ last_player = player;
+ }
+
+ last_player->next = player =
+ checked_malloc(sizeof(struct NetworkClientPlayerInfo));
+ player->nr = new_client_nr;
+ player->name[0] = '\0';
+ player->next = NULL;
+
+ stored_player[new_index_nr].connected_network = TRUE;
+}
+
+static void Handle_OP_PLAYER_DISCONNECTED(void)
+{
+ struct NetworkClientPlayerInfo *player, *player_disconnected;
+ int player_nr = getNetworkBuffer8BitInteger(read_buffer);
+ int index_nr = player_nr - 1;
+
+ printf("OP_PLAYER_DISCONNECTED: %d\n", player_nr);
+ player_disconnected = getNetworkPlayer(player_nr);
+ Error(ERR_NETWORK_CLIENT, "client %d (%s) disconnected",
+ player_nr, getNetworkPlayerName(player_nr));
+
+ for (player = &first_player; player; player = player->next)
+ if (player->next == player_disconnected)
+ player->next = player_disconnected->next;
+ free(player_disconnected);
+
+ stored_player[index_nr].connected_locally = FALSE;
+ stored_player[index_nr].connected_network = FALSE;
+
+ if (game_status == GAME_MODE_PLAYING)
+ {
+ char message[100];
+
+ sprintf(message, "Player %d left network server! Network game stopped!",
+ player_nr);
+
+ Request(message, REQ_CONFIRM | REQ_STAY_CLOSED);
+
+ SetGameStatus(GAME_MODE_MAIN);
+
+ DrawMainMenu();
+ }
+ else if (game_status == GAME_MODE_MAIN)
+ {
+ DrawNetworkPlayers();
+ }
+}
+
+static void Handle_OP_START_PLAYING(void)
+{
+ int player_nr = getNetworkBuffer8BitInteger(read_buffer);
+ char *new_leveldir_identifier = getNetworkBufferString(read_buffer);
+ int new_level_nr = getNetworkBuffer16BitInteger(read_buffer);
+ unsigned int new_random_seed = getNetworkBuffer32BitInteger(read_buffer);
+
+ if (!strEqual(new_leveldir_identifier, network_level.leveldir_identifier))
+ {
+ Error(ERR_WARN, "no such level identifier: '%s'", new_leveldir_identifier);
+
+ stop_network_game = TRUE;
+
+ return;
+ }
+
+ printf("OP_START_PLAYING: %d\n", player_nr);
+ Error(ERR_NETWORK_CLIENT,
+ "client %d starts game [level %d from level identifier '%s']\n",
+ player_nr, new_level_nr, new_leveldir_identifier);
+
+ LevelDirTree *new_leveldir =
+ getTreeInfoFromIdentifier(leveldir_first, new_leveldir_identifier);
+
+ if (new_leveldir != NULL)
+ {
+ leveldir_current = new_leveldir;
+ level_nr = new_level_nr;
+ }
+
+ // needed if level set of network game changed graphics, sounds or music
+ ReloadCustomArtwork(0);
+
+ TapeErase();
+
+ if (network_level.use_network_level_files)
+ LoadNetworkLevel(&network_level);