public void HandlePacket(GameClient client, GSPacketIn packet) { if (client.Player == null) { return; } packet.ReadShort(); // id ushort toClientSlot = packet.ReadShort(); ushort fromClientSlot = packet.ReadShort(); ushort itemCount = packet.ReadShort(); // If our toSlot is > 1000 then target is a game object (not a window) with an ObjectID of toSlot - 1000 if (toClientSlot > 1000) { ushort objectId = (ushort)(toClientSlot - 1000); GameObject obj = WorldMgr.GetObjectByIDFromRegion(client.Player.CurrentRegionID, objectId); if (obj == null || obj.ObjectState != GameObject.eObjectState.Active) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage($"Invalid trade target. ({objectId})", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } GamePlayer tradeTarget = obj as GamePlayer; // If our target is another player we set the tradetarget // trade permissions are done in GamePlayer if (tradeTarget != null) { if (tradeTarget.Client.ClientState != GameClient.eClientState.Playing) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("Can't trade with inactive players.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (tradeTarget == client.Player) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("You can't trade with yourself, silly!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (!GameServer.ServerRules.IsAllowedToTrade(client.Player, tradeTarget, false)) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } } // Is the item we want to move in our backpack? // we also allow drag'n drop from equipped to blacksmith if (fromClientSlot >= (ushort)eInventorySlot.FirstBackpack && fromClientSlot <= (ushort)eInventorySlot.LastBackpack || obj is Blacksmith && fromClientSlot >= (ushort)eInventorySlot.MinEquipable && fromClientSlot <= (ushort)eInventorySlot.MaxEquipable) { if (!obj.IsWithinRadius(client.Player, WorldMgr.GIVE_ITEM_DISTANCE)) { // show too far away message if (obj is GamePlayer player) { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerMoveItemRequestHandler.TooFarAway", client.Player.GetName(player)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } else { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerMoveItemRequestHandler.TooFarAway", obj.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromClientSlot); if (item == null) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage($"Null item (client slot# {fromClientSlot}).", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (obj is GameNPC == false || item.Count == 1) { // see if any event handlers will handle this move client.Player.Notify(GamePlayerEvent.GiveItem, client.Player, new GiveItemEventArgs(client.Player, obj, item)); } // If the item has been removed by the event handlers, return; if (item.OwnerID == null) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } // if a player to a GM and item is not dropable then don't allow trade???? This seems wrong. if (client.Account.PrivLevel == (uint)ePrivLevel.Player && tradeTarget != null && tradeTarget.Client.Account.PrivLevel != (uint)ePrivLevel.Player) { if (!item.IsDropable) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("You can not remove this item!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } } if (tradeTarget != null) { // This is a player trade, let trade code handle tradeTarget.ReceiveTradeItem(client.Player, item); client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } if (obj.ReceiveItem(client.Player, item)) { // this object was expecting an item and handled it client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } // Is the "item" we want to move money? For Version 1.78+ if (fromClientSlot >= (int)eInventorySlot.Mithril178 && fromClientSlot <= (int)eInventorySlot.Copper178) { fromClientSlot -= eInventorySlot.Mithril178 - eInventorySlot.Mithril; } // Is the "item" we want to move money? if (fromClientSlot >= (ushort)eInventorySlot.Mithril && fromClientSlot <= (ushort)eInventorySlot.Copper) { int[] money = new int[5]; money[fromClientSlot - (ushort)eInventorySlot.Mithril] = itemCount; long flatMoney = Money.GetMoney(money[0], money[1], money[2], money[3], money[4]); fromClientSlot += eInventorySlot.Mithril178 - eInventorySlot.Mithril; if (!obj.IsWithinRadius(client.Player, WorldMgr.GIVE_ITEM_DISTANCE)) { // show too far away message if (obj is GamePlayer player) { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerMoveItemRequestHandler.TooFarAway", client.Player.GetName(player)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } else { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerMoveItemRequestHandler.TooFarAway", obj.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } if (flatMoney > client.Player.GetCurrentMoney()) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } client.Player.Notify(GamePlayerEvent.GiveMoney, client.Player, new GiveMoneyEventArgs(client.Player, obj, flatMoney)); if (tradeTarget != null) { tradeTarget.ReceiveTradeMoney(client.Player, flatMoney); client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } if (obj.ReceiveMoney(client.Player, flatMoney)) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } client.Out.SendInventoryItemsUpdate(null); return; } // We did not drop an item on a game object, which means we should have valid from and to slots // since we are moving an item from one window to another. // First check for an active InventoryObject if (client.Player.ActiveInventoryObject != null && client.Player.ActiveInventoryObject.MoveItem(client.Player, fromClientSlot, toClientSlot)) { // ChatUtil.SendDebugMessage(client, "ActiveInventoryObject handled move"); return; } // Do we want to move an item from immediate inventory to immediate inventory or drop on the ground if (((fromClientSlot >= (ushort)eInventorySlot.Ground && fromClientSlot <= (ushort)eInventorySlot.LastBackpack) || (fromClientSlot >= (ushort)eInventorySlot.FirstVault && fromClientSlot <= (ushort)eInventorySlot.LastVault) || (fromClientSlot >= (ushort)eInventorySlot.FirstBagHorse && fromClientSlot <= (ushort)eInventorySlot.LastBagHorse)) && ((toClientSlot >= (ushort)eInventorySlot.Ground && toClientSlot <= (ushort)eInventorySlot.LastBackpack) || (toClientSlot >= (ushort)eInventorySlot.FirstVault && toClientSlot <= (ushort)eInventorySlot.LastVault) || (toClientSlot >= (ushort)eInventorySlot.FirstBagHorse && toClientSlot <= (ushort)eInventorySlot.LastBagHorse))) { // We want to drop the item if (toClientSlot == (ushort)eInventorySlot.Ground) { InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromClientSlot); if (item == null) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage($"Invalid item (slot# {fromClientSlot}).", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (fromClientSlot < (ushort)eInventorySlot.FirstBackpack) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } if (!item.IsDropable) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("You can not drop this item!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (client.Player.DropItem((eInventorySlot)fromClientSlot)) { client.Out.SendMessage($"You drop {item.GetName(0, false)} on the ground!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } client.Out.SendInventoryItemsUpdate(null); return; } client.Player.Inventory.MoveItem((eInventorySlot)fromClientSlot, (eInventorySlot)toClientSlot, itemCount); // ChatUtil.SendDebugMessage(client, "Player.Inventory handled move"); return; } if (((fromClientSlot >= (ushort)eInventorySlot.Ground && fromClientSlot <= (ushort)eInventorySlot.LastBackpack) || (fromClientSlot >= (ushort)eInventorySlot.FirstVault && fromClientSlot <= (ushort)eInventorySlot.LastVault) || (fromClientSlot >= (ushort)eInventorySlot.FirstBagHorse && fromClientSlot <= (ushort)eInventorySlot.LastBagHorse)) && ((toClientSlot == (ushort)eInventorySlot.PlayerPaperDoll || toClientSlot == (ushort)eInventorySlot.NewPlayerPaperDoll) || (toClientSlot >= (ushort)eInventorySlot.Ground && toClientSlot <= (ushort)eInventorySlot.LastBackpack) || (toClientSlot >= (ushort)eInventorySlot.FirstVault && toClientSlot <= (ushort)eInventorySlot.LastVault) || (toClientSlot >= (ushort)eInventorySlot.FirstBagHorse && toClientSlot <= (ushort)eInventorySlot.LastBagHorse))) { InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromClientSlot); if (item == null) { return; } toClientSlot = 0; if (item.Item_Type >= (int)eInventorySlot.MinEquipable && item.Item_Type <= (int)eInventorySlot.MaxEquipable) { toClientSlot = (ushort)item.Item_Type; } if (toClientSlot == 0) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } if (toClientSlot == (int)eInventorySlot.LeftBracer || toClientSlot == (int)eInventorySlot.RightBracer) { if (client.Player.Inventory.GetItem(eInventorySlot.LeftBracer) == null) { toClientSlot = (int)eInventorySlot.LeftBracer; } else { toClientSlot = (int)eInventorySlot.RightBracer; } } if (toClientSlot == (int)eInventorySlot.LeftRing || toClientSlot == (int)eInventorySlot.RightRing) { if (client.Player.Inventory.GetItem(eInventorySlot.LeftRing) == null) { toClientSlot = (int)eInventorySlot.LeftRing; } else { toClientSlot = (int)eInventorySlot.RightRing; } } client.Player.Inventory.MoveItem((eInventorySlot)fromClientSlot, (eInventorySlot)toClientSlot, itemCount); // ChatUtil.SendDebugMessage(client, "Player.Inventory handled move (2)"); return; } client.Out.SendInventoryItemsUpdate(null); }
/// <summary> /// Called on every timer tick /// </summary> protected override void OnTick() { var player = (GamePlayer)m_actionSource; if (player == null) { return; } // log.DebugFormat("Dialog - response: {0}, messageType: {1}, data1: {2}, data2: {3}, data3: {4}", m_response, m_messageType, m_data1, m_data2, m_data3); switch ((eDialogCode)m_messageType) { case eDialogCode.CustomDialog: { if (m_data2 == 0x01) { CustomDialogResponse callback; lock (player) { callback = player.CustomDialogCallback; player.CustomDialogCallback = null; } if (callback == null) { return; } callback(player, m_response); } break; } case eDialogCode.GuildInvite: { var guildLeader = WorldMgr.GetObjectByIDFromRegion(player.CurrentRegionID, (ushort)m_data1) as GamePlayer; if (m_response == 0x01) //accept { if (guildLeader == null) { player.Out.SendMessage("You need to be in the same region as the guild leader to accept an invitation.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (player.Guild != null) { player.Out.SendMessage("You are still in a guild, you'll have to leave it first.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (guildLeader.Guild != null) { guildLeader.Guild.AddPlayer(player); return; } player.Out.SendMessage("Player doing the invite is not in a guild!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (guildLeader != null) { guildLeader.Out.SendMessage(player.Name + " declined your invite.", eChatType.CT_System, eChatLoc.CL_SystemWindow); } return; } case eDialogCode.GuildLeave: { if (m_response == 0x01) //accepte { if (player.Guild == null) { player.Out.SendMessage("You are not in a guild.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } player.Guild.RemovePlayer(player.Name, player); } else { player.Out.SendMessage("You decline to quit your guild.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } break; } case eDialogCode.QuestSubscribe: { var questNPC = (GameLiving)WorldMgr.GetObjectByIDFromRegion(player.CurrentRegionID, (ushort)m_data2); if (questNPC == null) { return; } var args = new QuestEventArgs(questNPC, player, (ushort)m_data1); if (m_response == 0x01) // accept { // TODO add quest to player // Note: This is done withing quest code since we have to check requirements, etc for each quest individually // i'm reusing the questsubscribe command for quest abort since its 99% the same, only different event dets fired player.Notify(m_data3 == 0x01 ? GamePlayerEvent.AbortQuest : GamePlayerEvent.AcceptQuest, player, args); return; } player.Notify(m_data3 == 0x01 ? GamePlayerEvent.ContinueQuest : GamePlayerEvent.DeclineQuest, player, args); return; } case eDialogCode.GroupInvite: { if (m_response == 0x01) { GameClient cln = WorldMgr.GetClientFromID(m_data1); if (cln == null) { return; } GamePlayer groupLeader = cln.Player; if (groupLeader == null) { return; } if (player.Group != null) { player.Out.SendMessage("You are still in a group.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (!GameServer.ServerRules.IsAllowedToGroup(groupLeader, player, false)) { return; } if (player.InCombatPvE) { player.Out.SendMessage("You can't join a group while in combat!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (groupLeader.Group != null) { if (groupLeader.Group.Leader != groupLeader) { return; } if (groupLeader.Group.MemberCount >= ServerProperties.Properties.GROUP_MAX_MEMBER) { player.Out.SendMessage("The group is full.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } groupLeader.Group.AddMember(player); GameEventMgr.Notify(GamePlayerEvent.AcceptGroup, player); return; } var group = new Group(groupLeader); GroupMgr.AddGroup(group); group.AddMember(groupLeader); group.AddMember(player); GameEventMgr.Notify(GamePlayerEvent.AcceptGroup, player); return; } break; } case eDialogCode.KeepClaim: { if (m_response == 0x01) { if (player.Guild == null) { player.Out.SendMessage("You have to be a member of a guild, before you can use any of the commands!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(player.CurrentRegionID, player.Position, WorldMgr.VISIBILITY_DISTANCE); if (keep == null) { player.Out.SendMessage("You have to be near the keep to claim it.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (keep.CheckForClaim(player)) { keep.Claim(player); } break; } break; } case eDialogCode.HousePayRent: { if (m_response == 0x00) { if (player.TempProperties.getProperty <long>(HousingConstants.MoneyForHouseRent, -1) != -1) { player.TempProperties.removeProperty(HousingConstants.MoneyForHouseRent); } if (player.TempProperties.getProperty <long>(HousingConstants.BPsForHouseRent, -1) != -1) { player.TempProperties.removeProperty(HousingConstants.BPsForHouseRent); } player.TempProperties.removeProperty(HousingConstants.HouseForHouseRent); return; } var house = player.TempProperties.getProperty <House>(HousingConstants.HouseForHouseRent, null); var moneyToAdd = player.TempProperties.getProperty <long>(HousingConstants.MoneyForHouseRent, -1); var bpsToMoney = player.TempProperties.getProperty <long>(HousingConstants.BPsForHouseRent, -1); if (moneyToAdd != -1) { // if we're giving money and already have some in the lockbox, make sure we don't // take more than what would cover 4 weeks of rent. if (moneyToAdd + house.KeptMoney > HouseMgr.GetRentByModel(house.Model) * ServerProperties.Properties.RENT_LOCKBOX_PAYMENTS) { moneyToAdd = (HouseMgr.GetRentByModel(house.Model) * ServerProperties.Properties.RENT_LOCKBOX_PAYMENTS) - house.KeptMoney; } // take the money from the player if (!player.RemoveMoney(moneyToAdd)) { return; } InventoryLogging.LogInventoryAction(player, "(HOUSE;" + house.HouseNumber + ")", eInventoryActionType.Other, moneyToAdd); // add the money to the lockbox house.KeptMoney += moneyToAdd; // save the house and the player house.SaveIntoDatabase(); player.SaveIntoDatabase(); // notify the player of what we took and how long they are prepaid for player.Out.SendMessage("You deposit " + Money.GetString(moneyToAdd) + " in the lockbox.", eChatType.CT_System, eChatLoc.CL_SystemWindow); player.Out.SendMessage("The lockbox now has " + Money.GetString(house.KeptMoney) + " in it. The weekly payment is " + Money.GetString(HouseMgr.GetRentByModel(house.Model)) + ".", eChatType.CT_System, eChatLoc.CL_SystemWindow); player.Out.SendMessage("The house is now prepaid for the next " + (house.KeptMoney / HouseMgr.GetRentByModel(house.Model)) + " payments.", eChatType.CT_System, eChatLoc.CL_SystemWindow); // clean up player.TempProperties.removeProperty(HousingConstants.MoneyForHouseRent); } else { if (bpsToMoney + house.KeptMoney > HouseMgr.GetRentByModel(house.Model) * ServerProperties.Properties.RENT_LOCKBOX_PAYMENTS) { bpsToMoney = (HouseMgr.GetRentByModel(house.Model) * ServerProperties.Properties.RENT_LOCKBOX_PAYMENTS) - house.KeptMoney; } if (!player.RemoveBountyPoints(Money.GetGold(bpsToMoney))) { return; } // add the bps to the lockbox house.KeptMoney += bpsToMoney; // save the house and the player house.SaveIntoDatabase(); player.SaveIntoDatabase(); // notify the player of what we took and how long they are prepaid for player.Out.SendMessage("You deposit " + Money.GetString(bpsToMoney) + " in the lockbox.", eChatType.CT_System, eChatLoc.CL_SystemWindow); player.Out.SendMessage("The lockbox now has " + Money.GetString(house.KeptMoney) + " in it. The weekly payment is " + Money.GetString(HouseMgr.GetRentByModel(house.Model)) + ".", eChatType.CT_System, eChatLoc.CL_SystemWindow); player.Out.SendMessage("The house is now prepaid for the next " + (house.KeptMoney / HouseMgr.GetRentByModel(house.Model)) + " payments.", eChatType.CT_System, eChatLoc.CL_SystemWindow); // clean up player.TempProperties.removeProperty(HousingConstants.BPsForHouseRent); } // clean up player.TempProperties.removeProperty(HousingConstants.MoneyForHouseRent); break; } case eDialogCode.MasterLevelWindow: { player.Out.SendMasterLevelWindow(m_response); break; } } }