示例#1
0
        // All the following is for the tiny lock of doom

        static void SyncWorkerForSwapControlsHandler(SyncWorker sync, ref object obj)
        {
            Pawn pawn = null;

            if (sync.isWriting)
            {
                pawn = (Pawn)SwapControlsHandler_PawnProperty.GetValue(obj, new object[] { });

                // If Pawn is null, it was saved and got deleted.
                if (pawn == null)
                {
                    sync.Write(false);

                    // Must use more reflection to traverse SimpleSidearms.saveData.handlers
                    // This will desync if unhandled :(

                    throw new ArgumentException("About to desync, tiny lock of doom triggered. Refusing to comply");
                }
                else
                {
                    sync.Write(true);
                    sync.Write(pawn);
                }
            }
            else
            {
                bool exists = sync.Read <bool>();
                if (exists)
                {
                    pawn = sync.Read <Pawn>();
                    obj  = SwapControlsHandler_GetHandlerForPawnMethod.Invoke(null, new object[] { pawn });
                }
            }
        }
        private static void SyncFormTrackerInnerClass(SyncWorker sync, ref object inner)
        {
            if (sync.isWriting)
            {
                var tracker = innerClassParentField(inner);
                var comp    = formTrackerCompField(tracker);
                sync.Write(comp);

                var formList = propsFormsListField(comp.props);
                var index    = formList.IndexOf(innerClassFormField(inner));
                sync.Write(index);
            }
            else
            {
                var comp    = sync.Read <ThingComp>();
                var tracker = pokemonFormTrackerField(comp);
                innerClassParentField(inner) = tracker;

                var index = sync.Read <int>();
                if (index >= 0)
                {
                    var formList = propsFormsListField(comp.props);
                    innerClassFormField(inner) = formList[index];
                }
            }
        }
