fix(core): Fixes accounts and moves it to codegen (#644)

- [X] Fixes TimeSpan not working with codegen
- [X] Fixes bad check for generic classes with a serialize method and deserialize ctor
- [X] Moves Accounts to codegen so it is versioned
- [X] Fixes deserialization of old Accounts with no version variable.
- [X] Fixes deserialize seek not doing anything. 🙈 
- [X] Adds Email to serialization
This commit is contained in:
Kamron Batman 2021-06-05 19:39:16 -07:00 committed by GitHub
parent ac4d349caa
commit 75db56edc4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 378 additions and 464 deletions

View file

@ -44,12 +44,11 @@ namespace SerializationGenerator
if (isOverride) if (isOverride)
{ {
source.AppendLine();
source.AppendLine($"{indent}base.Serialize(writer);"); source.AppendLine($"{indent}base.Serialize(writer);");
source.AppendLine();
} }
// Version // Version
source.AppendLine();
source.AppendLine($"{indent}writer.{(encodedVersion ? "WriteEncodedInt" : "Write")}(_version);"); source.AppendLine($"{indent}writer.{(encodedVersion ? "WriteEncodedInt" : "Write")}(_version);");
foreach (var property in properties) foreach (var property in properties)

View file

@ -34,7 +34,7 @@ namespace SerializableMigration
out string[] ruleArguments out string[] ruleArguments
) )
{ {
if (symbol.IsIpAddress(compilation)) if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation))
{ {
ruleArguments = Array.Empty<string>(); ruleArguments = Array.Empty<string>();
return true; return true;
@ -91,6 +91,7 @@ namespace SerializableMigration
var argument = property.RuleArguments.Length >= 1 ? property.RuleArguments[0] : null; var argument = property.RuleArguments.Length >= 1 ? property.RuleArguments[0] : null;
const string ipAddress = SymbolMetadata.IPADDRESS_CLASS; const string ipAddress = SymbolMetadata.IPADDRESS_CLASS;
const string timeSpan = SymbolMetadata.TIMESPAN_STRUCT;
const string date = "System.DateTime"; const string date = "System.DateTime";
var readMethod = property.Type switch var readMethod = property.Type switch
@ -111,7 +112,8 @@ namespace SerializableMigration
"decimal" => "ReadDecimal", "decimal" => "ReadDecimal",
date when argument == "DeltaTime" => "ReadDeltaTime", date when argument == "DeltaTime" => "ReadDeltaTime",
date => "ReadDateTime", date => "ReadDateTime",
ipAddress => "ReadIPAddress" ipAddress => "ReadIPAddress",
timeSpan => "ReadTimeSpan"
}; };
var readArgument = readMethod == "ReadString" && argument == "InternString" ? "true" : ""; var readArgument = readMethod == "ReadString" && argument == "InternString" ? "true" : "";

View file

@ -15,6 +15,7 @@
using System; using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq;
using System.Text; using System.Text;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using SerializationGenerator; using SerializationGenerator;
@ -63,7 +64,7 @@ namespace SerializableMigration
var argument = property.RuleArguments.Length >= 1 && var argument = property.RuleArguments.Length >= 1 &&
property.RuleArguments[0] == "DeserializationRequiresParent" ? ", this" : ""; property.RuleArguments[0] == "DeserializationRequiresParent" ? ", this" : "";
source.AppendLine($"{indent}{propertyName} = new {property.Type}(reader{argument})"); source.AppendLine($"{indent}{propertyName} = new {property.Type}(reader{argument});");
} }
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property) public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)

View file

@ -23,6 +23,13 @@ namespace SerializationGenerator
public const string HASHSET_CLASS = "System.Collections.Generic.HashSet`1"; public const string HASHSET_CLASS = "System.Collections.Generic.HashSet`1";
public const string IPADDRESS_CLASS = "System.Net.IPAddress"; public const string IPADDRESS_CLASS = "System.Net.IPAddress";
public const string KEYVALUEPAIR_STRUCT = "System.Collections.Generic.KeyValuePair"; public const string KEYVALUEPAIR_STRUCT = "System.Collections.Generic.KeyValuePair";
public const string TIMESPAN_STRUCT = "System.TimeSpan";
public static bool IsTimeSpan(this ISymbol symbol, Compilation compilation) =>
symbol.Equals(
compilation.GetTypeByMetadataName(TIMESPAN_STRUCT),
SymbolEqualityComparer.Default
);
public static bool IsIpAddress(this ISymbol symbol, Compilation compilation) => public static bool IsIpAddress(this ISymbol symbol, Compilation compilation) =>
symbol.Equals( symbol.Equals(

View file

@ -73,10 +73,10 @@ namespace SerializationGenerator
m => !m.IsStatic && m => !m.IsStatic &&
m.MethodKind == MethodKind.Constructor && m.MethodKind == MethodKind.Constructor &&
m.Parameters.Length <= 2 && m.Parameters.Length <= 2 &&
m.Parameters[0].Equals(genericReaderInterface, SymbolEqualityComparer.Default) SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericReaderInterface)
); );
requiresParent = genericCtor?.Parameters.Length == 2 && genericCtor.Parameters[1].Equals(symbol, SymbolEqualityComparer.Default); requiresParent = genericCtor?.Parameters.Length == 2 && SymbolEqualityComparer.Default.Equals(genericCtor.Parameters[1].Type, symbol);
return genericCtor != null; return genericCtor != null;
} }
@ -98,7 +98,7 @@ namespace SerializationGenerator
m => !m.IsStatic && m => !m.IsStatic &&
m.ReturnsVoid && m.ReturnsVoid &&
m.Parameters.Length == 1 && m.Parameters.Length == 1 &&
m.Parameters[0].Equals(genericWriterInterface, SymbolEqualityComparer.Default) && SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericWriterInterface) &&
m.DeclaredAccessibility == Accessibility.Public m.DeclaredAccessibility == Accessibility.Public
); );
} }

