Пример #1
0
        public void NoMatchJunkString()
        {
            bool result = FriendCode.TryParse("aaa", out FriendCode friendCode);

            Assert.AreEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsFalse(result);
        }
Пример #2
0
        int applicationFriend = 3; //id2向id1申请好友
        private int TransformFriendType(FriendCode code)
        {
            switch (code)
            {
            case FriendCode.MyFriend:
                return(myFriend);

                break;

            case FriendCode.AddFriend:
                return(noFriend);

                break;

            case FriendCode.FriendApplication:
                return(applicationFriend);

                break;

            default:
                return(0);

                break;
            }
        }
Пример #3
0
 public void NegativeTestStripFCFromName2()
 {
     var(friendCode, stripped) = FriendCode.ParseAndStripFriendCode("0123SomeSquid4567");
     Assert.AreEqual(FriendCode.NO_FRIEND_CODE, friendCode);
     Assert.IsNotNull(stripped);
     Assert.AreEqual("0123SomeSquid4567", stripped);
 }
Пример #4
0
 public void NegativeTestStripFCFromName3()
 {
     var(friendCode, stripped) = FriendCode.ParseAndStripFriendCode("Ludic--<");
     Assert.AreEqual(FriendCode.NO_FRIEND_CODE, friendCode);
     Assert.IsNotNull(stripped);
     Assert.AreEqual("Ludic--<", stripped);
 }
Пример #5
0
        public void NoMatchJunkDigitsString()
        {
            bool result = FriendCode.TryParse("0123456789101112", out FriendCode friendCode);

            Assert.AreEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsFalse(result);
        }
Пример #6
0
 public void StripFCInsideName2()
 {
     var(friendCode, stripped) = FriendCode.ParseAndStripFriendCode("My name 1234 - 5678 - 9012");
     Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
     Assert.IsNotNull(stripped);
     Assert.AreEqual("1234-5678-9012", friendCode.ToString());
     Assert.AreEqual("My name", stripped);
 }
Пример #7
0
 public void StripFCInsideName()
 {
     var(friendCode, stripped) = FriendCode.ParseAndStripFriendCode(":) Some pleb (SW: 0123-4567-8912)");
     Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
     Assert.IsNotNull(stripped);
     Assert.AreEqual("0123 4567 8912", friendCode.ToString(" "));
     Assert.AreEqual(":) Some pleb", stripped);
 }
Пример #8
0
        public void FCInsideOtherTextShouldParse()
        {
            bool success = FriendCode.TryParse("This is a player name believe it or not with the fc 0123-4567-8912?", out FriendCode friendCode);

            Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsTrue(success);
            Assert.AreEqual("0123.4567.8912", friendCode.ToString("."));
        }
Пример #9
0
        public void MatchFCStringWithLabel2()
        {
            bool success = FriendCode.TryParse("SW-1234-5678-4321", out FriendCode friendCode);

            Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsTrue(success);
            Assert.AreEqual("1234-5678-4321", friendCode.ToString());
        }
Пример #10
0
        public void SeparatorTest()
        {
            bool success = FriendCode.TryParse("5555.6789 7890", out FriendCode friendCode);

            Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsTrue(success);
            Assert.AreEqual("5555/6789/7890", friendCode.ToString("/"));
        }
Пример #11
0
        public void MatchFCString()
        {
            bool result = FriendCode.TryParse("3333-4444-5555", out FriendCode friendCode);

            Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsTrue(result);
            Assert.AreEqual("3333-4444-5555", friendCode.ToString());
        }
Пример #12
0
        public void MatchFCStringWithLabel()
        {
            bool success = FriendCode.TryParse("SW: 3456.7654.9876", out FriendCode friendCode);

            Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsTrue(success);
            Assert.AreEqual("3456-7654-9876", friendCode.ToString());
        }
Пример #13
0
        public void MatchDigitsString()
        {
            bool result = FriendCode.TryParse("111122223333", out FriendCode friendCode);

            Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsTrue(result);
            Assert.AreEqual("1111-2222-3333", friendCode.ToString());
        }
