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'