Esempio n. 1
0
 public PendingGame(string[] userIds, Server server, RiichiGame log)
 {
     UserIds = userIds;
     Log     = log;
     Server  = server;
     usersOk = new HashSet <string>();
     usersNo = new HashSet <string>();
 }
Esempio n. 2
0
        public static RiichiGame ParseTenhouFormatGame(string payload, GameType gameType)
        {
            JsonTextReader reader = new JsonTextReader(new StringReader(payload));

            reader.Read();
            if (reader.TokenType != JsonToken.StartObject)
            {
                throw new System.Exception();
            }
            var game = new RiichiGame();

            game.FullLog = payload;
            reader.Read();
            game.GameType = gameType;
            game.Ver      = ParseStrProp("ver", reader);
            game.Ref      = ParseStrProp("ref", reader);
            game.Rounds   = ParseLog(reader);
            game.Ratingc  = ParseStrProp("ratingc", reader);
            game.Rule     = ParseRule(reader);
            game.Lobby    = ParseIntProp("lobby", reader);
            game.Dan      = ParseStrArray(reader, "dan");
            game.Rate     = ParseFloatArray(reader, "rate");
            game.Sx       = ParseStrArray(reader, "sx");
            var sc = ParseStrArray(reader, "sc");

            game.FinalScores     = GetScores(sc);
            game.FinalRankDeltas = GetRanks(sc);
            game.Names           = ParseStrArray(reader, "name");
            try
            {
                game.UserIds = ParseStrArray(reader, "mjsoulId");
                game.Title   = ParseStrArray(reader, "title");
            }
            catch
            {
                game.UserIds = new string[game.Names.Length];
            }
            return(game);
        }
Esempio n. 3
0
        public static (Game, List <Ranking>) RecordOnlineGame(RiichiGame gameLog, Server serverWithUsers)
        {
            var dbCon = DBConnection.Instance();

            var logId       = gameLog.Ref;
            var fullLog     = gameLog.FullLog;
            var gameType    = gameLog.GameType;
            var playerNames = gameLog.Names;
            var playerMjIds = gameLog.UserIds; //mahjongsoul internal Ids
            var scores      = gameLog.FinalScores;
            var userList    = serverWithUsers.Users;
            var platform    = gameLog.GameType;

            // TODO feed timestamp from game data
            if (playerNames.Length < 4)
            {
                throw new Exception("No sanma allowed");
            }

            var nameIdScorePos = new List <(string, string, int, int)>(); //0=start east, 1=start south,...

            for (int i = 0; i < 4; i++)
            {
                nameIdScorePos.Add((playerNames[i], playerMjIds[i], scores[i], i));
            }
            // We sort them by comparing their scores minus their initial pos, since initPos<<<score it's ok, I guess?
            nameIdScorePos.Sort((tuple1, tuple2) => (tuple2.Item3 - tuple2.Item4).CompareTo((tuple1.Item3 - tuple1.Item4)));
            int[]    sortedScores    = nameIdScorePos.Select(x => x.Item3).ToArray();
            string[] sortedNames     = nameIdScorePos.Select(x => x.Item1).ToArray();
            string[] sortedMjIds     = nameIdScorePos.Select(x => x.Item2).ToArray();
            string[] sortedPlayerIds = new string[4];

            List <int> toRecordMjId = new List <int>();

            for (int i = 0; i < 4; i++)
            {
                User user = null;
                switch (gameType)
                {
                //Get the User objects from the Name or Ids present in the log
                case GameType.Mahjsoul:
                    user = userList.Find(x => x.MahjsoulUserId == sortedMjIds[i]);
                    if (user == null)
                    {
                        user = userList.Find(x => x.MahjsoulName == sortedNames[i]);
                        toRecordMjId.Add(i);
                    }
                    break;

                case GameType.Tenhou:
                    user = userList.Find(x => x.TenhouName == sortedNames[i]);
                    break;

                default:
                    throw (new Exception("Bad game type, can't record"));
                }
                if (user == null)
                {
                    throw (new Exception($"couldn't find player with this name on the server: {sortedNames[i]}"));
                }
                sortedPlayerIds[i] = user.Id;
            }

            if (dbCon.IsConnect())
            {
                using var command   = SqlClientFactory.Instance.CreateCommand();
                command.Connection  = dbCon.Connection;
                command.CommandText = $"INSERT INTO {GameTableName} ({User1IdCol}, {User2IdCol}, {User3IdCol}, {User4IdCol}, {User1ScoreCol}, {User2ScoreCol}, {User3ScoreCol}, {User4ScoreCol}, {IdCol}, {FullLogIdCol}, {PlatformCol}, {ServerIdCol}) " +
                                      $"VALUES (@playerId1, @playerId2, @playerId3, @playerId4, {sortedScores[0]}, {sortedScores[1]}, {sortedScores[2]}, {sortedScores[3]}, @logId, @fullLog, @platform, @serverId);";
                command.CommandType = CommandType.Text;

                command.Parameters.Add(new SqlParameter("@playerId1", SqlDbType.NVarChar)
                {
                    Value = sortedPlayerIds[0]
                });
                command.Parameters.Add(new SqlParameter("@playerId2", SqlDbType.NVarChar)
                {
                    Value = sortedPlayerIds[1]
                });
                command.Parameters.Add(new SqlParameter("@playerId3", SqlDbType.NVarChar)
                {
                    Value = sortedPlayerIds[2]
                });
                command.Parameters.Add(new SqlParameter("@playerId4", SqlDbType.NVarChar)
                {
                    Value = sortedPlayerIds[3]
                });
                command.Parameters.Add(new SqlParameter("@fullLog", SqlDbType.NVarChar)
                {
                    Value = fullLog
                });
                command.Parameters.Add(new SqlParameter("@logId", SqlDbType.NVarChar)
                {
                    Value = logId
                });
                command.Parameters.Add(new SqlParameter("@platform", SqlDbType.NVarChar)
                {
                    Value = platform
                });
                command.Parameters.Add(new SqlParameter("@serverId", SqlDbType.NVarChar)
                {
                    Value = serverWithUsers.Id
                });
                command.ExecuteNonQuery();

                //Add the majsouldID to the new users:
                foreach (var idx in toRecordMjId)
                {
                    UserDbService.SetMahjsoulUserId(sortedPlayerIds[idx], sortedMjIds[idx]);
                }
                var config   = LeagueConfigDbService.GetLeagueConfig(serverWithUsers.LeagueConfigId);
                var game     = GetGameFromLogId(logId, serverWithUsers);
                var rankings = RankingDbService.UpdateRankings(game, config);

                return(game, rankings);
            }
            throw (new DbConnectionException());
        }
