protected virtual void OnGameBehaviorDetected(GameBehaviorDetectedArgs e)
 {
     GameBehaviorDetected?.Invoke(this, e);
 }
        public void Connect()
        {
            Process currentProcess = Process.GetCurrentProcess();
            string  pid            = currentProcess.Id.ToString();
            int     port           = 9500;

            server = new TcpListener(IPAddress.Any, port);
            server.Start();

            ltcProcess = new Process {
                StartInfo = new ProcessStartInfo {
                    FileName               = Environment.GetEnvironmentVariable("LocalAppData") + @"\Plays-ltc\0.54.7\PlaysTVComm.exe",
                    Arguments              = port + " " + pid + "",
                    UseShellExecute        = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow         = false
                }
            };

            ltcProcess.OutputDataReceived += new DataReceivedEventHandler((s, e) => {
                WriteToLog("LTCPROCESS", e.Data);
            });

            ltcProcess.Start();
            while (true)
            {
                TcpClient client = server.AcceptTcpClient();
                ns = client.GetStream();

                while (client.Connected)
                {
                    int           streamByte    = ns.ReadByte();
                    StringBuilder stringBuilder = new StringBuilder();

                    while (streamByte != 12)
                    {
                        stringBuilder.Append((char)streamByte);
                        streamByte = ns.ReadByte();
                    }

                    string msg = stringBuilder.ToString().Replace("\n", "").Replace("\r", "").Trim();
                    WriteToLog("RECEIVED", msg);

                    JsonElement jsonElement = GetDataType(msg);
                    string      type        = jsonElement.GetProperty("type").GetString();
                    var         data        = jsonElement.GetProperty("data");

                    switch (type)
                    {
                    case "LTC:handshake":
                        GetEncoderSupportLevel();
                        SetSavePaths("G:/Videos/Plays/", "G:/Videos/Plays/.temp/");
                        SetGameDVRQuality(10, 30, 720);

                        ConnectionHandshakeArgs connectionHandshakeArgs = new ConnectionHandshakeArgs
                        {
                            Version        = data.GetProperty("version").ToString(),
                            IntegrityCheck = data.GetProperty("integrityCheck").ToString(),
                        };
                        OnConnectionHandshake(connectionHandshakeArgs);
                        WriteToLog("INFO", string.Format("Connection Handshake: {0}, {1}", connectionHandshakeArgs.Version, connectionHandshakeArgs.IntegrityCheck));
                        break;

                    case "LTC:processCreated":
                        ProcessCreatedArgs processCreatedArgs = new ProcessCreatedArgs
                        {
                            Pid     = data.GetProperty("pid").GetInt32(),
                            ExeFile = data.GetProperty("exeFile").GetString(),
                            CmdLine = data.GetProperty("cmdLine").GetString()
                        };
                        OnProcessCreated(processCreatedArgs);
                        WriteToLog("INFO", string.Format("Process Created: {0}, {1}, {2}", processCreatedArgs.Pid, processCreatedArgs.ExeFile, processCreatedArgs.CmdLine));
                        break;

                    case "LTC:processTerminated":
                        ProcessTerminatedArgs processTerminatedArgs = new ProcessTerminatedArgs
                        {
                            Pid = data.GetProperty("pid").GetInt32(),
                        };
                        OnProcessTerminated(processTerminatedArgs);
                        WriteToLog("INFO", string.Format("Process Terminated: {0}", processTerminatedArgs.Pid));
                        break;

                    case "LTC:graphicsLibLoaded":
                        GraphicsLibLoadedArgs graphicsLibLoadedArgs = new GraphicsLibLoadedArgs
                        {
                            Pid        = data.GetProperty("pid").GetInt32(),
                            ModuleName = data.GetProperty("moduleName").GetString()
                        };
                        OnGraphicsLibLoaded(graphicsLibLoadedArgs);
                        WriteToLog("INFO", string.Format("Graphics Lib Loaded: {0}, {1}", graphicsLibLoadedArgs.Pid, graphicsLibLoadedArgs.ModuleName));
                        break;

                    case "LTC:moduleLoaded":
                        ModuleLoadedArgs moduleLoadedArgs = new ModuleLoadedArgs
                        {
                            Pid        = data.GetProperty("pid").GetInt32(),
                            ModuleName = data.GetProperty("moduleName").GetString()
                        };
                        OnModuleLoaded(moduleLoadedArgs);
                        WriteToLog("INFO", string.Format("Plays-ltc Recording Module Loaded: {0}, {1}", moduleLoadedArgs.Pid, moduleLoadedArgs.ModuleName));
                        break;

                    case "LTC:gameLoaded":
                        GameLoadedArgs gameLoadedArgs = new GameLoadedArgs
                        {
                            Pid    = data.GetProperty("pid").GetInt32(),
                            Width  = data.GetProperty("size").GetProperty("width").GetInt32(),
                            Height = data.GetProperty("size").GetProperty("height").GetInt32(),
                        };
                        OnGameLoaded(gameLoadedArgs);
                        WriteToLog("INFO", string.Format("Game finished loading: {0}, {1}x{2}", gameLoadedArgs.Pid, gameLoadedArgs.Width, gameLoadedArgs.Height));
                        break;

                    case "LTC:gameBehaviorDetected":
                        GameBehaviorDetectedArgs gameBehaviorDetectedArgs = new GameBehaviorDetectedArgs {
                            Pid = data.GetProperty("pid").GetInt32()
                        };
                        OnGameBehaviorDetected(gameBehaviorDetectedArgs);
                        WriteToLog("INFO", string.Format("Game behavior detected for pid: {0}", gameBehaviorDetectedArgs.Pid));
                        break;

                    case "LTC:videoCaptureReady":
                        VideoCaptureReadyArgs videoCaptureReadyArgs = new VideoCaptureReadyArgs
                        {
                            Pid = data.GetProperty("pid").GetInt32()
                        };
                        OnVideoCaptureReady(videoCaptureReadyArgs);
                        WriteToLog("INFO", string.Format("Video capture ready, can start recording: {0}", videoCaptureReadyArgs.Pid));
                        break;

                    case "LTC:recordingError":
                        int    errorCode    = data.GetProperty("code").GetInt32();
                        string errorDetails = "";
                        switch (errorCode)
                        {
                        case 11:
                            errorDetails = "- Issue with video directory";
                            break;

                        case 12:
                            errorDetails = "- Issue with temp directory";
                            break;

                        case 16:
                            errorDetails = "- Issue with disk space";
                            break;

                        default:
                            break;
                        }
                        WriteToLog("ERROR", string.Format("Recording Error code: {0} {1}", errorCode, errorDetails));
                        break;

                    case "LTC:gameScreenSizeChanged":
                        WriteToLog("INFO", string.Format("Game screen size changed, {0}x{1}", data.GetProperty("width").GetInt32(), data.GetProperty("height").GetInt32()));
                        break;

                    case "LTC:saveStarted":
                        WriteToLog("INFO", string.Format("Started saving recording to file, {0}", data.GetProperty("filename").GetString()));
                        break;

                    case "LTC:saveFinished":
                        WriteToLog("INFO", string.Format("Finished saving recording to file, {0}, {1}x{2}, {3}, {4}",
                                                         data.GetProperty("fileName"),
                                                         data.GetProperty("width"),
                                                         data.GetProperty("height"),
                                                         data.GetProperty("duration"),
                                                         data.GetProperty("recMode")));
                        break;

                    default:
                        WriteToLog("WARNING", string.Format("WAS SENT AN EVENT THAT DOES NOT MATCH CASE: {0}", msg));
                        break;
                    }
                }

                client.Close();
                ltcProcess.Close();
                server.Stop();
            }
        }