using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Serialization;
using BepInEx;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace PersonalLoot;
[Serializable]
public class LootEntry
{
public string Key;
public string Name;
public int ItemId;
public int Quantity;
public string SaveData;
public bool Silver;
}
[Serializable]
public class LootSource
{
public string Key;
public int CapturedSilver;
public List<LootEntry> Entries = new List<LootEntry>();
}
[Serializable]
public class LootClaim
{
public string Key;
public string CreatedItemUid;
public bool Complete;
}
[Serializable]
public class LootLedger
{
public int Version = 1;
public List<LootSource> Sources = new List<LootSource>();
public List<LootClaim> Claims = new List<LootClaim>();
public static string Hash(string value)
{
using SHA256 sHA = SHA256.Create();
return BitConverter.ToString(sHA.ComputeHash(Encoding.UTF8.GetBytes(value))).Replace("-", "").ToLowerInvariant();
}
public static string ClaimKey(string player, string source, string entry)
{
return Hash(player.Length + ":" + player + source.Length + ":" + source + entry);
}
public LootClaim Find(string player, string source, string entry)
{
string key = ClaimKey(player, source, entry);
return Claims.FirstOrDefault((LootClaim c) => c.Key == key);
}
public LootClaim Reserve(string player, string source, string entry)
{
LootClaim lootClaim = Find(player, source, entry);
if (lootClaim != null)
{
return lootClaim;
}
LootClaim lootClaim2 = new LootClaim
{
Key = ClaimKey(player, source, entry),
CreatedItemUid = "PL_" + Guid.NewGuid().ToString("N")
};
Claims.Add(lootClaim2);
return lootClaim2;
}
public static LootLedger Load(string path)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
if (!File.Exists(path))
{
return new LootLedger();
}
using FileStream fileStream = File.OpenRead(path);
LootLedger obj = (LootLedger)new XmlSerializer(typeof(LootLedger)).Deserialize((Stream)fileStream);
if (obj.Version != 1)
{
throw new InvalidDataException("Unsupported personal loot ledger version.");
}
return obj;
}
public void Save(string path)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
Directory.CreateDirectory(Path.GetDirectoryName(path));
string text = path + ".tmp";
using (FileStream fileStream = new FileStream(text, FileMode.Create, FileAccess.Write, FileShare.None))
{
new XmlSerializer(typeof(LootLedger)).Serialize((Stream)fileStream, (object)this);
fileStream.Flush(flushToDisk: true);
}
if (File.Exists(path))
{
File.Replace(text, path, path + ".bak");
}
else
{
File.Move(text, path);
}
}
}
public class LootMessage
{
public string Operation;
public string Player;
public string Container;
public string Entry;
public string Request;
public string Error;
public List<LootEntry> Entries = new List<LootEntry>();
}
public static class LootWire
{
public const string Protocol = "local.personal_loot.v2";
public static string[] Encode(LootMessage message)
{
List<string> list = new List<string>
{
"local.personal_loot.v2",
message.Operation ?? "",
message.Player ?? "",
message.Container ?? "",
message.Entry ?? "",
message.Request ?? "",
message.Error ?? "",
message.Entries.Count.ToString(CultureInfo.InvariantCulture)
};
foreach (LootEntry entry in message.Entries)
{
list.Add(entry.Key ?? "");
list.Add(entry.Name ?? "");
list.Add(entry.ItemId.ToString(CultureInfo.InvariantCulture));
list.Add(entry.Quantity.ToString(CultureInfo.InvariantCulture));
list.Add(entry.Silver ? "1" : "0");
}
return list.ToArray();
}
public static LootMessage Decode(string[] fields)
{
if (fields == null || fields.Length < 8 || fields[0] != "local.personal_loot.v2")
{
throw new InvalidDataException("Unsupported Personal Loot packet. Install 0.1.1 on every computer.");
}
if (!int.TryParse(fields[7], NumberStyles.None, CultureInfo.InvariantCulture, out var result) || result > 10000 || fields.Length != 8 + result * 5)
{
throw new InvalidDataException("Incomplete personal loot list.");
}
LootMessage lootMessage = new LootMessage
{
Operation = fields[1],
Player = fields[2],
Container = fields[3],
Entry = fields[4],
Request = fields[5],
Error = fields[6]
};
for (int i = 0; i < result; i++)
{
int num = 8 + i * 5;
if (string.IsNullOrEmpty(fields[num]) || !int.TryParse(fields[num + 2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) || !int.TryParse(fields[num + 3], NumberStyles.None, CultureInfo.InvariantCulture, out var result3) || result3 < 1 || (fields[num + 4] != "0" && fields[num + 4] != "1"))
{
throw new InvalidDataException("Invalid personal loot item.");
}
lootMessage.Entries.Add(new LootEntry
{
Key = fields[num],
Name = fields[num + 1],
ItemId = result2,
Quantity = result3,
Silver = (fields[num + 4] == "1")
});
}
return lootMessage;
}
}
[BepInPlugin("local.personal_loot", "Personal Loot", "0.1.1")]
public sealed class PersonalLootPlugin : BaseUnityPlugin
{
public const string PluginGuid = "local.personal_loot";
internal static PersonalLootPlugin Instance;
private Harmony harmony;
private byte eventCode;
private LootLedger ledger;
private string ledgerPath;
private string worldId;
private readonly HashSet<string> busyClaims = new HashSet<string>();
private Character viewingPlayer;
private ItemContainer viewingContainer;
private LootMessage displayed;
private string requestId;
private string status;
private float requestedAt;
private bool waiting;
private Vector2 scroll;
private CanvasGroup inventoryInput;
private bool previousInteractable;
private bool previousRaycasts;
private static bool IsHost => !PhotonNetwork.isNonMasterClientInRoom;
private void Awake()
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Expected O, but got Unknown
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Expected O, but got Unknown
Instance = this;
eventCode = ((BaseUnityPlugin)this).Config.Bind<byte>("Network", "EventCode", (byte)182, "Custom Photon event code (1-199). All players must use the same free code. Kyazh Power uses 181.").Value;
if (eventCode < 1 || eventCode > 199)
{
eventCode = 182;
}
PhotonNetwork.OnEventCall += new EventCallback(OnEvent);
SceneManager.sceneLoaded += OnScene;
harmony = new Harmony("local.personal_loot");
harmony.PatchAll(typeof(PersonalLootPlugin).Assembly);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Personal Loot 0.1.1 loaded. Install on host and every client.");
}
internal static bool Supported(ItemContainer container)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Invalid comparison between Unknown and I4
if (!Object.op_Implicit((Object)(object)container))
{
return false;
}
if (container is TreasureChest)
{
return (int)container.SpecialType == 0;
}
Character ownerCharacter = ((EffectSynchronizer)container).OwnerCharacter;
if (Object.op_Implicit((Object)(object)ownerCharacter) && ownerCharacter.IsAI && ownerCharacter.IsDead && Object.op_Implicit((Object)(object)ownerCharacter.Inventory))
{
return (Object)(object)ownerCharacter.Inventory.Pouch == (Object)(object)container;
}
return false;
}
internal void Open(ItemContainer container, Character player)
{
//IL_0035: 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 (!Object.op_Implicit((Object)(object)player) || !player.IsLocalPlayer || !Supported(container))
{
return;
}
Close();
viewingPlayer = player;
viewingContainer = container;
displayed = null;
scroll = Vector2.zero;
player.CharacterUI.ShowMenu((MenuScreens)2);
if (Object.op_Implicit((Object)(object)player.CharacterUI.InventoryPanel))
{
inventoryInput = ((Component)player.CharacterUI.InventoryPanel).GetComponent<CanvasGroup>();
if (!Object.op_Implicit((Object)(object)inventoryInput))
{
inventoryInput = ((Component)player.CharacterUI.InventoryPanel).gameObject.AddComponent<CanvasGroup>();
}
previousInteractable = inventoryInput.interactable;
previousRaycasts = inventoryInput.blocksRaycasts;
inventoryInput.interactable = false;
inventoryInput.blocksRaycasts = false;
}
Request("open", null);
}
private void Request(string operation, string entry)
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Expected O, but got Unknown
if (Object.op_Implicit((Object)(object)viewingPlayer) && Object.op_Implicit((Object)(object)viewingContainer))
{
requestId = Guid.NewGuid().ToString("N");
LootMessage message = new LootMessage
{
Operation = operation,
Player = UID.op_Implicit(viewingPlayer.UID),
Container = ((Item)viewingContainer).UID,
Entry = entry,
Request = requestId
};
waiting = true;
requestedAt = Time.unscaledTime;
status = ((operation == "open") ? "Loading your loot…" : "Taking item…");
if (IsHost)
{
HandleRequest(message, (PhotonNetwork.player != null) ? PhotonNetwork.player.ID : 0);
}
else if (!PhotonNetwork.RaiseEvent(eventCode, (object)LootWire.Encode(message), true, new RaiseEventOptions
{
Receivers = (ReceiverGroup)2
}))
{
waiting = false;
status = "Could not send the loot request. Reconnect and press Refresh.";
}
((BaseUnityPlugin)this).Logger.LogInfo((object)("Request " + operation + " " + requestId + " host=" + IsHost + " event=" + eventCode));
}
}
private void OnEvent(byte code, object payload, int sender)
{
if (code != eventCode)
{
return;
}
try
{
LootMessage lootMessage = LootWire.Decode(payload as string[]);
((BaseUnityPlugin)this).Logger.LogInfo((object)("Received " + lootMessage.Operation + " " + lootMessage.Request + " from actor=" + sender + " entries=" + lootMessage.Entries.Count));
if (lootMessage.Operation == "result")
{
if (PhotonNetwork.masterClient != null && sender == PhotonNetwork.masterClient.ID)
{
ShowResult(lootMessage);
}
}
else if (IsHost)
{
HandleRequest(lootMessage, sender);
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Personal loot message rejected: " + ex.Message));
if (waiting && PhotonNetwork.masterClient != null && sender == PhotonNetwork.masterClient.ID)
{
waiting = false;
status = "Could not read host loot. Install Personal Loot 0.1.1 on every computer, then restart.";
}
}
}
private Character Validate(LootMessage message, int sender, out ItemContainer source)
{
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
source = null;
if (string.IsNullOrEmpty(message.Player) || string.IsNullOrEmpty(message.Container) || !Object.op_Implicit((Object)(object)CharacterManager.Instance) || !Object.op_Implicit((Object)(object)ItemManager.Instance))
{
return null;
}
Character character = CharacterManager.Instance.GetCharacter(message.Player);
if (!Object.op_Implicit((Object)(object)character) || character.IsAI || character.IsDead || !Object.op_Implicit((Object)(object)character.OwnerPlayerSys))
{
return null;
}
PhotonPlayer photonOwner = character.OwnerPlayerSys.PhotonOwner;
if (PhotonNetwork.inRoom && photonOwner != null && photonOwner.ID != sender)
{
return null;
}
if (PhotonNetwork.inRoom && photonOwner == null && !character.IsPhotonPlayerLocal)
{
return null;
}
Item item = ItemManager.Instance.GetItem(message.Container);
source = (ItemContainer)(object)((item is ItemContainer) ? item : null);
if (!Supported(source))
{
return null;
}
if (Vector3.Distance(((Component)character).transform.position, ((Component)source).transform.position) > 12f)
{
return null;
}
return character;
}
private void EnsureLedger()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
Character worldHostCharacter = CharacterManager.Instance.GetWorldHostCharacter();
if (!Object.op_Implicit((Object)(object)worldHostCharacter))
{
throw new InvalidOperationException("The world host is not ready.");
}
string text = UID.op_Implicit(worldHostCharacter.UID);
if (ledger == null || !(text == worldId))
{
string path = Path.Combine(Paths.ConfigPath, "PersonalLoot", LootLedger.Hash(text) + ".xml");
LootLedger lootLedger = LootLedger.Load(path);
ledger = lootLedger;
worldId = text;
ledgerPath = path;
}
}
private static string SourceKey(ItemContainer source)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
return ((Scene)(ref activeScene)).name + "|" + ((Item)source).UID;
}
private LootSource Capture(ItemContainer source)
{
EnsureLedger();
TreasureChest val = (TreasureChest)(object)((source is TreasureChest) ? source : null);
if (Object.op_Implicit((Object)(object)val) && !val.HasGeneratedContent)
{
((SelfFilledItemContainer)val).GenerateContents();
}
List<Item> list = (from i in source.GetContainedItems()
where Object.op_Implicit((Object)(object)i) && ((EffectSynchronizer)i).FullyInitialized
select i).ToList();
string key = SourceKey(source);
LootSource lootSource = ledger.Sources.FirstOrDefault((LootSource s) => s.Key == key);
if (lootSource != null)
{
HashSet<string> oldIds = new HashSet<string>(from e in lootSource.Entries
where !e.Silver
select e.Key);
if (oldIds.Count > 0 && list.Count > 0 && !list.Any((Item i) => oldIds.Contains(i.UID)))
{
ledger.Sources.Remove(lootSource);
lootSource = null;
}
}
if (lootSource == null)
{
lootSource = new LootSource
{
Key = key
};
ledger.Sources.Add(lootSource);
}
bool flag = false;
foreach (Item item in list)
{
if (!lootSource.Entries.Any((LootEntry e) => e.Key == item.UID))
{
lootSource.Entries.Add(new LootEntry
{
Key = item.UID,
ItemId = item.ItemID,
Name = item.Name,
Quantity = Math.Max(1, item.RemainingAmount),
SaveData = item.ToSaveData()
});
flag = true;
}
}
if (source.ContainedSilver > lootSource.CapturedSilver)
{
lootSource.Entries.Add(new LootEntry
{
Key = "silver_" + Guid.NewGuid().ToString("N"),
Name = "Silver",
Silver = true,
Quantity = source.ContainedSilver - lootSource.CapturedSilver
});
lootSource.CapturedSilver = source.ContainedSilver;
flag = true;
}
if (flag)
{
ledger.Save(ledgerPath);
}
return lootSource;
}
internal void ResetChest(TreasureChest chest)
{
if (!IsHost || !Supported((ItemContainer)(object)chest) || !Object.op_Implicit((Object)(object)CharacterManager.Instance))
{
return;
}
try
{
EnsureLedger();
string key = SourceKey((ItemContainer)(object)chest);
if (ledger.Sources.RemoveAll((LootSource s) => s.Key == key) > 0)
{
ledger.Save(ledgerPath);
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Could not reset personal chest snapshot: " + ex));
}
}
private void HandleRequest(LootMessage message, int sender)
{
try
{
ItemContainer source;
Character val = Validate(message, sender, out source);
if (!Object.op_Implicit((Object)(object)val))
{
Reply(message, sender, null, "This loot source is unavailable or too far away.");
return;
}
TreasureChest val2 = (TreasureChest)(object)((source is TreasureChest) ? source : null);
if (Object.op_Implicit((Object)(object)val2) && !val2.HasGeneratedContent)
{
((SelfFilledItemContainer)val2).GenerateContents();
}
if (source.GetContainedItems().Any((Item i) => Object.op_Implicit((Object)(object)i) && !((EffectSynchronizer)i).FullyInitialized))
{
((MonoBehaviour)this).StartCoroutine(WaitForLoot(message, sender, source));
return;
}
LootSource lootSource = Capture(source);
if (message.Operation == "open")
{
Reply(message, sender, lootSource, null);
}
else
{
if (message.Operation != "take")
{
return;
}
LootEntry lootEntry = lootSource.Entries.FirstOrDefault((LootEntry e) => e.Key == message.Entry);
if (lootEntry == null)
{
Reply(message, sender, lootSource, "That item is no longer available.");
return;
}
LootClaim lootClaim = ledger.Reserve(message.Player, lootSource.Key, lootEntry.Key);
if (lootClaim.Complete)
{
Reply(message, sender, lootSource, null);
return;
}
if (!busyClaims.Add(lootClaim.Key))
{
Reply(message, sender, lootSource, "This item is already being delivered.");
return;
}
try
{
ledger.Save(ledgerPath);
}
catch
{
busyClaims.Remove(lootClaim.Key);
throw;
}
((MonoBehaviour)this).StartCoroutine(Deliver(message, sender, val, lootSource, lootEntry, lootClaim, ledger, ledgerPath));
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Personal loot request failed: " + ex));
Reply(message, sender, null, "Could not load or save personal loot. Check BepInEx/LogOutput.log.");
}
}
private IEnumerator WaitForLoot(LootMessage request, int sender, ItemContainer source)
{
float deadline = Time.realtimeSinceStartup + 5f;
while (Object.op_Implicit((Object)(object)source) && Time.realtimeSinceStartup < deadline)
{
if (!source.GetContainedItems().Any((Item i) => Object.op_Implicit((Object)(object)i) && !((EffectSynchronizer)i).FullyInitialized))
{
HandleRequest(request, sender);
yield break;
}
yield return null;
}
Reply(request, sender, null, "Loot is still loading. Press Refresh to try again.");
}
private IEnumerator Deliver(LootMessage request, int sender, Character player, LootSource source, LootEntry entry, LootClaim claim, LootLedger claimLedger, string path)
{
string error = null;
if (entry.Silver)
{
try
{
claim.Complete = true;
claimLedger.Save(path);
player.Inventory.Pouch.AddSilver(entry.Quantity, true);
}
catch (Exception ex)
{
error = "Silver delivery failed; inspect the log before retrying.";
((BaseUnityPlugin)this).Logger.LogError((object)ex);
}
}
else
{
Item copy = ItemManager.Instance.GetItem(claim.CreatedItemUid);
try
{
if (!Object.op_Implicit((Object)(object)copy))
{
string[] array = Item.GetSyncDataFromSaveData(entry.SaveData).Split(new char[1] { '|' });
if (array.Length < 21)
{
throw new InvalidDataException("Incomplete saved item data.");
}
array[0] = claim.CreatedItemUid;
array[2] = "0";
array[4] = "1" + ((Item)player.Inventory.Pouch).UID + ";" + ((Item)player.Inventory.Pouch).ItemID;
array[5] = "False";
array[6] = "";
array[7] = "";
array[8] = "";
array[11] = "-1";
array[20] = "-";
ItemManager.Instance.OnReceiveItemSync(string.Join("|", array), (ItemSyncType)0, request.Player);
}
}
catch (Exception ex2)
{
error = "Item creation failed; check the log.";
((BaseUnityPlugin)this).Logger.LogError((object)ex2);
}
float deadline = Time.realtimeSinceStartup + 12f;
while (error == null && Object.op_Implicit((Object)(object)player) && Time.realtimeSinceStartup < deadline)
{
copy = ItemManager.Instance.GetItem(claim.CreatedItemUid);
if (Object.op_Implicit((Object)(object)copy) && ((EffectSynchronizer)copy).FullyInitialized && copy.IsSynced && (Object)(object)((EffectSynchronizer)copy).OwnerCharacter == (Object)(object)player)
{
break;
}
yield return null;
}
if (error == null)
{
if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)copy) || !((EffectSynchronizer)copy).FullyInitialized || !copy.IsSynced || (Object)(object)((EffectSynchronizer)copy).OwnerCharacter != (Object)(object)player)
{
error = "Delivery is still pending. Reopen this source and retry; the same item ID will be reused.";
}
else
{
try
{
copy.SaveType = (SaveTypes)0;
claim.Complete = true;
claimLedger.Save(path);
if (PhotonNetwork.inRoom && !PhotonNetwork.offlineMode)
{
Global.RPCManager.SendItemSync(copy.ToNetworkData((SyncType)2), (PhotonTargets)1);
}
}
catch (Exception ex3)
{
error = "Could not finalize item delivery. Check the log.";
((BaseUnityPlugin)this).Logger.LogError((object)ex3);
}
}
}
}
busyClaims.Remove(claim.Key);
Reply(request, sender, source, error);
}
private void Reply(LootMessage request, int sender, LootSource source, string error)
{
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Expected O, but got Unknown
LootMessage lootMessage = new LootMessage
{
Operation = "result",
Player = request.Player,
Container = request.Container,
Request = request.Request,
Error = error
};
if (source != null && ledger != null)
{
foreach (LootEntry entry in source.Entries)
{
LootClaim lootClaim = ledger.Find(request.Player, source.Key, entry.Key);
if (lootClaim == null || !lootClaim.Complete)
{
lootMessage.Entries.Add(new LootEntry
{
Key = entry.Key,
Name = entry.Name,
ItemId = entry.ItemId,
Quantity = entry.Quantity,
Silver = entry.Silver
});
}
}
}
if (!PhotonNetwork.inRoom || PhotonNetwork.offlineMode || (PhotonNetwork.player != null && sender == PhotonNetwork.player.ID))
{
ShowResult(lootMessage);
}
else
{
byte num = eventCode;
string[] array = LootWire.Encode(lootMessage);
RaiseEventOptions val = new RaiseEventOptions();
val.TargetActors = new int[1] { sender };
if (!PhotonNetwork.RaiseEvent(num, (object)array, true, val))
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to send loot reply to actor=" + sender));
}
}
((BaseUnityPlugin)this).Logger.LogInfo((object)("Reply " + request.Request + " to actor=" + sender + " entries=" + lootMessage.Entries.Count + " error=" + error));
}
private void ShowResult(LootMessage response)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
if (Object.op_Implicit((Object)(object)viewingPlayer) && Object.op_Implicit((Object)(object)viewingContainer) && !(response.Request != requestId) && !(response.Player != UID.op_Implicit(viewingPlayer.UID)) && !(response.Container != ((Item)viewingContainer).UID))
{
displayed = response;
waiting = false;
status = ((!string.IsNullOrEmpty(response.Error)) ? response.Error : ((response.Entries.Count == 0) ? "No unclaimed loot here. Press Refresh if loot is still loading." : (response.Entries.Count + " loot entries. Other players have their own copies.")));
}
}
private void Update()
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
if (Object.op_Implicit((Object)(object)viewingPlayer))
{
if (!Object.op_Implicit((Object)(object)viewingContainer) || viewingPlayer.IsDead || !viewingPlayer.CharacterUI.IsInventoryPanelDisplayed || Vector3.Distance(((Component)viewingPlayer).transform.position, ((Component)viewingContainer).transform.position) > 12f)
{
Close();
}
else if (Input.GetKeyDown((KeyCode)27))
{
Close();
}
else if (waiting && Time.unscaledTime - requestedAt > 15f)
{
waiting = false;
status = "No host response. Check that every player has Personal Loot enabled, then press Refresh.";
}
}
}
private void OnGUI()
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Expected O, but got Unknown
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)viewingPlayer) || !Object.op_Implicit((Object)(object)viewingContainer))
{
return;
}
float num = Mathf.Min(560, Screen.width - 32);
float num2 = Mathf.Min(620, Screen.height - 32);
Rect val = default(Rect);
((Rect)(ref val))..ctor(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2);
GUI.depth = -1000;
GUILayout.Window(197402, val, (WindowFunction)delegate
{
//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_004e: Expected O, but got Unknown
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
GUILayout.Label("Personal Loot — " + ((Object)viewingPlayer).name, Array.Empty<GUILayoutOption>());
GUILayout.Label(status ?? "Loading…", new GUIStyle(GUI.skin.label)
{
wordWrap = true
}, Array.Empty<GUILayoutOption>());
scroll = GUILayout.BeginScrollView(scroll, Array.Empty<GUILayoutOption>());
if (displayed != null)
{
LootEntry[] array = displayed.Entries.ToArray();
foreach (LootEntry lootEntry in array)
{
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label(lootEntry.Name + " ×" + lootEntry.Quantity, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
GUI.enabled = !waiting;
if (GUILayout.Button("Take", (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Width(75f),
GUILayout.Height(30f)
}))
{
Request("take", lootEntry.Key);
}
GUI.enabled = true;
GUILayout.EndHorizontal();
}
}
GUILayout.EndScrollView();
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUI.enabled = !waiting;
if (GUILayout.Button("Refresh", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }))
{
Request("open", null);
}
GUI.enabled = true;
if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }))
{
Close();
}
GUILayout.EndHorizontal();
}, "Personal Loot", (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Width(num),
GUILayout.Height(num2)
});
}
private void Close()
{
if (Object.op_Implicit((Object)(object)inventoryInput))
{
inventoryInput.interactable = previousInteractable;
inventoryInput.blocksRaycasts = previousRaycasts;
inventoryInput = null;
}
Character val = viewingPlayer;
viewingPlayer = null;
viewingContainer = null;
displayed = null;
waiting = false;
if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.CharacterUI))
{
val.CharacterUI.HideMenu((MenuScreens)2, true);
}
}
private void OnScene(Scene scene, LoadSceneMode mode)
{
Close();
}
private void OnDestroy()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
Close();
PhotonNetwork.OnEventCall -= new EventCallback(OnEvent);
SceneManager.sceneLoaded -= OnScene;
if (harmony != null)
{
harmony.UnpatchSelf();
}
Instance = null;
}
}
[HarmonyPatch(typeof(CharacterInventory), "TakeItem", new Type[]
{
typeof(Item),
typeof(bool)
})]
internal static class TakePersonalLootItem
{
private static bool Prefix(Item takenItem, Character ___m_character)
{
if (!Object.op_Implicit((Object)(object)PersonalLootPlugin.Instance) || !Object.op_Implicit((Object)(object)takenItem) || !PersonalLootPlugin.Supported(takenItem.ParentContainer))
{
return true;
}
PersonalLootPlugin.Instance.Open(takenItem.ParentContainer, ___m_character);
return false;
}
}
[HarmonyPatch(typeof(ItemContainer), "ShowContent")]
internal static class OpenPersonalLoot
{
private static bool Prefix(ItemContainer __instance, Character _character)
{
if (!Object.op_Implicit((Object)(object)PersonalLootPlugin.Instance) || !PersonalLootPlugin.Supported(__instance))
{
return true;
}
PersonalLootPlugin.Instance.Open(__instance, _character);
return false;
}
}
[HarmonyPatch(typeof(CharacterInventory), "TakeAllContent")]
internal static class TakeAllPersonalLoot
{
private static bool Prefix(ItemContainer _container, Character ___m_character, ref bool __result)
{
if (!Object.op_Implicit((Object)(object)PersonalLootPlugin.Instance) || !PersonalLootPlugin.Supported(_container))
{
return true;
}
PersonalLootPlugin.Instance.Open(_container, ___m_character);
__result = false;
return false;
}
}
[HarmonyPatch(typeof(TreasureChest), "ResetDrop")]
internal static class ResetPersonalLoot
{
private static void Postfix(TreasureChest __instance)
{
if (Object.op_Implicit((Object)(object)PersonalLootPlugin.Instance))
{
PersonalLootPlugin.Instance.ResetChest(__instance);
}
}
}