Пример #1
0
        /// <summary>
        /// Tell the flipper that an auction was sold
        /// </summary>
        /// <param name="auction"></param>
        public void AuctionSold(SaveAuction auction)
        {
            if (!FlipIdLookup.ContainsKey(auction.UId))
            {
                return;
            }
            SoldAuctions[auction.UId] = auction.End;
            var auctionUUid = auction.Uuid;

            NotifySubsInactiveAuction(auctionUUid);
        }
Пример #2
0
 private bool GetAuctionToCheckFlipability(out SaveAuction auction)
 {
     // mix in lowerPrice
     if (_auctionCounter++ % 3 != 0)
     {
         if (PotetialFlipps.TryDequeue(out auction))
         {
             return(true);
         }
     }
     return(LowPriceQueue.TryDequeue(out auction));
 }
Пример #3
0
        public async Task <(List <SaveAuction>, DateTime)> GetRelevantAuctions(SaveAuction auction, HypixelContext context)
        {
            var itemData           = auction.NbtData.Data;
            var clearedName        = auction.Reforge != ItemReferences.Reforge.None ? ItemReferences.RemoveReforge(auction.ItemName) : auction.ItemName;
            var itemId             = ItemDetails.Instance.GetItemIdForName(auction.Tag, false);
            var youngest           = DateTime.Now;
            var relevantEnchants   = auction.Enchantments?.Where(e => UltimateEnchants.ContainsKey(e.Type) || e.Level >= 6).ToList();
            var matchingCount      = relevantEnchants.Count > 2 ? relevantEnchants.Count / 2 : relevantEnchants.Count;
            var ulti               = relevantEnchants.Where(e => UltimateEnchants.ContainsKey(e.Type)).FirstOrDefault();
            var highLvlEnchantList = relevantEnchants.Where(e => !UltimateEnchants.ContainsKey(e.Type)).Select(a => a.Type).ToList();
            var oldest             = DateTime.Now - TimeSpan.FromHours(1);

            IQueryable <SaveAuction> select = GetSelect(auction, context, clearedName, itemId, youngest, matchingCount, ulti, highLvlEnchantList, oldest, auction.Reforge, 10);

            var relevantAuctions = await select
                                   .ToListAsync();

            if (relevantAuctions.Count < 9)
            {
                // to few auctions in last hour, try a whole day
                oldest           = DateTime.Now - TimeSpan.FromDays(1.5);
                relevantAuctions = await GetSelect(auction, context, clearedName, itemId, youngest, matchingCount, ulti, highLvlEnchantList, oldest, auction.Reforge)
                                   .ToListAsync();

                if (relevantAuctions.Count < 50 && PotetialFlipps.Count < 2000)
                {
                    // to few auctions in a day, query a week
                    oldest           = DateTime.Now - TimeSpan.FromDays(8);
                    relevantAuctions = await GetSelect(auction, context, clearedName, itemId, youngest, matchingCount, ulti, highLvlEnchantList, oldest, auction.Reforge, 120)
                                       .ToListAsync();

                    if (relevantAuctions.Count < 10 && clearedName.Contains("✪"))
                    {
                        clearedName      = clearedName.Replace("✪", "").Trim();
                        relevantAuctions = await GetSelect(auction, context, clearedName, itemId, youngest, matchingCount, ulti, highLvlEnchantList, oldest, auction.Reforge, 120)
                                           .ToListAsync();
                    }
                }
            }

            /* got replaced with average overall lookup
             * if (relevantAuctions.Count < 3 && PotetialFlipps.Count < 100)
             * {
             *  oldest = DateTime.Now - TimeSpan.FromDays(25);
             *  relevantAuctions = await GetSelect(auction, context, null, itemId, youngest, matchingCount, ulti, ultiList, highLvlEnchantList, oldest)
             *          .ToListAsync();
             * } */


            return(relevantAuctions, oldest);
        }
Пример #4
0
        private static IQueryable <SaveAuction> AddPetLvlSelect(SaveAuction auction, IQueryable <SaveAuction> select)
        {
            var sb = new StringBuilder(auction.ItemName);

            if (sb[6] == ']')
            {
                sb[5] = '_';
            }
            else
            {
                sb[6] = '_';
            }
            select = select.Where(a => EF.Functions.Like(a.ItemName, sb.ToString()));
            return(select);
        }
