using System;
using System.Collections.Generic;
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 BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using OptimalScrapsOrganization.Patches;
using OptimalScrapsOrganization.Scripts;
using StaticNetcodeLib;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ShipScrapReorder")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("ShipScrapReorder")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+acbe9c371e7bf282bf82e7ea61b4d2d36ff38e5f")]
[assembly: AssemblyProduct("ShipScrapReorder")]
[assembly: AssemblyTitle("ShipScrapReorder")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace OptimalScrapsOrganization
{
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("wexop.ship_item_reorder", "ShipScrapReorder", "1.0.1")]
public class OptimalScrapsOrganizationPlugin : BaseUnityPlugin
{
public const string GUID = "wexop.ship_item_reorder";
public const string NAME = "ShipScrapReorder";
public const string VERSION = "1.0.1";
public ConfigEntry<float> distanceBewteenObjects;
public ConfigEntry<int> organiseDefaultValueRange;
public ConfigEntry<bool> autoReorderOnLeftMoon;
public ConfigEntry<OrganizeBy> defaultReorderType;
public static OptimalScrapsOrganizationPlugin instance;
private void Awake()
{
instance = this;
((BaseUnityPlugin)this).Logger.LogInfo((object)"OptimalScrapsOrganization starting....");
LoadConfig();
Harmony.CreateAndPatchAll(typeof(PatchTerminal), (string)null);
Harmony.CreateAndPatchAll(typeof(PatchStartOfRound), (string)null);
((BaseUnityPlugin)this).Logger.LogInfo((object)"OptimalScrapsOrganization Patched !!");
}
private void LoadConfig()
{
distanceBewteenObjects = ((BaseUnityPlugin)this).Config.Bind<float>("General", "distanceBewteenObjects", 0.6f, "Distance between each stacks of objects. No need to restart the game :)");
CreateFloatConfig(distanceBewteenObjects, 0f, 5f);
organiseDefaultValueRange = ((BaseUnityPlugin)this).Config.Bind<int>("General", "organiseDefaultValueRange", 20, "Distance between each stacks of objects. No need to restart the game :)");
CreateIntConfig(organiseDefaultValueRange, 1, 200);
autoReorderOnLeftMoon = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "autoReorderOnLeftMoon", true, "Auto reorder scraps when leaving the moon. No need to restart the game :)");
CreateBoolConfig(autoReorderOnLeftMoon);
defaultReorderType = ((BaseUnityPlugin)this).Config.Bind<OrganizeBy>("General", "defaultReorderType", OrganizeBy.VALUE, "Default reorder type. No need to restart the game :)");
CreateOrganiseByConfig(defaultReorderType);
}
private void CreateFloatConfig(ConfigEntry<float> configEntry, float min = 0f, float max = 100f)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
FloatSliderOptions val = new FloatSliderOptions();
((BaseRangeOptions<float>)val).Min = min;
((BaseRangeOptions<float>)val).Max = max;
((BaseOptions)val).RequiresRestart = false;
FloatSliderConfigItem val2 = new FloatSliderConfigItem(configEntry, val);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val2);
}
private void CreateIntConfig(ConfigEntry<int> configEntry, int min = 0, int max = 100)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
IntSliderOptions val = new IntSliderOptions();
((BaseRangeOptions<int>)val).Min = min;
((BaseRangeOptions<int>)val).Max = max;
((BaseOptions)val).RequiresRestart = false;
IntSliderConfigItem val2 = new IntSliderConfigItem(configEntry, val);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val2);
}
private void CreateStringConfig(ConfigEntry<string> configEntry)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Expected O, but got Unknown
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
TextInputFieldConfigItem val = new TextInputFieldConfigItem(configEntry, new TextInputFieldOptions
{
RequiresRestart = false
});
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val);
}
private void CreateBoolConfig(ConfigEntry<bool> configEntry)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Expected O, but got Unknown
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
BoolCheckBoxConfigItem val = new BoolCheckBoxConfigItem(configEntry, new BoolCheckBoxOptions
{
RequiresRestart = false
});
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val);
}
private void CreateOrganiseByConfig(ConfigEntry<OrganizeBy> configEntry)
{
EnumDropDownConfigItem<OrganizeBy> val = new EnumDropDownConfigItem<OrganizeBy>(configEntry, false);
LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val);
}
public bool StringContain(string name, string verifiedName)
{
string text = name.ToLower();
while (text.Contains(" "))
{
text = text.Replace(" ", "");
}
string text2 = verifiedName.ToLower();
while (text2.Contains(" "))
{
text2 = text2.Replace(" ", "");
}
return text.Contains(text2);
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "ShipScrapReorder";
public const string PLUGIN_NAME = "ShipScrapReorder";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace OptimalScrapsOrganization.Scripts
{
public enum OrganizeBy
{
VALUE,
NAME
}
[StaticNetcode]
public class NetworkOrganization
{
[ServerRpc]
public static void OrganizeScrapsServerRpc(OrganizeInformation organizeInformation)
{
OrganizeScrapsClientRpc(organizeInformation);
}
[ClientRpc]
public static void OrganizeScrapsClientRpc(OrganizeInformation organizeInformation)
{
ScrapsOrganizationManager.OrganizeShipScraps(organizeInformation);
}
}
public class OrganizeInformation
{
public OrganizeBy OrganizeBy;
public int value;
public float distanceBetweenObjects;
}
public class ScrapsOrganizationManager
{
public static Vector3 position = new Vector3(-6.1846676f, 0.10327625f, -5f);
public static Vector3 maxPosition = new Vector3(9.047635f, 0f, -5f);
public static Vector3 postionRight = new Vector3(-4.263417f, 0f, -9.5f);
public static Vector3 maxPostionRight = new Vector3(3.728537f, 0f, -9.5f);
public static Transform HangarShipTransform => StartOfRound.Instance.elevatorTransform;
public static bool IsScrap(GrabbableObject grabbableObject)
{
if ((Object)(object)grabbableObject == (Object)null)
{
return false;
}
if (!IsScrap(grabbableObject.itemProperties))
{
return false;
}
if (grabbableObject.isHeld || !grabbableObject.grabbable)
{
return false;
}
return true;
}
public static bool IsScrap(Item item)
{
if ((Object)(object)item == (Object)null)
{
return false;
}
return item.isScrap;
}
public static bool IsValidScrap(GrabbableObject grabbableObject)
{
if ((Object)(object)grabbableObject == (Object)null)
{
return false;
}
if (!IsScrap(grabbableObject))
{
return false;
}
return true;
}
private static List<GrabbableObject> GetValidScrap(IEnumerable<GrabbableObject> grabbableObjects)
{
if (grabbableObjects == null)
{
return new List<GrabbableObject>();
}
return grabbableObjects.Where((GrabbableObject x) => IsValidScrap(x)).ToList();
}
public static List<GrabbableObject> GetScrapFromShip()
{
if ((Object)(object)HangarShipTransform == (Object)null)
{
return new List<GrabbableObject>();
}
return GetValidScrap(((Component)HangarShipTransform).GetComponentsInChildren<GrabbableObject>());
}
public static void OrganizeShipScraps(OrganizeInformation organizeInformation)
{
//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_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
List<GrabbableObject> scrapsOnShip = GetScrapFromShip();
int value = organizeInformation.value;
OrganizeBy organizeBy = organizeInformation.OrganizeBy;
if (value <= 0)
{
value = 1;
}
switch (organizeBy)
{
case OrganizeBy.VALUE:
scrapsOnShip.Sort((GrabbableObject x, GrabbableObject y) => x.scrapValue.CompareTo(y.scrapValue));
break;
case OrganizeBy.NAME:
scrapsOnShip.Sort((GrabbableObject x, GrabbableObject y) => x.itemProperties.itemName.CompareTo(y.itemProperties.itemName));
break;
}
if (scrapsOnShip.Count == 0)
{
return;
}
Vector3 basePos = position;
Vector3 usePostion = basePos;
int valueRange;
for (valueRange = 0; valueRange < scrapsOnShip[0].scrapValue; valueRange += value)
{
}
int index = -1;
scrapsOnShip.ForEach(delegate(GrabbableObject scrap)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: 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_00a5: 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_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_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
index++;
if (!((Object)(object)scrap == (Object)null))
{
if (usePostion.z < maxPostionRight.z)
{
usePostion = position;
}
if (usePostion.x > maxPosition.x)
{
basePos += new Vector3(0f, 0f, 0f - organizeInformation.distanceBetweenObjects);
usePostion = basePos;
}
scrap.targetFloorPosition = usePostion;
((Component)scrap).transform.eulerAngles = Vector3.zero + scrap.itemProperties.restingRotation;
if ((organizeBy != OrganizeBy.NAME || index >= scrapsOnShip.Count - 1 || !(scrap.itemProperties.itemName == scrapsOnShip[index + 1].itemProperties.itemName)) && (organizeBy != 0 || index >= scrapsOnShip.Count - 1 || scrapsOnShip[index + 1].scrapValue > valueRange))
{
if (index < scrapsOnShip.Count - 1)
{
for (; valueRange < scrapsOnShip[index + 1].scrapValue; valueRange += value)
{
}
}
usePostion += new Vector3(organizeInformation.distanceBetweenObjects, 0f, 0f);
}
}
});
}
}
}
namespace OptimalScrapsOrganization.Patches
{
[HarmonyPatch(typeof(StartOfRound))]
public class PatchStartOfRound
{
[HarmonyPatch("AutoSaveShipData")]
[HarmonyPrefix]
private static void ShipHasLeftPostfix(StartOfRound __instance)
{
if (((NetworkBehaviour)__instance).IsServer && OptimalScrapsOrganizationPlugin.instance.autoReorderOnLeftMoon.Value)
{
OrganizeInformation organizeInformation = new OrganizeInformation();
organizeInformation.OrganizeBy = OptimalScrapsOrganizationPlugin.instance.defaultReorderType.Value;
organizeInformation.value = OptimalScrapsOrganizationPlugin.instance.organiseDefaultValueRange.Value;
organizeInformation.distanceBetweenObjects = OptimalScrapsOrganizationPlugin.instance.distanceBewteenObjects.Value;
NetworkOrganization.OrganizeScrapsClientRpc(organizeInformation);
}
}
}
[HarmonyPatch(typeof(Terminal))]
public class PatchTerminal
{
[HarmonyPatch("ParsePlayerSentence")]
[HarmonyPrefix]
[HarmonyPriority(800)]
private static bool ParsePlayerSentencePatch(Terminal __instance, ref TerminalNode __result)
{
string[] array = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (array[0].ToLower().Contains("reorder"))
{
if (array.Length > 1 && array[1].ToLower().Contains("help"))
{
__result = CreateTerminalNode("Commands :\n\n- reorder\n\n- reorder <valueRange>\n\n- reorder name\n\n");
return false;
}
OrganizeBy organizeBy = OptimalScrapsOrganizationPlugin.instance.defaultReorderType.Value;
int result = OptimalScrapsOrganizationPlugin.instance.organiseDefaultValueRange.Value;
if (array.Length > 1 && array[1].ToLower().Contains("name"))
{
organizeBy = OrganizeBy.NAME;
}
else if (array.Length > 1)
{
organizeBy = OrganizeBy.VALUE;
int.TryParse(array[1], out result);
}
OrganizeInformation organizeInformation = new OrganizeInformation();
organizeInformation.OrganizeBy = organizeBy;
organizeInformation.value = result;
organizeInformation.distanceBetweenObjects = OptimalScrapsOrganizationPlugin.instance.distanceBewteenObjects.Value;
NetworkOrganization.OrganizeScrapsServerRpc(organizeInformation);
__result = CreateTerminalNode("Done !");
return false;
}
return true;
}
[HarmonyPatch("Start")]
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void StartPatch(ref TerminalNodesList ___terminalNodes)
{
int index = 1;
string displayText = ___terminalNodes.specialNodes[index].displayText;
string displayText2 = (displayText += "\n[ShipScrapReorder]\nType \"reorder help\" for a list of commands.\n");
___terminalNodes.specialNodes[index].displayText = displayText2;
index = 13;
displayText = ___terminalNodes.specialNodes[index].displayText;
displayText2 = (displayText += "\n\n>REORDER HELP\nTo see the list of ShipScrapReorder commands.\n");
___terminalNodes.specialNodes[index].displayText = displayText2;
}
public static TerminalNode CreateTerminalNode(string message, bool clearPreviousText = true, int maxChar = 50)
{
TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>();
val.displayText = message;
val.clearPreviousText = clearPreviousText;
val.maxCharactersToType = maxChar;
return val;
}
}
}