using System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("KZDUPLICATE")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("KZDUPLICATE")] [assembly: AssemblyTitle("KZDUPLICATE")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [BepInPlugin("com.yourname.kzdub", "KZDuplicate (R.E.P.O)", "1.0.5")] public class KZDUPLICATEPlugin : BaseUnityPlugin, IOnEventCallback { private ConfigEntry DuplicateKey; private ConfigEntry GiveCoinKey; private ConfigEntry MaxDistance; private ConfigEntry SpawnOffset; private const byte DuplicateEventCode = 156; private const byte CoinEventCode = 157; private bool isCallbackRegistered; private void Awake() { DuplicateKey = ((BaseUnityPlugin)this).Config.Bind("General", "DuplicateKey", (KeyCode)109, "Key to duplicate grabbed item"); GiveCoinKey = ((BaseUnityPlugin)this).Config.Bind("General", "GiveCoinKey", (KeyCode)110, "Key to give a random cosmetic coin to all players"); MaxDistance = ((BaseUnityPlugin)this).Config.Bind("General", "MaxDistance", 5f, "Max distance to consider an object as grabbed"); SpawnOffset = ((BaseUnityPlugin)this).Config.Bind("General", "SpawnOffset", 0.5f, "Offset applied to duplicated object position"); } private void OnDestroy() { if (isCallbackRegistered && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.RemoveCallbackTarget((object)this); } } private void Update() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!isCallbackRegistered && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.AddCallbackTarget((object)this); isCallbackRegistered = true; } if (Input.GetKeyDown(DuplicateKey.Value)) { DuplicateNearbyGrabbed(); } if (Input.GetKeyDown(GiveCoinKey.Value)) { GiveRandomCoin(); } } public void OnEvent(EventData photonEvent) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (photonEvent.Code == 156) { try { object[] obj = (object[])photonEvent.CustomData; int num = (int)obj[0]; int[] array = (int[])obj[1]; Vector3 val = (Vector3)obj[2]; Quaternion val2 = (Quaternion)obj[3]; PhotonView val3 = PhotonView.Find(num); if ((Object)(object)val3 != (Object)null) { if (array.Length != 0 && (Object)(object)PhotonView.Find(array[0]) != (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"KZDuplicate: ViewID {array[0]} ya esta en uso. Abortando duplicacion para evitar kick."); } else { GameObject val4 = new GameObject("KZTempParent"); val4.SetActive(false); GameObject val5 = Object.Instantiate(((Component)val3).gameObject, val, val2, val4.transform); ((Object)val5).name = ((Object)((Component)val3).gameObject).name.Replace("(Clone)", "") + "_dup"; PhotonView[] componentsInChildren = val5.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length && i < array.Length; i++) { componentsInChildren[i].ViewID = array[i]; } ResetPhysGrabState(val5); val5.transform.SetParent((Transform)null); val5.SetActive(true); Object.Destroy((Object)(object)val4); if (PhotonNetwork.IsMasterClient) { CopyComponentState(((Component)val3).gameObject, val5, "CosmeticWorldObject"); CopyComponentState(((Component)val3).gameObject, val5, "ValuableObject"); CopyComponentState(((Component)val3).gameObject, val5, "ItemUpgrade"); SyncValuableObject(val5); } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"KZDuplicate: Received Network Duplication for '{((Object)val5).name}' with ViewID {array[0]}."); } } return; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("KZDuplicate: Error handling DuplicateEvent: " + ex)); return; } } if (photonEvent.Code == 157) { try { int rarity = (int)photonEvent.CustomData; GiveCoinLocalFallback(rarity); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)("KZDuplicate: Error handling CoinEvent: " + ex2)); } } } private void GiveRandomCoin() { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) try { int num = Random.Range(0, 4); if (PhotonNetwork.IsConnected && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient) { string baseName = "Cosmetic World Object - Common"; if (num == 1) { baseName = "Cosmetic World Object - Uncommon"; } if (num == 2) { baseName = "Cosmetic World Object - Rare"; } if (num == 3) { baseName = "Cosmetic World Object - UltraRare"; } string text = FindPrefabPathInPool(baseName); try { GameObject val = PhotonNetwork.InstantiateRoomObject(text, new Vector3(0f, -1000f, 0f), Quaternion.identity, (byte)0, (object[])null); if ((Object)(object)val != (Object)null) { PhotonView component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.RPC("ExtractRPC", (RpcTarget)0, Array.Empty()); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"KZDuplicate: Otorgada moneda cosmética (Rareza: {num}) vía ExtractRPC nativo."); return; } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("KZDuplicate: Native ExtractRPC failed: " + ex.Message + ". Fallback to RaiseEvent.")); } } if (PhotonNetwork.IsConnected && PhotonNetwork.InRoom) { object obj = num; RaiseEventOptions val2 = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; SendOptions val3 = default(SendOptions); ((SendOptions)(ref val3)).Reliability = true; SendOptions val4 = val3; PhotonNetwork.RaiseEvent((byte)157, obj, val2, val4); } GiveCoinLocalFallback(num); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)("KZDuplicate: Error al dar moneda cosmética: " + ex2)); } } private void GiveCoinLocalFallback(int rarity) { try { Type type = Type.GetType("RoundDirector, Assembly-CSharp"); if (type != null) { FieldInfo field = type.GetField("instance", BindingFlags.Static | BindingFlags.Public); if (field != null) { object value = field.GetValue(null); if (value != null) { MethodInfo method = type.GetMethod("CosmeticWorldObjectExtracted", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { Type type2 = Type.GetType("SemiFunc+Rarity, Assembly-CSharp") ?? Type.GetType("Rarity, Assembly-CSharp"); if (type2 != null) { object obj = Enum.ToObject(type2, rarity); method.Invoke(value, new object[1] { obj }); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"KZDuplicate: Otorgada moneda cosmética (Rareza: {rarity}) a través de RoundDirector (Fallback Local)."); return; } } } } } Type type3 = Type.GetType("PlayerCosmetics, Assembly-CSharp"); if (!(type3 != null)) { return; } Object[] array = Object.FindObjectsOfType(type3); Type type4 = Type.GetType("SemiFunc+Rarity, Assembly-CSharp") ?? Type.GetType("Rarity, Assembly-CSharp"); if (!(type4 != null)) { return; } object obj2 = Enum.ToObject(type4, rarity); Object[] array2 = array; foreach (Object obj3 in array2) { MethodInfo method2 = type3.GetMethod("CosmeticTokenAdd", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method2 != null) { method2.Invoke(obj3, new object[1] { obj2 }); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("KZDuplicate: Error en GiveCoinLocalFallback: " + ex)); } } private void DuplicateNearbyGrabbed() { //IL_054d: Unknown result type (might be due to invalid IL or missing references) //IL_0554: Expected O, but got Unknown //IL_055d: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Expected O, but got Unknown //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_04db: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_0504: Unknown result type (might be due to invalid IL or missing references) //IL_0506: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) //IL_0522: Expected O, but got Unknown //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return; } GameObject val = null; if ((Object)(object)PhysGrabber.instance != (Object)null && (Object)(object)PhysGrabber.instance.grabbedObjectTransform != (Object)null) { val = ((Component)PhysGrabber.instance.grabbedObjectTransform).gameObject; ((BaseUnityPlugin)this).Logger.LogInfo((object)("KZDuplicate: Detectado objeto agarrado: " + ((Object)val).name)); } RaycastHit val2 = default(RaycastHit); if ((Object)(object)val == (Object)null && Physics.Raycast(new Ray(((Component)main).transform.position, ((Component)main).transform.forward), ref val2, MaxDistance.Value, -1, (QueryTriggerInteraction)2) && (Object)(object)((RaycastHit)(ref val2)).collider != (Object)null) { val = (Object.op_Implicit((Object)(object)((RaycastHit)(ref val2)).collider.attachedRigidbody) ? ((Component)((RaycastHit)(ref val2)).collider.attachedRigidbody).gameObject : ((Component)((RaycastHit)(ref val2)).collider).gameObject); ((BaseUnityPlugin)this).Logger.LogInfo((object)("KZDuplicate: Raycast detecto: " + ((Object)val).name + (((RaycastHit)(ref val2)).collider.isTrigger ? " (Trigger)" : " (Solid)"))); } if ((Object)(object)val == (Object)null) { Collider[] array = Physics.OverlapSphere(((Component)main).transform.position + ((Component)main).transform.forward * 1f, 1f, -1, (QueryTriggerInteraction)2); foreach (Collider val3 in array) { if (!((Object)((Component)val3).gameObject).name.Contains("Player") && !((Object)((Component)val3).gameObject).name.Contains("Camera")) { val = (Object.op_Implicit((Object)(object)val3.attachedRigidbody) ? ((Component)val3.attachedRigidbody).gameObject : ((Component)val3).gameObject); if ((Object)(object)val != (Object)null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("KZDuplicate: OverlapSphere detecto: " + ((Object)val).name)); break; } } } } if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"KZDuplicate: No se encontro ningun objeto para duplicar (Mira mas de cerca)."); return; } if ((Object)(object)val.GetComponent("PlayerAvatar") != (Object)null || (Object)(object)val.GetComponent() != (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"KZDuplicate: Bloqueada duplicacion de jugador o camara por componente."); return; } string text = ((Object)val).name.ToLower(); if (text.Contains("player") && !text.Contains("item") && !text.Contains("upgrade") && !text.Contains("valuable")) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("KZDuplicate: Bloqueada duplicacion por nombre (posible jugador): " + ((Object)val).name)); return; } try { Vector3 val4 = ((Component)main).transform.position + ((Component)main).transform.forward * 1.5f; string text2 = ((Object)val).name.Replace("(Clone)", "").Replace("_dup", "").Trim(); string text3 = FindPrefabPathInPool(text2); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"KZDuplicate: Intentando duplicar '{text2}' en {val4}..."); if (PhotonNetwork.IsConnected && PhotonNetwork.InRoom) { try { GameObject val5 = PhotonNetwork.Instantiate(text3, val4, val.transform.rotation, (byte)0, (object[])null); if (PhotonNetwork.IsMasterClient && (Object)(object)val5 != (Object)null) { CopyComponentState(val, val5, "CosmeticWorldObject"); CopyComponentState(val, val5, "ValuableObject"); CopyComponentState(val, val5, "ItemUpgrade"); SyncValuableObject(val5); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"KZDuplicate: Duplicacion nativa Photon exitosa."); return; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("KZDuplicate: Photon.Instantiate fallo: " + ex.Message)); } } PhotonView component = val.GetComponent(); if ((Object)(object)component != (Object)null && PhotonNetwork.IsConnected && PhotonNetwork.InRoom) { int viewID = component.ViewID; GameObject val6 = new GameObject("KZTempParent"); val6.SetActive(false); GameObject val7 = Object.Instantiate(val, val4, val.transform.rotation, val6.transform); ((Object)val7).name = text2 + "_dup"; PhotonView[] componentsInChildren = val7.GetComponentsInChildren(true); int[] array2 = new int[componentsInChildren.Length]; for (int j = 0; j < componentsInChildren.Length; j++) { PhotonNetwork.AllocateViewID(componentsInChildren[j]); array2[j] = componentsInChildren[j].ViewID; } ResetPhysGrabState(val7); val7.transform.SetParent((Transform)null); val7.SetActive(true); Object.Destroy((Object)(object)val6); if (PhotonNetwork.IsMasterClient) { CopyComponentState(val, val7, "CosmeticWorldObject"); CopyComponentState(val, val7, "ValuableObject"); CopyComponentState(val, val7, "ItemUpgrade"); SyncValuableObject(val7); } object[] array3 = new object[4] { viewID, array2, val4, val.transform.rotation }; RaiseEventOptions val8 = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; SendOptions val9 = default(SendOptions); ((SendOptions)(ref val9)).Reliability = true; PhotonNetwork.RaiseEvent((byte)156, (object)array3, val8, val9); ((BaseUnityPlugin)this).Logger.LogInfo((object)("KZDuplicate: Fallback Network Duplicated via RaiseEvent '" + ((Object)val).name + "'.")); return; } GameObject val10 = new GameObject("KZTempParent"); val10.SetActive(false); GameObject val11 = Object.Instantiate(val, val4, val.transform.rotation, val10.transform); ((Object)val11).name = text2 + "_dup"; PhotonView[] componentsInChildren2 = val11.GetComponentsInChildren(true); foreach (PhotonView val12 in componentsInChildren2) { if (!PhotonNetwork.AllocateViewID(val12)) { val12.ViewID = Random.Range(10000, 99999); } } ResetPhysGrabState(val11); val11.transform.SetParent((Transform)null); val11.SetActive(true); Object.Destroy((Object)(object)val10); ((BaseUnityPlugin)this).Logger.LogInfo((object)"KZDuplicate: Duplicacion local exitosa."); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)("KZDuplicate: Failed to duplicate object: " + ex2)); } } private void SyncValuableObject(GameObject go) { try { Component component = go.GetComponent("ValuableObject"); if ((Object)(object)component == (Object)null) { return; } PhotonView component2 = go.GetComponent(); if (!((Object)(object)component2 == (Object)null)) { FieldInfo field = ((object)component).GetType().GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { float num = (float)field.GetValue(component); component2.RPC("DollarValueSetRPC", (RpcTarget)0, new object[1] { num }); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"KZDuplicate: Valor sincronizado para {((Object)go).name}: {num}"); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("KZDuplicate: Error al sincronizar valor: " + ex.Message)); } } private void CopyComponentState(GameObject source, GameObject target, string componentName) { if (componentName == "ItemUpgrade") { Type type = Type.GetType("ItemUpgrade, Assembly-CSharp"); if (type != null) { Component[] components = source.GetComponents(type); Component[] components2 = target.GetComponents(type); for (int i = 0; i < components.Length && i < components2.Length; i++) { CopyFields(components[i], components2[i]); SetPrivateField(components2[i], "upgradeDone", false); SetPrivateField(components2[i], "itemActivated", false); } return; } } Component component = source.GetComponent(componentName); Component component2 = target.GetComponent(componentName); if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { CopyFields(component, component2); } } private void CopyFields(Component src, Component dst) { FieldInfo[] fields = ((object)src).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { try { if (!(fieldInfo.Name == "photonView") && !(fieldInfo.Name == "pv") && !(fieldInfo.Name == "discovered")) { Type fieldType = fieldInfo.FieldType; bool num = fieldType.IsValueType || fieldType == typeof(string); bool flag = typeof(ScriptableObject).IsAssignableFrom(fieldType); if (num || flag) { fieldInfo.SetValue(dst, fieldInfo.GetValue(src)); } } } catch { } } } private string FindPrefabPathInPool(string baseName) { try { IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool; if (prefabPool == null) { return baseName; } if (((object)prefabPool).GetType().GetField("ResourceCache", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(prefabPool) is IDictionary dictionary) { foreach (DictionaryEntry item in dictionary) { object? value = item.Value; GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val != (Object)null && ((Object)val).name.Replace("(Clone)", "").Trim() == baseName) { return (string)item.Key; } } string[] array = new string[7] { baseName, "Items/" + baseName, "Props/" + baseName, "Prefabs/" + baseName, "Cosmetic/" + baseName, "Prefabs/Items/" + baseName, "Prefabs/Props/" + baseName }; foreach (string text in array) { GameObject val2 = Resources.Load(text); if ((Object)(object)val2 != (Object)null) { dictionary[text] = val2; return text; } } GameObject[] array2 = Resources.FindObjectsOfTypeAll(); foreach (GameObject val3 in array2) { if (((Object)val3).name == baseName) { string text2 = "KZ_" + baseName; dictionary[text2] = val3; return text2; } } } } catch { } return baseName; } private void ResetPhysGrabState(GameObject clone) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) try { Type type = Type.GetType("PhysGrabObject, Assembly-CSharp"); if (!(type != null)) { return; } Component[] componentsInChildren = clone.GetComponentsInChildren(type, true); foreach (Component val in componentsInChildren) { SetPrivateField(val, "grabbed", false); SetPrivateField(val, "grabbedLocal", false); SetPrivateField(val, "heldByLocalPlayer", false); SetPrivateField(val, "hasNeverBeenGrabbed", true); FieldInfo field = type.GetField("playerGrabbing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { (field.GetValue(val) as IList)?.Clear(); } Rigidbody component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.isKinematic = false; component.velocity = Vector3.zero; component.angularVelocity = Vector3.zero; } } } catch { } } private void SetPrivateField(object obj, string fieldName, object value) { FieldInfo field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(obj, value); } } }