using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyCompany("NGA")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Persistent player progression! Raid, stash loot, and deploy with seemless scene/loadout saving.")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("NGA.GunCaseFix")]
[assembly: AssemblyTitle("BepInEx Plugin Title")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.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 BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string id = null, string name = null, string version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null)
{
}
}
}
namespace NGA
{
[BepInPlugin("NGA.GunCaseFix", "GunCaseFix", "0.1.0")]
[BepInDependency("nrgill28.Sodalite", "1.4.1")]
[BepInProcess("h3vr.exe")]
public class GunCaseFix : BaseUnityPlugin
{
[HarmonyPatch(typeof(SaveableGunCase))]
[HarmonyPatch("OpenCase")]
private class SaveableGunCaseOpenCaseHook
{
private static void Postfix(SaveableGunCase __instance)
{
if ((Object)(object)__instance == (Object)null)
{
Logger.LogMessage((object)"SaveableGunCase is null!?");
}
__instance.m_containedPositions.Clear();
__instance.m_containedRotations.Clear();
}
}
[HarmonyPatch(typeof(SaveableGunCase))]
[HarmonyPatch("CloseCase")]
private class SaveableGunCloseCaseHook
{
private static void Postfix(SaveableGunCase __instance)
{
if ((Object)(object)__instance == (Object)null)
{
Logger.LogMessage((object)"SaveableGunCase is null!?");
}
}
}
[HarmonyPatch(typeof(VaultSystem))]
[HarmonyPatch("WriteToVaultFileObject")]
private class VaultSystemWriteToVaultFileObjectHook
{
private static bool Prefix(List<FVRPhysicalObject> objs, VaultFile f, bool savePositionsRelativeToSpawner, bool saveworldPositions, bool encodeAsLoadout, Transform ScanRoot)
{
Logger.LogMessage((object)"VaultSystem WriteToVaultFileObject Postfix HOOKED!");
f.Objects.Clear();
if (encodeAsLoadout)
{
f.QuickbeltLayoutName = ((Object)ManagerSingleton<GM>.Instance.QuickbeltConfigurations[GM.Options.QuickbeltOptions.QuickbeltPreset]).name;
}
Dictionary<FVRPhysicalObject, int> dictionary = new Dictionary<FVRPhysicalObject, int>();
Dictionary<FVRPhysicalObject, int> dictionary2 = new Dictionary<FVRPhysicalObject, int>();
Dictionary<FVRPhysicalObject, int> dictionary3 = new Dictionary<FVRPhysicalObject, int>();
Dictionary<FVRPhysicalObject, int> dictionary4 = new Dictionary<FVRPhysicalObject, int>();
List<FVRPhysicalObject> list = new List<FVRPhysicalObject>();
for (int i = 0; i < objs.Count; i++)
{
List<FVRPhysicalObject> containedObjectsRecursively = objs[i].GetContainedObjectsRecursively();
list.Add(objs[i]);
for (int j = 0; j < containedObjectsRecursively.Count; j++)
{
if (list.Contains(containedObjectsRecursively[j]))
{
list.Remove(containedObjectsRecursively[j]);
}
list.Add(containedObjectsRecursively[j]);
}
}
objs = list;
for (int k = 0; k < objs.Count; k++)
{
dictionary.Add(objs[k], k);
VaultObject val = VaultSystem.SavePhysicalObjectToVaultObject(objs[k], savePositionsRelativeToSpawner, saveworldPositions, dictionary2, dictionary3, dictionary4, k, ScanRoot);
val.Index = k;
f.Objects.Add(val);
}
for (int l = 0; l < objs.Count; l++)
{
List<FVRPhysicalObject> containedObjects = objs[l].GetContainedObjects();
if (containedObjects.Count > 0)
{
Logger.LogMessage((object)("Object of index:" + l + " has " + containedObjects.Count + " children"));
}
for (int m = 0; m < containedObjects.Count; m++)
{
int num = dictionary[containedObjects[m]];
Logger.LogMessage((object)("While writing file, Object of index:" + num + " is contained in object of index" + l));
f.Objects[num].IsContainedIn = l;
}
}
for (int n = 0; n < objs.Count; n++)
{
bool flag = false;
if (dictionary2.ContainsKey(objs[n]))
{
f.Objects[n].InSlotOfRootObjectIndex = dictionary2[objs[n]];
flag = true;
}
if (dictionary3.ContainsKey(objs[n]))
{
f.Objects[n].InSlotOfElementIndex = dictionary3[objs[n]];
flag = true;
}
if (dictionary4.ContainsKey(objs[n]))
{
f.Objects[n].QuickbeltSlotIndex = dictionary4[objs[n]];
flag = true;
}
if (flag)
{
Logger.LogMessage((object)(((Object)objs[n]).name + " was encoded on root object index:" + f.Objects[n].InSlotOfRootObjectIndex + " and element index:" + f.Objects[n].InSlotOfElementIndex + " in slot index:" + f.Objects[n].QuickbeltSlotIndex));
}
}
for (int num2 = 0; num2 < objs.Count; num2++)
{
if ((Object)(object)objs[num2].QuickbeltSlot != (Object)null && GM.CurrentPlayerBody.IsSlotInternal(objs[num2].QuickbeltSlot))
{
int num3 = GM.CurrentPlayerBody.QBSlots_Internal.IndexOf(objs[num2].QuickbeltSlot);
Logger.LogMessage((object)("Encoding Object:" + f.Objects[num2].Elements[0].ObjectID + " into player internal quickbelt slot: " + num3));
f.Objects[num2].QuickbeltSlotIndex = num3;
}
}
f.ModsUsed.Clear();
for (int num4 = 0; num4 < f.Objects.Count; num4++)
{
for (int num5 = 0; num5 < f.Objects[num4].Elements.Count; num5++)
{
string objectID = f.Objects[num4].Elements[num5].ObjectID;
FVRObject val2 = IM.OD[objectID];
string spawnedFromId = val2.SpawnedFromId;
if (IM.HasSpawnedID(spawnedFromId))
{
ItemSpawnerID spawnerID = IM.GetSpawnerID(spawnedFromId);
string fromMod = spawnerID.FromMod;
if (fromMod != string.Empty && !f.ModsUsed.Contains(fromMod))
{
f.ModsUsed.Add(fromMod);
}
}
}
}
Logger.LogMessage((object)"Printing VaultObjects in order after SAVE:");
foreach (VaultObject @object in f.Objects)
{
Logger.LogMessage((object)@object);
}
return false;
}
}
[HarmonyPatch(typeof(VaultSystem))]
[HarmonyPatch("SpawnVaultFileRoutine")]
private class VaultSystemSpawnVaultFileRoutineHook
{
private static bool Prefixfix(IEnumerator __result, VaultFile f, Transform SpawnRelativeTo, bool spawnRelativeTo, bool decodeAsLoadout, bool clearScene, Vector3 spawnOffset, ReturnObjectListDelegate del, bool displayFileLoad)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
Logger.LogMessage((object)"VaultSystem SpawnVaultFileRoutine Postfix HOOKED!");
__result = SpawnVaultFileRoutine(f, SpawnRelativeTo, spawnRelativeTo, decodeAsLoadout, clearScene, spawnOffset, del, displayFileLoad);
return false;
}
private static IEnumerator SpawnVaultFileRoutine(VaultFile f, Transform SpawnRelativeTo, bool spawnRelativeTo, bool decodeAsLoadout, bool clearScene, Vector3 spawnOffset, ReturnObjectListDelegate del, bool displayFileLoad)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
if (displayFileLoad)
{
GM.IsAsyncLoading = true;
}
Logger.LogMessage((object)("Initiating Spawn Routine for: " + f.Objects.Count + " root objects"));
if (displayFileLoad)
{
GM.CurrentPlayerBody.ShowLoadingBar();
}
if (decodeAsLoadout)
{
GM.CurrentPlayerBody.WipeQuickbeltContents();
}
yield return null;
if (clearScene)
{
VaultSystem.ClearExistingSaveableObjects(true);
}
yield return null;
FVRPhysicalObject[] spawnedObjs = (FVRPhysicalObject[])(object)new FVRPhysicalObject[f.Objects.Count];
if (decodeAsLoadout)
{
string quickbeltLayoutName = f.QuickbeltLayoutName;
if (GM.CurrentPlayerBody.DoesQuickbeltNameExist(quickbeltLayoutName))
{
int num = 0;
if (GM.CurrentPlayerBody.SetQuickbeltBasedOnStringName(quickbeltLayoutName, ref num))
{
GM.Options.QuickbeltOptions.QuickbeltPreset = num;
GM.Options.SaveToFile();
}
}
}
Dictionary<VaultElement, FVRPhysicalObject> dicElementToObj = new Dictionary<VaultElement, FVRPhysicalObject>();
OrderedDictionary dicObjectsContainedInIndex = new OrderedDictionary();
for (int o = 0; o < f.Objects.Count; o++)
{
VaultObject obj = f.Objects[o];
if (!IM.OD.ContainsKey(obj.Elements[0].ObjectID) || !IM.HasSpawnedID(IM.OD[obj.Elements[0].ObjectID].SpawnedFromId))
{
continue;
}
for (int e = 0; e < f.Objects[o].Elements.Count; e++)
{
if (IM.HasSpawnedID(IM.OD[obj.Elements[e].ObjectID].SpawnedFromId))
{
yield return ((AnvilAsset)IM.OD[obj.Elements[e].ObjectID]).GetGameObjectAsync();
}
}
}
for (int o2 = 0; o2 < f.Objects.Count; o2++)
{
VaultObject obj2 = f.Objects[o2];
if (!IM.OD.ContainsKey(obj2.Elements[0].ObjectID) || !IM.HasSpawnedID(IM.OD[obj2.Elements[0].ObjectID].SpawnedFromId))
{
continue;
}
GameObject rootObj = null;
List<GameObject> toDealWith = new List<GameObject>();
List<int> validIndexes = new List<int>();
Dictionary<GameObject, VaultElement> dicGO = new Dictionary<GameObject, VaultElement>();
Dictionary<int, GameObject> dicByIndex = new Dictionary<int, GameObject>();
Dictionary<GameObject, int> dicByObj = new Dictionary<GameObject, int>();
List<AnvilCallback<GameObject>> callbackList = new List<AnvilCallback<GameObject>>();
for (int i = 0; i < obj2.Elements.Count; i++)
{
callbackList.Add(((AnvilAsset)IM.OD[obj2.Elements[i].ObjectID]).GetGameObjectAsync());
}
yield return callbackList;
for (int j = 0; j < obj2.Elements.Count; j++)
{
GameObject gameObject = Object.Instantiate<GameObject>(callbackList[j].Result);
if (j == 0)
{
rootObj = gameObject;
}
FVRPhysicalObject component = gameObject.GetComponent<FVRPhysicalObject>();
dicGO.Add(gameObject, obj2.Elements[j]);
dicByIndex.Add(obj2.Elements[j].Index, gameObject);
dicByObj.Add(gameObject, obj2.Elements[j].Index);
dicElementToObj.Add(obj2.Elements[j], component);
component.SetGenericInts(obj2.Elements[j].GenericInts);
component.SetGenericStrings(obj2.Elements[j].GenericStrings);
component.SetGenericVector3s(obj2.Elements[j].GenericVector3s);
component.SetGenericRotations(obj2.Elements[j].GenericRotations);
component.ConfigureFromFlagDic(obj2.Elements[j].Flags.dictionary);
if (j == 0)
{
validIndexes.Add(j);
}
if (obj2.Elements[j].Type == "firearm")
{
FVRFireArm myGun = gameObject.GetComponent<FVRFireArm>();
Vector3 vector = Vector3.zero;
if ((Object)(object)SpawnRelativeTo != (Object)null)
{
vector = SpawnRelativeTo.position;
}
gameObject.transform.position = vector;
gameObject.transform.rotation = Quaternion.identity;
if ((Object)(object)myGun.Magazine != (Object)null && myGun.Magazine.IsIntegrated)
{
myGun.Magazine.ReloadMagWithList(obj2.Elements[j].LoadedRoundsInMag);
}
myGun.SetLoadedChambers(obj2.Elements[j].LoadedRoundsInChambers);
}
else if (obj2.Elements[j].Type == "magazine")
{
toDealWith.Add(gameObject);
FVRFireArmMagazine component2 = gameObject.GetComponent<FVRFireArmMagazine>();
component2.ReloadMagWithList(obj2.Elements[j].LoadedRoundsInMag);
}
else if (obj2.Elements[j].Type == "attachment")
{
toDealWith.Add(gameObject);
}
else if ((Object)(object)gameObject.GetComponent<Speedloader>() != (Object)null && obj2.Elements[j].LoadedRoundsInMag.Count > 0)
{
Speedloader component3 = gameObject.GetComponent<Speedloader>();
component3.ReloadSpeedLoaderWithList(obj2.Elements[j].LoadedRoundsInMag);
}
else if ((Object)(object)gameObject.GetComponent<FVRFireArmClip>() != (Object)null && obj2.Elements[j].LoadedRoundsInMag.Count > 0)
{
FVRFireArmClip component4 = gameObject.GetComponent<FVRFireArmClip>();
component4.ReloadClipWithList(obj2.Elements[j].LoadedRoundsInMag);
}
}
int BreakIterator = 400;
while (toDealWith.Count > 0 && BreakIterator > 0)
{
BreakIterator--;
for (int k = toDealWith.Count - 1; k >= 0; k--)
{
VaultElement vaultElement = dicGO[toDealWith[k]];
if (validIndexes.Contains(vaultElement.ObjectAttachedTo))
{
GameObject gameObject2 = toDealWith[k];
if ((Object)(object)gameObject2.GetComponent<FVRFireArmAttachment>() != (Object)null)
{
FVRFireArmAttachment component5 = gameObject2.GetComponent<FVRFireArmAttachment>();
FVRFireArmAttachmentMount mount = VaultSystem.GetMount(dicByIndex[vaultElement.ObjectAttachedTo], vaultElement.MountAttachedTo);
gameObject2.transform.rotation = Quaternion.LookRotation(vaultElement.OrientationForward, vaultElement.OrientationUp);
gameObject2.transform.position = VaultSystem.GetPositionRelativeToGun(vaultElement, rootObj.transform);
if (component5.CanScaleToMount && mount.CanThisRescale())
{
component5.ScaleToMount(mount);
}
component5.AttachToMount(mount, false);
if (component5 is Suppressor)
{
((Suppressor)((component5 is Suppressor) ? component5 : null)).AutoMountWell();
}
validIndexes.Add(vaultElement.Index);
toDealWith.RemoveAt(k);
}
else if ((Object)(object)gameObject2.GetComponent<FVRFireArmMagazine>() != (Object)null)
{
FVRFireArmMagazine component6 = gameObject2.GetComponent<FVRFireArmMagazine>();
GameObject gameObject3 = dicByIndex[vaultElement.ObjectAttachedTo];
FVRFireArm component7 = gameObject3.GetComponent<FVRFireArm>();
AttachableFirearmPhysicalObject component8 = gameObject3.GetComponent<AttachableFirearmPhysicalObject>();
VaultElement vaultElement2 = dicGO[gameObject2];
if (vaultElement2.MountAttachedTo < 0)
{
if ((Object)(object)component7 != (Object)null)
{
((Component)component6).transform.position = component7.GetMagMountPos(component6.IsBeltBox).position;
((Component)component6).transform.rotation = component7.GetMagMountPos(component6.IsBeltBox).rotation;
component6.Load(component7);
}
if ((Object)(object)component8 != (Object)null)
{
((Component)component6).transform.position = component8.FA.MagazineMountPos.position;
((Component)component6).transform.rotation = component8.FA.MagazineMountPos.rotation;
component6.Load(component8.FA);
}
}
else if ((Object)(object)component7 != (Object)null)
{
((Component)component6).transform.position = component7.SecondaryMagazineSlots[vaultElement2.MountAttachedTo].MagazineMountPos.position;
((Component)component6).transform.rotation = component7.SecondaryMagazineSlots[vaultElement2.MountAttachedTo].MagazineMountPos.rotation;
component6.LoadIntoSecondary(component7, vaultElement2.MountAttachedTo);
}
toDealWith.RemoveAt(k);
}
}
}
}
if (spawnRelativeTo)
{
rootObj.transform.position = SpawnRelativeTo.TransformPoint(obj2.Elements[0].PosOffset) + spawnOffset;
rootObj.transform.rotation = Quaternion.LookRotation(SpawnRelativeTo.TransformDirection(obj2.Elements[0].OrientationForward), SpawnRelativeTo.TransformDirection(obj2.Elements[0].OrientationUp));
}
else if (decodeAsLoadout)
{
rootObj.transform.position = SpawnRelativeTo.position + Vector3.up * 0.3f * (float)o2;
rootObj.transform.rotation = SpawnRelativeTo.rotation;
}
else if (!decodeAsLoadout)
{
rootObj.transform.position = obj2.Elements[0].PosOffset;
rootObj.transform.rotation = Quaternion.LookRotation(obj2.Elements[0].OrientationForward, obj2.Elements[0].OrientationUp);
}
if (obj2.IsContainedIn > -1)
{
Logger.LogMessage((object)(((Object)rootObj.gameObject).name + " is contained in index " + obj2.IsContainedIn));
rootObj.SetActive(false);
dicObjectsContainedInIndex.Add(rootObj, obj2.IsContainedIn);
}
spawnedObjs[obj2.Index] = rootObj.GetComponent<FVRPhysicalObject>();
}
yield return null;
for (int l = 0; l < spawnedObjs.Length; l++)
{
if (f.Objects[l].QuickbeltSlotIndex != -1)
{
if (f.Objects[l].InSlotOfRootObjectIndex == -1 && (Object)(object)spawnedObjs[l].QuickbeltSlot == (Object)null && decodeAsLoadout)
{
Logger.LogMessage((object)(((Object)((Component)spawnedObjs[l]).gameObject).name + " is in a player internal quickbelt slot: " + f.Objects[l].QuickbeltSlotIndex));
spawnedObjs[l].SetQuickBeltSlot(GM.CurrentPlayerBody.QBSlots_Internal[f.Objects[l].QuickbeltSlotIndex]);
}
else if ((Object)(object)spawnedObjs[l].QuickbeltSlot == (Object)null)
{
VaultElement vaultElement3 = f.Objects[f.Objects[l].InSlotOfRootObjectIndex].Elements[f.Objects[l].InSlotOfElementIndex];
FVRPhysicalObject fvrphysicalObject = dicElementToObj[vaultElement3];
FVRQuickBeltSlot fvrquickBeltSlot = fvrphysicalObject.Slots[f.Objects[l].QuickbeltSlotIndex];
spawnedObjs[l].SetQuickBeltSlot(fvrquickBeltSlot);
}
}
}
foreach (KeyValuePair<GameObject, int> keyValuePair in dicObjectsContainedInIndex)
{
FVRPhysicalObject fvrphysicalObject2 = spawnedObjs[keyValuePair.Value];
fvrphysicalObject2.ContainOtherObject(keyValuePair.Key.GetComponent<FVRPhysicalObject>());
}
if (del != null)
{
List<FVRPhysicalObject> list = new List<FVRPhysicalObject>();
for (int m = 0; m < spawnedObjs.Length; m++)
{
list.Add(spawnedObjs[m]);
}
Logger.LogMessage((object)("Delegate found in spawn routine with " + spawnedObjs.Length + " possible objects spawned"));
del.Invoke(list);
}
GM.IsAsyncLoading = false;
GM.CurrentPlayerBody.HideLoadingBar();
}
}
private static ConfigEntry<bool> config_enable_vanilla;
private static ConfigEntry<bool> config_enable_tnh;
private static ConfigEntry<bool> config_enable_modded;
private static ConfigEntry<string> config_exclude_ids;
private static ConfigEntry<string> config_include_ids;
internal static ManualLogSource Logger { get; private set; }
private void Awake()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
Harmony val = new Harmony("NGA.GunCaseFix");
Logger.LogMessage((object)"New harmony");
SetUpConfigFields();
Logger.LogMessage((object)"Setted the fields");
val.PatchAll();
Logger.LogMessage((object)"Hello, world! Sent from NGA.GunCaseFix 0.0.1");
}
private void SetUpConfigFields()
{
}
}
}