diff --git a/Assets/Dumper/DUMPDATA/botReqData.json b/Assets/Dumper/DUMPDATA/botReqData.json
new file mode 100644
index 0000000..2c8cffb
--- /dev/null
+++ b/Assets/Dumper/DUMPDATA/botReqData.json
@@ -0,0 +1,39 @@
+
+[
+ {"Role":"assault","Limit":2,"Difficulty":"easy"},
+ {"Role":"assault","Limit":2,"Difficulty":"normal"},
+ {"Role":"assault","Limit":2,"Difficulty":"hard"},
+ {"Role":"marksman","Limit":2,"Difficulty":"normal"},
+ {"Role":"marksman","Limit":2,"Difficulty":"hard"},
+ {"Role":"pmcBot","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossGluhar","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerGluharAssault","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerGluharSecurity","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerGluharScout","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossKolontay","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerKolontayAssault","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerKolontaySecurity","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossBoar","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerBoar","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerBoarClose1","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerBoarClose2","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossBoarSniper","Limit":2,"Difficulty":"normal"},
+ {"Role":"exUsec","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossZryachiy","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerZryachiy","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossKnight","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerBigPipe","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerBirdEye","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossBully","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerBully","Limit":2,"Difficulty":"normal"},
+ {"Role":"sectantPriest","Limit":2,"Difficulty":"normal"},
+ {"Role":"sectantWarrior","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossTagilla","Limit":2,"Difficulty":"normal"},
+ {"Role":"gifter","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossSanitar","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossKilla","Limit":2,"Difficulty":"normal"},
+ {"Role":"bossKojaniy","Limit":2,"Difficulty":"normal"},
+ {"Role":"followerKojaniy","Limit":2,"Difficulty":"normal"},
+ {"Role":"skier","Limit":2,"Difficulty":"normal"},
+ {"Role":"peacemaker","Limit":2,"Difficulty":"normal"}
+]
diff --git a/Assets/Dumper/DUMPDATA/config.json b/Assets/Dumper/DUMPDATA/config.json
new file mode 100644
index 0000000..4598933
--- /dev/null
+++ b/Assets/Dumper/DUMPDATA/config.json
@@ -0,0 +1,15 @@
+{
+ "Name": "Dumper",
+ "MapNames": [ "Interchange", "factory4_day", "laboratory", "bigmap", "Lighthouse", "RezervBase", "Sandbox", "Sandbox_high", "Shoreline", "TarkovStreets", "Woods" ],
+ "DateTimeFormat": "yyyy-MM-dd_HH-mm-ss",
+ "QuickDumpEnabled": true,
+ "SptTimings": {
+ "SingleIterationDelayMs": 10000,
+ "AllIterationDelayMs": 300000
+ },
+ "SptReflections": {
+ "MainUrlPropName": "get_MainURLFull",
+ "ParamFieldName": "Params",
+ "RequestFieldName": "responseText"
+ }
+}
\ No newline at end of file
diff --git a/Assets/Dumper/DUMPDATA/raidSettings.json b/Assets/Dumper/DUMPDATA/raidSettings.json
new file mode 100644
index 0000000..f48c7eb
--- /dev/null
+++ b/Assets/Dumper/DUMPDATA/raidSettings.json
@@ -0,0 +1,7 @@
+{
+ "serverId": null,
+ "location": "Lighthouse",
+ "timeVariant": "CURR",
+ "mode": "PVE_OFFLINE",
+ "playerSide": "Pmc"
+}
\ No newline at end of file
diff --git a/Assets/Dumper/DumpLib.dll b/Assets/Dumper/DumpLib.dll
new file mode 100644
index 0000000..bd93e8d
Binary files /dev/null and b/Assets/Dumper/DumpLib.dll differ
diff --git a/Templates/MappingTemplate.jsonc b/Assets/Templates/MappingTemplate.jsonc
similarity index 100%
rename from Templates/MappingTemplate.jsonc
rename to Assets/Templates/MappingTemplate.jsonc
diff --git a/Templates/Settings.jsonc b/Assets/Templates/Settings.jsonc
similarity index 100%
rename from Templates/Settings.jsonc
rename to Assets/Templates/Settings.jsonc
diff --git a/de4dot/AssemblyData.dll b/Assets/de4dot/AssemblyData.dll
similarity index 100%
rename from de4dot/AssemblyData.dll
rename to Assets/de4dot/AssemblyData.dll
diff --git a/de4dot/de4dot.blocks.dll b/Assets/de4dot/de4dot.blocks.dll
similarity index 100%
rename from de4dot/de4dot.blocks.dll
rename to Assets/de4dot/de4dot.blocks.dll
diff --git a/de4dot/de4dot.code.dll b/Assets/de4dot/de4dot.code.dll
similarity index 100%
rename from de4dot/de4dot.code.dll
rename to Assets/de4dot/de4dot.code.dll
diff --git a/de4dot/de4dot.cui.dll b/Assets/de4dot/de4dot.cui.dll
similarity index 100%
rename from de4dot/de4dot.cui.dll
rename to Assets/de4dot/de4dot.cui.dll
diff --git a/de4dot/de4dot.exe b/Assets/de4dot/de4dot.exe
similarity index 100%
rename from de4dot/de4dot.exe
rename to Assets/de4dot/de4dot.exe
diff --git a/de4dot/de4dot.mdecrypt.dll b/Assets/de4dot/de4dot.mdecrypt.dll
similarity index 100%
rename from de4dot/de4dot.mdecrypt.dll
rename to Assets/de4dot/de4dot.mdecrypt.dll
diff --git a/de4dot/dnlib.dll b/Assets/de4dot/dnlib.dll
similarity index 100%
rename from de4dot/dnlib.dll
rename to Assets/de4dot/dnlib.dll
diff --git a/DumpLib/DumpLib.csproj b/DumpLib/DumpLib.csproj
new file mode 100644
index 0000000..5370cef
--- /dev/null
+++ b/DumpLib/DumpLib.csproj
@@ -0,0 +1,20 @@
+
+
+
+ net471
+ DumpLib
+ 1.0.0
+ latestmajor
+ enable
+ enable
+ ..\Assets\Dumper
+
+
+
+
+
+
+
+
+
+
diff --git a/DumpLib/DumpyTool.cs b/DumpLib/DumpyTool.cs
new file mode 100644
index 0000000..8f5ed20
--- /dev/null
+++ b/DumpLib/DumpyTool.cs
@@ -0,0 +1,338 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using DumpLib.Helpers;
+using DumpLib.Models;
+
+namespace DumpLib
+{
+ public static class DumpyTool
+ {
+ ///
+ ///
+ ///
+ public static string DumpDataPath = (Directory.GetCurrentDirectory() + "\\DUMPDATA\\").Replace("\\\\", "\\");
+
+ public static SptConfigClass ConfigSettings = (SptConfigClass)GetSptConfig();
+
+ ///
+ /// always start from 1 as their iterations are 1 to 6
+ ///
+ public static int Iteration = 1;
+
+ ///
+ /// Method to create a "combined" Type that takes a GenericType
+ /// Example: ClientApplication + GInterface145 = ClientApplication(GInterface145)
+ ///
+ /// Object (Type)
+ /// Object (Type)
+ /// Type
+ public static Type CreateGenericType(object firstType, object secondType)
+ {
+ try
+ {
+ return (firstType as Type).MakeGenericType(new Type[] { secondType as Type });
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("CreateCombinedType");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static MethodInfo CreateDeserializerMethod(object type)
+ {
+ try
+ {
+ return ReflectionHelper.GetDeserializerMethodInfo().MakeGenericMethod(new Type[] { type as Type });
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("CreateCombinedMethod");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public static object CreateBackendSessionAndTarkovApp(out object tarkovApp)
+ {
+ try
+ {
+ // To get to this point and keeping this generic
+ // Get types required
+ var singletonType = ReflectionHelper.GetSingletonType();
+ var clientApplicationType = ReflectionHelper.GetClientApplicationType();
+ var interfaceType = ReflectionHelper.GetInterfaceType();
+
+ // Create singleton
+ var clientApplicationInterfaceType = CreateGenericType(clientApplicationType, interfaceType);
+ var singletonClientApplicationInterfaceType = CreateGenericType(singletonType, clientApplicationInterfaceType);
+
+ // Get singleton instance
+ var singletonClientApplicationInterfaceInstance = ReflectionHelper.GetSingletonInstance(singletonClientApplicationInterfaceType);
+
+ tarkovApp = singletonClientApplicationInterfaceInstance;
+ return ReflectionHelper.GetBackendSession(singletonClientApplicationInterfaceInstance);
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("CreateBackendSession");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public static object GetWaveSettings()
+ {
+ try
+ {
+ // combine List<> and WaveSettingsType
+ var listWaveType = CreateGenericType(ReflectionHelper.GetListType(), ReflectionHelper.GetWaveSettingsType());
+
+ // combine with JsonConvert.DeserializeObject<>() and invoke with getCurrentDir + "\\DUMPDATA\\.replace("\\\\","\\") + "botReqData.json";
+ return CreateDeserializerMethod(listWaveType).Invoke(null, new[] { File.ReadAllText(Path.Combine(DumpDataPath, "botReqData.json")) });
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetWaveSettings");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public static object GetSptConfig()
+ {
+ try
+ {
+ return CreateDeserializerMethod(typeof(SptConfigClass)).Invoke(null,
+ new[] { File.ReadAllText(Path.Combine(DumpDataPath, "config.json")) });
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+
+ public static object GetRaidSettings()
+ {
+ try
+ {
+ return CreateDeserializerMethod(ReflectionHelper.GetLocalRaidSettingsType()).Invoke(null,
+ new[] { File.ReadAllText(Path.Combine(DumpDataPath, "raidSettings.json")) });
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+
+ public static bool GotBackend = false;
+ public static object WaveSettings = null;
+ public static object RaidSettings = null;
+ public static object AppRaidSettings = null;
+ public static FieldInfo MainMenuController = null;
+ public static object Session = null;
+ public static object TarkovApp = null;
+ public static int ErrorCounter = 0;
+
+ ///
+ /// Method to run main menu Task, this will request data from BSG, map loot and bot data
+ ///
+ public static async Task StartDumpyTask()
+ {
+ if (!ConfigSettings.QuickDumpEnabled)
+ {
+ return;
+ }
+
+ await Task.Factory.StartNew(async delegate
+ {
+ UtilsHelper.LogInfo("[Dumpy] Starting Dumpy Loop");
+ while (true)
+ {
+ try
+ {
+ if (!GotBackend)
+ {
+ // get client backend session
+ Session = CreateBackendSessionAndTarkovApp(out TarkovApp);
+ // get field for MainMenuController
+ MainMenuController = ReflectionHelper.GetMainMenuControllerField();
+ // get wave information from json
+ WaveSettings = GetWaveSettings();
+ // get Raid Settings from json
+ RaidSettings = GetRaidSettings();
+ // get Raid settings from tarkovApp
+ AppRaidSettings = ReflectionHelper.GetRaidSettingsFromApp(TarkovApp);
+
+ CheckVariableConditions();
+ GotBackend = true;
+ }
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("[Dumpy] Exception occured in StartDumpyTask::GotBackend");
+ UtilsHelper.LogError(e);
+
+ if (ErrorCounter > 3)
+ {
+ UtilsHelper.LogError("[Dumpy] ErrorsCounter was above 3, exiting app!");
+ // use EFT method to close app
+ ReflectionHelper.GetApplicationQuitMethod().Invoke(null, null);
+ }
+
+ ErrorCounter += 1;
+
+ UtilsHelper.LogError("[Dumpy] Resetting backend and trying again");
+ ClearVariables();
+ }
+
+ try
+ {
+ if (Iteration > 6)
+ {
+ // reset to 1
+ Iteration = 1;
+
+ UtilsHelper.LogInfo($"[Dumpy] Restarting Loop in {ConfigSettings.SptTimings.AllIterationDelayMs}ms");
+ var controller = MainMenuController.GetValue(TarkovApp);
+
+ if (controller != null)
+ {
+ controller.GetType().GetMethod("StopAfkMonitor").Invoke(controller, null);
+ }
+
+ await Task.Delay(ConfigSettings.SptTimings.AllIterationDelayMs);
+ }
+ else
+ {
+ UtilsHelper.LogInfo($"Map iteration number: {Iteration}");
+ foreach (var map in ConfigSettings.MapNames)
+ {
+ // theory is send a request SendRaidSettings before starting
+
+ // Set location in the RaidSettings object
+ UtilsHelper.LogInfo($"[Dumpy] Setting RaidSettings location to: {map}");
+ RaidSettings.GetType().GetField("location").SetValue(RaidSettings, map);
+
+ // Call server with new map name
+ UtilsHelper.LogInfo($"[Dumpy] Getting loot for {map}");
+ await (Task)Session.GetType().GetMethod("LocalRaidStarted")
+ .Invoke(Session, new[] { RaidSettings });
+
+ // Call server with bot wave data
+ UtilsHelper.LogInfo($"[Dumpy] Getting Bot Data");
+ await (Task)Session.GetType().GetMethod("LoadBots")
+ .Invoke(Session, new[] { WaveSettings });
+
+ await Task.Delay(ConfigSettings.SptTimings.SingleIterationDelayMs);
+ }
+
+ Iteration++;
+ }
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("[Dumpy] Exception occured in StartDumpyTask::Iteration");
+ UtilsHelper.LogError(e);
+
+ if (ErrorCounter > 3)
+ {
+ UtilsHelper.LogError("[Dumpy] ErrorsCounter was above 3, exiting app");
+ // use EFT method to close app
+ ReflectionHelper.GetApplicationQuitMethod().Invoke(null, null);
+ }
+
+ ErrorCounter += 1;
+
+ UtilsHelper.LogError("[Dumpy] Resetting backend and trying again");
+ ClearVariables();
+ }
+ }
+ }, TaskCreationOptions.LongRunning);
+ }
+
+ private static void CheckVariableConditions()
+ {
+ UtilsHelper.LogInfo($"[Dumpy] CheckVariableConditions");
+ UtilsHelper.LogInfo($"[Dumpy] GotBackend- type: {GotBackend.GetType()} null?: {GotBackend == null}");
+ UtilsHelper.LogInfo($"[Dumpy] WaveSettings- type: {WaveSettings.GetType()} null?: {WaveSettings == null}");
+ UtilsHelper.LogInfo($"[Dumpy] MainMenuController- type: {MainMenuController.GetType()} null?: {MainMenuController == null}");
+ UtilsHelper.LogInfo($"[Dumpy] Session- type: {Session.GetType()} null?: {Session == null}");
+ UtilsHelper.LogInfo($"[Dumpy] TarkovApp- type: {TarkovApp.GetType()} null?: {TarkovApp == null}");
+ UtilsHelper.LogInfo($"[Dumpy] RaidSettings- type: {RaidSettings.GetType()} null?: {RaidSettings == null}");
+ UtilsHelper.LogInfo($"[Dumpy] CheckVariableConditions");
+ UtilsHelper.LogInfo($"[Dumpy] AppRaidSettings- type: {AppRaidSettings.GetType()} null?: {AppRaidSettings == null}");
+ UtilsHelper.LogInfo($"[Dumpy] CheckVariableConditions");
+ UtilsHelper.LogInfo($"[Dumpy] -----------------------------------------------------------------------------");
+ }
+
+ private static void ClearVariables()
+ {
+ GotBackend = false;
+ WaveSettings = null;
+ MainMenuController = null;
+ Session = null;
+ TarkovApp = null;
+ RaidSettings = null;
+ AppRaidSettings = null;
+ }
+
+ ///
+ /// Method to log Requests and Responses
+ ///
+ /// object (Type)
+ /// object (Type)
+ public static void LogRequestResponse(object requestType, object responseText)
+ {
+ try
+ {
+ var uri = new Uri((string)requestType.GetType().GetMethod(ConfigSettings.SptReflections.MainUrlPropName).Invoke(requestType, null));
+ var path = (Directory.GetCurrentDirectory() + "\\HTTP_DATA\\").Replace("\\\\", "\\");
+ var file = uri.LocalPath.Replace("/", ".").Remove(0, 1);
+ var time = DateTime.Now.ToString(ConfigSettings.DateTimeFormat);
+
+ if (Directory.CreateDirectory(path).Exists)
+ {
+ var reqParams = requestType.GetType().GetField(ConfigSettings.SptReflections.ParamFieldName).GetValue(requestType);
+ if (Directory.CreateDirectory($@"{path}req.{file}").Exists)
+ {
+ if (reqParams != null)
+ File.WriteAllText($@"{path}req.{file}\\req.{file}_{time}_{ConfigSettings.Name}.json", JsonConvert.SerializeObject(reqParams));
+ }
+
+ if (Directory.CreateDirectory($@"{path}resp.{file}").Exists)
+ File.WriteAllText($@"{path}resp.{file}\\resp.{file}_{time}_{ConfigSettings.Name}.json", (string)responseText);
+ }
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("[Dumpy] Exception occured at LogRequestResponse");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DumpLib/Helpers/ReflectionHelper.cs b/DumpLib/Helpers/ReflectionHelper.cs
new file mode 100644
index 0000000..1e80ee1
--- /dev/null
+++ b/DumpLib/Helpers/ReflectionHelper.cs
@@ -0,0 +1,260 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace DumpLib.Helpers
+{
+ public static class ReflectionHelper
+ {
+ private static Assembly _newtonAssembly = Assembly.LoadFrom((Directory.GetCurrentDirectory() + "\\EscapeFromTarkov_Data\\Managed\\Newtonsoft.Json.dll").Replace("\\\\", "\\"));
+
+ private static Assembly _msAssembly = Assembly.LoadFrom((Directory.GetCurrentDirectory() + "\\EscapeFromTarkov_Data\\Managed\\mscorlib.dll").Replace("\\\\", "\\"));
+
+ private static Assembly _eftAssembly = Assembly.LoadFrom((Directory.GetCurrentDirectory() + "\\EscapeFromTarkov_Data\\Managed\\Assembly-CSharp.dll").Replace("\\\\", "\\"));
+
+ private static Assembly _comfortAssembly = Assembly.LoadFrom((Directory.GetCurrentDirectory() + "\\EscapeFromTarkov_Data\\Managed\\Comfort.dll").Replace("\\\\", "\\"));
+
+ ///
+ /// Method to get Singleton<> type from Comfort.dll
+ ///
+ /// Type
+ public static Type GetSingletonType()
+ {
+ try
+ {
+ return _comfortAssembly.GetTypes().First(x => x.Name.StartsWith("Singleton"));
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetSingletonType");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Method to get ClientApplication<> type from EFT's assembly
+ ///
+ /// Type
+ public static Type GetClientApplicationType()
+ {
+ try
+ {
+ return _eftAssembly.GetTypes().First(x => x.Name.StartsWith("ClientApplication"));
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetClientApplicationType");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Method to get (as of 25/01/2024 - GInterface145) type from EFT's assembly
+ ///
+ /// Type
+ public static Type GetInterfaceType()
+ {
+ try
+ {
+ return _eftAssembly.GetTypes()
+ .First(x => x.IsInterface && x.GetMethods().Any(m => m.Name == "GetPhpSessionId"));
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetInterfaceType");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Method to get TarkovApplication type from EFT's assembly
+ ///
+ /// Type
+ public static Type GetTarkovApplicationType()
+ {
+ try
+ {
+ return _eftAssembly.GetTypes().First(x => x.Name == "TarkovApplication");
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetTarkovApplicationType");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Method to get (as of 25/01/2024 - GClass1464) type from EFT's assembly
+ ///
+ ///
+ public static object GetWaveSettingsType()
+ {
+ try
+ {
+ return _eftAssembly.GetTypes().First(x =>
+ {
+ // if type contains Role, Limit and Difficulty, return true
+ var fields = x.GetFields();
+ if (fields.Any(f => f.Name == "Role") && fields.Any(f => f.Name == "Limit") && fields.Any(f => f.Name == "Difficulty") && fields.Length == 3)
+ return true;
+
+ return false;
+ });
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetWaveSettingsType");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ public static Type GetListType()
+ {
+ try
+ {
+ return _msAssembly.GetTypes().First(x => x.Name.StartsWith("List") && x.Namespace == "System.Collections.Generic");
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetListType");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Method to get FieldInfo of a field on the TarkovApplication Type for later use
+ ///
+ /// FieldInfo
+ public static FieldInfo GetMainMenuControllerField()
+ {
+ try
+ {
+ return GetTarkovApplicationType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
+ .First(x => x.FieldType.GetMethods().Any(m => m.Name == "StopAfkMonitor"));
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetMainMenuControllerField");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Method to get the Instance of a Singleton(Type) passed in
+ ///
+ /// object (Type)
+ /// object (Type)
+ /// object
+ public static object GetSingletonInstance(object singletonType)
+ {
+ try
+ {
+ return (singletonType as Type).GetProperty("Instance", BindingFlags.Public | BindingFlags.Static)
+ .GetGetMethod().Invoke(singletonType, null);
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetSingletonInstance");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Method to get BackendSession object from the instance passed in
+ ///
+ /// object (Type)
+ /// object
+ public static object GetBackendSession(object instance)
+ {
+ try
+ {
+ return GetTarkovApplicationType().GetMethod("GetClientBackEndSession").Invoke(instance, null);
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetBackendSession");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Method to get DeserializeObject from Newtonsoft assembly
+ ///
+ /// MethodInfo
+ public static MethodInfo GetDeserializerMethodInfo()
+ {
+ try
+ {
+ return _newtonAssembly.GetTypes().First(x => x.Name == "JsonConvert").GetMethods().First(m =>
+ m.Name == "DeserializeObject" && m.IsGenericMethodDefinition && m.GetParameters().Length == 1 &&
+ m.GetParameters().Any(p => p.ParameterType == typeof(string)));
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetDeserializerMethodInfo");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Method to get Quit method from EFT (as of 20/05/2024 - GClass1955)
+ ///
+ /// MethodInfo
+ public static MethodInfo GetApplicationQuitMethod()
+ {
+ try
+ {
+ return _eftAssembly.GetTypes().First(x => x.GetMethods().Any(y => y.Name == "Quit")).GetMethod("Quit");
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetApplicationQuitMethod");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ ///
+ /// Method to get LocalRaidSettings Type from EFT
+ ///
+ /// object
+ public static object GetLocalRaidSettingsType()
+ {
+ try
+ {
+ return _eftAssembly.GetTypes().First(x => x.Name == "LocalRaidSettings");
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetLocalRaidSettingsType");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+
+ public static object GetRaidSettingsFromApp(object tarkovApp)
+ {
+ try
+ {
+ return tarkovApp.GetType().GetField("_raidSettings").GetValue(tarkovApp);
+ }
+ catch (Exception e)
+ {
+ UtilsHelper.LogError("GetRaidSettingsFromApp");
+ UtilsHelper.LogError(e);
+ throw;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/DumpLib/Helpers/UtilsHelper.cs b/DumpLib/Helpers/UtilsHelper.cs
new file mode 100644
index 0000000..b89d25f
--- /dev/null
+++ b/DumpLib/Helpers/UtilsHelper.cs
@@ -0,0 +1,64 @@
+using System;
+using System.IO;
+
+namespace DumpLib.Helpers
+{
+ public static class UtilsHelper
+ {
+ private static string _loggerPath = (Directory.GetCurrentDirectory() + "\\DUMPDATA\\Log.txt").Replace("\\\\", "\\");
+
+ ///
+ /// Log message to something
+ ///
+ /// object
+ private static void LogMessage(object message, string messageType)
+ {
+ StreamWriter writer = null;
+ try
+ {
+ writer = new StreamWriter(_loggerPath, true);
+ writer.WriteLine($"[{messageType}] - {DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ finally
+ {
+ if (writer != null)
+ {
+ writer.Close();
+ writer.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Log message to something
+ ///
+ /// object
+ public static void LogError(object message)
+ {
+ LogMessage(message, "Error");
+ }
+
+ ///
+ /// Log message to something
+ ///
+ /// object
+ public static void LogInfo(object message)
+ {
+ LogMessage(message, "Info");
+ }
+
+ ///
+ /// Log message to something
+ ///
+ /// object
+ public static void LogDebug(object message)
+ {
+ LogMessage(message, "Debug");
+ }
+ }
+}
\ No newline at end of file
diff --git a/DumpLib/Models/SptConfigClass.cs b/DumpLib/Models/SptConfigClass.cs
new file mode 100644
index 0000000..26f5c23
--- /dev/null
+++ b/DumpLib/Models/SptConfigClass.cs
@@ -0,0 +1,57 @@
+namespace DumpLib.Models
+{
+ public class SptConfigClass
+ {
+ ///
+ /// Default: Test
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Default: [ "Interchange", "factory4_day", "laboratory", "bigmap", "Lighthouse", "RezervBase", "Sandbox", "Shoreline", "TarkovStreets", "Woods" ]
+ ///
+ public string[] MapNames { get; set; }
+
+ ///
+ /// Default: "yyyy-MM-dd_HH-mm-ss"
+ ///
+ public string DateTimeFormat { get; set; }
+
+ public bool QuickDumpEnabled { get; set; }
+
+ public SptReflections SptReflections { get; set; }
+
+ public SptTimings SptTimings { get; set; }
+ }
+
+ public class SptTimings
+ {
+ ///
+ /// Default: 10s * 1000ms = 10000ms
+ ///
+ public int SingleIterationDelayMs { get; set; }
+
+ ///
+ /// Default: 5m * 60s * 1000ms = 300000ms
+ ///
+ public int AllIterationDelayMs { get; set; }
+ }
+
+ public class SptReflections
+ {
+ ///
+ /// Default: "get_MainURLFull" as of 128476 client
+ ///
+ public string MainUrlPropName { get; set; }
+
+ ///
+ /// Default: "Params" as of 128476 client
+ ///
+ public string ParamFieldName { get; set; }
+
+ ///
+ /// Default: "responseText" as of 128476 client
+ ///
+ public string RequestFieldName { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ReCodeItCLI/Commands/Dumper.cs b/ReCodeItCLI/Commands/Dumper.cs
new file mode 100644
index 0000000..43c79c5
--- /dev/null
+++ b/ReCodeItCLI/Commands/Dumper.cs
@@ -0,0 +1,39 @@
+using CliFx;
+using CliFx.Attributes;
+using CliFx.Infrastructure;
+using ReCodeIt.Utils;
+using ReCodeItLib.Dumper;
+
+namespace ReCodeIt.Commands;
+
+[Command("Dumper", Description = "Generates a dumper zip")]
+public class Dumper : ICommand
+{
+ [CommandParameter(0, IsRequired = true, Description = "The absolute path to your DeObfuscated assembly file, folder must contain all references to be resolved.")]
+ public string GameAssemblyPath { get; init; }
+
+ [CommandParameter(1, IsRequired = true, Description = "The absolute path to your FileChecker.dll file, folder must contain all refgerences to be resolved.")]
+ public string CheckerAssemblyPath { get; init; }
+
+ private Dumpy _dumpy { get; set; }
+
+ public ValueTask ExecuteAsync(IConsole console)
+ {
+ DataProvider.IsCli = true;
+ DataProvider.LoadAppSettings();
+
+ Logger.Log("Creating Dumper...");
+
+ _dumpy = new Dumpy(GameAssemblyPath, CheckerAssemblyPath, Path.GetDirectoryName(GameAssemblyPath));
+ _dumpy.CreateDumpFolders();
+ _dumpy.CreateDumper();
+
+ Logger.Log("Complete", ConsoleColor.Green);
+
+ // Wait for log termination
+ Logger.Terminate();
+ while (Logger.IsRunning()) { }
+
+ return default;
+ }
+}
\ No newline at end of file
diff --git a/ReCodeItCLI/ReCodeIt.csproj b/ReCodeItCLI/ReCodeIt.csproj
index 24eb2c2..ae4ce9c 100644
--- a/ReCodeItCLI/ReCodeIt.csproj
+++ b/ReCodeItCLI/ReCodeIt.csproj
@@ -9,8 +9,8 @@
-
-
+
+
diff --git a/RecodeIt.sln b/RecodeIt.sln
index e6edcaf..1f0f886 100644
--- a/RecodeIt.sln
+++ b/RecodeIt.sln
@@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReCodeItLib", "RecodeItLib\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReCodeIt", "ReCodeItCLI\ReCodeIt.csproj", "{E404EC0B-06D2-4964-8ABA-A634F259655C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DumpLib", "DumpLib\DumpLib.csproj", "{D0837899-F129-46DB-8BDB-7C9AFB72BD30}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -83,6 +85,26 @@ Global
{E404EC0B-06D2-4964-8ABA-A634F259655C}.Release|x64.Build.0 = Release|Any CPU
{E404EC0B-06D2-4964-8ABA-A634F259655C}.Release|x86.ActiveCfg = Release|Any CPU
{E404EC0B-06D2-4964-8ABA-A634F259655C}.Release|x86.Build.0 = Release|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|ARM.Build.0 = Debug|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|x64.Build.0 = Debug|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Debug|x86.Build.0 = Debug|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|ARM.ActiveCfg = Release|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|ARM.Build.0 = Release|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|ARM64.Build.0 = Release|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|x64.ActiveCfg = Release|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|x64.Build.0 = Release|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|x86.ActiveCfg = Release|Any CPU
+ {D0837899-F129-46DB-8BDB-7C9AFB72BD30}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/RecodeItLib/Dumper/Dumpy.cs b/RecodeItLib/Dumper/Dumpy.cs
new file mode 100644
index 0000000..b3b1b2a
--- /dev/null
+++ b/RecodeItLib/Dumper/Dumpy.cs
@@ -0,0 +1,331 @@
+using System.Collections;
+using dnlib.DotNet;
+using dnlib.DotNet.Emit;
+using ReCodeIt.Utils;
+
+namespace ReCodeItLib.Dumper;
+
+public class Dumpy
+{
+ private ModuleDefMD? _gameModule { get; set; }
+ private ModuleDefMD? _checkerModule { get; set; }
+ private string _assemblyPath { get; set; }
+ private string _fileCheckerPath { get; set; }
+ private string _path { get; set; }
+ private List? _gameTypes { get; set; }
+ private List? _checkerTypes { get; set; }
+
+ public Dumpy(string assemblyPath, string fileCheckerPath, string path)
+ {
+ _assemblyPath = assemblyPath;
+ _fileCheckerPath = fileCheckerPath;
+ _path = path;
+
+ if (!File.Exists(_assemblyPath))
+ {
+ Logger.Log($"File does not exist at: {_assemblyPath}", ConsoleColor.Red);
+ return;
+ }
+
+ if (!File.Exists(_fileCheckerPath))
+ {
+ Logger.Log($"File does not exist at: {_fileCheckerPath}", ConsoleColor.Red);
+ return;
+ }
+
+ _gameModule = DataProvider.LoadModule(_assemblyPath);
+ _checkerModule = DataProvider.LoadModule(_fileCheckerPath);
+ _gameTypes = _gameModule.GetTypes().ToList();
+ _checkerTypes = _checkerModule.GetTypes().ToList();
+ }
+
+ public void CreateDumper()
+ {
+ if (_gameModule == null || _gameTypes == null)
+ {
+ Logger.Log($"_gameModule or _gameTypes in Dumpy was null", ConsoleColor.Red);
+ return;
+ }
+
+ if (_checkerModule == null || _checkerTypes == null)
+ {
+ Logger.Log($"_checkerModule or _checkerTypes in Dumpy was null", ConsoleColor.Red);
+ return;
+ }
+
+ // make changes to assembly
+
+ // get required types
+ // var backRequestType = _gameTypes.Where(DumpyTypeHelper.GetBackRequestType).ToList();
+ // var validateCertType = _gameTypes.Where(DumpyTypeHelper.GetValidateCertType).ToList();
+ // var runValidationType = _gameTypes.Where(DumpyTypeHelper.GetRunValidationType).ToList();
+ // var dumpyTaskType = _gameTypes.Where(DumpyTypeHelper.GetMenuscreenType).ToList();
+
+ // check types
+ // CheckNullOrMulti(backRequestType, "BackRequest");
+ // CheckNullOrMulti(validateCertType, "ValidateCertificate");
+ // CheckNullOrMulti(runValidationType, "RunValidation");
+ // CheckNullOrMulti(dumpyTaskType, "DumpyTask");
+
+ // apply code changes
+ // SetBackRequestCode(backRequestType[0]);
+ // SetValidateCertCode(validateCertificateType[0]);
+ // SetRunValidationCode(runValidationType[0]);
+ // SetDumpyTaskCode(dumpyTaskType[0]);
+
+ // TODO: Write game assembly to file
+
+ // get types
+ // var ensureConsistencyTypes = _checkerTypes.Where(DumpyTypeHelper.GetEnsureConsistencyType).ToList();
+ // check types
+ // CheckNullOrMulti(ensureConsistencyTypes, "EnsureConsistency");
+
+ // apply code changes
+ // SetEnsureConsistencyCode(ensureConsistencyType[0]);
+ // SetEnsureConsistencySingleCode(ensureConsistencyType[0]);
+
+ // TODO: Write fileChecker assembly to file
+ }
+
+ public void CreateDumpFolders()
+ {
+ // create dumper folders
+ }
+
+ ///
+ /// Checks for null or multiple types
+ ///
+ /// ICollection
+ /// string
+ private void CheckNullOrMulti(ICollection types, string name = "")
+ {
+ if (types == null)
+ {
+ Logger.Log($"{name} was null");
+ }
+
+ if (types.Count > 1)
+ {
+ Logger.Log($"{name} count was more than 1");
+ }
+ }
+
+ ///
+ /// Finds the method with backRequest and bResponse as params.
+ /// Checks the method instructions before modification has a count of 269,
+ /// if this is not the case, this needs to be checked.
+ /// This type passed in is the only type with this method.
+ ///
+ ///
+ ///
+ private void SetBackRequestCode(TypeDef type)
+ {
+ // find method
+ var method = type.Methods.First(x => x.Parameters.Any(p => p.Name is "backRequest" && x.Parameters.Any(p => p.Name == "bResponse")));
+
+ if (method == null || method.Body.Instructions.Count != 269)
+ {
+ Logger.Log($"BackRequest Instructions count has changed from 269 to {method.Body.Instructions.Count}", ConsoleColor.Red);
+ }
+
+ var startOfInstructions = 252;
+ // var liList = DumpyInstructionsHelper.GetBackRequestInstructions();
+ var index = method.Body.Instructions[startOfInstructions];
+
+ // foreach (var li in liList)
+ // {
+ // // something along these lines, this needs to be tested
+ // method.Body.Instructions.InsertBefore(index, li);
+ // }
+
+ // create instruction
+ var ins = Instruction.Create(OpCodes.Brfalse_S, method.Body.Instructions[startOfInstructions]);
+
+ // replace instruction at 220 with this
+ method.Body.Instructions[220] = ins;
+ }
+
+ ///
+ /// Finds the method called ValidateCertificate.
+ /// Checks that we found two of these methods,
+ /// if this is not the case, this needs to be checked.
+ /// This type passed in is the only type with this method.
+ ///
+ ///
+ ///
+ private void SetValidateCertCode(TypeDef type)
+ {
+ var methods = type.Methods.Where(x =>
+ x.Name == "ValidateCertificate"); // should be 2
+
+ // check make sure nothing has changed
+ var firstMethod = methods.FirstOrDefault(m => m.Parameters.Any(p => p.Name == "certificate"));
+ var secondMethod = methods.FirstOrDefault(m => m.Parameters.Any(p => p.Name == "certificateData"));
+
+ if (firstMethod?.Body.Instructions.Count != 55 || secondMethod?.Body.Instructions.Count != 14)
+ {
+ Logger.Log($"Instruction count has changed, method with 'certificate' as a param - before: 51, now: {firstMethod.Body.Instructions.Count}, " +
+ $"method with 'certificateData' as a param - before: 14, now: {secondMethod.Body.Instructions.Count}", ConsoleColor.Red);
+ }
+
+ if (methods.Count() != 2)
+ {
+ Logger.Log($"ValidateCertificate should be found twice, count was: {methods.Count()}", ConsoleColor.Red);
+ }
+
+ foreach (var method in methods)
+ {
+ // clear these from the body.
+ method.Body.Instructions.Clear();
+ method.Body.Variables.Clear();
+ method.Body.ExceptionHandlers.Clear();
+
+ // return true;
+ var ins = Instruction.Create(OpCodes.Ldc_I4_1);
+ var ins1 = Instruction.Create(OpCodes.Ret);
+
+ // add instructions
+ method.Body.Instructions.Add(ins);
+ method.Body.Instructions.Add(ins1);
+ }
+ }
+
+ ///
+ /// Finds the method called RunValidation and MoveNext.
+ /// Checks that we found two of these methods,
+ /// if this is not the case, this needs to be checked.
+ /// This type passed in is the only type with this method.
+ ///
+ ///
+ ///
+ private void SetRunValidationCode(TypeDef type)
+ {
+ var method = type.Methods.First(x => x.Name == "RunValidation");
+ var method2 = type.NestedTypes[0].Methods.First(x => x.Name == "MoveNext");
+
+ if (method == null || method.Body.Instructions.Count != 25)
+ {
+ Logger.Log($"RunValidation Instructions count has changed from 25 to {method.Body.Instructions.Count}");
+ }
+
+ if (method2 == null || method2.Body.Instructions.Count != 171)
+ {
+ Logger.Log($"RunValidation's MoveNext Instructions count has changed from 171 to {method2.Body.Instructions.Count}");
+ }
+
+ // Clear these from the body of each method respectively
+ method.Body.Instructions.Clear();
+ method2.Body.Instructions.Clear();
+ method2.Body.Variables.Clear();
+ method2.Body.ExceptionHandlers.Clear();
+
+ // var liList = DumpyInstructionsHelper.GetRunValidationInstructions(oldAssembly, method);
+ // var liList2 = DumpyInstructionsHelper.GetRunValidationInstructionsMoveNext(oldAssembly, method2);
+
+ // foreach (var instruction in liList)
+ // {
+ // method.Body.Instructions.Append(instruction);
+ // }
+ //
+ // foreach (var instruction in liList2)
+ // {
+ // method2.Body.Instructions.Append(instruction);
+ // }
+
+ var ins = Instruction.Create(OpCodes.Leave_S, method2.Body.Instructions[14]); // Create instruction to jump to index 14
+ var ins1 = Instruction.Create(OpCodes.Leave_S, method2.Body.Instructions[method2.Body.Instructions.IndexOf(method2.Body.Instructions.Last())]); // Create instruction to jump to last index
+
+ method2.Body.Instructions.InsertAfter(method2.Body.Instructions[5], ins); // Instruction to jump from 5 to 14
+ method2.Body.Instructions.InsertAfter(method2.Body.Instructions[14], ins1); // Instruction to jump from 14 to last index
+
+ // Create exception handler with defined indexes
+ var handler = new ExceptionHandler(ExceptionHandlerType.Catch)
+ {
+ TryStart = method2.Body.Instructions[3],
+ TryEnd = method2.Body.Instructions[7],
+ HandlerStart = method2.Body.Instructions[7],
+ HandlerEnd = method2.Body.Instructions[16],
+ // CatchType = method2.Module.ImportReference(typeof(Exception)), // needs fixing
+ };
+
+ // Add exception handler to method body
+ method2.Body.ExceptionHandlers.Add(handler);
+ }
+
+ private void SetDumpyTaskCode(TypeDef type)
+ {
+ var method = type.Methods.First(x => x.Name == "Awake");
+
+ if (method == null || method.Body.Instructions.Count != 62)
+ {
+ Logger.Log($"MainMenu is null or isnt 62 instructions, SOMETHING HAD CHANGED!", ConsoleColor.Red);
+ }
+
+ // var liList = DumpyInstructionsHelper.GetDumpyTaskInstructions(oldAssembly, method);
+
+ var index = method.Body.Instructions.First(x => x.OpCode == OpCodes.Ret);
+
+ // foreach (var item in liList)
+ // {
+ // method.Body.Instructions.InsertBefore(index, item);
+ // }
+ }
+
+ ///
+ /// Finds the method called EnsureConsistency.
+ /// if this is not the case, this needs to be checked.
+ /// This type passed in is the only type with this method.
+ ///
+ ///
+ ///
+ private static void SetEnsureConsistencyCode(TypeDef type)
+ {
+ var method = type.Methods.First(x => x.Name == "EnsureConsistency");
+
+ if (method == null || method.Body.Instructions.Count != 152)
+ {
+ Logger.Log($"EnsureConsistency Instructions count has changed from 152 to {method.Body.Instructions.Count}", ConsoleColor.Red);
+ }
+
+ // clear these from the method body
+ method.Body.Instructions.Clear();
+ method.Body.Variables.Clear();
+ method.Body.ExceptionHandlers.Clear();
+
+ // var liList = DumpyInstructionsHelper.GetEnsureConsistencyInstructions(oldFileChecker, method);
+ //
+ // foreach (var li in liList)
+ // {
+ // method.Body.Instructions.Append(li);
+ // }
+ }
+
+ ///
+ /// Finds the method called EnsureConsistencySingle.
+ /// if this is not the case, this needs to be checked.
+ /// This type passed in is the only type with this method.
+ ///
+ ///
+ ///
+ private static void SetEnsureConsistencySingleCode(TypeDef type)
+ {
+ var method = type.Methods.First(x => x.Name == "EnsureConsistencySingle");
+
+ if (method == null || method.Body.Instructions.Count != 101)
+ {
+ Logger.Log($"EnsureConsistencySingle Instructions count has changed from 101 to {method.Body.Instructions.Count}", ConsoleColor.Red);
+ }
+
+ // clear these from the method body
+ method.Body.Instructions.Clear();
+ method.Body.Variables.Clear();
+ method.Body.ExceptionHandlers.Clear();
+
+ // var liList = DumpyInstructionsHelper.GetEnsureConsistencyInstructions(oldFileChecker, method);
+ //
+ // foreach (var li in liList)
+ // {
+ // method.Body.Instructions.Append(li);
+ // }
+ }
+}
\ No newline at end of file
diff --git a/RecodeItLib/Dumper/DumpyInstructionsHelper.cs b/RecodeItLib/Dumper/DumpyInstructionsHelper.cs
new file mode 100644
index 0000000..dcf252f
--- /dev/null
+++ b/RecodeItLib/Dumper/DumpyInstructionsHelper.cs
@@ -0,0 +1,170 @@
+// using System;
+// using System.Collections.Generic;
+// using System.Linq;
+// using System.Threading.Tasks;
+// using DumpLib;
+//
+// namespace ReCodeItLib.Dumper;
+//
+// public static class DumpyInstructionsHelper
+// {
+// ///
+// /// Sets up local variables and returns a List of instructions to add.
+// ///
+// /// AssemblyDefinition
+// /// MethodDefinition
+// /// List
+// public static List GetBackRequestInstructions(AssemblyDefinition assembly, MethodDefinition method)
+// {
+// return new List
+// {
+// Instruction.Create(OpCodes.Ldarg_1),
+// Instruction.Create(OpCodes.Ldloc_S, method.Body.Variables[6]),
+// Instruction.Create(OpCodes.Call, assembly.MainModule.ImportReference(typeof(DumpLib.DumpyTool).GetMethod("LogRequestResponse", new[] { typeof(object), typeof(object) })))
+// };
+// }
+//
+// ///
+// /// Returns a List of instructions to be added to the method.
+// /// This is an Async method so there is two parts, this part and a RunValidation method.
+// ///
+// /// AssemblyDefinition
+// /// MethodDefinition
+// /// List
+// public static List GetRunValidationInstructionsMoveNext(AssemblyDefinition assembly, MethodDefinition method)
+// {
+// // Add our own local variables
+//
+// // var1 index0 class1159Type
+// var sptClassType = assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType);
+// var sptClass = new VariableDefinition(sptClassType);
+// method.Body.Variables.Add(sptClass);
+//
+// // var2 index1 ExceptionType
+// var sptExceptionType = method.Module.ImportReference(typeof(Exception));
+// var sptException = new VariableDefinition(sptExceptionType);
+// method.Body.Variables.Add(sptException);
+//
+// return new List
+// {
+// // most of this is to keep the Async happy
+//
+// Instruction.Create(OpCodes.Ldarg_0),
+// Instruction.Create(OpCodes.Ldfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[2]),
+// Instruction.Create(OpCodes.Stloc_0),
+//
+// // this.Succeed = true;
+// Instruction.Create(OpCodes.Ldloc_0),
+// Instruction.Create(OpCodes.Ldc_I4_1),
+// Instruction.Create(OpCodes.Call, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).Methods.First(x => x.Name == "set_Succeed")),
+//
+// Instruction.Create(OpCodes.Stloc_1),
+// Instruction.Create(OpCodes.Ldarg_0),
+// Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)-2),
+// Instruction.Create(OpCodes.Stfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[0]),
+// Instruction.Create(OpCodes.Ldarg_0),
+// Instruction.Create(OpCodes.Ldflda, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1]),
+// Instruction.Create(OpCodes.Ldloc_1),
+// Instruction.Create(OpCodes.Call,
+// method.Module.ImportReference(assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1].FieldType.Resolve().Methods.First(x => x.Name == "SetException"))),
+//
+// Instruction.Create(OpCodes.Ldarg_0),
+// Instruction.Create(OpCodes.Ldc_I4_S, (sbyte)-2),
+// Instruction.Create(OpCodes.Stfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[0]),
+//
+// Instruction.Create(OpCodes.Ldarg_0),
+// Instruction.Create(OpCodes.Ldflda, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1]),
+// Instruction.Create(OpCodes.Call, method.Module.ImportReference(assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1].FieldType.Resolve().Methods.First(x => x.Name == "SetResult"))),
+//
+// Instruction.Create(OpCodes.Ret),
+// };
+// }
+//
+// ///
+// /// Returns a List of instructions to be added to the method.
+// /// This is an Async method so there is two parts, this part and a RunValidation method.
+// ///
+// /// AssemblyDefinition
+// /// MethodDefinition
+// /// List
+// public static List GetEnsureConsistencyInstructions(AssemblyDefinition oldFileChecker, MethodDefinition method)
+// {
+// // init local vars
+// // var1 index0 TimeSpan type
+// var sptTimeSpanType = method.Module.ImportReference(typeof(TimeSpan));
+// var sptClass = new VariableDefinition(sptTimeSpanType);
+// method.Body.Variables.Add(sptClass);
+//
+// // Create genericInstance of a method
+// var type = oldFileChecker.MainModule.GetTypes().First(DumpyTypeHelper.GetEnsureConsistencyType).NestedTypes[0].Interfaces[0].InterfaceType;
+// var typeMethod = method.Module.ImportReference(typeof(Task).GetMethod("FromResult"));
+// var instanceType = new GenericInstanceMethod(typeMethod);
+// instanceType.GenericArguments.Add(type);
+//
+// return new List
+// {
+// // return Task.FromResult(ConsistencyController.CheckResult.Succeed(default(TimeSpan)));
+// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
+// Instruction.Create(OpCodes.Initobj, method.Module.ImportReference(typeof(TimeSpan))),
+// Instruction.Create(OpCodes.Ldloc_0),
+// Instruction.Create(OpCodes.Call, oldFileChecker.MainModule.GetTypes().First(DumpyTypeHelper.GetEnsureConsistencyType).NestedTypes[0].Methods.First(x => x.Name == "Succeed")),
+// Instruction.Create(OpCodes.Call, instanceType),
+// Instruction.Create(OpCodes.Ret)
+// };
+// }
+//
+// ///
+// /// Returns a List of instructions to be added to the method.
+// /// This is an Async method so there is two parts, this part and a MoveNext method.
+// ///
+// /// AssemblyDefinition
+// /// MethodDefinition
+// /// List
+// public static List GetRunValidationInstructions(AssemblyDefinition assembly, MethodDefinition method)
+// {
+// // Create genericInstance of a method
+// var type = assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0];
+// var typeMethod = method.Module.ImportReference(assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1].FieldType.Resolve().Methods.First(x => x.Name == "Start"));
+// var instanceMethod = new GenericInstanceMethod(typeMethod);
+// instanceMethod.GenericArguments.Add(type);
+//
+// return new List
+// {
+// // d__.<>t__builder = AsyncTaskMethodBuilder.Create();
+// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
+// Instruction.Create(OpCodes.Call, method.Module.ImportReference(assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1].FieldType.Resolve().Methods.First(x => x.Name == "Create"))),
+// Instruction.Create(OpCodes.Stfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1]),
+//
+// // d__.<>4__this = this;
+// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
+// Instruction.Create(OpCodes.Ldarg_0),
+// Instruction.Create(OpCodes.Stfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[2]),
+//
+// // d__.<>1__state = -1;
+// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
+// Instruction.Create(OpCodes.Ldc_I4_M1),
+// Instruction.Create(OpCodes.Stfld, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[0]),
+//
+// // d__.<>t__builder.Startd__0>(ref d__);
+// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
+// Instruction.Create(OpCodes.Ldflda, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1]),
+// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
+// Instruction.Create(OpCodes.Call, instanceMethod),
+//
+// // return d__.<>t__builder.Task;
+// Instruction.Create(OpCodes.Ldloca_S, method.Body.Variables[0]),
+// Instruction.Create(OpCodes.Ldflda, assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1]),
+// Instruction.Create(OpCodes.Call, method.Module.ImportReference(assembly.MainModule.GetTypes().First(DumpyTypeHelper.GetRunValidationType).NestedTypes[0].Fields[1].FieldType.Resolve().Methods.First(x => x.Name == "get_Task"))),
+// Instruction.Create(OpCodes.Ret),
+// };
+// }
+//
+// public static List GetDumpyTaskInstructions(AssemblyDefinition oldAssembly, MethodDefinition method)
+// {
+// return new List
+// {
+// Instruction.Create(OpCodes.Call, oldAssembly.MainModule.ImportReference(typeof(DumpyTool).GetMethod("StartDumpyTask"))),
+// Instruction.Create(OpCodes.Pop)
+// };
+// }
+// }
\ No newline at end of file
diff --git a/RecodeItLib/Dumper/DumpyTypeHelper.cs b/RecodeItLib/Dumper/DumpyTypeHelper.cs
new file mode 100644
index 0000000..92fdb6f
--- /dev/null
+++ b/RecodeItLib/Dumper/DumpyTypeHelper.cs
@@ -0,0 +1,54 @@
+// using System.Linq;
+// using Mono.Cecil;
+//
+// namespace ReCodeItLib.Dumper;
+//
+// public static class DumpyTypeHelper
+// {
+// ///
+// /// Gets the type that has a method called SendAndHandleRetries.
+// /// This type is the only one with method.
+// ///
+// /// TypeDefinition
+// /// boolean
+// public static bool GetBackRequestType(TypeDefinition type)
+// {
+// return type.Methods.Any(m => m.Name == "SendAndHandleRetries");
+// }
+//
+// ///
+// /// Gets the type that has a method called ValidateCertificate as the name.
+// ///
+// /// TypeDefinition
+// /// boolean
+// public static bool GetValidateCertificateType(TypeDefinition type)
+// {
+// return type.Methods.Any(m => m.Name == "ValidateCertificate");
+// }
+//
+// ///
+// /// Gets the type that has a method called RunValidation as the name.
+// ///
+// /// TypeDefinition
+// /// boolean
+// public static bool GetRunValidationType(TypeDefinition type)
+// {
+// return type.Methods.Any(m => m.Name == "RunValidation");
+// }
+//
+// ///
+// /// Gets the type that has ConsistencyController as the name.
+// /// FilesChecker.dll is not obfuscated.
+// ///
+// /// TypeDefinition
+// /// boolean
+// public static bool GetEnsureConsistencyType(TypeDefinition type)
+// {
+// return type.Name == "ConsistencyController";
+// }
+//
+// public static bool GetMenuScreenType(TypeDefinition type)
+// {
+// return type.Name == "MenuScreen";
+// }
+// }
\ No newline at end of file
diff --git a/RecodeItLib/Dumper/InstructionsExtensions.cs b/RecodeItLib/Dumper/InstructionsExtensions.cs
new file mode 100644
index 0000000..0c47b58
--- /dev/null
+++ b/RecodeItLib/Dumper/InstructionsExtensions.cs
@@ -0,0 +1,49 @@
+using dnlib.DotNet.Emit;
+
+namespace ReCodeItLib.Dumper;
+
+public static class InstructionsExtensions
+{
+ public static void InsertBefore(this IList instructions, Instruction target, Instruction instruction)
+ {
+ if (target == null)
+ {
+ throw new ArgumentNullException(nameof (target));
+ }
+
+ if (instruction == null)
+ {
+ throw new ArgumentNullException(nameof (instruction));
+ }
+
+ int index = instructions.IndexOf(target);
+ if (index == -1)
+ {
+ throw new ArgumentOutOfRangeException(nameof (target));
+ }
+
+ instructions.Insert(index, instruction);
+ }
+
+ public static void InsertAfter(this IList instructions, Instruction target, Instruction instruction)
+ {
+ if (target == null)
+ {
+ throw new ArgumentNullException(nameof (target));
+ }
+
+ if (instruction == null)
+ {
+ throw new ArgumentNullException(nameof (instruction));
+ }
+
+ int index = instructions.IndexOf(target);
+
+ if (index == -1)
+ {
+ throw new ArgumentOutOfRangeException(nameof (target));
+ }
+
+ instructions.Insert(index + 1, instruction);
+ }
+}
\ No newline at end of file
diff --git a/RecodeItLib/ReCodeItLib.csproj b/RecodeItLib/ReCodeItLib.csproj
index 420ec58..2472aa9 100644
--- a/RecodeItLib/ReCodeItLib.csproj
+++ b/RecodeItLib/ReCodeItLib.csproj
@@ -18,4 +18,14 @@
+
+
+
+
+
+
+
+ Assets\DumpLib.dll
+
+
diff --git a/RecodeItLib/Remapper/DeObfuscator.cs b/RecodeItLib/Remapper/DeObfuscator.cs
index 3aebe88..0b5cee6 100644
--- a/RecodeItLib/Remapper/DeObfuscator.cs
+++ b/RecodeItLib/Remapper/DeObfuscator.cs
@@ -9,7 +9,7 @@ public static class Deobfuscator
{
public static void Deobfuscate(string assemblyPath)
{
- var executablePath = Path.Combine(DataProvider.DataPath, "De4dot", "de4dot.exe");
+ var executablePath = Path.Combine(DataProvider.DataPath, "Assets", "De4dot", "de4dot.exe");
string token;