/// <summary> /// Loads settings and features from .xml file. /// </summary> /// <param name="stream"></param> public void LoadFromXml(Stream stream) { using (var xml = XmlReader.Create(stream)) { xml.ReadToFollowing("Settings"); using (var settingsXml = xml.ReadSubtree()) { while (settingsXml.ReadToFollowing("Setting")) { var setting = new FeaturesSetting(); setting.Name = settingsXml.GetAttribute("Name"); setting.Locale = settingsXml.GetAttribute("Locale"); setting.Test = Convert.ToBoolean(settingsXml.GetAttribute("Test")); setting.Development = Convert.ToBoolean(settingsXml.GetAttribute("Development")); setting.Generation = Convert.ToByte(settingsXml.GetAttribute("Generation")); setting.Season = Convert.ToByte(settingsXml.GetAttribute("Season")); setting.Subseason = Convert.ToByte(settingsXml.GetAttribute("Subseason")); _settings.Add(setting); } } xml.ReadToFollowing("Features"); using (var featuresXml = xml.ReadSubtree()) { while (featuresXml.ReadToFollowing("Feature")) { var feature = new FeaturesFeature(); feature.Hash = Convert.ToUInt32(featuresXml.GetAttribute("Hash") ?? featuresXml.GetAttribute("_Name"), 16); feature.Name = featuresXml.GetAttribute("Hash") != null?featuresXml.GetAttribute("Name") : featuresXml.GetAttribute("_RealName"); feature.Default = featuresXml.GetAttribute("Default"); feature.Enable = featuresXml.GetAttribute("Enable"); feature.Disable = featuresXml.GetAttribute("Disable"); var startTime = featuresXml.GetAttribute("StartTime"); var endTime = featuresXml.GetAttribute("EndTime"); if (startTime != null || endTime != null) { feature.StartTime = startTime; feature.EndTime = endTime; } _features.Add(feature); } } } }
/// <summary> /// Loads settings and features from compiled file. /// </summary> /// <author>Yiting</author> /// <param name="stream"></param> private void LoadFromCompiled(Stream stream) { var buffer = new byte[0x100]; var num = 0; if (stream.Read(buffer, 0, 2) != 2) { throw new EndOfStreamException(); } var settingCount = BitConverter.ToUInt16(buffer, 0); for (var i = 0; i < settingCount; i++) { var setting = new FeaturesSetting(); if (stream.Read(buffer, 0, 2) != 2) { throw new EndOfStreamException(); } num = BitConverter.ToUInt16(buffer, 0); if ((num <= 0) || (num > 0x100)) { throw new NotSupportedException(); } if (stream.Read(buffer, 0, num) != num) { throw new EndOfStreamException(); } for (var k = 0; k < num; k++) { buffer[k] = (byte)(buffer[k] ^ 0x80); } setting.Name = Encoding.UTF8.GetString(buffer, 0, num); if (stream.Read(buffer, 0, 2) != 2) { throw new EndOfStreamException(); } num = BitConverter.ToUInt16(buffer, 0); if (num <= 0 || num > 0x100) { throw new NotSupportedException(); } if (stream.Read(buffer, 0, num) != num) { throw new EndOfStreamException(); } for (var m = 0; m < num; m++) { buffer[m] = (byte)(buffer[m] ^ 0x80); } setting.Locale = Encoding.UTF8.GetString(buffer, 0, num); if (stream.Read(buffer, 0, 3) != 3) { throw new EndOfStreamException(); } setting.Generation = buffer[0]; setting.Season = buffer[1]; setting.Subseason = (byte)(buffer[2] >> 2); setting.Test = (buffer[2] & 1) != 0; setting.Development = (buffer[2] & 2) != 0; _settings.Add(setting); } if (stream.Read(buffer, 0, 2) != 2) { throw new EndOfStreamException(); } var featureCount = BitConverter.ToUInt16(buffer, 0); for (var j = 0; j < featureCount; j++) { var feature = new FeaturesFeature(); if (stream.Read(buffer, 0, 4) != 4) { throw new EndOfStreamException(); } feature.Hash = BitConverter.ToUInt32(buffer, 0); feature.Name = _featureNames.ContainsKey(feature.Hash) ? _featureNames[feature.Hash] : "?"; if (stream.Read(buffer, 0, 2) != 2) { throw new EndOfStreamException(); } num = BitConverter.ToUInt16(buffer, 0); if (num > 0x100) { throw new NotSupportedException(); } if (num > 0) { if (stream.Read(buffer, 0, num) != num) { throw new EndOfStreamException(); } for (var n = 0; n < num; n++) { buffer[n] = (byte)(buffer[n] ^ 0x80); } feature.Default = Encoding.UTF8.GetString(buffer, 0, num); } if (stream.Read(buffer, 0, 2) != 2) { throw new EndOfStreamException(); } num = BitConverter.ToUInt16(buffer, 0); if (num > 0x100) { throw new NotSupportedException(); } if (num > 0) { if (stream.Read(buffer, 0, num) != num) { throw new EndOfStreamException(); } for (var num9 = 0; num9 < num; num9++) { buffer[num9] = (byte)(buffer[num9] ^ 0x80); } feature.Enable = Encoding.UTF8.GetString(buffer, 0, num); } if (stream.Read(buffer, 0, 2) != 2) { throw new EndOfStreamException(); } num = BitConverter.ToUInt16(buffer, 0); if (num > 0x100) { throw new NotSupportedException(); } if (num > 0) { if (stream.Read(buffer, 0, num) != num) { throw new EndOfStreamException(); } for (var num10 = 0; num10 < num; num10++) { buffer[num10] = (byte)(buffer[num10] ^ 0x80); } feature.Disable = Encoding.UTF8.GetString(buffer, 0, num); } _features.Add(feature); } }
/// <summary> /// Loads settings and features from .compiled file. /// </summary> /// <author>Yiting</author> /// <param name="stream"></param> private void LoadFromCompiled(Stream stream) { var buffer = new byte[0x100]; var num = 0; if (stream.Read(buffer, 0, 2) != 2) throw new EndOfStreamException(); var settingCount = BitConverter.ToUInt16(buffer, 0); for (int i = 0; i < settingCount; i++) { var setting = new FeaturesSetting(); if (stream.Read(buffer, 0, 2) != 2) throw new EndOfStreamException(); num = BitConverter.ToUInt16(buffer, 0); if ((num <= 0) || (num > 0x100)) throw new NotSupportedException(); if (stream.Read(buffer, 0, num) != num) throw new EndOfStreamException(); for (int k = 0; k < num; k++) buffer[k] = (byte)(buffer[k] ^ 0x80); setting.Name = Encoding.UTF8.GetString(buffer, 0, num); if (stream.Read(buffer, 0, 2) != 2) throw new EndOfStreamException(); num = BitConverter.ToUInt16(buffer, 0); if (num <= 0 || num > 0x100) throw new NotSupportedException(); if (stream.Read(buffer, 0, num) != num) throw new EndOfStreamException(); for (int m = 0; m < num; m++) buffer[m] = (byte)(buffer[m] ^ 0x80); setting.Locale = Encoding.UTF8.GetString(buffer, 0, num); if (stream.Read(buffer, 0, 3) != 3) throw new EndOfStreamException(); setting.Generation = buffer[0]; setting.Season = buffer[1]; setting.Subseason = (byte)(buffer[2] >> 2); setting.Test = (buffer[2] & 1) != 0; setting.Development = (buffer[2] & 2) != 0; settings.Add(setting); } if (stream.Read(buffer, 0, 2) != 2) throw new EndOfStreamException(); var featureCount = BitConverter.ToUInt16(buffer, 0); for (int j = 0; j < featureCount; j++) { var feature = new FeaturesFeature(); if (stream.Read(buffer, 0, 4) != 4) throw new EndOfStreamException(); feature.Hash = BitConverter.ToUInt32(buffer, 0); feature.Name = featureNames.ContainsKey(feature.Hash) ? featureNames[feature.Hash] : "?"; if (stream.Read(buffer, 0, 2) != 2) throw new EndOfStreamException(); num = BitConverter.ToUInt16(buffer, 0); if (num > 0x100) throw new NotSupportedException(); if (num > 0) { if (stream.Read(buffer, 0, num) != num) throw new EndOfStreamException(); for (int n = 0; n < num; n++) buffer[n] = (byte)(buffer[n] ^ 0x80); feature.Default = Encoding.UTF8.GetString(buffer, 0, num); } if (stream.Read(buffer, 0, 2) != 2) throw new EndOfStreamException(); num = BitConverter.ToUInt16(buffer, 0); if (num > 0x100) throw new NotSupportedException(); if (num > 0) { if (stream.Read(buffer, 0, num) != num) throw new EndOfStreamException(); for (int num9 = 0; num9 < num; num9++) buffer[num9] = (byte)(buffer[num9] ^ 0x80); feature.Enable = Encoding.UTF8.GetString(buffer, 0, num); } if (stream.Read(buffer, 0, 2) != 2) throw new EndOfStreamException(); num = BitConverter.ToUInt16(buffer, 0); if (num > 0x100) throw new NotSupportedException(); if (num > 0) { if (stream.Read(buffer, 0, num) != num) throw new EndOfStreamException(); for (int num10 = 0; num10 < num; num10++) buffer[num10] = (byte)(buffer[num10] ^ 0x80); feature.Disable = Encoding.UTF8.GetString(buffer, 0, num); } features.Add(feature); } }
/// <summary> /// Loads settings and features from .xml file. /// </summary> /// <param name="stream"></param> public void LoadFromXml(Stream stream) { using (var xml = XmlReader.Create(stream)) { xml.ReadToFollowing("Settings"); using (var settingsXml = xml.ReadSubtree()) { while (settingsXml.ReadToFollowing("Setting")) { var setting = new FeaturesSetting(); setting.Name = settingsXml.GetAttribute("Name"); setting.Locale = settingsXml.GetAttribute("Locale"); setting.Test = Convert.ToBoolean(settingsXml.GetAttribute("Test")); setting.Development = Convert.ToBoolean(settingsXml.GetAttribute("Development")); setting.Generation = Convert.ToByte(settingsXml.GetAttribute("Generation")); setting.Season = Convert.ToByte(settingsXml.GetAttribute("Season")); setting.Subseason = Convert.ToByte(settingsXml.GetAttribute("Subseason")); settings.Add(setting); } } xml.ReadToFollowing("Features"); using (var featuresXml = xml.ReadSubtree()) { while (featuresXml.ReadToFollowing("Feature")) { var feature = new FeaturesFeature(); feature.Hash = Convert.ToUInt32(featuresXml.GetAttribute("Hash") ?? featuresXml.GetAttribute("_Name"), 16); feature.Name = featuresXml.GetAttribute("Hash") != null ? featuresXml.GetAttribute("Name") : featuresXml.GetAttribute("_RealName"); feature.Default = featuresXml.GetAttribute("Default"); feature.Enable = featuresXml.GetAttribute("Enable"); feature.Disable = featuresXml.GetAttribute("Disable"); features.Add(feature); } } } }
/// <summary> /// Loads settings and features from compiled file. /// </summary> /// <author>Yiting</author> /// <param name="stream"></param> private void LoadFromCompiled(Stream stream) { var buffer = new byte[0x100]; if (stream.Read(buffer, 0, 2) != 2) { throw new EndOfStreamException(); } var settingCount = BitConverter.ToUInt16(buffer, 0); for (var i = 0; i < settingCount; i++) { var setting = new FeaturesSetting(); setting.Name = this.ReadEncryptedLpString(stream); setting.Locale = this.ReadEncryptedLpString(stream); if (stream.Read(buffer, 0, 3) != 3) { throw new EndOfStreamException(); } setting.Generation = buffer[0]; setting.Season = buffer[1]; setting.Subseason = (byte)(buffer[2] >> 2); setting.Test = (buffer[2] & 1) != 0; setting.Development = (buffer[2] & 2) != 0; _settings.Add(setting); } if (stream.Read(buffer, 0, 2) != 2) { throw new EndOfStreamException(); } var featureCount = BitConverter.ToUInt16(buffer, 0); for (var j = 0; j < featureCount; j++) { var feature = new FeaturesFeature(); if (stream.Read(buffer, 0, 4) != 4) { throw new EndOfStreamException(); } feature.Hash = BitConverter.ToUInt32(buffer, 0); feature.Name = _featureNames.ContainsKey(feature.Hash) ? _featureNames[feature.Hash] : "?"; feature.Default = this.ReadEncryptedLpString(stream); feature.Enable = this.ReadEncryptedLpString(stream); feature.Disable = this.ReadEncryptedLpString(stream); // Determine version // In May 2022 they added two new strings here, which appear // to represent a start and an end time. Since these strings // are empty for the first feature, the next four bytes will // be 0 if we're reading the new format, otherwise they would // be the next hash. if (j == 0) { if (stream.Read(buffer, 0, 4) != 4) { throw new EndOfStreamException(); } if (BitConverter.ToUInt32(buffer, 0) == 0) { _formatVersion = 1; } // Rewind, so we can read the bytes again stream.Seek(-4, SeekOrigin.Current); } if (_formatVersion > 0) { feature.StartTime = this.ReadEncryptedLpString(stream); feature.EndTime = this.ReadEncryptedLpString(stream); } _features.Add(feature); } }