-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSettingsJsonConverter.cs
222 lines (181 loc) · 8.92 KB
/
SettingsJsonConverter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using PearlCalculatorLib.General;
using PearlCalculatorLib.PearlCalculationLib.Entity;
using PearlCalculatorLib.PearlCalculationLib.World;
namespace PearlCalculatorBlazor;
public class SettingsJsonConverter : JsonConverter<Settings>
{
private readonly Space3DJsonConverter _space3DJsonConverter = new();
public override Settings Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using var document = JsonDocument.ParseValue(ref reader);
var rootElement = document.RootElement;
// If the root element has a "Version" property, it's an app version, otherwise it's a web version
return rootElement.TryGetProperty("Version", out _)
? ReadAppSettings(rootElement)
: ReadOldFormatSettings(rootElement);
}
private Settings ReadOldFormatSettings(JsonElement rootElement)
{
var settings = new Settings();
settings.NorthEastTNT = ReadSpace3D(rootElement.GetProperty(nameof(settings.NorthEastTNT)));
settings.NorthWestTNT = ReadSpace3D(rootElement.GetProperty(nameof(settings.NorthWestTNT)));
settings.SouthEastTNT = ReadSpace3D(rootElement.GetProperty(nameof(settings.SouthEastTNT)));
settings.SouthWestTNT = ReadSpace3D(rootElement.GetProperty(nameof(settings.SouthWestTNT)));
var pearlElemRoot = rootElement.GetProperty(nameof(settings.Pearl));
settings.Pearl = new PearlEntity
{
Position = ReadSpace3D(pearlElemRoot.GetProperty(nameof(settings.Pearl.Position))),
Motion = ReadSpace3D(pearlElemRoot.GetProperty(nameof(settings.Pearl.Motion)))
};
settings.RedTNT = rootElement.GetProperty(nameof(settings.RedTNT)).GetInt32();
settings.BlueTNT = rootElement.GetProperty(nameof(settings.BlueTNT)).GetInt32();
settings.MaxTNT = rootElement.GetProperty(nameof(settings.MaxTNT)).GetInt32();
settings.Destination = ReadSpace3D(rootElement.GetProperty(nameof(settings.Destination)));
settings.Offset = ReadSurface2D(rootElement.GetProperty(nameof(settings.Offset)));
settings.Direction = ReadDirection(
rootElement,
nameof(settings.Direction), Direction.North
);
settings.DefaultRedTNTDirection = ReadDirection(
rootElement,
nameof(settings.DefaultRedTNTDirection),
Direction.SouthEast
);
settings.DefaultBlueTNTDirection = ReadDirection(
rootElement,
nameof(settings.DefaultBlueTNTDirection),
Direction.NorthWest
);
// For null safety
settings.PearlYMotionCancellation = rootElement.TryGetProperty(
nameof(settings.PearlYMotionCancellation), out var elem) && elem.GetBoolean();
settings.PearlYPositionOriginal = rootElement.TryGetProperty(
nameof(settings.PearlYPositionOriginal), out elem)
? elem.GetDouble()
: settings.Pearl.Position.Y;
settings.PearlYPositionAdjusted = rootElement.TryGetProperty(
nameof(settings.PearlYPositionAdjusted), out elem)
? elem.GetDouble()
: Math.Floor(settings.Pearl.Position.Y);
return settings;
}
private Settings ReadAppSettings(JsonElement rootElement)
{
var settings = new Settings();
var cannonSettings = rootElement.GetProperty("CannonSettings")[0];
settings.NorthEastTNT = ReadSpace3D(cannonSettings.GetProperty(nameof(settings.NorthEastTNT)));
settings.NorthWestTNT = ReadSpace3D(cannonSettings.GetProperty(nameof(settings.NorthWestTNT)));
settings.SouthEastTNT = ReadSpace3D(cannonSettings.GetProperty(nameof(settings.SouthEastTNT)));
settings.SouthWestTNT = ReadSpace3D(cannonSettings.GetProperty(nameof(settings.SouthWestTNT)));
var pearlElemRoot = cannonSettings.GetProperty(nameof(settings.Pearl));
settings.Pearl = new PearlEntity
{
Position = ReadSpace3D(pearlElemRoot.GetProperty(nameof(settings.Pearl.Position))),
Motion = ReadSpace3D(pearlElemRoot.GetProperty(nameof(settings.Pearl.Motion)))
};
settings.RedTNT = rootElement.GetProperty(nameof(settings.RedTNT)).GetInt32();
settings.BlueTNT = rootElement.GetProperty(nameof(settings.BlueTNT)).GetInt32();
settings.MaxTNT = cannonSettings.GetProperty(nameof(settings.MaxTNT)).GetInt32();
settings.Destination = ReadSurface2D(rootElement.GetProperty(nameof(settings.Destination))).ToSpace3D();
settings.Offset = ReadSurface2D(cannonSettings.GetProperty(nameof(settings.Offset)));
settings.Direction = ReadDirection(
cannonSettings,
nameof(settings.Direction),
Direction.North
);
settings.DefaultRedTNTDirection = ReadDirection(
cannonSettings,
nameof(settings.DefaultRedTNTDirection),
Direction.SouthEast
);
settings.DefaultBlueTNTDirection = ReadDirection(
cannonSettings,
nameof(settings.DefaultBlueTNTDirection),
Direction.NorthWest
);
return settings;
}
public override void Write(Utf8JsonWriter writer, Settings value, JsonSerializerOptions options)
{
writer.WriteStartObject();
WriteObject(writer, options, nameof(value.NorthEastTNT), ref value.NorthEastTNT, _space3DJsonConverter);
WriteObject(writer, options, nameof(value.NorthWestTNT), ref value.NorthWestTNT, _space3DJsonConverter);
WriteObject(writer, options, nameof(value.SouthEastTNT), ref value.SouthEastTNT, _space3DJsonConverter);
WriteObject(writer, options, nameof(value.SouthWestTNT), ref value.SouthWestTNT, _space3DJsonConverter);
WriteObject(writer, options, nameof(value.Destination), ref value.Destination, _space3DJsonConverter);
WriteObject(writer, nameof(value.Offset), ref value.Offset, o =>
{
writer.WriteNumber("X", o.X);
writer.WriteNumber("Z", o.Z);
});
WriteObject(writer, nameof(value.Pearl), ref value.Pearl, o =>
{
WriteObject(writer, options, nameof(o.Position), ref o.Position, _space3DJsonConverter);
WriteObject(writer, options, nameof(o.Motion), ref o.Motion, _space3DJsonConverter);
});
writer.WriteNumber(nameof(value.RedTNT), value.RedTNT);
writer.WriteNumber(nameof(value.BlueTNT), value.BlueTNT);
writer.WriteNumber(nameof(value.MaxTNT), value.MaxTNT);
writer.WriteString(nameof(value.Direction), value.Direction.ToString());
writer.WriteString(nameof(value.DefaultRedTNTDirection), value.DefaultRedTNTDirection.ToString());
writer.WriteString(nameof(value.DefaultBlueTNTDirection), value.DefaultBlueTNTDirection.ToString());
writer.WriteBoolean(nameof(value.PearlYMotionCancellation), value.PearlYMotionCancellation);
writer.WriteNumber(nameof(value.PearlYPositionOriginal), value.PearlYPositionOriginal);
writer.WriteNumber(nameof(value.PearlYPositionAdjusted), value.PearlYPositionAdjusted);
writer.WriteEndObject();
}
private void WriteObject<T>(Utf8JsonWriter writer, JsonSerializerOptions options, string propertyName,
ref T value, JsonConverter<T> converter)
{
writer.WriteStartObject(propertyName);
converter.Write(writer, value, options);
writer.WriteEndObject();
}
private void WriteObject<T>(Utf8JsonWriter writer, string propertyName,
ref T value, Action<T> action)
{
writer.WriteStartObject(propertyName);
action?.Invoke(value);
writer.WriteEndObject();
}
private Space3D ReadSpace3D(JsonElement elem)
{
return new Space3D
{
X = elem.GetProperty("X").GetDouble(),
Y = elem.GetProperty("Y").GetDouble(),
Z = elem.GetProperty("Z").GetDouble()
};
}
private Surface2D ReadSurface2D(JsonElement elem)
{
return new Surface2D
{
X = elem.GetProperty("X").GetDouble(),
Z = elem.GetProperty("Z").GetDouble()
};
}
private Direction ReadDirection(JsonElement rootElement, string key, Direction defaultValue)
{
if (rootElement.TryGetProperty(key, out var elem) && elem.ValueKind == JsonValueKind.String)
if (Enum.TryParse<Direction>(elem.GetString(), out var direction))
return direction;
return defaultValue;
}
}
internal class Space3DJsonConverter : JsonConverter<Space3D>
{
public override Space3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
public override void Write(Utf8JsonWriter writer, Space3D value, JsonSerializerOptions options)
{
writer.WriteNumber("X", value.X);
writer.WriteNumber("Y", value.Y);
writer.WriteNumber("Z", value.Z);
}
}