diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 000000000..e5a7001db
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,12 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "modernuoschemagenerator": {
+ "version": "2.1.4",
+ "commands": [
+ "ModernUOSchemaGenerator"
+ ]
+ }
+ }
+}
diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml
index cf746c82e..bfc63eaa8 100644
--- a/.github/workflows/build-test.yml
+++ b/.github/workflows/build-test.yml
@@ -14,19 +14,19 @@ jobs:
fail-fast: false
matrix:
include:
- - os: macos-latest
- name: MacOS 10
- os: macos-11
name: MacOS 11
+ - os: macos-12
+ name: MacOS 12
steps:
- 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.300
- name: Build
run: ./publish.cmd
- name: Test
diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml
index f08889d15..7be14200d 100644
--- a/.github/workflows/create-release.yml
+++ b/.github/workflows/create-release.yml
@@ -3,6 +3,7 @@ name: Create Release
on:
repository_dispatch:
types: [release]
+ workflow_dispatch:
jobs:
release:
@@ -30,7 +31,11 @@ jobs:
git checkout ${{ steps.last_release.outputs.release }}
git tag -fa v0.1.0 -m "Fake release"
git checkout -
- git push --follow-tags
+ - name: Push git changes
+ uses: ad-m/github-push-action@master
+ with:
+ GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
+ tags: true
- name: Conventional Changelog
id: changelog
uses: TriPSs/conventional-changelog-action@v3
@@ -55,7 +60,7 @@ jobs:
delete_release: true
tag_name: v0.1.0
env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
- name: Create Release
id: create_release
uses: actions/create-release@v1
diff --git a/.github/workflows/update-docs.yml b/.github/workflows/update-docs.yml
index ccd2c2280..62b080225 100644
--- a/.github/workflows/update-docs.yml
+++ b/.github/workflows/update-docs.yml
@@ -3,6 +3,7 @@ name: Updates Docs
on:
repository_dispatch:
types: [docs]
+ workflow_dispatch:
jobs:
update-docs:
diff --git a/.gitignore b/.gitignore
index 325476c99..ae6dbf334 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,4 @@
.DS_Store
/packages/*
+/Distribution/Configuration/server-access.json
diff --git a/Directory.Build.props b/Directory.Build.props
index 0ac231599..5b23e4a72 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -4,14 +4,14 @@
Kamron Batman
ModernUO
2019-2020
- net5.0
+ net6.0
x64
x64
preview
true
true
NU1603
- win-x64;debian.10-x64;debian.9-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;rhel.7-x64;rhel.8-x64;osx-x64
+ win-x64;debian.10-x64;debian.11-x64;ubuntu.16.04-x64;ubuntu.18.04-x64;ubuntu.20.04-x64;centos.7-x64;centos.8-x64;fedora.32-x64;fedora.33-x64;fedora.34-x64;rhel.7-x64;rhel.8-x64;linuxmint.17-x64;linuxmint.18-x64;linuxmint.19-x64;osx-x64
Debug;Release;Analyze
false
true
@@ -28,6 +28,7 @@
NO_LOCAL_INIT
MUO
$(SolutionDir)
+ false
true
@@ -54,13 +55,13 @@
latest
-
+
-
+
- 3.4.240
+ 3.5.107
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/Distribution/Data/Decoration/Britannia/bucs.cfg b/Distribution/Data/Decoration/Britannia/bucs.cfg
index deda623cf..1b9cfa84f 100644
--- a/Distribution/Data/Decoration/Britannia/bucs.cfg
+++ b/Distribution/Data/Decoration/Britannia/bucs.cfg
@@ -10,56 +10,6 @@ Static 0x051F
Static 0x0520
2669 2073 -20
-# stone
-Static 0x071E
-2726 2133 0
-2727 2131 0
-2727 2131 5
-2727 2131 10
-2727 2131 15
-2727 2131 20
-2727 2131 25
-2727 2132 0
-2727 2132 30
-2727 2133 0
-2727 2133 30
-2727 2133 35
-2727 2134 0
-2727 2134 30
-2727 2135 0
-2727 2135 5
-2727 2135 10
-2727 2135 15
-2727 2135 20
-2727 2135 25
-2728 2133 0
-
-# stone stairs
-Static 0x071F
-2727 2134 35
-2727 2135 30
-
-# stone stairs
-Static 0x0737
-2727 2131 30
-2727 2132 35
-
-# stone stairs
-Static 0x07A0
-2726 2132 0
-
-# stone stairs
-Static 0x07A1
-2728 2134 0
-
-# stone stairs
-Static 0x07A2
-2728 2132 0
-
-# stone stairs
-Static 0x07DA
-2726 2134 0
-
# bottle of ale
BeverageBottle 0x099F (Content=Ale)
2659 2187 8
@@ -719,4 +669,4 @@ GlassMug 0x1F81
# glass of water
GlassMug 0x1F91 (Content=Water)
-2679 2233 4
\ No newline at end of file
+2679 2233 4
diff --git a/Distribution/Data/Decoration/Britannia/wind.cfg b/Distribution/Data/Decoration/Britannia/wind.cfg
index 695d46747..93746ee8a 100644
--- a/Distribution/Data/Decoration/Britannia/wind.cfg
+++ b/Distribution/Data/Decoration/Britannia/wind.cfg
@@ -770,4 +770,4 @@ Static 0x1F3C
# Arch Cure
Static 0x1F45
-5304 88 19
\ No newline at end of file
+5304 88 19
diff --git a/Distribution/Data/categorization.json b/Distribution/Data/categorization.json
index 6eff0b152..4ddec6a0a 100644
--- a/Distribution/Data/categorization.json
+++ b/Distribution/Data/categorization.json
@@ -3337,7 +3337,6 @@
{ "type": "DiseasedCat" },
{ "type": "Doppleganger" },
{ "type": "Drithen" },
- { "type": "DummyThief" },
{ "type": "Efreet" },
{ "type": "ElderAbbein" },
{ "type": "ElderAcob" },
@@ -3630,19 +3629,6 @@
{ "type": "SeaSerpent" }
]
},
- {
- "category": "Mobiles.Dummies",
- "objects": [
- { "type": "DummyAssassin" },
- { "type": "DummyFence" },
- { "type": "DummyHealer" },
- { "type": "DummyMace" },
- { "type": "DummyNox" },
- { "type": "DummyStun" },
- { "type": "DummySuper" },
- { "type": "DummySword" }
- ]
- },
{
"category": "Mobiles.Escortables",
"objects": [
@@ -3682,8 +3668,7 @@
{
"category": "Mobiles.Uncategorized",
"objects": [
- { "type": "TownCrier" },
- { "type": "Wanderer" }
+ { "type": "TownCrier" }
]
},
{
diff --git a/Distribution/Data/expansion.json b/Distribution/Data/expansion.json
index e0b036f61..a89041813 100644
--- a/Distribution/Data/expansion.json
+++ b/Distribution/Data/expansion.json
@@ -4,7 +4,6 @@
"ClientVersion": null,
"ClientFlags": null,
"FeatureFlags": {
- "None": true,
"T2A": false,
"UOR": false,
"UOTD": false,
@@ -13,7 +12,7 @@
"SixthCharacterSlot": false,
"SE": false,
"ML": false,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": false,
"TenthAge": false,
"IncreasedStorage": false,
@@ -31,7 +30,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": true,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -50,7 +48,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": true,
"AOS": false,
"SE": false,
"ML": false,
@@ -70,7 +67,6 @@
"ClientVersion": null,
"ClientFlags": "Felucca",
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": false,
"UOTD": false,
@@ -79,7 +75,7 @@
"SixthCharacterSlot": false,
"SE": false,
"ML": false,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": false,
"TenthAge": false,
"IncreasedStorage": false,
@@ -97,7 +93,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -116,7 +111,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": true,
"AOS": false,
"SE": false,
"ML": false,
@@ -136,7 +130,6 @@
"ClientVersion": null,
"ClientFlags": "Trammel",
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": true,
"UOTD": false,
@@ -145,7 +138,7 @@
"SixthCharacterSlot": false,
"SE": false,
"ML": false,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": false,
"TenthAge": false,
"IncreasedStorage": false,
@@ -163,7 +156,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -182,7 +174,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": true,
"AOS": false,
"SE": false,
"ML": false,
@@ -202,7 +193,6 @@
"ClientVersion": null,
"ClientFlags": "Ilshenar",
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": true,
"UOTD": true,
@@ -211,7 +201,7 @@
"SixthCharacterSlot": false,
"SE": false,
"ML": false,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": false,
"TenthAge": false,
"IncreasedStorage": false,
@@ -229,7 +219,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -248,7 +237,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": true,
"AOS": false,
"SE": false,
"ML": false,
@@ -268,7 +256,6 @@
"ClientVersion": null,
"ClientFlags": "Ilshenar",
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": true,
"UOTD": true,
@@ -277,7 +264,7 @@
"SixthCharacterSlot": false,
"SE": false,
"ML": false,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": false,
"TenthAge": false,
"IncreasedStorage": false,
@@ -295,7 +282,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -314,7 +300,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": true,
"AOS": false,
"SE": false,
"ML": false,
@@ -334,16 +319,15 @@
"ClientVersion": null,
"ClientFlags": "Malas",
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": true,
- "UOTD": true,
+ "UOTD": false,
"LBR": true,
"AOS": true,
"SixthCharacterSlot": false,
"SE": false,
"ML": false,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": false,
"TenthAge": false,
"IncreasedStorage": false,
@@ -361,7 +345,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -380,7 +363,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": false,
"AOS": true,
"SE": false,
"ML": false,
@@ -400,16 +382,15 @@
"ClientVersion": null,
"ClientFlags": "Tokuno",
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": true,
- "UOTD": true,
+ "UOTD": false,
"LBR": true,
"AOS": true,
"SixthCharacterSlot": false,
"SE": true,
"ML": false,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": false,
"TenthAge": false,
"IncreasedStorage": false,
@@ -427,7 +408,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -446,7 +426,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": false,
"AOS": true,
"SE": true,
"ML": false,
@@ -466,16 +445,15 @@
"ClientVersion": "5.0.0a",
"ClientFlags": null,
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": true,
- "UOTD": true,
+ "UOTD": false,
"LBR": true,
"AOS": true,
"SixthCharacterSlot": false,
"SE": true,
"ML": true,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": true,
"TenthAge": false,
"IncreasedStorage": false,
@@ -493,7 +471,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -512,7 +489,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": false,
"AOS": true,
"SE": true,
"ML": true,
@@ -532,16 +508,15 @@
"ClientVersion": null,
"ClientFlags": "TerMur",
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": true,
- "UOTD": true,
+ "UOTD": false,
"LBR": true,
"AOS": true,
"SixthCharacterSlot": false,
"SE": true,
"ML": true,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": true,
"TenthAge": false,
"IncreasedStorage": false,
@@ -559,7 +534,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -578,7 +552,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": false,
"AOS": true,
"SE": true,
"ML": true,
@@ -598,16 +571,15 @@
"ClientVersion": "7.0.9.0",
"ClientFlags": null,
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": true,
- "UOTD": true,
+ "UOTD": false,
"LBR": true,
"AOS": true,
"SixthCharacterSlot": false,
"SE": true,
"ML": true,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": true,
"TenthAge": false,
"IncreasedStorage": false,
@@ -625,7 +597,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -644,7 +615,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": false,
"AOS": true,
"SE": true,
"ML": true,
@@ -664,16 +634,15 @@
"ClientVersion": "7.0.45.65",
"ClientFlags": null,
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": true,
- "UOTD": true,
+ "UOTD": false,
"LBR": true,
"AOS": true,
"SixthCharacterSlot": false,
"SE": true,
"ML": true,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": true,
"TenthAge": false,
"IncreasedStorage": false,
@@ -691,7 +660,6 @@
"EJ": false
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -710,7 +678,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": false,
"AOS": true,
"SE": true,
"ML": true,
@@ -730,16 +697,15 @@
"ClientVersion": "7.0.61.0",
"ClientFlags": null,
"FeatureFlags": {
- "None": false,
"T2A": true,
"UOR": true,
- "UOTD": true,
+ "UOTD": false,
"LBR": true,
"AOS": true,
"SixthCharacterSlot": false,
"SE": true,
"ML": true,
- "EigthAge": false,
+ "EighthAge": false,
"NinthAge": true,
"TenthAge": false,
"IncreasedStorage": false,
@@ -757,7 +723,6 @@
"EJ": true
},
"CharacterListFlags": {
- "None": false,
"Unk1": false,
"OverwriteConfigButton": false,
"OneCharacterSlot": false,
@@ -776,7 +741,6 @@
"NewFeluccaAreas": false
},
"HousingFlags": {
- "None": false,
"AOS": true,
"SE": true,
"ML": true,
diff --git a/Distribution/Data/npc-speeds.json b/Distribution/Data/npc-speeds.json
new file mode 100644
index 000000000..5ea8371ae
--- /dev/null
+++ b/Distribution/Data/npc-speeds.json
@@ -0,0 +1,148 @@
+[
+ {
+ "name": "Slow",
+ "active": 0.3,
+ "passive": 0.6,
+ "types": [
+ "AntLion", "ArcticOgreLord", "BogThing",
+ "Bogle", "BoneKnight", "EarthElemental",
+ "Ettin", "FrostOoze", "FrostTroll",
+ "GazerLarva", "Ghoul", "Golem",
+ "HeadlessOne", "Jwilson", "Mummy",
+ "Ogre", "OgreLord", "PlagueBeast",
+ "Quagmire", "Rat", "RottingCorpse",
+ "SewerRat", "Skeleton", "Slime",
+ "Zombie", "Walrus", "RestlessSoul",
+ "CrystalElemental", "DarknightCreeper", "MoundOfMaggots",
+ "Juggernaut", "Yamandon", "Serado",
+ "GreaterDragon", "PlagueBeastLord"
+ ]
+ },
+ {
+ "name": "Medium",
+ "active": 0.25,
+ "passive": 0.5,
+ "types": [
+ "AcidElemental", "AgapiteElemental", "Alligator",
+ "AncientLich", "Betrayer", "Bird",
+ "BlackBear", "BlackSolenInfiltratorQueen", "BlackSolenInfiltratorWarrior",
+ "BlackSolenQueen", "BlackSolenWarrior", "BlackSolenWorker",
+ "BloodElemental", "Boar", "Bogling",
+ "BoneMagi", "Brigand", "BronzeElemental",
+ "BrownBear", "Bull", "BullFrog",
+ "Cat", "Centaur", "ChaosDaemon",
+ "Chicken", "GolemController", "CopperElemental",
+ "CopperElemental", "Cougar", "Cow",
+ "Cyclops", "Daemon", "DeepSeaSerpent",
+ "DesertOstard", "DireWolf", "Dog",
+ "Dolphin", "Dragon", "Drake",
+ "DullCopperElemental", "Eagle", "ElderGazer",
+ "EvilMage", "EvilMageLord", "Executioner",
+ "Savage", "FireElemental", "FireGargoyle",
+ "FireSteed", "ForestOstard", "FrenziedOstard",
+ "FrostSpider", "Gargoyle", "Gazer",
+ "IceSerpent", "GiantRat", "GiantSerpent",
+ "GiantSpider", "GiantToad", "Goat",
+ "GoldenElemental", "Gorilla", "GreatHart",
+ "GreyWolf", "GrizzlyBear", "Guardian",
+ "Harpy", "Harrower", "HellHound",
+ "Hind", "HordeMinion", "Horse",
+ "Horse", "IceElemental", "IceFiend",
+ "IceSnake", "Imp", "JackRabbit",
+ "Kirin", "Kraken", "PredatorHellCat",
+ "LavaLizard", "LavaSerpent", "LavaSnake",
+ "Lizardman", "Llama", "Mongbat",
+ "StrongMongbat", "MountainGoat", "Orc",
+ "OrcBomber", "OrcBrute", "OrcCaptain",
+ "OrcishLord", "OrcishMage", "PackHorse",
+ "PackLlama", "Panther", "Pig",
+ "PlagueSpawn", "PolarBear", "Rabbit",
+ "Ratman", "RatmanArcher", "RatmanMage",
+ "RedSolenInfiltratorQueen", "RedSolenInfiltratorWarrior", "RedSolenQueen",
+ "RedSolenWarrior", "RedSolenWorker", "RidableLlama",
+ "Ridgeback", "Scorpion", "SeaSerpent",
+ "SerpentineDragon", "Shade", "ShadowIronElemental",
+ "ShadowWisp", "ShadowWyrm", "Sheep",
+ "SilverSteed", "SkeletalDragon", "SkeletalMage",
+ "SkeletalMount", "HellCat", "Snake",
+ "SnowLeopard", "SpectralArmour", "Spectre",
+ "StoneGargoyle", "StoneHarpy", "SwampDragon",
+ "ScaledSwampDragon", "SwampTentacle", "TerathanAvenger",
+ "TerathanDrone", "TerathanMatriarch", "TerathanWarrior",
+ "TimberWolf", "Titan", "Troll",
+ "Unicorn", "ValoriteElemental", "VeriteElemental",
+ "CoMWarHorse", "MinaxWarHorse", "SLWarHorse",
+ "TBWarHorse", "WaterElemental", "WhippingVine",
+ "WhiteWolf", "Wraith", "Wyvern",
+ "KhaldunZealot", "KhaldunSummoner", "SavageRidgeback",
+ "LichLord", "SkeletalKnight", "SummonedDaemon",
+ "SummonedEarthElemental", "SummonedWaterElemental", "SummonedFireElemental",
+ "MeerWarrior", "MeerEternal", "MeerMage",
+ "MeerCaptain", "JukaLord", "JukaMage",
+ "JukaWarrior", "AbysmalHorror", "BoneDemon",
+ "Devourer", "FleshGolem", "Gibberling",
+ "GoreFiend", "Impaler", "PatchworkSkeleton",
+ "Ravager", "ShadowKnight", "SkitteringHopper",
+ "Treefellow", "VampireBat", "WailingBanshee",
+ "WandererOfTheVoid", "Cursed", "GrimmochDrummel",
+ "LysanderGathenwale", "MorgBergen", "ShadowFiend",
+ "SpectralArmour", "TavaraSewel", "ArcaneDaemon",
+ "Doppleganger", "EnslavedGargoyle", "ExodusMinion",
+ "ExodusOverseer", "GargoyleDestroyer", "GargoyleEnforcer",
+ "Moloch", "BakeKitsune", "DeathwatchBeetleHatchling",
+ "Kappa", "KazeKemono", "DeathwatchBeetle",
+ "TsukiWolf", "YomotsuElder", "YomotsuPriest",
+ "YomotsuWarrior", "RevenantLion", "Oni",
+ "Gaman", "Crane", "Beetle",
+ "Parrot", "ElfBrigand", "GreaterMongbat",
+ "AnimatedWeapon", "Reaper", "Corpser"
+ ]
+ },
+ {
+ "name": "Fast",
+ "active": 0.2,
+ "passive": 0.4,
+ "types": [
+ "LordOaks", "Silvani", "AirElemental",
+ "AncientWyrm", "Balron", "BladeSpirits",
+ "DreadSpider", "Efreet", "EtherealWarrior",
+ "Lich", "Nightmare", "OphidianArchmage",
+ "OphidianMage", "OphidianWarrior", "OphidianMatriarch",
+ "OphidianKnight", "PoisonElemental",
+ "SandVortex", "SavageRider", "SavageShaman",
+ "SnowElemental", "WhiteWyrm", "Wisp",
+ "DemonKnight", "GiantBlackWidow", "SummonedAirElemental",
+ "LesserHiryu", "Hiryu", "LadyOfTheSnow",
+ "RaiJu", "Ronin", "RuneBeetle",
+ "Changeling", "LadyJennifyr", "LadyMarai", "MasterJonath",
+ "MasterMikael", "MasterTheophilus", "RedDeath",
+ "SirPatrick", "Miasma", "Rend",
+ "Grobu", "Gnaw", "Guile",
+ "Irk", "Spite", "LadyLissith",
+ "LadySabrix", "Malefic", "Silk",
+ "Virulent", "SeaHorse", "UnholyFamiliar",
+ "HolyFamiliar", "GiantIceWorm", "Phoenix",
+ "Succubus", "EnragedRabbit", "EnragedHind",
+ "EnragedHart", "EnragedBlackBear", "EnragedEagle",
+ "RagingGrizzlyBear", "CorrosiveSlime", "DarkWisp",
+ "DarkGuardian", "HarrowerTentacles", "ServantOfSemidar",
+ "Reptalon"
+ ]
+ },
+ {
+ "name": "Very Fast",
+ "active": 0.175,
+ "passive": 0.35,
+ "types": [
+ "Barracoon", "Mephitis", "Neira",
+ "Rikktor", "Semidar", "EnergyVortex",
+ "EliteNinja", "Pixie", "SilverSerpent",
+ "VorpalBunny", "FleshRenderer", "KhaldunRevenant",
+ "FactionDragoon", "FactionKnight", "FactionPaladin",
+ "FactionHenchman", "FactionMercenary", "FactionNecromancer",
+ "FactionSorceress", "FactionWizard", "FactionBerserker",
+ "FactionPaladin", "Leviathan", "FireBeetle",
+ "FanDancer", "FactionDeathKnight", "Revenant"
+ ]
+ }
+]
diff --git a/Distribution/Data/teleporters.json b/Distribution/Data/teleporters.json
index 82a4fe684..91e70eb0b 100644
--- a/Distribution/Data/teleporters.json
+++ b/Distribution/Data/teleporters.json
@@ -40,9 +40,9 @@
"back": true
},
{
- "src": { "map": "Felucca", "loc": [589, 1637, 0] },
- "dst": { "map": "Felucca", "loc": [6575, 888, 0] },
- "back": false
+ "src": { "map": "Felucca", "loc": [588, 1637, 0] },
+ "dst": { "map": "Felucca", "loc": [6472, 868, 26] },
+ "back": true
},
{
"src": { "map": "Felucca", "loc": [766, 1645, 0] },
@@ -2054,16 +2054,6 @@
"dst": { "map": "Felucca", "loc": [6503, 88, 0] },
"back": false
},
- {
- "src": { "map": "Felucca", "loc": [6488, 849, 40] },
- "dst": { "map": "Felucca", "loc": [6587, 867, 0] },
- "back": false
- },
- {
- "src": { "map": "Felucca", "loc": [6488, 850, 41] },
- "dst": { "map": "Felucca", "loc": [6587, 868, 0] },
- "back": false
- },
{
"src": { "map": "Felucca", "loc": [6540, 116, -15] },
"dst": { "map": "Felucca", "loc": [6537, 138, -20] },
@@ -2085,13 +2075,8 @@
"back": false
},
{
- "src": { "map": "Felucca", "loc": [6574, 889, 0] },
- "dst": { "map": "Felucca", "loc": [6472, 869, 20] },
- "back": false
- },
- {
- "src": { "map": "Felucca", "loc": [6575, 889, 0] },
- "dst": { "map": "Felucca", "loc": [6473, 869, 20] },
+ "src": { "map": "Felucca", "loc": [6477, 860, 9] },
+ "dst": { "map": "Felucca", "loc": [6574, 889, 0] },
"back": false
},
{
@@ -2116,7 +2101,7 @@
},
{
"src": { "map": "Felucca", "loc": [6588, 867, 0] },
- "dst": { "map": "Felucca", "loc": [6489, 849, 39] },
+ "dst": { "map": "Felucca", "loc": [6488, 849, 40] },
"back": false
},
{
@@ -2220,8 +2205,13 @@
"back": true
},
{
- "src": { "map": "Trammel", "loc": [589, 1637, 0] },
- "dst": { "map": "Trammel", "loc": [6575, 888, 0] },
+ "src": { "map": "Trammel", "loc": [588, 1637, 0] },
+ "dst": { "map": "Trammel", "loc": [6472, 868, 26] },
+ "back": true
+ },
+ {
+ "src": { "map": "Trammel", "loc": [6477, 860, 9] },
+ "dst": { "map": "Trammel", "loc": [6574, 889, 0] },
"back": false
},
{
@@ -4179,16 +4169,6 @@
"dst": { "map": "Trammel", "loc": [6503, 88, 0] },
"back": false
},
- {
- "src": { "map": "Trammel", "loc": [6488, 849, 40] },
- "dst": { "map": "Trammel", "loc": [6587, 867, 0] },
- "back": false
- },
- {
- "src": { "map": "Trammel", "loc": [6488, 850, 41] },
- "dst": { "map": "Trammel", "loc": [6587, 868, 0] },
- "back": false
- },
{
"src": { "map": "Trammel", "loc": [6540, 116, -15] },
"dst": { "map": "Trammel", "loc": [6537, 138, -20] },
@@ -4209,16 +4189,6 @@
"dst": { "map": "Trammel", "loc": [6576, 73, 0] },
"back": false
},
- {
- "src": { "map": "Trammel", "loc": [6574, 889, 0] },
- "dst": { "map": "Trammel", "loc": [6472, 869, 20] },
- "back": false
- },
- {
- "src": { "map": "Trammel", "loc": [6575, 889, 0] },
- "dst": { "map": "Trammel", "loc": [6473, 869, 20] },
- "back": false
- },
{
"src": { "map": "Trammel", "loc": [6577, 159, 13] },
"dst": { "map": "Trammel", "loc": [6577, 177, 30] },
@@ -4241,7 +4211,7 @@
},
{
"src": { "map": "Trammel", "loc": [6588, 867, 0] },
- "dst": { "map": "Trammel", "loc": [6489, 849, 39] },
+ "dst": { "map": "Trammel", "loc": [6488, 849, 40] },
"back": false
},
{
diff --git a/ModernUO.sln b/ModernUO.sln
index 75eb761a4..92647cca4 100644
--- a/ModernUO.sln
+++ b/ModernUO.sln
@@ -10,12 +10,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server.Tests", "Projects\Se
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UOContent.Tests", "Projects\UOContent.Tests\UOContent.Tests.csproj", "{3C4797F9-603E-44EF-8E8C-9275CC9EA74B}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Projects\Benchmarks\Benchmarks.csproj", "{38B7E4A1-FDDD-486C-98EE-BA7B13712528}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializationGenerator", "Projects\SerializationGenerator\SerializationGenerator.csproj", "{07DDB8CF-F926-44F4-A584-FF2997D2C9D0}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializationSchemaGenerator", "Projects\SerializationSchemaGenerator\SerializationSchemaGenerator.csproj", "{A30150A3-796C-4C6D-B3E4-B7BEB0021701}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Analyze|x64 = Analyze|x64
@@ -47,24 +41,6 @@ Global
{3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Debug|x64.Build.0 = Debug|x64
{3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Release|x64.ActiveCfg = Release|x64
{3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Release|x64.Build.0 = Release|x64
- {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Analyze|x64.ActiveCfg = Release|x64
- {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Analyze|x64.Build.0 = Release|x64
- {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Debug|x64.ActiveCfg = Debug|x64
- {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Debug|x64.Build.0 = Debug|x64
- {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.ActiveCfg = Release|x64
- {38B7E4A1-FDDD-486C-98EE-BA7B13712528}.Release|x64.Build.0 = Release|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Analyze|x64.ActiveCfg = Analyze|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Analyze|x64.Build.0 = Analyze|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Debug|x64.ActiveCfg = Debug|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Debug|x64.Build.0 = Debug|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Release|x64.ActiveCfg = Release|x64
- {07DDB8CF-F926-44F4-A584-FF2997D2C9D0}.Release|x64.Build.0 = Release|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Analyze|x64.ActiveCfg = Analyze|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Analyze|x64.Build.0 = Analyze|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Debug|x64.ActiveCfg = Debug|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Debug|x64.Build.0 = Debug|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Release|x64.ActiveCfg = Release|x64
- {A30150A3-796C-4C6D-B3E4-B7BEB0021701}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Projects/Benchmarks/Benchmarks.csproj b/Projects/Benchmarks/Benchmarks.csproj
deleted file mode 100644
index 2ed8e89fd..000000000
--- a/Projects/Benchmarks/Benchmarks.csproj
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- Exe
- net5.0
- x64
- x64
- 9
- true
- true
-
-
-
-
-
-
-
diff --git a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs b/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs
deleted file mode 100644
index 1414c571e..000000000
--- a/Projects/Benchmarks/Benchmarks/Collections/BenchmarkOrderedHashSet.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-using System.Collections.Generic;
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Server.Collections;
-
-namespace Benchmarks
-{
- [MemoryDiagnoser]
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class BenchmarkOrderedHashSet
- {
- private readonly string[] _iterations = new string[16];
-
- [IterationSetup]
- public void IterationSetup()
- {
- for (var i = 0; i < _iterations.Length; i++)
- {
- _iterations[i] = i.ToString();
- }
- }
-
- [Benchmark]
- public int UsingList()
- {
- var list = new List();
- for (int i = 0; i < _iterations.Length / 2; i++)
- {
- AddIfNotPresent(list, _iterations[i]);
- }
-
- for (int i = 0; i < _iterations.Length; i++)
- {
- AddIfNotPresent(list, _iterations[i]);
- }
-
- for (int i = 0; i < list.Count; i++)
- {
- list[i].ToString();
- }
-
- return list.Count;
- }
-
- private static int AddIfNotPresent(List list, T item)
- {
- var index = list.IndexOf(item);
- if (index > -1)
- {
- return index;
- }
-
- list.Add(item);
- return list.Count - 1;
- }
-
- [Benchmark]
- public int UsingOrderedHashSet()
- {
- var ordered = new OrderedHashSet();
- for (int i = 0; i < _iterations.Length / 2; i++)
- {
- ordered.GetOrAdd(_iterations[i]).ToString();
- }
-
- for (int i = 0; i < _iterations.Length; i++)
- {
- ordered.GetOrAdd(_iterations[i]).ToString();
- }
-
- foreach (var str in ordered)
- {
- str.ToString();
- }
-
- return ordered.Count;
- }
-
- [Benchmark]
- public int UsingPooledOrderedHashSet()
- {
- var ordered = new PooledOrderedHashSet();
- for (int i = 0; i < _iterations.Length / 2; i++)
- {
- ordered.GetOrAdd(_iterations[i]).ToString();
- }
-
- for (int i = 0; i < _iterations.Length; i++)
- {
- ordered.GetOrAdd(_iterations[i]).ToString();
- }
-
- foreach (var str in ordered)
- {
- str.ToString();
- }
-
- return ordered.Count;
- }
-
- [Benchmark]
- public int UsingHashSet()
- {
- var hashSet = new HashSet<(string, int)>(new OrderedStringComparer());
- for (int i = 0; i < _iterations.Length / 2; i++)
- {
- hashSet.Add((_iterations[i], i));
- }
-
- for (int i = 0; i < _iterations.Length; i++)
- {
- hashSet.Add((_iterations[i], i));
- }
-
- foreach (var str in hashSet)
- {
- str.ToString();
- }
-
- return hashSet.Count;
- }
-
- private class OrderedStringComparer : EqualityComparer<(string, int)>
- {
- public override bool Equals((string, int) x, (string, int) y) => x.Item1.Equals(y.Item1, System.StringComparison.Ordinal);
-
- public override int GetHashCode((string, int) obj) => obj.Item1.GetHashCode();
- }
- }
-}
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
deleted file mode 100644
index 62bc428fa..000000000
--- a/Projects/Benchmarks/Benchmarks/Logging/BenchmarkConsoleLogging.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System;
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Serilog;
-using Serilog.Core;
-
-namespace Benchmarks
-{
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class BenchmarkConsoleLogging
- {
- private const string text = "Sample message";
-
- private Logger logger;
- private Logger asyncLogger;
-
- [GlobalSetup]
- public void GlobalSetup()
- {
- logger = new LoggerConfiguration()
- .WriteTo.Console()
- .CreateLogger();
-
- asyncLogger = new LoggerConfiguration()
- .WriteTo.Async(a => a.Console())
- .CreateLogger();
- }
-
- [GlobalCleanup]
- public void GlobalCleanup()
- {
- logger = null;
- asyncLogger = null;
- }
-
- [Benchmark]
- public void TestConsoleWriteLine()
- {
- for (int i = 0; i < 10000; i++)
- {
- Console.WriteLine(text);
- }
- }
-
- [Benchmark]
- public void TestSerilogConsoleSink()
- {
- for (int i = 0; i < 10000; i++)
- {
- logger.Information(text);
- }
- }
-
- [Benchmark]
- public void TestSerilogAsyncConsoleSink()
- {
- for (int i = 0; i < 10000; i++)
- {
- asyncLogger.Information(text);
- }
- }
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs
deleted file mode 100644
index 0225af652..000000000
--- a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkOutgoingGumpPacket.cs
+++ /dev/null
@@ -1,173 +0,0 @@
-using System;
-using System.Buffers;
-using System.IO;
-using System.IO.Compression;
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Server.Collections;
-using Server.Gumps;
-using Server.Network;
-using Server.Tests.Network;
-
-namespace Benchmarks
-{
- [MemoryDiagnoser]
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class OutgoingGumpPacketBenchmarks
- {
- private static readonly byte[] _layoutBuffer = GC.AllocateUninitializedArray(0x20000);
- private static readonly byte[] _stringsBuffer = GC.AllocateUninitializedArray(0x20000);
-
- public static void CreateDisplayGump(Gump gump, out int switches, out int entries)
- {
- switches = 0;
- entries = 0;
-
- const bool packed = false;
-
- var layoutWriter = new SpanWriter(_layoutBuffer);
-
- if (!gump.Draggable)
- {
- layoutWriter.Write(Gump.NoMove);
- }
-
- if (!gump.Closable)
- {
- layoutWriter.Write(Gump.NoClose);
- }
-
- if (!gump.Disposable)
- {
- layoutWriter.Write(Gump.NoDispose);
- }
-
- if (!gump.Resizable)
- {
- layoutWriter.Write(Gump.NoResize);
- }
-
- var stringsList = new OrderedHashSet(32);
-
- foreach (var entry in gump.Entries)
- {
- entry.AppendTo(ref layoutWriter, stringsList, ref entries, ref switches);
- }
-
- var stringsWriter = new SpanWriter(_stringsBuffer);
-
- foreach (var str in stringsList)
- {
- var s = str ?? "";
- stringsWriter.Write((ushort)s.Length);
- stringsWriter.WriteBigUni(s);
- }
-
- int maxLength;
- if (packed)
- {
- var worstLayoutLength = Zlib.MaxPackSize(layoutWriter.BytesWritten);
- var worstStringsLength = Zlib.MaxPackSize(stringsWriter.BytesWritten);
- maxLength = 40 + worstLayoutLength + worstStringsLength;
- }
- else
- {
- maxLength = 23 + layoutWriter.BytesWritten + stringsWriter.BytesWritten;
- }
-
- var writer = new SpanWriter(maxLength);
- writer.Write((byte)(packed ? 0xDD : 0xB0)); // Packet ID
- writer.Seek(2, SeekOrigin.Current);
-
- writer.Write(gump.Serial);
- writer.Write(gump.TypeID);
- writer.Write(gump.X);
- writer.Write(gump.Y);
-
- if (packed)
- {
- layoutWriter.Write((byte)0); // Layout text terminator
- OutgoingGumpPackets.WritePacked(layoutWriter.Span, ref writer);
-
- writer.Write(stringsList.Count);
- OutgoingGumpPackets.WritePacked(stringsWriter.Span, ref writer);
- }
- else
- {
- writer.Write((ushort)layoutWriter.BytesWritten);
- writer.Write(layoutWriter.Span);
-
- writer.Write((ushort)stringsList.Count);
- writer.Write(stringsWriter.Span);
- }
-
- writer.WritePacketLength();
-
- layoutWriter.Dispose(); // Just in case
- stringsWriter.Dispose(); // Just in case
- }
-
- public class NameChangeDeedGump : Gump
- {
- public NameChangeDeedGump() : base(50, 50)
- {
- Closable = false;
- Draggable = false;
- Resizable = false;
-
- AddPage(0);
-
- AddBlackAlpha(10, 120, 250, 85);
- AddHtml(10, 125, 250, 20, Color(Center("Name Change Deed"), 0xFFFFFF));
-
- AddLabel(73, 15, 1152, "");
- AddLabel(20, 150, 0x480, "New Name:");
- AddTextField(100, 150, 150, 20, 0);
-
- AddButtonLabeled(75, 180, 1, "Submit");
- }
-
- public void AddBlackAlpha(int x, int y, int width, int height)
- {
- AddImageTiled(x, y, width, height, 2624);
- AddAlphaRegion(x, y, width, height);
- }
-
- public void AddTextField(int x, int y, int width, int height, int index)
- {
- AddBackground(x - 2, y - 2, width + 4, height + 4, 0x2486);
- AddTextEntry(x + 2, y + 2, width - 4, height - 4, 0, index, "");
- }
-
- public static string Center(string text) => $"{text}";
-
- public static string Color(string text, int color) => $"{text}";
-
- public void AddButtonLabeled(int x, int y, int buttonID, string text)
- {
- AddButton(x, y - 1, 4005, 4007, buttonID);
- AddHtml(x + 35, y, 240, 20, Color(text, 0xFFFFFF));
- }
- }
-
- private static Gump _gump;
-
- [GlobalSetup]
- public void Setup()
- {
- _gump = new NameChangeDeedGump();
- }
-
- [Benchmark]
- public void TestNewStack()
- {
- CreateDisplayGump(_gump, out var _, out var _);
- }
-
- [Benchmark]
- public void TestOldStack()
- {
- _gump.Compile().Compile(false, out var _);
- }
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs b/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs
deleted file mode 100644
index 2535dca0f..000000000
--- a/Projects/Benchmarks/Benchmarks/Packets/BenchmarkPacketBroadcast.cs
+++ /dev/null
@@ -1,174 +0,0 @@
-using System;
-using System.Buffers;
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Server;
-using Server.Network;
-
-namespace Benchmarks
-{
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class BenchmarkPacketBroadcast
- {
- public static int SendUnicodeMessage(
- ArraySegment[] buffer,
- Serial serial, int graphic, MessageType type, int hue, int font, string lang, string name, string text
- )
- {
- name = name?.Trim() ?? "";
- text = text?.Trim() ?? "";
- lang = lang?.Trim() ?? "ENU";
-
- if (hue == 0)
- {
- hue = 0x3B2;
- }
-
- var writer = new CircularBufferWriter(buffer);
- writer.Write((byte)0xAE);
- writer.Write((ushort)(50 + text.Length * 2));
- writer.Write(serial.Value);
- writer.Write((short)graphic);
- writer.Write((byte)type);
- writer.Write((short)hue);
- writer.Write((short)font);
- writer.WriteAscii(lang, 4);
- writer.WriteAscii(name, 30);
- writer.WriteBigUniNull(text);
-
- return writer.Position;
- }
-
- public static int CreateUnicodeMessage(
- Span buffer,
- Serial serial, int graphic, MessageType type, int hue, int font, string lang, string name, string text
- )
- {
- name = name?.Trim() ?? "";
- text = text?.Trim() ?? "";
- lang = lang?.Trim() ?? "ENU";
-
- if (hue == 0)
- {
- hue = 0x3B2;
- }
-
- var writer = new SpanWriter(buffer);
- writer.Write((byte)0xAE);
- writer.Write((ushort)(50 + text.Length * 2));
- writer.Write(serial);
- writer.Write((short)graphic);
- writer.Write((byte)type);
- writer.Write((short)hue);
- writer.Write((short)font);
- writer.WriteAscii(lang, 4);
- writer.WriteAscii(name, 30);
- writer.WriteBigUniNull(text);
-
- return writer.Position;
- }
-
- private Pipe[] _pipes = new Pipe[25000];
-
- [IterationSetup]
- public void SetUp()
- {
- for (var i = 0; i < _pipes.Length; i++)
- {
- _pipes[i] = new Pipe(new byte[4096]);
- }
- }
-
- [IterationCleanup]
- public void CleanUp()
- {
- for (var i = 0; i < _pipes.Length; i++)
- {
- _pipes[i] = null;
- }
- }
-
- [Benchmark]
- public int TestCircularBuffer()
- {
- var text = "This is some really long text that we want to handle. It should take a little bit to encode this.";
- foreach (var pipe in _pipes)
- {
- var result = pipe.Writer.TryGetMemory();
- var length = SendUnicodeMessage(
- result.Buffer,
- Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text
- );
- pipe.Writer.Advance((uint)length);
- }
-
- return _pipes.Length;
- }
-
- [Benchmark]
- public int TestSpanWriterFromBuffer()
- {
- var text = "This is some really long text that we want to handle. It should take a little bit to encode this.";
- foreach (var pipe in _pipes)
- {
- var result = pipe.Writer.TryGetMemory();
-
- Span buffer = result.Buffer[0];
-
- var length = CreateUnicodeMessage(
- buffer, Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text
- );
- pipe.Writer.Advance((uint)length);
- }
-
- return _pipes.Length;
- }
-
- [Benchmark]
- public int TestSpanWriter()
- {
- var text = "This is some really long text that we want to handle. It should take a little bit to encode this.";
- Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(text)];
- var length = CreateUnicodeMessage(
- buffer, Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text
- );
-
- buffer = buffer[..length];
-
- foreach (var pipe in _pipes)
- {
- var result = pipe.Writer.TryGetMemory();
- result.CopyFrom(buffer);
- pipe.Writer.Advance((uint)buffer.Length);
- }
-
- return _pipes.Length;
- }
-
- private static void SendUnicodeMessageWithSpan(Pipe pipe, string text)
- {
- Span buffer = stackalloc byte[OutgoingMessagePackets.GetMaxMessageLength(text)];
- var length = CreateUnicodeMessage(
- buffer, Serial.MinusOne, -1, MessageType.Regular, 0x3B2, 3, "ENU", "System", text
- );
-
- buffer = buffer[..length];
- var result = pipe.Writer.TryGetMemory();
- result.CopyFrom(buffer);
- pipe.Writer.Advance((uint)buffer.Length);
- }
-
- [Benchmark]
- public int TestSpanWriterLooped()
- {
- var text = "This is some really long text that we want to handle. It should take a little bit to encode this.";
-
- foreach (var pipe in _pipes)
- {
- SendUnicodeMessageWithSpan(pipe, text);
- }
-
- return _pipes.Length;
- }
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/Packets/GumpPackets.cs b/Projects/Benchmarks/Benchmarks/Packets/GumpPackets.cs
deleted file mode 100644
index 74888fd37..000000000
--- a/Projects/Benchmarks/Benchmarks/Packets/GumpPackets.cs
+++ /dev/null
@@ -1,315 +0,0 @@
-using System.Buffers;
-using System.Collections.Generic;
-using System.IO;
-using System.IO.Compression;
-using System.Text;
-using Server.Gumps;
-using Server.Network;
-
-namespace Server.Tests
-{
- public interface IGumpWriter
- {
- int TextEntries { get; set; }
- int Switches { get; set; }
-
- void AppendLayout(bool val);
- void AppendLayout(int val);
- void AppendLayout(uint val);
- void AppendLayout(Serial serial);
- void AppendLayoutNS(int val);
- void AppendLayout(string text);
- void AppendLayoutNS(string text);
- void AppendLayout(byte[] buffer);
- void WriteStrings(List strings);
- void Flush();
- }
-
- public sealed class CloseGump : Packet
- {
- public CloseGump(int typeID, int buttonID) : base(0xBF)
- {
- EnsureCapacity(13);
-
- Stream.Write((short)0x04);
- Stream.Write(typeID);
- Stream.Write(buttonID);
- }
- }
-
- public sealed class DisplayGumpPacked : Packet, IGumpWriter
- {
- private static readonly byte[] m_True = Gump.StringToBuffer(" 1");
- private static readonly byte[] m_False = Gump.StringToBuffer(" 0");
-
- private static readonly byte[] m_BeginTextSeparator = Gump.StringToBuffer(" @");
- private static readonly byte[] m_EndTextSeparator = Gump.StringToBuffer("@");
-
- private static readonly byte[] m_Buffer = new byte[48];
-
- private readonly Gump m_Gump;
-
- private readonly PacketWriter m_Layout;
- private readonly PacketWriter m_Strings;
-
- private int m_StringCount;
-
- static DisplayGumpPacked() => m_Buffer[0] = (byte)' ';
-
- public DisplayGumpPacked(Gump gump)
- : base(0xDD)
- {
- m_Gump = gump;
-
- m_Layout = PacketWriter.CreateInstance(8192);
- m_Strings = PacketWriter.CreateInstance(8192);
- }
-
- public int TextEntries { get; set; }
-
- public int Switches { get; set; }
-
- public void AppendLayout(bool val)
- {
- AppendLayout(val ? m_True : m_False);
- }
-
- public void AppendLayout(int val)
- {
- var toString = val.ToString();
- var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1;
-
- m_Layout.Write(m_Buffer, 0, bytes);
- }
-
- public void AppendLayout(uint val)
- {
- var toString = val.ToString();
- var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1;
-
- m_Layout.Write(m_Buffer, 0, bytes);
- }
-
- public void AppendLayout(Serial serial) => AppendLayout(serial.Value);
-
- public void AppendLayoutNS(int val)
- {
- var toString = val.ToString();
- var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1);
-
- m_Layout.Write(m_Buffer, 1, bytes);
- }
-
- public void AppendLayoutNS(string text)
- {
- m_Layout.WriteAsciiFixed(text, text.Length);
- }
-
- public void AppendLayout(string text)
- {
- AppendLayout(m_BeginTextSeparator);
-
- m_Layout.WriteAsciiFixed(text, text.Length);
-
- AppendLayout(m_EndTextSeparator);
- }
-
- public void AppendLayout(byte[] buffer)
- {
- m_Layout.Write(buffer, 0, buffer.Length);
- }
-
- public void WriteStrings(List strings)
- {
- m_StringCount = strings.Count;
-
- for (var i = 0; i < strings.Count; ++i)
- {
- var v = strings[i] ?? "";
-
- m_Strings.Write((ushort)v.Length);
- m_Strings.WriteBigUniFixed(v, v.Length);
- }
- }
-
- public void Flush()
- {
- EnsureCapacity(28 + (int)m_Layout.Length + (int)m_Strings.Length);
-
- Stream.Write(m_Gump.Serial);
- Stream.Write(m_Gump.TypeID);
- Stream.Write(m_Gump.X);
- Stream.Write(m_Gump.Y);
-
- // Note: layout MUST be null terminated (don't listen to krrios)
- m_Layout.Write((byte)0);
-
- WritePacked(m_Layout);
-
- Stream.Write(m_StringCount);
-
- WritePacked(m_Strings);
-
- PacketWriter.ReleaseInstance(m_Layout);
- PacketWriter.ReleaseInstance(m_Strings);
- }
-
- private void WritePacked(PacketWriter src)
- {
- var buffer = src.UnderlyingStream.GetBuffer();
- var length = (int)src.Length;
-
- if (length == 0)
- {
- Stream.Write(0);
- return;
- }
-
- var wantLength = 1 + length * 1024 / 1000;
-
- wantLength += 4095;
- wantLength &= ~4095;
-
- var packBuffer = ArrayPool.Shared.Rent(wantLength);
-
- var packLength = wantLength;
-
- Zlib.Pack(packBuffer, ref packLength, buffer, length, ZlibQuality.Default);
-
- Stream.Write(4 + packLength);
- Stream.Write(length);
- Stream.Write(packBuffer, 0, packLength);
-
- ArrayPool.Shared.Return(packBuffer);
- }
- }
-
- public sealed class DisplayGumpFast : Packet, IGumpWriter
- {
- private static readonly byte[] m_True = Gump.StringToBuffer(" 1");
- private static readonly byte[] m_False = Gump.StringToBuffer(" 0");
-
- private static readonly byte[] m_BeginTextSeparator = Gump.StringToBuffer(" @");
- private static readonly byte[] m_EndTextSeparator = Gump.StringToBuffer("@");
-
- private readonly byte[] m_Buffer = new byte[48];
- private int m_LayoutLength;
-
- public DisplayGumpFast(Gump g) : base(0xB0)
- {
- m_Buffer[0] = (byte)' ';
-
- EnsureCapacity(4096);
-
- Stream.Write(g.Serial);
- Stream.Write(g.TypeID);
- Stream.Write(g.X);
- Stream.Write(g.Y);
- Stream.Write((ushort)0xFFFF);
- }
-
- public int TextEntries { get; set; }
-
- public int Switches { get; set; }
-
- public void AppendLayout(bool val)
- {
- AppendLayout(val ? m_True : m_False);
- }
-
- public void AppendLayout(int val)
- {
- var toString = val.ToString();
- var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1;
-
- Stream.Write(m_Buffer, 0, bytes);
- m_LayoutLength += bytes;
- }
-
- public void AppendLayout(uint val)
- {
- var toString = val.ToString();
- var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1) + 1;
-
- Stream.Write(m_Buffer, 0, bytes);
- m_LayoutLength += bytes;
- }
-
- public void AppendLayout(Serial serial) => AppendLayout(serial.Value);
-
- public void AppendLayoutNS(int val)
- {
- var toString = val.ToString();
- var bytes = Encoding.ASCII.GetBytes(toString, 0, toString.Length, m_Buffer, 1);
-
- Stream.Write(m_Buffer, 1, bytes);
- m_LayoutLength += bytes;
- }
-
- public void AppendLayoutNS(string text)
- {
- var length = text.Length;
- Stream.WriteAsciiFixed(text, length);
- m_LayoutLength += length;
- }
-
- public void AppendLayout(string text)
- {
- AppendLayout(m_BeginTextSeparator);
-
- var length = text.Length;
- Stream.WriteAsciiFixed(text, length);
- m_LayoutLength += length;
-
- AppendLayout(m_EndTextSeparator);
- }
-
- public void AppendLayout(byte[] buffer)
- {
- var length = buffer.Length;
- Stream.Write(buffer, 0, length);
- m_LayoutLength += length;
- }
-
- public void WriteStrings(List text)
- {
- Stream.Seek(19, SeekOrigin.Begin);
- Stream.Write((ushort)m_LayoutLength);
- Stream.Seek(0, SeekOrigin.End);
-
- Stream.Write((ushort)text.Count);
-
- for (var i = 0; i < text.Count; ++i)
- {
- var v = text[i] ?? "";
-
- int length = (ushort)v.Length;
-
- Stream.Write((ushort)length);
- Stream.WriteBigUniFixed(v, length);
- }
- }
-
- public void Flush()
- {
- }
- }
-
- public sealed class DisplaySignGump : Packet
- {
- public DisplaySignGump(Serial serial, int gumpID, string unknown, string caption) : base(0x8B)
- {
- unknown ??= "";
- caption ??= "";
-
- EnsureCapacity(15 + unknown.Length + caption.Length);
-
- Stream.Write(serial);
- Stream.Write((short)gumpID);
- Stream.Write((short)(unknown.Length + 1));
- Stream.WriteAsciiNull(unknown);
- Stream.Write((short)(caption.Length + 1));
- Stream.WriteAsciiNull(caption);
- }
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/Packets/GumpUtilities.cs b/Projects/Benchmarks/Benchmarks/Packets/GumpUtilities.cs
deleted file mode 100644
index 5df0a12fe..000000000
--- a/Projects/Benchmarks/Benchmarks/Packets/GumpUtilities.cs
+++ /dev/null
@@ -1,476 +0,0 @@
-using System.Collections.Generic;
-using Server.Gumps;
-using Server.Network;
-
-namespace Server.Tests.Network
-{
- public static class GumpUtilities
- {
- private static readonly byte[] m_BeginLayout = Gump.StringToBuffer("{ ");
- private static readonly byte[] m_EndLayout = Gump.StringToBuffer(" }");
-
- public static Packet Compile(this Gump g, NetState ns = null)
- {
- IGumpWriter disp = new DisplayGumpFast(g);
- // IGumpWriter disp = new DisplayGumpPacked(g);
-
- if (!g.Draggable)
- {
- disp.AppendLayout(Gump.NoMove);
- }
-
- if (!g.Closable)
- {
- disp.AppendLayout(Gump.NoClose);
- }
-
- if (!g.Disposable)
- {
- disp.AppendLayout(Gump.NoDispose);
- }
-
- if (!g.Resizable)
- {
- disp.AppendLayout(Gump.NoResize);
- }
-
- var count = g.Entries.Count;
- var strings = new List();
-
- for (var i = 0; i < count; ++i)
- {
- var e = g.Entries[i];
-
- disp.AppendLayout(m_BeginLayout);
- e.AppendToByType(disp, strings);
- disp.AppendLayout(m_EndLayout);
- }
-
- disp.WriteStrings(strings);
-
- disp.Flush();
-
- return (Packet)disp;
- }
-
- public static int Intern(this List strings, string value)
- {
- var indexOf = strings.IndexOf(value);
-
- if (indexOf >= 0)
- {
- return indexOf;
- }
-
- strings.Add(value);
- return strings.Count - 1;
- }
-
- public static void AppendToByType(this GumpEntry e, IGumpWriter disp, List strings)
- {
- switch (e)
- {
- case GumpAlphaRegion g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpBackground g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpButton g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpCheck g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpGroup g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpECHandleInput g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpHtml g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpHtmlLocalized g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpImage g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpImageTileButton g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpImageTiled g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpItem g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpItemProperty g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpLabel g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpLabelCropped g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpMasterGump g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpPage g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpRadio g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpSpriteImage g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpTextEntry g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpTextEntryLimited g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- case GumpTooltip g:
- {
- g.AppendTo(disp, strings);
- break;
- }
- }
- }
-
- public static void AppendTo(this GumpAlphaRegion g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpAlphaRegion.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- }
-
- public static void AppendTo(this GumpBackground g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpBackground.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.GumpID);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- }
-
- public static void AppendTo(this GumpButton g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpButton.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.NormalID);
- disp.AppendLayout(g.PressedID);
- disp.AppendLayout((int)g.Type);
- disp.AppendLayout(g.Param);
- disp.AppendLayout(g.ButtonID);
- }
-
- public static void AppendTo(this GumpCheck g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpButton.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.InactiveID);
- disp.AppendLayout(g.ActiveID);
- disp.AppendLayout(g.InitialState);
- disp.AppendLayout(g.SwitchID);
-
- disp.Switches++;
- }
-
- public static void AppendTo(this GumpGroup g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpGroup.LayoutName);
- disp.AppendLayout(g.Group);
- }
-
- public static void AppendTo(this GumpECHandleInput g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpECHandleInput.LayoutName);
- }
-
- public static void AppendTo(this GumpHtml g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpHtml.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- disp.AppendLayout(strings.Intern(g.Text));
- disp.AppendLayout(g.Background);
- disp.AppendLayout(g.Scrollbar);
- }
-
- public static void AppendTo(this GumpHtmlLocalized g, IGumpWriter disp, List strings)
- {
- switch (g.Type)
- {
- case GumpHtmlLocalizedType.Plain:
- {
- disp.AppendLayout(GumpHtmlLocalized.LayoutNamePlain);
-
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- disp.AppendLayout(g.Number);
- disp.AppendLayout(g.Background);
- disp.AppendLayout(g.Scrollbar);
-
- break;
- }
-
- case GumpHtmlLocalizedType.Color:
- {
- disp.AppendLayout(GumpHtmlLocalized.LayoutNameColor);
-
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- disp.AppendLayout(g.Number);
- disp.AppendLayout(g.Background);
- disp.AppendLayout(g.Scrollbar);
- disp.AppendLayout(g.Color);
-
- break;
- }
-
- case GumpHtmlLocalizedType.Args:
- {
- disp.AppendLayout(GumpHtmlLocalized.LayoutNameArgs);
-
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- disp.AppendLayout(g.Background);
- disp.AppendLayout(g.Scrollbar);
- disp.AppendLayout(g.Color);
- disp.AppendLayout(g.Number);
- disp.AppendLayout(g.Args);
-
- break;
- }
- }
- }
-
- public static void AppendTo(this GumpImage g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpImage.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.GumpID);
-
- if (g.Hue != 0)
- {
- disp.AppendLayout(GumpImage.HueEquals);
- disp.AppendLayoutNS(g.Hue);
- }
-
- if (!string.IsNullOrEmpty(g.Class))
- {
- disp.AppendLayout(GumpImage.ClassEquals);
- disp.AppendLayoutNS(g.Class);
- }
- }
-
- public static void AppendTo(this GumpImageTileButton g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpImageTileButton.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.NormalID);
- disp.AppendLayout(g.PressedID);
- disp.AppendLayout((int)g.Type);
- disp.AppendLayout(g.Param);
- disp.AppendLayout(g.ButtonID);
-
- disp.AppendLayout(g.ItemID);
- disp.AppendLayout(g.Hue);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
-
- if (g.LocalizedTooltip > 0)
- {
- disp.AppendLayout(GumpImageTileButton.LayoutTooltip);
- disp.AppendLayout(g.LocalizedTooltip);
- }
- }
-
- public static void AppendTo(this GumpImageTiled g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpImageTiled.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- disp.AppendLayout(g.GumpID);
- }
-
- public static void AppendTo(this GumpItem g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(g.Hue == 0 ? GumpItem.LayoutName : GumpItem.LayoutNameHue);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.ItemID);
-
- if (g.Hue != 0)
- {
- disp.AppendLayout(g.Hue);
- }
- }
-
- public static void AppendTo(this GumpItemProperty g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpItemProperty.LayoutName);
- disp.AppendLayout(g.Serial);
- }
-
- public static void AppendTo(this GumpLabel g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpLabel.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.Hue);
- disp.AppendLayout(strings.Intern(g.Text));
- }
-
- public static void AppendTo(this GumpLabelCropped g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpLabelCropped.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- disp.AppendLayout(g.Hue);
- disp.AppendLayout(strings.Intern(g.Text));
- }
-
- public static void AppendTo(this GumpMasterGump g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpMasterGump.LayoutName);
- disp.AppendLayout(g.GumpID);
- }
-
- public static void AppendTo(this GumpPage g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpPage.LayoutName);
- disp.AppendLayout(g.Page);
- }
-
- public static void AppendTo(this GumpRadio g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpRadio.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.InactiveID);
- disp.AppendLayout(g.ActiveID);
- disp.AppendLayout(g.InitialState);
- disp.AppendLayout(g.SwitchID);
-
- disp.Switches++;
- }
-
- public static void AppendTo(this GumpSpriteImage g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpSpriteImage.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.GumpID);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- disp.AppendLayout(g.SX);
- disp.AppendLayout(g.SY);
- }
-
- public static void AppendTo(this GumpTextEntry g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpTextEntry.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- disp.AppendLayout(g.Hue);
- disp.AppendLayout(g.EntryID);
- disp.AppendLayout(strings.Intern(g.InitialText));
-
- disp.TextEntries++;
- }
-
- public static void AppendTo(this GumpTextEntryLimited g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpTextEntryLimited.LayoutName);
- disp.AppendLayout(g.X);
- disp.AppendLayout(g.Y);
- disp.AppendLayout(g.Width);
- disp.AppendLayout(g.Height);
- disp.AppendLayout(g.Hue);
- disp.AppendLayout(g.EntryID);
- disp.AppendLayout(strings.Intern(g.InitialText));
- disp.AppendLayout(g.Size);
-
- disp.TextEntries++;
- }
-
- public static void AppendTo(this GumpTooltip g, IGumpWriter disp, List strings)
- {
- disp.AppendLayout(GumpTooltip.LayoutName);
- disp.AppendLayout(g.Number);
-
- if (!string.IsNullOrEmpty(g.Args))
- {
- disp.AppendLayout(g.Args);
- }
- }
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/Packets/Packet.cs b/Projects/Benchmarks/Benchmarks/Packets/Packet.cs
deleted file mode 100644
index 7b634fcce..000000000
--- a/Projects/Benchmarks/Benchmarks/Packets/Packet.cs
+++ /dev/null
@@ -1,265 +0,0 @@
-using System;
-using System.Buffers;
-using System.Diagnostics;
-using System.IO;
-using Server.Diagnostics;
-
-namespace Server.Network
-{
- public abstract class Packet
- {
- private const int CompressorBufferSize = 0x10000;
-
- private readonly int m_Length;
-
- private byte[] m_CompiledBuffer;
- private int m_CompiledLength;
- private State m_State;
-
- protected Packet(int packetID)
- {
- PacketID = packetID;
-
- if (Core.Profiling)
- {
- var prof = PacketSendProfile.Acquire(PacketID);
- prof.Increment();
- }
- }
-
- protected Packet(int packetID, int length)
- {
- PacketID = packetID;
- m_Length = length;
-
- Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length );
- Stream.Write((byte)packetID);
-
- if (Core.Profiling)
- {
- var prof = PacketSendProfile.Acquire(PacketID);
- prof.Increment();
- }
- }
-
- public int PacketID { get; }
-
- public PacketWriter Stream { get; protected set; }
-
- public void EnsureCapacity(int length)
- {
- Stream = PacketWriter.CreateInstance(length); // new PacketWriter( length );
- Stream.Write((byte)PacketID);
- Stream.Write((short)0);
- }
-
- public static Packet SetStatic(Packet p)
- {
- p.SetStatic();
- return p;
- }
-
- public static Packet Acquire(Packet p)
- {
- p.Acquire();
- return p;
- }
-
- public static void Release(ref Packet p)
- {
- p?.Release();
- p = null;
- }
-
- public static void Release(Packet p)
- {
- p?.Release();
- }
-
- public void SetStatic()
- {
- m_State |= State.Static | State.Acquired;
- }
-
- public void Acquire()
- {
- m_State |= State.Acquired;
- }
-
- public void OnSend()
- {
- if ((m_State & (State.Acquired | State.Static)) == 0)
- {
- Free();
- }
- }
-
- private void Free()
- {
- if (m_CompiledBuffer == null)
- {
- return;
- }
-
- if ((m_State & State.Buffered) != 0)
- {
- ArrayPool.Shared.Return(m_CompiledBuffer);
- }
-
- m_State &= ~(State.Static | State.Acquired | State.Buffered);
-
- m_CompiledBuffer = null;
- }
-
- public void Release()
- {
- if ((m_State & State.Acquired) != 0)
- {
- Free();
- }
- }
-
- private readonly object _object = new();
-
- public byte[] Compile(bool compress, out int length)
- {
- lock (_object)
- {
- if (m_CompiledBuffer == null)
- {
- if ((m_State & State.Accessed) == 0)
- {
- m_State |= State.Accessed;
- }
- else
- {
- if ((m_State & State.Warned) == 0)
- {
- m_State |= State.Warned;
-
- try
- {
- using var op = new StreamWriter("net_opt.log", true);
- op.WriteLine("Redundant compile for packet {0}, use Acquire() and Release()", GetType());
- op.WriteLine(new StackTrace());
- }
- catch
- {
- // ignored
- }
- }
-
- m_CompiledBuffer = Array.Empty();
- m_CompiledLength = 0;
-
- length = m_CompiledLength;
- return m_CompiledBuffer;
- }
-
- InternalCompile(compress);
- }
-
- length = m_CompiledLength;
- return m_CompiledBuffer;
- }
- }
-
- private void InternalCompile(bool compress)
- {
- if (m_Length == 0)
- {
- var streamLen = Stream.Length;
-
- Stream.Seek(1, SeekOrigin.Begin);
- Stream.Write((ushort)streamLen);
- }
- else if (Stream.Length != m_Length)
- {
- var diff = (int)Stream.Length - m_Length;
-
- Console.WriteLine(
- "Packet: 0x{0:X2}: Bad packet length! ({1}{2} bytes)",
- PacketID,
- diff >= 0 ? "+" : "",
- diff
- );
- }
-
- var ms = Stream.UnderlyingStream;
-
- m_CompiledBuffer = ms.GetBuffer();
- var length = (int)ms.Length;
-
- if (compress)
- {
- var compressorBuffer = new byte[CompressorBufferSize];
- var compressedLength = NetworkCompression.Compress(m_CompiledBuffer.AsSpan(0, length), compressorBuffer);
-
- if (length <= 0)
- {
- Console.WriteLine(
- "Warning: Compression buffer overflowed on packet 0x{0:X2} ('{1}') (length={2})",
- PacketID,
- GetType().Name,
- length
- );
- using var op = new StreamWriter("compression_overflow.log", true);
- op.WriteLine(
- "{0} Warning: Compression buffer overflowed on packet 0x{1:X2} ('{2}') (length={3})",
- Core.Now,
- PacketID,
- GetType().Name,
- length
- );
- op.WriteLine(new StackTrace());
- }
- else
- {
- m_CompiledBuffer = compressorBuffer;
- m_CompiledLength = compressedLength;
- }
- }
- else
- {
- m_CompiledLength = length;
- }
-
- if (m_CompiledLength > 0)
- {
- var old = m_CompiledBuffer;
-
- if ((m_State & State.Static) != 0)
- {
- m_CompiledBuffer = new byte[m_CompiledLength];
- }
- else
- {
- // Release it later using Release()
- m_CompiledBuffer = ArrayPool.Shared.Rent(m_CompiledLength);
- m_State |= State.Buffered;
- }
-
- Buffer.BlockCopy(old, 0, m_CompiledBuffer, 0, m_CompiledLength);
-
- if (compress)
- {
- ArrayPool.Shared.Return(old);
- }
- }
-
- PacketWriter.ReleaseInstance(Stream);
- Stream = null;
- }
-
- [Flags]
- private enum State
- {
- Inactive = 0x00,
- Static = 0x01,
- Acquired = 0x02,
- Accessed = 0x04,
- Buffered = 0x08,
- Warned = 0x10
- }
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/Packets/PacketTestUtilities.cs b/Projects/Benchmarks/Benchmarks/Packets/PacketTestUtilities.cs
deleted file mode 100644
index e7a01619f..000000000
--- a/Projects/Benchmarks/Benchmarks/Packets/PacketTestUtilities.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System;
-using System.Buffers.Binary;
-using System.Runtime.CompilerServices;
-using Server;
-using Server.Network;
-
-namespace Benchmarks
-{
- public static class PacketTestUtilities
- {
- public static Span Compile(this Packet p) =>
- p.Compile(false, out var length).AsSpan(0, length);
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void Write(this Span data, ref int pos, Serial serial)
- {
- BinaryPrimitives.WriteUInt32BigEndian(data.Slice(pos, 4), serial.Value);
- pos += 4;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void Write(this Span data, ref int pos, ushort value)
- {
- BinaryPrimitives.WriteUInt16BigEndian(data.Slice(pos, 2), value);
- pos += 2;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void Write(this Span data, ref int pos, byte value) => data[pos++] = value;
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/Packets/PacketWriter.cs b/Projects/Benchmarks/Benchmarks/Packets/PacketWriter.cs
deleted file mode 100644
index 696dbc7e8..000000000
--- a/Projects/Benchmarks/Benchmarks/Packets/PacketWriter.cs
+++ /dev/null
@@ -1,354 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.IO;
-using System.Text;
-
-namespace Server.Network
-{
- ///
- /// Provides functionality for writing primitive binary data.
- ///
- public class PacketWriter
- {
- private static readonly ConcurrentQueue m_Pool = new();
-
- ///
- /// Internal format buffer.
- ///
- private readonly byte[] m_Buffer = new byte[4];
-
- private int m_Capacity;
-
- ///
- /// Instantiates a new PacketWriter instance with a given capacity.
- ///
- /// Initial capacity for the internal stream.
- public PacketWriter(int capacity = 32)
- {
- UnderlyingStream = new MemoryStream(capacity);
- m_Capacity = capacity;
- }
-
- ///
- /// Gets the total stream length.
- ///
- public long Length => UnderlyingStream.Length;
-
- ///
- /// Gets or sets the current stream position.
- ///
- public long Position
- {
- get => UnderlyingStream.Position;
- set => UnderlyingStream.Position = value;
- }
-
- ///
- /// The internal stream used by this PacketWriter instance.
- ///
- public MemoryStream UnderlyingStream { get; }
-
- public static PacketWriter CreateInstance(int capacity = 32)
- {
- if (m_Pool.TryDequeue(out var pw))
- {
- pw.m_Capacity = capacity;
- pw.UnderlyingStream.SetLength(0);
- return pw;
- }
-
- return new PacketWriter(capacity);
- }
-
- public static void ReleaseInstance(PacketWriter pw)
- {
- m_Pool.Enqueue(pw);
- }
-
- ///
- /// Writes a 1-byte boolean value to the underlying stream. False is represented by 0, true by 1.
- ///
- public void Write(bool value)
- {
- UnderlyingStream.WriteByte((byte)(value ? 1 : 0));
- }
-
- ///
- /// Writes a 1-byte unsigned integer value to the underlying stream.
- ///
- public void Write(byte value)
- {
- UnderlyingStream.WriteByte(value);
- }
-
- ///
- /// Writes a 1-byte signed integer value to the underlying stream.
- ///
- public void Write(sbyte value)
- {
- UnderlyingStream.WriteByte((byte)value);
- }
-
- ///
- /// Writes a 2-byte signed integer value to the underlying stream.
- ///
- public void Write(short value)
- {
- m_Buffer[0] = (byte)(value >> 8);
- m_Buffer[1] = (byte)value;
-
- UnderlyingStream.Write(m_Buffer, 0, 2);
- }
-
- ///
- /// Writes a 2-byte unsigned integer value to the underlying stream.
- ///
- public void Write(ushort value)
- {
- m_Buffer[0] = (byte)(value >> 8);
- m_Buffer[1] = (byte)value;
-
- UnderlyingStream.Write(m_Buffer, 0, 2);
- }
-
- public void Write(Serial serial) => Write(serial.Value);
-
- ///
- /// Writes a 4-byte signed integer value to the underlying stream.
- ///
- public void Write(int value)
- {
- m_Buffer[0] = (byte)(value >> 24);
- m_Buffer[1] = (byte)(value >> 16);
- m_Buffer[2] = (byte)(value >> 8);
- m_Buffer[3] = (byte)value;
-
- UnderlyingStream.Write(m_Buffer, 0, 4);
- }
-
- ///
- /// Writes a 4-byte unsigned integer value to the underlying stream.
- ///
- public void Write(uint value)
- {
- m_Buffer[0] = (byte)(value >> 24);
- m_Buffer[1] = (byte)(value >> 16);
- m_Buffer[2] = (byte)(value >> 8);
- m_Buffer[3] = (byte)value;
-
- UnderlyingStream.Write(m_Buffer, 0, 4);
- }
-
- ///
- /// Writes a sequence of bytes to the underlying stream
- ///
- public void Write(byte[] buffer, int offset, int size)
- {
- UnderlyingStream.Write(buffer, offset, size);
- }
-
- ///
- /// Writes a fixed-length ASCII-encoded string value to the underlying stream. To fit (size), the string content is either
- /// truncated or padded with null characters.
- ///
- public void WriteAsciiFixed(string value, int size)
- {
- if (value == null)
- {
- Console.WriteLine("Network: Attempted to WriteAsciiFixed() with null value");
- value = string.Empty;
- }
-
- var length = value.Length;
-
- UnderlyingStream.SetLength(UnderlyingStream.Length + size);
-
- if (length >= size)
- {
- UnderlyingStream.Position +=
- Encoding.ASCII.GetBytes(value, 0, size, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position);
- }
- else
- {
- Encoding.ASCII.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position);
- UnderlyingStream.Position += size;
- }
- }
-
- ///
- /// Writes a dynamic-length ASCII-encoded string value to the underlying stream, followed by a 1-byte null character.
- ///
- public void WriteAsciiNull(string value)
- {
- if (value == null)
- {
- Console.WriteLine("Network: Attempted to WriteAsciiNull() with null value");
- value = string.Empty;
- }
-
- var length = value.Length;
-
- UnderlyingStream.SetLength(UnderlyingStream.Length + length + 1);
-
- Encoding.ASCII.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position);
- UnderlyingStream.Position += length + 1;
- }
-
- ///
- /// Writes a dynamic-length little-endian unicode string value to the underlying stream, followed by a 2-byte null
- /// character.
- ///
- public void WriteLittleUniNull(string value)
- {
- if (value == null)
- {
- Console.WriteLine("Network: Attempted to WriteLittleUniNull() with null value");
- value = string.Empty;
- }
-
- var length = value.Length;
-
- UnderlyingStream.SetLength(UnderlyingStream.Length + (length + 1) * 2);
-
- UnderlyingStream.Position +=
- Encoding.Unicode.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position);
- UnderlyingStream.Position += 2;
- }
-
- ///
- /// Writes a fixed-length little-endian unicode string value to the underlying stream. To fit (size), the string content is
- /// either truncated or padded with null characters.
- ///
- public void WriteLittleUniFixed(string value, int size)
- {
- if (value == null)
- {
- Console.WriteLine("Network: Attempted to WriteLittleUniFixed() with null value");
- value = string.Empty;
- }
-
- var length = value.Length;
- size *= 2;
-
- UnderlyingStream.SetLength(UnderlyingStream.Length + size);
-
- if (length * 2 >= size)
- {
- UnderlyingStream.Position +=
- Encoding.Unicode.GetBytes(
- value,
- 0,
- size / 2,
- UnderlyingStream.GetBuffer(),
- (int)UnderlyingStream.Position
- );
- }
- else
- {
- Encoding.Unicode.GetBytes(value, 0, length, UnderlyingStream.GetBuffer(), (int)UnderlyingStream.Position);
- UnderlyingStream.Position += size;
- }
- }
-
- ///
- /// Writes a dynamic-length big-endian unicode string value to the underlying stream, followed by a 2-byte null character.
- ///
- public void WriteBigUniNull(string value)
- {
- if (value == null)
- {
- Console.WriteLine("Network: Attempted to WriteBigUniNull() with null value");
- value = string.Empty;
- }
-
- var length = value.Length;
-
- UnderlyingStream.SetLength(UnderlyingStream.Length + (length + 1) * 2);
-
- UnderlyingStream.Position +=
- Encoding.BigEndianUnicode.GetBytes(
- value,
- 0,
- length,
- UnderlyingStream.GetBuffer(),
- (int)UnderlyingStream.Position
- );
- UnderlyingStream.Position += 2;
- }
-
- ///
- /// Writes a fixed-length big-endian unicode string value to the underlying stream. To fit (size), the string content is
- /// either truncated or padded with null characters.
- ///
- public void WriteBigUniFixed(string value, int size)
- {
- if (value == null)
- {
- Console.WriteLine("Network: Attempted to WriteBigUniFixed() with null value");
- value = string.Empty;
- }
-
- var length = value.Length;
- size *= 2;
-
- UnderlyingStream.SetLength(UnderlyingStream.Length + size);
-
- if (length * 2 >= size)
- {
- UnderlyingStream.Position +=
- Encoding.BigEndianUnicode.GetBytes(
- value,
- 0,
- size / 2,
- UnderlyingStream.GetBuffer(),
- (int)UnderlyingStream.Position
- );
- }
- else
- {
- Encoding.BigEndianUnicode.GetBytes(
- value,
- 0,
- length,
- UnderlyingStream.GetBuffer(),
- (int)UnderlyingStream.Position
- );
- UnderlyingStream.Position += size;
- }
- }
-
- ///
- /// Fills the stream from the current position up to (capacity) with 0x00's
- ///
- public void Fill()
- {
- Fill(m_Capacity - UnderlyingStream.Length);
- }
-
- ///
- /// Writes a number of 0x00 byte values to the underlying stream.
- ///
- public void Fill(long length)
- {
- if (UnderlyingStream.Position == UnderlyingStream.Length)
- {
- UnderlyingStream.SetLength(UnderlyingStream.Length + length);
- UnderlyingStream.Seek(0, SeekOrigin.End);
- }
- else
- {
- UnderlyingStream.Write(new byte[length], 0, (int)length);
- }
- }
-
- ///
- /// Offsets the current position from an origin.
- ///
- public long Seek(long offset, SeekOrigin origin) => UnderlyingStream.Seek(offset, origin);
-
- ///
- /// Gets the entire stream content as a byte array.
- ///
- public byte[] ToArray() => UnderlyingStream.ToArray();
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs b/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs
deleted file mode 100644
index 5594bf937..000000000
--- a/Projects/Benchmarks/Benchmarks/Text/BenchmarkTextEncoding.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Server.Text;
-
-namespace Benchmarks.BenchmarkText
-{
- [MemoryDiagnoser]
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class BenchmarkTextEncoding
- {
- private const string text =
- "This is supposed to be a really long text Ƞă¼ÖƄŭȘú😅¥♓ǵDƤĂ😋ġǁ⚕😐'ƿī😪_l" +
- "This is supposed to be a really long text Ƞă¼ÖƄŭȘú😅¥♓ǵDƤĂ😋ġǁ⚕😐'ƿī😪_l" +
- "This is supposed to be a really long text Ƞă¼ÖƄŭȘú😅¥♓ǵDƤĂ😋ġǁ⚕😐'ƿī😪_l" +
- "This is supposed to be a really long text Ƞă¼ÖƄŭȘú😅¥♓ǵDƤĂ😋ġǁ⚕😐'ƿī😪_l" +
- "This is supposed to be a really long text Ƞă¼ÖƄŭȘú😅¥♓ǵDƤĂ😋ġǁ⚕😐'ƿī😪_l";
-
- [Benchmark]
- public byte[] TestEncodingOldReturnBytes()
- {
- var bytes = TextEncoding.UTF8.GetBytes(text);
- return bytes;
- }
-
- [Benchmark]
- public byte[] TestEncodingNewReturnBytes()
- {
- var bytes = text.GetBytesUtf8();
- return bytes;
- }
- }
-}
diff --git a/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs b/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs
deleted file mode 100644
index 01cf5bb3c..000000000
--- a/Projects/Benchmarks/Benchmarks/Utilities/BenchmarkStringHelpers.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-using System.Buffers;
-using System.Text;
-using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Jobs;
-using Server.Buffers;
-
-namespace Benchmarks.BenchmarkUtilities
-{
- [MemoryDiagnoser]
- [SimpleJob(RuntimeMoniker.NetCoreApp50)]
- public class BenchmarkStringHelpers
- {
- private readonly string[] names =
- {
- "Kamron", "Owyn", "Luthius", "Jaedan", "Vorspire", "other people",
- "Kamron-2", "Owyn-2", "Luthius-2", "Jaedan-2", "Vorspire-2", "other people too"
- };
-
- private int length;
-
- [GlobalSetup]
- public void Setup()
- {
- var chrs = ArrayPool.Shared.Rent(65535);
- ArrayPool.Shared.Return(chrs);
- length = 0;
-
- for (int i = 0; i < names.Length; i++)
- {
- length += names.Length;
- }
-
- length += 2 * (names.Length - 1) + 3;
- }
-
- [Benchmark]
- public string BenchmarkStringBuilder()
- {
- var sb = new StringBuilder();
- for (var i = 0; i < names.Length; i++)
- {
- if (i > 0)
- {
- sb.Append(i == names.Length - 1 ? ", and" : ", ");
- }
-
- sb.Append(names[i]);
- }
-
- return sb.ToString();
- }
-
- [Benchmark]
- public string BenchmarkValueStringBuilderWithStack()
- {
- using var sb = new ValueStringBuilder(stackalloc char[length]);
- for (var i = 0; i < names.Length; i++)
- {
- if (i > 0)
- {
- sb.Append(i == names.Length - 1 ? ", and" : ", ");
- }
-
- sb.Append(names[i]);
- }
-
- return sb.ToString();
- }
-
- [Benchmark]
- public string BenchmarkValueStringBuilderWithRentedBuffer()
- {
- using var sb = new ValueStringBuilder(stackalloc char[32]);
- for (var i = 0; i < names.Length; i++)
- {
- if (i > 0)
- {
- sb.Append(i == names.Length - 1 ? ", and" : ", ");
- }
-
- sb.Append(names[i]);
- }
-
- return sb.ToString();
- }
- }
-}
diff --git a/Projects/Benchmarks/Directory.Build.props b/Projects/Benchmarks/Directory.Build.props
deleted file mode 100644
index b9b7c8ad8..000000000
--- a/Projects/Benchmarks/Directory.Build.props
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/Projects/Benchmarks/Program.cs b/Projects/Benchmarks/Program.cs
deleted file mode 100644
index f28cc3e6f..000000000
--- a/Projects/Benchmarks/Program.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using BenchmarkDotNet.Running;
-
-namespace Benchmarks
-{
- public static class Program
- {
- private static void Main(string[] args)
- {
- // var featureFlags = BenchmarkRunner.Run();
- // var packetConstruction = BenchmarkRunner.Run();
- // var broadcast = BenchmarkRunner.Run();
- // var stringHelpers = BenchmarkRunner.Run();
- var indexList = BenchmarkRunner.Run();
- // var textEncoding = BenchmarkRunner.Run();
- // var logging = BenchmarkRunner.Run();
- // var gumpPacket = BenchmarkRunner.Run();
- }
- }
-}
diff --git a/Projects/SerializationGenerator/EntitySerializationGenerator.cs b/Projects/SerializationGenerator/EntitySerializationGenerator.cs
deleted file mode 100755
index e5b1e0f0d..000000000
--- a/Projects/SerializationGenerator/EntitySerializationGenerator.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: EntityJsonGenerator.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Text;
-using SerializableMigration;
-
-namespace SerializationGenerator
-{
- [Generator]
- public class EntitySerializationGenerator : ISourceGenerator
- {
- public void Initialize(GeneratorInitializationContext context)
- {
- context.RegisterForSyntaxNotifications(() => new SerializerSyntaxReceiver());
- }
-
- public void Execute(GeneratorExecutionContext context)
- {
- if (context.SyntaxContextReceiver is not SerializerSyntaxReceiver receiver)
- {
- return;
- }
-
- var jsonOptions = SerializableMigrationSchema.GetJsonSerializerOptions();
- // List of types that _will_ become ISerializable
- var serializableList = receiver.SerializableList;
- var embeddedSerializableList = receiver.EmbeddedSerializableList;
-
- foreach (var (classSymbol, (serializableAttr, fieldsList)) in receiver.ClassAndFields)
- {
- if (serializableAttr == null)
- {
- continue;
- }
-
- string classSource = context.GenerateSerializationPartialClass(
- classSymbol,
- serializableAttr,
- false,
- fieldsList.ToImmutableArray(),
- jsonOptions,
- serializableList,
- embeddedSerializableList
- );
-
- if (classSource != null)
- {
- context.AddSource($"{classSymbol.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8));
- }
- }
-
- foreach (var (classSymbol, (embeddedSerializableAttr, fieldsList)) in receiver.EmbeddedClassAndFields)
- {
- if (embeddedSerializableAttr == null)
- {
- continue;
- }
-
- string classSource = context.GenerateSerializationPartialClass(
- classSymbol,
- embeddedSerializableAttr,
- true,
- fieldsList.ToImmutableArray(),
- jsonOptions,
- serializableList,
- embeddedSerializableList
- );
-
- if (classSource != null)
- {
- context.AddSource($"{classSymbol.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8));
- }
- }
- }
- }
-}
diff --git a/Projects/SerializationGenerator/IsExternalInit.cs b/Projects/SerializationGenerator/IsExternalInit.cs
deleted file mode 100644
index eb2da113f..000000000
--- a/Projects/SerializationGenerator/IsExternalInit.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace System.Runtime.CompilerServices
-{
- internal static class IsExternalInit {}
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs
deleted file mode 100644
index 7611d5799..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Class.cs
+++ /dev/null
@@ -1,436 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableEntityGeneration.Class.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.Collections.Generic;
-using System.Collections.Immutable;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.Json;
-using Microsoft.CodeAnalysis;
-using SerializableMigration;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- public static string GenerateSerializationPartialClass(
- this GeneratorExecutionContext context,
- INamedTypeSymbol classSymbol,
- AttributeData serializableAttr,
- bool embedded,
- ImmutableArray fieldsAndProperties,
- JsonSerializerOptions jsonSerializerOptions,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes
- )
- {
- var version = (int)serializableAttr.ConstructorArguments[0].Value!;
-
- var migrations = context.GetMigrationsByAnalyzerConfig(
- classSymbol,
- version,
- jsonSerializerOptions
- );
-
- return context.Compilation.GenerateSerializationPartialClass(
- classSymbol,
- serializableAttr,
- null, // Do not generate schema
- embedded,
- null,
- migrations.ToImmutableArray(),
- fieldsAndProperties,
- serializableTypes,
- embeddedSerializableTypes
- );
- }
-
- public static string GenerateSerializationPartialClass(
- this Compilation compilation,
- INamedTypeSymbol classSymbol,
- AttributeData serializableAttr,
- string? migrationPath,
- bool embedded,
- JsonSerializerOptions? jsonSerializerOptions,
- ImmutableArray fieldsAndProperties,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes
- )
- {
- var version = (int)serializableAttr.ConstructorArguments[0].Value!;
-
- var migrations = SerializableMigrationSchema.GetMigrations(
- classSymbol,
- version,
- migrationPath,
- jsonSerializerOptions
- );
-
- return compilation.GenerateSerializationPartialClass(
- classSymbol,
- serializableAttr,
- migrationPath,
- embedded,
- jsonSerializerOptions,
- migrations.ToImmutableArray(),
- fieldsAndProperties,
- serializableTypes,
- embeddedSerializableTypes
- );
- }
-
- public static string GenerateSerializationPartialClass(
- this Compilation compilation,
- INamedTypeSymbol classSymbol,
- AttributeData serializableAttr,
- string? migrationPath,
- bool embedded,
- JsonSerializerOptions? jsonSerializerOptions,
- ImmutableArray migrations,
- ImmutableArray fieldsAndProperties,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes
- )
- {
- var serializableFieldAttribute =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTRIBUTE);
- var serializableFieldAttrAttribute =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTR_ATTRIBUTE);
- var serializableInterface =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_INTERFACE);
- var parentSerializableAttribute =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE);
- var serializableFieldSaveFlagAttribute =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_SAVE_FLAG_ATTRIBUTE);
- var serializableFieldDefaultAttribute =
- compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_DEFAULT_ATTRIBUTE);
-
- // If we have a parent that is or derives from ISerializable, then we are in override
- var isOverride = classSymbol.BaseType.ContainsInterface(serializableInterface);
-
- if (!(embedded || isOverride || classSymbol.ContainsInterface(serializableInterface)))
- {
- return null;
- }
-
- var isRawSerializable = classSymbol.HasRawSerializableInterface(compilation, ImmutableArray.Empty);
-
- var version = (int)serializableAttr.ConstructorArguments[0].Value!;
- var encodedVersion = (bool)serializableAttr.ConstructorArguments[1].Value!;
-
- // Let's find out if we need to do serialization flags
- var serializableFieldSaveFlags = new SortedDictionary();
- foreach (var m in classSymbol.GetMembers().OfType())
- {
- var getSaveFlagAttribute = m.GetAttribute(serializableFieldSaveFlagAttribute);
- var getDefaultValueAttribute = m.GetAttribute(serializableFieldDefaultAttribute);
-
- if (getSaveFlagAttribute == null && getDefaultValueAttribute == null)
- {
- continue;
- }
-
- var attrCtorArgs = getSaveFlagAttribute?.ConstructorArguments ?? getDefaultValueAttribute.ConstructorArguments;
- var order = (int)attrCtorArgs[0].Value!;
-
- serializableFieldSaveFlags.TryGetValue(order, out var saveFlagMethods);
-
- serializableFieldSaveFlags[order] = new SerializableFieldSaveFlagMethods
- {
- DetermineFieldShouldSerialize = getSaveFlagAttribute != null ? m : saveFlagMethods?.DetermineFieldShouldSerialize,
- GetFieldDefaultValue = getDefaultValueAttribute != null ? m : saveFlagMethods?.GetFieldDefaultValue
- };
- }
-
- var namespaceName = classSymbol.ContainingNamespace.ToDisplayString();
- var className = classSymbol.Name;
-
- StringBuilder source = new StringBuilder();
-
- source.AppendLine("#pragma warning disable\n");
- source.GenerateNamespaceStart(namespaceName);
-
- var interfaces = !embedded || isRawSerializable
- ? Array.Empty()
- : new ITypeSymbol[] { compilation.GetTypeByMetadataName(SymbolMetadata.RAW_SERIALIZABLE_INTERFACE) };
-
- var indent = " ";
-
- source.RecursiveGenerateClassStart(classSymbol, interfaces.ToImmutableArray(), ref indent);
-
- source.GenerateClassField(
- indent,
- Accessibility.Private,
- InstanceModifier.Const,
- "int",
- "_version",
- version.ToString()
- );
- source.AppendLine();
-
- var parentFieldOrProperty = embedded ? fieldsAndProperties.FirstOrDefault(
- fieldOrPropertySymbol => fieldOrPropertySymbol.GetAttributes()
- .FirstOrDefault(
- attr =>
- SymbolEqualityComparer.Default.Equals(attr.AttributeClass, parentSerializableAttribute)
- ) != null
- ) : null;
-
- var serializablePropertySet = new SortedDictionary(new SerializablePropertyComparer());
-
- foreach (var fieldOrPropertySymbol in fieldsAndProperties)
- {
- var allAttributes = fieldOrPropertySymbol.GetAttributes();
-
- var serializableFieldAttr = allAttributes
- .FirstOrDefault(
- attr =>
- SymbolEqualityComparer.Default.Equals(attr.AttributeClass, serializableFieldAttribute)
- );
-
- if (serializableFieldAttr == null)
- {
- continue;
- }
-
- foreach (var attr in allAttributes)
- {
- if (!SymbolEqualityComparer.Default.Equals(attr.AttributeClass, serializableFieldAttrAttribute))
- {
- continue;
- }
-
- if (attr.AttributeClass == null)
- {
- continue;
- }
-
- var ctorArgs = attr.ConstructorArguments;
- var attrTypeArg = ctorArgs[0];
-
- if (attrTypeArg.Kind == TypedConstantKind.Primitive && attrTypeArg.Value is string attrStr)
- {
- source.AppendLine($"{indent}{attrStr}");
- }
- else
- {
- var attrType = (ITypeSymbol)attrTypeArg.Value;
- source.GenerateAttribute(indent, attrType?.Name, ctorArgs[1].Values);
- }
- }
-
- var attrCtorArgs = serializableFieldAttr.ConstructorArguments;
-
- var order = (int)attrCtorArgs[0].Value!;
- var getterAccessor = Helpers.GetAccessibility(attrCtorArgs[1].Value?.ToString());
- var setterAccessor = Helpers.GetAccessibility(attrCtorArgs[2].Value?.ToString());
- var virtualProperty = (bool)attrCtorArgs[3].Value!;
-
- if (fieldOrPropertySymbol is IFieldSymbol fieldSymbol)
- {
- source.GenerateSerializableProperty(
- compilation,
- indent,
- fieldSymbol,
- getterAccessor,
- setterAccessor,
- virtualProperty,
- parentFieldOrProperty
- );
- source.AppendLine();
- }
-
- serializableFieldSaveFlags.TryGetValue(order, out var serializableFieldSaveFlagMethods);
-
- var serializableProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- fieldOrPropertySymbol,
- order,
- allAttributes,
- serializableTypes,
- embeddedSerializableTypes,
- classSymbol,
- serializableFieldSaveFlagMethods
- );
-
- serializablePropertySet.Add(serializableProperty, fieldOrPropertySymbol);
- }
-
- var serializableFields = serializablePropertySet.Keys.ToImmutableArray();
- var serializableProperties = serializablePropertySet.Select(
- kvp => kvp.Key with
- {
- Name = (kvp.Value as IFieldSymbol)?.GetPropertyName() ?? ((IPropertySymbol)kvp.Value).Name
- }
- ).ToImmutableArray();
-
- // If we are not inheriting ISerializable, then we need to define some stuff
- if (!(isOverride || embedded))
- {
- // long ISerializable.SavePosition { get; set; } = -1;
- source.GenerateAutoProperty(
- Accessibility.NotApplicable,
- "long",
- "ISerializable.SavePosition",
- Accessibility.NotApplicable,
- Accessibility.NotApplicable,
- indent,
- defaultValue: "-1"
- );
-
- // BufferWriter ISerializable.SaveBuffer { get; set; }
- source.GenerateAutoProperty(
- Accessibility.NotApplicable,
- "BufferWriter",
- "ISerializable.SaveBuffer",
- Accessibility.NotApplicable,
- Accessibility.NotApplicable,
- indent
- );
- }
-
- if (!embedded)
- {
- // Serial constructor
- source.GenerateSerialCtor(compilation, className, indent, isOverride);
- source.AppendLine();
- }
-
- if (version > 0)
- {
- for (var i = 0; i < migrations.Length; i++)
- {
- var migration = migrations[i];
- if (migration.Version < version)
- {
- source.GenerateMigrationContentStruct(compilation, indent, migration, classSymbol);
- source.AppendLine();
- }
- }
- }
-
- // Serialize Method
- source.GenerateSerializeMethod(
- compilation,
- indent,
- isOverride,
- encodedVersion,
- serializableFields,
- serializableProperties,
- serializableFieldSaveFlags
- );
- source.AppendLine();
-
- // Deserialize Method
- source.GenerateDeserializeMethod(
- compilation,
- classSymbol,
- indent,
- isOverride,
- version,
- encodedVersion,
- migrations,
- serializableFields,
- serializableProperties,
- parentFieldOrProperty,
- serializableFieldSaveFlags
- );
-
- // Serialize SaveFlag enum class
- if (serializableFieldSaveFlags.Count > 0)
- {
- source.AppendLine();
- source.GenerateEnumStart(
- "SaveFlag",
- $"{indent} ",
- true,
- Accessibility.Private
- );
-
- source.GenerateEnumValue($"{indent} ", true, "None", -1);
- int index = 0;
- foreach (var (order, _) in serializableFieldSaveFlags)
- {
- source.GenerateEnumValue($"{indent} ", true, serializableProperties[order].Name, index++);
- }
-
- source.GenerateEnumEnd($"{indent} ");
- }
-
- source.RecursiveGenerateClassEnd(classSymbol, ref indent);
- source.GenerateNamespaceEnd();
-
- if (migrationPath != null)
- {
- // Write the migration file
- var newMigration = new SerializableMetadata
- {
- Version = version,
- Type = classSymbol.ToDisplayString(),
- Properties = serializableProperties.Length > 0 ? serializableProperties : null
- };
-
- WriteMigration(migrationPath, newMigration, jsonSerializerOptions);
- }
-
- return source.ToString();
- }
-
- private static void WriteMigration(string migrationPath, SerializableMetadata metadata, JsonSerializerOptions options)
- {
- Directory.CreateDirectory(migrationPath);
- var filePath = Path.Combine(migrationPath, $"{metadata.Type}.v{metadata.Version}.json");
- File.WriteAllText(filePath, JsonSerializer.Serialize(metadata, options));
- }
-
- private static void RecursiveGenerateClassStart(
- this StringBuilder source,
- INamedTypeSymbol classSymbol,
- ImmutableArray interfaces,
- ref string indent
- )
- {
- var containingSymbolList = new List();
-
- do
- {
- containingSymbolList.Add(classSymbol);
- classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol;
- } while (classSymbol != null);
-
- containingSymbolList.Reverse();
-
- for (var i = 0; i < containingSymbolList.Count; i++)
- {
- var symbol = containingSymbolList[i];
- source.GenerateClassStart(symbol, indent, i == containingSymbolList.Count - 1 ? interfaces : ImmutableArray.Empty);
- indent += " ";
- }
- }
-
- private static void RecursiveGenerateClassEnd(this StringBuilder source, INamedTypeSymbol classSymbol, ref string indent)
- {
- do
- {
- indent = indent.Substring(0, indent.Length - 4);
- source.GenerateClassEnd(indent);
-
- classSymbol = classSymbol.ContainingSymbol as INamedTypeSymbol;
- } while (classSymbol != null);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs
deleted file mode 100644
index 59048a125..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.DeserializeMethod.cs
+++ /dev/null
@@ -1,213 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableEntityGeneration.DeserializeMethod.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.Collections.Generic;
-using System.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializableMigration;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- public static void GenerateDeserializeMethod(
- this StringBuilder source,
- Compilation compilation,
- INamedTypeSymbol classSymbol,
- string indent,
- bool isOverride,
- int version,
- bool encodedVersion,
- ImmutableArray migrations,
- ImmutableArray fields,
- ImmutableArray properties,
- ISymbol parentFieldOrProperty,
- SortedDictionary serializableFieldSaveFlagMethodsDictionary
- )
- {
- var genericReaderInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_READER_INTERFACE);
-
- source.GenerateMethodStart(
- indent,
- "Deserialize",
- Accessibility.Public,
- isOverride,
- "void",
- ImmutableArray.Create<(ITypeSymbol, string)>((genericReaderInterface, "reader"))
- );
-
- var bodyIndent = $"{indent} ";
- var innerIndent = $"{bodyIndent} ";
-
- if (isOverride)
- {
- source.AppendLine($"{bodyIndent}base.Deserialize(reader);");
- source.AppendLine();
- }
-
- var afterDeserialization = classSymbol
- .GetMembers()
- .OfType()
- .Select(
- m =>
- {
- if (!m.ReturnsVoid || m.Parameters.Length != 0)
- {
- return (m, null);
- }
-
- return (m, m.GetAttributes()
- .FirstOrDefault(
- attr => SymbolEqualityComparer.Default.Equals(
- attr.AttributeClass,
- compilation.GetTypeByMetadataName(SymbolMetadata.AFTERDESERIALIZATION_ATTRIBUTE)
- )
- ));
- }
- ).Where(m => m.Item2 != null).ToList();
-
- // Version
- source.AppendLine($"{bodyIndent}var version = reader.{(encodedVersion ? "ReadEncodedInt" : "ReadInt")}();");
-
- if (version > 0)
- {
- var parent = parentFieldOrProperty?.Name ?? "this";
- var nextVersion = 0;
-
- for (var i = 0; i < migrations.Length; i++)
- {
- var migrationVersion = migrations[i].Version;
- if (migrationVersion == nextVersion)
- {
- nextVersion++;
- }
-
- source.AppendLine();
- source.AppendLine($"{bodyIndent}if (version == {migrationVersion})");
- source.AppendLine($"{bodyIndent}{{");
- source.AppendLine($"{bodyIndent} MigrateFrom(new V{migrationVersion}Content(reader, this));");
- source.AppendLine($"{bodyIndent} {parent}.MarkDirty();");
- source.GenerateAfterDeserialization($"{bodyIndent} ", afterDeserialization);
- source.AppendLine($"{bodyIndent} return;");
- source.AppendLine($"{bodyIndent}}}");
- }
-
- if (nextVersion < version)
- {
- source.AppendLine();
- source.AppendLine($"{bodyIndent}if (version < _version)");
- source.AppendLine($"{bodyIndent}{{");
- source.AppendLine($"{bodyIndent} Deserialize(reader, version);");
- source.AppendLine($"{bodyIndent} {parent}.MarkDirty();");
- source.GenerateAfterDeserialization($"{bodyIndent} ", afterDeserialization);
- source.AppendLine($"{bodyIndent} return;");
- source.AppendLine($"{bodyIndent}}}");
- }
- }
-
- if (serializableFieldSaveFlagMethodsDictionary.Count > 0)
- {
- source.AppendLine();
- source.AppendLine($"{bodyIndent}var saveFlags = reader.ReadEnum();");
- }
-
- for (var i = 0; i < properties.Length; i++)
- {
- var field = fields[i];
- var property = properties[i];
- var rule = SerializableMigrationRulesEngine.Rules[property.Rule];
-
- if (serializableFieldSaveFlagMethodsDictionary.TryGetValue(
- property.Order,
- out var serializableFieldSaveFlagMethods
- ))
- {
- source.AppendLine();
- // Special case
- if (property.Type == "bool")
- {
- source.AppendLine($"{bodyIndent}{field.Name} = (saveFlags & SaveFlag.{property.Name}) != 0;");
- }
- else
- {
- source.AppendLine($"{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{");
- rule.GenerateDeserializationMethod(
- source,
- innerIndent,
- field,
- parentFieldOrProperty?.Name ?? "this"
- );
- (rule as IPostDeserializeMethod)?.PostDeserializeMethod(
- source,
- innerIndent,
- field,
- compilation,
- classSymbol
- );
-
- if (serializableFieldSaveFlagMethods.GetFieldDefaultValue != null)
- {
- source.AppendLine($"{bodyIndent}}}\n{bodyIndent}else\n{bodyIndent}{{");
- source.AppendLine(
- $"{bodyIndent} {field.Name} = {serializableFieldSaveFlagMethods.GetFieldDefaultValue.Name}();"
- );
- }
-
- source.AppendLine($"{bodyIndent}}}");
- }
- }
- else
- {
- source.AppendLine();
- rule.GenerateDeserializationMethod(
- source,
- bodyIndent,
- field,
- parentFieldOrProperty?.Name ?? "this"
- );
- (rule as IPostDeserializeMethod)?.PostDeserializeMethod(
- source,
- bodyIndent,
- field,
- compilation,
- classSymbol
- );
- }
- }
-
- source.GenerateAfterDeserialization($"{bodyIndent}", afterDeserialization);
- source.GenerateMethodEnd(indent);
- }
-
- private static void GenerateAfterDeserialization(
- this StringBuilder source, string indent, IList<(IMethodSymbol, AttributeData?)> afterDeserialization
- )
- {
- foreach (var (method, attr) in afterDeserialization)
- {
- if ((bool)attr.ConstructorArguments[0].Value!)
- {
- source.AppendLine($"{indent}{method.Name}();");
- }
- else
- {
- source.AppendLine($"{indent}Timer.DelayCall({method.Name});");
- }
- }
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs
deleted file mode 100644
index d2457bb90..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.Property.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableEntityGeneration.Property.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.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- public static void GenerateSerializableProperty(
- this StringBuilder source,
- Compilation compilation,
- string indent,
- IFieldSymbol fieldSymbol,
- Accessibility getter,
- Accessibility? setter,
- bool isVirtual,
- ISymbol? parentFieldOrProperty
- )
- {
- var fieldName = fieldSymbol.Name;
-
- var invalidatePropertiesAttribute = fieldSymbol
- .GetAttributes()
- .OfType()
- .FirstOrDefault(
- attr => attr.AttributeClass?.Equals(
- compilation.GetTypeByMetadataName(SymbolMetadata.INVALIDATEPROPERTIES_ATTRIBUTE),
- SymbolEqualityComparer.Default
- ) ?? false
- );
-
- var propertyIndent = $"{indent} ";
- var innerIndent = $"{propertyIndent} ";
-
- var propertyAccessor = setter > getter ? setter : getter;
- var getterAccessor = getter == propertyAccessor ? Accessibility.NotApplicable : getter;
-
- source.GeneratePropertyStart(indent, propertyAccessor.Value, isVirtual, fieldSymbol);
-
- // Getter
- source.GeneratePropertyGetterReturnsField(propertyIndent, fieldSymbol, getterAccessor);
-
- if (setter != null && setter != Accessibility.NotApplicable)
- {
- var setterAccessor = setter == propertyAccessor ? Accessibility.NotApplicable : setter;
-
- var parentSymbol = parentFieldOrProperty?.Name ?? "this";
-
- // Setter
- source.GeneratePropertySetterStart(propertyIndent, false, setterAccessor.Value);
- source.AppendLine($"{innerIndent}if (value != {fieldName})");
- source.AppendLine($"{innerIndent}{{");
- source.AppendLine($"{innerIndent} {fieldName} = value;");
- source.AppendLine($"{innerIndent} {parentSymbol}.MarkDirty();");
-
- if (invalidatePropertiesAttribute != null)
- {
- source.AppendLine($"{innerIndent} InvalidateProperties();");
- }
- source.AppendLine($"{innerIndent}}}");
- source.GeneratePropertyGetSetEnd(propertyIndent, false);
- }
-
- source.GeneratePropertyEnd(indent);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs
deleted file mode 100644
index 7b7ebcb7f..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerialCtor.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableEntityGeneration.SerialCtor.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- private static readonly ImmutableArray _baseParameters = new[] { "serial" }.ToImmutableArray();
- public static void GenerateSerialCtor(
- this StringBuilder source,
- Compilation compilation,
- string className,
- string indent,
- bool isOverride
- )
- {
- var serialType = (ITypeSymbol)compilation.GetTypeByMetadataName("Server.Serial");
-
- source.GenerateConstructorStart(
- indent,
- className,
- Accessibility.Public,
- new []{ (serialType, "serial") }.ToImmutableArray(),
- isOverride ? _baseParameters : ImmutableArray.Empty
- );
-
- if (!isOverride)
- {
- source.AppendLine($"{indent} Serial = serial;");
- source.AppendLine($"{indent} SetTypeRef(typeof({className}));");
- }
-
- source.GenerateMethodEnd(indent);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs
deleted file mode 100644
index 6aff93f5e..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableEntityGeneration.SerializeMethod.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableEntityGeneration.SerializeMethod.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.Collections.Generic;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializableMigration;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- public static void GenerateSerializeMethod(
- this StringBuilder source,
- Compilation compilation,
- string indent,
- bool isOverride,
- bool encodedVersion,
- ImmutableArray fields,
- ImmutableArray properties,
- SortedDictionary serializableFieldSaveFlagMethodsDictionary
- )
- {
- var genericWriterInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_WRITER_INTERFACE);
-
- source.GenerateMethodStart(
- indent,
- "Serialize",
- Accessibility.Public,
- isOverride,
- "void",
- ImmutableArray.Create<(ITypeSymbol, string)>((genericWriterInterface, "writer"))
- );
-
- var bodyIndent = $"{indent} ";
- var innerIndent = $"{bodyIndent} ";
-
- if (isOverride)
- {
- source.AppendLine($"{bodyIndent}base.Serialize(writer);");
- source.AppendLine();
- }
-
- // Version
- source.AppendLine($"{bodyIndent}writer.{(encodedVersion ? "WriteEncodedInt" : "Write")}(_version);");
-
- // Let's collect the flags
- if (serializableFieldSaveFlagMethodsDictionary.Count > 0)
- {
- source.AppendLine($"\n{bodyIndent}var saveFlags = SaveFlag.None;");
-
- foreach (var (order, saveFlagMethods) in serializableFieldSaveFlagMethodsDictionary)
- {
- source.AppendLine($"{bodyIndent}if ({saveFlagMethods.DetermineFieldShouldSerialize!.Name}())\n{bodyIndent}{{");
-
- var propertyName = properties[order].Name;
- source.AppendLine($"{innerIndent}saveFlags |= SaveFlag.{propertyName};");
-
- source.AppendLine($"{bodyIndent}}}");
- }
-
- source.AppendLine($"{bodyIndent}writer.WriteEnum(saveFlags);");
- }
-
- for (var i = 0; i < properties.Length; i++)
- {
- var field = fields[i];
- var property = properties[i];
- if (serializableFieldSaveFlagMethodsDictionary.ContainsKey(property.Order))
- {
- // Special case
- if (property.Type != "bool")
- {
- source.AppendLine($"\n{bodyIndent}if ((saveFlags & SaveFlag.{property.Name}) != 0)\n{bodyIndent}{{");
- SerializableMigrationRulesEngine.Rules[property.Rule]
- .GenerateSerializationMethod(
- source,
- innerIndent,
- field
- );
- source.AppendLine($"{bodyIndent}}}");
- }
- }
- else
- {
- source.AppendLine();
- SerializableMigrationRulesEngine.Rules[property.Rule]
- .GenerateSerializationMethod(
- source,
- bodyIndent,
- field
- );
- }
- }
-
- source.GenerateMethodEnd(indent);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs
deleted file mode 100644
index 55a087914..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializableFieldSaveFlagMethods.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public record SerializableFieldSaveFlagMethods
- {
- public IMethodSymbol? DetermineFieldShouldSerialize { get; init; }
-
- public IMethodSymbol? GetFieldDefaultValue { get; init; }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs b/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs
deleted file mode 100644
index 7e664920e..000000000
--- a/Projects/SerializationGenerator/SerializableEntityGeneration/SerializationEntityGeneration.ContentStruct.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializationEntityGeneration.ContentStruct.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.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializableMigration;
-
-namespace SerializationGenerator
-{
- public static partial class SerializableEntityGeneration
- {
- public static void GenerateMigrationContentStruct(
- this StringBuilder source,
- Compilation compilation,
- string indent,
- SerializableMetadata migration,
- INamedTypeSymbol classSymbol
- )
- {
- source.AppendLine($"{indent}ref struct V{migration.Version}Content");
- source.AppendLine($"{indent}{{");
- var properties = migration.Properties ?? ImmutableArray.Empty;
-
- foreach (var serializableProperty in properties)
- {
- var propertyType = serializableProperty.Type;
- var type = compilation.GetTypeByMetadataName(propertyType)?.IsValueType == true
- || SymbolMetadata.IsPrimitiveFromTypeDisplayString(propertyType) && propertyType != "bool"
- ? $"{propertyType}{(serializableProperty.UsesSaveFlag == true ? "?" : "")}" : propertyType;
-
- source.AppendLine($"{indent} internal readonly {type} {serializableProperty.Name};");
- }
-
- var innerIndent = $"{indent} ";
-
- var usesSaveFlags = properties.Any(p => p.UsesSaveFlag == true);
-
- if (usesSaveFlags)
- {
- source.AppendLine();
- source.GenerateEnumStart(
- $"V{migration.Version}SaveFlag",
- $"{indent} ",
- true,
- Accessibility.Private
- );
-
- source.GenerateEnumValue(innerIndent, true, "None", -1);
- int index = 0;
- foreach (var property in properties)
- {
- if (property.UsesSaveFlag == true)
- {
- source.GenerateEnumValue(innerIndent, true, property.Name, index++);
- }
- }
-
- source.GenerateEnumEnd($"{indent} ");
- }
-
- source.AppendLine($"{indent} internal V{migration.Version}Content(IGenericReader reader, {classSymbol.ToDisplayString()} entity)");
- source.AppendLine($"{indent} {{");
-
- if (usesSaveFlags)
- {
- source.AppendLine($"{innerIndent}var saveFlags = reader.ReadEnum();");
- }
-
- if (properties.Length > 0)
- {
- foreach (var property in properties)
- {
- if (property.UsesSaveFlag == true)
- {
- source.AppendLine();
- // Special case
- if (property.Type == "bool")
- {
- source.AppendLine($"{innerIndent}{property.Name} = (saveFlags & V{migration.Version}SaveFlag.{property.Name}) != 0;");
- }
- else
- {
- source.AppendLine($"{innerIndent}if ((saveFlags & V{migration.Version}SaveFlag.{property.Name}) != 0)\n{innerIndent}{{");
-
- SerializableMigrationRulesEngine.Rules[property.Rule].GenerateDeserializationMethod(
- source,
- $"{innerIndent} ",
- property,
- "entity"
- );
-
- source.AppendLine($"{innerIndent}}}\n{innerIndent}else\n{innerIndent}{{");
- source.AppendLine($"{innerIndent} {property.Name} = default;");
- source.AppendLine($"{innerIndent}}}");
- }
- }
- else
- {
- SerializableMigrationRulesEngine.Rules[property.Rule].GenerateDeserializationMethod(
- source,
- innerIndent,
- property,
- "entity"
- );
- }
- }
- }
-
- source.AppendLine($"{indent} }}");
-
- source.AppendLine($"{indent}}}");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs b/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs
deleted file mode 100644
index 0a48c0117..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/IPostDeserializeMethod.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: IPostDeserializeMethod.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.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializableMigration
-{
- public interface IPostDeserializeMethod
- {
- public void PostDeserializeMethod(
- StringBuilder source,
- string indent,
- SerializableProperty property,
- Compilation compilation,
- INamedTypeSymbol classSymbol
- );
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs
deleted file mode 100644
index 1f944c4fa..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/ISerializableMigrationRule.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableMigrationRule.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializableMigration
-{
- public interface ISerializableMigrationRule
- {
- string RuleName { get; }
-
- bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- );
-
- void GenerateDeserializationMethod(
- StringBuilder source,
- string indent,
- SerializableProperty property,
- string? parentReference
- );
-
- void GenerateSerializationMethod(
- StringBuilder source,
- string indent,
- SerializableProperty property
- );
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs
deleted file mode 100644
index 54b63cc1c..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/ArrayMigrationRule.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: ArrayMigrationRule.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializableMigration
-{
- public class ArrayMigrationRule : ISerializableMigrationRule
- {
- public string RuleName => nameof(ArrayMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not IArrayTypeSymbol arrayTypeSymbol)
- {
- ruleArguments = null;
- return false;
- }
-
- var serializableArrayType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "ArrayEntry",
- arrayTypeSymbol.ElementType,
- 0,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var length = serializableArrayType.RuleArguments?.Length?? 0;
- ruleArguments = new string[length + 2];
- ruleArguments[0] = arrayTypeSymbol.ElementType.ToDisplayString();
- ruleArguments[1] = serializableArrayType.Rule;
- if (length > 0)
- {
- Array.Copy(serializableArrayType.RuleArguments!, 0, ruleArguments, 2, length);
- }
-
- return true;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
- var ruleArguments = property.RuleArguments;
- var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]];
- var arrayElementRuleArguments = new string[ruleArguments.Length - 2];
- Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2);
-
- var propertyIndex = $"{property.Name}Index";
- source.AppendLine($"{indent}{property.Name} = new {ruleArguments[0]}[reader.ReadEncodedInt()];");
- source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {property.Name}.Length; {propertyIndex}++)");
- source.AppendLine($"{indent}{{");
-
- var serializableArrayElement = new SerializableProperty
- {
- Name = $"{property.Name}[{propertyIndex}]",
- Type = ruleArguments[0],
- Rule = arrayElementRule.RuleName,
- RuleArguments = arrayElementRuleArguments
- };
-
- arrayElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableArrayElement, parentReference);
-
- source.AppendLine($"{indent}}}");
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]];
- var arrayElementRuleArguments = new string[ruleArguments.Length - 2];
- Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2);
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyIndex = $"{propertyVarPrefix}Index";
- var propertyLength = $"{propertyVarPrefix}Length";
- source.AppendLine($"{indent}var {propertyLength} = {property.Name}?.Length ?? 0;");
- source.AppendLine($"{indent}writer.WriteEncodedInt({propertyLength});");
- source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyLength}; {propertyIndex}++)");
- source.AppendLine($"{indent}{{");
-
- var serializableArrayElement = new SerializableProperty
- {
- Name = $"{property.Name}![{propertyIndex}]",
- Type = ruleArguments[0],
- Rule = arrayElementRule.RuleName,
- RuleArguments = arrayElementRuleArguments
- };
-
- arrayElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableArrayElement);
-
- source.AppendLine($"{indent}}}");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs
deleted file mode 100644
index 18ebc3678..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/EnumMigrationRule.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: EnumMigrationRule.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public class EnumMigrationRule : ISerializableMigrationRule
- {
- public string RuleName => nameof(EnumMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum())
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = Array.Empty();
- return true;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();");
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- source.AppendLine($"{indent}writer.WriteEnum<{property.Type}>({property.Name});");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs
deleted file mode 100644
index 46e425a3d..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/HashSetMigrationRule.cs
+++ /dev/null
@@ -1,166 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: HashSetMigrationRule.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.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public class HashSetMigrationRule : ISerializableMigrationRule
- {
- public string RuleName => nameof(HashSetMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsHashSet(compilation))
- {
- ruleArguments = null;
- return false;
- }
-
- var setTypeSymbol = namedTypeSymbol.TypeArguments[0];
-
- var serializableSetType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "SetEntry",
- setTypeSymbol,
- 0,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var extraOptions = "";
- if (attributes.Any(a => a.IsTidy(compilation)))
- {
- extraOptions += "@Tidy";
- }
-
- var length = serializableSetType.RuleArguments?.Length ?? 0;
- ruleArguments = new string[length + 3];
- ruleArguments[0] = extraOptions;
- ruleArguments[1] = setTypeSymbol.ToDisplayString();
- ruleArguments[2] = serializableSetType.Rule;
- Array.Copy(serializableSetType.RuleArguments, 0, ruleArguments, 3, length);
-
- return true;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
- var argumentsOffset = hasExtraOptions ? 1 : 0;
-
- var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
- var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
- Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyIndex = $"{propertyVarPrefix}Index";
- var propertyEntry = $"{propertyVarPrefix}Entry";
- var propertyCount = $"{propertyVarPrefix}Count";
-
- source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};");
- source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
- source.AppendLine($"{indent}{property.Name} = new System.Collections.Generic.HashSet<{ruleArguments[argumentsOffset]}>({propertyCount});");
- source.AppendLine($"{indent}for (var {propertyIndex} = 0; i < {propertyCount}; {propertyIndex}++)");
- source.AppendLine($"{indent}{{");
-
- var serializableSetElement = new SerializableProperty
- {
- Name = propertyEntry,
- Type = ruleArguments[argumentsOffset],
- Rule = setElementRule.RuleName,
- RuleArguments = setElementRuleArguments
- };
-
- setElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableSetElement, parentReference);
- source.AppendLine($"{indent} {property.Name}.Add({propertyEntry});");
-
- source.AppendLine($"{indent}}}");
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
- var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy");
- var argumentsOffset = hasExtraOptions ? 1 : 0;
-
- var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
- var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
- Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyEntry = $"{propertyVarPrefix}Entry";
- var propertyCount = $"{propertyVarPrefix}Count";
-
- if (shouldTidy)
- {
- source.AppendLine($"{indent}{property.Name}?.Tidy();");
- }
- source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
- source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
- source.AppendLine($"{indent}if ({propertyCount} > 0)");
- source.AppendLine($"{indent}{{");
- source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)");
- source.AppendLine($"{indent} {{");
-
- var serializableSetElement = new SerializableProperty
- {
- Name = propertyEntry,
- Type = ruleArguments[argumentsOffset],
- Rule = setElementRule.RuleName,
- RuleArguments = setElementRuleArguments
- };
-
- setElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableSetElement);
-
- source.AppendLine($"{indent} }}");
- source.AppendLine($"{indent}}}");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs
deleted file mode 100644
index 7ebdf064d..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/KeyValuePairMigrationRule.cs
+++ /dev/null
@@ -1,202 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: KeyValuePairMigrationRule.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public class KeyValuePairMigrationRule : ISerializableMigrationRule
- {
- public string RuleName => nameof(KeyValuePairMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsKeyValuePair(compilation))
- {
- ruleArguments = null;
- return false;
- }
-
- var typeArguments = namedTypeSymbol.TypeArguments;
-
- var keySerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "key",
- typeArguments[0],
- 0,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "value",
- typeArguments[1],
- 1,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var keyArgumentsLength = keySerializedProperty.RuleArguments?.Length ?? 0;
- var valueArgumentsLength = valueSerializedProperty.RuleArguments?.Length ?? 0;
- var index = 0;
-
- // Key
- ruleArguments = new string[5 + keyArgumentsLength + valueArgumentsLength];
- ruleArguments[index++] = typeArguments[0].ToDisplayString();
- ruleArguments[index++] = keySerializedProperty.Rule;
- ruleArguments[index++] = keyArgumentsLength.ToString();
- if (keyArgumentsLength > 0)
- {
- Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
- }
-
- // Value
- ruleArguments[index++] = typeArguments[1].ToDisplayString();
- ruleArguments[index++] = valueSerializedProperty.Rule;
-
- if (valueArgumentsLength > 0)
- {
- Array.Copy(valueSerializedProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength);
- }
-
- return true;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- 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 serializableKeyProperty = new SerializableProperty
- {
- Name = "key",
- Type = keyType,
- Rule = keyRule.RuleName,
- RuleArguments = keyRuleArguments
- };
-
- keyRule.GenerateDeserializationMethod(
- source,
- indent,
- serializableKeyProperty,
- 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 serializableValueProperty = new SerializableProperty
- {
- Name = "value",
- Type = valueType,
- Rule = valueRule.RuleName,
- RuleArguments = valueRuleArguments
- };
-
- keyRule.GenerateDeserializationMethod(
- source,
- indent,
- serializableValueProperty,
- parentReference
- );
-
- source.AppendLine(
- $"{indent}{property.Name} = new {SymbolMetadata.KEYVALUEPAIR_STRUCT}<{keyType}, {valueType}>(key, value);"
- );
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- 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 serializableKeyProperty = new SerializableProperty
- {
- Name = $"{property.Name}.Key",
- Type = keyType,
- Rule = keyRule.RuleName,
- RuleArguments = keyRuleArguments
- };
-
- keyRule.GenerateSerializationMethod(
- source,
- indent,
- 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 serializableValueProperty = new SerializableProperty
- {
- Name = $"{property.Name}.Value",
- Type = valueType,
- Rule = valueRule.RuleName,
- RuleArguments = valueRuleArguments
- };
-
- keyRule.GenerateSerializationMethod(
- source,
- indent,
- serializableValueProperty
- );
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs
deleted file mode 100644
index f11e3f369..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/ListMigrationRule.cs
+++ /dev/null
@@ -1,171 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: ListMigrationRule.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.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public class ListMigrationRule : ISerializableMigrationRule
- {
- public string RuleName => nameof(ListMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsList(compilation))
- {
- ruleArguments = null;
- return false;
- }
-
- var listTypeSymbol = namedTypeSymbol.TypeArguments[0];
-
- var serializableListType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
- compilation,
- "ListEntry",
- listTypeSymbol,
- 0,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- null
- );
-
- var extraOptions = "";
- if (attributes.Any(a => a.IsTidy(compilation)))
- {
- extraOptions += "@Tidy";
- }
-
- var length = serializableListType.RuleArguments?.Length ?? 0;
- ruleArguments = new string[length + 3];
- ruleArguments[0] = extraOptions;
- ruleArguments[1] = listTypeSymbol.ToDisplayString();
- ruleArguments[2] = serializableListType.Rule;
-
- if (length > 0)
- {
- Array.Copy(serializableListType.RuleArguments!, 0, ruleArguments, 3, length);
- }
-
- return true;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
- var argumentsOffset = hasExtraOptions ? 1 : 0;
-
- var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[argumentsOffset + 1]];
-
- var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
- Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyIndex = $"{propertyVarPrefix}Index";
- var propertyEntry = $"{propertyVarPrefix}Entry";
- var propertyCount = $"{propertyVarPrefix}Count";
-
- source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};");
- source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
- source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.List<{ruleArguments[argumentsOffset]}>({propertyCount});");
- source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
- source.AppendLine($"{indent}{{");
-
- var serializableListElement = new SerializableProperty
- {
- Name = propertyEntry,
- Type = ruleArguments[argumentsOffset],
- Rule = listElementRule.RuleName,
- RuleArguments = listElementRuleArguments
- };
-
- listElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableListElement, parentReference);
- source.AppendLine($"{indent} {propertyName}.Add({propertyEntry});");
-
- source.AppendLine($"{indent}}}");
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var ruleArguments = property.RuleArguments;
- var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
- var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy");
- var argumentsOffset = hasExtraOptions ? 1 : 0;
-
- var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
- var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
- Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
-
- var propertyName = property.Name;
- var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
- var propertyEntry = $"{propertyVarPrefix}Entry";
- var propertyCount = $"{propertyVarPrefix}Count";
-
- if (shouldTidy)
- {
- source.AppendLine($"{indent}{property.Name}?.Tidy();");
- }
- source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
- source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
- source.AppendLine($"{indent}if ({propertyCount} > 0)");
- source.AppendLine($"{indent}{{");
- source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)");
- source.AppendLine($"{indent} {{");
-
- var serializableListElement = new SerializableProperty
- {
- Name = propertyEntry,
- Type = ruleArguments[argumentsOffset],
- Rule = listElementRule.RuleName,
- RuleArguments = listElementRuleArguments
- };
-
- listElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableListElement);
-
- source.AppendLine($"{indent} }}");
- source.AppendLine($"{indent}}}");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs
deleted file mode 100644
index f3d8135bd..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveTypeMigrationRule.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: PrimitiveTypeMigrationRule.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.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public class PrimitiveTypeMigrationRule : ISerializableMigrationRule
- {
- public string RuleName => nameof(PrimitiveTypeMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation))
- {
- ruleArguments = Array.Empty();
- return true;
- }
-
- if (
- symbol is not ITypeSymbol {
- SpecialType: not (not
- SpecialType.System_Boolean and not
- SpecialType.System_SByte and not
- SpecialType.System_Int16 and not
- SpecialType.System_Int32 and not
- SpecialType.System_Int64 and not
- SpecialType.System_Byte and not
- SpecialType.System_UInt16 and not
- SpecialType.System_UInt32 and not
- SpecialType.System_UInt64 and not
- SpecialType.System_Single and not
- SpecialType.System_Double and not
- SpecialType.System_String and not
- SpecialType.System_Decimal and not
- SpecialType.System_DateTime)
- } typeSymbol
- )
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = typeSymbol.SpecialType switch
- {
- SpecialType.System_Int32 when attributes.Any(a => a.IsEncodedInt(compilation)) =>
- new[] { "EncodedInt" },
- SpecialType.System_DateTime when attributes.Any(a => a.IsDeltaDateTime(compilation)) =>
- new[] { "DeltaTime" },
- SpecialType.System_String when attributes.Any(a => a.IsInternString(compilation)) =>
- new[] { "InternString" },
- _ => new[] { "" }
- };
-
- return true;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null;
-
- const string ipAddress = SymbolMetadata.IPADDRESS_CLASS;
- const string timeSpan = SymbolMetadata.TIMESPAN_STRUCT;
- const string date = "System.DateTime";
-
- var readMethod = property.Type switch
- {
- "bool" => "ReadBool",
- "sbyte" => "ReadSByte",
- "short" => "ReadShort",
- "int" when argument == "EncodedInt" => "ReadEncodedInt",
- "int" => "ReadInt",
- "long" => "ReadLong",
- "byte" => "ReadByte",
- "ushort" => "ReadUShort",
- "uint" => "ReadUInt",
- "ulong" => "ReadULong",
- "float" => "ReadFloat",
- "double" => "ReadDouble",
- "string" => "ReadString",
- "decimal" => "ReadDecimal",
- date when argument == "DeltaTime" => "ReadDeltaTime",
- date => "ReadDateTime",
- ipAddress => "ReadIPAddress",
- timeSpan => "ReadTimeSpan"
- };
-
- var readArgument = readMethod == "ReadString" && argument == "InternString" ? "true" : "";
-
- source.AppendLine($"{indent}{propertyName} = reader.{readMethod}({readArgument});");
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null;
-
- var writeMethod = property.Type switch
- {
- "System.DateTime" when argument == "DeltaTime" => "WriteDeltaTime",
- "int" when argument == "EncodedInt" => "WriteEncodedInt",
- _ => "Write"
- };
-
- source.AppendLine($"{indent}writer.{writeMethod}({propertyName});");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs
deleted file mode 100644
index ec3562317..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/PrimitiveUOTypeMigrationRule.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: PrimitiveUOTypeMigrationRule.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public class PrimitiveUOTypeMigrationRule : ISerializableMigrationRule
- {
- public string RuleName => nameof(PrimitiveUOTypeMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- ruleArguments = symbol switch
- {
- _ when symbol.IsPoint2D(compilation) => new[] { "Point2D" },
- _ when symbol.IsPoint3D(compilation) => new[] { "Point3D" },
- _ when symbol.IsRectangle2D(compilation) => new[] { "Rect2D" },
- _ when symbol.IsRectangle3D(compilation) => new[] { "Rect3D" },
- _ when symbol.IsRace(compilation) => new[] { "Race" },
- _ when symbol.IsMap(compilation) => new[] { "Map" },
- _ => null
- };
-
- return ruleArguments != null;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName} = reader.Read{property.RuleArguments?[0] ?? ""}();");
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}writer.Write({propertyName});");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs
deleted file mode 100644
index e5ee8c725..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/RawSerializableMigrationRule.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: RawSerializableMigrationRule.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public class RawSerializableMigrationRule : ISerializableMigrationRule
- {
- public string RuleName => nameof(RawSerializableMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is not ITypeSymbol typeSymbol)
- {
- ruleArguments = null;
- return false;
- }
-
- if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes))
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = new[] { "" };
- return true;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName} = new {property.Type}({parentReference ?? "this"});");
- source.AppendLine($"{indent}{propertyName}.Deserialize(reader);");
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs
deleted file mode 100644
index 3cc932c80..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializableInterfaceMigrationRule.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableInterfaceMigrationRule.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public class SerializableInterfaceMigrationRule : ISerializableMigrationRule
- {
- public string RuleName => nameof(SerializableInterfaceMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes))
- {
- ruleArguments = Array.Empty();
- return true;
- }
-
- ruleArguments = null;
- return false;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName} = reader.ReadEntity<{property.Type}>();");
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}writer.Write({propertyName});");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs
deleted file mode 100644
index 1cd17971b..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/SerializationMethodSignatureMigrationRule.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializationMethodSignatureMigrationRule.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public class SerializationMethodSignatureMigrationRule : ISerializableMigrationRule
- {
- public string RuleName => nameof(SerializationMethodSignatureMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if ((symbol as ITypeSymbol)?.HasPublicSerializeMethod(compilation, serializableTypes) != true)
- {
- ruleArguments = null;
- return false;
- }
-
- if (symbol is not INamedTypeSymbol namedTypeSymbol ||
- !namedTypeSymbol.HasGenericReaderCtor(compilation, parentSymbol, out var requiresParent))
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = new[] { requiresParent ? "DeserializationRequiresParent" : "" };
- return true;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var argument = property.RuleArguments?.Length >= 1 &&
- property.RuleArguments[0] == "DeserializationRequiresParent" ? ", this" : "";
-
- source.AppendLine($"{indent}{propertyName} = new {property.Type}(reader{argument});");
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs b/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs
deleted file mode 100644
index 9fba1913a..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/Rules/TimerMigrationRule.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: TimerMigrationRule.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.Collections.Immutable;
-using System.Linq;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public class TimerMigrationRule : ISerializableMigrationRule, IPostDeserializeMethod
- {
- public string RuleName => nameof(TimerMigrationRule);
-
- public bool GenerateRuleState(
- Compilation compilation,
- ISymbol symbol,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- out string[] ruleArguments
- )
- {
- if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation)))
- {
- ruleArguments = null;
- return false;
- }
-
- ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation))
- ? new[] { "@TimerDrift" }
- : new[] { "" };
-
- return true;
- }
-
- public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var ruleArguments = property.RuleArguments;
- var driftTimer = ruleArguments![0].Contains("@TimerDrift");
-
- var readTimer = driftTimer ? "reader.ReadDeltaTime()" : "reader.ReadDateTime()";
- source.AppendLine($"{indent}var {propertyName}Next = {readTimer};");
- source.AppendLine($"{indent}var {propertyName}Delay = {propertyName}Next == System.DateTime.MinValue ? System.TimeSpan.MinValue : {propertyName}Next - Core.Now;");
- }
-
- public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
- {
- var expectedRule = RuleName;
- var ruleName = property.Rule;
- if (expectedRule != ruleName)
- {
- throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
- }
-
- var propertyName = property.Name;
- var ruleArguments = property.RuleArguments;
- var driftTimer = ruleArguments![0].Contains("@TimerDrift");
-
- var writerMethod = driftTimer ? "WriteDeltaTime" : "Write";
- source.AppendLine($"{indent}writer.{writerMethod}({propertyName}?.Next ?? System.DateTime.MinValue);");
- }
-
- public void PostDeserializeMethod(
- StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol
- )
- {
- var deserializeTimerMethod = classSymbol
- .GetMembers()
- .OfType()
- .FirstOrDefault(
- m =>
- {
- if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation))
- {
- return false;
- }
-
- return m.GetAttributes()
- .FirstOrDefault(
- attr =>
- {
- if (!SymbolEqualityComparer.Default.Equals(
- attr.AttributeClass,
- compilation.GetTypeByMetadataName(
- SymbolMetadata.DESERIALIZE_TIMER_FIELD_ATTRIBUTE
- )
- ))
- {
- return false;
- }
-
- var order = (int)attr.ConstructorArguments[0].Value!;
- return order == property.Order;
- }
- ) != null;
- }
- ) ?? throw new Exception("Serializing a timer requires a method with the DeserializeTimerField attribute to handle creating the timer itself.");
-
- source.AppendLine($"{indent}{deserializeTimerMethod.Name}({property.Name}Delay);");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs
deleted file mode 100644
index 13fd600b2..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializableMetadataComparer.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Collections.Generic;
-
-namespace SerializableMigration
-{
- public class SerializableMetadataComparer : IComparer
- {
- public int Compare(SerializableMetadata x, SerializableMetadata y)
- {
- if (ReferenceEquals(x, y))
- {
- return 0;
- }
-
- if (ReferenceEquals(null, y))
- {
- return 1;
- }
-
- if (ReferenceEquals(null, x))
- {
- return -1;
- }
-
- return x.Version.CompareTo(y.Version);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs
deleted file mode 100644
index 15abef66a..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationRulesEngine.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableMigrationRulesEngine.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.Collections.Generic;
-using System.Collections.Immutable;
-using Microsoft.CodeAnalysis;
-using SerializationGenerator;
-
-namespace SerializableMigration
-{
- public static class SerializableMigrationRulesEngine
- {
- public static readonly Dictionary Rules = new();
-
- static SerializableMigrationRulesEngine()
- {
- var rules = new ISerializableMigrationRule[]
- {
- new EnumMigrationRule(),
- new ListMigrationRule(),
- new ArrayMigrationRule(),
- new HashSetMigrationRule(),
- new KeyValuePairMigrationRule(),
- new PrimitiveTypeMigrationRule(),
- new PrimitiveUOTypeMigrationRule(),
- new SerializableInterfaceMigrationRule(),
- new SerializationMethodSignatureMigrationRule(),
- new RawSerializableMigrationRule(),
- new TimerMigrationRule()
- };
-
- foreach (var rule in rules)
- {
- Rules.Add(rule.RuleName, rule);
- }
- }
-
- public static SerializableProperty? GenerateSerializableProperty(
- Compilation compilation,
- ISymbol fieldOrPropertySymbol,
- int order,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- SerializableFieldSaveFlagMethods? serializableFieldSaveFlagMethods
- )
- {
- string propertyName;
- ITypeSymbol propertyType;
-
- if (fieldOrPropertySymbol is IFieldSymbol fieldSymbol)
- {
- propertyName = fieldSymbol.Name;
- propertyType = fieldSymbol.Type;
- }
- else if (fieldOrPropertySymbol is IPropertySymbol propertySymbol)
- {
- propertyName = fieldOrPropertySymbol.Name;
- propertyType = propertySymbol.Type;
- }
- else
- {
- return null;
- }
-
- return GenerateSerializableProperty(
- compilation,
- propertyName,
- propertyType,
- order,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- serializableFieldSaveFlagMethods
- );
- }
-
- public static SerializableProperty GenerateSerializableProperty(
- Compilation compilation,
- string propertyName,
- ISymbol propertyType,
- int order,
- ImmutableArray attributes,
- ImmutableArray serializableTypes,
- ImmutableArray embeddedSerializableTypes,
- ISymbol? parentSymbol,
- SerializableFieldSaveFlagMethods? serializableFieldSaveFlagMethods
- )
- {
- foreach (var rule in Rules.Values)
- {
- if (rule.GenerateRuleState(
- compilation,
- propertyType,
- attributes,
- serializableTypes,
- embeddedSerializableTypes,
- parentSymbol,
- out var ruleArguments
- ))
- {
- return new SerializableProperty
- {
- Name = propertyName,
- Type = propertyType.ToDisplayString(),
- Order = order,
- UsesSaveFlag = serializableFieldSaveFlagMethods?.DetermineFieldShouldSerialize != null ? true : null,
- Rule = rule.RuleName,
- RuleArguments = ruleArguments.Length > 0 ? ruleArguments : null
- };
- }
- }
-
- throw new Exception($"No rule found for property {propertyName} of type {propertyType} ({Rules.Count})");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs
deleted file mode 100644
index 52b94d505..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializableMigrationSchema.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableMigrationSchema.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.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.Json;
-using System.Text.RegularExpressions;
-using Microsoft.CodeAnalysis;
-
-namespace SerializableMigration
-{
- public static class SerializableMigrationSchema
- {
- public static JsonSerializerOptions GetJsonSerializerOptions() =>
- new()
- {
- WriteIndented = true,
- AllowTrailingCommas = true,
- IgnoreNullValues = true,
- ReadCommentHandling = JsonCommentHandling.Skip
- };
-
- private static Dictionary _cache = new();
-
- private static readonly Regex _fileRegex = new(@"\S+\.v\d+\.json$");
-
- public static List GetMigrations(
- INamedTypeSymbol typeSymbol,
- int version,
- string migrationPath,
- JsonSerializerOptions options
- )
- {
- var typeName = typeSymbol.ToDisplayString();
- var migrations = new SortedSet(new SerializableMetadataComparer());
-
- var migrationFiles = Directory.GetFiles(migrationPath, $"{typeName}.v*.json");
-
- foreach (var file in migrationFiles)
- {
- var fi = new FileInfo(file);
- if (!_cache.TryGetValue(fi.Name, out var migration))
- {
- var text = File.ReadAllText(file, Encoding.UTF8);
- migration = JsonSerializer.Deserialize(text, options);
- _cache[fi.Name] = migration;
- }
-
- if (typeName == migration!.Type && version > migration.Version)
- {
- migrations.Add(migration);
- }
- }
-
- return migrations.ToList();
- }
-
- public static List GetMigrationsByAnalyzerConfig(
- this GeneratorExecutionContext context,
- INamedTypeSymbol typeSymbol,
- int version,
- JsonSerializerOptions options
- )
- {
- var typeName = typeSymbol.ToDisplayString();
- var migrations = new SortedSet(new SerializableMetadataComparer());
-
- foreach (var additionalText in context.AdditionalFiles)
- {
- var fi = new FileInfo(additionalText.Path);
- if (!_fileRegex.IsMatch(fi.Name))
- {
- continue;
- }
-
- if (!_cache.TryGetValue(fi.Name, out var migration))
- {
- var text = additionalText.GetText(context.CancellationToken)?.ToString();
- if (text == null)
- {
- continue;
- }
-
- migration = JsonSerializer.Deserialize(text, options);
- _cache[fi.Name] = migration;
- }
-
- if (typeName == migration!.Type && version > migration.Version)
- {
- migrations.Add(migration);
- }
- }
-
- return migrations.ToList();
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs b/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs
deleted file mode 100644
index 1f6f0c55e..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializableProperty.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializableProperty.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.Text.Json.Serialization;
-
-namespace SerializableMigration
-{
- public record SerializableProperty
- {
- [JsonPropertyName("name")]
- public string Name { get; init; }
-
- [JsonPropertyName("type")]
- public string Type { get; init; }
-
- [JsonPropertyName("usesSaveFlag")]
- public bool? UsesSaveFlag { get; init; }
-
- [JsonPropertyName("rule")]
- public string Rule { get; init; }
-
- [JsonPropertyName("ruleArguments")]
- public string[]? RuleArguments { get; init; }
-
- [JsonIgnore]
- public int Order { get; init; }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs b/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs
deleted file mode 100644
index d4b736978..000000000
--- a/Projects/SerializationGenerator/SerializableMigration/SerializablePropertyComparer.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SerializablePropertyComparer.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.Collections.Generic;
-
-namespace SerializableMigration
-{
- public class SerializablePropertyComparer : IComparer
- {
- public int Compare(SerializableProperty x, SerializableProperty y)
- {
- if (Equals(x, y))
- {
- return 0;
- }
-
- if (Equals(null, y))
- {
- return 1;
- }
-
- if (Equals(null, x))
- {
- return -1;
- }
-
- return x.Order.CompareTo(y.Order);
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SerializationGenerator.csproj b/Projects/SerializationGenerator/SerializationGenerator.csproj
deleted file mode 100755
index 1839dfeb3..000000000
--- a/Projects/SerializationGenerator/SerializationGenerator.csproj
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
- netstandard2.0
- preview
- analyzers
-
-
-
-
-
-
-
-
-
-
-
- $(GetTargetPathDependsOn);GetDependencyTargetPaths
-
-
-
-
-
-
-
-
-
-
diff --git a/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs b/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs
deleted file mode 100755
index fea02e69d..000000000
--- a/Projects/SerializationGenerator/SerializerSyntaxReceiver.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SyntaxReceiver.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.Collections.Generic;
-using System.Collections.Immutable;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-
-namespace SerializationGenerator
-{
- public class SerializerSyntaxReceiver : ISyntaxContextReceiver
- {
-#pragma warning disable RS1024
- public Dictionary)> ClassAndFields { get; } = new(SymbolEqualityComparer.Default);
- public Dictionary)> EmbeddedClassAndFields { get; } = new(SymbolEqualityComparer.Default);
-#pragma warning restore RS1024
-
- public ImmutableArray SerializableList => ClassAndFields.Keys.ToImmutableArray();
-
- public ImmutableArray EmbeddedSerializableList => EmbeddedClassAndFields.Keys.ToImmutableArray();
-
- public void OnVisitSyntaxNode(SyntaxNode node, SemanticModel semanticModel)
- {
- var compilation = semanticModel.Compilation;
-
- if (node is ClassDeclarationSyntax { AttributeLists: { Count: > 0 } } classDeclarationSyntax)
- {
- if (semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol)
- {
- return;
- }
-
- if (classSymbol.IsEmbeddedSerializable(compilation, out var attrData))
- {
- if (EmbeddedClassAndFields.TryGetValue(classSymbol, out var value))
- {
- var (_, fieldsList) = value;
- EmbeddedClassAndFields[classSymbol] = (attrData, fieldsList);
- }
- else
- {
- EmbeddedClassAndFields.Add(classSymbol, (attrData, new List()));
- }
- }
- else if (classSymbol.WillBeSerializable(compilation, out attrData))
- {
- if (ClassAndFields.TryGetValue(classSymbol, out var value))
- {
- var (_, fieldsList) = value;
- ClassAndFields[classSymbol] = (attrData, fieldsList);
- }
- else
- {
- ClassAndFields.Add(classSymbol, (attrData, new List()));
- }
- }
-
- return;
- }
-
- if (node is FieldDeclarationSyntax { AttributeLists: { Count: > 0 } } fieldDeclarationSyntax)
- {
- foreach (var variable in fieldDeclarationSyntax.Declaration.Variables)
- {
- if (semanticModel.GetDeclaredSymbol(variable) is IFieldSymbol fieldSymbol)
- {
- AddFieldOrProperty(fieldSymbol, compilation);
- }
- }
-
- return;
- }
-
- if (node is PropertyDeclarationSyntax { AttributeLists: { Count: > 0 } } propertyDeclarationSyntax)
- {
- if (semanticModel.GetDeclaredSymbol(propertyDeclarationSyntax) is IPropertySymbol propertySymbol)
- {
- AddFieldOrProperty(propertySymbol, compilation);
- }
- }
- }
-
- public void OnVisitSyntaxNode(GeneratorSyntaxContext context) =>
- OnVisitSyntaxNode(context.Node, context.SemanticModel);
-
- private void AddFieldOrProperty(ISymbol symbol, Compilation compilation)
- {
- var serializableFieldAttr = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTRIBUTE);
- var parentAttr = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE);
-
- if (symbol.GetAttribute(serializableFieldAttr) == null && symbol.GetAttribute(parentAttr) == null)
- {
- return;
- }
-
- var classSymbol = symbol.ContainingType;
- if (ClassAndFields.TryGetValue(classSymbol, out var value))
- {
- var (_, fieldsList) = value;
- fieldsList.Add(symbol);
- return;
- }
-
- if (EmbeddedClassAndFields.TryGetValue(classSymbol, out value))
- {
- var (_, fieldsList) = value;
- fieldsList.Add(symbol);
- return;
- }
-
- if (classSymbol.WillBeSerializable(compilation, out var attrData))
- {
- ClassAndFields.Add(classSymbol, (attrData, new List { symbol }));
- }
- else if (classSymbol.IsEmbeddedSerializable(compilation, out attrData))
- {
- EmbeddedClassAndFields.Add(classSymbol, (attrData, new List { symbol }));
- }
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/Helpers.cs b/Projects/SerializationGenerator/SourceGeneration/Helpers.cs
deleted file mode 100644
index f1a9a88e5..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/Helpers.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: Helpers.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.Collections.Generic;
-using System.Collections.Immutable;
-using System.Linq;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-
-namespace SerializationGenerator
-{
- public static class Helpers
- {
- public static bool ContainsInterface(this ITypeSymbol symbol, ISymbol interfaceSymbol) =>
- symbol.Interfaces.Any(i => i.ConstructedFrom.Equals(interfaceSymbol, SymbolEqualityComparer.Default)) ||
- symbol.AllInterfaces.Any(i => i.ConstructedFrom.Equals(interfaceSymbol, SymbolEqualityComparer.Default));
-
- public static ImmutableArray GetAllMethods(this ITypeSymbol symbol, string name)
- {
- var methods = symbol.GetMembers(name).OfType().ToImmutableArray();
- if (symbol.ContainingSymbol is not ITypeSymbol typeSymbol)
- {
- return methods;
- }
-
- var list = new List();
- list.AddRange(methods.ToList());
- list.AddRange(GetAllMethods(typeSymbol, name).ToList());
-
- return list.ToImmutableArray();
- }
-
- public static string ToFriendlyString(this Accessibility accessibility) => SyntaxFacts.GetText(accessibility);
-
- public static Accessibility GetAccessibility(string? value) =>
- value switch
- {
- "private" => Accessibility.Private,
- "protected" => Accessibility.Protected,
- "internal" => Accessibility.Internal,
- "public" => Accessibility.Public,
- "protected internal" => Accessibility.ProtectedOrInternal,
- "private protected" => Accessibility.ProtectedAndInternal,
- _ => Accessibility.NotApplicable
- };
-
- public static bool CanBeConstructedFrom(this ITypeSymbol? symbol, ISymbol classSymbol) =>
- symbol is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.ConstructedFrom.Equals(
- classSymbol,
- SymbolEqualityComparer.Default
- ) || symbol != null && CanBeConstructedFrom(symbol.BaseType, classSymbol);
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs
deleted file mode 100644
index 53dc5823c..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Arguments.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SourceGeneration.Arguments.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.Collections.Generic;
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SourceGeneration
- {
- public static void GetTypesFromTypedConstant(TypedConstant arg, List list)
- {
- if (arg.Kind == TypedConstantKind.Type)
- {
- list.Add((ITypeSymbol)arg.Value);
- }
- else if (arg.Kind == TypedConstantKind.Array)
- {
- for (var i = 0; i < arg.Values.Length; i++)
- {
- GetTypesFromTypedConstant(arg.Values[i], list);
- }
- }
- }
-
- public static void GenerateSignatureArguments(this StringBuilder source, ImmutableArray<(ITypeSymbol, string)> parameters)
- {
- for (var i = 0; i < parameters.Length; i++)
- {
- var (t, v) = parameters[i];
- source.AppendFormat("{0} {1}", t.ToDisplayString(), v);
- if (i < parameters.Length - 1)
- {
- source.Append(", ");
- }
- }
- }
-
- public static void GenerateNamedArgument(this StringBuilder source, KeyValuePair namedArg)
- {
- source.AppendFormat("{0} = ", namedArg.Key);
- source.GenerateTypedConstant(namedArg.Value);
- }
-
- public static void GenerateTypedConstants(this StringBuilder source, ImmutableArray args)
- {
- source.Append("new []{");
- for (var i = 0; i < args.Length; i++)
- {
- source.GenerateTypedConstant(args[i]);
- if (i < args.Length - 1)
- {
- source.Append(", ");
- }
- }
- source.Append('}');
- }
-
- public static void GenerateTypedConstant(this StringBuilder source, TypedConstant arg)
- {
- if (arg.IsNull)
- {
- source.Append("null");
- return;
- }
-
- switch (arg.Kind)
- {
- default:
- {
- return;
- }
- case TypedConstantKind.Primitive:
- {
-
- if (arg.Value is string str)
- {
- source.AppendFormat("\"{0}\"", str);
- }
- else
- {
- source.Append(arg.Value);
- }
- break;
- }
- case TypedConstantKind.Enum:
- {
- if (arg.Type == null || arg.Value == null)
- {
- source.Append("null");
- }
- else
- {
- source.AppendFormat("({0}){1}", arg.Type.ToDisplayString(), arg.Value);
- }
- break;
- }
- case TypedConstantKind.Type:
- {
- source.AppendFormat("typeof({0})", ((ITypeSymbol)arg.Value)?.Name);
- break;
- }
- case TypedConstantKind.Array:
- {
- source.GenerateTypedConstants(arg.Values);
- break;
- }
- }
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs
deleted file mode 100644
index eda4cf08c..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Attribute.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SourceGeneration.Attribute.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SourceGeneration
- {
- public static void GenerateAttribute(
- this StringBuilder source,
- string indent,
- string attrClassName,
- ImmutableArray args
- )
- {
- source.Append($"{indent}[{attrClassName}");
- var hasArgs = args.Length > 0;
-
- if (hasArgs)
- {
- source.Append("(");
- }
-
- for (var i = 0; i < args.Length; i++)
- {
- var arg = args[i];
- source.GenerateTypedConstant(arg);
- if (i < args.Length - 1)
- {
- source.Append(", ");
- }
- }
-
- if (hasArgs)
- {
- source.Append(")");
- }
-
- source.AppendLine("]");
- }
-
- public static void GenerateAttribute(this StringBuilder source, AttributeData attr)
- {
- source.Append($" [{attr.AttributeClass?.Name}");
- var ctorArgs = attr.ConstructorArguments;
- var namedArgs = attr.NamedArguments;
- var hasArgs = ctorArgs.Length + namedArgs.Length > 0;
-
- if (hasArgs)
- {
- source.Append("(");
- }
-
- for (var i = 0; i < ctorArgs.Length; i++)
- {
- var arg = ctorArgs[i];
- source.GenerateTypedConstant(arg);
- if (i < ctorArgs.Length - 1)
- {
- source.Append(", ");
- }
- }
-
- for (var i = 0; i < namedArgs.Length; i++)
- {
- var arg = namedArgs[i];
- source.GenerateNamedArgument(arg);
- if (i < namedArgs.Length - 1)
- {
- source.Append(", ");
- }
- }
-
- if (hasArgs)
- {
- source.Append(")");
- }
-
- source.AppendLine("]");
- }
-
- public static void AggressiveInline(this StringBuilder source, string indent) =>
- source.AppendLine(
- $"{indent}[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]"
- );
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs
deleted file mode 100644
index c25999cd8..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Class.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SourceGeneration.Class.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SourceGeneration
- {
- public static void GenerateClassStart(
- this StringBuilder source,
- INamedTypeSymbol classSymbol,
- string indent,
- ImmutableArray interfaces,
- bool isPartial = true
- )
- {
- var accessor = classSymbol.DeclaredAccessibility;
- source.Append($"{indent}{accessor.ToFriendlyString()} {(isPartial ? "partial " : "")}class {classSymbol.Name}");
- if (!interfaces.IsEmpty)
- {
- source.Append(" : ");
- for (var i = 0; i < interfaces.Length; i++)
- {
- source.Append(interfaces[i].ToDisplayString());
- if (i < interfaces.Length - 1)
- {
- source.Append(", ");
- }
- }
- }
-
- source.AppendLine($"\n{indent}{{");
- }
-
- public static void GenerateClassEnd(this StringBuilder source, string indent)
- {
- source.AppendLine($"{indent}}}");
- }
-
- // TODO: Generalize this to any field using dynamic indentation
- public static void GenerateClassField(
- this StringBuilder source,
- string indent,
- Accessibility accessors,
- InstanceModifier instance,
- string type,
- string variableName,
- string value
- )
- {
- var instanceStr = instance == InstanceModifier.None ? "" : $"{instance.ToFriendlyString()} ";
- var accessorStr = accessors == Accessibility.NotApplicable ? "" : $"{accessors.ToFriendlyString()} ";
- var valueStr = value == null ? "" : $" = {value}";
- source.AppendLine($"{indent}{accessorStr}{instanceStr}{type} {variableName}{valueStr};");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs
deleted file mode 100644
index 6f8213561..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Enum.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SourceGeneration.Enum.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.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SourceGeneration
- {
- public static void GenerateEnumStart(
- this StringBuilder source,
- string enumName,
- string indent,
- bool useFlags,
- Accessibility accessor = Accessibility.Public
- )
- {
- if (useFlags)
- {
- source.AppendLine($"{indent}[System.Flags]");
- }
- source.AppendLine($"{indent}{accessor.ToFriendlyString()} enum {enumName}\n{indent}{{");
- }
-
- public static void GenerateEnumValue(this StringBuilder source, string indent, bool isFlag, string name, int value)
- {
- var number = value < 0 ? 0 : 1 << value;
- var valueStr = isFlag ? $"0x{number:X8}" : value.ToString();
- source.AppendLine($"{indent}{name} = {valueStr},");
- }
-
- public static void GenerateEnumEnd(this StringBuilder source, string indent)
- {
- source.AppendLine($"{indent}}}");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs
deleted file mode 100644
index 2fdfef6da..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.InstanceModifier.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SourceGeneration.InstanceModifier.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 . *
- *************************************************************************/
-
-namespace SerializationGenerator
-{
- public enum InstanceModifier
- {
- None,
- Const,
- ReadOnly,
- Static,
- StaticReadOnly
- }
-
- public static partial class SourceGeneration
- {
- public static string ToFriendlyString(this InstanceModifier modifier) =>
- modifier switch
- {
- InstanceModifier.Const => "const",
- InstanceModifier.ReadOnly => "readonly",
- InstanceModifier.Static => "static",
- InstanceModifier.StaticReadOnly => "static readonly",
- _ => ""
- };
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs
deleted file mode 100644
index 407fd3e32..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Method.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SourceGeneration.Method.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.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SourceGeneration
- {
- public static void GenerateMethodStart(
- this StringBuilder source, string indent, string methodName, Accessibility accessors, bool isOverride,
- string returnType, ImmutableArray<(ITypeSymbol, string)> parameters
- )
- {
- source.Append($"{indent}{accessors.ToFriendlyString()}{(isOverride ? " override" : "")} {returnType} {methodName}(");
- source.GenerateSignatureArguments(parameters);
- source.AppendLine($")\n{indent}{{");
- }
-
- public static void GenerateMethodEnd(this StringBuilder source, string indent) => source.AppendLine($"{indent}}}");
-
- public static void GenerateConstructorStart(
- this StringBuilder source, string indent, string className, Accessibility accessors, ImmutableArray<(ITypeSymbol, string)> parameters,
- ImmutableArray baseParameters, bool isOverload = false
- )
- {
- source.Append($"{indent}{accessors.ToFriendlyString()} {className}(");
- source.GenerateSignatureArguments(parameters);
- source.Append(')');
- bool hasBaseParams = baseParameters.Length > 0;
- if (hasBaseParams)
- {
- source.AppendFormat(" : {0}(", isOverload ? "this" : "base");
- for (int i = 0; i < baseParameters.Length; i++)
- {
- source.Append(baseParameters[i]);
- if (i < baseParameters.Length - 1)
- {
- source.Append(',');
- }
- }
- source.Append(')');
- }
-
- source.AppendLine($"\n{indent}{{");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs
deleted file mode 100644
index 24ced2544..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Namespace.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SourceGeneration.Namespace.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.Text;
-
-namespace SerializationGenerator
-{
- public static partial class SourceGeneration
- {
- public static void GenerateNamespaceStart(this StringBuilder source, string namespaceName)
- {
- source.AppendLine($@"namespace {namespaceName}
-{{");
- }
-
- public static void GenerateNamespaceEnd(this StringBuilder source)
- {
- source.AppendLine("}");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs b/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs
deleted file mode 100644
index fc66bc985..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SourceGeneration.Property.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright (C) 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SourceGeneration.Property.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.Text;
-using Humanizer;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SourceGeneration
- {
- public static string GetPropertyName(this IFieldSymbol fieldSymbol)
- {
- var fieldName = fieldSymbol.Name;
-
- var propertyName = fieldName;
-
- if (propertyName.StartsWith("m_", StringComparison.OrdinalIgnoreCase))
- {
- propertyName = propertyName.Substring(2);
- }
- else if (propertyName.StartsWith("_", StringComparison.OrdinalIgnoreCase))
- {
- propertyName = propertyName.Substring(1);
- }
-
- return propertyName.Dehumanize();
- }
-
- public static void GeneratePropertyStart(
- this StringBuilder source,
- string indent,
- Accessibility accessors,
- bool isVirtual,
- IFieldSymbol fieldSymbol
- )
- {
- var propertyName = fieldSymbol.GetPropertyName();
- var virt = isVirtual ? "virtual " : "";
-
- source.AppendLine($"{indent}{accessors.ToFriendlyString()} {virt}{fieldSymbol.Type} {propertyName}");
- source.AppendLine($"{indent}{{");
- }
-
- public static void GenerateAutoProperty(
- this StringBuilder source,
- Accessibility accessors,
- string type,
- string propertyName,
- Accessibility? getAccessor,
- Accessibility? setAccessor,
- string indent,
- bool useInit = false,
- string defaultValue = null,
- bool isOverride = false
- )
- {
- if (getAccessor == null && setAccessor == null)
- {
- throw new ArgumentNullException($"Must specify a {nameof(getAccessor)} or {nameof(setAccessor)} parameter");
- }
-
- var getter = getAccessor == null ?
- "" :
- $"{(getAccessor != Accessibility.NotApplicable ? $"{getAccessor.Value.ToFriendlyString()} " : "")}get;";
-
- var getterSpace = getAccessor != null ? " " : "";
- var setOrInit = useInit ? "init;" : "set;";
-
- var setterAccessor = setAccessor is null or Accessibility.NotApplicable
- ? ""
- : $"{setAccessor.Value.ToFriendlyString() ?? ""} ";
-
- var setter = setAccessor == null ? "" : $"{getterSpace}{setterAccessor}{setOrInit}";
-
- var propertyAccessor = accessors == Accessibility.NotApplicable ? "" : $"{accessors.ToFriendlyString()} ";
- var printOverride = isOverride ? "override " : "";
- var printDefaultValue = defaultValue != null ? $"{(setAccessor != null ? " =" : "")} {defaultValue};" : "";
- var printGetterSetter = setAccessor == null ? "=>" : $"{{ {getter}{setter} }}";
-
- source.AppendLine($"{indent}{propertyAccessor}{printOverride}{type} {propertyName} {printGetterSetter}{printDefaultValue}");
- }
-
- public static void GeneratePropertyEnd(this StringBuilder source, string indent) => source.AppendLine($"{indent}}}");
-
- public static void GeneratePropertyGetterReturnsField(
- this StringBuilder source,
- string indent,
- IFieldSymbol fieldSymbol,
- Accessibility Accessibility
- )
- {
- var accessor = Accessibility != Accessibility.NotApplicable ? $"{Accessibility.ToFriendlyString()} " : "";
- source.AppendLine($"{indent}{accessor}get => {fieldSymbol.Name};");
- }
-
- public static void GeneratePropertyGetterStart(
- this StringBuilder source,
- string indent,
- bool useExpression,
- Accessibility Accessibility
- )
- {
- var accessor = Accessibility != Accessibility.NotApplicable ? $"{Accessibility.ToFriendlyString()} " : "";
- var expression = useExpression ? " => " : $"\n{indent}{{";
- source.AppendLine($"{indent}{accessor}get{expression}");
- }
-
- public static void GeneratePropertyGetSetEnd(this StringBuilder source, string indent, bool useExpression)
- {
- if (!useExpression)
- {
- source.AppendLine($"{indent}}}");
- }
- }
-
- public static void GeneratePropertySetterStart(
- this StringBuilder source,
- string indent,
- bool useExpression,
- Accessibility Accessibility,
- bool useInit = false
- )
- {
- var init = useInit ? "init" : "set";
- var expression = useExpression ? " => " : $"\n{indent}{{";
- var accessor = Accessibility != Accessibility.NotApplicable ? $"{Accessibility.ToFriendlyString()} " : "";
- source.AppendLine($"{indent}{accessor}{init}{expression}");
- }
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs b/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs
deleted file mode 100644
index af2bc3241..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.Builtin.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SymbolMetadata.Builtin.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 Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SymbolMetadata
- {
- public const string LIST_CLASS = "System.Collections.Generic.List`1";
- public const string HASHSET_CLASS = "System.Collections.Generic.HashSet`1";
- public const string IPADDRESS_CLASS = "System.Net.IPAddress";
- public const string KEYVALUEPAIR_STRUCT = "System.Collections.Generic.KeyValuePair";
- public const string TIMESPAN_STRUCT = "System.TimeSpan";
-
- public static bool IsTimeSpan(this ISymbol symbol, Compilation compilation) =>
- symbol.Equals(
- compilation.GetTypeByMetadataName(TIMESPAN_STRUCT),
- SymbolEqualityComparer.Default
- );
-
- public static bool IsIpAddress(this ISymbol symbol, Compilation compilation) =>
- symbol.Equals(
- compilation.GetTypeByMetadataName(IPADDRESS_CLASS),
- SymbolEqualityComparer.Default
- );
-
- public static bool IsKeyValuePair(this ISymbol symbol, Compilation compilation) =>
- (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals(
- compilation.GetTypeByMetadataName(KEYVALUEPAIR_STRUCT),
- SymbolEqualityComparer.Default
- ) == true;
-
- public static bool IsList(this ISymbol symbol, Compilation compilation) =>
- (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals(
- compilation.GetTypeByMetadataName(LIST_CLASS),
- SymbolEqualityComparer.Default
- ) == true;
-
- public static bool IsHashSet(this ISymbol symbol, Compilation compilation) =>
- (symbol as INamedTypeSymbol)?.ConstructedFrom.Equals(
- compilation.GetTypeByMetadataName(HASHSET_CLASS),
- SymbolEqualityComparer.Default
- ) == true;
-
- public static bool IsPrimitiveFromTypeDisplayString(string type) =>
- type is "bool" or "sbyte" or "short" or "int" or "long" or "byte" or "ushort"
- or "uint" or "ulong" or "float" or "double" or "string" or "decimal";
- }
-}
diff --git a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs b/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs
deleted file mode 100644
index 9b88b7493..000000000
--- a/Projects/SerializationGenerator/SourceGeneration/SymbolMetadata/SymbolMetadata.UO.cs
+++ /dev/null
@@ -1,220 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SymbolMetadata.UO.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.Collections.Immutable;
-using System.Linq;
-using Microsoft.CodeAnalysis;
-
-namespace SerializationGenerator
-{
- public static partial class SymbolMetadata
- {
- public const string INVALIDATEPROPERTIES_ATTRIBUTE = "Server.InvalidatePropertiesAttribute";
- public const string AFTERDESERIALIZATION_ATTRIBUTE = "Server.AfterDeserializationAttribute";
- public const string SERIALIZABLE_ATTRIBUTE = "Server.SerializableAttribute";
- public const string EMBEDDED_SERIALIZABLE_ATTRIBUTE = "Server.EmbeddedSerializableAttribute";
- public const string SERIALIZABLE_PARENT_ATTRIBUTE = "Server.SerializableParentAttribute";
- public const string SERIALIZABLE_FIELD_ATTRIBUTE = "Server.SerializableFieldAttribute";
- public const string SERIALIZABLE_FIELD_ATTR_ATTRIBUTE = "Server.SerializableFieldAttrAttribute";
- public const string SERIALIZABLE_INTERFACE = "Server.ISerializable";
- public const string GENERIC_WRITER_INTERFACE = "Server.IGenericWriter";
- public const string GENERIC_READER_INTERFACE = "Server.IGenericReader";
- public const string DELTA_DATE_TIME_ATTRIBUTE = "Server.DeltaDateTimeAttribute";
- public const string INTERN_STRING_ATTRIBUTE = "Server.InternStringAttribute";
- public const string ENCODED_INT_ATTRIBUTE = "Server.EncodedIntAttribute";
- public const string TIDY_ATTRIBUTE = "Server.TidyAttribute";
- public const string POINT2D_STRUCT = "Server.Point2D";
- public const string POINT3D_STRUCT = "Server.Point3D";
- public const string RECTANGLE2D_STRUCT = "Server.Rectangle2D";
- public const string RECTANGLE3D_STRUCT = "Server.Rectangle3D";
- public const string RACE_CLASS = "Server.Race";
- public const string MAP_CLASS = "Server.Map";
- public const string TIMER_CLASS = "Server.Timer";
- public const string TIMER_DRIFT_ATTRIBUTE = "Server.TimerDriftAttribute";
- public const string DESERIALIZE_TIMER_FIELD_ATTRIBUTE = "Server.DeserializeTimerFieldAttribute";
- public const string SERIALIZABLE_FIELD_SAVE_FLAG_ATTRIBUTE = "Server.SerializableFieldSaveFlagAttribute";
- public const string SERIALIZABLE_FIELD_DEFAULT_ATTRIBUTE = "Server.SerializableFieldDefaultAttribute";
- public const string RAW_SERIALIZABLE_INTERFACE = "Server.IRawSerializable";
-
- public static bool IsTimerDrift(this AttributeData attr, Compilation compilation) =>
- attr?.IsAttribute(compilation.GetTypeByMetadataName(TIMER_DRIFT_ATTRIBUTE)) == true;
-
- public static bool IsTimer(this ITypeSymbol symbol, Compilation compilation) =>
- symbol.CanBeConstructedFrom(compilation.GetTypeByMetadataName(TIMER_CLASS));
-
- public static bool IsEncodedInt(this AttributeData attr, Compilation compilation) =>
- attr?.IsAttribute(compilation.GetTypeByMetadataName(ENCODED_INT_ATTRIBUTE)) == true;
-
- public static bool IsDeltaDateTime(this AttributeData attr, Compilation compilation) =>
- attr?.IsAttribute(compilation.GetTypeByMetadataName(DELTA_DATE_TIME_ATTRIBUTE)) == true;
-
- public static bool IsInternString(this AttributeData attr, Compilation compilation) =>
- attr?.IsAttribute(compilation.GetTypeByMetadataName(INTERN_STRING_ATTRIBUTE)) == true;
-
- public static bool IsTidy(this AttributeData attr, Compilation compilation) =>
- attr?.IsAttribute(compilation.GetTypeByMetadataName(TIDY_ATTRIBUTE)) == true;
-
- public static bool IsAttribute(this AttributeData attr, ISymbol symbol) =>
- attr?.AttributeClass?.Equals(symbol, SymbolEqualityComparer.Default) == true;
-
- public static bool IsEnum(this ITypeSymbol symbol) =>
- symbol.SpecialType == SpecialType.System_Enum || symbol.TypeKind == TypeKind.Enum;
-
- public static bool HasSerializableInterface(
- this ITypeSymbol symbol,
- Compilation compilation,
- ImmutableArray serializableTypes
- ) =>
- symbol.ContainsInterface(compilation.GetTypeByMetadataName(SERIALIZABLE_INTERFACE)) ||
- serializableTypes.Contains(symbol);
-
- public static bool HasRawSerializableInterface(
- this ITypeSymbol symbol,
- Compilation compilation,
- ImmutableArray embeddedSerializableTypes
- ) =>
- symbol.ContainsInterface(compilation.GetTypeByMetadataName(RAW_SERIALIZABLE_INTERFACE)) ||
- embeddedSerializableTypes.Contains(symbol);
-
- public static bool Contains(this ImmutableArray symbols, ITypeSymbol? symbol) =>
- symbol is INamedTypeSymbol namedSymbol &&
- symbols.Contains(namedSymbol, SymbolEqualityComparer.Default) || symbols.Contains(symbol?.BaseType);
-
- public static bool HasGenericReaderCtor(
- this INamedTypeSymbol symbol,
- Compilation compilation,
- ISymbol? parentSymbol,
- out bool requiresParent
- )
- {
- var genericReaderInterface = compilation.GetTypeByMetadataName(GENERIC_READER_INTERFACE);
- var genericCtor = symbol.Constructors.FirstOrDefault(
- m => !m.IsStatic &&
- m.MethodKind == MethodKind.Constructor &&
- m.Parameters.Length >= 1 &&
- m.Parameters.Length <= 2 &&
- SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericReaderInterface)
- );
-
- requiresParent = genericCtor?.Parameters.Length == 2 && SymbolEqualityComparer.Default.Equals(genericCtor.Parameters[1].Type, parentSymbol);
- return genericCtor != null;
- }
-
- public static bool HasPublicSerializeMethod(
- this ITypeSymbol symbol,
- Compilation compilation,
- ImmutableArray serializableTypes
- )
- {
- var genericWriterInterface = compilation.GetTypeByMetadataName(GENERIC_WRITER_INTERFACE);
-
- return symbol.GetAllMethods("Serialize")
- .Any(
- m => !m.IsStatic &&
- m.ReturnsVoid &&
- m.Parameters.Length == 1 &&
- SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericWriterInterface) &&
- m.DeclaredAccessibility == Accessibility.Public
- );
- }
-
- public static bool HasPublicDeserializeMethod(
- this ITypeSymbol symbol,
- Compilation compilation,
- ImmutableArray serializableTypes
- )
- {
- var genericReaderInterface = compilation.GetTypeByMetadataName(GENERIC_READER_INTERFACE);
-
- return symbol.GetAllMethods("Deserialize")
- .Any(
- m => !m.IsStatic &&
- m.ReturnsVoid &&
- m.Parameters.Length == 1 &&
- SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericReaderInterface) &&
- m.DeclaredAccessibility == Accessibility.Public
- );
- }
-
- public static bool IsPoint2D(this ISymbol symbol, Compilation compilation) =>
- symbol.Equals(
- compilation.GetTypeByMetadataName(POINT2D_STRUCT),
- SymbolEqualityComparer.Default
- );
-
- public static bool IsPoint3D(this ISymbol symbol, Compilation compilation) =>
- symbol.Equals(
- compilation.GetTypeByMetadataName(POINT3D_STRUCT),
- SymbolEqualityComparer.Default
- );
-
- public static bool IsRectangle2D(this ISymbol symbol, Compilation compilation) =>
- symbol.Equals(
- compilation.GetTypeByMetadataName(RECTANGLE2D_STRUCT),
- SymbolEqualityComparer.Default
- );
-
- public static bool IsRectangle3D(this ISymbol symbol, Compilation compilation) =>
- symbol.Equals(
- compilation.GetTypeByMetadataName(RECTANGLE3D_STRUCT),
- SymbolEqualityComparer.Default
- );
-
- public static bool IsRace(this ISymbol symbol, Compilation compilation) =>
- symbol.Equals(
- compilation.GetTypeByMetadataName(RACE_CLASS),
- SymbolEqualityComparer.Default
- );
-
- public static bool IsMap(this ISymbol symbol, Compilation compilation) =>
- symbol.Equals(
- compilation.GetTypeByMetadataName(MAP_CLASS),
- SymbolEqualityComparer.Default
- );
-
- public static AttributeData? GetAttribute(this ISymbol symbol, ISymbol attrSymbol) =>
- symbol
- .GetAttributes()
- .FirstOrDefault(
- ad => ad.AttributeClass != null && SymbolEqualityComparer.Default.Equals(ad.AttributeClass, attrSymbol)
- );
-
- public static bool WillBeSerializable(this INamedTypeSymbol classSymbol, Compilation compilation, out AttributeData? attributeData)
- {
- var serializableInterface = compilation.GetTypeByMetadataName(SERIALIZABLE_INTERFACE);
-
- if (!classSymbol.ContainsInterface(serializableInterface))
- {
- attributeData = null;
- return false;
- }
-
- var serializableEntityAttribute =
- compilation.GetTypeByMetadataName(SERIALIZABLE_ATTRIBUTE);
-
- attributeData = classSymbol.GetAttribute(serializableEntityAttribute);
- return attributeData != null;
- }
-
- public static bool IsEmbeddedSerializable(this INamedTypeSymbol classSymbol, Compilation compilation, out AttributeData? attributeData)
- {
- var embeddedSerializableEntityAttribute =
- compilation.GetTypeByMetadataName(EMBEDDED_SERIALIZABLE_ATTRIBUTE);
-
- attributeData = classSymbol.GetAttribute(embeddedSerializableEntityAttribute);
- return attributeData != null;
- }
- }
-}
diff --git a/Projects/SerializationGenerator/Utility.cs b/Projects/SerializationGenerator/Utility.cs
deleted file mode 100644
index ad3f9c9c8..000000000
--- a/Projects/SerializationGenerator/Utility.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: Utility.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.Collections.Generic;
-
-namespace SerializationGenerator
-{
- public static class Utility
- {
- public static void Deconstruct(this KeyValuePair tuple, out T1 key, out T2 value)
- {
- key = tuple.Key;
- value = tuple.Value;
- }
- }
-}
diff --git a/Projects/SerializationSchemaGenerator/.gitignore b/Projects/SerializationSchemaGenerator/.gitignore
deleted file mode 100644
index 2fe317a80..000000000
--- a/Projects/SerializationSchemaGenerator/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-Output/
diff --git a/Projects/SerializationSchemaGenerator/Application.cs b/Projects/SerializationSchemaGenerator/Application.cs
deleted file mode 100644
index e8634aab7..000000000
--- a/Projects/SerializationSchemaGenerator/Application.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: Application.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.Collections.Immutable;
-using System.IO;
-using System.Text.Json;
-using System.Threading.Tasks;
-using SerializationGenerator;
-
-namespace SerializationSchemaGenerator
-{
- public static class Application
- {
- public static void Main(string[] args)
- {
- if (args.Length < 1)
- {
- throw new ArgumentException("Usage: dotnet SerializationSchemaGenerator.dll ");
- }
-
- var solutionPath = args[0];
-
- Parallel.ForEach(
- SourceCodeAnalysis.GetCompilation(solutionPath),
- (projectCompilation) =>
- {
- var (project, compilation) = projectCompilation;
- if (project.Name.EndsWith(".Tests", StringComparison.Ordinal) || project.Name == "Benchmarks")
- {
- return;
- }
-
- var projectFile = new FileInfo(project.FilePath!);
- var projectPath = projectFile.Directory?.FullName;
- var migrationPath = Path.Join(projectPath, "Migrations");
- Directory.CreateDirectory(migrationPath);
-
- var syntaxReceiver = new SerializerSyntaxReceiver();
-
- foreach (var syntaxTree in compilation.SyntaxTrees)
- {
- var root = syntaxTree.GetRoot();
- var syntaxVisitor = new SyntaxVisitor(compilation.GetSemanticModel(syntaxTree), syntaxReceiver);
- syntaxVisitor.Visit(root);
- }
-
- var jsonOptions = new JsonSerializerOptions
- {
- WriteIndented = true,
- AllowTrailingCommas = true,
- IgnoreNullValues = true,
- ReadCommentHandling = JsonCommentHandling.Skip
- };
-
- var serializableTypes = syntaxReceiver.SerializableList;
- var embeddedSerializableTypes = syntaxReceiver.EmbeddedSerializableList;
-
- foreach (var (classSymbol, (attributeData, fieldsList)) in syntaxReceiver.ClassAndFields)
- {
- var source = compilation.GenerateSerializationPartialClass(
- classSymbol,
- attributeData,
- migrationPath,
- false,
- jsonOptions,
- fieldsList.ToImmutableArray(),
- serializableTypes,
- embeddedSerializableTypes
- );
- }
-
- foreach (var (classSymbol, (attributeData, fieldsList)) in syntaxReceiver.EmbeddedClassAndFields)
- {
- var source = compilation.GenerateSerializationPartialClass(
- classSymbol,
- attributeData,
- migrationPath,
- true,
- jsonOptions,
- fieldsList.ToImmutableArray(),
- serializableTypes,
- embeddedSerializableTypes
- );
- }
- }
- );
- }
- }
-}
diff --git a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj b/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
deleted file mode 100755
index 31e89d561..000000000
--- a/Projects/SerializationSchemaGenerator/SerializationSchemaGenerator.csproj
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
- Exe
- net5.0
- Output
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
diff --git a/Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs b/Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs
deleted file mode 100644
index ac578b406..000000000
--- a/Projects/SerializationSchemaGenerator/SourceCodeAnalysis.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SourceCodeAnalysis.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.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Microsoft.Build.Locator;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.MSBuild;
-
-namespace SerializationSchemaGenerator
-{
- public static class SourceCodeAnalysis
- {
- public static List<(Project, Compilation)> GetCompilation(string solutionPath)
- {
- if (!File.Exists(solutionPath) || !solutionPath.EndsWith(".sln", StringComparison.Ordinal))
- {
- throw new FileNotFoundException($"Could not open a valid solution at location {solutionPath}");
- }
-
- MSBuildLocator.RegisterDefaults();
-
- var workspace = MSBuildWorkspace.Create();
-
- var solutionToAnalyze = workspace.OpenSolutionAsync(solutionPath).Result;
-
- var results = solutionToAnalyze.Projects.AsParallel()
- .Select((project) => (project, project?.GetCompilationAsync().Result))
- .Where((value) => value.Result != null)
- .ToList();
-
- return results;
- }
- }
-}
diff --git a/Projects/SerializationSchemaGenerator/SyntaxVisitor.cs b/Projects/SerializationSchemaGenerator/SyntaxVisitor.cs
deleted file mode 100644
index 1e47733be..000000000
--- a/Projects/SerializationSchemaGenerator/SyntaxVisitor.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-/*************************************************************************
- * ModernUO *
- * Copyright 2019-2021 - ModernUO Development Team *
- * Email: hi@modernuo.com *
- * File: SyntaxVisitor.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 Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using SerializationGenerator;
-
-namespace SerializationSchemaGenerator
-{
- public class SyntaxVisitor : CSharpSyntaxWalker
- {
- private readonly SemanticModel _semanticModel;
- private readonly SerializerSyntaxReceiver _syntaxReceiver;
-
- public SyntaxVisitor(SemanticModel semanticModel, SerializerSyntaxReceiver syntaxReceiver)
- {
- _semanticModel = semanticModel;
- _syntaxReceiver = syntaxReceiver;
- }
-
- public override void VisitClassDeclaration(ClassDeclarationSyntax node)
- {
- base.VisitClassDeclaration(node);
- _syntaxReceiver.OnVisitSyntaxNode(node, _semanticModel);
- }
-
- public override void VisitFieldDeclaration(FieldDeclarationSyntax node)
- {
- base.VisitFieldDeclaration(node);
- _syntaxReceiver.OnVisitSyntaxNode(node, _semanticModel);
- }
-
- public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node)
- {
- base.VisitPropertyDeclaration(node);
- _syntaxReceiver.OnVisitSyntaxNode(node, _semanticModel);
- }
- }
-}
diff --git a/Projects/Server.Tests/Helpers/GumpUtilities.cs b/Projects/Server.Tests/Helpers/GumpUtilities.cs
index 70e7c69af..98ef15d59 100644
--- a/Projects/Server.Tests/Helpers/GumpUtilities.cs
+++ b/Projects/Server.Tests/Helpers/GumpUtilities.cs
@@ -193,7 +193,7 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpAlphaRegion g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpAlphaRegion.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("checkertrans"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.Width);
@@ -202,7 +202,7 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpBackground g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpBackground.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("resizepic"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.GumpID);
@@ -212,7 +212,7 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpButton g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpButton.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("button"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.NormalID);
@@ -224,7 +224,7 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpCheck g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpButton.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("checkbox"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.InactiveID);
@@ -237,18 +237,18 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpGroup g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpGroup.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("group"));
disp.AppendLayout(g.Group);
}
public static void AppendTo(this GumpECHandleInput g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpECHandleInput.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("echandleinput"));
}
public static void AppendTo(this GumpHtml g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpHtml.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("htmlgump"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.Width);
@@ -264,7 +264,7 @@ namespace Server.Tests.Network
{
case GumpHtmlLocalizedType.Plain:
{
- disp.AppendLayout(GumpHtmlLocalized.LayoutNamePlain);
+ disp.AppendLayout(Gump.StringToBuffer("xmfhtmlgump"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
@@ -279,7 +279,7 @@ namespace Server.Tests.Network
case GumpHtmlLocalizedType.Color:
{
- disp.AppendLayout(GumpHtmlLocalized.LayoutNameColor);
+ disp.AppendLayout(Gump.StringToBuffer("xmfhtmlgumpcolor"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
@@ -295,7 +295,7 @@ namespace Server.Tests.Network
case GumpHtmlLocalizedType.Args:
{
- disp.AppendLayout(GumpHtmlLocalized.LayoutNameArgs);
+ disp.AppendLayout(Gump.StringToBuffer("xmfhtmltok"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
@@ -314,27 +314,27 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpImage g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpImage.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("gumppic"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.GumpID);
if (g.Hue != 0)
{
- disp.AppendLayout(GumpImage.HueEquals);
+ disp.AppendLayoutNS(" hue=");
disp.AppendLayoutNS(g.Hue);
}
if (!string.IsNullOrEmpty(g.Class))
{
- disp.AppendLayout(GumpImage.ClassEquals);
- disp.AppendLayoutNS(g.Class);
+ disp.AppendLayoutNS(" class=");
+ disp.AppendLayout(Gump.StringToBuffer(g.Class));
}
}
public static void AppendTo(this GumpImageTileButton g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpImageTileButton.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("buttontileart"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.NormalID);
@@ -347,17 +347,11 @@ namespace Server.Tests.Network
disp.AppendLayout(g.Hue);
disp.AppendLayout(g.Width);
disp.AppendLayout(g.Height);
-
- if (g.LocalizedTooltip > 0)
- {
- disp.AppendLayout(GumpImageTileButton.LayoutTooltip);
- disp.AppendLayout(g.LocalizedTooltip);
- }
}
public static void AppendTo(this GumpImageTiled g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpImageTiled.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("gumppictiled"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.Width);
@@ -367,7 +361,7 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpItem g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(g.Hue == 0 ? GumpItem.LayoutName : GumpItem.LayoutNameHue);
+ disp.AppendLayout(Gump.StringToBuffer(g.Hue == 0 ? "tilepic" : "tilepichue"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.ItemID);
@@ -380,13 +374,13 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpItemProperty g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpItemProperty.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("itemproperty"));
disp.AppendLayout(g.Serial);
}
public static void AppendTo(this GumpLabel g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpLabel.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("text"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.Hue);
@@ -395,7 +389,7 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpLabelCropped g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpLabelCropped.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("croppedtext"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.Width);
@@ -406,19 +400,19 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpMasterGump g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpMasterGump.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("mastergump"));
disp.AppendLayout(g.GumpID);
}
public static void AppendTo(this GumpPage g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpPage.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("page"));
disp.AppendLayout(g.Page);
}
public static void AppendTo(this GumpRadio g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpRadio.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("radio"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.InactiveID);
@@ -431,7 +425,7 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpSpriteImage g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpSpriteImage.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("picinpic"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.GumpID);
@@ -443,7 +437,7 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpTextEntry g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpTextEntry.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("textentry"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.Width);
@@ -457,7 +451,7 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpTextEntryLimited g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpTextEntryLimited.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("textentrylimited"));
disp.AppendLayout(g.X);
disp.AppendLayout(g.Y);
disp.AppendLayout(g.Width);
@@ -472,7 +466,7 @@ namespace Server.Tests.Network
public static void AppendTo(this GumpTooltip g, IGumpWriter disp, List strings)
{
- disp.AppendLayout(GumpTooltip.LayoutName);
+ disp.AppendLayout(Gump.StringToBuffer("tooltip"));
disp.AppendLayout(g.Number);
if (!string.IsNullOrEmpty(g.Args))
diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj
index b6339a9a0..db30edf70 100644
--- a/Projects/Server.Tests/Server.Tests.csproj
+++ b/Projects/Server.Tests/Server.Tests.csproj
@@ -3,17 +3,13 @@
false
-
-
+
+
-
-
+
-
- Data\Professions\LBR\prof.txt
-
diff --git a/Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs b/Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs
new file mode 100644
index 000000000..0b7ee8937
--- /dev/null
+++ b/Projects/Server.Tests/Tests/Buffers/STArrayPoolTests.cs
@@ -0,0 +1,72 @@
+using System;
+using Server.Buffers;
+using Xunit;
+
+namespace Server.Tests.Tests.Buffers;
+
+[Collection("Sequential Tests")]
+public class STArrayPoolTests
+{
+ [Theory]
+ [InlineData(0, 0)]
+ [InlineData(2, 16)]
+ [InlineData(56, 64)]
+ [InlineData(120, 128)]
+ [InlineData(65535, 65536)]
+ [InlineData(1024 * 1024 * 15, 1024 * 1024 * 16)]
+ public void ValidMinimumLengths(int requestedLength, int expectedLength)
+ {
+ var arr = STArrayPool.Shared.Rent(requestedLength);
+ Assert.Equal(expectedLength, arr.Length);
+ }
+
+ [Fact]
+ public void NegativeLengthThrows()
+ {
+ Assert.Throws(
+ () =>
+ {
+ var arr = STArrayPool.Shared.Rent(-1);
+ }
+ );
+ }
+
+ [Fact]
+ public void CachesOnlyUpToCPUCountPerBucket()
+ {
+ STArrayPool.Shared.ResetForTesting();
+
+ var cores = Environment.ProcessorCount;
+ var arrays1 = new byte[cores * 8 + 2][]; // 1 for the cache, and 8 * CPU for the stacks
+ var weakReferences1 = new WeakReference[cores * 8 + 2];
+
+ var arrays2 = new byte[cores * 8 + 2][]; // 1 for the cache, and 8 * CPU for the stacks
+ var weakReferences2 = new WeakReference[cores * 8 + 2];
+
+ for (var i = 0; i < arrays1.Length; i++)
+ {
+ arrays1[i] = STArrayPool.Shared.Rent(32);
+ weakReferences1[i] = new WeakReference(arrays1[i]);
+
+ arrays2[i] = STArrayPool.Shared.Rent(64);
+ weakReferences2[i] = new WeakReference(arrays2[i]);
+ }
+
+ for (var i = 0; i < arrays1.Length; i++)
+ {
+ STArrayPool.Shared.Return(arrays1[i]);
+ arrays1[i] = null;
+
+ STArrayPool.Shared.Return(arrays2[i]);
+ arrays2[i] = null;
+ }
+
+ GC.Collect();
+ for (var i = 0; i < weakReferences1.Length; i++)
+ {
+ // When the last one is returned, the one right before it is dropped.
+ Assert.Equal(i != weakReferences1.Length - 2, weakReferences1[i].IsAlive);
+ Assert.Equal(i != weakReferences2.Length - 2, weakReferences2[i].IsAlive);
+ }
+ }
+}
diff --git a/Projects/Server.Tests/Tests/Collections/BitArrayTests.cs b/Projects/Server.Tests/Tests/Collections/BitArrayTests.cs
new file mode 100644
index 000000000..31d2fb2e1
--- /dev/null
+++ b/Projects/Server.Tests/Tests/Collections/BitArrayTests.cs
@@ -0,0 +1,29 @@
+using Server.Collections;
+using Xunit;
+
+namespace Server.Tests;
+
+public class BitArrayTests
+{
+ [Fact]
+ public void TestBitArray()
+ {
+ var bitArray = new BitArray(700); // Restricted Spells;
+ bitArray.Set(5, true);
+ bitArray.Set(39, true);
+ bitArray.Set(125, true);
+
+ // Simulate World Saving
+ var writer = new BufferWriter(1024, false);
+ writer.Write(bitArray); // Save it to a file
+
+ // Simulate World Loading
+ var reader = new BufferReader(writer.Buffer);
+ var bitArrayTest = reader.ReadBitArray();
+ Assert.Equal(700, bitArrayTest.Length);
+ for (var i = 0; i < bitArrayTest.Length; i++)
+ {
+ Assert.Equal(i is 5 or 39 or 125, bitArrayTest.Get(i));
+ }
+ }
+}
diff --git a/Projects/Server.Tests/Tests/Collections/PooledRefQueueTests.cs b/Projects/Server.Tests/Tests/Collections/PooledRefQueueTests.cs
new file mode 100644
index 000000000..a9d3576b0
--- /dev/null
+++ b/Projects/Server.Tests/Tests/Collections/PooledRefQueueTests.cs
@@ -0,0 +1,102 @@
+using System;
+using Moq;
+using Server.Collections;
+using Server.Random;
+using Xunit;
+
+namespace Server.Tests;
+
+public sealed class PooledRefQueueTests : IDisposable
+{
+ public void Dispose() => RandomSources.SetRng(null);
+
+ private static void PrepareRng(int queueCount, int rngValue)
+ {
+ Mock mockRng = new Mock();
+ mockRng
+ .Setup(rng => rng.Next(It.IsAny()))
+ .Returns(
+ (int size) =>
+ {
+ Assert.Equal(queueCount, size);
+ return rngValue;
+ }
+ );
+
+ RandomSources.SetRng(mockRng.Object);
+ }
+
+ [Fact]
+ public void TestPeekRandom1()
+ {
+ // Random value for _head = 0, _tail = 5, _size = 5,
+ using var queue = PooledRefQueue.Create(10);
+ queue.Enqueue(0);
+ queue.Enqueue(1);
+ queue.Enqueue(2);
+ queue.Enqueue(3); // <-----
+ queue.Enqueue(4);
+ queue.Enqueue(5);
+
+ PrepareRng(6, 3);
+ Assert.Equal(3, queue.PeekRandom());
+ }
+
+ [Fact]
+ public void TestPeekRandom2()
+ {
+ // Random value for _head = 3, _tail = 10, _size = 7,
+ using var queue = PooledRefQueue.Create(10);
+ queue.Enqueue(0);
+ queue.Enqueue(1);
+ queue.Enqueue(2);
+
+ queue.Enqueue(3);
+ queue.Enqueue(4);
+ queue.Enqueue(5);
+ queue.Enqueue(6); // <---
+ queue.Enqueue(7);
+ queue.Enqueue(8);
+ queue.Enqueue(9);
+
+ queue.Dequeue();
+ queue.Dequeue();
+ queue.Dequeue();
+
+ PrepareRng(7, 3);
+ Assert.Equal(6, queue.PeekRandom());
+ }
+
+ [Theory]
+ [InlineData(3, 6)]
+ [InlineData(8, 11)]
+ [InlineData(6, 9)]
+ [InlineData(7, 10)]
+ public void TestPeekRandom3(int rngValue, int expectedIndex)
+ {
+ // Random value for _head = 3, _tail = 2, _size = 10,
+ using var queue = PooledRefQueue.Create(10);
+ queue.Enqueue(0);
+ queue.Enqueue(1);
+ queue.Enqueue(2);
+
+ queue.Enqueue(3);
+ queue.Enqueue(4);
+ queue.Enqueue(5);
+ queue.Enqueue(6);
+ queue.Enqueue(7);
+ queue.Enqueue(8);
+ queue.Enqueue(9);
+
+ queue.Dequeue();
+ queue.Dequeue();
+ queue.Dequeue();
+
+ queue.Enqueue(10);
+ queue.Enqueue(11);
+ queue.Enqueue(12);
+
+ PrepareRng(10, rngValue);
+ Assert.Equal(expectedIndex, queue.PeekRandom());
+ }
+}
diff --git a/Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs b/Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs
new file mode 100644
index 000000000..d37046591
--- /dev/null
+++ b/Projects/Server.Tests/Tests/Localization/LocalizationEntryTests.cs
@@ -0,0 +1,19 @@
+using Xunit;
+
+namespace Server.Tests;
+
+public class LocalizationEntryTests
+{
+ [Fact]
+ public void TestClilocAsParameter()
+ {
+ Localization.Add("enu", 500002, "This tests ~1_NUMBER~ as parameters.");
+ Localization.Add("enu", 500003, "clilocs");
+
+ string numericFormatter = Localization.Format(500002, "enu", $"{500003:#}");
+ string stringParam = Localization.Format(500002, "enu", $"{"#500003"}");
+
+ Assert.Equal("This tests clilocs as parameters.", numericFormatter);
+ Assert.Equal("This tests clilocs as parameters.", stringParam);
+ }
+}
diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/GumpPacketTests.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/GumpPacketTests.cs
index fd8aeba6c..61332a2a0 100644
--- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/GumpPacketTests.cs
+++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/GumpPacketTests.cs
@@ -24,9 +24,9 @@ namespace Server.Tests.Network
public void TestDisplaySignGump()
{
Serial gumpSerial = (Serial)0x1000;
- var gumpId = 100;
- var unknownString = "This is an unknown string";
- var caption = "This is a caption";
+ const int gumpId = 100;
+ const string unknownString = "This is an unknown string";
+ const string caption = "This is a caption";
var expected = new DisplaySignGump(gumpSerial, gumpId, unknownString, caption).Compile();
diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs
index 0573d3263..d7414ea4c 100644
--- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs
+++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/VendorBuyPackets.cs
@@ -50,7 +50,7 @@ namespace Server.Network
{
EnsureCapacity(256);
- Stream.Write(!(vendor.FindItemOnLayer(Layer.ShopBuy) is Container buyPack) ? Serial.MinusOne : buyPack.Serial);
+ Stream.Write(vendor.FindItemOnLayer(Layer.ShopBuy) is not Container buyPack ? Serial.MinusOne : buyPack.Serial);
Stream.Write((byte)list.Count);
diff --git a/Projects/Server.Tests/Tests/Network/PipeTests.cs b/Projects/Server.Tests/Tests/Network/PipeTests.cs
index ab4556dc6..31b9baaa3 100644
--- a/Projects/Server.Tests/Tests/Network/PipeTests.cs
+++ b/Projects/Server.Tests/Tests/Network/PipeTests.cs
@@ -11,7 +11,7 @@ namespace Server.Tests.Network
{
private async void DelayedExecute(Action action)
{
- await Task.Delay(5);
+ await Task.Delay(1);
action();
}
@@ -130,8 +130,12 @@ namespace Server.Tests.Network
continue;
}
- result.CopyFrom(new[] { expected_value, expected_value, expected_value, expected_value, expected_value, expected_value, expected_value, expected_value,
- expected_value, expected_value, expected_value, expected_value, expected_value, expected_value, expected_value, expected_value });
+ result.CopyFrom(new[] {
+ expected_value, expected_value, expected_value, expected_value,
+ expected_value, expected_value, expected_value, expected_value,
+ expected_value, expected_value, expected_value, expected_value,
+ expected_value, expected_value, expected_value, expected_value
+ });
writer.Advance(16);
count += 16;
diff --git a/Projects/Server.Tests/Tests/Network/PollGroupTests.cs b/Projects/Server.Tests/Tests/Network/PollGroupTests.cs
new file mode 100644
index 000000000..34d97e9a2
--- /dev/null
+++ b/Projects/Server.Tests/Tests/Network/PollGroupTests.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Server.Network;
+using Xunit;
+
+namespace Server.Tests.Network;
+
+public class PollGroupTests
+{
+ [Fact]
+ public void TestPollGroup()
+ {
+ // var group = new KQueuePollGroup();
+ var nss = new NetState[2048];
+ var handles = new IntPtr[2048];
+ for (var i = 0; i < nss.Length; i++)
+ {
+ nss[i] = PacketTestUtilities.CreateTestNetState();
+ handles[i] = (IntPtr)nss[i].Handle;
+ }
+
+ GC.AddMemoryPressure(10000000000);
+ GC.Collect();
+ GC.RemoveMemoryPressure(10000000000);
+ GC.Collect();
+
+ Thread.Sleep(1000);
+
+ for (var i = 0; i < nss.Length; i++)
+ {
+ Assert.Equal(nss[i].Handle, (GCHandle)handles[i]);
+ }
+
+ // group.Dispose();
+ }
+}
diff --git a/Projects/Server.Tests/Tests/SerialTests.cs b/Projects/Server.Tests/Tests/SerialTests.cs
new file mode 100644
index 000000000..60ff3d370
--- /dev/null
+++ b/Projects/Server.Tests/Tests/SerialTests.cs
@@ -0,0 +1,37 @@
+using System;
+using Xunit;
+
+namespace Server.Tests;
+
+public class SerialTests
+{
+ [Fact]
+ public void TestSerialTryFormatDefault()
+ {
+ var serial = (Serial)0xABCD1234u;
+ const string serialStr = "0xABCD1234";
+ Span buffer = stackalloc char[serialStr.Length];
+ var result = serial.TryFormat(buffer, out var charsWritten, null, null);
+ Assert.True(result);
+ Assert.Equal(serialStr.Length, charsWritten);
+ Assert.Equal(serialStr, buffer.ToString());
+
+ var interpolated = $"{serial}";
+ Assert.Equal(serialStr, interpolated);
+ }
+
+ [Fact]
+ public void TestSerialTryFormatCustom()
+ {
+ var serial = (Serial)0xABCD1234u;
+ const string serialStr = "2882343476";
+ Span buffer = stackalloc char[serialStr.Length];
+ var result = serial.TryFormat(buffer, out var charsWritten, "##", null);
+ Assert.True(result);
+ Assert.Equal(serialStr.Length, charsWritten);
+ Assert.Equal(serialStr, buffer.ToString());
+
+ var interpolated = $"{serial:##}";
+ Assert.Equal(serialStr, interpolated);
+ }
+}
diff --git a/Projects/Server/Attributes.cs b/Projects/Server/Attributes.cs
index e81a91bed..000e50bd7 100644
--- a/Projects/Server/Attributes.cs
+++ b/Projects/Server/Attributes.cs
@@ -71,7 +71,7 @@ namespace Server
return 50;
}
- if (!(objs[0] is CallPriorityAttribute attr))
+ if (objs[0] is not CallPriorityAttribute attr)
{
return 50;
}
diff --git a/Projects/Server/Buffers/CircularBuffer.cs b/Projects/Server/Buffers/CircularBuffer.cs
index 540d23a0b..20a9d3a55 100644
--- a/Projects/Server/Buffers/CircularBuffer.cs
+++ b/Projects/Server/Buffers/CircularBuffer.cs
@@ -129,7 +129,7 @@ namespace System.Buffers
public Span GetSpan(int index)
{
- if (index < 0 || index > 1)
+ if (index is < 0 or > 1)
{
throw new ArgumentOutOfRangeException(nameof(index));
}
diff --git a/Projects/Server/Buffers/CircularBufferReader.cs b/Projects/Server/Buffers/CircularBufferReader.cs
index 56619c6e0..aa8b9aa08 100644
--- a/Projects/Server/Buffers/CircularBufferReader.cs
+++ b/Projects/Server/Buffers/CircularBufferReader.cs
@@ -32,6 +32,10 @@ namespace Server.Network
public int Position { get; private set; }
public int Remaining => Length - Position;
+ // Only used for debugging!
+ public ReadOnlySpan First => _first;
+ public ReadOnlySpan Second => _second;
+
public CircularBufferReader(ref CircularBuffer buffer) : this(buffer.GetSpan(0), buffer.GetSpan(1))
{
}
@@ -58,12 +62,9 @@ namespace Server.Network
try
{
- using var sw = new StreamWriter("Packets.log", true);
-
+ using var sw = new StreamWriter("unhandled-packets.log", true);
sw.WriteLine("Client: {0}: Unhandled packet 0x{1:X2}", state, _first[0]);
-
- Utility.FormatBuffer(sw, _first.ToArray(), new Memory(_second.ToArray()));
-
+ sw.FormatBuffer(_first, _second, Length);
sw.WriteLine();
sw.WriteLine();
}
@@ -244,7 +245,7 @@ namespace Server.Network
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string ReadString(Encoding encoding, bool safeString = false, int fixedLength = -1)
{
- int sizeT = TextEncoding.GetByteLengthForEncoding(encoding);
+ int byteLength = encoding.GetByteLengthForEncoding();
bool isFixedLength = fixedLength > -1;
@@ -253,7 +254,7 @@ namespace Server.Network
if (isFixedLength)
{
- size = fixedLength * sizeT;
+ size = fixedLength * byteLength;
if (size > Remaining)
{
throw new OutOfMemoryException();
@@ -261,7 +262,7 @@ namespace Server.Network
}
else
{
- size = remaining - (remaining & (sizeT - 1));
+ size = remaining - (remaining & (byteLength - 1));
}
ReadOnlySpan span;
@@ -272,7 +273,7 @@ namespace Server.Network
var firstLength = Math.Min(_first.Length - Position, size);
// Find terminator
- index = _first.Slice(Position, firstLength).IndexOfTerminator(sizeT);
+ index = _first.Slice(Position, firstLength).IndexOfTerminator(byteLength);
if (index < 0)
{
@@ -284,7 +285,7 @@ namespace Server.Network
}
else
{
- index = _second[..remaining].IndexOfTerminator(sizeT);
+ index = _second[..remaining].IndexOfTerminator(byteLength);
int secondLength = index < 0 ? remaining : index;
int length = firstLength + secondLength;
@@ -294,7 +295,7 @@ namespace Server.Network
_first[Position..].CopyTo(bytes);
_second[..secondLength].CopyTo(bytes[firstLength..]);
- Position += length + (index >= 0 ? sizeT : 0);
+ Position += length + (index >= 0 ? byteLength : 0);
return TextEncoding.GetString(bytes, encoding, safeString);
}
}
@@ -305,7 +306,7 @@ namespace Server.Network
{
size = Math.Min(remaining, size);
span = _second.Slice( Position - _first.Length, size);
- index = span.IndexOfTerminator(sizeT);
+ index = span.IndexOfTerminator(byteLength);
if (index >= 0)
{
@@ -317,7 +318,7 @@ namespace Server.Network
}
}
- Position += isFixedLength ? size : index + sizeT;
+ Position += isFixedLength ? size : index + byteLength;
return TextEncoding.GetString(span, encoding, safeString);
}
diff --git a/Projects/Server/Buffers/PooledArraySpanFormattable.cs b/Projects/Server/Buffers/PooledArraySpanFormattable.cs
new file mode 100644
index 000000000..7290f250a
--- /dev/null
+++ b/Projects/Server/Buffers/PooledArraySpanFormattable.cs
@@ -0,0 +1,70 @@
+/*************************************************************************
+ * ModernUO *
+ * Copyright 2019-2022 - ModernUO Development Team *
+ * Email: hi@modernuo.com *
+ * File: PooledArraySpanFormattable.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 . *
+ *************************************************************************/
+
+#nullable enable
+using System;
+
+namespace Server.Buffers;
+
+public struct PooledArraySpanFormattable : ISpanFormattable, IDisposable
+{
+ private char[] _arrayToReturnToPool;
+ private int _pos;
+ private string _value;
+
+ public PooledArraySpanFormattable(char[] arrayToReturnToPool, int length)
+ {
+ _arrayToReturnToPool = arrayToReturnToPool;
+ _pos = length;
+ _value = null;
+ }
+
+ public ReadOnlySpan Chars => _arrayToReturnToPool.AsSpan(.._pos);
+
+ public static implicit operator string(PooledArraySpanFormattable f) => f.ToString();
+
+ public string ToString(string? format = null, IFormatProvider formatProvider = null)
+ {
+ _value ??= new string(_arrayToReturnToPool.AsSpan(0, _pos));
+
+ STArrayPool.Shared.Return(_arrayToReturnToPool);
+ _arrayToReturnToPool = null;
+
+ return _value;
+ }
+
+ public bool TryFormat(
+ Span destination, out int charsWritten, ReadOnlySpan format = default,
+ IFormatProvider provider = null
+ )
+ {
+ if (destination.Length < _pos)
+ {
+ charsWritten = 0;
+ return false;
+ }
+
+ _arrayToReturnToPool.AsSpan(0, _pos).CopyTo(destination);
+ charsWritten = _pos;
+ return true;
+ }
+
+ public void Dispose()
+ {
+ STArrayPool.Shared.Return(_arrayToReturnToPool);
+ _arrayToReturnToPool = null;
+ this = default; // Defensive clear
+ }
+}
diff --git a/Projects/Server/Buffers/RawInterpolatedStringHandler.cs b/Projects/Server/Buffers/RawInterpolatedStringHandler.cs
new file mode 100644
index 000000000..699b61792
--- /dev/null
+++ b/Projects/Server/Buffers/RawInterpolatedStringHandler.cs
@@ -0,0 +1,600 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Diagnostics;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+
+namespace Server.Buffers;
+
+/// Provides a handler to interpolate strings which UNSAFELY exposes it's internal character span.
+[InterpolatedStringHandler]
+public ref struct RawInterpolatedStringHandler
+{
+ // Implementation note:
+ // As this type lives in CompilerServices and is only intended to be targeted by the compiler,
+ // public APIs eschew argument validation logic in a variety of places, e.g. allowing a null input
+ // when one isn't expected to produce a NullReferenceException rather than an ArgumentNullException.
+
+ /// Expected average length of formatted data used for an individual interpolation expression result.
+ ///
+ /// This is inherited from string.Format, and could be changed based on further data.
+ /// string.Format actually uses `format.Length + args.Length * 8`, but format.Length
+ /// includes the format items themselves, e.g. "{0}", and since it's rare to have double-digit
+ /// numbers of items, we bump the 8 up to 11 to account for the three extra characters in "{d}",
+ /// since the compiler-provided base length won't include the equivalent character count.
+ ///
+ private const int GuessedLengthPerHole = 11;
+ /// Minimum size array to rent from the pool.
+ /// Same as stack-allocation size used today by string.Format.
+ private const int MinimumArrayPoolLength = 256;
+
+ /// Optional provider to pass to IFormattable.ToString or ISpanFormattable.TryFormat calls.
+ private readonly IFormatProvider? _provider;
+ /// Array rented from the array pool and used to back .
+ private char[]? _arrayToReturnToPool;
+ /// The span to write into.
+ private Span _chars;
+ /// Position at which to write the next character.
+ private int _pos;
+ /// Whether provides an ICustomFormatter.
+ ///
+ /// Custom formatters are very rare. We want to support them, but it's ok if we make them more expensive
+ /// in order to make them as pay-for-play as possible. So, we avoid adding another reference type field
+ /// to reduce the size of the handler and to reduce required zero'ing, by only storing whether the provider
+ /// provides a formatter, rather than actually storing the formatter. This in turn means, if there is a
+ /// formatter, we pay for the extra interface call on each AppendFormatted that needs it.
+ ///
+ private readonly bool _hasCustomFormatter;
+
+ /// Creates a handler used to translate an interpolated string into a .
+ /// The number of constant characters outside of interpolation expressions in the interpolated string.
+ /// The number of interpolation expressions in the interpolated string.
+ /// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly.
+ public RawInterpolatedStringHandler(int literalLength, int formattedCount)
+ {
+ _provider = null;
+ _chars = _arrayToReturnToPool = STArrayPool.Shared.Rent(GetDefaultLength(literalLength, formattedCount));
+ _pos = 0;
+ _hasCustomFormatter = false;
+ }
+
+ /// Creates a handler used to translate an interpolated string into a .
+ /// The number of constant characters outside of interpolation expressions in the interpolated string.
+ /// The number of interpolation expressions in the interpolated string.
+ /// An object that supplies culture-specific formatting information.
+ /// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly.
+ public RawInterpolatedStringHandler(int literalLength, int formattedCount, IFormatProvider? provider)
+ {
+ _provider = provider;
+ _chars = _arrayToReturnToPool = STArrayPool.Shared.Rent(GetDefaultLength(literalLength, formattedCount));
+ _pos = 0;
+ _hasCustomFormatter = provider is not null && HasCustomFormatter(provider);
+ }
+
+ /// Derives a default length with which to seed the handler.
+ /// The number of constant characters outside of interpolation expressions in the interpolated string.
+ /// The number of interpolation expressions in the interpolated string.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)] // becomes a constant when inputs are constant
+ internal static int GetDefaultLength(int literalLength, int formattedCount) =>
+ Math.Max(MinimumArrayPoolLength, literalLength + formattedCount * GuessedLengthPerHole);
+
+ /// Clears the handler, returning any rented array to the pool.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)] // used only on a few hot paths
+ public void Clear()
+ {
+ char[]? toReturn = _arrayToReturnToPool;
+ this = default; // defensive clear
+ if (toReturn is not null)
+ {
+ STArrayPool.Shared.Return(toReturn);
+ }
+ }
+
+ /// Gets a span of the written characters thus far.
+ public ReadOnlySpan Text => _chars[.._pos];
+
+ /// Writes the specified string to the handler.
+ /// The string to write.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void AppendLiteral(string value)
+ {
+ if (value.Length == 1)
+ {
+ Span chars = _chars;
+ int pos = _pos;
+ if ((uint)pos < (uint)chars.Length)
+ {
+ chars[pos] = value[0];
+ _pos = pos + 1;
+ }
+ else
+ {
+ GrowThenCopyString(value);
+ }
+ return;
+ }
+
+ AppendStringDirect(value);
+ }
+
+ /// Writes the specified string to the handler.
+ /// The string to write.
+ private void AppendStringDirect(string value)
+ {
+ if (value.TryCopyTo(_chars[_pos..]))
+ {
+ _pos += value.Length;
+ }
+ else
+ {
+ GrowThenCopyString(value);
+ }
+ }
+
+ #region AppendFormatted
+ // Design note:
+ // The compiler requires a AppendFormatted overload for anything that might be within an interpolation expression;
+ // if it can't find an appropriate overload, for handlers in general it'll simply fail to compile.
+ // (For target-typing to string where it uses DefaultInterpolatedStringHandler implicitly, it'll instead fall back to
+ // its other mechanisms, e.g. using string.Format. This fallback has the benefit that if we miss a case,
+ // interpolated strings will still work, but it has the downside that a developer generally won't know
+ // if the fallback is happening and they're paying more.)
+ //
+ // At a minimum, then, we would need an overload that accepts:
+ // (object value, int alignment = 0, string? format = null)
+ // Such an overload would provide the same expressiveness as string.Format. However, this has several
+ // shortcomings:
+ // - Every value type in an interpolation expression would be boxed.
+ // - ReadOnlySpan could not be used in interpolation expressions.
+ // - Every AppendFormatted call would have three arguments at the call site, bloating the IL further.
+ // - Every invocation would be more expensive, due to lack of specialization, every call needing to account
+ // for alignment and format, etc.
+ //
+ // To address that, we could just have overloads for T and ReadOnlySpan:
+ // (T)
+ // (T, int alignment)
+ // (T, string? format)
+ // (T, int alignment, string? format)
+ // (ReadOnlySpan)
+ // (ReadOnlySpan, int alignment)
+ // (ReadOnlySpan, string? format)
+ // (ReadOnlySpan, int alignment, string? format)
+ // but this also has shortcomings:
+ // - Some expressions that would have worked with an object overload will now force a fallback to string.Format
+ // (or fail to compile if the handler is used in places where the fallback isn't provided), because the compiler
+ // can't always target type to T, e.g. `b switch { true => 1, false => null }` where `b` is a bool can successfully
+ // be passed as an argument of type `object` but not of type `T`.
+ // - Reference types get no benefit from going through the generic code paths, and actually incur some overheads
+ // from doing so.
+ // - Nullable value types also pay a heavy price, in particular around interface checks that would generally evaporate
+ // at compile time for value types but don't (currently) if the Nullable goes through the same code paths
+ // (see https://github.com/dotnet/runtime/issues/50915).
+ //
+ // We could try to take a more elaborate approach for DefaultInterpolatedStringHandler, since it is the most common handler
+ // and we want to minimize overheads both at runtime and in IL size, e.g. have a complete set of overloads for each of:
+ // (T, ...) where T : struct
+ // (T?, ...) where T : struct
+ // (object, ...)
+ // (ReadOnlySpan, ...)
+ // (string, ...)
+ // but this also has shortcomings, most importantly:
+ // - If you have an unconstrained T that happens to be a value type, it'll now end up getting boxed to use the object overload.
+ // This also necessitates the T? overload, since nullable value types don't meet a T : struct constraint, so without those
+ // they'd all map to the object overloads as well.
+ // - Any reference type with an implicit cast to ROS