View file

@ -95,7 +95,7 @@ namespace Server.Accounting
long GetTotalGold(); long GetTotalGold();
} }
public interface IAccount : IGoldAccount, IComparable<IAccount>, ISerializable public interface IAccount : IGoldAccount, IComparable<IAccount>
{ {
string Username { get; set; } string Username { get; set; }
string Email { get; set; } string Email { get; set; }

View file

@ -164,6 +164,8 @@ namespace Server
throw new ArgumentException($"BufferReader does not support {nameof(offset)} beyond Int32.MaxValue"); throw new ArgumentException($"BufferReader does not support {nameof(offset)} beyond Int32.MaxValue");
} }
_position = (int)position;
return _position; return _position;
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -64,23 +64,6 @@ namespace Server.Accounting
/// </summary> /// </summary>
public DateTime LastModified { get; private set; } public DateTime LastModified { get; private set; }
/// <summary>
/// Serializes this AccountComment instance to an XmlTextWriter.
/// </summary>
/// <param name="xml">The XmlTextWriter instance from which to serialize.</param>
public void Save(XmlTextWriter xml)
{
xml.WriteStartElement("comment");
xml.WriteAttributeString("addedBy", AddedBy);
xml.WriteAttributeString("lastModified", XmlConvert.ToString(LastModified, XmlDateTimeSerializationMode.Utc));
xml.WriteString(m_Content);
xml.WriteEndElement();
}
/// <summary> /// <summary>
/// Serializes this AccountComment instance. /// Serializes this AccountComment instance.
/// </summary> /// </summary>

View file

@ -45,18 +45,6 @@ namespace Server.Accounting
/// </summary> /// </summary>
public string Value { get; set; } public string Value { get; set; }
/// <summary>
/// Serializes this AccountTag instance to an XmlTextWriter.
/// </summary>
/// <param name="xml">The XmlTextWriter instance from which to serialize.</param>
public void Save(XmlTextWriter xml)
{
xml.WriteStartElement("tag");
xml.WriteAttributeString("name", Name);
xml.WriteString(Value);
xml.WriteEndElement();
}
/// <summary> /// <summary>
/// Serializes this AccountTag instance to an XmlTextWriter. /// Serializes this AccountTag instance to an XmlTextWriter.
/// </summary> /// </summary>

View file

