using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ChatCommandAPI;
using EasyTextEffects.Editor.MyBoxCopy.Extensions;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
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("gafoneo.quicksell")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.4.0")]
[assembly: AssemblyInformationalVersion("1.1.4+133645a4fede6e24c0f8db361e9430ed8c055df6")]
[assembly: AssemblyProduct("QuickSell")]
[assembly: AssemblyTitle("gafoneo.quicksell")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.4.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 QuickSell
{
public class HelperFuncs
{
public static void TryClearDepositItemsDesk()
{
DepositItemsDesk val = Object.FindObjectOfType<DepositItemsDesk>();
if (!((Object)(object)val == (Object)null))
{
val.itemsOnCounter?.Clear();
}
}
}
public class Patches
{
[HarmonyPatch(typeof(GameNetworkManager))]
public class LobbyPatches
{
[HarmonyPatch("StartHost")]
[HarmonyPostfix]
private static void OnLobbyCreated()
{
QuickSell.OnLobbyEntrance();
HelperFuncs.TryClearDepositItemsDesk();
valueOnDesk = 0;
}
[HarmonyPatch("StartClient")]
[HarmonyPostfix]
private static void OnLobbyJoined()
{
QuickSell.OnLobbyEntrance();
HelperFuncs.TryClearDepositItemsDesk();
valueOnDesk = 0;
}
}
[HarmonyPatch(typeof(DepositItemsDesk))]
public class DepositItemsDeskPatch
{
[HarmonyPostfix]
[HarmonyPatch("AddObjectToDeskClientRpc")]
public static void FetchValue(ref DepositItemsDesk __instance)
{
if (!NetworkManager.Singleton.IsServer && NetworkManager.Singleton.IsClient)
{
NetworkObject lastObjectAddedToDesk = __instance.lastObjectAddedToDesk;
__instance.itemsOnCounter.Add(((Component)lastObjectAddedToDesk).GetComponentInChildren<GrabbableObject>());
}
int num = 0;
for (int i = 0; i < __instance.itemsOnCounter.Count; i++)
{
if (__instance.itemsOnCounter[i].itemProperties.isScrap)
{
num += __instance.itemsOnCounter[i].scrapValue;
}
}
valueOnDesk = (int)((float)num * StartOfRound.Instance.companyBuyingRate);
QuickSell.Logger.LogDebug((object)$"Value on desk: {valueOnDesk}");
}
[HarmonyPostfix]
[HarmonyPatch("SellItemsClientRpc")]
public static void ClearValue(ref DepositItemsDesk __instance)
{
if (!NetworkManager.Singleton.IsServer && NetworkManager.Singleton.IsClient)
{
__instance.itemsOnCounter.Clear();
}
valueOnDesk = 0;
QuickSell.Logger.LogDebug((object)$"Value on desk: {valueOnDesk}");
}
}
[HarmonyPatch(typeof(StartOfRound), "SyncShipUnlockablesClientRpc")]
public static class FixItemSaveDataMismatch
{
[HarmonyPrefix]
public static void SafeLoadData(int[] itemSaveData)
{
try
{
GrabbableObject[] source = Object.FindObjectsByType<GrabbableObject>((FindObjectsInactive)0, (FindObjectsSortMode)0);
int num = source.Count((GrabbableObject o) => o.itemProperties.saveItemVariable);
if (itemSaveData.Length < num)
{
Debug.LogWarning((object)$"ItemSaveData length mismatch: {itemSaveData.Length} < {num}. Truncating.");
}
}
catch (Exception arg)
{
Debug.LogError((object)$"[Patch] Error checking itemSaveData length: {arg}");
}
}
}
public static int valueOnDesk;
}
[BepInPlugin("gafoneo.quicksell", "QuickSell", "1.1.4")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class QuickSell : BaseUnityPlugin
{
internal ConfigEntry<string> itemBlacklistConfig;
internal HashSet<string> ItemBlacklistSet = new HashSet<string>();
internal HashSet<string> TempBlacklistAddSet = new HashSet<string>();
internal HashSet<string> TempBlacklistRmSet = new HashSet<string>();
internal HashSet<string> ActiveBlacklistSet = new HashSet<string>();
internal bool UpdateBlacklist = true;
internal ConfigEntry<string> priorityItemsConfig;
internal HashSet<string> PriorityItemsSet = new HashSet<string>();
internal HashSet<string> TempPriorityAddSet = new HashSet<string>();
internal HashSet<string> TempPriorityRmSet = new HashSet<string>();
internal HashSet<string> ActivePrioritySet = new HashSet<string>();
internal bool UpdatePriority = true;
public static List<(string prefabName, string name, string itemName, string scanNodeName)> allItems = new List<(string, string, string, string)>();
public static QuickSell Instance { get; private set; } = null;
internal static ManualLogSource Logger { get; private set; } = null;
private void Awake()
{
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
Instance = this;
itemBlacklistConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "ItemBlacklist", CommaJoin(new HashSet<string> { "ShotgunItem", "KnifeItem", "ZeddogPlushie", "GiftBox" }), "Items to never sell by internal name (comma-separated)");
priorityItemsConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "PriorityItems", CommaJoin(new HashSet<string> { "Clock", "EasterEgg", "SoccerBall", "WhoopieCushion" }), "Items which are prioritized when selling");
RebuildBlacklistSet();
itemBlacklistConfig.SettingChanged += delegate
{
RebuildBlacklistSet();
};
RebuildPrioritySet();
priorityItemsConfig.SettingChanged += delegate
{
RebuildPrioritySet();
};
new SellCommand();
new OvertimeCommand();
Harmony val = new Harmony("gafoneo.quicksell");
val.PatchAll();
Logger.LogInfo((object)"gafoneo.quicksell v1.1.4 was loaded!");
}
public static void OnLobbyEntrance()
{
Logger.LogDebug((object)"Calling OnLobbyEntrance()");
Logger.LogDebug((object)"Creating allItems list");
allItems = (from i in Resources.FindObjectsOfTypeAll<Item>()
where Object.op_Implicit((Object)(object)i.spawnPrefab) && "box" != i.itemName
select (((Object)i.spawnPrefab).name, ((Object)i).name, i.itemName, i.spawnPrefab.GetComponentInChildren<ScanNodeProperties>()?.headerText ?? "")).ToList();
Logger.LogDebug((object)$"allItems list created. Length: {allItems.Count}");
}
public void RebuildBlacklistSet()
{
if (UpdateBlacklist)
{
Logger.LogDebug((object)"Constructing a new blacklist");
Logger.LogDebug((object)("Old blacklist set: " + string.Join(",", ItemBlacklistSet)));
ItemBlacklistSet = CommaSplit(itemBlacklistConfig.Value);
RebuildActiveBlacklist();
Logger.LogDebug((object)("New blacklist set: " + string.Join(",", ItemBlacklistSet)));
}
}
public void RebuildActiveBlacklist()
{
HashSet<string> hashSet = new HashSet<string>();
foreach (string item in ItemBlacklistSet.Union(TempBlacklistAddSet).Except(TempBlacklistRmSet))
{
hashSet.Add(item);
}
ActiveBlacklistSet = hashSet;
}
public void RebuildPrioritySet()
{
if (UpdatePriority)
{
Logger.LogDebug((object)"Constructing a new priority set");
Logger.LogDebug((object)("Old priority set: " + string.Join(",", PriorityItemsSet)));
PriorityItemsSet = CommaSplit(priorityItemsConfig.Value);
RebuildActivePrioritySet();
Logger.LogDebug((object)("New priority set: " + string.Join(",", PriorityItemsSet)));
}
}
public void RebuildActivePrioritySet()
{
HashSet<string> hashSet = new HashSet<string>();
foreach (string item in PriorityItemsSet.Union(TempPriorityAddSet).Except(TempPriorityRmSet))
{
hashSet.Add(item);
}
ActivePrioritySet = hashSet;
}
internal static string CommaJoin(HashSet<string> i)
{
return GeneralExtensions.Join<string>((IEnumerable<string>)i, (Func<string, string>)null, ",");
}
internal static HashSet<string> CommaSplit(string i)
{
HashSet<string> hashSet = new HashSet<string>();
foreach (string item in from i in i.Split(',', StringSplitOptions.RemoveEmptyEntries)
select i.Trim())
{
hashSet.Add(item);
}
return hashSet;
}
public static void FancyChatDisplay(string message, string title = "", bool addColorToContents = true, string line = "===============================", string color = "#00ffff")
{
string text2;
if (title != "")
{
string text = " " + title + " ";
int num = Math.Max(line.Length, text.Length + 2);
int num2 = num - text.Length;
int num3 = num2 / 2;
int count = num2 - num3;
text2 = "<color=" + color + ">" + new string('=', num3) + text + new string('=', count) + "</color>\n";
}
else
{
text2 = "<color=" + color + ">" + line + "</color>\n";
}
string text3 = (addColorToContents ? ("<color=" + color + ">" + message + "</color>") : message) + ((message.Last() != '\n') ? "\n" : "");
string text4 = "<color=" + color + ">" + line + "</color>";
HUDManager.Instance.ChatMessageHistory.Add(text2 + text3 + text4);
UpdateChat();
}
public static void UpdateChat()
{
((TMP_Text)HUDManager.Instance.chatText).text = string.Join("\n", HUDManager.Instance.ChatMessageHistory);
HUDManager.Instance.PingHUDElement(HUDManager.Instance.Chat, 4f, 1f, 0.2f);
}
}
public class SellCommand : Command
{
protected struct SellData
{
public string[] args;
public DepositItemsDesk desk;
public string variation;
public int value;
public string originalValue;
public int quotaLeft;
public int existingMoney;
public bool e;
public bool o;
public bool a;
public bool n;
public bool p;
public SellData()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
args = Array.Empty<string>();
desk = new DepositItemsDesk();
variation = "";
value = 0;
originalValue = "";
quotaLeft = 0;
existingMoney = 0;
e = false;
o = false;
a = false;
n = false;
p = false;
}
}
[CompilerGenerated]
private sealed class <DelayedDeskCheck>d__32 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DelayedDeskCheck>d__32(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
QuickSell.Logger.LogDebug((object)"Calling DelayedDeskCheck() (DDS)");
<>2__current = (object)new WaitForSeconds(10f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
QuickSell.Logger.LogDebug((object)"DDS: 10 seconds passed");
if (sellData.desk.itemsOnCounter.Count <= 0)
{
QuickSell.Logger.LogDebug((object)"DDS: Desk still has no items, terminating");
return false;
}
QuickSell.Logger.LogDebug((object)"DDS: Desk still has items");
if (sellData.desk.doorOpen)
{
QuickSell.Logger.LogDebug((object)"Door was already open, terminating");
return false;
}
QuickSell.Logger.LogDebug((object)"Opening a door");
sellData.desk.SetTimesHeardNoiseServerRpc(5f);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
protected Dictionary<string, Action> actions = new Dictionary<string, Action>
{
{ "help", SellHelp },
{ "blacklist", SellBlacklist },
{ "priority", SellPriority },
{
"",
CompleteOnlyWithDesk(SellNoArgs)
},
{
"item",
CompleteOnlyWithDesk(SellParticularItem)
},
{
"quota",
CompleteOnlyWithDesk(SellQuota)
},
{
"all",
CompleteOnlyWithDesk(SellAll)
},
{
"amount",
CompleteOnlyWithDesk(SellForRequestedAmount)
}
};
protected static SellData sellData;
public override string Name => "Sell";
public override string Description => "Sells items, use /sell help to see available uses.If you find any bugs, inaccuracies or have any improvements in mind please open an issue on github (the link is on the QuickSell's modpage).";
public override string[] Syntax => new string[5] { "", "help [flags]", "item [item]", "{ quota | all } [-a]", "<value> [-o] [-t] [-a] [-n]" };
protected static Action CompleteOnlyWithDesk(Action action)
{
Action action2 = action;
return delegate
{
if (FindDesk(out sellData.desk))
{
action2();
}
};
}
public override bool Invoke(string[] args, Dictionary<string, string> kwargs, out string _)
{
QuickSell.Logger.LogDebug((object)"The sell command was initiated");
_ = "";
SellData sellData = new SellData();
sellData.args = args;
SellCommand.sellData = sellData;
ParseArguments();
if (actions.TryGetValue(SellCommand.sellData.variation, out Action value))
{
value();
}
return true;
}
protected static void ParseArguments()
{
QuickSell.Logger.LogDebug((object)"Calling ParseArguments()");
string text = string.Join("", from i in sellData.args
where i != "" && i.First() == '-' && i.Length > 1
select i.Substring(1, i.Length - 1));
sellData.e = text.Contains("e") || text.Contains("t");
sellData.o = text.Contains("o");
sellData.a = text.Contains("a");
sellData.n = text.Contains("n");
sellData.p = text.Contains("p");
if (text.Contains("t"))
{
ChatCommandAPI.PrintError("Flag -t as a check for existing money will be depricated soon. Use -e instead");
}
QuickSell.Logger.LogDebug((object)$"Flags: -e == {sellData.e}; -o == {sellData.o}; -a == {sellData.a}; -n == {sellData.n}; -p == {sellData.p}");
sellData.args = sellData.args.Where((string i) => i != "" && (i.First() != '-' || i.Length <= 1)).ToArray();
if (sellData.args.Length != 0)
{
string value = sellData.args[0].ToLower();
if (new string[1] { "help" }.Contains(value))
{
sellData.variation = "help";
}
else if (new string[3] { "item", "items", "scrap" }.Contains(value))
{
sellData.variation = "item";
}
else if (new string[1] { "quota" }.Contains(value))
{
sellData.variation = "quota";
}
else if (new string[1] { "all" }.Contains(value))
{
sellData.variation = "all";
}
else if (new string[2] { "blacklist", "bl" }.Contains(value))
{
sellData.variation = "blacklist";
}
else if (new string[2] { "priority", "pr" }.Contains(value))
{
sellData.variation = "priority";
}
else
{
sellData.variation = "amount";
}
QuickSell.Logger.LogDebug((object)("variation: " + ((sellData.variation == "amount") ? "no variation keyword was used so assuming <amount>" : sellData.variation)));
}
}
protected static void SellNoArgs()
{
QuickSell.Logger.LogDebug((object)"Got no arguments -> calling SellNoArgs");
if (OpenDoor(out var itemCount, out var totalValue))
{
QuickSell.FancyChatDisplay("Selling " + NumberOfItems(itemCount) + " with a total value of " + ValueOfItems(totalValue));
}
}
protected static void SellHelp()
{
QuickSell.Logger.LogDebug((object)"variation == \"help\" -> calling SellHelp()");
Dictionary<string, string> dictionary = new Dictionary<string, string>
{
{ "", "Usage:\r\n/sell <variation> [flags]\r\n\r\nCommand variations:\r\n\"help\" to open this page or a specific help page\r\n\"item\" to sell all items like the one you are holding or the one you specified\r\n\"quota\" to sell exactly for quota\r\n\"all\" to sell all unfiltered scrap available\r\n<amount> (input a number instead of \\\"amount\\\") to sell exactly how much you need\r\n\r\nUse \"/sell help pages\" to see info on all pages\r\nUse \"/sell help flags\" to see info on important flags\r\nUse \"/sell help <variation>\" to see info on specific command" },
{ "pages", "Usage:\r\n/sell help [page]\r\n\r\nPages:\r\ndefault, pages, flags, item, quota, all, amount, -o, -e, -a, -n" },
{ "flags", "Usage:\r\n/sell <variation> [flags]\r\n\r\nCombining flags:\r\nSplit: /sell <variation> -e -o -a\r\nTogether: /sell <variation> -eoa\r\n\r\n\"-o\" to sell accounting for overtime (used with <amount>)\r\n\"-e\" for accounting for existing money in terminal and overtime (used with <amount>)\r\n\"-a\" to ignore blacklist (used with quota, all, <amount>)\r\n\"-n\" to force non-restart overtime calculations (needed in rare edge cases)\r\n\r\nUse \"/sell help <flag>\" to see info on specific flag" },
{ "item", "Usage:\r\n/sell item [item]\r\n\r\nSells all items with the specified name. If no name was specified then checks what item you are holding and gets it's name instead (and sells this held item too)" },
{ "quota", "Usage:\r\n/sell quota [-a]\r\n\r\nChecks how much quota is left and tries to sell exactly that (if it's not enough, nothing will be sold and if exact value isn't achievable sells the smallest value after that)" },
{ "all", "Usage:\r\n/sell all [-a]\r\n\r\nSells all (non-blacklisted, use -a to ignore blacklist) items" },
{ "amount", "Usage:\r\n/sell <amount> [-o] [-e] [-a] [-n]\r\n\r\nTries to sell exactly how much you specified. If there is not enough scrap, sells nothing. If an exact value isn't achievable sells the smallest value after that" },
{ "blacklist", "Usage:\r\n/sell bl [-a] [-p]\r\n/sell bl {add | ad | a | +} [itemName] [-p]\r\n/sell bl {remove | rm | r | -} [itemName] [-p]\r\n/sell bl {empty | flash | flush}\r\n\r\nWithout modifiers just prints an active blacklist, you can add -a to also display temporary blacklist or -p to display permanent blacklist instead.\r\nBy using \"/sell bl +\" (\"/sell bl -\") you can temporarily blacklist (or prohibit to blacklist) an item currently in your hands. You can also add/remove it from a permanent blacklist by using -p flag.\r\nBy using \"/sell bl empty\" you can clear temporary blacklist in case you don't need it anymore (keep in mind that it automatically resets when you close the game window)" },
{ "priority", "Usage:\r\n/sell pr [-a] [-p]\r\n/sell pr {add | ad | a | +} [itemName] [-p]\r\n/sell pr {remove | rm | r | -} [itemName] [-p]\r\n/sell pr {empty | flash | flush}\r\n\r\nWithout modifiers just prints an active priority set, you can add -a to also display temporary priority set or -p to display permanent priority set instead.\r\nBy using \"/sell pr +\" (\"/sell bl -\") you can temporarily prioritize (or prohibit form being prioritized) an item currently in your hands. You can also add/remove it from a permanent priority set by using -p flag.\r\nBy using \"/sell pr empty\" you can clear temporary priority set in case you don't need it anymore (keep in mind that it automatically resets when you close the game window)" },
{ "-o", "Usage:\r\n/sell <amount> -o\r\n\r\nRespects the fact that your sold items can cause overtime and includes it in the calculations (note that the overtime caused by already sold items isn't included, you need -e flag for that) so that: requested value = final value in terminal (after leaving the planet) - existing money (look into -e help page for that)" },
{ "-e", "Usage:\r\n/sell <amount> -e\r\n\r\n(Previously -t, but was changed to -e)\r\nRemoves existing money (already existing credits in terminal, items on desk and, if -o flag is present, future overtime based on these two) from your requsted value so that: requested value = final value in terminal (after leaving the planet) = existing money + sold items (+ overtime caused by sold items if -o flag is present)" },
{ "-a", "Usage:\r\n/sell {quota | all | amount | bl | pr} -a\r\n\r\nWhen trying to find right items to sell, ignores all blacklists so that *EVERY* item can be sold. If used with \"/sell bl\" or \"/sell pr\" displays both temporary blacklists (or priority sets) along with the active one" },
{ "-p", "Usage:\r\n/sell {bl | pr} [+ | -] -p\r\n\r\nWhen using the blacklist (or priority) command can be used to affect permanent blacklist (or priority set) instead of the temporary one" },
{ "-n", "Usage:\r\n/sell <amount> -n\r\n\r\nForces EVERY overtime calculation that occures during the execution of THIS command to think that there was no rehost after the final day of this quota, even if there was one). It is only needed if a host has a mod for late joining (aka LateCompany) and you joined after the final day of this quota (your client will think that there was a rehost then). There is no way (that I know of, at least, if you know one please tell me) to check if there was or wasn't a real rehost in this case, and if there wasn't, then all overtime calculations will be 15 smaller. This flag accounts for that, but note that if the rehost has actually occured and you used this flag then all overtime calculation will be 15 bigger so you should ask your host if they have done a rehost or not to get it right" }
};
if (sellData.args.Length <= 1 && !sellData.o && !sellData.e && !sellData.a && !sellData.n)
{
QuickSell.FancyChatDisplay(dictionary[""], "HELP PAGE");
return;
}
bool flag = true;
if (sellData.o)
{
QuickSell.FancyChatDisplay(dictionary["-o"], "-O HELP PAGE");
return;
}
if (sellData.e)
{
QuickSell.FancyChatDisplay(dictionary["-e"], "-E HELP PAGE");
return;
}
if (sellData.a)
{
QuickSell.FancyChatDisplay(dictionary["-a"], "-A HELP PAGE");
return;
}
if (sellData.p)
{
QuickSell.FancyChatDisplay(dictionary["-p"], "-P HELP PAGE");
return;
}
if (sellData.n)
{
QuickSell.FancyChatDisplay(dictionary["-n"], "-N HELP PAGE");
return;
}
switch (sellData.args[1].ToLower())
{
case "pages":
case "page":
case "help":
QuickSell.FancyChatDisplay(dictionary["pages"], "PAGES HELP PAGE");
break;
case "flags":
case "flag":
QuickSell.FancyChatDisplay(dictionary["flags"], "FLAG HELP PAGE");
break;
case "items":
case "item":
QuickSell.FancyChatDisplay(dictionary["item"], "ITEM HELP PAGE");
break;
case "quota":
QuickSell.FancyChatDisplay(dictionary["quota"], "QUOTA HELP PAGE");
break;
case "all":
QuickSell.FancyChatDisplay(dictionary["all"], "ALL HELP PAGE");
break;
case "<amount>":
case "amount":
QuickSell.FancyChatDisplay(dictionary["amount"], "AMOUNT HELP PAGE");
break;
case "blacklist":
QuickSell.FancyChatDisplay(dictionary["blacklist"], "BLACKLIST HELP PAGE");
break;
case "priority":
QuickSell.FancyChatDisplay(dictionary["priority"], "PRIORITY HELP PAGE");
break;
default:
ChatCommandAPI.PrintError("No page with this name exists");
break;
}
}
protected static void SellParticularItem()
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
QuickSell.Logger.LogDebug((object)"variation == \"item\" -> calling SellParticularItem()");
string itemName;
if (sellData.args.Length <= 1)
{
if (!CheckHeldItem(out itemName))
{
return;
}
QuickSell.Logger.LogDebug((object)("Item to sell: " + itemName));
QuickSell.Logger.LogDebug((object)"Dropping held item");
StartOfRound.Instance.localPlayerController.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true);
}
else
{
itemName = GetActualItemByName(sellData.args[1]).prefabName;
QuickSell.Logger.LogDebug((object)("Item to sell: " + itemName));
}
GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
if (array == null || array.Length == 0)
{
QuickSell.Logger.LogDebug((object)"No items were found");
ChatCommandAPI.PrintError("No items were found");
return;
}
array = FindItems(array, itemName);
int itemCount;
if (array == null || array.Length == 0)
{
QuickSell.Logger.LogDebug((object)("No items called \"" + itemName + "\" were detected"));
ChatCommandAPI.PrintError("No items called \"" + itemName + "\" were detected");
}
else if (SellItems(array.ToList(), out itemCount))
{
if (!sellData.desk.doorOpen)
{
QuickSell.Logger.LogDebug((object)"The door is not open -> opening it");
sellData.desk.SetTimesHeardNoiseServerRpc(5f);
}
QuickSell.FancyChatDisplay("Selling " + NumberOfItems(itemCount) + " named \"" + itemName + "\" with a total value of " + ValueOfItems(array.ToList()));
QuickSell.Logger.LogDebug((object)"The sell command completed it's job, terminating");
}
}
protected static void SellQuota()
{
QuickSell.Logger.LogDebug((object)"variation == \"quota\" -> calling SellQuota()");
sellData.value = TimeOfDay.Instance.profitQuota - (TimeOfDay.Instance.quotaFulfilled + Patches.valueOnDesk);
sellData.originalValue = sellData.value.ToString();
QuickSell.Logger.LogDebug((object)$"The requested value (profitQuota - (quotaFulfilled + value on desk)): {sellData.value}");
if (sellData.value < 1)
{
QuickSell.FancyChatDisplay("Quota is already fulfilled");
QuickSell.Logger.LogDebug((object)"Quota is already fulfilled -> nothing left to do");
}
else
{
SellForValue();
}
}
protected static void SellAll()
{
QuickSell.Logger.LogDebug((object)"variation == \"all\" -> calling SellAll()");
sellData.value = -1;
sellData.quotaLeft = TimeOfDay.Instance.profitQuota - (TimeOfDay.Instance.quotaFulfilled + Patches.valueOnDesk);
SellForValue();
}
protected static void SellForRequestedAmount()
{
QuickSell.Logger.LogDebug((object)"variation == \"<amount>\" -> calling SellForRequestedAmount()");
string text = string.Join(' ', sellData.args.Where((string i) => i.First() != '-' || i.Length <= 1)).Trim();
QuickSell.Logger.LogDebug((object)("Expression: \"" + text + "\" "));
QuickSell.Logger.LogDebug((object)"Evaluating expression");
string text2 = "";
try
{
text2 = new DataTable().Compute(text, "").ToString();
}
catch
{
QuickSell.Logger.LogDebug((object)"Failed to evalute expression");
ChatCommandAPI.PrintError("Failed to evalute expression");
return;
}
if (!int.TryParse(text2, out sellData.value) || sellData.value < 0)
{
QuickSell.Logger.LogDebug((object)"The value is not convertable into integer");
ChatCommandAPI.PrintError("The value is not convertable into integer");
return;
}
if (sellData.value < 0)
{
QuickSell.Logger.LogDebug((object)"The value must be positive");
ChatCommandAPI.PrintError("The value must be positive");
return;
}
QuickSell.Logger.LogDebug((object)("Expression evaluated: " + text + " => " + text2));
sellData.originalValue = sellData.value.ToString();
if (sellData.e)
{
QuickSell.Logger.LogDebug((object)"Entering logic for accounting for existing money");
Terminal val = Object.FindObjectOfType<Terminal>();
if ((Object)(object)val == (Object)null)
{
ChatCommandAPI.PrintError("Cannot find terminal!");
QuickSell.Logger.LogDebug((object)"Cannot find terminal!");
return;
}
int value = Traverse.Create((object)val).Field("groupCredits").GetValue<int>();
QuickSell.Logger.LogDebug((object)$"Credits in terminal: {value}");
if (sellData.o)
{
QuickSell.Logger.LogDebug((object)"Accounting for both terminal money and existing overtime");
sellData.existingMoney = value + Patches.valueOnDesk + FindOvertime(TimeOfDay.Instance.quotaFulfilled + Patches.valueOnDesk, TimeOfDay.Instance.profitQuota, sellData.n);
sellData.value -= sellData.existingMoney;
QuickSell.Logger.LogDebug((object)$"Overall existing money: {sellData.existingMoney}");
QuickSell.Logger.LogDebug((object)$"Adjusted value: {sellData.value}");
}
else
{
QuickSell.Logger.LogDebug((object)"Accounting just for terminal money");
sellData.existingMoney = value + Patches.valueOnDesk;
sellData.value -= sellData.existingMoney;
QuickSell.Logger.LogDebug((object)$"Money in terminal: {sellData.existingMoney}");
QuickSell.Logger.LogDebug((object)$"Adjusted value: {sellData.value}");
}
if (sellData.value <= 0)
{
QuickSell.Logger.LogDebug((object)$"{sellData.value} <= 0 -> There is no need to sell anything, terminating");
QuickSell.FancyChatDisplay($"You already have {sellData.existingMoney} existing money out of desired {sellData.originalValue}");
return;
}
}
if (sellData.o)
{
QuickSell.Logger.LogDebug((object)"Entering logic for overtime calculations");
sellData.quotaLeft = TimeOfDay.Instance.profitQuota - (TimeOfDay.Instance.quotaFulfilled + Patches.valueOnDesk);
QuickSell.Logger.LogDebug((object)$"Quota left: {sellData.quotaLeft}");
sellData.value = FindValueWithOvertime(sellData.value, sellData.quotaLeft, sellData.n);
QuickSell.Logger.LogDebug((object)$"New value before overtime: {sellData.value}");
}
SellForValue();
}
protected static void SellBlacklist()
{
QuickSell.Logger.LogDebug((object)"variation == \"blacklist\" -> calling SellBlacklist()");
if (sellData.args.Length <= 1 && sellData.p)
{
ItemDisplay(QuickSell.Instance.ItemBlacklistSet, "PERMANENT BLACKLIST");
return;
}
if (sellData.args.Length <= 1)
{
if (sellData.a)
{
ItemDisplay(QuickSell.Instance.TempBlacklistRmSet, "TEMPORARY UNBLACKLISTED");
ItemDisplay(QuickSell.Instance.TempBlacklistAddSet, "TEMPORARY BLACKLIST");
}
ItemDisplay(QuickSell.Instance.ActiveBlacklistSet, "ACTIVE BLACKLIST");
return;
}
bool add;
if (new string[4] { "add", "ad", "a", "+" }.Contains(sellData.args[1]))
{
add = true;
}
else
{
if (!new string[4] { "remove", "rm", "r", "-" }.Contains(sellData.args[1]))
{
if (new string[3] { "empty", "flash", "flush" }.Contains(sellData.args[1]))
{
if (sellData.p)
{
QuickSell.Logger.LogDebug((object)"Denied request to empty permanent blacklist");
ChatCommandAPI.PrintError("The permanent blacklist cannot be emptied by the mod itself for safety reasons. If you really want to do it use something like LethalConfig or R2Modman config editor");
return;
}
QuickSell.Instance.TempBlacklistAddSet.Clear();
QuickSell.Instance.TempBlacklistRmSet.Clear();
QuickSell.Instance.RebuildActiveBlacklist();
QuickSell.FancyChatDisplay("Successfully emptied temporary blacklist");
}
else
{
QuickSell.Logger.LogDebug((object)"Wrong arguments. If you don't know how to use the command use \"/sell help blacklist\"");
ChatCommandAPI.PrintError("Wrong arguments. If you don't know how to use the command use \"/sell help blacklist\"");
}
return;
}
add = false;
}
string itemName;
if (sellData.args.Length <= 2)
{
if (!CheckHeldItem(out itemName))
{
return;
}
}
else
{
itemName = GetActualItemByName(sellData.args[2]).prefabName;
}
QuickSell.Logger.LogDebug((object)("Item to blacklist: " + itemName));
if (sellData.p)
{
ChangePermanentBlacklist(itemName, add);
}
else
{
ChangeTemporaryBlacklist(itemName, add);
}
}
protected static void ChangePermanentBlacklist(string actualItemName, bool add)
{
if (actualItemName == "")
{
QuickSell.Logger.LogDebug((object)"Wrong item name");
ChatCommandAPI.PrintError("Wrong item name");
return;
}
if (add && QuickSell.Instance.ItemBlacklistSet.Contains(actualItemName))
{
QuickSell.Logger.LogDebug((object)("\"" + actualItemName + "\" is already in the permanent blacklist"));
ChatCommandAPI.PrintWarning("\"" + actualItemName + "\" is already in the permanent blacklist");
return;
}
if (add)
{
QuickSell.Instance.ItemBlacklistSet.Add(actualItemName);
QuickSell.FancyChatDisplay("Successfully permanently blacklisted \"" + actualItemName + "\"");
}
else
{
if (!QuickSell.Instance.ItemBlacklistSet.Contains(actualItemName))
{
QuickSell.Logger.LogDebug((object)("\"" + actualItemName + "\" is not in the permanent blacklist"));
ChatCommandAPI.PrintWarning("\"" + actualItemName + "\" is not in the permanent blacklist");
return;
}
QuickSell.Instance.ItemBlacklistSet.Remove(actualItemName);
QuickSell.FancyChatDisplay("Successfully removed \"" + actualItemName + "\" from the permanent blacklist");
}
QuickSell.Logger.LogDebug((object)("Config before: " + QuickSell.Instance.itemBlacklistConfig.Value));
QuickSell.Instance.UpdateBlacklist = false;
QuickSell.Instance.itemBlacklistConfig.Value = QuickSell.CommaJoin(QuickSell.Instance.ItemBlacklistSet);
QuickSell.Instance.UpdateBlacklist = true;
QuickSell.Logger.LogDebug((object)("Config after: " + QuickSell.Instance.itemBlacklistConfig.Value));
QuickSell.Instance.RebuildActiveBlacklist();
}
protected static void ChangeTemporaryBlacklist(string actualItemName, bool add)
{
if (actualItemName == "")
{
QuickSell.Logger.LogDebug((object)"Wrong item name");
ChatCommandAPI.PrintError("Wrong item name");
return;
}
if (add && QuickSell.Instance.TempBlacklistAddSet.Contains(actualItemName))
{
QuickSell.Logger.LogDebug((object)("\"" + actualItemName + "\" is already temporarily blacklisted"));
ChatCommandAPI.PrintWarning("\"" + actualItemName + "\" is already temporarily blacklisted");
return;
}
if (add)
{
QuickSell.Instance.TempBlacklistRmSet.Remove(actualItemName);
QuickSell.Instance.TempBlacklistAddSet.Add(actualItemName);
QuickSell.FancyChatDisplay("Successfully temporarily blacklisted \"" + actualItemName + "\"");
}
else
{
if (QuickSell.Instance.TempBlacklistRmSet.Contains(actualItemName))
{
QuickSell.Logger.LogDebug((object)("\"" + actualItemName + "\" is already temporarily prohibited to blacklist"));
ChatCommandAPI.PrintWarning("\"" + actualItemName + "\" is already temporarily prohibited to blacklist");
return;
}
QuickSell.Instance.TempBlacklistRmSet.Add(actualItemName);
QuickSell.Instance.TempBlacklistAddSet.Remove(actualItemName);
QuickSell.FancyChatDisplay("Successfully temporarily prohibited to blacklist \"" + actualItemName + "\"");
}
QuickSell.Instance.RebuildActiveBlacklist();
}
protected static void SellPriority()
{
QuickSell.Logger.LogDebug((object)"variation == \"priority\" -> calling SellPriority()");
if (sellData.args.Length <= 1 && sellData.p)
{
ItemDisplay(QuickSell.Instance.PriorityItemsSet, "PERMANENT PRIORITY SET");
return;
}
if (sellData.args.Length <= 1)
{
if (sellData.a)
{
ItemDisplay(QuickSell.Instance.TempPriorityRmSet, "TEMPORARY UNPRIORITIZED");
ItemDisplay(QuickSell.Instance.TempPriorityAddSet, "TEMPORARY PRIORITY SET");
}
ItemDisplay(QuickSell.Instance.ActivePrioritySet, "ACTIVE PRIORITY SET");
return;
}
bool add;
if (new string[4] { "add", "ad", "a", "+" }.Contains(sellData.args[1]))
{
add = true;
}
else
{
if (!new string[4] { "remove", "rm", "r", "-" }.Contains(sellData.args[1]))
{
if (new string[3] { "empty", "flash", "flush" }.Contains(sellData.args[1]))
{
if (sellData.p)
{
QuickSell.Logger.LogDebug((object)"Denied request to empty permanent priority set");
ChatCommandAPI.PrintError("The permanent priority set cannot be emptied by the mod itself for safety reasons. If you really want to do it use something like LethalConfig or R2Modman config editor");
return;
}
QuickSell.Instance.TempPriorityAddSet.Clear();
QuickSell.Instance.TempPriorityRmSet.Clear();
QuickSell.Instance.RebuildActivePrioritySet();
QuickSell.FancyChatDisplay("Successfully emptied temporary priority set");
}
else
{
QuickSell.Logger.LogDebug((object)"Wrong arguments. If you don't know how to use the command use \"/sell help priority\"");
ChatCommandAPI.PrintError("Wrong arguments. If you don't know how to use the command use \"/sell help priority\"");
}
return;
}
add = false;
}
string itemName;
if (sellData.args.Length <= 2)
{
if (!CheckHeldItem(out itemName))
{
return;
}
}
else
{
itemName = GetActualItemByName(sellData.args[2]).prefabName;
}
QuickSell.Logger.LogDebug((object)("Item: " + itemName));
if (sellData.p)
{
ChangePermanentPrioritySet(itemName, add);
}
else
{
ChangeTemporaryPrioritySet(itemName, add);
}
}
protected static void ChangePermanentPrioritySet(string actualItemName, bool add)
{
if (actualItemName == "")
{
QuickSell.Logger.LogDebug((object)"Wrong item name");
ChatCommandAPI.PrintError("Wrong item name");
return;
}
if (add && QuickSell.Instance.PriorityItemsSet.Contains(actualItemName))
{
QuickSell.Logger.LogDebug((object)("\"" + actualItemName + "\" is already in the permanent priority set"));
ChatCommandAPI.PrintWarning("\"" + actualItemName + "\" is already in the permanent priority set");
return;
}
if (add)
{
QuickSell.Instance.PriorityItemsSet.Add(actualItemName);
QuickSell.FancyChatDisplay("Successfully added \"" + actualItemName + "\" to the permanent priority set");
}
else
{
if (!QuickSell.Instance.PriorityItemsSet.Contains(actualItemName))
{
QuickSell.Logger.LogDebug((object)("\"" + actualItemName + "\" is not in the permanent priority set"));
ChatCommandAPI.PrintWarning("\"" + actualItemName + "\" is not in the permanent priority set");
return;
}
QuickSell.Instance.PriorityItemsSet.Remove(actualItemName);
QuickSell.FancyChatDisplay("Successfully removed \"" + actualItemName + "\" from the permanent priority set");
}
QuickSell.Logger.LogDebug((object)("Config before: " + QuickSell.Instance.priorityItemsConfig.Value));
QuickSell.Instance.UpdatePriority = false;
QuickSell.Instance.priorityItemsConfig.Value = QuickSell.CommaJoin(QuickSell.Instance.PriorityItemsSet);
QuickSell.Instance.UpdatePriority = true;
QuickSell.Logger.LogDebug((object)("Config after: " + QuickSell.Instance.priorityItemsConfig.Value));
QuickSell.Instance.RebuildActivePrioritySet();
}
protected static void ChangeTemporaryPrioritySet(string actualItemName, bool add)
{
if (actualItemName == "")
{
QuickSell.Logger.LogDebug((object)"Wrong item name");
ChatCommandAPI.PrintError("Wrong item name");
return;
}
if (add && QuickSell.Instance.TempPriorityAddSet.Contains(actualItemName))
{
QuickSell.Logger.LogDebug((object)("\"" + actualItemName + "\" is already in the temporarily priority set"));
ChatCommandAPI.PrintWarning("\"" + actualItemName + "\" is already in the temporarily priority set");
return;
}
if (add)
{
QuickSell.Instance.TempPriorityRmSet.Remove(actualItemName);
QuickSell.Instance.TempPriorityAddSet.Add(actualItemName);
QuickSell.FancyChatDisplay("Successfully added \"" + actualItemName + "\" to the temporary priority set");
}
else
{
if (QuickSell.Instance.TempPriorityRmSet.Contains(actualItemName))
{
QuickSell.Logger.LogDebug((object)("\"" + actualItemName + "\" is already temporarily prohibited to prioritize"));
ChatCommandAPI.PrintWarning("\"" + actualItemName + "\" is already temporarily prohibited to prioritize");
return;
}
QuickSell.Instance.TempPriorityRmSet.Add(actualItemName);
QuickSell.Instance.TempPriorityAddSet.Remove(actualItemName);
QuickSell.FancyChatDisplay("Successfully temporarily prohibited to prioritize \"" + actualItemName + "\"");
}
QuickSell.Instance.RebuildActivePrioritySet();
}
protected static void ItemDisplay(IEnumerable<string> items, string title, string normalColor = "#00ffff", string errorColor = "#ff0000", string noNameText = "MISSING NAME")
{
if (MyCollections.IsNullOrEmpty<string>(items))
{
return;
}
string text = "";
foreach (string item2 in items)
{
string item = GetActualItemByName(item2).itemName;
text = ((!(item != "")) ? (text + "<color=" + errorColor + ">" + noNameText + " (" + item2 + ")</color>\n") : (text + "<color=" + normalColor + ">" + item + " (" + item2 + ")</color>\n"));
}
QuickSell.FancyChatDisplay(text, title, addColorToContents: false);
}
protected static (string prefabName, string name, string itemName, string scanNodeName) GetActualItemByName(string itemName)
{
string itemName2 = itemName;
return QuickSell.allItems.Where<(string, string, string, string)>(((string prefabName, string name, string itemName, string scanNodeName) i) => new string[4] { i.prefabName, i.name, i.itemName, i.scanNodeName }.Any((string j) => j?.Equals(itemName2, StringComparison.OrdinalIgnoreCase) ?? false)).DefaultIfEmpty(("", "", "", "")).First();
}
protected static bool CheckHeldItem(out string itemName)
{
itemName = "";
PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
if ((Object)(object)localPlayerController == (Object)null)
{
QuickSell.Logger.LogDebug((object)"localPlayerController == null -> returning false");
ChatCommandAPI.PrintError("localPlayerController == null");
return false;
}
GrabbableObject val = localPlayerController.ItemSlots[localPlayerController.currentItemSlot];
if ((Object)(object)val == (Object)null || ((Object)val).name == "")
{
QuickSell.Logger.LogDebug((object)"No item is held and no item was specified");
ChatCommandAPI.PrintError("No item is held and no item was specified");
return false;
}
itemName = RemoveClone(((Object)val).name);
return true;
}
protected static async void SellForValue()
{
QuickSell.Logger.LogDebug((object)$"Calling SellForValue({sellData.value})");
List<GrabbableObject> list = await Task.Run(() => ItemsForValue(sellData.value, sellData.a));
if (list == null)
{
QuickSell.Logger.LogDebug((object)"Got null from ItemsForValue() -> not selling anything");
ChatCommandAPI.PrintError("No items were found");
return;
}
if (list.Count == 0)
{
QuickSell.Logger.LogDebug((object)"The list of items you need to sell is empty so you probably can't afford the amount you requested. If not, please report this.");
ChatCommandAPI.PrintError("You can't afford to sell that amount");
return;
}
if (!SellItems(list, out var itemCount))
{
QuickSell.Logger.LogDebug((object)"Error selling items");
ChatCommandAPI.PrintError("Error selling items");
return;
}
if (!sellData.desk.doorOpen)
{
QuickSell.Logger.LogDebug((object)"The door is not open -> opening it");
sellData.desk.SetTimesHeardNoiseServerRpc(5f);
}
else
{
QuickSell.Logger.LogDebug((object)"The door is open -> starting coroutine to check later if the items are still on desk");
((MonoBehaviour)StartOfRound.Instance).StartCoroutine(DelayedDeskCheck());
}
int num = ((sellData.o || sellData.variation == "all") ? FindOvertime((int)((float)list.Sum((GrabbableObject i) => i.scrapValue) * StartOfRound.Instance.companyBuyingRate), sellData.quotaLeft, sellData.n) : 0);
QuickSell.FancyChatDisplay("Selling " + NumberOfItems(itemCount) + " with a total value of " + ValueOfItems(list) + ((num != 0) ? $" + {num} overtime" : "") + (sellData.e ? $" + {sellData.existingMoney} existing money" : "") + ((sellData.originalValue != "") ? $":\n{(int)((float)list.Sum((GrabbableObject i) => i.scrapValue) * StartOfRound.Instance.companyBuyingRate) + num + sellData.existingMoney} sold / {sellData.originalValue} requested" : (", sold every " + (sellData.a ? "" : "unfiltered ") + "item")));
QuickSell.Logger.LogDebug((object)"The sell command completed it's job, terminating");
}
protected static List<GrabbableObject>? ItemsForValue(int value, bool ignoreBlacklist)
{
QuickSell.Logger.LogDebug((object)$"Calling ItemsForValue({value})");
if (value == 0)
{
QuickSell.Logger.LogDebug((object)"value == 0 -> returning null");
return null;
}
GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
if (array == null || array.Length == 0)
{
QuickSell.Logger.LogDebug((object)"No items were found -> returning null");
return null;
}
QuickSell.Logger.LogDebug((object)$"Cost of all scrap: {array.Sum((GrabbableObject i) => i.scrapValue)}, {NumberOfItems(array.Count())}");
array = FilterItems(array, ignoreBlacklist);
if (array.Length == 0)
{
QuickSell.Logger.LogDebug((object)"No items were left after filtering -> returning null");
return null;
}
QuickSell.Logger.LogDebug((object)$"Cost of all unfiltered scrap (max possible value): {array.Sum((GrabbableObject i) => i.scrapValue)}, {NumberOfItems(array.Count())}");
if (value == -1)
{
QuickSell.Logger.LogDebug((object)"value == -1 -> need to sell everything -> returning [.. items]");
if (array.Length == 0)
{
return null;
}
return array.ToList();
}
value = (int)Math.Ceiling((float)value / StartOfRound.Instance.companyBuyingRate);
QuickSell.Logger.LogDebug((object)$"Value after accounting for buying rate: {value}");
GrabbableObject val = array.OrderBy((GrabbableObject i) => i.scrapValue).First();
QuickSell.Logger.LogDebug((object)$"The cheapest item is {val.scrapValue}");
if (value <= val.scrapValue)
{
QuickSell.Logger.LogDebug((object)$"value <= {val.scrapValue} -> returning the cheapest item");
return new List<GrabbableObject>(1) { val };
}
if (array.Sum((GrabbableObject i) => i.scrapValue) < value)
{
QuickSell.Logger.LogDebug((object)"Max possible value is not enough to get to the desired value -> returning empty list");
return new List<GrabbableObject>();
}
List<GrabbableObject> list = CombinationFinder(array, value);
QuickSell.Logger.LogDebug((object)("ItemsForValue() returns a list of " + NumberOfItems(list.Count()) + " worth " + ValueOfItems(list)));
return list;
}
protected static List<GrabbableObject> CombinationFinder(GrabbableObject[] items, int value)
{
QuickSell.Logger.LogDebug((object)$"Calling CombinationFinder({NumberOfItems(items.Count())}, {value})");
List<GrabbableObject> list = new List<GrabbableObject>();
int num = items.Sum((GrabbableObject item) => item.scrapValue);
bool[] array = new bool[num + 1];
List<GrabbableObject>[] array2 = new List<GrabbableObject>[num + 1];
int[] array3 = new int[num + 1];
for (int i = 0; i <= num; i++)
{
array[i] = false;
array2[i] = new List<GrabbableObject>();
array3[i] = 0;
}
array[0] = true;
QuickSell.Logger.LogDebug((object)("Items with priority: " + GeneralExtensions.Join<string>((IEnumerable<string>)QuickSell.Instance.ActivePrioritySet, (Func<string, string>)null, ", ")));
QuickSell.Logger.LogDebug((object)"Starting looping through every item");
foreach (GrabbableObject val in items)
{
int num2 = (IsPriority(val) ? 1 : 0);
QuickSell.Logger.LogDebug((object)$"Item: {RemoveClone(((Object)val).name)}, price: {val.scrapValue}, priority: {num2}");
for (int num3 = num; num3 >= val.scrapValue; num3--)
{
int num4 = num3 - val.scrapValue;
if (array[num4])
{
int num5 = array3[num4] + num2;
if (!array[num3] || num5 > array3[num3])
{
array[num3] = true;
int num6 = num3;
List<GrabbableObject> list2 = array2[num4];
List<GrabbableObject> list3 = new List<GrabbableObject>(1 + list2.Count);
list3.AddRange(list2);
list3.Add(val);
array2[num6] = list3;
array3[num3] = num5;
}
}
}
}
if (array[value])
{
QuickSell.Logger.LogDebug((object)$"CombinationFinder() has found a perfect combination for {value} (there still can be off-by-one errors because of how overtime works)");
return array2[value];
}
for (int k = value + 1; k <= num; k++)
{
if (array[k])
{
QuickSell.Logger.LogDebug((object)$"CombinationFinder() has found the best imperfect combination: {k}/{value}");
return array2[k];
}
}
QuickSell.Logger.LogDebug((object)"CombinationFinder() failed to execute for unknown reason. Please report this to the mod author.");
return new List<GrabbableObject>();
}
protected static bool SellItems(List<GrabbableObject> items, out int itemCount)
{
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: 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_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
QuickSell.Logger.LogDebug((object)("Calling SellItems(" + NumberOfItems(items.Count()) + ")"));
itemCount = 0;
QuickSell.Logger.LogDebug((object)"Looping through every item");
RaycastHit val2 = default(RaycastHit);
foreach (GrabbableObject item in items)
{
if (!((Object)(object)item == (Object)null))
{
QuickSell.Logger.LogDebug((object)$"Item: {((Object)item).name}, price: {item.scrapValue}");
itemCount++;
Vector3 val = RoundManager.RandomPointInBounds(((Collider)sellData.desk.triggerCollider).bounds);
Bounds bounds = ((Collider)sellData.desk.triggerCollider).bounds;
val.y = ((Bounds)(ref bounds)).min.y;
if (Physics.Raycast(new Ray(val + Vector3.up * 3f, Vector3.down), ref val2, 8f, 1048640, (QueryTriggerInteraction)2))
{
val = ((RaycastHit)(ref val2)).point;
}
val.y += item.itemProperties.verticalOffset;
val = ((Component)sellData.desk.deskObjectsContainer).transform.InverseTransformPoint(val);
sellData.desk.AddObjectToDeskServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)item).NetworkObject));
GameNetworkManager.Instance.localPlayerController.PlaceGrabbableObject(((Component)sellData.desk.deskObjectsContainer).transform, val, false, item);
GameNetworkManager.Instance.localPlayerController.PlaceObjectServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)item).NetworkObject), NetworkObjectReference.op_Implicit(sellData.desk.deskObjectsContainer), val, false);
}
}
QuickSell.Logger.LogDebug((object)"Selling completed");
return true;
}
protected static bool OpenDoor(out int itemCount, out int totalValue)
{
QuickSell.Logger.LogDebug((object)"Calling OpenDoor()");
itemCount = 0;
totalValue = 0;
itemCount = sellData.desk.itemsOnCounter.Count;
totalValue = sellData.desk.itemsOnCounter.Sum((GrabbableObject i) => i.scrapValue);
QuickSell.Logger.LogDebug((object)("There are " + NumberOfItems(itemCount) + " on the desk worth " + ValueOfItems(totalValue)));
if (itemCount == 0)
{
QuickSell.Logger.LogDebug((object)"No items on the desk");
ChatCommandAPI.PrintError("No items on the desk");
return false;
}
if (sellData.desk.doorOpen)
{
QuickSell.Logger.LogDebug((object)"Door was already open -> nothing left to do");
ChatCommandAPI.PrintError("Door already open");
return false;
}
QuickSell.Logger.LogDebug((object)"Opening a door");
sellData.desk.SetTimesHeardNoiseServerRpc(5f);
return true;
}
[IteratorStateMachine(typeof(<DelayedDeskCheck>d__32))]
public static IEnumerator DelayedDeskCheck()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DelayedDeskCheck>d__32(0);
}
protected internal static int GetDeadline(bool forceNonRestart = false)
{
QuickSell.Logger.LogDebug((object)$"Calling GetDeadline({forceNonRestart})");
int num = (((double)TimeOfDay.Instance.globalTimeAtEndOfDay == 0.0 && !forceNonRestart) ? TimeOfDay.Instance.daysUntilDeadline : (TimeOfDay.Instance.daysUntilDeadline - 1));
QuickSell.Logger.LogDebug((object)$"Real days until deadline: {num}");
return num;
}
protected static int FindValueWithOvertime(int a, int q, bool forceNonRestart = false)
{
QuickSell.Logger.LogDebug((object)$"Calling FindValueWithOvertime({a}, {q}, {forceNonRestart})");
int deadline = GetDeadline(forceNonRestart);
int num = ((a < q) ? a : ((q < 0) ? ((int)Math.Ceiling((double)(5 * a + Math.Max(q - 75 * deadline, q % 5)) / 6.0)) : ((int)Math.Ceiling((double)(5 * a + Math.Max(q - 75 * deadline, 0)) / 6.0))));
QuickSell.Logger.LogDebug((object)$"FindValueWithOvertime() returns value: {num}");
return num;
}
protected static int FindOvertime(int x, int q, bool forceNonRestart = false)
{
QuickSell.Logger.LogDebug((object)$"Calling FindOvertime({x}, {q}, {forceNonRestart})");
int deadline = GetDeadline(forceNonRestart);
int num = ((q >= 0) ? Math.Max((x + Math.Min(75 * deadline - q, 0)) / 5, 0) : Math.Max((x + Math.Min(75 * deadline - q, Math.Abs(q % 5))) / 5, 0));
QuickSell.Logger.LogDebug((object)$"FindOvertime() returns overtime: {num}");
return num;
}
protected static string NumberOfItems(int itemCount)
{
return itemCount + ((itemCount == 1) ? " item" : " items");
}
protected static string ValueOfItems(List<GrabbableObject> items)
{
return items.Sum((GrabbableObject i) => i.scrapValue) + (Mathf.Approximately(StartOfRound.Instance.companyBuyingRate, 1f) ? "" : $" ({(int)((float)items.Sum((GrabbableObject i) => i.scrapValue) * StartOfRound.Instance.companyBuyingRate)})");
}
protected static string ValueOfItems(int totalValue)
{
return totalValue + (Mathf.Approximately(StartOfRound.Instance.companyBuyingRate, 1f) ? "" : $" ({(int)((float)totalValue * StartOfRound.Instance.companyBuyingRate)})");
}
protected static bool IsPriority(GrabbableObject item)
{
return QuickSell.Instance.ActivePrioritySet.Contains<string>(RemoveClone(((Object)item).name), StringComparer.OrdinalIgnoreCase);
}
protected static string RemoveClone(string name, string cloneString = "(Clone)")
{
if (!name.EndsWith(cloneString))
{
return name;
}
int length = cloneString.Length;
return name.Substring(0, name.Length - length);
}
protected static GrabbableObject[] FilterItems(GrabbableObject[] items, bool ignoreBlacklist)
{
QuickSell.Logger.LogDebug((object)("Calling FilterItems(" + NumberOfItems(items.Count()) + ")"));
if (ignoreBlacklist)
{
QuickSell.Logger.LogDebug((object)"Ignoring blacklist");
}
else
{
QuickSell.Logger.LogDebug((object)("Blacklisted items: " + GeneralExtensions.Join<string>((IEnumerable<string>)QuickSell.Instance.ActiveBlacklistSet, (Func<string, string>)null, ", ")));
}
return (from i in items.Where(delegate(GrabbableObject i)
{
if (i != null && i.scrapValue > 0 && !i.isHeld && !i.isPocketed)
{
Item itemProperties = i.itemProperties;
if (itemProperties != null && itemProperties.isScrap)
{
return !sellData.desk.itemsOnCounter.Contains(i);
}
}
return false;
})
where !QuickSell.Instance.ActiveBlacklistSet.Contains<string>(RemoveClone(((Object)i).name), StringComparer.OrdinalIgnoreCase) || ignoreBlacklist
select i).ToArray();
}
protected static GrabbableObject[] FindItems(GrabbableObject[] items, string itemName)
{
string itemName2 = itemName;
QuickSell.Logger.LogDebug((object)("Calling FindItems(" + NumberOfItems(items.Count()) + ", " + itemName2 + ")"));
return (from i in items
where i != null && !i.isHeld && !i.isPocketed && !sellData.desk.itemsOnCounter.Contains(i)
where RemoveClone(((Object)i).name).ToLower() == itemName2.ToLower()
select i).ToArray();
}
protected internal static bool FindDesk(out DepositItemsDesk desk)
{
QuickSell.Logger.LogDebug((object)"Calling FindDesk1()");
desk = Object.FindObjectOfType<DepositItemsDesk>();
if ((Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)desk == (Object)null)
{
QuickSell.Logger.LogDebug((object)"A desk was not found");
ChatCommandAPI.PrintError("A desk was not found");
return false;
}
QuickSell.Logger.LogDebug((object)"A desk was found");
return true;
}
}
public class OvertimeCommand : Command
{
public override string Name => "Overtime";
public override string Description => "Shows how much overtime you will get\n-n to force non-restart calculations (if you don't know what it is don't use it)";
public override string[] Commands => new string[2]
{
((Command)this).Name.ToLower(),
"ot"
};
public override string[] Syntax => new string[2] { "", "[-n]" };
public override bool Invoke(string[] args, Dictionary<string, string> kwargs, out string error)
{
QuickSell.Logger.LogDebug((object)"The overtime command was initiated");
error = "it should not happen";
int deadline = SellCommand.GetDeadline(args.Length != 0 && args[0] == "-n");
QuickSell.FancyChatDisplay($"Overtime: {Math.Max((TimeOfDay.Instance.quotaFulfilled + Patches.valueOnDesk + Math.Min(75 * deadline - TimeOfDay.Instance.profitQuota, 0)) / 5, 0)}", "OVERTIME");
QuickSell.Logger.LogDebug((object)"Terminating");
return true;
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "gafoneo.quicksell";
public const string PLUGIN_NAME = "QuickSell";
public const string PLUGIN_VERSION = "1.1.4";
}
}