public CmdChooseCharacterStrategy(ILogger logger, AccountData accountData, ICharacterInfo characterInfo, PlayerHandler playerHandler) { _logger = logger ?? throw new Exception("CmdChooseCharacterStrategy - logger cannot be NULL!"); _accountData = accountData ?? throw new Exception("CmdChooseCharacterStrategy - account data cannot be NULL!"); _characterInfo = characterInfo ?? throw new Exception("CmdChooseCharacterStrategy - character info cannot be NULL!"); _playerHandler = playerHandler ?? throw new Exception("CmdChooseCharacterStrategy - player handler cannot be NULL!"); }
public virtual void NotifyPlayerAddedToLobby(ICharacterInfo toon) { try { } catch { } }
public EquipmentLogic(ICharacterInfo characterInfo, IEquipmentAccess equipmentAccess, IInventoryLogic inventoryLogic, ICharacterManager characterManager) { _characterInfo = characterInfo; _equipmentAccess = equipmentAccess; _inventoryLogic = inventoryLogic; _characterManager = characterManager; }
public MoveCharRequestStrategy(ILogger logger, ICharacterActionManager charActionManager, ICharacterInfo charInfo, PlayerHandler playerHandler) { _logger = logger ?? throw new Exception("MoveCharRequestStrategy - logger cannot be NULL!"); _charActionManager = charActionManager ?? throw new Exception("MoveCharRequestStrategy - char. action manager cannot be NULL!"); _charInfo = charInfo ?? throw new Exception("MoveCharRequestStrategy - char. info cannot be NULL!"); _playerHandler = playerHandler ?? throw new Exception("MoveCharRequestStrategy - player handler cannot be NULL!"); }
/// <summary> /// Causes the nextp player in the PlayerTurnOrder to get a turn /// </summary> public void NextPlayersTurn() { m_TurnOrderIndex = GetNextTurnOrderIndex(); if (m_TurnOrderIndex == -1) { // Next round EndCurrentRound(); return; } // assign new current player ICharacterInfo player = null; if (!Players.TryGetValue(PlayerTurnOrder[m_TurnOrderIndex], out player)) { // player got removed since the last few lines of code NextPlayersTurn(); } CurrentPlayer = player as ServerCharacterInfo; // set up the player's turn phases GamePhaseSequencer.ClearSequence(); Phase itm = OnCreateInitialPlayerTurnPhase(); GamePhaseSequencer.AddItem(itm, GetTurnPhaseDelay(itm)); GamePhaseSequencer.ActivateNextItem(); }
/// <summary> /// Checks all characte properties against the Character template xml /// </summary> /// <param name="character">The character that will be created.</param> /// <param name="msg">anything you want the player to know</param> /// <returns></returns> private bool ValidateCharacterCreateRequest(ICharacterInfo character, ref string msg) { // check the properties and stats against the character template. don't allow the client to submit stats or properties that aren't in the template Stat[] stats = character.Stats.AllStats; for (int i = 0; i < stats.Length; i++) { if (m_CharacterTemplateStats.GetStat(stats[i].StatID) == null) { msg = "Server does not allow characters to be created with Stats of StatID " + stats[i].StatID.ToString(); return(false); } } Property[] props = character.Properties.AllProperties; for (int i = 0; i < props.Length; i++) { if (m_CharacterTemplateProperties.GetProperty(props[i].PropertyId) == null) { msg = "Server does not allow characters to be created with Properties of PropertyId" + props[i].PropertyId.ToString(); return(false); } } if (!CharacterValidateName(character.CharacterName, ref msg)) { // send error if we can't validate the name return(false); } return(true); }
private async Task <Image <Rgba32> > GetCharacterPictureAsync(ICharacterInfo character) { var characterImg = Image.Load($"./Pictures/PW/empty.png"); using (var stream = await GetImageFromUrlAsync(character.PictureUrl, true)) { if (stream == null) { return(characterImg); } using (var image = Image.Load(stream)) { image.Mutate(x => x.Resize(new ResizeOptions { Mode = ResizeMode.Max, Size = new Size(characterImg.Width, 0) })); int startY = 0; if (characterImg.Height > image.Height) { startY = (characterImg.Height / 2) - (image.Height / 2); } characterImg.Mutate(x => x.DrawImage(image, new Point(0, startY), 1)); } } return(characterImg); }
public QuestLogic(IQuestAccess questAccess, ICharacterInfo characterInfo, IInventoryAccess inventoryAccess, ICharacterManager characterManager) { _questAccess = questAccess; _characterInfo = characterInfo; _inventoryAccess = inventoryAccess; _characterManager = characterManager; }
private Executable GetSafariExe(EmbedBuilder embed, IUserMessage msg, Card newCard, SafariImage pokeImage, ICharacterInfo character, ITextChannel trashChannel, IUser winner) { return(new Executable("safari", new Task(() => { using (var db = new Database.UserContext(_config)) { var botUser = db.GetUserOrCreateAsync(winner.Id).Result; newCard.FirstIdOwner = winner.Id; newCard.Affection += botUser.GameDeck.AffectionFromKarma(); botUser.GameDeck.RemoveCharacterFromWishList(newCard.Character); botUser.GameDeck.Cards.Add(newCard); db.SaveChanges(); QueryCacheManager.ExpireTag(new string[] { $"user-{botUser.Id}", "users" }); using (var dba = new Database.AnalyticsContext(_config)) { dba.UsersData.Add(new Database.Models.Analytics.UserAnalytics { Value = 1, UserId = winner.Id, MeasureDate = DateTime.Now, GuildId = trashChannel?.Guild?.Id ?? 0, Type = Database.Models.Analytics.UserAnalyticsEventType.Card }); dba.SaveChanges(); } } _ = Task.Run(async() => { try { embed.ImageUrl = await _waifu.GetSafariViewAsync(pokeImage, newCard, trashChannel); embed.Description = $"{winner.Mention} zdobył na polowaniu i wsadził do klatki:\n" + $"{newCard.GetString(false, false, true)}\n({newCard.Title})"; await msg.ModifyAsync(x => x.Embed = embed.Build()); var privEmb = new EmbedBuilder() { Color = EMType.Info.Color(), Description = $"Na [polowaniu]({msg.GetJumpUrl()}) zdobyłeś: {newCard.GetString(false, false, true)}" }; var priv = await winner.GetOrCreateDMChannelAsync(); if (priv != null) { await priv.SendMessageAsync("", false, privEmb.Build()); } } catch (Exception ex) { _logger.Log($"In Safari: {ex}"); } }); }))); }
private void RunSafari(EmbedBuilder embed, IUserMessage msg, Card newCard, SafariImage pokeImage, ICharacterInfo character, ITextChannel trashChannel) { _ = Task.Run(async() => { try { await Task.Delay(TimeSpan.FromMinutes(5)); var usersReacted = await msg.GetReactionUsersAsync(ClaimEmote, 300).FlattenAsync(); var users = usersReacted.ToList(); IUser winner = null; using (var db = new Database.UserContext(_config)) { var watch = Stopwatch.StartNew(); while (winner == null) { if (watch.ElapsedMilliseconds > 60000) { throw new Exception("Timeout"); } if (users.Count < 1) { embed.Description = $"Na polowanie nie stawił się żaden łowca!"; await msg.ModifyAsync(x => x.Embed = embed.Build()); return; } var selected = Fun.GetOneRandomFrom(users); var dUser = await db.GetCachedFullUserAsync(selected.Id); if (dUser != null) { if (!dUser.IsBlacklisted) { winner = selected; } } else { users.Remove(selected); } } } var exe = GetSafariExe(embed, msg, newCard, pokeImage, character, trashChannel, winner); await _executor.TryAdd(exe, TimeSpan.FromSeconds(1)); await msg.RemoveAllReactionsAsync(); } catch (Exception ex) { _logger.Log($"In Safari: {ex}"); await msg.ModifyAsync(x => x.Embed = "Karta uciekła!".ToEmbedMessage(EMType.Error).Build()); await msg.RemoveAllReactionsAsync(); } }); }
public HomeController(ITaskInfo taskInfo, IUserInfo userInfo, ICharacterInfo characterInfo, ITaskManager taskManager, IQuestLogic questLogic) { _taskInfo = taskInfo; _taskManager = taskManager; _userInfo = userInfo; _characterInfo = characterInfo; _questLogic = questLogic; }
public ChatHandler(ILogger logger, ICharacterInfo characterInfo, PlayerHandler playerHandler) { _logger = logger ?? throw new Exception("Chat handler - logger cannot be NULL!"); _characterInfo = characterInfo ?? throw new Exception("Chat handler - character info is NULL!"); _playerHandler = playerHandler ?? throw new Exception("Chat handler - player handler is NULL!"); HandleMessagesAsync(); }
public async Task <Image <Rgba32> > GetWaifuCardAsync(ICharacterInfo character, Card card) { var image = await GetWaifuCardNoStatsAsync(character, card); ApplyStats(image, card, !character.HasImage); return(image); }
public SwitchPlaceRequestStrategy(ILogger logger, ICharacterActionManager charActionManager, ICharacterInfo charInfo, IGeoDataInfo geoDataInfo, PlayerHandler playerHandler) { _logger = logger ?? throw new Exception("SwitchPlaceRequestStrategy - logger cannot be NULL!"); _charActionManager = charActionManager ?? throw new Exception("SwitchPlaceRequestStrategy - char. action manager cannot be NULL!"); _charInfo = charInfo ?? throw new Exception("SwitchPlaceRequestStrategy - char. info cannot be NULL!"); _playerHandler = playerHandler ?? throw new Exception("SwitchPlaceRequestStrategy - player handler cannot be NULL!"); _geoDataInfo = geoDataInfo ?? throw new Exception("SwitchPlaceRequestStrategy - geo data info cannot be NULL!"); }
public GameStateHandler(ILogger logger, IGeoDataInfo geoDataInfo, ICharacterInfo characterInfo, PlayerHandler playerHandler) { _logger = logger ?? throw new Exception("Game state handler - logger cannot be NULL!"); _geoDataInfo = geoDataInfo ?? throw new Exception("Game state handler - geo data info cannot be NULL!"); _characterInfo = characterInfo ?? throw new Exception("Game state handler - character info cannot be NULL!"); _playerHandler = playerHandler ?? throw new Exception("Game state handler - player handler cannot be NULL!"); StartHandling(); }
public async Task <Image <Rgba32> > GetWaifuCardAsync(string url, ICharacterInfo character, Card card) { if (url == null) { return(await GetWaifuCardAsync(character, card)); } return(Image.Load(url)); }
public void Deserialize(byte[] data, Pointer p) { LastLogin = new DateTime(BitPacker.GetLong(data, p), DateTimeKind.Utc); UserSince = new DateTime(BitPacker.GetLong(data, p), DateTimeKind.Utc); LastPasswordChange = new DateTime(BitPacker.GetLong(data, p), DateTimeKind.Utc); ID = new Guid(BitPacker.GetString(data, p)); Email = BitPacker.GetString(data, p); Username = BitPacker.GetString(data, p); IsLocked = BitPacker.GetBool(data, p); IsOnline = BitPacker.GetBool(data, p); IsApproved = BitPacker.GetBool(data, p); Roles = BitPacker.GetStringList(data, p); int notes = BitPacker.GetInt(data, p); for (int i = 0; i < notes; i++) { ServiceLogEntry sle = new ServiceLogEntry(); sle.Account = ID; sle.EntryBy = BitPacker.GetString(data, p); sle.Note = BitPacker.GetString(data, p); sle.EntryType = BitPacker.GetString(data, p); sle.CharacterId = BitPacker.GetInt(data, p); sle.TimeStampUTC = new DateTime(BitPacker.GetLong(data, p), DateTimeKind.Utc); ServiceNotes.Add(sle); } AddedProperties = BitPacker.GetPropertyBag(data, p); int numSessions = BitPacker.GetInt(data, p); for (int i = 0; i < numSessions; i++) { DateTime login = new DateTime(BitPacker.GetLong(data, p), DateTimeKind.Utc); DateTime logout = new DateTime(BitPacker.GetLong(data, p), DateTimeKind.Utc); string ip = BitPacker.GetString(data, p); ip = ip.Substring(0, ip.LastIndexOf("]") + 1); AccountProfile.Session s = new AccountProfile.Session(login, logout, ip); LoginSessions.Add(s); } //LoginSessions = LoginSessions.OrderBy(session => session.LogoutUTC).ToList(); LoginSessions.Reverse(); CurrentLoginTime = new DateTime(BitPacker.GetLong(data, p), DateTimeKind.Utc); int characters = BitPacker.GetInt(data, p); for (int i = 0; i < characters; i++) { ICharacterInfo ci = BitPacker.GetComponent(data, p) as ICharacterInfo; Characters.Add(ci); } }
public Card GenerateNewCard(IUser user, ICharacterInfo character, Rarity rarity) { var card = new Card { Title = character?.Relations?.OrderBy(x => x.Id)?.FirstOrDefault()?.Title ?? "????", Defence = RandomizeDefence(rarity), ArenaStats = new CardArenaStats(), Attack = RandomizeAttack(rarity), QualityOnStart = Quality.Broken, TagList = new List <CardTag>(), CreationDate = DateTime.Now, PAS = PreAssembledFigure.No, Name = character.ToString(), StarStyle = StarStyle.Full, Source = CardSource.Other, Character = character.Id, Quality = Quality.Broken, Dere = RandomizeDere(), RarityOnStart = rarity, CustomBorder = null, FromFigure = false, CustomImage = null, IsTradable = true, FirstIdOwner = 1, DefenceBonus = 0, HealthBonus = 0, AttackBonus = 0, UpgradesCnt = 2, LastIdOwner = 0, MarketValue = 1, Rarity = rarity, EnhanceCnt = 0, Unique = false, InCage = false, RestartCnt = 0, Active = false, Affection = 0, Image = null, Health = 0, ExpCnt = 0, }; if (user != null) { card.FirstIdOwner = user.Id; } if (character.HasImage) { card.Image = character.PictureUrl; } card.Health = RandomizeHealth(card); return(card); }
/// <summary> /// Gets a reference to the character, given the character ID. If that character is not part of this game, null is returned. /// </summary> /// <param name="id">id of the character to return</param> /// <returns></returns> public ICharacterInfo GetCharacter(int id) { ICharacterInfo toon = null; lock (m_Game.AllPlayersSyncRoot) { Players.TryGetValue(id, out toon); } return(toon); }
private void Start() { _statesEffects = new Dictionary <int, float>(); MatchManager.Instance?.RegisterCharacter(this, gameObject); _currentMana = _maxMana; _characterInfo = GetComponentInChildren <ICharacterInfo>(); _characterInfo.SetNametag(photonView.Owner.NickName); _characterInfo.UpdateHealthValue(_health, _maxHealth); }
/// <summary> /// Gets a player from the character list, or null if that player isnt part of the game. /// </summary> /// <param name="id"></param> /// <returns></returns> public ICharacterInfo GetPlayer(int id, bool onlyCurrentlyAttached) { ICharacterInfo ci = null; Players.TryGetValue(id, out ci); if (ci == null && !onlyCurrentlyAttached) { EverActivePlayers.TryGetValue(id, out ci); } return(ci as ICharacterInfo); }
public static Embed ToEmbed(this ICharacterInfo info) { return(new EmbedBuilder() { Title = $"{info} ({info.Id})".TrimToLength(EmbedBuilder.MaxTitleLength), Description = info?.Biography?.Content?.TrimToLength(1000), Color = EMType.Info.Color(), ImageUrl = info.PictureUrl, Fields = info.GetFields(), Url = info.CharacterUrl, }.Build()); }
public async Task <string> GetWaifuProfileImageAsync(Card card, ICharacterInfo character, ITextChannel trashCh) { using (var cardImage = await _img.GetWaifuCardNoStatsAsync(character, card)) { cardImage.SaveToPath($"./GOut/Profile/P{card.Id}.png"); using (var stream = cardImage.ToPngStream()) { var fs = await trashCh.SendFileAsync(stream, $"P{card.Id}.png"); var im = fs.Attachments.FirstOrDefault(); return(im.Url); } } }
public void Serialize(ref byte[] buffer, Pointer p) { BitPacker.AddLong(ref buffer, p, LastLogin.Ticks); BitPacker.AddLong(ref buffer, p, UserSince.Ticks); BitPacker.AddLong(ref buffer, p, LastPasswordChange.Ticks); BitPacker.AddString(ref buffer, p, ID.ToString()); BitPacker.AddString(ref buffer, p, Email); BitPacker.AddString(ref buffer, p, Username); BitPacker.AddBool(ref buffer, p, IsLocked); BitPacker.AddBool(ref buffer, p, IsOnline); BitPacker.AddBool(ref buffer, p, IsApproved); BitPacker.AddStringList(ref buffer, p, Roles); BitPacker.AddInt(ref buffer, p, ServiceNotes.Count); for (int i = 0; i < ServiceNotes.Count; i++) { ServiceLogEntry sle = ServiceNotes[i]; BitPacker.AddString(ref buffer, p, sle.EntryBy); BitPacker.AddString(ref buffer, p, sle.Note); BitPacker.AddString(ref buffer, p, sle.EntryType); BitPacker.AddInt(ref buffer, p, sle.CharacterId); BitPacker.AddLong(ref buffer, p, sle.TimeStampUTC.Ticks); } BitPacker.AddPropertyBag(ref buffer, p, AddedProperties); BitPacker.AddInt(ref buffer, p, LoginSessions.Count); for (int i = 0; i < LoginSessions.Count; i++) { AccountProfile.Session s = LoginSessions[i]; BitPacker.AddLong(ref buffer, p, s.LoginUTC.Ticks); BitPacker.AddLong(ref buffer, p, s.LogoutUTC.Ticks); BitPacker.AddString(ref buffer, p, s.IP); } BitPacker.AddLong(ref buffer, p, CurrentLoginTime.Ticks); BitPacker.AddInt(ref buffer, p, Characters.Count); for (int i = 0; i < Characters.Count; i++) { ICharacterInfo ci = Characters[i]; BitPacker.AddComponent(ref buffer, p, ci); } }
public async Task <Image <Rgba32> > GetWaifuCardNoStatsAsync(ICharacterInfo character, Card card) { var image = new Image <Rgba32>(475, 667); using (var chara = await GetCharacterPictureAsync(character)) { image.Mutate(x => x.DrawImage(chara, new Point(13, 13), 1)); } using (var bord = GenerateBorder(card)) { image.Mutate(x => x.DrawImage(bord, new Point(0, 0), 1)); } return(image); }
public void Dispose() { _movementHandlingInProgress = false; _geoDataInfo = null; _characterInfo = null; lock (_movementDetailsLock) { foreach (CharacterMovementDetails movementDetails in _movementDetailsList) { movementDetails.Dispose(); } _movementDetailsList.Clear(); } }
private Executable GetSafariExe(EmbedBuilder embed, IUserMessage msg, Card newCard, SafariImage pokeImage, ICharacterInfo character, ITextChannel trashChannel, IUser winner) { return(new Executable("safari", new Task(() => { using (var db = new Database.UserContext(_config)) { var botUser = db.GetUserOrCreateAsync(winner.Id).Result; botUser.GameDeck.Cards.Add(newCard); db.SaveChanges(); QueryCacheManager.ExpireTag(new string[] { $"user-{botUser.Id}", "users" }); } _ = Task.Run(async() => { try { embed.ImageUrl = await _waifu.GetSafariViewAsync(pokeImage, character, newCard, trashChannel); embed.Description = $"{winner.Mention} zdobył na polowaniu i wsadził do klatki:\n" + $"{newCard.GetString(false, false, true)}\n({newCard.Title})"; await msg.ModifyAsync(x => x.Embed = embed.Build()); var privEmb = new EmbedBuilder() { Color = EMType.Info.Color(), Description = $"Na [polowaniu]({msg.GetJumpUrl()}) zdobyłeś: {newCard.GetString(false, false, true)}" }; var priv = await winner.GetOrCreateDMChannelAsync(); if (priv != null) { await priv.SendMessageAsync("", false, privEmb.Build()); } } catch (Exception ex) { _logger.Log($"In Safari: {ex}"); } }); }))); }
public override void Serialize(ref byte[] buffer, Pointer p, bool includeSubComponents) { // General match info BitPacker.AddInt(ref buffer, p, Owner); BitPacker.AddString(ref buffer, p, GameID.ToString()); BitPacker.AddPropertyBag(ref buffer, p, Properties); // Players List <ICharacterInfo> players = AllPlayers; BitPacker.AddInt(ref buffer, p, players.Count); for (int i = 0; i < players.Count; i++) { ICharacterInfo ci = players[i]; BitPacker.AddPropertyBag(ref buffer, p, ci.Properties); BitPacker.AddStatBag(ref buffer, p, ci.Stats); BitPacker.AddInt(ref buffer, p, ci.ID); } base.Serialize(ref buffer, p, includeSubComponents); }
public override bool DeSerialize(byte[] data, Pointer p) { base.DeSerialize(data, p); Kind = (MatchNotificationType)BitPacker.GetInt(data, p); bool haveGame = BitPacker.GetBool(data, p); if (haveGame) { TheGame = BitPacker.GetComponent(data, p, false) as IGame; } bool haveTargetPlayer = BitPacker.GetBool(data, p); if (haveTargetPlayer) { TargetPlayer = BitPacker.GetComponent(data, p, false) as ICharacterInfo; } TheGameID = new Guid(BitPacker.GetString(data, p)); return(true); }
public Card GenerateNewCard(ICharacterInfo character, Rarity rarity) { var card = new Card { Title = character?.Relations?.OrderBy(x => x.Id)?.FirstOrDefault()?.Title ?? "????", Defence = RandomizeDefence(rarity), ArenaStats = new CardArenaStats(), Attack = RandomizeAttack(rarity), CreationDate = DateTime.Now, Name = character.ToString(), Source = CardSource.Other, Character = character.Id, Dere = RandomizeDere(), RarityOnStart = rarity, IsTradable = true, UpgradesCnt = 2, Rarity = rarity, Tags = null, }; card.Health = RandomizeHealth(card); return(card); }
public override void PlayerDone(ICharacterInfo player) { base.PlayerDone(player); EndPhase(); }
public virtual void PlayerDone(ICharacterInfo player) { }
public virtual void NotifyPlayerAddedToGame(ICharacterInfo toon) { }
public virtual bool CanPlayerSubmitCommand(ICharacterInfo player) { bool rslt = Sequencer.OwningGame.Players.Values.FirstOrDefault(p => p.ID == player.ID) != null; return rslt; }
/// <summary> /// Checks all characte properties against the Character template xml /// </summary> /// <param name="character">The character that will be created.</param> /// <param name="msg">anything you want the player to know</param> /// <returns></returns> private bool ValidateCharacterCreateRequest(ICharacterInfo character, ref string msg) { // check the properties and stats against the character template. don't allow the client to submit stats or properties that aren't in the template Stat[] stats = character.Stats.AllStats; for (int i = 0; i < stats.Length; i++) { if (m_CharacterTemplateStats.GetStat(stats[i].StatID) == null) { msg = "Server does not allow characters to be created with Stats of StatID " + stats[i].StatID.ToString(); return false; } } Property[] props = character.Properties.AllProperties; for (int i = 0; i < props.Length; i++) { if (m_CharacterTemplateProperties.GetProperty(props[i].PropertyId) == null) { msg = "Server does not allow characters to be created with Properties of PropertyId" + props[i].PropertyId.ToString(); return false; } } if (!CharacterValidateName(character.CharacterName, ref msg)) { // send error if we can't validate the name return false; } return true; }
public static bool PersistNewCharacter_Inventory(this CharacterUtil util, ICharacterInfo ci, SqlConnection con, SqlTransaction tran) { DB.Instance.Character_Create_Inventory(con, tran); return true; }
public static bool SaveCharacter_TSRating(this CharacterUtil util, ICharacterInfo ci, SqlConnection con, SqlTransaction tran) { DB.Instance.Character_Save_TSRating(con, tran); return true; }
/// <summary> /// Gets players that are most suited for competition (would provide as close as possible to an even match). Both @candidates and @target need to have the TSCharacterComponent attached. /// </summary> /// <param name="candidates">the possible candidates to match against</param> /// <param name="target">the player for whom we wish to find matches</param> /// <returns>a list of character IDs in order of </returns> public static List<SkillMatchInfo> GetTopQualityMatches(IEnumerable<ICharacterInfo> candidates, ICharacterInfo target, int maxResults) { DateTime start = DateTime.UtcNow; List<SkillMatchInfo> matches = new List<SkillMatchInfo>(); try { GameInfo gi = GameInfo.DefaultGameInfo; Player targetPlayer = new Player(target.ID); double targetMu = target.Properties.GetDoubleProperty((int)TSPropertyID.RatingMean).GetValueOrDefault(); double targetSigma = target.Properties.GetDoubleProperty((int)TSPropertyID.RatingStandardDeviation).GetValueOrDefault(); Rating targetRating = new Rating(targetMu, targetSigma); Team targetTeam = new Team(targetPlayer, targetRating); int numCandidates = 0; IEnumerator<ICharacterInfo> enu = candidates.GetEnumerator(); while (enu.MoveNext()) { numCandidates++; Player player = new Player(enu.Current.ID); double mu = enu.Current.Properties.GetDoubleProperty((int)TSPropertyID.RatingMean).GetValueOrDefault(); double sigma = enu.Current.Properties.GetDoubleProperty((int)TSPropertyID.RatingStandardDeviation).GetValueOrDefault(); Rating rating = new Rating(mu, sigma); Team team = new Team(player, rating); double quality = TrueSkillCalculator.CalculateMatchQuality(gi, Teams.Concat(targetTeam, team)); matches.Add(new SkillMatchInfo(enu.Current.ID, quality)); } // Sort it matches.OrderBy(i => i.MatchQuality); // trim it, if necessary if (maxResults > 0) { if (maxResults > matches.Count) { maxResults = matches.Count; } matches = matches.GetRange(0, maxResults - 1); } DateTime end = DateTime.UtcNow; TimeSpan exeTime = end - start; int highestQuality = 0; if (matches.Count > 0) { highestQuality = (int)Math.Floor(matches[0].MatchQuality * 100); } Log.LogMsg("TrueSkill match maker tested [" + numCandidates + "] candidates for character [" + target.CharacterName + " | " + target.ID + "]. Returned [" + matches.Count + "] possible matches in [" + exeTime.TotalMilliseconds + " ms]. Best match found had a [" + highestQuality + "%] quality rating."); } catch(Exception e) { Log.LogMsg("TrueSkill match maker encountered an error when searching for match candidates. " + e.Message); } return matches; }