using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LuckyUpgrades.Patches;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("REPOShareMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("R.E.P.O 업그레이드 확률 공유 모드 - 스탯 아이템 획득 시 설정된 확률에 따라 다른 플레이어에게도 적용")]
[assembly: AssemblyFileVersion("1.0.5.0")]
[assembly: AssemblyInformationalVersion("1.0.5+58fa60b808466df103f65d9e1e395dccdaa242a1")]
[assembly: AssemblyProduct("LuckyUpgrades")]
[assembly: AssemblyTitle("LuckyUpgrades")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.5.0")]
[module: UnverifiableCode]
[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;
}
}
}
namespace LuckyUpgrades
{
[BepInPlugin("com.reposharemod.luckyupgrades", "LuckyUpgrades", "1.0.5")]
public class Plugin : BaseUnityPlugin
{
private Harmony _harmony;
public static Plugin Instance { get; private set; }
internal static ManualLogSource Log { get; private set; }
public static UpgradeConfig UpgradeConfiguration { get; private set; }
private void Awake()
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
Log.LogInfo((object)"[LuckyUpgrades] Plugin loading...");
UpgradeConfiguration = new UpgradeConfig(((BaseUnityPlugin)this).Config);
Log.LogInfo((object)"[LuckyUpgrades] Configuration loaded");
_harmony = new Harmony("com.reposharemod.luckyupgrades");
UpgradePatcher.PatchAll(_harmony);
Log.LogInfo((object)"[LuckyUpgrades] v1.0.5 loaded successfully!");
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.reposharemod.luckyupgrades";
public const string PLUGIN_NAME = "LuckyUpgrades";
public const string PLUGIN_VERSION = "1.0.5";
}
public class UpgradeConfig
{
public ConfigEntry<bool> ModEnabled { get; private set; }
public ConfigEntry<bool> HostOnly { get; private set; }
public ConfigEntry<bool> UseOneChanceForAll { get; private set; }
public ConfigEntry<int> GlobalChanceToActivate { get; private set; }
public ConfigEntry<int> ChanceToWasteUpgrade { get; private set; }
public ConfigEntry<int> ChanceToActivatePlayerHealth { get; private set; }
public ConfigEntry<int> ChanceToActivatePlayerEnergy { get; private set; }
public ConfigEntry<int> ChanceToActivatePlayerSprintSpeed { get; private set; }
public ConfigEntry<int> ChanceToActivatePlayerExtraJump { get; private set; }
public ConfigEntry<int> ChanceToActivatePlayerTumbleLaunch { get; private set; }
public ConfigEntry<int> ChanceToActivatePlayerGrabRange { get; private set; }
public ConfigEntry<int> ChanceToActivatePlayerGrabStrength { get; private set; }
public ConfigEntry<int> ChanceToActivatePlayerGrabThrow { get; private set; }
public ConfigEntry<int> ChanceToActivateMapPlayerCount { get; private set; }
public UpgradeConfig(ConfigFile config)
{
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Expected O, but got Unknown
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Expected O, but got Unknown
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Expected O, but got Unknown
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Expected O, but got Unknown
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Expected O, but got Unknown
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Expected O, but got Unknown
//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Expected O, but got Unknown
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Expected O, but got Unknown
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_022a: Expected O, but got Unknown
//IL_024f: Unknown result type (might be due to invalid IL or missing references)
//IL_0259: Expected O, but got Unknown
ModEnabled = config.Bind<bool>("Global", "ModEnabled", true, "Enable or disable the mod");
HostOnly = config.Bind<bool>("Global", "HostOnly", true, "Only the host will run the mod logic (recommended: true)");
UseOneChanceForAll = config.Bind<bool>("Global", "UseOneChanceForAll", true, "If true, the GlobalChanceToActivate will be used for all upgrades");
GlobalChanceToActivate = config.Bind<int>("Global", "GlobalChanceToActivate", 25, new ConfigDescription("% Chance to activate the upgrade for every player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
ChanceToWasteUpgrade = config.Bind<int>("Global", "ChanceToWasteUpgrade", 0, new ConfigDescription("% Chance to waste the upgrade and activate it for nobody", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
ChanceToActivatePlayerHealth = config.Bind<int>("SpecificUpgrades", "ChanceToActivatePlayerHealth", 50, new ConfigDescription("% Chance to activate the Health upgrade for every player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
ChanceToActivatePlayerEnergy = config.Bind<int>("SpecificUpgrades", "ChanceToActivatePlayerEnergy", 25, new ConfigDescription("% Chance to activate the Energy (Stamina) upgrade for every player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
ChanceToActivatePlayerSprintSpeed = config.Bind<int>("SpecificUpgrades", "ChanceToActivatePlayerSprintSpeed", 25, new ConfigDescription("% Chance to activate the Sprint Speed upgrade for every player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
ChanceToActivatePlayerExtraJump = config.Bind<int>("SpecificUpgrades", "ChanceToActivatePlayerExtraJump", 25, new ConfigDescription("% Chance to activate the Extra Jump upgrade for every player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
ChanceToActivatePlayerTumbleLaunch = config.Bind<int>("SpecificUpgrades", "ChanceToActivatePlayerTumbleLaunch", 25, new ConfigDescription("% Chance to activate the Tumble Launch upgrade for every player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
ChanceToActivatePlayerGrabRange = config.Bind<int>("SpecificUpgrades", "ChanceToActivatePlayerGrabRange", 25, new ConfigDescription("% Chance to activate the Grab Range upgrade for every player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
ChanceToActivatePlayerGrabStrength = config.Bind<int>("SpecificUpgrades", "ChanceToActivatePlayerGrabStrength", 25, new ConfigDescription("% Chance to activate the Grab Strength upgrade for every player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
ChanceToActivatePlayerGrabThrow = config.Bind<int>("SpecificUpgrades", "ChanceToActivatePlayerGrabThrow", 25, new ConfigDescription("% Chance to activate the Grab Throw upgrade for every player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
ChanceToActivateMapPlayerCount = config.Bind<int>("SpecificUpgrades", "ChanceToActivateMapPlayerCount", 25, new ConfigDescription("% Chance to activate the Map Player Count upgrade for every player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
}
public int GetShareChance(string upgradeType)
{
if (UseOneChanceForAll.Value)
{
return GlobalChanceToActivate.Value;
}
string text = upgradeType.ToLower();
if (text.Contains("health"))
{
return ChanceToActivatePlayerHealth.Value;
}
if (text.Contains("energy") || text.Contains("stamina"))
{
return ChanceToActivatePlayerEnergy.Value;
}
if (text.Contains("sprint") || text.Contains("speed"))
{
return ChanceToActivatePlayerSprintSpeed.Value;
}
if (text.Contains("jump"))
{
return ChanceToActivatePlayerExtraJump.Value;
}
if (text.Contains("tumble") || text.Contains("launch"))
{
return ChanceToActivatePlayerTumbleLaunch.Value;
}
if (text.Contains("range"))
{
return ChanceToActivatePlayerGrabRange.Value;
}
if (text.Contains("strength"))
{
return ChanceToActivatePlayerGrabStrength.Value;
}
if (text.Contains("throw"))
{
return ChanceToActivatePlayerGrabThrow.Value;
}
if (text.Contains("map") || text.Contains("count"))
{
return ChanceToActivateMapPlayerCount.Value;
}
return GlobalChanceToActivate.Value;
}
public bool ShouldWasteUpgrade()
{
if (ChanceToWasteUpgrade.Value <= 0)
{
return false;
}
return new Random().Next(0, 100) < ChanceToWasteUpgrade.Value;
}
}
}
namespace LuckyUpgrades.Patches
{
[HarmonyPatch]
public class UpgradePatch
{
private static readonly Random _random = new Random();
[HarmonyTargetMethod]
public static MethodBase TargetMethod()
{
string[] array = new string[13]
{
"ItemUpgradePlayerHealth", "ItemUpgradePlayerEnergy", "ItemUpgradePlayerSprintSpeed", "ItemUpgradePlayerExtraJump", "ItemUpgradePlayerTumbleLaunch", "ItemUpgradePlayerGrabRange", "ItemUpgradePlayerGrabStrength", "ItemUpgradePlayerGrabThrow", "ItemUpgradeMapPlayerCount", "ItemUpgrade",
"UpgradeItem", "PlayerUpgrade", "StatsManager"
};
string[] array2 = new string[6] { "Upgrade", "ApplyUpgrade", "Apply", "AddUpgrade", "PickUp", "OnPickup" };
string[] array3 = array;
foreach (string text in array3)
{
Type type = AccessTools.TypeByName(text);
if (type == null)
{
continue;
}
string[] array4 = array2;
foreach (string text2 in array4)
{
MethodInfo methodInfo = AccessTools.Method(type, text2, (Type[])null, (Type[])null);
if (methodInfo != null)
{
Plugin.Log.LogInfo((object)("[LuckyUpgrades] Patch target found: " + text + "." + text2));
return methodInfo;
}
}
}
Plugin.Log.LogWarning((object)"[LuckyUpgrades] Could not find patch target method. Manual configuration required.");
return null;
}
[HarmonyPostfix]
public static void Postfix(object __instance)
{
try
{
if (!Plugin.UpgradeConfiguration.ModEnabled.Value || (Plugin.UpgradeConfiguration.HostOnly.Value && !IsHost()))
{
return;
}
if (Plugin.UpgradeConfiguration.ShouldWasteUpgrade())
{
Plugin.Log.LogInfo((object)"[LuckyUpgrades] Upgrade wasted - no one gets it!");
return;
}
string upgradeType = GetUpgradeType(__instance);
if (string.IsNullOrEmpty(upgradeType))
{
Plugin.Log.LogWarning((object)"[LuckyUpgrades] Could not determine upgrade type.");
return;
}
object sourcePlayer = GetSourcePlayer(__instance);
if (sourcePlayer == null)
{
Plugin.Log.LogWarning((object)"[LuckyUpgrades] Could not determine source player.");
}
else
{
ApplyUpgradeToOtherPlayers(upgradeType, sourcePlayer);
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[LuckyUpgrades] Error in Postfix: " + ex.Message));
}
}
private static bool IsHost()
{
try
{
Type type = AccessTools.TypeByName("Photon.Pun.PhotonNetwork");
if (type != null)
{
PropertyInfo property = type.GetProperty("IsMasterClient");
if (property != null)
{
return (bool)property.GetValue(null);
}
}
Type type2 = AccessTools.TypeByName("GameManager");
if (type2 != null)
{
PropertyInfo propertyInfo = type2.GetProperty("IsHost") ?? type2.GetProperty("isHost");
if (propertyInfo != null)
{
object gameManagerInstance = GetGameManagerInstance();
if (gameManagerInstance != null)
{
return (bool)propertyInfo.GetValue(gameManagerInstance);
}
}
}
return true;
}
catch
{
return true;
}
}
private static object GetGameManagerInstance()
{
try
{
Type type = AccessTools.TypeByName("GameManager");
if (type == null)
{
return null;
}
PropertyInfo propertyInfo = type.GetProperty("Instance") ?? type.GetProperty("instance");
if (propertyInfo != null)
{
return propertyInfo.GetValue(null);
}
FieldInfo fieldInfo = type.GetField("Instance") ?? type.GetField("instance");
if (fieldInfo != null)
{
return fieldInfo.GetValue(null);
}
return null;
}
catch
{
return null;
}
}
private static string GetUpgradeType(object instance)
{
if (instance == null)
{
return null;
}
try
{
Type type = instance.GetType();
string name = type.Name;
if (name.Contains("Health"))
{
return "Health";
}
if (name.Contains("Energy") || name.Contains("Stamina"))
{
return "Energy";
}
if (name.Contains("Sprint") || name.Contains("Speed"))
{
return "SprintSpeed";
}
if (name.Contains("Jump"))
{
return "ExtraJump";
}
if (name.Contains("Tumble") || name.Contains("Launch"))
{
return "TumbleLaunch";
}
if (name.Contains("Range"))
{
return "GrabRange";
}
if (name.Contains("Strength"))
{
return "GrabStrength";
}
if (name.Contains("Throw"))
{
return "GrabThrow";
}
if (name.Contains("Map") || name.Contains("Count"))
{
return "MapPlayerCount";
}
PropertyInfo propertyInfo = type.GetProperty("upgradeType") ?? type.GetProperty("UpgradeType");
if (propertyInfo != null)
{
return propertyInfo.GetValue(instance)?.ToString();
}
FieldInfo fieldInfo = type.GetField("upgradeType") ?? type.GetField("UpgradeType");
if (fieldInfo != null)
{
return fieldInfo.GetValue(instance)?.ToString();
}
return name;
}
catch
{
return null;
}
}
private static object GetSourcePlayer(object instance)
{
if (instance == null)
{
return null;
}
try
{
Type type = instance.GetType();
string[] array = new string[8] { "player", "Player", "playerController", "PlayerController", "owner", "Owner", "playerAvatar", "PlayerAvatar" };
foreach (string name in array)
{
PropertyInfo property = type.GetProperty(name);
if (property != null)
{
return property.GetValue(instance);
}
FieldInfo field = type.GetField(name);
if (field != null)
{
return field.GetValue(instance);
}
}
return null;
}
catch
{
return null;
}
}
private static void ApplyUpgradeToOtherPlayers(string upgradeType, object sourcePlayer)
{
try
{
int shareChance = Plugin.UpgradeConfiguration.GetShareChance(upgradeType);
List<object> allPlayers = GetAllPlayers();
if (allPlayers == null || allPlayers.Count <= 1)
{
Plugin.Log.LogDebug((object)"[LuckyUpgrades] No other players found.");
return;
}
int num = 0;
foreach (object item in allPlayers)
{
if (IsSamePlayer(item, sourcePlayer))
{
continue;
}
int num2 = _random.Next(0, 100);
if (num2 < shareChance)
{
if (ApplyUpgradeToPlayer(item, upgradeType))
{
num++;
Plugin.Log.LogInfo((object)$"[LuckyUpgrades] {upgradeType} upgrade shared to player (chance: {shareChance}%)");
}
}
else
{
Plugin.Log.LogDebug((object)$"[LuckyUpgrades] {upgradeType} upgrade not shared (roll: {num2}, chance: {shareChance})");
}
}
if (num > 0)
{
Plugin.Log.LogInfo((object)$"[LuckyUpgrades] {upgradeType} upgrade shared to {num} players total");
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[LuckyUpgrades] Error sharing upgrade: " + ex.Message));
}
}
private static List<object> GetAllPlayers()
{
try
{
List<object> list = new List<object>();
Type type = AccessTools.TypeByName("PlayerController");
if (type != null)
{
MethodInfo methodInfo = type.GetMethod("GetAllPlayers") ?? type.GetMethod("GetAll");
if (methodInfo != null && methodInfo.IsStatic && methodInfo.Invoke(null, null) is IEnumerable enumerable)
{
foreach (object item3 in enumerable)
{
list.Add(item3);
}
return list;
}
}
object gameManagerInstance = GetGameManagerInstance();
if (gameManagerInstance != null)
{
Type type2 = gameManagerInstance.GetType();
PropertyInfo propertyInfo = type2.GetProperty("players") ?? type2.GetProperty("Players");
if (propertyInfo != null && propertyInfo.GetValue(gameManagerInstance) is IEnumerable enumerable2)
{
foreach (object item4 in enumerable2)
{
list.Add(item4);
}
return list;
}
}
if (type != null)
{
Object[] array = Object.FindObjectsOfType(type);
foreach (Object item in array)
{
list.Add(item);
}
return list;
}
Type type3 = AccessTools.TypeByName("PlayerAvatar");
if (type3 != null)
{
Object[] array = Object.FindObjectsOfType(type3);
foreach (Object item2 in array)
{
list.Add(item2);
}
return list;
}
return list;
}
catch
{
return new List<object>();
}
}
private static bool IsSamePlayer(object player1, object player2)
{
if (player1 == null || player2 == null)
{
return false;
}
if (!player1.Equals(player2))
{
return player1 == player2;
}
return true;
}
private static bool ApplyUpgradeToPlayer(object player, string upgradeType)
{
try
{
Type type = AccessTools.TypeByName("StatsManager");
if (type != null)
{
object statsManagerForPlayer = GetStatsManagerForPlayer(player);
if (statsManagerForPlayer != null)
{
MethodInfo methodInfo = type.GetMethod("AddUpgrade") ?? type.GetMethod("ApplyUpgrade") ?? type.GetMethod("IncreaseLevel");
if (methodInfo != null)
{
methodInfo.Invoke(statsManagerForPlayer, new object[1] { upgradeType });
return true;
}
}
}
return upgradeType.ToLower() switch
{
"health" => ModifyPlayerStat(player, "maxHealth", 20f, isAdditive: true),
"energy" => ModifyPlayerStat(player, "maxEnergy", 10f, isAdditive: true),
"sprintspeed" => ModifyPlayerStat(player, "sprintSpeed", 0.1f, isAdditive: true),
"extrajump" => ModifyPlayerStat(player, "extraJumps", 1f, isAdditive: true),
"tumblelaunch" => ModifyPlayerStat(player, "tumbleLaunchLevel", 1f, isAdditive: true),
"grabrange" => ModifyPlayerStat(player, "grabRange", 0.5f, isAdditive: true),
"grabstrength" => ModifyPlayerStat(player, "grabStrength", 1f, isAdditive: true),
"grabthrow" => ModifyPlayerStat(player, "throwStrength", 1f, isAdditive: true),
_ => false,
};
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[LuckyUpgrades] Failed to apply upgrade to player: " + ex.Message));
return false;
}
}
private static object GetStatsManagerForPlayer(object player)
{
if (player == null)
{
return null;
}
try
{
Type type = player.GetType();
PropertyInfo propertyInfo = type.GetProperty("statsManager") ?? type.GetProperty("StatsManager") ?? type.GetProperty("stats");
if (propertyInfo != null)
{
return propertyInfo.GetValue(player);
}
FieldInfo fieldInfo = type.GetField("statsManager") ?? type.GetField("StatsManager") ?? type.GetField("stats");
if (fieldInfo != null)
{
return fieldInfo.GetValue(player);
}
Component val = (Component)((player is Component) ? player : null);
if (val != null)
{
Type type2 = AccessTools.TypeByName("StatsManager");
if (type2 != null)
{
MethodInfo methodInfo = typeof(Component).GetMethod("GetComponent", Type.EmptyTypes)?.MakeGenericMethod(type2);
if (methodInfo != null)
{
return methodInfo.Invoke(val, null);
}
}
}
return null;
}
catch
{
return null;
}
}
private static bool ModifyPlayerStat(object player, string statName, float amount, bool isAdditive)
{
if (player == null)
{
return false;
}
try
{
Type type = player.GetType();
PropertyInfo property = type.GetProperty(statName);
if (property != null && property.CanWrite)
{
float num = Convert.ToSingle(property.GetValue(player));
float num2 = (isAdditive ? (num + amount) : (num * amount));
property.SetValue(player, num2);
return true;
}
FieldInfo field = type.GetField(statName);
if (field != null)
{
float num3 = Convert.ToSingle(field.GetValue(player));
float num4 = (isAdditive ? (num3 + amount) : (num3 * amount));
field.SetValue(player, num4);
return true;
}
return false;
}
catch
{
return false;
}
}
}
public static class UpgradePatcher
{
private static readonly Random _random = new Random();
public static void PatchAll(Harmony harmony)
{
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Expected O, but got Unknown
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Expected O, but got Unknown
string[] obj = new string[9] { "ItemUpgradePlayerHealth", "ItemUpgradePlayerEnergy", "ItemUpgradePlayerSprintSpeed", "ItemUpgradePlayerExtraJump", "ItemUpgradePlayerTumbleLaunch", "ItemUpgradePlayerGrabRange", "ItemUpgradePlayerGrabStrength", "ItemUpgradePlayerGrabThrow", "ItemUpgradeMapPlayerCount" };
int num = 0;
MethodInfo method = typeof(UpgradePatcher).GetMethod("Postfix", BindingFlags.Static | BindingFlags.Public);
string[] array = obj;
foreach (string text in array)
{
Type type = AccessTools.TypeByName(text);
if (!(type == null))
{
MethodInfo methodInfo = AccessTools.Method(type, "Upgrade", (Type[])null, (Type[])null) ?? AccessTools.Method(type, "ApplyUpgrade", (Type[])null, (Type[])null) ?? AccessTools.Method(type, "Apply", (Type[])null, (Type[])null);
if (methodInfo != null)
{
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Plugin.Log.LogInfo((object)("[LuckyUpgrades] Patch applied to: " + text + "." + methodInfo.Name));
num++;
}
}
}
if (num != 0)
{
return;
}
Type type2 = AccessTools.TypeByName("ItemUpgrade");
if (type2 != null)
{
MethodInfo methodInfo2 = AccessTools.Method(type2, "Upgrade", (Type[])null, (Type[])null) ?? AccessTools.Method(type2, "ApplyUpgrade", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Plugin.Log.LogInfo((object)("[LuckyUpgrades] Patch applied to generic class: " + type2.Name));
}
}
}
public static void Postfix(object __instance)
{
try
{
if (!Plugin.UpgradeConfiguration.ModEnabled.Value || (Plugin.UpgradeConfiguration.HostOnly.Value && !IsHost()))
{
return;
}
if (Plugin.UpgradeConfiguration.ShouldWasteUpgrade())
{
Plugin.Log.LogInfo((object)"[LuckyUpgrades] Upgrade chance failed - Upgrade wasted!");
return;
}
string upgradeType = GetUpgradeType(__instance);
object sourcePlayer = GetSourcePlayer(__instance);
if (!string.IsNullOrEmpty(upgradeType) && sourcePlayer != null)
{
ApplyUpgradeToOtherPlayers(upgradeType, sourcePlayer);
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[LuckyUpgrades] Error in Postfix patch: " + ex.Message));
}
}
private static bool IsHost()
{
try
{
Type type = AccessTools.TypeByName("Photon.Pun.PhotonNetwork");
if (type != null)
{
PropertyInfo property = type.GetProperty("IsMasterClient");
if (property != null)
{
return (bool)property.GetValue(null);
}
}
Type type2 = AccessTools.TypeByName("GameManager");
if (type2 != null)
{
object obj = AccessTools.Property(type2, "Instance")?.GetValue(null) ?? AccessTools.Field(type2, "instance")?.GetValue(null);
if (obj != null)
{
return (bool)(AccessTools.Property(type2, "IsHost")?.GetValue(obj) ?? AccessTools.Field(type2, "isHost")?.GetValue(obj) ?? ((object)true));
}
}
return true;
}
catch
{
return true;
}
}
private static string GetUpgradeType(object instance)
{
string name = instance.GetType().Name;
if (name.Contains("Health"))
{
return "Health";
}
if (name.Contains("Energy") || name.Contains("Stamina"))
{
return "Energy";
}
if (name.Contains("Sprint") || name.Contains("Speed"))
{
return "SprintSpeed";
}
if (name.Contains("Jump"))
{
return "ExtraJump";
}
if (name.Contains("Tumble") || name.Contains("Launch"))
{
return "TumbleLaunch";
}
if (name.Contains("Range"))
{
return "GrabRange";
}
if (name.Contains("Strength"))
{
return "GrabStrength";
}
if (name.Contains("Throw"))
{
return "GrabThrow";
}
if (name.Contains("Map") || name.Contains("Count"))
{
return "MapPlayerCount";
}
return name;
}
private static object GetSourcePlayer(object instance)
{
Type type = instance.GetType();
string[] array = new string[8] { "player", "Player", "playerController", "PlayerController", "owner", "Owner", "playerAvatar", "PlayerAvatar" };
foreach (string text in array)
{
object obj = AccessTools.Property(type, text)?.GetValue(instance) ?? AccessTools.Field(type, text)?.GetValue(instance);
if (obj != null)
{
return obj;
}
}
return null;
}
private static void ApplyUpgradeToOtherPlayers(string upgradeType, object sourcePlayer)
{
int shareChance = Plugin.UpgradeConfiguration.GetShareChance(upgradeType);
foreach (object allPlayer in GetAllPlayers())
{
if (allPlayer != null && !allPlayer.Equals(sourcePlayer) && _random.Next(0, 100) < shareChance && ApplyUpgradeToPlayer(allPlayer, upgradeType))
{
Plugin.Log.LogInfo((object)$"[LuckyUpgrades] Success! {upgradeType} upgrade shared with another player (Chance: {shareChance}%)");
}
}
}
private static List<object> GetAllPlayers()
{
List<object> list = new List<object>();
Type type = AccessTools.TypeByName("PlayerController");
if (type != null && (AccessTools.Method(type, "GetAllPlayers", (Type[])null, (Type[])null)?.Invoke(null, null) ?? AccessTools.Method(type, "GetAll", (Type[])null, (Type[])null)?.Invoke(null, null)) is IEnumerable enumerable)
{
{
foreach (object item2 in enumerable)
{
list.Add(item2);
}
return list;
}
}
Type type2 = AccessTools.TypeByName("GameManager");
if (type2 != null)
{
object obj = AccessTools.Property(type2, "Instance")?.GetValue(null) ?? AccessTools.Field(type2, "instance")?.GetValue(null);
if (obj != null && (AccessTools.Property(type2, "players")?.GetValue(obj) ?? AccessTools.Field(type2, "players")?.GetValue(obj)) is IEnumerable enumerable2)
{
{
foreach (object item3 in enumerable2)
{
list.Add(item3);
}
return list;
}
}
}
if (type != null)
{
Object[] array = Object.FindObjectsOfType(type);
foreach (Object item in array)
{
list.Add(item);
}
}
return list;
}
private static bool ApplyUpgradeToPlayer(object player, string upgradeType)
{
try
{
Type type = AccessTools.TypeByName("StatsManager");
if (type != null)
{
object obj = AccessTools.Property(player.GetType(), "statsManager")?.GetValue(player);
if (obj == null)
{
obj = AccessTools.Field(player.GetType(), "statsManager")?.GetValue(player);
if (obj == null)
{
object obj2 = ((player is Component) ? player : null);
obj = ((obj2 != null) ? ((Component)obj2).GetComponent(type) : null);
}
}
object obj3 = obj;
if (obj3 != null)
{
MethodInfo methodInfo = AccessTools.Method(type, "AddUpgrade", (Type[])null, (Type[])null) ?? AccessTools.Method(type, "ApplyUpgrade", (Type[])null, (Type[])null) ?? AccessTools.Method(type, "IncreaseLevel", (Type[])null, (Type[])null);
if (methodInfo != null)
{
methodInfo.Invoke(obj3, new object[1] { upgradeType });
return true;
}
}
}
return false;
}
catch
{
return false;
}
}
}
}