Пример #5
0
 public PreditionInput Map(SaveAuction auction, DateTime time)
 {
     return(new PreditionInput()
     {
         AnvilUses = auction.AnvilUses,
         Bin = auction.Bin,
         Category = auction.Category,
         End = time,
         HighestBid = auction.HighestBidAmount,
         ItemId = auction.ItemId,
         Rarity = (int)auction.Tier,
         Reforge = (int)auction.Reforge,
         Start = auction.Start,
         StartingBid = (int)auction.StartingBid,
         Enchantments = auction.Enchantments.Select(e => ((byte)e.Type, (int)e.Level)).ToList(),
         NbtData = auction.NBTLookup.Select(l =>
         {
             if (KeysToInclude.TryGetValue(l.KeyId, out short mapped))
             {
                 return (mapped, l.Value);
             }
             return ((short)0, 0L);
         }).Where(el => el.Item1 != 0).ToList()
     });
Пример #6
0
        private static IQueryable <SaveAuction> AddEnchantmentSubselect(SaveAuction auction, int matchingCount, List <Enchantment.EnchantmentType> highLvlEnchantList, IQueryable <SaveAuction> select, byte ultiLevel, Enchantment.EnchantmentType ultiType)
        {
            var maxImportantEnchants = highLvlEnchantList.Count() + 1 + (ultiType == Enchantment.EnchantmentType.unknown ? 0 : 1);

            if (matchingCount > 0)
            {
                select = select.Where(a => a.Enchantments
                                      .Where(e => (e.Level > 5 && highLvlEnchantList.Contains(e.Type) ||
                                                   e.Type == ultiType && e.Level == ultiLevel)).Count() >= matchingCount &&
                                      a.Enchantments.Where(e => UltiEnchantList.Contains(e.Type) || e.Level > 5).Count() <= maxImportantEnchants);
            }
            else if (auction.Enchantments?.Count == 1)
            {
                select = select.Where(a => a.Enchantments != null && a.Enchantments.Any() &&
                                      a.Enchantments.First().Type == auction.Enchantments.First().Type &&
                                      a.Enchantments.First().Level == auction.Enchantments.First().Level);
            }
            else if (auction.Enchantments?.Count == 2)
            {
                select = select.Where(a => a.Enchantments != null && a.Enchantments.Count() == 2 &&
                                      a.Enchantments.Where(e =>
                                                           e.Type == auction.Enchantments[0].Type && e.Level == auction.Enchantments[0].Level ||
                                                           e.Type == auction.Enchantments[1].Type && e.Level == auction.Enchantments[1].Level).Count() == 2);
            }

            // make sure we exclude special enchants to get a reasonable price
            else if (auction.Enchantments.Any())
            {
                select = select.Where(a => !a.Enchantments.Where(e => UltiEnchantList.Contains(e.Type) || e.Level > 5).Any());
            }
            else if (auction.Category == Category.WEAPON || auction.Category == Category.ARMOR) // || auction.Tag == "ENCHANTED_BOOK")
            {
                select = select.Where(a => !a.Enchantments.Any());
            }
            return(select);
        }
Пример #7
0
        private static IQueryable <SaveAuction> GetSelect(
            SaveAuction auction,
            HypixelContext context,
            string clearedName,
            int itemId,
            DateTime youngest,
            int matchingCount,
            Enchantment ulti,
            List <Enchantment.EnchantmentType> highLvlEnchantList,
            DateTime oldest,
            ItemReferences.Reforge reforge,
            int limit = 60)
        {
            var select = context.Auctions
                         .Where(a => a.ItemId == itemId)
                         .Where(a => a.HighestBidAmount > 0)
                         .Where(a => a.Tier == auction.Tier);

            byte ultiLevel = 127;

            Enchantment.EnchantmentType ultiType = Enchantment.EnchantmentType.unknown;
            if (ulti != null)
            {
                ultiLevel = ulti.Level;
                ultiType  = ulti.Type;
            }

            if (relevantReforges.Contains(reforge))
            {
                select = select.Where(a => a.Reforge == reforge);
            }


            if (auction.ItemName != clearedName && clearedName != null)
            {
                select = select.Where(a => EF.Functions.Like(a.ItemName, "%" + clearedName));
            }
            else if (auction.Tag.StartsWith("PET"))
            {
                select = AddPetLvlSelect(auction, select);
            }
            else
            {
                select = select.Where(a => a.ItemName == clearedName);
            }

            if (auction.Tag == "MIDAS_STAFF" || auction.Tag == "MIDAS_SWORD")
            {
                try
                {
                    var val   = (long)auction.NbtData.Data["winning_bid"];
                    var keyId = NBT.GetLookupKey(auction.Tag);
                    select  = select.Where(a => a.NBTLookup.Where(n => n.KeyId == keyId && n.Value > val - 2_000_000 && n.Value < val + 2_000_000).Any());
                    oldest -= TimeSpan.FromDays(10);
                } catch
                {}
            }

            select = AddEnchantmentSubselect(auction, matchingCount, highLvlEnchantList, select, ultiLevel, ultiType);
            if (limit == 0)
            {
                return(select);
            }

            return(select
                   .Where(a => a.End > oldest && a.End < youngest)
                   //.OrderByDescending(a=>a.Id)
                   //.Include(a => a.NbtData)
                   .Take(limit));
        }
Пример #8
0
        public async System.Threading.Tasks.Task NewAuction(SaveAuction auction, HypixelContext context)
        {
            if (!Program.Migrated)
            {
                if (auction.UId % 20 == 0) // don't spam the log
                {
                    Console.WriteLine("not yet migrated skiping flip");
                }
                return;
            }
            if (diabled && auction.UId % 5 != 0)
            {
                return; // don't run on full cap on my dev machine :D
            }
            var price = (auction.HighestBidAmount == 0 ? auction.StartingBid : (auction.HighestBidAmount * 1.1)) / auction.Count;

            // if(auction.Enchantments.Count == 0 && auction.Reforge == ItemReferences.Reforge.None)
            //    Console.WriteLine("easy item");

            var(relevantAuctions, oldest) = await GetRelevantAuctions(auction, context);

            long medianPrice = 0;

            if (relevantAuctions.Count < 2)
            {
                Console.WriteLine($"Could not find enough relevant auctions for {auction.ItemName} {auction.Uuid} ({auction.Enchantments.Count} {relevantAuctions.Count})");
                var itemId = ItemDetails.Instance.GetItemIdForName(auction.Tag, false);
                medianPrice = (long)(await ItemPrices.GetLookupForToday(itemId)).Prices.Average(p => p.Avg * 0.8 + p.Min * 0.2);
            }
            else
            {
                medianPrice = relevantAuctions
                              .OrderByDescending(a => a.HighestBidAmount)
                              .Select(a => a.HighestBidAmount / a.Count)
                              .Skip(relevantAuctions.Count / 2)
                              .FirstOrDefault();
            }



            var recomendedBuyUnder = medianPrice * 0.8;

            if (price > recomendedBuyUnder) // at least 20% profit
            {
                return;                     // not a good flip
            }

            relevantAuctionIds[auction.UId] = relevantAuctions.Select(a => a.UId == 0 ? AuctionService.Instance.GetId(a.Uuid) : a.UId).ToList();
            if (relevantAuctionIds.Count > 10000)
            {
                relevantAuctionIds.Clear();
            }
            var query = new ActiveItemSearchQuery()
            {
                Order  = SortOrder.LOWEST_PRICE,
                Limit  = 1,
                Filter = new Dictionary <string, string>()
                {
                    { "Bin", "true" }
                },
                name = auction.Tag
            };
            var lowestBin = Server.ExecuteCommandWithCache <ActiveItemSearchQuery, List <ItemPrices.AuctionPreview> >("activeAuctions", query);

            var flip = new FlipInstance()
            {
                MedianPrice   = (int)medianPrice,
                Name          = auction.ItemName,
                Uuid          = auction.Uuid,
                LastKnownCost = (int)price,
                Volume        = (float)(relevantAuctions.Count / (DateTime.Now - oldest).TotalDays),
                Tag           = auction.Tag,
                Bin           = auction.Bin,
                UId           = auction.UId,
                SellerName    = await PlayerSearch.Instance.GetNameWithCacheAsync(auction.AuctioneerId),
                LowestBin     = (await lowestBin).FirstOrDefault()?.Price
            };

            FlippFound(flip);
            if (auction.Uuid[0] == 'a') // reduce saves
            {
                await CacheService.Instance.SaveInRedis(FoundFlippsKey, Flipps);
            }
        }