Add custom handling of Point serialization to fix startup crashes of tournament client

SixLabors moved their data types around in a recent update (see
https://github.com/ppy/osu-framework/pull/4025) and it was deemed that
we should prefer `System.Drawing` primitives where possible.

This was applied to the tournament client via
https://github.com/ppy/osu/pull/11072 without correct consideration
given to the fact that we serialize these types.

`System.Drawing.Point` serializes into a comma separated string, which
seems to be less correct than what we had, so I've switched back to the
old format for the time being. We can reasses this in the future; the
main goal here is to restore usability to the tournament client.

Closes #11443.
This commit is contained in:
Dean Herbert 2021-01-08 17:08:01 +09:00
parent 8df060ad6e
commit a6766e64de
2 changed files with 71 additions and 3 deletions

View File

@ -0,0 +1,67 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Diagnostics;
using System.Drawing;
using Newtonsoft.Json;
namespace osu.Game.Tournament
{
/// <summary>
/// We made a change from using SixLabors.ImageSharp.Point to System.Drawing.Point at some stage.
/// This handles converting to a standardised format on json serialize/deserialize operations.
/// </summary>
internal class JsonPointConverter : JsonConverter<Point>
{
public override void WriteJson(JsonWriter writer, Point value, JsonSerializer serializer)
{
// use the format of LaborSharp's Point since it is nicer.
serializer.Serialize(writer, new SixLabors.ImageSharp.Point(value.X, value.Y));
}
public override Point ReadJson(JsonReader reader, Type objectType, Point existingValue, bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.StartObject)
{
// if there's no object present then this is using string representation (System.Drawing.Point serializes to "x,y")
string str = (string)reader.Value;
Debug.Assert(str != null);
var split = str.Split(',');
return new Point(int.Parse(split[0]), int.Parse(split[1]));
}
var point = new Point();
while (reader.Read())
{
if (reader.TokenType == JsonToken.EndObject) break;
if (reader.TokenType == JsonToken.PropertyName)
{
var name = reader.Value?.ToString();
int? val = reader.ReadAsInt32();
if (val == null)
continue;
switch (name)
{
case "X":
point.X = val.Value;
break;
case "Y":
point.Y = val.Value;
break;
}
}
}
return point;
}
}
}

View File

@ -8,12 +8,12 @@ using Newtonsoft.Json;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input;
using osu.Framework.Platform;
using osu.Framework.IO.Stores;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Online.API.Requests;
using osu.Game.Tournament.IPC;
using osu.Game.Tournament.IO;
using osu.Game.Tournament.IPC;
using osu.Game.Tournament.Models;
using osu.Game.Users;
using osuTK.Input;
@ -60,7 +60,7 @@ namespace osu.Game.Tournament
{
using (Stream stream = storage.GetStream(bracket_filename, FileAccess.Read, FileMode.Open))
using (var sr = new StreamReader(stream))
ladder = JsonConvert.DeserializeObject<LadderInfo>(sr.ReadToEnd());
ladder = JsonConvert.DeserializeObject<LadderInfo>(sr.ReadToEnd(), new JsonPointConverter());
}
ladder ??= new LadderInfo();
@ -251,6 +251,7 @@ namespace osu.Game.Tournament
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
Converters = new JsonConverter[] { new JsonPointConverter() }
}));
}
}