Пример #14
0
        public void NoCodeProperty()
        {
            var fc = new FriendCode("1111-2222-3333");

            Assert.IsFalse(fc.NoCode);
            fc = FriendCode.NO_FRIEND_CODE;
            Assert.IsTrue(fc.NoCode);
        }
Пример #15
0
        public void JoinSeparatorTest()
        {
            bool success = FriendCode.TryParse("123456789", out FriendCode friendCode);

            Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsTrue(success);
            Assert.AreEqual("000123456789", friendCode.ToString(""));
        }
Пример #16
0
        public Source Load()
        {
            Debug.WriteLine("Loading " + jsonFile);
            string      json = File.ReadAllText(jsonFile);
            StatInkRoot root = JsonConvert.DeserializeObject <StatInkRoot>(json) ?? new StatInkRoot();

            source.Start = new DateTime(root.EndAt?.Time ?? Builtins.UNKNOWN_DATE_TIME_TICKS);

            List <Player> players = new();

            // Don't load the details if they are manual entries.
            if (!root.Automated || root.Players == default)
            {
                return(source);
            }

            if (root.Url != null)
            {
                source.Uris = new Uri[] { root.Url };
            }

            foreach (var p in root.Players)
            {
                var newPlayer = new Player(p.Name ?? Builtins.UNKNOWN_PLAYER, source)
                {
                    SplatnetId = p.SplatnetId,
                    Top500     = p.Top500 == true,
                };
                if (p.IsMe)
                {
                    if (root.User?.Profile?.Twitter != null)
                    {
                        newPlayer.AddTwitter(root.User.Profile.Twitter, source);
                    }
                    if (root.User?.Profile?.FriendCode != null)
                    {
                        if (FriendCode.TryParse(root.User.Profile.FriendCode, out FriendCode friendCode))
                        {
                            newPlayer.AddFCs(friendCode, source);
                        }
                    }
                }
                if (p.Weapon?.MainRef != null)
                {
                    newPlayer.AddWeapons(new string[] { p.Weapon.MainRef });
                }
                players.Add(newPlayer);
            }

            source.Players = players.ToArray();
            return(source);
        }
Пример #17
0
        public void ToULongRoundTrip_2()
        {
            bool result = FriendCode.TryParse("9999-9999-9998", out FriendCode friendCode);

            Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsTrue(result);
            Assert.AreEqual("9999-9999-9998", friendCode.ToString());
            Assert.AreEqual((ulong)999999999998, friendCode.ToULong());

            var fc2 = new FriendCode(999999999998);

            Assert.AreEqual(fc2, friendCode);
        }
Пример #18
0
        public void ToULongRoundTrip()
        {
            bool result = FriendCode.TryParse("0001-2345-6789", out FriendCode friendCode);

            Assert.AreNotEqual(FriendCode.NO_FRIEND_CODE, friendCode);
            Assert.IsTrue(result);
            Assert.AreEqual("0001-2345-6789", friendCode.ToString());
            Assert.AreEqual((ulong)123456789, friendCode.ToULong());

            var fc2 = new FriendCode(123456789);

            Assert.AreEqual(friendCode, fc2);
        }
