コード例 #1
0
        public void UpdateState()
        {
            using (ISession session = SessionCreator.OpenSession()) {
                using (ITransaction transaction = session.BeginTransaction()) {
                    Populate(session);

                    IList <AugmentationItem> items = session.CreateCriteria <AugmentationItem>().List <AugmentationItem>();
                    var stats = _databaseItemStatDao.GetStats(session, StatFetch.AugmentItems);

                    foreach (var item in items)
                    {
                        var rarity       = ItemOperationsUtility.GetRarityForRecord(stats, item.BaseRecord);
                        var minimumLevel = ItemOperationsUtility.GetMinimumLevelForRecord(stats, item.BaseRecord);
                        var name         = ItemOperationsUtility.GetItemName(session, stats, item);

                        item.Rarity       = rarity;
                        item.MinimumLevel = minimumLevel;
                        item.Name         = name;
                        session.Update(item);
                    }

                    transaction.Commit();
                }
            }
        }
コード例 #2
0
        private void UpdateItemDetails(ISession session, PlayerItem item, Dictionary <String, List <DBStatRow> > stats)
        {
            var table         = nameof(PlayerItem);
            var rarity        = nameof(PlayerItem.Rarity);
            var levelReq      = nameof(PlayerItem.LevelRequirement);
            var name          = nameof(PlayerItem.Name);
            var id            = nameof(PlayerItem.Id);
            var prefixRarity  = PlayerItemTable.PrefixRarity;
            var nameLowercase = nameof(PlayerItem.NameLowercase);


            var itemName = ItemOperationsUtility.GetItemName(session, stats, item);
            var records  = GetRecordsForItem(item);

            session.CreateQuery($@"UPDATE {table} 
                    SET {name} = :name, {nameLowercase} = :namelowercase, {rarity} = :rarity, {levelReq} = :levelreq, {prefixRarity} = :prefixrarity 
                    WHERE {id} = :id"
                                )
            .SetParameter("name", itemName)
            .SetParameter("namelowercase", itemName.ToLowerInvariant())
            .SetParameter("prefixrarity", GetGreenQualityLevelForRecords(stats, records))
            .SetParameter("rarity", ItemOperationsUtility.GetRarityForRecords(stats, records))
            .SetParameter("levelreq", ItemOperationsUtility.GetMinimumLevelForRecords(stats, records))
            .SetParameter("id", item.Id)
            .ExecuteUpdate();
        }
コード例 #3
0
ファイル: ItemHtmlWriter.cs プロジェクト: marius00/iagd
        public static List <List <JsonItem> > ToJsonSerializable(List <PlayerHeldItem> items)
        {
            var jsonItems = items.Select(GetJsonItem).ToList();

            var merged = ItemOperationsUtility.MergeStackSize(jsonItems);

            foreach (var itemList in merged)
            {
                itemList.Sort();
            }

            return(merged);
        }
