예제 #1
0
        static void ReadBackupLogFile(string LogFile, DateTime Timestamp, Stopwatch Elapsed)
        {
            using (var FileHandle = File.Open(LogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var BufferedStreamHandle = new BufferedStream(FileHandle))
                {
                    using (var Reader = new StreamReader(BufferedStreamHandle, Encoding.UTF8, true))
                    {
                        Elapsed.Start();
                        string Line = SeekTimestamp(Reader, Timestamp);

                        if (Line == null)
                        {
                            return;
                        }
                        string LastLine = Line;
                        do
                        {
                            if (Line.Length > 30)
                            {
                                Parser.Parse(Line, Events.List);
                            }
                            LastLine = Line;
                        }while ((Line = Reader.ReadLine()) != null);

                        // Write server close event to trigger serialization
                        var Event = new ServerClosed();
                        Event.Parse(LastLine);

                        Elapsed.Stop();
                    }
                }
            }
        }
예제 #2
0
        private void Run()
        {
            try
            {
                TcpListener server = new TcpListener(IPAddress.Any, port);

                server.Start();
                ServerStarted?.Invoke();

                while (!stop)
                {
                    if (server.Pending())
                    {
                        Socket connection = server.AcceptSocket();

                        Worker w = new Worker(this, connection, "Client " + idCounter++);
                        lock (workersLock)
                        {
                            workers.Add(w);
                            UserConnected?.Invoke(w.Username);
                        }
                    }
                }

                server.Server.Close(); // Release all resources
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace);
            }
            finally
            {
                ServerClosed?.Invoke();
            }
        }
예제 #3
0
        public override async Task InitServer(Server server)
        {
            if (server.PID != null && server.PID != default)
            {
                try
                {
                    Process ps = Process.GetProcessById((int)server.PID);

                    /*
                     * ps.OutputDataReceived += (sender, e) =>
                     * {
                     *      ConsoleMessage?.Invoke(server, new ConsoleEventArgs()
                     *      {
                     *              NewLine = e.Data
                     *      });
                     * };
                     * ps.ErrorDataReceived += (sender, e) =>
                     * {
                     *      ConsoleMessage?.Invoke(server, new ConsoleEventArgs()
                     *      {
                     *              NewLine = e.Data,
                     *              IsError = true
                     *      });
                     * };
                     */
                    ps.Exited += (sender, e) =>
                    {
                        //serverProcess[server.Id].Close();
                        serverProcess[server.Id].Dispose();
                        serverProcess.Remove(server.Id);

                        ServerClosed?.Invoke(server, e);
                    };
                    ps.EnableRaisingEvents = true;

                    //ps.BeginOutputReadLine();
                    //ps.BeginErrorReadLine();

                    //serverProcess[server.Id] = new Tuple<Process, IPtyConnection>(ps, null);
                    serverProcess[server.Id] = ps;
                }
                catch
                {
                    server.PID = default;
                    using (var scope = _serviceScopeFactory.CreateScope())
                        using (var db = scope.ServiceProvider.GetRequiredService <MonitorDBContext>())
                        {
                            db.Update(server);
                            await db.SaveChangesAsync();
                        }

                    await OpenServer(server);
                }
            }
        }
예제 #4
0
 protected virtual void OnServerClosed()
 {
     ServerClosed?.Invoke(this, EventArgs.Empty);
 }
예제 #5
0
 private void OnServerClosed()
 {
     ServerClosed?.Invoke();
 }
예제 #6
0
 public void SetServerClosedCallBack(ServerClosed callback)
 {
     serverClosed += callback;
 }
