Skip to content

Commit

Permalink
IVerbOwner, ISelectable - support all implementations by default
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
SokyranTheDragon committed Jan 7, 2024
1 parent 269709e commit 6a96199
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 98 deletions.
2 changes: 2 additions & 0 deletions Source/Client/MultiplayerData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
138 changes: 53 additions & 85 deletions Source/Client/Syncing/Dict/SyncDictRimWorld.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,6 @@ public static class SyncDictRimWorld
}
}, true // implicit
},
{
(ByteWriter data, IVerbOwner obj) => {
WriteWithImpl<IVerbOwner>(data, obj, supportedVerbOwnerTypes);
},
(ByteReader data) => {
return ReadWithImpl<IVerbOwner>(data, supportedVerbOwnerTypes);
}, true // Implicit
},
#endregion

#region AI
Expand Down Expand Up @@ -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<ISelectableImpl>(data);

return impl switch
{
ISelectableImpl.None => null,
ISelectableImpl.Thing => ReadSync<Thing>(data),
ISelectableImpl.Zone => ReadSync<Zone>(data),
ISelectableImpl.WorldObject => ReadSync<WorldObject>(data),
_ => throw new Exception($"Unknown ISelectable {impl}")
};
}, true
},
{
(ByteWriter data, IStoreSettingsParent obj) => {
WriteWithImpl<IStoreSettingsParent>(data, obj, storageParents);
},
(ByteReader data) => {
return ReadWithImpl<IStoreSettingsParent>(data, storageParents);
}
},
{
(ByteWriter data, IPlantToGrowSettable obj) => {
WriteWithImpl<IPlantToGrowSettable>(data, obj, plantToGrowSettables);
},
(ByteReader data) => {
return ReadWithImpl<IPlantToGrowSettable>(data, plantToGrowSettables);
}
},
{
(ByteWriter data, IThingHolder obj) => {
WriteWithImpl<IThingHolder>(data, obj, supportedThingHolders);
},
(ByteReader data) => {
return ReadWithImpl<IThingHolder>(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<Thing>(data)
},

#endregion

#region Storage
{
(ByteWriter data, StorageSettings storage) => {
Expand Down Expand Up @@ -1144,6 +1059,59 @@ public static class SyncDictRimWorld
}, true // Implicit
},
#endregion

#region Interfaces
{
(ByteWriter data, ISelectable obj) => {
WriteWithImpl<ISelectable>(data, obj, selectables);
},
(ByteReader data) => {
return ReadWithImpl<ISelectable>(data, selectables);
}, true // Implicit
},
{
(ByteWriter data, IStoreSettingsParent obj) => {
WriteWithImpl<IStoreSettingsParent>(data, obj, storageParents);
},
(ByteReader data) => {
return ReadWithImpl<IStoreSettingsParent>(data, storageParents);
}
},
{
(ByteWriter data, IPlantToGrowSettable obj) => {
WriteWithImpl<IPlantToGrowSettable>(data, obj, plantToGrowSettables);
},
(ByteReader data) => {
return ReadWithImpl<IPlantToGrowSettable>(data, plantToGrowSettables);
}
},
{
(ByteWriter data, IThingHolder obj) => {
WriteWithImpl<IThingHolder>(data, obj, supportedThingHolders);
},
(ByteReader data) => {
return ReadWithImpl<IThingHolder>(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<Thing>(data)
},
{
(ByteWriter data, IVerbOwner obj) => {
WriteWithImpl<IVerbOwner>(data, obj, verbOwners);
},
(ByteReader data) => {
return ReadWithImpl<IVerbOwner>(data, verbOwners);
}, true // Implicit
},
#endregion
};

class Dummy_ITab_Pawn_Visitor : ITab_Pawn_Visitor { }
Expand Down
17 changes: 4 additions & 13 deletions Source/Client/Syncing/Game/RwImplSerialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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));
Expand Down

0 comments on commit 6a96199

Please sign in to comment.