diff --git a/.circleci/checksum.txt b/.circleci/checksum.txt deleted file mode 100644 index 9b522fb67..000000000 --- a/.circleci/checksum.txt +++ /dev/null @@ -1,12 +0,0 @@ -6b0276b603e867108643104978963ddd2e599e58 ../Projects/Argon2/Argon2.csproj -214715e88298b66715dee7c06080fc083f2c9e26 ../Projects/Argon2/Argon2.cs -1e89625abe364f895346d0c5753f3ca6653cf7df ../Projects/Argon2/Argon2Context.cs -abbb34d85f55ca1d78a400b4d46afbd6965f642b ../Projects/Argon2/Argon2Error.cs -00ef35a6809d4959bdda1de01f45e39ff388270f ../Projects/Argon2/Argon2Exception.cs -58979ca359777ae45a6233264f0741ba23203959 ../Projects/Argon2/Argon2PasswordHasher.cs -a137d2fe0478d065d478366168f80ab9eaaa9c3a ../Projects/Argon2/Argon2Type.cs -c09f7a2f9690d56ca838aafb28640c09950c5a8c ../Projects/Argon2/HashMetadata.cs -c9fb8b37bd035c6597047d4279f9b6e6384db944 ../Projects/Argon2/Utility.cs -c9fb8b37bd035c6597047d4279f9b6e6384db944 ../Projects/ZLib/Utility.cs -a4c3595dada3e596ab3131886616d5c27107ec7f ../Projects/ZLib/ZLib.cs -d129d82f8607e97090088a6e1956706d886e8294 ../Projects/ZLib/ZLib.csproj diff --git a/.circleci/config.yml b/.circleci/config.yml index ba1b5fc68..646e64ed0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,84 +17,35 @@ jobs: steps: - run: rm -rf ~/project/.git # CircleCI git caching is likely broken - checkout - - restore_cache: - keys: - - dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - run: - name: Build native libraries - command: /mnt/ramdisk/Tools/build-native-libraries.sh - - save_cache: - paths: - - /mnt/ramdisk/packages - key: dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - - run: - name: Install ModernUO dependencies - command: dotnet restore - - run: - name: Building ModernUO for Linux (Debug) - command: dotnet build -c Debug -r linux-x64 + name: Building ModernUO for Linux + command: Tools/publish.cmd linux build_windows: description: Build application executor: win/default steps: - checkout - - restore_cache: - keys: - - dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - run: - name: Build native libraries - command: Tools\build-native-libraries.cmd - - save_cache: - paths: - - packages - key: dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - - run: - name: Install ModernUO dependencies - command: dotnet restore - - run: - name: Building ModernUO for Windows (Debug) - command: dotnet build -c Debug -r win-x64 + name: Building ModernUO for Windows + command: Tools/publish.cmd win code_styling: description: Code analysis executor: linux-build steps: - run: rm -rf ~/project/.git # CircleCI git caching is likely broken - checkout - - restore_cache: - keys: - - dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - - run: - name: Build native libraries - command: /mnt/ramdisk/Tools/build-native-libraries.sh - - save_cache: - paths: - - /mnt/ramdisk/packages - key: dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - - run: - name: Install ModernUO dependencies - command: dotnet restore - run: name: Building with Analyzers - command: dotnet build -c Analyze -r linux-x64 + command: Tools/publish.cmd linux Analyze tests: description: Unit Tests executor: linux-build steps: - run: rm -rf ~/project/.git # CircleCI git caching is likely broken - checkout - - restore_cache: - keys: - - dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - run: name: Build native libraries command: /mnt/ramdisk/Tools/build-native-libraries.sh - - save_cache: - paths: - - /mnt/ramdisk/packages - key: dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - - run: - name: Install ModernUO dependencies - command: dotnet restore - run: name: Running unit tests command: dotnet test -r linux-x64 diff --git a/.circleci/genchecksum.sh b/.circleci/genchecksum.sh deleted file mode 100755 index c19eed6d5..000000000 --- a/.circleci/genchecksum.sh +++ /dev/null @@ -1 +0,0 @@ -sha1sum ../Projects/Argon2/*.csproj ../Projects/Argon2/*.cs ../Projects/ZLib/*.cs ../Projects/ZLib/*.csproj > "checksum.txt" diff --git a/Projects/Scripts/Mobiles/BaseCreature.cs b/Projects/Scripts/Mobiles/BaseCreature.cs index f23258d50..7cd95c591 100644 --- a/Projects/Scripts/Mobiles/BaseCreature.cs +++ b/Projects/Scripts/Mobiles/BaseCreature.cs @@ -3036,7 +3036,7 @@ namespace Server.Mobiles IsDeadPet = false; - Effects.SendPacket(Location, Map, new BondedStatus(0, Serial, 0)); + Effects.SendPacket(Location, Map, new BondedStatus(Serial, false)); SendIncomingPacket(); SendIncomingPacket(); diff --git a/Projects/Scripts/Scripts.csproj b/Projects/Scripts/Scripts.csproj index 1e99d260f..b3237f5dc 100644 --- a/Projects/Scripts/Scripts.csproj +++ b/Projects/Scripts/Scripts.csproj @@ -14,8 +14,8 @@ true x64 8.0 - $(SolutionDir)\Distribution\Assemblies - $(SolutionDir)\Distribution\Assemblies + + $(SolutionDir)\Distribution\Assemblies true Debug;Release;Analyze diff --git a/Projects/Server.Tests/AssertExtensions.cs b/Projects/Server.Tests/AssertExtensions.cs index 34bc3b7c3..306fa7c56 100644 --- a/Projects/Server.Tests/AssertExtensions.cs +++ b/Projects/Server.Tests/AssertExtensions.cs @@ -15,7 +15,7 @@ namespace Server.Tests return builder.ToString(); } - public static void Equal(ReadOnlySpan expected, ReadOnlySpan actual) => + public static void Equal(ReadOnlySpan actual, ReadOnlySpan expected) => Xunit.Assert.True( MemoryExtensions.SequenceEqual(expected, actual), $"Expected does not match actual.\nExpected:\t{SpanToString(expected)}\nActual:\t\t{SpanToString(actual)}" diff --git a/Projects/Server.Tests/Network/Packets/Outgoing/Old/ArrowPacketTests.cs b/Projects/Server.Tests/Network/Packets/Old/Outgoing/ArrowPacketTests.cs similarity index 85% rename from Projects/Server.Tests/Network/Packets/Outgoing/Old/ArrowPacketTests.cs rename to Projects/Server.Tests/Network/Packets/Old/Outgoing/ArrowPacketTests.cs index cf601391f..fb45facb5 100644 --- a/Projects/Server.Tests/Network/Packets/Outgoing/Old/ArrowPacketTests.cs +++ b/Projects/Server.Tests/Network/Packets/Old/Outgoing/ArrowPacketTests.cs @@ -11,7 +11,8 @@ namespace Server.Tests.Network.Packets { Span data = new CancelArrow().Compile(); - Span expectedData = stackalloc byte[] { + Span expectedData = stackalloc byte[] + { 0xBA, // Packet 0x00, // Command 0xFF, 0xFF, // X @@ -29,7 +30,8 @@ namespace Server.Tests.Network.Packets { Span data = new SetArrow(x, y).Compile(); - Span expectedData = stackalloc byte[] { + Span expectedData = stackalloc byte[] + { 0xBA, // Packet 0x01, // Command 0x00, 0x00, // X @@ -50,7 +52,8 @@ namespace Server.Tests.Network.Packets { Span data = new CancelArrowHS(x, y, 0x1).Compile(); - Span expectedData = stackalloc byte[] { + Span expectedData = stackalloc byte[] + { 0xBA, // Packet 0x00, // Command 0x00, 0x00, // X @@ -72,7 +75,8 @@ namespace Server.Tests.Network.Packets { Span data = new SetArrowHS(x, y, 0x1).Compile(); - Span expectedData = stackalloc byte[] { + Span expectedData = stackalloc byte[] + { 0xBA, // Packet 0x01, // Command 0x00, 0x00, // X diff --git a/Projects/Server.Tests/Network/Packets/Outgoing/Old/DamagePacketTests.cs b/Projects/Server.Tests/Network/Packets/Old/Outgoing/DamagePacketTests.cs similarity index 65% rename from Projects/Server.Tests/Network/Packets/Outgoing/Old/DamagePacketTests.cs rename to Projects/Server.Tests/Network/Packets/Old/Outgoing/DamagePacketTests.cs index fe86f60e9..130aa6965 100644 --- a/Projects/Server.Tests/Network/Packets/Outgoing/Old/DamagePacketTests.cs +++ b/Projects/Server.Tests/Network/Packets/Old/Outgoing/DamagePacketTests.cs @@ -6,19 +6,19 @@ namespace Server.Tests.Network.Packets { public class DamagePacketTests : IClassFixture { - private readonly Mobile mobile; - - public DamagePacketTests(ServerFixture fixture) => mobile = fixture.fromMobile; - [Theory] [InlineData(10, 10)] [InlineData(-5, 0)] [InlineData(1024, 0xFF)] public void TestDamagePacketOld(int inputAmount, byte expectedAmount) { - Span data = new DamagePacketOld(mobile, inputAmount).Compile(); + var m = new Mobile(0x1); + m.DefaultMobileInit(); - Span expectedData = stackalloc byte[] { + Span data = new DamagePacketOld(m, inputAmount).Compile(); + + Span expectedData = stackalloc byte[] + { 0xBF, // Packet 0x00, 0x0B, // Length 0x00, 0x22, // Sub-packet @@ -27,7 +27,7 @@ namespace Server.Tests.Network.Packets expectedAmount // Amount }; - mobile.Serial.CopyTo(expectedData.Slice(6, 4)); + m.Serial.CopyTo(expectedData.Slice(6, 4)); AssertThat.Equal(data, expectedData); } @@ -38,15 +38,19 @@ namespace Server.Tests.Network.Packets [InlineData(100000, 0xFFFF)] public void TestDamagePacket(int inputAmount, ushort expectedAmount) { - Span data = new DamagePacket(mobile, inputAmount).Compile(); + var m = new Mobile(0x1); + m.DefaultMobileInit(); - Span expectedData = stackalloc byte[] { + Span data = new DamagePacket(m, inputAmount).Compile(); + + Span expectedData = stackalloc byte[] + { 0x0B, // Packet 0x00, 0x00, 0x00, 0x00, // Mobile Serial 0x00, 0x00 // Amount }; - mobile.Serial.CopyTo(expectedData.Slice(1, 4)); + m.Serial.CopyTo(expectedData.Slice(1, 4)); expectedAmount.CopyTo(expectedData.Slice(5, 2)); AssertThat.Equal(data, expectedData); diff --git a/Projects/Server.Tests/Network/Packets/Old/Outgoing/DisplayHuePickerTests.cs b/Projects/Server.Tests/Network/Packets/Old/Outgoing/DisplayHuePickerTests.cs new file mode 100644 index 000000000..e62c17c1e --- /dev/null +++ b/Projects/Server.Tests/Network/Packets/Old/Outgoing/DisplayHuePickerTests.cs @@ -0,0 +1,32 @@ +using System; +using Server.HuePickers; +using Server.Network; +using Xunit; + +namespace Server.Tests.Network.Packets +{ + public class DisplayHuePickerTests + { + [Fact] + public void TestDisplayHuePicker() + { + ushort itemID = 0xFF01; + var huePicker = new HuePicker(itemID); + + Span data = new DisplayHuePicker(huePicker).Compile(); + + Span expectedData = stackalloc byte[] + { + 0x95, // Packet ID + 0x00, 0x00, 0x00, 0x00, // Hue Picker Serial + 0x00, 0x00, // Nothing + 0x00, 0x00 // Item ID + }; + + huePicker.Serial.CopyTo(expectedData.Slice(1, 4)); + itemID.CopyTo(expectedData.Slice(7, 2)); + + AssertThat.Equal(data, expectedData); + } + } +} diff --git a/Projects/Server.Tests/Network/Packets/Outgoing/Old/MapPatchesPacketTests.cs b/Projects/Server.Tests/Network/Packets/Old/Outgoing/MapPacketTests.cs similarity index 67% rename from Projects/Server.Tests/Network/Packets/Outgoing/Old/MapPatchesPacketTests.cs rename to Projects/Server.Tests/Network/Packets/Old/Outgoing/MapPacketTests.cs index 9d94805d1..9b072f64b 100644 --- a/Projects/Server.Tests/Network/Packets/Outgoing/Old/MapPatchesPacketTests.cs +++ b/Projects/Server.Tests/Network/Packets/Old/Outgoing/MapPacketTests.cs @@ -11,7 +11,8 @@ namespace Server.Tests.Network.Packets { Span data = new MapPatches().Compile(); - Span expectedData = stackalloc byte[] { + Span expectedData = stackalloc byte[] + { 0xBF, // Packet 0x00, 0x29, // Length 0x00, 0x18, // Sub-packet @@ -28,5 +29,18 @@ namespace Server.Tests.Network.Packets AssertThat.Equal(data, expectedData); } + + [Fact] + public void TestInvalidMapEnable() + { + Span data = new InvalidMapEnable().Compile(); + + Span expectedData = stackalloc byte[] + { + 0xC6 // Packet ID + }; + + AssertThat.Equal(data, expectedData); + } } } diff --git a/Projects/Server.Tests/Network/Packets/Old/Outgoing/MenuPacketTests.cs b/Projects/Server.Tests/Network/Packets/Old/Outgoing/MenuPacketTests.cs new file mode 100644 index 000000000..d4a2ef5eb --- /dev/null +++ b/Projects/Server.Tests/Network/Packets/Old/Outgoing/MenuPacketTests.cs @@ -0,0 +1,219 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Server.ContextMenus; +using Server.Menus.ItemLists; +using Server.Menus.Questions; +using Server.Network; +using Xunit; + +namespace Server.Tests.Network.Packets +{ + internal class ContextMenuItem : Item + { + public override void GetContextMenuEntries(Mobile from, List list) + { + base.GetContextMenuEntries(from, list); + + list.Add(new ContextMenuEntry(500000)); + list.Add(new ContextMenuEntry(500001)); + list.Add(new ContextMenuEntry(500002)); + } + + public ContextMenuItem(Serial serial) : base(serial) + { + } + } + + public class MenuPacketTests : IClassFixture + { + [Fact] + public void TestDisplayItemListMenu() + { + var menu = new ItemListMenu( + "Which item would you choose?", + new[] + { + new ItemListEntry("Item 1", 0x01), + new ItemListEntry("Item 2", 0x100), + new ItemListEntry("Item 3", 0x1000, 250) + } + ); + + string question = menu.Question?.Trim() ?? ""; + int questionLength = Math.Min(255, question.Length); + + int length = 11 + questionLength + menu.Entries.Sum(entry => 5 + entry.Name?.Trim().Length ?? 0); + + Span data = new DisplayItemListMenu(menu).Compile(); + + Span expectedData = stackalloc byte[length]; + + int pos = 0; + + expectedData[pos++] = 0x7C; // Packet ID + ((ushort)length).CopyTo(ref pos, expectedData); + menu.Serial.CopyTo(ref pos, expectedData); + pos += 2; // ((ushort)0x00).CopyTo(ref pos, expectedData); + expectedData[pos++] = (byte)questionLength; + question.CopyASCIITo(ref pos, expectedData); + expectedData[pos++] = (byte)menu.Entries.Length; + for (int i = 0; i < menu.Entries.Length; i++) + { + var entry = menu.Entries[i]; + ((ushort)entry.ItemID).CopyTo(ref pos, expectedData); + ((ushort)entry.Hue).CopyTo(ref pos, expectedData); + string name = entry.Name?.Trim() ?? ""; + + expectedData[pos++] = (byte)name.Length; + name.CopyASCIITo(ref pos, expectedData); + } + + AssertThat.Equal(data, expectedData); + } + + [Fact] + public void TestDisplayQuestionMenu() + { + var menu = new QuestionMenu( + "Which option would you choose?", + new[] + { + "Option 1", + "Option 2", + "Option 3" + } + ); + + string question = menu.Question?.Trim() ?? ""; + int questionLength = Math.Min(255, question.Length); + + int length = 11 + questionLength + menu.Answers.Sum(answer => 5 + answer?.Trim().Length ?? 0); + + Span data = new DisplayQuestionMenu(menu).Compile(); + + Span expectedData = stackalloc byte[length]; + + int pos = 0; + + expectedData[pos++] = 0x7C; // Packet ID + ((ushort)length).CopyTo(ref pos, expectedData); + menu.Serial.CopyTo(ref pos, expectedData); + pos += 2; // ((ushort)0x00).CopyTo(ref pos, expectedData); + expectedData[pos++] = (byte)questionLength; + question?.CopyASCIITo(ref pos, expectedData); + expectedData[pos++] = (byte)menu.Answers.Length; + for (int i = 0; i < menu.Answers.Length; i++) + { + pos += 4; // 0x0.CopyTo(ref pos, expectedData); + var answer = menu.Answers[i]?.Trim() ?? ""; + expectedData[pos++] = (byte)answer.Length; + answer.CopyASCIITo(ref pos, expectedData); + } + + AssertThat.Equal(data, expectedData); + } + + [Fact] + public void TestDisplayContextMenu() + { + var m = new Mobile(0x1); + m.DefaultMobileInit(); + + var item = new ContextMenuItem(Serial.LastItem + 1); + var menu = new ContextMenu(m, item); + + Span data = new DisplayContextMenu(menu).Compile(); + + int length = 12 + menu.Entries.Length * 8; + + Span expectedData = stackalloc byte[length]; + + int pos = 0; + expectedData[pos++] = 0xBF; // Packet ID + ((ushort)length).CopyTo(ref pos, expectedData); // Length + ((ushort)0x14).CopyTo(ref pos, expectedData); // Command + ((ushort)0x02).CopyTo(ref pos, expectedData); // Subcommand + menu.Target.Serial.CopyTo(ref pos, expectedData); + var entries = menu.Entries; + + expectedData[pos++] = (byte)entries.Length; + + for (int i = 0; i < entries.Length; i++) + { + var entry = entries[i]; + entry.Number.CopyTo(ref pos, expectedData); + ((ushort)i).CopyTo(ref pos, expectedData); + + var flags = entry.Flags; + + var range = entry.Range; + + if (range == -1) + range = 18; + + if (!(entry.Enabled && menu.From.InRange(item.GetWorldLocation(), range))) + flags |= CMEFlags.Disabled; + + ((ushort)flags).CopyTo(ref pos, expectedData); + } + + AssertThat.Equal(data, expectedData); + } + + [Fact] + public void TestDisplayContextMenuOld() + { + var m = new Mobile(0x1); + m.DefaultMobileInit(); + + var item = new ContextMenuItem(Serial.LastItem + 1); + var menu = new ContextMenu(m, item); + + Span data = new DisplayContextMenuOld(menu).Compile(); + + int length = 12 + menu.Entries.Sum(entry => 6 + ((entry.Color & 0xFFFF) != 0xFFFF ? 2 : 0)); + + Span expectedData = stackalloc byte[length]; + + int pos = 0; + expectedData[pos++] = 0xBF; // Packet ID + ((ushort)length).CopyTo(ref pos, expectedData); // Length + ((ushort)0x14).CopyTo(ref pos, expectedData); // Command + ((ushort)0x01).CopyTo(ref pos, expectedData); // Subcommand + menu.Target.Serial.CopyTo(ref pos, expectedData); + var entries = menu.Entries; + + expectedData[pos++] = (byte)entries.Length; + + for (int i = 0; i < entries.Length; i++) + { + var entry = entries[i]; + ((ushort)i).CopyTo(ref pos, expectedData); + ((ushort)(entry.Number - 3000000)).CopyTo(ref pos, expectedData); + + var flags = entry.Flags; + + var color = entry.Color & 0xFFFF; + + if (color != 0xFFFF) + flags |= CMEFlags.Colored; + + var range = entry.Range; + + if (range == -1) + range = 18; + + if (!(entry.Enabled && menu.From.InRange(item.GetWorldLocation(), range))) + flags |= CMEFlags.Disabled; + + ((ushort)flags).CopyTo(ref pos, expectedData); + + if ((flags & CMEFlags.Colored) != 0) + ((ushort)color).CopyTo(ref pos, expectedData); + } + + AssertThat.Equal(data, expectedData); + } + } +} diff --git a/Projects/Server.Tests/Network/Packets/Outgoing/Old/SecureTradePacketTests.cs b/Projects/Server.Tests/Network/Packets/Old/Outgoing/SecureTradePacketTests.cs similarity index 63% rename from Projects/Server.Tests/Network/Packets/Outgoing/Old/SecureTradePacketTests.cs rename to Projects/Server.Tests/Network/Packets/Old/Outgoing/SecureTradePacketTests.cs index 4654f3647..6766de0a2 100644 --- a/Projects/Server.Tests/Network/Packets/Outgoing/Old/SecureTradePacketTests.cs +++ b/Projects/Server.Tests/Network/Packets/Old/Outgoing/SecureTradePacketTests.cs @@ -7,25 +7,18 @@ namespace Server.Tests.Network.Packets { public class SecureTradePacketTests : IClassFixture { - private readonly Mobile to; - private readonly Container firstCont; - private readonly Container secondCont; - private readonly Item itemInFirstCont; - - public SecureTradePacketTests(ServerFixture fixture) - { - to = fixture.toMobile; - firstCont = fixture.fromCont; - secondCont = fixture.toCont; - itemInFirstCont = fixture.itemInFromCont; - } - [Theory] [InlineData("short-name")] [InlineData("this is a really long name that is more than 30 characters, probably")] public void TestDisplaySecureTrade(string name) { - Span data = new DisplaySecureTrade(to, firstCont, secondCont, name).Compile(); + var m = new Mobile(0x1); + m.DefaultMobileInit(); + + var firstCont = new Container(Serial.LastItem + 1); + var secondCont = new Container(Serial.LastItem + 2); + + Span data = new DisplaySecureTrade(m, firstCont, secondCont, name).Compile(); Span expectedData = stackalloc byte[] { @@ -42,7 +35,7 @@ namespace Server.Tests.Network.Packets }; int pos = 4; - to.Serial.CopyTo(ref pos, expectedData); + m.Serial.CopyTo(ref pos, expectedData); firstCont.Serial.CopyTo(ref pos, expectedData); secondCont.Serial.CopyTo(ref pos, expectedData); pos++; @@ -54,7 +47,9 @@ namespace Server.Tests.Network.Packets [Fact] public void TestCloseSecureTrade() { - Span data = new CloseSecureTrade(firstCont).Compile(); + var cont = new Container(Serial.LastItem + 1); + + Span data = new CloseSecureTrade(cont).Compile(); Span expectedData = stackalloc byte[] { @@ -64,7 +59,7 @@ namespace Server.Tests.Network.Packets 0x00, 0x00, 0x00, 0x00 // Container Serial }; - firstCont.Serial.CopyTo(expectedData.Slice(4, 4)); + cont.Serial.CopyTo(expectedData.Slice(4, 4)); AssertThat.Equal(data, expectedData); } @@ -74,6 +69,9 @@ namespace Server.Tests.Network.Packets [InlineData(false, true)] // Update second public void TestUpdateSecureTrade(bool first, bool second) { + var firstCont = new Container(Serial.LastItem + 1); + var secondCont = new Container(Serial.LastItem + 2); + Container cont = first ? firstCont : secondCont; Span data = new UpdateSecureTrade(cont, first, second).Compile(); @@ -97,7 +95,8 @@ namespace Server.Tests.Network.Packets [InlineData(250000, 50000, TradeFlag.UpdateLedger)] public void TestUpdateGoldSecureTrade(int gold, int plat, TradeFlag flag) { - Span data = new UpdateSecureTrade(firstCont, flag, gold, plat).Compile(); + var cont = new Container(Serial.LastItem + 1); + Span data = new UpdateSecureTrade(cont, flag, gold, plat).Compile(); Span expectedData = stackalloc byte[] { 0x6F, // Packet ID @@ -109,7 +108,7 @@ namespace Server.Tests.Network.Packets }; int pos = 4; - firstCont.Serial.CopyTo(ref pos, expectedData); + cont.Serial.CopyTo(ref pos, expectedData); gold.CopyTo(ref pos, expectedData); plat.CopyTo(ref pos, expectedData); @@ -119,7 +118,13 @@ namespace Server.Tests.Network.Packets [Fact] public void TestSecureTradeEquip() { - Span data = new SecureTradeEquip(itemInFirstCont, to).Compile(); + var m = new Mobile(0x1); + m.DefaultMobileInit(); + + var cont = new Container(Serial.LastItem + 1); + var itemInCont = new Item(Serial.LastItem + 2) { Parent = cont }; + + Span data = new SecureTradeEquip(itemInCont, m).Compile(); Span expectedData = stackalloc byte[] { 0x25, // Packet ID @@ -134,14 +139,14 @@ namespace Server.Tests.Network.Packets }; int pos = 1; - itemInFirstCont.Serial.CopyTo(ref pos, expectedData); - ((short)itemInFirstCont.ItemID).CopyTo(ref pos, expectedData); - pos++; - ((short)itemInFirstCont.Amount).CopyTo(ref pos, expectedData); - ((short)itemInFirstCont.X).CopyTo(ref pos, expectedData); - ((short)itemInFirstCont.Y).CopyTo(ref pos, expectedData); - to.Serial.CopyTo(ref pos, expectedData); - ((short)itemInFirstCont.Hue).CopyTo(ref pos, expectedData); + itemInCont.Serial.CopyTo(ref pos, expectedData); + ((short)itemInCont.ItemID).CopyTo(ref pos, expectedData); + pos++; // expectedData[pos++] = 0x0; + ((short)itemInCont.Amount).CopyTo(ref pos, expectedData); + ((short)itemInCont.X).CopyTo(ref pos, expectedData); + ((short)itemInCont.Y).CopyTo(ref pos, expectedData); + m.Serial.CopyTo(ref pos, expectedData); + ((short)itemInCont.Hue).CopyTo(ref pos, expectedData); AssertThat.Equal(data, expectedData); } @@ -149,7 +154,13 @@ namespace Server.Tests.Network.Packets [Fact] public void TestSecureTradeEquip6017() { - Span data = new SecureTradeEquip6017(itemInFirstCont, to).Compile(); + var m = new Mobile(0x1); + m.DefaultMobileInit(); + + var cont = new Container(Serial.LastItem + 1); + var itemInCont = new Item(Serial.LastItem + 2) { Parent = cont }; + + Span data = new SecureTradeEquip6017(itemInCont, m).Compile(); Span expectedData = stackalloc byte[] { 0x25, // Packet ID @@ -165,15 +176,15 @@ namespace Server.Tests.Network.Packets }; int pos = 1; - itemInFirstCont.Serial.CopyTo(ref pos, expectedData); - ((short)itemInFirstCont.ItemID).CopyTo(ref pos, expectedData); + itemInCont.Serial.CopyTo(ref pos, expectedData); + ((short)itemInCont.ItemID).CopyTo(ref pos, expectedData); pos++; - ((short)itemInFirstCont.Amount).CopyTo(ref pos, expectedData); - ((short)itemInFirstCont.X).CopyTo(ref pos, expectedData); - ((short)itemInFirstCont.Y).CopyTo(ref pos, expectedData); + ((short)itemInCont.Amount).CopyTo(ref pos, expectedData); + ((short)itemInCont.X).CopyTo(ref pos, expectedData); + ((short)itemInCont.Y).CopyTo(ref pos, expectedData); pos++; - to.Serial.CopyTo(ref pos, expectedData); - ((short)itemInFirstCont.Hue).CopyTo(ref pos, expectedData); + m.Serial.CopyTo(ref pos, expectedData); + ((short)itemInCont.Hue).CopyTo(ref pos, expectedData); AssertThat.Equal(data, expectedData); } diff --git a/Projects/Server.Tests/Network/Packets/Old/Outgoing/TestEquipmentPackets.cs b/Projects/Server.Tests/Network/Packets/Old/Outgoing/TestEquipmentPackets.cs new file mode 100644 index 000000000..f28828e20 --- /dev/null +++ b/Projects/Server.Tests/Network/Packets/Old/Outgoing/TestEquipmentPackets.cs @@ -0,0 +1,95 @@ +using System; +using Server.Network; +using Xunit; + +namespace Server.Tests.Network.Packets +{ + public class TestEquipmentPackets : IClassFixture + { + [Fact] + public void TestDisplayEquipmentInfo() + { + var m = new Mobile(0x1); + m.DefaultMobileInit(); + + var item = new Item(Serial.LastItem + 1); + + var info = new EquipmentInfo( + 500000, + m, + false, + new [] + { + new EquipInfoAttribute(500001, 1), + new EquipInfoAttribute(500002, 2), + new EquipInfoAttribute(500002, 3) + } + ); + + Span data = new DisplayEquipmentInfo(item, info).Compile(); + + var attrs = info.Attributes; + + int length = 17 + (info.Unidentified ? 4 : 0) + attrs.Length * 6; + if (info.Crafter != null) length += 6 + (info.Crafter.Name?.Length ?? 0); + + Span expectedData = stackalloc byte[length]; + + int pos = 0; + + expectedData[pos++] = 0xBF; // Packet ID + ((ushort)length).CopyTo(ref pos, expectedData); // Length + ((ushort)0x10).CopyTo(ref pos, expectedData); // Subcommand + item.Serial.CopyTo(ref pos, expectedData); + info.Number.CopyTo(ref pos, expectedData); + if (info.Crafter != null) + { + var name = info.Crafter.Name ?? ""; + (-3).CopyTo(ref pos, expectedData); + ((ushort)name.Length).CopyTo(ref pos, expectedData); + name.CopyASCIITo(ref pos, expectedData); + } + + if (info.Unidentified) (-4).CopyTo(ref pos, expectedData); + + for (var i = 0; i < attrs.Length; i++) + { + var attr = attrs[i]; + attr.Number.CopyTo(ref pos, expectedData); + ((ushort)attr.Charges).CopyTo(ref pos, expectedData); + } + + (-1).CopyTo(ref pos, expectedData); + + AssertThat.Equal(data, expectedData); + } + + [Fact] + public void TestEquipUpdate() + { + var m = new Mobile(0x1); + m.DefaultMobileInit(); + + var item = new Item(Serial.LastItem + 1) { Parent = m }; + + Span data = new EquipUpdate(item).Compile(); + + Span expectedData = stackalloc byte[] + { + 0x2E, // Packet ID + 0x00, 0x00, 0x00, 0x00, // Serial + 0x00, 0x00, // Item ID + 0x00, (byte)item.Layer, + 0x00, 0x00, 0x00, 0x00, // Parent Serial + 0x00, 0x00, // Hue + }; + + item.Serial.CopyTo(expectedData.Slice(1, 4)); + ((ushort)item.ItemID).CopyTo(expectedData.Slice(5, 2)); + item.Parent.Serial.CopyTo(expectedData.Slice(9, 4)); + ((ushort)item.Hue).CopyTo(expectedData.Slice(13, 2)); + + AssertThat.Equal(data, expectedData); + } + } +} diff --git a/Projects/Server.Tests/Network/Packets/Old/Outgoing/UnicodePromptTests.cs b/Projects/Server.Tests/Network/Packets/Old/Outgoing/UnicodePromptTests.cs new file mode 100644 index 000000000..a7de5dd55 --- /dev/null +++ b/Projects/Server.Tests/Network/Packets/Old/Outgoing/UnicodePromptTests.cs @@ -0,0 +1,37 @@ +using System; +using Server.Network; +using Server.Prompts; +using Xunit; + +namespace Server.Tests.Network.Packets +{ + internal class TestPrompt : Prompt + { + } + + public class UnicodePromptTests + { + [Fact] + public void TestUnicodePrompt() + { + var prompt = new TestPrompt(); + Span data = new UnicodePrompt(prompt).Compile(); + + Span expectedData = stackalloc byte[] + { + 0xC2, // Packet ID + 0x00, 0x15, // Length + 0x00, 0x00, 0x00, 0x00, // Serial + 0x00, 0x00, 0x00, 0x00, // Prompt Serial + 0x00, 0x00, 0x00, 0x00, // Unused + 0x00, 0x00, 0x00, 0x00, // Unused + 0x00, 0x00 // Unused + }; + + prompt.Serial.CopyTo(expectedData.Slice(3, 4)); + prompt.Serial.CopyTo(expectedData.Slice(7, 4)); + + AssertThat.Equal(data, expectedData); + } + } +} diff --git a/Projects/Server.Tests/Network/Packets/Outgoing/Old/VendorBuyPacketTests.cs b/Projects/Server.Tests/Network/Packets/Old/Outgoing/VendorBuyPacketTests.cs similarity index 72% rename from Projects/Server.Tests/Network/Packets/Outgoing/Old/VendorBuyPacketTests.cs rename to Projects/Server.Tests/Network/Packets/Old/Outgoing/VendorBuyPacketTests.cs index bf801f2eb..ebc3d11a6 100644 --- a/Projects/Server.Tests/Network/Packets/Outgoing/Old/VendorBuyPacketTests.cs +++ b/Projects/Server.Tests/Network/Packets/Old/Outgoing/VendorBuyPacketTests.cs @@ -4,33 +4,23 @@ using System.Linq; using Server.Items; using Server.Network; using Xunit; -using Xunit.Abstractions; namespace Server.Tests.Network.Packets { public class VendorBuyPacketTests : IClassFixture { - private readonly Mobile vendor; - private readonly Container cont; - - private readonly List buyStates; - - public VendorBuyPacketTests(ServerFixture fixture) + [Fact] + public void TestVendorBuyContent() { - vendor = fixture.fromMobile; - cont = fixture.fromCont; + var cont = new Container(Serial.LastItem + 1); - buyStates = new List + var buyStates = new List { new BuyItemState("First Item", cont.Serial, Serial.NewItem, 10, 1, 0x01, 0), new BuyItemState("Second Item", cont.Serial, Serial.NewItem, 20, 2, 0x0A, 0), new BuyItemState("Third Item", cont.Serial, Serial.NewItem, 30, 10, 0x0F, 0) }; - } - [Fact] - public void TestVendorBuyContent() - { Span data = new VendorBuyContent(buyStates).Compile(); Span expectedData = stackalloc byte[5 + buyStates.Count * 19]; @@ -62,6 +52,15 @@ namespace Server.Tests.Network.Packets [Fact] public void TestVendorBuyContent6017() { + var cont = new Container(Serial.LastItem + 1); + + var buyStates = new List + { + new BuyItemState("First Item", cont.Serial, Serial.NewItem, 10, 1, 0x01, 0), + new BuyItemState("Second Item", cont.Serial, Serial.NewItem, 20, 2, 0x0A, 0), + new BuyItemState("Third Item", cont.Serial, Serial.NewItem, 30, 10, 0x0F, 0) + }; + Span data = new VendorBuyContent6017(buyStates).Compile(); Span expectedData = stackalloc byte[5 + buyStates.Count * 20]; @@ -94,6 +93,9 @@ namespace Server.Tests.Network.Packets [Fact] public void TestDisplayBuyList() { + var vendor = new Mobile(0x1); + vendor.DefaultMobileInit(); + Span data = new DisplayBuyList(vendor).Compile(); Span expectedData = stackalloc byte[] @@ -111,6 +113,9 @@ namespace Server.Tests.Network.Packets [Fact] public void TestDisplayBuyListHS() { + var vendor = new Mobile(0x1); + vendor.DefaultMobileInit(); + Span data = new DisplayBuyListHS(vendor).Compile(); Span expectedData = stackalloc byte[] @@ -129,6 +134,18 @@ namespace Server.Tests.Network.Packets [Fact] public void TestVendorBuyList() { + var vendor = new Mobile(0x1); + vendor.DefaultMobileInit(); + + var cont = new Container(Serial.LastItem + 1); + + var buyStates = new List + { + new BuyItemState("First Item", cont.Serial, Serial.NewItem, 10, 1, 0x01, 0), + new BuyItemState("Second Item", cont.Serial, Serial.NewItem, 20, 2, 0x0A, 0), + new BuyItemState("Third Item", cont.Serial, Serial.NewItem, 30, 10, 0x0F, 0) + }; + Span data = new VendorBuyList(vendor, buyStates).Compile(); int length = 8 + 5 * 3 + buyStates.Sum(state => state.Description.Length + 1); @@ -154,5 +171,26 @@ namespace Server.Tests.Network.Packets AssertThat.Equal(data, expectedData); } + + [Fact] + public void TestEndVendorBuy() + { + var vendor = new Mobile(0x1); + vendor.DefaultMobileInit(); + + Span data = new EndVendorBuy(vendor).Compile(); + + Span expectedData = stackalloc byte[] + { + 0x3B, // Packet ID + 0x00, 0x08, // Length + 0x00, 0x00, 0x00, 0x00, // Vendor Serial + 0x00 + }; + + vendor.Serial.CopyTo(expectedData.Slice(3, 4)); + + AssertThat.Equal(data, expectedData); + } } } diff --git a/Projects/Server.Tests/Network/Packets/Old/Outgoing/VendorSellPacketTests.cs b/Projects/Server.Tests/Network/Packets/Old/Outgoing/VendorSellPacketTests.cs new file mode 100644 index 000000000..ee04014fd --- /dev/null +++ b/Projects/Server.Tests/Network/Packets/Old/Outgoing/VendorSellPacketTests.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Server.Network; +using Xunit; + +namespace Server.Tests.Network.Packets +{ + public class VendorSellPacketTests : IClassFixture + { + [Fact] + public void TestVendorSellList() + { + var vendor = new Mobile(0x1); + vendor.DefaultMobileInit(); + + var item1 = new Item(Serial.LastItem + 1); + var item2 = new Item(Serial.LastItem + 2) { Name = "Second Item" }; + var item3 = new Item(Serial.LastItem + 3); + + var sellStates = new List + { + new SellItemState(item1, 100, "Item 1"), + new SellItemState(item2, 100000, "Item 2"), + new SellItemState(item3, 1, "Item 3") + }; + + Span data = new VendorSellList(vendor, sellStates).Compile(); + + int length = 9 + 14 * 3 + sellStates.Sum(state => + (string.IsNullOrWhiteSpace(state.Item.Name) ? state.Name ?? "" : state.Item.Name.Trim()).Length + ); + + Span expectedData = stackalloc byte[length]; + + int pos = 0; + expectedData[pos++] = 0x9E; // Packet ID + ((ushort)length).CopyTo(ref pos, expectedData); + vendor.Serial.CopyTo(ref pos, expectedData); + ((ushort)sellStates.Count).CopyTo(ref pos, expectedData); + + for (int i = 0; i < sellStates.Count; i++) + { + SellItemState state = sellStates[i]; + state.Item.Serial.CopyTo(ref pos, expectedData); + ((ushort)state.Item.ItemID).CopyTo(ref pos, expectedData); + ((ushort)state.Item.Hue).CopyTo(ref pos, expectedData); + ((ushort)state.Item.Amount).CopyTo(ref pos, expectedData); + ((ushort)state.Price).CopyTo(ref pos, expectedData); + string name = string.IsNullOrWhiteSpace(state.Item.Name) ? state.Name ?? "" : state.Item.Name.Trim(); + ((ushort)name.Length).CopyTo(ref pos, expectedData); + name.CopyASCIITo(ref pos, expectedData); + } + + AssertThat.Equal(data, expectedData); + } + + [Fact] + public void TestEndVendorSell() + { + var vendor = new Mobile(0x1); + vendor.DefaultMobileInit(); + + Span data = new EndVendorBuy(vendor).Compile(); + + Span expectedData = stackalloc byte[] + { + 0x3B, // Packet ID + 0x00, 0x08, // Length + 0x00, 0x00, 0x00, 0x00, // Vendor Serial + 0x00 + }; + + vendor.Serial.CopyTo(expectedData.Slice(3, 4)); + + AssertThat.Equal(data, expectedData); + } + } +} diff --git a/Projects/Server.Tests/ServerFixture.cs b/Projects/Server.Tests/ServerFixture.cs index 07a9f95c7..59e15d9c7 100644 --- a/Projects/Server.Tests/ServerFixture.cs +++ b/Projects/Server.Tests/ServerFixture.cs @@ -6,11 +6,6 @@ namespace Server.Tests { public class ServerFixture : IDisposable { - private static Mobile m_FromMobile; - private static Mobile m_ToMobile; - private static Container m_FromCont; - private static Container m_ToCont; - private static Item m_ItemInFromCont; // Global setup static ServerFixture() @@ -23,24 +18,8 @@ namespace Server.Tests // Load the world World.Load(); - - m_FromMobile = new Mobile(Serial.NewMobile); - m_FromMobile.DefaultMobileInit(); - - m_ToMobile = new Mobile(Serial.NewMobile); - m_ToMobile.DefaultMobileInit(); - - m_FromCont = new Container(Serial.NewItem); - m_ToCont = new Container(Serial.NewItem); - m_ItemInFromCont = new Item(Serial.NewItem) { Parent = m_FromCont }; } - public Mobile fromMobile => m_FromMobile; - public Mobile toMobile => m_ToMobile; - public Container fromCont => m_FromCont; - public Container toCont => m_ToCont; - public Item itemInFromCont => m_ItemInFromCont; - public void Dispose() { } diff --git a/Projects/Server/ContextMenus/ContextMenu.cs b/Projects/Server/ContextMenus/ContextMenu.cs index 73b2346b7..9e8184b65 100644 --- a/Projects/Server/ContextMenus/ContextMenu.cs +++ b/Projects/Server/ContextMenus/ContextMenu.cs @@ -19,6 +19,7 @@ ***************************************************************************/ using System.Collections.Generic; +using System.Linq; namespace Server.ContextMenus { @@ -40,7 +41,7 @@ namespace Server.ContextMenus /// The or for which this ContextMenu is on. /// /// - public ContextMenu(Mobile from, object target) + public ContextMenu(Mobile from, IEntity target) { From = from; Target = target; @@ -52,8 +53,6 @@ namespace Server.ContextMenus else if (target is Item item) item.GetContextMenuEntries(from, list); - // m_Entries = (ContextMenuEntry[])list.ToArray( typeof( ContextMenuEntry ) ); - Entries = list.ToArray(); for (var i = 0; i < Entries.Length; ++i) @@ -68,7 +67,7 @@ namespace Server.ContextMenus /// /// Gets an object of the or for which this ContextMenu is on. /// - public object Target { get; } + public IEntity Target { get; } /// /// Gets the list of entries contained in this ContextMenu. @@ -78,16 +77,7 @@ namespace Server.ContextMenus /// /// Returns true if this ContextMenu requires packet version 2. /// - public bool RequiresNewPacket - { - get - { - for (var i = 0; i < Entries.Length; ++i) - if (Entries[i].Number < 3000000 || Entries[i].Number > 3032767) - return true; - - return false; - } - } + public bool RequiresNewPacket => + Entries.Any(t => t.Number < 3000000 || t.Number > 3032767); } } diff --git a/Projects/Server/Mobile.cs b/Projects/Server/Mobile.cs index 96013bad5..d26b705f1 100644 --- a/Projects/Server/Mobile.cs +++ b/Projects/Server/Mobile.cs @@ -889,7 +889,7 @@ namespace Server ++m_ChangingCombatant; m_Combatant = value; - if ((m_Combatant != null && !CanBeHarmful(m_Combatant, false)) || + if (m_Combatant != null && !CanBeHarmful(m_Combatant, false) || !Region.OnCombatantChange(this, old, m_Combatant)) { m_Combatant = old; @@ -2519,7 +2519,7 @@ namespace Server if (m.IsDeadBondedPet) { - deadPacket ??= Packet.Acquire(new BondedStatus(0, m.Serial, 1)); + deadPacket ??= Packet.Acquire(new BondedStatus(m.Serial, true)); state.Send(deadPacket); } @@ -6231,7 +6231,7 @@ namespace Server } if (m.IsDeadBondedPet) - ns.Send(new BondedStatus(0, m.Serial, 1)); + ns.Send(new BondedStatus(m.Serial, true)); if (ObjectPropertyList.Enabled) ns.Send(m.OPLPacket); } @@ -6356,7 +6356,7 @@ namespace Server state.Send(MobileIncoming.Create(state, state.Mobile, this)); if (IsDeadBondedPet) - state.Send(new BondedStatus(0, Serial, 1)); + state.Send(new BondedStatus(Serial, true)); if (ObjectPropertyList.Enabled) state.Send(OPLPacket); } @@ -6594,7 +6594,7 @@ namespace Server } if (IsDeadBondedPet) - m.m_NetState.Send(new BondedStatus(0, Serial, 1)); + m.m_NetState.Send(new BondedStatus(Serial, true)); if (ObjectPropertyList.Enabled) m.m_NetState.Send(OPLPacket); } @@ -6614,7 +6614,7 @@ namespace Server } if (m.IsDeadBondedPet) - ourState.Send(new BondedStatus(0, m.Serial, 1)); + ourState.Send(new BondedStatus(m.Serial, true)); if (ObjectPropertyList.Enabled) ourState.Send(m.OPLPacket); } @@ -6642,7 +6642,7 @@ namespace Server } if (IsDeadBondedPet) - ns.Send(new BondedStatus(0, Serial, 1)); + ns.Send(new BondedStatus(Serial, true)); if (ObjectPropertyList.Enabled) ns.Send(OPLPacket); } @@ -6712,7 +6712,7 @@ namespace Server } if (IsDeadBondedPet) - state.Send(new BondedStatus(0, Serial, 1)); + state.Send(new BondedStatus(Serial, true)); if (ObjectPropertyList.Enabled) state.Send(OPLPacket); } diff --git a/Projects/Server/Network/PacketHandlers.cs b/Projects/Server/Network/PacketHandlers.cs index 06163d015..f27589285 100644 --- a/Projects/Server/Network/PacketHandlers.cs +++ b/Projects/Server/Network/PacketHandlers.cs @@ -636,7 +636,7 @@ namespace Server.Network public static void HuePickerResponse(NetState state, PacketReader pvSrc) { var serial = pvSrc.ReadUInt32(); - int value = pvSrc.ReadInt16(); + _ = pvSrc.ReadInt16(); // Item ID var hue = pvSrc.ReadInt16() & 0x3FFF; hue = Utility.ClipDyedHue(hue); diff --git a/Projects/Server/Network/Packets.cs b/Projects/Server/Network/Packets.cs index d62cb17ee..7730d22f4 100644 --- a/Projects/Server/Network/Packets.cs +++ b/Projects/Server/Network/Packets.cs @@ -29,7 +29,6 @@ using Server.Accounting; using Server.Compression; using Server.ContextMenus; using Server.Gumps; -using Server.HuePickers; using Server.Items; using Server.Menus; using Server.Menus.ItemLists; @@ -58,474 +57,6 @@ namespace Server.Network Inspecific = 5 } - public sealed class VendorSellList : Packet - { - public VendorSellList(Mobile shopkeeper, ICollection sis) : base(0x9E) - { - EnsureCapacity(256); - - Stream.Write(shopkeeper.Serial); - - Stream.Write((ushort)sis.Count); - - foreach (var state in sis) - { - Stream.Write(state.Item.Serial); - Stream.Write((ushort)state.Item.ItemID); - Stream.Write((ushort)state.Item.Hue); - Stream.Write((ushort)state.Item.Amount); - Stream.Write((ushort)state.Price); - - var name = state.Item.Name?.Trim(); - if (string.IsNullOrWhiteSpace(name)) - name = state.Name ?? ""; - - Stream.Write((ushort)name.Length); - Stream.WriteAsciiFixed(name, (ushort)name.Length); - } - } - } - - public sealed class EndVendorSell : Packet - { - public EndVendorSell(Mobile vendor) : base(0x3B, 8) - { - Stream.Write((ushort)8); // length - Stream.Write(vendor.Serial); - Stream.Write((byte)0); - } - } - - public sealed class EndVendorBuy : Packet - { - public EndVendorBuy(Mobile vendor) : base(0x3B, 8) - { - Stream.Write((ushort)8); // length - Stream.Write(vendor.Serial); - Stream.Write((byte)0); - } - } - - public sealed class DeathAnimation : Packet - { - public DeathAnimation(Mobile killed, Item corpse) : base(0xAF, 13) - { - Stream.Write(killed.Serial); - Stream.Write(corpse?.Serial ?? Serial.Zero); - Stream.Write(0); - } - } - - public sealed class StatLockInfo : Packet - { - public StatLockInfo(Mobile m) : base(0xBF) - { - EnsureCapacity(12); - - Stream.Write((short)0x19); - Stream.Write((byte)2); - Stream.Write(m.Serial); - Stream.Write((byte)0); - - var lockBits = ((int)m.StrLock << 4) | ((int)m.DexLock << 2) | (int)m.IntLock; - - Stream.Write((byte)lockBits); - } - } - - public class EquipInfoAttribute - { - public EquipInfoAttribute(int number, int charges = -1) - { - Number = number; - Charges = charges; - } - - public int Number { get; } - - public int Charges { get; } - } - - public class EquipmentInfo - { - public EquipmentInfo(int number, Mobile crafter, bool unidentified, EquipInfoAttribute[] attributes) - { - Number = number; - Crafter = crafter; - Unidentified = unidentified; - Attributes = attributes; - } - - public int Number { get; } - - public Mobile Crafter { get; } - - public bool Unidentified { get; } - - public EquipInfoAttribute[] Attributes { get; } - } - - public sealed class DisplayEquipmentInfo : Packet - { - public DisplayEquipmentInfo(Item item, EquipmentInfo info) : base(0xBF) - { - var attrs = info.Attributes; - - EnsureCapacity(17 + (info.Crafter?.Name.Length ?? 0) + - (info.Unidentified ? 4 : 0) + attrs.Length * 6); - - Stream.Write((short)0x10); - Stream.Write(item.Serial); - - Stream.Write(info.Number); - - if (info.Crafter != null) - { - var name = info.Crafter.Name; - - Stream.Write(-3); - - if (name == null) - { - Stream.Write((ushort)0); - } - else - { - var length = name.Length; - Stream.Write((ushort)length); - Stream.WriteAsciiFixed(name, length); - } - } - - if (info.Unidentified) Stream.Write(-4); - - for (var i = 0; i < attrs.Length; ++i) - { - Stream.Write(attrs[i].Number); - Stream.Write((short)attrs[i].Charges); - } - - Stream.Write(-1); - } - } - - public sealed class ChangeUpdateRange : Packet - { - private static readonly ChangeUpdateRange[] m_Cache = new ChangeUpdateRange[0x100]; - - public ChangeUpdateRange(int range) : base(0xC8, 2) - { - Stream.Write((byte)range); - } - - public static ChangeUpdateRange Instantiate(int range) - { - var idx = (byte)range; - var p = m_Cache[idx]; - - if (p == null) - { - m_Cache[idx] = p = new ChangeUpdateRange(range); - p.SetStatic(); - } - - return p; - } - } - - public sealed class ChangeCombatant : Packet - { - public ChangeCombatant(Mobile combatant) : base(0xAA, 5) - { - Stream.Write(combatant?.Serial ?? Serial.Zero); - } - } - - public sealed class DisplayHuePicker : Packet - { - public DisplayHuePicker(HuePicker huePicker) : base(0x95, 9) - { - Stream.Write(huePicker.Serial); - Stream.Write((short)0); - Stream.Write((short)huePicker.ItemID); - } - } - - public sealed class TripTimeResponse : Packet - { - public TripTimeResponse(int unk) : base(0xC9, 6) - { - Stream.Write((byte)unk); - Stream.Write(Environment.TickCount); - } - } - - public sealed class UTripTimeResponse : Packet - { - public UTripTimeResponse(int unk) : base(0xCA, 6) - { - Stream.Write((byte)unk); - Stream.Write(Environment.TickCount); - } - } - - public sealed class UnicodePrompt : Packet - { - public UnicodePrompt(Prompt prompt) : base(0xC2) - { - EnsureCapacity(21); - - Stream.Write(prompt.Serial); - Stream.Write(prompt.Serial); - Stream.Write(0); - Stream.Write(0); - Stream.Write((short)0); - } - } - - public sealed class ChangeCharacter : Packet - { - public ChangeCharacter(IAccount a) : base(0x81) - { - EnsureCapacity(305); - - var count = 0; - - for (var i = 0; i < a.Length; ++i) - if (a[i] != null) - ++count; - - Stream.Write((byte)count); - Stream.Write((byte)0); - - for (var i = 0; i < a.Length; ++i) - if (a[i] != null) - { - var name = a[i].Name; - - if (name == null) - name = "-null-"; - else if ((name = name.Trim()).Length == 0) - name = "-empty-"; - - Stream.WriteAsciiFixed(name, 30); - Stream.Fill(30); // password - } - else - { - Stream.Fill(60); - } - } - } - - public sealed class DeathStatus : Packet - { - public static readonly Packet Dead = SetStatic(new DeathStatus(true)); - public static readonly Packet Alive = SetStatic(new DeathStatus(false)); - - public DeathStatus(bool dead) : base(0x2C, 2) - { - Stream.Write((byte)(dead ? 0 : 2)); - } - - public static Packet Instantiate(bool dead) => dead ? Dead : Alive; - } - - public sealed class SpeedControl : Packet - { - public static readonly Packet WalkSpeed = SetStatic(new SpeedControl(2)); - public static readonly Packet MountSpeed = SetStatic(new SpeedControl(1)); - public static readonly Packet Disable = SetStatic(new SpeedControl(0)); - - public SpeedControl(int speedControl) - : base(0xBF) - { - EnsureCapacity(3); - - Stream.Write((short)0x26); - Stream.Write((byte)speedControl); - } - } - - public sealed class InvalidMapEnable : Packet - { - public InvalidMapEnable() : base(0xC6, 1) - { - } - } - - public sealed class BondedStatus : Packet - { - public BondedStatus(int val1, Serial serial, int val2) : base(0xBF) - { - EnsureCapacity(11); - - Stream.Write((short)0x19); - Stream.Write((byte)val1); - Stream.Write(serial); - Stream.Write((byte)val2); - } - } - - public sealed class ToggleSpecialAbility : Packet - { - public ToggleSpecialAbility(int abilityID, bool active) - : base(0xBF) - { - EnsureCapacity(7); - - Stream.Write((short)0x25); - - Stream.Write((short)abilityID); - Stream.Write(active); - } - } - - public sealed class DisplayItemListMenu : Packet - { - public DisplayItemListMenu(ItemListMenu menu) : base(0x7C) - { - EnsureCapacity(256); - - Stream.Write(((IMenu)menu).Serial); - Stream.Write((short)0); - - var question = menu.Question; - - if (question == null) - { - Stream.Write((byte)0); - } - else - { - var questionLength = question.Length; - Stream.Write((byte)questionLength); - Stream.WriteAsciiFixed(question, questionLength); - } - - var entries = menu.Entries; - - int entriesLength = (byte)entries.Length; - - Stream.Write((byte)entriesLength); - - for (var i = 0; i < entriesLength; ++i) - { - var e = entries[i]; - - Stream.Write((ushort)e.ItemID); - Stream.Write((short)e.Hue); - - var name = e.Name; - - if (name == null) - { - Stream.Write((byte)0); - } - else - { - var nameLength = name.Length; - Stream.Write((byte)nameLength); - Stream.WriteAsciiFixed(name, nameLength); - } - } - } - } - - public sealed class DisplayQuestionMenu : Packet - { - public DisplayQuestionMenu(QuestionMenu menu) : base(0x7C) - { - EnsureCapacity(256); - - Stream.Write(((IMenu)menu).Serial); - Stream.Write((short)0); - - var question = menu.Question; - - if (question == null) - { - Stream.Write((byte)0); - } - else - { - var questionLength = question.Length; - Stream.Write((byte)questionLength); - Stream.WriteAsciiFixed(question, questionLength); - } - - var answers = menu.Answers; - - int answersLength = (byte)answers.Length; - - Stream.Write((byte)answersLength); - - for (var i = 0; i < answersLength; ++i) - { - Stream.Write(0); - - var answer = answers[i]; - - if (answer == null) - { - Stream.Write((byte)0); - } - else - { - var answerLength = answer.Length; - Stream.Write((byte)answerLength); - Stream.WriteAsciiFixed(answer, answerLength); - } - } - } - } - - public sealed class GlobalLightLevel : Packet - { - private static readonly GlobalLightLevel[] m_Cache = new GlobalLightLevel[0x100]; - - public GlobalLightLevel(int level) : base(0x4F, 2) - { - Stream.Write((sbyte)level); - } - - public static GlobalLightLevel Instantiate(int level) - { - var lvl = (byte)level; - var p = m_Cache[lvl]; - - if (p == null) - { - m_Cache[lvl] = p = new GlobalLightLevel(level); - p.SetStatic(); - } - - return p; - } - } - - public sealed class PersonalLightLevel : Packet - { - public PersonalLightLevel(Mobile m) : this(m, m.LightLevel) - { - } - - public PersonalLightLevel(Mobile m, int level) : base(0x4E, 6) - { - Stream.Write(m.Serial); - Stream.Write((sbyte)level); - } - } - - public sealed class PersonalLightLevelZero : Packet - { - public PersonalLightLevelZero(Mobile m) : base(0x4E, 6) - { - Stream.Write(m.Serial); - Stream.Write((sbyte)0); - } - } - [Flags] public enum CMEFlags { @@ -536,112 +67,6 @@ namespace Server.Network Colored = 0x20 } - public sealed class DisplayContextMenu : Packet - { - public DisplayContextMenu(ContextMenu menu) : base(0xBF) - { - var entries = menu.Entries; - - int length = (byte)entries.Length; - - EnsureCapacity(12 + length * 8); - - Stream.Write((short)0x14); - Stream.Write((short)0x02); - - var target = menu.Target as IEntity; - - Stream.Write(target?.Serial ?? Serial.MinusOne); - - Stream.Write((byte)length); - - Point3D p; - - if (target is Mobile) - p = target.Location; - else if (target is Item item) - p = item.GetWorldLocation(); - else - p = Point3D.Zero; - - for (var i = 0; i < length; ++i) - { - var e = entries[i]; - - Stream.Write(e.Number); - Stream.Write((short)i); - - var range = e.Range; - - if (range == -1) - range = 18; - - var flags = e.Enabled && menu.From.InRange(p, range) ? CMEFlags.None : CMEFlags.Disabled; - - flags |= e.Flags; - - Stream.Write((short)flags); - } - } - } - - public sealed class DisplayContextMenuOld : Packet - { - public DisplayContextMenuOld(ContextMenu menu) : base(0xBF) - { - var entries = menu.Entries; - - int length = (byte)entries.Length; - - EnsureCapacity(12 + length * 8); - - Stream.Write((short)0x14); - Stream.Write((short)0x01); - - var target = menu.Target as IEntity; - - Stream.Write(target?.Serial ?? Serial.MinusOne); - - Stream.Write((byte)length); - - Point3D p; - - if (target is Mobile) - p = target.Location; - else if (target is Item item) - p = item.GetWorldLocation(); - else - p = Point3D.Zero; - - for (var i = 0; i < length; ++i) - { - var e = entries[i]; - - Stream.Write((short)i); - Stream.Write((ushort)(e.Number - 3000000)); - - var range = e.Range; - - if (range == -1) - range = 18; - - var flags = e.Enabled && menu.From.InRange(p, range) ? CMEFlags.None : CMEFlags.Disabled; - - var color = e.Color & 0xFFFF; - - if (color != 0xFFFF) - flags |= CMEFlags.Colored; - - flags |= e.Flags; - - Stream.Write((short)flags); - - if ((flags & CMEFlags.Colored) != 0) - Stream.Write((short)color); - } - } - } - public sealed class DisplayProfile : Packet { public DisplayProfile(bool realSerial, Mobile m, string header, string body, string footer) : base(0xB8) @@ -671,38 +96,6 @@ namespace Server.Network } } - public sealed class EquipUpdate : Packet - { - public EquipUpdate(Item item) : base(0x2E, 15) - { - Serial parentSerial; - - var parent = item.Parent as Mobile; - - if (parent != null) - { - parentSerial = parent.Serial; - } - else - { - Console.WriteLine("Warning: EquipUpdate on item with !(parent is Mobile)"); - parentSerial = Serial.Zero; - } - - var hue = item.Hue; - - if (parent?.SolidHueOverride >= 0) - hue = parent.SolidHueOverride; - - Stream.Write(item.Serial); - Stream.Write((short)item.ItemID); - Stream.Write((byte)0); - Stream.Write((byte)item.Layer); - Stream.Write(parentSerial); - Stream.Write((short)hue); - } - } - public sealed class WorldItem : Packet { public WorldItem(Item item) : base(0x1A) @@ -909,80 +302,6 @@ namespace Server.Network } } - public sealed class UnkD3 : Packet - { - public UnkD3(Mobile beholder, Mobile beheld) : base(0xD3) - { - EnsureCapacity(256); - - // int - // short - // short - // short - // byte - // byte - // short - // byte - // byte - // short - // short - // short - // while ( int != 0 ) - // { - // short - // byte - // short - // } - - Stream.Write(beheld.Serial); - Stream.Write((short)beheld.Body); - Stream.Write((short)beheld.X); - Stream.Write((short)beheld.Y); - Stream.Write((sbyte)beheld.Z); - Stream.Write((byte)beheld.Direction); - Stream.Write((ushort)beheld.Hue); - Stream.Write((byte)beheld.GetPacketFlags()); - Stream.Write((byte)Notoriety.Compute(beholder, beheld)); - - Stream.Write((short)0); - Stream.Write((short)0); - Stream.Write((short)0); - - Stream.Write(0); - } - } - - public sealed class GQRequest : Packet - { - public GQRequest() : base(0xC3) - { - EnsureCapacity(256); - - Stream.Write(1); - Stream.Write(2); // ID - Stream.Write(3); // Customer ? (this) - Stream.Write(4); // Customer this (?) - Stream.Write(0); - Stream.Write((short)0); - Stream.Write((short)6); - Stream.Write((byte)'r'); - Stream.Write((byte)'e'); - Stream.Write((byte)'g'); - Stream.Write((byte)'i'); - Stream.Write((byte)'o'); - Stream.Write((byte)'n'); - Stream.Write(7); // Call time in seconds - Stream.Write((short)2); // Map (0=fel,1=tram,2=ilsh) - Stream.Write(8); // X - Stream.Write(9); // Y - Stream.Write(10); // Z - Stream.Write(11); // Volume - Stream.Write(12); // Rank - Stream.Write(-1); - Stream.Write(1); // type - } - } - /// /// Causes the client to walk in a given direction. It does not send a movement request. /// @@ -996,18 +315,6 @@ namespace Server.Network } } - /// - /// Displays a message "There are currently [count] available calls in the global queue.". - /// - public sealed class GQCount : Packet - { - public GQCount(int unk, int count) : base(0xCB, 7) - { - Stream.Write((short)unk); - Stream.Write(count); - } - } - /// /// Asks the client for it's version /// @@ -1019,19 +326,6 @@ namespace Server.Network } } - /// - /// Asks the client for it's "assist version". (Perhaps for UOAssist?) - /// - public sealed class AssistVersionReq : Packet - { - public AssistVersionReq(int unk) : base(0xBE) - { - EnsureCapacity(7); - - Stream.Write(unk); - } - } - public enum EffectType { Moving = 0x00, @@ -3444,70 +2738,6 @@ namespace Server.Network } } - [Flags] - public enum ThirdPartyFeature : ulong - { - FilterWeather = 1, - FilterLight = 1 << 1, - - SmartTarget = 1 << 2, - RangedTarget = 1 << 3, - - AutoOpenDoors = 1 << 4, - - DequipOnCast = 1 << 5, - AutoPotionEquip = 1 << 6, - - ProtectHeals = 1 << 7, - - LoopedMacros = 1 << 8, - - UseOnceAgent = 1 << 9, - RestockAgent = 1 << 10, - SellAgent = 1 << 11, - BuyAgent = 1 << 12, - - PotionHotkeys = 1 << 13, - - RandomTargets = 1 << 14, - ClosestTargets = 1 << 15, // All closest target hotkeys - OverheadHealth = 1 << 16, // Health and Mana/Stam messages shown over player's heads - - AutolootAgent = 1 << 17, - BoneCutterAgent = 1 << 18, - AdvancedMacros = 1 << 19, - AutoRemount = 1 << 20, - AutoBandage = 1 << 21, - EnemyTargetShare = 1 << 22, - FilterSeason = 1 << 23, - SpellTargetShare = 1 << 24, - - All = ulong.MaxValue - } - - public static class FeatureProtection - { - public static ThirdPartyFeature DisabledFeatures { get; private set; } = 0; - - public static void Disable(ThirdPartyFeature feature) - { - SetDisabled(feature, true); - } - - public static void Enable(ThirdPartyFeature feature) - { - SetDisabled(feature, false); - } - - public static void SetDisabled(ThirdPartyFeature feature, bool value) - { - if (value) - DisabledFeatures |= feature; - else - DisabledFeatures &= ~feature; - } - } - public sealed class CharacterList : Packet { // private static MD5CryptoServiceProvider m_MD5Provider; @@ -3568,35 +2798,6 @@ namespace Server.Network Stream.Write((int)(flags | AdditionalFlags)); // Additional Flags Stream.Write((short)-1); - - /*ThirdPartyFeature disabled = FeatureProtection.DisabledFeatures; - - if (disabled != 0) - { - if (m_MD5Provider == null) - m_MD5Provider = new MD5CryptoServiceProvider(); - - m_Stream.UnderlyingStream.Flush(); - - byte[] hashCode = m_MD5Provider.ComputeHash(m_Stream.UnderlyingStream.GetBuffer(), 0, - (int)m_Stream.UnderlyingStream.Length); - byte[] buffer = new byte[28]; - - for (int i = 0; i < count; ++i) - { - Utility.RandomBytes(buffer); - - m_Stream.Seek(35 + i * 60, SeekOrigin.Begin); - m_Stream.Write(buffer, 0, buffer.Length); - } - - m_Stream.Seek(35, SeekOrigin.Begin); - m_Stream.Write((int)((long)disabled >> 32)); - m_Stream.Write((int)disabled); - - m_Stream.Seek(95, SeekOrigin.Begin); - m_Stream.Write(hashCode, 0, hashCode.Length); - }*/ } public static CharacterListFlags AdditionalFlags { get; set; } diff --git a/Projects/Server/Network/Packets/Old Packets/AccountPackets.cs b/Projects/Server/Network/Packets/Old Packets/AccountPackets.cs new file mode 100644 index 000000000..c06aa3963 --- /dev/null +++ b/Projects/Server/Network/Packets/Old Packets/AccountPackets.cs @@ -0,0 +1,59 @@ +/************************************************************************* + * ModernUO * + * Copyright (C) 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: AccountPackets.cs - Created: 2020/05/08 - Updated: 2020/05/08 * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using Server.Accounting; + +namespace Server.Network +{ + public sealed class ChangeCharacter : Packet + { + public ChangeCharacter(IAccount a) : base(0x81) + { + EnsureCapacity(305); + + var count = 0; + + for (var i = 0; i < a.Length; ++i) + if (a[i] != null) + ++count; + + Stream.Write((byte)count); + Stream.Write((byte)0); + + for (var i = 0; i < a.Length; ++i) + if (a[i] != null) + { + var name = a[i].Name; + + if (name == null) + name = "-null-"; + else if ((name = name.Trim()).Length == 0) + name = "-empty-"; + + Stream.WriteAsciiFixed(name, 30); + Stream.Fill(30); // password + } + else + { + Stream.Fill(60); + } + } + } +} diff --git a/Projects/Server/Network/Packets/OldPackets/ArrowPackets.cs b/Projects/Server/Network/Packets/Old Packets/ArrowPackets.cs similarity index 100% rename from Projects/Server/Network/Packets/OldPackets/ArrowPackets.cs rename to Projects/Server/Network/Packets/Old Packets/ArrowPackets.cs diff --git a/Projects/Server/Network/Packets/OldPackets/DamagePackets.cs b/Projects/Server/Network/Packets/Old Packets/DamagePackets.cs similarity index 100% rename from Projects/Server/Network/Packets/OldPackets/DamagePackets.cs rename to Projects/Server/Network/Packets/Old Packets/DamagePackets.cs diff --git a/Projects/Server/Network/Packets/Old Packets/DisplayHuePicker.cs b/Projects/Server/Network/Packets/Old Packets/DisplayHuePicker.cs new file mode 100644 index 000000000..7125b1376 --- /dev/null +++ b/Projects/Server/Network/Packets/Old Packets/DisplayHuePicker.cs @@ -0,0 +1,35 @@ +/************************************************************************* + * ModernUO * + * Copyright (C) 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: DisplayHuePicker.cs * + * Created: 2020/05/08 - Updated: 2020/05/08 * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using Server.HuePickers; + +namespace Server.Network +{ + public sealed class DisplayHuePicker : Packet + { + public DisplayHuePicker(HuePicker huePicker) : base(0x95, 9) + { + Stream.Write(huePicker.Serial); + Stream.Write((short)0); + Stream.Write((short)huePicker.ItemID); + } + } +} diff --git a/Projects/Server/Network/Packets/Old Packets/EquipmentPackets.cs b/Projects/Server/Network/Packets/Old Packets/EquipmentPackets.cs new file mode 100644 index 000000000..aa14061bc --- /dev/null +++ b/Projects/Server/Network/Packets/Old Packets/EquipmentPackets.cs @@ -0,0 +1,131 @@ +/************************************************************************* + * ModernUO * + * Copyright (C) 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: EquipmentPackets.cs - Created: 2020/05/07 - Updated: 2020/05/07 * * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; + +namespace Server.Network +{ + public class EquipInfoAttribute + { + public EquipInfoAttribute(int number, int charges = -1) + { + Number = number; + Charges = charges; + } + + public int Number { get; } + + public int Charges { get; } + } + + public class EquipmentInfo + { + public EquipmentInfo(int number, Mobile crafter, bool unidentified, EquipInfoAttribute[] attributes) + { + Number = number; + Crafter = crafter; + Unidentified = unidentified; + Attributes = attributes; + } + + public int Number { get; } + + public Mobile Crafter { get; } + + public bool Unidentified { get; } + + public EquipInfoAttribute[] Attributes { get; } + } + + public sealed class DisplayEquipmentInfo : Packet + { + public DisplayEquipmentInfo(Item item, EquipmentInfo info) : base(0xBF) + { + var attrs = info.Attributes; + + EnsureCapacity(17 + (info.Crafter?.Name?.Length ?? 0) + + (info.Unidentified ? 4 : 0) + attrs.Length * 6); + + Stream.Write((short)0x10); + Stream.Write(item.Serial); + + Stream.Write(info.Number); + + if (info.Crafter != null) + { + var name = info.Crafter.Name; + + Stream.Write(-3); + + if (name == null) + { + Stream.Write((ushort)0); + } + else + { + var length = name.Length; + Stream.Write((ushort)length); + Stream.WriteAsciiFixed(name, length); + } + } + + if (info.Unidentified) Stream.Write(-4); + + for (var i = 0; i < attrs.Length; ++i) + { + Stream.Write(attrs[i].Number); + Stream.Write((short)attrs[i].Charges); + } + + Stream.Write(-1); + } + } + + public sealed class EquipUpdate : Packet + { + public EquipUpdate(Item item) : base(0x2E, 15) + { + Serial parentSerial; + + var parent = item.Parent as Mobile; + var hue = item.Hue; + + if (parent != null) + { + parentSerial = parent.Serial; + + if (parent.SolidHueOverride >= 0) + hue = parent.SolidHueOverride; + } + else + { + Console.WriteLine("Warning: EquipUpdate on item with !(parent is Mobile)"); + parentSerial = Serial.Zero; + } + + Stream.Write(item.Serial); + Stream.Write((short)item.ItemID); + Stream.Write((byte)0); + Stream.Write((byte)item.Layer); + Stream.Write(parentSerial); + Stream.Write((short)hue); + } + } +} diff --git a/Projects/Server/Network/Packets/OldPackets/MapPatches.cs b/Projects/Server/Network/Packets/Old Packets/MapPackets.cs similarity index 89% rename from Projects/Server/Network/Packets/OldPackets/MapPatches.cs rename to Projects/Server/Network/Packets/Old Packets/MapPackets.cs index c5956b70b..3095c609f 100644 --- a/Projects/Server/Network/Packets/OldPackets/MapPatches.cs +++ b/Projects/Server/Network/Packets/Old Packets/MapPackets.cs @@ -2,7 +2,7 @@ * ModernUO * * Copyright (C) 2019-2020 - ModernUO Development Team * * Email: hi@modernuo.com * - * File: MapPatches.cs - Created: 2020/05/03 - Updated: 2020/05/03 * + * File: MapPackets.cs - Created: 2020/05/03 - Updated: 2020/05/08 * * * * 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 * @@ -44,4 +44,11 @@ namespace Server.Network Stream.Write(Map.Malas.Tiles.Patch.LandBlocks); } } + + public sealed class InvalidMapEnable : Packet + { + public InvalidMapEnable() : base(0xC6, 1) + { + } + } } diff --git a/Projects/Server/Network/Packets/Old Packets/MenuPackets.cs b/Projects/Server/Network/Packets/Old Packets/MenuPackets.cs new file mode 100644 index 000000000..02926a98a --- /dev/null +++ b/Projects/Server/Network/Packets/Old Packets/MenuPackets.cs @@ -0,0 +1,228 @@ +/************************************************************************* + * ModernUO * + * Copyright (C) 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: MenuPackets.cs - Created: 2020/05/08 - Updated: 2020/05/08 * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using Server.ContextMenus; +using Server.Menus; +using Server.Menus.ItemLists; +using Server.Menus.Questions; + +namespace Server.Network +{ + public sealed class DisplayItemListMenu : Packet + { + public DisplayItemListMenu(ItemListMenu menu) : base(0x7C) + { + EnsureCapacity(256); + + Stream.Write(((IMenu)menu).Serial); + Stream.Write((short)0); + + var question = menu.Question; + + if (question == null) + { + Stream.Write((byte)0); + } + else + { + var questionLength = question.Length; + Stream.Write((byte)questionLength); + Stream.WriteAsciiFixed(question, questionLength); + } + + var entries = menu.Entries; + + int entriesLength = (byte)entries.Length; + + Stream.Write((byte)entriesLength); + + for (var i = 0; i < entriesLength; ++i) + { + var e = entries[i]; + + Stream.Write((ushort)e.ItemID); + Stream.Write((short)e.Hue); + + var name = e.Name; + + if (name == null) + { + Stream.Write((byte)0); + } + else + { + var nameLength = name.Length; + Stream.Write((byte)nameLength); + Stream.WriteAsciiFixed(name, nameLength); + } + } + } + } + + public sealed class DisplayQuestionMenu : Packet + { + public DisplayQuestionMenu(QuestionMenu menu) : base(0x7C) + { + EnsureCapacity(256); + + Stream.Write(((IMenu)menu).Serial); + Stream.Write((short)0); + + var question = menu.Question; + + if (question == null) + { + Stream.Write((byte)0); + } + else + { + var questionLength = question.Length; + Stream.Write((byte)questionLength); + Stream.WriteAsciiFixed(question, questionLength); + } + + var answers = menu.Answers; + + int answersLength = (byte)answers.Length; + + Stream.Write((byte)answersLength); + + for (var i = 0; i < answersLength; ++i) + { + Stream.Write(0); + + var answer = answers[i]; + + if (answer == null) + { + Stream.Write((byte)0); + } + else + { + var answerLength = answer.Length; + Stream.Write((byte)answerLength); + Stream.WriteAsciiFixed(answer, answerLength); + } + } + } + } + + public sealed class DisplayContextMenu : Packet + { + public DisplayContextMenu(ContextMenu menu) : base(0xBF) + { + var entries = menu.Entries; + + int length = (byte)entries.Length; + + EnsureCapacity(12 + length * 8); + + Stream.Write((short)0x14); + Stream.Write((short)0x02); + + var target = menu.Target; + + Stream.Write(target.Serial); + + Stream.Write((byte)length); + + Point3D p = target switch + { + Mobile _ => target.Location, + Item item => item.GetWorldLocation(), + _ => Point3D.Zero + }; + + for (var i = 0; i < length; ++i) + { + var e = entries[i]; + + Stream.Write(e.Number); + Stream.Write((short)i); + + var range = e.Range; + + if (range == -1) + range = 18; + + var flags = e.Flags; + if (!(e.Enabled && menu.From.InRange(p, range))) + flags |= CMEFlags.Disabled; + + Stream.Write((short)flags); + } + } + } + + public sealed class DisplayContextMenuOld : Packet + { + public DisplayContextMenuOld(ContextMenu menu) : base(0xBF) + { + var entries = menu.Entries; + + int length = (byte)entries.Length; + + EnsureCapacity(12 + length * 8); + + Stream.Write((short)0x14); + Stream.Write((short)0x01); + + var target = menu.Target; + + Stream.Write(target.Serial); + + Stream.Write((byte)length); + + Point3D p = target switch + { + Mobile _ => target.Location, + Item item => item.GetWorldLocation(), + _ => Point3D.Zero + }; + + for (var i = 0; i < length; ++i) + { + var e = entries[i]; + + Stream.Write((short)i); + Stream.Write((ushort)(e.Number - 3000000)); + + var range = e.Range; + + if (range == -1) + range = 18; + + var flags = e.Flags; + if (!(e.Enabled && menu.From.InRange(p, range))) + flags |= CMEFlags.Disabled; + + var color = e.Color & 0xFFFF; + + if (color != 0xFFFF) + flags |= CMEFlags.Colored; + + Stream.Write((short)flags); + + if ((flags & CMEFlags.Colored) != 0) + Stream.Write((short)color); + } + } + } +} diff --git a/Projects/Server/Network/Packets/Old Packets/MobilePackets.cs b/Projects/Server/Network/Packets/Old Packets/MobilePackets.cs new file mode 100644 index 000000000..768194062 --- /dev/null +++ b/Projects/Server/Network/Packets/Old Packets/MobilePackets.cs @@ -0,0 +1,45 @@ +/************************************************************************* + * ModernUO * + * Copyright (C) 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: MobilePackets.cs - Created: 2020/05/07 - Updated: 2020/05/07 * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +namespace Server.Network +{ + public sealed class DeathAnimation : Packet + { + public DeathAnimation(Mobile killed, Item corpse) : base(0xAF, 13) + { + Stream.Write(killed.Serial); + Stream.Write(corpse?.Serial ?? Serial.Zero); + Stream.Write(0); + } + } + + public sealed class BondedStatus : Packet + { + public BondedStatus(Serial serial, bool bonded) : base(0xBF) + { + EnsureCapacity(11); + + Stream.Write((short)0x19); + Stream.Write((byte)0); + Stream.Write(serial); + Stream.Write((byte)(bonded ? 1 : 0)); + } + } +} diff --git a/Projects/Server/Network/Packets/OldPackets/ObjectHelpResponse.cs b/Projects/Server/Network/Packets/Old Packets/ObjectHelpResponse.cs similarity index 100% rename from Projects/Server/Network/Packets/OldPackets/ObjectHelpResponse.cs rename to Projects/Server/Network/Packets/Old Packets/ObjectHelpResponse.cs diff --git a/Projects/Server/Network/Packets/Old Packets/PlayerPackets.cs b/Projects/Server/Network/Packets/Old Packets/PlayerPackets.cs new file mode 100644 index 000000000..5f981dff9 --- /dev/null +++ b/Projects/Server/Network/Packets/Old Packets/PlayerPackets.cs @@ -0,0 +1,154 @@ +/************************************************************************* + * ModernUO * + * Copyright (C) 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: PlayerPackets.cs - Created: 2020/05/07 - Updated: 2020/05/07 * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +namespace Server.Network +{ + public sealed class StatLockInfo : Packet + { + public StatLockInfo(Mobile m) : base(0xBF) + { + EnsureCapacity(12); + + Stream.Write((short)0x19); + Stream.Write((byte)2); + Stream.Write(m.Serial); + Stream.Write((byte)0); + + var lockBits = ((int)m.StrLock << 4) | ((int)m.DexLock << 2) | (int)m.IntLock; + + Stream.Write((byte)lockBits); + } + } + + public sealed class ChangeCombatant : Packet + { + public ChangeCombatant(Mobile combatant) : base(0xAA, 5) + { + Stream.Write(combatant?.Serial ?? Serial.Zero); + } + } + + public sealed class ChangeUpdateRange : Packet + { + private static readonly ChangeUpdateRange[] m_Cache = new ChangeUpdateRange[0x100]; + + public ChangeUpdateRange(int range) : base(0xC8, 2) + { + Stream.Write((byte)range); + } + + public static ChangeUpdateRange Instantiate(int range) + { + var idx = (byte)range; + var p = m_Cache[idx]; + + if (p == null) + { + m_Cache[idx] = p = new ChangeUpdateRange(range); + p.SetStatic(); + } + + return p; + } + } + + public sealed class DeathStatus : Packet + { + public static readonly Packet Dead = SetStatic(new DeathStatus(true)); + public static readonly Packet Alive = SetStatic(new DeathStatus(false)); + + public DeathStatus(bool dead) : base(0x2C, 2) + { + Stream.Write((byte)(dead ? 0 : 2)); + } + + public static Packet Instantiate(bool dead) => dead ? Dead : Alive; + } + + public sealed class SpeedControl : Packet + { + public static readonly Packet WalkSpeed = SetStatic(new SpeedControl(2)); + public static readonly Packet MountSpeed = SetStatic(new SpeedControl(1)); + public static readonly Packet Disable = SetStatic(new SpeedControl(0)); + + public SpeedControl(int speedControl) : base(0xBF) + { + EnsureCapacity(3); + + Stream.Write((short)0x26); + Stream.Write((byte)speedControl); + } + } + + public sealed class ToggleSpecialAbility : Packet + { + public ToggleSpecialAbility(int abilityID, bool active) : base(0xBF) + { + EnsureCapacity(7); + + Stream.Write((short)0x25); + + Stream.Write((short)abilityID); + Stream.Write(active); + } + } + + public sealed class GlobalLightLevel : Packet + { + private static readonly GlobalLightLevel[] m_Cache = new GlobalLightLevel[0x100]; + + public GlobalLightLevel(int level) : base(0x4F, 2) + { + Stream.Write((sbyte)level); + } + + public static GlobalLightLevel Instantiate(int level) + { + var lvl = (byte)level; + var p = m_Cache[lvl]; + + if (p == null) + { + m_Cache[lvl] = p = new GlobalLightLevel(level); + p.SetStatic(); + } + + return p; + } + } + + public sealed class PersonalLightLevel : Packet + { + public PersonalLightLevel(Mobile m, int level) : base(0x4E, 6) + { + Stream.Write(m.Serial); + Stream.Write((sbyte)level); + } + } + + public sealed class PersonalLightLevelZero : Packet + { + public PersonalLightLevelZero(Mobile m) : base(0x4E, 6) + { + Stream.Write(m.Serial); + Stream.Write((sbyte)0); + } + } +} diff --git a/Projects/Server/Network/Packets/OldPackets/SecureTradePackets.cs b/Projects/Server/Network/Packets/Old Packets/SecureTradePackets.cs similarity index 100% rename from Projects/Server/Network/Packets/OldPackets/SecureTradePackets.cs rename to Projects/Server/Network/Packets/Old Packets/SecureTradePackets.cs diff --git a/Projects/Server/Network/Packets/Old Packets/UnicodePrompt.cs b/Projects/Server/Network/Packets/Old Packets/UnicodePrompt.cs new file mode 100644 index 000000000..54472fc9c --- /dev/null +++ b/Projects/Server/Network/Packets/Old Packets/UnicodePrompt.cs @@ -0,0 +1,38 @@ +/************************************************************************* + * ModernUO * + * Copyright (C) 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: UnicodePrompt.cs - Created: 2020/05/08 - Updated: 2020/05/08 * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using Server.Prompts; + +namespace Server.Network +{ + public sealed class UnicodePrompt : Packet + { + public UnicodePrompt(Prompt prompt) : base(0xC2) + { + EnsureCapacity(21); + + Stream.Write(prompt.Serial); // TODO: Does this value even matter? + Stream.Write(prompt.Serial); + Stream.Write(0); + Stream.Write(0); + Stream.Write((short)0); + } + } +} diff --git a/Projects/Server/Network/Packets/OldPackets/VendorBuyPackets.cs b/Projects/Server/Network/Packets/Old Packets/VendorBuyPackets.cs similarity index 89% rename from Projects/Server/Network/Packets/OldPackets/VendorBuyPackets.cs rename to Projects/Server/Network/Packets/Old Packets/VendorBuyPackets.cs index dd53964c3..7d1c24a7a 100644 --- a/Projects/Server/Network/Packets/OldPackets/VendorBuyPackets.cs +++ b/Projects/Server/Network/Packets/Old Packets/VendorBuyPackets.cs @@ -109,9 +109,20 @@ namespace Server.Network var desc = bis.Description ?? ""; + // TODO: Test if this is actually WriteAsciiFixed and the extra null doesn't matter. Stream.Write((byte)(desc.Length + 1)); Stream.WriteAsciiNull(desc); } } } + + public sealed class EndVendorBuy : Packet + { + public EndVendorBuy(Mobile vendor) : base(0x3B, 8) + { + Stream.Write((ushort)8); // length + Stream.Write(vendor.Serial); + Stream.Write((byte)0); + } + } } diff --git a/Projects/Server/Network/Packets/Old Packets/VendorSellPackets.cs b/Projects/Server/Network/Packets/Old Packets/VendorSellPackets.cs new file mode 100644 index 000000000..e0ac8ab8c --- /dev/null +++ b/Projects/Server/Network/Packets/Old Packets/VendorSellPackets.cs @@ -0,0 +1,61 @@ +/************************************************************************* + * ModernUO * + * Copyright (C) 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: VendorSellPackets.cs * + * Created: 2020/05/07 - Updated: 2020/05/07 * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System.Collections.Generic; + +namespace Server.Network +{ + public sealed class VendorSellList : Packet + { + public VendorSellList(Mobile shopkeeper, List sis) : base(0x9E) + { + EnsureCapacity(256); + + Stream.Write(shopkeeper.Serial); + + Stream.Write((ushort)sis.Count); + + foreach (var state in sis) + { + Stream.Write(state.Item.Serial); + Stream.Write((ushort)state.Item.ItemID); + Stream.Write((ushort)state.Item.Hue); + Stream.Write((ushort)state.Item.Amount); + Stream.Write((ushort)state.Price); + + var name = string.IsNullOrWhiteSpace(state.Item.Name) ? state.Name ?? "" : state.Item.Name.Trim(); + + Stream.Write((ushort)name.Length); + Stream.WriteAsciiFixed(name, (ushort)name.Length); + } + } + } + + public sealed class EndVendorSell : Packet + { + public EndVendorSell(Mobile vendor) : base(0x3B, 8) + { + Stream.Write((ushort)8); // length + Stream.Write(vendor.Serial); + Stream.Write((byte)0); + } + } +} diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index bf6baba94..0034d8262 100644 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -17,8 +17,8 @@ x64 8.0 $(SolutionDir)\Distribution - + + true true diff --git a/Tools/publish.cmd b/Tools/publish.cmd index 626770478..6be1b99d9 100755 --- a/Tools/publish.cmd +++ b/Tools/publish.cmd @@ -2,7 +2,6 @@ dotnet clean :<<"::SHELLSCRIPT" @ECHO OFF GOTO :CMDSCRIPT - ::SHELLSCRIPT Tools/build-native-libraries.cmd @@ -15,33 +14,34 @@ fi if [[ $1 ]] then - o="-r $1-x64" + r="-r $1-x64" else if [[ $(uname) = "Darwin" ]] then - o="-r osx-x64" + r="-r osx-x64" else - o="-r linux-x64" + r="-r linux-x64" fi fi -echo dotnet publish ${c} ${o} --self-contained=false -dotnet publish ${c} ${o} --self-contained=false +dotnet publish Projects/Server/Server.csproj ${c} ${r} --self-contained=false -o Distribution +dotnet publish Projects/Scripts/Scripts.csproj ${c} ${r} --self-contained=false -o Distribution/Assemblies exit $? :CMDSCRIPT -Tools\build-native-libraries.cmd +CALL Tools\build-native-libraries.cmd IF "%~2" == "" ( - SET c = "-c Release" + SET c =-c Release ) ELSE ( - SET c = "-c %~2" + SET c =-c %~2 ) -IF "%~1" != "" ( - SET o = "-r %~1-x64" +IF NOT "%~1" == "" ( + SET r =-r %~1-x64 ) ELSE ( - SET o = "-r win-x64" + SET r =-r win-x64 ) -dotnet publish %c% %o% --self-contained=false +dotnet publish Projects\Server\Server.csproj %c% %r% --self-contained=false -o Distribution +dotnet publish Projects\Scripts\Scripts.csproj %c% %r% --self-contained=false -o Distribution\Assemblies