Esempio n. 1
0
        public override void PrePlayPlayer(PlayerInfo playerInfo, int index, HandlerContext context)
        {
            if (handlerData.SymlinkGame || handlerData.HardcopyGame)
            {
                List <string> dirExclusions  = new List <string>();
                List <string> fileExclusions = new List <string>();
                List <string> fileCopies     = new List <string>();

                // symlink the game folder (and not the bin folder, if we have one)
                linkFolder = Path.Combine(tempDir, "Instance" + index);

                try
                {
                    if (Directory.Exists(linkFolder))
                    {
                        Directory.Delete(linkFolder, true);
                    }
                }
                catch { }

                Directory.CreateDirectory(linkFolder);

                linkWorkingDir = linkFolder;
                if (!string.IsNullOrEmpty(handlerData.BinariesFolder))
                {
                    linkWorkingDir = Path.Combine(linkFolder, handlerData.BinariesFolder);
                    dirExclusions.Add(handlerData.BinariesFolder);
                }
                exePath = Path.Combine(linkWorkingDir, Path.GetFileName(this.userGame.ExePath));

                if (!string.IsNullOrEmpty(handlerData.WorkingFolder))
                {
                    linkWorkingDir = Path.Combine(linkFolder, handlerData.WorkingFolder);
                    dirExclusions.Add(handlerData.WorkingFolder);
                }

                // some games have save files inside their game folder, so we need to access them inside the loop
                handlerData.RegisterAdditional(Folder.InstancedGameFolder.ToString(), linkFolder);

                if (handlerData.Hook.CustomDllEnabled)
                {
                    fileExclusions.Add("xinput1_3.dll");
                    fileExclusions.Add("ncoop.ini");
                }
                if (!handlerData.SymlinkExe)
                {
                    fileCopies.Add(handlerData.ExecutableName.ToLower());
                }

                // additional ignored files by the generic info
                if (handlerData.FileSymlinkExclusions != null)
                {
                    string[] symlinkExclusions = handlerData.FileSymlinkExclusions;
                    for (int k = 0; k < symlinkExclusions.Length; k++)
                    {
                        string s = symlinkExclusions[k];
                        // make sure it's lower case
                        fileExclusions.Add(s.ToLower());
                    }
                }
                if (handlerData.FileSymlinkCopyInstead != null)
                {
                    string[] fileSymlinkCopyInstead = handlerData.FileSymlinkCopyInstead;
                    for (int k = 0; k < fileSymlinkCopyInstead.Length; k++)
                    {
                        string s = fileSymlinkCopyInstead[k];
                        // make sure it's lower case
                        fileCopies.Add(s.ToLower());
                    }
                }
                if (handlerData.DirSymlinkExclusions != null)
                {
                    string[] symlinkExclusions = handlerData.DirSymlinkExclusions;
                    for (int k = 0; k < symlinkExclusions.Length; k++)
                    {
                        string s = symlinkExclusions[k];
                        // make sure it's lower case
                        dirExclusions.Add(s.ToLower());
                    }
                }

                string[] fileExclusionsArr = fileExclusions.ToArray();
                string[] fileCopiesArr     = fileCopies.ToArray();

                if (handlerData.HardcopyGame)
                {
                    // copy the directory
                    //int exitCode;
                    //FileUtil.CopyDirectory(rootFolder, new DirectoryInfo(rootFolder), linkFolder, out exitCode, dirExclusions.ToArray(), fileExclusionsArr, true);
                }
                else
                {
                    int exitCode;
                    //CmdUtil.LinkDirectory(rootFolder, new DirectoryInfo(rootFolder), linkFolder, out exitCode, dirExclusions.ToArray(), fileExclusionsArr, fileCopiesArr, true);
                    WinDirectoryUtil.LinkDirectory(rootFolder, new DirectoryInfo(rootFolder), linkFolder, out exitCode, dirExclusions.ToArray(), fileExclusionsArr, fileCopiesArr, true);

                    if (!handlerData.SymlinkExe)
                    {
                        //File.Copy(userGame.ExePath, exePath, true);
                    }
                }
            }
            else
            {
                exePath        = userGame.ExePath;
                linkWorkingDir = rootFolder;
                linkFolder     = workingFolder;
            }

            context.ExePath           = exePath;
            context.RootInstallFolder = exeFolder;
            context.RootFolder        = linkFolder;
        }
Esempio n. 2
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;
            }
        }