Skip to content

Commit 1f65433

Browse files
authored
fix: rewrite forgot password/password change windows, add change password button to select character window (#2678)
* update LoginWindow to fit Forgot Password button * fix/improve JSON serialization of game configuration * refactoring, fixes, and better status messages for password reset * change password from select character window * fix textbox select all * LoadJsonUi for PCW/SCW
1 parent a589db3 commit 1f65433

40 files changed

+1712
-966
lines changed

Framework/Intersect.Framework.Core/Config/Options.cs

Lines changed: 26 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ namespace Intersect;
1010

1111
public partial record Options
1212
{
13+
private static readonly JsonSerializerSettings PrivateIndentedSerializerSettings = new()
14+
{
15+
ContractResolver = new OptionsContractResolver(true, false),
16+
Formatting = Formatting.Indented,
17+
};
18+
19+
private static readonly JsonSerializerSettings PrivateSerializerSettings = new()
20+
{
21+
ContractResolver = new OptionsContractResolver(true, false),
22+
};
23+
24+
private static readonly JsonSerializerSettings PublicSerializerSettings = new()
25+
{
26+
ContractResolver = new OptionsContractResolver(false, true),
27+
};
28+
1329
#region Constants
1430

1531
public const string DefaultGameName = "Intersect";
@@ -48,10 +64,6 @@ public partial record Options
4864
[JsonIgnore]
4965
public string OptionsData { get; private set; } = string.Empty;
5066

51-
[Ignore]
52-
[JsonIgnore]
53-
public bool SendingToClient { get; set; } = true;
54-
5567
[Ignore]
5668
public bool SmtpValid { get; private set; }
5769

@@ -235,7 +247,8 @@ public static bool LoadFromDisk()
235247
}
236248
else if (File.Exists(pathToServerConfig))
237249
{
238-
instance = JsonConvert.DeserializeObject<Options>(File.ReadAllText(pathToServerConfig)) ?? instance;
250+
var rawJson = File.ReadAllText(pathToServerConfig);
251+
instance = JsonConvert.DeserializeObject<Options>(rawJson, PrivateSerializerSettings) ?? instance;
239252
Instance = instance;
240253
}
241254

@@ -269,13 +282,10 @@ public static void SaveToDisk()
269282

270283
var pathToServerConfig = Path.Combine(ResourcesDirectory, "config.json");
271284

272-
instance.SendingToClient = false;
273285
try
274286
{
275-
File.WriteAllText(
276-
pathToServerConfig,
277-
JsonConvert.SerializeObject(instance, Formatting.Indented)
278-
);
287+
var serializedPrivateConfiguration = JsonConvert.SerializeObject(instance, PrivateIndentedSerializerSettings);
288+
File.WriteAllText(pathToServerConfig, serializedPrivateConfiguration);
279289
}
280290
catch (Exception exception)
281291
{
@@ -285,15 +295,15 @@ public static void SaveToDisk()
285295
pathToServerConfig
286296
);
287297
}
288-
instance.SendingToClient = true;
289-
instance.OptionsData = JsonConvert.SerializeObject(instance);
298+
299+
instance.OptionsData = JsonConvert.SerializeObject(instance, PublicSerializerSettings);
290300
}
291301

