From 2a141dd1fe874d185377fe27ac61a133f179a612 Mon Sep 17 00:00:00 2001 From: skittles1 Date: Sun, 21 Feb 2016 22:13:17 +0800 Subject: [PATCH] Add server-specific .roo file loading. There are now 3 OpenMeridian servers open and due to differing update schedules and content, the same .roo file may be different on each server. Currently this is the case for Raza, where the version of the city (7 rooms anyway) is different on 103/112 and 105. To allow the single Ogre client to work on all 3 servers, I have changed .roo loading to first check a server-specific folder (currently this is the server name/number) for any .roo files before checking the parent rooms directory. 103 would have its changed rooms in \rooms\103\, 105 in \rooms\105\ etc. Specifically preloading rooms on client startup has been removed (default .roos are still loaded in Init) and when a user tries to connect to a server, the additional .roos are loaded and if preloading rooms is enabled, this occurs in the same thread. The server's name/number is saved as RoomsSubFolder for future use on room loads, and for removing the extra rooms from the Rooms dictionary if the user switches between servers. --- Meridian59.Ogre.Client/OgreClient.cpp | 1 - Meridian59/Client/BaseClient.cs | 3 + Meridian59/Files/ResourceManager.cs | 124 +++++++++++++++++++------- 3 files changed, 95 insertions(+), 33 deletions(-) diff --git a/Meridian59.Ogre.Client/OgreClient.cpp b/Meridian59.Ogre.Client/OgreClient.cpp index e10c6e5f..b0d6ee32 100644 --- a/Meridian59.Ogre.Client/OgreClient.cpp +++ b/Meridian59.Ogre.Client/OgreClient.cpp @@ -654,7 +654,6 @@ namespace Meridian59 { namespace Ogre ResourceManager->Preload( Config->PreloadObjects, Config->PreloadRoomTextures, - Config->PreloadRooms, Config->PreloadSound, Config->PreloadMusic); diff --git a/Meridian59/Client/BaseClient.cs b/Meridian59/Client/BaseClient.cs index 5fcee78f..31069793 100644 --- a/Meridian59/Client/BaseClient.cs +++ b/Meridian59/Client/BaseClient.cs @@ -116,6 +116,9 @@ public virtual void Connect() Config.SelectedConnectionInfo.StringDictionary, LanguageCode.English); // todo: from config + // Load server-specific rooms if needed + ResourceManager.AddServerRooms(Config.SelectedConnectionInfo.Name, Config.PreloadRooms); + // fill ignore list in datacontroller with ignored // playernames for this connectionentry. Data.IgnoreList.Clear(); diff --git a/Meridian59/Files/ResourceManager.cs b/Meridian59/Files/ResourceManager.cs index 97c222b3..3c6ae6d7 100644 --- a/Meridian59/Files/ResourceManager.cs +++ b/Meridian59/Files/ResourceManager.cs @@ -120,6 +120,11 @@ public class ResourceManager /// public string RoomsFolder { get; set; } + /// + /// Folder containing server-specific .roo files. + /// + public string RoomsSubFolder { get; set; } + /// /// Folder containing all object BGFs /// @@ -221,9 +226,13 @@ public RooFile GetRoom(string File) { // haven't loaded it yet? if (rooFile == null) - { + { // load it - rooFile = new RooFile(RoomsFolder + "/" + File); + if (!String.IsNullOrEmpty(RoomsSubFolder) + && System.IO.File.Exists(RoomsFolder + "/" + RoomsSubFolder + "/" + File)) + rooFile = new RooFile(RoomsFolder + "/" + RoomsSubFolder + "/" + File); + else + rooFile = new RooFile(RoomsFolder + "/" + File); // resolve resource references (may load texture bgfs) rooFile.ResolveResources(this); @@ -523,19 +532,97 @@ public void SelectStringDictionary(string RsbFile, LanguageCode Language) StringDictionarySelected(this, new EventArgs()); } + /// + /// Adds server-specific rooms to the Rooms dictionary, and + /// loads all rooms if room preloading is enabled. If we already + /// have server-specific rooms loaded, unload them and reload + /// the correct room (if one exists). + /// + /// + /// + public void AddServerRooms(string serverNum, bool preloadRooms) + { + string[] files; + string subFolder; + RooFile r; + + // RoomsSubFolder is set and not equal to the server number (subfolder) we + // now have. Need to remove the previous server-specific rooms and add the + // default ones in place of them. + if (!String.IsNullOrEmpty(RoomsSubFolder) && !RoomsSubFolder.Equals(serverNum)) + { + subFolder = Path.Combine(RoomsFolder, RoomsSubFolder); + if (Directory.Exists(subFolder)) + { + files = Directory.GetFiles(subFolder, '*' + FileExtensions.ROO); + foreach (string s in files) + { + // Remove the old server-specific files. + Rooms.TryRemove(Path.GetFileName(s), out r); + // Try to add from default folder. Check for existence as the + // previous room may not have a default. + if (System.IO.File.Exists(Path.Combine(RoomsFolder, Path.GetFileName(s)))) + Rooms.TryAdd(Path.GetFileName(s), null); + } + } + } + + subFolder = Path.Combine(RoomsFolder, serverNum); + // Now check for a new subfolder, and add any .roo files. + if (Directory.Exists(subFolder)) + { + files = Directory.GetFiles(subFolder, '*' + FileExtensions.ROO); + + foreach (string s in files) + { + // Try to remove the room if already added to the dictionary, + // then add the server-specific one. + Rooms.TryRemove(Path.GetFileName(s), out r); + Rooms.TryAdd(Path.GetFileName(s), null); + } + } + + // Save the subfolder identifying string for future room loading/resetting. + RoomsSubFolder = serverNum; + + // Preload if user has chosen to do so. + if (preloadRooms) + LoadRooms(); + } + + /// + /// Loads rooms before connecting if user has chosen to preload. + /// + protected void LoadRooms() + { + IEnumerator> it = Rooms.GetEnumerator(); + RooFile file; + + while (it.MoveNext()) + { + // load + if (!String.IsNullOrEmpty(RoomsSubFolder) + && System.IO.File.Exists(Path.Combine(RoomsFolder, RoomsSubFolder, it.Current.Key))) + file = new RooFile(Path.Combine(RoomsFolder, RoomsSubFolder, it.Current.Key)); + else + file = new RooFile(Path.Combine(RoomsFolder, it.Current.Key)); + + // update + Rooms.TryUpdate(it.Current.Key, file, null); + } + } + /// /// Starts preloading resources in several threads. /// /// /// - /// /// /// - public void Preload(bool Objects, bool RoomTextures, bool Rooms, bool Sounds, bool Music) + public void Preload(bool Objects, bool RoomTextures, bool Sounds, bool Music) { Thread threadObjects = null; Thread threadRoomTextures = null; - Thread threadRooms = null; Thread threadSounds = null; Thread threadMusic = null; @@ -554,12 +641,6 @@ public void Preload(bool Objects, bool RoomTextures, bool Rooms, bool Sounds, bo threadRoomTextures.Start(); } - if (Rooms) - { - threadRooms = new Thread(LoadThreadRooms); - threadRooms.Start(); - } - if (Sounds) { threadSounds = new Thread(LoadThreadSounds); @@ -577,7 +658,6 @@ public void Preload(bool Objects, bool RoomTextures, bool Rooms, bool Sounds, bo // lock until all loaders are finished while ( (threadObjects != null && threadObjects.IsAlive) || (threadRoomTextures != null && threadRoomTextures.IsAlive) || - (threadRooms != null && threadRooms.IsAlive) || (threadSounds != null && threadSounds.IsAlive) || (threadMusic != null && threadMusic.IsAlive)) { @@ -637,26 +717,6 @@ protected void LoadThreadRoomTextures() } } - /// - /// Stars loading all rooms in a background thread. - /// - protected void LoadThreadRooms() - { - IEnumerator> it = Rooms.GetEnumerator(); - RooFile file; - - while (it.MoveNext()) - { - // load - file = new RooFile(Path.Combine(RoomsFolder, it.Current.Key)); - - // update - Rooms.TryUpdate(it.Current.Key, file, null); - - queueAsyncFilesLoaded.Enqueue(it.Current.Key); - } - } - /// /// Stars loading all sounds in a background thread. ///