예제 #7
0
        public override async Task OpenServer(Server server)
        {
            if (serverProcess.ContainsKey(server.Id) && !serverProcess[server.Id].HasExited)
            {
                return;                 // Server is open?
            }

            var proc = new Process();

            proc.StartInfo.FileName         = Path.Combine(server.Path, server.Executable);
            proc.StartInfo.WorkingDirectory = Path.GetDirectoryName(Path.Combine(server.Path, server.Executable));

            /*var options = new PtyOptions()
             * {
             *      Name = $"srcds Server {server.Id}",
             *      App = Path.Combine(server.Path, server.Executable),
             *      CommandLine = (this as IGameHandlerBase).ServerStartParameters(server).ToArray(),
             *      VerbatimCommandLine = true,
             *      Cwd = Path.GetDirectoryName(Path.Combine(server.Path, server.Executable)),
             *      Cols = 100,
             *      Rows = 80,
             *      Environment = server.EnvironmentVariables.ToDictionary(v => v.Key, v => v.Value)
             * };
             *
             * IPtyConnection proc = await PtyProvider.SpawnAsync(options, new System.Threading.CancellationToken());
             * var procObj = Process.GetProcessById(proc.Pid);
             * procObj.PriorityClass = server.ProcessPriority;
             */


            proc.StartInfo.Arguments = (this as IGameHandlerBase).ServerStartParametersFormed(server);

            proc.StartInfo.RedirectStandardError  = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
            proc.StartInfo.CreateNoWindow         = true;
            proc.StartInfo.UseShellExecute        = false;
            proc.EnableRaisingEvents = true;             // Investigate?
            //activeSteamCMD.EnableRaisingEvents = false;
            // activeSteamCMD.OutputDataReceived += (sender, eventArgs) => outputStringBuilder.AppendLine(eventArgs.Data);
            // activeSteamCMD.ErrorDataReceived += (sender, eventArgs) => outputStringBuilder.AppendLine(eventArgs.Data);

            proc.OutputDataReceived += (sender, e) =>
            {
                _logger.LogDebug("Log received from server {0}: {1}", server.Id, e.Data);
                ConsoleMessage?.Invoke(server, new ConsoleEventArgs()
                {
                    NewLine = e.Data
                });
            };
            proc.ErrorDataReceived += (sender, e) =>
            {
                _logger.LogError("Error received from server {0}", server.Id);
                ConsoleMessage?.Invoke(server, new ConsoleEventArgs()
                {
                    NewLine = e.Data,
                    IsError = true
                });
            };

            /*
             * var processExitedCTS = new CancellationTokenSource();
             * var processExitedCToken = processExitedCTS.Token;
             * var processExitedTcs = new TaskCompletionSource<uint>();
             */

            proc.Exited += (sender, e) =>
            {
                //serverProcess[server.Id].Close();
                serverProcess.Remove(server.Id);

                //processExitedTcs.TrySetResult((uint)proc.ExitCode);
                //processExitedCTS.Cancel();

                ServerClosed?.Invoke(server, e);

                proc.Dispose();
            };

            /*
             * var backgroundTask = Task.Run(async () =>
             * {
             *      var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
             *      var decoder = encoding.GetDecoder();
             *      var sb = new StringBuilder();
             *
             *      var byteBuffer = new byte[1024];
             *      var maxCharsPerBuffer = encoding.GetMaxCharCount(1024);
             *      var charBuffer = new char[maxCharsPerBuffer];
             *
             *      int currentLinePos = 0;
             *      bool bLastCarriageReturn = false;
             *
             *      while (!processExitedTcs.Task.IsCompleted)
             *      {
             *              try
             *              {
             *                      var bytesRead = await proc.ReaderStream.ReadAsync(byteBuffer, 0, byteBuffer.Length).WithCancellation(processExitedCToken);
             *                      if (bytesRead == 0)
             *                              break;
             *
             *                      int charLen = decoder.GetChars(byteBuffer, 0, bytesRead, charBuffer, 0);
             *                      sb!.Append(charBuffer, 0, charLen);
             *
             *                      MonitorUtils.MoveLinesFromStringBuilderToMessageQueue(ref currentLinePos, ref bLastCarriageReturn, sb,
             *                              (line) => ConsoleMessage?.Invoke(server, new ConsoleEventArgs()
             *                              {
             *                                      NewLine = line
             *                              }));
             *              }
             *              catch (OperationCanceledException)
             *              {
             *                      break;
             *              }
             *      }
             * });
             */

            proc.Start();
            proc.BeginOutputReadLine();
            proc.BeginErrorReadLine();

            // Has to be set AFTER it starts
            proc.PriorityClass = server.ProcessPriority;

            //serverProcess[server.Id] = new Tuple<Process, IPtyConnection>(procObj, proc);
            serverProcess[server.Id] = proc;


            using (var scope = _serviceScopeFactory.CreateScope())
                using (var db = scope.ServiceProvider.GetRequiredService <MonitorDBContext>())
                {
                    server.PID = proc.Id;

                    db.Update(server);
                    await db.SaveChangesAsync();
                }

            ServerOpened?.Invoke(server, new EventArgs());
        }