determineLevelFileInfo_Filetype(level_file_info);
}
+static void copyLevelFileInfo(struct LevelFileInfo *lfi_from,
+ struct LevelFileInfo *lfi_to)
+{
+ lfi_to->nr = lfi_from->nr;
+ lfi_to->type = lfi_from->type;
+ lfi_to->packed = lfi_from->packed;
+
+ setString(&lfi_to->basename, lfi_from->basename);
+ setString(&lfi_to->filename, lfi_from->filename);
+}
+
/* ------------------------------------------------------------------------- */
/* functions for loading R'n'D level */
/* ------------------------------------------------------------------------- */
CopyNativeLevel_RND_to_Native(level);
}
+static void LoadLevelTemplate_LoadAndInit()
+{
+ LoadLevelFromFileInfo(&level_template, &level_template.file_info, FALSE);
+
+ LoadLevel_InitVersion(&level_template);
+ LoadLevel_InitElements(&level_template);
+
+ ActivateLevelTemplate();
+}
+
void LoadLevelTemplate(int nr)
{
if (!fileExists(getGlobalLevelTemplateFilename()))
setLevelFileInfo(&level_template.file_info, nr);
- LoadLevelFromFileInfo(&level_template, &level_template.file_info, FALSE);
+ LoadLevelTemplate_LoadAndInit();
+}
- LoadLevel_InitVersion(&level_template);
- LoadLevel_InitElements(&level_template);
+static void LoadLevelTemplateFromNetwork(struct LevelFileInfo *lfi_network_template)
+{
+ copyLevelFileInfo(lfi_network_template, &level_template.file_info);
- ActivateLevelTemplate();
+ LoadLevelTemplate_LoadAndInit();
}
-void LoadLevel(int nr)
+static void LoadLevel_LoadAndInit(struct LevelFileInfo *lfi_network_template)
{
- setLevelFileInfo(&level.file_info, nr);
-
LoadLevelFromFileInfo(&level, &level.file_info, FALSE);
if (level.use_custom_template)
- LoadLevelTemplate(-1);
+ {
+ if (lfi_network_template != NULL)
+ LoadLevelTemplateFromNetwork(lfi_network_template);
+ else
+ LoadLevelTemplate(-1);
+ }
LoadLevel_InitVersion(&level);
LoadLevel_InitElements(&level);
LoadLevel_InitNativeEngines(&level);
}
+void LoadLevel(int nr)
+{
+ setLevelFileInfo(&level.file_info, nr);
+
+ LoadLevel_LoadAndInit(NULL);
+}
+
void LoadLevelInfoOnly(int nr)
{
setLevelFileInfo(&level.file_info, nr);
LoadLevelFromFileInfo(&level, &level.file_info, TRUE);
}
+void LoadLevelFromNetwork(struct LevelFileInfo *lfi_network_level,
+ struct LevelFileInfo *lfi_network_template)
+{
+ copyLevelFileInfo(lfi_network_level, &level.file_info);
+
+ LoadLevel_LoadAndInit(lfi_network_template);
+}
+
static int SaveLevel_VERS(FILE *file, struct LevelInfo *level)
{
int chunk_size = 0;
NULL
};
+struct NetworkLevelFileInfo
+{
+ char *leveldir_identifier;
+ struct LevelFileInfo file_info;
+ struct LevelFileInfo tmpl_info;
+ boolean use_network_level_files;
+ boolean use_custom_template;
+};
+
/* server stuff */
static TCPsocket sfd; /* TCP server socket */
static boolean stop_network_client = FALSE;
static char stop_network_client_message[MAX_OUTPUT_LINESIZE + 1];
+static struct NetworkLevelFileInfo network_level;
+
static void DrawNetworkTextExt(char *message, int font_nr, boolean initialize)
{
static int xpos = 0, ypos = 0;
SendNetworkBufferToServer(write_buffer);
}
+void SendToServer_LevelFile()
+{
+ initNetworkBufferForWriting(write_buffer, OP_LEVEL_FILE, 0);
+
+ putNetworkBufferString( write_buffer, leveldir_current->identifier);
+ putNetworkBuffer16BitInteger(write_buffer, level.file_info.nr);
+ putNetworkBuffer8BitInteger( write_buffer, level.file_info.type);
+ putNetworkBuffer8BitInteger( write_buffer, level.file_info.packed);
+ putNetworkBufferString( write_buffer, level.file_info.basename);
+ putNetworkBufferFile( write_buffer, level.file_info.filename);
+ putNetworkBuffer8BitInteger( write_buffer, level.use_custom_template);
+
+ if (level.use_custom_template)
+ {
+ putNetworkBufferString(write_buffer, level_template.file_info.basename);
+ putNetworkBufferFile( write_buffer, level_template.file_info.filename);
+ }
+
+ SendNetworkBufferToServer(write_buffer);
+
+ setString(&network_level.leveldir_identifier, leveldir_current->identifier);
+
+ /* the sending client does not use network level files (but the real ones) */
+ network_level.use_network_level_files = FALSE;
+
+#if 0
+ printf("::: '%s'\n", leveldir_current->identifier);
+ printf("::: '%d'\n", level.file_info.nr);
+ printf("::: '%d'\n", level.file_info.type);
+ printf("::: '%d'\n", level.file_info.packed);
+ printf("::: '%s'\n", level.file_info.basename);
+ printf("::: '%s'\n", level.file_info.filename);
+
+ if (level.use_custom_template)
+ printf("::: '%s'\n", level_template.file_info.filename);
+#endif
+}
+
void SendToServer_StartPlaying()
{
unsigned int new_random_seed = InitRND(level.random_seed);
int new_level_nr = getNetworkBuffer16BitInteger(read_buffer);
unsigned int new_random_seed = getNetworkBuffer32BitInteger(read_buffer);
- LevelDirTree *new_leveldir =
- getTreeInfoFromIdentifier(leveldir_first, new_leveldir_identifier);
-
- if (new_leveldir == NULL)
+ if (!strEqual(new_leveldir_identifier, network_level.leveldir_identifier))
{
Error(ERR_WARN, "no such level identifier: '%s'", new_leveldir_identifier);
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);
+ player_nr, new_level_nr, new_leveldir_identifier);
+
+ LevelDirTree *new_leveldir =
+ getTreeInfoFromIdentifier(leveldir_first, new_leveldir_identifier);
- leveldir_current = new_leveldir;
- level_nr = new_level_nr;
+ if (new_leveldir != NULL)
+ {
+ leveldir_current = new_leveldir;
+ level_nr = new_level_nr;
+ }
TapeErase();
- LoadTape(level_nr);
- LoadLevel(level_nr);
+
+ if (network_level.use_network_level_files)
+ LoadLevelFromNetwork(&network_level.file_info,
+ &network_level.tmpl_info);
+ else
+ LoadLevel(level_nr);
StartGameActions(FALSE, setup.autorecord, new_random_seed);
}
Error(ERR_NETWORK_CLIENT, "client %d sends message", player_nr);
}
+static void Handle_OP_LEVEL_FILE()
+{
+ 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);
+
+ printf("OP_LEVEL_FILE: %d\n", player_nr);
+
+ leveldir_identifier = getStringCopy(getNetworkBufferString(read_buffer));
+ 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);
+
+ InitNetworkLevelDirectory(leveldir_identifier);
+
+ getNetworkBufferFile(read_buffer, 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);
+
+ getNetworkBufferFile(read_buffer, 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
+ printf("::: '%s'\n", leveldir_identifier);
+ printf("::: '%d'\n", file_info->nr);
+ printf("::: '%d'\n", file_info->type);
+ printf("::: '%d'\n", file_info->packed);
+ printf("::: '%s'\n", file_info->basename);
+ printf("::: '%s'\n", file_info->filename);
+
+ if (use_custom_template)
+ printf("::: '%s'\n", tmpl_info->filename);
+#endif
+}
+
static void HandleNetworkingMessage()
{
stop_network_game = FALSE;
Handle_OP_BROADCAST_MESSAGE();
break;
+ case OP_LEVEL_FILE:
+ Handle_OP_LEVEL_FILE();
+ break;
+
default:
if (options.verbose)
Error(ERR_NETWORK_CLIENT,