public async Task <ConnectionResult> StartMatchWithAuth(RconService.AuthType authType,
                                                                PavlovServer server,
                                                                Match match)
        {
            var connectionInfo = RconStatic.ConnectionInfoInternal(server.SshServer, authType, out var result);

            using var clientSsh  = new SshClient(connectionInfo);
            using var clientSftp = new SftpClient(connectionInfo);
            try
            {
                var listOfSteamIdentietiesWhichCanPlay = match.MatchTeam0SelectedSteamIdentities;
                listOfSteamIdentietiesWhichCanPlay.AddRange(match.MatchTeam1SelectedSteamIdentities);
                var list = new List <string>();
                if (listOfSteamIdentietiesWhichCanPlay.Count <= 0 && match.MatchSelectedSteamIdentities.Count <= 0)
                {
                    DataBaseLogger.LogToDatabaseAndResultPlusNotify("There are no team members so no match will start!",
                                                                    LogEventLevel.Fatal, _notifyService, result);
                    return(result);
                }


                if (match.MatchSelectedSteamIdentities.Count > 0)
                {
                    list = match.MatchSelectedSteamIdentities
                           .Select(x => Strings.Trim(x.SteamIdentityId)).ToList();
                }
                else if (listOfSteamIdentietiesWhichCanPlay.Count > 0)
                {
                    list = listOfSteamIdentietiesWhichCanPlay.Select(x => Strings.Trim(x.SteamIdentityId)).ToList();
                }

                list = list.Distinct().ToList();
                //GetAllAdminsForTheMatch
                var mods = new List <string>();
                //Todo what if the match is not team based? there are no mods or admins?
                mods = listOfSteamIdentietiesWhichCanPlay.Where(x => x.OverWriteRole == "Mod" || x.OverWriteRole == "Admin").Select(x => x.SteamIdentityId).ToList();


                //Write whitelist and set server settings


                RconStatic.WriteFile(server.SshServer,
                                     server.ServerFolderPath + FilePaths.WhiteList,
                                     list.ToArray(), _notifyService);
                RconStatic.WriteFile(server.SshServer,
                                     server.ServerFolderPath + FilePaths.ModList,
                                     mods.ToArray(), _notifyService);
                RconStatic.WriteFile(server.SshServer,
                                     server.ServerFolderPath + FilePaths.BanList,
                                     Array.Empty <string>(), _notifyService);


                var oldSettings = new PavlovServerGameIni();
                oldSettings.ReadFromFile(server, _notifyService);

                var serverSettings = new PavlovServerGameIni
                {
                    bEnabled        = true,
                    ServerName      = match.Name,
                    MaxPlayers      = match.PlayerSlots,
                    bSecured        = true,
                    bCustomServer   = true,
                    bWhitelist      = true,
                    RefreshListTime = 120,
                    LimitedAmmoType = 0,
                    TickRate        = 90,
                    TimeLimit       = match.TimeLimit,
                    Password        = "",
                    BalanceTableURL = "",
                    bVerboseLogging = true,
                    bCompetitive    = true,
                    MapRotation     = new List <PavlovServerGameIniMap>
                    {
                        new()
                        {
                            MapLabel = match.MapId,
                            GameMode = match.GameMode
                        }
                    },
                    ApiKey = oldSettings.ApiKey
                };
                var map = await _mapsService.FindOne(match.MapId.Replace("UGC", ""));

                serverSettings.SaveToFile(server, new[]
                {
                    new ServerSelectedMap()
                    {
                        Map      = map,
                        GameMode = match.GameMode
                    }
                }, _notifyService);
                await RconStatic.SystemDStart(server, _pavlovServerService);

                //StartWatchServiceForThisMatch
                match.Status = Status.StartetWaitingForPlayer;
                await Upsert(match);

                DataBaseLogger.LogToDatabaseAndResultPlusNotify("Start backgroundjob", LogEventLevel.Verbose,
                                                                _notifyService);

                BackgroundJob.Enqueue(
                    () => MatchInspector(match.Id)); // ChecjServerState
            }
Example #2
0
        /// <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)