@ -10,8 +10,8 @@ namespace Server.Accounting
{ {
private static readonly ILogger logger = LogFactory.GetLogger(typeof(Accounts)); private static readonly ILogger logger = LogFactory.GetLogger(typeof(Accounts));
private static readonly Dictionary<string, IAccount> _accountsByName = new(32, StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, Account> _accountsByName = new(32, StringComparer.OrdinalIgnoreCase);
private static Dictionary<Serial, IAccount> _accountsById = new(32); private static Dictionary<Serial, Account> _accountsById = new(32);
private static Serial _lastAccount; private static Serial _lastAccount;
internal static List<Type> Types { get; } = new(); internal static List<Type> Types { get; } = new();
@ -44,7 +44,7 @@ namespace Server.Accounting
Persistence.Register("Accounts", Serialize, WriteSnapshot, Deserialize); Persistence.Register("Accounts", Serialize, WriteSnapshot, Deserialize);
internal static void Serialize() => internal static void Serialize() =>
EntityPersistence.SaveEntities(_accountsById.Values, account => account.Serialize()); EntityPersistence.SaveEntities(_accountsById.Values, account => ((ISerializable)account).Serialize());
internal static void WriteSnapshot(string basePath) internal static void WriteSnapshot(string basePath)
{ {
@ -54,19 +54,19 @@ namespace Server.Accounting
public static IEnumerable<IAccount> GetAccounts() => _accountsByName.Values; public static IEnumerable<IAccount> GetAccounts() => _accountsByName.Values;
public static IAccount GetAccount(string username) public static Account GetAccount(string username)
{ {
_accountsByName.TryGetValue(username, out var a); _accountsByName.TryGetValue(username, out var a);
return a; return a;
} }
public static void Add(IAccount a) public static void Add(Account a)
{ {
_accountsByName[a.Username] = a; _accountsByName[a.Username] = a;
_accountsById[a.Serial] = a; _accountsById[a.Serial] = a;
} }
public static void Remove(IAccount a) public static void Remove(Account a)
{ {
_accountsByName.Remove(a.Username); _accountsByName.Remove(a.Username);
_accountsById.Remove(a.Serial); _accountsById.Remove(a.Serial);
@ -85,7 +85,7 @@ namespace Server.Accounting
IIndexInfo<Serial> indexInfo = new EntityTypeIndex("Accounts"); IIndexInfo<Serial> indexInfo = new EntityTypeIndex("Accounts");
_accountsById = EntityPersistence.LoadIndex(path, indexInfo, out List<EntityIndex<IAccount>> accounts); _accountsById = EntityPersistence.LoadIndex(path, indexInfo, out List<EntityIndex<Account>> accounts);
EntityPersistence.LoadData(path, indexInfo, accounts); EntityPersistence.LoadData(path, indexInfo, accounts);
foreach (var a in _accountsById.Values) foreach (var a in _accountsById.Values)

View file

@ -1056,7 +1056,7 @@ namespace Server.Gumps
if (m_List == null) if (m_List == null)
{ {
ipRestrictions = a.IPRestrictions.ToList(); ipRestrictions = a.IpRestrictions.ToList();
m_List = ipRestrictions.ToList<object>(); m_List = ipRestrictions.ToList<object>();
} }
else else
@ -3000,7 +3000,7 @@ namespace Server.Gumps
} }
else else
{ {
var list = a.IPRestrictions; var list = a.IpRestrictions;
var contains = false; var contains = false;
for (var i = 0; !contains && i < list.Length; ++i) for (var i = 0; !contains && i < list.Length; ++i)
@ -3023,7 +3023,7 @@ namespace Server.Gumps
newList[list.Length] = ip; newList[list.Length] = ip;
a.IPRestrictions = newList; a.IpRestrictions = newList;
notice = $"{ip} : Added to restriction list."; notice = $"{ip} : Added to restriction list.";
} }
@ -3888,9 +3888,9 @@ namespace Server.Gumps
} }
else if (m_PageType == AdminGumpPage.AccountDetails_Access_Restrictions) else if (m_PageType == AdminGumpPage.AccountDetails_Access_Restrictions)
{ {
var list = a.IPRestrictions.ToList(); var list = a.IpRestrictions.ToList();
list.Remove(m_List[index] as string); list.Remove(m_List[index] as string);
a.IPRestrictions = list.ToArray(); a.IpRestrictions = list.ToArray();
from.SendGump( from.SendGump(
new AdminGump( new AdminGump(

View file

@ -0,0 +1,108 @@
{
"version": 2,
"type": "Server.Accounting.Account",
"properties": [
{
"name": "Username",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
},
{
"name": "PasswordAlgorithm",
"type": "Server.Accounting.Security.PasswordProtectionAlgorithm",
"rule": "EnumMigrationRule",
"ruleArguments": []
},
{
"name": "Password",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
},
{
"name": "AccessLevel",
"type": "Server.AccessLevel",
"rule": "EnumMigrationRule",
"ruleArguments": []
},
{
"name": "Flags",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
},
{
"name": "Created",
"type": "System.DateTime",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
},
{
"name": "LastLogin",
"type": "System.DateTime",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
},
{
"name": "TotalGold",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
},
{
"name": "TotalPlat",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
},
{
"name": "Mobiles",
"type": "Server.Mobile[]",
"rule": "ArrayMigrationRule",
"ruleArguments": [
"Server.Mobile",
"SerializableInterfaceMigrationRule"
]
},
{
"name": "Comments",
"type": "System.Collections.Generic.List\u003CServer.Accounting.AccountComment\u003E",
"rule": "ListMigrationRule",
"ruleArguments": [
"Server.Accounting.AccountComment",
"SerializationMethodSignatureMigrationRule"
]
},
{
"name": "LoginIPs",
"type": "System.Net.IPAddress[]",
"rule": "ArrayMigrationRule",
"ruleArguments": [
"System.Net.IPAddress",
"PrimitiveTypeMigrationRule"
]
},
{
"name": "IpRestrictions",
"type": "string[]",
"rule": "ArrayMigrationRule",
"ruleArguments": [
"string",
"PrimitiveTypeMigrationRule"
]
},
{
"name": "TotalGameTime",
"type": "System.TimeSpan",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
},
{
"name": "Email",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
}
]
}