public void EloExpected_EqualEloShouldHaveSameValue()
        {
            var expectedScore1 = new EloRating(1300).ExpectedScoreAgainst(1300);
            var expectedScore2 = new EloRating(1300).ExpectedScoreAgainst(1300);

            Assert.AreEqual(expectedScore1, expectedScore2);
        }
        public void EloExpected_HigherEloShouldBeExpectedToWin()
        {
            var expectedScore1 = new EloRating(1400).ExpectedScoreAgainst(1300);
            var expectedScore2 = new EloRating(1300).ExpectedScoreAgainst(1400);

            Assert.Greater(expectedScore1, expectedScore2);
        }
        public void BasicRankIt()
        {
            //for (int i = 0; i < 500; i++)
            {
                var eloRatingConfig = new EloRatingConfig();
                eloRatingConfig.FlatScore = 400;
                eloRatingConfig.Factor    = 120;

                var eloRatingInput = new EloRatingInput(EloRatingVictoryEnum.FirstPlayerWins);
                eloRatingInput.Player1Points = 1700;
                eloRatingInput.Player2Points = 1300;

                var eloRating       = new EloRating(eloRatingConfig);
                var eloRatingOutput = eloRating.RankIt(eloRatingInput);

                Assert.IsTrue(eloRatingConfig.FlatScore > 0 && eloRatingConfig.Factor > 0);
                Assert.IsTrue(eloRatingInput.Victory == EloRatingVictoryEnum.FirstPlayerWins);
                Assert.IsTrue(eloRating.Config == eloRatingConfig);

                Assert.IsTrue(eloRatingOutput.SourceInput.Player1Points == eloRatingInput.Player1Points);
                Assert.IsTrue(eloRatingOutput.SourceInput.Player2Points == eloRatingInput.Player2Points);

                Assert.IsTrue(eloRatingOutput.Player1NewPoints > eloRatingInput.Player1Points);
                Assert.IsTrue(eloRatingOutput.Player2NewPoints < eloRatingInput.Player2Points);

                int i = 0;
                Console.WriteLine($"interatction {i} Player 1 Input {eloRatingInput.Player1Points} --- Player1 Output {eloRatingOutput.Player1NewPoints}");
                Console.WriteLine($"interatction {i} Player 2 Input {eloRatingInput.Player2Points} --- Player2 Output {eloRatingOutput.Player2NewPoints}");
                Console.WriteLine("------");
            }
        }
Esempio n. 4
0
        public void ComputeRatingNbMatchAbove30()
        {
            var catA = new Cat
            {
                CatId  = "a",
                Looses = 15,
                Wins   = 16,
                Rating = 1220
            };

            var catB = new Cat
            {
                CatId  = "b",
                Looses = 0,
                Wins   = 0,
                Rating = 1200
            };

            var expectedRatingA = 1230;
            var expectedRatingB = 1180;

            var elo = new EloRating(catA.Rating, catB.Rating, true, false, catA.TotalMatches, catB.TotalMatches);

            var(newRatingA, newRatingB) = elo.GetNewResults();

            Assert.AreEqual(expectedRatingA, newRatingA);
            Assert.AreEqual(expectedRatingB, newRatingB);
        }
Esempio n. 5
0
    protected void nextCats_Click(object sender, EventArgs e)
    {
        var allCats  = SessionHelper.Get <List <Cat> >("Cats");
        var leftCat  = allCats.Find(c => c.id == leftCatId.Value);
        var rightCat = allCats.Find(c => c.id == rightCatId.Value);

        EloRating.UpdateScores(leftCat, rightCat, 0.5, 400, 10);
        DisplayTwoCats();
    }
Esempio n. 6
0
        public void Handle(GamePlayed @event)
        {
            var redTeam  = GetTeam(@event.RedOffensive, @event.RedDefensive);
            var blueTeam = GetTeam(@event.BlueOffensive, @event.BlueDefensive);
            var rating   = new EloRating(redTeam.Score, blueTeam.Score, @event.ScoreRed, @event.ScoreBlue, 0);

            redTeam.UpdateScore(rating.Point1);
            blueTeam.UpdateScore(rating.Point2);
        }
Esempio n. 7
0
    public void ScoreCat(WhichCat whichCat)
    {
        var allCats  = SessionHelper.Get <List <Cat> >("Cats");
        var leftCat  = allCats.Find(c => c.id == leftCatId.Value);
        var rightCat = allCats.Find(c => c.id == rightCatId.Value);
        var resultat = whichCat == WhichCat.Left ? 1 : 0;

        EloRating.UpdateScores(leftCat, rightCat, resultat, 400, 10);
    }
        public void PlayerWithSameIdentifierAndRating_AssertEquality()
        {
            var identifier = new EloPlayerIdentifier(Guid.NewGuid());
            var rating     = new EloRating(1200);
            var player1    = new EloPlayer(identifier, rating);
            var player2    = new EloPlayer(identifier, rating);

            Assert.AreEqual(player1, player2);
            Assert.IsTrue(player1 == player2);
            Assert.IsTrue(player1.Equals(player2));
        }
        public void TwoTeamsWithSamePlayers_AssertEquality()
        {
            var playerIdentifier = new EloPlayerIdentifier();
            var rating           = new EloRating(1200);
            var player1          = new EloPlayer(playerIdentifier, rating);
            var player2          = new EloPlayer(playerIdentifier, rating);
            var teamIdentifier   = new EloTeamIdentifier();
            var team1            = new EloTeam(teamIdentifier, player1, true);
            var team2            = new EloTeam(teamIdentifier, player2, false);

            Assert.AreEqual(team1, team2);
            Assert.IsTrue(team1 == team2);
            Assert.IsTrue(team1.Equals(team2));
        }
