public static bool DesignateMultiCell(Designator __instance, IEnumerable <IntVec3> __0) { if (!Multiplayer.ShouldSync) { return(true); } // No cells implies Finalize(false), which currently doesn't cause side effects if (__0.Count() == 0) { return(true); } Designator designator = __instance; Map map = Find.CurrentMap; LoggingByteWriter writer = new LoggingByteWriter(); writer.log.Node("Designate multi cell: " + designator.GetType()); IntVec3[] cellArray = __0.ToArray(); WriteData(writer, DesignatorMode.MultiCell, designator); Sync.WriteSync(writer, cellArray); Multiplayer.Client.SendCommand(CommandType.Designator, map.uniqueID, writer.ToArray()); Multiplayer.WriterLog.nodes.Add(writer.log.current); return(false); }
public bool DoSync(object delegateInstance, object[] args) { if (!Multiplayer.ShouldSync) { return(false); } LoggingByteWriter writer = new LoggingByteWriter(); MpContext context = writer.MpContext(); writer.LogNode($"Sync delegate: {delegateType} method: {method}"); writer.LogNode("Patch: " + patch?.FullDescription()); writer.WriteInt32(syncId); Sync.WriteContext(this, writer); int mapId = ScheduledCommand.Global; IEnumerable <object> fields = fieldPaths.Select(p => delegateInstance.GetPropertyOrField(p)); EnumerableHelper.ProcessCombined(fields.Concat(args), fieldTypes.Concat(argTypes), (obj, type) => { if (type.IsCompilerGenerated()) { return; } Sync.WriteSyncObject(writer, obj, type); if (context.map is Map map) { if (mapId != ScheduledCommand.Global && mapId != map.uniqueID) { throw new Exception("SyncDelegate map mismatch"); } mapId = map.uniqueID; } }); writer.LogNode("Map id: " + mapId); Multiplayer.PacketLog.nodes.Add(writer.current); Multiplayer.Client.SendCommand(CommandType.Sync, mapId, writer.ToArray()); return(true); }
public static bool DesignateSingleCell(Designator __instance, IntVec3 __0) { if (!Multiplayer.ShouldSync) { return(true); } Designator designator = __instance; Map map = Find.CurrentMap; LoggingByteWriter writer = new LoggingByteWriter(); writer.log.Node("Designate single cell: " + designator.GetType()); WriteData(writer, DesignatorMode.SingleCell, designator); Sync.WriteSync(writer, __0); Multiplayer.Client.SendCommand(CommandType.Designator, map.uniqueID, writer.ToArray()); Multiplayer.WriterLog.nodes.Add(writer.log.current); return(false); }
public static void SendCmd(DebugSource source, int hash, Map map) { var writer = new LoggingByteWriter(); writer.Log.Node($"Debug tool {source}, map {map.ToStringSafe()}"); int cursorX = 0, cursorZ = 0; if (map != null) { cursorX = UI.MouseCell().x; cursorZ = UI.MouseCell().z; } else { cursorX = GenWorld.MouseTile(false); } writer.WriteInt32(Multiplayer.session.playerId); writer.WriteInt32((int)source); writer.WriteInt32(cursorX); writer.WriteInt32(cursorZ); writer.WriteInt32(hash); if (map != null) { writer.WriteInt32(Find.Selector.SingleSelectedThing?.thingIDNumber ?? -1); } else { writer.WriteInt32(Find.WorldSelector.SingleSelectedObject?.ID ?? -1); } Multiplayer.WriterLog.AddCurrentNode(writer); var mapId = map?.uniqueID ?? ScheduledCommand.Global; Multiplayer.Client.SendCommand(CommandType.DebugTools, mapId, writer.ToArray()); }
/// <summary> /// Returns whether the original should be cancelled /// </summary> public bool DoSync(object target, object value, object index = null) { if (!(inGameLoop || Multiplayer.ShouldSync)) { return(false); } LoggingByteWriter writer = new LoggingByteWriter(); MpContext context = writer.MpContext(); writer.Log.Node(ToString()); writer.WriteInt32(syncId); int mapId = ScheduledCommand.Global; if (targetType != null) { SyncSerialization.WriteSyncObject(writer, target, targetType); if (context.map != null) { mapId = context.map.uniqueID; } } SyncSerialization.WriteSyncObject(writer, value, fieldType); if (indexType != null) { SyncSerialization.WriteSyncObject(writer, index, indexType); } writer.Log.Node($"Map id: {mapId}"); Multiplayer.WriterLog.AddCurrentNode(writer); Multiplayer.Client.SendCommand(CommandType.Sync, mapId, writer.ToArray()); return(true); }
/// <summary> /// Returns whether the original should cancelled /// </summary> public bool DoSync(object target, object value, object index = null) { if (!(inGameLoop || Multiplayer.ShouldSync)) { return(false); } LoggingByteWriter writer = new LoggingByteWriter(); MpContext context = writer.MpContext(); writer.LogNode("Sync field " + memberPath); writer.WriteInt32(syncId); int mapId = ScheduledCommand.Global; if (targetType != null) { Sync.WriteSyncObject(writer, target, targetType); if (context.map != null) { mapId = context.map.uniqueID; } } Sync.WriteSyncObject(writer, value, fieldType); if (indexType != null) { Sync.WriteSyncObject(writer, index, indexType); } writer.LogNode("Map id: " + mapId); Multiplayer.PacketLog.nodes.Add(writer.current); Multiplayer.Client.SendCommand(CommandType.Sync, mapId, writer.ToArray()); return(true); }
private void ActualSync(A target, B arg0, C arg1, Action original) { LoggingByteWriter writer = new LoggingByteWriter(); MpContext context = writer.MpContext(); writer.LogNode("Sync action"); writer.WriteInt32(syncId); Sync.WriteSync(writer, target); Sync.WriteSync(writer, arg0); Sync.WriteSync(writer, arg1); writer.WriteInt32(GenText.StableStringHash(original.Method.MethodDesc())); Log.Message(original.Method.MethodDesc()); int mapId = writer.MpContext().map?.uniqueID ?? -1; writer.LogNode("Map id: " + mapId); Multiplayer.PacketLog.nodes.Add(writer.current); Multiplayer.Client.SendCommand(CommandType.Sync, mapId, writer.ToArray()); }
public static bool DesignateThing(Designator __instance, Thing __0) { if (!Multiplayer.ShouldSync) { return(true); } Designator designator = __instance; Map map = Find.CurrentMap; LoggingByteWriter writer = new LoggingByteWriter(); writer.log.Node("Designate thing: " + __0 + " " + designator.GetType()); WriteData(writer, DesignatorMode.Thing, designator); Sync.WriteSync(writer, __0); Multiplayer.Client.SendCommand(CommandType.Designator, map.uniqueID, writer.ToArray()); Multiplayer.WriterLog.nodes.Add(writer.log.current); MoteMaker.ThrowMetaPuffs(__0); return(false); }
public static void WriteSyncObject(ByteWriter data, object obj, SyncType syncType) { MpContext context = data.MpContext(); Type type = syncType.type; LoggingByteWriter log = data as LoggingByteWriter; log?.LogEnter(type.FullName + ": " + (obj ?? "null")); if (obj != null && !type.IsAssignableFrom(obj.GetType())) { throw new SerializationException($"Serializing with type {type} but got object of type {obj.GetType()}"); } try { if (typeof(object) == type) { return; } if (type.IsByRef) { return; } if (syncWorkersEarly.TryGetValue(type, out var syncWorkerEntryEarly)) { syncWorkerEntryEarly.Invoke(new WritingSyncWorker(data), ref obj); return; } if (syncType.expose) { if (!typeof(IExposable).IsAssignableFrom(type)) { throw new SerializationException($"Type {type} can't be exposed because it isn't IExposable"); } IExposable exposable = obj as IExposable; data.WritePrefixedBytes(ScribeUtil.WriteExposable(exposable)); return; } if (typeof(ISynchronizable).IsAssignableFrom(type)) { ((ISynchronizable)obj).Sync(new WritingSyncWorker(data)); return; } if (type.IsEnum) { Type enumType = Enum.GetUnderlyingType(type); WriteSyncObject(data, Convert.ChangeType(obj, enumType), enumType); return; } if (type.IsArray && type.GetArrayRank() == 1) { Type elementType = type.GetElementType(); Array arr = (Array)obj; if (arr.Length > ushort.MaxValue) { throw new Exception($"Tried to serialize a {elementType}[] with too many ({arr.Length}) items."); } data.WriteUShort((ushort)arr.Length); foreach (object e in arr) { WriteSyncObject(data, e, elementType); } return; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List <>)) { ListType specialList = ListType.Normal; Type listType = type.GetGenericArguments()[0]; if (listType == typeof(Thing) && obj == Find.CurrentMap.listerThings.AllThings) { context.map = Find.CurrentMap; specialList = ListType.MapAllThings; } else if (listType == typeof(Designation) && obj == Find.CurrentMap.designationManager.allDesignations) { context.map = Find.CurrentMap; specialList = ListType.MapAllDesignations; } WriteSync(data, specialList); if (specialList == ListType.Normal) { IList list = (IList)obj; if (list.Count > ushort.MaxValue) { throw new Exception($"Tried to serialize a {type} with too many ({list.Count}) items."); } data.WriteUShort((ushort)list.Count); foreach (object e in list) { WriteSyncObject(data, e, listType); } } return; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { bool isNull = obj == null; data.WriteBool(isNull); if (isNull) { return; } bool hasValue = (bool)obj.GetPropertyOrField("HasValue"); data.WriteBool(hasValue); Type nullableType = type.GetGenericArguments()[0]; if (hasValue) { WriteSyncObject(data, obj.GetPropertyOrField("Value"), nullableType); } return; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { IEnumerable e = (IEnumerable)obj; Type elementType = type.GetGenericArguments()[0]; var listType = typeof(List <>).MakeGenericType(elementType); IList list = (IList)Activator.CreateInstance(listType); foreach (var o in e) { if (list.Count > ushort.MaxValue) { throw new Exception($"Tried to serialize a {type} with too many ({list.Count}) items."); } list.Add(o); } WriteSyncObject(data, list, listType); return; } // special case if (typeof(Def).IsAssignableFrom(type)) { Def def = obj as Def; data.WriteUShort(def != null ? def.shortHash : (ushort)0); return; } // Where the magic happens if (syncWorkers.TryGetValue(type, out var syncWorkerEntry)) { syncWorkerEntry.Invoke(new WritingSyncWorker(data), ref obj); return; } log?.LogNode("No writer for " + type); throw new SerializationException("No writer for type " + type); } catch (Exception e) { MpLog.Error($"Error writing type: {type}, obj: {obj}, {e}"); throw; } finally { log?.LogExit(); } }
/// <summary> /// Returns whether the original should be cancelled /// </summary> public bool DoSync(object target, params object[] args) { if (!Multiplayer.ShouldSync) { return(false); } // todo limit per specific target/argument //if (Utils.MillisNow - lastSendTime < minTime) // return true; LoggingByteWriter writer = new LoggingByteWriter(); MpContext context = writer.MpContext(); writer.LogNode("Sync method " + method.FullDescription()); writer.WriteInt32(syncId); Sync.WriteContext(this, writer); Map map = writer.MpContext().map; if (targetType != null) { Sync.WriteSyncObject(writer, target, targetType); if (context.map is Map newMap) { map = newMap; } } for (int i = 0; i < argTypes.Length; i++) { var argType = argTypes[i]; Sync.WriteSyncObject(writer, args[i], argType); if (argType.contextMap && args[i] is Map contextMap) { map = contextMap; } if (context.map is Map newMap) { if (map != null && map != newMap) { throw new Exception($"SyncMethod map mismatch ({map?.uniqueID} and {newMap?.uniqueID})"); } map = newMap; } } int mapId = map?.uniqueID ?? ScheduledCommand.Global; writer.LogNode("Map id: " + mapId); Multiplayer.PacketLog.nodes.Add(writer.current); Multiplayer.Client.SendCommand(CommandType.Sync, mapId, writer.ToArray()); lastSendTime = Utils.MillisNow; return(true); }