using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ChatCommandAPI;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("0Harmony")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("baer1.ChatCommandAPI")]
[assembly: IgnoresAccessChecksTo("BepInEx")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("UnityEngine.IMGUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("QuickSort")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("made by Asta")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1+644f591bb1e79799e329bdb84240036f1945b788")]
[assembly: AssemblyProduct("QuickSort")]
[assembly: AssemblyTitle("QuickSort")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.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 QuickSort
{
public static class Chat
{
[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static bool OnChatSubmit(HUDManager __instance, CallbackContext context)
{
if (!((CallbackContext)(ref context)).performed || !Player.Local.isTypingChat)
{
return true;
}
string text = __instance.chatTextField.text;
if (text == "/help")
{
string text2 = "Commands: ";
text2 += string.Join(", ", ChatCommand.Commands);
Log.Chat(text2);
CloseChat(__instance);
return false;
}
if (text.StartsWith("/"))
{
text = text.Substring(1).Trim();
foreach (ChatCommand command in ChatCommand.Commands)
{
if (text.StartsWith(command.keyword))
{
CloseChat(__instance);
try
{
command.action(command.GetArgs(text));
}
catch (Exception e)
{
Log.Exception(e);
}
return false;
}
}
}
return true;
}
public static void CloseChat(HUDManager instance)
{
instance.localPlayer.isTypingChat = false;
instance.chatTextField.text = "";
EventSystem.current.SetSelectedGameObject((GameObject)null);
((Behaviour)instance.typingIndicator).enabled = false;
}
}
public abstract class Argument
{
public string name;
}
public class Argument<T> : Argument
{
public T value;
public Argument(string name, T value)
{
base.name = name;
this.value = value;
}
public static implicit operator T(Argument<T> arg)
{
return arg.value;
}
}
public struct ChatArgs
{
public Argument[] arguments;
public string help;
public int Length => arguments.Length;
public bool Empty => arguments.Length == 0;
public bool this[string name] => Get<bool>(name);
public string this[int name] => Get<string>(name);
public T Get<T>(string name)
{
Argument[] array = arguments;
Argument[] array2 = array;
foreach (Argument argument in array2)
{
if (argument.name == name)
{
return ((Argument<T>)argument).value;
}
}
return default(T);
}
public T Get<T>(int name)
{
Argument[] array = arguments;
Argument[] array2 = array;
foreach (Argument argument in array2)
{
if (argument.name == name.ToString())
{
return ((Argument<T>)argument).value;
}
}
return default(T);
}
}
public class ChatCommand
{
public static List<ChatCommand> Commands = new List<ChatCommand>();
public string keyword;
public Action<ChatArgs> action;
public string help;
public ChatCommand(string keyword, string help, Action<ChatArgs> action)
{
this.keyword = keyword;
this.help = help;
this.action = action;
}
public static ChatCommand New(string keyword, string help, Action<ChatArgs> action)
{
ChatCommand chatCommand = new ChatCommand(keyword, help, action);
Commands.Add(chatCommand);
return chatCommand;
}
public ChatArgs GetArgs(string raw)
{
List<Argument> list = new List<Argument>();
string[] array = raw.Split(' ');
keyword = array[0];
for (int i = 1; i < array.Length; i++)
{
if (array[i].StartsWith("-"))
{
string name = array[i].Substring(1);
list.Add(new Argument<bool>(name, value: true));
}
else
{
list.Add(new Argument<string>((i - 1).ToString(), array[i]));
}
}
ChatArgs result = default(ChatArgs);
result.arguments = list.ToArray();
result.help = help;
return result;
}
public override string ToString()
{
return keyword;
}
}
public static class Extensions
{
private static readonly Dictionary<string, string> NameAliases = BuildNameAliases();
private static string NormalizeKeyNoAlias(string s)
{
if (string.IsNullOrWhiteSpace(s))
{
return "";
}
return s.ToLower().Replace(" ", "_").Replace("-", "_")
.Trim();
}
private static Dictionary<string, string> BuildNameAliases()
{
Dictionary<string, string> d = new Dictionary<string, string>();
(string, string[])[] array = new(string, string[])[19]
{
("boombox", new string[1] { "붐박스" }),
("flashlight", new string[1] { "손전등" }),
("jetpack", new string[1] { "제트팩" }),
("key", new string[1] { "열쇠" }),
("lockpicker", new string[1] { "자물쇠 따개" }),
("apparatus", new string[2] { "장치", "apparatice" }),
("pro_flashlight", new string[2] { "프로 손전등", "pro-flashlight" }),
("shovel", new string[1] { "철제 삽" }),
("stun_grenade", new string[2] { "기절 수류탄", "stun grenade" }),
("extension_ladder", new string[2] { "연장형 사다리", "extension ladder" }),
("tzp_inhalant", new string[2] { "tzp-흡입제", "tzp-inhalant" }),
("walkie_talkie", new string[2] { "무전기", "walkie-talkie" }),
("zap_gun", new string[2] { "잽건", "zap gun" }),
("radar_booster", new string[3] { "레이더 부스터", "radar booster", "radar-booster" }),
("spray_paint", new string[3] { "페인트 스프레이", "스프레이 페인트", "spray paint" }),
("shotgun", new string[1] { "산탄총" }),
("ammo", new string[1] { "탄약" }),
("clipboard", new string[1] { "클립보드" }),
("sticky_note", new string[3] { "스티커 메모", "스티커메모", "sticky note" })
};
(string, string[])[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
(string, string[]) tuple = array2[i];
AddAliases(tuple.Item1, tuple.Item2);
}
(string, string[])[] array3 = new(string, string[])[9]
{
("coffee_mug", new string[4] { "mug", "머그잔", "coffee mug", "커피 머그잔" }),
("hair_brush", new string[3] { "brush", "hair brush", "빗" }),
("brass_bell", new string[4] { "bell", "brass bell", "황동 종", "종" }),
("bee_hive", new string[3] { "hive", "bee hive", "벌집" }),
("wedding_ring", new string[3] { "ring", "wedding ring", "반지" }),
("robot_toy", new string[4] { "toy robot", "robot toy", "장난감 로봇", "로봇 장난감" }),
("rubber_ducky", new string[2] { "rubber ducky", "고무 오리" }),
("tattered_metal_sheet", new string[4] { "metal sheet", "tattered metal sheet", "금속 판", "너덜너덜한 금속 판" }),
("homemade_flashbang", new string[2] { "homemade flashbang", "사제 섬광탄" })
};
(string, string[])[] array4 = array3;
for (int j = 0; j < array4.Length; j++)
{
(string, string[]) tuple2 = array4[j];
AddAliases(tuple2.Item1, tuple2.Item2);
}
(string, string[])[] array5 = new(string, string[])[31]
{
("bubblegun", new string[1] { "비눗방울 총" }),
("broken_p88", new string[2] { "망가진 p88", "broken p88" }),
("employee", new string[1] { "직원" }),
("mine", new string[1] { "지뢰" }),
("toothles", new string[2] { "투슬리스", "toothles" }),
("crossbow", new string[2] { "석궁", "crossbow" }),
("physgun", new string[2] { "피직스건", "physgun" }),
("ammo_crate", new string[2] { "탄약 상자", "ammo crate" }),
("drink", new string[1] { "음료수" }),
("radio", new string[1] { "라디오" }),
("mouse", new string[1] { "마우스" }),
("monitor", new string[1] { "모니터" }),
("battery", new string[1] { "건전지" }),
("cannon", new string[1] { "대포" }),
("health_drink", new string[2] { "건강 음료", "health drink" }),
("chemical", new string[1] { "화학 약품" }),
("disinfecting_alcohol", new string[2] { "소독용 알코올", "disinfecting alcohol" }),
("ampoule", new string[1] { "앰풀" }),
("blood_pack", new string[2] { "혈액 팩", "blood pack" }),
("flip_lighter", new string[2] { "라이터", "flip lighter" }),
("rubber_ball", new string[2] { "고무 공", "rubber ball" }),
("video_tape", new string[2] { "비디오 테이프", "video tape" }),
("first_aid_kit", new string[2] { "구급 상자", "first aid kit" }),
("gold_medallion", new string[2] { "금메달", "gold medallion" }),
("steel_pipe", new string[2] { "금속 파이프", "steel pipe" }),
("axe", new string[1] { "도끼" }),
("emergency_hammer", new string[2] { "비상용 망치", "emergency hammer" }),
("katana", new string[1] { "카타나" }),
("silver_medallion", new string[2] { "은메달", "silver medallion" }),
("pocket_radio", new string[2] { "휴대용 라디오", "pocket radio" }),
("teddy_plush", new string[2] { "곰 인형", "teddy plush" })
};
(string, string[])[] array6 = array5;
for (int k = 0; k < array6.Length; k++)
{
(string, string[]) tuple3 = array6[k];
AddAliases(tuple3.Item1, tuple3.Item2);
}
Add("마법의 7번 공", "Magic 7 ball");
Add("에어혼", "Airhorn");
Add("황동 종", "Brass bell");
Add("큰 나사", "Big bolt");
Add("병 묶음", "Bottles");
Add("빗", "Hair brush");
Add("사탕", "Candy");
Add("금전 등록기", "Cash register");
Add("화학 용기", "Chemical jug");
Add("광대 나팔", "Clown horn");
Add("대형 축", "Large axle");
Add("틀니", "Teeth");
Add("쓰레받기", "Dust pan");
Add("달걀 거품기", "Egg beater");
Add("v형 엔진", "V-type engine");
Add("황금 컵", "Golden cup");
Add("멋진 램프", "Fancy lamp");
Add("그림", "Painting");
Add("플라스틱 물고기", "Plastic fish");
Add("레이저 포인터", "Laser pointer");
Add("금 주괴", "Gold Bar");
Add("헤어 드라이기", "Hairdryer");
Add("돋보기", "Magnifying glass");
Add("너덜너덜한 금속 판", "Tattered metal sheet");
Add("쿠키 틀", "Cookie mold pan");
Add("머그잔", "Coffee mug");
Add("커피 머그잔", "Coffee mug");
Add("향수 병", "Perfume bottle");
Add("구식 전화기", "Old phone");
Add("피클 병", "Jar of pickles");
Add("약 병", "Pill bottle");
Add("리모컨", "Remote");
Add("결혼 반지", "Wedding ring");
Add("로봇 장난감", "Robot Toy");
Add("고무 오리", "Rubber ducky");
Add("빨간색 소다", "Red soda");
Add("운전대", "Steering wheel");
Add("정지 표지판", "Stop sign");
Add("찻주전자", "Tea Kettle");
Add("치약", "Toothpaste");
Add("장난감 큐브", "Toy cube");
Add("벌집", "Bee hive");
Add("양보 표지판", "Yield sign");
Add("산탄총", "Shotgun");
Add("더블 배럴", "Double-barrel");
Add("산탄총 탄약", "ammo");
Add("탄약", "ammo");
Add("사제 섬광탄", "Homemade Flashbang");
Add("선물", "Gift");
Add("선물 상자", "Gift box");
Add("플라스크", "Flask");
Add("비극", "Tragedy");
Add("희극", "Comedy");
Add("방귀 쿠션", "Whoopie cushion");
Add("방퀴 쿠션", "Whoopie cushion");
Add("식칼", "Kitchen knife");
Add("부활절 달걀", "Easter egg");
Add("제초제", "Weed killer");
Add("벨트 배낭", "Belt bag");
Add("축구공", "Soccer ball");
Add("조작 패드", "Control pad");
Add("쓰레기통 뚜껑", "Garbage lid");
Add("플라스틱 컵", "Plastic cup");
Add("화장실 휴지", "Toilet paper");
Add("장난감 기차", "Toy train");
Add("제드 도그", "Zed Dog");
Add("시계", "Clock");
Add("시체", "Body");
Add("알", "Egg");
Add("열쇠", "Key");
Add("데이터 칩", "Data chip");
Add("교육용 지침서", "Training manual");
Add("장치", "Apparatus");
Add("장치", "Apparatice");
Add("알코올 플라스크", "Alcohol Flask");
Add("모루", "Anvil");
Add("야구 방망이", "Baseball bat");
Add("맥주 캔", "Beer can");
Add("벽돌", "Brick");
Add("망가진 엔진", "Broken engine");
Add("양동이", "Bucket");
Add("페인트 캔", "Can paint");
Add("수통", "Canteen");
Add("자동차 배터리", "Car battery");
Add("조임틀", "Clamp");
Add("멋진 그림", "Fancy Painting");
Add("선풍기", "Fan");
Add("소방 도끼", "Fireaxe");
Add("소화기", "Fire extinguisher");
Add("소화전", "Fire hydrant");
Add("통조림", "Food can");
Add("게임보이", "Gameboy");
Add("쓰레기", "Garbage");
Add("망치", "Hammer");
Add("기름통", "Jerrycan");
Add("키보드", "Keyboard");
Add("랜턴", "Lantern");
Add("도서관 램프", "Library lamp");
Add("식물", "Plant");
Add("플라이어", "Pliers");
Add("뚫어뻥", "Plunger");
Add("레트로 장난감", "Retro Toy");
Add("스크류 드라이버", "Screwdriver");
Add("싱크대", "Sink");
Add("소켓 렌치", "Socket Wrench");
Add("여행 가방", "Suitcase");
Add("토스터기", "Toaster");
Add("공구 상자", "Toolbox");
Add("실크햇", "Top hat");
Add("라바콘", "Traffic cone");
Add("환풍구", "Vent");
Add("물뿌리개", "Watering Can");
Add("바퀴", "Wheel");
Add("와인 병", "Wine bottle");
Add("렌치", "Wrench");
Add("자수정 군집", "Amethyst Cluster");
Add("주사기", "Syringe");
Add("주사기총", "Syringe Gun");
Add("코너 파이프", "Corner Pipe");
Add("작은 파이프", "Small Pipe");
Add("파이프", "Flow Pipe");
Add("뇌가 담긴 병", "Brain Jar");
Add("호두까기 인형 장난감", "Toy Nutcracker");
Add("시험관", "Test Tube");
Add("시험관 랙", "Test Tube Rack");
Add("호두까기 인형 눈", "Nutcracker Eye");
Add("파란색 시험관", "Blue Test Tube");
Add("노란색 시험관", "Yellow Test Tube");
Add("빨간색 시험관", "Red Test Tube");
Add("초록색 시험관", "Green Test Tube");
Add("쇠지렛대", "Crowbar");
Add("플젠", "Plzen");
Add("컵", "Cup");
Add("전자레인지", "Microwave");
Add("hyper acid 실험 기록", "Experiment Log Hyper Acid");
Add("희극 가면 실험 기록", "Experiment Log Comedy Mask");
Add("저주받은 동전 실험 기록", "Experiment Log Cursed Coin");
Add("바이오 hxnv7 실험 기록", "Experiment Log BIO HXNV7");
Add("파란색 폴더", "Blue Folder");
Add("빨간색 폴더", "Red Folder");
Add("코일", "Coil");
Add("타자기", "Typewriter");
Add("서류 더미", "Documents");
Add("스테이플러", "Stapler");
Add("구식 컴퓨터", "Old Computer");
Add("브론즈 트로피", "Bronze Trophy");
Add("바나나", "Banana");
Add("스턴봉", "Stun Baton");
Add("바이오-hxnv7", "BIO-HXNV7");
Add("복구된 비밀 일지", "Recovered Secret Log");
Add("황금 단검 실험 기록", "Experiment Log Golden Dagger");
Add("대합", "Clam");
Add("거북이 등딱지", "Turtle Shell");
Add("생선 뼈", "Fish Bones");
Add("뿔 달린 껍질", "Horned Shell");
Add("도자기 찻잔", "Porcelain Teacup");
Add("대리석", "Marble");
Add("도자기 병", "Porcelain Bottle");
Add("도자기 향수 병", "Porcelain Perfume Bottle");
Add("발광구", "Glowing Orb");
Add("황금 해골", "Golden Skull");
Add("코스모코스 지도", "Map of Cosmocos");
Add("젖은 노트 1", "Wet Note 1");
Add("젖은 노트 2", "Wet Note 2");
Add("젖은 노트 3", "Wet Note 3");
Add("젖은 노트 4", "Wet Note 4");
Add("우주빛 파편", "Cosmic Shard");
Add("우주 생장물", "Cosmic Growth");
Add("천상의 두뇌 덩어리", "Chunk of Celestial Brain");
Add("파편이 든 양동이", "Bucket of Shards");
Add("우주빛 손전등", "Cosmic Flashlight");
Add("잊혀진 일지 1", "Forgotten Log 1");
Add("잊혀진 일지 2", "Forgotten Log 2");
Add("잊혀진 일지 3", "Forgotten Log 3");
Add("안경", "Glasses");
Add("생장한 배양 접시", "Grown Petri Dish");
Add("배양 접시", "Petri Dish");
Add("코스모채드", "Cosmochad");
Add("죽어가는 우주빛 손전등", "Dying Cosmic Flashlight");
Add("죽어가는 우주 생장물", "Dying Cosmic Growth");
Add("혈액 배양 접시", "Blood Petri Dish");
Add("악마 코스모채드", "Evil Cosmochad");
Add("악마 코스모", "Evil Cosmo");
Add("릴 코스모", "Lil Cosmo");
Add("죽어가는 생장물 배양 접시", "Dying Grown Petri Dish");
Add("감시하는 배양 접시", "Watching Petri Dish");
Add("현미경", "Microscope");
Add("원통형 바일", "Round Vile");
Add("사각형 바일", "Square Vile");
Add("타원형 바일", "Oval Vile");
Add("해링턴 일지 1", "Harrington Log 1");
Add("해링턴 일지 2", "Harrington Log 2");
Add("해링턴 일지 3", "Harrington Log 3");
Add("해링턴 일지 4", "Harrington Log 4");
Add("생장물이 든 병", "Jar of Growth");
Add("테이프 플레이어 일지 1", "Tape Player Log 1");
Add("테이프 플레이어 일지 2", "Tape Player Log 2");
Add("테이프 플레이어 일지 3", "Tape Player Log 3");
Add("테이프 플레이어 일지 4", "Tape Player Log 4");
Add("쇼핑 카트", "Shopping Cart");
return d;
void Add(string localized, string canonical)
{
string text = NormalizeKeyNoAlias(localized);
string value = NormalizeKeyNoAlias(canonical);
if (!string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(value) && !d.ContainsKey(text))
{
d.Add(text, value);
}
}
void AddAliases(string canonicalKey, params string[] aliases)
{
Add(canonicalKey, canonicalKey);
if (aliases != null)
{
foreach (string localized2 in aliases)
{
Add(localized2, canonicalKey);
}
}
}
}
public static string NormalizeName(string s)
{
string text = NormalizeKeyNoAlias(s);
string value;
return NameAliases.TryGetValue(text, out value) ? value : text;
}
public static string Name(this GrabbableObject item)
{
return NormalizeName(item.itemProperties.itemName);
}
public static string Name(this Item item)
{
return NormalizeName(item.itemName);
}
}
[HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")]
internal static class GrabPatch
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Expected O, but got Unknown
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Expected O, but got Unknown
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Expected O, but got Unknown
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Expected O, but got Unknown
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Expected O, but got Unknown
//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Expected O, but got Unknown
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Expected O, but got Unknown
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)list, ilGenerator);
CodeInstruction val2 = null;
MethodInfo methodInfo = AccessTools.Method(typeof(NetworkBehaviour), "get_NetworkObject", (Type[])null, (Type[])null);
for (int i = 0; i < list.Count - 1; i++)
{
CodeInstruction val3 = list[i];
if (val3.opcode == OpCodes.Callvirt && val3.operand is MethodInfo methodInfo2 && methodInfo2 == methodInfo)
{
CodeInstruction val4 = list[i + 1];
if (IsStloc(val4.opcode))
{
val2 = val4.Clone();
break;
}
}
}
if (val2 == null)
{
val2 = new CodeInstruction(OpCodes.Stloc_0, (object)null);
}
Label label = default(Label);
return val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(GrabbableObject), "InteractItem", (Type[])null, (Type[])null), (string)null)
}).MatchBack(true, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null)
}).Insert((CodeInstruction[])(object)new CodeInstruction[4]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(PlayerControllerB), "currentlyGrabbingObject")),
new CodeInstruction(OpCodes.Callvirt, (object)methodInfo),
val2
})
.ThrowIfInvalid("QuickSort: BeginGrabObject pattern not found (InteractItem)")
.CreateLabel(ref label)
.Start()
.Insert((CodeInstruction[])(object)new CodeInstruction[2]
{
new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Player), "OverrideGrabbingObject", (Type[])null, (Type[])null)),
new CodeInstruction(OpCodes.Brtrue, (object)label)
})
.InstructionEnumeration();
}
private static bool IsStloc(OpCode op)
{
return op == OpCodes.Stloc || op == OpCodes.Stloc_S || op == OpCodes.Stloc_0 || op == OpCodes.Stloc_1 || op == OpCodes.Stloc_2 || op == OpCodes.Stloc_3;
}
}
internal static class InteractionLockPatch
{
[HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")]
[HarmonyPrefix]
private static bool BlockBeginGrabObject()
{
if (!Sorter.IsInteractionLocked)
{
return true;
}
if (Sorter.IsInteractionBypassActive)
{
return true;
}
return false;
}
[HarmonyPatch(typeof(PlayerControllerB), "DiscardHeldObject")]
[HarmonyPrefix]
private static bool BlockDiscardHeldObject()
{
if (!Sorter.IsInteractionLocked)
{
return true;
}
if (Sorter.IsInteractionBypassActive)
{
return true;
}
return false;
}
}
public class Log
{
private static ManualLogSource _log;
public static void Init(ManualLogSource log)
{
_log = log;
}
public static void NotifyPlayer(string header, string body = "", bool isWarning = false)
{
if ((Object)(object)HUDManager.Instance != (Object)null)
{
HUDManager.Instance.DisplayTip(header, body, isWarning, false, "LC_Tip1");
}
Debug(header);
Debug(body);
}
public static void Chat(string body, string color = "FFFFFF")
{
if ((Object)(object)HUDManager.Instance != (Object)null)
{
HUDManager.Instance.AddChatMessage("<color=#" + color + ">[Pasta] " + body + "</color>", "", -1, false);
}
Debug(body);
}
public static void ConfirmSound()
{
if ((Object)(object)HUDManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance != (Object)null)
{
HUDManager.Instance.UIAudio.PlayOneShot(GameNetworkManager.Instance.buttonTuneSFX);
}
}
public static void Exception(Exception e)
{
string message = e.Message;
string stackTrace = e.StackTrace;
_log.LogError((object)message);
_log.LogError((object)stackTrace);
}
public static void Error(params object[] objects)
{
_log.LogError((object)string.Join(" ", objects));
}
public static void Warning(params object[] objects)
{
_log.LogWarning((object)string.Join(" ", objects));
}
public static void Info(params object[] objects)
{
_log.LogInfo((object)string.Join(" ", objects));
}
public static void Debug(params object[] objects)
{
_log.LogDebug((object)string.Join(" ", objects));
}
}
internal static class MoveUtils
{
private static bool ShouldAvoidHeldSideEffects(PlayerControllerB player, GrabbableObject targetItem)
{
if ((Object)(object)player == (Object)null)
{
return true;
}
if ((Object)(object)targetItem == (Object)null)
{
return true;
}
GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer;
return (Object)(object)currentlyHeldObjectServer != (Object)null && (Object)(object)currentlyHeldObjectServer != (Object)(object)targetItem;
}
public static bool MoveItemOnShip(GrabbableObject item, Vector3 worldPos, int floorYRot = -1)
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)item == (Object)null)
{
return false;
}
PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
if ((Object)(object)val == (Object)null)
{
return false;
}
GameObject val2 = GameObject.Find("Environment/HangarShip");
if ((Object)(object)val2 == (Object)null)
{
return false;
}
Vector3 val3 = val2.transform.InverseTransformPoint(worldPos);
((Component)item).transform.position = worldPos;
if (!ShouldAvoidHeldSideEffects(val, item))
{
val.SetObjectAsNoLongerHeld(true, true, val3, item, floorYRot);
}
val.ThrowObjectServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)item).NetworkObject), true, true, val3, floorYRot);
return true;
}
public static bool MoveItemOnShipLocal(GrabbableObject item, Vector3 shipLocalPos, int floorYRot = -1)
{
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)item == (Object)null)
{
return false;
}
PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
if ((Object)(object)val == (Object)null)
{
return false;
}
GameObject val2 = GameObject.Find("Environment/HangarShip");
if ((Object)(object)val2 == (Object)null)
{
return false;
}
((Component)item).transform.position = val2.transform.TransformPoint(shipLocalPos);
try
{
if (!ShouldAvoidHeldSideEffects(val, item))
{
val.SetObjectAsNoLongerHeld(true, true, shipLocalPos, item, floorYRot);
}
}
catch
{
}
try
{
val.PlaceGrabbableObject(val2.transform, shipLocalPos, false, item);
val.PlaceObjectServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)item).NetworkObject), NetworkObjectReference.op_Implicit(val2), shipLocalPos, false);
}
catch
{
try
{
val.ThrowObjectServerRpc(NetworkObjectReference.op_Implicit(((NetworkBehaviour)item).NetworkObject), true, true, shipLocalPos, floorYRot);
}
catch
{
return false;
}
}
return true;
}
public static bool TryTeleportToWorld(GameObject go, Vector3 worldPos, Quaternion worldRot)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
GrabbableObject val = (((Object)(object)go != (Object)null) ? go.GetComponent<GrabbableObject>() : null);
if ((Object)(object)val != (Object)null)
{
return MoveItemOnShip(val, worldPos, val.floorYRot);
}
if ((Object)(object)go == (Object)null)
{
return false;
}
go.transform.SetPositionAndRotation(worldPos, worldRot);
return true;
}
}
public static class Player
{
[CompilerGenerated]
private sealed class <StartGrabbingObject>d__5 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public GrabbableObject grabbableObject;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <StartGrabbingObject>d__5(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if (CanGrabObject(grabbableObject))
{
overrideObject = grabbableObject;
Local.BeginGrabObject();
<>2__current = Local.grabObjectCoroutine;
<>1__state = 1;
return true;
}
break;
case 1:
<>1__state = -1;
break;
}
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();
}
}
[CompilerGenerated]
private sealed class <StartMovingObject>d__6 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public GrabbableObject item;
public Vector3 position;
public NetworkObject parent;
private int <frames>5__1;
private Exception <e>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <StartMovingObject>d__6(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<e>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = StartGrabbingObject(item);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if ((Object)(object)Local == (Object)null)
{
return false;
}
<frames>5__1 = 0;
break;
case 2:
<>1__state = -1;
break;
}
if (<frames>5__1 < 30 && ((Object)(object)Local.currentlyHeldObjectServer == (Object)null || (Object)(object)Local.currentlyHeldObjectServer != (Object)(object)item))
{
<frames>5__1++;
<>2__current = null;
<>1__state = 2;
return true;
}
if ((Object)(object)Local.currentlyHeldObjectServer == (Object)null || (Object)(object)Local.currentlyHeldObjectServer != (Object)(object)item)
{
Log.Warning("Failed to grab " + (item?.itemProperties?.itemName ?? "item") + "; skipping move to avoid crash.");
return false;
}
try
{
item.floorYRot = -1;
Local.DiscardHeldObject(true, parent, position, false);
}
catch (Exception ex)
{
<e>5__2 = ex;
Log.Exception(<e>5__2);
}
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();
}
}
public static GrabbableObject overrideObject;
public static PlayerControllerB Local => StartOfRound.Instance?.localPlayerController;
public static bool CanGrabObject(GrabbableObject item)
{
if ((Object)(object)item == (Object)null || !item.grabbable || item.deactivated || item.isHeld || item.isPocketed)
{
return false;
}
if ((Object)(object)Local == (Object)null || Local.isPlayerDead || Local.isTypingChat || Local.inTerminalMenu || Local.throwingObject || Local.IsInspectingItem || Local.isGrabbingObjectAnimation || (Object)(object)Local.inAnimationWithEnemy != (Object)null || Local.inSpecialInteractAnimation || Local.jetpackControls || Local.disablingJetpackControls || Local.activatingItem || Local.waitingToDropItem || Local.FirstEmptyItemSlot((GrabbableObject)null) == -1)
{
return false;
}
return true;
}
public static bool OverrideGrabbingObject()
{
if ((Object)(object)overrideObject == (Object)null)
{
return false;
}
Local.currentlyGrabbingObject = overrideObject;
overrideObject = null;
return true;
}
[IteratorStateMachine(typeof(<StartGrabbingObject>d__5))]
public static IEnumerator StartGrabbingObject(GrabbableObject grabbableObject)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <StartGrabbingObject>d__5(0)
{
grabbableObject = grabbableObject
};
}
[IteratorStateMachine(typeof(<StartMovingObject>d__6))]
public static IEnumerator StartMovingObject(GrabbableObject item, Vector3 position, NetworkObject? parent = null)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <StartMovingObject>d__6(0)
{
item = item,
position = position,
parent = parent
};
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("pasta.quicksort", "QuickSort", "0.1.8")]
public class Plugin : BaseUnityPlugin
{
private const string CurrentConfigSchemaVersion = "0.1.8";
public static ManualLogSource Log;
public static ConfigFile config;
public static ConfigEntry<string> configVersion;
private static Harmony harmony;
public static GameObject sorterObject;
private static bool applicationIsQuitting;
public static Plugin Instance { get; private set; }
private void Awake()
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected O, but got Unknown
//IL_0388: Unknown result type (might be due to invalid IL or missing references)
//IL_0392: Expected O, but got Unknown
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Expected O, but got Unknown
//IL_0283: Unknown result type (might be due to invalid IL or missing references)
//IL_028d: Expected O, but got Unknown
applicationIsQuitting = false;
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
config = ((BaseUnityPlugin)this).Config;
bool flag = File.Exists(config.ConfigFilePath);
ConfigEntry<string> val = default(ConfigEntry<string>);
bool flag2 = config.TryGetEntry<string>(new ConfigDefinition("General", "configVersion"), ref val);
configVersion = config.Bind<string>("General", "configVersion", "0.1.8", "Config schema version (used for internal migrations).");
bool flag3 = false;
string text = configVersion.Value ?? "";
if (string.IsNullOrWhiteSpace(text))
{
text = "0.0.0";
configVersion.Value = text;
flag3 = true;
}
bool flag4 = flag && (!flag2 || IsVersionLessThan(text, "0.1.8"));
if (flag4 && (!flag2 || IsVersionLessThan(text, "0.1.5")))
{
ConfigEntry<float> val2 = config.Bind<float>("Sorter", "sortOriginY", 0.1f, "Y coordinate of the origin position for sorting items (relative to ship)");
if (Mathf.Abs(val2.Value - 0.5f) < 0.0001f)
{
val2.Value = 0.1f;
flag3 = true;
}
ConfigEntry<string> val3 = config.Bind<string>("Sorter", "skippedItems", "body, clipboard, sticky_note, boombox, shovel, jetpack, flashlight, pro_flashlight, key, stun_grenade, lockpicker, mapper, extension_ladder, tzp_inhalant, walkie_talkie, zap_gun, kitchen_knife, weed_killer, radar_booster, spray_paint, belt_bag, shotgun, ammo", "Global skip list (comma-separated, substring match). Applies to all grabbable items.");
string text2 = AddTokensToCommaList(val3.Value, "shotgun", "ammo");
if (!string.Equals(text2, val3.Value, StringComparison.Ordinal))
{
val3.Value = text2;
flag3 = true;
}
}
ConfigEntry<string> val4 = default(ConfigEntry<string>);
if (flag4 && (!flag2 || IsVersionLessThan(text, "0.1.7")) && config.TryGetEntry<string>(new ConfigDefinition("Sorter", "skippedItems"), ref val4) && IsOnlyShotgunAmmo(val4.Value))
{
val4.Value = "body, clipboard, sticky_note, boombox, shovel, jetpack, flashlight, pro_flashlight, key, stun_grenade, lockpicker, mapper, extension_ladder, tzp_inhalant, walkie_talkie, zap_gun, kitchen_knife, weed_killer, radar_booster, spray_paint, belt_bag, shotgun, ammo";
flag3 = true;
}
if (flag4 && !string.Equals(configVersion.Value, "0.1.8", StringComparison.Ordinal))
{
configVersion.Value = "0.1.8";
flag3 = true;
}
if (flag3)
{
config.Save();
}
QuickSort.Log.Init(((BaseUnityPlugin)this).Logger);
QuickSort.Log.Info("QuickSort - Item Sorter loading...");
SortShortcuts.EnsureFileExists();
SortPositions.EnsureFileExists();
harmony = new Harmony("pasta.quicksort");
harmony.PatchAll(typeof(Ship));
harmony.PatchAll(typeof(Startup));
harmony.PatchAll(typeof(GrabPatch));
harmony.PatchAll(typeof(InteractionLockPatch));
try
{
new SortCommand();
new SortBindCommand();
new SortSetCommand();
new SortResetCommand();
new SortPositionsCommand();
new SortBindingsListCommand();
new SortSkipCommand();
new PileCommand();
QuickSort.Log.Info("Sort command registered in Awake");
}
catch (Exception ex)
{
QuickSort.Log.Error("Failed to register sort command in Awake: " + ex.Message);
QuickSort.Log.Error("Stack trace: " + ex.StackTrace);
}
try
{
if ((Object)(object)sorterObject == (Object)null)
{
sorterObject = new GameObject("PastaSorter");
sorterObject.AddComponent<Sorter>();
Object.DontDestroyOnLoad((Object)(object)sorterObject);
QuickSort.Log.Info("Sorter initialized in Awake");
}
}
catch (Exception ex2)
{
QuickSort.Log.Error("Failed to initialize Sorter in Awake: " + ex2.Message);
QuickSort.Log.Error("Stack trace: " + ex2.StackTrace);
}
QuickSort.Log.Info("QuickSort - Item Sorter loaded!");
}
private void OnDestroy()
{
if (Instance == this)
{
Instance = null;
}
if (!applicationIsQuitting)
{
QuickSort.Log.Warning("Plugin OnDestroy fired before application quit; skipping cleanup to avoid self-unpatching.");
return;
}
if (harmony != null)
{
harmony.UnpatchSelf();
}
if ((Object)(object)sorterObject != (Object)null)
{
Object.Destroy((Object)(object)sorterObject);
}
}
private void OnApplicationQuit()
{
applicationIsQuitting = true;
}
private static bool IsVersionLessThan(string a, string b)
{
int[] array = Parse(a);
int[] array2 = Parse(b);
for (int i = 0; i < 3; i++)
{
if (array[i] < array2[i])
{
return true;
}
if (array[i] > array2[i])
{
return false;
}
}
return false;
static int[] Parse(string s)
{
if (string.IsNullOrWhiteSpace(s))
{
return new int[3];
}
string[] array3 = s.Trim().Split('.');
int[] array4 = new int[3];
for (int j = 0; j < 3; j++)
{
if (j < array3.Length && int.TryParse(array3[j], out var result))
{
array4[j] = result;
}
else
{
array4[j] = 0;
}
}
return array4;
}
}
private static string AddTokensToCommaList(string? list, params string[] tokensToAdd)
{
List<string> tokens = new List<string>();
HashSet<string> seen = new HashSet<string>();
if (!string.IsNullOrWhiteSpace(list))
{
string[] array = list.Split(',');
foreach (string raw2 in array)
{
Add(raw2);
}
}
if (tokensToAdd != null)
{
foreach (string raw3 in tokensToAdd)
{
Add(raw3);
}
}
return string.Join(", ", tokens);
void Add(string raw)
{
string text = (raw ?? "").Trim();
if (!string.IsNullOrWhiteSpace(text))
{
text = Extensions.NormalizeName(text).Trim('_');
if (!string.IsNullOrWhiteSpace(text) && seen.Add(text))
{
tokens.Add(text);
}
}
}
}
private static bool IsOnlyShotgunAmmo(string? list)
{
HashSet<string> seen = new HashSet<string>();
if (!string.IsNullOrWhiteSpace(list))
{
string[] array = list.Split(',');
foreach (string raw2 in array)
{
Add(raw2);
}
}
return seen.Count == 2 && seen.Contains("shotgun") && seen.Contains("ammo");
void Add(string raw)
{
string text = (raw ?? "").Trim();
if (!string.IsNullOrWhiteSpace(text))
{
text = Extensions.NormalizeName(text).Trim('_');
if (!string.IsNullOrWhiteSpace(text))
{
seen.Add(text);
}
}
}
}
}
public static class Startup
{
private static bool commandRegistered;
[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
[HarmonyPostfix]
private static void OnLocalPlayerCreated(PlayerControllerB __instance)
{
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Expected O, but got Unknown
if ((Object)(object)__instance != (Object)(object)StartOfRound.Instance.localPlayerController)
{
return;
}
if (!commandRegistered)
{
try
{
new SortCommand();
new SortBindCommand();
new SortSetCommand();
new SortResetCommand();
new SortPositionsCommand();
new SortBindingsListCommand();
new SortSkipCommand();
new PileCommand();
commandRegistered = true;
Log.Info("Sort command registered");
}
catch (Exception ex)
{
Log.Error("Failed to register sort command: " + ex.Message);
}
}
if ((Object)(object)Plugin.sorterObject != (Object)null)
{
Object.Destroy((Object)(object)Plugin.sorterObject);
}
Plugin.sorterObject = new GameObject("PastaSorter");
Plugin.sorterObject.AddComponent<Sorter>();
Object.DontDestroyOnLoad((Object)(object)Plugin.sorterObject);
}
}
public static class Ship
{
public static Action OnShipOrbit;
public static Action OnShipTouchdown;
public static Action OnShipAscent;
public static Action OnShipDescent;
private static readonly Dictionary<string, FieldInfo?> _startOfRoundBoolFields = new Dictionary<string, FieldInfo>();
private static readonly Dictionary<string, PropertyInfo?> _startOfRoundBoolProps = new Dictionary<string, PropertyInfo>();
private static readonly Dictionary<string, MemberInfo?> _startOfRoundBoolFuzzy = new Dictionary<string, MemberInfo>();
public static bool Stationary
{
get
{
if (GetStartOfRoundBool("shipHasLanded", "ShipHasLanded", "hasLanded", "HasLanded").GetValueOrDefault())
{
return true;
}
if (GetStartOfRoundBool("inShipPhase", "InShipPhase", "shipPhase", "ShipPhase").GetValueOrDefault() && !GetStartOfRoundBool("shipIsLeaving", "ShipIsLeaving", "isShipLeaving", "IsShipLeaving", "shipLeaving").GetValueOrDefault())
{
return true;
}
return false;
}
}
public static bool CanSortNow
{
get
{
if (GetStartOfRoundBool("shipHasLanded", "ShipHasLanded", "hasLanded", "HasLanded").GetValueOrDefault())
{
return true;
}
if (GetStartOfRoundBool("inShipPhase", "InShipPhase", "shipPhase", "ShipPhase").GetValueOrDefault())
{
return true;
}
return InOrbit || Stationary;
}
}
public static bool InOrbit => GetStartOfRoundBool("inShipPhase", "InShipPhase", "shipPhase", "ShipPhase").GetValueOrDefault() && !GetStartOfRoundBool("shipHasLanded", "ShipHasLanded", "hasLanded", "HasLanded").GetValueOrDefault();
public static bool IsCompanyLevel => CurrentLevelTextContains("Gordion", "Company", "CompanyBuilding");
public static bool ShouldSortAllDetectedItems => InOrbit || IsCompanyLevel;
private static bool? GetStartOfRoundBoolExact(string name)
{
StartOfRound instance = StartOfRound.Instance;
if ((Object)(object)instance == (Object)null)
{
return null;
}
Type type = ((object)instance).GetType();
if (!_startOfRoundBoolFields.TryGetValue(name, out FieldInfo value))
{
value = AccessTools.Field(type, name);
_startOfRoundBoolFields[name] = value;
}
if (value != null)
{
try
{
object value2 = value.GetValue(instance);
if (value2 is bool)
{
bool value3 = (bool)value2;
if (true)
{
return value3;
}
}
}
catch
{
}
}
if (!_startOfRoundBoolProps.TryGetValue(name, out PropertyInfo value4))
{
value4 = AccessTools.Property(type, name);
_startOfRoundBoolProps[name] = value4;
}
if (value4 != null && value4.PropertyType == typeof(bool) && value4.GetIndexParameters().Length == 0)
{
try
{
object value2 = value4.GetValue(instance, null);
if (value2 is bool)
{
bool value5 = (bool)value2;
if (true)
{
return value5;
}
}
}
catch
{
}
}
return null;
}
private static bool? GetStartOfRoundBoolFuzzy(string containsOrAltName)
{
StartOfRound instance = StartOfRound.Instance;
if ((Object)(object)instance == (Object)null)
{
return null;
}
Type type = ((object)instance).GetType();
if (!_startOfRoundBoolFuzzy.TryGetValue(containsOrAltName, out MemberInfo value))
{
string needle = containsOrAltName;
FieldInfo fieldInfo = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((FieldInfo f) => f.FieldType == typeof(bool) && string.Equals(f.Name, needle, StringComparison.OrdinalIgnoreCase));
if (fieldInfo != null)
{
value = fieldInfo;
}
else
{
PropertyInfo propertyInfo = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((PropertyInfo p) => p.PropertyType == typeof(bool) && p.GetIndexParameters().Length == 0 && string.Equals(p.Name, needle, StringComparison.OrdinalIgnoreCase));
value = propertyInfo;
}
if (value == null)
{
FieldInfo fieldInfo2 = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((FieldInfo f) => f.FieldType == typeof(bool) && f.Name.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0);
if (fieldInfo2 != null)
{
value = fieldInfo2;
}
else
{
PropertyInfo propertyInfo2 = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((PropertyInfo p) => p.PropertyType == typeof(bool) && p.GetIndexParameters().Length == 0 && p.Name.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0);
value = propertyInfo2;
}
}
_startOfRoundBoolFuzzy[containsOrAltName] = value;
}
try
{
if (value is FieldInfo fieldInfo3 && fieldInfo3.FieldType == typeof(bool))
{
return (bool)fieldInfo3.GetValue(instance);
}
if (value is PropertyInfo propertyInfo3 && propertyInfo3.PropertyType == typeof(bool) && propertyInfo3.GetIndexParameters().Length == 0)
{
return (bool)propertyInfo3.GetValue(instance, null);
}
}
catch
{
}
return null;
}
private static bool? GetStartOfRoundBool(params string[] candidates)
{
foreach (string text in candidates)
{
if (!string.IsNullOrWhiteSpace(text))
{
bool? startOfRoundBoolExact = GetStartOfRoundBoolExact(text);
if (startOfRoundBoolExact.HasValue)
{
return startOfRoundBoolExact;
}
}
}
foreach (string text2 in candidates)
{
if (!string.IsNullOrWhiteSpace(text2))
{
bool? startOfRoundBoolFuzzy = GetStartOfRoundBoolFuzzy(text2);
if (startOfRoundBoolFuzzy.HasValue)
{
return startOfRoundBoolFuzzy;
}
}
}
return null;
}
private static object? GetCurrentLevel()
{
StartOfRound instance = StartOfRound.Instance;
if ((Object)(object)instance == (Object)null)
{
return null;
}
Type type = ((object)instance).GetType();
try
{
FieldInfo fieldInfo = type.GetField("currentLevel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("CurrentLevel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (fieldInfo != null)
{
return fieldInfo.GetValue(instance);
}
PropertyInfo propertyInfo = type.GetProperty("currentLevel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetProperty("CurrentLevel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (propertyInfo != null && propertyInfo.GetIndexParameters().Length == 0)
{
return propertyInfo.GetValue(instance, null);
}
}
catch
{
}
return null;
}
private static bool CurrentLevelTextContains(params string[] needles)
{
object currentLevel = GetCurrentLevel();
if (currentLevel == null)
{
return false;
}
try
{
Type type = currentLevel.GetType();
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
string value = null;
if (fieldInfo.FieldType == typeof(string))
{
value = fieldInfo.GetValue(currentLevel) as string;
}
else if (fieldInfo.FieldType == typeof(int) && string.Equals(fieldInfo.Name, "levelID", StringComparison.OrdinalIgnoreCase))
{
value = fieldInfo.GetValue(currentLevel)?.ToString();
}
if (ContainsAny(value, needles))
{
return true;
}
}
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (PropertyInfo propertyInfo in properties)
{
if (propertyInfo.GetIndexParameters().Length == 0)
{
string value2 = null;
if (propertyInfo.PropertyType == typeof(string))
{
value2 = propertyInfo.GetValue(currentLevel, null) as string;
}
else if (propertyInfo.PropertyType == typeof(int) && string.Equals(propertyInfo.Name, "levelID", StringComparison.OrdinalIgnoreCase))
{
value2 = propertyInfo.GetValue(currentLevel, null)?.ToString();
}
if (ContainsAny(value2, needles))
{
return true;
}
}
}
}
catch
{
}
return false;
}
private static bool ContainsAny(string? value, string[] needles)
{
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
foreach (string value2 in needles)
{
if (!string.IsNullOrWhiteSpace(value2) && value.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
return false;
}
[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
[HarmonyPostfix]
[HarmonyWrapSafe]
public static void OnShipLeave()
{
OnShipAscent?.Invoke();
OnShipDescent?.Invoke();
}
[HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")]
[HarmonyPostfix]
[HarmonyWrapSafe]
public static void OnShipLanded()
{
OnShipTouchdown?.Invoke();
OnShipOrbit?.Invoke();
}
}
public class Sorter : MonoBehaviour
{
private sealed class DisposeAction : IDisposable
{
private readonly Action _onDispose;
private bool _disposed;
public DisposeAction(Action onDispose)
{
_onDispose = onDispose;
}
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
_onDispose?.Invoke();
}
}
}
[CompilerGenerated]
private sealed class <DropHeldItemIfAny>d__37 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public GameObject ship;
public Sorter <>4__this;
private PlayerControllerB <player>5__1;
private GrabbableObject <held>5__2;
private NetworkObject <shipNetObj>5__3;
private Vector3 <dropLocal>5__4;
private float <groundYLocal>5__5;
private int <frames>5__6;
private float <vOff>5__7;
private IDisposable <>s__8;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DropHeldItemIfAny>d__37(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<player>5__1 = null;
<held>5__2 = null;
<shipNetObj>5__3 = null;
<>s__8 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
{
<>1__state = -1;
<player>5__1 = Player.Local;
if ((Object)(object)<player>5__1 == (Object)null)
{
return false;
}
<held>5__2 = <player>5__1.currentlyHeldObjectServer;
if ((Object)(object)<held>5__2 == (Object)null)
{
return false;
}
<shipNetObj>5__3 = (((Object)(object)ship != (Object)null) ? ship.GetComponent<NetworkObject>() : null);
<dropLocal>5__4 = ship.transform.InverseTransformPoint(((Component)<player>5__1).transform.position + ((Component)<player>5__1).transform.forward * 0.75f);
if (<>4__this.TryGetGroundYLocalAt(<dropLocal>5__4, out <groundYLocal>5__5, out string _))
{
<vOff>5__7 = 0f;
try
{
if ((Object)(object)<held>5__2.itemProperties != (Object)null)
{
<vOff>5__7 = <held>5__2.itemProperties.verticalOffset - 0.05f;
}
}
catch
{
}
<dropLocal>5__4.y = <groundYLocal>5__5 + <vOff>5__7;
}
<>s__8 = BeginInteractionBypass();
try
{
<held>5__2.floorYRot = -1;
<player>5__1.DiscardHeldObject(true, <shipNetObj>5__3, <dropLocal>5__4, false);
}
finally
{
if (<>s__8 != null)
{
<>s__8.Dispose();
}
}
<>s__8 = null;
<frames>5__6 = 0;
break;
}
case 1:
<>1__state = -1;
break;
}
if (<frames>5__6 < 30 && (Object)(object)<player>5__1.currentlyHeldObjectServer != (Object)null)
{
<frames>5__6++;
<>2__current = null;
<>1__state = 1;
return true;
}
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();
}
}
[CompilerGenerated]
private sealed class <GrabbableRetry>d__52 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public GrabbableObject item;
public Sorter <>4__this;
private int <retry>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <GrabbableRetry>d__52(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;
<retry>5__1 = 15;
break;
case 1:
<>1__state = -1;
<retry>5__1--;
break;
}
if (!Player.CanGrabObject(item) && <retry>5__1 > 0)
{
<>2__current = (object)new WaitForEndOfFrame();
<>1__state = 1;
return true;
}
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();
}
}
[CompilerGenerated]
private sealed class <MoveItemsOfTypeToPosition>d__48 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public string itemKey;
public Vector3 targetCenterShipLocal;
public bool force;
public bool announce;
public bool ignoreSkipLists;
public bool applyTwoHandedSortYOffset;
public bool dropHeldFirst;
public Sorter <>4__this;
private GameObject <ship>5__1;
private Dictionary<string, List<GrabbableObject>> <groupedItems>5__2;
private List<GrabbableObject> <items>5__3;
private Vector3 <pileCenterLocal>5__4;
private float <extraYOffset>5__5;
private float <groundYLocal>5__6;
private GrabbableObject <held>5__7;
private List<GrabbableObject> <itemsToMove>5__8;
private int <moved>5__9;
private GrabbableObject <heldBeforeDrop>5__10;
private List<GrabbableObject>.Enumerator <>s__11;
private GrabbableObject <item>5__12;
private string <name>5__13;
private List<GrabbableObject> <list>5__14;
private Vector3 <rayStartCenter>5__15;
private RaycastHit <hitCenter>5__16;
private int <stackIndex>5__17;
private GrabbableObject <item>5__18;
private float <pileX>5__19;
private float <pileZ>5__20;
private float <pileY>5__21;
private Vector3 <targetLocal>5__22;
private Vector3 <worldPos>5__23;
private int <cols>5__24;
private int <rows>5__25;
private int <perLayer>5__26;
private int <layer>5__27;
private int <inLayer>5__28;
private int <r>5__29;
private int <c>5__30;
private int <retry>5__31;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <MoveItemsOfTypeToPosition>d__48(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<ship>5__1 = null;
<groupedItems>5__2 = null;
<items>5__3 = null;
<held>5__7 = null;
<itemsToMove>5__8 = null;
<heldBeforeDrop>5__10 = null;
<>s__11 = default(List<GrabbableObject>.Enumerator);
<item>5__12 = null;
<name>5__13 = null;
<list>5__14 = null;
<item>5__18 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_07b6: Unknown result type (might be due to invalid IL or missing references)
//IL_0821: Unknown result type (might be due to invalid IL or missing references)
//IL_082b: Expected O, but got Unknown
//IL_0664: Unknown result type (might be due to invalid IL or missing references)
//IL_0669: Unknown result type (might be due to invalid IL or missing references)
//IL_067b: Unknown result type (might be due to invalid IL or missing references)
//IL_0680: Unknown result type (might be due to invalid IL or missing references)
//IL_0685: Unknown result type (might be due to invalid IL or missing references)
//IL_0693: Unknown result type (might be due to invalid IL or missing references)
//IL_06a3: Unknown result type (might be due to invalid IL or missing references)
//IL_0345: Unknown result type (might be due to invalid IL or missing references)
//IL_034a: Unknown result type (might be due to invalid IL or missing references)
//IL_037f: Unknown result type (might be due to invalid IL or missing references)
//IL_0384: Unknown result type (might be due to invalid IL or missing references)
//IL_038e: Unknown result type (might be due to invalid IL or missing references)
//IL_0393: Unknown result type (might be due to invalid IL or missing references)
//IL_0398: Unknown result type (might be due to invalid IL or missing references)
//IL_039d: Unknown result type (might be due to invalid IL or missing references)
//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
//IL_06ff: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
inProgress = true;
if (announce)
{
Log.Chat("Moving '" + itemKey + "' to your position... Press [Escape] to cancel", "FFFF00");
}
if ((Object)(object)Player.Local == (Object)null)
{
Log.NotifyPlayer("Sorter Error", "Local player not ready yet", isWarning: true);
inProgress = false;
return false;
}
<ship>5__1 = GameObject.Find("Environment/HangarShip");
if ((Object)(object)<ship>5__1 == (Object)null)
{
Log.NotifyPlayer("Sorter Error", "Ship not found", isWarning: true);
inProgress = false;
return false;
}
if (dropHeldFirst)
{
<heldBeforeDrop>5__10 = Player.Local.currentlyHeldObjectServer;
<>2__current = <>4__this.DropHeldItemIfAny(<ship>5__1);
<>1__state = 1;
return true;
}
goto IL_01ca;
case 1:
<>1__state = -1;
<>4__this.CategorizeItems(includeSkippedItems: true);
if ((Object)(object)<heldBeforeDrop>5__10 != (Object)null && <heldBeforeDrop>5__10.Name() == itemKey && <heldBeforeDrop>5__10.isInShipRoom)
{
if (<>4__this.scrap == null)
{
<>4__this.scrap = new List<GrabbableObject>();
}
if (!<>4__this.scrap.Contains(<heldBeforeDrop>5__10))
{
<>4__this.scrap.Add(<heldBeforeDrop>5__10);
}
}
<heldBeforeDrop>5__10 = null;
goto IL_01ca;
case 2:
<>1__state = -1;
goto IL_0888;
case 3:
<>1__state = -1;
if (!(ignoreSkipLists ? <>4__this.ShouldSkipExplicitQuery(<item>5__18) : <>4__this.ShouldSkip(<item>5__18)))
{
<item>5__18.floorYRot = -1;
if (!MoveUtils.MoveItemOnShipLocal(<item>5__18, <targetLocal>5__22, <item>5__18.floorYRot))
{
Log.Warning("Failed to move " + (<item>5__18.itemProperties?.itemName ?? ((Object)<item>5__18).name));
}
<retry>5__31 = 15;
goto IL_084e;
}
goto IL_0880;
case 4:
{
<>1__state = -1;
<retry>5__31--;
goto IL_084e;
}
IL_089a:
if (<stackIndex>5__17 < <itemsToMove>5__8.Count)
{
<item>5__18 = <itemsToMove>5__8[<stackIndex>5__17];
if (<>4__this.ShouldBreak(<item>5__18))
{
Log.NotifyPlayer("Sorter Stopping", "Operation cancelled or ship is in motion", isWarning: true);
inProgress = false;
return false;
}
<pileX>5__19 = 0f;
<pileZ>5__20 = 0f;
if (<>4__this.stackSameTypeTogether.Value)
{
<pileY>5__21 = (float)<stackIndex>5__17 * Mathf.Max(0f, <>4__this.sameTypeStackStepY.Value);
}
else
{
<cols>5__24 = Mathf.Max(1, <>4__this.itemsPerRow.Value);
<rows>5__25 = <cols>5__24;
<perLayer>5__26 = <cols>5__24 * <rows>5__25;
<layer>5__27 = <stackIndex>5__17 / <perLayer>5__26;
<inLayer>5__28 = <stackIndex>5__17 % <perLayer>5__26;
<r>5__29 = <inLayer>5__28 / <cols>5__24;
<c>5__30 = <inLayer>5__28 % <cols>5__24;
<pileX>5__19 = ((float)<c>5__30 - (float)(<cols>5__24 - 1) / 2f) * 0.1f;
<pileZ>5__20 = ((float)<r>5__29 - (float)(<rows>5__25 - 1) / 2f) * 0.1f;
<pileY>5__21 = (float)<layer>5__27 * 0.07f;
}
<targetLocal>5__22 = new Vector3(<pileCenterLocal>5__4.x + <pileX>5__19, <groundYLocal>5__6 + (<item>5__18.itemProperties.verticalOffset - 0.05f) + <extraYOffset>5__5 + <pileY>5__21, <pileCenterLocal>5__4.z + <pileZ>5__20);
<worldPos>5__23 = <ship>5__1.transform.TransformPoint(<targetLocal>5__22);
if (!force && Vector3.Distance(<worldPos>5__23, ((Component)<item>5__18).transform.position) < 0.25f)
{
goto IL_0888;
}
if ((Object)(object)<held>5__7 != (Object)null && (Object)(object)<item>5__18 == (Object)(object)<held>5__7)
{
<item>5__18.floorYRot = -1;
MoveUtils.MoveItemOnShipLocal(<item>5__18, <targetLocal>5__22, <item>5__18.floorYRot);
<moved>5__9++;
<>2__current = null;
<>1__state = 2;
return true;
}
<>2__current = <>4__this.GrabbableRetry(<item>5__18);
<>1__state = 3;
return true;
}
Log.Chat($"Moved '{itemKey}' ({<moved>5__9} items)", "00FF00");
inProgress = false;
return false;
IL_084e:
if (!Player.CanGrabObject(<item>5__18) && <retry>5__31 > 0)
{
<>2__current = (object)new WaitForEndOfFrame();
<>1__state = 4;
return true;
}
<moved>5__9++;
goto IL_0880;
IL_01ca:
BeginOperationLock();
<groupedItems>5__2 = new Dictionary<string, List<GrabbableObject>>();
<>s__11 = <>4__this.scrap.GetEnumerator();
try
{
while (<>s__11.MoveNext())
{
<item>5__12 = <>s__11.Current;
if (!(ignoreSkipLists ? <>4__this.ShouldSkipExplicitQuery(<item>5__12) : <>4__this.ShouldSkip(<item>5__12)))
{
<name>5__13 = <item>5__12.Name();
if (!<groupedItems>5__2.TryGetValue(<name>5__13, out <list>5__14))
{
<list>5__14 = new List<GrabbableObject>();
<groupedItems>5__2[<name>5__13] = <list>5__14;
}
<list>5__14.Add(<item>5__12);
<name>5__13 = null;
<list>5__14 = null;
<item>5__12 = null;
}
}
}
finally
{
((IDisposable)<>s__11).Dispose();
}
<>s__11 = default(List<GrabbableObject>.Enumerator);
if (!<groupedItems>5__2.TryGetValue(itemKey, out <items>5__3) || <items>5__3.Count == 0)
{
<items>5__3 = new List<GrabbableObject>();
}
<pileCenterLocal>5__4 = new Vector3(targetCenterShipLocal.x, 0f, targetCenterShipLocal.z);
<extraYOffset>5__5 = targetCenterShipLocal.y;
<groundYLocal>5__6 = <pileCenterLocal>5__4.y;
<rayStartCenter>5__15 = <ship>5__1.transform.TransformPoint(<pileCenterLocal>5__4 + Vector3.up * 2f);
if (Physics.Raycast(<rayStartCenter>5__15, Vector3.down, ref <hitCenter>5__16, 80f, 268437761, (QueryTriggerInteraction)1))
{
<groundYLocal>5__6 = <ship>5__1.transform.InverseTransformPoint(((RaycastHit)(ref <hitCenter>5__16)).point).y;
}
<held>5__7 = (((Object)(object)Player.Local != (Object)null) ? Player.Local.currentlyHeldObjectServer : null);
<itemsToMove>5__8 = new List<GrabbableObject>(<items>5__3);
if ((Object)(object)<held>5__7 != (Object)null && <held>5__7.Name() == itemKey && !<itemsToMove>5__8.Contains(<held>5__7))
{
<itemsToMove>5__8.Insert(0, <held>5__7);
}
<moved>5__9 = 0;
<stackIndex>5__17 = 0;
goto IL_089a;
IL_0888:
<stackIndex>5__17++;
goto IL_089a;
IL_0880:
<item>5__18 = null;
goto IL_0888;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <SortItems>d__40 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public bool force;
public bool ignoreSkippedItems;
public bool includeSavedPositionTypesEvenIfSkipped;
public Sorter <>4__this;
private GameObject <ship>5__1;
private Vector3 <originLocal>5__2;
private HashSet<string> <savedTypes>5__3;
private List<(string itemKey, Vector3 shipLocalPos)> <savedPositions>5__4;
private string <posListError>5__5;
private Dictionary<string, List<GrabbableObject>> <groupedItems>5__6;
private List<KeyValuePair<string, List<GrabbableObject>>> <orderedGroups>5__7;
private List<string> <orderedTypeNames>5__8;
private HashSet<string> <reservedTypes>5__9;
private Dictionary<string, Vector3> <layout>5__10;
private List<GrabbableObject>.Enumerator <>s__11;
private GrabbableObject <item>5__12;
private string <itemName>5__13;
private bool <ignoreSkipTokensForThisItem>5__14;
private List<KeyValuePair<string, List<GrabbableObject>>>.Enumerator <>s__15;
private KeyValuePair<string, List<GrabbableObject>> <group>5__16;
private string <itemName>5__17;
private List<GrabbableObject> <items>5__18;
private Vector3 <typePos>5__19;
private bool <hasCustomPos>5__20;
private Vector3 <customShipLocal>5__21;
private string <posError>5__22;
private bool <ignoreSkipTokensForThisType>5__23;
private Vector3 <pileCenterLocal>5__24;
private float <customYOffset>5__25;
private float <typeLayerYOffset>5__26;
private float <originYOffset>5__27;
private float <groundYLocal>5__28;
private Vector3 <rayStartCenter>5__29;
private RaycastHit <hitCenter>5__30;
private int <stackIndex>5__31;
private GrabbableObject <item>5__32;
private float <pileX>5__33;
private float <pileZ>5__34;
private float <pileY>5__35;
private Vector3 <targetLocal>5__36;
private Vector3 <worldPos>5__37;
private int <cols>5__38;
private int <rows>5__39;
private int <perLayer>5__40;
private int <layer>5__41;
private int <inLayer>5__42;
private int <r>5__43;
private int <c>5__44;
private int <retry>5__45;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SortItems>d__40(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || (uint)(num - 1) <= 1u)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<ship>5__1 = null;
<savedTypes>5__3 = null;
<savedPositions>5__4 = null;
<posListError>5__5 = null;
<groupedItems>5__6 = null;
<orderedGroups>5__7 = null;
<orderedTypeNames>5__8 = null;
<reservedTypes>5__9 = null;
<layout>5__10 = null;
<>s__11 = default(List<GrabbableObject>.Enumerator);
<item>5__12 = null;
<itemName>5__13 = null;
<>s__15 = default(List<KeyValuePair<string, List<GrabbableObject>>>.Enumerator);
<group>5__16 = default(KeyValuePair<string, List<GrabbableObject>>);
<itemName>5__17 = null;
<items>5__18 = null;
<posError>5__22 = null;
<item>5__32 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_082c: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_0897: Unknown result type (might be due to invalid IL or missing references)
//IL_08a1: Expected O, but got Unknown
//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
//IL_0393: Unknown result type (might be due to invalid IL or missing references)
//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
//IL_0762: Unknown result type (might be due to invalid IL or missing references)
//IL_0767: Unknown result type (might be due to invalid IL or missing references)
//IL_0779: Unknown result type (might be due to invalid IL or missing references)
//IL_077e: Unknown result type (might be due to invalid IL or missing references)
//IL_0783: Unknown result type (might be due to invalid IL or missing references)
//IL_0791: Unknown result type (might be due to invalid IL or missing references)
//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
//IL_0457: Unknown result type (might be due to invalid IL or missing references)
//IL_0410: Unknown result type (might be due to invalid IL or missing references)
//IL_0430: Unknown result type (might be due to invalid IL or missing references)
//IL_0435: Unknown result type (might be due to invalid IL or missing references)
//IL_045c: Unknown result type (might be due to invalid IL or missing references)
//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0504: Unknown result type (might be due to invalid IL or missing references)
//IL_0509: Unknown result type (might be due to invalid IL or missing references)
//IL_053d: Unknown result type (might be due to invalid IL or missing references)
//IL_0542: Unknown result type (might be due to invalid IL or missing references)
bool result;
try
{
switch (<>1__state)
{
default:
result = false;
break;
case 0:
<>1__state = -1;
inProgress = true;
Log.Chat("Press [Escape] to cancel sorting", "FFFF00");
if ((Object)(object)Player.Local == (Object)null)
{
Log.NotifyPlayer("Sorter Error", "Local player not ready yet", isWarning: true);
inProgress = false;
result = false;
break;
}
<ship>5__1 = GameObject.Find("Environment/HangarShip");
if ((Object)(object)<ship>5__1 == (Object)null)
{
Log.NotifyPlayer("Sorter Error", "Ship not found", isWarning: true);
inProgress = false;
result = false;
break;
}
BeginOperationLock();
<originLocal>5__2 = <>4__this.SortOrigin;
<savedTypes>5__3 = null;
<savedPositions>5__4 = SortPositions.ListAll(out <posListError>5__5);
if (<posListError>5__5 != null)
{
Log.Warning(<posListError>5__5);
}
else
{
<savedTypes>5__3 = new HashSet<string>(<savedPositions>5__4.Select<(string, Vector3), string>(((string itemKey, Vector3 shipLocalPos) p) => p.itemKey));
}
<groupedItems>5__6 = new Dictionary<string, List<GrabbableObject>>();
<>s__11 = <>4__this.scrap.GetEnumerator();
try
{
while (<>s__11.MoveNext())
{
<item>5__12 = <>s__11.Current;
<itemName>5__13 = <item>5__12.Name();
<ignoreSkipTokensForThisItem>5__14 = ignoreSkippedItems || (includeSavedPositionTypesEvenIfSkipped && <savedTypes>5__3 != null && <savedTypes>5__3.Contains(<itemName>5__13));
if (!<>4__this.ShouldSkipFullSort(<item>5__12, <ignoreSkipTokensForThisItem>5__14))
{
if (!<groupedItems>5__6.ContainsKey(<itemName>5__13))
{
<groupedItems>5__6[<itemName>5__13] = new List<GrabbableObject>();
}
<groupedItems>5__6[<itemName>5__13].Add(<item>5__12);
<itemName>5__13 = null;
<item>5__12 = null;
}
}
}
finally
{
((IDisposable)<>s__11).Dispose();
}
<>s__11 = default(List<GrabbableObject>.Enumerator);
<orderedGroups>5__7 = (from kvp in <groupedItems>5__6
orderby kvp.Value != null && kvp.Value.Any(IsTwoHandedItem) descending, kvp.Key
select kvp).ToList();
<orderedTypeNames>5__8 = <orderedGroups>5__7.Select((KeyValuePair<string, List<GrabbableObject>> kvp) => kvp.Key).ToList();
<reservedTypes>5__9 = <savedTypes>5__3;
<layout>5__10 = <>4__this.CreateLayout(<orderedTypeNames>5__8, <reservedTypes>5__9);
<>s__15 = <orderedGroups>5__7.GetEnumerator();
<>1__state = -3;
goto IL_0942;
case 1:
<>1__state = -3;
if (!<>4__this.ShouldSkipFullSort(<item>5__32, ignoreSkippedItems | <ignoreSkipTokensForThisType>5__23))
{
<item>5__32.floorYRot = -1;
if (!MoveUtils.MoveItemOnShipLocal(<item>5__32, <targetLocal>5__36, <item>5__32.floorYRot))
{
Log.Warning("Failed to move " + (<item>5__32.itemProperties?.itemName ?? ((Object)<item>5__32).name));
}
<retry>5__45 = 15;
goto IL_08ca;
}
goto IL_08ea;
case 2:
{
<>1__state = -3;
<retry>5__45--;
goto IL_08ca;
}
IL_08ca:
if (!Player.CanGrabObject(<item>5__32) && <retry>5__45 > 0)
{
<>2__current = (object)new WaitForEndOfFrame();
<>1__state = 2;
result = true;
break;
}
goto IL_08ea;
IL_08ea:
<item>5__32 = null;
goto IL_08f2;
IL_0904:
if (<stackIndex>5__31 < <items>5__18.Count)
{
<item>5__32 = <items>5__18[<stackIndex>5__31];
if (<>4__this.ShouldBreak(<item>5__32))
{
Log.NotifyPlayer("Sorter Stopping", "Operation cancelled or ship is in motion", isWarning: true);
inProgress = false;
result = false;
<>m__Finally1();
break;
}
<pileX>5__33 = 0f;
<pileZ>5__34 = 0f;
if (<>4__this.stackSameTypeTogether.Value)
{
<pileY>5__35 = (float)<stackIndex>5__31 * Mathf.Max(0f, <>4__this.sameTypeStackStepY.Value);
}
else
{
<cols>5__38 = Mathf.Max(1, <>4__this.itemsPerRow.Value);
<rows>5__39 = <cols>5__38;
<perLayer>5__40 = <cols>5__38 * <rows>5__39;
<layer>5__41 = <stackIndex>5__31 / <perLayer>5__40;
<inLayer>5__42 = <stackIndex>5__31 % <perLayer>5__40;
<r>5__43 = <inLayer>5__42 / <cols>5__38;
<c>5__44 = <inLayer>5__42 % <cols>5__38;
<pileX>5__33 = ((float)<c>5__44 - (float)(<cols>5__38 - 1) / 2f) * 0.1f;
<pileZ>5__34 = ((float)<r>5__43 - (float)(<rows>5__39 - 1) / 2f) * 0.1f;
<pileY>5__35 = (float)<layer>5__41 * 0.07f;
}
<targetLocal>5__36 = new Vector3(<pileCenterLocal>5__24.x + <pileX>5__33, <groundYLocal>5__28 + <originYOffset>5__27 + (<item>5__32.itemProperties.verticalOffset - 0.1f) + (<typeLayerYOffset>5__26 + <customYOffset>5__25) + <pileY>5__35 - (ShouldLowerYOffset(<item>5__32) ? 0.2f : 0f), <pileCenterLocal>5__24.z + <pileZ>5__34);
<worldPos>5__37 = <ship>5__1.transform.TransformPoint(<targetLocal>5__36);
if (!force && Vector3.Distance(<worldPos>5__37, ((Component)<item>5__32).transform.position) < 0.25f)
{
goto IL_08f2;
}
<>2__current = <>4__this.GrabbableRetry(<item>5__32);
<>1__state = 1;
result = true;
break;
}
<itemName>5__17 = null;
<items>5__18 = null;
<posError>5__22 = null;
<group>5__16 = default(KeyValuePair<string, List<GrabbableObject>>);
goto IL_0942;
IL_08f2:
<stackIndex>5__31++;
goto IL_0904;
IL_0942:
if (<>s__15.MoveNext())
{
<group>5__16 = <>s__15.Current;
<itemName>5__17 = <group>5__16.Key;
<items>5__18 = <group>5__16.Value;
<typePos>5__19 = (<layout>5__10.ContainsKey(<itemName>5__17) ? <layout>5__10[<itemName>5__17] : Vector3.zero);
<hasCustomPos>5__20 = SortPositions.TryGet(<itemName>5__17, out <customShipLocal>5__21, out <posError>5__22);
if (<posError>5__22 != null)
{
Log.Warning(<posError>5__22);
}
<ignoreSkipTokensForThisType>5__23 = includeSavedPositionTypesEvenIfSkipped & <hasCustomPos>5__20;
<pileCenterLocal>5__24 = (Vector3)(<hasCustomPos>5__20 ? new Vector3(<customShipLocal>5__21.x, 0f, <customShipLocal>5__21.z) : (<originLocal>5__2 + new Vector3(<typePos>5__19.x, 0f, <typePos>5__19.z)));
<customYOffset>5__25 = (<hasCustomPos>5__20 ? <customShipLocal>5__21.y : 0f);
<typeLayerYOffset>5__26 = (<hasCustomPos>5__20 ? 0f : <typePos>5__19.y);
<originYOffset>5__27 = (<hasCustomPos>5__20 ? 0f : <originLocal>5__2.y);
<groundYLocal>5__28 = <pileCenterLocal>5__24.y;
<rayStartCenter>5__29 = <ship>5__1.transform.TransformPoint(<pileCenterLocal>5__24 + Vector3.up * 2f);
if (Physics.Raycast(<rayStartCenter>5__29, Vector3.down, ref <hitCenter>5__30, 80f, 268437761, (QueryTriggerInteraction)1))
{
<groundYLocal>5__28 = <ship>5__1.transform.InverseTransformPoint(((RaycastHit)(ref <hitCenter>5__30)).point).y;
}
<stackIndex>5__31 = 0;
goto IL_0904;
}
<>m__Finally1();
<>s__15 = default(List<KeyValuePair<string, List<GrabbableObject>>>.Enumerator);
Log.Chat("Sorting complete!", "00FF00");
inProgress = false;
result = false;
break;
}
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
return result;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
((IDisposable)<>s__15).Dispose();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public const string DefaultSkippedItems = "body, clipboard, sticky_note, boombox, shovel, jetpack, flashlight, pro_flashlight, key, stun_grenade, lockpicker, mapper, extension_ladder, tzp_inhalant, walkie_talkie, zap_gun, kitchen_knife, weed_killer, radar_booster, spray_paint, belt_bag, shotgun, ammo";
private static readonly HashSet<string> LowerYOffsetTypes = new HashSet<string> { "toilet_paper", "chemical_jug", "cash_register", "fancy_lamp", "large_axle", "v_type_engine" };
public ConfigEntry<float> sortOriginX;
public ConfigEntry<float> sortOriginY;
public ConfigEntry<float> sortOriginZ;
public ConfigEntry<float> itemSpacing;
public ConfigEntry<float> rowSpacing;
public ConfigEntry<int> itemsPerRow;
public ConfigEntry<string> skippedItems;
public ConfigEntry<float> sortAreaWidth;
public ConfigEntry<float> sortAreaDepth;
public ConfigEntry<float> wallPadding;
public ConfigEntry<bool> stackSameTypeTogether;
public ConfigEntry<float> sameTypeStackStepY;
private List<GrabbableObject> scrap;
public static bool inProgress;
private static bool _interactionLocked;
private static int _interactionBypassCount;
private static List<(string name, bool isProperty, float value)>? _savedWeight;
private Vector3 SortOrigin => new Vector3(sortOriginX.Value, sortOriginY.Value, sortOriginZ.Value);
private bool CanSort => true;
internal static bool IsInteractionLocked => _interactionLocked;
internal static bool IsInteractionBypassActive => _interactionBypassCount > 0;
private static bool ShouldLowerYOffset(GrabbableObject item)
{
if ((Object)(object)item == (Object)null)
{
return false;
}
string text = item.Name();
if (string.IsNullOrWhiteSpace(text))
{
return false;
}
return LowerYOffsetTypes.Contains(text);
}
private static string ApplyDefaultInputAliases(string normalizedKey)
{
if (string.IsNullOrWhiteSpace(normalizedKey))
{
return normalizedKey;
}
if (1 == 0)
{
}
string result = ((normalizedKey == "double_barrel") ? "shotgun" : ((!(normalizedKey == "shotgun_shell")) ? normalizedKey : "ammo"));
if (1 == 0)
{
}
return result;
}
internal static bool EnsureLocalPlayerInShip(out string? error)
{
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
error = null;
PlayerControllerB local = Player.Local;
if ((Object)(object)local == (Object)null)
{
error = "Local player not ready yet";
return false;
}
try
{
Type type2 = ((object)local).GetType();
string[] array = new string[6] { "isInHangarShipRoom", "IsInHangarShipRoom", "isInShipRoom", "IsInShipRoom", "inShipRoom", "InShipRoom" };
string[] array2 = array;
foreach (string name2 in array2)
{
bool? flag = TryGetBool(local, type2, name2);
if (flag.HasValue)
{
if (!flag.Value)
{
error = "You must be inside the ship to use this command.";
return false;
}
return true;
}
}
}
catch
{
}
GameObject val = GameObject.Find("Environment/HangarShip");
if ((Object)(object)val == (Object)null)
{
error = "Ship not found";
return false;
}
Vector3 val2 = val.transform.InverseTransformPoint(((Component)local).transform.position);
if (!(val2.x >= -10f) || !(val2.x <= 10f) || !(val2.z >= -20f) || !(val2.z <= 10f) || !(val2.y >= -6f) || !(val2.y <= 10f))
{
error = "You must be inside the ship to use this command.";
return false;
}
return true;
static bool? TryGetBool(object obj, Type type, string name)
{
FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null && field.FieldType == typeof(bool))
{
return (bool)field.GetValue(obj);
}
PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null && property.PropertyType == typeof(bool) && property.GetIndexParameters().Length == 0)
{
return (bool)property.GetValue(obj, null);
}
return null;
}
}
private void Awake()
{
sortOriginX = Plugin.config.Bind<float>("Sorter", "sortOriginX", -2.8f, "X coordinate of the origin position for sorting items (relative to ship)");
sortOriginY = Plugin.config.Bind<float>("Sorter", "sortOriginY", 0.1f, "Y coordinate of the origin position for sorting items (relative to ship)");
sortOriginZ = Plugin.config.Bind<float>("Sorter", "sortOriginZ", -4.8f, "Z coordinate of the origin position for sorting items (relative to ship)");
itemSpacing = Plugin.config.Bind<float>("Sorter", "itemSpacing", 0.8f, "Spacing between items horizontally");
rowSpacing = Plugin.config.Bind<float>("Sorter", "rowSpacing", 0.8f, "Spacing between rows vertically");
itemsPerRow = Plugin.config.Bind<int>("Sorter", "itemsPerRow", 9, "Number of items per row");
skippedItems = Plugin.config.Bind<string>("Sorter", "skippedItems", "body, clipboard, sticky_note, boombox, shovel, jetpack, flashlight, pro_flashlight, key, stun_grenade, lockpicker, mapper, extension_ladder, tzp_inhalant, walkie_talkie, zap_gun, kitchen_knife, weed_killer, radar_booster, spray_paint, belt_bag, shotgun, ammo", "Global skip list (comma-separated, substring match). Applies to all grabbable items.");
skippedItems.Value = NormalizeSkipListConfig(skippedItems.Value);
sortAreaWidth = Plugin.config.Bind<float>("Sorter", "sortAreaWidth", 9f, "Reserved: used only for future bounding. (Keeping for compatibility)");
sortAreaDepth = Plugin.config.Bind<float>("Sorter", "sortAreaDepth", 6f, "How far forward (Z) types are allowed to expand from sortOriginZ before starting a new type-layer above.");
wallPadding = Plugin.config.Bind<float>("Sorter", "wallPadding", 0.25f, "Padding used for depth calculation (prevents placing type rows into doors/walls).");
stackSameTypeTogether = Plugin.config.Bind<bool>("Sorter", "stackSameTypeTogether", true, "If true, items of the same type will be stacked at the exact same X/Z position (only Y increases), instead of being spread in a small grid.");
sameTypeStackStepY = Plugin.config.Bind<float>("Sorter", "sameTypeStackStepY", 0f, "Vertical spacing between items when stackSameTypeTogether is enabled. Set to 0 for exact overlap; increase (e.g. 0.1~0.2) if physics makes items push apart.");
}
internal static IDisposable BeginInteractionBypass()
{
_interactionBypassCount++;
return new DisposeAction(delegate
{
_interactionBypassCount = Math.Max(0, _interactionBypassCount - 1);
});
}
private static void CapturePlayerWeightIfNeeded()
{
if (_savedWeight != null)
{
return;
}
PlayerControllerB local = Player.Local;
if ((Object)(object)local == (Object)null)
{
return;
}
Type type = ((object)local).GetType();
List<(string, bool, float)> list = new List<(string, bool, float)>();
try
{
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (!(fieldInfo.FieldType != typeof(float)) && IsCarryWeightName(fieldInfo.Name))
{
list.Add((fieldInfo.Name, false, (float)fieldInfo.GetValue(local)));
}
}
}
catch
{
}
try
{
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (PropertyInfo propertyInfo in properties)
{
if (!(propertyInfo.PropertyType != typeof(float)) && propertyInfo.GetIndexParameters().Length == 0 && propertyInfo.CanRead && propertyInfo.CanWrite && IsCarryWeightName(propertyInfo.Name))
{
list.Add((propertyInfo.Name, true, (float)propertyInfo.GetValue(local, null)));
}
}
}
catch
{
}
if (list.Count > 0)
{
_savedWeight = list;
}
static bool IsCarryWeightName(string n)
{
return n != null && n.IndexOf("carry", StringComparison.OrdinalIgnoreCase) >= 0 && n.IndexOf("weight", StringComparison.OrdinalIgnoreCase) >= 0;
}
}
private static void RestorePlayerWeightIfNeeded()
{
if (_savedWeight == null)
{
return;
}
PlayerControllerB local = Player.Local;
if ((Object)(object)local == (Object)null)
{
_savedWeight = null;
return;
}
Type type = ((object)local).GetType();
foreach (var item in _savedWeight)
{
try
{
if (!item.isProperty)
{
FieldInfo field = type.GetField(item.name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null && field.FieldType == typeof(float))
{
field.SetValue(local, item.value);
}
}
else
{
PropertyInfo property = type.GetProperty(item.name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null && property.PropertyType == typeof(float) && property.GetIndexParameters().Length == 0 && property.CanWrite)
{
property.SetValue(local, item.value, null);
}
}
}
catch
{
}
}
_savedWeight = null;
}
private static void BeginOperationLock()
{
if (!_interactionLocked)
{
CapturePlayerWeightIfNeeded();
_interactionLocked = true;
}
}
private static void EndOperationLock()
{
_interactionLocked = false;
_interactionBypassCount = 0;
RestorePlayerWeightIfNeeded();
}
[IteratorStateMachine(typeof(<DropHeldItemIfAny>d__37))]
private IEnumerator DropHeldItemIfAny(GameObject ship)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DropHeldItemIfAny>d__37(0)
{
<>4__this = this,
ship = ship
};
}
private void Update()
{
if (inProgress && ((ButtonControl)Keyboard.current.escapeKey).wasPressedThisFrame)
{
inProgress = false;
Log.Chat("Sorting cancelled", "FF0000");
}
if (_interactionLocked && !inProgress)
{
EndOperationLock();
}
}
private void SortCommandHandler(string[] args)
{
if (args.Length != 0 && args[0] == "help")
{
Log.Chat("Usage: /sort [help]", "FFFF00");
return;
}
if (inProgress)
{
Log.NotifyPlayer("Sorter Error", "Operation in progress", isWarning: true);
return;
}
CategorizeItems();
Log.ConfirmSound();
((MonoBehaviour)this).StartCoroutine(SortItems(force: false));
}
[IteratorStateMachine(typeof(<SortItems>d__40))]
public IEnumerator SortItems(bool force, bool ignoreSkippedItems = false, bool includeSavedPositionTypesEvenIfSkipped = false)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SortItems>d__40(0)
{
<>4__this = this,
force = force,
ignoreSkippedItems = ignoreSkippedItems,
includeSavedPositionTypesEvenIfSkipped = includeSavedPositionTypesEvenIfSkipped
};
}
private static bool IsTwoHandedItem(GrabbableObject item)
{
try
{
if ((Object)(object)item == (Object)null)
{
return false;
}
Item itemProperties = item.itemProperties;
if ((Object)(object)itemProperties == (Object)null)
{
return false;
}
Type type = ((object)itemProperties).GetType();
FieldInfo fieldInfo = type.GetField("twoHanded", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("isTwoHanded", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("twoHandedItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("<twoHanded>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("<isTwoHanded>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetField("<twoHandedItem>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (fieldInfo != null && fieldInfo.FieldType == typeof(bool))
{
return (bool)fieldInfo.GetValue(itemProperties);
}
PropertyInfo propertyInfo = type.GetProperty("twoHanded", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetProperty("isTwoHanded", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? type.GetProperty("twoHandedItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (propertyInfo != null && propertyInfo.PropertyType == typeof(bool) && propertyInfo.GetIndexParameters().Length == 0)
{
return (bool)propertyInfo.GetValue(itemProperties, null);
}
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo2 in fields)
{
if (!(fieldInfo2.FieldType != typeof(bool)) && fieldInfo2.Name.IndexOf("twohand", StringComparison.OrdinalIgnoreCase) >= 0)
{
return (bool)fieldInfo2.GetValue(itemProperties);
}
}
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (PropertyInfo propertyInfo2 in properties)
{
if (!(propertyInfo2.PropertyType != typeof(bool)) && propertyInfo2.GetIndexParameters().Length == 0 && propertyInfo2.Name.IndexOf("twohand", StringComparison.OrdinalIgnoreCase) >= 0)
{
return (bool)propertyInfo2.GetValue(itemProperties, null);
}
}
return false;
}
catch
{
return false;
}
}
public bool TryStartGatherByQuery(string query, bool force, out string? error)
{
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
error = null;
if (inProgress)
{
error = "Operation in progress";
return false;
}
if (string.IsNullOrWhiteSpace(query))
{
error = "Missing item name";
return false;
}
CategorizeItems(includeSkippedItems: true);
if (scrap == null || scrap.Count == 0)
{
error = "No items found in ship";
return false;
}
Dictionary<string, List<GrabbableObject>> dictionary = new Dictionary<string, List<GrabbableObject>>();
foreach (GrabbableObject item in scrap)
{
if (!ShouldSkipExplicitQuery(item))
{
string key = item.Name();
if (!dictionary.TryGetValue(key, out var value))
{
value = (dictionary[key] = new List<GrabbableObject>());
}
value.Add(item);
}
}
if (!TryResolveItemKeyFromGrouped(dictionary, query, out string resolvedKey, out error))
{
return false;
}
if (!TryGetPlayerShipLocalTarget(out var shipLocalTarget, out error))
{
return false;
}
if (!TryGetGroundYLocalAt(shipLocalTarget, out float groundYLocal, out string error2))
{
error = error2;
return false;
}
Vector3 targetCenterShipLocal = default(Vector3);
((Vector3)(ref targetCenterShipLocal))..ctor(shipL