Esempio n. 4
0
        //Checks if a log is compatible with a player base
        private async Task <List <User> > GetUsersFromLog(RiichiGame log, List <User> users, CommandContext ctx)
        {
            int           nbPlayers  = log.Names.Length;
            List <string> notFound   = new List <string>();
            List <User>   foundUsers = new List <User>();

            for (int i = 0; i < nbPlayers; i++)
            {
                User foundUser = null;
                foreach (var user in users)
                {
                    switch (log.GameType)
                    {
                    case GameType.Mahjsoul:
                        bool matchName = user.MahjsoulName != null && user.MahjsoulName == log.Names[i];
                        bool matchId   = user.MahjsoulUserId != null && user.MahjsoulUserId == log.UserIds[i];
                        if (matchId && !matchName)
                        {
                            UserDbService.SetMahjsoulName(user.Id, log.Names[i]);
                            await ctx.RespondAsync($"Detected Bad user name for <@{user.Id}>. Changed from {user.MahjsoulName} to {log.Names[i]}, don't thank me ;)");
                        }
                        if (matchName && !matchId)
                        {
                            UserDbService.SetMahjsoulUserId(user.Id, log.UserIds[i]);
                        }
                        if (matchName || matchId)
                        {
                            foundUser = user;
                        }
                        break;

                    case GameType.Tenhou:
                        if (user.TenhouName != null && user.TenhouName == log.Names[i])
                        {
                            foundUser = user;
                        }
                        break;

                    default:
                        throw new Exception("Unsupported game type");
                    }
                    if (foundUser != null)
                    {
                        break;
                    }
                }
                if (foundUser == null)
                {
                    notFound.Add(log.Names[i]);
                }
                else
                {
                    foundUsers.Add(foundUser);
                }
            }
            if (notFound.Count > 0)
            {
                {
                    throw new Exception($"The log has names that do not match with any players: {string.Join(", ", notFound)}");
                }
            }
            return(foundUsers);
        }