コード例 #4
0
ファイル: ItemHtmlWriter.cs プロジェクト: hallgeirl/iagd
        private static JsonItem GetJsonItem(PlayerHeldItem item)
        {
            // TODO: Modifiers

            bool isCloudSynced = false;

            object[] id = { item.Id, "", "", "", "" };
            if (item is PlayerItem pi)
            {
                id            = new object[] { pi.Id, pi.BaseRecord, pi.PrefixRecord, pi.SuffixRecord, pi.MateriaRecord };
                isCloudSynced = !string.IsNullOrWhiteSpace(pi.AzureUuid);
            }


            ItemTypeDto type;
            string      extras = string.Empty;

            if (item.IsRecipe)
            {
                type = ItemTypeDto.Recipe;
            }
            else if (!string.IsNullOrEmpty(item.Stash))
            {
                type = ItemTypeDto.Buddy;
            }
            else if (item is PlayerItem)
            {
                type = ItemTypeDto.Player;
            }
            else if (item is AugmentationItem)
            {
                type   = ItemTypeDto.Augmentation;
                extras = ItemOperationsUtility.TranslateFaction(
                    GlobalSettings.Language,
                    ((AugmentationItem)item).Tags.FirstOrDefault(m => m.Stat == "factionSource")?.TextValue ?? string.Empty
                    );
            }
            else
            {
                type = ItemTypeDto.Unknown;
            }



            var json = new JsonItem {
                BaseRecord = item.BaseRecord ?? string.Empty,
                URL        = id,
                Icon       = item.Bitmap ?? string.Empty,
                Name       = PureItemName(item.Name) ?? string.Empty,
                Quality    = item.Rarity ?? string.Empty,
                Level      = item.MinimumLevel,
                Socket     = GetSocketFromItem(item?.Name) ?? string.Empty,
                NumItems   = item.Count,
                PetStats   = item.PetStats.Select(m => new JsonStat {
                    Label = m.ToString(), Extras = m.Extra?.ToString()
                }).ToList(),
                BodyStats = item.BodyStats.Select(m => new JsonStat {
                    Label = m.ToString(), Extras = m.Extra?.ToString()
                }).ToList(),
                HeaderStats = item.HeaderStats.Select(m => new JsonStat {
                    Label = m.ToString(), Extras = m.Extra?.ToString()
                }).ToList(),
                Type      = type,
                HasRecipe = item.HasRecipe,
                Buddies   = item.Buddies.ToArray(),
                Skill     = item.Skill != null?GetJsonSkill(item.Skill) : null,
                                GreenRarity    = item.PrefixRarity,
                                HasCloudBackup = isCloudSynced,
                                Slot           = SlotTranslator.Translate(GlobalSettings.Language, item.Slot ?? ""),
                                Extras         = extras
            };

            var modifiedSkills = item.ModifiedSkills;

            foreach (var modifiedSkill in modifiedSkills)
            {
                var translated = modifiedSkill.Translated;
                foreach (var translatedStat in translated)
                {
                    json.BodyStats.Add(new JsonStat {
                        Label  = translatedStat.ToString(),
                        Extras = translatedStat.Extra?.ToString()
                    });
                }

                if (translated.Count == 0)
                {
                    Logger.Debug($"Could not translate skill-modifier stats for \"{item.Name}\"");
                }
            }

            return(json);
        }
コード例 #5
0
        public static JsonItem GetJsonItem(PlayerHeldItem item)
        {
            // TODO: Modifiers

            bool isCloudSynced = false;

            object[] transferUrl = { "", "", "", "" };
            string   uniqueIdentifier;

            if (item is PlayerItem pi)
            {
                transferUrl      = new object[] { pi.BaseRecord, pi.PrefixRecord, pi.SuffixRecord, pi.MateriaRecord };
                isCloudSynced    = pi.IsCloudSynchronized;
                uniqueIdentifier = $"PI/{pi.Id}/{pi.CloudId}";
            }
            else if (item is BuddyItem bi)
            {
                // TODO: Remove this, buddy items are never transferable. Gotta provide a better unique id.
                uniqueIdentifier = $"BI/{bi.BuddyId}/{bi.RemoteItemId}";
            }
            else if (item is RecipeItem)
            {
                uniqueIdentifier = $"RI/{item.BaseRecord}";
            }
            else if (item is AugmentationItem)
            {
                uniqueIdentifier = $"AI/{item.BaseRecord}";
            }
            else
            {
                uniqueIdentifier = $"UK/{item.BaseRecord}";
            }


            ItemTypeDto type;
            string      extras = string.Empty;

            if (item.IsRecipe)
            {
                type = ItemTypeDto.Recipe;
            }
            else if (!string.IsNullOrEmpty(item.Stash))
            {
                type = ItemTypeDto.Buddy;
            }
            else if (item is PlayerItem)
            {
                type = ItemTypeDto.Player;
            }
            else if (item is AugmentationItem augmentationItem)
            {
                type   = ItemTypeDto.Augmentation;
                extras = ItemOperationsUtility.TranslateFaction(
                    RuntimeSettings.Language,
                    augmentationItem.Tags.FirstOrDefault(m => m.Stat == "factionSource")?.TextValue ?? string.Empty
                    );
            }
            else
            {
                type = ItemTypeDto.Unknown;
            }


            var json = new JsonItem {
                UniqueIdentifier = uniqueIdentifier,
                BaseRecord       = item.BaseRecord ?? string.Empty,
                URL                                                       = transferUrl,
                Icon                                                      = item.Bitmap ?? string.Empty,
                Name                                                      = PureItemName(item.Name) ?? string.Empty,
                Quality                                                   = item.Rarity ?? string.Empty,
                Level                                                     = item.MinimumLevel,
                Socket                                                    = GetSocketFromItem(item?.Name) ?? string.Empty,
                NumItems                                                  = (uint)item.Count,
                InitialNumItems                                           = (uint)item.Count,
                PetStats                                                  = item.PetStats.Select(ToJsonStat).ToHashSet().ToList(),
                BodyStats                                                 = item.BodyStats.Select(ToJsonStat).ToHashSet().ToList(),
                HeaderStats                                               = item.HeaderStats.Select(ToJsonStat).ToHashSet().ToList(),
                Type                                                      = type,
                HasRecipe                                                 = item.HasRecipe,
                Buddies                                                   = item.Buddies.ToArray(),
                Skill                                                     = item.Skill != null?GetJsonSkill(item.Skill) : null,
                                                      GreenRarity         = (int)item.PrefixRarity,
                                                      HasCloudBackup      = isCloudSynced,
                                                      Slot                = SlotTranslator.Translate(RuntimeSettings.Language, item.Slot ?? ""),
                                                      Extras              = extras,
                                                      IsMonsterInfrequent = item.ModifiedSkills.Any(s => s.IsMonsterInfrequent),
            };

            var modifiedSkills = item.ModifiedSkills;

            foreach (var modifiedSkill in modifiedSkills)
            {
                var translated = modifiedSkill.Translated;
                foreach (var stat in translated.Select(ToJsonStat))
                {
                    json.BodyStats.Add(stat);
                }

                if (translated.Count == 0 && !(modifiedSkill.Class == null || modifiedSkill.Tier == null))
                {
                    string[] uri = json.URL.Select(o => o.ToString()).ToArray();

                    var error = $@"Could not translate skill-modifier on: '{item.Name}', {json.BaseRecord} - {string.Join(";", uri)}";
                    ExceptionReporter.ReportIssue(error);
                    Logger.Debug($"Could not translate skill-modifier stats for \"{item.Name}\"");
                }
            }


            return(json);
        }
