From 6a96199d263f3209b1e787ba0e666df77e161021 Mon Sep 17 00:00:00 2001 From: SokyranTheDragon Date: Sun, 7 Jan 2024 18:36:43 +0100 Subject: [PATCH] IVerbOwner, ISelectable - support all implementations by default I've placed `IVerbOwner` sync worker in the `Interfaces` region, which I've placed at the very bottom. This is due to issues with syncing `IVerbOwner` - for example, trying to sync a `Pawn` caused it to be synced as `IVerbOwner`, which caused it to be recursively synced as `IVerbOwner` until the game crashed. Placing it lower fixed the issue. --- Source/Client/MultiplayerData.cs | 2 + .../Client/Syncing/Dict/SyncDictRimWorld.cs | 138 +++++++----------- .../Syncing/Game/RwImplSerialization.cs | 17 +-- 3 files changed, 59 insertions(+), 98 deletions(-) diff --git a/Source/Client/MultiplayerData.cs b/Source/Client/MultiplayerData.cs index 98cf9b4d..1e5f499a 100644 --- a/Source/Client/MultiplayerData.cs +++ b/Source/Client/MultiplayerData.cs @@ -124,6 +124,8 @@ internal static void CollectDefInfos() dict["HediffComp"] = GetDefInfo(RwImplSerialization.hediffCompTypes, TypeHash); dict["IStoreSettingsParent"] = GetDefInfo(RwImplSerialization.storageParents, TypeHash); dict["IPlantToGrowSettable"] = GetDefInfo(RwImplSerialization.plantToGrowSettables, TypeHash); + dict["IVerbOwner"] = GetDefInfo(RwImplSerialization.verbOwners, TypeHash); + dict["ISelectable"] = GetDefInfo(RwImplSerialization.selectables, TypeHash); dict["DefTypes"] = GetDefInfo(DefSerialization.DefTypes, TypeHash); dict["GameComponent"] = GetDefInfo(RwImplSerialization.gameCompTypes, TypeHash); diff --git a/Source/Client/Syncing/Dict/SyncDictRimWorld.cs b/Source/Client/Syncing/Dict/SyncDictRimWorld.cs index 522b14b8..d55d3c25 100644 --- a/Source/Client/Syncing/Dict/SyncDictRimWorld.cs +++ b/Source/Client/Syncing/Dict/SyncDictRimWorld.cs @@ -317,14 +317,6 @@ public static class SyncDictRimWorld } }, true // implicit }, - { - (ByteWriter data, IVerbOwner obj) => { - WriteWithImpl(data, obj, supportedVerbOwnerTypes); - }, - (ByteReader data) => { - return ReadWithImpl(data, supportedVerbOwnerTypes); - }, true // Implicit - }, #endregion #region AI @@ -1021,83 +1013,6 @@ public static class SyncDictRimWorld }, #endregion - #region Interfaces - { - (ByteWriter data, ISelectable obj) => { - if (obj == null) - { - WriteSync(data, ISelectableImpl.None); - } - else if (obj is Thing thing) - { - WriteSync(data, ISelectableImpl.Thing); - WriteSync(data, thing); - } - else if (obj is Zone zone) - { - WriteSync(data, ISelectableImpl.Zone); - WriteSync(data, zone); - } - else if (obj is WorldObject worldObj) - { - WriteSync(data, ISelectableImpl.WorldObject); - WriteSync(data, worldObj); - } - else - { - throw new SerializationException($"Unknown ISelectable type: {obj.GetType()}"); - } - }, - (ByteReader data) => { - ISelectableImpl impl = ReadSync(data); - - return impl switch - { - ISelectableImpl.None => null, - ISelectableImpl.Thing => ReadSync(data), - ISelectableImpl.Zone => ReadSync(data), - ISelectableImpl.WorldObject => ReadSync(data), - _ => throw new Exception($"Unknown ISelectable {impl}") - }; - }, true - }, - { - (ByteWriter data, IStoreSettingsParent obj) => { - WriteWithImpl(data, obj, storageParents); - }, - (ByteReader data) => { - return ReadWithImpl(data, storageParents); - } - }, - { - (ByteWriter data, IPlantToGrowSettable obj) => { - WriteWithImpl(data, obj, plantToGrowSettables); - }, - (ByteReader data) => { - return ReadWithImpl(data, plantToGrowSettables); - } - }, - { - (ByteWriter data, IThingHolder obj) => { - WriteWithImpl(data, obj, supportedThingHolders); - }, - (ByteReader data) => { - return ReadWithImpl(data, supportedThingHolders); - } - }, - { - (ByteWriter data, IStorageGroupMember obj) => - { - if (obj is Thing thing) - WriteSync(data, thing); - else - throw new SerializationException($"Unknown IStorageGroupMember type: {obj.GetType()}"); - }, - (ByteReader data) => (IStorageGroupMember)ReadSync(data) - }, - - #endregion - #region Storage { (ByteWriter data, StorageSettings storage) => { @@ -1144,6 +1059,59 @@ public static class SyncDictRimWorld }, true // Implicit }, #endregion + + #region Interfaces + { + (ByteWriter data, ISelectable obj) => { + WriteWithImpl(data, obj, selectables); + }, + (ByteReader data) => { + return ReadWithImpl(data, selectables); + }, true // Implicit + }, + { + (ByteWriter data, IStoreSettingsParent obj) => { + WriteWithImpl(data, obj, storageParents); + }, + (ByteReader data) => { + return ReadWithImpl(data, storageParents); + } + }, + { + (ByteWriter data, IPlantToGrowSettable obj) => { + WriteWithImpl(data, obj, plantToGrowSettables); + }, + (ByteReader data) => { + return ReadWithImpl(data, plantToGrowSettables); + } + }, + { + (ByteWriter data, IThingHolder obj) => { + WriteWithImpl(data, obj, supportedThingHolders); + }, + (ByteReader data) => { + return ReadWithImpl(data, supportedThingHolders); + } + }, + { + (ByteWriter data, IStorageGroupMember obj) => + { + if (obj is Thing thing) + WriteSync(data, thing); + else + throw new SerializationException($"Unknown IStorageGroupMember type: {obj.GetType()}"); + }, + (ByteReader data) => (IStorageGroupMember)ReadSync(data) + }, + { + (ByteWriter data, IVerbOwner obj) => { + WriteWithImpl(data, obj, verbOwners); + }, + (ByteReader data) => { + return ReadWithImpl(data, verbOwners); + }, true // Implicit + }, + #endregion }; class Dummy_ITab_Pawn_Visitor : ITab_Pawn_Visitor { } diff --git a/Source/Client/Syncing/Game/RwImplSerialization.cs b/Source/Client/Syncing/Game/RwImplSerialization.cs index 43911054..367c5ae3 100644 --- a/Source/Client/Syncing/Game/RwImplSerialization.cs +++ b/Source/Client/Syncing/Game/RwImplSerialization.cs @@ -12,6 +12,8 @@ public static class RwImplSerialization { public static Type[] storageParents; public static Type[] plantToGrowSettables; + public static Type[] verbOwners; + public static Type[] selectables; public static Type[] thingCompTypes; public static Type[] hediffCompTypes; @@ -32,23 +34,12 @@ public static class RwImplSerialization typeof(WorldObjectComp) }; - internal static Type[] supportedVerbOwnerTypes = - { - typeof(Thing), - typeof(Ability), - typeof(ThingComp), - }; - - // ReSharper disable once InconsistentNaming - internal enum ISelectableImpl : byte - { - None, Thing, Zone, WorldObject - } - public static void Init() { storageParents = TypeUtil.AllImplementationsOrdered(typeof(IStoreSettingsParent)); plantToGrowSettables = TypeUtil.AllImplementationsOrdered(typeof(IPlantToGrowSettable)); + verbOwners = TypeUtil.AllImplementationsOrdered(typeof(IVerbOwner)); + selectables = TypeUtil.AllImplementationsOrdered(typeof(ISelectable)); thingCompTypes = TypeUtil.AllSubclassesNonAbstractOrdered(typeof(ThingComp)); hediffCompTypes = TypeUtil.AllSubclassesNonAbstractOrdered(typeof(HediffComp));