mirror of
https://github.com/ppy/osu
synced 2025-01-01 03:42:19 +00:00
Serialise and deserialise SkinInfo.InstantiationInfo
to allow for more correct imports
Until now, skins were always imported using the `LegacySkin` instantiation type. For cases where a user has edited the lazer or classic default (via the new skin editor), which would result in incorrect fallback paths after exporting and importing the edited skin.
This commit is contained in:
parent
b976848774
commit
cdf2fa9930
@ -24,6 +24,8 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
public class SkinModelManager : RealmArchiveModelManager<SkinInfo>
|
||||
{
|
||||
private const string skin_info_file = "skininfo.json";
|
||||
|
||||
private readonly IStorageResourceProvider skinResources;
|
||||
|
||||
public SkinModelManager(Storage storage, RealmContextFactory contextFactory, GameHost host, IStorageResourceProvider skinResources)
|
||||
@ -49,8 +51,36 @@ namespace osu.Game.Skinning
|
||||
|
||||
protected override Task Populate(SkinInfo model, ArchiveReader? archive, Realm realm, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrEmpty(model.InstantiationInfo))
|
||||
model.InstantiationInfo = createInstance(model).GetType().GetInvariantInstantiationInfo();
|
||||
var skinInfoFile = model.Files.SingleOrDefault(f => f.Filename == skin_info_file);
|
||||
|
||||
if (skinInfoFile != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var existingStream = Files.Storage.GetStream(skinInfoFile.File.GetStoragePath()))
|
||||
using (var reader = new StreamReader(existingStream))
|
||||
{
|
||||
var deserialisedSkinInfo = JsonConvert.DeserializeObject<SkinInfo>(reader.ReadToEnd());
|
||||
|
||||
if (deserialisedSkinInfo != null)
|
||||
{
|
||||
// for now we only care about the instantiation info.
|
||||
// eventually we probably want to transfer everything across.
|
||||
model.InstantiationInfo = deserialisedSkinInfo.InstantiationInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogForModel(model, $"Error during {skin_info_file} parsing, falling back to default", e);
|
||||
|
||||
// Not sure if we should still run the import in the case of failure here, but let's do so for now.
|
||||
model.InstantiationInfo = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
// Always rewrite instantiation info (even after parsing in from the skin json) for sanity.
|
||||
model.InstantiationInfo = createInstance(model).GetType().GetInvariantInstantiationInfo();
|
||||
|
||||
checkSkinIniMetadata(model, realm);
|
||||
|
||||
@ -203,6 +233,15 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
skin.SkinInfo.PerformWrite(s =>
|
||||
{
|
||||
// Serialise out the SkinInfo itself.
|
||||
string skinInfoJson = JsonConvert.SerializeObject(s, new JsonSerializerSettings { Formatting = Formatting.Indented });
|
||||
|
||||
using (var streamContent = new MemoryStream(Encoding.UTF8.GetBytes(skinInfoJson)))
|
||||
{
|
||||
AddFile(s, streamContent, skin_info_file, s.Realm);
|
||||
}
|
||||
|
||||
// Then serialise each of the drawable component groups into respective files.
|
||||
foreach (var drawableInfo in skin.DrawableComponentInfo)
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(drawableInfo.Value, new JsonSerializerSettings { Formatting = Formatting.Indented });
|
||||
|
Loading…
Reference in New Issue
Block a user