Esempio n. 10
0
    private void DisplayTwoCats()
    {
        nbVotes = getNbCats();

        if ((SessionHelper.Get <List <Cat> >("Cats")) != null)
        {
            var catsForVote = SessionHelper.Get <List <Cat> >("Cats");
            if (catsForVote != null)
            {
                var twoCats = CatsHelper.Random <Cat>(catsForVote);
                btnLeftCat.ImageUrl = twoCats.First().url;
                leftCatId.Value     = twoCats.First().id;
                probaWinLeft.Text   = Math.Round(EloRating.GetProbaWinCat(twoCats.First(), twoCats.Last()) * 100, 2) + " %";

                var rightCat = CatsHelper.Random <Cat>(catsForVote);
                btnRightCat.ImageUrl = twoCats.Last().url;
                rightCatId.Value     = twoCats.Last().id;
                probaWinRight.Text   = Math.Round(EloRating.GetProbaWinCat(twoCats.Last(), twoCats.First()) * 100, 2) + " %";
            }
        }
    }
Esempio n. 11
0
        public bool Finish(string matchId, int challengerPoints, int opponentPoints)
        {
            Claim objectId = ClaimsPrincipal.Current.Identities.First().Claims.FirstOrDefault(c => c.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier");
            var   userId   = objectId.Value;
            var   match    = Matches.GetMatchById(Guid.Parse(matchId));

            if (match.ChallengerId == userId || match.OpponentId == userId)
            {
                if (match.Status != 1)
                {
                    return(false);
                }

                match.Status           = 2;
                match.ChallengerPoints = challengerPoints;
                match.OpponentPoints   = opponentPoints;
                Matches.Update(match);

                var challenger = Users.GetByUserId(match.ChallengerId);
                var opponent   = Users.GetByUserId(match.OpponentId);

                // update users
                EloRating elo = new EloRating(challenger.EloRating, opponent.EloRating, challengerPoints, opponentPoints);
                challenger.EloRating = elo.FinalResult1;
                opponent.EloRating   = elo.FinalResult2;

                Users.Update(challenger);
                Users.Update(opponent);

                return(true);
            }
            else
            {
                return(false);
            }

            // if match status is not equal to 0, accept is not possible.
        }
Esempio n. 12
0
        public void TestElo()
        {
            int elop1 = 2400;
            int elop2 = 2000;

            int elop1new;
            int elop2new;

            EloRating.Calculate(elop1, elop2, 1, out elop1new, out elop2new);

            Assert.AreEqual(2403, elop1new);
            Assert.AreEqual(1997, elop2new);

            EloRating.Calculate(elop1, elop2, 2, out elop1new, out elop2new);

            Assert.AreEqual(2371, elop1new);
            Assert.AreEqual(2029, elop2new);

            EloRating.Calculate(elop1, elop2, 0, out elop1new, out elop2new);

            Assert.AreEqual(2387, elop1new);
            Assert.AreEqual(2013, elop2new);
        }
Esempio n. 13
0
        private unsafe void OnDataReceived(IAsyncResult async)
        {
            SocketState state = (SocketState)async.AsyncState;

            if (state == null || state.Socket == null || !state.Socket.Connected)
            {
                return;
            }

            try
            {
                // receive data from the socket
                int received = state.Socket.EndReceive(async);

                if (received == 0)
                {
                    return;
                }

                var buffer = state.Buffer;

                var input = Encoding.UTF8.GetString(XorBytes(buffer, 0, received - 7, XorKEY), 0, received);

                Log(Category, input);

                if (input.StartsWith(@"\auth\\gamename\"))
                {
                    var sesskey = Interlocked.Increment(ref _sessionCounter).ToString("0000000000");

                    SendToClient(state, $@"\lc\2\sesskey\{sesskey}\proof\0\id\1\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\authp\\pid\"))
                {
                    //var clientData = LoginDatabase.Instance.GetData(state.Name);


                    // \authp\\pid\87654321\resp\67512e365ba89497d60963caa4ce23d4\lid\1\final\

                    // \authp\\pid\87654321\resp\7e2270c581e8daf5a5321ff218953035\lid\1\final\

                    var pid = input.Substring(12, 9);

                    state.ProfileId = long.Parse(pid);

                    SendToClient(state, $@"\pauthr\{pid}\lid\1\final\");
                    //SendToClient(state, @"\pauthr\-3\lid\1\errmsg\helloworld\final\");
                    //SendToClient(state, @"\pauthr\100000004\lid\1\final\");

                    goto CONTINUE;
                }


                if (input.StartsWith(@"\getpd\"))
                {
                    // \\getpd\\\\pid\\87654321\\ptype\\3\\dindex\\0\\keys\\\u0001points\u0001points2\u0001points3\u0001stars\u0001games\u0001wins\u0001disconn\u0001a_durat\u0001m_streak\u0001f_race\u0001SM_wins\u0001Chaos_wins\u0001Ork_wins\u0001Tau_wins\u0001SoB_wins\u0001DE_wins\u0001Eldar_wins\u0001IG_wins\u0001Necron_wins\u0001lsw\u0001rnkd_vics\u0001con_rnkd_vics\u0001team_vics\u0001mdls1\u0001mdls2\u0001rg\u0001pw\\lid\\1\\final\\
                    // \getpd\\pid\87654321\ptype\3\dindex\0\keys\pointspoints2points3starsgameswinsdisconna_duratm_streakf_raceSM_winsChaos_winsOrk_winsTau_winsSoB_winsDE_winsEldar_winsIG_winsNecron_winslswrnkd_vicscon_rnkd_vicsteam_vicsmdls1mdls2rgpw\lid\1\final\
                    var pid = input.Substring(12, 9);

                    var keysIndex = input.IndexOf("keys") + 5;
                    var keys      = input.Substring(keysIndex);
                    var keysList  = keys.Split(new string[] { "\u0001", "\\lid\\1\\final\\", "final", "\\", "lid" }, StringSplitOptions.RemoveEmptyEntries);

                    var keysResult = new StringBuilder();
                    var stats      = UsersDatabase.Instance.GetStatsDataByProfileId(long.Parse(pid));

                    var gamesCount = stats.GamesCount;
                    var stars      = Math.Min(5, gamesCount);

                    for (int i = 0; i < keysList.Length; i++)
                    {
                        var key = keysList[i];

                        keysResult.Append("\\" + key + "\\");

                        switch (key)
                        {
                        case "points": keysResult.Append(stats.Score1v1); break;

                        case "points2": keysResult.Append(stats.Score2v2); break;

                        case "points3": keysResult.Append(stats.Score3v3); break;

                        case "stars": keysResult.Append(stars); break;

                        case "games": keysResult.Append(gamesCount); break;

                        case "wins": keysResult.Append(stats.WinsCount); break;

                        case "disconn": keysResult.Append(stats.Disconnects); break;

                        case "a_durat": keysResult.Append(stats.AverageDuractionTicks); break;

                        case "m_streak": keysResult.Append(stats.Best1v1Winstreak); break;

                        case "f_race": keysResult.Append(stats.FavouriteRace); break;

                        case "SM_wins": keysResult.Append(stats.Smwincount); break;

                        case "Chaos_wins": keysResult.Append(stats.Csmwincount); break;

                        case "Ork_wins": keysResult.Append(stats.Orkwincount); break;

                        case "Tau_wins": keysResult.Append(stats.Tauwincount); break;

                        case "SoB_wins": keysResult.Append(stats.Sobwincount); break;

                        case "DE_wins": keysResult.Append(stats.Dewincount); break;

                        case "Eldar_wins": keysResult.Append(stats.Eldarwincount); break;

                        case "IG_wins": keysResult.Append(stats.Igwincount); break;

                        case "Necron_wins": keysResult.Append(stats.Necrwincount); break;

                        /*case "lsw": keysResult.Append("123"); break;
                         * case "rnkd_vics": keysResult.Append("50"); break;
                         * case "con_rnkd_vics": keysResult.Append("200"); break;
                         * case "team_vics": keysResult.Append("250"); break;
                         * case "mdls1": keysResult.Append("260"); break;
                         * case "mdls2": keysResult.Append("270"); break;
                         * case "rg": keysResult.Append("280"); break;
                         * case "pw": keysResult.Append("290"); break;*/
                        default:
                            keysResult.Append("0");
                            break;
                        }
                    }

                    SendToClient(state, $@"\getpdr\1\lid\1\pid\{pid}\mod\{stats.Modified}\length\{keys.Length}\data\{keysResult}\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\setpd\"))
                {
                    var pid = input.Substring(12, 9);

                    var lidIndex = input.IndexOf("\\lid\\", StringComparison.OrdinalIgnoreCase);
                    var lid      = input.Substring(lidIndex + 5, 1);

                    var timeInSeconds = (ulong)((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);

                    SendToClient(state, $@"\setpdr\1\lid\{lid}\pid\{pid}\mod\{timeInSeconds}\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\updgame\"))
                {
                    var gamedataIndex = input.IndexOf("gamedata");
                    var finalIndex    = input.IndexOf("final");

                    var gameDataString = input.Substring(gamedataIndex + 9, finalIndex - gamedataIndex - 10);

                    var valuesList = gameDataString.Split(new string[] { "\u0001", "\\lid\\1\\final\\", "final", "\\", "lid" }, StringSplitOptions.RemoveEmptyEntries);

                    var dictionary = new Dictionary <string, string>();

                    for (int i = 0; i < valuesList.Length; i += 2)
                    {
                        dictionary[valuesList[i]] = valuesList[i + 1];
                    }

                    var playersCount = int.Parse(dictionary["Players"]);

                    for (int i = 0; i < playersCount; i++)
                    {
                        // Dont process games with AI
                        if (dictionary["PHuman_" + i] != "1")
                        {
                            goto CONTINUE;
                        }
                    }

                    var gameInternalSession = dictionary["SessionID"];
                    var teamsCount          = int.Parse(dictionary["Teams"]);
                    var version             = dictionary["Version"];
                    var mod        = dictionary["Mod"];
                    var modVersion = dictionary["ModVer"];


                    var uniqueGameSessionBuilder = new StringBuilder(gameInternalSession);

                    for (int i = 0; i < playersCount; i++)
                    {
                        uniqueGameSessionBuilder.Append('<');
                        uniqueGameSessionBuilder.Append(dictionary["PID_" + i]);
                        uniqueGameSessionBuilder.Append('>');
                    }

                    var uniqueSession = uniqueGameSessionBuilder.ToString();

                    if (!HandledGamesCache.Add(uniqueSession, uniqueSession, new CacheItemPolicy()
                    {
                        SlidingExpiration = TimeSpan.FromDays(1)
                    }))
                    {
                        goto CONTINUE;
                    }

                    var usersGameInfos = new GameUserInfo[playersCount];

                    GameUserInfo currentUserInfo = null;

                    for (int i = 0; i < playersCount; i++)
                    {
                        //var nick = dictionary["player_"+i];
                        var pid = long.Parse(dictionary["PID_" + i]);

                        var info = new GameUserInfo()
                        {
                            Stats      = UsersDatabase.Instance.GetStatsDataByProfileId(pid),
                            Race       = (Race)Enum.Parse(typeof(Race), dictionary["PRace_" + i], true),
                            Team       = int.Parse(dictionary["PTeam_" + i]),
                            FinalState = (PlayerFinalState)Enum.Parse(typeof(PlayerFinalState), dictionary["PFnlState_" + i]),
                        };

                        usersGameInfos[i] = info;

                        if (pid == state.ProfileId)
                        {
                            currentUserInfo = info;
                        }
                    }

                    var teams        = usersGameInfos.GroupBy(x => x.Team).ToDictionary(x => x.Key, x => x.ToArray());
                    var gameDuration = long.Parse(dictionary["Duration"]);

                    foreach (var team in teams)
                    {
                        for (int i = 0; i < team.Value.Length; i++)
                        {
                            var info = team.Value[i];

                            info.Stats.AllInGameTicks += gameDuration;

                            switch (info.Race)
                            {
                            case Race.space_marine_race:
                                info.Stats.Smgamescount++;
                                break;

                            case Race.chaos_marine_race:
                                info.Stats.Csmgamescount++;
                                break;

                            case Race.ork_race:
                                info.Stats.Orkgamescount++;
                                break;

                            case Race.eldar_race:
                                info.Stats.Eldargamescount++;
                                break;

                            case Race.guard_race:
                                info.Stats.Iggamescount++;
                                break;

                            case Race.necron_race:
                                info.Stats.Necrgamescount++;
                                break;

                            case Race.tau_race:
                                info.Stats.Taugamescount++;
                                break;

                            case Race.dark_eldar_race:
                                info.Stats.Degamescount++;
                                break;

                            case Race.sisters_race:
                                info.Stats.Sobgamescount++;
                                break;

                            default:
                                break;
                            }

                            if (info.FinalState == PlayerFinalState.Winner)
                            {
                                switch (info.Race)
                                {
                                case Race.space_marine_race:
                                    info.Stats.Smwincount++;
                                    break;

                                case Race.chaos_marine_race:
                                    info.Stats.Csmwincount++;
                                    break;

                                case Race.ork_race:
                                    info.Stats.Orkwincount++;
                                    break;

                                case Race.eldar_race:
                                    info.Stats.Eldarwincount++;
                                    break;

                                case Race.guard_race:
                                    info.Stats.Igwincount++;
                                    break;

                                case Race.necron_race:
                                    info.Stats.Necrwincount++;
                                    break;

                                case Race.tau_race:
                                    info.Stats.Tauwincount++;
                                    break;

                                case Race.dark_eldar_race:
                                    info.Stats.Dewincount++;
                                    break;

                                case Race.sisters_race:
                                    info.Stats.Sobwincount++;
                                    break;

                                default:
                                    break;
                                }
                            }
                        }
                    }

                    var chatUserInfo = ChatServer.IrcDaemon.Users[state.ProfileId];
                    var game         = chatUserInfo.Game;

                    // For rated games
                    if (game != null && game.Clean())
                    {
                        chatUserInfo.Game = null;

                        var usersInGame = game.UsersInGame;

                        if (usersGameInfos.Select(x => x.Stats.ProfileId).OrderBy(x => x).SequenceEqual(usersInGame.OrderBy(x => x)))
                        {
                            // Update winstreaks for 1v1 only
                            if (usersInGame.Length == 2)
                            {
                                UpdateStreak(usersGameInfos[0]);
                                UpdateStreak(usersGameInfos[1]);
                            }

                            var groupedTeams = usersGameInfos.GroupBy(x => x.Team).Select(x => x.ToArray()).ToArray();

                            var players1Team = groupedTeams[0];
                            var players2Team = groupedTeams[1];

                            Func <StatsData, long>   scoreSelector = null;
                            Action <StatsData, long> scoreUpdater  = null;

                            switch (usersInGame.Length)
                            {
                            case 2:
                                scoreSelector = StatsDelegates.Score1v1Selector;
                                scoreUpdater  = StatsDelegates.Score1v1Updated;
                                break;

                            case 4:
                                scoreSelector = StatsDelegates.Score2v2Selector;
                                scoreUpdater  = StatsDelegates.Score2v2Updated;
                                break;

                            case 6:
                            case 8:
                                scoreSelector = StatsDelegates.Score3v3Selector;
                                scoreUpdater  = StatsDelegates.Score3v3Updated;
                                break;

                            default: goto UPDATE;
                            }

                            var team0score = (long)players1Team.Average(x => scoreSelector(x.Stats));
                            var team1score = (long)players2Team.Average(x => scoreSelector(x.Stats));

                            var isFirstTeamResult = players1Team.Any(x => x.FinalState == PlayerFinalState.Winner);
                            var delta             = EloRating.CalculateELOdelta(team0score, team1score, isFirstTeamResult? EloRating.GameOutcome.Win : EloRating.GameOutcome.Loss);

                            //if (isFirstTeamResult)
                            //{
                            for (int i = 0; i < players1Team.Length; i++)
                            {
                                scoreUpdater(players1Team[i].Stats, Math.Max(1000L, scoreSelector(players1Team[i].Stats) + delta));
                            }

                            for (int i = 0; i < players2Team.Length; i++)
                            {
                                scoreUpdater(players2Team[i].Stats, Math.Max(1000L, scoreSelector(players1Team[i].Stats) - delta));
                            }

                            /*}
                             * else
                             * {
                             *  for (int i = 0; i < players1Team.Length; i++)
                             *      scoreUpdater(players1Team[i].Stats, scoreSelector(players1Team[i].Stats) + delta);
                             *
                             *  for (int i = 0; i < players2Team.Length; i++)
                             *      scoreUpdater(players1Team[i].Stats, scoreSelector(players1Team[i].Stats) - delta);
                             * }*/
                        }
                    }

UPDATE:
                    for (int i = 0; i < usersGameInfos.Length; i++)
                    {
                        UsersDatabase.Instance.UpdateUserStats(usersGameInfos[i].Stats);
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                if (state != null)
                {
                    state.Dispose();
                }
                state = null;
                return;
            }
            catch (SocketException e)
            {
                switch (e.SocketErrorCode)
                {
                case SocketError.ConnectionReset:
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;

                case SocketError.Disconnecting:
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;

                default:
                    LogError(Category, "Error receiving data");
                    LogError(Category, String.Format("{0} {1}", e.SocketErrorCode, e));
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;
                }
            }
            catch (Exception e)
            {
                LogError(Category, "Error receiving data");
                LogError(Category, e.ToString());
            }

            // and we wait for more data...
            CONTINUE : WaitForData(state);
        }
Esempio n. 14
0
        public void GetExpectedScoreScenario()
        {
            var expectedScore = new EloRating(1460).ExpectedScoreAgainst(1130);

            Assert.Greater(expectedScore, 0.5);
        }
Esempio n. 15
0
        public async Task <IActionResult> Result([FromRoute] int matchId, [FromBody] ResultModel model)
        {
            try
            {
                var match = _context.Matches
                            .Include(x => x.CatA)
                            .Include(x => x.CatB)
                            .FirstOrDefault(x => x.MatchId == matchId);

                if (match != null)
                {
                    var catA = match.CatA;
                    var catB = match.CatB;

                    var rating = new EloRating(catA.Rating,
                                               catB.Rating,
                                               model.Result == MatchResult.PLAYER_A_WIN,
                                               model.Result == MatchResult.PLAYER_B_WIN,
                                               catA.TotalMatches,
                                               catB.TotalMatches);

                    var(newRatingA, newRatingB) = rating.GetNewResults();

                    var now = DateTime.UtcNow;

                    catA.Rating = newRatingA;
                    catA.Wins   = model.Result == MatchResult.PLAYER_A_WIN ? catA.Wins + 1 : catA.Wins;
                    catA.Looses = model.Result == MatchResult.PLAYER_B_WIN ? catA.Looses + 1 : catA.Looses;
                    catA.Histories.Add(new History
                    {
                        Date    = now,
                        Rating  = newRatingA,
                        MatchId = matchId
                    });

                    catB.Rating = newRatingB;
                    catB.Wins   = model.Result == MatchResult.PLAYER_B_WIN ? catB.Wins + 1 : catB.Wins;
                    catB.Looses = model.Result == MatchResult.PLAYER_A_WIN ? catB.Looses + 1 : catB.Looses;
                    catB.Histories.Add(new History
                    {
                        Date    = now,
                        Rating  = newRatingB,
                        MatchId = matchId
                    });

                    match.Result = (int)model.Result;

                    await _context.SaveChangesAsync();

                    var winnerId = model.Result == MatchResult.PLAYER_A_WIN ? catA.CatId : catB.CatId;

                    return(Ok(winnerId));
                }

                return(BadRequest());
            }
            catch (Exception)
            {
                return(StatusCode(500));
            }
        }
Esempio n. 16
0
        public virtual async Task<IEnumerable<EloRating>> GetRatings(DateTime time, IEnumerable<Team> teams)
        {
            time = time.Date;
            if (!_eloCache.ContainsKey(time))
            {
                await UpdateCacheForDate(time);
            }

            var teamsList = teams.ToList();
            var result = new List<EloRating>();
            var ratings = _eloCache[time];
            foreach (var ratingsRow in ratings)
            {
                var team = teamsList.FirstOrDefault(x => x.MatchName(ratingsRow.Club));
                if (team != null)
                {
                    var rating = new EloRating
                    {
                        TeamName = team.Name,
                        Rating = ratingsRow.Elo,
                        Time = time,
                    };
                    result.Add(rating);
                }
            }
            return result;
        }
Esempio n. 17
0
        private unsafe void OnDataReceived(IAsyncResult async)
        {
            SocketState state = (SocketState)async.AsyncState;

            if (state == null || state.Socket == null || !state.Socket.Connected)
                return;

            try
            {
                // receive data from the socket
                int received = state.Socket.EndReceive(async);

                if (received == 0)
                    return;

                var buffer = state.Buffer;

                var input = Encoding.UTF8.GetString(XorBytes(buffer, 0, received - 7, XorKEY), 0, received);

                Logger.Info($"Receive data from the socket: {input}");

                if (input.StartsWith(@"\auth\\gamename\"))
                {
                    var sesskey = Interlocked.Increment(ref _sessionCounter).ToString("0000000000");

                    SendToClient(state, $@"\lc\2\sesskey\{sesskey}\proof\0\id\1\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\authp\\pid\"))
                {
                    try
                    {
                        var pid = GetPidFromInput(input, 12);
                        var profileId = long.Parse(pid);

                        state.ProfileId = profileId;
                        state.Nick = Database.UsersDBInstance.GetProfileById(profileId).Name;

                        SendToClient(state, $@"\pauthr\{pid}\lid\1\final\");
                    }
                    catch (Exception)
                    {
                        state.Dispose();
                        return;
                    }

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\getpd\"))
                {
                    // \\getpd\\\\pid\\87654321\\ptype\\3\\dindex\\0\\keys\\\u0001points\u0001points2\u0001points3\u0001stars\u0001games\u0001wins\u0001disconn\u0001a_durat\u0001m_streak\u0001f_race\u0001SM_wins\u0001Chaos_wins\u0001Ork_wins\u0001Tau_wins\u0001SoB_wins\u0001DE_wins\u0001Eldar_wins\u0001IG_wins\u0001Necron_wins\u0001lsw\u0001rnkd_vics\u0001con_rnkd_vics\u0001team_vics\u0001mdls1\u0001mdls2\u0001rg\u0001pw\\lid\\1\\final\\
                    // \getpd\\pid\87654321\ptype\3\dindex\0\keys\pointspoints2points3starsgameswinsdisconna_duratm_streakf_raceSM_winsChaos_winsOrk_winsTau_winsSoB_winsDE_winsEldar_winsIG_winsNecron_winslswrnkd_vicscon_rnkd_vicsteam_vicsmdls1mdls2rgpw\lid\1\final\
                    var pid = GetPidFromInput(input, 12);

                    var keysIndex = input.IndexOf("keys") + 5;
                    var keys = input.Substring(keysIndex);
                    var keysList = keys.Split(new string[] { "\u0001", "\\lid\\1\\final\\", "final", "\\", "lid" }, StringSplitOptions.RemoveEmptyEntries );

                    var keysResult = new StringBuilder();
                    var stats = ProfilesCache.GetProfileByPid(pid);

                    for (int i = 0; i < keysList.Length; i++)
                    {
                        var key = keysList[i];

                        keysResult.Append("\\"+key+"\\");

                        switch (key)
                        {
                            case "points": keysResult.Append(stats.Score1v1); break;
                            case "points2": keysResult.Append(stats.Score2v2); break;
                            case "points3": keysResult.Append(stats.Score3v3); break;

                            case "stars": keysResult.Append(stats.StarsCount); break;

                            case "games": keysResult.Append(stats.GamesCount); break;
                            case "wins": keysResult.Append(stats.WinsCount); break;
                            case "disconn": keysResult.Append(stats.Disconnects); break;
                            case "a_durat": keysResult.Append(stats.AverageDuractionTicks); break;
                            case "m_streak": keysResult.Append(stats.Best1v1Winstreak); break;

                            case "f_race": keysResult.Append(stats.FavouriteRace); break;

                            case "SM_wins": keysResult.Append(stats.Smwincount); break;
                            case "Chaos_wins": keysResult.Append(stats.Csmwincount); break;
                            case "Ork_wins": keysResult.Append(stats.Orkwincount); break;
                            case "Tau_wins": keysResult.Append(stats.Tauwincount); break;
                            case "SoB_wins": keysResult.Append(stats.Sobwincount); break;
                            case "DE_wins": keysResult.Append(stats.Dewincount); break;
                            case "Eldar_wins": keysResult.Append(stats.Eldarwincount); break;
                            case "IG_wins": keysResult.Append(stats.Igwincount); break;
                            case "Necron_wins": keysResult.Append(stats.Necrwincount); break;
                            /*case "lsw": keysResult.Append("123"); break;
                            case "rnkd_vics": keysResult.Append("50"); break;
                            case "con_rnkd_vics": keysResult.Append("200"); break;
                            case "team_vics": keysResult.Append("250"); break;
                            case "mdls1": keysResult.Append("260"); break;
                            case "mdls2": keysResult.Append("270"); break;
                            case "rg": keysResult.Append("280"); break;
                            case "pw": keysResult.Append("290"); break;*/
                            default:
                                keysResult.Append("0");
                                break;
                        }

                    }

                    SendToClient(state, $@"\getpdr\1\lid\1\pid\{pid}\mod\{stats.Modified}\length\{keys.Length}\data\{keysResult}\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\setpd\"))
                {
                    var pid = GetPidFromInput(input, 12);

                    var lidIndex = input.IndexOf("\\lid\\", StringComparison.OrdinalIgnoreCase);
                    var lid = input.Substring(lidIndex+5, 1);

                    var timeInSeconds = (ulong)((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);

                    SendToClient(state, $@"\setpdr\1\lid\{lid}\pid\{pid}\mod\{timeInSeconds}\final\");

                    goto CONTINUE;
                }

                if (input.StartsWith(@"\updgame\"))
                {
                    Task.Factory.StartNew(() =>
                    {
                        var gamedataIndex = input.IndexOf("gamedata");
                        var finalIndex = input.IndexOf("final");

                        var gameDataString = input.Substring(gamedataIndex + 9, finalIndex - gamedataIndex - 10);

                        var valuesList = gameDataString.Split(new string[] { "\u0001", "\\lid\\1\\final\\", "final", "\\", "lid" }, StringSplitOptions.RemoveEmptyEntries);

                        var dictionary = new Dictionary<string, string>();

                        for (int i = 0; i < valuesList.Length; i += 2)
                            dictionary[valuesList[i]] = valuesList[i + 1];

                        var playersCount = int.Parse(dictionary["Players"]);

                        for (int i = 0; i < playersCount; i++)
                        {
                            // Dont process games with AI
                            if (dictionary["PHuman_" + i] != "1")
                                return;
                        }

                        var gameInternalSession = dictionary["SessionID"];
                        var teamsCount = int.Parse(dictionary["Teams"]);
                        var version = dictionary["Version"];
                        var mod = dictionary["Mod"];
                        var modVersion = dictionary["ModVer"];

                        var uniqueGameSessionBuilder = new StringBuilder(gameInternalSession);

                        for (int i = 0; i < playersCount; i++)
                        {
                            uniqueGameSessionBuilder.Append('<');
                            uniqueGameSessionBuilder.Append(dictionary["player_" + i]);
                            uniqueGameSessionBuilder.Append('>');
                        }

                        var uniqueSession = uniqueGameSessionBuilder.ToString();

                        if (!HandledGamesCache.Add(uniqueSession, uniqueSession, new CacheItemPolicy() { SlidingExpiration = TimeSpan.FromDays(1) }))
                        {
                            return;
                        }

                        var usersGameInfos = new GameUserInfo[playersCount];

                        GameUserInfo currentUserInfo = null;

                        for (int i = 0; i < playersCount; i++)
                        {
                            var nick = dictionary["player_"+i];

                            var info = new GameUserInfo
                            {
                                Profile = ProfilesCache.GetProfileByName(nick),
                                Race = Enum.Parse<Race>(dictionary["PRace_" + i], true),
                                Team = int.Parse(dictionary["PTeam_" + i]),
                                FinalState = Enum.Parse<PlayerFinalState>(dictionary["PFnlState_" + i]),
                            };

                            usersGameInfos[i] = info;

                            if (nick.Equals(state.Nick, StringComparison.Ordinal))
                                currentUserInfo = info;
                        }

                        var teams = usersGameInfos.GroupBy(x => x.Team).ToDictionary(x => x.Key, x => x.ToArray());
                        var gameDuration = long.Parse(dictionary["Duration"]);

                        foreach (var team in teams)
                        {
                            for (int i = 0; i < team.Value.Length; i++)
                            {
                                var info = team.Value[i];

                                info.Profile.AllInGameTicks += gameDuration;

                                switch (info.Race)
                                {
                                    case Race.space_marine_race:
                                        info.Profile.Smgamescount++;
                                        break;
                                    case Race.chaos_marine_race:
                                        info.Profile.Csmgamescount++;
                                        break;
                                    case Race.ork_race:
                                        info.Profile.Orkgamescount++;
                                        break;
                                    case Race.eldar_race:
                                        info.Profile.Eldargamescount++;
                                        break;
                                    case Race.guard_race:
                                        info.Profile.Iggamescount++;
                                        break;
                                    case Race.necron_race:
                                        info.Profile.Necrgamescount++;
                                        break;
                                    case Race.tau_race:
                                        info.Profile.Taugamescount++;
                                        break;
                                    case Race.dark_eldar_race:
                                        info.Profile.Degamescount++;
                                        break;
                                    case Race.sisters_race:
                                        info.Profile.Sobgamescount++;
                                        break;
                                    default:
                                        break;
                                }

                                if (info.FinalState == PlayerFinalState.Winner)
                                {
                                    switch (info.Race)
                                    {
                                        case Race.space_marine_race:
                                            info.Profile.Smwincount++;
                                            break;
                                        case Race.chaos_marine_race:
                                            info.Profile.Csmwincount++;
                                            break;
                                        case Race.ork_race:
                                            info.Profile.Orkwincount++;
                                            break;
                                        case Race.eldar_race:
                                            info.Profile.Eldarwincount++;
                                            break;
                                        case Race.guard_race:
                                            info.Profile.Igwincount++;
                                            break;
                                        case Race.necron_race:
                                            info.Profile.Necrwincount++;
                                            break;
                                        case Race.tau_race:
                                            info.Profile.Tauwincount++;
                                            break;
                                        case Race.dark_eldar_race:
                                            info.Profile.Dewincount++;
                                            break;
                                        case Race.sisters_race:
                                            info.Profile.Sobwincount++;
                                            break;
                                        default:
                                            break;
                                    }
                                }
                            }
                        }

                        bool isRateGame = false;

                        if (ChatServer.IrcDaemon.Users.TryGetValue(state.ProfileId, out UserInfo chatUserInfo))
                        {
                            var game = chatUserInfo.Game;
                            isRateGame = game != null && game.Clean();

                            // For rated games
                            if (isRateGame)
                            {
                                Console.WriteLine("UPDATE RATING GAME " + uniqueSession);

                                chatUserInfo.Game = null;

                                var usersInGame = game.UsersInGame;

                                if (usersGameInfos.Select(x => x.Profile.Id).OrderBy(x => x).SequenceEqual(usersInGame.OrderBy(x => x)))
                                {
                                    // Update winstreaks for 1v1 only
                                    if (usersInGame.Length == 2)
                                    {
                                        UpdateStreak(usersGameInfos[0]);
                                        UpdateStreak(usersGameInfos[1]);
                                    }

                                    var groupedTeams = usersGameInfos.GroupBy(x => x.Team).Select(x => x.ToArray()).ToArray();

                                    var players1Team = groupedTeams[0];
                                    var players2Team = groupedTeams[1];

                                    Func<ProfileData, long> scoreSelector = null;
                                    Action<ProfileData, long> scoreUpdater = null;

                                    ReatingGameType type = ReatingGameType.Unknown;

                                    switch (usersInGame.Length)
                                    {
                                        case 2:
                                            scoreSelector = StatsDelegates.Score1v1Selector;
                                            scoreUpdater = StatsDelegates.Score1v1Updated;
                                            type = ReatingGameType.Rating1v1;
                                            break;
                                        case 4:
                                            scoreSelector = StatsDelegates.Score2v2Selector;
                                            scoreUpdater = StatsDelegates.Score2v2Updated;
                                            type = ReatingGameType.Rating2v2;
                                            break;
                                        case 6:
                                        case 8:
                                            type = ReatingGameType.Rating3v3_4v4;
                                            scoreSelector = StatsDelegates.Score3v3Selector;
                                            scoreUpdater = StatsDelegates.Score3v3Updated;
                                            break;
                                        default:
                                            goto UPDATE;
                                    }

                                    var team0score = (long)players1Team.Average(x => scoreSelector(x.Profile));
                                    var team1score = (long)players2Team.Average(x => scoreSelector(x.Profile));

                                    var isFirstTeamResult = players1Team.Any(x => x.FinalState == PlayerFinalState.Winner);
                                    var delta = EloRating.CalculateELOdelta(team0score, team1score, isFirstTeamResult ? EloRating.GameOutcome.Win : EloRating.GameOutcome.Loss);

                                    for (int i = 0; i < players1Team.Length; i++)
                                    {
                                        players1Team[i].Delta = delta;
                                        players1Team[i].RatingGameType = type;
                                        scoreUpdater(players1Team[i].Profile, Math.Max(1000L, scoreSelector(players1Team[i].Profile) + delta));
                                    }

                                    for (int i = 0; i < players2Team.Length; i++)
                                    {
                                        players2Team[i].Delta = -delta;
                                        players2Team[i].RatingGameType = type;
                                        scoreUpdater(players2Team[i].Profile, Math.Max(1000L, scoreSelector(players2Team[i].Profile) - delta));
                                    }
                                }
                            }
                        }

                    UPDATE:
                        for (int i = 0; i < usersGameInfos.Length; i++)
                        {
                            var info = usersGameInfos[i];
                            var profile = info.Profile;
                            ProfilesCache.UpdateProfilesCache(profile);
                            Database.UsersDBInstance.UpdateProfileData(profile);

                            if (info.Delta != 0)
                            {
                                Task.Delay(5000).ContinueWith(task =>
                                {
                                    switch (info.RatingGameType)
                                    {
                                        case ReatingGameType.Unknown:
                                            break;
                                        case ReatingGameType.Rating1v1:
                                            ChatServer.IrcDaemon.SendToUser(profile.Id, $@"Ваш рейтинг 1v1 изменился на {GetDeltaString(info.Delta)} и сейчас равен {info.Profile.Score1v1}.");
                                            break;
                                        case ReatingGameType.Rating2v2:
                                            ChatServer.IrcDaemon.SendToUser(profile.Id, $@"Ваш рейтинг 2v2 изменился на {GetDeltaString(info.Delta)} и сейчас равен {info.Profile.Score2v2}.");
                                            break;
                                        case ReatingGameType.Rating3v3_4v4:
                                            ChatServer.IrcDaemon.SendToUser(profile.Id, $@"Ваш рейтинг 3v3/4v4 изменился на {GetDeltaString(info.Delta)} и сейчас равен {info.Profile.Score3v3}.");
                                            break;
                                        default:
                                            break;
                                    }
                                });
                            }
                        }

                        Dowstats.UploadGame(dictionary, usersGameInfos, isRateGame);
                    }, CancellationToken.None, TaskCreationOptions.LongRunning | TaskCreationOptions.PreferFairness, _exclusiveScheduler);

                    goto CONTINUE;
                }
            }
            catch (ObjectDisposedException)
            {
                if (state != null)
                    state.Dispose();
                state = null;
                return;
            }
            catch (SocketException e)
            {
                switch (e.SocketErrorCode)
                {
                    case SocketError.ConnectionReset:
                        if (state != null)
                            state.Dispose();
                        state = null;
                        return;
                    case SocketError.Disconnecting:
                        if (state != null)
                            state.Dispose();
                        state = null;
                        return;
                    default:
                        Logger.Error(e, $"Error receiving data. SocketErrorCode: {e.SocketErrorCode}");
                        if (state != null)
                            state.Dispose();
                        state = null;
                        return;
                }
            }
            catch (Exception e)
            {
                Logger.Error(e, "Error receiving data");
            }

            // and we wait for more data...
            CONTINUE: WaitForData(state);
        }