Exemple #1
0
        // 设置窗口焦点状态与BringToTop计时器
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);

            // Do upward compatible
            var NoFocusFlag = false;

            try
            {
                var ret = EHConfig.GetValue(EHNode.NoFocus);
                NoFocusFlag = bool.Parse(ret);
            }
            catch (NullReferenceException)
            {
                // create the node
                EHConfig.SetValue(EHNode.NoFocus, NoFocusFlag.ToString());
            }

            // 处理全局开启了MTMode,在加载别的游戏时focus选项还没打开的情况
            if (Properties.Settings.Default.OnlyMachineTranslation && NoFocusFlag == false)
            {
                NoFocusFlag = true;
                EHConfig.SetValue(EHNode.NoFocus, NoFocusFlag.ToString());
            }

            if (NoFocusFlag)
            {
                var interopHelper = new WindowInteropHelper(this);
                int exStyle       = Hook.GetWindowLong(interopHelper.Handle, Hook.GWL_EXSTYLE);
                Hook.SetWindowLong(interopHelper.Handle, Hook.GWL_EXSTYLE, exStyle | Hook.WS_EX_NOACTIVATE);
            }

            DispatcherTimer timer   = new DispatcherTimer();
            var             pointer = new WindowInteropHelper(this);

            timer.Tick += (sender, _) =>
            {
                if (pointer.Handle == IntPtr.Zero)
                {
                    timer.Stop();
                }
                // Still get a little bad exprience with right click taskbar icon
                if (gameHWnd == Hook.GetForegroundWindow())
                {
                    Hook.BringWindowToTop(pointer.Handle);
                }
            };

            timer.Interval = TimeSpan.FromMilliseconds(100);
            timer.Start();
        }
        public HookConfigViewModel(IHookConfigDataService dataService)
        {
            _dataService = dataService;
            HookMapData  = _dataService.GetHookMapData();

            if (IsInDesignMode)
            {
                InputCode     = "/HS-10@21967:NUKITASHI2.EXE";
                Regexp        = @"[\x00-\xFF]";
                SelectedText  = "悠真くんを攻略すれば210円か。なるほどなぁ…";
                ConsoleOutput = "Textractor inject kirikiri\n" +
                                "Textractor inject SiglusEngine\n" +
                                "Textractor inject Cs2";
            }
            else
            {
                // initialize
                InsertCodeCommand         = new RelayCommand(() => Textractor.InsertHook(InputCode), CanInsertCode);
                SelectedHookChangeCommand = new RelayCommand(SelectedHookChangeHandle);
                SubmitCommand             = new RelayCommand(SubmitMessage, CanSubmitMessage);

                if (File.Exists(SimpleIoc.Default.GetInstance <GameInfo>().ConfigPath))
                {
                    Regexp = EHConfig.GetValue(EHNode.Regexp);
                }

                Textractor.DataEvent += DataRecvEventHandler;

                Task.Run(async() =>
                {
                    SearchedCode = await QueryHCodeApi.QueryCode(SimpleIoc.Default.GetInstance <GameInfo>().MD5);
                    if (SearchedCode != "")
                    {
                        log.Info($"Find code {SearchedCode} in Aniclan");
                    }
                });
            }
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            var currentDirectory = Path.GetDirectoryName(GetType().Assembly.Location);

            Directory.SetCurrentDirectory(currentDirectory);
            Utils.AddEnvironmentPaths((currentDirectory + @"\libs").Split());
            DispatcherHelper.Initialize();
            SimpleIoc.Default.Register <GameInfo>();
            SimpleIoc.Default.Register <AppSetting>();
            //new TaskbarView();
            notifyIcon = (TaskbarIcon)FindResource("NotifyIcon");
            log4net.Config.XmlConfigurator.Configure();
            // AppDomain.CurrentDomain.UnhandledException += GlobalErrorHandle 非ui线程
            DispatcherUnhandledException += (s, eventArgs) => {
                log.Error(eventArgs.Exception);
                MessageBox.Show(eventArgs.Exception.ToString(), "Eroge Helper");
                // TODO: 复制粘贴板转到github. Friendly error message
            };
            log.Info("Started Logging");
            log.Info($"Enviroment directory: {Directory.GetCurrentDirectory()}");

            if (e.Args.Length == 0)
            {
                MessageBox.Show("请使用 EHInstaller 安装我> < \n\r" +
                                "如果你已经安装了直接右键游戏选择Eroge Helper启动就好了~",
                                "ErogeHelper");
                Current.Shutdown();
                return;
            }

            GameInfo gameInfo = SimpleIoc.Default.GetInstance(typeof(GameInfo)) as GameInfo;

            gameInfo.Path        = e.Args[0];
            gameInfo.ConfigPath  = gameInfo.Path + ".eh.config";
            gameInfo.Dir         = gameInfo.Path.Substring(0, gameInfo.Path.LastIndexOf('\\'));
            gameInfo.ProcessName = Path.GetFileNameWithoutExtension(gameInfo.Path);
            gameInfo.MD5         = Utils.GetMD5(gameInfo.Path);

            log.Info($"Game's path: {e.Args[0]}");
            log.Info($"Locate Emulator statu: {e.Args.Contains("/le")}");

            if (e.Args.Contains("/le"))
            {
                // Use Locate Emulator
                try
                {
                    Process.Start(new ProcessStartInfo
                    {
                        FileName        = Directory.GetCurrentDirectory() + @"\libs\x86\LEProc.exe",
                        UseShellExecute = false,

                        Arguments = File.Exists(gameInfo.Path + ".le.config")
                                               ? $"-run \"{gameInfo.Path}\""
                                               : $"\"{gameInfo.Path}\""
                    });
                }
                // XXX: 捕获不到,7秒超时
                catch (AccessViolationException)
                {
                    throw new AccessViolationException("LE执行出现内存错误,这可能是游戏进程还未退出,问题不大请重新尝试用LE启动游戏~");
                }
            }
            else
            {
                // Direct start
                Process.Start(new ProcessStartInfo
                {
                    FileName         = gameInfo.Path,
                    UseShellExecute  = false,
                    WorkingDirectory = gameInfo.Dir
                });
            }

            bool newProcFind;
            // Pid标记
            List <int> procMark = new List <int>();
            // tmpProcList 每次循环 Process.GetProcessesByName() 命中的进程
            List <Process> tmpProcList = new List <Process>();
            var            totalTime   = new Stopwatch();

            totalTime.Start();
            do
            {
                newProcFind = false;
                gameInfo.ProcList.Clear();
                tmpProcList.Clear();
                #region Collect Processes To tmpProcList
                foreach (Process p in Process.GetProcessesByName(gameInfo.ProcessName))
                {
                    tmpProcList.Add(p);
                }
                foreach (Process p in Process.GetProcessesByName(gameInfo.ProcessName + ".log"))
                {
                    tmpProcList.Add(p);
                }
                #endregion
                foreach (Process p in tmpProcList)
                {
                    gameInfo.ProcList.Add(p);
                    if (!procMark.Contains(p.Id))
                    {
                        procMark.Add(p.Id);
                        try
                        {
                            if (p.WaitForInputIdle(500) == false) // 500 延迟随意写的,正常启动一般在100~200范围
                            {
                                log.Info($"Procces {p.Id} maybe stuck");
                            }
                        }
                        catch (InvalidOperationException ex)
                        {
                            // skip no effect exception
                            // This occurrent because process has no window event
                            log.Warn(ex.Message);
                        }

                        newProcFind = true;
                    }
                }
                // 进程找完却没有得到hWnd的可能也是存在的,所以以带hWnd的进程为主
                gameInfo.HWndProc = Utils.FindHWndProc(gameInfo.ProcList);

                // timeout
                if (totalTime.Elapsed.TotalSeconds > 7 && gameInfo.HWndProc == null)
                {
                    log.Info("Timeout! Find MainWindowHandle Faied");
                    MessageBox.Show("(超时)没能找到游戏窗口!", "ErogeHelper");
                    Current.Shutdown();
                    return;
                }
            } while (newProcFind || (gameInfo.HWndProc == null));
            totalTime.Stop();

            log.Info($"{gameInfo.ProcList.Count} Process(es) and window handle 0x{Convert.ToString(gameInfo.HWndProc.MainWindowHandle.ToInt64(), 16).ToUpper()} Found. Spend time {totalTime.Elapsed.TotalSeconds:0:00}s");

            // Cheak if there is eh.config file
            if (File.Exists(gameInfo.ConfigPath))
            {
                gameInfo.HookCode         = EHConfig.GetValue(EHNode.HookCode);
                gameInfo.ThreadContext    = long.Parse(EHConfig.GetValue(EHNode.ThreadContext));
                gameInfo.SubThreadContext = long.Parse(EHConfig.GetValue(EHNode.SubThreadContext));
                gameInfo.Regexp           = EHConfig.GetValue(EHNode.Regexp);

                log.Info($"Get HCode {gameInfo.HookCode} from file {gameInfo.ProcessName}.exe.eh.config");
                // Display text window
                new GameView().Show();
            }
            else
            {
                log.Info("Not find xml config file, open hook panel.");
                new HookConfigView().Show();
            }

            Textractor.Init();
        }