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(); } }
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); } } }
protected virtual void OnServerClosed() { ServerClosed?.Invoke(this, EventArgs.Empty); }
private void OnServerClosed() { ServerClosed?.Invoke(); }
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()); }