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:
parent
ac4d349caa
commit
75db56edc4
13 changed files with 378 additions and 464 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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" : "";
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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; }
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
108
Projects/UOContent/Migrations/Server.Accounting.Account.v2.json
Normal file
108
Projects/UOContent/Migrations/Server.Accounting.Account.v2.json
Normal 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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue