aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-09-17 15:35:20 +0200
committerShauren <shauren.trinity@gmail.com>2024-09-17 15:35:20 +0200
commit1f60e76b7f157af6a24fa3c962b59f3391b21e75 (patch)
tree3ca7f084b56c54c1d1fa91669255fc62a4a00070
parent2639bf25e77ddb5f46c1dc9ed1d992cd33026ade (diff)
Core/Commands: Refactor .additem to use typed args
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp249
1 files changed, 46 insertions, 203 deletions
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index fae41f2d995..8275a80d887 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -1153,74 +1153,57 @@ public:
return true;
}
- static bool HandleAddItemCommand(ChatHandler* handler, char const* args)
+ static bool HandleAddItemCommandHelper(ChatHandler* handler, Player* player, Player* playerTarget,
+ Variant<Hyperlink<item>, uint32, std::string_view> const& itemArg, Optional<int32> countArg,
+ Optional<std::string_view> const& bonusListIdString, Optional<uint8> itemContextArg)
{
- if (!*args)
- return false;
-
uint32 itemId = 0;
-
- if (args[0] == '[') // [name] manual form
- {
- char const* itemNameStr = strtok((char*)args, "]");
-
- if (itemNameStr && itemNameStr[0])
+ if (Hyperlink<::item> const* itemLinkData = std::get_if<Hyperlink<::item>>(&itemArg))
+ itemId = (*itemLinkData)->Item->GetId();
+ else if (uint32 const* itemIdPtr = std::get_if<uint32>(&itemArg))
+ itemId = *itemIdPtr;
+ else if (std::string_view const* itemNameText = std::get_if<std::string_view>(&itemArg))
+ {
+ std::string itemName(*itemNameText);
+ if (itemName.starts_with('['))
+ itemName.erase(0, 1);
+ if (itemName.ends_with(']'))
+ itemName.pop_back();
+
+ auto itr = std::ranges::find_if(sItemSparseStore, [&itemName](ItemSparseEntry const* sparse)
{
- std::string itemName = itemNameStr+1;
- auto itr = std::find_if(sItemSparseStore.begin(), sItemSparseStore.end(), [&itemName](ItemSparseEntry const* sparse)
- {
- for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
- if (itemName == sparse->Display[i])
- return true;
- return false;
- });
-
- if (itr == sItemSparseStore.end())
- {
- handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemNameStr+1);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- itemId = itr->ID;
- }
- else
+ for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
+ if (itemName == sparse->Display[i])
+ return true;
return false;
- }
- else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
- {
- char const* id = handler->extractKeyFromLink((char*)args, "Hitem");
- if (!id)
+ });
+
+ if (itr == sItemSparseStore.end())
+ {
+ handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemName.c_str());
+ handler->SetSentErrorMessage(true);
return false;
+ }
- itemId = Trinity::StringTo<uint32>(id).value_or(0);
+ itemId = itr->ID;
}
- char const* ccount = strtok(nullptr, " ");
-
- int32 count = 1;
-
- if (ccount)
- count = strtol(ccount, nullptr, 10);
-
+ int32 count = countArg.value_or(1);
if (count == 0)
count = 1;
std::vector<int32> bonusListIDs;
- char const* bonuses = strtok(nullptr, " ");
-
- char const* context = strtok(nullptr, " ");
// semicolon separated bonuslist ids (parse them after all arguments are extracted by strtok!)
- if (bonuses)
- for (std::string_view token : Trinity::Tokenize(bonuses, ';', false))
+ if (bonusListIdString)
+ for (std::string_view token : Trinity::Tokenize(*bonusListIdString, ';', false))
if (Optional<int32> bonusListId = Trinity::StringTo<int32>(token); bonusListId && *bonusListId)
bonusListIDs.push_back(*bonusListId);
ItemContext itemContext = ItemContext::NONE;
- if (context)
+ if (itemContextArg)
{
- itemContext = ItemContext(Trinity::StringTo<uint8>(context).value_or(0));
+ itemContext = ItemContext(*itemContextArg);
if (itemContext < ItemContext::Max)
{
std::vector<int32> contextBonuses = ItemBonusMgr::GetBonusListsForItem(itemId, itemContext);
@@ -1228,11 +1211,6 @@ public:
}
}
- Player* player = handler->GetSession()->GetPlayer();
- Player* playerTarget = handler->getSelectedPlayer();
- if (!playerTarget)
- playerTarget = player;
-
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
if (!itemTemplate)
{
@@ -1307,164 +1285,29 @@ public:
return true;
}
- static bool HandleAddItemToCommand(ChatHandler* handler, char const* args)
+ static bool HandleAddItemCommand(ChatHandler* handler,
+ Variant<Hyperlink<::item>, uint32, std::string_view> const& item, Optional<int32> countArg,
+ Optional<std::string_view> const& bonusListIdString, Optional<uint8> itemContextArg)
{
- if (!*args)
- return false;
-
Player* player = handler->GetSession()->GetPlayer();
- Player* playerTarget = nullptr;
- if (!handler->extractPlayerTarget((char*)args, &playerTarget))
- {
- handler->SetSentErrorMessage(true);
- return false;
- }
+ Player* playerTarget = handler->getSelectedPlayerOrSelf();
- char* tailArgs = strtok(nullptr, "");
- if (!tailArgs)
- return false;
-
- uint32 itemId = 0;
-
- if (tailArgs[0] == '[') // [name] manual form
- {
- char const* itemNameStr = strtok(tailArgs, "]");
-
- if (itemNameStr && itemNameStr[0])
- {
- std::string itemName = itemNameStr+1;
- auto itr = std::find_if(sItemSparseStore.begin(), sItemSparseStore.end(), [&itemName](ItemSparseEntry const* sparse)
- {
- for (LocaleConstant i = LOCALE_enUS; i < TOTAL_LOCALES; i = LocaleConstant(i + 1))
- if (itemName == sparse->Display[i])
- return true;
- return false;
- });
-
- if (itr == sItemSparseStore.end())
- {
- handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemNameStr+1);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- itemId = itr->ID;
- }
- else
- return false;
- }
- else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r
- {
- char const* id = handler->extractKeyFromLink(tailArgs, "Hitem");
- if (!id)
- return false;
-
- itemId = Trinity::StringTo<uint32>(id).value_or(0);
- }
-
- char const* ccount = strtok(nullptr, " ");
-
- int32 count = 1;
-
- if (ccount)
- count = strtol(ccount, nullptr, 10);
-
- if (count == 0)
- count = 1;
-
- std::vector<int32> bonusListIDs;
- char const* bonuses = strtok(nullptr, " ");
-
- char const* context = strtok(nullptr, " ");
-
- // semicolon separated bonuslist ids (parse them after all arguments are extracted by strtok!)
- if (bonuses)
- for (std::string_view token : Trinity::Tokenize(bonuses, ';', false))
- if (Optional<int32> bonusListId = Trinity::StringTo<int32>(token); bonusListId && *bonusListId)
- bonusListIDs.push_back(*bonusListId);
-
- ItemContext itemContext = ItemContext::NONE;
- if (context)
- {
- itemContext = ItemContext(Trinity::StringTo<uint8>(context).value_or(0));
- if (itemContext < ItemContext::Max)
- {
- std::vector<int32> contextBonuses = ItemBonusMgr::GetBonusListsForItem(itemId, itemContext);
- bonusListIDs.insert(bonusListIDs.begin(), contextBonuses.begin(), contextBonuses.end());
- }
- }
-
- ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
- if (!itemTemplate)
- {
- handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- // Subtract
- if (count < 0)
- {
- uint32 destroyedItemCount = playerTarget->DestroyItemCount(itemId, -count, true, false);
-
- if (destroyedItemCount > 0)
- {
- // output the amount of items successfully destroyed
- handler->PSendSysMessage(LANG_REMOVEITEM, itemId, destroyedItemCount, handler->GetNameLink(playerTarget).c_str());
-
- // check to see if we were unable to destroy all of the amount requested.
- uint32 unableToDestroyItemCount = -count - destroyedItemCount;
- if (unableToDestroyItemCount > 0)
- {
- // output message for the amount of items we couldn't destroy
- handler->PSendSysMessage(LANG_REMOVEITEM_FAILURE, itemId, unableToDestroyItemCount, handler->GetNameLink(playerTarget).c_str());
- }
- }
- else
- {
- // failed to destroy items of the amount requested
- handler->PSendSysMessage(LANG_REMOVEITEM_FAILURE, itemId, -count, handler->GetNameLink(playerTarget).c_str());
- }
-
- return true;
- }
-
- // Adding items
- uint32 noSpaceForCount = 0;
-
- // check space and find places
- ItemPosCountVec dest;
- InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount);
- if (msg != EQUIP_ERR_OK) // convert to possible store amount
- count -= noSpaceForCount;
+ return HandleAddItemCommandHelper(handler, player, playerTarget, item, countArg, bonusListIdString, itemContextArg);
+ }
- if (count == 0 || dest.empty()) // can't add any
+ static bool HandleAddItemToCommand(ChatHandler* handler, PlayerIdentifier const& target,
+ Variant<Hyperlink<::item>, uint32, std::string_view> const& item, Optional<int32> countArg,
+ Optional<std::string_view> const& bonusListIdString, Optional<uint8> itemContextArg)
+ {
+ Player* player = handler->GetSession()->GetPlayer();
+ if (!target.IsConnected())
{
- handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
+ handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
handler->SetSentErrorMessage(true);
return false;
}
- Item* item = playerTarget->StoreNewItem(dest, itemId, true, GenerateItemRandomBonusListId(itemId), GuidSet(), itemContext,
- bonusListIDs.empty() ? nullptr : &bonusListIDs);
-
- // remove binding (let GM give it to another player later)
- if (player == playerTarget)
- for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr)
- if (Item* item1 = player->GetItemByPos(itr->pos))
- item1->SetBinding(false);
-
- if (count > 0 && item)
- {
- player->SendNewItem(item, count, false, true);
- if (player != playerTarget)
- playerTarget->SendNewItem(item, count, true, false);
- }
-
- if (noSpaceForCount > 0)
- handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount);
-
- return true;
+ return HandleAddItemCommandHelper(handler, player, target.GetConnectedPlayer(), item, countArg, bonusListIdString, itemContextArg);
}
static bool HandleAddItemSetCommand(ChatHandler* handler, Variant<Hyperlink<itemset>, uint32> itemSetId, Optional<std::string_view> bonuses, Optional<uint8> context)