Пример #19
0
        public Source Load()
        {
            Debug.WriteLine("Loading " + tsvFile);
            string[] text = File.ReadAllLines(tsvFile);
            if (text.Length < 1)
            {
                throw new ArgumentException("TSV does not have any data. Check format of spreadsheet.");
            }

            // Build a map of the incoming data
            string headerRow = text[0];

            string[] columns         = headerRow.Split('\t').Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
            int      numberOfHeaders = columns.Length;

            PropertyEnum[] resolved = new PropertyEnum[numberOfHeaders];
            for (int i = 0; i < numberOfHeaders; ++i)
            {
                string header = columns[i].ToLowerInvariant()
                                .Replace("your ", "")
                                .Replace(" ", "")
                                .Replace("_", "")
                                .Replace(":", "")
                                .Replace("-", "")
                                .Replace("'s", "")
                                .Replace("teamcaptain", "captain")
                                .Replace("teammember", "player")
                ;
                if (string.IsNullOrWhiteSpace(header))
                {
                    Console.WriteLine($"Warning: Unable to resolve header, it is blank after processing: \"{header}\", (was \"{columns[i]}\")");
                    resolved[i] = PropertyEnum.UNKNOWN;
                }
                // Quick case
                else if (propertyValueStringMap.ContainsKey(header))
                {
                    resolved[i] = propertyValueStringMap[header];
                }
                else
                {
                    // Need to do some searching
                    int playerNum = 0;
                    if (header.Contains("captain"))
                    {
                        playerNum = 1;
                        header    = header.Replace("captain", "");
                    }
                    else
                    {
                        for (playerNum = 10; playerNum > 0; --playerNum)
                        {
                            if (header.Contains(playerNum.ToString()))
                            {
                                header = header.Replace(playerNum.ToString(), "");
                                break;
                            }
                        }
                    }

                    var matchedKey = propertyValueStringMap.Keys.FirstOrDefault(key => header.StartsWith(key));
                    if (matchedKey != null)
                    {
                        // For player num = 0 (not found), this will just return the appropriate header.
                        resolved[i] = (playerNum * (int)PropertyEnum.PlayerN_Offset) + propertyValueStringMap[matchedKey];
                    }
                    else if (playerNum == 0)
                    {
                        resolved[i] = PropertyEnum.UNKNOWN;
                        Console.WriteLine("Warning: Unable to resolve header: " + header);
                    }
                    else
                    {
                        resolved[i] = PropertyEnum.UNKNOWN;
                        Console.WriteLine("Warning: Unable to resolve header for player " + playerNum + ": " + header);
                    }
                }
            }

            // Now read the data...
            // Most tsv files will be team sheets, but for draft cups and verif they could be player records instead.
            // Each row therefore might be a single team with players, or a single player entry.
            List <Team>   teams   = new List <Team>();
            List <Player> players = new List <Player>();

            // From 1 as [0] is header row
            for (int lineIndex = 1; lineIndex < text.Length; ++lineIndex)
            {
                string line = text[lineIndex];
                if (!line.Contains('\t'))
                {
                    continue;
                }

                string[] cells = line.Split('\t').ToArray();

                // Warn if the values exceeds the number of defined headers (but don't bother if we're only one over and it's empty -- trailing tab)
                if (numberOfHeaders < cells.Length && (numberOfHeaders != cells.Length - 1 || !string.IsNullOrWhiteSpace(cells[cells.Length - 1])))
                {
                    Console.WriteLine($"Warning: Line {lineIndex} contains more cells in this row {cells.Length} than headers {numberOfHeaders}.");
                    Debug.WriteLine(line);
                }

                SortedDictionary <int, Player> rowPlayers = new SortedDictionary <int, Player>();
                Team t = new Team();

                for (int i = 0; i < cells.Length && i < numberOfHeaders; ++i)
                {
                    int          playerNum        = 0;
                    PropertyEnum resolvedProperty = resolved[i];
                    if (resolvedProperty > PropertyEnum.PlayerN_Offset)
                    {
                        playerNum        = (int)resolved[i] / (int)PropertyEnum.PlayerN_Offset;
                        resolvedProperty = (PropertyEnum)((int)resolved[i] % (int)PropertyEnum.PlayerN_Offset);
                    }

                    string value = cells[i];
                    if (string.IsNullOrWhiteSpace(value))
                    {
                        continue;
                    }

                    switch (resolvedProperty)
                    {
                    case PropertyEnum.UNKNOWN:
                    {
                        continue;
                    }

                    case PropertyEnum.Country:
                    {
                        var p = GetCurrentPlayer(ref rowPlayers, playerNum, tsvFile);
                        p.Country = value;
                        break;
                    }

                    case PropertyEnum.DiscordId:
                    {
                        var p = GetCurrentPlayer(ref rowPlayers, playerNum, tsvFile);
                        if (value.Length >= 14 && value.Length < 21)
                        {
                            // First, test is decimal (of length 17+)
                            bool isDecimal = value.Length >= 17 && value.All("0123456789".Contains);
                            if (isDecimal)
                            {
                                p.AddDiscordId(value, source);
                            }
                            // Otherwise test if we can get from a hex string (of length 14+ to give the correct 17 digit decimal)
                            else if (ulong.TryParse(value, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out ulong parsedId))
                            {
                                p.AddDiscordId(value, source);
                            }
                            else
                            {
                                Console.WriteLine($"Warning: DiscordId was specified ({lineIndex},{i}), but the value could not be parsed from a decimal or hex string. {value}.");
                                Debug.WriteLine(line);
                            }
                        }
                        else
                        {
                            Console.WriteLine($"Warning: DiscordId was specified ({lineIndex},{i}), but the value length does not fit into a discord id. {value}.");
                            Debug.WriteLine(line);
                        }
                        break;
                    }

                    case PropertyEnum.DiscordName:
                    {
                        var p = GetCurrentPlayer(ref rowPlayers, playerNum, tsvFile);
                        if (Discord.DISCORD_NAME_REGEX.IsMatch(value))
                        {
                            p.AddDiscordUsername(value, source);
                        }
                        else if (FriendCode.TryParse(value, out FriendCode friendCode))
                        {
                            p.AddFCs(friendCode, source);
                            Console.WriteLine($"Warning: This value was declared as a Discord name but looks like a friend code. Bad data formatting? {value} on ({lineIndex},{i}).");
                        }
                        else
                        {
                            Console.WriteLine($"Warning: DiscordName was specified ({lineIndex},{i}), but the value was not in a Discord format of name#0000. {value}.");
                            Debug.WriteLine(line);
                        }
                        break;
                    }

                    case PropertyEnum.FC:
                    {
                        var p = GetCurrentPlayer(ref rowPlayers, playerNum, tsvFile);
                        if (FriendCode.TryParse(value, out FriendCode friendCode))
                        {
                            p.AddFCs(friendCode, source);
                        }
                        else
                        {
                            Console.WriteLine($"Warning: FC was specified ({lineIndex},{i}), but the value was not in an FC format of 0000-0000-0000 or 0000 0000 0000. {value}.");
                            Debug.WriteLine(line);
                        }
                        break;
                    }

                    case PropertyEnum.Div:
                    {
                        t.AddDivision(new Division(value, divType, season), source);

                        if (divType == DivType.Unknown)
                        {
                            Console.WriteLine($"Warning: Div was specified ({lineIndex},{i}), but I don't know what type of division this file represents.");
                        }
                        break;
                    }

                    case PropertyEnum.LUTIDiv:
                    {
                        t.AddDivision(new Division(value, DivType.LUTI, season), source);
                        break;
                    }

                    case PropertyEnum.EBTVDiv:
                    {
                        t.AddDivision(new Division(value, DivType.EBTV, season), source);
                        break;
                    }

                    case PropertyEnum.DSBDiv:
                    {
                        t.AddDivision(new Division(value, DivType.DSB, season), source);
                        break;
                    }

                    case PropertyEnum.Timestamp:
                    {
                        // TODO - not supported right now. In future we could customise the source timestamp for this entry.
                        break;
                    }

                    case PropertyEnum.Name:
                    {
                        var p = GetCurrentPlayer(ref rowPlayers, playerNum, tsvFile);

                        var playerName = value.Trim();
                        playerName = t.Tag?.StripFromPlayer(playerName) ?? playerName;
                        p.AddName(playerName, source);

                        if (FriendCode.TryParse(value, out FriendCode friendCode))
                        {
                            p.AddFCs(friendCode, source);
                            Console.WriteLine($"Warning: This value was declared as a name but looks like a friend code. Bad data formatting? {value} on ({lineIndex},{i}).");
                            Debug.WriteLine(line);
                        }
                        break;
                    }

                    case PropertyEnum.Role:
                    {
                        var p = GetCurrentPlayer(ref rowPlayers, playerNum, tsvFile);
                        p.AddWeapons(value.Split(',').Select(s => s.Trim()).Where(s => !string.IsNullOrWhiteSpace(s)));
                        break;
                    }

                    case PropertyEnum.Pronouns:
                    {
                        var p = GetCurrentPlayer(ref rowPlayers, playerNum, tsvFile);
                        p.PronounInformation.SetPronoun(value, source);
                        break;
                    }

                    case PropertyEnum.Tag:
                    {
                        t.AddClanTag(value, source);
                        break;
                    }

                    case PropertyEnum.TeamName:
                    {
                        t.AddName(value, source);
                        break;
                    }

                    case PropertyEnum.Twitter:
                    {
                        var p = GetCurrentPlayer(ref rowPlayers, playerNum, tsvFile);
                        p.AddTwitter(value, source);
                        break;
                    }

                    case PropertyEnum.Twitch:
                    {
                        var p = GetCurrentPlayer(ref rowPlayers, playerNum, tsvFile);
                        p.AddTwitch(value, source);
                        break;
                    }

                    case PropertyEnum.Team_Offset:
                    case PropertyEnum.UnspecifiedPlayer_Offset:
                    case PropertyEnum.PlayerN_Offset:
                    default:
                    {
                        Console.WriteLine($"Warning: Unhandled header {resolvedProperty}. {value}. Line {lineIndex}:");
                        Debug.WriteLine(line);
                        break;
                    }
                    }
                }

                // End of the row, add the data.
                foreach (var pair in rowPlayers)
                {
                    // Don't add empty players
                    Player p = pair.Value;
                    if (p.Name.Equals(Builtins.UnknownPlayerName))
                    {
                        continue;
                    }
                    // Don't add the team to the player if it's not complete (e.g. single player record)
                    if (!t.Name.Equals(Builtins.UnknownTeamName))
                    {
                        p.TeamInformation.Add(t.Id, source);
                    }
                    players.Add(p);
                }

                // Don't bother adding the team if it has no players
                if (players.Count > 0)
                {
                    // Don't register a team if that information doesn't exist.
                    if (!t.Name.Equals(Builtins.UnknownTeamName))
                    {
                        // Recalculate the ClanTag layout
                        if (t.Tag != null)
                        {
                            t.Tag.CalculateTagOption(players[0].Name.Value);
                        }
                        else
                        {
                            ClanTag?newTag = ClanTag.CalculateTagFromNames(players.Select(p => p.Name.Value).ToArray(), source);

                            if (newTag != null)
                            {
                                t.AddClanTag(newTag);
                            }
                        }
                        teams.Add(t);
                    }
                }
            }

            source.Players = players.ToArray();
            source.Teams   = teams.ToArray();
            return(source);
        }
