Resource icon

3.3.5 TC List Inventory Command 1.0

Lists Players Inventory

Darksoke

Well-known member
Darksoke Rep
1
0
0
Rep
1
Darksoke Vouches
0
0
0
Vouches
0
Posts
58
Likes
69
Bits
2 YEARS
2 YEARS OF SERVICE
LEVEL 2 50 XP
How is this saving memory? GetItemCount searches everything again.
Since GetItemCount is already optimized for inventory search, there is no need to create a new method and execute an unnecessary database query. Additionally, what you previously wrote, may be done in a single loop instead of 5 since player inventory is an uint8 (min 0 max 255). If a bag slot is empty you just continue the loop until it reaches the max INVENTORY_SLOT_BAG_0

EDIT:
nvm I just realized the mistake lol :))), since i loop through inventory I do already have the damn Item count as well .... so we'll just stay on a single loop and count
 

Kearu

Divine
Divine
Rep
1
0
0
Rep
1
Vouches
0
0
0
Vouches
0
Posts
139
Likes
81
2 YEARS
2 YEARS OF SERVICE
LEVEL 3 120 XP
Suggested changes: Untested
C++:
    static bool HandleListInventoryCommand(ChatHandler* handler, Optional<PlayerIdentifier> targetIdentifier)
    {
        if (!targetIdentifier)
            targetIdentifier = PlayerIdentifier::FromTarget(handler);
        if (!targetIdentifier)
        {
            handler->PSendSysMessage("Syntax: .list inventory [$playername]|nOutputs a list of character with $playername (or selected if name not provided) Inventory.");
            return true;
        }
    
        Player* target = targetIdentifier->GetConnectedPlayer();

        // check if target is ingame
        if (target)
        {
            std::string Output = target->GetSession()->GetPlayerInfo();

            for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++)
                if (Item* pItem = target->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
                    handler->PSendSysMessage("%s%sx%u - %s", Output.c_str(), (handler->IsConsole() ? "[" + std::to_string(pItem->GetEntry()) + "] [" + pItem->GetTemplate()->Name1 + "]" : pItem->GetItemLink()), pItem->GetCount(), i >= INVENTORY_SLOT_BAG_END ? "Bag" : "Equipped");

            for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
                for (uint8 j = 0; j < MAX_BAG_SIZE; j++)
                    if (Item* pItem = target->GetItemByPos(((i << 8) | j)))
                        handler->PSendSysMessage("%s%sx%u - Bag", Output.c_str(), (handler->IsConsole() ? "[" + std::to_string(pItem->GetEntry()) + "] [" + pItem->GetTemplate()->Name1 + "]" : pItem->GetItemLink()), pItem->GetCount());

            for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; i++)
                if (Item* pItem = target->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
                    handler->PSendSysMessage("%s%sx%u - Bank", Output.c_str(), (handler->IsConsole() ? "[" + std::to_string(pItem->GetEntry()) + "] [" + pItem->GetTemplate()->Name1 + "]" : pItem->GetItemLink()), pItem->GetCount());

            for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
                if (Item* pItem = target->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
                {
                    handler->PSendSysMessage("%s%sx%u - Bank", Output.c_str(), (handler->IsConsole() ? "[" + std::to_string(pItem->GetEntry()) + "] [" + pItem->GetTemplate()->Name1 + "]" : pItem->GetItemLink()), pItem->GetCount());

                    for (uint8 j = 0; j < MAX_BAG_SIZE; j++)
                        if (Item* pItem2 = target->GetItemByPos(i, j))
                            handler->PSendSysMessage("%s%sx%u - Bank", Output.c_str(), (handler->IsConsole() ? "[" + std::to_string(pItem->GetEntry()) + "] [" + pItem2->GetTemplate()->Name1 + "]" : pItem2->GetItemLink()), pItem2->GetCount());
                }

            for (uint8 i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++)
                if (Item* pItem = target->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
                    handler->PSendSysMessage("%s%sx%u - Currency", Output.c_str(), (handler->IsConsole() ? "[" + std::to_string(pItem->GetEntry()) + "][" + pItem->GetTemplate()->Name1 + "]" : pItem->GetItemLink()), pItem->GetCount());
        }
        else // otherwise db lookup
        {
            CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_INVENTORY);
            stmt->setUInt32(0, targetIdentifier->GetGUID().GetCounter());
            PreparedQueryResult queryResult = CharacterDatabase.Query(stmt);
            if (queryResult)
            {
                do
                {
                    Field* fields = queryResult->Fetch();

                    Item* item = nullptr;
                    ObjectGuid::LowType bagGuid  = fields[11].GetUInt32();
                    uint8  slot                  = fields[12].GetUInt8();
                    ObjectGuid::LowType itemGuid = fields[13].GetUInt32();
                    uint32 itemEntry             = fields[14].GetUInt32();

                    if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemEntry))
                    {
                        item = NewItemOrBag(proto);

                        if (!item->LoadFromDB(itemGuid, targetIdentifier->GetGUID(), fields, itemEntry))
                        {
                            delete item;
                            continue;
                        }

                        std::ostringstream ItemLink;
                        if (!handler->IsConsole())
                            ItemLink << item->GetItemLink();
                        else
                            ItemLink << "[" << itemEntry << "] [" << proto->Name1 << "]";

                        handler->PSendSysMessage("GUID %u: %s has %sx%u", targetIdentifier->GetGUID().GetCounter(), targetIdentifier->GetName().c_str(), ItemLink.str().c_str(), item->GetCount());
                        delete item;
                    }
                } while (queryResult->NextRow());
            }
            else
                handler->PSendSysMessage("Player %s not found, or doesn't have any items.", targetIdentifier->GetName().c_str());
        }

        return true;
    }

