public async Task <bool> SaveModListToFileAndDb(List <string> userIds, PavlovServer server) { var steamIdentities = (await _steamIdentityService.FindAll()).ToList(); //delete old stuff foreach (var old in await FindAllFrom(server)) { await Delete(old.Id); } //only save SteamIdsList to DB var steamIdentitiesToReturn = await SteamIdentitiesToReturn(userIds, server, steamIdentities); //Find all mods and add it to the list steamIdentitiesToReturn var additionalUsers = new List <LiteDbUser>(); if (server.Owner == null || server.SshServer.Owner == null) { additionalUsers = (await _userService.FindAllInRole("Admin")).ToList(); // admins additionalUsers.AddRange(await _userService.FindAllInRole("Mod")); // mods } if (server.Shack) { steamIdentitiesToReturn.AddRange(await SteamIdentitiesToReturn( additionalUsers.Select(x => x.Id.ToString()).ToList(), server, steamIdentities, false)); } else { steamIdentitiesToReturn.AddRange(await SteamIdentitiesToReturn( additionalUsers.Select(x => x.Id.ToString()).ToList(), server, steamIdentities, false)); } await SaveToFile(server, steamIdentitiesToReturn); return(true); }
/// <summary> /// Return back if the server should forceStop /// </summary> /// <param name="server"></param> /// <param name="match"></param> /// <returns></returns> /// <exception cref="CommandException"></exception> public async Task <bool> SShTunnelGetAllInfoFromPavlovServer(PavlovServer server, Match match = null) { var result = RconStatic.StartClient(server, out var client); var costumesToSet = new Dictionary <string, string>(); try { client.Connect(); if (client.IsConnected) { var nextFreePort = RconStatic.GetAvailablePort(); var portToForward = nextFreePort; var portForwarded = new ForwardedPortLocal("127.0.0.1", (uint)portToForward, "127.0.0.1", (uint)server.TelnetPort); client.AddForwardedPort(portForwarded); portForwarded.Start(); using (var client2 = new Client("127.0.0.1", portToForward, new CancellationToken())) { if (client2.IsConnected) { var password = await client2.ReadAsync(TimeSpan.FromMilliseconds(2000)); DataBaseLogger.LogToDatabaseAndResultPlusNotify("Answer: " + password, LogEventLevel.Verbose, _notifyService); if (password.ToLower().Contains("password")) { DataBaseLogger.LogToDatabaseAndResultPlusNotify("start sending password!", LogEventLevel.Verbose, _notifyService); await client2.WriteLine(server.TelnetPassword); DataBaseLogger.LogToDatabaseAndResultPlusNotify("did send password and wait for auth", LogEventLevel.Verbose, _notifyService); var auth = await client2.ReadAsync(TimeSpan.FromMilliseconds(2000)); DataBaseLogger.LogToDatabaseAndResultPlusNotify("waited for auth get : " + auth, LogEventLevel.Verbose, _notifyService); if (auth.ToLower().Contains("authenticated=1")) { // it is authetificated var commandOne = "RefreshList"; var singleCommandResult1 = await RconStatic.SingleCommandResult(client2, commandOne); var playersList = JsonConvert.DeserializeObject <PlayerListClass>(singleCommandResult1); var steamIds = playersList?.PlayerList.Select(x => x.UniqueId); //Inspect PlayerList var commands = new List <string>(); if (steamIds != null) { foreach (var steamId in steamIds) { commands.Add("InspectPlayer " + steamId); } } var playerListRaw = new List <string>(); foreach (var command in commands) { var commandResult = await RconStatic.SingleCommandResult(client2, command); playerListRaw.Add(commandResult); } var playerListJson = string.Join(",", playerListRaw); playerListJson = "[" + playerListJson + "]"; var finsihedPlayerList = new List <PlayerModelExtended>(); var tmpPlayers = JsonConvert.DeserializeObject <List <PlayerModelExtendedRconModel> >( playerListJson, new JsonSerializerSettings { CheckAdditionalContent = false }); var steamIdentities = (await _steamIdentityService.FindAll()).ToList(); if (tmpPlayers != null) { foreach (var player in tmpPlayers) { player.PlayerInfo.Username = player.PlayerInfo.PlayerName; var identity = steamIdentities?.FirstOrDefault(x => x.Id == player.PlayerInfo.UniqueId); if (identity != null && (identity.Costume != "None" || !string.IsNullOrEmpty(identity.Costume))) { if (server.Shack) { costumesToSet.Add(identity.OculusId, identity.Costume); } else { costumesToSet.Add(identity.Id, identity.Costume); } } } finsihedPlayerList = tmpPlayers.Select(x => x.PlayerInfo).ToList(); } var pavlovServerPlayerList = finsihedPlayerList.Select(x => { var player = new PavlovServerPlayer(); player.Username = x.Username; player.UniqueId = x.UniqueId; player.KDA = x.KDA; player.Cash = x.Cash; player.TeamId = x.TeamId; player.Score = x.Score; player.ServerId = server.Id; return(player); }).ToList(); var oldServerInfo = await _pavlovServerInfoService.FindServer(server.Id); //Todo maybe check if we lost a player its possible that we need that if allstats after the end of a match doesent give back all the player if some had a disconnect await _pavlovServerPlayerService.Upsert(pavlovServerPlayerList, server.Id); await _pavlovServerPlayerHistoryService.Upsert(pavlovServerPlayerList.Select(x => { var history = new PavlovServerPlayerHistory(); history.Username = x.Username; history.UniqueId = x.UniqueId; history.PlayerName = x.PlayerName; history.KDA = x.KDA; history.Cash = x.Cash; history.TeamId = x.TeamId; history.Score = x.Score; history.ServerId = x.ServerId; history.date = DateTime.Now; return(history); }).ToList(), server.Id, 1); var singleCommandResultTwo = await RconStatic.SingleCommandResult(client2, "ServerInfo"); var tmp = JsonConvert.DeserializeObject <ServerInfoViewModel>( singleCommandResultTwo.Replace("\"\"", "\"ServerInfo\"")); if (tmp == null || tmp.ServerInfo == null) { return(false); } if (!string.IsNullOrEmpty(tmp.ServerInfo.GameMode)) { DataBaseLogger.LogToDatabaseAndResultPlusNotify( "Got the server info for the server: " + server.Name + "\n " + singleCommandResultTwo, LogEventLevel.Verbose, _notifyService); } tmp.ServerId = server.Id; var map = await _mapsService.FindOne(tmp.ServerInfo.MapLabel.Replace("UGC", "")); if (map != null) { tmp.ServerInfo.MapPictureLink = map.ImageUrl; } //Check of next round bool nextRound = oldServerInfo != null && oldServerInfo.MapLabel != tmp.ServerInfo.MapLabel; if (!nextRound && oldServerInfo != null && match is { Status : Status.OnGoing }) // more checks cause in a match the map is only one and will not trigger the first try { var gotResult1 = int.TryParse(oldServerInfo.Team0Score, out var oldTeam0Score); var gotResult2 = int.TryParse(oldServerInfo.Team1Score, out var oldTeam1Score); var gotResult3 = int.TryParse(tmp.ServerInfo.Team0Score, out var newTeam0Score); var gotResult4 = int.TryParse(tmp.ServerInfo.Team1Score, out var newTeam1Score); if (gotResult1 && gotResult2 && gotResult3 && gotResult4 && ( oldTeam0Score > newTeam0Score || oldTeam1Score > newTeam1Score) ) { nextRound = true; } } var round = oldServerInfo?.Round ?? 0; if (nextRound) { if (round == 999) { round = 0; // reset value that's why you have to use the nextRound bool down from here to know if its the next round } round++; } if (match is { Status : Status.OnGoing } && nextRound)