diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml
index cf746c82e..8e8872f94 100644
--- a/.github/workflows/build-test.yml
+++ b/.github/workflows/build-test.yml
@@ -23,11 +23,11 @@ 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
- run: dotnet test --no-restore
+ run: dotnet test --no-restore --framework net6.0
diff --git a/Directory.Build.props b/Directory.Build.props
index 0ac231599..c48855eab 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
@@ -56,9 +56,9 @@
-
+
- 3.4.240
+ 3.4.244
all
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
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/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/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/SerializationGenerator/SerializationGenerator.csproj b/Projects/SerializationGenerator/SerializationGenerator.csproj
index 1839dfeb3..f74e5e965 100755
--- a/Projects/SerializationGenerator/SerializationGenerator.csproj
+++ b/Projects/SerializationGenerator/SerializationGenerator.csproj
@@ -6,11 +6,12 @@
-
-
-
-
-
+
+
+
+
+
+
@@ -22,6 +23,7 @@
+
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/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.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/Interfaces.cs b/Projects/Server/Interfaces.cs
index 587abead0..3e46e8bb2 100644
--- a/Projects/Server/Interfaces.cs
+++ b/Projects/Server/Interfaces.cs
@@ -22,8 +22,7 @@ namespace Server
{
int MaxRange { get; }
void OnBeforeSwing(Mobile attacker, Mobile defender);
- TimeSpan OnSwing(Mobile attacker, Mobile defender);
- TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus);
+ TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0);
void GetStatusDamage(Mobile from, out int min, out int max);
}
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/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/Targeting/Target.cs b/Projects/Server/Targeting/Target.cs
index d0035ed3b..e60231322 100644
--- a/Projects/Server/Targeting/Target.cs
+++ b/Projects/Server/Targeting/Target.cs
@@ -164,36 +164,33 @@ namespace Server.Targeting
{
OnTargetOutOfRange(from, targeted);
}
- else
+ else if (!from.CanSee(targeted))
{
- if (!from.CanSee(targeted))
- {
- OnCantSeeTarget(from, targeted);
- }
- else if (CheckLOS && !from.InLOS(targeted))
- {
- OnTargetOutOfLOS(from, targeted);
- }
- else if (item?.InSecureTrade == true)
- {
- OnTargetInSecureTrade(from, targeted);
- }
- else if (item?.IsAccessibleTo(from) == false)
- {
- OnTargetNotAccessible(from, targeted);
- }
- else if (item?.CheckTarget(from, this, targeted) == false)
- {
- OnTargetUntargetable(from, targeted);
- }
- else if (mobile?.CheckTarget(from, this, mobile) == false)
- {
- OnTargetUntargetable(from, mobile);
- }
- else if (from.Region.OnTarget(from, this, targeted))
- {
- OnTarget(from, targeted);
- }
+ OnCantSeeTarget(from, targeted);
+ }
+ else if (CheckLOS && !from.InLOS(targeted))
+ {
+ OnTargetOutOfLOS(from, targeted);
+ }
+ else if (item?.InSecureTrade == true)
+ {
+ OnTargetInSecureTrade(from, targeted);
+ }
+ else if (item?.IsAccessibleTo(from) == false)
+ {
+ OnTargetNotAccessible(from, targeted);
+ }
+ else if (item?.CheckTarget(from, this, targeted) == false)
+ {
+ OnTargetUntargetable(from, targeted);
+ }
+ else if (mobile?.CheckTarget(from, this, mobile) == false)
+ {
+ OnTargetUntargetable(from, mobile);
+ }
+ else if (from.Region.OnTarget(from, this, targeted))
+ {
+ OnTarget(from, targeted);
}
OnTargetFinish(from);
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/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/Server/World/World.cs b/Projects/Server/World/World.cs
index 02b3013d5..a5d57436a 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)
{
@@ -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;
}
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/Commands/Handlers.cs b/Projects/UOContent/Commands/Handlers.cs
index 867ed68d6..b289f9acd 100644
--- a/Projects/UOContent/Commands/Handlers.cs
+++ b/Projects/UOContent/Commands/Handlers.cs
@@ -7,11 +7,9 @@ using Server.Gumps;
using Server.Items;
using Server.Menus.ItemLists;
using Server.Menus.Questions;
-using Server.Misc;
using Server.Mobiles;
using Server.Multis;
using Server.Network;
-using Server.Saves;
using Server.Spells;
using Server.Targeting;
using Server.Targets;
diff --git a/Projects/UOContent/Compression/TarArchive.cs b/Projects/UOContent/Compression/TarArchive.cs
index 0e5889e4a..4905a3683 100755
--- a/Projects/UOContent/Compression/TarArchive.cs
+++ b/Projects/UOContent/Compression/TarArchive.cs
@@ -1,10 +1,9 @@
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
-using System.Net;
+using System.Net.Http;
using Server.Buffers;
namespace Server.Compression
@@ -53,13 +52,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/Items/Construction/Ankhs.cs b/Projects/UOContent/Items/Construction/Ankhs.cs
index 2e3202048..d75e968f5 100644
--- a/Projects/UOContent/Items/Construction/Ankhs.cs
+++ b/Projects/UOContent/Items/Construction/Ankhs.cs
@@ -80,9 +80,8 @@ namespace Server.Items
if (m_Mobile.KarmaLocked)
{
- m_Mobile.SendLocalizedMessage(
- 1060192
- ); // Your karma has been locked. Your karma can no longer be raised.
+ // Your karma has been locked. Your karma can no longer be raised.
+ m_Mobile.SendLocalizedMessage(1060192);
}
else
{
@@ -112,20 +111,17 @@ namespace Server.Items
}
}
- public class AnkhWest : Item
+ [Serializable(0, false)]
+ public partial class AnkhWest : Item
{
- private InternalItem m_Item;
+ [SerializableField(0, getter: "private", setter: "private")]
+ private InternalItem _item;
[Constructible]
public AnkhWest(bool bloodied = false) : base(bloodied ? 0x1D98 : 0x3)
{
Movable = false;
-
- m_Item = new InternalItem(bloodied, this);
- }
-
- public AnkhWest(Serial serial) : base(serial)
- {
+ _item = new InternalItem(bloodied, this);
}
public override bool HandlesOnMovement => true; // Tell the core that we implement OnMovement
@@ -138,9 +134,9 @@ namespace Server.Items
set
{
base.Hue = value;
- if (m_Item.Hue != value)
+ if (_item.Hue != value)
{
- m_Item.Hue = value;
+ _item.Hue = value;
}
}
}
@@ -166,17 +162,17 @@ namespace Server.Items
public override void OnLocationChange(Point3D oldLocation)
{
- if (m_Item != null)
+ if (_item != null)
{
- m_Item.Location = new Point3D(X, Y + 1, Z);
+ _item.Location = new Point3D(X, Y + 1, Z);
}
}
public override void OnMapChange()
{
- if (m_Item != null)
+ if (_item != null)
{
- m_Item.Map = Map;
+ _item.Map = Map;
}
}
@@ -184,40 +180,19 @@ namespace Server.Items
{
base.OnAfterDelete();
- m_Item?.Delete();
+ _item?.Delete();
}
- public override void Serialize(IGenericWriter writer)
+ [Serializable(0, false)]
+ private partial class InternalItem : Item
{
- base.Serialize(writer);
-
- writer.Write(0); // version
-
- writer.Write(m_Item);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
-
- m_Item = reader.ReadEntity();
- }
-
- private class InternalItem : Item
- {
- private AnkhWest m_Item;
+ [SerializableField(0)]
+ private AnkhWest _item;
public InternalItem(bool bloodied, AnkhWest item) : base(bloodied ? 0x1D97 : 0x2)
{
Movable = false;
-
- m_Item = item;
- }
-
- public InternalItem(Serial serial) : base(serial)
- {
+ _item = item;
}
public override bool HandlesOnMovement => true; // Tell the core that we implement OnMovement
@@ -230,26 +205,26 @@ namespace Server.Items
set
{
base.Hue = value;
- if (m_Item.Hue != value)
+ if (_item.Hue != value)
{
- m_Item.Hue = value;
+ _item.Hue = value;
}
}
}
public override void OnLocationChange(Point3D oldLocation)
{
- if (m_Item != null)
+ if (_item != null)
{
- m_Item.Location = new Point3D(X, Y - 1, Z);
+ _item.Location = new Point3D(X, Y - 1, Z);
}
}
public override void OnMapChange()
{
- if (m_Item != null)
+ if (_item != null)
{
- m_Item.Map = Map;
+ _item.Map = Map;
}
}
@@ -257,7 +232,7 @@ namespace Server.Items
{
base.OnAfterDelete();
- m_Item?.Delete();
+ _item?.Delete();
}
public override void OnMovement(Mobile m, Point3D oldLocation)
@@ -278,43 +253,22 @@ namespace Server.Items
{
Ankhs.Resurrect(m, this);
}
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0); // version
-
- writer.Write(m_Item);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
-
- m_Item = reader.ReadEntity();
- }
}
}
[TypeAlias("Server.Items.AnkhEast")]
- public class AnkhNorth : Item
+ [Serializable(0, false)]
+ public partial class AnkhNorth : Item
{
- private InternalItem m_Item;
+ [SerializableField(0, getter: "private", setter: "private")]
+ private InternalItem _item;
[Constructible]
public AnkhNorth(bool bloodied = false) : base(bloodied ? 0x1E5D : 0x4)
{
Movable = false;
- m_Item = new InternalItem(bloodied, this);
- }
-
- public AnkhNorth(Serial serial)
- : base(serial)
- {
+ _item = new InternalItem(bloodied, this);
}
public override bool HandlesOnMovement => true; // Tell the core that we implement OnMovement
@@ -327,9 +281,9 @@ namespace Server.Items
set
{
base.Hue = value;
- if (m_Item.Hue != value)
+ if (_item.Hue != value)
{
- m_Item.Hue = value;
+ _item.Hue = value;
}
}
}
@@ -355,17 +309,17 @@ namespace Server.Items
public override void OnLocationChange(Point3D oldLocation)
{
- if (m_Item != null)
+ if (_item != null)
{
- m_Item.Location = new Point3D(X + 1, Y, Z);
+ _item.Location = new Point3D(X + 1, Y, Z);
}
}
public override void OnMapChange()
{
- if (m_Item != null)
+ if (_item != null)
{
- m_Item.Map = Map;
+ _item.Map = Map;
}
}
@@ -373,42 +327,21 @@ namespace Server.Items
{
base.OnAfterDelete();
- m_Item?.Delete();
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0); // version
-
- writer.Write(m_Item);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
-
- m_Item = reader.ReadEntity();
+ _item?.Delete();
}
[TypeAlias("Server.Items.AnkhEast+InternalItem")]
- private class InternalItem : Item
+ [Serializable(0, false)]
+ private partial class InternalItem : Item
{
- private AnkhNorth m_Item;
+ [SerializableField(0)]
+ private AnkhNorth _item;
public InternalItem(bool bloodied, AnkhNorth item)
: base(bloodied ? 0x1E5C : 0x5)
{
Movable = false;
-
- m_Item = item;
- }
-
- public InternalItem(Serial serial) : base(serial)
- {
+ _item = item;
}
public override bool HandlesOnMovement => true; // Tell the core that we implement OnMovement
@@ -421,26 +354,26 @@ namespace Server.Items
set
{
base.Hue = value;
- if (m_Item.Hue != value)
+ if (_item.Hue != value)
{
- m_Item.Hue = value;
+ _item.Hue = value;
}
}
}
public override void OnLocationChange(Point3D oldLocation)
{
- if (m_Item != null)
+ if (_item != null)
{
- m_Item.Location = new Point3D(X - 1, Y, Z);
+ _item.Location = new Point3D(X - 1, Y, Z);
}
}
public override void OnMapChange()
{
- if (m_Item != null)
+ if (_item != null)
{
- m_Item.Map = Map;
+ _item.Map = Map;
}
}
@@ -448,7 +381,7 @@ namespace Server.Items
{
base.OnAfterDelete();
- m_Item?.Delete();
+ _item?.Delete();
}
public override void OnMovement(Mobile m, Point3D oldLocation)
@@ -469,24 +402,6 @@ namespace Server.Items
{
Ankhs.Resurrect(m, this);
}
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0); // version
-
- writer.Write(m_Item);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
-
- m_Item = reader.ReadEntity();
- }
}
}
}
diff --git a/Projects/UOContent/Items/Construction/Tables/Tables.cs b/Projects/UOContent/Items/Construction/Tables/Tables.cs
index eef852237..65f1bdbf1 100644
--- a/Projects/UOContent/Items/Construction/Tables/Tables.cs
+++ b/Projects/UOContent/Items/Construction/Tables/Tables.cs
@@ -1,145 +1,45 @@
namespace Server.Items
{
[Furniture]
- public class ElegantLowTable : Item
+ [Serializable(0, false)]
+ public partial class ElegantLowTable : Item
{
[Constructible]
public ElegantLowTable() : base(0x2819) => Weight = 1.0;
-
- public ElegantLowTable(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
- }
}
[Furniture]
- public class PlainLowTable : Item
+ [Serializable(0, false)]
+ public partial class PlainLowTable : Item
{
[Constructible]
public PlainLowTable() : base(0x281A) => Weight = 1.0;
-
- public PlainLowTable(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
- }
}
[Furniture]
[Flippable(0xB90, 0xB7D)]
- public class LargeTable : Item
+ [Serializable(0, false)]
+ public partial class LargeTable : Item
{
[Constructible]
public LargeTable() : base(0xB90) => Weight = 1.0;
-
- public LargeTable(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
-
- if (Weight == 4.0)
- {
- Weight = 1.0;
- }
- }
}
[Furniture]
[Flippable(0xB35, 0xB34)]
- public class Nightstand : Item
+ [Serializable(0, false)]
+ public partial class Nightstand : Item
{
[Constructible]
public Nightstand() : base(0xB35) => Weight = 1.0;
-
- public Nightstand(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
-
- if (Weight == 4.0)
- {
- Weight = 1.0;
- }
- }
}
[Furniture]
[Flippable(0xB8F, 0xB7C)]
- public class YewWoodTable : Item
+ [Serializable(0, false)]
+ public partial class YewWoodTable : Item
{
[Constructible]
public YewWoodTable() : base(0xB8F) => Weight = 1.0;
-
- public YewWoodTable(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
-
- if (Weight == 4.0)
- {
- Weight = 1.0;
- }
- }
}
}
diff --git a/Projects/UOContent/Items/Construction/Tables/WritingTable.cs b/Projects/UOContent/Items/Construction/Tables/WritingTable.cs
index a711392b7..35ec06c37 100644
--- a/Projects/UOContent/Items/Construction/Tables/WritingTable.cs
+++ b/Projects/UOContent/Items/Construction/Tables/WritingTable.cs
@@ -2,32 +2,10 @@ namespace Server.Items
{
[Furniture]
[Flippable(0xB4A, 0xB49, 0xB4B, 0xB4C)]
- public class WritingTable : Item
+ [Serializable(0, false)]
+ public partial class WritingTable : Item
{
[Constructible]
public WritingTable() : base(0xB4A) => Weight = 1.0;
-
- public WritingTable(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0);
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
-
- if (Weight == 4.0)
- {
- Weight = 1.0;
- }
- }
}
}
diff --git a/Projects/UOContent/Items/Construction/Walls/BaseWall.cs b/Projects/UOContent/Items/Construction/Walls/BaseWall.cs
index d7ab25c27..6b5914a07 100644
--- a/Projects/UOContent/Items/Construction/Walls/BaseWall.cs
+++ b/Projects/UOContent/Items/Construction/Walls/BaseWall.cs
@@ -1,25 +1,8 @@
namespace Server.Items
{
- public abstract class BaseWall : Item
+ [Serializable(0, false)]
+ public abstract partial class BaseWall : Item
{
public BaseWall(int itemID) : base(itemID) => Movable = false;
-
- public BaseWall(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0); // version
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
- }
}
}
diff --git a/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs b/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs
index 282863781..a1e6e4077 100644
--- a/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs
+++ b/Projects/UOContent/Items/Construction/Walls/DarkWoodWall.cs
@@ -24,29 +24,12 @@ namespace Server.Items
EastWallVShort
}
- public class DarkWoodWall : BaseWall
+ [Serializable(0, false)]
+ public partial class DarkWoodWall : BaseWall
{
[Constructible]
public DarkWoodWall(DarkWoodWallTypes type) : base(0x0006 + (int)type)
{
}
-
- public DarkWoodWall(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0); // version
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
- }
}
}
diff --git a/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs b/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs
index 044af3bc8..17514de42 100644
--- a/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs
+++ b/Projects/UOContent/Items/Construction/Walls/ThickGrayStoneWall.cs
@@ -34,29 +34,12 @@ namespace Server.Items
EastWindow2
}
- public class ThickGrayStoneWall : BaseWall
+ [Serializable(0, false)]
+ public partial class ThickGrayStoneWall : BaseWall
{
[Constructible]
public ThickGrayStoneWall(ThickGrayStoneWallTypes type) : base(0x007A + (int)type)
{
}
-
- public ThickGrayStoneWall(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0); // version
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
- }
}
}
diff --git a/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs b/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs
index a7636cccf..f69a3cda3 100644
--- a/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs
+++ b/Projects/UOContent/Items/Construction/Walls/ThinBrickWall.cs
@@ -40,29 +40,12 @@ namespace Server.Items
EastWallVShort
}
- public class ThinBrickWall : BaseWall
+ [Serializable(0, false)]
+ public partial class ThinBrickWall : BaseWall
{
[Constructible]
public ThinBrickWall(ThinBrickWallTypes type) : base(0x0033 + (int)type)
{
}
-
- public ThinBrickWall(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0); // version
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
- }
}
}
diff --git a/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs b/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs
index 49794458c..7754c7b10 100644
--- a/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs
+++ b/Projects/UOContent/Items/Construction/Walls/ThinStoneWall.cs
@@ -29,29 +29,12 @@ namespace Server.Items
EastWallShort2
}
- public class ThinStoneWall : BaseWall
+ [Serializable(0, false)]
+ public partial class ThinStoneWall : BaseWall
{
[Constructible]
public ThinStoneWall(ThinStoneWallTypes type) : base(0x001A + (int)type)
{
}
-
- public ThinStoneWall(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0); // version
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
- }
}
}
diff --git a/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs b/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs
index 093892d15..07a6f0d16 100644
--- a/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs
+++ b/Projects/UOContent/Items/Construction/Walls/WhiteStoneWall.cs
@@ -47,29 +47,12 @@ namespace Server.Items
EastWallVVShort
}
- public class WhiteStoneWall : BaseWall
+ [Serializable(0, false)]
+ public partial class WhiteStoneWall : BaseWall
{
[Constructible]
public WhiteStoneWall(WhiteStoneWallTypes type) : base(0x0057 + (int)type)
{
}
-
- public WhiteStoneWall(Serial serial) : base(serial)
- {
- }
-
- public override void Serialize(IGenericWriter writer)
- {
- base.Serialize(writer);
-
- writer.Write(0); // version
- }
-
- public override void Deserialize(IGenericReader reader)
- {
- base.Deserialize(reader);
-
- var version = reader.ReadInt();
- }
}
}
diff --git a/Projects/UOContent/Items/Weapons/BaseWeapon.cs b/Projects/UOContent/Items/Weapons/BaseWeapon.cs
index b50b97f32..8e183a7b9 100644
--- a/Projects/UOContent/Items/Weapons/BaseWeapon.cs
+++ b/Projects/UOContent/Items/Weapons/BaseWeapon.cs
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
+using Server.Collections;
using Server.Engines.Craft;
using Server.Ethics;
using Server.Factions;
@@ -695,8 +695,6 @@ namespace Server.Items
}
}
- public virtual TimeSpan OnSwing(Mobile attacker, Mobile defender) => OnSwing(attacker, defender, 1.0);
-
public virtual void GetStatusDamage(Mobile from, out int min, out int max)
{
GetBaseDamageRange(from, out var baseMin, out var baseMax);
@@ -713,7 +711,7 @@ namespace Server.Items
}
}
- public virtual TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus)
+ public virtual TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0)
{
var canSwing = true;
@@ -723,12 +721,12 @@ namespace Server.Items
if (canSwing)
{
- canSwing = !(attacker.Spell is Spell sp) || !sp.IsCasting || !sp.BlocksMovement;
+ canSwing = attacker.Spell is not Spell sp || !sp.IsCasting || !sp.BlocksMovement;
}
if (canSwing)
{
- canSwing = !(attacker is PlayerMobile p) || p.PeacedUntil <= Core.Now;
+ canSwing = attacker is not PlayerMobile p || p.PeacedUntil <= Core.Now;
}
}
@@ -786,7 +784,7 @@ namespace Server.Items
public override void OnAfterDuped(Item newItem)
{
- if (!(newItem is BaseWeapon weap))
+ if (newItem is not BaseWeapon weap)
{
return;
}
@@ -877,8 +875,8 @@ namespace Server.Items
return true;
}
- if (Layer == Layer.OneHanded && layer == Layer.TwoHanded && !(item is BaseShield) &&
- !(item is BaseEquipableLight))
+ if (Layer == Layer.OneHanded && layer == Layer.TwoHanded && item is not BaseShield &&
+ item is not BaseEquipableLight)
{
m.SendLocalizedMessage(500215); // You can only wield one weapon at a time.
return true;
@@ -1096,7 +1094,6 @@ namespace Server.Items
var defWeapon = defender.Weapon as BaseWeapon;
var atkSkill = attacker.Skills[atkWeapon?.Skill ?? SkillName.Wrestling];
- // Skill defSkill = defender.Skills[defWeapon.Skill];
var atkValue = atkWeapon?.GetAttackSkillValue(attacker, defender) ?? 0.0;
var defValue = defWeapon?.GetDefendSkillValue(attacker, defender) ?? 0.0;
@@ -1209,23 +1206,11 @@ namespace Server.Items
}
else
{
- if (atkValue <= -50.0)
- {
- atkValue = -49.9;
- }
-
- if (defValue <= -50.0)
- {
- defValue = -49.9;
- }
-
- ourValue = atkValue + 50.0;
- theirValue = defValue + 50.0;
+ ourValue = Math.Max(0.1, atkValue + 50.0);
+ theirValue = Math.Max(0.1, defValue + 50.0);
}
- var chance = ourValue / (theirValue * 2.0);
-
- chance *= 1.0 + (double)bonus / 100;
+ var chance = ourValue / (theirValue * 2.0) * 1.0 + (double)bonus / 100;
if (Core.AOS && chance < 0.02)
{
@@ -1418,7 +1403,7 @@ namespace Server.Items
return defender.CheckSkill(SkillName.Parry, chance);
}
- if (defender.Weapon is Fists || defender.Weapon is BaseRanged)
+ if (defender.Weapon is Server.Items.Fists or BaseRanged)
{
return false;
}
@@ -1459,9 +1444,8 @@ namespace Server.Items
return defender.CheckSkill(SkillName.Parry, chance);
}
- return
- aosChance > Utility
- .RandomDouble(); // Only skillcheck if wielding a shield & there's no effect from Bushido
+ // Only skillcheck if wielding a shield & there's no effect from Bushido
+ return aosChance > Utility.RandomDouble();
}
public virtual int AbsorbDamageAOS(Mobile attacker, Mobile defender, int damage)
@@ -1493,9 +1477,8 @@ namespace Server.Items
if (Confidence.IsConfident(defender))
{
- defender.SendLocalizedMessage(
- 1063117
- ); // Your confidence reassures you as you successfully block your opponent's blow.
+ // Your confidence reassures you as you successfully block your opponent's blow.
+ defender.SendLocalizedMessage(1063117);
var bushido = defender.Skills.Bushido.Value;
@@ -1590,7 +1573,7 @@ namespace Server.Items
return 0;
}
- if (!(attacker is BaseCreature bc) || bc.PackInstinct == PackInstinct.None || !bc.Controlled && !bc.Summoned)
+ if (attacker is not BaseCreature bc || bc.PackInstinct == PackInstinct.None || !bc.Controlled && !bc.Summoned)
{
return 0;
}
@@ -1603,16 +1586,26 @@ namespace Server.Items
}
var eable = defender.GetMobilesInRange(1);
- var inPack = 1 + eable
- .Where(m => m != attacker && (m.PackInstinct & bc.PackInstinct) != 0 && (m.Controlled || m.Summoned))
- .Count(m => master == (m.ControlMaster ?? m.SummonMaster) && m.Combatant == defender);
+ var inPack = 1;
+ foreach (var m in eable)
+ {
+ if (m != attacker && (m.PackInstinct & bc.PackInstinct) != 0 && (m.Controlled || m.Summoned) &&
+ master == (m.ControlMaster ?? m.SummonMaster) && m.Combatant == defender)
+ {
+ inPack++;
+ }
+ }
eable.Free();
- return inPack >= 5 ? 100 :
- inPack >= 4 ? 75 :
- inPack >= 3 ? 50 :
- inPack >= 2 ? 25 : 0;
+ return inPack switch
+ {
+ >= 5 => 100,
+ 4 => 75,
+ 3 => 50,
+ 2 => 25,
+ _ => 0
+ };
}
public virtual void OnHit(Mobile attacker, Mobile defender, double damageBonus = 1.0)
@@ -1688,12 +1681,9 @@ namespace Server.Items
if (!attacker.Player)
{
- if (defender is PlayerMobile pm)
+ if (defender is PlayerMobile pm && pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType())
{
- if (pm.EnemyOfOneType != null && pm.EnemyOfOneType != attacker.GetType())
- {
- percentageBonus += 100;
- }
+ percentageBonus += 100;
}
}
else if (!defender.Player)
@@ -1769,16 +1759,14 @@ namespace Server.Items
{
damage = 1;
}
- else if (Core.AOS && damage == 0) // parried
+ // Parried
+ else if (Core.AOS && damage == 0 && a?.Validate(attacker) == true)
{
- if (a?.Validate(attacker) == true) /*&& a.CheckMana( attacker, true )*/
- // Parried special moves have no mana cost
- {
- a = null;
- WeaponAbility.ClearCurrentAbility(attacker);
-
- attacker.SendLocalizedMessage(1061140); // Your attack was parried!
- }
+ /*&& a.CheckMana( attacker, true )*/
+ // Parried special moves have no mana cost
+ a = null;
+ WeaponAbility.ClearCurrentAbility(attacker);
+ attacker.SendLocalizedMessage(1061140); // Your attack was parried!
}
AddBlood(attacker, defender, damage);
@@ -1936,9 +1924,8 @@ namespace Server.Items
if (context?.Type == typeof(WraithFormSpell))
{
- wraithLeech =
- 5 + (int)(15 * attacker.Skills.SpiritSpeak.Value /
- 100); // Wraith form gives an additional 5-20% mana leech
+ // Wraith form gives an additional 5-20% mana leech
+ wraithLeech = 5 + (int)(15 * attacker.Skills.SpiritSpeak.Value / 100);
// Mana leeched by the Wraith Form spell is actually stolen, not just leeched.
defender.Mana -= AOS.Scale(damageGiven, wraithLeech);
@@ -1967,10 +1954,10 @@ namespace Server.Items
}
}
- if (m_MaxHits > 0 && (MaxRange <= 1 && (defender is Slime || defender is AcidElemental) ||
- Utility.RandomDouble() < .04)) // Stratics says 50% chance, seems more like 4%..
+ // Stratics says 50% chance, seems more like 4%..
+ if (m_MaxHits > 0 && MaxRange <= 1 && defender is Slime or AcidElemental |Utility.RandomDouble() < .04)
{
- if (MaxRange <= 1 && (defender is Slime || defender is AcidElemental))
+ if (MaxRange <= 1 && defender is Slime or AcidElemental)
{
attacker.LocalOverheadMessage(MessageType.Regular, 0x3B2, 500263); // *Acid blood scars your weapon!*
}
@@ -1979,29 +1966,23 @@ namespace Server.Items
{
HitPoints += 2;
}
+ else if (m_Hits > 0)
+ {
+ --HitPoints;
+ }
+ else if (m_MaxHits > 1)
+ {
+ --MaxHitPoints;
+
+ if (Parent is Mobile mobile)
+ {
+ // Your equipment is severely damaged.
+ mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061121);
+ }
+ }
else
{
- if (m_Hits > 0)
- {
- --HitPoints;
- }
- else if (m_MaxHits > 1)
- {
- --MaxHitPoints;
-
- if (Parent is Mobile mobile)
- {
- mobile.LocalOverheadMessage(
- MessageType.Regular,
- 0x3B2,
- 1061121 // Your equipment is severely damaged.
- );
- }
- }
- else
- {
- Delete();
- }
+ Delete();
}
}
@@ -2021,16 +2002,20 @@ namespace Server.Items
if (Core.AOS)
{
- var physChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPhysicalArea) *
- propertyBonus);
+ var physChance =
+ (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPhysicalArea) * propertyBonus);
+
var fireChance =
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitFireArea) * propertyBonus);
+
var coldChance =
(int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitColdArea) * propertyBonus);
- var poisChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPoisonArea) *
- propertyBonus);
- var nrgyChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitEnergyArea) *
- propertyBonus);
+
+ var poisChance =
+ (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitPoisonArea) * propertyBonus);
+
+ var nrgyChance =
+ (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitEnergyArea) * propertyBonus);
if (physChance != 0 && physChance > Utility.Random(100))
{
@@ -2092,10 +2077,10 @@ namespace Server.Items
DoDispel(attacker, defender);
}
- var laChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerAttack) *
- propertyBonus);
- var ldChance = (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerDefend) *
- propertyBonus);
+ var laChance =
+ (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerAttack) * propertyBonus);
+ var ldChance =
+ (int)(AosWeaponAttributes.GetValue(attacker, AosWeaponAttribute.HitLowerDefend) * propertyBonus);
if (laChance != 0 && laChance > Utility.Random(100))
{
@@ -2121,7 +2106,7 @@ namespace Server.Items
it.ReceivedHonorContext?.OnTargetHit(attacker);
}
- if (!(this is BaseRanged))
+ if (this is not BaseRanged)
{
if (AnimalForm.UnderTransformation(attacker, typeof(GiantSerpent)))
{
@@ -2157,7 +2142,7 @@ namespace Server.Items
// SDI bonus
damageBonus += AosAttributes.GetValue(attacker, AosAttribute.SpellDamage);
- if(PsychicAttack.Registry.TryGetValue(attacker,out var timer))
+ if (PsychicAttack.Registry.TryGetValue(attacker,out var timer))
{
damageBonus -= timer.SpellDamageMalus;
}
@@ -2319,13 +2304,8 @@ namespace Server.Items
attacker.PlaySound(GetMissAttackSound(attacker, defender));
defender.PlaySound(GetMissDefendSound(attacker, defender));
- var ability = WeaponAbility.GetCurrentAbility(attacker);
-
- ability?.OnMiss(attacker, defender);
-
- var move = SpecialMove.GetCurrentMove(attacker);
-
- move?.OnMiss(attacker, defender);
+ WeaponAbility.GetCurrentAbility(attacker)?.OnMiss(attacker, defender);
+ SpecialMove.GetCurrentMove(attacker)?.OnMiss(attacker, defender);
if (defender is IHonorTarget target)
{
@@ -2417,56 +2397,38 @@ namespace Server.Items
{
var bonus = VirtualDamageBonus;
- switch (m_Quality)
+ bonus += m_Quality switch
{
- case WeaponQuality.Low:
- bonus -= 20;
- break;
- case WeaponQuality.Exceptional:
- bonus += 20;
- break;
- }
+ WeaponQuality.Low => -20,
+ WeaponQuality.Exceptional => 20,
+ _ => 0
+ };
- switch (m_DamageLevel)
+ return bonus + m_DamageLevel switch
{
- case WeaponDamageLevel.Ruin:
- bonus += 15;
- break;
- case WeaponDamageLevel.Might:
- bonus += 20;
- break;
- case WeaponDamageLevel.Force:
- bonus += 25;
- break;
- case WeaponDamageLevel.Power:
- bonus += 30;
- break;
- case WeaponDamageLevel.Vanq:
- bonus += 35;
- break;
- }
-
- return bonus;
+ WeaponDamageLevel.Ruin => 15,
+ WeaponDamageLevel.Might => 20,
+ WeaponDamageLevel.Force => 25,
+ WeaponDamageLevel.Power => 30,
+ WeaponDamageLevel.Vanq => 35,
+ _ => bonus
+ };
}
public virtual double ScaleDamageAOS(Mobile attacker, double damage, bool checkSkills)
{
if (checkSkills)
{
- attacker.CheckSkill(
- SkillName.Tactics,
- 0.0,
- attacker.Skills.Tactics.Cap
- ); // Passively check tactics for gain
- attacker.CheckSkill(
- SkillName.Anatomy,
- 0.0,
- attacker.Skills.Anatomy.Cap
- ); // Passively check Anatomy for gain
+ // Passively check tactics for gain
+ attacker.CheckSkill(SkillName.Tactics, 0.0, attacker.Skills.Tactics.Cap);
+
+ // Passively check Anatomy for gain
+ attacker.CheckSkill(SkillName.Anatomy, 0.0, attacker.Skills.Anatomy.Cap);
if (Type == WeaponType.Axe)
{
- attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0); // Passively check Lumberjacking for gain
+ // Passively check Lumberjacking for gain
+ attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0);
}
}
@@ -2536,20 +2498,16 @@ namespace Server.Items
{
if (checkSkills)
{
- attacker.CheckSkill(
- SkillName.Tactics,
- 0.0,
- attacker.Skills.Tactics.Cap
- ); // Passively check tactics for gain
- attacker.CheckSkill(
- SkillName.Anatomy,
- 0.0,
- attacker.Skills.Anatomy.Cap
- ); // Passively check Anatomy for gain
+ // Passively check tactics for gain
+ attacker.CheckSkill(SkillName.Tactics, 0.0, attacker.Skills.Tactics.Cap);
+
+ // Passively check Anatomy for gain
+ attacker.CheckSkill(SkillName.Anatomy, 0.0, attacker.Skills.Anatomy.Cap);
if (Type == WeaponType.Axe)
{
- attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0); // Passively check Lumberjacking for gain
+ // Passively check Lumberjacking for gain
+ attacker.CheckSkill(SkillName.Lumberjacking, 0.0, 100.0);
}
}
@@ -2633,9 +2591,9 @@ namespace Server.Items
var damage = (int)ScaleDamageOld(attacker, GetBaseDamage(attacker), true);
// pre-AOS, halve damage if the defender is a player or the attacker is not a player
- if (defender is PlayerMobile || !(attacker is PlayerMobile))
+ if (defender is PlayerMobile || attacker is not PlayerMobile)
{
- damage = (int)(damage / 2.0);
+ damage /= 2;
}
return damage;
@@ -2643,6 +2601,11 @@ namespace Server.Items
public virtual void PlayHurtAnimation(Mobile from)
{
+ if (from.Mounted)
+ {
+ return;
+ }
+
int action;
int frames;
@@ -2667,12 +2630,10 @@ namespace Server.Items
frames = 5;
break;
}
- default: return;
- }
-
- if (from.Mounted)
- {
- return;
+ default:
+ {
+ return;
+ }
}
from.Animate(action, frames, 1, true, false, 0);
@@ -2695,10 +2656,18 @@ namespace Server.Items
switch (Animation)
{
default:
- action = Utility.Random(4, 3);
- break;
- case WeaponAnimation.ShootBow: return; // 7
- case WeaponAnimation.ShootXBow: return; // 8
+ {
+ action = Utility.Random(4, 3);
+ break;
+ }
+ case WeaponAnimation.ShootBow:
+ {
+ return; // 7
+ }
+ case WeaponAnimation.ShootXBow:
+ {
+ return; // 8
+ }
}
break;
@@ -2728,7 +2697,10 @@ namespace Server.Items
break;
}
- default: return;
+ default:
+ {
+ return;
+ }
}
from.Animate(action, 7, 1, true, false, 0);
@@ -2739,11 +2711,11 @@ namespace Server.Items
public int GetElementalDamageHue()
{
GetDamageTypes(null, out _, out var fire, out var cold, out var pois, out var nrgy, out _, out _);
- // Order is Cold, Energy, Fire, Poison, Physical left
var currentMax = 50;
var hue = 0;
+ // Order is Cold, Energy, Fire, Poison, Physical
if (pois >= currentMax)
{
hue = 1267 + (pois - 50) / 10;
@@ -2812,7 +2784,7 @@ namespace Server.Items
* formatting show, and remove CLILOCs embedded: more like OSI
* did with the books that had markup, etc.
*
- * This will have a negative effect on a few event things imgame
+ * This will have a negative effect on a few event things in-game
* as is.
*
* If we cant find a more OSI-ish way to clean it up, we can
@@ -2828,29 +2800,10 @@ namespace Server.Items
/* list.Add( 1062613, Utility.FixHtml( m_EngravedText ) ); */
}
- public override bool AllowEquippedCast(Mobile from)
- {
- if (base.AllowEquippedCast(from))
- {
- return true;
- }
+ public override bool AllowEquippedCast(Mobile from) =>
+ base.AllowEquippedCast(from) || Attributes.SpellChanneling != 0;
- return Attributes.SpellChanneling != 0;
- }
-
- public virtual int GetLuckBonus()
- {
- var resInfo = CraftResources.GetInfo(m_Resource);
-
- var attrInfo = resInfo?.AttributeInfo;
-
- if (attrInfo == null)
- {
- return 0;
- }
-
- return attrInfo.WeaponLuck;
- }
+ public virtual int GetLuckBonus() => CraftResources.GetInfo(m_Resource)?.AttributeInfo?.WeaponLuck ?? 0;
public override void GetProperties(ObjectPropertyList list)
{
@@ -3235,17 +3188,25 @@ namespace Server.Items
switch (Skill)
{
case SkillName.Swords:
- list.Add(1061172);
- break; // skill required: swordsmanship
+ {
+ list.Add(1061172); // skill required: swordsmanship
+ break;
+ }
case SkillName.Macing:
- list.Add(1061173);
- break; // skill required: mace fighting
+ {
+ list.Add(1061173); // skill required: mace fighting
+ break;
+ }
case SkillName.Fencing:
- list.Add(1061174);
- break; // skill required: fencing
+ {
+ list.Add(1061174); // skill required: fencing
+ break;
+ }
case SkillName.Archery:
- list.Add(1061175);
- break; // skill required: archery
+ {
+ list.Add(1061175); // skill required: archery
+ break;
+ }
}
}
@@ -3351,13 +3312,7 @@ namespace Server.Items
public virtual int GetHitAttackSound(Mobile attacker, Mobile defender)
{
var sound = attacker.GetAttackSound();
-
- if (sound == -1)
- {
- sound = HitSound;
- }
-
- return sound;
+ return sound == -1 ? HitSound : sound;
}
public virtual int GetHitDefendSound(Mobile attacker, Mobile defender) => defender.GetHurtSound();
@@ -3518,33 +3473,37 @@ namespace Server.Items
var range = Core.ML ? 5 : 10;
var eable = from.GetMobilesInRange(range);
- var list = eable.Where(
- m =>
- from != m && defender != m && SpellHelper.ValidIndirectTarget(from, m)
- && from.CanBeHarmful(m, false) && (!Core.ML || from.InLOS(m))
- )
- .ToList();
+ using var queue = PooledRefQueue.Create();
+ foreach (var m in eable)
+ {
+ if (from != m && defender != m && SpellHelper.ValidIndirectTarget(from, m)
+ && from.CanBeHarmful(m, false) && (!Core.ML || from.InLOS(m)))
+ {
+ queue.Enqueue(m);
+ }
+ }
eable.Free();
- if (list.Count == 0)
+ if (queue.Count == 0)
{
return;
}
Effects.PlaySound(from.Location, map, sound);
- for (var i = 0; i < list.Count; ++i)
+ while (queue.Count > 0)
{
- var m = list[i];
+ var m = queue.Dequeue();
var scalar = Core.ML ? 1.0 : (11 - from.GetDistanceToSqrt(m)) / 10;
- var damage = GetBaseDamage(from);
if (scalar <= 0)
{
continue;
}
+ var damage = GetBaseDamage(from);
+
if (scalar < 1.0)
{
damage *= (11 - from.GetDistanceToSqrt(m)) / 10;
diff --git a/Projects/UOContent/Items/Weapons/Fists.cs b/Projects/UOContent/Items/Weapons/Fists.cs
index 8be6fe5ac..b2fe3fc93 100644
--- a/Projects/UOContent/Items/Weapons/Fists.cs
+++ b/Projects/UOContent/Items/Weapons/Fists.cs
@@ -157,7 +157,7 @@ namespace Server.Items
}
}
- public override TimeSpan OnSwing(Mobile attacker, Mobile defender)
+ public override TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0)
{
if (!Core.AOS)
{
diff --git a/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs b/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs
index 2c66dd3f2..a3a393a33 100644
--- a/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs
+++ b/Projects/UOContent/Items/Weapons/Ranged/BaseRanged.cs
@@ -37,7 +37,7 @@ namespace Server.Items
public override SkillName AccuracySkill => SkillName.Archery;
- public override TimeSpan OnSwing(Mobile attacker, Mobile defender)
+ public override TimeSpan OnSwing(Mobile attacker, Mobile defender, double damageBonus = 1.0)
{
// WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
diff --git a/Projects/UOContent/Migrations/Server.Items.AnkhNorth.InternalItem.v0.json b/Projects/UOContent/Migrations/Server.Items.AnkhNorth.InternalItem.v0.json
new file mode 100644
index 000000000..f0bb8bf9d
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.AnkhNorth.InternalItem.v0.json
@@ -0,0 +1,11 @@
+{
+ "version": 0,
+ "type": "Server.Items.AnkhNorth.InternalItem",
+ "properties": [
+ {
+ "name": "Item",
+ "type": "Server.Items.AnkhNorth",
+ "rule": "SerializableInterfaceMigrationRule"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.AnkhNorth.v0.json b/Projects/UOContent/Migrations/Server.Items.AnkhNorth.v0.json
new file mode 100644
index 000000000..e6276daa9
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.AnkhNorth.v0.json
@@ -0,0 +1,11 @@
+{
+ "version": 0,
+ "type": "Server.Items.AnkhNorth",
+ "properties": [
+ {
+ "name": "Item",
+ "type": "Server.Items.AnkhNorth.InternalItem",
+ "rule": "SerializableInterfaceMigrationRule"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.AnkhWest.InternalItem.v0.json b/Projects/UOContent/Migrations/Server.Items.AnkhWest.InternalItem.v0.json
new file mode 100644
index 000000000..ce8487ea3
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.AnkhWest.InternalItem.v0.json
@@ -0,0 +1,11 @@
+{
+ "version": 0,
+ "type": "Server.Items.AnkhWest.InternalItem",
+ "properties": [
+ {
+ "name": "Item",
+ "type": "Server.Items.AnkhWest",
+ "rule": "SerializableInterfaceMigrationRule"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.AnkhWest.v0.json b/Projects/UOContent/Migrations/Server.Items.AnkhWest.v0.json
new file mode 100644
index 000000000..4d2c54228
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.AnkhWest.v0.json
@@ -0,0 +1,11 @@
+{
+ "version": 0,
+ "type": "Server.Items.AnkhWest",
+ "properties": [
+ {
+ "name": "Item",
+ "type": "Server.Items.AnkhWest.InternalItem",
+ "rule": "SerializableInterfaceMigrationRule"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.BaseWall.v0.json b/Projects/UOContent/Migrations/Server.Items.BaseWall.v0.json
new file mode 100644
index 000000000..6d0cdab23
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.BaseWall.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.BaseWall"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.DarkWoodWall.v0.json b/Projects/UOContent/Migrations/Server.Items.DarkWoodWall.v0.json
new file mode 100644
index 000000000..f520f6f5d
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.DarkWoodWall.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.DarkWoodWall"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.ElegantLowTable.v0.json b/Projects/UOContent/Migrations/Server.Items.ElegantLowTable.v0.json
new file mode 100644
index 000000000..2ea3c2834
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.ElegantLowTable.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.ElegantLowTable"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.LargeTable.v0.json b/Projects/UOContent/Migrations/Server.Items.LargeTable.v0.json
new file mode 100644
index 000000000..238f1c5c9
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.LargeTable.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.LargeTable"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.Nightstand.v0.json b/Projects/UOContent/Migrations/Server.Items.Nightstand.v0.json
new file mode 100644
index 000000000..96a1d9f80
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.Nightstand.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.Nightstand"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.PlainLowTable.v0.json b/Projects/UOContent/Migrations/Server.Items.PlainLowTable.v0.json
new file mode 100644
index 000000000..f11168e93
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.PlainLowTable.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.PlainLowTable"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.ThickGrayStoneWall.v0.json b/Projects/UOContent/Migrations/Server.Items.ThickGrayStoneWall.v0.json
new file mode 100644
index 000000000..783cf62be
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.ThickGrayStoneWall.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.ThickGrayStoneWall"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.ThinBrickWall.v0.json b/Projects/UOContent/Migrations/Server.Items.ThinBrickWall.v0.json
new file mode 100644
index 000000000..a91f76dfa
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.ThinBrickWall.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.ThinBrickWall"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.ThinStoneWall.v0.json b/Projects/UOContent/Migrations/Server.Items.ThinStoneWall.v0.json
new file mode 100644
index 000000000..a10bfd271
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.ThinStoneWall.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.ThinStoneWall"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.WhiteStoneWall.v0.json b/Projects/UOContent/Migrations/Server.Items.WhiteStoneWall.v0.json
new file mode 100644
index 000000000..e8172178e
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.WhiteStoneWall.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.WhiteStoneWall"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.WritingTable.v0.json b/Projects/UOContent/Migrations/Server.Items.WritingTable.v0.json
new file mode 100644
index 000000000..14728f82e
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.WritingTable.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.WritingTable"
+}
\ No newline at end of file
diff --git a/Projects/UOContent/Migrations/Server.Items.YewWoodTable.v0.json b/Projects/UOContent/Migrations/Server.Items.YewWoodTable.v0.json
new file mode 100644
index 000000000..72738fa69
--- /dev/null
+++ b/Projects/UOContent/Migrations/Server.Items.YewWoodTable.v0.json
@@ -0,0 +1,4 @@
+{
+ "version": 0,
+ "type": "Server.Items.YewWoodTable"
+}
\ No newline at end of file
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/BaseCreature.cs b/Projects/UOContent/Mobiles/BaseCreature.cs
index f846378ac..1debdd3cd 100644
--- a/Projects/UOContent/Mobiles/BaseCreature.cs
+++ b/Projects/UOContent/Mobiles/BaseCreature.cs
@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
+using Server.Collections;
using Server.ContextMenus;
using Server.Engines.ConPVP;
using Server.Engines.MLQuests;
@@ -512,11 +512,11 @@ namespace Server.Mobiles
public virtual bool DeathAdderCharmable => false;
// TODO: Find the pub 31 tweaks to the DispelDifficulty and apply them of course.
- public virtual double DispelDifficulty // at this skill level we dispel 50% chance
- => 0.0;
+ // at this skill level we dispel 50% chance
+ public virtual double DispelDifficulty => 0.0;
- public virtual double DispelFocus // at difficulty - focus we have 0%, at difficulty + focus we have 100%
- => 20.0;
+ // at difficulty - focus we have 0%, at difficulty + focus we have 100%
+ public virtual double DispelFocus => 20.0;
public virtual bool DisplayWeight => Backpack is StrongBackpack;
@@ -1169,9 +1169,8 @@ namespace Server.Mobiles
if (m_MLQuests == null)
{
- return
- MLQuestSystem
- .EmptyList; // return EmptyList, but don't cache it (run construction again next time)
+ // return EmptyList, but don't cache it (run construction again next time)
+ return MLQuestSystem.EmptyList;
}
}
@@ -1211,7 +1210,7 @@ namespace Server.Mobiles
return false;
}
- if (!(m is BaseCreature c) || m is MilitiaFighter)
+ if (m is not BaseCreature c || m is MilitiaFighter)
{
return true;
}
@@ -2153,11 +2152,8 @@ namespace Server.Mobiles
// even if they can't offer you anything at the moment
if (MLQuestSystem.Enabled && CanGiveMLQuest && from is PlayerMobile mobile)
{
- MLQuestSystem.Tell(
- this,
- mobile,
- 1074893
- ); // You need to mark your quest items so I don't take the wrong object. Then speak to me.
+ // You need to mark your quest items so I don't take the wrong object. Then speak to me.
+ MLQuestSystem.Tell(this, mobile, 1074893);
return false;
}
@@ -2536,8 +2532,8 @@ namespace Server.Mobiles
public override bool IsHarmfulCriminal(Mobile target) =>
(!Controlled || target != m_ControlMaster) && (!Summoned || target != m_SummonMaster) &&
- (!(target is BaseCreature creature) || !creature.InitialInnocent || creature.Controlled) &&
- (!(target is PlayerMobile mobile) || mobile.PermaFlags.Count <= 0) && base.IsHarmfulCriminal(target);
+ (target is not BaseCreature { InitialInnocent: true } creature || creature.Controlled) &&
+ (target is not PlayerMobile mobile || mobile.PermaFlags.Count <= 0) && base.IsHarmfulCriminal(target);
public override void CriminalAction(bool message)
{
@@ -2837,18 +2833,6 @@ namespace Server.Mobiles
return null;
}
- public static void Cap(ref int val, int min, int max)
- {
- if (val < min)
- {
- val = min;
- }
- else if (val > max)
- {
- val = max;
- }
- }
-
public override void OnDoubleClick(Mobile from)
{
if (from.AccessLevel >= AccessLevel.GameMaster && !Body.IsHuman)
@@ -2903,7 +2887,8 @@ namespace Server.Mobiles
}
else if (Controlled && Commandable)
{
- if (IsBonded) // Intentional difference (showing ONLY bonded when bonded instead of bonded & tame)
+ // Intentional difference (showing ONLY bonded when bonded instead of bonded & tame)
+ if (IsBonded)
{
list.Add(1049608); // (bonded)
}
@@ -3028,7 +3013,7 @@ namespace Server.Mobiles
{
var de = list[i];
- if (de.Damager == m || !(de.Damager is BaseCreature bc))
+ if (de.Damager == m || de.Damager is not BaseCreature bc)
{
continue;
}
@@ -3144,10 +3129,8 @@ namespace Server.Mobiles
if (rights.Count > 0)
{
- rights[0].m_Damage =
- (int)(rights[0].m_Damage *
- 1.25
- ); // This would be the first valid person attacking it. Gets a 25% bonus. Per 1/19/07 Five on Friday
+ // This would be the first valid person attacking it. Gets a 25% bonus. Per 1/19/07 Five on Friday
+ rights[0].m_Damage = (int)(rights[0].m_Damage * 1.25);
if (rights.Count > 1)
{
@@ -3155,24 +3138,14 @@ namespace Server.Mobiles
}
var topDamage = rights[0].m_Damage;
- int minDamage;
- if (hitsMax >= 3000)
+ int minDamage = hitsMax switch
{
- minDamage = topDamage / 16;
- }
- else if (hitsMax >= 1000)
- {
- minDamage = topDamage / 8;
- }
- else if (hitsMax >= 200)
- {
- minDamage = topDamage / 4;
- }
- else
- {
- minDamage = topDamage / 2;
- }
+ >= 3000 => topDamage / 16,
+ >= 1000 => topDamage / 8,
+ >= 200 => topDamage / 4,
+ _ => topDamage / 2
+ };
for (var i = 0; i < rights.Count; ++i)
{
@@ -3271,127 +3244,126 @@ namespace Server.Mobiles
GiftOfLifeSpell.HandleDeath(this);
CheckStatTimers();
+ return;
}
- else
- {
- if (!Summoned && !NoKillAwards)
- {
- var totalFame = Fame / 100;
- var totalKarma = -Karma / 100;
- if (Map == Map.Felucca)
+ if (!Summoned && !NoKillAwards)
+ {
+ var totalFame = Fame / 100;
+ var totalKarma = -Karma / 100;
+
+ if (Map == Map.Felucca)
+ {
+ totalFame += totalFame / 10 * 3;
+ totalKarma += totalKarma / 10 * 3;
+ }
+
+ var list = GetLootingRights(DamageEntries, HitsMax);
+ var titles = new List();
+ var fame = new List();
+ var karma = new List();
+
+ var givenQuestKill = false;
+ var givenFactionKill = false;
+ var givenToTKill = false;
+
+ for (var i = 0; i < list.Count; ++i)
+ {
+ var ds = list[i];
+
+ if (!ds.m_HasRight)
{
- totalFame += totalFame / 10 * 3;
- totalKarma += totalKarma / 10 * 3;
+ continue;
}
- var list = GetLootingRights(DamageEntries, HitsMax);
- var titles = new List();
- var fame = new List();
- var karma = new List();
+ var party = Engines.PartySystem.Party.Get(ds.m_Mobile);
- var givenQuestKill = false;
- var givenFactionKill = false;
- var givenToTKill = false;
-
- for (var i = 0; i < list.Count; ++i)
+ if (party != null)
{
- var ds = list[i];
+ var divedFame = totalFame / party.Members.Count;
+ var divedKarma = totalKarma / party.Members.Count;
- if (!ds.m_HasRight)
+ for (var j = 0; j < party.Members.Count; ++j)
+ {
+ var info = party.Members[j];
+
+ if (info?.Mobile != null)
+ {
+ var index = titles.IndexOf(info.Mobile);
+
+ if (index == -1)
+ {
+ titles.Add(info.Mobile);
+ fame.Add(divedFame);
+ karma.Add(divedKarma);
+ }
+ else
+ {
+ fame[index] += divedFame;
+ karma[index] += divedKarma;
+ }
+ }
+ }
+ }
+ else
+ {
+ titles.Add(ds.m_Mobile);
+ fame.Add(totalFame);
+ karma.Add(totalKarma);
+ }
+
+ OnKilledBy(ds.m_Mobile);
+
+ if (!givenFactionKill)
+ {
+ givenFactionKill = true;
+ Faction.HandleDeath(this, ds.m_Mobile);
+ }
+
+ var region = ds.m_Mobile.Region;
+
+ if (!givenToTKill && (Map == Map.Tokuno || region.IsPartOf("Yomotsu Mines") ||
+ region.IsPartOf("Fan Dancer's Dojo")))
+ {
+ givenToTKill = true;
+ TreasuresOfTokuno.HandleKill(this, ds.m_Mobile);
+ }
+
+ if (ds.m_Mobile is PlayerMobile pm)
+ {
+ if (MLQuestSystem.Enabled)
+ {
+ MLQuestSystem.HandleKill(pm, this);
+ }
+
+ if (givenQuestKill)
{
continue;
}
- var party = Engines.PartySystem.Party.Get(ds.m_Mobile);
+ var qs = pm.Quest;
- if (party != null)
+ if (qs != null)
{
- var divedFame = totalFame / party.Members.Count;
- var divedKarma = totalKarma / party.Members.Count;
-
- for (var j = 0; j < party.Members.Count; ++j)
- {
- var info = party.Members[j];
-
- if (info?.Mobile != null)
- {
- var index = titles.IndexOf(info.Mobile);
-
- if (index == -1)
- {
- titles.Add(info.Mobile);
- fame.Add(divedFame);
- karma.Add(divedKarma);
- }
- else
- {
- fame[index] += divedFame;
- karma[index] += divedKarma;
- }
- }
- }
+ qs.OnKill(this, c);
+ givenQuestKill = true;
}
- else
- {
- titles.Add(ds.m_Mobile);
- fame.Add(totalFame);
- karma.Add(totalKarma);
- }
-
- OnKilledBy(ds.m_Mobile);
-
- if (!givenFactionKill)
- {
- givenFactionKill = true;
- Faction.HandleDeath(this, ds.m_Mobile);
- }
-
- var region = ds.m_Mobile.Region;
-
- if (!givenToTKill && (Map == Map.Tokuno || region.IsPartOf("Yomotsu Mines") ||
- region.IsPartOf("Fan Dancer's Dojo")))
- {
- givenToTKill = true;
- TreasuresOfTokuno.HandleKill(this, ds.m_Mobile);
- }
-
- if (ds.m_Mobile is PlayerMobile pm)
- {
- if (MLQuestSystem.Enabled)
- {
- MLQuestSystem.HandleKill(pm, this);
- }
-
- if (givenQuestKill)
- {
- continue;
- }
-
- var qs = pm.Quest;
-
- if (qs != null)
- {
- qs.OnKill(this, c);
- givenQuestKill = true;
- }
- }
- }
-
- for (var i = 0; i < titles.Count; ++i)
- {
- Titles.AwardFame(titles[i], fame[i], true);
- Titles.AwardKarma(titles[i], karma[i], true);
}
}
- base.OnDeath(c);
-
- if (DeleteCorpseOnDeath)
+ for (var i = 0; i < titles.Count; ++i)
{
- c.Delete();
+ Titles.AwardFame(titles[i], fame[i], true);
+ Titles.AwardKarma(titles[i], karma[i], true);
}
}
+
+ base.OnDeath(c);
+
+ if (DeleteCorpseOnDeath)
+ {
+ c.Delete();
+ }
}
public override void OnDelete()
@@ -3642,17 +3614,25 @@ namespace Server.Mobiles
public virtual bool Rummage()
{
- var eable = GetItemsInRange(2);
- var toRummage = eable.FirstOrDefault(item => item.Items.Count > 0);
-
- eable.Free();
-
- if (toRummage == null)
+ if (Backpack == null)
{
return false;
}
- if (Backpack == null)
+ var eable = GetItemsInRange(2);
+ Corpse toRummage = null;
+ foreach (var c in eable)
+ {
+ if (c.Items.Count > 0)
+ {
+ toRummage = c;
+ break;
+ }
+ }
+
+ eable.Free();
+
+ if (toRummage == null)
{
return false;
}
@@ -3788,27 +3768,24 @@ namespace Server.Mobiles
public static void TeleportPets(Mobile master, Point3D loc, Map map, bool onlyBonded = false)
{
- var move = new List();
+ using var queue = PooledRefQueue.Create();
- foreach (var m in master.GetMobilesInRange(3))
+ var eable = master.GetMobilesInRange(3);
+ foreach (var m in eable)
{
- if (
- m is BaseCreature {
- Controlled: true,
- ControlOrder: OrderType.Guard or OrderType.Follow or OrderType.Come
- } pet
- )
+ if (m is BaseCreature
+ { Controlled: true, ControlOrder: OrderType.Guard or OrderType.Follow or OrderType.Come } pet &&
+ pet.ControlMaster == master && (!onlyBonded || pet.IsBonded))
{
- if (pet.ControlMaster == master && (!onlyBonded || pet.IsBonded))
- {
- move.Add(pet);
- }
+ queue.Enqueue(pet);
}
}
- foreach (var m in move)
+ eable.Free();
+
+ while (queue.Count > 0)
{
- m.MoveToWorld(loc, map);
+ queue.Dequeue().MoveToWorld(loc, map);
}
}
@@ -3844,18 +3821,14 @@ namespace Server.Mobiles
var owner = ControlMaster;
- if (owner?.Deleted != false || owner.Map != Map || !owner.InRange(this, 12) || !CanSee(owner) ||
- !InLOS(owner))
- {
- if (OwnerAbandonTime == DateTime.MinValue)
- {
- OwnerAbandonTime = Core.Now;
- }
- }
- else
+ if (owner?.Deleted == false && owner.Map == Map && owner.InRange(this, 12) && CanSee(owner) && InLOS(owner))
{
OwnerAbandonTime = DateTime.MinValue;
}
+ else if (OwnerAbandonTime == DateTime.MinValue)
+ {
+ OwnerAbandonTime = Core.Now;
+ }
CheckStatTimers();
}
@@ -3961,7 +3934,7 @@ namespace Server.Mobiles
public void BeginDeleteTimer()
{
- if (!(this is BaseEscortable) && !Summoned && !Deleted && !IsStabled)
+ if (this is not BaseEscortable && !Summoned && !Deleted && !IsStabled)
{
StopDeleteTimer();
m_DeleteTimer = new DeleteTimer(this, TimeSpan.FromDays(3.0));
@@ -4261,40 +4234,13 @@ namespace Server.Mobiles
{
}
- public virtual bool CheckFoodPreference(Item f)
- {
- if (CheckFoodPreference(f, FoodType.Eggs, m_Eggs))
- {
- return true;
- }
-
- if (CheckFoodPreference(f, FoodType.Fish, m_Fish))
- {
- return true;
- }
-
- if (CheckFoodPreference(f, FoodType.GrainsAndHay, m_GrainsAndHay))
- {
- return true;
- }
-
- if (CheckFoodPreference(f, FoodType.Meat, m_Meat))
- {
- return true;
- }
-
- if (CheckFoodPreference(f, FoodType.FruitsAndVegies, m_FruitsAndVegies))
- {
- return true;
- }
-
- if (CheckFoodPreference(f, FoodType.Gold, m_Gold))
- {
- return true;
- }
-
- return false;
- }
+ public virtual bool CheckFoodPreference(Item f) =>
+ CheckFoodPreference(f, FoodType.Eggs, m_Eggs) ||
+ CheckFoodPreference(f, FoodType.Fish, m_Fish) ||
+ CheckFoodPreference(f, FoodType.GrainsAndHay, m_GrainsAndHay) ||
+ CheckFoodPreference(f, FoodType.Meat, m_Meat) ||
+ CheckFoodPreference(f, FoodType.FruitsAndVegies, m_FruitsAndVegies) ||
+ CheckFoodPreference(f, FoodType.Gold, m_Gold);
public virtual bool CheckFoodPreference(Item fed, FoodType type, Type[] types)
{
@@ -4396,9 +4342,8 @@ namespace Server.Mobiles
}
else if (Core.ML)
{
- from.SendLocalizedMessage(
- 1075268
- ); // Your pet cannot form a bond with you until your animal taming ability has risen.
+ // Your pet cannot form a bond with you until your animal taming ability has risen.
+ from.SendLocalizedMessage(1075268);
}
}
}
@@ -4454,12 +4399,7 @@ namespace Server.Mobiles
return false;
}
- if (!Core.AOS && (skill == SkillName.Focus || skill == SkillName.Chivalry || skill == SkillName.Necromancy))
- {
- return false;
- }
-
- return true;
+ return Core.AOS || skill != SkillName.Focus && skill != SkillName.Chivalry && skill != SkillName.Necromancy;
}
public virtual TeachResult CheckTeachSkills(
@@ -5033,8 +4973,8 @@ namespace Server.Mobiles
return false;
}
- Cap(ref minLevel, 0, 5);
- Cap(ref maxLevel, 0, 5);
+ minLevel = Math.Clamp(minLevel, 0, 5);
+ maxLevel = Math.Clamp(maxLevel, 0, 5);
if (Core.AOS)
{
@@ -5121,9 +5061,7 @@ namespace Server.Mobiles
if (min > max)
{
- var hold = min;
- min = max;
- max = hold;
+ (min, max) = (max, min);
}
/* Example:
@@ -5204,8 +5142,8 @@ namespace Server.Mobiles
return false;
}
- Cap(ref minLevel, 0, 5);
- Cap(ref maxLevel, 0, 5);
+ minLevel = Math.Clamp(minLevel, 0, 5);
+ maxLevel = Math.Clamp(maxLevel, 0, 5);
if (Core.AOS)
{
@@ -5481,15 +5419,21 @@ namespace Server.Mobiles
}
var eable = GetMobilesInRange(AuraRange);
-
- var list = eable.Where(
- m =>
- m != this && CanBeHarmful(m, false) && (Core.AOS || InLOS(m)) &&
- (m is BaseCreature bc && (bc.Controlled || bc.Summoned || bc.Team != Team) || m.Player)
- );
-
- foreach (var m in list)
+ using var queue = PooledRefQueue.Create();
+ foreach (var m in eable)
{
+ if (m != this && CanBeHarmful(m, false) && (Core.AOS || InLOS(m)) &&
+ (m is BaseCreature bc && (bc.Controlled || bc.Summoned || bc.Team != Team) || m.Player))
+ {
+ queue.Enqueue(m);
+ }
+ }
+ eable.Free();
+
+ while (queue.Count > 0)
+ {
+ var m = queue.Dequeue();
+
AOS.Damage(
m,
this,
@@ -5503,8 +5447,6 @@ namespace Server.Mobiles
);
AuraEffect(m);
}
-
- eable.Free();
}
public virtual void AuraEffect(Mobile m)
@@ -5599,10 +5541,8 @@ namespace Server.Mobiles
private DateTime m_NextHourlyCheck;
- public LoyaltyTimer() : base(InternalDelay, InternalDelay)
- {
+ public LoyaltyTimer() : base(InternalDelay, InternalDelay) =>
m_NextHourlyCheck = Core.Now + TimeSpan.FromHours(1.0);
- }
public static void Initialize()
{
@@ -5618,14 +5558,14 @@ namespace Server.Mobiles
m_NextHourlyCheck = Core.Now + TimeSpan.FromHours(1.0);
- var toRelease = new List();
+ using var toRelease = PooledRefQueue.Create();
// added array for wild creatures in house regions to be removed
- var toRemove = new List();
+ using var toRemove = PooledRefQueue.Create();
foreach (var m in World.Mobiles.Values)
{
- if (!(m is BaseCreature c))
+ if (m is not BaseCreature c)
{
continue;
}
@@ -5649,7 +5589,7 @@ namespace Server.Mobiles
}
else if (c.OwnerAbandonTime + c.BondingAbandonDelay <= Core.Now)
{
- toRemove.Add(c);
+ toRemove.Enqueue(c);
}
}
else
@@ -5673,7 +5613,7 @@ namespace Server.Mobiles
if (c.Loyalty <= 0)
{
- toRelease.Add(c);
+ toRelease.Enqueue(c);
}
}
}
@@ -5686,7 +5626,7 @@ namespace Server.Mobiles
if (c.RemoveStep >= 20)
{
- toRemove.Add(c);
+ toRemove.Enqueue(c);
}
}
else
@@ -5695,22 +5635,24 @@ namespace Server.Mobiles
}
}
- foreach (var c in toRelease)
+ while (toRelease.Count > 0)
{
- c.Say(1043255, c.Name); // ~1_NAME~ appears to have decided that is better off without a master!
+ var c = toRelease.Dequeue();
+
+ c.Say(1043255, c.Name); // ~1_NAME~ appears to have decided that is better off without a master!
c.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully Happy
c.IsBonded = false;
c.BondingBegin = DateTime.MinValue;
c.OwnerAbandonTime = DateTime.MinValue;
c.ControlTarget = null;
- c.AIObject
- .DoOrderRelease(); // this will prevent no release of creatures left alone with AI disabled (and consequent bug of Followers)
+ // This will prevent no release of creatures left alone with AI disabled (and consequent bug of Followers)
+ c.AIObject.DoOrderRelease();
c.DropBackpack();
}
- foreach (var c in toRemove)
+ while (toRemove.Count > 0)
{
- c.Delete();
+ toRemove.Dequeue().Delete();
}
}
}
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/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) =>
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/Spell.cs b/Projects/UOContent/Spells/Base/Spell.cs
index 4be93b9b3..85c8c4ceb 100644
--- a/Projects/UOContent/Spells/Base/Spell.cs
+++ b/Projects/UOContent/Spells/Base/Spell.cs
@@ -377,20 +377,19 @@ namespace Server.Spells
return;
}
+ if (!firstCircle && !Core.AOS && (this as MagerySpell)?.Circle == SpellCircle.First)
+ {
+ return;
+ }
+
+ State = SpellState.None;
+ Caster.Spell = null;
+
if (State == SpellState.Casting)
{
- if (!firstCircle && !Core.AOS && this is MagerySpell && ((MagerySpell)this).Circle == SpellCircle.First)
- {
- return;
- }
-
- State = SpellState.None;
- Caster.Spell = null;
-
OnDisturb(type, true);
m_CastTimer?.Stop();
-
m_AnimTimer?.Stop();
if (Core.AOS && Caster.Player && type == DisturbType.Hurt)
@@ -402,14 +401,6 @@ namespace Server.Spells
}
else if (State == SpellState.Sequencing)
{
- if (!firstCircle && !Core.AOS && this is MagerySpell && ((MagerySpell)this).Circle == SpellCircle.First)
- {
- return;
- }
-
- State = SpellState.None;
- Caster.Spell = null;
-
OnDisturb(type, false);
Target.Cancel(Caster);
diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs
index 6b7cb8a24..f855ad5ac 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;
@@ -1229,7 +1226,7 @@ namespace Server.Spells
public static class TransformationSpellHelper
{
- private static readonly Dictionary m_Table = new();
+ private static readonly Dictionary _table = new();
public static bool CheckCast(Mobile caster, Spell spell)
{
@@ -1363,7 +1360,7 @@ namespace Server.Spells
public static void AddContext(Mobile m, TransformContext context)
{
- m_Table[m] = context;
+ _table[m] = context;
}
public static void RemoveContext(Mobile m, bool resetGraphics)
@@ -1378,7 +1375,7 @@ namespace Server.Spells
public static void RemoveContext(Mobile m, TransformContext context, bool resetGraphics)
{
- if (!m_Table.Remove(m))
+ if (!_table.Remove(m))
{
return;
}
@@ -1402,7 +1399,7 @@ namespace Server.Spells
public static TransformContext GetContext(Mobile m)
{
- m_Table.TryGetValue(m, out var context);
+ _table.TryGetValue(m, out var context);
return context;
}
diff --git a/Projects/UOContent/Spells/Bushido/Confidence.cs b/Projects/UOContent/Spells/Bushido/Confidence.cs
index a846088f1..e8eab62dc 100644
--- a/Projects/UOContent/Spells/Bushido/Confidence.cs
+++ b/Projects/UOContent/Spells/Bushido/Confidence.cs
@@ -5,17 +5,17 @@ namespace Server.Spells.Bushido
{
public class Confidence : SamuraiSpell
{
- private static readonly SpellInfo m_Info = new(
+ private static readonly SpellInfo _info = new(
"Confidence",
null,
-1,
9002
);
- private static readonly Dictionary m_Table = new();
+ private static readonly Dictionary _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)
{
}
@@ -49,7 +49,7 @@ namespace Server.Spells.Bushido
FinishSequence();
}
- public static bool IsConfident(Mobile m) => m_Table.ContainsKey(m);
+ public static bool IsConfident(Mobile m) => _table.ContainsKey(m);
public static void BeginConfidence(Mobile m)
{
@@ -64,12 +64,12 @@ namespace Server.Spells.Bushido
out var timerToken
);
- m_Table[m] = timerToken;
+ _table[m] = timerToken;
}
private static bool StopConfidenceTimer(Mobile m)
{
- if (m_Table.Remove(m, out var timerToken))
+ if (_table.Remove(m, out var timerToken))
{
timerToken.Cancel();
return true;
diff --git a/Projects/UOContent/Spells/Bushido/CounterAttack.cs b/Projects/UOContent/Spells/Bushido/CounterAttack.cs
index 04eb1ebcb..ea3c07e22 100644
--- a/Projects/UOContent/Spells/Bushido/CounterAttack.cs
+++ b/Projects/UOContent/Spells/Bushido/CounterAttack.cs
@@ -6,16 +6,16 @@ namespace Server.Spells.Bushido
{
public class CounterAttack : SamuraiSpell
{
- private static readonly SpellInfo m_Info = new(
+ private static readonly SpellInfo _info = new(
"CounterAttack",
null,
-1,
9002
);
- private static readonly Dictionary m_Table = new();
+ private static readonly Dictionary _table = new();
- public CounterAttack(Mobile caster, Item scroll) : base(caster, scroll, m_Info)
+ public CounterAttack(Mobile caster, Item scroll) : base(caster, scroll, _info)
{
}
@@ -71,11 +71,11 @@ namespace Server.Spells.Bushido
FinishSequence();
}
- public static bool IsCountering(Mobile m) => m_Table.ContainsKey(m);
+ public static bool IsCountering(Mobile m) => _table.ContainsKey(m);
private static bool StopCounterTimer(Mobile m)
{
- if (m_Table.Remove(m, out var timerToken))
+ if (_table.Remove(m, out var timerToken))
{
timerToken.Cancel();
return true;
@@ -97,7 +97,7 @@ namespace Server.Spells.Bushido
out var timerToken
);
- m_Table[m] = timerToken;
+ _table[m] = timerToken;
}
public static void StopCountering(Mobile m)
diff --git a/Projects/UOContent/Spells/Bushido/Evasion.cs b/Projects/UOContent/Spells/Bushido/Evasion.cs
index 6c1c37b5c..a5eab88e2 100644
--- a/Projects/UOContent/Spells/Bushido/Evasion.cs
+++ b/Projects/UOContent/Spells/Bushido/Evasion.cs
@@ -6,17 +6,16 @@ namespace Server.Spells.Bushido
{
public class Evasion : SamuraiSpell
{
- private static readonly SpellInfo m_Info = new(
+ private static readonly SpellInfo _info = new(
"Evasion",
null,
-1,
9002
);
- private static readonly Dictionary m_Table = new();
+ private static readonly Dictionary _table = new();
- public Evasion(Mobile caster, Item scroll)
- : base(caster, scroll, m_Info)
+ public Evasion(Mobile caster, Item scroll) : base(caster, scroll, _info)
{
}
@@ -139,7 +138,7 @@ namespace Server.Spells.Bushido
FinishSequence();
}
- public static bool IsEvading(Mobile m) => m_Table.ContainsKey(m);
+ public static bool IsEvading(Mobile m) => _table.ContainsKey(m);
public static TimeSpan GetEvadeDuration(Mobile m)
{
@@ -217,12 +216,12 @@ namespace Server.Spells.Bushido
out var timerToken
);
- m_Table[m] = timerToken;
+ _table[m] = timerToken;
}
private static bool StopEvasionTimer(Mobile m)
{
- if (m_Table.Remove(m, out var timer))
+ if (_table.Remove(m, out var timer))
{
timer.Cancel();
return true;
diff --git a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs
index 0df746862..266644850 100644
--- a/Projects/UOContent/Spells/Bushido/HonorableExecution.cs
+++ b/Projects/UOContent/Spells/Bushido/HonorableExecution.cs
@@ -5,7 +5,7 @@ namespace Server.Spells.Bushido
{
public class HonorableExecution : SamuraiMove
{
- private static readonly Dictionary m_Table = new();
+ private static readonly Dictionary _table = new();
public override int BaseMana => 0;
public override double RequiredSkill => 25.0;
@@ -63,20 +63,20 @@ namespace Server.Spells.Bushido
timer = new HonorableExecutionTimer(attacker, mods);
}
- m_Table[attacker] = timer;
+ _table[attacker] = timer;
timer.Start();
attacker.Delta(MobileDelta.WeaponDamage);
CheckGain(attacker);
}
- public static int GetSwingBonus(Mobile target) => m_Table.TryGetValue(target, out var info) ? info.m_SwingBonus : 0;
+ public static int GetSwingBonus(Mobile target) => _table.TryGetValue(target, out var info) ? info.m_SwingBonus : 0;
- public static bool IsUnderPenalty(Mobile target) => m_Table.TryGetValue(target, out var info) && info.m_Penalty;
+ public static bool IsUnderPenalty(Mobile target) => _table.TryGetValue(target, out var info) && info.m_Penalty;
public static void RemovePenalty(Mobile target)
{
- if (m_Table.Remove(target, out var timer))
+ if (_table.Remove(target, out var timer))
{
timer.Clear();
}
@@ -98,8 +98,8 @@ namespace Server.Spells.Bushido
}
public HonorableExecutionTimer(
- TimeSpan duration, Mobile from, int swingBonus, List