예제 #1
0
        public async Task BuyItemHandler(GameSession session, CBuyItemReqMessage message)
        {
            var shop = GameServer.Instance.ResourceCache.GetShop();
            var plr  = session.Player;

            foreach (var item in message.Items)
            {
                var shopItemInfo = shop.GetItemInfo(item.ItemNumber, item.PriceType);
                if (shopItemInfo == null)
                {
                    Logger.ForAccount(session)
                    .Error("No shop entry found for {item}",
                           new { item.ItemNumber, item.PriceType, item.Period, item.PeriodType });

                    session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem));
                    return;
                }
                if (!shopItemInfo.IsEnabled)
                {
                    Logger.ForAccount(session)
                    .Error("Shop entry is not enabled {item}",
                           new { item.ItemNumber, item.PriceType, item.Period, item.PeriodType });

                    session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem));
                    return;
                }

                var priceGroup = shopItemInfo.PriceGroup;
                var price      = priceGroup.GetPrice(item.PeriodType, item.Period);
                if (price == null)
                {
                    Logger.ForAccount(session)
                    .Error("Invalid price group for shop entry {item}",
                           new { item.ItemNumber, item.PriceType, item.Period, item.PeriodType });

                    session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem));
                    return;
                }

                if (!price.IsEnabled)
                {
                    Logger.ForAccount(session)
                    .Error("Shop entry is not enabled {item}",
                           new { item.ItemNumber, item.PriceType, item.Period, item.PeriodType });

                    session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem));
                    return;
                }

                if (item.Color > shopItemInfo.ShopItem.ColorGroup)
                {
                    Logger.ForAccount(session)
                    .Error("Shop entry has no color {color} {item}",
                           item.Color, new { item.ItemNumber, item.PriceType, item.Period, item.PeriodType });

                    session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem));
                    return;
                }

                if (item.Effect != 0)
                {
                    if (shopItemInfo.EffectGroup.Effects.All(effect => effect.Effect != item.Effect))
                    {
                        Logger.ForAccount(session)
                        .Error("Shop entry has no effect {effect} {item}",
                               item.Effect, new { item.ItemNumber, item.PriceType, item.Period, item.PeriodType });

                        session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem));
                        return;
                    }
                }

                if (shopItemInfo.ShopItem.License != ItemLicense.None &&
                    !plr.LicenseManager.Contains(shopItemInfo.ShopItem.License) &&
                    Config.Instance.Game.EnableLicenseRequirement)
                {
                    Logger.ForAccount(session)
                    .Error("Doesn't have license {license}", shopItemInfo.ShopItem.License);

                    session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem));
                    return;
                }

                // ToDo missing price types
                switch (shopItemInfo.PriceGroup.PriceType)
                {
                case ItemPriceType.PEN:
                    if (plr.PEN < price.Price)
                    {
                        session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.NotEnoughMoney));
                        return;
                    }

                    plr.PEN -= (uint)price.Price;
                    break;

                case ItemPriceType.AP:
                case ItemPriceType.Premium:
                    if (plr.AP < price.Price)
                    {
                        session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.NotEnoughMoney));
                        return;
                    }

                    plr.AP -= (uint)price.Price;
                    break;

                case ItemPriceType.CP:
                {
                    var CP = plr.Inventory.FirstOrDefault(p => p.ItemNumber == 6000001);
                    if (CP == null || CP.Count < price.Price)
                    {
                        session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.NotEnoughMoney));
                        return;
                    }

                    CP.Count -= (uint)price.Price;

                    session.SendAsync(new SInventoryActionAckMessage(InventoryAction.Update, CP.Map <PlayerItem, ItemDto>()));
                }

                break;

                default:
                    Logger.ForAccount(session)
                    .Error("Unknown PriceType {priceType}", shopItemInfo.PriceGroup.PriceType);
                    return;
                }

                // ToDo
                //var purchaseDto = new PlayerPurchaseDto
                //{
                //    account_id = (int)plr.Account.Id,
                //    shop_item_id = item.ItemNumber,
                //    shop_item_info_id = shopItemInfo.Id,
                //    shop_price_id = price.Id,
                //    time = DateTimeOffset.Now.ToUnixTimeSeconds()
                //};
                //db.player_purchase.Add(purchaseDto);

                var plrItem = session.Player.Inventory.Create(shopItemInfo, price, item.Color, item.Effect, (uint)(price.PeriodType == ItemPeriodType.Units ? price.Period : 0));

                await session.SendAsync(new SBuyItemAckMessage(new[] { plrItem.Id }, item));

                await session.SendAsync(new SRefreshCashInfoAckMessage(plr.PEN, plr.AP));
            }
        }
