public void RemovePatch() { try { PurgeFiles(); string[] entryPoint = m_strEntryPoint.Split(new string[] { "::" }, StringSplitOptions.None); string strTempFile = m_strGameAssemblyPath + Constants.VORTEX_BACKUP_TAG; File.Copy(m_strGameAssemblyPath, strTempFile, true); using (AssemblyDefinition unityAssembly = AssemblyDefinition.ReadAssembly(strTempFile, new ReaderParameters { ReadWrite = true })) { if (!IsInjected(unityAssembly, entryPoint)) { return; } TypeDefinition type = unityAssembly.MainModule.GetType(entryPoint[0]); if ((type == null) || !type.IsClass) { throw new EntryPointNotFoundException("Invalid type"); } MethodDefinition methodDefinition = type.Methods.FirstOrDefault(meth => meth.Name == entryPoint[1]); if ((methodDefinition == null) || !methodDefinition.HasBody) { throw new EntryPointNotFoundException("Invalid method"); } var instructions = methodDefinition.Body.Instructions .Where(instr => instr.OpCode == OpCodes.Call) .ToArray(); Instruction patcherInstr = instructions.FirstOrDefault(instr => instr.Operand.ToString().Contains(Constants.VORTEX_PATCH_METHOD)); methodDefinition.Body.Instructions.Remove(patcherInstr); unityAssembly.Write(m_strGameAssemblyPath); } } catch (Exception exc) { Enums.EErrorCode errorCode = Enums.EErrorCode.UNKNOWN; Util.RestoreBackup(m_strGameAssemblyPath); if (exc is FileNotFoundException) { errorCode = Enums.EErrorCode.MISSING_FILE; } else if (exc is EntryPointNotFoundException) { errorCode = Enums.EErrorCode.INVALID_ENTRYPOINT; } string strMessage = "Failed to remove patcher."; string strResponse = JSONResponse.CreateSerializedResponse(strMessage, errorCode, exc); Console.Error.WriteLine(strResponse); Environment.Exit((int)(errorCode)); } }
internal static string CreateSerializedResponse(string message, Enums.EErrorCode code, Exception exc = null) { JSONResponse response = new JSONResponse(); response.Message = message; response.ErrorCode = (int)(code); response.RaisedException = exc; return(JsonConvert.SerializeObject(response)); }
/// <summary> /// Certain games distribute modified assemblies which disable /// reflection and impede modding. /// </summary> private void EnableReflection(string strDataPath) { string strMscorlib = Path.Combine(strDataPath, Constants.MSCORLIB); FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(strMscorlib); string version = fvi.FileVersion; string strLib = LIB_REPLACEMENTS .Where(replacement => replacement.Substring(Constants.MSCORLIB.Length + 1, 1) == version.Substring(0, 1)) .SingleOrDefault(); if (null != strLib) { try { WebClient wc = new WebClient(); Uri uri = new Uri(Constants.GITHUB_LINK + strLib); wc.DownloadDataAsync(uri, Path.Combine(strDataPath, strLib)); wc.DownloadDataCompleted += (sender, e) => { string strFileName = e.UserState.ToString(); File.WriteAllBytes(strFileName, e.Result); Util.ReplaceFile(strMscorlib, strFileName); m_eInjectorState = Enums.EInjectorState.FINISHED; }; } catch (Exception exc) { m_eInjectorState = Enums.EInjectorState.FINISHED; string strMessage = "Unhandled mscorlib version."; Enums.EErrorCode err = Enums.EErrorCode.MISSING_FILE; string strResponse = JSONResponse.CreateSerializedResponse(strMessage, err, exc); Console.Error.WriteLine(strResponse); Environment.Exit((int)(err)); } } else { m_eInjectorState = Enums.EInjectorState.FINISHED; string strMessage = "Unhandled mscorlib version."; Enums.EErrorCode err = Enums.EErrorCode.UNHANDLED_FILE_VERSION; string strResponse = JSONResponse.CreateSerializedResponse(strMessage, err); Console.Error.WriteLine(strResponse); Environment.Exit((int)(err)); } }
public Injector(string strDataPath, string strEntryPoint) { try { m_strDataPath = strDataPath; m_strEntryPoint = strEntryPoint; m_strGameAssemblyPath = Path.Combine(strDataPath, Constants.UNITY_ASSEMBLY_LIB); m_strModsDirectory = Path.Combine(strDataPath, Constants.MODS_DIRNAME); m_resolver = new MissingAssemblyResolver(strDataPath); } catch (Exception exc) { Enums.EErrorCode errorCode = Enums.EErrorCode.INVALID_ARGUMENT; string strMessage = "Injector received invalid argument."; string strResponse = JSONResponse.CreateSerializedResponse(strMessage, errorCode, exc); Console.Error.WriteLine(strResponse); Environment.Exit((int)(errorCode)); } }
private static void SyncFailed_OnSyncFailedEvent(Enums.EErrorCode e) { new System.Threading.Tasks.Task( () => { if ((int)e == 4010 || e == 0 || e == Enums.EErrorCode.INVALID_SESSION || e == Enums.EErrorCode.COLLECTION_IN_FUTURE || e == Enums.EErrorCode.COLLECTION_IN_PAST || (int)e == 1011 || (int)e == 2006) { Logger.Logger.Info(Localization.CORE_RESTARTING); if (Core.GlobalData != null) { if (!Directory.Exists("crashlog")) { Directory.CreateDirectory("crashlog"); } aftercrash = true; File.WriteAllText("crashlog/" + "bfcrashdmp" + DateTime.Now.ToString(@"yyyy-MM-dd HH-mm-ss"), JsonConvert.SerializeObject(Core.GlobalData)); } restartwithdelay(0); } if (e == Enums.EErrorCode.PLAYER_BANNED) { Logger.Logger.Fatal(Localization.CORE_USER_BANNED); StopBot(); } if (e == Enums.EErrorCode.MAINTENANCE || e == Enums.EErrorCode.PLAYER_MAINTENANCE) { Logger.Logger.Info(Localization.CORE_MAINTENANCE_30MIN); restartwithdelay(20); } }).Start(); }
private static void SyncFailedChat_OnSyncFailedEvent(Enums.EErrorCode e) { System.Threading.Tasks.Task.Run( () => { if (e == Enums.EErrorCode.WRONG_SESSION) { Logger.Logger.Info( string.Format(Localization.NETWORKING_SOMEONE_IS_PLAYING, Core.hibernation)); if (Core.IsBotRunning) { _syncThread.Abort(); Logger.Logger.Muted = true; Thread.Sleep(Core.hibernation * 1000 * 60); Logger.Logger.Muted = false; Logger.Logger.Info(Localization.NETWORKING_WAKING_UP); StartThread(); Login(); } } }); }
public void Inject() { m_eInjectorState = Enums.EInjectorState.RUNNING; string strTempFile = null; AssemblyDefinition unityAssembly = null; try { // Ensure we have reflection enabled - there's no point // in continuing if reflection is disabled. if (!Util.IsReflectionEnabled(m_strDataPath)) { EnableReflection(m_strDataPath); } else { m_eInjectorState = Enums.EInjectorState.FINISHED; } // Deploy patcher related files. DeployFiles(); // Start the patching process. string[] patcherPoints = Constants.VORTEX_PATCH_METHOD.Split(new string[] { "::" }, StringSplitOptions.None); string[] entryPoint = m_strEntryPoint.Split(new string[] { "::" }, StringSplitOptions.None); strTempFile = Util.GetTempFile(m_strGameAssemblyPath); using (unityAssembly = AssemblyDefinition.ReadAssembly(strTempFile, new ReaderParameters { ReadWrite = true, AssemblyResolver = m_resolver })) { if (IsInjected(unityAssembly, entryPoint)) { unityAssembly.Dispose(); Util.DeleteTemp(strTempFile); return; } // Back up the game assembly before we do anything. Util.BackupFile(m_strGameAssemblyPath); AssemblyDefinition vrtxPatcher = AssemblyDefinition.ReadAssembly(Path.Combine(m_strDataPath, Constants.VORTEX_LIB)); MethodDefinition patcherMethod = vrtxPatcher.MainModule.GetType(patcherPoints[0]).Methods.First(x => x.Name == patcherPoints[1]); TypeDefinition type = unityAssembly.MainModule.GetType(entryPoint[0]); if ((type == null) || !type.IsClass) { throw new EntryPointNotFoundException("Invalid entry point"); } MethodDefinition methodDefinition = type.Methods.FirstOrDefault(meth => meth.Name == entryPoint[1]); if ((methodDefinition == null) || !methodDefinition.HasBody) { throw new EntryPointNotFoundException("Invalid entry point"); } methodDefinition.Body.GetILProcessor().InsertBefore(methodDefinition.Body.Instructions[0], Instruction.Create(OpCodes.Call, methodDefinition.Module.ImportReference(patcherMethod))); unityAssembly.Write(m_strGameAssemblyPath); unityAssembly.Dispose(); Util.DeleteTemp(strTempFile); } } catch (Exception exc) { Enums.EErrorCode errorCode = Enums.EErrorCode.UNKNOWN; if (unityAssembly != null) { unityAssembly.Dispose(); } if (strTempFile != null) { Util.DeleteTemp(strTempFile); } Util.RestoreBackup(m_strGameAssemblyPath); if (exc is FileNotFoundException) { errorCode = Enums.EErrorCode.MISSING_FILE; } else if (exc is EntryPointNotFoundException) { errorCode = Enums.EErrorCode.INVALID_ENTRYPOINT; } string strMessage = "Failed to inject patcher."; string strResponse = JSONResponse.CreateSerializedResponse(strMessage, errorCode, exc); Console.Error.WriteLine(strResponse); Environment.Exit((int)(errorCode)); } while (InjectorState != Enums.EInjectorState.FINISHED) { // Do nothing. } }
private static void Kicked_OnWrongSession(Enums.EErrorCode e) { kicked = true; Console.WriteLine("Kicked us with error " + e); }
internal static void OnSyncFailed(Enums.EErrorCode e) { OnSyncFailedEvent?.Invoke(e); }
internal static void Invoke(Enums.EErrorCode e) { OnSyncFailed(e); }