示例#3
0
        private static void SyncZoneData(SyncWorker sync, ref object zoneData)
        {
            if (sync.isWriting)
            {
                int?id           = null;
                var comp         = compCache[Find.CurrentMap];
                var zoneRegistry = growZoneRegistryField(comp);

                foreach (DictionaryEntry entry in zoneRegistry)
                {
                    if (entry.Value == zoneData)
                    {
                        id = (int)entry.Key;
                        break;
                    }
                }

                sync.Write(id);
                if (id != null)
                {
                    sync.Write(Find.CurrentMap);
                }
            }
            else
            {
                var id = sync.Read <int?>();
                if (id != null)
                {
                    var comp         = compCache[sync.Read <Map>()];
                    var zoneRegistry = growZoneRegistryField(comp);
                    zoneData = zoneRegistry[id.Value];
                }
            }
        }
        private static void SyncFacepaintCombination(SyncWorker sync, ref object obj)
        {
            var defs = (IList)orderedFacepaintDefsField.GetValue(null);

            if (sync.isWriting)
            {
                sync.Write((Color)facepaintColourOneField.GetValue(obj));
                sync.Write((Color)facepaintColourTwoField.GetValue(obj));
                sync.Write(defs.IndexOf(facepaintDefOneField.GetValue(obj)));
                sync.Write(defs.IndexOf(facepaintDefTwoField.GetValue(obj)));
            }
            else
            {
                facepaintColourOneField.SetValue(obj, sync.Read <Color>());
                facepaintColourTwoField.SetValue(obj, sync.Read <Color>());
                int index = sync.Read <int>();
                if (index >= 0)
                {
                    facepaintDefOneField.SetValue(obj, defs[index]);
                }
                index = sync.Read <int>();
                if (index >= 0)
                {
                    facepaintDefTwoField.SetValue(obj, defs[index]);
                }
            }
        }
        // Sync worker for the Dialog_AssignPreacher (and Dialog_AssignAssistant, as it's implicit worker)
        private static void SyncDialogAssignPreacher(SyncWorker sync, ref Window obj)
        {
            if (sync.isWriting)
            {
                var sermon = assignPreacherSermonField(obj);
                var altar  = assignPreacherAltarField(obj) as Building;

                if (TryGetDataForSermon(sermon, altar, out var index))
                {
                    sync.Write(index);
                    sync.Write(altar);
                    sync.Write(obj.GetType() == assignPreacherType);
                }
                else
                {
                    sync.Write(-1);
                }
            }
            else
            {
                var index = sync.Read <int>();

                if (index >= 0)
                {
                    var altar  = sync.Read <Building>();
                    var sermon = GetSermon(altar, index);
                    var type   = sync.Read <bool>() ? assignPreacherType : assignAssistantType;

                    obj = Activator.CreateInstance(type, altar, sermon) as Window;
                }
            }
        }
        // Used for syncing inner, compiler-generated class inside of TempleCardUtility
        private static void SyncTemplaCardUtilityInnerClass(SyncWorker sync, object obj)
        {
            if (sync.isWriting)
            {
                var altar  = templeCardUtilityInnerAltarField(obj) as Building;
                var sermon = templeCardUtilityInnerSermonField(obj);

                if (TryGetDataForSermon(sermon, altar, out var index))
                {
                    sync.Write(index);
                    sync.Write(altar);
                }
                else
                {
                    sync.Write(-1);
                }
            }
            else
            {
                var index = sync.Read <int>();

                if (index >= 0)
                {
                    var altar = sync.Read <Building>();
                    templeCardUtilityInnerAltarField(obj)  = altar;
                    templeCardUtilityInnerSermonField(obj) = GetSermon(altar, index);
                }
            }
        }
        private static void SyncPsykerDisciplineWindowAny(SyncWorker sync, ref object obj, Type windowType)
        {
            if (sync.isWriting)
            {
                sync.Write((ThingComp)psykerDisciplineWindowCompField.GetValue(obj));
                sync.Write(((Def)psykerDisciplineWindowSelectedDefField.GetValue(obj)).shortHash);
            }
            else
            {
                var comp = sync.Read <ThingComp>();
                var hash = sync.Read <ushort>();
                var def  = getDefByShortHash.Invoke(null, new object[] { hash });

                // If the window exists, we try to find a window for the discipline field for that pawn
                obj = Find.WindowStack.Windows.FirstOrDefault(x => x.GetType() == windowType && (ThingComp)psykerDisciplineWindowCompField.GetValue(x) == comp);

                // If a specific player doesn't have the psyker menu open we'll have null here, we need to create it for our synced method
                if (obj == null)
                {
                    // The Window_Psyker is needed for constructor and the synced method
                    // It won't really do anything useful, but is needed
                    var psykerWindow = Activator.CreateInstance(psykerWindowType, comp);
                    obj = Activator.CreateInstance(windowType, comp, psykerWindow);
                }

                // Set the def to the correct one (someone might have another one selected, so make sure the same one is picked for everyone)
                psykerDisciplineWindowSelectedDefField.SetValue(obj, def);
            }
        }
        private static void SyncSetIngredientCommand(SyncWorker sync, ref Command command)
        {
            var traverse       = Traverse.Create(command);
            var building       = traverse.Field("building");
            var ingredientList = traverse.Field("things");

            if (sync.isWriting)
            {
                sync.Write(building.GetValue() as Thing);
                var list = ingredientList.GetValue() as List <Thing>;
                sync.Write(list.Count);
                foreach (var item in list)
                {
                    sync.Write(item as Thing);
                }
            }
            else
            {
                building.SetValue(sync.Read <Thing>());
                int count = sync.Read <int>();
                var list  = new List <Thing>(count);
                for (int i = 0; i < count; i++)
                {
                    list.Add(sync.Read <Thing>());
                }
                ingredientList.SetValue(list);
            }
        }
示例#9
0
        private static void SyncSetIngredientCommand(SyncWorker sync, ref Command command)
        {
            var traverse       = Traverse.Create(command);
            var building       = traverse.Field("building");
            var ingredientList = traverse.Field("things");

            if (sync.isWriting)
            {
                sync.Write(building.GetValue() as Thing);
                var ingredientListValue = ingredientList.GetValue();
                if (ingredientListValue == null)
                {
                    sync.Write(false);
                }
                else
                {
                    sync.Write(true);
                    sync.Write(ingredientList.GetValue() as List <Thing>);
                }
            }
            else
            {
                building.SetValue(sync.Read <Thing>());
                if (sync.Read <bool>())
                {
                    ingredientList.SetValue(sync.Read <List <Thing> >());
                }
            }
        }
        private static void SyncInnerClassWithPawn(SyncWorker sync, ref object inner)
        {
            var traverse = Traverse.Create(inner);

            if (sync.isWriting)
            {
                var comp = (ThingComp)traverse.Field("<>4__this").GetValue();
                var pawn = (Pawn)traverse.Field("p").GetValue();

                sync.Write(comp);
                sync.Write(pawn.thingIDNumber);
            }
            else
            {
                var comp = sync.Read <ThingComp>();
                var id   = sync.Read <int>();
                var pawn = GetPawnFromComp(comp, id);

                traverse.Field("<>4__this").SetValue(comp);
                if (pawn != null)
                {
                    traverse.Field("p").SetValue(pawn);
                }
            }
        }
        private static void SyncSurrogateToHackDesignator(SyncWorker sync, ref Designator designator)
        {
            if (sync.isWriting)
            {
                sync.Write((byte)surrogateToHackHackTypeField(designator));
                sync.Write(surrogateToHackTargetField(designator));
                var map = surrogateToHackMapField(designator);

                // Looks like the map and cell are set in only one method, which is never called
                // so we'll most likely end up never syncing them. I'm leaving it for safety, though.
                if (map == null)
                {
                    sync.Write(IntVec3.Invalid);
                }
                else
                {
                    sync.Write(surrogateToHackPosField(designator));
                    sync.Write(map);
                }
            }
            else
            {
                designator = (Designator)surrogateToHackConstructor.Invoke(new object[] { (int)sync.Read <byte>() });
                surrogateToHackTargetField(designator) = sync.Read <Pawn>();
                var pos = sync.Read <IntVec3>();

                if (pos.IsValid)
                {
                    surrogateToHackPosField(designator) = pos;
                    surrogateToHackMapField(designator) = sync.Read <Map>();
                }
            }
        }