コード例 #6
0
ファイル: BuddyItemDaoImpl.cs プロジェクト: 211847750/iagd
        public IList <BuddyItem> FindBy(ItemSearchRequest query)
        {
            List <string> queryFragments            = new List <string>();
            Dictionary <string, object> queryParams = new Dictionary <string, object>();

            if (!string.IsNullOrEmpty(query.Wildcard))
            {
                queryFragments.Add($"{BuddyItemsTable.NameLowercase} LIKE :name");
                queryParams.Add("name", $"%{query.Wildcard.Replace(' ', '%').ToLowerInvariant()}%");
            }


            queryFragments.Add($"(LOWER({BuddyItemsTable.Mod}) = LOWER( :mod ) OR {BuddyItemsTable.Mod} IS NULL)");
            queryParams.Add("mod", query.Mod);

            if (!string.IsNullOrEmpty(query.Rarity))
            {
                queryFragments.Add($"{BuddyItemsTable.Rarity} = :rarity");
                queryParams.Add("rarity", query.Rarity);
            }

            if (query.PrefixRarity > 1)
            {
                queryFragments.Add($"{BuddyItemsTable.PrefixRarity} >= :prefixRarity");
                queryParams.Add("prefixRarity", query.PrefixRarity);
            }

            queryFragments.Add(query.IsHardcore ? "IsHardcore" : "NOT IsHardcore");

            if (query.RecentOnly)
            {
                queryFragments.Add($"{BuddyItemsTable.CreatedAt} > :filter_recentOnly");
                queryParams.Add("filter_recentOnly", DateTime.UtcNow.AddHours(-12).ToTimestamp());
            }

            // Add the MINIMUM level requirement (if any)
            if (query.MinimumLevel > 0)
            {
                queryFragments.Add($"{BuddyItemsTable.LevelRequirement} >= :minlevel");
                queryParams.Add("minlevel", query.MinimumLevel);
            }

            // Add the MAXIMUM level requirement (if any)
            if (query.MaximumLevel < 120 && query.MaximumLevel > 0)
            {
                queryFragments.Add($"{BuddyItemsTable.LevelRequirement} <= :maxlevel");
                queryParams.Add("maxlevel", query.MaximumLevel);
            }

            List <string> sql = new List <string>();

            sql.Add($@"SELECT
                                {BuddyItemsTable.BaseRecord} as BaseRecord,
                                {BuddyItemsTable.PrefixRecord} as PrefixRecord,
                                {BuddyItemsTable.SuffixRecord} as SuffixRecord,
                                {BuddyItemsTable.ModifierRecord} as ModifierRecord,
                                {BuddyItemsTable.TransmuteRecord} as TransmuteRecord,
                                {BuddyItemsTable.MateriaRecord} as MateriaRecord,
                                {BuddyItemsTable.Rarity} as Rarity,
                                {BuddyItemsTable.PrefixRarity} as PrefixRarity,
                                {BuddyItemsTable.Name} as Name,
 
                                {BuddyItemsTable.LevelRequirement} as MinimumLevel,
                                {BuddyItemsTable.RemoteItemId} as RemoteItemId,
                                {BuddyItemsTable.StackCount} as Count,
                                {BuddyItemsTable.SubscriptionId} as BuddyId,
                                S.{BuddySubscriptionTable.Nickname} as Stash,
                                coalesce((SELECT group_concat(Record, '|') FROM {BuddyItemRecordTable.Table} pir WHERE pir.{BuddyItemRecordTable.Item} = PI.{BuddyItemsTable.RemoteItemId} AND NOT {BuddyItemRecordTable.Record} IN (PI.BaseRecord, PI.SuffixRecord, PI.MateriaRecord, PI.PrefixRecord)), '') AS PetRecord


                FROM {BuddyItemsTable.Table} PI, {BuddySubscriptionTable.Table} S WHERE "
                    + string.Join(" AND ", queryFragments)
                    + $" AND {BuddyItemsTable.SubscriptionId} = {BuddySubscriptionTable.Id} "
                    );

            var subquery = CreateDatabaseStatQueryParams(query);

            if (subquery != null)
            {
                sql.Add($" AND PI.{BuddyItemsTable.RemoteItemId} IN (" + subquery.SQL + ")");
            }



            using (ISession session = SessionCreator.OpenSession()) {
                using (session.BeginTransaction()) {
                    Logger.Debug(string.Join(" ", sql));
                    var q = session.CreateSQLQuery(string.Join(" ", sql));
                    q.AddScalar("BaseRecord", NHibernateUtil.String);
                    q.AddScalar("PrefixRecord", NHibernateUtil.String);
                    q.AddScalar("SuffixRecord", NHibernateUtil.String);
                    q.AddScalar("ModifierRecord", NHibernateUtil.String);
                    q.AddScalar("PrefixRarity", NHibernateUtil.Int64);
                    q.AddScalar("TransmuteRecord", NHibernateUtil.String);
                    q.AddScalar("MateriaRecord", NHibernateUtil.String);
                    q.AddScalar("Rarity", NHibernateUtil.String);
                    q.AddScalar("Name", NHibernateUtil.String);
                    q.AddScalar("MinimumLevel", NHibernateUtil.UInt32);
                    q.AddScalar("Id", NHibernateUtil.Int64);
                    q.AddScalar("Count", NHibernateUtil.UInt32);
                    q.AddScalar("Stash", NHibernateUtil.String);
                    q.AddScalar("BuddyId", NHibernateUtil.Int64);
                    q.AddScalar("RemoteItemId", NHibernateUtil.String);
                    q.AddScalar("PetRecord", NHibernateUtil.String);

                    foreach (var key in queryParams.Keys)
                    {
                        q.SetParameter(key, queryParams[key]);
                        Logger.Debug($"{key}: " + queryParams[key]);
                    }

                    if (subquery != null)
                    {
                        foreach (var key in subquery.Parameters.Keys)
                        {
                            q.SetParameterList(key, subquery.Parameters[key]);
                            Logger.Debug($"{key}: " + string.Join(",", subquery.Parameters[key]));
                        }
                    }

                    Logger.Debug(q.QueryString);
                    q.SetResultTransformer(Transformers.AliasToBean <BuddyItem>());
                    var result = ItemOperationsUtility.MergeStackSize(q.List <BuddyItem>());

                    // stacksize is correct.. record is not
                    Logger.Debug($"Search returned {result.Count} items");
                    return(result);
                }
            }
        }
