Ejemplo n.º 1
0
        private static (long characterId, DestinyItemComponent item) FindItemToLock(
            DestinyProfileResponse profile)
        {
            string selectedCharacterId        = default;
            DestinyItemComponent selectedItem = default;

            foreach (var(characterId, characterInventory) in profile.CharacterEquipment.Data)
            {
                foreach (var item in characterInventory.Items)
                {
                    if (item.ItemInstanceId == 0 ||
                        (item.BucketHash != BucketShips && item.BucketHash != BucketSparrows))
                    {
                        continue;
                    }

                    selectedCharacterId = characterId;
                    selectedItem        = item;
                    break;
                }

                if (selectedCharacterId != null)
                {
                    break;
                }
            }

            return(characterId : Convert.ToInt64(selectedCharacterId), item : selectedItem);
        }
Ejemplo n.º 2
0
        private static async Task AddFakeItem(DestinyProfileResponse profile, uint itemHash, long itemInstanceId)
        {
            var random = new Random(unchecked ((int)itemHash));

            var itemDef = await Definitions.GetInventoryItem(itemHash);

            var character   = profile.Characters.Data.Values.First(v => v.ClassType == itemDef.ClassType);
            var characterId = character.CharacterId.ToString();

            profile.CharacterInventories.Data[characterId].Items.Add(new DestinyItemComponent()
            {
                ItemHash       = itemHash,
                BucketHash     = itemDef.Inventory.BucketTypeHash,
                ItemInstanceId = itemInstanceId,
            });
            profile.ItemComponents.Objectives.Data[itemInstanceId.ToString()] = new DestinyItemObjectivesComponent()
            {
                Objectives = new List <DestinyObjectiveProgress>()
            };

            foreach (var objectiveHash in itemDef.Objectives.ObjectiveHashes)
            {
                var objectiveDef = await Definitions.GetObjective(objectiveHash);

                profile.ItemComponents.Objectives.Data[itemInstanceId.ToString()].Objectives.Add(new DestinyObjectiveProgress()
                {
                    ObjectiveHash   = objectiveHash,
                    Progress        = random.Next(0, Convert.ToInt32(objectiveDef.CompletionValue)),
                    CompletionValue = objectiveDef.CompletionValue,
                });
            }
        }
Ejemplo n.º 3
0
        public async Task <DestinyProfileResponse> GetProfile()
        {
            if (currentProfile != null)
            {
                return(currentProfile);
            }

            var account = await GetAccount();

            var profile = await Util.RequestAndRetry(() => destinyApi.GetProfile(oauthManager.currentToken.AccessToken, BungieMembershipType.TigerSteam, account.MembershipId));

            currentProfile = profile;

            return(profile);
        }
Ejemplo n.º 4
0
        public static async Task <CrucibleMapTrackable> CreateFromProfile(DestinyProfileResponse profile)
        {
            string   activeCharacterId = "";
            DateTime activityStart     = DateTime.MinValue;
            DestinyCharacterActivitiesComponent currentActivitiesComponent = default;

            foreach (var(characterId, activitiesComponent) in profile.CharacterActivities.Data)
            {
                // TODO: validate dates are correct
                Log.Info("TODO: validate dates are correct: DateActivityStarted: {DateActivityStarted}, activityStart: {activityStart}", activitiesComponent.DateActivityStarted, activityStart);

                if (activitiesComponent.CurrentActivityHash != 0 && activitiesComponent.DateActivityStarted > activityStart)
                {
                    activeCharacterId          = characterId;
                    currentActivitiesComponent = activitiesComponent;
                    activityStart = activitiesComponent.DateActivityStarted;
                }
            }

            if (currentActivitiesComponent == null)
            {
                return(new CrucibleMapTrackable());
            }

            var tracker = new CrucibleMapTrackable()
            {
                CurrentActivityHash     = currentActivitiesComponent.CurrentActivityHash,
                CurrentActivityModeHash = currentActivitiesComponent.CurrentActivityModeHash,
            };

            if (profile.Characters.Data.ContainsKey(activeCharacterId))
            {
                tracker.OwnerCharacter = new Character {
                    CharacterComponent = profile.Characters.Data[activeCharacterId]
                };
                await tracker.OwnerCharacter.PopulateDefinition();
            }

            await tracker.PopulateDefinitions();

            return(tracker);
        }
