Exemple #1
0
        private static Int32 Unpack(ProgramArguments arguments)
        {
            try
            {
                var spec = new UnpackGamePackagesSpecPreprocessor();
                if (arguments.TryGetNext(out String gameDirectoryPath))
                {
                    spec.GameDirectoryPath = gameDirectoryPath;
                }
                else
                {
                    spec.GameDirectory = GameDirectoryProvider.GetDefault();
                }

                if (arguments.TryGetNext(out String outputPath))
                {
                    spec.OutputDirectory = outputPath;
                }
                else
                {
                    spec.OutputDirectory = $".\\Data";
                }

                while (arguments.TryGetNext(out String arg))
                {
                    switch (arg)
                    {
                    case "-convert":
                        spec.Convert = true;
                        break;

                    case "-rename":
                        spec.Rename = true;
                        break;

                    default:
                        throw new ArgumentException(arg, nameof(arguments));
                    }
                }

                spec.Preprocess();

                UnpackGamePackagesCoroutine coroutine = new UnpackGamePackagesCoroutine(spec);
                coroutine.Execute();

                return(0);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("----------------------------");
                Console.Error.WriteLine("Failed to unpack game data.");
                Console.Error.WriteLine("----------------------------");
                Console.Error.WriteLine(ex);
                Console.Error.WriteLine("----------------------------");
                ShowUnpackHelp();
                Console.WriteLine();
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
                return(255);
            }
        }
        public void Execute()
        {
            if (!_spec.GameDirectory.IsDataExists)
            {
                UnpackGamePackagesSpecPreprocessor unpackSpec = new UnpackGamePackagesSpecPreprocessor {
                    GameDirectory = _spec.GameDirectory, OutputDirectory = _spec.GameDirectory.DataPath, Convert = true, Rename = true
                };
                unpackSpec.Preprocess();

                UnpackGamePackagesCoroutine unpack = new UnpackGamePackagesCoroutine(unpackSpec);
                unpack.Execute();
            }

            MyProcess process = new MyProcess();

            process.StartInfo = new ProcessStartInfo(_spec.GameDirectory.ExecutablePath, _spec.GameArguments);
            process.StartInfo.WorkingDirectory       = _spec.GameDirectory.DirectoryPath;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError  = true;
            process.StartInfo.UseShellExecute        = false;
            process.Start(0x4);

            try
            {
                StringBuilder output = new StringBuilder();
                StringBuilder error  = new StringBuilder();
                process.OutputDataReceived += (s, z) => output.AppendLine(z.Data);
                process.ErrorDataReceived  += (s, z) => error.AppendLine(z.Data);
                process.BeginOutputReadLine();
                process.BeginErrorReadLine();

                var dllPath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Septerra.Injection.dll");
                if (!File.Exists(dllPath))
                {
                    throw new FileNotFoundException(dllPath);
                }

                var unicodeDllPath = Encoding.Unicode.GetBytes(dllPath);

                using (SafeProcessHandle processHandle = new SafeProcessHandle(process.Id, ProcessAccessFlags.All, false))
                    using (SafeVirtualMemoryHandle memoryHandle = processHandle.Allocate(unicodeDllPath.Length, AllocationType.Commit, MemoryProtection.ReadWrite))
                    {
                        memoryHandle.Write(unicodeDllPath);

                        IntPtr loadLibraryAddress = GetLoadLibraryAddress();
                        using (SafeRemoteThread thread = processHandle.CreateThread(loadLibraryAddress, memoryHandle))
                        {
                            thread.Join();
                            Thread.Sleep(1000); // TODO:: Wait for DLL_THREAD_DETACH
                        }

                        var dxWndDirectory = Path.GetFullPath("dxwnd");
                        var dxWndPath      = dxWndDirectory + "\\dxwnd.exe";
                        if (File.Exists(dxWndPath))
                        {
                            unsafe
                            {
                                Int32 processInformationSize = sizeof(MyProcess.PROCESS_INFORMATION);
                                using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("Global\\DxWndSuspendedProcessInfo", processInformationSize, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None))
                                    using (MemoryMappedViewAccessor accessor = mmf.CreateViewAccessor(0, processInformationSize, MemoryMappedFileAccess.Write))
                                    {
                                        MyProcess.PROCESS_INFORMATION processInformation = process.ProcessInformation;
                                        accessor.Write(0, ref processInformation);

                                        Process dxWnd = new Process
                                        {
                                            StartInfo = new ProcessStartInfo(dxWndPath, "/r:0")
                                            {
                                                WorkingDirectory = dxWndDirectory
                                            }
                                        };

                                        dxWnd.Start();

                                        process.WaitForExit();
                                        dxWnd.Kill();
                                    }
                            }
                        }
                        else
                        {
                            process.ResumeMainThread();
                            HideConsole();
                            process.WaitForExit();
                        }
                    }
            }
            catch
            {
                process.Kill();
                throw;
            }
        }