示例#12
0
 static void SyncLearnPsycasts(SyncWorker sync, ref Command_Action command)
 {
     if (sync.isWriting) {
         sync.Write(levelField(command));
         sync.Write(parentField(command));
     } else {
         command = (Command_Action) Activator.CreateInstance(learnPsycastsType, sync.Read<int>(), sync.Read<Pawn>());
     }
 }
 private static void SyncVisitSite(SyncWorker sync, ref TransportPodsArrivalAction_VisitSite transportPodAction)
 {
     if (sync.isWriting)
     {
         sync.Write((Site)siteField.GetValue(transportPodAction));
         sync.Write((PawnsArrivalModeDef)visitSiteArrivalModeField.GetValue(transportPodAction));
     }
     else
     {
         transportPodAction = new TransportPodsArrivalAction_VisitSite(sync.Read <Site>(), sync.Read <PawnsArrivalModeDef>());
     }
 }
 private static void SyncIntVec3Pair(SyncWorker sync, ref Pair <IntVec3, IntVec3> pair)
 {
     if (sync.isWriting)
     {
         sync.Write(pair.First);
         sync.Write(pair.Second);
     }
     else
     {
         pair = new Pair <IntVec3, IntVec3>(sync.Read <IntVec3>(), sync.Read <IntVec3>());
     }
 }
 private static void SyncAttackSettlement(SyncWorker sync, ref TransportPodsArrivalAction_AttackSettlement transportPodAction)
 {
     if (sync.isWriting)
     {
         sync.Write((Settlement)attackSettlementField.GetValue(transportPodAction));
         sync.Write((PawnsArrivalModeDef)attackSettlementArrivalModeField.GetValue(transportPodAction));
     }
     else
     {
         transportPodAction = new TransportPodsArrivalAction_AttackSettlement(sync.Read <Settlement>(), sync.Read <PawnsArrivalModeDef>());
     }
 }
