private void LoadShopItem(long owner, KeyValuePair <long, MapShop> shop) { string packetToSend = $"n_inv 1 {owner} 0 0"; for (short i = 0; i < 20; i++) { PersonalShopItem item = shop.Value.Items.Count() > i?shop.Value.Items.ElementAt(i) : null; if (item != null) { if ((item.ItemInstance as ItemInstance).Item.Type == 0) { packetToSend += $" 0.{i}.{item.ItemInstance.ItemVNum}.{item.ItemInstance.Rare}.{item.ItemInstance.Upgrade}.{item.Price}."; } else { packetToSend += $" {(byte)(item.ItemInstance as ItemInstance).Item.Type}.{i}.{item.ItemInstance.ItemVNum}.{item.Amount}.{item.Price}.-1."; } } else { packetToSend += " -1"; } } packetToSend += " -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1"; Session.SendPacket(packetToSend); }
public void CreateShop(string packet) { Logger.Debug(packet, Session.SessionId); string[] packetsplit = packet.Split(' '); InventoryType[] type = new InventoryType[20]; long[] gold = new long[20]; short[] slot = new short[20]; byte[] qty = new byte[20]; short typePacket; string shopname = String.Empty; if (packetsplit.Length > 2) { short.TryParse(packetsplit[2], out typePacket); if (Session.Character.InExchangeOrTrade && typePacket != 1) { return; } foreach (PortalDTO por in Session.CurrentMap.Portals) { if (Session.Character.MapX < por.SourceX + 6 && Session.Character.MapX > por.SourceX - 6 && Session.Character.MapY < por.SourceY + 6 && Session.Character.MapY > por.SourceY - 6) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SHOP_NEAR_PORTAL"), 0)); return; } } if (!Session.CurrentMap.ShopAllowed) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SHOP_NOT_ALLOWED"), 0)); return; } if (typePacket == 2) { Session.SendPacket("ishop"); } else if (typePacket == 0) { if (Session.CurrentMap.UserShops.Where(s => s.Value.OwnerId == Session.Character.CharacterId).Count() != 0) { return; } MapShop myShop = new MapShop(); if (packetsplit.Length > 82) { for (short j = 3, i = 0; j < 82; j += 4, i++) { Enum.TryParse <InventoryType>(packetsplit[j], out type[i]); short.TryParse(packetsplit[j + 1], out slot[i]); byte.TryParse(packetsplit[j + 2], out qty[i]); long.TryParse(packetsplit[j + 3], out gold[i]); if (gold[i] < 0) { return; } if (qty[i] > 0) { Inventory inv = Session.Character.InventoryList.LoadInventoryBySlotAndType(slot[i], type[i]); if (inv.ItemInstance.Amount < qty[i]) { return; } if (!((ItemInstance)inv.ItemInstance).Item.IsTradable || ((ItemInstance)inv.ItemInstance).IsBound) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SHOP_ONLY_TRADABLE_ITEMS"), 0)); Session.SendPacket("shop_end 0"); return; } PersonalShopItem personalshopitem = new PersonalShopItem() { Slot = slot[i], Type = type[i], Price = gold[i], Id = inv.Id, CharacterId = inv.CharacterId, Amount = qty[i], ItemInstance = inv.ItemInstance }; myShop.Items.Add(personalshopitem); } } } if (myShop.Items.Count != 0) { if (!myShop.Items.Any(s => !(s.ItemInstance as ItemInstance).Item.IsSoldable || (s.ItemInstance as ItemInstance).IsBound)) { for (int i = 83; i < packetsplit.Length; i++) { shopname += $"{packetsplit[i]} "; } // trim shopname shopname.TrimEnd(' '); // create default shopname if it's empty if (String.IsNullOrWhiteSpace(shopname) || String.IsNullOrEmpty(shopname)) { shopname = Language.Instance.GetMessageFromKey("SHOP_PRIVATE_SHOP"); } // truncate the string to a max-length of 20 shopname = StringHelper.Truncate(shopname, 20); myShop.OwnerId = Session.Character.CharacterId; myShop.Name = shopname; Session.CurrentMap.UserShops.Add(Session.CurrentMap.UserShops.Count(), myShop); Session.Character.HasShopOpened = true; Session.CurrentMap?.Broadcast(Session, Session.Character.GeneratePlayerFlag(Session.CurrentMap.UserShops.Count()), ReceiverType.AllExceptMe); Session.CurrentMap?.Broadcast(Session.Character.GenerateShop(shopname)); Session.SendPacket(Session.Character.GenerateInfo(Language.Instance.GetMessageFromKey("SHOP_OPEN"))); Session.Character.IsSitting = true; Session.Character.IsShopping = true; Session.Character.LoadSpeed(); Session.SendPacket(Session.Character.GenerateCond()); Session.CurrentMap?.Broadcast(Session.Character.GenerateRest()); } else { Session.SendPacket("shop_end 0"); Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ITEM_NOT_SOLDABLE"), 10)); } } else { Session.SendPacket("shop_end 0"); Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("SHOP_EMPTY"), 10)); } } else if (typePacket == 1) { KeyValuePair <long, MapShop> shop = Session.CurrentMap.UserShops.FirstOrDefault(mapshop => mapshop.Value.OwnerId.Equals(Session.Character.CharacterId)); Session.CurrentMap.UserShops.Remove(shop.Key); Session.CurrentMap?.Broadcast(Session.Character.GenerateShopEnd()); Session.CurrentMap?.Broadcast(Session, Session.Character.GeneratePlayerFlag(0), ReceiverType.AllExceptMe); Session.Character.IsShopping = false; Session.Character.IsSitting = false; Session.Character.LoadSpeed(); Session.SendPacket(Session.Character.GenerateCond()); Session.CurrentMap?.Broadcast(Session.Character.GenerateRest()); } } }
public void BuyShop(string packet) { if (Session.Character.InExchangeOrTrade) { return; } Logger.Debug(packet, Session.SessionId); string[] packetsplit = packet.Split(' '); long owner; byte type; short slot; Random random = new Random(); if (packetsplit.Length < 5) { return; } byte amount = 0; long.TryParse(packetsplit[3], out owner); byte.TryParse(packetsplit[2], out type); short.TryParse(packetsplit[4], out slot); if (packetsplit.Length == 6) { byte.TryParse(packetsplit[5], out amount); } if (type == 1) { // User shop KeyValuePair <long, MapShop> shop = Session.CurrentMap.UserShops.FirstOrDefault(mapshop => mapshop.Value.OwnerId.Equals(owner)); PersonalShopItem item = shop.Value.Items.FirstOrDefault(i => i.Slot.Equals(slot)); if (item == null || amount <= 0) { return; } if (amount > item.Amount) { amount = item.Amount; } if (item.Price * amount + ServerManager.Instance.GetProperty <long>(shop.Value.OwnerId, nameof(Character.Gold)) > 1000000000) { Session.SendPacket(Session.Character.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("MAX_GOLD"))); return; } if (item.Price * amount >= Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"))); return; } ItemInstance item2 = (item.ItemInstance as ItemInstance).DeepCopy(); item2.Amount = amount; item2.Id = Guid.NewGuid(); // this is necessary due the deepcopy would cause duplicate GUID Inventory inv = Session.Character.InventoryList.AddToInventory(item2); if (inv != null) { Session.SendPacket(Session.Character.GenerateInventoryAdd(inv.ItemInstance.ItemVNum, inv.ItemInstance.Amount, inv.Type, inv.Slot, inv.ItemInstance.Rare, inv.ItemInstance.Design, inv.ItemInstance.Upgrade, 0)); Session.Character.Gold -= item.Price * amount; Session.SendPacket(Session.Character.GenerateGold()); ServerManager.Instance.BuyValidate(Session, shop, slot, amount); KeyValuePair <long, MapShop> shop2 = Session.CurrentMap.UserShops.FirstOrDefault(s => s.Value.OwnerId.Equals(owner)); LoadShopItem(owner, shop2); } else { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_PLACE"), 0)); } } else if (packetsplit.Length == 5) { // skill shop if (Session.Character.UseSp) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("REMOVE_SP"), 0)); return; } Skill skillinfo = ServerManager.GetSkill(slot); if (Session.Character.Skills.Any(s => s.SkillVNum == slot)) { return; } if (skillinfo == null) { return; } if (Session.Character.Gold < skillinfo.Price) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 0)); return; } else if (Session.Character.GetCP() < skillinfo.CPCost) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_CP"), 0)); } else { if (skillinfo.SkillVNum < 200) { int SkillMiniumLevel = 0; if (skillinfo.MinimumSwordmanLevel == 0 && skillinfo.MinimumArcherLevel == 0 && skillinfo.MinimumMagicianLevel == 0) { SkillMiniumLevel = skillinfo.MinimumAdventurerLevel; } else { switch (Session.Character.Class) { case (byte)ClassType.Adventurer: SkillMiniumLevel = skillinfo.MinimumAdventurerLevel; break; case (byte)ClassType.Swordman: SkillMiniumLevel = skillinfo.MinimumSwordmanLevel; break; case (byte)ClassType.Archer: SkillMiniumLevel = skillinfo.MinimumArcherLevel; break; case (byte)ClassType.Magician: SkillMiniumLevel = skillinfo.MinimumMagicianLevel; break; } } if (SkillMiniumLevel == 0) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SKILL_CANT_LEARN"), 0)); return; } else if (Session.Character.Level < SkillMiniumLevel) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("LOW_LVL"), 0)); return; } for (int i = Session.Character.Skills.Count - 1; i >= 0; i--) { if ((skillinfo.CastId == Session.Character.Skills[i].Skill.CastId) && (Session.Character.Skills[i].Skill.SkillVNum < 200)) { Session.Character.Skills.Remove(Session.Character.Skills[i]); } } } else { if (Session.Character.Class != skillinfo.Class) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SKILL_CANT_LEARN"), 0)); return; } else if (Session.Character.JobLevel < skillinfo.LevelMinimum) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("LOW_JOB_LVL"), 0)); return; } if (skillinfo.UpgradeSkill != 0) { CharacterSkill oldupgrade = Session.Character.Skills.FirstOrDefault(s => s.Skill.UpgradeSkill == skillinfo.UpgradeSkill && s.Skill.UpgradeType == skillinfo.UpgradeType && s.Skill.UpgradeSkill != 0); if (oldupgrade != null) { Session.Character.Skills.Remove(oldupgrade); } } } Session.Character.Skills.Add(new CharacterSkill() { SkillVNum = slot, CharacterId = Session.Character.CharacterId }); Session.Character.Gold -= skillinfo.Price; Session.SendPacket(Session.Character.GenerateGold()); Session.SendPacket(Session.Character.GenerateSki()); Session.SendPackets(Session.Character.GenerateQuicklist()); Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SKILL_LEARNED"), 0)); Session.SendPacket(Session.Character.GenerateLev()); } } else { MapNpc npc = Session.CurrentMap.Npcs.FirstOrDefault(n => n.MapNpcId.Equals((short)owner)); ShopItemDTO item = npc?.Shop.ShopItems.FirstOrDefault(it => it.Slot == slot); if (item == null) { return; } Item iteminfo = ServerManager.GetItem(item.ItemVNum); long price = iteminfo.Price * amount; long Reputprice = iteminfo.ReputPrice * amount; double percent = 1; if (Session.Character.GetDignityIco() == 3) { percent = 1.10; } else if (Session.Character.GetDignityIco() == 4) { percent = 1.20; } else if (Session.Character.GetDignityIco() == 5 || Session.Character.GetDignityIco() == 6) { percent = 1.5; } sbyte rare = item.Rare; if (iteminfo.Type == 0) { amount = 1; } if (iteminfo.ReputPrice == 0) { if (price < 0 || price * percent > Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"))); return; } } else { if (Reputprice <= 0 || Reputprice > Session.Character.Reput) { Session.SendPacket(Session.Character.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_REPUT"))); return; } byte ra = (byte)random.Next(0, 100); int[] rareprob = { 100, 100, 70, 50, 30, 15, 5, 1 }; if (iteminfo.ReputPrice != 0) { for (int i = 0; i < rareprob.Length; i++) { if (ra <= rareprob[i]) { rare = (sbyte)i; } } } } Inventory newItem = Session.Character.InventoryList.AddNewItemToInventory(item.ItemVNum, amount); if (newItem == null) { return; } newItem.ItemInstance.Rare = rare; newItem.ItemInstance.Upgrade = item.Upgrade; newItem.ItemInstance.Design = item.Color; if (newItem != null && newItem.Slot != -1) { Session.SendPacket(Session.Character.GenerateInventoryAdd(newItem.ItemInstance.ItemVNum, newItem.ItemInstance.Amount, newItem.Type, newItem.Slot, newItem.ItemInstance.Rare, newItem.ItemInstance.Design, newItem.ItemInstance.Upgrade, 0)); if (iteminfo.ReputPrice == 0) { Session.SendPacket(Session.Character.GenerateShopMemo(1, string.Format(Language.Instance.GetMessageFromKey("BUY_ITEM_VALID"), iteminfo.Name, amount))); Session.Character.Gold -= (long)(price * percent); Session.SendPacket(Session.Character.GenerateGold()); } else { Session.SendPacket(Session.Character.GenerateShopMemo(1, string.Format(Language.Instance.GetMessageFromKey("BUY_ITEM_VALID"), iteminfo.Name, amount))); Session.Character.Reput -= Reputprice; Session.SendPacket(Session.Character.GenerateFd()); Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("REPUT_DECREASED"), 11)); } } else { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_PLACE"), 0)); } } }
public void BuyShop(BuyPacket buyPacket) { if (Session.Character.InExchangeOrTrade) { return; } Logger.Debug(buyPacket.ToString(), Session.SessionId); Random random = new Random(); byte amount = buyPacket.Amount; switch (buyPacket.Type) { case BuyShopType.CharacterShop: { // User shop KeyValuePair <long, MapShop> shop = Session.CurrentMap.UserShops.FirstOrDefault(mapshop => mapshop.Value.OwnerId.Equals(buyPacket.OwnerId)); PersonalShopItem item = shop.Value.Items.FirstOrDefault(i => i.ShopSlot.Equals(buyPacket.Slot)); if (item == null || amount <= 0 || amount > 99) { return; } if (amount > item.SellAmount) { amount = item.SellAmount; } if (item.Price * amount + ServerManager.Instance.GetProperty <long>(shop.Value.OwnerId, nameof(Character.Gold)) > 1000000000) { Session.SendPacket(Session.Character.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("MAX_GOLD"))); return; } if (item.Price * amount >= Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"))); return; } // check if the item has been removed successfully from previous owner and remove it if (BuyValidate(Session, shop, buyPacket.Slot, amount)) { ItemInstance inv = item.ItemInstance.Type == InventoryType.Equipment ? Session.Character.Inventory.AddToInventory(item.ItemInstance) : Session.Character.Inventory.AddNewToInventory(item.ItemInstance.ItemVNum, amount, item.ItemInstance.Type); if (inv != null) { Session.SendPacket(Session.Character.GenerateInventoryAdd(inv.ItemVNum, inv.Amount, inv.Type, inv.Slot, inv.Rare, inv.Design, inv.Upgrade, 0)); Session.Character.Gold -= item.Price * amount; Session.SendPacket(Session.Character.GenerateGold()); KeyValuePair <long, MapShop> shop2 = Session.CurrentMap.UserShops.FirstOrDefault(s => s.Value.OwnerId.Equals(buyPacket.OwnerId)); LoadShopItem(buyPacket.OwnerId, shop2); } else { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_PLACE"), 0)); } } break; } case BuyShopType.ItemShop: { // load shop MapNpc npc = Session.CurrentMap.Npcs.FirstOrDefault(n => n.MapNpcId.Equals((short)buyPacket.OwnerId)); int dist = Map.GetDistance(new MapCell() { MapId = Session.CurrentMap.MapId, X = Session.Character.MapX, Y = Session.Character.MapY }, new MapCell() { MapId = npc.MapId, X = npc.MapX, Y = npc.MapY }); if (npc == null || npc.Shop == null || dist > 5) { return; } if (npc.Shop.ShopSkills.Any()) { // skill shop if (Session.Character.UseSp) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("REMOVE_SP"), 0)); return; } Skill skillinfo = ServerManager.GetSkill(buyPacket.Slot); if (Session.Character.Skills.GetAllItems().Any(s => s.SkillVNum == buyPacket.Slot) || skillinfo == null) { return; } if (Session.Character.Gold < skillinfo.Price) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 0)); return; } else if (Session.Character.GetCP() < skillinfo.CPCost) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_CP"), 0)); } else { if (skillinfo.SkillVNum < 200) { int SkillMiniumLevel = 0; if (skillinfo.MinimumSwordmanLevel == 0 && skillinfo.MinimumArcherLevel == 0 && skillinfo.MinimumMagicianLevel == 0) { SkillMiniumLevel = skillinfo.MinimumAdventurerLevel; } else { switch (Session.Character.Class) { case ClassType.Adventurer: SkillMiniumLevel = skillinfo.MinimumAdventurerLevel; break; case ClassType.Swordman: SkillMiniumLevel = skillinfo.MinimumSwordmanLevel; break; case ClassType.Archer: SkillMiniumLevel = skillinfo.MinimumArcherLevel; break; case ClassType.Magician: SkillMiniumLevel = skillinfo.MinimumMagicianLevel; break; } } if (SkillMiniumLevel == 0) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SKILL_CANT_LEARN"), 0)); return; } else if (Session.Character.Level < SkillMiniumLevel) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("LOW_LVL"), 0)); return; } foreach (var skill in Session.Character.Skills.GetAllItems()) { if ((skillinfo.CastId == skill.Skill.CastId) && skill.Skill.SkillVNum < 200) { Session.Character.Skills.Remove(skill.SkillVNum); } } } else { if ((byte)Session.Character.Class != skillinfo.Class) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SKILL_CANT_LEARN"), 0)); return; } else if (Session.Character.JobLevel < skillinfo.LevelMinimum) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("LOW_JOB_LVL"), 0)); return; } if (skillinfo.UpgradeSkill != 0) { CharacterSkill oldupgrade = Session.Character.Skills.GetAllItems().FirstOrDefault(s => s.Skill.UpgradeSkill == skillinfo.UpgradeSkill && s.Skill.UpgradeType == skillinfo.UpgradeType && s.Skill.UpgradeSkill != 0); if (oldupgrade != null) { Session.Character.Skills.Remove(oldupgrade.SkillVNum); } } } Session.Character.Skills[buyPacket.Slot] = new CharacterSkill() { SkillVNum = buyPacket.Slot, CharacterId = Session.Character.CharacterId }; Session.Character.Gold -= skillinfo.Price; Session.SendPacket(Session.Character.GenerateGold()); Session.SendPacket(Session.Character.GenerateSki()); Session.SendPackets(Session.Character.GenerateQuicklist()); Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SKILL_LEARNED"), 0)); Session.SendPacket(Session.Character.GenerateLev()); } } else if (npc.Shop.ShopItems.Any()) { // npc shop ShopItemDTO item = npc?.Shop.ShopItems.FirstOrDefault(it => it.Slot == buyPacket.Slot); if (item == null || amount <= 0 || amount > 99) { return; } Item iteminfo = ServerManager.GetItem(item.ItemVNum); long price = iteminfo.Price * amount; long Reputprice = iteminfo.ReputPrice * amount; double percent = 1; if (Session.Character.GetDignityIco() == 3) { percent = 1.10; } else if (Session.Character.GetDignityIco() == 4) { percent = 1.20; } else if (Session.Character.GetDignityIco() == 5 || Session.Character.GetDignityIco() == 6) { percent = 1.5; } sbyte rare = item.Rare; if (iteminfo.Type == 0) { amount = 1; } if (iteminfo.ReputPrice == 0) { if (price < 0 || price * percent > Session.Character.Gold) { Session.SendPacket(Session.Character.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"))); return; } } else { if (Reputprice <= 0 || Reputprice > Session.Character.Reput) { Session.SendPacket(Session.Character.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_REPUT"))); return; } byte ra = (byte)random.Next(0, 100); int[] rareprob = { 100, 100, 70, 50, 30, 15, 5, 1 }; if (iteminfo.ReputPrice != 0) { for (int i = 0; i < rareprob.Length; i++) { if (ra <= rareprob[i]) { rare = (sbyte)i; } } } } ItemInstance newItem = Session.Character.Inventory.AddNewToInventory(item.ItemVNum, amount); if (newItem == null) { return; } newItem.Rare = rare; newItem.Upgrade = item.Upgrade; newItem.Design = item.Color; if (newItem != null && newItem.Slot != -1) { Session.SendPacket(Session.Character.GenerateInventoryAdd(newItem.ItemVNum, newItem.Amount, newItem.Type, newItem.Slot, newItem.Rare, newItem.Design, newItem.Upgrade, 0)); if (iteminfo.ReputPrice == 0) { Session.SendPacket(Session.Character.GenerateShopMemo(1, String.Format(Language.Instance.GetMessageFromKey("BUY_ITEM_VALID"), iteminfo.Name, amount))); Session.Character.Gold -= (long)(price * percent); Session.SendPacket(Session.Character.GenerateGold()); } else { Session.SendPacket(Session.Character.GenerateShopMemo(1, String.Format(Language.Instance.GetMessageFromKey("BUY_ITEM_VALID"), iteminfo.Name, amount))); Session.Character.Reput -= Reputprice; Session.SendPacket(Session.Character.GenerateFd()); Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("REPUT_DECREASED"), 11)); } } else { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_PLACE"), 0)); } } break; } } }
private void ExecuteHandler(ClientSession session) { if (session.Character.InExchangeOrTrade) { return; } switch (Type) { case BuyShopType.CharacterShop: if (!session.HasCurrentMapInstance) { return; } KeyValuePair <long, MapShop> shop = session.CurrentMapInstance.UserShops.FirstOrDefault(mapshop => mapshop.Value.OwnerId.Equals(OwnerId)); PersonalShopItem item = shop.Value?.Items.Find(i => i.ShopSlot.Equals(Slot)); ClientSession sess = ServerManager.Instance.GetSessionByCharacterId(shop.Value?.OwnerId ?? 0); if (sess == null || item == null || Amount <= 0 || Amount > 999) { return; } GameLogger.Instance.LogItemBuyPlayerShop(ServerManager.Instance.ChannelId, session.Character.Name, session.Character.CharacterId, sess.Character.Name, OwnerId, item.ItemInstance, Amount, item.Price, session.CurrentMapInstance.Map.MapId, session.Character.PositionX, session.Character.PositionY); if (Amount > item.SellAmount) { Amount = item.SellAmount; } if ((item.Price * Amount) + sess.Character.Gold > ServerManager.Instance.Configuration.MaxGold) { session.SendPacket(UserInterfaceHelper.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("MAX_GOLD"))); return; } if (item.Price * Amount >= session.Character.Gold) { session.SendPacket(UserInterfaceHelper.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"))); return; } // check if the item has been removed successfully from previous owner and remove it if (session.BuyValidate(shop, Slot, Amount)) { session.Character.Gold -= item.Price * Amount; session.SendPacket(session.Character.GenerateGold()); KeyValuePair <long, MapShop> shop2 = session.CurrentMapInstance.UserShops.FirstOrDefault(s => s.Value.OwnerId.Equals(OwnerId)); session.LoadShopItem(OwnerId, shop2); } else { session.SendPacket( UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_PLACE"), 0)); } break; case BuyShopType.ItemShop: if (!session.HasCurrentMapInstance) { return; } MapNpc npc = session.CurrentMapInstance.Npcs.Find(n => n.MapNpcId.Equals((short)OwnerId)); if (npc != null) { int dist = Map.GetDistance( new MapCell { X = session.Character.PositionX, Y = session.Character.PositionY }, new MapCell { X = npc.MapX, Y = npc.MapY }); if (npc.Shop == null || dist > 5) { return; } if (npc.Shop.ShopSkills.Count > 0) { if (!npc.Shop.ShopSkills.Exists(s => s.SkillVNum == Slot)) { return; } // skill shop if (session.Character.UseSp) { session.SendPacket( UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("REMOVE_SP"), 0)); return; } if (session.Character.Skills.Any(s => s.LastUse.AddMilliseconds(s.Skill.Cooldown * 100) > DateTime.UtcNow)) { session.SendPacket( UserInterfaceHelper.GenerateMsg( Language.Instance.GetMessageFromKey("SKILL_NEED_COOLDOWN"), 0)); return; } Skill skillinfo = ServerManager.GetSkill(Slot); if (session.Character.Skills.Any(s => s.SkillVNum == Slot) || skillinfo == null) { return; } GameLogger.Instance.LogSkillBuy(ServerManager.Instance.ChannelId, session.Character.Name, session.Character.CharacterId, npc.MapNpcId, skillinfo.SkillVNum, skillinfo.Price, session.CurrentMapInstance.Map.MapId, session.Character.PositionX, session.Character.PositionY); if (session.Character.Gold < skillinfo.Price) { session.SendPacket( UserInterfaceHelper.GenerateMsg( Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 0)); } else if (session.Character.GetCP() < skillinfo.CPCost) { session.SendPacket( UserInterfaceHelper.GenerateMsg( Language.Instance.GetMessageFromKey("NOT_ENOUGH_CP"), 0)); } else { if (skillinfo.SkillVNum < 200) { int skillMiniumLevel = 0; if (skillinfo.MinimumSwordmanLevel == 0 && skillinfo.MinimumArcherLevel == 0 && skillinfo.MinimumMagicianLevel == 0) { skillMiniumLevel = skillinfo.MinimumAdventurerLevel; } else { switch (session.Character.Class) { case ClassType.Adventurer: skillMiniumLevel = skillinfo.MinimumAdventurerLevel; break; case ClassType.Swordman: skillMiniumLevel = skillinfo.MinimumSwordmanLevel; break; case ClassType.Archer: skillMiniumLevel = skillinfo.MinimumArcherLevel; break; case ClassType.Magician: skillMiniumLevel = skillinfo.MinimumMagicianLevel; break; } } if (skillMiniumLevel == 0) { session.SendPacket(UserInterfaceHelper.GenerateMsg( Language.Instance.GetMessageFromKey("SKILL_CANT_LEARN"), 0)); return; } if (session.Character.Level < skillMiniumLevel) { session.SendPacket( UserInterfaceHelper.GenerateMsg( Language.Instance.GetMessageFromKey("LOW_LVL"), 0)); return; } foreach (CharacterSkill skill in session.Character.Skills.GetAllItems()) { if (skillinfo.CastId == skill.Skill.CastId && skill.Skill.SkillVNum < 200) { session.Character.Skills.Remove(skill.SkillVNum); } } } else { if ((byte)session.Character.Class != skillinfo.Class) { session.SendPacket(UserInterfaceHelper.GenerateMsg( Language.Instance.GetMessageFromKey("SKILL_CANT_LEARN"), 0)); return; } if (session.Character.JobLevel < skillinfo.LevelMinimum) { session.SendPacket( UserInterfaceHelper.GenerateMsg( Language.Instance.GetMessageFromKey("LOW_JOB_LVL"), 0)); return; } if (skillinfo.UpgradeSkill != 0) { CharacterSkill oldupgrade = session.Character.Skills.FirstOrDefault(s => s.Skill.UpgradeSkill == skillinfo.UpgradeSkill && s.Skill.UpgradeType == skillinfo.UpgradeType && s.Skill.UpgradeSkill != 0); if (oldupgrade != null) { session.Character.Skills.Remove(oldupgrade.SkillVNum); } } } session.Character.Skills[Slot] = new CharacterSkill { SkillVNum = Slot, CharacterId = session.Character.CharacterId }; session.Character.Gold -= skillinfo.Price; session.SendPacket(session.Character.GenerateGold()); session.SendPacket(session.Character.GenerateSki()); session.SendPackets(session.Character.GenerateQuicklist()); session.SendPacket( UserInterfaceHelper.GenerateMsg( Language.Instance.GetMessageFromKey("SKILL_LEARNED"), 0)); session.Character.LoadPassiveSkills(); session.SendPacket(session.Character.GenerateLev()); } } else if (npc.Shop.ShopItems.Count > 0) { // npc shop ShopItemDTO shopItem = npc.Shop.ShopItems.Find(it => it.Slot == Slot); if (shopItem == null || Amount <= 0 || Amount > 999) { return; } Item iteminfo = ServerManager.GetItem(shopItem.ItemVNum); long price = iteminfo.Price * Amount; long reputprice = iteminfo.ReputPrice * Amount; double percent; switch (session.Character.GetDignityIco()) { case 3: percent = 1.10; break; case 4: percent = 1.20; break; case 5: case 6: percent = 1.5; break; default: percent = 1; break; } GameLogger.Instance.LogItemBuyNpcShop(ServerManager.Instance.ChannelId, session.Character.Name, session.Character.CharacterId, npc.MapNpcId, iteminfo.VNum, Amount, (long)(price * percent), session.CurrentMapInstance.Map.MapId, session.Character.PositionX, session.Character.PositionY); sbyte rare = shopItem.Rare; if (iteminfo.Type == 0) { Amount = 1; } if (iteminfo.ReputPrice == 0) { if (price < 0 || price * percent > session.Character.Gold) { session.SendPacket(UserInterfaceHelper.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"))); return; } } else { if (reputprice <= 0 || reputprice > session.Character.Reputation) { session.SendPacket(UserInterfaceHelper.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_REPUT"))); return; } byte ra = (byte)ServerManager.RandomNumber(); int[] rareprob = { 100, 100, 70, 50, 30, 15, 5, 1 }; if (iteminfo.ReputPrice != 0) { for (int i = 0; i < rareprob.Length; i++) { if (ra <= rareprob[i]) { rare = (sbyte)i; } } } } List <ItemInstance> newItems = session.Character.Inventory.AddNewToInventory( shopItem.ItemVNum, Amount, rare: rare, upgrade: shopItem.Upgrade, design: shopItem.Color); if (newItems.Count == 0) { session.SendPacket(UserInterfaceHelper.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_PLACE"))); return; } if (newItems.Count > 0) { foreach (ItemInstance itemInst in newItems) { switch (itemInst.Item.EquipmentSlot) { case EquipmentType.Armor: case EquipmentType.MainWeapon: case EquipmentType.SecondaryWeapon: bool isPartner = (itemInst.ItemVNum >= 990 && itemInst.ItemVNum <= 992) || (itemInst.ItemVNum >= 995 && itemInst.ItemVNum <= 997); itemInst.SetRarityPoint(isPartner); break; case EquipmentType.Boots: case EquipmentType.Gloves: itemInst.FireResistance = (short)(itemInst.Item.FireResistance * shopItem.Upgrade); itemInst.DarkResistance = (short)(itemInst.Item.DarkResistance * shopItem.Upgrade); itemInst.LightResistance = (short)(itemInst.Item.LightResistance * shopItem.Upgrade); itemInst.WaterResistance = (short)(itemInst.Item.WaterResistance * shopItem.Upgrade); break; } } if (iteminfo.ReputPrice == 0) { session.SendPacket(UserInterfaceHelper.GenerateShopMemo(1, string.Format(Language.Instance.GetMessageFromKey("BUY_ITEM_VALID"), iteminfo.Name, Amount))); session.Character.Gold -= (long)(price * percent); session.SendPacket(session.Character.GenerateGold()); } else { session.SendPacket(UserInterfaceHelper.GenerateShopMemo(1, string.Format(Language.Instance.GetMessageFromKey("BUY_ITEM_VALID"), iteminfo.Name, Amount))); session.Character.Reputation -= reputprice; session.SendPacket(session.Character.GenerateFd()); session.SendPacket( session.Character.GenerateSay( Language.Instance.GetMessageFromKey("REPUT_DECREASED"), 11)); } } else { session.SendPacket( UserInterfaceHelper.GenerateMsg( Language.Instance.GetMessageFromKey("NOT_ENOUGH_PLACE"), 0)); } } } break; } }
private void ExecuteHandler(ClientSession session) { bool isNpcShopItem = false; ItemInstance inventory = null; switch (Type) { case 0: inventory = session.Character.Inventory.LoadBySlotAndType(Slot, InventoryType.Wear); break; case 1: inventory = session.Character.Inventory.LoadBySlotAndType(Slot, InventoryType.Equipment); break; case 2: isNpcShopItem = true; if (ServerManager.GetItem(Slot) != null) { inventory = new ItemInstance(Slot, 1); break; } return; case 5: if (session.Character.ExchangeInfo != null) { ClientSession sess = ServerManager.Instance.GetSessionByCharacterId(session.Character.ExchangeInfo .TargetCharacterId); if (sess?.Character.ExchangeInfo?.ExchangeList?.ElementAtOrDefault(Slot) != null) { Guid id = sess.Character.ExchangeInfo.ExchangeList[Slot].Id; inventory = sess.Character.Inventory.GetItemInstanceById(id); } } break; case 6: if (ShopOwnerId.HasValue) { KeyValuePair <long, MapShop> shop = session.CurrentMapInstance.UserShops.FirstOrDefault(mapshop => mapshop.Value.OwnerId.Equals(ShopOwnerId.Value)); PersonalShopItem item = shop.Value?.Items.Find(i => i.ShopSlot.Equals(Slot)); if (item != null) { inventory = item.ItemInstance; } } break; case 7: if (!PartnerSlot.HasValue) { break; } if (Slot >= 1 && Slot <= 12) { inventory = session.Character.Inventory.LoadBySlotAndType((short)PartnerSlot.Value, (InventoryType)(Slot + 12)); } break; case 10: inventory = session.Character.Inventory.LoadBySlotAndType(Slot, InventoryType.Specialist); break; case 11: inventory = session.Character.Inventory.LoadBySlotAndType(Slot, InventoryType.Costume); break; } if (inventory?.Item != null) { if (inventory.IsEmpty || isNpcShopItem) { session.SendPacket(inventory.GenerateEInfo()); return; } session.SendPacket(inventory.Item.EquipmentSlot != EquipmentType.Sp ? inventory.GenerateEInfo() : inventory.Item.SpType == 0 && inventory.Item.ItemSubType == 4 ? inventory.GeneratePslInfo() : inventory.GenerateSlInfo()); } }
private bool BuyValidate(ClientSession clientSession, KeyValuePair <long, MapShop> shop, short slot, byte amount) { PersonalShopItem shopitem = clientSession.CurrentMap.UserShops[shop.Key].Items.FirstOrDefault(i => i.ShopSlot.Equals(slot)); if (shopitem == null) { return(false); } Guid id = shopitem.ItemInstance.Id; ClientSession shopOwnerSession = ServerManager.Instance.GetSessionByCharacterId(shop.Value.OwnerId); if (shopOwnerSession == null) { return(false); } if (amount > shopitem.SellAmount) { amount = shopitem.SellAmount; } shopOwnerSession.Character.Gold += shopitem.Price * amount; shopOwnerSession.SendPacket(shopOwnerSession.Character.GenerateGold()); shopOwnerSession.SendPacket(shopOwnerSession.Character.GenerateShopMemo(1, String.Format(Language.Instance.GetMessageFromKey("BUY_ITEM"), Session.Character.Name, shopitem.ItemInstance.Item.Name, amount))); clientSession.CurrentMap.UserShops[shop.Key].Sell += shopitem.Price * amount; if (shopitem.ItemInstance.Type != InventoryType.Equipment) { // remove sold amount of items shopOwnerSession.Character.Inventory.RemoveItemAmountFromInventory(amount, id); // remove sold amount from sellamount shopitem.SellAmount -= amount; } else { // remove equipment shopOwnerSession.Character.Inventory.Remove(shopitem.ItemInstance.Id); // send empty slot to owners inventory shopOwnerSession.SendPacket(shopOwnerSession.Character.GenerateInventoryAdd(-1, 0, shopitem.ItemInstance.Type, shopitem.ItemInstance.Slot, 0, 0, 0, 0)); // remove the sell amount shopitem.SellAmount = 0; } // remove item from shop if the amount the user wanted to sell has been sold if (shopitem.SellAmount == 0) { clientSession.CurrentMap.UserShops[shop.Key].Items.Remove(shopitem); } // update currently sold item shopOwnerSession.SendPacket($"sell_list {shop.Value.Sell} {slot}.{amount}.{shopitem.SellAmount}"); // end shop if (!clientSession.CurrentMap.UserShops[shop.Key].Items.Any(s => s.SellAmount > 0)) { shopOwnerSession.Character.CloseShop(); } return(true); }
private static ShopPlayerShopCreateEvent ParseMShopPacket(string data, IPlayerEntity player) { var tmp = new ShopPlayerShopCreateEvent { ShopItems = new List <PersonalShopItem>() }; string[] packetsplit = data.Split(' '); InventoryType[] type = new InventoryType[20]; long[] gold = new long[20]; short[] slot = new short[20]; byte[] qty = new byte[20]; string shopname = string.Empty; short shopSlot = 0; if (packetsplit.Length > 79) { for (short j = 0, i = 0; j < 79; j += 4, i++) { Enum.TryParse(packetsplit[j], out type[i]); short.TryParse(packetsplit[j + 1], out slot[i]); byte.TryParse(packetsplit[j + 2], out qty[i]); long.TryParse(packetsplit[j + 3], out gold[i]); if (gold[i] < 0) { // should not input unsigned amount return(null); } if (qty[i] <= 0) { continue; } ItemInstanceDto itemFromSlotAndType = player.Inventory.GetItemFromSlotAndType(slot[i], type[i]); if (itemFromSlotAndType == null) { continue; } if (itemFromSlotAndType.Amount < qty[i]) { return(null); } if (!itemFromSlotAndType.Item.IsTradable || itemFromSlotAndType.BoundCharacterId.HasValue) { // await session.SendPacketAsync(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("SHOP_ONLY_TRADABLE_ITEMS"), 10)); return(null); } var personalshopitem = new PersonalShopItem { Slot = shopSlot++, Price = gold[i], ItemInstance = itemFromSlotAndType, Quantity = qty[i] }; tmp.ShopItems.Add(personalshopitem); } } for (int i = 80; i < packetsplit.Length; i++) { shopname += $"{packetsplit[i]} "; } // trim shopname shopname = shopname.TrimEnd(' '); // create default shopname if it's empty if (string.IsNullOrWhiteSpace(shopname) || string.IsNullOrEmpty(shopname)) { shopname = "SHOP_PRIVATE_SHOP"; } // truncate the string to a max-length of 20 shopname = shopname.Truncate(20); tmp.Name = shopname; return(tmp); }
internal static bool BuyValidate(this ClientSession session, KeyValuePair <long, MapShop> shop, short slot, byte amount) { if (!session.HasCurrentMapInstance) { return(false); } PersonalShopItem shopitem = session.CurrentMapInstance.UserShops[shop.Key].Items .Find(i => i.ShopSlot.Equals(slot)); if (shopitem == null) { return(false); } Guid id = shopitem.ItemInstance.Id; ClientSession shopOwnerSession = ServerManager.Instance.GetSessionByCharacterId(shop.Value.OwnerId); if (shopOwnerSession == null) { return(false); } if (amount > shopitem.SellAmount) { amount = shopitem.SellAmount; } ItemInstance sellerItem = shopOwnerSession.Character.Inventory.GetItemInstanceById(id); if (sellerItem == null || sellerItem.Amount < amount) { return(false); } List <ItemInstance> inv = shopitem.ItemInstance.Type == InventoryType.Equipment ? session.Character.Inventory.AddToInventory(shopitem.ItemInstance) : session.Character.Inventory.AddNewToInventory(shopitem.ItemInstance.ItemVNum, amount, shopitem.ItemInstance.Type); if (inv.Count == 0) { return(false); } shopOwnerSession.Character.Gold += shopitem.Price * amount; shopOwnerSession.SendPacket(shopOwnerSession.Character.GenerateGold()); shopOwnerSession.SendPacket(UserInterfaceHelper.GenerateShopMemo(1, string.Format(Language.Instance.GetMessageFromKey("BUY_ITEM"), session.Character.Name, shopitem.ItemInstance.Item.Name, amount))); session.CurrentMapInstance.UserShops[shop.Key].Sell += shopitem.Price * amount; if (shopitem.ItemInstance.Type != InventoryType.Equipment) { // remove sold amount of items shopOwnerSession.Character.Inventory.RemoveItemFromInventory(id, amount); // remove sold amount from sellamount shopitem.SellAmount -= amount; } else { // remove equipment shopOwnerSession.Character.Inventory.Remove(shopitem.ItemInstance.Id); // send empty slot to owners inventory shopOwnerSession.SendPacket( UserInterfaceHelper.Instance.GenerateInventoryRemove(shopitem.ItemInstance.Type, shopitem.ItemInstance.Slot)); // remove the sell amount shopitem.SellAmount = 0; } // remove item from shop if the amount the user wanted to sell has been sold if (shopitem.SellAmount == 0) { session.CurrentMapInstance.UserShops[shop.Key].Items.Remove(shopitem); } // update currently sold item shopOwnerSession.SendPacket($"sell_list {shop.Value.Sell} {slot}.{amount}.{shopitem.SellAmount}"); // end shop if (!session.CurrentMapInstance.UserShops[shop.Key].Items.Any(s => s.SellAmount > 0)) { shopOwnerSession.Character.CloseShop(); } return(true); }
public void CreateShop(string packet) { Logger.Debug(packet, Session.SessionId); string[] packetsplit = packet.Split(' '); InventoryType[] type = new InventoryType[20]; long[] gold = new long[20]; short[] slot = new short[20]; byte[] qty = new byte[20]; string shopname = string.Empty; if (packetsplit.Length > 2) { short typePacket; short.TryParse(packetsplit[2], out typePacket); if (Session.Character.HasShopOpened && typePacket != 1 || !Session.HasCurrentMapInstance) { return; } foreach (Portal por in Session.CurrentMapInstance.Portals) { if (Session.Character.PositionX < por.SourceX + 6 && Session.Character.PositionX > por.SourceX - 6 && Session.Character.PositionY < por.SourceY + 6 && Session.Character.PositionY > por.SourceY - 6) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SHOP_NEAR_PORTAL"), 0)); return; } } if (!Session.CurrentMapInstance.ShopAllowed) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SHOP_NOT_ALLOWED"), 0)); return; } if (typePacket == 2) { Session.SendPacket("ishop"); } else if (typePacket == 0) { if (Session.CurrentMapInstance.UserShops.Count(s => s.Value.OwnerId == Session.Character.CharacterId) != 0) { return; } MapShop myShop = new MapShop(); if (packetsplit.Length > 82) { short shopSlot = 0; for (short j = 3, i = 0; j < 82; j += 4, i++) { Enum.TryParse(packetsplit[j], out type[i]); short.TryParse(packetsplit[j + 1], out slot[i]); byte.TryParse(packetsplit[j + 2], out qty[i]); long.TryParse(packetsplit[j + 3], out gold[i]); if (gold[i] < 0) { return; } if (qty[i] > 0) { ItemInstance inv = Session.Character.Inventory.LoadBySlotAndType(slot[i], type[i]); if (inv.Amount < qty[i]) { return; } if (!inv.Item.IsTradable || inv.IsBound) { Session.SendPacket(Session.Character.GenerateMsg(Language.Instance.GetMessageFromKey("SHOP_ONLY_TRADABLE_ITEMS"), 0)); Session.SendPacket("shop_end 0"); return; } PersonalShopItem personalshopitem = new PersonalShopItem() { ShopSlot = shopSlot, Price = gold[i], ItemInstance = inv, SellAmount = qty[i] }; myShop.Items.Add(personalshopitem); shopSlot++; } } } if (myShop.Items.Count != 0) { if (!myShop.Items.Any(s => !s.ItemInstance.Item.IsSoldable || s.ItemInstance.IsBound)) { for (int i = 83; i < packetsplit.Length; i++) { shopname += $"{packetsplit[i]} "; } // trim shopname shopname = shopname.TrimEnd(' '); // create default shopname if it's empty if (string.IsNullOrWhiteSpace(shopname) || string.IsNullOrEmpty(shopname)) { shopname = Language.Instance.GetMessageFromKey("SHOP_PRIVATE_SHOP"); } // truncate the string to a max-length of 20 shopname = StringHelper.Truncate(shopname, 20); myShop.OwnerId = Session.Character.CharacterId; myShop.Name = shopname; Session.CurrentMapInstance.UserShops.Add(Session.CurrentMapInstance.LastUserShopId++, myShop); Session.Character.HasShopOpened = true; Session.CurrentMapInstance?.Broadcast(Session, Session.Character.GeneratePlayerFlag(Session.CurrentMapInstance.LastUserShopId), ReceiverType.AllExceptMe); Session.CurrentMapInstance?.Broadcast(Session.Character.GenerateShop(shopname)); Session.SendPacket(Session.Character.GenerateInfo(Language.Instance.GetMessageFromKey("SHOP_OPEN"))); Session.Character.IsSitting = true; Session.Character.IsShopping = true; Session.Character.LoadSpeed(); Session.SendPacket(Session.Character.GenerateCond()); Session.CurrentMapInstance?.Broadcast(Session.Character.GenerateRest()); } else { Session.SendPacket("shop_end 0"); Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("ITEM_NOT_SOLDABLE"), 10)); } } else { Session.SendPacket("shop_end 0"); Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("SHOP_EMPTY"), 10)); } } else if (typePacket == 1) { Session.Character.CloseShop(); } } }
private void ExecuteHandler(ClientSession session, string[] packetSplit) { InventoryType[] inventoryType = new InventoryType[20]; long[] gold = new long[20]; short[] slot = new short[20]; byte[] qty = new byte[20]; string shopname = string.Empty; if ((session.Character.HasShopOpened && Type != 1) || !session.HasCurrentMapInstance || session.Character.IsExchanging || session.Character.ExchangeInfo != null) { return; } if (session.CurrentMapInstance.Portals.Any(por => session.Character.PositionX < por.SourceX + 6 && session.Character.PositionX > por.SourceX - 6 && session.Character.PositionY < por.SourceY + 6 && session.Character.PositionY > por.SourceY - 6)) { session.SendPacket( UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHOP_NEAR_PORTAL"), 0)); return; } if (session.Character.Group != null && session.Character.Group?.GroupType != GroupType.Group) { session.SendPacket( UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHOP_NOT_ALLOWED_IN_RAID"), 0)); return; } if (!session.CurrentMapInstance.ShopAllowed) { session.SendPacket( UserInterfaceHelper.GenerateMsg(Language.Instance.GetMessageFromKey("SHOP_NOT_ALLOWED"), 0)); return; } switch (Type) { case 2: session.SendPacket("ishop"); break; case 0: if (session.CurrentMapInstance.UserShops.Any(s => s.Value.OwnerId == session.Character.CharacterId)) { return; } MapShop myShop = new MapShop(); if (packetSplit.Length > 82) { short shopSlot = 0; for (short j = 3, i = 0; j < 82; j += 4, i++) { Enum.TryParse(packetSplit[j], out inventoryType[i]); short.TryParse(packetSplit[j + 1], out slot[i]); byte.TryParse(packetSplit[j + 2], out qty[i]); long.TryParse(packetSplit[j + 3], out gold[i]); if (gold[i] < 0) { return; } if (qty[i] > 0) { ItemInstance inv = session.Character.Inventory.LoadBySlotAndType(slot[i], inventoryType[i]); if (inv != null) { if (inv.Amount < qty[i]) { return; } if (!inv.Item.IsTradable || (inv.IsBound && !(inv.Item.Type == InventoryType.Equipment && (inv.Item.ItemType == ItemType.Armor || inv.Item.ItemType == ItemType.Weapon)))) { session.SendPacket(UserInterfaceHelper.GenerateMsg( Language.Instance.GetMessageFromKey("SHOP_ONLY_TRADABLE_ITEMS"), 0)); session.SendPacket("shop_end 0"); return; } PersonalShopItem personalshopitem = new PersonalShopItem { ShopSlot = shopSlot, Price = gold[i], ItemInstance = inv, SellAmount = qty[i] }; myShop.Items.Add(personalshopitem); } } shopSlot++; } } if (myShop.Items.Count != 0) { if (!myShop.Items.Any(s => !s.ItemInstance.Item.IsSoldable || (s.ItemInstance.IsBound && !(s.ItemInstance.Item.Type == InventoryType.Equipment && (s.ItemInstance.Item.ItemType == ItemType.Armor || s.ItemInstance.Item.ItemType == ItemType.Weapon))))) { for (int i = 83; i < packetSplit.Length; i++) { shopname += $"{packetSplit[i]} "; } // trim shopname shopname = shopname.TrimEnd(' '); // create default shopname if it's empty if (string.IsNullOrWhiteSpace(shopname) || string.IsNullOrEmpty(shopname)) { shopname = Language.Instance.GetMessageFromKey("SHOP_PRIVATE_SHOP"); } // truncate the string to a max-length of 20 shopname = shopname.Truncate(20); myShop.OwnerId = session.Character.CharacterId; myShop.Name = shopname; session.CurrentMapInstance.UserShops.Add(session.CurrentMapInstance.LastUserShopId++, myShop); session.Character.HasShopOpened = true; session.CurrentMapInstance?.Broadcast(session, session.Character.GeneratePlayerFlag(session.CurrentMapInstance.LastUserShopId), ReceiverType.AllExceptMe); session.CurrentMapInstance?.Broadcast(session.Character.GenerateShop(shopname)); session.SendPacket( UserInterfaceHelper.GenerateInfo(Language.Instance.GetMessageFromKey("SHOP_OPEN"))); session.Character.IsSitting = true; session.Character.IsShopping = true; session.Character.LoadSpeed(); session.SendPacket(session.Character.GenerateCond()); session.CurrentMapInstance?.Broadcast(session.Character.GenerateRest()); } else { session.SendPacket("shop_end 0"); session.SendPacket( session.Character.GenerateSay( Language.Instance.GetMessageFromKey("ITEM_NOT_SOLDABLE"), 10)); } } else { session.SendPacket("shop_end 0"); session.SendPacket( session.Character.GenerateSay(Language.Instance.GetMessageFromKey("SHOP_EMPTY"), 10)); } break; case 1: session.Character.CloseShop(); break; } }
/// <summary> /// buy packet /// </summary> /// <param name="buyPacket"></param> public void BuyShop(BuyPacket buyPacket) { if (Session.Character.InExchangeOrTrade) { return; } Logger.Debug(Session.Character.GenerateIdentity(), buyPacket.ToString()); byte amount = buyPacket.Amount; switch (buyPacket.Type) { case BuyShopType.CharacterShop: { // User shop if (!Session.HasCurrentMapInstance) { return; } KeyValuePair <long, MapShop> shop = Session.CurrentMapInstance.UserShops.FirstOrDefault(mapshop => mapshop.Value.OwnerId.Equals(buyPacket.OwnerId)); PersonalShopItem item = shop.Value?.Items.FirstOrDefault(i => i.ShopSlot.Equals(buyPacket.Slot)); if (item == null || amount <= 0 || amount > 99) { return; } if (amount > item.SellAmount) { amount = item.SellAmount; } if (item.Price * amount + ServerManager.Instance.GetProperty <long>(shop.Value.OwnerId, nameof(Character.Gold)) > ServerManager.Instance.MaxGold) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("MAX_GOLD"))); return; } if (item.Price * amount >= Session.Character.Gold) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"))); return; } // check if the item has been removed successfully from previous owner and // remove it if (BuyValidate(Session, shop, buyPacket.Slot, amount)) { Session.Character.Gold -= item.Price * amount; Session.SendPacket(Session.Character.GenerateGold()); KeyValuePair <long, MapShop> shop2 = Session.CurrentMapInstance.UserShops.FirstOrDefault(s => s.Value.OwnerId.Equals(buyPacket.OwnerId)); LoadShopItem(buyPacket.OwnerId, shop2); } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_PLACE"), 0)); } break; } case BuyShopType.ItemShop: { // load shop if (!Session.HasCurrentMapInstance) { return; } MapNpc npc = Session.CurrentMapInstance.Npcs.FirstOrDefault(n => n.MapNpcId.Equals((short)buyPacket.OwnerId)); if (npc != null) { int dist = Map.GetDistance(new MapCell { X = Session.Character.PositionX, Y = Session.Character.PositionY }, new MapCell { X = npc.MapX, Y = npc.MapY }); if (npc.Shop == null || dist > 5) { return; } if (npc.Shop.ShopSkills.Any()) { if (!npc.Shop.ShopSkills.Exists(s => s.SkillVNum == buyPacket.Slot)) { return; } // skill shop if (Session.Character.UseSp) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("REMOVE_SP"), 0)); return; } if (Session.Character.Skills.GetAllItems().Any(s => s.LastUse.AddMilliseconds(s.Skill.Cooldown * 100) > DateTime.Now)) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("SKILL_NEED_COOLDOWN"), 0)); return; } Skill skillinfo = ServerManager.Instance.GetSkill(buyPacket.Slot); if (Session.Character.Skills.GetAllItems().Any(s => s.SkillVNum == buyPacket.Slot) || skillinfo == null) { return; } if (Session.Character.Gold < skillinfo.Price) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"), 0)); } else if (Session.Character.GetCP() < skillinfo.CPCost) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_CP"), 0)); } else { if (skillinfo.SkillVNum < 200) { int SkillMiniumLevel = 0; if (skillinfo.MinimumSwordmanLevel == 0 && skillinfo.MinimumArcherLevel == 0 && skillinfo.MinimumMagicianLevel == 0) { SkillMiniumLevel = skillinfo.MinimumAdventurerLevel; } else { switch (Session.Character.Class) { case ClassType.Adventurer: SkillMiniumLevel = skillinfo.MinimumAdventurerLevel; break; case ClassType.Swordman: SkillMiniumLevel = skillinfo.MinimumSwordmanLevel; break; case ClassType.Archer: SkillMiniumLevel = skillinfo.MinimumArcherLevel; break; case ClassType.Magician: SkillMiniumLevel = skillinfo.MinimumMagicianLevel; break; } } if (SkillMiniumLevel == 0) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("SKILL_CANT_LEARN"), 0)); return; } if (Session.Character.Level < SkillMiniumLevel) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("LOW_LVL"), 0)); return; } foreach (CharacterSkill skill in Session.Character.Skills.GetAllItems()) { if (skillinfo.CastId == skill.Skill.CastId && skill.Skill.SkillVNum < 200) { Session.Character.Skills.Remove(skill.SkillVNum); } } } else { if ((byte)Session.Character.Class != skillinfo.Class) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("SKILL_CANT_LEARN"), 0)); return; } if (Session.Character.JobLevel < skillinfo.LevelMinimum) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("LOW_JOB_LVL"), 0)); return; } if (skillinfo.UpgradeSkill != 0) { CharacterSkill oldupgrade = Session.Character.Skills.GetAllItems().FirstOrDefault(s => s.Skill.UpgradeSkill == skillinfo.UpgradeSkill && s.Skill.UpgradeType == skillinfo.UpgradeType && s.Skill.UpgradeSkill != 0); if (oldupgrade != null) { Session.Character.Skills.Remove(oldupgrade.SkillVNum); } } } Session.Character.Skills[buyPacket.Slot] = new CharacterSkill { SkillVNum = buyPacket.Slot, CharacterId = Session.Character.CharacterId }; Session.Character.Gold -= skillinfo.Price; Session.SendPacket(Session.Character.GenerateGold()); Session.SendPacket(Session.Character.GenerateSki()); Session.SendPackets(Session.Character.GenerateQuicklist()); Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("SKILL_LEARNED"), 0)); Session.SendPacket(Session.Character.GenerateLev()); } } else if (npc.Shop.ShopItems.Any()) { // npc shop ShopItemDTO item = npc.Shop.ShopItems.FirstOrDefault(it => it.Slot == buyPacket.Slot); if (item == null || amount <= 0 || amount > 99) { return; } Item iteminfo = ServerManager.Instance.GetItem(item.ItemVNum); long price = iteminfo.Price * amount; long Reputprice = iteminfo.ReputPrice * amount; double percent; switch (Session.Character.GetDignityIco()) { case 3: percent = 1.10; break; case 4: percent = 1.20; break; case 5: case 6: percent = 1.5; break; default: percent = 1; break; } sbyte rare = item.Rare; if (iteminfo.Type == 0) { amount = 1; } if (iteminfo.ReputPrice == 0) { if (price < 0 || price * percent > Session.Character.Gold) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_MONEY"))); return; } } else { if (Reputprice <= 0 || Reputprice > Session.Character.Reput) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_REPUT"))); return; } byte ra = (byte)ServerManager.Instance.RandomNumber(); int[] rareprob = { 100, 100, 70, 50, 30, 15, 5, 1 }; if (iteminfo.ReputPrice != 0) { for (int i = 0; i < rareprob.Length; i++) { if (ra <= rareprob[i]) { rare = (sbyte)i; } } } } List <ItemInstance> newItem = Session.Character.Inventory.AddNewToInventory(item.ItemVNum, amount, Rare: rare, Upgrade: item.Upgrade, Design: item.Color); if (!newItem.Any()) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateShopMemo(3, Language.Instance.GetMessageFromKey("NOT_ENOUGH_PLACE"))); return; } if (newItem.Any()) { if (iteminfo.ReputPrice == 0) { Session.SendPacket(UserInterfaceHelper.Instance.GenerateShopMemo(1, string.Format(Language.Instance.GetMessageFromKey("BUY_ITEM_VALID"), iteminfo.Name, amount))); Session.Character.Gold -= (long)(price * percent); Session.SendPacket(Session.Character.GenerateGold()); } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateShopMemo(1, string.Format(Language.Instance.GetMessageFromKey("BUY_ITEM_VALID"), iteminfo.Name, amount))); Session.Character.Reput -= Reputprice; Session.SendPacket(Session.Character.GenerateFd()); Session.SendPacket(Session.Character.GenerateSay(Language.Instance.GetMessageFromKey("REPUT_DECREASED"), 11)); } } else { Session.SendPacket(UserInterfaceHelper.Instance.GenerateMsg(Language.Instance.GetMessageFromKey("NOT_ENOUGH_PLACE"), 0)); } } } break; } } }