Ejemplo n.º 5
0
        public async Task CacheBust(DestinyProfileResponse profile)
        {
            var(characterId, item) = FindItemToLock(profile);
            var itemState    = item?.State ?? 0;
            var itemIsLocked = itemState == ItemState.Locked;

            if (item == null)
            {
                return;
            }

            Log.Debug("Found item to toggle lock state, character ID {characterId}, {itemHash}:{itemInstanceId}. locked state:{locked}", characterId, item.ItemHash, item.ItemInstanceId, itemIsLocked);

            try
            {
                await SetLockState(itemIsLocked, item.ItemInstanceId, characterId, profile.Profile.Data.UserInfo.MembershipType);
            }
            catch (Exception err)
            {
                Log.Error("Error busting profile cache, silently ignoring {Error}", err);
            }
        }
Ejemplo n.º 6
0
        public static DestinyPresentationNodeComponent FindProfilePresentationNode(long hash, DestinyProfileResponse profile)
        {
            var profilePresentationNodes   = profile?.ProfilePresentationNodes?.Data?.Nodes;
            var characterPresentationNodes = profile?.CharacterPresentationNodes?.Data;
            var hashString = hash.ToString();

            if (profilePresentationNodes != null && profilePresentationNodes.ContainsKey(hashString))
            {
                return(profilePresentationNodes[hashString]);
            }

            if (characterPresentationNodes != null)
            {
                foreach (var(_, value) in characterPresentationNodes)
                {
                    if (value.Nodes.ContainsKey(hashString))
                    {
                        return(value.Nodes[hashString]);
                    }
                }
            }

            return(default);
 public void Test03_GetProfile(long destinyMembershipId)
 {
     DestinyProfileResponse profile = _client.Destiny2.GetProfile(BungieMembershipType.TigerPsn, destinyMembershipId, DestinyComponentTypes.Profile);
 }
Ejemplo n.º 8
0
        public static async Task <Item> ItemFromItemComponent(DestinyItemComponent item, DestinyProfileResponse profile, Character ownerCharacter = default)
        {
            var uninstancedObjectivesData =
                ownerCharacter == null
                ?  new Dictionary <string, DestinyItemObjectivesComponent>()
                : profile.CharacterUninstancedItemComponents[ownerCharacter.CharacterComponent.CharacterId.ToString()].Objectives.Data;

            var objectives     = new List <DestinyObjectiveProgress>();
            var itemInstanceId = item.ItemInstanceId.ToString();
            var itemHash       = item.ItemHash.ToString();

            if (profile.ItemComponents.Objectives.Data.ContainsKey(itemInstanceId))
            {
                objectives.AddRange(profile.ItemComponents.Objectives.Data[itemInstanceId]?.Objectives);
            }

            if (item.ItemInstanceId.Equals(0) && uninstancedObjectivesData.ContainsKey(itemHash))
            {
                objectives.AddRange(uninstancedObjectivesData[itemHash].Objectives);
            }

            if (objectives.Count == 0)
            {
                return(new Item());
            }

            var bounty = new Item()
            {
                ItemHash       = item.ItemHash,
                ItemInstanceId = item.ItemInstanceId,
                BucketHash     = item.BucketHash,
                OwnerCharacter = ownerCharacter,
                Objectives     = new List <Objective>()
            };

            await bounty.PopulateDefinition();

            foreach (var destinyQuestsDestinyObjectiveProgress in objectives)
            {
                var obj = new Objective {
                    Progress = destinyQuestsDestinyObjectiveProgress
                };
                await obj.PopulateDefinition();

                bounty.Objectives.Add(obj);
            }

            return(bounty);
        }
Ejemplo n.º 9
0
        public static async Task <List <Item> > ItemsFromProfile(DestinyProfileResponse profile, Character activeCharacter)
        {
            var bounties = new List <Item>();

            async Task EachInventoryItem(DestinyItemComponent inventoryItem, Character ownerCharacter = default)
Ejemplo n.º 10
0
        /// <summary>
        /// Gets all current activities for all characters for all clan members.
        /// Only gets the latest page of activies for ScoredNightfall activities.
        /// Scores then get inserted into the collection.
        /// </summary>
        /// <returns></returns>
        private async Task GetBungieScores(int count)
        {
            // Get Clan ID from Environment Variables
            long clanID = Convert.ToInt64(Environment.GetEnvironmentVariable("NFLBOT_CLANID"), CultureInfo.InvariantCulture);

            WriteLog(LogSeverity.Info, "Loading Clan Information..");
            // Get Members of Clan from Bungie
            SearchResultOfGroupMember clanResult = await bungieClient.GroupV2.GetMembersOfGroupAsync(
                groupId : clanID,
                currentpage : 0,
                memberType : RuntimeGroupMemberType.Member,
                nameSearch : string.Empty).ConfigureAwait(false);

            WriteLog(LogSeverity.Info, $"Clan Information loaded! {clanResult.Results.Length} members found.");

            // Loop through Members
            foreach (GroupMember clanMember in clanResult.Results)
            {
                // Get their Membership ID required for getting their Profile & Activity Information
                long membershipId = clanMember.DestinyUserInfo.MembershipId;

                // Get their Profile Information
                DestinyProfileResponse memberdata = await bungieClient.Destiny2.GetProfileAsync(
                    membershipType : clanMember.DestinyUserInfo.MembershipType,
                    destinyMembershipId : membershipId,
                    components : new BungieNet.Destiny.DestinyComponentType[] { BungieNet.Destiny.DestinyComponentType.Characters }).ConfigureAwait(false);

                WriteLog(LogSeverity.Debug, $"Found {memberdata.Characters.Data.Count} characters for {clanMember.DestinyUserInfo.DisplayName}");

                // Loop through Characters of Member
                foreach (var playerCharacter in memberdata.Characters.Data)
                {
                    // Hold Character ID in seperate Variable for convienence
                    long characterId = playerCharacter.Key;

                    // Get Activity History of Character
                    // Using a Try-Catch Block as players might opt-in to refuse API calls to their history
                    DestinyActivityHistoryResults activityData = null;
                    try
                    {
                        activityData = await bungieClient.Destiny2.GetActivityHistoryAsync(
                            membershipType : playerCharacter.Value.MembershipType,
                            destinyMembershipId : membershipId,
                            characterId : characterId,
                            count : count,
                            mode : BungieNet.Destiny.HistoricalStats.Definitions.DestinyActivityModeType.ScoredNightfall,
                            page : 0).ConfigureAwait(false);
                    }
                    catch (BungieException e) // Most likely to be privacy related exceptions. For now we just ignore those scores.
                    {
                        Console.WriteLine(e);
                        continue;
                    }

                    // If we didn't get any data, skip
                    if (activityData == null || activityData.Activities == null)
                    {
                        continue;
                    }

                    // Loop through Activities
                    foreach (var activity in activityData.Activities)
                    {
                        // If we already collected that Nightfall, skip it.
                        if (collection.Find(x => x.NightfallId == activity.ActivityDetails.InstanceId).Any())
                        {
                            continue;
                        }

                        // If the Activity is before the start of the ranking period (usually a Season), skip the Score.
                        var activityDate = activity.Period;
                        if (activityDate <= currentSeasonStart)
                        {
                            continue;
                        }

                        // API might return aborted Nightfalls, so their Score is 0. We want to ignore those.
                        var nightfallScore = activity.Values["teamScore"].Basic.Value;
                        if (nightfallScore <= 0)
                        {
                            continue;
                        }

                        // Get the Director Hash required for finding the Nightfall Name
                        uint directorHash = activity.ActivityDetails.DirectorActivityHash;

                        // Get the Nightfall Name
                        string activityName = GetNameFromHash(directorHash);
                        if (activityName.Equals("INVALID", StringComparison.InvariantCulture))
                        {
                            continue;
                        }

                        // Create new Score Entry
                        ScoreEntry entry = new ScoreEntry(
                            name: clanMember.DestinyUserInfo.DisplayName,
                            accountId: membershipId,
                            directorActivityHash: activity.ActivityDetails.DirectorActivityHash.ToString(),
                            nightfallId: activity.ActivityDetails.InstanceId,
                            activityName: activityName,
                            activityDate: activityDate,
                            score: nightfallScore);

                        // Insert into Collection
                        collection.InsertOne(entry);
                        WriteLog(LogSeverity.Info, $"Added Score {nightfallScore} for Player {clanMember.DestinyUserInfo.DisplayName} from {activityDate} in {activityName}");
                    }
                }
            }
        }
Ejemplo n.º 11
0
        private async Task <KeyValuePair <long, CharacterOverview> > CollectDataAboutCharacter(DestinyProfileResponse characters, KeyValuePair <long, CharacterComponent> character)
        {
            var curActivity        = characters.Response.characterActivities.data.Where(x => x.Key == character.Key).Select(x => x.Value).First();
            var characterEquipment = characters.Response.characterEquipment.data.Where(x => x.Key == character.Key).FirstOrDefault().Value.items.Select(x => new { x.itemHash, x.itemInstanceId });

            var characterStats = characters.Response.characters.data.Where(x => x.Key == character.Key).FirstOrDefault();

            var activityDisplay = (await DataEngine.GetDetailedInformationFromHash <dynamic>(DestinyTable.ActivityDefinition, curActivity.currentActivityHash))
                                  .Select(x => x.Value.displayProperties).FirstOrDefault();

            var className = (await DataEngine.GetDetailedInformationFromHash <dynamic>(DestinyTable.ClassDefinition, character.Value.classHash))
                            .Where(x => x.Key == character.Value.classHash)
                            .Select(x => x.Value)
                            .First().displayProperties.name;

            var raceName = (await DataEngine.GetDetailedInformationFromHash <dynamic>(DestinyTable.RaceDefinition, character.Value.raceHash))
                           .Where(x => x.Key == character.Value.raceHash)
                           .Select(x => x.Value)
                           .First().displayProperties.name;

            var genderName = (await DataEngine.GetDetailedInformationFromHash <dynamic>(DestinyTable.GenderDefinition, character.Value.genderHash))
                             .Where(x => x.Key == character.Value.genderHash)
                             .Select(x => x.Value)
                             .First().displayProperties.name;

            return(new KeyValuePair <long, CharacterOverview>(character.Key, new CharacterOverview()
            {
                Light = character.Value.light,
                LevelProgression = character.Value.levelProgression,
                Class = className,
                Race = raceName,
                Gender = genderName,
                Super = await GetItemInformation("Subclass", characterEquipment, characters.Response.itemComponents.instances),
                Helm = await GetItemInformation("Helmet", characterEquipment, characters.Response.itemComponents.instances),
                Arms = await GetItemInformation("Gauntlets", characterEquipment, characters.Response.itemComponents.instances),
                Chest = await GetItemInformation("Chest Armor", characterEquipment, characters.Response.itemComponents.instances),
                Feet = await GetItemInformation("Leg Armor", characterEquipment, characters.Response.itemComponents.instances),
                ClassGear = await GetItemInformation("Class Armor", characterEquipment, characters.Response.itemComponents.instances),
                Primary = await GetItemInformation("Kinetic Weapons", characterEquipment, characters.Response.itemComponents.instances),
                Secondary = await GetItemInformation("Energy Weapons", characterEquipment, characters.Response.itemComponents.instances),
                Heavy = await GetItemInformation("Power Weapons", characterEquipment, characters.Response.itemComponents.instances),
                Ghost = await GetItemInformation("Ghost", characterEquipment, characters.Response.itemComponents.instances),
                Emblem = await GetItemInformation("Emblems", characterEquipment, characters.Response.itemComponents.instances),
                CurrentActivity = activityDisplay == null ? null : JsonConvert.DeserializeObject <DestinyDisplayPropertiesDefinition>(JsonConvert.SerializeObject(activityDisplay))
            }));
        }
Ejemplo n.º 12
0
        public static DestinyRecordComponent FindRecordInProfileOrDefault(string triumphHash, DestinyProfileResponse profile)
        {
            var characterIds = profile?.Profile?.Data?.CharacterIds ?? new List <long>();

            if (profile?.CharacterRecords?.Data == null)
            {
                return(default);