示例#16
0
 private static void SyncCommand(SyncWorker sync, ref Command command)
 {
     if (sync.isWriting)
     {
         sync.Write(setGenomeListMap(command));
         sync.Write(setGenomeListBuilding(command));
     }
     else
     {
         setGenomeListMap(command)      = sync.Read <Map>();
         setGenomeListBuilding(command) = sync.Read <Building>();
     }
 }
 private static void SyncLandInSpecificCell(SyncWorker sync, ref TransportPodsArrivalAction_LandInSpecificCell transportPodAction)
 {
     if (sync.isWriting)
     {
         sync.Write((MapParent)mapParentField.GetValue(transportPodAction));
         sync.Write((IntVec3)cellField.GetValue(transportPodAction));
         sync.Write((bool)landInShuttleField.GetValue(transportPodAction));
     }
     else
     {
         transportPodAction = new TransportPodsArrivalAction_LandInSpecificCell(sync.Read <MapParent>(), sync.Read <IntVec3>(), sync.Read <bool>());
     }
 }
 private static void SyncFishingZoneChange(SyncWorker sync, ref Command command)
 {
     if (sync.isWriting)
     {
         sync.Write(mapField(command));
         sync.Write(fishingZoneField(command));
     }
     else
     {
         command                   = (Command)FormatterServices.GetUninitializedObject(commandType);
         mapField(command)         = sync.Read <Map>();
         fishingZoneField(command) = sync.Read <Zone>();
     }
 }
 private static void SyncFishingZoneChange(SyncWorker sync, ref Command command)
 {
     if (sync.isWriting)
     {
         sync.Write(((Map)mapField.GetValue(command)).Index);
         sync.Write((Zone)fishingZoneField.GetValue(command));
     }
     else
     {
         command = (Command)FormatterServices.GetUninitializedObject(commandType);
         mapField.SetValue(command, Find.Maps[sync.Read <int>()]);
         fishingZoneField.SetValue(command, sync.Read <Zone>());
     }
 }
        private static void SyncRitualReferenceInnerClass(SyncWorker sync, ref object obj)
        {
            if (sync.isWriting)
            {
                var ritualReference = ritualReferenceInnerSelfField.GetValue(obj);
                var parent          = (ThingWithComps)ritualReferenceInnerParentField.GetValue(obj);
                var rituals         = ritualReferenceInnerRitualsField.GetValue(obj);

                // Get the index of our ritual reference inside of the comp props
                var comp        = parent.AllComps.First(x => x.GetType() == compRitualAltarType);
                var ritualsList = (IList)ritualCompPropertiesRitualsField.GetValue(comp.props);
                var index       = ritualsList.IndexOf(ritualReference);

                // We need to be able to retrieve the RitualReference, otherwise we won't really be able to sync
                // (We could technically sync the Def inside of this object, but it ended up not syncing when I tried)
                sync.Write(index);
                if (index >= 0)
                {
                    sync.Write <Thing>(parent);
                    SyncRitualTracker(sync, ref rituals);
                }
            }
            else
            {
                var index = sync.Read <int>();

                if (index >= 0)
                {
                    var    parent  = sync.Read <Thing>();
                    object rituals = null;
                    SyncRitualTracker(sync, ref rituals);

                    ritualReferenceInnerParentField.SetValue(obj, parent);
                    ritualReferenceInnerRitualsField.SetValue(obj, rituals);

                    if (index >= 0)
                    {
                        var comp            = ((ThingWithComps)parent).AllComps.First(x => x.GetType() == compRitualAltarType);
                        var ritualsList     = (IList)ritualCompPropertiesRitualsField.GetValue(comp.props);
                        var ritualReference = ritualsList[index];
                        ritualReferenceInnerSelfField.SetValue(obj, ritualReference);

                        var def        = ritualReferenceDefField.GetValue(ritualReference);
                        var ritualList = ritualTrackerGetRitualMethod.Invoke(rituals, new object[] { def });
                        ritualReferenceInnerRitualField.SetValue(obj, ritualList);
                    }
                }
            }
        }
        // Besides syncing a normal WonderWorker, we also need the info for target and if it was cancelled
        private static void SyncWonderTargetableWorker(SyncWorker sync, ref object obj)
        {
            SyncWonderWorker(sync, ref obj);

            if (sync.isWriting)
            {
                sync.Write(wonderWorkerTargetableCanceledField(obj));
                sync.Write(wonderWorkerTargetableTargetField(obj));
            }
            else
            {
                wonderWorkerTargetableCanceledField(obj) = sync.Read <bool>();
                wonderWorkerTargetableTargetField(obj)   = sync.Read <TargetInfo>();
            }
        }
 static void SyncLearnPsycasts(SyncWorker sync, ref Command_Action command)
 {
     if (sync.isWriting)
     {
         sync.Write((int)levelField.GetValue(command));
         sync.Write((Pawn)parentField.GetValue(command));
     }
     else
     {
         command = (Command_Action)Activator.CreateInstance(learnPsycastsType, new object[] {
             sync.Read <int>(),
             sync.Read <Pawn>()
         });
     }
 }
        private static void SyncVerbManager(SyncWorker sync, ref object obj)
        {
            if (sync.isWriting)
            {
                // Sync the pawn that has the VerbManager
                sync.Write((Pawn)mvcfPawnGetter.Invoke(obj, Array.Empty <object>()));
            }
            else
            {
                var pawn = sync.Read <Pawn>();

                var comp      = mvcfGetWorldCompMethod.Invoke(null, Array.Empty <object>());
                var weakTable = mvcfManagersTableField.GetValue(comp);

                var outParam = new object[] { pawn, null };

                // Either try getting the VerbManager from the comp, or create it if it's missing
                if ((bool)conditionalWeakTableTryGetValueMethod.Invoke(weakTable, outParam))
                {
                    obj = outParam[1];
                }
                else
                {
                    obj = InitVerbManager(pawn, (WorldComponent)comp, table: weakTable);
                }
            }
        }
        private static void SyncExtendedPawnData(SyncWorker sync, ref object data)
        {
            if (sync.isWriting)
            {
                var id = int.MaxValue;

                foreach (DictionaryEntry dictionaryEntry in pawnStorageDictionary(extendedDataStorageInstance))
                {
                    if (dictionaryEntry.Value == data)
                    {
                        id = (int)dictionaryEntry.Key;
                        break;
                    }
                }

                sync.Write(id);
            }
            else
            {
                var id = sync.Read <int>();

                if (id != int.MaxValue && thingsById.TryGetValue(id, out var thing) && thing is Pawn)
                {
                    data = getExtendedDataForPawnMethod.Invoke(extendedDataStorageInstance, new object[] { thing });
                }
            }
        }
        private static void SyncManagedVerb(SyncWorker sync, ref object obj)
        {
            if (sync.isWriting)
            {
                // Get the VerbManager from inside of the ManagedVerb itself
                var verbManager = mvcfManagerVerbManagerField.GetValue(obj);
                // Find the ManagedVerb inside of list of all verbs
                var managedVerbsList = mvcfVerbsField.GetValue(verbManager) as IList;
                var index            = managedVerbsList.IndexOf(obj);

                // Sync the index of the verb as well as the manager (if it's valid)
                sync.Write(index);
                if (index >= 0)
                {
                    SyncVerbManager(sync, ref verbManager);
                }
            }
            else
            {
                // Read and check if the index is valid
                var index = sync.Read <int>();

                if (index >= 0)
                {
                    // Read the verb manager
                    object verbManager = null;
                    SyncVerbManager(sync, ref verbManager);

                    // Find the ManagedVerb with specific index inside of list of all verbs
                    var managedVerbsList = mvcfVerbsField.GetValue(verbManager) as IList;
                    obj = managedVerbsList[index];
                }
            }
        }
