public void ScanExes()
        {
            DriveInfo[] drives = DriveInfo.GetDrives();
            Stopwatch   stop   = new Stopwatch();

            for (int i = 0; i < drives.Length; i++)
            {
                DriveInfo d = drives[i];

                if (d.DriveFormat != "NTFS")
                {
                    continue;
                }

                LogManager.Log("> Searching drive {0} for game executables", d.Name);

                stop.Reset();
                stop.Start();

                Dictionary <ulong, FileNameAndParentFrn> mDict = new Dictionary <ulong, FileNameAndParentFrn>();
                MFTReader mft = new MFTReader();
                mft.Drive = d.RootDirectory.FullName;

                mft.EnumerateVolume(out mDict, new string[] { ".exe" });
                foreach (KeyValuePair <UInt64, FileNameAndParentFrn> entry in mDict)
                {
                    FileNameAndParentFrn file = (FileNameAndParentFrn)entry.Value;

                    string name  = file.Name;
                    string lower = name.ToLower();

                    GameInfo game;
                    if (gameManager.GameInfos.TryGetValue(lower, out game))
                    {
                        string path = mft.GetFullPath(file);
                        LogManager.Log("Found game: {0}, full path: {1}", game.GameName, path);

                        UserGameInfo info = new UserGameInfo();
                        info.InitializeDefault(game, path);
                        gameManager.User.Games.Add(info);
                    }
                }

                stop.Stop();
                LogManager.Log("> Took {0} seconds to search drive {1}", stop.Elapsed.TotalSeconds.ToString("0.00"), d.Name);
            }

            gameManager.SaveUserProfile();
            gameManager.WaitSave();
        }
Beispiel #2
0
        private void SearchDrive(object state)
        {
            int             i    = (int)state;
            SearchDriveInfo info = toSearch[i];

            if (!info.drive.IsReady)
            {
                done++;
                return;
            }

            float totalDiskPc = 1 / (float)toSearch.Count;
            float thirdDiskPc = totalDiskPc / 3.0f;

            // 1/3 done, we started the operation
            UpdateProgress(thirdDiskPc);

            LogManager.Log("> Searching drive {0} for game executables", info.drive.Name);

            Dictionary <ulong, FileNameAndParentFrn> mDict = new Dictionary <ulong, FileNameAndParentFrn>();
            MFTReader mft = new MFTReader();

            mft.Drive = info.drive.RootDirectory.FullName;

            mft.EnumerateVolume(out mDict, new string[] { ".exe" });

            progress += thirdDiskPc; // 2/3 done
            UpdateProgress(thirdDiskPc);

            float increment = thirdDiskPc / (float)mDict.Count;

            foreach (KeyValuePair <UInt64, FileNameAndParentFrn> entry in mDict)
            {
                if (closed)
                {
                    return;
                }

                UpdateProgress(increment);

                FileNameAndParentFrn file = (FileNameAndParentFrn)entry.Value;

                string name  = file.Name;
                string lower = name.ToLower();

                if (GameManager.Instance.AnyGame(lower))
                {
                    string path = mft.GetFullPath(file);
                    if (path.Contains("$Recycle.Bin") ||
                        path.Contains(@"\Instance"))
                    {
                        // noope
                        continue;
                    }

                    UserGameInfo uinfo = GameManager.Instance.TryAddGame(path);

                    if (uinfo != null)
                    {
#if RELEASE
                        if (uinfo.Game.Debug)
                        {
                            continue;
                        }
#endif

                        LogManager.Log("> Found new game {0} on drive {1}", uinfo.Game.GameName, info.drive.Name);
                        Invoke(new Action(delegate
                        {
                            listGames.Items.Add(uinfo.Game.GameName + " - " + path);
                            listGames.Invalidate();
                            main.NewUserGame(uinfo);
                        }));
                    }
                }
            }

            if (closed)
            {
                return;
            }

            done++;
            if (done == toSearch.Count)
            {
                searching = false;
                Invoke(new Action(delegate
                {
                    progress = 1;
                    UpdateProgress(0);
                    btnSearch.Enabled = true;
                    main.RefreshGames();
                    MessageBox.Show("Finished searching!");
                }));
            }
        }
