From c31bf20d0e96dcc93c4c0f8737eaeb9cae40aa90 Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Sat, 13 Nov 2021 13:38:01 -0800
Subject: [PATCH 01/16] feat: Updates to .NET 6 (#843)
* Fixes an issue with moving directories across volumes
* Removes usages of WebClient
* Removes usages of Cryptographic Providers
Note: Even though .NET 6 introduces Xoshiro RNG, there is no way to control the seed. I'll do some reconciliation of Xoshiro so it functions closer to the built in one. For the most part, it has parity though.
Benchmarks show there is nothing odd about the implementations, they are within 1ns of each other.
---
.github/workflows/build-test.yml | 4 +-
Directory.Build.props | 4 +-
Projects/Benchmarks/Benchmarks.csproj | 2 +-
.../Collections/BenchmarkOrderedHashSet.cs | 2 +-
.../FeatureFlags/BenchmarkFeatureFlags.cs | 90 -------------------
.../Benchmarks/FeatureFlags/FeatureFlag.cs | 9 --
.../Logging/BenchmarkConsoleLogging.cs | 2 +-
.../Packets/BenchmarkOutgoingGumpPacket.cs | 2 +-
.../Packets/BenchmarkPacketBroadcast.cs | 2 +-
.../Benchmarks/Rng/BenchmarkXoshiro.cs | 46 ++++++++++
.../Benchmarks/Text/BenchmarkTextEncoding.cs | 2 +-
.../Utilities/BenchmarkStringHelpers.cs | 2 +-
Projects/Benchmarks/Program.cs | 4 +-
.../SerializableMigrationSchema.cs | 3 +-
.../Application.cs | 3 +-
Projects/Server.Tests/Server.Tests.csproj | 2 +-
Projects/Server/Json/JsonConfig.cs | 2 +-
Projects/Server/Random/SecureRandom.cs | 4 +-
Projects/Server/Utilities/PathUtility.cs | 19 ++++
Projects/Server/World/World.cs | 2 +-
.../Security/PasswordProtectionTest.cs | 55 +++++++++---
.../UOContent.Tests/UOContent.Tests.csproj | 2 +-
.../Accounting/Security/AccountSecurity.cs | 6 +-
....cs => HashAlgorithmPasswordProtection.cs} | 16 ++--
.../Security/MD5PasswordProtection.cs | 38 --------
.../Security/SHA1PasswordProtection.cs | 38 --------
Projects/UOContent/Compression/TarArchive.cs | 17 +++-
Projects/UOContent/Compression/ZstdArchive.cs | 1 +
Projects/UOContent/Misc/ProfessionInfo.cs | 2 +-
Projects/UOContent/Misc/ServerList.cs | 10 ++-
Projects/UOContent/Mobiles/Townfolk/Noble.cs | 1 -
Projects/UOContent/UOContent.csproj | 2 +-
Projects/UOContent/World Saves/AutoArchive.cs | 4 +-
README.md | 11 ++-
azure-pipelines.yml | 14 ++-
35 files changed, 192 insertions(+), 231 deletions(-)
delete mode 100644 Projects/Benchmarks/Benchmarks/FeatureFlags/BenchmarkFeatureFlags.cs
delete mode 100644 Projects/Benchmarks/Benchmarks/FeatureFlags/FeatureFlag.cs
create mode 100644 Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs
rename Projects/UOContent/Accounting/Security/{SHA2PasswordProtection.cs => HashAlgorithmPasswordProtection.cs} (64%)
delete mode 100644 Projects/UOContent/Accounting/Security/MD5PasswordProtection.cs
delete mode 100644 Projects/UOContent/Accounting/Security/SHA1PasswordProtection.cs
diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml
index cf746c82e..3a2b28871 100644
--- a/.github/workflows/build-test.yml
+++ b/.github/workflows/build-test.yml
@@ -23,10 +23,10 @@ jobs:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
- - name: Setup .NET 5
+ - name: Setup .NET 6
uses: actions/setup-dotnet@v1
with:
- dotnet-version: 5.0.401
+ dotnet-version: 6.0.100
- name: Build
run: ./publish.cmd
- name: Test
diff --git a/Directory.Build.props b/Directory.Build.props
index 0ac231599..7ebed0b53 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -4,7 +4,7 @@
Kamron Batman
ModernUO
2019-2020
- net5.0
+ net6.0
x64
x64
preview
@@ -58,7 +58,7 @@
- 3.4.240
+ 3.4.244
all
diff --git a/Projects/Benchmarks/Benchmarks.csproj b/Projects/Benchmarks/Benchmarks.csproj
index 2ed8e89fd..eff9ed660 100644
--- a/Projects/Benchmarks/Benchmarks.csproj
+++ b/Projects/Benchmarks/Benchmarks.csproj
@@ -1,7 +1,7 @@
Exe
- net5.0
+ net6.0
x64
x64
9
diff --git a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs
index 1414c571e..b9ec3d676 100644
--- a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs
+++ b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs
@@ -6,7 +6,7 @@ using Server.Collections;
namespace Benchmarks
{
[MemoryDiagnoser]
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
+ [SimpleJob(RuntimeMoniker.Net60)]
public class BenchmarkOrderedHashSet
{
private readonly string[] _iterations = new string[16];
diff --git a/Projects/Benchmarks/Benchmarks/FeatureFlags/BenchmarkFeatureFlags.cs b/Projects/Benchmarks/Benchmarks/FeatureFlags/BenchmarkFeatureFlags.cs
deleted file mode 100644
index fcfffebbe..000000000
--- a/Projects/Benchmarks/Benchmarks/FeatureFlags/BenchmarkFeatureFlags.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using System;
-using System.Buffers.Binary;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.Loader;
-using System.Security.Cryptography;
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Server;
-using Server.Items;
-
-namespace Benchmarks
-{
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class BenchmarkFeatureFlags
- {
- public Dictionary> m_Dictionary;
- public ILookup> m_Lookup;
-
- public Type[] m_TypesToLookUp;
-
- [GlobalSetup]
- public void Setup()
- {
- RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider();
-
- string file = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "UOContent.dll");
- Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(file);
-
- m_Dictionary = new Dictionary>();
- List> m_Types = new List>();
- m_TypesToLookUp = new Type[100];
-
- foreach (var type in assembly.GetTypes())
- {
- if (typeof(Item).IsAssignableFrom(type))
- {
- m_Dictionary.Add(type, new FeatureFlag- ());
- m_Types.Add(new FeatureFlag
- {Type = type});
- }
- }
-
- Console.WriteLine("Dictionary Size: {0}", m_Dictionary.Count);
- Console.WriteLine("Lookup Size: {0}", m_Types.Count);
-
- m_Dictionary.TrimExcess();
- m_Lookup = m_Types.ToLookup(f => f.Type);
- Span bytes = stackalloc byte[4];
-
- for (int i = 0; i < 100; i++)
- {
- csp.GetBytes(bytes);
- m_TypesToLookUp[i] = m_Types[(int)(BinaryPrimitives.ReadUInt32BigEndian(bytes) % m_Types.Count)].Type;
- }
- }
-
- [Benchmark]
- public FeatureFlag
- TestDictionary()
- {
- for (int i = 0; i < 100; i++)
- {
- m_Dictionary.TryGetValue(typeof(ExplosionPotion), out var ff);
- if (i == 99)
- {
- return ff;
- }
- }
-
- return null;
- }
-
- [Benchmark]
- public FeatureFlag
- TestLookup()
- {
- FeatureFlag
- ff;
- for (int i = 0; i < 100; i++)
- {
- ff = m_Lookup[typeof(ExplosionPotion)].GetEnumerator().Current;
- if (i == 99)
- {
- return ff;
- }
- }
-
- return null;
- }
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/FeatureFlags/FeatureFlag.cs b/Projects/Benchmarks/Benchmarks/FeatureFlags/FeatureFlag.cs
deleted file mode 100644
index f8b04716c..000000000
--- a/Projects/Benchmarks/Benchmarks/FeatureFlags/FeatureFlag.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace Server
-{
- public class FeatureFlag where T : Item
- {
- public Type Type { get; set; }
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs b/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs
index 62bc428fa..f794d64b4 100644
--- a/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs
+++ b/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs
@@ -6,7 +6,7 @@ using Serilog.Core;
namespace Benchmarks
{
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
+ [SimpleJob(RuntimeMoniker.Net60)]
public class BenchmarkConsoleLogging
{
private const string text = "Sample message";
diff --git a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs
index 0225af652..114cac192 100644
--- a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs
+++ b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs
@@ -12,7 +12,7 @@ using Server.Tests.Network;
namespace Benchmarks
{
[MemoryDiagnoser]
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
+ [SimpleJob(RuntimeMoniker.Net60)]
public class OutgoingGumpPacketBenchmarks
{
private static readonly byte[] _layoutBuffer = GC.AllocateUninitializedArray(0x20000);
diff --git a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs
index 2535dca0f..4db59d432 100644
--- a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs
+++ b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs
@@ -7,7 +7,7 @@ using Server.Network;
namespace Benchmarks
{
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
+ [SimpleJob(RuntimeMoniker.Net60)]
public class BenchmarkPacketBroadcast
{
public static int SendUnicodeMessage(
diff --git a/Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs b/Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs
new file mode 100644
index 000000000..caced76b3
--- /dev/null
+++ b/Projects/Benchmarks/Benchmarks/Rng/BenchmarkXoshiro.cs
@@ -0,0 +1,46 @@
+using System;
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Jobs;
+using Server.Random;
+
+namespace Benchmarks.Benchmarks.Rng
+{
+ [MemoryDiagnoser]
+ [SimpleJob(RuntimeMoniker.Net60)]
+ public class BenchmarkXoshiro
+ {
+ private Random _random;
+ private Xoshiro256PlusPlus _xoshiro256PlusPlus;
+
+ [GlobalSetup]
+ public void Setup()
+ {
+ _xoshiro256PlusPlus = new Xoshiro256PlusPlus();
+ _random = new Random();
+ }
+
+ [Benchmark]
+ public int SystemRandomULong() => _random.Next(10000);
+
+ [Benchmark]
+ public int XoshiroRandomULong() => _xoshiro256PlusPlus.Next(10000);
+
+ [Benchmark]
+ public double SystemRandomDouble() => _random.NextDouble();
+
+ [Benchmark]
+ public double XoshiroRandomDouble() => _xoshiro256PlusPlus.NextDouble();
+
+ [Benchmark]
+ public int SystemRandomMinMax() => _random.Next(5000, 85000);
+
+ [Benchmark]
+ public int XoshiroRandomMinMax()
+ {
+ const int min = 5000;
+ const int max = 85000;
+
+ return min + (int)_xoshiro256PlusPlus.Next((uint)(max - min + 1));
+ }
+ }
+}
diff --git a/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs b/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs
index 5594bf937..b2f716861 100644
--- a/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs
+++ b/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs
@@ -5,7 +5,7 @@ using Server.Text;
namespace Benchmarks.BenchmarkText
{
[MemoryDiagnoser]
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
+ [SimpleJob(RuntimeMoniker.Net60)]
public class BenchmarkTextEncoding
{
private const string text =
diff --git a/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs b/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs
index 01cf5bb3c..55e4fd289 100644
--- a/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs
+++ b/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs
@@ -7,7 +7,7 @@ using Server.Buffers;
namespace Benchmarks.BenchmarkUtilities
{
[MemoryDiagnoser]
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
+ [SimpleJob(RuntimeMoniker.Net60)]
public class BenchmarkStringHelpers
{
private readonly string[] names =
diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs
index f28cc3e6f..845354d56 100644
--- a/Projects/Benchmarks/Program.cs
+++ b/Projects/Benchmarks/Program.cs
@@ -1,4 +1,5 @@
using BenchmarkDotNet.Running;
+using Benchmarks.Benchmarks.Rng;
namespace Benchmarks
{
@@ -10,10 +11,11 @@ namespace Benchmarks
// var packetConstruction = BenchmarkRunner.Run();
// var broadcast = BenchmarkRunner.Run();
// var stringHelpers = BenchmarkRunner.Run();
- var indexList = BenchmarkRunner.Run();
+ // var indexList = BenchmarkRunner.Run();
// var textEncoding = BenchmarkRunner.Run();
// var logging = BenchmarkRunner.Run();
// var gumpPacket = BenchmarkRunner.Run();
+ var rngTest = BenchmarkRunner.Run();
}
}
}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs
index 52b94d505..2f8613456 100644
--- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs
@@ -18,6 +18,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
+using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
@@ -30,7 +31,7 @@ namespace SerializableMigration
{
WriteIndented = true,
AllowTrailingCommas = true,
- IgnoreNullValues = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
ReadCommentHandling = JsonCommentHandling.Skip
};
diff --git a/Projects/SerializationSchemaGenerator/Application.cs b/Projects/SerializationSchemaGenerator/Application.cs
index e8634aab7..eb6946787 100644
--- a/Projects/SerializationSchemaGenerator/Application.cs
+++ b/Projects/SerializationSchemaGenerator/Application.cs
@@ -17,6 +17,7 @@ using System;
using System.Collections.Immutable;
using System.IO;
using System.Text.Json;
+using System.Text.Json.Serialization;
using System.Threading.Tasks;
using SerializationGenerator;
@@ -61,7 +62,7 @@ namespace SerializationSchemaGenerator
{
WriteIndented = true,
AllowTrailingCommas = true,
- IgnoreNullValues = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
ReadCommentHandling = JsonCommentHandling.Skip
};
diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj
index b6339a9a0..46a5a0981 100644
--- a/Projects/Server.Tests/Server.Tests.csproj
+++ b/Projects/Server.Tests/Server.Tests.csproj
@@ -3,7 +3,7 @@
false
-
+
diff --git a/Projects/Server/Json/JsonConfig.cs b/Projects/Server/Json/JsonConfig.cs
index 163776d84..7bddd24c8 100644
--- a/Projects/Server/Json/JsonConfig.cs
+++ b/Projects/Server/Json/JsonConfig.cs
@@ -34,7 +34,7 @@ namespace Server.Json
{
WriteIndented = true,
AllowTrailingCommas = true,
- IgnoreNullValues = true,
+ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
ReadCommentHandling = JsonCommentHandling.Skip,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
diff --git a/Projects/Server/Random/SecureRandom.cs b/Projects/Server/Random/SecureRandom.cs
index 284502d1b..30006b871 100644
--- a/Projects/Server/Random/SecureRandom.cs
+++ b/Projects/Server/Random/SecureRandom.cs
@@ -25,13 +25,13 @@ namespace Server
{
private RandomNumberGenerator m_Random;
- public RandomNumberGenerator Generator => m_Random ??= new RNGCryptoServiceProvider();
+ public RandomNumberGenerator Generator => m_Random ??= RandomNumberGenerator.Create();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override ulong NextULong()
{
Span buffer = stackalloc byte[sizeof(ulong)];
- Generator.GetBytes(buffer);
+ NextBytes(buffer);
return BinaryPrimitives.ReadUInt64BigEndian(buffer);
}
diff --git a/Projects/Server/Utilities/PathUtility.cs b/Projects/Server/Utilities/PathUtility.cs
index d2206143d..6f22c46db 100644
--- a/Projects/Server/Utilities/PathUtility.cs
+++ b/Projects/Server/Utilities/PathUtility.cs
@@ -63,5 +63,24 @@ namespace Server
Utility.RandomBytes(bytes);
return EnsureDirectory(Path.Combine(basePath, bytes.ToHexString()));
}
+
+ public static void CopyDirectory(string sourcePath, string destinationPath, bool recursive = true)
+ {
+ var searchOptions = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
+ foreach (var file in Directory.EnumerateFiles(sourcePath, "*", searchOptions))
+ {
+ var fi = new FileInfo(file);
+ var relativePath = Path.GetRelativePath(sourcePath, fi.DirectoryName!);
+ var destFolder = Path.Combine(destinationPath, relativePath);
+ EnsureDirectory(destFolder);
+ fi.CopyTo(Path.Combine(destFolder, fi.Name));
+ }
+ }
+
+ public static void MoveDirectory(string sourcePath, string destinationPath)
+ {
+ CopyDirectory(sourcePath, destinationPath);
+ Directory.Delete(sourcePath, true);
+ }
}
}
diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs
index 02b3013d5..72d21ac2b 100644
--- a/Projects/Server/World/World.cs
+++ b/Projects/Server/World/World.cs
@@ -421,7 +421,7 @@ namespace Server
try
{
EventSink.InvokeWorldSavePostSnapshot(SavePath, tempPath);
- Directory.Move(tempPath, SavePath);
+ PathUtility.MoveDirectory(tempPath, SavePath);
}
catch (Exception ex)
{
diff --git a/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs b/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs
index e69e8db6c..380ab8954 100644
--- a/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs
+++ b/Projects/UOContent.Tests/Tests/Accounting/Security/PasswordProtectionTest.cs
@@ -1,4 +1,5 @@
using System;
+using System.Security.Cryptography;
using Server.Accounting;
using Server.Accounting.Security;
using Xunit;
@@ -9,12 +10,29 @@ namespace Server.Tests.Accounting.Security
{
private const string plainPassword = "hello-good-sir";
- [Theory, InlineData(typeof(Argon2PasswordProtection)), InlineData(typeof(PBKDF2PasswordProtection)),
- InlineData(typeof(SHA2PasswordProtection)), InlineData(typeof(SHA1PasswordProtection)),
- InlineData(typeof(MD5PasswordProtection))]
- public void TestValidates(Type protectionType)
+ [Theory]
+ [InlineData(typeof(Argon2PasswordProtection), null)]
+ [InlineData(typeof(PBKDF2PasswordProtection), null)]
+ [InlineData(typeof(HashAlgorithmPasswordProtection), "MD5")]
+ [InlineData(typeof(HashAlgorithmPasswordProtection), "SHA1")]
+ [InlineData(typeof(HashAlgorithmPasswordProtection), "SHA2")]
+ public void TestValidates(Type protectionType, string algorithmType)
{
- var passwordProtection = Activator.CreateInstance(protectionType) as IPasswordProtection;
+ IPasswordProtection passwordProtection;
+ if (protectionType == typeof(HashAlgorithmPasswordProtection))
+ {
+ passwordProtection = algorithmType switch
+ {
+ "SHA1" => HashAlgorithmPasswordProtection.SHA1Instance,
+ "SHA2" => HashAlgorithmPasswordProtection.SHA2Instance,
+ _ => HashAlgorithmPasswordProtection.MD5Instance,
+ };
+ }
+ else
+ {
+ passwordProtection = Activator.CreateInstance(protectionType) as IPasswordProtection;
+ }
+
if (passwordProtection == null)
{
Assert.False(true, $"{protectionType.Name} is not an IPasswordProtection.");
@@ -25,12 +43,29 @@ namespace Server.Tests.Accounting.Security
Assert.True(passwordProtection.ValidatePassword(encryptedPassword, plainPassword));
}
- [Theory, InlineData(typeof(Argon2PasswordProtection)), InlineData(typeof(PBKDF2PasswordProtection)),
- InlineData(typeof(SHA2PasswordProtection)), InlineData(typeof(SHA1PasswordProtection)),
- InlineData(typeof(MD5PasswordProtection))]
- public void TestPasswordDoesNotValidate(Type protectionType)
+ [Theory]
+ [InlineData(typeof(Argon2PasswordProtection), null)]
+ [InlineData(typeof(PBKDF2PasswordProtection), null)]
+ [InlineData(typeof(HashAlgorithmPasswordProtection), "MD5")]
+ [InlineData(typeof(HashAlgorithmPasswordProtection), "SHA1")]
+ [InlineData(typeof(HashAlgorithmPasswordProtection), "SHA2")]
+ public void TestPasswordDoesNotValidate(Type protectionType, string algorithmType)
{
- var passwordProtection = Activator.CreateInstance(protectionType) as IPasswordProtection;
+ IPasswordProtection passwordProtection;
+ if (protectionType == typeof(HashAlgorithmPasswordProtection))
+ {
+ passwordProtection = algorithmType switch
+ {
+ "SHA1" => HashAlgorithmPasswordProtection.SHA1Instance,
+ "SHA2" => HashAlgorithmPasswordProtection.SHA2Instance,
+ _ => HashAlgorithmPasswordProtection.MD5Instance,
+ };
+ }
+ else
+ {
+ passwordProtection = Activator.CreateInstance(protectionType) as IPasswordProtection;
+ }
+
if (passwordProtection == null)
{
Assert.False(true, $"{protectionType.Name} is not an IPasswordProtection.");
diff --git a/Projects/UOContent.Tests/UOContent.Tests.csproj b/Projects/UOContent.Tests/UOContent.Tests.csproj
index baa2a972e..fc960bae1 100644
--- a/Projects/UOContent.Tests/UOContent.Tests.csproj
+++ b/Projects/UOContent.Tests/UOContent.Tests.csproj
@@ -3,7 +3,7 @@
false
-
+
diff --git a/Projects/UOContent/Accounting/Security/AccountSecurity.cs b/Projects/UOContent/Accounting/Security/AccountSecurity.cs
index 0725b3af8..b6d697f6a 100644
--- a/Projects/UOContent/Accounting/Security/AccountSecurity.cs
+++ b/Projects/UOContent/Accounting/Security/AccountSecurity.cs
@@ -55,9 +55,9 @@ namespace Server.Accounting.Security
{
var passwordProtection = algorithm switch
{
- PasswordProtectionAlgorithm.MD5 => MD5PasswordProtection.Instance,
- PasswordProtectionAlgorithm.SHA1 => SHA1PasswordProtection.Instance,
- PasswordProtectionAlgorithm.SHA2 => SHA2PasswordProtection.Instance,
+ PasswordProtectionAlgorithm.MD5 => HashAlgorithmPasswordProtection.MD5Instance,
+ PasswordProtectionAlgorithm.SHA1 => HashAlgorithmPasswordProtection.SHA1Instance,
+ PasswordProtectionAlgorithm.SHA2 => HashAlgorithmPasswordProtection.SHA2Instance,
PasswordProtectionAlgorithm.PBKDF2 => PBKDF2PasswordProtection.Instance,
PasswordProtectionAlgorithm.Argon2 => Argon2PasswordProtection.Instance,
PasswordProtectionAlgorithm.None => throw new Exception("Do not use PasswordProtectionAlgorithm.None"),
diff --git a/Projects/UOContent/Accounting/Security/SHA2PasswordProtection.cs b/Projects/UOContent/Accounting/Security/HashAlgorithmPasswordProtection.cs
similarity index 64%
rename from Projects/UOContent/Accounting/Security/SHA2PasswordProtection.cs
rename to Projects/UOContent/Accounting/Security/HashAlgorithmPasswordProtection.cs
index 02d333aa2..5a689b3ce 100644
--- a/Projects/UOContent/Accounting/Security/SHA2PasswordProtection.cs
+++ b/Projects/UOContent/Accounting/Security/HashAlgorithmPasswordProtection.cs
@@ -1,8 +1,8 @@
/*************************************************************************
* ModernUO *
- * Copyright 2019-2020 - ModernUO Development Team *
+ * Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
- * File: SHA2PasswordProtection.cs *
+ * File: HashAlgorithmPasswordProtection.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
@@ -19,15 +19,19 @@ using Server.Text;
namespace Server.Accounting.Security
{
- public class SHA2PasswordProtection : IPasswordProtection
+ public class HashAlgorithmPasswordProtection : IPasswordProtection
{
- public static IPasswordProtection Instance = new SHA2PasswordProtection();
- private readonly SHA512CryptoServiceProvider m_SHA2HashProvider = new();
+ public static IPasswordProtection MD5Instance = new HashAlgorithmPasswordProtection(MD5.Create());
+ public static IPasswordProtection SHA1Instance = new HashAlgorithmPasswordProtection(SHA1.Create());
+ public static IPasswordProtection SHA2Instance = new HashAlgorithmPasswordProtection(SHA512.Create());
+ private readonly HashAlgorithm _hashAlgorithm;
+
+ public HashAlgorithmPasswordProtection(HashAlgorithm hashAlgorithm) => _hashAlgorithm = hashAlgorithm;
public string EncryptPassword(string plainPassword)
{
byte[] bytes = plainPassword.AsSpan(0, Math.Min(256, plainPassword.Length)).GetBytesAscii();
- return m_SHA2HashProvider.ComputeHash(bytes).ToHexString();
+ return _hashAlgorithm.ComputeHash(bytes).ToHexString();
}
public bool ValidatePassword(string encryptedPassword, string plainPassword) =>
diff --git a/Projects/UOContent/Accounting/Security/MD5PasswordProtection.cs b/Projects/UOContent/Accounting/Security/MD5PasswordProtection.cs
deleted file mode 100644
index ba69522d3..000000000
--- a/Projects/UOContent/Accounting/Security/MD5PasswordProtection.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2020 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: MD5PasswordProtection.cs *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- *************************************************************************/
-
-using System;
-using System.Security.Cryptography;
-using Server.Text;
-
-namespace Server.Accounting.Security
-{
- public class MD5PasswordProtection : IPasswordProtection
- {
- public static IPasswordProtection Instance = new MD5PasswordProtection();
-#pragma warning disable CA5351
- private readonly MD5CryptoServiceProvider m_MD5HashProvider = new();
-#pragma warning restore CA5351
-
- public string EncryptPassword(string plainPassword)
- {
- byte[] bytes = plainPassword.AsSpan(0, Math.Min(256, plainPassword.Length)).GetBytesAscii();
- return m_MD5HashProvider.ComputeHash(bytes).ToHexString();
- }
-
- public bool ValidatePassword(string encryptedPassword, string plainPassword) =>
- EncryptPassword(plainPassword) == encryptedPassword;
- }
-}
diff --git a/Projects/UOContent/Accounting/Security/SHA1PasswordProtection.cs b/Projects/UOContent/Accounting/Security/SHA1PasswordProtection.cs
deleted file mode 100644
index fb2fa0ea5..000000000
--- a/Projects/UOContent/Accounting/Security/SHA1PasswordProtection.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2020 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SHA1PasswordProtection.cs *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see . *
- *************************************************************************/
-
-using System;
-using System.Security.Cryptography;
-using Server.Text;
-
-namespace Server.Accounting.Security
-{
- public class SHA1PasswordProtection : IPasswordProtection
- {
- public static IPasswordProtection Instance = new SHA1PasswordProtection();
-#pragma warning disable CA5350
- private readonly SHA1CryptoServiceProvider m_SHA1HashProvider = new();
-#pragma warning restore CA5350
-
- public string EncryptPassword(string plainPassword)
- {
- byte[] bytes = plainPassword.AsSpan(0, Math.Min(256, plainPassword.Length)).GetBytesAscii();
- return m_SHA1HashProvider.ComputeHash(bytes).ToHexString();
- }
-
- public bool ValidatePassword(string encryptedPassword, string plainPassword) =>
- EncryptPassword(plainPassword) == encryptedPassword;
- }
-}
diff --git a/Projects/UOContent/Compression/TarArchive.cs b/Projects/UOContent/Compression/TarArchive.cs
index 0e5889e4a..69083e509 100755
--- a/Projects/UOContent/Compression/TarArchive.cs
+++ b/Projects/UOContent/Compression/TarArchive.cs
@@ -5,6 +5,10 @@ using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Net;
+using System.Net.Http;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
using Server.Buffers;
namespace Server.Compression
@@ -53,13 +57,18 @@ namespace Server.Compression
var tempDir = PathUtility.EnsureRandomPath(Path.GetTempPath());
var libarchiveFile = Path.Combine(tempDir, "libarchive.zip");
- using WebClient wc = new WebClient();
- wc.DownloadFile (new Uri(_libArchiveWindowsUrl), libarchiveFile);
+ // This isn't called often so we don't need to optimize
+ using (HttpClient hc = new HttpClient())
+ {
+ var result = hc.Send(new HttpRequestMessage(HttpMethod.Get, new Uri(_libArchiveWindowsUrl)));
+ using var stream = result.Content.ReadAsStream();
+ using FileStream fs = new FileStream(libarchiveFile, FileMode.Create, FileAccess.Write, FileShare.None);
+ stream.CopyTo(fs);
+ }
ZipFile.ExtractToDirectory(libarchiveFile, tempDir);
var libArchivePath = Path.Combine(tempDir, "libarchive");
- Directory.Move(Path.Combine(libArchivePath, "bin"), "bsdtar");
- Directory.Delete(libArchivePath, true);
+ PathUtility.MoveDirectory(Path.Combine(libArchivePath, "bin"), Path.Combine(Core.BaseDirectory, "bsdtar"));
File.Delete(libarchiveFile);
return Path.Combine(Core.BaseDirectory, "bsdtar/bsdtar.exe");
diff --git a/Projects/UOContent/Compression/ZstdArchive.cs b/Projects/UOContent/Compression/ZstdArchive.cs
index 35fd533d5..a1f1fee2c 100755
--- a/Projects/UOContent/Compression/ZstdArchive.cs
+++ b/Projects/UOContent/Compression/ZstdArchive.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
diff --git a/Projects/UOContent/Misc/ProfessionInfo.cs b/Projects/UOContent/Misc/ProfessionInfo.cs
index 9eda06bd9..6a2902d20 100644
--- a/Projects/UOContent/Misc/ProfessionInfo.cs
+++ b/Projects/UOContent/Misc/ProfessionInfo.cs
@@ -43,7 +43,7 @@ namespace Server
}
};
- var file = Core.FindDataFile("prof.txt");
+ var file = Core.FindDataFile("prof.txt", false);
if (!File.Exists(file))
{
var parent = Path.Combine(Core.BaseDirectory, "Data/Professions");
diff --git a/Projects/UOContent/Misc/ServerList.cs b/Projects/UOContent/Misc/ServerList.cs
index 031f44bc8..7d3a95194 100644
--- a/Projects/UOContent/Misc/ServerList.cs
+++ b/Projects/UOContent/Misc/ServerList.cs
@@ -1,5 +1,7 @@
using System;
+using System.IO;
using System.Net;
+using System.Net.Http;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using Server.Logging;
@@ -165,12 +167,16 @@ namespace Server.Misc
Utility.IPMatch("169.254.*", ip) ||
Utility.IPMatch("100.64-127.*", ip));
+ private const string _ipifyUrl = "https://api.ipify.org";
+
private static IPAddress FindPublicAddress()
{
try
{
- using WebClient wc = new WebClient();
- return IPAddress.Parse(wc.DownloadString("https://api.ipify.org"));
+ // This isn't called often so we don't need to optimize
+ using HttpClient hc = new HttpClient();
+ var ipAddress = hc.GetStringAsync(_ipifyUrl).Result;
+ return IPAddress.Parse(ipAddress);
}
catch
{
diff --git a/Projects/UOContent/Mobiles/Townfolk/Noble.cs b/Projects/UOContent/Mobiles/Townfolk/Noble.cs
index 85af8457d..46cbe227b 100644
--- a/Projects/UOContent/Mobiles/Townfolk/Noble.cs
+++ b/Projects/UOContent/Mobiles/Townfolk/Noble.cs
@@ -25,7 +25,6 @@ namespace Server.Mobiles
{
return Utility.Random(6) switch
{
- 0 => 0,
1 => Utility.RandomBlueHue(),
2 => Utility.RandomGreenHue(),
3 => Utility.RandomRedHue(),
diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj
index aab3a5561..5f322c829 100755
--- a/Projects/UOContent/UOContent.csproj
+++ b/Projects/UOContent/UOContent.csproj
@@ -39,7 +39,7 @@
false
-
+
diff --git a/Projects/UOContent/World Saves/AutoArchive.cs b/Projects/UOContent/World Saves/AutoArchive.cs
index 7d46d6168..b7cf2d50b 100755
--- a/Projects/UOContent/World Saves/AutoArchive.cs
+++ b/Projects/UOContent/World Saves/AutoArchive.cs
@@ -97,7 +97,7 @@ namespace Server.Saves
Directory.CreateDirectory(AutomaticBackupPath);
var backupPath = Path.Combine(AutomaticBackupPath, Utility.GetTimeStamp());
- Directory.Move(args.OldSavePath, backupPath);
+ PathUtility.MoveDirectory(args.OldSavePath, backupPath);
logger.Information($"Created backup at {backupPath}");
@@ -150,7 +150,7 @@ namespace Server.Saves
Directory.Delete(savePath, true);
var dirInfo = new DirectoryInfo(folder);
logger.Information($"Restoring backup {dirInfo.Name}");
- Directory.Move(folder, savePath);
+ PathUtility.MoveDirectory(folder, savePath);
break;
}
diff --git a/README.md b/README.md
index 9cd03b05e..b37e7ef2e 100644
--- a/README.md
+++ b/README.md
@@ -24,16 +24,19 @@ ModernUO [](https://access.redhat.com/downloads)
#### Running the server
-[](https://dotnet.microsoft.com/download/dotnet/5.0)
+[](https://dotnet.microsoft.com/download/dotnet/6.0)
#### Development
[](https://git-scm.com/downloads)
-[](https://dotnet.microsoft.com/download/dotnet/5.0)
+[](https://dotnet.microsoft.com/download/dotnet/6.0)
#### Supported IDEs
-[
](https://www.jetbrains.com/rider/download)
-[
](https://visualstudio.microsoft.com/downloads)
+
+[
](https://www.jetbrains.com/rider/download)
+
+[
](https://visualstudio.microsoft.com/downloads)
+Rider 2021.3+ Visual Studio 2022+
###### Note: VS Code is not currently supported.
## Getting Started
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 4f721fc49..db3ef8f9a 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -18,7 +18,12 @@ jobs:
displayName: 'Install .NET 5'
inputs:
packageType: sdk
- version: 5.0.401
+ version: 5.0.403
+ - task: UseDotNet@2
+ displayName: 'Install .NET 6'
+ inputs:
+ packageType: sdk
+ version: 6.0.100
- task: NuGetAuthenticate@0
- script: ./publish.cmd Release win
displayName: 'Build'
@@ -62,7 +67,12 @@ jobs:
displayName: 'Install .NET 5'
inputs:
packageType: sdk
- version: 5.0.401
+ version: 5.0.403
+ - task: UseDotNet@2
+ displayName: 'Install .NET 6'
+ inputs:
+ packageType: sdk
+ version: 6.0.100
- task: NuGetAuthenticate@0
- script: ./publish.cmd Release $(os)
displayName: 'Build'
From 78f587f49604484aef7b60ea0006f73d07267715 Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Sat, 13 Nov 2021 16:18:16 -0800
Subject: [PATCH 02/16] fix: Fixes dictionary codegen (#844)
* Fixes code gen with .net 6 by not using .net 6
* Fixes dictionary codegen
* Fixes kvp codegen
---
.github/workflows/build-test.yml | 2 +-
Directory.Build.props | 2 +-
.../Rules/DictionaryMigrationRule.cs | 96 +++++++++++--------
.../Rules/KeyValuePairMigrationRule.cs | 74 +++++++++-----
.../SerializationGenerator.csproj | 2 +-
azure-pipelines.yml | 4 +-
publish.cmd | 8 +-
7 files changed, 112 insertions(+), 76 deletions(-)
diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml
index 3a2b28871..8e8872f94 100644
--- a/.github/workflows/build-test.yml
+++ b/.github/workflows/build-test.yml
@@ -30,4 +30,4 @@ jobs:
- name: Build
run: ./publish.cmd
- name: Test
- run: dotnet test --no-restore
+ run: dotnet test --no-restore --framework net6.0
diff --git a/Directory.Build.props b/Directory.Build.props
index 7ebed0b53..27ca9d899 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -4,7 +4,7 @@
Kamron Batman
ModernUO
2019-2020
- net6.0
+ net5.0;net6.0
x64
x64
preview
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs
index 632fa61fd..309e4c461 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/DictionaryMigrationRule.cs
@@ -15,7 +15,6 @@
using System;
using System.Collections.Immutable;
-using System.IO;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
@@ -25,7 +24,6 @@ namespace SerializableMigration
{
public class DictionaryMigrationRule : ISerializableMigrationRule
{
- private const string KEY_VALUE_PAIR_DELIMITER = "----";
public string RuleName => nameof(DictionaryMigrationRule);
public bool GenerateRuleState(
@@ -78,25 +76,29 @@ namespace SerializableMigration
extraOptions += "@Tidy";
}
- var keyPropertyLength = serializableKeyProperty.RuleArguments?.Length ?? 0;
- var valuePropertyLength = serializableValueProperty.RuleArguments?.Length ?? 0;
- ruleArguments = new string[keyPropertyLength + valuePropertyLength + 6];
- ruleArguments[0] = extraOptions;
- ruleArguments[1] = keySymbolType.ToDisplayString();
- ruleArguments[2] = serializableKeyProperty.Rule;
+ var keyArgumentsLength = serializableKeyProperty.RuleArguments?.Length ?? 0;
+ var valueArgumentsLength = serializableValueProperty.RuleArguments?.Length ?? 0;
+ var index = 0;
- if (keyPropertyLength > 0)
+ ruleArguments = new string[7 + keyArgumentsLength + valueArgumentsLength];
+ ruleArguments[index++] = extraOptions;
+ ruleArguments[index++] = keySymbolType.ToDisplayString();
+ ruleArguments[index++] = serializableKeyProperty.Rule;
+ ruleArguments[index++] = keyArgumentsLength.ToString();
+
+ if (keyArgumentsLength > 0)
{
- Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, 3, keyPropertyLength);
+ Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
+ index += keyArgumentsLength;
}
- ruleArguments[3 + keyPropertyLength] = KEY_VALUE_PAIR_DELIMITER;
- ruleArguments[4 + keyPropertyLength] = valueSymbolType.ToDisplayString();
- ruleArguments[5 + keyPropertyLength] = serializableValueProperty.Rule;
+ ruleArguments[index++] = valueSymbolType.ToDisplayString();
+ ruleArguments[index++] = serializableValueProperty.Rule;
+ ruleArguments[index++] = valueArgumentsLength.ToString();
- if (valuePropertyLength > 0)
+ if (valueArgumentsLength > 0)
{
- Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, 6 + keyPropertyLength, valuePropertyLength);
+ Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength);
}
return true;
@@ -112,20 +114,26 @@ namespace SerializableMigration
}
var ruleArguments = property.RuleArguments;
+ var index = 1;
+ var keyType = ruleArguments![index++];
- var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![2]];
- var valueRuleIndex = Array.IndexOf(ruleArguments, KEY_VALUE_PAIR_DELIMITER, 4);
- if (valueRuleIndex == -1)
+ var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
+ var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
+
+ if (keyRuleArguments.Length > 0)
{
- throw new InvalidDataException($"Cannot find key-value delimiter in arguments for {property.Name}");
+ Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
+ index += keyRuleArguments.Length;
}
- var keyRuleArguments = new string[valueRuleIndex - 3];
- Array.Copy(ruleArguments, 3, keyRuleArguments, 0, keyRuleArguments.Length);
+ var valueType = ruleArguments[index++];
+ var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
+ var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
- var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[valueRuleIndex + 2]];
- var valueRuleArguments = new string[ruleArguments.Length - valueRuleIndex - 2];
- Array.Copy(ruleArguments, 2 + valueRuleIndex, valueRuleArguments, 0, valueRuleArguments.Length);
+ if (valueRuleArguments.Length > 0)
+ {
+ Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
+ }
var propertyName = property.Name;
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
@@ -135,16 +143,16 @@ namespace SerializableMigration
var propertyCount = $"{propertyVarPrefix}Count";
source.AppendLine($"{indent}{ruleArguments[1]} {propertyKeyEntry};");
- source.AppendLine($"{indent}{ruleArguments[valueRuleIndex + 1]} {propertyValueEntry};");
+ source.AppendLine($"{indent}{valueType} {propertyValueEntry};");
source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
- source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{ruleArguments[1]}, {ruleArguments[valueRuleIndex + 1]}>({propertyCount});");
+ source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{keyType}, {valueType}>({propertyCount});");
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
source.AppendLine($"{indent}{{");
var serializableKeyElement = new SerializableProperty
{
Name = propertyKeyEntry,
- Type = ruleArguments[1],
+ Type = keyType,
Rule = keyElementRule.RuleName,
RuleArguments = keyRuleArguments
};
@@ -154,7 +162,7 @@ namespace SerializableMigration
var serializableValueElement = new SerializableProperty
{
Name = propertyValueEntry,
- Type = ruleArguments[valueRuleIndex + 1],
+ Type = valueType,
Rule = valueElementRule.RuleName,
RuleArguments = valueRuleArguments
};
@@ -175,21 +183,27 @@ namespace SerializableMigration
}
var ruleArguments = property.RuleArguments;
- var shouldTidy = ruleArguments![0].Contains("@Tidy");
+ var index = 0;
+ var shouldTidy = ruleArguments![index++].Contains("@Tidy");
+ var keyType = ruleArguments![index++];
- var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[2]];
- var valueRuleIndex = Array.IndexOf(ruleArguments, KEY_VALUE_PAIR_DELIMITER, 3);
- if (valueRuleIndex == -1)
+ var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![index++]];
+ var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
+
+ if (keyRuleArguments.Length > 0)
{
- throw new InvalidDataException($"Cannot find key-value delimiter in arguments for {property.Name}");
+ Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
+ index += keyRuleArguments.Length;
}
- var keyRuleArguments = new string[valueRuleIndex - 3];
- Array.Copy(ruleArguments, 3, keyRuleArguments, 0, keyRuleArguments.Length);
+ var valueType = ruleArguments[index++];
+ var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
+ var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
- var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[valueRuleIndex + 2]];
- var valueRuleArguments = new string[ruleArguments.Length - valueRuleIndex - 2];
- Array.Copy(ruleArguments, 2 + valueRuleIndex, valueRuleArguments, 0, valueRuleArguments.Length);
+ if (valueRuleArguments.Length > 0)
+ {
+ Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
+ }
var propertyName = property.Name;
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
@@ -211,7 +225,7 @@ namespace SerializableMigration
var serializableKeyElement = new SerializableProperty
{
Name = propertyKeyEntry,
- Type = ruleArguments[1],
+ Type = keyType,
Rule = keyElementRule.RuleName,
RuleArguments = keyRuleArguments
};
@@ -221,12 +235,12 @@ namespace SerializableMigration
var serializableValueElement = new SerializableProperty
{
Name = propertyValueEntry,
- Type = ruleArguments[valueRuleIndex + 1],
+ Type = valueType,
Rule = valueElementRule.RuleName,
RuleArguments = valueRuleArguments
};
- keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement);
+ valueElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement);
source.AppendLine($"{indent} }}");
source.AppendLine($"{indent}}}");
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs
index 7ebdf064d..1797764c1 100644
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs
+++ b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs
@@ -41,12 +41,12 @@ namespace SerializableMigration
return false;
}
- var typeArguments = namedTypeSymbol.TypeArguments;
+ var keySymbolType = namedTypeSymbol.TypeArguments[0];
var keySerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
compilation,
"key",
- typeArguments[0],
+ keySymbolType,
0,
attributes,
serializableTypes,
@@ -55,10 +55,12 @@ namespace SerializableMigration
null
);
+ var valueSymbolType = namedTypeSymbol.TypeArguments[1];
+
var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
compilation,
"value",
- typeArguments[1],
+ valueSymbolType,
1,
attributes,
serializableTypes,
@@ -72,17 +74,19 @@ namespace SerializableMigration
var index = 0;
// Key
- ruleArguments = new string[5 + keyArgumentsLength + valueArgumentsLength];
- ruleArguments[index++] = typeArguments[0].ToDisplayString();
+ ruleArguments = new string[6 + keyArgumentsLength + valueArgumentsLength];
+ ruleArguments[index++] = ""; // Extra options
+ ruleArguments[index++] = keySymbolType.ToDisplayString();
ruleArguments[index++] = keySerializedProperty.Rule;
ruleArguments[index++] = keyArgumentsLength.ToString();
if (keyArgumentsLength > 0)
{
Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
+ index += keyArgumentsLength;
}
// Value
- ruleArguments[index++] = typeArguments[1].ToDisplayString();
+ ruleArguments[index++] = valueSymbolType.ToDisplayString();
ruleArguments[index++] = valueSerializedProperty.Rule;
if (valueArgumentsLength > 0)
@@ -103,10 +107,16 @@ namespace SerializableMigration
}
var ruleArguments = property.RuleArguments;
- var keyType = ruleArguments![0];
- var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1]];
- var keyRuleArguments = new string[int.Parse(ruleArguments[2])];
- Array.Copy(ruleArguments, 3, keyRuleArguments, 0, keyRuleArguments.Length);
+ var index = 1; // skip extra options
+ var keyType = ruleArguments![index++];
+ var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
+ var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
+
+ if (keyRuleArguments.Length > 0)
+ {
+ Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
+ index += keyRuleArguments.Length;
+ }
var serializableKeyProperty = new SerializableProperty
{
@@ -123,11 +133,14 @@ namespace SerializableMigration
parentReference
);
- var valueIndex = 3 + keyRuleArguments.Length;
- var valueType = ruleArguments[valueIndex++];
- var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[valueIndex++]];
- var valueRuleArguments = new string[ruleArguments.Length - valueIndex];
- Array.Copy(ruleArguments, valueIndex, valueRuleArguments, 0, valueRuleArguments.Length);
+ var valueType = ruleArguments[index++];
+ var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
+ var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
+
+ if (valueRuleArguments.Length > 0)
+ {
+ Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
+ }
var serializableValueProperty = new SerializableProperty
{
@@ -137,7 +150,7 @@ namespace SerializableMigration
RuleArguments = valueRuleArguments
};
- keyRule.GenerateDeserializationMethod(
+ valueRule.GenerateDeserializationMethod(
source,
indent,
serializableValueProperty,
@@ -159,10 +172,16 @@ namespace SerializableMigration
}
var ruleArguments = property.RuleArguments;
- var keyType = ruleArguments![0];
- var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1]];
- var keyRuleArguments = new string[int.Parse(ruleArguments[2])];
- Array.Copy(ruleArguments, 3, keyRuleArguments, 0, keyRuleArguments.Length);
+ var index = 1; // skip extra options
+ var keyType = ruleArguments![index++];
+ var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
+ var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
+
+ if (keyRuleArguments.Length > 0)
+ {
+ Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
+ index += keyRuleArguments.Length;
+ }
var serializableKeyProperty = new SerializableProperty
{
@@ -178,11 +197,14 @@ namespace SerializableMigration
serializableKeyProperty
);
- var valueIndex = 3 + keyRuleArguments.Length;
- var valueType = ruleArguments[valueIndex++];
- var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[valueIndex++]];
- var valueRuleArguments = new string[ruleArguments.Length - valueIndex];
- Array.Copy(ruleArguments, valueIndex, valueRuleArguments, 0, valueRuleArguments.Length);
+ var valueType = ruleArguments[index++];
+ var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
+ var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
+
+ if (valueRuleArguments.Length > 0)
+ {
+ Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
+ }
var serializableValueProperty = new SerializableProperty
{
@@ -192,7 +214,7 @@ namespace SerializableMigration
RuleArguments = valueRuleArguments
};
- keyRule.GenerateSerializationMethod(
+ valueRule.GenerateSerializationMethod(
source,
indent,
serializableValueProperty
diff --git a/Projects/SerializationGenerator/SerializationGenerator.csproj b/Projects/SerializationGenerator/SerializationGenerator.csproj
index 1839dfeb3..03b5a5bdb 100755
--- a/Projects/SerializationGenerator/SerializationGenerator.csproj
+++ b/Projects/SerializationGenerator/SerializationGenerator.csproj
@@ -1,6 +1,6 @@
- netstandard2.0
+ netstandard2.0
preview
analyzers
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index db3ef8f9a..6923ed2ae 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -27,7 +27,7 @@ jobs:
- task: NuGetAuthenticate@0
- script: ./publish.cmd Release win
displayName: 'Build'
- - script: dotnet test --no-restore
+ - script: dotnet test --no-restore --framework net6.0
displayName: 'Test'
- job: BuildLinux
@@ -76,5 +76,5 @@ jobs:
- task: NuGetAuthenticate@0
- script: ./publish.cmd Release $(os)
displayName: 'Build'
- - script: dotnet test --no-restore
+ - script: dotnet test --no-restore --framework net6.0
displayName: 'Test'
diff --git a/publish.cmd b/publish.cmd
index 140dd547c..e0f9fe6df 100755
--- a/publish.cmd
+++ b/publish.cmd
@@ -32,8 +32,8 @@ dotnet clean --verbosity quiet
echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json
dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json
-echo dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
-dotnet publish ${config} ${os} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
+echo dotnet publish ${config} ${os} --framework net6.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
+dotnet publish ${config} ${os} --framework net6.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
@@ -65,8 +65,8 @@ dotnet clean --verbosity quiet
echo dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json
dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json
-echo dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
-dotnet publish %config% %os% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
+echo dotnet publish %config% %os% --framework net6.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
+dotnet publish %config% %os% --framework net6.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
echo dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
dotnet build -c Release Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
From ecaf8ca98a6814f21fef082ab17c77affbf8ec6b Mon Sep 17 00:00:00 2001
From: Arthrutus <75637913+Arthrutus@users.noreply.github.com>
Date: Sat, 13 Nov 2021 18:18:46 -0600
Subject: [PATCH 03/16] fix: Fixes door location at hedge maze (#841)
---
.../Data/Decoration/Britannia/_hedgemaze.cfg | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/Distribution/Data/Decoration/Britannia/_hedgemaze.cfg b/Distribution/Data/Decoration/Britannia/_hedgemaze.cfg
index 127f363c9..25a7f712f 100644
--- a/Distribution/Data/Decoration/Britannia/_hedgemaze.cfg
+++ b/Distribution/Data/Decoration/Britannia/_hedgemaze.cfg
@@ -133,8 +133,13 @@ LocalizedSign 0x1F28 (LabelNumber=1016109)
# wooden gate
DarkWoodGate 0x0866 (Facing=WestCW)
-1131 2237 40
-1131 2237 50
+1132 2237 40
+1132 2237 50
+
+# wooden gate
+DarkWoodGate 0x0868 (Facing=EastCCW)
+1133 2237 40
+1133 2237 50
# candelabra
CandelabraStand 0x0B26
@@ -148,11 +153,6 @@ FancyArmoire 0x0A51
1132 2231 40
1132 2230 40
-# wooden gate
-DarkWoodGate 0x0868 (Facing=EastCCW)
-1132 2237 40
-1132 2237 50
-
# book
Static 0x1E20
1133 2235 24
From 38c4d09028cb3219c64d29490b767eea9f5230f4 Mon Sep 17 00:00:00 2001
From: nullptr-w8 <79784082+nullptr-w8@users.noreply.github.com>
Date: Sun, 14 Nov 2021 05:19:34 +0500
Subject: [PATCH 04/16] fix: Fixes animal taming timeout in case target is
cancelled. (#842)
---
Projects/UOContent/Skills/AnimalTaming.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Projects/UOContent/Skills/AnimalTaming.cs b/Projects/UOContent/Skills/AnimalTaming.cs
index 99833a41e..99b1293ef 100644
--- a/Projects/UOContent/Skills/AnimalTaming.cs
+++ b/Projects/UOContent/Skills/AnimalTaming.cs
@@ -33,7 +33,7 @@ namespace Server.SkillHandlers
m.SendLocalizedMessage(502789); // Tame which animal?
}
- return TimeSpan.FromHours(6.0);
+ return TimeSpan.FromSeconds(30);
}
public static bool CheckMastery(Mobile tamer, BaseCreature creature) =>
From 91493f7f274c080a976c11781cc20cb82aecd219 Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Sat, 13 Nov 2021 16:31:10 -0800
Subject: [PATCH 05/16] fix: Fixes guild assignment (#846)
---
Projects/Server/World/World.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs
index 72d21ac2b..a5d57436a 100644
--- a/Projects/Server/World/World.cs
+++ b/Projects/Server/World/World.cs
@@ -666,7 +666,7 @@ namespace Server
T entity;
// Add to this list when creating new serializable types
- if (typeof(BaseGuild).IsAssignableTo(typeT))
+ if (typeof(BaseGuild).IsAssignableFrom(typeT))
{
entity = FindGuild(serial) as T;
}
From e5f55a424aec658481ef471ab4cb588d715cd51d Mon Sep 17 00:00:00 2001
From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
Date: Sun, 14 Nov 2021 18:31:32 -0800
Subject: [PATCH 06/16] fix: Cleans up spell info variable (#848)
---
Projects/UOContent/Spells/Base/MagerySpell.cs | 3 +--
Projects/UOContent/Spells/Base/SpellHelper.cs | 9 +++------
Projects/UOContent/Spells/Bushido/Confidence.cs | 4 ++--
Projects/UOContent/Spells/Bushido/CounterAttack.cs | 4 ++--
Projects/UOContent/Spells/Bushido/Evasion.cs | 5 ++---
Projects/UOContent/Spells/Bushido/HonorableExecution.cs | 4 ++--
Projects/UOContent/Spells/Chivalry/CleanseByFire.cs | 4 ++--
Projects/UOContent/Spells/Chivalry/CloseWounds.cs | 4 ++--
Projects/UOContent/Spells/Chivalry/ConsecrateWeapon.cs | 4 ++--
Projects/UOContent/Spells/Chivalry/DispelEvil.cs | 4 ++--
Projects/UOContent/Spells/Chivalry/DivineFury.cs | 4 ++--
Projects/UOContent/Spells/Chivalry/EnemyOfOne.cs | 4 ++--
Projects/UOContent/Spells/Chivalry/HolyLight.cs | 4 ++--
Projects/UOContent/Spells/Chivalry/NobleSacrifice.cs | 4 ++--
Projects/UOContent/Spells/Chivalry/RemoveCurse.cs | 4 ++--
Projects/UOContent/Spells/Chivalry/SacredJourney.cs | 4 ++--
Projects/UOContent/Spells/Eighth/AirElemental.cs | 4 ++--
Projects/UOContent/Spells/Eighth/EarthElemental.cs | 4 ++--
Projects/UOContent/Spells/Eighth/Earthquake.cs | 4 ++--
Projects/UOContent/Spells/Eighth/EnergyVortex.cs | 4 ++--
Projects/UOContent/Spells/Eighth/FireElemental.cs | 4 ++--
Projects/UOContent/Spells/Eighth/Resurrection.cs | 4 ++--
Projects/UOContent/Spells/Eighth/SummonDaemon.cs | 4 ++--
Projects/UOContent/Spells/Eighth/WaterElemental.cs | 4 ++--
Projects/UOContent/Spells/Fifth/BladeSpirits.cs | 4 ++--
Projects/UOContent/Spells/Fifth/DispelField.cs | 4 ++--
Projects/UOContent/Spells/Fifth/Incognito.cs | 4 ++--
Projects/UOContent/Spells/Fifth/MagicReflect.cs | 4 ++--
Projects/UOContent/Spells/Fifth/MindBlast.cs | 6 +++---
Projects/UOContent/Spells/Fifth/Paralyze.cs | 4 ++--
Projects/UOContent/Spells/Fifth/PoisonField.cs | 4 ++--
Projects/UOContent/Spells/Fifth/SummonCreature.cs | 4 ++--
Projects/UOContent/Spells/First/Clumsy.cs | 4 ++--
Projects/UOContent/Spells/First/CreateFood.cs | 4 ++--
Projects/UOContent/Spells/First/Feeblemind.cs | 4 ++--
Projects/UOContent/Spells/First/Heal.cs | 4 ++--
Projects/UOContent/Spells/First/MagicArrow.cs | 4 ++--
Projects/UOContent/Spells/First/NightSight.cs | 4 ++--
Projects/UOContent/Spells/First/ReactiveArmor.cs | 4 ++--
Projects/UOContent/Spells/First/Weaken.cs | 4 ++--
Projects/UOContent/Spells/Fourth/ArchCure.cs | 4 ++--
Projects/UOContent/Spells/Fourth/ArchProtection.cs | 4 ++--
Projects/UOContent/Spells/Fourth/Curse.cs | 4 ++--
Projects/UOContent/Spells/Fourth/FireField.cs | 4 ++--
Projects/UOContent/Spells/Fourth/GreaterHeal.cs | 4 ++--
Projects/UOContent/Spells/Fourth/Lightning.cs | 4 ++--
Projects/UOContent/Spells/Fourth/ManaDrain.cs | 4 ++--
Projects/UOContent/Spells/Fourth/Recall.cs | 4 ++--
.../Spells/Gargoyle/SpellDefinitions/FlySpell.cs | 4 ++--
.../UOContent/Spells/Mysticism/AnimatedWeaponSpell.cs | 4 ++--
Projects/UOContent/Spells/Mysticism/EagleStrikeSpell.cs | 4 ++--
Projects/UOContent/Spells/Mysticism/HailStormSpell.cs | 4 ++--
.../UOContent/Spells/Mysticism/NetherCycloneSpell.cs | 4 ++--
Projects/UOContent/Spells/Mysticism/SpellPlagueSpell.cs | 4 ++--
Projects/UOContent/Spells/Mysticism/StoneFormSpell.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/AnimateDeadSpell.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/BloodOathSpell.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/CorpseSkin.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/CurseWeapon.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/EvilOmen.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/Exorcism.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/HorrificBeast.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/LichForm.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/MindRot.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/PainSpike.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/PoisonStrike.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/Strangle.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/SummonFamiliar.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/VampiricEmbrace.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/VengefulSpirit.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/Wither.cs | 4 ++--
Projects/UOContent/Spells/Necromancy/WraithForm.cs | 4 ++--
Projects/UOContent/Spells/Ninjitsu/AnimalForm.cs | 4 ++--
Projects/UOContent/Spells/Ninjitsu/MirrorImage.cs | 4 ++--
Projects/UOContent/Spells/Ninjitsu/ShadowJump.cs | 4 ++--
Projects/UOContent/Spells/Second/Agility.cs | 4 ++--
Projects/UOContent/Spells/Second/Cunning.cs | 4 ++--
Projects/UOContent/Spells/Second/Cure.cs | 4 ++--
Projects/UOContent/Spells/Second/Harm.cs | 4 ++--
Projects/UOContent/Spells/Second/MagicTrap.cs | 4 ++--
Projects/UOContent/Spells/Second/Protection.cs | 4 ++--
Projects/UOContent/Spells/Second/RemoveTrap.cs | 4 ++--
Projects/UOContent/Spells/Second/Strength.cs | 4 ++--
Projects/UOContent/Spells/Seventh/ChainLightning.cs | 4 ++--
Projects/UOContent/Spells/Seventh/EnergyField.cs | 4 ++--
Projects/UOContent/Spells/Seventh/FlameStrike.cs | 4 ++--
Projects/UOContent/Spells/Seventh/GateTravel.cs | 4 ++--
Projects/UOContent/Spells/Seventh/ManaVampire.cs | 4 ++--
Projects/UOContent/Spells/Seventh/MassDispel.cs | 4 ++--
Projects/UOContent/Spells/Seventh/MeteorSwarm.cs | 4 ++--
Projects/UOContent/Spells/Seventh/Polymorph.cs | 4 ++--
Projects/UOContent/Spells/Sixth/Dispel.cs | 4 ++--
Projects/UOContent/Spells/Sixth/EnergyBolt.cs | 4 ++--
Projects/UOContent/Spells/Sixth/Explosion.cs | 5 ++---
Projects/UOContent/Spells/Sixth/Invisibility.cs | 4 ++--
Projects/UOContent/Spells/Sixth/Mark.cs | 4 ++--
Projects/UOContent/Spells/Sixth/MassCurse.cs | 4 ++--
Projects/UOContent/Spells/Sixth/ParalyzeField.cs | 4 ++--
Projects/UOContent/Spells/Sixth/Reveal.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/ArcaneCircle.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/AttuneWeapon.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/EssenceOfWind.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/EtherealVoyage.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/GiftOfLife.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/GiftOfRenewal.cs | 4 ++--
.../UOContent/Spells/Spellweaving/ImmolatingWeapon.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/NatureFury.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/ReaperForm.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/SummonFey.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/SummonFiend.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/Thunderstorm.cs | 4 ++--
Projects/UOContent/Spells/Spellweaving/WordOfDeath.cs | 4 ++--
Projects/UOContent/Spells/Third/Bless.cs | 4 ++--
Projects/UOContent/Spells/Third/Fireball.cs | 4 ++--
Projects/UOContent/Spells/Third/MagicLock.cs | 4 ++--
Projects/UOContent/Spells/Third/Poison.cs | 4 ++--
Projects/UOContent/Spells/Third/Telekinesis.cs | 4 ++--
Projects/UOContent/Spells/Third/Teleport.cs | 4 ++--
Projects/UOContent/Spells/Third/Unlock.cs | 4 ++--
Projects/UOContent/Spells/Third/WallOfStone.cs | 4 ++--
120 files changed, 241 insertions(+), 247 deletions(-)
diff --git a/Projects/UOContent/Spells/Base/MagerySpell.cs b/Projects/UOContent/Spells/Base/MagerySpell.cs
index d496cf100..c42d60954 100644
--- a/Projects/UOContent/Spells/Base/MagerySpell.cs
+++ b/Projects/UOContent/Spells/Base/MagerySpell.cs
@@ -9,8 +9,7 @@ namespace Server.Spells
private static readonly int[] m_ManaTable = { 4, 6, 9, 11, 14, 20, 40, 50 };
- public MagerySpell(Mobile caster, Item scroll, SpellInfo info)
- : base(caster, scroll, info)
+ public MagerySpell(Mobile caster, Item scroll, SpellInfo info) : base(caster, scroll, info)
{
}
diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs
index 6b7cb8a24..cbf225459 100644
--- a/Projects/UOContent/Spells/Base/SpellHelper.cs
+++ b/Projects/UOContent/Spells/Base/SpellHelper.cs
@@ -33,8 +33,7 @@ namespace Server
{
private readonly Mobile m_Mobile;
- public InternalTimer(Mobile m)
- : base(TimeSpan.FromMinutes(1.0))
+ public InternalTimer(Mobile m) : base(TimeSpan.FromMinutes(1.0))
{
m_Mobile = m;
}
@@ -1128,8 +1127,7 @@ namespace Server.Spells
private readonly Mobile m_Target;
private int m_Damage;
- public SpellDamageTimer(Spell s, Mobile target, Mobile from, int damage, TimeSpan delay)
- : base(delay)
+ public SpellDamageTimer(Spell s, Mobile target, Mobile from, int damage, TimeSpan delay) : base(delay)
{
m_Target = target;
m_From = from;
@@ -1170,8 +1168,7 @@ namespace Server.Spells
public SpellDamageTimerAOS(
Spell s, TimeSpan delay, Mobile target, Mobile from, int damage, int phys, int fire, int cold,
int pois, int nrgy, int chaos, DFAlgorithm dfa
- )
- : base(delay)
+ ) : base(delay)
{
m_Target = target;
m_From = from;
diff --git a/Projects/UOContent/Spells/Bushido/Confidence.cs b/Projects/UOContent/Spells/Bushido/Confidence.cs
index a846088f1..be3313cf8 100644
--- a/Projects/UOContent/Spells/Bushido/Confidence.cs
+++ b/Projects/UOContent/Spells/Bushido/Confidence.cs
@@ -5,7 +5,7 @@ namespace Server.Spells.Bushido
{
public class Confidence : SamuraiSpell
{
- private static readonly SpellInfo m_Info = new(
+ private static readonly SpellInfo _info = new(
"Confidence",
null,
-1,
@@ -15,7 +15,7 @@ namespace Server.Spells.Bushido
private static readonly Dictionary m_Table = new();
private static readonly Dictionary m_RegenTable = new();
- public Confidence(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
+ public Confidence(Mobile caster, Item scroll) : base(caster, scroll, _info)
{
}
diff --git a/Projects/UOContent/Spells/Bushido/CounterAttack.cs b/Projects/UOContent/Spells/Bushido/CounterAttack.cs
index 04eb1ebcb..ba546fa5b 100644
--- a/Projects/UOContent/Spells/Bushido/CounterAttack.cs
+++ b/Projects/UOContent/Spells/Bushido/CounterAttack.cs
@@ -6,7 +6,7 @@ namespace Server.Spells.Bushido
{
public class CounterAttack : SamuraiSpell
{
- private static readonly SpellInfo m_Info = new(
+ private static readonly SpellInfo _info = new(
"CounterAttack",
null,
-1,
@@ -15,7 +15,7 @@ namespace Server.Spells.Bushido
private static readonly Dictionary m_Table = new();
- public CounterAttack(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
+ public CounterAttack(Mobile caster, Item scroll) : base(caster, scroll, _info)
{
}
diff --git a/Projects/UOContent/Spells/Bushido/Evasion.cs b/Projects/UOContent/Spells/Bushido/Evasion.cs
index 6c1c37b5c..d39b43194 100644
--- a/Projects/UOContent/Spells/Bushido/Evasion.cs
+++ b/Projects/UOContent/Spells/Bushido/Evasion.cs
@@ -6,7 +6,7 @@ namespace Server.Spells.Bushido
{
public class Evasion : SamuraiSpell
{
- private static readonly SpellInfo m_Info = new(
+ private static readonly SpellInfo _info = new(
"Evasion",
null,
-1,
@@ -15,8 +15,7 @@ namespace Server.Spells.Bushido
private static readonly Dictionary m_Table = new();
- public Evasion(Mobile caster, Item scroll)
- : base(caster, scroll, m_Info)
+ public Evasion(Mobile caster, Item scroll) : base(caster, scroll, _info)
{
}
diff --git a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs
index 0df746862..35da3b3d8 100644
--- a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs
+++ b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs
@@ -98,8 +98,8 @@ namespace Server.Spells.Bushido
}
public HonorableExecutionTimer(
- TimeSpan duration, Mobile from, int swingBonus, List
diff --git a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj b/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
index 31e89d561..d3d1a168e 100755
--- a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
+++ b/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
@@ -1,7 +1,6 @@
Exe
- net5.0
Output
@@ -14,7 +13,10 @@
-
-
+
+
+
+
+
diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj
index cf357a582..f2cc0ec7a 100755
--- a/Projects/Server/Server.csproj
+++ b/Projects/Server/Server.csproj
@@ -34,7 +34,7 @@
-
+
diff --git a/Projects/Server/Utilities/Utility.cs b/Projects/Server/Utilities/Utility.cs
index a184d4b23..d3a780a4f 100644
--- a/Projects/Server/Utilities/Utility.cs
+++ b/Projects/Server/Utilities/Utility.cs
@@ -1049,6 +1049,21 @@ namespace Server
return min + (int)RandomSources.Source.Next((uint)(max - min + 1));
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static long RandomMinMax(long min, long max)
+ {
+ if (min > max)
+ {
+ (min, max) = (max, min);
+ }
+ else if (min == max)
+ {
+ return min;
+ }
+
+ return min + RandomSources.Source.Next(max - min + 1);
+ }
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Random(int from, int count) => RandomSources.Source.Next(from, count);
diff --git a/Projects/UOContent/Items/Construction/Ankhs.cs b/Projects/UOContent/Items/Construction/Ankhs.cs
index a9993b5df..d75e968f5 100644
--- a/Projects/UOContent/Items/Construction/Ankhs.cs
+++ b/Projects/UOContent/Items/Construction/Ankhs.cs
@@ -114,7 +114,7 @@ namespace Server.Items
[Serializable(0, false)]
public partial class AnkhWest : Item
{
- [SerializableField(0)]
+ [SerializableField(0, getter: "private", setter: "private")]
private InternalItem _item;
[Constructible]
@@ -184,7 +184,7 @@ namespace Server.Items
}
[Serializable(0, false)]
- private class InternalItem : Item
+ private partial class InternalItem : Item
{
[SerializableField(0)]
private AnkhWest _item;
@@ -260,7 +260,7 @@ namespace Server.Items
[Serializable(0, false)]
public partial class AnkhNorth : Item
{
- [SerializableField(0)]
+ [SerializableField(0, getter: "private", setter: "private")]
private InternalItem _item;
[Constructible]
@@ -332,7 +332,7 @@ namespace Server.Items
[TypeAlias("Server.Items.AnkhEast+InternalItem")]
[Serializable(0, false)]
- private class InternalItem : Item
+ private partial class InternalItem : Item
{
[SerializableField(0)]
private AnkhNorth _item;
diff --git a/Projects/UOContent/UOContent.csproj b/Projects/UOContent/UOContent.csproj
index 5f322c829..2ef0f6dfc 100755
--- a/Projects/UOContent/UOContent.csproj
+++ b/Projects/UOContent/UOContent.csproj
@@ -40,7 +40,7 @@
-
+