Esempio n. 1
0
        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);
        }
Esempio n. 2
0
            /// <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;
                }
                }
            }