Пример #20
0
        public Source Load()
        {
            Debug.WriteLine("Loading " + jsonFile);
            string json = File.ReadAllText(jsonFile);

            BattlefyJsonTeam[] rows = JsonConvert.DeserializeObject <BattlefyJsonTeam[]>(json) ?? Array.Empty <BattlefyJsonTeam>();

            List <Team>   teams   = new();
            List <Player> players = new();

            foreach (BattlefyJsonTeam row in rows)
            {
                if (row.TeamName == null || row.Players == null)
                {
                    Console.Error.WriteLine("ERROR: JSON did not import a team correctly. Ignoring this team entry. File: " + jsonFile);
                    continue;
                }

                if (row.Players.Length < 1)
                {
                    // Report if the team name doesn't begin with "bye"
                    if (!row.TeamName.StartsWith("bye", StringComparison.OrdinalIgnoreCase))
                    {
                        Console.Error.WriteLine($"ERROR: JSON does not contain a player for team \"{row.TeamName}\". Ignoring this team entry. File: " + jsonFile);
                    }
                    continue;
                }

                // Set the source start time if not already
                if (source.Start == Builtins.UnknownDateTime && row.CheckInTime != null)
                {
                    source.Start = new DateTime(row.CheckInTime.Value.Year, row.CheckInTime.Value.Month, row.CheckInTime.Value.DayOfYear);
                }

                if (row.Captain == null)
                {
                    Console.WriteLine($"Warning: JSON does not contain a Team Captain for team \"{row.TeamName}\". Assuming player 1 is captain. File: " + jsonFile);
                    row.Captain = row.Players[0];
                }

                if (string.IsNullOrEmpty(row.Captain.Name))
                {
                    Console.Error.WriteLine($"ERROR: The captain for team \"{row.TeamName}\" does not have a name. Ignoring this team entry. File: " + jsonFile);
                    continue;
                }

                // Attempt to resolve the team tags
                ClanTag?teamTag = ClanTag.CalculateTagFromNames(row.Players.Select(p => p.Name).Where(name => name != null && !string.IsNullOrWhiteSpace(name)).ToArray() !, source);

                Team newTeam = new(row.TeamName, source);
                if (teamTag != null)
                {
                    newTeam.AddClanTag(teamTag);
                }

                if (row.BattlefyPersistentTeamId != null)
                {
                    newTeam.AddBattlefyId(row.BattlefyPersistentTeamId, source);
                }

                // If we already have a team with this id then merge it.
                if (newTeam.BattlefyPersistentTeamId != null)
                {
                    var knownTeam = teams.Find(t => newTeam.BattlefyPersistentTeamId.Equals(t.BattlefyPersistentTeamId));
                    if (knownTeam != null)
                    {
                        knownTeam.Merge(newTeam);
                    }
                    else
                    {
                        teams.Add(newTeam);
                    }
                }
                else
                {
                    teams.Add(newTeam);
                }

                foreach (BattlefyJsonPlayer p in row.Players)
                {
                    if (p.Name == null)
                    {
                        Console.Error.WriteLine($"ERROR: Player's Name ({p.Name}) not populated. Ignoring this player entry. File: " + jsonFile);
                        continue;
                    }

                    if (p.PersistentPlayerId == null)
                    {
                        Console.WriteLine($"Warning: Player ({p.Name}) does not have a PersistentPlayerId. Did they sub? Ignoring this player entry. File: " + jsonFile);
                        continue;
                    }

                    // Filter the friend code from the name, if found
                    var(parsedFriendCode, strippedName) = FriendCode.ParseAndStripFriendCode(p.Name);
                    if (!parsedFriendCode.NoCode)
                    {
                        p.Name = strippedName;
                    }

                    // Remove tag from player
                    if (teamTag != null)
                    {
                        p.Name = teamTag.StripFromPlayer(p.Name.Trim());
                    }

                    // Add Discord information, if we have it
                    var newPlayer = new Player(p.Name, new[] { newTeam.Id }, source);

                    if (p.BattlefyName != null && p.BattlefyName == row.Captain.BattlefyName)
                    {
                        if (parsedFriendCode.NoCode && !row.CaptainFriendCode.NoCode)
                        {
                            parsedFriendCode = row.CaptainFriendCode;
                        }

                        if (row.CaptainDiscordName != null)
                        {
                            newPlayer.AddDiscordUsername(row.CaptainDiscordName, source);
                        }
                    }

                    // Add Battlefy
                    if (p.BattlefyName != null && p.BattlefyUserSlug != null && p.PersistentPlayerId != null)
                    {
                        newPlayer.AddBattlefyInformation(p.BattlefyUserSlug, p.BattlefyName, p.PersistentPlayerId, source);
                    }
                    newPlayer.AddFCs(parsedFriendCode, source);
                    players.Add(newPlayer);
                }
            }

            source.Players = players.ToArray();
            source.Teams   = teams.ToArray();
            return(source);
        }