Exemplo n.º 1
0
            /// <summary>
            /// When overridden in the derived class, performs additional processing to handle an Inventory slot
            /// changing. This is only called when the object references changes, not when any part of the object
            /// (such as the Item's amount) changes. It is guarenteed that if <paramref name="newItem"/> is null,
            /// <paramref name="oldItem"/> will not be, and vise versa. Both will never be null or non-null.
            /// </summary>
            /// <param name="slot">Slot that the change took place in.</param>
            /// <param name="newItem">The item that was added to the <paramref name="slot"/>, or null if the slot changed to empty.</param>
            /// <param name="oldItem">The item that used to be in the <paramref name="slot"/>,
            /// or null if the slot used to be empty.</param>
            protected override void HandleSlotChanged(InventorySlot slot, ItemEntity newItem, ItemEntity oldItem)
            {
                base.HandleSlotChanged(slot, newItem, oldItem);

                // Do not need to update the database if the item has not changed
                if (newItem == oldItem)
                {
                    return;
                }

                if (oldItem != null)
                {
                    // Remove the old item from the database (after making sure it isn't in the inventory still)
                    if (!TryGetSlot(oldItem).HasValue)
                    {
                        _removeItemQuery.Execute(oldItem.ID);
                    }
                }

                if (newItem != null)
                {
                    // Add the new item to the database
                    Debug.Assert(TryGetSlot(newItem).HasValue, "How is the new item not in the database?!");
                    _insertItemQuery.Execute(newItem.ID, _owner.ID);
                }
            }
Exemplo n.º 2
0
        /// <summary>
        /// Recovers items from the <see cref="ActiveTradeItemTable"/> for a character, and gives them to the character. Items can
        /// get stuck in this table when the server unexpectedly shuts down during a peer trade session. Calling this method
        /// will attempt to give the <see cref="Character"/> any items they might have in this table. This cannot be done if the
        /// <paramref name="character"/> is currently trading.
        /// </summary>
        /// <param name="character">The <see cref="Character"/> to get the lost items for.</param>
        /// <param name="recovered">The number of items that were able to be given back to the <paramref name="character"/>.</param>
        /// <param name="remaining">The number of items still remaining in the table for the <paramref name="character"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="character"/> is null.</exception>
        public static void RecoverLostTradeItems(User character, out int recovered, out int remaining)
        {
            recovered = 0;

            if (character == null)
            {
                throw new ArgumentNullException("character");
            }

            // Make sure that we do not try executing this while they are trading! Doing so would be very, very ugly.
            if (character.IsPeerTrading)
            {
                const string errmsg = "Tried to recover lost trade items for `{0}` while they were trading. Very bad idea...";
                if (log.IsWarnEnabled)
                {
                    log.WarnFormat(errmsg, character);
                }
                remaining = 0;
                return;
            }

            // Get the list of lost items
            var lostItemIDs = _getLostItemsQuery.Execute(character.ID);

            // Check if there are even any items to recover
            remaining = lostItemIDs.Count();
            if (remaining == 0)
            {
                return;
            }

            // One by one, try to add the lost items back to the character
            foreach (var lostItemID in lostItemIDs)
            {
                // Create the item instance
                var lostItem = ItemEntity.LoadFromDatabase(lostItemID);

                // Remove the entry from the table containing the lost items
                _removeItemQuery.Execute(lostItemID);

                remaining--;

                // Make sure the item was valid (which it should always be unless something went horribly wrong)
                // We do NOT try to add it back again, since who knows what is wrong with the item... its just not worth risking
                if (lostItem == null)
                {
                    Debug.Fail("Why did we fail to load the item... from a RELATIONAL database!?");
                    continue;
                }

                recovered++;

                // Try to give the item to the character
                var lostItemRemainder = character.TryGiveItem(lostItem);

                // If there was a remainder when we tried to give the character the item, then we will have to put it back into the
                // database table so we can try to give it to them again another time.
                if (lostItemRemainder != null)
                {
                    _insertItemQuery.Execute(new PeerTradingInsertItemQuery.QueryArgs(lostItemRemainder.ID, character.ID));
                    remaining++;
                    break;
                }
            }

            // Notify the character about the items recovered and remaining
            if (remaining > 0)
            {
                character.Send(GameMessage.PeerTradingItemsRecovered, ServerMessageType.GUI, recovered, remaining);
            }
            else
            {
                character.Send(GameMessage.PeerTradingItemsRecoveredNoRemaining, ServerMessageType.GUI, recovered);
            }
        }