예제 #2
0
        public async Task BuyItemHandler(GameSession session, CBuyItemReqMessage message)
        {
            var shop = GameServer.Instance.ResourceCache.GetShop();
            var plr  = session.Player;

            foreach (var item in message.Items)
            {
                var shopItemInfo = shop.GetItemInfo(item.ItemNumber, item.PriceType);
                if (shopItemInfo == null)
                {
                    _logger.Error()
                    .Account(session)
                    .Message("No shop entry found for {0} {1} {3}{2}", item.ItemNumber, item.PriceType, item.PeriodType, item.Period)
                    .Write();

                    await session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem))
                    .ConfigureAwait(false);

                    return;
                }
                if (!shopItemInfo.IsEnabled)
                {
                    _logger.Error()
                    .Account(session)
                    .Message("No shop entry {0} {1} {3}{2} is not enabled", item.ItemNumber, item.PriceType, item.PeriodType, item.Period)
                    .Write();

                    await session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem))
                    .ConfigureAwait(false);

                    return;
                }

                var priceGroup = shopItemInfo.PriceGroup;
                var price      = priceGroup.GetPrice(item.PeriodType, item.Period);
                if (price == null)
                {
                    _logger.Error()
                    .Account(session)
                    .Message("Invalid price group for shop entry {0} {1} {3}{2}", item.ItemNumber, item.PriceType, item.PeriodType, item.Period)
                    .Write();

                    await session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem))
                    .ConfigureAwait(false);

                    return;
                }
                if (!price.IsEnabled)
                {
                    _logger.Error()
                    .Account(session)
                    .Message("Shop entry {0} {1} {3}{2} is not enabled", item.ItemNumber, item.PriceType, item.PeriodType, item.Period)
                    .Write();

                    await session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem))
                    .ConfigureAwait(false);

                    return;
                }

                if (item.Color > shopItemInfo.ShopItem.ColorGroup)
                {
                    _logger.Error()
                    .Account(session)
                    .Message("Shop entry {0} {1} {3}{2} has no color {4}", item.ItemNumber, item.PriceType, item.PeriodType, item.Period, item.Color)
                    .Write();

                    await session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem))
                    .ConfigureAwait(false);

                    return;
                }

                if (item.Effect != 0)
                {
                    if (shopItemInfo.EffectGroup.Effects.All(effect => effect.Effect != item.Effect))
                    {
                        _logger.Error()
                        .Account(session)
                        .Message("Shop entry {0} {1} {3}{2} has no effect {4}", item.ItemNumber, item.PriceType, item.PeriodType, item.Period, item.Effect)
                        .Write();

                        await session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem))
                        .ConfigureAwait(false);

                        return;
                    }
                }

                if (shopItemInfo.ShopItem.License != ItemLicense.None &&
                    !plr.LicenseManager.Contains(shopItemInfo.ShopItem.License) &&
                    Config.Instance.Game.EnableLicenseRequirement)
                {
                    _logger.Error()
                    .Account(session)
                    .Message("Doesn't have license {0}", shopItemInfo.ShopItem.License)
                    .Write();

                    await session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.UnkownItem))
                    .ConfigureAwait(false);

                    return;
                }

                // ToDo missing price types

                switch (shopItemInfo.PriceGroup.PriceType)
                {
                case ItemPriceType.PEN:
                    if (plr.PEN < price.Price)
                    {
                        await session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.NotEnoughMoney))
                        .ConfigureAwait(false);

                        return;
                    }
                    plr.PEN -= (uint)price.Price;
                    break;

                case ItemPriceType.AP:
                    if (plr.AP < price.Price)
                    {
                        await session.SendAsync(new SBuyItemAckMessage(ItemBuyResult.NotEnoughMoney))
                        .ConfigureAwait(false);

                        return;
                    }
                    plr.AP -= (uint)price.Price;
                    break;

                default:
                    _logger.Error()
                    .Account(session)
                    .Message("Unknown PriceType {0}", shopItemInfo.PriceGroup.PriceType)
                    .Write();
                    return;
                }

                // ToDo
                //var purchaseDto = new PlayerPurchaseDto
                //{
                //    account_id = (int)plr.Account.Id,
                //    shop_item_id = item.ItemNumber,
                //    shop_item_info_id = shopItemInfo.Id,
                //    shop_price_id = price.Id,
                //    time = DateTimeOffset.Now.ToUnixTimeSeconds()
                //};
                //db.player_purchase.Add(purchaseDto);

                var plrItem = session.Player.Inventory.Create(shopItemInfo, price, item.Color, item.Effect, (uint)(price.PeriodType == ItemPeriodType.Units ? price.Period : 0));

                await session.SendAsync(new SBuyItemAckMessage(new[] { plrItem.Id }, item))
                .ConfigureAwait(false);

                await session.SendAsync(new SRefreshCashInfoAckMessage(plr.PEN, plr.AP))
                .ConfigureAwait(false);
            }
        }