コード例 #7
0
ファイル: ItemHtmlWriter.cs プロジェクト: marius00/iagd
        private static JsonItem GetJsonItem(PlayerHeldItem item)
        {
            // TODO: Modifiers

            bool isHardcore    = false;
            bool isCloudSynced = false;

            object[]            transferUrl      = { "", "", "", "" };
            string              uniqueIdentifier = GetUniqueIdentifier(item);
            List <ItemStatInfo> replicaStats     = null;
            var mergeIdentifier = item.BaseRecord ?? string.Empty;

            if (item is PlayerItem pi)
            {
                transferUrl   = new object[] { pi.BaseRecord, pi.PrefixRecord, pi.SuffixRecord, pi.MateriaRecord, pi.Mod, pi.IsHardcore };
                isCloudSynced = pi.IsCloudSynchronized;
                isHardcore    = pi.IsHardcore;

                if (!string.IsNullOrEmpty(pi.ReplicaInfo))
                {
                    replicaStats = JsonConvert.DeserializeObject <List <ItemStatInfo> >(pi.ReplicaInfo);
                }


                mergeIdentifier += (pi.PrefixRecord ?? string.Empty) + (pi.SuffixRecord ?? string.Empty);
            }
            else if (item is BuddyItem bi)
            {
                mergeIdentifier += (bi.PrefixRecord ?? string.Empty) + (bi.SuffixRecord ?? string.Empty);
                if (!string.IsNullOrEmpty(bi.ReplicaInfo))
                {
                    replicaStats = JsonConvert.DeserializeObject <List <ItemStatInfo> >(bi.ReplicaInfo);
                }
            }

            ItemTypeDto type;
            string      extras = item.Stash;

            if (item.IsRecipe)
            {
                type = ItemTypeDto.Recipe;
            }
            else if (!string.IsNullOrEmpty(item.Stash))
            {
                type = ItemTypeDto.Buddy;
            }
            else if (item is PlayerItem)
            {
                type = ItemTypeDto.Player;
            }
            else if (item is AugmentationItem augmentationItem)
            {
                type   = ItemTypeDto.Augmentation;
                extras = ItemOperationsUtility.TranslateFaction(
                    RuntimeSettings.Language,
                    augmentationItem.Tags.FirstOrDefault(m => m.Stat == "factionSource")?.TextValue ?? string.Empty
                    );
            }
            else
            {
                type = ItemTypeDto.Unknown;
            }

            bool skipStats        = replicaStats != null;
            var  replicaBodyStats = new List <JsonStat>(0);

            if (skipStats)
            {
                // Add skillz
                replicaBodyStats = item.BodyStats
                                   .Where(m => m.Extra != null)
                                   .Select(ToJsonStat)
                                   .ToHashSet()
                                   .ToList();
            }

            var json = new JsonItem {
                UniqueIdentifier = uniqueIdentifier,
                MergeIdentifier  = mergeIdentifier,
                BaseRecord       = item.BaseRecord ?? string.Empty,
                URL                 = transferUrl,
                Icon                = item.Bitmap ?? string.Empty,
                Name                = PureItemName(item.Name) ?? string.Empty,
                Quality             = item.Rarity ?? string.Empty,
                Level               = item.MinimumLevel,
                Socket              = GetSocketFromItem(item?.Name) ?? string.Empty,
                PetStats            = skipStats ? new List <JsonStat>() : item.PetStats.Select(ToJsonStat).ToHashSet().ToList(),
                BodyStats           = skipStats ? replicaBodyStats : item.BodyStats.Select(ToJsonStat).ToHashSet().ToList(),
                HeaderStats         = skipStats ? new List <JsonStat>() : item.HeaderStats.Select(ToJsonStat).ToHashSet().ToList(),
                Type                = type,
                HasRecipe           = item.HasRecipe,
                Skill               = (item.Skill != null && !skipStats) ? GetJsonSkill(item.Skill) : null,
                GreenRarity         = (int)item.PrefixRarity,
                HasCloudBackup      = isCloudSynced,
                Slot                = SlotTranslator.Translate(RuntimeSettings.Language, item.Slot ?? ""),
                Extras              = extras,
                IsMonsterInfrequent = item.ModifiedSkills.Any(s => s.IsMonsterInfrequent),
                IsHardcore          = isHardcore,
                ReplicaStats        = replicaStats,
            };

            if (!skipStats)
            {
                var modifiedSkills = item.ModifiedSkills;
                foreach (var modifiedSkill in modifiedSkills)
                {
                    var translated = modifiedSkill.Translated;
                    foreach (var stat in translated.Select(ToJsonStat))
                    {
                        json.BodyStats.Add(stat);
                    }
                }
            }


            return(json);
        }
