+ if (server_frame_counter != FrameCounter)
+ {
+ Warn("frame counters of client %d and server out of sync", player_nr);
+ Warn("frame counter of client is %d", FrameCounter);
+ Warn("frame counter of server is %d", server_frame_counter);
+ Warn("this should not happen -- please debug");
+
+ stop_network_game = TRUE;
+
+ return;
+ }
+
+ // copy valid player actions (will be set to 0 for not connected players)
+ for (i = 0; i < MAX_PLAYERS; i++)
+ stored_player[i].effective_action =
+ getNetworkBuffer8BitInteger(read_buffer);
+
+ network_player_action_received = TRUE;
+}
+
+static void Handle_OP_BROADCAST_MESSAGE(void)
+{
+ int player_nr = getNetworkBuffer8BitInteger(read_buffer);
+
+ Debug("network:client", "OP_BROADCAST_MESSAGE: %d", player_nr);
+ Debug("network:client", "client %d sends message", player_nr);
+}
+
+static void Handle_OP_LEVEL_FILE(void)
+{
+ int player_nr = getNetworkBuffer8BitInteger(read_buffer);
+ char *leveldir_identifier;
+ char *network_level_dir;
+ struct LevelFileInfo *file_info = &network_level.file_info;
+ struct LevelFileInfo *tmpl_info = &network_level.tmpl_info;
+ boolean use_custom_template;
+
+ setString(&network_level.leveldir_identifier, NULL);
+ setString(&network_level.file_info.basename, NULL);
+ setString(&network_level.file_info.filename, NULL);
+ setString(&network_level.tmpl_info.basename, NULL);
+ setString(&network_level.tmpl_info.filename, NULL);
+
+ Debug("network:client", "OP_LEVEL_FILE: %d", player_nr);
+
+ leveldir_identifier = getStringCopy(getNetworkBufferString(read_buffer));
+
+ if (hasPathSeparator(leveldir_identifier))
+ Fail("protocol error: invalid filename from network client");
+
+ InitNetworkLevelDirectory(leveldir_identifier);
+
+ network_level_dir = getNetworkLevelDir(leveldir_identifier);
+
+ file_info->nr = getNetworkBuffer16BitInteger(read_buffer);
+ file_info->type = getNetworkBuffer8BitInteger(read_buffer);
+ file_info->packed = getNetworkBuffer8BitInteger(read_buffer);
+ file_info->basename = getStringCopy(getNetworkBufferString(read_buffer));
+ file_info->filename = getPath2(network_level_dir, file_info->basename);
+
+ if (hasPathSeparator(file_info->basename))
+ Fail("protocol error: invalid filename from network client");
+
+ int num_bytes = getNetworkBufferFile(read_buffer, file_info->filename);
+
+ // if received level file is empty, remove it (as being non-existent)
+ if (num_bytes == 0)
+ remove(file_info->filename);
+
+ use_custom_template = getNetworkBuffer8BitInteger(read_buffer);
+ if (use_custom_template)
+ {
+ *tmpl_info = *file_info;
+
+ tmpl_info->basename = getStringCopy(getNetworkBufferString(read_buffer));
+ tmpl_info->filename = getPath2(network_level_dir, tmpl_info->basename);
+
+ if (hasPathSeparator(tmpl_info->basename))
+ Fail("protocol error: invalid filename from network client");
+
+ getNetworkBufferFile(read_buffer, tmpl_info->filename);
+
+ // if received level file is empty, use level template file instead
+ if (num_bytes == 0)
+ setString(&file_info->filename, tmpl_info->filename);
+ }
+
+ network_level.leveldir_identifier = leveldir_identifier;
+ network_level.use_custom_template = use_custom_template;
+
+ // the receiving client(s) use(s) the transferred network level files
+ network_level.use_network_level_files = TRUE;
+
+#if 0
+ Debug("network:client", "'%s'", leveldir_identifier);
+ Debug("network:client", "'%d'", file_info->nr);
+ Debug("network:client", "'%d'", file_info->type);
+ Debug("network:client", "'%d'", file_info->packed);
+ Debug("network:client", "'%s'", file_info->basename);
+ Debug("network:client", "'%s'", file_info->filename);
+
+ if (use_custom_template)
+ Debug("network:client", "'%s'", tmpl_info->filename);
+#endif
+}
+
+static void HandleNetworkingMessage(void)
+{
+ stop_network_game = FALSE;
+
+ initNetworkBufferForReading(read_buffer);
+
+ int message_type = getNetworkBuffer8BitInteger(read_buffer);
+
+ switch (message_type)
+ {
+ case OP_BAD_PROTOCOL_VERSION:
+ Handle_OP_BAD_PROTOCOL_VERSION();
+ break;
+
+ case OP_YOUR_NUMBER:
+ Handle_OP_YOUR_NUMBER();
+ break;
+
+ case OP_NUMBER_WANTED:
+ Handle_OP_NUMBER_WANTED();
+ break;
+
+ case OP_PLAYER_NAME:
+ Handle_OP_PLAYER_NAME();
+ break;
+
+ case OP_PLAYER_CONNECTED:
+ Handle_OP_PLAYER_CONNECTED();
+ break;
+
+ case OP_PLAYER_DISCONNECTED:
+ Handle_OP_PLAYER_DISCONNECTED();
+ break;
+
+ case OP_START_PLAYING:
+ Handle_OP_START_PLAYING();
+ break;
+
+ case OP_PAUSE_PLAYING:
+ Handle_OP_PAUSE_PLAYING();
+ break;
+
+ case OP_CONTINUE_PLAYING:
+ Handle_OP_CONTINUE_PLAYING();
+ break;
+
+ case OP_STOP_PLAYING:
+ Handle_OP_STOP_PLAYING();
+ break;
+
+ case OP_MOVE_PLAYER:
+ Handle_OP_MOVE_PLAYER();
+ break;
+
+ case OP_BROADCAST_MESSAGE:
+ Handle_OP_BROADCAST_MESSAGE();
+ break;
+
+ case OP_LEVEL_FILE:
+ Handle_OP_LEVEL_FILE();
+ break;
+
+ default:
+ Debug("network:client", "unknown opcode %d from server", message_type);
+ }