Beispiel #3
0
        private void SearchDrive(object state)
        {
            int driveIndex         = (int)state;
            SearchStorageInfo info = drivesToSearch[driveIndex];

            if (!info.Drive.IsReady)
            {
                drivesFinishedSearching++;
                return;
            }

            float totalDiskPc = 1 / (float)drivesToSearch.Count;
            float thirdDiskPc = totalDiskPc / 3.0f;

            // 1/3 done, we started the operation
            UpdateProgress(thirdDiskPc);

            Log.WriteLine($"> Searching drive {info.Drive.Name} for game executables");

            Dictionary <ulong, FileNameAndParentFrn> allExes = new Dictionary <ulong, FileNameAndParentFrn>();
            MFTReader mft = new MFTReader();

            mft.Drive = info.Drive.RootDirectory.FullName;

            // TODO: search only for specific games?
            mft.EnumerateVolume(out allExes, new string[] { ".exe" });

            UpdateProgress(thirdDiskPc); // 2/3 done

            float perFilePCIncrement = thirdDiskPc / (float)allExes.Count;
            bool  shouldUpdate       = false;

            foreach (KeyValuePair <UInt64, FileNameAndParentFrn> entry in allExes)
            {
                UpdateProgress(perFilePCIncrement);

                FileNameAndParentFrn file = (FileNameAndParentFrn)entry.Value;

                string name  = file.Name;
                string lower = name.ToLower();

                if (GameManager.Instance.AnyGame(lower))
                {
                    string path = mft.GetFullPath(file);
                    if (path.Contains("$Recycle.Bin") ||
                        path.Contains(@"\Instance"))
                    {
                        // noope
                        continue;
                    }

                    UserGameInfo uinfo = GameManager.Instance.TryAddGame(path);

                    if (uinfo != null)
                    {
                        Log.WriteLine($"> Found new game ID {uinfo.GameID} on drive {info.Drive.Name}");
                        Invoke(new Action(delegate {
                            list_games.Items.Add(GameManager.Instance.MetadataManager.GetGameName(uinfo.GameID) + " - " + path);
                            list_games.Invalidate();

                            shouldUpdate = true;
                        }));
                    }
                }
            }

            if (shouldUpdate)
            {
                MainForm.Instance.Invoke((Action)MainForm.Instance.RefreshGames);
            }

            drivesFinishedSearching++;
            if (drivesFinishedSearching == drivesToSearch.Count)
            {
                searching = false;
                Invoke(new Action(delegate {
                    progress = 1;
                    UpdateProgress(0);
                    btn_search.Enabled = true;

                    // TODO make it better
                    MainForm.Instance.RefreshGames();
                    MessageBox.Show("Finished searching!");
                }));
            }
        }
