public string Play()
        {
            if (!SteamUtil.IsSteamRunning())
            {
                MessageBox.Show("Steam must be opened to play Portal 2 splitScreen. Open it then click OK.");
            }

            // minimize everything
            User32.MinimizeEverything();

            // copy the correct xinput to the bin folder
            byte[] xdata = GamesResources.Portal_xinput1_3;
            xinputPath = Path.Combine(binFolder, "xinput1_3.dll");
            using (MemoryStream stream = new MemoryStream(xdata))
            {
                // write to bin folder
                using (FileStream file = new FileStream(xinputPath, FileMode.Create))
                {
                    stream.WriteTo(file);
                }
            }

            int pid = StartGameUtil.StartGame(executablePlace, "-novid", 0);

            proc = Process.GetProcessById(pid);

            loaded = true;
            return(string.Empty);
        }
Esempio n. 2
0
        private void ScanDrivesThread(object state)
        {
            List <SearchStorageInfo> storage = (List <SearchStorageInfo>)state;

            string[] result = StartGameUtil.ScanGames(storage.ToArray());

            bool shouldUpdate = false;

            for (int i = 0; i < result.Length; i++)
            {
                string path = result[i];

#if false
                UserGameInfo uinfo = GameManager.Instance.TryAddGame(path);

                if (uinfo != null)
                {
                    Log.WriteLine($"> Found new game ID {uinfo.GameID}");
                    shouldUpdate = true;
                }
#endif
            }

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

            Invoke(new Action(() => {
                btn_search.Text    = "Scan";
                btn_search.Enabled = true;
            }));
        }
Esempio n. 3
0
        public override void PlayPlayer(int index, HandlerContext context)
        {
            ProcessInfo       procData = Player.ProcessData;
            List <PlayerInfo> players  = profile.PlayerData;

            ProcessInfo pdata = Player.ProcessData;

            for (int j = 0; j < handlerData.KillMutex.Length; j++)
            {
                string mutex = handlerData.KillMutex[j];
                StartGameUtil.KillMutex(pdata.Process, mutex);
            }
        }