示例#26
0
 void ReallowInStockpileGizmoWorker(SyncWorker sync, ref Command obj)
 {
     if (sync.isWriting)
     {
         sync.Write(thingDefLabel(obj));
         sync.Write(zoneStockpileLabel(obj));
         sync.Write(categoryLabel(obj));
     }
     else
     {
         obj = (Command)FormatterServices.GetUninitializedObject(reallowGizmoType);
         thingDefLabel(obj)      = sync.Read <ThingDef>();
         zoneStockpileLabel(obj) = sync.Read <Zone_Stockpile>();
         categoryLabel(obj)      = sync.Read <ThingCategoryDef>();
     }
 }
 static void SyncRename(SyncWorker sync, ref Dialog_RenameColony rename)
 {
     if (sync.isWriting)
     {
         sync.Write(rename.changeNameTo);
         sync.Write(rename.changeSecondNameTo);
         sync.Write(rename.changingSettlement);
     }
     else
     {
         string     new_faction_name = sync.Read <string>();
         string     new_base_name    = sync.Read <string>();
         Settlement new_base_obj     = sync.Read <Settlement>();
         NamePlayerFactionDialogUtility.Named(new_faction_name);
         NamePlayerSettlementDialogUtility.Named(new_base_obj, new_base_name);
     }
 }
 static void SyncCommand(SyncWorker sync, ref Command type)
 {
     if (sync.isWriting)
     {
         sync.Write(type.actionHash);
         sync.Write(type.amount);
         sync.Write(type.boughtBy);
     }
     else
     {
         Command command = new Command();
         command.actionHash = sync.Read <string>();
         command.amount     = sync.Read <int>();
         command.boughtBy   = sync.Read <string>();
         type = command;
     }
 }
示例#29
0
        private static void SyncOperation(SyncWorker sync, ref object operation)
        {
            if (sync.isWriting)
            {
                sync.Write(operationPodField(operation));
                // Right now we have 2 types it could be, but there could be more in the future
                sync.Write(operation.GetType());
            }
            else
            {
                var pod  = sync.Read <ThingComp>();
                var type = sync.Read <Type>();

                // All the current types right now have 1 argument
                operation = Activator.CreateInstance(type, pod);
            }
        }
        static void SyncWorkerForThingDefStuffDefPair(SyncWorker sync, ref object obj)
        {
            var traverse = Traverse.Create(obj);

            var thingField = traverse.Field("thing");
            var stuffField = traverse.Field("stuff");

            if (sync.isWriting)
            {
                sync.Write(thingField.GetValue <ThingDef>());
                sync.Write(stuffField.GetValue <ThingDef>());
            }
            else
            {
                thingField.SetValue(sync.Read <ThingDef>());
                stuffField.SetValue(sync.Read <ThingDef>());
            }
        }