Beispiel #4
0
        private static void ExecuteTask(StartGameData data)
        {
            switch (data.Task)
            {
            case GameStarterTask.StartGame: {
                string gamePath       = data.Parameters[0];
                string gameArgs       = data.Parameters[1];
                string gameWorkingDir = data.Parameters[2];

                ConsoleU.WriteLine($"Start game: EXE: {gamePath} ARGS: {gameArgs} WORKDIR: {gameWorkingDir}", Palette.Feedback);
                StartGame(gamePath, gameArgs, gameWorkingDir);
            }
            break;

            case GameStarterTask.KillMutex: {
                Log.WriteLine($"Kill Mutex Task");
                string   procId  = data.Parameters[0];
                string[] mutexes = new string[data.Parameters.Length - 1];
                for (int j = 1; j < data.Parameters.Length; j++)
                {
                    string m = data.Parameters[j];
                    mutexes[j - 1] = m;
                }
                KillMutex(procId, mutexes);
                WriteToDataFile(Assembly.GetEntryAssembly().Location, true.ToString());
            }
            break;

            case GameStarterTask.RenameMutex: {
                Log.WriteLine($"Rename Mutex Task");
                string   procId  = data.Parameters[0];
                string[] mutexes = new string[data.Parameters.Length - 1];
                for (int j = 1; j < data.Parameters.Length; j++)
                {
                    string m = data.Parameters[j];
                    mutexes[j - 1] = m;
                }
                KillMutex(procId, mutexes);
                WriteToDataFile(Assembly.GetEntryAssembly().Location, true.ToString());
            }
            break;

            case GameStarterTask.ScanKillMutex: {
                Log.WriteLine($"Scan Kill Mutex");

                List <int> processIds = new List <int>();

                for (int j = 0; j < data.Parameters.Length; j++)
                {
                    string        scanMutexDataRaw = data.Parameters[j];
                    ScanMutexData scanMutex        = JsonConvert.DeserializeObject <ScanMutexData>(scanMutexDataRaw);
                    Log.WriteLine($"Kill Mutex for process {scanMutex.ProcessName}");

                    for (; ;)
                    {
                        Process[] procs = Process.GetProcessesByName(scanMutex.ProcessName);
                        if (procs == null || procs.Length == 0)
                        {
                            Thread.Sleep(250);
                        }
                        else
                        {
                            // kill mutexes
                            bool killedMutexes = false;
                            for (int k = 0; k < procs.Length; k++)
                            {
                                Process p = procs[k];
                                if (processIds.Contains(p.Id))
                                {
                                    continue;
                                }

                                // start other process, as the mutexes are only truly killed
                                // when the process is ended
                                if (scanMutex.ShouldRename)
                                {
                                    StartGameUtil.RenameMutex(p, scanMutex.Mutexes);
                                }
                                else
                                {
                                    StartGameUtil.KillMutex(p, scanMutex.Mutexes);
                                }
                                //KillMutex(p.Id.ToString(), scanMutex.Mutexes);
                                processIds.Add(p.Id);
                                killedMutexes = true;
                                break;
                            }

                            if (killedMutexes)
                            {
                                Log.WriteLine($"Killed all mutexes for process {scanMutex.ProcessName}");
                                WriteToDataFile(Assembly.GetEntryAssembly().Location, true.ToString());
                                break;
                            }
                        }
                    }
                }
            }
            break;

            case GameStarterTask.MultipleTasks: {
                Log.WriteLine($"Multiple tasks");
                for (int j = 0; j < data.Parameters.Length; j++)
                {
                    string        taskDataRaw = data.Parameters[j];
                    StartGameData taskData    = JsonConvert.DeserializeObject <StartGameData>(taskDataRaw);

                    Log.WriteLine($"Executing task {j + 1}");
                    ExecuteTask(taskData);
                }
            }
            break;

            case GameStarterTask.QueryMutex: {
                string   procId  = data.Parameters[0];
                string[] mutexes = new string[data.Parameters.Length - 1];
                for (int j = 1; j < data.Parameters.Length; j++)
                {
                    string m = data.Parameters[j];
                    mutexes[j - 1] = m;
                }
            }
            break;

            case GameStarterTask.ListMonitors:
                break;

            case GameStarterTask.ScanGames: {
                // initialize game manager to read available handlers
                GameManager gameManager = new GameManager();

                List <string> games = new List <string>();
                for (int j = 0; j < data.Parameters.Length; j++)
                {
                    string driveName = data.Parameters[j];
                    //SearchStorageInfo info = JsonConvert.DeserializeObject<SearchStorageInfo>(storageData);
                    DriveInfo drive = new DriveInfo(driveName);

                    if (!drive.IsReady)
                    {
                        continue;
                    }

                    Log.WriteLine($"> Searching drive {drive.Name} for game executables");

                    Dictionary <ulong, FileNameAndParentFrn> allExes = new Dictionary <ulong, FileNameAndParentFrn>();
                    MFTReader mft = new MFTReader();
                    mft.Drive = drive.RootDirectory.FullName;

                    // TODO: search only for specific games?
                    mft.EnumerateVolume(out allExes, new string[] { ".exe" });

                    foreach (KeyValuePair <UInt64, FileNameAndParentFrn> entry in allExes)
                    {
                        FileNameAndParentFrn file = (FileNameAndParentFrn)entry.Value;

                        string name  = file.Name;
                        string lower = name.ToLower();

                        string path = mft.GetFullPath(file);
                        if (path.Contains("$Recycle.Bin") ||
                            path.Contains(@"\Instance"))
                        {
                            // noope
                            continue;
                        }

                        if (GameManager.Instance.AnyGame(lower))
                        {
                            Log.WriteLine($"Found game at path: {path}");
                            games.Add(path);
                        }
                    }
                }

                WriteToDataFile(Assembly.GetEntryAssembly().Location, JsonConvert.SerializeObject(games));
            }
            break;

            case GameStarterTask.SymlinkFolders:
                for (int j = 0; j < data.Parameters.Length; j++)
                {
                    string symData = data.Parameters[j];
                    Log.WriteLine($"Symlink game instance {j + 1}");

                    SymlinkGameData gameData = JsonConvert.DeserializeObject <SymlinkGameData>(symData);
                    int             exitCode;
                    WinDirectoryUtil.LinkDirectory(gameData.SourcePath, new DirectoryInfo(gameData.SourcePath), gameData.DestinationPath, out exitCode, gameData.DirExclusions, gameData.FileExclusions, gameData.FileCopies, true);
                }
                WriteToDataFile(Assembly.GetEntryAssembly().Location, true.ToString());
                break;
            }
        }