Esempio n. 4
0
        public override void PrePlayPlayer(PlayerInfo player, int index, HandlerContext context)
        {
            ProcessInfo       procData  = player.ProcessData;
            bool              hasSetted = procData != null && procData.Setted;
            List <PlayerInfo> players   = profile.PlayerData;

            if (index > 0 && (handlerData.KillMutex?.Length > 0 || !hasSetted))
            {
                PlayerInfo before = players[index - 1];
                for (; ;)
                {
                    Thread.Sleep(1000);

                    if (handlerData.KillMutex != null)
                    {
                        if (handlerData.KillMutex.Length > 0 && !before.ProcessData.KilledMutexes)
                        {
                            // check for the existence of the mutexes
                            // before invoking our StartGame app to kill them
                            ProcessInfo pdata = before.ProcessData;

                            if (StartGameUtil.MutexExists(pdata.Process, handlerData.KillMutex))
                            {
                                // mutexes still exist, must kill
                                StartGameUtil.KillMutex(pdata.Process, handlerData.KillMutex);
                                //pdata.KilledMutexes = true;
                                break;
                            }
                            else
                            {
                                // mutexes dont exist anymore
                                break;
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            for (int i = 0; i < players.Count; i++)
            {
            }
        }
        public void Update(int delayMS)
        {
            if (profile == null)
            {
                return;
            }

            exited = 0;
            List <PlayerInfo> players = profile.PlayerData;

            timer += delayMS;

            for (int i = 0; i < players.Count; i++)
            {
                PlayerInfo  p    = players[i];
                ProcessData data = p.ProcessData;
                if (data == null)
                {
                    continue;
                }

                if (p.SteamEmu)
                {
                    List <int> children = ProcessUtil.GetChildrenProcesses(data.Process);

                    // catch the game process, that was spawned from Smart Steam Emu
                    if (children.Count > 0)
                    {
                        for (int j = 0; j < children.Count; j++)
                        {
                            int     id    = children[j];
                            Process child = Process.GetProcessById(id);
                            try
                            {
                                if (child.ProcessName.Contains("conhost"))
                                {
                                    continue;
                                }
                            }
                            catch
                            {
                                continue;
                            }

                            data.AssignProcess(child);
                            p.SteamEmu = child.ProcessName.Contains("SmartSteamLoader") || child.ProcessName.Contains("cmd");
                        }
                    }
                }
                else
                {
                    if (data.Setted)
                    {
                        if (data.Process.HasExited)
                        {
                            exited++;
                            continue;
                        }

                        if (!p.ProcessData.KilledMutexes && gen.KillMutex.Length > 0)
                        {
                            StartGameUtil.KillMutex(data.Process, gen.KillMutex);
                            p.ProcessData.KilledMutexes = true;
                        }

                        uint lStyle = User32Interop.GetWindowLong(data.HWnd.NativePtr, User32_WS.GWL_STYLE);
                        if (lStyle != data.RegLong)
                        {
                            uint toRemove = User32_WS.WS_CAPTION;
                            lStyle = lStyle & (~toRemove);

                            User32Interop.SetWindowLong(data.HWnd.NativePtr, User32_WS.GWL_STYLE, lStyle);
                            data.RegLong       = lStyle;
                            data.HWnd.Location = data.Position;
                        }

                        data.HWnd.TopMost = true;

                        if (p.IsKeyboardPlayer)
                        {
                            Rectangle r = p.MonitorBounds;
                            Cursor.Clip = r;
                            User32Interop.SetForegroundWindow(data.HWnd.NativePtr);
                        }
                    }
                    else
                    {
                        data.Process.Refresh();

                        if (data.Process.HasExited)
                        {
                            if (p.GotLauncher)
                            {
                                if (p.GotGame)
                                {
                                    exited++;
                                }
                                else
                                {
                                    List <int> children = ProcessUtil.GetChildrenProcesses(data.Process);
                                    if (children.Count > 0)
                                    {
                                        for (int j = 0; j < children.Count; j++)
                                        {
                                            int     id  = children[j];
                                            Process pro = Process.GetProcessById(id);

                                            if (!attached.Contains(pro))
                                            {
                                                attached.Add(pro);
                                                data.HWnd = null;
                                                p.GotGame = true;
                                                data.AssignProcess(pro);
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // Steam showing a launcher, need to find our game process
                                string launcher = gen.LauncherExe;
                                if (launcher.ToLower().EndsWith(".exe"))
                                {
                                    launcher = launcher.Remove(launcher.Length - 4, 4);
                                }

                                Process[] procs = Process.GetProcessesByName(launcher);
                                for (int j = 0; j < procs.Length; j++)
                                {
                                    Process pro = procs[j];
                                    if (!attached.Contains(pro))
                                    {
                                        attached.Add(pro);
                                        data.AssignProcess(pro);
                                        p.GotLauncher = true;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (data.HWNDRetry || data.HWnd == null || data.HWnd.NativePtr != data.Process.MainWindowHandle)
                            {
                                data.HWnd = new HwndObject(data.Process.MainWindowHandle);
                                Point pos = data.HWnd.Location;

                                if (String.IsNullOrEmpty(data.HWnd.Title) ||
                                    pos.X == -32000 ||
                                    data.HWnd.Title.ToLower() == gen.LauncherTitle.ToLower())
                                {
                                    data.HWNDRetry = true;
                                }
                                else
                                {
                                    Size s = data.Size;
                                    data.Setted        = true;
                                    data.HWnd.TopMost  = true;
                                    data.HWnd.Size     = data.Size;
                                    data.HWnd.Location = data.Position;
                                }
                            }
                        }
                    }
                }
            }

            if (exited == players.Count)
            {
                if (!hasEnded)
                {
                    End();
                }
            }
        }
        public string Play()
        {
            List <PlayerInfo> players = profile.PlayerData;

            Screen[] all = Screen.AllScreens;

            string backupDir  = GameManager.Instance.GetBackupFolder(this.userGame.Game);
            string binFolder  = Path.GetDirectoryName(userGame.ExePath);
            string rootFolder = ReplaceCaseInsensitive(binFolder, gen.BinariesFolder, "");

            int  gamePadId = 0;
            bool first     = true;

            hidetaskbar = false;

            bool keyboard = false;

            if (gen.SupportsKeyboard)
            {
                // make sure the keyboard player is the last to be started,
                // so it will get the focus by default
                KeyboardPlayer player = (KeyboardPlayer)profile.Options["KeyboardPlayer"];
                if (player.Value != -1)
                {
                    keyboard = true;
                    List <PlayerInfo> newPlayers = new List <PlayerInfo>();

                    for (int i = 0; i < players.Count; i++)
                    {
                        PlayerInfo p = players[i];
                        if (i == player.Value)
                        {
                            continue;
                        }

                        newPlayers.Add(p);
                    }
                    newPlayers.Add(players[player.Value]);
                    players = newPlayers;
                }
            }

            for (int i = 0; i < players.Count; i++)
            {
                PlayerInfo player = players[i];
                if (i > 0 && gen.KillMutex.Length > 0)
                {
                    PlayerInfo before = players[i - 1];
                    for (;;)
                    {
                        if (exited > 0)
                        {
                            return("");
                        }
                        Thread.Sleep(100);
                        if (before.ProcessData.KilledMutexes)
                        {
                            break;
                        }
                    }
                }

                Rectangle playerBounds = player.MonitorBounds;

                // find the monitor that has this screen
                Screen owner = null;
                for (int j = 0; j < all.Length; j++)
                {
                    Screen s = all[j];
                    if (s.Bounds.Contains(playerBounds))
                    {
                        owner = s;
                        break;
                    }
                }

                int  width        = playerBounds.Width;
                int  height       = playerBounds.Height;
                bool isFullscreen = false;

                if (owner != null)
                {
                    Rectangle ob = owner.Bounds;
                    if (playerBounds.X == ob.X &&
                        playerBounds.Y == ob.Y &&
                        playerBounds.Width == ob.Width &&
                        playerBounds.Height == ob.Height)
                    {
                        isFullscreen = true;
                    }
                }

                GenericContext context = gen.CreateContext(profile, player, this);
                context.PlayerID         = i;
                context.IsFullscreen     = isFullscreen;
                context.IsKeyboardPlayer = keyboard && i == players.Count - 1;
                gen.PrePlay(context);

                player.IsKeyboardPlayer = context.IsKeyboardPlayer;

                string saveFile = context.SavePath;
                if (gen.SaveType != SaveType.None && first)
                {
                    GameManager.Instance.BeginBackup(gen);
                    GameManager.Instance.BackupFile(gen, saveFile);
                }

                // symlink the game folder
                // find out the folder that contains the game executable
                string root = GetRootFolder(gen.BinariesFolder);

                string linkFolder = Path.Combine(backupDir, "Instance" + i);
                Directory.CreateDirectory(linkFolder);
                int exitCode;
                CmdUtil.LinkDirectories(rootFolder, linkFolder, out exitCode, root.ToLower());

                string linkBin = Path.Combine(linkFolder, gen.BinariesFolder);

                if (!string.IsNullOrEmpty(gen.BinariesFolder))
                {
                    // this needs fixing, if there are several folder to the exe and they have important files inside, this won't work! TODO
                    Directory.CreateDirectory(linkBin);
                    CmdUtil.LinkDirectories(binFolder, linkBin, out exitCode);
                }

                string exePath = Path.Combine(linkBin, this.userGame.Game.ExecutableName);

                if (context.SymlinkExe)
                {
                    CmdUtil.LinkFiles(binFolder, linkBin, out exitCode, "xinput", "ncoop");
                }
                else
                {
                    CmdUtil.LinkFiles(binFolder, linkBin, out exitCode, "xinput", "ncoop", Path.GetFileNameWithoutExtension(gen.ExecutableName.ToLower()));
                    File.Copy(userGame.ExePath, exePath, true);
                }

                // some games have save files inside their game folder, so we need to access them inside the loop
                this.data[Folder.GameFolder.ToString()] = linkFolder;

                IniFile file = new IniFile(saveFile);

                switch (context.SaveType)
                {
                case SaveType.INI:
                    for (int j = 0; j < context.ModifySave.Length; j++)
                    {
                        SaveInfo save = context.ModifySave[j];
                        if (save is IniSaveInfo)
                        {
                            IniSaveInfo ini = (IniSaveInfo)save;
                            file.IniWriteValue(ini.Section, ini.Key, ini.Value);
                        }
                    }
                    break;
                }

                string startArgs = context.StartArguments;

                if (context.CustomXinput)
                {
                    byte[] xdata = null;
                    if (context.IsKeyboardPlayer)
                    {
                        // TODO: need to make an xinput that answers to no gamepad?
                        xdata = Properties.Resources.xinput4;
                    }
                    else
                    {
                        switch (gamePadId)
                        {
                        case 0:
                            xdata = Properties.Resources.xinput1;
                            break;

                        case 1:
                            xdata = Properties.Resources.xinput2;
                            break;

                        case 2:
                            xdata = Properties.Resources.xinput3;
                            break;

                        case 3:
                        default:
                            xdata = Properties.Resources.xinput4;
                            break;
                        }
                        gamePadId++;
                    }

                    using (Stream str = File.OpenWrite(Path.Combine(linkBin, "xinput1_3.dll")))
                    {
                        str.Write(xdata, 0, xdata.Length);
                    }

                    string ncoopIni = Path.Combine(linkBin, "ncoop.ini");

                    using (Stream str = File.OpenWrite(ncoopIni))
                    {
                        byte[] ini = Properties.Resources.ncoop;
                        str.Write(ini, 0, ini.Length);
                    }

                    IniFile x360 = new IniFile(ncoopIni);
                    x360.IniWriteValue("Options", "HookWindows", context.HookWindows.ToString(CultureInfo.InvariantCulture));
                    x360.IniWriteValue("Options", "HookGameWindow", context.HookGameWindow.ToString(CultureInfo.InvariantCulture));
                    x360.IniWriteValue("Options", "HookNeeded", context.HookNeeded.ToString(CultureInfo.InvariantCulture));
                }

                Process proc;
                if (context.NeedsSteamEmulation)
                {
                    string steamEmu = GameManager.Instance.ExtractSteamEmu();
                    if (string.IsNullOrEmpty(steamEmu))
                    {
                        return("Extraction of SmartSteamEmu failed!");
                    }

                    string emuExe = Path.Combine(steamEmu, "SmartSteamLoader.exe");

                    string  emuIni = Path.Combine(steamEmu, "SmartSteamEmu.ini");
                    IniFile emu    = new IniFile(emuIni);

                    emu.IniWriteValue("Launcher", "Target", exePath);
                    emu.IniWriteValue("Launcher", "StartIn", Path.GetDirectoryName(exePath));
                    emu.IniWriteValue("Launcher", "CommandLine", startArgs);
                    emu.IniWriteValue("Launcher", "SteamClientPath", Path.Combine(steamEmu, "SmartSteamEmu.dll"));
                    emu.IniWriteValue("Launcher", "SteamClientPath64", Path.Combine(steamEmu, "SmartSteamEmu64.dll"));
                    emu.IniWriteValue("Launcher", "InjectDll", "0");
                    emu.IniWriteValue("SmartSteamEmu", "AppId", context.SteamID);

                    if (context.KillMutex.Length > 0)
                    {
                        // to kill the mutexes we need to orphanize the process
                        proc = ProcessUtil.RunOrphanProcess(emuExe);
                    }
                    else
                    {
                        ProcessStartInfo startInfo = new ProcessStartInfo();
                        startInfo.FileName = emuExe;
                        proc = Process.Start(startInfo);
                    }

                    player.SteamEmu = true;
                }
                else
                {
                    if (context.KillMutex.Length > 0)
                    {
                        proc = Process.GetProcessById(StartGameUtil.StartGame(exePath, startArgs));
                    }
                    else
                    {
                        ProcessStartInfo startInfo = new ProcessStartInfo();
                        startInfo.FileName         = exePath;
                        startInfo.WindowStyle      = ProcessWindowStyle.Hidden;
                        startInfo.Arguments        = startArgs;
                        startInfo.UseShellExecute  = true;
                        startInfo.WorkingDirectory = Path.GetDirectoryName(exePath);
                        proc = Process.Start(startInfo);
                    }

                    if (proc == null)
                    {
                        for (int times = 0; times < 200; times++)
                        {
                            Thread.Sleep(50);

                            Process[] procs        = Process.GetProcesses();
                            string    proceName    = Path.GetFileNameWithoutExtension(context.ExecutableName).ToLower();
                            string    launcherName = Path.GetFileNameWithoutExtension(context.LauncherExe).ToLower();

                            for (int j = 0; j < procs.Length; j++)
                            {
                                Process p      = procs[j];
                                string  lowerP = p.ProcessName.ToLower();
                                if (((lowerP == proceName) || lowerP == launcherName) &&
                                    !attached.Contains(p))
                                {
                                    attached.Add(p);
                                    proc = p;
                                    break;
                                }
                            }

                            if (proc != null)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        attached.Add(proc);
                    }
                }

                ProcessData data = new ProcessData(proc);

                data.Position      = new Point(playerBounds.X, playerBounds.Y);
                data.Size          = new Size(playerBounds.Width, playerBounds.Height);
                data.KilledMutexes = context.KillMutex.Length == 0;
                player.ProcessData = data;

                if (first)
                {
                    if (context.HideTaskbar)
                    {
                        hidetaskbar = true;
                    }
                }

                first = false;
            }

            //if (hidetaskbar)
            //{
            //    User32.HideTaskbar();
            //}

            return(string.Empty);
        }
        public string Play()
        {
            if (handlerData.ForceFinishOnPlay)
            {
                ProcessUtil.ForceKill(Path.GetFileNameWithoutExtension(handlerData.ExecutableName.ToLower()));
            }

            List <PlayerInfo> players = profile.PlayerData;

            for (int i = 0; i < players.Count; i++)
            {
                players[i].PlayerID = i;
            }

            UserScreen[] all = ScreensUtil.AllScreens();

            string nucleusRootFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            string tempDir       = GameManager.Instance.GempTempFolder(handlerData);
            string exeFolder     = Path.GetDirectoryName(userGame.ExePath).ToLower();
            string rootFolder    = exeFolder;
            string workingFolder = exeFolder;

            if (!string.IsNullOrEmpty(handlerData.BinariesFolder))
            {
                rootFolder = StringUtil.ReplaceCaseInsensitive(exeFolder, handlerData.BinariesFolder.ToLower(), "");
            }
            if (!string.IsNullOrEmpty(handlerData.WorkingFolder))
            {
                workingFolder = Path.Combine(exeFolder, handlerData.WorkingFolder.ToLower());
            }

            bool first    = true;
            bool keyboard = false;

            //if (handlerData.SupportsKeyboard)
            //{
            //    // make sure the keyboard player is the last to be started,
            //    // so it will get the focus by default
            //    KeyboardPlayer player = (KeyboardPlayer)profile.Options["KeyboardPlayer"];
            //    if (player.Value != -1)
            //    {
            //        keyboard = true;
            //        List<PlayerInfo> newPlayers = new List<PlayerInfo>();

            //        for (int i = 0; i < players.Count; i++)
            //        {
            //            PlayerInfo p = players[i];
            //            if (i == player.Value)
            //            {
            //                continue;
            //            }

            //            newPlayers.Add(p);
            //        }
            //        newPlayers.Add(players[player.Value]);
            //        players = newPlayers;
            //    }
            //}

            for (int i = 0; i < players.Count; i++)
            {
                PlayerInfo  player    = players[i];
                ProcessInfo procData  = player.ProcessData;
                bool        hasSetted = procData != null && procData.Setted;

                if (i > 0 && (handlerData.KillMutex?.Length > 0 || !hasSetted))
                {
                    PlayerInfo before = players[i - 1];
                    for (; ;)
                    {
                        if (exited > 0)
                        {
                            return("");
                        }
                        Thread.Sleep(1000);

                        if (handlerData.KillMutex != null)
                        {
                            if (handlerData.KillMutex.Length > 0 && !before.ProcessData.KilledMutexes)
                            {
                                // check for the existence of the mutexes
                                // before invoking our StartGame app to kill them
                                ProcessInfo pdata = before.ProcessData;

                                if (StartGameUtil.MutexExists(pdata.Process, handlerData.KillMutex))
                                {
                                    // mutexes still exist, must kill
                                    StartGameUtil.KillMutex(pdata.Process, handlerData.KillMutex);
                                    pdata.KilledMutexes = true;
                                    break;
                                }
                                else
                                {
                                    // mutexes dont exist anymore
                                    break;
                                }
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                Rectangle  playerBounds = player.MonitorBounds;
                UserScreen owner        = player.Owner;

                int  width        = playerBounds.Width;
                int  height       = playerBounds.Height;
                bool isFullscreen = owner.Type == UserScreenType.FullScreen;

                string exePath;
                string linkFolder;
                string linkBinFolder;

                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" + i);
                    Directory.CreateDirectory(linkFolder);

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

                    if (!string.IsNullOrEmpty(handlerData.WorkingFolder))
                    {
                        linkBinFolder = 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
                    jsData[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);

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

                HandlerContext context = handlerData.CreateContext(profile, player);
                context.PlayerID     = player.PlayerID;
                context.IsFullscreen = isFullscreen;

                context.ExePath           = exePath;
                context.RootInstallFolder = exeFolder;
                context.RootFolder        = linkFolder;

                handlerData.PrePlay(context, player);

                string startArgs = context.StartArguments;

                if (context.Hook.CustomDllEnabled)
                {
                    byte[] xdata = Properties.Resources.xinput1_3;
                    if (context.Hook.XInputNames == null)
                    {
                        using (Stream str = File.OpenWrite(Path.Combine(linkBinFolder, "xinput1_3.dll")))
                        {
                            str.Write(xdata, 0, xdata.Length);
                        }
                    }
                    else
                    {
                        string[] xinputs = context.Hook.XInputNames;
                        for (int z = 0; z < xinputs.Length; z++)
                        {
                            string xinputName = xinputs[z];
                            using (Stream str = File.OpenWrite(Path.Combine(linkBinFolder, xinputName)))
                            {
                                str.Write(xdata, 0, xdata.Length);
                            }
                        }
                    }

                    string ncoopIni = Path.Combine(linkBinFolder, "ncoop.ini");
                    using (Stream str = File.OpenWrite(ncoopIni))
                    {
                        byte[] ini = Properties.Resources.ncoop;
                        str.Write(ini, 0, ini.Length);
                    }

                    IniFile x360 = new IniFile(ncoopIni);
                    x360.IniWriteValue("Options", "ForceFocus", handlerData.Hook.ForceFocus.ToString(CultureInfo.InvariantCulture));
                    x360.IniWriteValue("Options", "ForceFocusWindowName", handlerData.Hook.ForceFocusWindowName.ToString(CultureInfo.InvariantCulture));

                    x360.IniWriteValue("Options", "WindowX", playerBounds.X.ToString(CultureInfo.InvariantCulture));
                    x360.IniWriteValue("Options", "WindowY", playerBounds.Y.ToString(CultureInfo.InvariantCulture));

                    if (context.Hook.SetWindowSize)
                    {
                        x360.IniWriteValue("Options", "ResWidth", context.Width.ToString(CultureInfo.InvariantCulture));
                        x360.IniWriteValue("Options", "ResHeight", context.Height.ToString(CultureInfo.InvariantCulture));
                    }
                    else
                    {
                        x360.IniWriteValue("Options", "ResWidth", "0");
                        x360.IniWriteValue("Options", "ResHeight", "0");
                    }

                    x360.IniWriteValue("Options", "RerouteInput", context.Hook.XInputReroute.ToString(CultureInfo.InvariantCulture));
                    x360.IniWriteValue("Options", "RerouteJoystickTemplate", JoystickDatabase.GetID(player.GamepadProductGuid.ToString()).ToString(CultureInfo.InvariantCulture));

                    x360.IniWriteValue("Options", "EnableMKBInput", player.IsKeyboardPlayer.ToString(CultureInfo.InvariantCulture));

                    // windows events
                    x360.IniWriteValue("Options", "BlockInputEvents", context.Hook.BlockInputEvents.ToString(CultureInfo.InvariantCulture));
                    x360.IniWriteValue("Options", "BlockMouseEvents", context.Hook.BlockMouseEvents.ToString(CultureInfo.InvariantCulture));
                    x360.IniWriteValue("Options", "BlockKeyboardEvents", context.Hook.BlockKeyboardEvents.ToString(CultureInfo.InvariantCulture));

                    // xinput
                    x360.IniWriteValue("Options", "XInputEnabled", context.Hook.XInputEnabled.ToString(CultureInfo.InvariantCulture));
                    x360.IniWriteValue("Options", "XInputPlayerID", player.GamepadId.ToString(CultureInfo.InvariantCulture));

                    // dinput
                    x360.IniWriteValue("Options", "DInputEnabled", context.Hook.DInputEnabled.ToString(CultureInfo.InvariantCulture));
                    x360.IniWriteValue("Options", "DInputGuid", player.GamepadGuid.ToString().ToUpper());
                    x360.IniWriteValue("Options", "DInputForceDisable", context.Hook.DInputForceDisable.ToString());
                }

                Process proc;
                if (context.NeedsSteamEmulation)
                {
                    string steamEmu = GameManager.Instance.ExtractSteamEmu(Path.Combine(linkFolder, "SmartSteamLoader"));
                    //string steamEmu = GameManager.Instance.ExtractSteamEmu();
                    if (string.IsNullOrEmpty(steamEmu))
                    {
                        return("Extraction of SmartSteamEmu failed!");
                    }

                    string  emuExe = Path.Combine(steamEmu, "SmartSteamLoader.exe");
                    string  emuIni = Path.Combine(steamEmu, "SmartSteamEmu.ini");
                    IniFile emu    = new IniFile(emuIni);

                    emu.IniWriteValue("Launcher", "Target", exePath);
                    emu.IniWriteValue("Launcher", "StartIn", Path.GetDirectoryName(exePath));
                    emu.IniWriteValue("Launcher", "CommandLine", startArgs);
                    emu.IniWriteValue("Launcher", "SteamClientPath", Path.Combine(steamEmu, "SmartSteamEmu.dll"));
                    emu.IniWriteValue("Launcher", "SteamClientPath64", Path.Combine(steamEmu, "SmartSteamEmu64.dll"));
                    emu.IniWriteValue("Launcher", "InjectDll", "1");

                    emu.IniWriteValue("SmartSteamEmu", "AppId", context.SteamID);
                    //emu.IniWriteValue("SmartSteamEmu", "SteamIdGeneration", "Static");

                    //string userName = $"Player { context.PlayerID }";

                    //emu.IniWriteValue("SmartSteamEmu", "PersonaName", userName);
                    //emu.IniWriteValue("SmartSteamEmu", "ManualSteamId", userName);

                    //emu.IniWriteValue("SmartSteamEmu", "Offline", "False");
                    //emu.IniWriteValue("SmartSteamEmu", "MasterServer", "");
                    //emu.IniWriteValue("SmartSteamEmu", "MasterServerGoldSrc", "");

                    handlerData.SetupSse?.Invoke();

                    if (context.KillMutex?.Length > 0)
                    {
                        // to kill the mutexes we need to orphanize the process
                        proc = ProcessUtil.RunOrphanProcess(emuExe);
                    }
                    else
                    {
                        ProcessStartInfo startInfo = new ProcessStartInfo();
                        startInfo.FileName = emuExe;
                        proc = Process.Start(startInfo);
                    }

                    player.SteamEmu = true;
                }
                else
                {
                    if (context.KillMutex?.Length > 0)
                    {
                        proc = Process.GetProcessById(StartGameUtil.StartGame(
                                                          new DirectoryInfo(exePath).GetRelativePath(nucleusRootFolder), startArgs,
                                                          new DirectoryInfo(linkFolder).GetRelativePath(nucleusRootFolder)));
                    }
                    else
                    {
                        ProcessStartInfo startInfo = new ProcessStartInfo();
                        startInfo.FileName = exePath;
                        //startInfo.WindowStyle = ProcessWindowStyle.Hidden;
                        startInfo.Arguments        = startArgs;
                        startInfo.UseShellExecute  = true;
                        startInfo.WorkingDirectory = Path.GetDirectoryName(exePath);
                        proc = Process.Start(startInfo);
                    }

                    if (proc == null)
                    {
                        for (int times = 0; times < 200; times++)
                        {
                            Thread.Sleep(50);

                            Process[] procs        = Process.GetProcesses();
                            string    proceName    = Path.GetFileNameWithoutExtension(context.ExecutableName).ToLower();
                            string    launcherName = Path.GetFileNameWithoutExtension(context.LauncherExe).ToLower();

                            for (int j = 0; j < procs.Length; j++)
                            {
                                Process p      = procs[j];
                                string  lowerP = p.ProcessName.ToLower();
                                if (((lowerP == proceName) || lowerP == launcherName) &&
                                    !attached.Contains(p))
                                {
                                    attached.Add(p);
                                    proc = p;
                                    break;
                                }
                            }

                            if (proc != null)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        attached.Add(proc);
                    }
                }

                ProcessInfo data = new ProcessInfo(proc);

                data.Position      = new Point(playerBounds.X, playerBounds.Y);
                data.Size          = new Size(playerBounds.Width, playerBounds.Height);
                data.KilledMutexes = context.KillMutex?.Length == 0;
                player.ProcessData = data;

                first = false;

                Thread.Sleep(TimeSpan.FromSeconds(handlerData.PauseBetweenStarts));
            }

            return(string.Empty);
        }
Esempio n. 8
0
        public string Play()
        {
            if (!SteamUtil.IsSteamRunning())
            {
                return("Steam must be opened to play Left 4 Dead 2 splitScreen");
            }

            using (Stream videoStream = new FileStream(videoFile, FileMode.Open))
            {
                videoCfg = new SourceCfgFile(videoStream);
            }
            string originalCFG = String.Copy(videoCfg.RawData);

            // minimize everything
            User32.MinimizeEverything();
            Screen[] allScreens = Screen.AllScreens;

            string folder    = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            string l4dFolder = Path.GetDirectoryName(executablePlace);
            int    gamePadId = 0;


            if (instances)
            {
                for (int i = 0; i < players.Count; i++)
                {
                    PlayerInfo p = players[i];

                    Screen    screen   = allScreens[p.ScreenIndex];
                    int       width    = 0;
                    int       height   = 0;
                    Rectangle bounds   = screen.Bounds;
                    Point     location = new Point();

                    ViewportUtil.GetPlayerViewport(p, 0, out width, out height, out location);

                    CultureInfo c = CultureInfo.InvariantCulture;
                    UpdateVideoCfg(width.ToString(c), height.ToString(c), "0", "1");

                    if (i == 0)
                    {
                        MakeAutoExecServer();
                    }
                    else
                    {
                        MakeAutoExecClient();
                    }
                    MakeMakeSplit();

                    string execPlace = executablePlace;
                    string l4dBinFolder;
                    if (i == 0)
                    {
                        l4dBinFolder = Path.Combine(l4dFolder, "bin");
                    }
                    else
                    {
                        string l4d = Path.Combine(folder, "L4D2_" + (i + 1));
                        Directory.CreateDirectory(l4d);

                        int exitCode;
                        #region mklink
                        CmdUtil.ExecuteCommand(l4d, out exitCode,
                                               "mklink /d \"" + Path.Combine(l4d, "config") + "\" \"" + Path.Combine(l4dFolder, "config") + "\"",
                                               "mklink /d \"" + Path.Combine(l4d, "hl2") + "\" \"" + Path.Combine(l4dFolder, "hl2") + "\"",
                                               "mklink /d \"" + Path.Combine(l4d, "left4dead2") + "\" \"" + Path.Combine(l4dFolder, "left4dead2") + "\"",
                                               "mklink /d \"" + Path.Combine(l4d, "left4dead2_dlc1") + "\" \"" + Path.Combine(l4dFolder, "left4dead2_dlc1") + "\"",
                                               "mklink /d \"" + Path.Combine(l4d, "left4dead2_dlc2") + "\" \"" + Path.Combine(l4dFolder, "left4dead2_dlc2") + "\"",
                                               "mklink /d \"" + Path.Combine(l4d, "left4dead2_dlc3") + "\" \"" + Path.Combine(l4dFolder, "left4dead2_dlc3") + "\"",
                                               "mklink /d \"" + Path.Combine(l4d, "platform") + "\" \"" + Path.Combine(l4dFolder, "platform") + "\"",
                                               "mklink /d \"" + Path.Combine(l4d, "RemStorage") + "\" \"" + Path.Combine(l4dFolder, "RemStorage") + "\"",
                                               "mklink /d \"" + Path.Combine(l4d, "update") + "\" \"" + Path.Combine(l4dFolder, "update") + "\"");
                        #endregion

                        // copy executable
                        File.Copy(Path.Combine(l4dFolder, "left4dead2.exe"), Path.Combine(l4d, "left4dead2.exe"), true);

                        // make bin folder now
                        l4dBinFolder = Path.Combine(l4d, "bin");
                        string originalBinFolder = Path.Combine(l4dFolder, "bin");
                        Directory.CreateDirectory(l4dBinFolder);

                        #region mklink
                        CmdUtil.ExecuteCommand(l4d, out exitCode,
                                               "mklink /d \"" + Path.Combine(l4dBinFolder, "dedicated") + "\"  \"" + Path.Combine(originalBinFolder, "dedicated") + "\"",
                                               "mklink /d \"" + Path.Combine(l4dBinFolder, "linux32") + "\"  \"" + Path.Combine(originalBinFolder, "linux32") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "addoninstaller.exe") + "\"  \"" + Path.Combine(originalBinFolder, "addoninstaller.exe") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "addoninstaller_osx") + "\"  \"" + Path.Combine(originalBinFolder, "addoninstaller_osx") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "adminserver.dll") + "\"  \"" + Path.Combine(originalBinFolder, "adminserver.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "binkw32.dll") + "\"  \"" + Path.Combine(originalBinFolder, "binkw32.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "bsppack.dll") + "\"  \"" + Path.Combine(originalBinFolder, "bsppack.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "bugreporter.dll") + "\"  \"" + Path.Combine(originalBinFolder, "bugreporter.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "bugreporter_public.dll") + "\"  \"" + Path.Combine(originalBinFolder, "bugreporter_public.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "chromehtml.dll") + "\"  \"" + Path.Combine(originalBinFolder, "chromehtml.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "config.SoftTHconfig") + "\"  \"" + Path.Combine(originalBinFolder, "config.SoftTHconfig") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "crashhandler.dll") + "\"  \"" + Path.Combine(originalBinFolder, "crashhandler.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "datacache.dll") + "\"  \"" + Path.Combine(originalBinFolder, "datacache.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "dxsupport.cfg") + "\"  \"" + Path.Combine(originalBinFolder, "dxsupport.cfg") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "dxsupport_episodic.cfg") + "\"  \"" + Path.Combine(originalBinFolder, "dxsupport_episodic.cfg") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "dxsupport_mac.cfg") + "\"  \"" + Path.Combine(originalBinFolder, "dxsupport_mac.cfg") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "engine.dll") + "\"  \"" + Path.Combine(originalBinFolder, "engine.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "export_entity_group.pl") + "\"  \"" + Path.Combine(originalBinFolder, "export_entity_group.pl") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "export_entity_layer.pl") + "\"  \"" + Path.Combine(originalBinFolder, "export_entity_layer.pl") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "filesystemopendialog.dll") + "\"  \"" + Path.Combine(originalBinFolder, "filesystemopendialog.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "filesystem_stdio.dll") + "\"  \"" + Path.Combine(originalBinFolder, "filesystem_stdio.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "GameOverlayRenderer.log") + "\"  \"" + Path.Combine(originalBinFolder, "GameOverlayRenderer.log") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "gameui.dll") + "\"  \"" + Path.Combine(originalBinFolder, "gameui.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "hl_ent.cnt") + "\"  \"" + Path.Combine(originalBinFolder, "hl_ent.cnt") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "icudt.dll") + "\"  \"" + Path.Combine(originalBinFolder, "icudt.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "icudt42.dll") + "\"  \"" + Path.Combine(originalBinFolder, "icudt42.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "inputsystem.dll") + "\"  \"" + Path.Combine(originalBinFolder, "inputsystem.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "launcher.dll") + "\"  \"" + Path.Combine(originalBinFolder, "launcher.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "libcef.dll") + "\"  \"" + Path.Combine(originalBinFolder, "libcef.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "libmysql.dll") + "\"  \"" + Path.Combine(originalBinFolder, "libmysql.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "maplist_terror.txt") + "\"  \"" + Path.Combine(originalBinFolder, "maplist_terror.txt") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "materialsystem.dll") + "\"  \"" + Path.Combine(originalBinFolder, "materialsystem.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "mdllib.dll") + "\"  \"" + Path.Combine(originalBinFolder, "mdllib.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "mss32.dll") + "\"  \"" + Path.Combine(originalBinFolder, "mss32.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "mssdolby.flt") + "\"  \"" + Path.Combine(originalBinFolder, "mssdolby.flt") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "mssds3d.flt") + "\"  \"" + Path.Combine(originalBinFolder, "mssds3d.flt") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "mssdsp.flt") + "\"  \"" + Path.Combine(originalBinFolder, "mssdsp.flt") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "msseax.flt") + "\"  \"" + Path.Combine(originalBinFolder, "msseax.flt") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "mssmp3.asi") + "\"  \"" + Path.Combine(originalBinFolder, "mssmp3.asi") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "msssrs.flt") + "\"  \"" + Path.Combine(originalBinFolder, "msssrs.flt") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "msvcr71.dll") + "\"  \"" + Path.Combine(originalBinFolder, "msvcr71.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "parsifal.dll") + "\"  \"" + Path.Combine(originalBinFolder, "parsifal.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "rdmwin32.dll") + "\"  \"" + Path.Combine(originalBinFolder, "rdmwin32.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "scenefilecache.dll") + "\"  \"" + Path.Combine(originalBinFolder, "scenefilecache.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "serverbrowser.dll") + "\"  \"" + Path.Combine(originalBinFolder, "serverbrowser.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "serverplugin_empty.dll") + "\"  \"" + Path.Combine(originalBinFolder, "serverplugin_empty.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "shaderapidx10.dll") + "\"  \"" + Path.Combine(originalBinFolder, "shaderapidx10.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "shaderapidx9.dll") + "\"  \"" + Path.Combine(originalBinFolder, "shaderapidx9.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "shaderapiempty.dll") + "\"  \"" + Path.Combine(originalBinFolder, "shaderapiempty.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "soundemittersystem.dll") + "\"  \"" + Path.Combine(originalBinFolder, "soundemittersystem.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "soundsystem.dll") + "\"  \"" + Path.Combine(originalBinFolder, "soundsystem.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "stats.bin") + "\"  \"" + Path.Combine(originalBinFolder, "stats.bin") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "stdshader_dbg.dll") + "\"  \"" + Path.Combine(originalBinFolder, "stdshader_dbg.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "stdshader_dx9.dll") + "\"  \"" + Path.Combine(originalBinFolder, "stdshader_dx9.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "Steam.dll") + "\"  \"" + Path.Combine(originalBinFolder, "Steam.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "steamclient.dll") + "\"  \"" + Path.Combine(originalBinFolder, "steamclient.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "steamclient_l4d2.dll") + "\"  \"" + Path.Combine(originalBinFolder, "steamclient_l4d2.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "steam_api.dll") + "\"  \"" + Path.Combine(originalBinFolder, "steam_api.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "steam_appid.txt") + "\"  \"" + Path.Combine(originalBinFolder, "steam_appid.txt") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "Steam_l4d2.dll") + "\"  \"" + Path.Combine(originalBinFolder, "Steam_l4d2.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "studiorender.dll") + "\"  \"" + Path.Combine(originalBinFolder, "studiorender.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "texturecompile_dll.dll") + "\"  \"" + Path.Combine(originalBinFolder, "texturecompile_dll.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "tier0.dll") + "\"  \"" + Path.Combine(originalBinFolder, "tier0.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "tier0_s.dll") + "\"  \"" + Path.Combine(originalBinFolder, "tier0_s.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "unicode.dll") + "\"  \"" + Path.Combine(originalBinFolder, "unicode.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "unicows.dll") + "\"  \"" + Path.Combine(originalBinFolder, "unicows.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "unitlib.dll") + "\"  \"" + Path.Combine(originalBinFolder, "unitlib.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "valve_avi.dll") + "\"  \"" + Path.Combine(originalBinFolder, "valve_avi.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "vaudio_miles.dll") + "\"  \"" + Path.Combine(originalBinFolder, "vaudio_miles.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "vaudio_speex.dll") + "\"  \"" + Path.Combine(originalBinFolder, "vaudio_speex.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "vgui2.dll") + "\"  \"" + Path.Combine(originalBinFolder, "vgui2.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "vguimatsurface.dll") + "\"  \"" + Path.Combine(originalBinFolder, "vguimatsurface.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "vidcfg.bin") + "\"  \"" + Path.Combine(originalBinFolder, "vidcfg.bin") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "vphysics.dll") + "\"  \"" + Path.Combine(originalBinFolder, "vphysics.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "vscript.dll") + "\"  \"" + Path.Combine(originalBinFolder, "vscript.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "vstdlib.dll") + "\"  \"" + Path.Combine(originalBinFolder, "vstdlib.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "vstdlib_s.dll") + "\"  \"" + Path.Combine(originalBinFolder, "vstdlib_s.dll") + "\"",
                                               "mklink \"" + Path.Combine(l4dBinFolder, "vtex_dll.dll") + "\"  \"" + Path.Combine(originalBinFolder, "vtex_dll.dll") + "\"");
                        #endregion

                        execPlace = Path.Combine(l4d, "left4dead2.exe");
                    }

                    if ((int)keyboardId == i)
                    {
                        // delete if there are any xinput
                        string xinputPath = Path.Combine(l4dBinFolder, "xinput1_3.dll");
                        if (File.Exists(xinputPath))
                        {
                            File.Delete(xinputPath);
                        }
                    }
                    else
                    {
                        // copy the correct xinput to the bin folder
                        byte[] xdata = null;
                        switch (gamePadId)
                        {
                        case 0:
                            xdata = Nucleus.Coop.Games.GamesResources._1_xinput1_3;
                            break;

                        case 1:
                            xdata = Nucleus.Coop.Games.GamesResources._2_xinput1_3;
                            break;

                        case 2:
                            xdata = Nucleus.Coop.Games.GamesResources._3_xinput1_3;
                            break;

                        case 3:
                            xdata = Nucleus.Coop.Games.GamesResources._4_xinput1_3;
                            break;

                        default:
                            xdata = Nucleus.Coop.Games.GamesResources._4_xinput1_3;
                            break;
                        }
                        string xinputPath = Path.Combine(l4dBinFolder, "xinput1_3.dll");
                        using (MemoryStream stream = new MemoryStream(xdata))
                        {
                            // write to bin folder
                            using (FileStream file = new FileStream(xinputPath, FileMode.Create))
                            {
                                stream.CopyTo(file);
                            }
                        }
                        gamePadId++;
                    }


                    int pid = StartGameUtil.StartGame(execPlace,
                                                      "-novid -insecure", delayTime, "hl2_singleton_mutex", "steam_singleton_mutext");
                    Process proc = Process.GetProcessById(pid);

                    HwndObject hwnd = new HwndObject(proc.Handle);
                    ScreenData data = new ScreenData();
                    data.Position = location;
                    data.HWND     = hwnd;
                    data.Size     = new Size(width, height);
                    p.Process     = proc;
                    p.Tag         = data;

                    Thread.Sleep(delayTime);

                    //uint processHandle;
                    //IntPtr windowHandle = proc.MainWindowHandle;
                    //uint threadID = User32.GetWindowThreadProcessId(windowHandle, out processHandle);
                    //bool installed = InstallHook(threadID);
                }
            }
            else
            {
                List <DuetPlayerInfo> duets = ViewportUtil.GetPlayerDuets(players);
                for (int i = 0; i < duets.Count; i++)
                {
                    DuetPlayerInfo duet = duets[i];
                }
            }

            int  screenIndex = -1;
            bool twoScreens  = false;
            int  fullWidth   = 0;
            int  fullHeight  = 0;
            for (int i = 0; i < players.Count; i++)
            {
                PlayerInfo player = players[i];
                Screen     scr    = allScreens[player.ScreenIndex];

                if (screenIndex == -1)
                {
                    screenIndex = player.ScreenIndex;
                    fullWidth   = scr.Bounds.Width;
                    fullHeight  = scr.Bounds.Height;
                }
                else
                {
                    if (screenIndex != player.ScreenIndex)
                    {
                        twoScreens = true;
                        // Add 2nd monitor
                        fullWidth += scr.Bounds.Width;
                    }
                }
            }

            loaded = true;

            return("");

            string fWidth            = fullWidth.ToString();
            string fHeight           = fullHeight.ToString();
            string fullScr           = (0).ToString();
            string noWindowBorderStr = (1).ToString();

            //if (players.Count == 1)
            //{
            //    // 1 monitor
            //    Screen monitor = allScreens[players.First().Key];
            //    fWidth = monitor.Bounds.Width.ToString(CultureInfo.InvariantCulture);
            //    fHeight = monitor.Bounds.Height.ToString(CultureInfo.InvariantCulture);

            //    fullScr = (0).ToString();
            //    noWindowBorderStr = (1).ToString();
            //}
            //else
            //{
            //    // 2 or more monitors

            //    //??
            //    fullScr = (1).ToString();
            //    noWindowBorderStr = (0).ToString();
            //}

            fWidth  = "1920";// 960x540
            fHeight = "540";

            string d3d9Path = binFolder + @"\d3d9.dll";
            // SoftTH
            if (twoScreens)
            {
                // Copy SoftTH to the game folder
                // Get the SoftTH stream
                if (!File.Exists(d3d9Path))
                {
                    using (MemoryStream stream = new MemoryStream(Nucleus.Coop.Games.GamesResources.d3d9))
                    {
                        // write to bin folder
                        using (FileStream file = new FileStream(d3d9Path, FileMode.Create))
                        {
                            stream.CopyTo(file);
                        }
                    }
                }
            }
            else
            {
                // Delete SoftTH from the game folder
                FileInfo file = new FileInfo(d3d9Path);
                // Only delete if it's not read only
                if (File.Exists(d3d9Path))
                {
                    File.Delete(d3d9Path);
                }
            }

            // PAK hex edit
            if (twoScreens)
            {
                FileInfo f = new FileInfo(pak01_000_path);
                if (!f.IsReadOnly)
                {
                    // make a backup of pak01_000, if it isn't already made
                    string dir = Path.GetDirectoryName(backupPak);
                    if (!Directory.Exists(dir))
                    {
                        Directory.CreateDirectory(dir);
                    }
                    if (!File.Exists(backupPak))
                    {
                        File.Copy(pak01_000_path, backupPak);
                    }

                    using (FileStream str = File.OpenRead(backupPak))
                    {
                        // Now modify some stuff
                        // Eat Point that comes at 29.664.480
                        // The 8 is at position 29.664.483

                        // 29.675.904

                        byte one = 49;
                        byte six = 54;

                        using (FileStream stream = new FileStream(pak01_000_path, FileMode.Create))
                        {
                            byte[] buff = new byte[4096];

                            int point = 29664480;

                            while (str.Position < point)
                            {
                                int length = 4096;
                                if (point - str.Position < length)
                                {
                                    length = (int)(point - str.Position);
                                }

                                str.Read(buff, 0, length);
                                stream.Write(buff, 0, length);
                            }
                            // Jumps 1 byte
                            str.Position += 1;

                            str.Read(buff, 0, 2);
                            stream.Write(buff, 0, 2);

                            // Jumps the 8
                            str.Position += 1;

                            buff[0] = one;
                            buff[1] = six;
                            stream.Write(buff, 0, 2);

                            while (stream.Position < str.Length)
                            {
                                int length = 4096;
                                if (str.Length - str.Position < length)
                                {
                                    length = (int)(str.Length - str.Position);
                                }

                                str.Read(buff, 0, length);
                                stream.Write(buff, 0, length);
                            }
                        }
                    }

                    f.IsReadOnly = true;
                }
            }
            //else
            //{
            //    if (File.Exists(backupPak))
            //    {
            //        if (File.Exists(pak01_000))
            //        {
            //            FileInfo f = new FileInfo(pak01_000);
            //            f.IsReadOnly = false;
            //            File.Delete(pak01_000);
            //        }
            //        File.Copy(backupPak, pak01_000);
            //    }
            //}

            int splitMode = 1;
            for (int i = 0; i < players.Count; i++)
            {
                PlayerInfo player = players[i];
                if (player.ScreenType == ScreenType.HorizontalBottom ||
                    player.ScreenType == ScreenType.HorizontalTop)
                {
                    splitMode = 1;
                }
                else
                {
                    splitMode = 2;
                }
            }


            MakeAutoExecSplitscreen(splitMode.ToString(CultureInfo.InvariantCulture));
            MakeMakeSplit();


            /* if (player.ScreenType == ScreenType.VerticalLeft ||
             *      player.ScreenType == ScreenType.VerticalRight)*/

            //ss_splitmode 1 = horizontal
            //ss_splitmode 2 = vertical

            //ProcessStartInfo startInfo = new ProcessStartInfo();
            //startInfo.FileName = executablePlace;
            //startInfo.WindowStyle = ProcessWindowStyle.Hidden;

            //MessageBox.Show("Press the F8 key after the game is loaded to begin splitscreen!");

            //proc = Process.Start(startInfo);


            return(string.Empty);
        }
Esempio n. 9
0
        public RequestResult <string> Play()
        {
            List <PlayerInfo> players = profile.PlayerData;

            for (int i = 0; i < players.Count; i++)
            {
                players[i].PlayerID = i;
            }
            RequestResult <String> result = new RequestResult <String>();

            List <HandlerContext> contexts = new List <HandlerContext>();

            for (int i = 0; i < players.Count; i++)
            {
                PlayerInfo player = players[i];

                HandlerContext context = handlerManager.HandlerData.CreateContext(profile, player, hasKeyboardPlayer);
                contexts.Add(context);

                context.PlayerID = player.PlayerID;

                List <HandlerModule> modules = player.Modules;
                for (int j = 0; j < modules.Count; j++)
                {
                    modules[j].PrePlayPlayer(i, context);
                }
            }

            // get all the SymlinkData from each players IOModule
            // and start the StartGame application to symlink them
            List <SymlinkGameData> symData = new List <SymlinkGameData>();

            for (int i = 0; i < players.Count; i++)
            {
                PlayerInfo      player = players[i];
                IOModule        mod    = GetModule <IOModule>(player);
                SymlinkGameData data   = mod.SymlinkData;
                symData.Add(data);
            }
            StartGameData symStartData = StartGameUtil.BuildSymlinkGameData(symData.ToArray());

            // check if we need to kill mutexes
            bool killingMutexes = false;

            if (handlerManager.HandlerData.KillMutex?.Length > 0)
            {
                // need to also kill mutexes
                killingMutexes = true;
                StartGameData scanKillData = StartGameUtil.BuildScanKillMutexData(Path.GetFileNameWithoutExtension(userGame.ExePath), players.Count, handlerManager.HandlerData.KillMutex);
                StartGameUtil.RunMultipleTasks(new StartGameData[] { symStartData, scanKillData }, true);

                // wait for confirmation file that the folders were symlinked
                // (RunMultipleTasks doesnt wait for process to finish)
                string dataFile = StartGameUtil.GetStartDataPath();
                for (; ;)
                {
                    if (File.Exists(dataFile))
                    {
                        try {
                            string txt = File.ReadAllText(dataFile);
                            bool   res;
                            if (bool.TryParse(txt, out res))
                            {
                                break;
                            }
                        } catch {
                        }
                    }
                    Thread.Sleep(250);
                }
                File.Delete(dataFile);
            }
            else
            {
                // just symlink the folders
                StartGameUtil.RunPreBuiltData(symStartData, true);
            }

            for (int i = 0; i < players.Count; i++)
            {
                PlayerInfo     player  = players[i];
                HandlerContext context = contexts[i];
                handlerManager.Play(context, player);

                List <HandlerModule> modules = player.Modules;
                for (int j = 0; j < modules.Count; j++)
                {
                    modules[j].PlayPlayer(i, context);
                }

                Thread.Sleep(TimeSpan.FromMilliseconds(handlerManager.HandlerData.PauseBetweenStarts));

                IGameProcessModule procModule = GetModule <IGameProcessModule>(player);
                if (handlerManager.HandlerData.WaitFullWindowLoad)
                {
                    for (; ;)
                    {
                        Thread.Sleep(100);

                        // check for window status
                        if (procModule.HasWindowSetup(player))
                        {
                            break;
                        }
                    }
                }

                if (killingMutexes)
                {
                    // wait for StartGame confirmation that mutexes were killed
                    string dataFile = StartGameUtil.GetStartDataPath();
                    for (; ;)
                    {
                        if (File.Exists(dataFile))
                        {
                            try {
                                string txt = File.ReadAllText(dataFile);
                                bool   res;
                                if (bool.TryParse(txt, out res))
                                {
                                    break;
                                }
                            } catch {
                            }
                        }
                        Thread.Sleep(250);
                    }
                    File.Delete(dataFile);
                }
            }

            return(result);
        }
        public override void PlayPlayer(int index, HandlerContext context)
        {
            Process  proc;
            IOModule ioModule = handler.GetModule <IOModule>(Player);

            string startArgs = context.StartArguments;

            string startingApp = ioModule.LinkedExePath;

            if (!string.IsNullOrEmpty(context.OverrideStartProcess))
            {
                startingApp = context.OverrideStartProcess;
            }

            if (context.KillMutex?.Length > 0)
            {
                int processId = StartGameUtil.StartGame(startingApp, startArgs, ioModule.LinkedWorkingDir);
                proc = Process.GetProcessById(processId);
            }
            else
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName         = startingApp;
                startInfo.Arguments        = startArgs;
                startInfo.UseShellExecute  = true;
                startInfo.WorkingDirectory = Path.GetDirectoryName(ioModule.LinkedExePath);
                proc = Process.Start(startInfo);
            }

            if (proc == null)
            {
                for (int times = 0; times < 200; times++)
                {
                    Thread.Sleep(50);

                    Process[] procs        = Process.GetProcesses();
                    string    proceName    = Path.GetFileNameWithoutExtension(context.ExecutableName).ToLower();
                    string    launcherName = string.IsNullOrEmpty(context.LauncherExe) ? string.Empty : Path.GetFileNameWithoutExtension(context.LauncherExe).ToLower();

                    for (int j = 0; j < procs.Length; j++)
                    {
                        Process p      = procs[j];
                        string  lowerP = p.ProcessName.ToLower();
                        if (((lowerP == proceName) || lowerP == launcherName) &&
                            !attached.Contains(p))
                        {
                            attached.Add(p);
                            proc = p;
                            break;
                        }
                    }

                    if (proc != null)
                    {
                        break;
                    }
                }
            }
            else
            {
                attached.Add(proc);
            }

            ProcessInfo data = new ProcessInfo(proc);

            Rectangle  playerBounds = Player.MonitorBounds;
            UserScreen owner        = Player.Owner;

            int width  = playerBounds.Width;
            int height = playerBounds.Height;

            data.Position      = new Point(playerBounds.X, playerBounds.Y);
            data.Size          = new Size(playerBounds.Width, playerBounds.Height);
            data.KilledMutexes = context.KillMutex?.Length == 0;
            Player.ProcessData = data;
        }
Esempio n. 11
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;
            }
        }
        public string Play()
        {
            if (!SteamUtil.IsSteamRunning())
            {
                return("Steam must be opened to play Left 4 Dead splitscreen");
            }

            using (Stream videoStream = new FileStream(videoFile, FileMode.Open))
            {
                videoCfg = new SourceCfgFile(videoStream);
            }
            string originalCFG = String.Copy(videoCfg.RawData);

            // minimize everything
            User32.MinimizeEverything();
            Screen[] allScreens = Screen.AllScreens;

            string folder    = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            string l4dFolder = Path.GetDirectoryName(executablePlace);
            int    gamePadId = 0;


            if (instances)
            {
                for (int i = 0; i < players.Count; i++)
                {
                    PlayerInfo p = players[i];

                    Screen    screen   = allScreens[p.ScreenIndex];
                    int       width    = 0;
                    int       height   = 0;
                    Rectangle bounds   = screen.Bounds;
                    Point     location = new Point();

                    ViewportUtil.GetPlayerViewport(p, 0, out width, out height, out location);

                    CultureInfo c = CultureInfo.InvariantCulture;
                    UpdateVideoCfg(width.ToString(c), height.ToString(c), "0", "1");

                    if (i == 0)
                    {
                        MakeAutoExecServer();
                    }
                    else
                    {
                        MakeAutoExecClient();
                    }
                    MakeMakeSplit();

                    string execPlace    = executablePlace;
                    string l4dBinFolder = Path.Combine(l4dFolder, "bin");

                    if (i != 0)
                    {
                        string l4d = Path.Combine(folder, "L4D_" + (i + 1));
                        Directory.CreateDirectory(l4d);

                        FolderUtil.MkLink(l4dFolder, l4d, "bin", "left4dead.exe");

                        // copy executable
                        execPlace = Path.Combine(l4d, "left4dead.exe");
                        File.Copy(Path.Combine(l4dFolder, "left4dead.exe"), execPlace, true);

                        // make bin folder now
                        l4dBinFolder = Path.Combine(l4d, "bin");
                        string originalBinFolder = Path.Combine(l4dFolder, "bin");
                        Directory.CreateDirectory(l4dBinFolder);

                        FolderUtil.MkLink(originalBinFolder, l4dBinFolder, "xinput1_3.dll");

                        // add exec to firewall
                        FirewallUtil.AuthorizeProgram("Left 4 Dead", execPlace);
                    }

                    // copy the correct xinput to the bin folder
                    byte[] xdata = null;
                    if (firstKeyboard)
                    {
                        switch (gamePadId)
                        {
                        case 0:
                            xdata = GamesResources._4_xinput1_3;
                            break;

                        case 1:
                            xdata = GamesResources._1_xinput1_3;
                            break;

                        case 2:
                            xdata = GamesResources._2_xinput1_3;
                            break;

                        case 3:
                            xdata = GamesResources._3_xinput1_3;
                            break;
                        }
                    }
                    else
                    {
                        switch (gamePadId)
                        {
                        case 0:
                            xdata = GamesResources._1_xinput1_3;
                            break;

                        case 1:
                            xdata = GamesResources._2_xinput1_3;
                            break;

                        case 2:
                            xdata = GamesResources._3_xinput1_3;
                            break;

                        case 3:
                            xdata = GamesResources._4_xinput1_3;
                            break;
                        }
                    }
                    string xinputPath = Path.Combine(l4dBinFolder, "xinput1_3.dll");
                    using (MemoryStream stream = new MemoryStream(xdata))
                    {
                        // write to bin folder
                        using (FileStream file = new FileStream(xinputPath, FileMode.Create))
                        {
                            stream.WriteTo(file);
                        }
                    }
                    gamePadId++;


                    int pid = StartGameUtil.StartGame(execPlace,
                                                      "-novid -insecure", delayTime, "hl2_singleton_mutex", "steam_singleton_mutext");
                    Process proc = Process.GetProcessById(pid);

                    HwndObject hwnd = new HwndObject(proc.Handle);
                    ScreenData data = new ScreenData();
                    data.Position = location;
                    data.HWND     = hwnd;
                    data.Size     = new Size(width, height);
                    p.Process     = proc;
                    p.Tag         = data;

                    Thread.Sleep(delayTime);
                }

                loaded = true;
            }
            else
            {
                int screenIndex = -1;
                int fullWidth   = 0;
                int fullHeight  = 0;
                for (int i = 0; i < players.Count; i++)
                {
                    PlayerInfo player = players[i];
                    Screen     scr    = allScreens[player.ScreenIndex];

                    if (screenIndex == -1)
                    {
                        screenIndex = player.ScreenIndex;
                        fullWidth   = scr.Bounds.Width;
                        fullHeight  = scr.Bounds.Height;
                    }
                    else
                    {
                        if (screenIndex != player.ScreenIndex)
                        {
                            //twoScreens = true;
                            // Add 2nd monitor
                            fullWidth += scr.Bounds.Width;
                        }
                    }
                }

                loaded = true;

                string fWidth            = fullWidth.ToString();
                string fHeight           = fullHeight.ToString();
                string fullScr           = (0).ToString();
                string noWindowBorderStr = (1).ToString();

                int splitMode = 1;
                for (int i = 0; i < players.Count; i++)
                {
                    PlayerInfo player = players[i];
                    if (player.ScreenType == ScreenType.HorizontalBottom ||
                        player.ScreenType == ScreenType.HorizontalTop)
                    {
                        splitMode = 1;
                    }
                    else
                    {
                        splitMode = 2;
                    }
                }

                MakeAutoExecSplitscreen(splitMode.ToString(CultureInfo.InvariantCulture));
                MakeMakeSplit();

                StartGameUtil.StartGame(executablePlace, "-novid -insecure", delayTime, "hl2_singleton_mutex", "steam_singleton_mutext");
            }

            return(string.Empty);
        }
Esempio n. 13
0
        public void Update(int delayMS)
        {
            if (profile == null)
            {
                return;
            }

            exited = 0;
            List <PlayerInfo> players = profile.PlayerData;

            timer += delayMS;

            for (int i = 0; i < players.Count; i++)
            {
                PlayerInfo p = players[i];
                if (p.screenData == null || p.Process == null)
                {
                    continue;
                }

                if (p.SteamEmu)
                {
                    List <int> children = ProcessUtil.GetChildrenProcesses(p.Process);
                    if (children.Count > 0)
                    {
                        for (int j = 0; j < children.Count; j++)
                        {
                            int     id    = children[j];
                            Process child = Process.GetProcessById(id);
                            try
                            {
                                if (child.ProcessName.Contains("conhost"))
                                {
                                    continue;
                                }
                            }
                            catch
                            {
                                continue;
                            }

                            p.Process  = child;
                            p.SteamEmu = child.ProcessName.Contains("SmartSteamLoader") || child.ProcessName.Contains("cmd");
                        }
                    }
                }
                else
                {
                    ScreenData data = p.screenData;

                    if (data.Set)
                    {
                        if (p.Process.HasExited)
                        {
                            exited++;
                            continue;
                        }

                        if (!p.screenData.KilledMutexes && gen.KillMutex.Length > 0)
                        {
                            StartGameUtil.KillMutex(p.Process, gen.KillMutex);
                            p.screenData.KilledMutexes = true;
                        }

                        uint lStyle = User32Interop.GetWindowLong(data.HWND.Hwnd, User32_WS.GWL_STYLE);
                        if (lStyle != data.RegLong)
                        {
                            uint toRemove = User32_WS.WS_CAPTION;
                            lStyle = lStyle & (~toRemove);

                            User32Interop.SetWindowLong(data.HWND.Hwnd, User32_WS.GWL_STYLE, lStyle);
                            data.RegLong       = lStyle;
                            data.HWND.Location = data.Position;
                        }
                    }
                    else
                    {
                        p.Process.Refresh();

                        if (p.Process.HasExited)
                        {
                            if (p.GotLauncher)
                            {
                                if (p.GotGame)
                                {
                                    exited++;
                                }
                                else
                                {
                                    List <int> children = ProcessUtil.GetChildrenProcesses(p.Process);
                                    if (children.Count > 0)
                                    {
                                        for (int j = 0; j < children.Count; j++)
                                        {
                                            int     id  = children[j];
                                            Process pro = Process.GetProcessById(id);

                                            if (!attached.Contains(pro))
                                            {
                                                attached.Add(pro);
                                                data.HWND = null;
                                                p.GotGame = true;
                                                p.Process = pro;
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // Steam showing a launcher, need to find our game process
                                string launcher = gen.LauncherExe;
                                if (launcher.ToLower().EndsWith(".exe"))
                                {
                                    launcher = launcher.Remove(launcher.Length - 4, 4);
                                }

                                Process[] procs = Process.GetProcessesByName(launcher);
                                for (int j = 0; j < procs.Length; j++)
                                {
                                    Process pro = procs[j];
                                    if (!attached.Contains(pro))
                                    {
                                        attached.Add(pro);
                                        p.Process     = pro;
                                        p.GotLauncher = true;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (data.HWNDRetry || data.HWND == null || data.HWND.Hwnd != p.Process.MainWindowHandle)
                            {
                                data.HWND = new HwndObject(p.Process.MainWindowHandle);
                                Point pos = data.HWND.Location;

                                if (String.IsNullOrEmpty(data.HWND.Title) || pos.X == -32000 || data.HWND.Title.ToLower() == gen.LauncherTitle.ToLower())
                                {
                                    data.HWNDRetry = true;
                                }
                                else
                                {
                                    Size s = data.Size;
                                    data.Set           = true;
                                    data.HWND.TopMost  = true;
                                    data.HWND.Size     = data.Size;
                                    data.HWND.Location = data.Position;
                                }
                            }
                        }
                    }
                }

                if (exited == players.Count)
                {
                    if (!hasEnded)
                    {
                        hasEnded = true;
                        GameManager.Instance.ExecuteBackup(this.userGame.Game);

                        if (Ended != null)
                        {
                            Ended();
                        }
                    }
                }
            }
        }
Esempio n. 14
0
        public string Play()
        {
            List <PlayerInfo> players = profile.PlayerData;

            Screen[] all = Screen.AllScreens;

            string backupDir  = GameManager.Instance.GetBackupFolder(this.userGame.Game);
            string binFolder  = Path.GetDirectoryName(userGame.ExePath);
            string rootFolder = ReplaceCaseInsensitive(binFolder, gen.BinariesFolder, "");

            int gamePadId = 0;

            for (int i = 0; i < players.Count; i++)
            {
                PlayerInfo player = players[i];
                if (i > 0 && gen.KillMutex.Length > 0)
                {
                    PlayerInfo before = players[i - 1];
                    for (;;)
                    {
                        if (exited > 0)
                        {
                            return("");
                        }
                        Thread.Sleep(100);
                        if (before.screenData.KilledMutexes)
                        {
                            break;
                        }
                    }
                }

                Rectangle playerBounds = player.monitorBounds;

                // find the monitor that has this screen
                Screen owner = null;
                for (int j = 0; j < all.Length; j++)
                {
                    Screen s = all[j];
                    if (s.Bounds.Contains(playerBounds))
                    {
                        owner = s;
                        break;
                    }
                }

                int  width        = playerBounds.Width;
                int  height       = playerBounds.Height;
                bool isFullscreen = false;

                if (owner != null)
                {
                    Rectangle ob = owner.Bounds;
                    if (playerBounds.X == ob.X &&
                        playerBounds.Y == ob.Y &&
                        playerBounds.Width == ob.Width &&
                        playerBounds.Height == ob.Height)
                    {
                        isFullscreen = true;
                    }
                }

                engine.SetValue("Id", i.ToString(CultureInfo.InvariantCulture));
                engine.SetValue("Width", width.ToString(CultureInfo.InvariantCulture));
                engine.SetValue("Height", height.ToString(CultureInfo.InvariantCulture));
                engine.SetValue("IsFullscreen", isFullscreen);

                // symlink the game folder
                // find out the folder that contains the game executable
                string root = GetRootFolder(gen.BinariesFolder);

                string linkFolder = Path.Combine(backupDir, "Instance" + i);
                Directory.CreateDirectory(linkFolder);
                int exitCode;
                CmdUtil.LinkDirectories(rootFolder, linkFolder, out exitCode, root.ToLower());

                string linkBin = Path.Combine(linkFolder, gen.BinariesFolder);

                if (!string.IsNullOrEmpty(gen.BinariesFolder))
                {
                    // this needs fixing, if there are several folder to the exe and they have important files inside, this won't work! TODO
                    Directory.CreateDirectory(linkBin);
                    CmdUtil.LinkDirectories(binFolder, linkBin, out exitCode);
                }

                string exePath = Path.Combine(linkBin, this.userGame.Game.ExecutableName);

                if (gen.SymlinkExe)
                {
                    CmdUtil.LinkFiles(binFolder, linkBin, out exitCode, "xinput");
                }
                else
                {
                    CmdUtil.LinkFiles(binFolder, linkBin, out exitCode, "xinput", Path.GetFileNameWithoutExtension(gen.ExecutableName.ToLower()));
                    File.Copy(userGame.ExePath, exePath, true);
                }


                // some games have save files inside their game folder, so we need to access them inside the loop
                this.data[NucleusFolderEnum.GameFolder.ToString()] = linkFolder;

                string  saveFile = ProcessPath(gen.SavePath);
                IniFile file     = new IniFile(saveFile);

                switch (gen.SaveType)
                {
                case GenericGameSaveType.INI:
                    foreach (var modPair in gen.ModifySave)
                    {
                        string   key  = modPair.Key;
                        string[] keys = key.Split('/');

                        engine.Execute(modPair.Value);
                        string val = engine.GetCompletionValue().ToString();

                        file.IniWriteValue(keys[0], keys[1], val);
                    }
                    break;
                }

                string startArgs = gen.StartArguments;

                byte[] xdata = null;

                if (gen.SupportsKeyboard && i == (int)profile.Options["KeyboardPlayer"])
                {
                    engine.SetValue("Keyboard", true);

                    // need to make an xinput that answers to no gamepad?
                    xdata = Properties.Resources.xinput4;
                }
                else
                {
                    engine.SetValue("Keyboard", false);

                    switch (gamePadId)
                    {
                    case 0:
                        xdata = Properties.Resources.xinput1;
                        break;

                    case 1:
                        xdata = Properties.Resources.xinput2;
                        break;

                    case 2:
                        xdata = Properties.Resources.xinput3;
                        break;

                    case 3:
                        xdata = Properties.Resources.xinput4;
                        break;

                    default:
                        xdata = Properties.Resources.xinput4;
                        break;
                    }
                    gamePadId++;
                }

                using (Stream str = File.OpenWrite(Path.Combine(linkBin, "xinput1_3.dll")))
                {
                    str.Write(xdata, 0, xdata.Length);
                }

                if (!string.IsNullOrEmpty(startArgs))
                {
                    startArgs = engine.Execute(startArgs).GetCompletionValue().AsString();
                }

                if (gen.NeedsSteamEmulation)
                {
                    string steamEmu = GameManager.Instance.ExtractSteamEmu();
                    string emuExe   = Path.Combine(steamEmu, "SmartSteamLoader.exe");

                    string  emuIni = Path.Combine(steamEmu, "SmartSteamEmu.ini");
                    IniFile emu    = new IniFile(emuIni);

                    emu.IniWriteValue("Launcher", "Target", exePath);
                    emu.IniWriteValue("Launcher", "StartIn", Path.GetDirectoryName(exePath));
                    emu.IniWriteValue("Launcher", "CommandLine", startArgs);
                    emu.IniWriteValue("Launcher", "SteamClientPath", Path.Combine(steamEmu, "SmartSteamEmu.dll"));
                    emu.IniWriteValue("Launcher", "SteamClientPath64", Path.Combine(steamEmu, "SmartSteamEmu64.dll"));
                    emu.IniWriteValue("Launcher", "InjectDll", "0");
                    emu.IniWriteValue("SmartSteamEmu", "AppId", gen.SteamID);

                    Process proc;
                    if (gen.KillMutex.Length > 0)
                    {
                        // to kill the mutexes we need to orphanize the process
                        proc = ProcessUtil.RunOrphanProcess(emuExe);
                    }
                    else
                    {
                        ProcessStartInfo startInfo = new ProcessStartInfo();
                        startInfo.FileName = emuExe;
                        proc = Process.Start(startInfo);
                    }

                    player.Process  = proc;
                    player.SteamEmu = true;
                }
                else
                {
                    Process proc;
                    if (gen.KillMutex.Length > 0)
                    {
                        proc = Process.GetProcessById(StartGameUtil.StartGame(exePath, startArgs));
                    }
                    else
                    {
                        ProcessStartInfo startInfo = new ProcessStartInfo();
                        startInfo.FileName         = exePath;
                        startInfo.WindowStyle      = ProcessWindowStyle.Hidden;
                        startInfo.Arguments        = startArgs;
                        startInfo.UseShellExecute  = true;
                        startInfo.WorkingDirectory = Path.GetDirectoryName(exePath);
                        proc = Process.Start(startInfo);
                    }
                    if (proc == null)
                    {
                        for (int times = 0; times < 200; times++)
                        {
                            Thread.Sleep(50);

                            Process[] procs        = Process.GetProcesses();
                            string    proceName    = Path.GetFileNameWithoutExtension(gen.ExecutableName).ToLower();
                            string    launcherName = Path.GetFileNameWithoutExtension(gen.LauncherExe).ToLower();

                            for (int j = 0; j < procs.Length; j++)
                            {
                                Process p      = procs[j];
                                string  lowerP = p.ProcessName.ToLower();
                                if (((lowerP == proceName) || lowerP == launcherName) &&
                                    !attached.Contains(p))
                                {
                                    attached.Add(p);
                                    proc = p;
                                    break;
                                }
                            }

                            if (proc != null)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        attached.Add(proc);
                    }
                    player.Process = proc;
                }

                ScreenData data = new ScreenData();
                data.Position      = new Point(playerBounds.X, playerBounds.Y);
                data.Size          = new Size(playerBounds.Width, playerBounds.Height);
                data.KilledMutexes = gen.KillMutex.Length == 0;
                player.screenData  = data;
            }

            return(string.Empty);
        }
Esempio n. 15
0
        public override void PlayPlayer(PlayerInfo playerInfo, int index, HandlerContext context)
        {
            Process  proc;
            IOModule ioModule = handler.GetModule <IOModule>();

            string startArgs = context.StartArguments;

            if (context.KillMutex?.Length > 0)
            {
                //DirectoryInfo exeFolderDir = new DirectoryInfo(Path.GetDirectoryName(ioModule.ExePath));
                //DirectoryInfo linkedFolderDir = new DirectoryInfo(ioModule.LinkedFolder);

                //string exePath = Path.Combine(exeFolderDir.GetRelativePath(ioModule.NucleusRootFolder), Path.GetFileName(ioModule.ExePath));
                //string exeRoot = linkedFolderDir.GetRelativePath(ioModule.NucleusRootFolder);

                proc = Process.GetProcessById(StartGameUtil.StartGame(ioModule.ExePath, startArgs, ioModule.WorkingFolder));
            }
            else
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = ioModule.ExePath;
                //startInfo.WindowStyle = ProcessWindowStyle.Hidden;
                startInfo.Arguments        = startArgs;
                startInfo.UseShellExecute  = true;
                startInfo.WorkingDirectory = Path.GetDirectoryName(ioModule.ExePath);
                proc = Process.Start(startInfo);
            }

            if (proc == null)
            {
                for (int times = 0; times < 200; times++)
                {
                    Thread.Sleep(50);

                    Process[] procs        = Process.GetProcesses();
                    string    proceName    = Path.GetFileNameWithoutExtension(context.ExecutableName).ToLower();
                    string    launcherName = Path.GetFileNameWithoutExtension(context.LauncherExe).ToLower();

                    for (int j = 0; j < procs.Length; j++)
                    {
                        Process p      = procs[j];
                        string  lowerP = p.ProcessName.ToLower();
                        if (((lowerP == proceName) || lowerP == launcherName) &&
                            !attached.Contains(p))
                        {
                            attached.Add(p);
                            proc = p;
                            break;
                        }
                    }

                    if (proc != null)
                    {
                        break;
                    }
                }
            }
            else
            {
                attached.Add(proc);
            }

            ProcessInfo data = new ProcessInfo(proc);

            Rectangle  playerBounds = playerInfo.MonitorBounds;
            UserScreen owner        = playerInfo.Owner;

            int  width        = playerBounds.Width;
            int  height       = playerBounds.Height;
            bool isFullscreen = owner.Type == UserScreenType.FullScreen;

            data.Position          = new Point(playerBounds.X, playerBounds.Y);
            data.Size              = new Size(playerBounds.Width, playerBounds.Height);
            data.KilledMutexes     = context.KillMutex?.Length == 0;
            playerInfo.ProcessData = data;
        }