예제 #3
0
        public async Task <bool> OnHandle(MessageContext context, CBuyItemReqMessage message)
        {
            var session   = context.GetSession <Session>();
            var plr       = session.Player;
            var plrLogger = plr.AddContextToLogger(_logger);
            var logger    = plrLogger;

            var itemsTobuy = message.Items.GroupBy(x => x);
            var newItems   = new List <PlayerItem>();

            foreach (var group in itemsTobuy)
            {
                logger = plrLogger.ForContext("@ItemToBuy", group.Key);
                var itemToBuy  = group.Key;
                var count      = group.Count();
                var itemInfo   = _gameDataService.Items.GetValueOrDefault(itemToBuy.ItemNumber);
                var hasLicense = !_gameOptions.EnableLicenseRequirement || plr.LicenseManager.Contains(itemInfo.License);

                logger.Debug("Trying to buy item");

                if (itemInfo.License != ItemLicense.None && !hasLicense)
                {
                    logger.Warning("Trying to buy item without required license");
                    session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.UnkownItem));
                    continue;
                }

                if (itemInfo.Level > plr.Level)
                {
                    logger.Warning("Trying to buy item without required level playerLevel={PlayerLevel}", plr.Level);
                    session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.UnkownItem));
                    continue;
                }

                // TODO master level

                var shopItem = _gameDataService.GetShopItem(itemToBuy.ItemNumber);
                if (shopItem == null)
                {
                    logger.Warning("Trying to buy non-existant item");
                    session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.UnkownItem));
                    continue;
                }

                if (itemToBuy.Color > shopItem.ColorGroup)
                {
                    logger.Warning("Trying to buy item with invalid color");
                    session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.UnkownItem));
                    continue;
                }

                var shopItemInfo = shopItem.GetItemInfo(itemToBuy.PriceType);
                if (shopItemInfo == null)
                {
                    logger.Warning("Trying to buy non-existant item");
                    session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.UnkownItem));
                    continue;
                }

                if (!shopItemInfo.IsEnabled)
                {
                    logger.Warning("Trying to buy disabled item");
                    session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.UnkownItem));
                    continue;
                }

                var priceInfo = shopItemInfo.PriceGroup.GetPrice(itemToBuy.PeriodType, itemToBuy.Period);
                if (priceInfo == null)
                {
                    logger.Warning("Trying to buy item with invalid price info");
                    session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.UnkownItem));
                    continue;
                }

                if (!priceInfo.IsEnabled)
                {
                    logger.Warning("Trying to buy item with disabled price info");
                    session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.UnkownItem));
                    continue;
                }

                ShopEffect effectInfo = null;
                if (itemToBuy.Effect != 0)
                {
                    effectInfo = shopItemInfo.EffectGroup.GetEffectByEffect(itemToBuy.Effect);
                }

                var cost = (uint)(priceInfo.Price * count);
                switch (itemToBuy.PriceType)
                {
                case ItemPriceType.PEN:
                    if (plr.PEN < cost)
                    {
                        logger.Warning("Trying to buy item without enough PEN currentPEN={CurrentPEN}", plr.PEN);
                        session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.NotEnoughMoney));
                        return(true);
                    }

                    plr.PEN -= cost;

                    break;

                case ItemPriceType.AP:
                case ItemPriceType.Premium:
                    if (plr.AP < cost)
                    {
                        logger.Warning("Trying to buy item without enough AP currentAP={CurrentAP}", plr.AP);
                        session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.NotEnoughMoney));
                        return(true);
                    }

                    plr.AP -= cost;

                    break;

                // TODO Implement other price types

                default:
                    logger.Warning("Trying to buy item with invalid price type");
                    session.Send(new SBuyItemAckMessage(itemToBuy, ItemBuyResult.DBError));
                    return(true);
                }

                try
                {
                    for (var i = 0; i < count; ++i)
                    {
                        var newItem = plr.Inventory.Create(shopItemInfo, priceInfo, itemToBuy.Color,
                                                           effectInfo?.Effect ?? 0, 0);
                        newItems.Add(newItem);
                    }
                }
                catch (Exception ex)
                {
                    logger.Error(ex, "Unable to create item");
                }

                var newItemIds = newItems.Select(x => x.Id).ToArray();
                session.Send(new SBuyItemAckMessage(newItemIds, itemToBuy));
                newItems.Clear();

                plr.SendMoneyUpdate();
            }

            return(true);
        }