コード例 #8
0
        /*
         * private static PlayerItem ToPlayerItem(object o) {
         *  object[] arr = (object[]) o;
         *  int idx = 0;
         *  string name = arr[idx++] as string;
         *  long stackCount = (long) arr[idx++];
         *  string rarity = (string) arr[idx++];
         *  int levelrequirement = (int) (double) arr[idx++];
         *  string baserecord = (string) arr[idx++];
         *  string prefixrecord = (string) arr[idx++];
         *  string suffixrecord = (string) arr[idx++];
         *  string ModifierRecord = (string) arr[idx++];
         *  string MateriaRecord = (string) arr[idx++];
         *  int PrefixRarity = (int) arr[idx++];
         *  string AzureUuid = (string) arr[idx++];
         *  string CloudId = (string) arr[idx++];
         *  long? IsCloudSynchronized = (long?) arr[idx++];
         *  string PetRecord = (string) arr[idx++];
         *
         *  return new PlayerItem {
         *      Name = name,
         *      StackCount = stackCount,
         *      Rarity = rarity,
         *      LevelRequirement = levelrequirement,
         *      BaseRecord = baserecord,
         *      PrefixRecord = prefixrecord,
         *      SuffixRecord = suffixrecord,
         *      ModifierRecord = ModifierRecord,
         *      MateriaRecord = MateriaRecord,
         *      PrefixRarity = PrefixRarity,
         *      AzureUuid = AzureUuid,
         *      CloudId = CloudId,
         *      IsCloudSynchronized = IsCloudSynchronized.HasValue && IsCloudSynchronized.Value == 1,
         *      PetRecord = PetRecord
         *  };
         * }*/

        public List <PlayerItem> SearchForItems(ItemSearchRequest query)
        {
            Logger.Debug($"Searching for items with query {query}");
            List <string> queryFragments            = new List <string>();
            Dictionary <string, object> queryParams = new Dictionary <string, object>();

            if (!String.IsNullOrEmpty(query.Wildcard))
            {
                queryFragments.Add("(PI.namelowercase LIKE :name OR searchabletext LIKE :wildcard)");
                queryParams.Add("name", $"%{query.Wildcard.Replace(' ', '%').ToLower()}%");
                queryParams.Add("wildcard", $"%{query.Wildcard.ToLower()}%");
            }

            // Filter by mod/hc
            queryFragments.Add("(LOWER(PI.Mod) = LOWER( :mod ) OR PI.Mod IS NULL)");
            queryParams.Add("mod", query.Mod);

            if (query.IsHardcore)
            {
                queryFragments.Add("PI.IsHardcore");
            }
            else
            {
                queryFragments.Add("NOT PI.IsHardcore");
            }

            if (!String.IsNullOrEmpty(query.Rarity))
            {
                queryFragments.Add("PI.Rarity = :rarity");
                queryParams.Add("rarity", query.Rarity);
            }

            if (query.PrefixRarity > 0)
            {
                queryFragments.Add("PI.PrefixRarity >= :prefixRarity");
                queryParams.Add("prefixRarity", query.PrefixRarity);
            }

            if (query.SocketedOnly)
            {
                queryFragments.Add("PI.MateriaRecord is not null and PI.MateriaRecord != ''");
            }

            // Add the MINIMUM level requirement (if any)
            if (query.MinimumLevel > 0)
            {
                queryFragments.Add("PI.LevelRequirement >= :minlevel");
                queryParams.Add("minlevel", query.MinimumLevel);
            }

            // Add the MAXIMUM level requirement (if any)
            if (query.MaximumLevel < 120 && query.MaximumLevel > 0)
            {
                queryFragments.Add("PI.LevelRequirement <= :maxlevel");
                queryParams.Add("maxlevel", query.MaximumLevel);
            }

            // Show only items from the past 12 hours
            if (query.RecentOnly)
            {
                queryFragments.Add("created_at > :filter_recentOnly");
                queryParams.Add("filter_recentOnly", DateTime.UtcNow.AddHours(-12).ToTimestamp());
            }

            // Only items which grants new skills
            if (query.WithGrantSkillsOnly)
            {
                // TODO: Are there any prefixes or suffixes which grants skills?
                queryFragments.Add($"PI.baserecord IN (SELECT PlayerItemRecord from ({ItemSkillDaoImpl.ListItemsQuery}) y)");
            }

            if (query.WithSummonerSkillOnly)
            {
                queryFragments.Add(@"PI.baserecord IN (SELECT p.baserecord as PlayerItemRecord
                    from itemskill_v2 s, itemskill_mapping map, DatabaseItem_v2 db,  playeritem p, DatabaseItemStat_v2 stat  
                    where s.id_skill = map.id_skill 
                    and map.id_databaseitem = db.id_databaseitem  
                    and db.baserecord = p.baserecord 
                    and stat.id_databaseitem = s.id_databaseitem
                    and stat.stat = 'spawnObjects')");
            }


            List <string> sql = new List <string>();

            sql.Add($@"select name as Name, 
                StackCount, 
                rarity as Rarity, 
                levelrequirement as LevelRequirement, 
                baserecord as BaseRecord, 
                prefixrecord as PrefixRecord, 
                suffixrecord as SuffixRecord, 
                ModifierRecord as ModifierRecord, 
                MateriaRecord as MateriaRecord,
                {PlayerItemTable.PrefixRarity} as PrefixRarity,
                {PlayerItemTable.AzureUuid} as AzureUuid,
                {PlayerItemTable.CloudId} as CloudId,
                {PlayerItemTable.IsCloudSynchronized} as IsCloudSynchronizedValue,
                {PlayerItemTable.Id} as Id,
                coalesce((SELECT group_concat(Record, '|') FROM PlayerItemRecord pir WHERE pir.PlayerItemId = PI.Id AND NOT Record IN (PI.BaseRecord, PI.SuffixRecord, PI.MateriaRecord, PI.PrefixRecord)), '') AS PetRecord
                FROM PlayerItem PI WHERE " + string.Join(" AND ", queryFragments));

            var subquery = CreateDatabaseStatQueryParams(query);

            if (subquery != null)
            {
                sql.Add(" AND PI.Id IN (" + subquery.SQL + ")");
            }


            // Can be several slots for stuff like "2 Handed"
            if (query.Slot?.Length > 0)
            {
                string subquerySql = $@"
                SELECT Playeritemid FROM PlayerItemRecord WHERE record IN (
                    select baserecord from databaseitem_V2 db where db.baserecord in (
                        select baserecord from {PlayerItemTable.Table} union 
                        select prefixrecord from {PlayerItemTable.Table} union 
                        select suffixrecord from {PlayerItemTable.Table} union 
                        select materiarecord from {PlayerItemTable.Table}
                    )
                    AND exists (
                        select id_databaseitem from databaseitemstat_v2 dbs 
                        WHERE stat = 'Class' 
                        AND TextValue in ( :class ) 
                        AND db.id_databaseitem = dbs.id_databaseitem
                    )
                )
                ";

                sql.Add($" AND PI.Id IN ({subquerySql})");

                // ItemRelic = Components, we don't want to find every item that has a component, only those that are one.
                if (query.Slot.Length == 1 && query.Slot[0] == "ItemRelic")
                {
                    sql.Add($" AND PI.{PlayerItemTable.Materia} = ''");
                }
            }

            using (ISession session = SessionCreator.OpenSession()) {
                using (ITransaction transaction = session.BeginTransaction()) {
                    IQuery q = session.CreateSQLQuery(string.Join(" ", sql));
                    foreach (var key in queryParams.Keys)
                    {
                        q.SetParameter(key, queryParams[key]);
                        Logger.Debug($"{key}: " + queryParams[key]);
                    }

                    if (subquery != null)
                    {
                        foreach (var key in subquery.Parameters.Keys)
                        {
                            var parameterList = subquery.Parameters[key];
                            q.SetParameterList(key, parameterList);
                            Logger.Debug($"{key}: " + string.Join(",", subquery.Parameters[key]));
                        }
                    }

                    if (query.Slot?.Length > 0)
                    {
                        q.SetParameterList("class", query.Slot);
                    }

                    Logger.Debug(q.QueryString);
                    q.SetResultTransformer(new AliasToBeanResultTransformer(typeof(PlayerItem)));

                    /*
                     * List<PlayerItem> items = new List<PlayerItem>();
                     * foreach (var item in q.List()) {
                     *  items.Add(ToPlayerItem(item));
                     * }*/

                    var items = ItemOperationsUtility.MergeStackSize(q.List <PlayerItem>());

                    Logger.Debug($"Search returned {items.Count} items");
                    return(items);
                }
            }
        }