292302
public static void LoadFromServer(string data)
293303
{
294304
try
295305
{
296-
var loadedOptions = JsonConvert.DeserializeObject<Options>(data);
306+
var loadedOptions = JsonConvert.DeserializeObject<Options>(data, PublicSerializerSettings);
297307
Instance = loadedOptions;
298308
OptionsLoaded?.Invoke(loadedOptions);
299309
}
@@ -306,47 +316,7 @@ public static void LoadFromServer(string data)
306316

307317
public static event OptionsLoadedEventHandler? OptionsLoaded;
308318

309-
// ReSharper disable once UnusedMember.Global
310-
public bool ShouldSerializeGameDatabase()
311-
{
312-
return !SendingToClient;
313-
}
314-
315-
// ReSharper disable once UnusedMember.Global
316-
public bool ShouldSerializeLoggingDatabase()
317-
{
318-
return !SendingToClient;
319-
}
320-
321-
// ReSharper disable once UnusedMember.Global
322-
public bool ShouldSerializeLogging()
323-
{
324-
return !SendingToClient;
325-
}
326-
327-
// ReSharper disable once UnusedMember.Global
328-
public bool ShouldSerializePlayerDatabase()
329-
{
330-
return !SendingToClient;
331-
}
332-
333-
// ReSharper disable once UnusedMember.Global
334-
public bool ShouldSerializeSmtpSettings()
335-
{
336-
return !SendingToClient;
337-
}
338-
339-
// ReSharper disable once UnusedMember.Global
340-
public bool ShouldSerializeSmtpValid()
341-
{
342-
return SendingToClient;
343-
}
344-
345-
// ReSharper disable once UnusedMember.Global
346-
public bool ShouldSerializeSecurity()
347-
{
348-
return !SendingToClient;
349-
}
350-
351-
public Options DeepClone() => JsonConvert.DeserializeObject<Options>(JsonConvert.SerializeObject(this with { SendingToClient = false }));
319+
public Options DeepClone() => JsonConvert.DeserializeObject<Options>(
320+
JsonConvert.SerializeObject(this, PrivateSerializerSettings)
321+
);
352322
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System.Reflection;
2+
using Newtonsoft.Json;
3+
using Newtonsoft.Json.Serialization;
4+
5+
namespace Intersect;
6+
7+
public sealed class OptionsContractResolver(bool serializePrivateProperties, bool serializePublicProperties) : DefaultContractResolver
8+
{
9+
private readonly bool _serializePrivateProperties = serializePrivateProperties;
10+
private readonly bool _serializePublicProperties = serializePublicProperties;
11+
12+
private static readonly HashSet<PropertyInfo> PrivateProperties =
13+
[
14+
typeof(Options).GetProperty(nameof(Options.AdminOnly)),
15+
typeof(Options).GetProperty(nameof(Options.EventWatchdogKillThreshold)),
16+
typeof(Options).GetProperty(nameof(Options.GameDatabase)),
17+
typeof(Options).GetProperty(nameof(Options.Logging)),
18+
typeof(Options).GetProperty(nameof(Options.LoggingDatabase)),
19+
typeof(Options).GetProperty(nameof(Options.MaxClientConnections)),
20+
typeof(Options).GetProperty(nameof(Options.MaximumLoggedInUsers)),
21+
typeof(Options).GetProperty(nameof(Options.Metrics)),
22+
typeof(Options).GetProperty(nameof(Options.OpenPortChecker)),
23+
typeof(Options).GetProperty(nameof(Options.PlayerDatabase)),
24+
typeof(Options).GetProperty(nameof(Options.PortCheckerUrl)),
25+
typeof(Options).GetProperty(nameof(Options.Security)),
26+
typeof(Options).GetProperty(nameof(Options.ServerPort)),
27+
typeof(Options).GetProperty(nameof(Options.SmtpSettings)),
28+
typeof(Options).GetProperty(nameof(Options.UPnP)),
29+
typeof(Options).GetProperty(nameof(Options.ValidPasswordResetTimeMinutes)),
30+
];
31+
32+
private static readonly HashSet<PropertyInfo> PublicProperties =
33+
[
34+
typeof(Options).GetProperty(nameof(Options.SmtpValid)),
35+
];
36+
37+
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
38+
{
39+
var property = base.CreateProperty(member, memberSerialization);
40+
41+
if (PrivateProperties.Contains(member))
42+
{
43+
property.ShouldDeserialize = AlwaysSerialize;
44+
property.ShouldSerialize = ShouldSerializePrivateProperty;
45+
property.Writable = true;
46+
}
47+
48+
if (PublicProperties.Contains(member))
49+
{
50+
property.ShouldDeserialize = AlwaysSerialize;
51+
property.ShouldSerialize = ShouldSerializePublicProperty;
52+
property.Writable = true;
53+
}
54+
55+
return property;
56+
}
57+
58+
private static bool AlwaysSerialize(object _) => true;
59+
60+
private bool ShouldSerializePublicProperty(object _) => _serializePublicProperties;
61+
62+
private bool ShouldSerializePrivateProperty(object _) => _serializePrivateProperties;
63+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using MessagePack;
2+
3+
namespace Intersect.Network.Packets.Client;
4+
5+
[MessagePackObject]
6+
public partial class PasswordChangeRequestPacket : IntersectPacket
7+
{
8+
//Parameterless Constructor for MessagePack
9+
public PasswordChangeRequestPacket()
10+
{
11+
}
12+
13+
public PasswordChangeRequestPacket(string identifier, string token, string password)
14+
{
15+
Identifier = identifier;
16+
Token = token;
17+
Password = password;
18+
}
19+
20+
[Key(0)]
21+
public string? Identifier { get; set; }
22+
23+
[Key(1)]
24+
public string? Token { get; set; }
25+
26+
[Key(2)]
27+
public string? Password { get; set; }
28+
29+
}

Framework/Intersect.Framework.Core/Network/Packets/Client/ResetPasswordPacket.cs

Lines changed: 0 additions & 29 deletions
This file was deleted.

Framework/Intersect.Framework.Core/Network/Packets/Client/CreateAccountPacket.cs renamed to Framework/Intersect.Framework.Core/Network/Packets/Client/UserRegistrationRequestPacket.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
namespace Intersect.Network.Packets.Client;
44

55
[MessagePackObject]
6-
public partial class CreateAccountPacket : IntersectPacket
6+
public partial class UserRegistrationRequestPacket : IntersectPacket
77
{
88
//Parameterless Constructor for MessagePack
9-
public CreateAccountPacket()
9+
public UserRegistrationRequestPacket()
1010
{
1111
}
1212

13-
public CreateAccountPacket(string username, string password, string email)
13+
public UserRegistrationRequestPacket(string username, string password, string email)
1414
{
1515
Username = username;
1616
Password = password;

Framework/Intersect.Framework.Core/Network/Packets/Server/CharactersPacket.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,20 @@ public CharactersPacket()
1010
{
1111
}
1212

13-
public CharactersPacket(CharacterPacket[] characters, bool freeSlot)
13+
public CharactersPacket(string username, CharacterPacket[] characters, bool freeSlot)
1414
{
15+
Username = username;
1516
Characters = characters;
1617
FreeSlot = freeSlot;
1718
}
1819

1920
[Key(0)]
20-
public CharacterPacket[] Characters { get; set; }
21+
public string Username { get; set; }
2122

2223
[Key(1)]
24+
public CharacterPacket[] Characters { get; set; }
25+
26+
[Key(2)]
2327
public bool FreeSlot { get; set; }
2428

2529
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Intersect.Framework.Core.Security;
2+
using MessagePack;
3+
4+
namespace Intersect.Network.Packets.Server;
5+
6+
[MessagePackObject]
7+
public partial class PasswordChangeResultPacket : IntersectPacket
8+
{
9+
10+
//Parameterless Constructor for MessagePack
11+
public PasswordChangeResultPacket()
12+
{
13+
}
14+
15+
public PasswordChangeResultPacket(PasswordResetResultType succeeded)
16+
{
17+
ResultType = succeeded;
18+
}
19+
20+
[Key(0)]
21+
public PasswordResetResultType ResultType { get; set; }
22+
23+
}

Framework/Intersect.Framework.Core/Network/Packets/Server/PasswordResetResultPacket.cs

Lines changed: 0 additions & 21 deletions
This file was deleted.

Framework/Intersect.Framework.Core/Point.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ public static Point FromString(string val)
7171

7272
public static Point operator +(Point left, Point right) => new(left.X + right.X, left.Y + right.Y);
7373

74+
public static Vector2 operator +(Point left, Vector2 right) => new(left.X + right.X, left.Y + right.Y);
75+
76+
public static Vector2 operator +(Vector2 left, Point right) => new(left.X + right.X, left.Y + right.Y);
77+
7478
public static Point operator -(Point left, Point right) => new(left.X - right.X, left.Y - right.Y);
7579

7680
public static Point operator *(Point point, float scalar) => new((int)(point.X * scalar), (int)(point.Y * scalar));
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Intersect.Framework.Core.Security;
2+
3+
public enum PasswordResetResultType
4+
{
5+
Unknown,
6+
Success,
7+
NoUserFound,
8+
InvalidRequest,
9+
InvalidToken,
10+
}

0 commit comments

Comments
 (0)