using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using OutwardModsCommunicator.EventBus;
using OutwardSceneTester.Managers;
using OutwardSceneTester.Scene;
using OutwardSceneTester.Utility.Helpers;
using SceneTester;
using SideLoader;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OutwardModPackTemplate")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OutwardModPackTemplate")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c5450fe0-edcf-483f-b9ea-4b1ef9d36da7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace SceneTester
{
[BepInPlugin("gymmed.scene_tester", "Scene Tester", "0.0.3")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class ST : BaseUnityPlugin
{
[HarmonyPatch(typeof(ResourcesPrefabManager), "Load")]
public class ResourcesPrefabManager_Load
{
private static void Postfix(ResourcesPrefabManager __instance)
{
}
}
public const string GUID = "gymmed.scene_tester";
public const string NAME = "Scene Tester";
public const string VERSION = "0.0.3";
public static string prefix = "[Scene-Tester]";
public const string EVENT_LISTENER_GUID = "gymmed.scene_tester_*";
public static bool hasStartedLooping = false;
public const string SCENE_TESTER_KEY = "Scene Tester Start/Stop Looping";
internal static ManualLogSource Log;
internal void Awake()
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
LogMessage("Hello world from Scene Tester 0.0.3!");
CustomKeybindings.AddAction("Scene Tester Start/Stop Looping", (KeybindingsCategory)0, (ControlType)2, (InputType)1);
new Harmony("gymmed.scene_tester").PatchAll();
EventBus.RegisterEvent("gymmed.scene_tester_*", "AddSceneLoopAction", "Add scene loop action. Provided action will execute on each area load. After each area is looped will notify with FinishedSceneLoopAction. Tip: you can store scene data in static variables to outlive and not be deleted by garbage collector.", new(string, Type, string)[3]
{
("actionId", typeof(string), "Optional. You will need this as unique value if you want to tack(remove/listen for finish) action execution."),
("action", typeof(Action), "Required. Action to execute after each area load."),
("hashSetOfAreas", typeof(HashSet<AreaEnum>), "Required. HashSet of AreaManager.AreaEnum to fast loop through and execute \"action\" on.")
});
EventBus.RegisterEvent("gymmed.scene_tester_*", "RemoveSceneLoopAction", "Remove specific scene loop action from rules list.", new(string, Type, string)[1] { ("actionId", typeof(string), "Required. Scene loop action id that will be removed.") });
EventBus.RegisterEvent("gymmed.scene_tester", "FinishedSceneLoopAction", "Notifies which scene loop action rule looped through all of his areas.", new(string, Type, string)[1] { ("actionId", typeof(string), "Finished scene loop action id.") });
EventBus.Subscribe("gymmed.scene_tester_*", "AddSceneLoopAction", (Action<EventPayload>)SceneActionManager.Instance.AddSceneLoopAction);
EventBus.Subscribe("gymmed.scene_tester_*", "RemoveSceneLoopAction", (Action<EventPayload>)SceneActionManager.Instance.RemoveSceneLoopAction);
SceneActionManager.Instance.AddSceneLoadSubscribtion();
}
internal void Update()
{
if (CustomKeybindings.GetKeyDown("Scene Tester Start/Stop Looping"))
{
if (hasStartedLooping)
{
hasStartedLooping = false;
SceneActionManager.Instance.CurrentSceneLoop = 0;
}
else if (!(SceneManagerHelper.ActiveSceneName == "LowMemory_TransitionScene") && !(SceneManagerHelper.ActiveSceneName == "MainMenu_Empty"))
{
hasStartedLooping = true;
SceneActionManager.Instance.TryToLoadNextScene();
}
}
}
public static void LogMessage(string message)
{
Log.LogMessage((object)(prefix + " " + message));
}
public static void LogSL(string message)
{
SL.Log(prefix + " " + message);
}
public static string GetProjectLocation()
{
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
}
}
namespace OutwardSceneTester.Utility.Helpers
{
public static class AreaHelpers
{
public static void TravelTo(AreaEnum area)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Invalid comparison between Unknown and I4
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
if ((int)area == 205)
{
ST.LogMessage("Trying to load Hallowed_Dungeon4 (Dark Ziggurat), which doesn't work! You should use Hallowed_Dungeon4_Interior (Dark Ziggurat Interior) instead!");
}
TravelData val = new TravelData();
val.RationCost = 0;
val.SilverCost = 0;
val.From = GetAreaEnumFromArea(AreaManager.Instance.CurrentArea);
val.Destination = area;
ProceedFastTravel(Global.Lobby.PlayersInLobby[0].ControlledCharacter, val);
}
public static void ProceedFastTravel(Character _instigator, TravelData _travelData)
{
if (NetworkLevelLoader.Instance.GetAllPlayerCanTravel() && GetAllPlayersOwnDLC(_instigator, _notifyOnFail: true))
{
CharacterManager.Instance.SendMerchantFastTravel(_instigator, _travelData);
}
}
public static bool GetAllPlayersOwnDLC(Character _instigator, bool _notifyOnFail = false)
{
bool allPlayersOwnDLC = CharacterManager.Instance.GetAllPlayersOwnDLC((DLCs)2);
if (!allPlayersOwnDLC && _notifyOnFail && Object.op_Implicit((Object)(object)_instigator) && Object.op_Implicit((Object)(object)_instigator.CharacterUI))
{
_instigator.CharacterUI.ShowInfoNotificationLoc("Notification_Interaction_DLCRequiredCOOP", new string[1] { StoreManager.Instance.GetDLCName((DLCs)2) });
}
return allPlayersOwnDLC;
}
public static AreaEnum GetAreaEnumFromArea(Area area)
{
return (AreaEnum)area.ID;
}
}
}
namespace OutwardSceneTester.Scene
{
public class SceneActionRule
{
public string ID { get; set; }
public Action ProvidedFunction { get; set; }
public HashSet<AreaEnum> Areas { get; set; }
public HashSet<AreaEnum> VisitedAreas { get; set; }
public SceneActionRule(Action providedFunction, HashSet<AreaEnum> areas)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
UID val = UID.Generate();
ID = ((UID)(ref val)).Value;
ProvidedFunction = providedFunction;
Areas = areas ?? new HashSet<AreaEnum>();
VisitedAreas = new HashSet<AreaEnum>();
}
public SceneActionRule(string id, Action providedFunction, HashSet<AreaEnum> areas)
{
ID = id;
ProvidedFunction = providedFunction;
Areas = areas ?? new HashSet<AreaEnum>();
VisitedAreas = new HashSet<AreaEnum>();
}
public HashSet<AreaEnum> GetUnvisitedAreas()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: 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)
HashSet<AreaEnum> hashSet = new HashSet<AreaEnum>();
foreach (AreaEnum area in Areas)
{
if (!VisitedAreas.TryGetValue(area, out var _))
{
hashSet.Add(area);
}
}
return hashSet;
}
public bool IsMatching()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
foreach (AreaEnum unvisitedArea in GetUnvisitedAreas())
{
if (AreaManager.Instance.CurrentArea.ID == AreaManager.Instance.GetArea(unvisitedArea).ID)
{
return true;
}
}
return false;
}
public void ValidateRule()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
if (IsMatching() && ProvidedFunction != null)
{
ProvidedFunction();
VisitedAreas.Add(GetAreaEnumFromArea(AreaManager.Instance.CurrentArea));
}
}
public static AreaEnum GetAreaEnumFromArea(Area area)
{
return (AreaEnum)area.ID;
}
}
}
namespace OutwardSceneTester.Managers
{
public class SceneActionManager
{
private static SceneActionManager _instance;
private int currentSceneLoop;
private List<SceneActionRule> sceneActions = new List<SceneActionRule>();
public static SceneActionManager Instance
{
get
{
if (_instance == null)
{
_instance = new SceneActionManager();
}
return _instance;
}
}
public int CurrentSceneLoop
{
get
{
return currentSceneLoop;
}
set
{
currentSceneLoop = value;
}
}
private SceneActionManager()
{
}
public void AddSceneLoadSubscribtion()
{
SL.OnSceneLoaded += delegate
{
TryToLoadNextScene();
};
}
public void TryToLoadNextScene()
{
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
try
{
if (SceneManagerHelper.ActiveSceneName == "LowMemory_TransitionScene" || SceneManagerHelper.ActiveSceneName == "MainMenu_Empty" || !ST.hasStartedLooping)
{
return;
}
foreach (SceneActionRule sceneAction in sceneActions)
{
Instance.TryExecuteAction(sceneAction);
}
if (sceneActions.Count > 0)
{
AreaHelpers.TravelTo(sceneActions[0].GetUnvisitedAreas().First());
}
}
catch (Exception ex)
{
ST.LogMessage("SceneActionManager@TryToLoadNextScene received an error: \"" + ex.Message + "\"!");
}
}
public void RemoveSceneLoopAction(EventPayload payload)
{
if (payload == null)
{
return;
}
string id = payload.Get<string>("actionId", (string)null);
if (string.IsNullOrEmpty(id))
{
return;
}
foreach (SceneActionRule item in sceneActions.Where((SceneActionRule action) => id == action.ID))
{
FinishedLoopAction(item);
}
sceneActions.RemoveAll((SceneActionRule action) => id == action.ID);
}
public void AddSceneLoopAction(EventPayload payload)
{
if (payload == null)
{
return;
}
Action action = payload.Get<Action>("action", (Action)null);
if (action == null)
{
return;
}
HashSet<AreaEnum> hashSet = payload.Get<HashSet<AreaEnum>>("hashSetOfAreas", new HashSet<AreaEnum>());
if (hashSet.Count >= 1)
{
string text = payload.Get<string>("actionId", (string)null);
if (string.IsNullOrEmpty(text))
{
sceneActions.Add(new SceneActionRule(action, hashSet));
}
else
{
sceneActions.Add(new SceneActionRule(text, action, hashSet));
}
}
}
public void TryExecuteAction(SceneActionRule rule)
{
try
{
NetworkLevelLoader.Instance.SetContinueAfterLoading();
rule.ValidateRule();
if (rule.VisitedAreas.Count == rule.Areas.Count)
{
FinishedLoopAction(rule);
sceneActions.Remove(rule);
}
}
catch (Exception ex)
{
ST.LogMessage("SceneActionManager@TryExecuteAction received an error: \"" + ex.Message + "\"!");
}
}
public static void FinishedLoopAction(SceneActionRule rule)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0017: Expected O, but got Unknown
EventPayload val = new EventPayload();
((Dictionary<string, object>)val)["actionId"] = rule.ID;
EventPayload val2 = val;
EventBus.Publish("gymmed.scene_tester", "FinishedSceneLoopAction", val2);
}
}
}