Ahh sweet, didn't realize PlayerIdentifier worked with chat input, assumed it was just player target. Will definitely be able to clean some of the code up, didn't add the GetConnectedPlayerInfo() for Output information as it kind of has information that isn't necessarily needed and in my opinion makes it feel cluttered. Will definitely also be adding more comments though incase people want to change it up, that way it's easier to know what's going on. As for the offline part, it won't work properly. CHAR_SEL_CHARACTER_INVENTORY Query is a custom query, which selects some info from item_instance and joins it with the item Name from item_template where char name = X;

Also I'm not sure what the point of Creating a new instance of the Item is, since I don't need the Item* to link the item, I mean the only thing I can think of is it would make it so linking the item would be slightly easier. Wouldn't need the for loop, for the enchantments but I'd imagine creating the item already does something similar, and would be just adding extra steps that aren't required.

I greatly appreciate the suggestion, and will be updating the script with some of the changes. Also I'm not sure if it would be better to use if / else, when you can if and return in the if. I'd imagine they probably are about the same performance wise. I'm guessing mostly just preferred style, but not sure.

Since GetItemCount is already optimized for inventory search, there is no need to create a new method and execute an unnecessary database query. Additionally, what you previously wrote, may be done in a single loop instead of 5 since player inventory is an uint8 (min 0 max 255). If a bag slot is empty you just continue the loop until it reaches the max INVENTORY_SLOT_BAG_0

EDIT:
nvm I just realized the mistake lol :))), since i loop through inventory I do already have the damn Item count as well .... so we'll just stay on a single loop and count

The issue is, it doesn't loop through bag inventories. 0-255 only gets Equipment, Bags Equipped, first bag slot (16 slot default bag), Bank Items (not bagged items), Bank Bags equipped, Buy Back Slots, Key Slots, and Currencies. Unless I'm missing something, I mean you can have up to like 11 bags I think (4 inventory, 7 bank) which max size is 36. 36 * 11 = 396 which it's self is bigger than a char.
 

Kearu

Divine
Divine
Rep
1
0
0
Rep
1
Vouches
0
0
0
Vouches
0
Posts
139
Likes
81
2 YEARS
2 YEARS OF SERVICE
LEVEL 3 120 XP

Reloac

Active member
Reloac Rep
2
0
0
Rep
2
Reloac Vouches
0
0
0
Vouches
0
Posts
42
Likes
31
Bits
2 YEARS
2 YEARS OF SERVICE
LEVEL 1 55 XP
I create a new item so you can use the function which I guess is custom, GetItemLink, and so it handles the enchants automatically. The pointer is deleted right after anyway. I didn't test it but it should also remove the need for your custom prepared statement.
 

sam666999s

Member
sam666999s Rep
0
0
0
Rep
0
sam666999s Vouches
0
0
0
Vouches
0
Posts
10
Likes
13
Bits
2 YEARS
2 YEARS OF SERVICE
LEVEL 1 105 XP
there is a way to make it eluna as well xD
simple as this
you can change the commands if u want but it still does the same job
 

Attachments

  • Inventory_Checker.lua
    2.5 KB · Views: 8
Liked By 2 members :

Kearu

Divine
Divine
Rep
1
0
0
Rep
1
Vouches
0
0
0
Vouches
0
Posts
139
Likes
81
2 YEARS
2 YEARS OF SERVICE
LEVEL 3 120 XP
there is a way to make it eluna as well xD
simple as this
you can change the commands if u want but it still does the same job
Yeah, thanks for the share. Not a fan of Lua myself, more so that I don’t know the language well and already know cpp and haven’t had a need for Lua personally yet.
 

sam666999s

Member
sam666999s Rep
0
0
0
Rep
0
sam666999s Vouches
0
0
0
Vouches
0
Posts
10
Likes
13
Bits
2 YEARS
2 YEARS OF SERVICE
LEVEL 1 105 XP
Yeah, thanks for the share. Not a fan of Lua myself, more so that I don’t know the language well and already know cpp and haven’t had a need for Lua personally yet.
the two languages are pretty close and eluna is very easy xD but ofc if you prefer cpp the choice is entirely yours
 

Darksoke

Well-known member
Darksoke Rep
1
0
0
Rep
1
Darksoke Vouches
0
0
0
Vouches
0
Posts
58
Likes
69
Bits
2 YEARS
2 YEARS OF SERVICE
LEVEL 2 50 XP
the two languages are pretty close and eluna is very easy xD but ofc if you prefer cpp the choice is entirely yours
not even close, LUA being line based language is more related to PYTHON than C++ or the good ol Pascal actually if I look closer, LUA it's just a Pascal on steroids.
 

sam666999s

Member
sam666999s Rep
0
0
0
Rep
0
sam666999s Vouches
0
0
0
Vouches
0
Posts
10
Likes
13
Bits
2 YEARS
2 YEARS OF SERVICE
LEVEL 1 105 XP
not even close, LUA being line based language is more related to PYTHON than C++ or the good ol Pascal actually if I look closer, LUA it's just a Pascal on steroids.
ok might be just me since i studied python and c++ in school :D
 

3,388

1,270

9,554

428

Top