diff --git a/EXILED/Exiled.API/Extensions/MirrorExtensions.cs b/EXILED/Exiled.API/Extensions/MirrorExtensions.cs index 8b4350b5b..22d799677 100644 --- a/EXILED/Exiled.API/Extensions/MirrorExtensions.cs +++ b/EXILED/Exiled.API/Extensions/MirrorExtensions.cs @@ -431,6 +431,7 @@ public static void ScaleNetworkIdentityObject(this NetworkIdentity identity, Vec /// 's type. /// Property name starting with Network. /// Value of send to target. + [Obsolete("Use overload with type-template instead.")] public static void SendFakeSyncVar(this Player target, NetworkIdentity behaviorOwner, Type targetType, string propertyName, object value) { if (!target.IsConnected) @@ -454,6 +455,38 @@ void CustomSyncVarGenerator(NetworkWriter targetWriter) } } + /// + /// Send fake values to client's . + /// + /// Target SyncVar property type. + /// Target to send. + /// of object that owns . + /// 's type. + /// Property name starting with Network. + /// Value of send to target. + public static void SendFakeSyncVar(this Player target, NetworkIdentity behaviorOwner, Type targetType, string propertyName, T value) + { + if (!target.IsConnected) + return; + + NetworkWriterPooled writer = NetworkWriterPool.Get(); + NetworkWriterPooled writer2 = NetworkWriterPool.Get(); + MakeCustomSyncWriter(behaviorOwner, targetType, null, CustomSyncVarGenerator, writer, writer2); + target.Connection.Send(new EntityStateMessage + { + netId = behaviorOwner.netId, + payload = writer.ToArraySegment(), + }); + + NetworkWriterPool.Return(writer); + NetworkWriterPool.Return(writer2); + void CustomSyncVarGenerator(NetworkWriter targetWriter) + { + targetWriter.WriteULong(SyncVarDirtyBits[$"{targetType.Name}.{propertyName}"]); + WriterExtensions[typeof(T)]?.Invoke(null, new object[2] { targetWriter, value }); + } + } + /// /// Force resync to client's . /// diff --git a/EXILED/Exiled.Events/Patches/Generic/DoorList.cs b/EXILED/Exiled.Events/Patches/Generic/DoorList.cs index 4f1ce6e33..b8b653455 100644 --- a/EXILED/Exiled.Events/Patches/Generic/DoorList.cs +++ b/EXILED/Exiled.Events/Patches/Generic/DoorList.cs @@ -30,14 +30,48 @@ namespace Exiled.Events.Patches.Generic [HarmonyPatch(typeof(DoorVariant), nameof(DoorVariant.RegisterRooms))] internal class DoorList { - private static void Postfix(DoorVariant __instance) + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { - if (Door.DoorVariantToDoor.ContainsKey(__instance)) + List newInstructions = ListPool.Pool.Get(instructions); + + Label ret = generator.DefineLabel(); + + // if (Rooms == null) + // return; + newInstructions.InsertRange( + 0, + new CodeInstruction[] + { + new(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(DoorVariant), nameof(DoorVariant.Rooms))), + new(OpCodes.Brfalse_S, ret), + }); + + // DoorList.InitDoor(this); + newInstructions.InsertRange( + newInstructions.Count - 1, + new CodeInstruction[] + { + new(OpCodes.Ldarg_0), + new(OpCodes.Call, Method(typeof(DoorList), nameof(DoorList.InitDoor))), + }); + + newInstructions[newInstructions.Count - 1].labels.Add(ret); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + + private static void InitDoor(DoorVariant doorVariant) + { + if (Door.DoorVariantToDoor.ContainsKey(doorVariant)) return; - List rooms = __instance.Rooms.Select(identifier => Room.RoomIdentifierToRoom[identifier]).ToList(); + List rooms = doorVariant.Rooms.Select(identifier => Room.RoomIdentifierToRoom[identifier]).ToList(); - Door door = Door.Create(__instance, rooms); + Door door = Door.Create(doorVariant, rooms); foreach (Room room in rooms) {