using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.SceneManagement;
using WorldDumper.Dumpers;
using WorldDumper.Formats;
using WorldDumper.Jsonl;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("WorldDumper")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Log everything in White Knuckle world. Writes .jsonl files with all events, entites, levels, etc.")]
[assembly: AssemblyFileVersion("0.6.1.0")]
[assembly: AssemblyInformationalVersion("0.6.1+e676f891e750e19658be9647334c427b1b58f5c6")]
[assembly: AssemblyProduct("WorldDumper")]
[assembly: AssemblyTitle("WorldDumper")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.6.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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
[Serializable]
public class Position3
{
public float x = tr.position.x;
public float y = tr.position.y;
public float z = tr.position.z;
public Position3(Transform tr)
{
}//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
}
namespace WorldDumper
{
[BepInPlugin("shishyando.WK.WorldDumper", "WorldDumper", "0.6.1")]
public class WorldDumperPlugin : BaseUnityPlugin
{
internal static WorldDumperPlugin Instance;
internal static ManualLogSource Beep;
private Harmony _harmony;
public static bool Playing;
public static ConfigEntry<string> LogsDir;
public static ConfigEntry<bool> LogGameObjectIds;
public static ConfigEntry<bool> SortLogsAfterRun;
private void Awake()
{
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Expected O, but got Unknown
Instance = this;
Beep = ((BaseUnityPlugin)this).Logger;
LogsDir = ((BaseUnityPlugin)this).Config.Bind<string>("Logging", "Directory", Path.Combine(Paths.BepInExRootPath, "WorldDumperOutput"), "Directory for WorldDumper logs");
LogGameObjectIds = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "LogGameObjectIds", false, "If true, WorldDumper will dump some unique ids (e.g. GameObject.InstanceID, GameObject.SiblingIdx) for game object formats");
SortLogsAfterRun = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "SortLogsAfterRun", false, "If true, WorldDumper will sort the logs after the run (may be useful for diffing)");
_harmony = new Harmony("shishyando.WK.WorldDumper");
Beep.LogInfo((object)"shishyando.WK.WorldDumper is loaded");
SceneManager.sceneUnloaded += OnSceneUnloaded;
SceneManager.sceneLoaded += OnSceneLoaded;
Instance._harmony.PatchAll();
}
public void OnSceneLoaded(Scene s, LoadSceneMode m)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
Beep.LogInfo((object)$"OnSceneLoaded: {((Scene)(ref s)).name} (mode: {m})");
if (((Scene)(ref s)).name == "Game-Main")
{
Start();
}
}
public void OnSceneUnloaded(Scene s)
{
Beep.LogInfo((object)("OnSceneUnloaded: " + ((Scene)(ref s)).name));
if (((Scene)(ref s)).name == "Game-Main")
{
Stop();
}
}
public static void Start()
{
if (!TryToRotateLogs())
{
return;
}
Playing = true;
List<Perk> perkAssets = CL_AssetManager.GetFullCombinedAssetDatabase().perkAssets;
foreach (Perk item in perkAssets)
{
PerkDumper.DumpPerk(item, "GameStart");
}
}
public static void Stop()
{
Playing = false;
Jsonler.DisposeWriters();
}
public static bool TryToRotateLogs()
{
Jsonler.DisposeWriters();
try
{
string text = Path.Combine(Paths.BepInExRootPath, LogsDir.Value + "_prev");
if (Directory.Exists(text))
{
Directory.Delete(text, recursive: true);
}
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
DirectoryInfo directoryInfo = Directory.CreateDirectory(LogsDir.Value);
foreach (FileInfo item in directoryInfo.EnumerateFiles())
{
item.MoveTo(Path.Combine(text, item.Name));
}
return true;
}
catch (Exception arg)
{
Beep.LogError((object)$"Recreating logs directory failed: {arg}");
Stop();
return false;
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "shishyando.WK.WorldDumper";
public const string PLUGIN_NAME = "WorldDumper";
public const string PLUGIN_VERSION = "0.6.1";
}
}
namespace WorldDumper.Patches
{
[HarmonyPatch(typeof(App_PerkPage), "GenerateCards", new Type[] { typeof(bool) })]
public static class App_PerkPage_GenerateCards_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(bool refresh, App_PerkPage __instance)
{
if (WorldDumperPlugin.Playing)
{
PerkDumper.DumpPerkPage(__instance, "App_PerkPage_GenerateCards", refresh);
}
}
}
[HarmonyPatch(typeof(ENV_ArtifactDevice), "Start")]
public static class ENV_ArtifactDevice_Start_Patcher
{
public static readonly FieldRef<ENV_ArtifactDevice, List<Item_Object>> spawnedArtifactsRef = AccessTools.FieldRefAccess<ENV_ArtifactDevice, List<Item_Object>>("spawnedArtifacts");
[HarmonyPriority(0)]
public static void Finalizer(ENV_ArtifactDevice __instance)
{
if (!WorldDumperPlugin.Playing)
{
return;
}
foreach (Item_Object item in spawnedArtifactsRef.Invoke(__instance))
{
ItemObjectDumper.Dump(item, "ENV_ArtifactDevice_Start", ((Component)__instance).transform);
}
}
}
[HarmonyPatch(typeof(ENV_VendingMachine), "GenerateOptions")]
public static class ENV_VendingMachine_GenerateOptions_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(ENV_VendingMachine __instance)
{
if (WorldDumperPlugin.Playing)
{
VendingMachineDumper.Dump(__instance, "ENV_VendingMachine_GenerateOptions");
}
}
}
[HarmonyPatch(typeof(GameEntity), "Start")]
public static class GameEntity_Start_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(GameEntity __instance)
{
if (WorldDumperPlugin.Playing)
{
GameEntityDumper.Dump(__instance, "GameEntity_Start");
}
}
}
[HarmonyPatch(typeof(Item_Object), "Start")]
public static class Item_Object_Start_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(Item_Object __instance)
{
if (WorldDumperPlugin.Playing)
{
ItemObjectDumper.Dump(__instance, "Item_Object_Start");
}
}
}
[HarmonyPatch(typeof(M_Level), "Initialize")]
public static class M_Level_Initialize_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(M_Level __instance)
{
if (WorldDumperPlugin.Playing)
{
LevelDumper.Dump(__instance, "M_Level_Initialize");
}
}
}
[HarmonyPatch(typeof(SessionEvent), "StartEvent")]
public static class SessionEvent_StartEvent_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(SessionEvent __instance)
{
if (WorldDumperPlugin.Playing)
{
SessionEventDumper.Dump(__instance, "SessionEvent_StartEvent");
}
}
}
[HarmonyPatch(typeof(UT_ObjectSpawner), "Spawn", new Type[] { })]
public static class UT_ObjectSpawner_Spawn_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(UT_ObjectSpawner __instance)
{
if (WorldDumperPlugin.Playing)
{
GameObjectDumper.Dump(((Component)__instance).gameObject, "UT_ObjectSpawner_Spawn");
}
}
}
[HarmonyPatch(typeof(UT_ObjectSpawner), "Spawn", new Type[] { typeof(GameObject) })]
public static class UT_ObjectSpawner_SpawnGameObject_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(GameObject o)
{
if (WorldDumperPlugin.Playing)
{
GameObjectDumper.Dump(o, "UT_ObjectSpawner_SpawnGameObject");
}
}
}
[HarmonyPatch(typeof(UT_ObjectSpawner), "SpawnAtTransform")]
public static class UT_ObjectSpawner_SpawnAtTransform_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(UT_ObjectSpawner __instance)
{
if (WorldDumperPlugin.Playing && (Object)(object)__instance.spawnObject != (Object)null)
{
GameObjectDumper.Dump(__instance.spawnObject, "UT_ObjectSpawner_SpawnAtTransform");
}
}
}
[HarmonyPatch(typeof(UT_RadiusSpawner), "Spawn")]
public static class UT_RadiusSpawner_Spawn_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(UT_RadiusSpawner __instance)
{
if (!WorldDumperPlugin.Playing)
{
return;
}
if ((Object)(object)__instance.spawnTable != (Object)null)
{
try
{
SpawnTableAsset randomSpawnObject = __instance.spawnTable.GetRandomSpawnObject();
if (randomSpawnObject != null)
{
GameObject randomPrefab = randomSpawnObject.GetRandomPrefab();
if ((Object)(object)randomPrefab != (Object)null)
{
GameObjectDumper.Dump(randomPrefab, "UT_RadiusSpawner_SpawnTable");
}
}
}
catch (Exception ex)
{
Debug.LogWarning((object)("Failed to dump spawn table object: " + ex.Message));
}
}
if (__instance.spawnObjects == null || __instance.spawnObjects.Count <= 0)
{
return;
}
foreach (GameObject spawnObject in __instance.spawnObjects)
{
if ((Object)(object)spawnObject != (Object)null)
{
GameObjectDumper.Dump(spawnObject, "UT_RadiusSpawner_SpawnObjects");
}
}
}
}
[HarmonyPatch(typeof(UT_SpawnChance), "Start")]
public static class UT_SpawnChance_Start_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(UT_SpawnChance __instance)
{
if (WorldDumperPlugin.Playing)
{
GameObjectDumper.Dump(((Component)__instance).gameObject, "UT_SpawnChance_Start");
}
}
}
[HarmonyPatch(typeof(UT_SpawnEntity), "Spawn")]
public static class UT_SpawnEntity_Spawn_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(UT_SpawnEntity __instance)
{
if (!WorldDumperPlugin.Playing)
{
return;
}
if (__instance.randomizeObjects != null && __instance.randomizeObjects.Count > 0)
{
foreach (GameObject randomizeObject in __instance.randomizeObjects)
{
if ((Object)(object)randomizeObject != (Object)null)
{
GameObjectDumper.Dump(randomizeObject, "UT_SpawnEntity_RandomizeObjects");
}
}
}
if ((Object)(object)__instance.spawnObject != (Object)null)
{
GameObjectDumper.Dump(__instance.spawnObject, "UT_SpawnEntity_SpawnObject");
}
}
}
[HarmonyPatch(typeof(UT_SpawnEntity), "SpawnCustom")]
public static class UT_SpawnEntity_SpawnCustom_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(GameObject g)
{
if (WorldDumperPlugin.Playing && (Object)(object)g != (Object)null)
{
GameObjectDumper.Dump(g, "UT_SpawnEntity_SpawnCustom");
}
}
}
[HarmonyPatch(typeof(UT_SPT_Spawner), "Spawn")]
public static class UT_SPT_Spawner_Spawn_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(UT_SPT_Spawner __instance)
{
if (!WorldDumperPlugin.Playing || !((Object)(object)__instance.spawnTable != (Object)null))
{
return;
}
try
{
SpawnTableAsset randomSpawnObject = __instance.spawnTable.GetRandomSpawnObject();
if (randomSpawnObject != null && randomSpawnObject.prefabs != null)
{
GameObject randomPrefab = randomSpawnObject.GetRandomPrefab();
if ((Object)(object)randomPrefab != (Object)null)
{
GameObjectDumper.Dump(randomPrefab, "UT_SPT_Spawner_SpawnTable");
}
}
}
catch (Exception ex)
{
Debug.LogWarning((object)("Failed to dump spawn table object: " + ex.Message));
}
}
}
[HarmonyPatch(typeof(UT_TriggerSpawner), "Spawn")]
public static class UT_TriggerSpawner_Spawn_Patcher
{
[HarmonyPriority(0)]
public static void Finalizer(UT_TriggerSpawner __instance)
{
if (!WorldDumperPlugin.Playing)
{
return;
}
if ((Object)(object)__instance.spawnTable != (Object)null)
{
try
{
SpawnTableAsset randomSpawnObject = __instance.spawnTable.GetRandomSpawnObject();
if (randomSpawnObject != null)
{
GameObject randomPrefab = randomSpawnObject.GetRandomPrefab();
if ((Object)(object)randomPrefab != (Object)null)
{
GameObjectDumper.Dump(randomPrefab, "UT_TriggerSpawner_SpawnTable");
}
}
}
catch (Exception ex)
{
Debug.LogWarning((object)("Failed to dump spawn table object: " + ex.Message));
}
}
if (__instance.spawnObjects == null || __instance.spawnObjects.Count <= 0)
{
return;
}
foreach (GameObject spawnObject in __instance.spawnObjects)
{
if ((Object)(object)spawnObject != (Object)null)
{
GameObjectDumper.Dump(spawnObject, "UT_TriggerSpawner_SpawnObjects");
}
}
}
}
}
namespace WorldDumper.Jsonl
{
public static class Jsonler
{
private static readonly ConcurrentDictionary<string, Lazy<TextWriter>> Writers = new ConcurrentDictionary<string, Lazy<TextWriter>>();
private static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings
{
ReferenceLoopHandling = (ReferenceLoopHandling)1,
Formatting = (Formatting)0,
NullValueHandling = (NullValueHandling)0
};
public static void Dump<T>(T data, string prefix)
{
if (data != null)
{
string path = Path.Combine(WorldDumperPlugin.LogsDir.Value, prefix + "_" + typeof(T).Name + ".jsonl");
string line = JsonConvert.SerializeObject((object)data, SerializerSettings);
WriteLine(path, line);
}
}
public static void DisposeWriters()
{
foreach (KeyValuePair<string, Lazy<TextWriter>> writer in Writers)
{
if (writer.Value.IsValueCreated)
{
writer.Value.Value.Dispose();
}
}
if (WorldDumperPlugin.SortLogsAfterRun.Value)
{
foreach (string key in Writers.Keys)
{
string[] array = File.ReadAllLines(key, Encoding.UTF8);
Array.Sort(array, (IComparer<string>?)StringComparer.Ordinal);
File.WriteAllLines(key, array, Encoding.UTF8);
}
}
Writers.Clear();
}
private static void WriteLine(string path, string line)
{
TextWriter value = Writers.GetOrAdd(path, CreateLazy).Value;
value.WriteLine(line);
}
private static Lazy<TextWriter> CreateLazy(string path)
{
return new Lazy<TextWriter>(delegate
{
FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
StreamWriter writer = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), 65536)
{
AutoFlush = true,
NewLine = "\n"
};
return TextWriter.Synchronized(writer);
}, LazyThreadSafetyMode.ExecutionAndPublication);
}
}
}
namespace WorldDumper.Formats
{
[Serializable]
public class GameEntityFormat
{
public string EntityID;
public GameObjectFormat GameObject;
public string EntityType;
public string Tag;
public Position3 Position;
public LevelFormat Level;
}
[Serializable]
public class GameObjectFormat
{
public string Name;
public string ParentName;
public string Path;
public Position3 Position;
public bool Active;
public int InstanceId;
public int SiblingIdx;
}
[Serializable]
public class ItemObjectFormat
{
public string PrefabName;
public string ItemName;
public string ItemTag;
public GameObjectFormat GameObject;
public LevelFormat Level;
}
[Serializable]
public class LevelFormat
{
public string LevelName;
public string RegionName;
public string SubregionName;
public int Seed;
public bool IsLastLevel;
public bool Flipped;
public bool Active;
public int InstanceId;
}
[Serializable]
public class PerkPageFormat
{
public string PerkPageType;
public GameObjectFormat GameObject;
public int Seed;
public int MinCards;
public int MaxCards;
public List<PerkCardFormat> PerkCards;
public bool AfterRefresh;
}
[Serializable]
public class PerkCardFormat
{
public string Name;
public PerkFormat PerkInfo;
}
[Serializable]
public class PerkFormat
{
public string Title;
public string Description;
public string Id;
public int Cost;
public string SpawnPool;
}
[Serializable]
public class SessionEventFormat
{
public string Id;
public string StartCheck;
public List<string> EventModules;
public LevelFormat StartLevel;
}
[Serializable]
public class VendingPurchaseFormat
{
public string PrefabName;
public float Chance;
public int Price;
}
[Serializable]
public class VendingMachineFormat
{
public string VendorId;
public VendingPurchaseFormat[] PurchaseArray;
public int LocalSeed;
public bool RandomGeneration;
public LevelFormat Level;
public GameObjectFormat GameObject;
}
}
namespace WorldDumper.Dumpers
{
public static class AsIsDumper
{
public static void Dump<T>(T obj, string preifx)
{
Jsonler.Dump(obj, preifx);
}
}
public static class GameEntityDumper
{
public static void Dump(GameEntity e, string prefix)
{
GameEntityFormat data = new GameEntityFormat
{
EntityID = e.entityPrefabID,
EntityType = e.objectType,
Tag = ((Component)e).tag,
Position = new Position3(((Component)e).gameObject.transform),
Level = LevelDumper.FormatLevelOf(((Component)e).transform),
GameObject = GameObjectDumper.FormatGameObject(((Component)e).gameObject)
};
Jsonler.Dump(data, prefix + "_" + ((Component)e).tag);
}
}
public static class GameObjectDumper
{
public static void Dump(GameObject obj, string prefix)
{
Jsonler.Dump(FormatGameObject(obj), prefix);
}
public static GameObjectFormat FormatGameObject(GameObject obj)
{
GameObjectFormat obj2 = new GameObjectFormat
{
Name = ((Object)obj).name,
Position = new Position3(obj.transform)
};
Transform parent = obj.transform.parent;
object obj3;
if (parent == null)
{
obj3 = null;
}
else
{
GameObject gameObject = ((Component)parent).gameObject;
obj3 = ((gameObject != null) ? ((Object)gameObject).name : null);
}
if (obj3 == null)
{
obj3 = "<root>";
}
obj2.ParentName = (string)obj3;
obj2.Path = GetPath(obj.transform);
obj2.Active = obj.activeSelf;
obj2.InstanceId = (WorldDumperPlugin.LogGameObjectIds.Value ? ((Object)obj).GetInstanceID() : 0);
obj2.SiblingIdx = (WorldDumperPlugin.LogGameObjectIds.Value ? obj.transform.GetSiblingIndex() : 0);
return obj2;
}
private static string GetPath(Transform t)
{
StringBuilder stringBuilder = new StringBuilder(((Object)t).name);
Transform parent = t.parent;
while ((Object)(object)parent != (Object)null)
{
stringBuilder.Insert(0, ((Object)parent).name + "/");
parent = parent.parent;
}
return stringBuilder.ToString();
}
}
public static class ItemObjectDumper
{
public static void Dump(Item_Object obj, string prefix, Transform customTr = null, bool dumpGameObject = true)
{
Jsonler.Dump(FormatItemObject(obj, customTr, dumpGameObject), prefix);
}
public static ItemObjectFormat FormatItemObject(Item_Object it, Transform customTr = null, bool dumpGameObject = false)
{
return new ItemObjectFormat
{
ItemName = it.itemData.itemName,
ItemTag = it.itemData.itemTag,
PrefabName = it.itemData.prefabName,
GameObject = (dumpGameObject ? GameObjectDumper.FormatGameObject(((Component)it).gameObject) : null),
Level = (LevelDumper.FormatLevelOf(customTr) ?? LevelDumper.FormatLevelOf(((Component)it).transform) ?? null)
};
}
}
public static class LevelDumper
{
public static readonly FieldRef<M_Level, bool> flippedRef = AccessTools.FieldRefAccess<M_Level, bool>("flipped");
public static void Dump(M_Level lvl, string prefix)
{
Jsonler.Dump(FormatLevel(lvl), prefix);
}
public static LevelFormat FormatLevel(M_Level lvl)
{
return new LevelFormat
{
InstanceId = (WorldDumperPlugin.LogGameObjectIds.Value ? ((Object)lvl).GetInstanceID() : 0),
LevelName = lvl.levelName,
IsLastLevel = lvl.lastLevel,
RegionName = (lvl.region?.regionName ?? "no_region_name"),
SubregionName = (lvl.subRegion?.subregionName ?? "no_subregion_name"),
Flipped = flippedRef.Invoke(lvl),
Seed = lvl.GetLevelSeed(),
Active = ((Component)lvl).gameObject.activeSelf
};
}
public static LevelFormat FormatLevelOf(Transform tr)
{
M_Level val = LevelOf(tr);
return Object.op_Implicit((Object)(object)val) ? FormatLevel(val) : null;
}
public static M_Level LevelOf(Transform tr)
{
if ((Object)(object)tr == (Object)null)
{
return null;
}
return ((Component)tr).GetComponentInParent<M_Level>(true);
}
}
public static class PerkDumper
{
public static readonly FieldRef<App_PerkPage, List<App_PerkPage_Card>> cardsRef = AccessTools.FieldRefAccess<App_PerkPage, List<App_PerkPage_Card>>("cards");
private static readonly FieldRef<App_PerkPage, OS_Manager> osRef = (FieldRef<App_PerkPage, OS_Manager>)(object)AccessTools.FieldRefAccess<OS_Manager>(typeof(App_PerkPage), "os");
public static void DumpPerkPage(App_PerkPage page, string prefix, bool refresh)
{
PerkPageFormat perkPageFormat = new PerkPageFormat();
perkPageFormat.PerkPageType = ((object)(PerkPageType)(ref page.perkPageType)).ToString();
perkPageFormat.GameObject = GameObjectDumper.FormatGameObject(((Component)page).gameObject);
perkPageFormat.Seed = osRef.Invoke(page).worldInterface.GetSeed();
perkPageFormat.MinCards = page.minCards;
perkPageFormat.MaxCards = page.maxCards;
perkPageFormat.PerkCards = cardsRef.Invoke(page).ConvertAll(ConvertPerkCard);
perkPageFormat.AfterRefresh = refresh;
PerkPageFormat perkPageFormat2 = perkPageFormat;
perkPageFormat2.GameObject.Position = new Position3(((Component)osRef.Invoke(page).worldInterface).transform);
Jsonler.Dump(perkPageFormat2, prefix);
}
public static PerkCardFormat ConvertPerkCard(App_PerkPage_Card card)
{
return new PerkCardFormat
{
Name = ((Object)card).name,
PerkInfo = FormatPerk(card.perk)
};
}
public static void DumpPerk(Perk perk, string prefix)
{
Jsonler.Dump(FormatPerk(perk), prefix);
}
public static PerkFormat FormatPerk(Perk perk)
{
return new PerkFormat
{
Title = perk.GetTitle(false),
Description = perk.GetDescription(false, false, false),
Id = perk.id,
Cost = perk.cost,
SpawnPool = ((object)(PerkPool)(ref perk.spawnPool)).ToString()
};
}
}
public static class SessionEventDumper
{
public static readonly FieldRef<SessionEvent, M_Level> startLevelRef = AccessTools.FieldRefAccess<SessionEvent, M_Level>("startLevel");
public static void Dump(SessionEvent e, string prefix)
{
SessionEventFormat data = new SessionEventFormat
{
Id = e.id,
StartCheck = ((object)(EventStart)(ref e.startCheck)).ToString(),
EventModules = e.modules.ConvertAll((SessionEventModule x) => x.name),
StartLevel = LevelDumper.FormatLevel(startLevelRef.Invoke(e))
};
Jsonler.Dump(data, prefix);
}
}
public static class VendingMachineDumper
{
public static readonly FieldRef<ENV_VendingMachine, int> localSeedRef = AccessTools.FieldRefAccess<ENV_VendingMachine, int>("localSeed");
public static void Dump(ENV_VendingMachine vendo, string prefix)
{
VendingMachineFormat vendingMachineFormat = new VendingMachineFormat();
vendingMachineFormat.VendorId = vendo.vendorId;
vendingMachineFormat.PurchaseArray = Array.ConvertAll(vendo.buttons, GetPurchase);
vendingMachineFormat.LocalSeed = localSeedRef.Invoke(vendo);
vendingMachineFormat.RandomGeneration = vendo.randomGeneration;
vendingMachineFormat.Level = LevelDumper.FormatLevelOf(((Component)vendo).transform);
vendingMachineFormat.GameObject = GameObjectDumper.FormatGameObject(((Component)vendo).gameObject);
VendingMachineFormat data = vendingMachineFormat;
Jsonler.Dump(data, prefix);
}
public static VendingPurchaseFormat GetPurchase(VendingButton button)
{
return new VendingPurchaseFormat
{
PrefabName = ((Object)button.purchase.itemObject).name,
Chance = button.purchase.chance,
Price = button.purchase.price
};
}
}
}