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 [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc [![RedHat 7/8](https://img.shields.io/badge/-8-BE0000?logo=red%20hat&logoColor=white)](https://access.redhat.com/downloads) #### Running the server -[![.NET](https://img.shields.io/badge/.NET-%205.0-5C2D91)](https://dotnet.microsoft.com/download/dotnet/5.0) +[![.NET](https://img.shields.io/badge/.NET-%206.0-5C2D91)](https://dotnet.microsoft.com/download/dotnet/6.0) #### Development [![git](https://img.shields.io/badge/-git-F05032?logo=git&logoColor=white)](https://git-scm.com/downloads) -[![.NET](https://img.shields.io/badge/.NET-%205.0.10%20SDK-5C2D91)](https://dotnet.microsoft.com/download/dotnet/5.0) +[![.NET](https://img.shields.io/badge/.NET-%206.0%20SDK-5C2D91)](https://dotnet.microsoft.com/download/dotnet/6.0) #### Supported IDEs -[Jetbrains Rider 2021.2](https://www.jetbrains.com/rider/download) -[Visual Studio 2019](https://visualstudio.microsoft.com/downloads) +  +[Jetbrains Rider 2021.3](https://www.jetbrains.com/rider/download) +                     +[Visual Studio 2022](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'