public int ReadFrom(byte[] Buffer, int StartIndex = 0) { int cursor = StartIndex; uint sig = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; if (sig == SIGNATURE) { uint ver = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; uint entries = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; // decrypt old versions first (v4 first unencryted) // note: this might need different passwords for other versions if (ver <= VERSION3) { #if WINCLR && X86 uint streamlength = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; uint expectedresponse = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; Crush32.Decrypt(Buffer, cursor, (int)streamlength, ver, expectedresponse, PASSWORDV3); #else throw new Exception(RooFile.ERRORCRUSHPLATFORM); #endif } // now load strings StringResources.Clear(); for (int i = 0; i < entries; i++) { uint ID = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; // look for terminating 0x00 (NULL) ushort strlen = 0; while ((Buffer.Length > cursor + strlen) && Buffer[cursor + strlen] != 0x00) { strlen++; } string Value = Encoding.Default.GetString(Buffer, cursor, strlen); cursor += strlen + TypeSizes.BYTE; StringResources.TryAdd(ID, Value); } } else { throw new Exception("Wrong RSC file signature: " + sig + " (expected " + SIGNATURE + ")."); } return(cursor - StartIndex); }
/// <summary> /// Clears and reloads the strings from another dictionary file within the strings folder, /// which was previously initialized during Init() /// </summary> /// <param name="RsbFile">Plain filename, like rsc0000.rsb</param> /// <param name="Language"></param> public void SelectStringDictionary(string RsbFile, LanguageCode Language) { // clear old entries StringResources.Clear(); // set preferred language StringResources.Language = Language; // try get the dictionary for argument RsbFile file = GetStringDictionary(RsbFile); // load strings of the rsbfile to use // into the multithreaded dictionary if (file != null) { foreach (RsbResourceID res in file.StringResources) { StringResources.TryAdd(res.ID, res.Text, res.Language); } } // raise event if (StringDictionarySelected != null) { StringDictionarySelected(this, new EventArgs()); } }
public int ReadFrom(byte[] Buffer, int StartIndex = 0) { int cursor = StartIndex; uint sig = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; if (sig == SIGNATURE) { version = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; uint entries = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; // decrypt old versions first (v4 first unencryted) // note: this might need different passwords for other versions if (version <= VERSION3) { #if WINCLR && X86 uint streamlength = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; uint expectedresponse = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; Crush32.Decrypt(Buffer, cursor, (int)streamlength, version, expectedresponse, PASSWORDV3); #else throw new Exception(RooFile.ERRORCRUSHPLATFORM); #endif } // now load strings StringResources.Clear(); StringResources.Capacity = (int)entries + 100; for (int i = 0; i < entries; i++) { RsbResourceID entry = new RsbResourceID(version, Buffer, cursor); cursor += entry.ByteLength; StringResources.Add(entry); } } else { throw new Exception("Wrong RSC file signature: " + sig + " (expected " + SIGNATURE + ")."); } return(cursor - StartIndex); }
/// <summary> /// Clears and reloads the strings from another dictionary file. /// </summary> /// <param name="RsbFile"></param> public void ReloadStrings(string RsbFile) { // update stringfile Config.StringResourcesFile = RsbFile; // clear old entries StringResources.Clear(); // check if new string dictionary exists if (File.Exists(Config.StringResourcesFile)) { // load string resources RsbFile rsbFile = new RsbFile(Config.StringResourcesFile); // add to dictionary foreach (KeyValuePair <uint, string> pair in rsbFile.StringResources) { StringResources.TryAdd(pair.Key, pair.Value); } } }
/// <summary> /// Clears and reloads the strings from another dictionary file within the strings folder, /// which was previously initialized during Init() /// </summary> /// <param name="RsbFile">Plain filename, like rsc0000.rsb</param> /// <param name="Language"></param> public void SelectStringDictionary(string RsbFile, LanguageCode Language) { // clear old entries StringResources.Clear(); // set preferred language StringResources.Language = Language; // Save the MD5 hash of this rsb file as our RsbHash. byte[] rsbMD5Hash = MeridianMD5.ComputeGenericFileMD5(StringsFolder + "/" + RsbFile); Hash128Bit rsbHash = new Hash128Bit(); rsbHash.HASH1 = BitConverter.ToUInt32(rsbMD5Hash, 0); rsbHash.HASH2 = BitConverter.ToUInt32(rsbMD5Hash, 4); rsbHash.HASH3 = BitConverter.ToUInt32(rsbMD5Hash, 8); rsbHash.HASH4 = BitConverter.ToUInt32(rsbMD5Hash, 12); RsbHash = rsbHash; // try get the dictionary for argument RsbFile file = GetStringDictionary(RsbFile); // load strings of the rsbfile to use // into the multithreaded dictionary if (file != null) { foreach (RsbResourceID res in file.StringResources) { StringResources.TryAdd(res.ID, res.Text, res.Language); } } // raise event if (StringDictionarySelected != null) { StringDictionarySelected(this, new EventArgs()); } }
/// <summary> /// Sets pathes to required resources. /// Will also remove any existing resources from the current lists. /// </summary> /// <param name="PathStrings"></param> /// <param name="PathRooms"></param> /// <param name="PathObjects"></param> /// <param name="PathRoomTextures"></param> /// <param name="PathSounds"></param> /// <param name="PathMusic"></param> /// <param name="PathMails"></param> public void Init( string PathStrings, string PathRooms, string PathObjects, string PathRoomTextures, string PathSounds, string PathMusic, string PathMails) { this.StringsFolder = PathStrings; this.RoomsFolder = PathRooms; this.ObjectsFolder = PathObjects; this.RoomTexturesFolder = PathRoomTextures; this.WavFolder = PathSounds; this.MusicFolder = PathMusic; this.MailFolder = PathMails; string[] files; // already executed once? if (Initialized) { StringResources.Clear(); StringDictionaries.Clear(); Objects.Clear(); RoomTextures.Clear(); Rooms.Clear(); Wavs.Clear(); Music.Clear(); // detach mail listener so we don't delete them Mails.ListChanged -= OnMailsListChanged; // clear our objects Mails.Clear(); } // register string dictionaries for different servers if (Directory.Exists(StringsFolder)) { // get available files files = Directory.GetFiles(StringsFolder, '*' + FileExtensions.RSB); foreach (string s in files) { StringDictionaries.TryAdd(Path.GetFileName(s), null); } } else { Directory.CreateDirectory(StringsFolder); } // register objects if (Directory.Exists(ObjectsFolder)) { // get available files files = Directory.GetFiles(ObjectsFolder, '*' + FileExtensions.BGF); foreach (string s in files) { string filename = Path.GetFileName(s); if (!filename.StartsWith("grd")) { Objects.TryAdd(filename, null); } } } else { Directory.CreateDirectory(ObjectsFolder); } // register roomtextures if (Directory.Exists(RoomTexturesFolder)) { // get available files files = Directory.GetFiles(RoomTexturesFolder, "grd*" + FileExtensions.BGF); foreach (string s in files) { RoomTextures.TryAdd(Path.GetFileName(s), null); } } else { Directory.CreateDirectory(RoomTexturesFolder); } // register rooms if (Directory.Exists(RoomsFolder)) { // get available files files = Directory.GetFiles(RoomsFolder, '*' + FileExtensions.ROO); foreach (string s in files) { Rooms.TryAdd(Path.GetFileName(s), null); } } else { Directory.CreateDirectory(RoomsFolder); } // register wav sounds if (Directory.Exists(WavFolder)) { // get available files files = Directory.GetFiles(WavFolder, '*' + FileExtensions.OGG); foreach (string s in files) { Wavs.TryAdd(Path.GetFileName(s), null); } } else { Directory.CreateDirectory(WavFolder); } // register music if (Directory.Exists(MusicFolder)) { // get available files files = Directory.GetFiles(MusicFolder, '*' + FileExtensions.OGG); foreach (string s in files) { Music.TryAdd(Path.GetFileName(s), null); } } else { Directory.CreateDirectory(MusicFolder); } // load mails if (Directory.Exists(MailFolder)) { // read available mail files files = Directory.GetFiles(MailFolder, '*' + FileExtensions.XML); foreach (string s in files) { // create mail object Mail mail = new Mail(); // load values from xml mail.Load(s); #if !VANILLA && !OPENMERIDIAN // Fix timestamp if necessary and write out mail. if (!mail.IsTimestampUpdated) { mail.Timestamp += MeridianDate.CONVERTOFFSET; mail.IsTimestampUpdated = true; mail.Save(s); } #endif // add to list Mails.Add(mail); } } else { Directory.CreateDirectory(MailFolder); } // hookup mails listener to write/delete the files Mails.ListChanged += OnMailsListChanged; // forced GC collection Util.ForceMaximumGC(); // mark initialized Initialized = true; }
/// <summary> /// Sets pathes to required resources. /// Will also remove any existing resources from the current lists. /// </summary> /// <param name="PathStrings"></param> /// <param name="PathRooms"></param> /// <param name="PathObjects"></param> /// <param name="PathRoomTextures"></param> /// <param name="PathSounds"></param> /// <param name="PathMusic"></param> /// <param name="PathMails"></param> public void Init( string PathStrings, string PathRooms, string PathObjects, string PathRoomTextures, string PathSounds, string PathMusic, string PathMails) { this.StringsFolder = PathStrings; this.RoomsFolder = PathRooms; this.ObjectsFolder = PathObjects; this.RoomTexturesFolder = PathRoomTextures; this.WavFolder = PathSounds; this.MusicFolder = PathMusic; this.MailFolder = PathMails; string[] files; // already executed once? if (Initialized) { StringResources.Clear(); StringDictionaries.Clear(); Objects.Clear(); RoomTextures.Clear(); Rooms.Clear(); Wavs.Clear(); Music.Clear(); // detach mail listener so we don't delete them Mails.ListChanged -= OnMailsListChanged; // clear our objects Mails.Clear(); } // register string dictionaries for different servers if (Directory.Exists(StringsFolder)) { // get available files files = Directory.GetFiles(StringsFolder, '*' + FileExtensions.RSB); foreach (string s in files) { StringDictionaries.TryAdd(Path.GetFileName(s), null); } } // register objects if (Directory.Exists(ObjectsFolder)) { // get available files files = Directory.GetFiles(ObjectsFolder, '*' + FileExtensions.BGF); foreach (string s in files) { string filename = Path.GetFileName(s); if (!filename.StartsWith("grd")) { Objects.TryAdd(filename, null); } } } // register roomtextures if (Directory.Exists(RoomTexturesFolder)) { // get available files files = Directory.GetFiles(RoomTexturesFolder, "grd*" + FileExtensions.BGF); foreach (string s in files) { RoomTextures.TryAdd(Path.GetFileName(s), null); } } // register rooms if (Directory.Exists(RoomsFolder)) { // get available files files = Directory.GetFiles(RoomsFolder, '*' + FileExtensions.ROO); foreach (string s in files) { Rooms.TryAdd(Path.GetFileName(s), null); } } // register wav sounds if (Directory.Exists(WavFolder)) { // get available files files = Directory.GetFiles(WavFolder, '*' + FileExtensions.OGG); foreach (string s in files) { Wavs.TryAdd(Path.GetFileName(s), null); } } // register music if (Directory.Exists(MusicFolder)) { // get available files files = Directory.GetFiles(MusicFolder, '*' + FileExtensions.OGG); foreach (string s in files) { Music.TryAdd(Path.GetFileName(s), null); } } // load mails if (Directory.Exists(MailFolder)) { // read available mail files files = Directory.GetFiles(MailFolder, '*' + FileExtensions.XML); foreach (string s in files) { // create mail object Mail mail = new Mail(); // load values from xml mail.Load(s); // add to list Mails.Add(mail); } } // hookup mails listener to write/delete the files Mails.ListChanged += OnMailsListChanged; // forced GC collection GC.Collect(2); // mark initialized Initialized = true; }
/// <summary> /// Initializes the ResourceManager from given config. /// </summary> /// <param name="Config"></param> public void InitConfig(ResourceManagerConfig Config) { string[] files; // save new config this.Config = Config; // already executed once? if (Initialized) { // clear current string dictionary StringResources.Clear(); // clear current lookup dictionaries Objects.Clear(); RoomTextures.Clear(); Rooms.Clear(); Wavs.Clear(); Music.Clear(); // detach mail listener so we don't delete them Mails.ListChanged -= OnMailsListChanged; // clear our objects Mails.Clear(); } // register strings if (File.Exists(Config.StringResourcesFile)) { // load string resources RsbFile rsbFile = new RsbFile(Config.StringResourcesFile); // add to dictionary foreach (KeyValuePair <uint, string> pair in rsbFile.StringResources) { StringResources.TryAdd(pair.Key, pair.Value); } } // register objects if (Directory.Exists(Config.ObjectsFolder)) { // get available files files = Directory.GetFiles(Config.ObjectsFolder, '*' + FileExtensions.BGF); foreach (string s in files) { string filename = Path.GetFileName(s); if (!filename.StartsWith("grd")) { Objects.TryAdd(filename, null); } } } // register roomtextures if (Directory.Exists(Config.RoomTexturesFolder)) { // get available files files = Directory.GetFiles(Config.RoomTexturesFolder, "grd*" + FileExtensions.BGF); foreach (string s in files) { RoomTextures.TryAdd(Path.GetFileName(s), null); } } // register rooms if (Directory.Exists(Config.RoomsFolder)) { // get available files files = Directory.GetFiles(Config.RoomsFolder, '*' + FileExtensions.ROO); foreach (string s in files) { Rooms.TryAdd(Path.GetFileName(s), null); } } // register wav sounds if (Directory.Exists(Config.WavFolder)) { // get available files files = Directory.GetFiles(Config.WavFolder, '*' + FileExtensions.WAV); foreach (string s in files) { Wavs.TryAdd(Path.GetFileName(s), null); } } // register music if (Directory.Exists(Config.MusicFolder)) { // get available files files = Directory.GetFiles(Config.MusicFolder, '*' + FileExtensions.MP3); foreach (string s in files) { Music.TryAdd(Path.GetFileName(s), null); } } // load mails if (Directory.Exists(Config.MailFolder)) { // read available mail files files = Directory.GetFiles(Config.MailFolder, '*' + FileExtensions.XML); foreach (string s in files) { // create mail object Mail mail = new Mail(); // load values from xml mail.Load(s); // add to list Mails.Add(mail); } } // hookup mails listener to write/delete the files Mails.ListChanged += OnMailsListChanged; // forced GC collection GC.Collect(2); // mark initialized Initialized = true; }