JD2022-TU1/main/tools/services/JD.MicrosoftAchievement.Service/MicrosoftAchievementService.cs

176 lines
7.1 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;
using JD.MicrosoftAchievement.Service.Extension;
using Plume.Interfaces.Services;
namespace JD.MicrosoftAchievement.Service
{
public sealed class MicrosoftAchievementService : IMicrosoftAchievementService
{
#region IMicrosoftAchievementService
public Task<Achievement[]> ReadAchievementsAsync(string settingsFilePath) => Task.Run(() =>
{
if (settingsFilePath is null)
{
throw new ArgumentNullException(nameof(settingsFilePath));
}
if (!File.Exists(settingsFilePath))
{
throw new ArgumentException($"Settings file \"{settingsFilePath}\" does not exists", nameof(settingsFilePath));
}
List<Achievement> achievements = new List<Achievement>();
using (ZipArchive archive = ZipFile.OpenRead(settingsFilePath))
{
ZipArchiveEntry entry = archive.Entries.FirstOrDefault(e => e.Name == "achievements2017.xml");
if (entry is null) throw new ArgumentException($"Could not find \"achievements2017.xml\" in settings file \"{settingsFilePath}\"", nameof(settingsFilePath));
using (Stream stream = entry.Open())
{
XDocument document = XDocument.Load(stream);
foreach (XElement element in document.Root.GetElements("Achievement"))
{
achievements.Add(new Achievement(
int.TryParse(element.GetElement("AchievementId")?.Value, out int id) ? id : -1,
element.GetElement("AchievementNameId")?.Value,
element.GetElement("LockedDescriptionId")?.Value,
element.GetElement("UnlockedDescriptionId")?.Value,
element.GetElement("IsHidden")?.Value == "true",
element.GetElement("BaseAchievement")?.Value == "true",
int.TryParse(element.GetElement("Rewards").GetElement("Gamerscore")?.Value, out int gamerscore) ? gamerscore : 0));
}
}
}
return achievements.ToArray();
});
public Task UpdateAchievementsAsync(string settingsFilePath, Achievement[] achievements) => Task.Run(() =>
{
if (settingsFilePath is null)
{
throw new ArgumentNullException(nameof(settingsFilePath));
}
if (achievements is null)
{
throw new ArgumentNullException(nameof(achievements));
}
if (!File.Exists(settingsFilePath))
{
throw new ArgumentException($"Settings file \"{settingsFilePath}\" does not exist", nameof(settingsFilePath));
}
FileInfo settingsFile = new FileInfo(settingsFilePath);
settingsFile.Attributes &= ~FileAttributes.ReadOnly;
using (ZipArchive archive = ZipFile.Open(settingsFilePath, ZipArchiveMode.Update))
{
ZipArchiveEntry entry = archive.Entries.FirstOrDefault(e => e.FullName == "achievements2017.xml");
if (entry is null) throw new ArgumentException($"Could not find \"achievements2017.xml\" in settings file \"{settingsFilePath}\"", nameof(settingsFilePath));
XDocument document;
using (Stream stream = entry.Open())
{
document = XDocument.Load(stream);
}
Dictionary<int, Achievement> achievementsById = achievements.ToDictionary(a => a.Id);
foreach (XElement element in document.Root.GetElements("Achievement"))
{
if (int.TryParse(element.GetElement("AchievementId")?.Value, out int id)
&& achievementsById.TryGetValue(id, out Achievement achievement))
{
element.UpdateOrAddElement("IsHidden", achievement.IsSecret ? "true" : "false");
element.UpdateOrAddElement("BaseAchievement", achievement.IsBaseAchievement ? "true" : "false");
element.UpdateOrAddElement("Rewards", null).UpdateOrAddElement("Gamerscore", achievement.Gamerscore.ToString());
}
}
entry.Delete();
using (Stream stream = archive.CreateEntry(entry.Name).Open())
{
document.Save(stream);
}
}
});
public Task UpdateLocalizationAsync(string settingsFilePath, LocalizedString[] localizedStrings) => Task.Run(() =>
{
if (settingsFilePath is null)
{
throw new ArgumentNullException(nameof(settingsFilePath));
}
if (localizedStrings is null)
{
throw new ArgumentNullException(nameof(localizedStrings));
}
if (!File.Exists(settingsFilePath))
{
throw new ArgumentException($"Settings file \"{settingsFilePath}\" does not exists", nameof(settingsFilePath));
}
FileInfo settingsFile = new FileInfo(settingsFilePath);
settingsFile.Attributes &= ~FileAttributes.ReadOnly;
using (ZipArchive archive = ZipFile.Open(settingsFilePath, ZipArchiveMode.Update))
{
ZipArchiveEntry entry = archive.Entries.FirstOrDefault(e => e.FullName == "localization.xml");
if (entry is null) throw new ArgumentException($"Could not find \"localization.xml\" in settings file \"{settingsFilePath}\"", nameof(settingsFilePath));
XDocument document;
using (Stream stream = entry.Open())
{
document = XDocument.Load(stream);
}
Dictionary<string, LocalizedString> localizedStringsById = localizedStrings.ToDictionary(a => a.Id);
foreach (XElement element in document.Root.GetElements("LocalizedString"))
{
if (localizedStringsById.TryGetValue(element.Attribute("id")?.Value, out LocalizedString localizedString))
{
element.RemoveNodes();
foreach (KeyValuePair<string, string> pair in localizedString.Values)
{
element.AddElement("Value", pair.Value).SetAttributeValue("locale", pair.Key);
}
}
}
entry.Delete();
using (Stream stream = archive.CreateEntry(entry.Name).Open())
{
document.Save(stream);
}
}
});
#endregion
#region IService
public void Initialize(IServiceContext serviceContext)
{ }
#endregion
#region IDisposable
public void Dispose()
{ }
#endregion
}
}