176 lines
7.1 KiB
C#
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
|
|
}
|
|
}
|