Implemented class Client::TextLink

This commit is contained in:
Uleat 2014-12-28 12:49:14 -05:00
parent 4fb1a3ff3f
commit dab3d1181e
10 changed files with 498 additions and 393 deletions

View File

@ -1,5 +1,8 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50) EQEMu Changelog (Started on Sept 24, 2003 15:50)
------------------------------------------------------- -------------------------------------------------------
== 12/28/2014 ==
Uleat: Implemented class Client::TextLink as a replacement for the dozens of individual link formatters.
== 12/27/2014 == == 12/27/2014 ==
Akkadius: Add option to automatic database upgrade script 5) Download latest Opcodes from Github Akkadius: Add option to automatic database upgrade script 5) Download latest Opcodes from Github
Trevius: (RoF2) Fixed dropping items on the ground so they go to ground level instead of camera height. Trevius: (RoF2) Fixed dropping items on the ground so they go to ground level instead of camera height.

View File

@ -11699,58 +11699,47 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
const char* equipped[EmuConstants::EQUIPMENT_SIZE] = {"Charm", "Left Ear", "Head", "Face", "Right Ear", "Neck", "Shoulders", "Arms", "Back", const char* equipped[EmuConstants::EQUIPMENT_SIZE] = {"Charm", "Left Ear", "Head", "Face", "Right Ear", "Neck", "Shoulders", "Arms", "Back",
"Left Wrist", "Right Wrist", "Range", "Hands", "Primary Hand", "Secondary Hand", "Left Wrist", "Right Wrist", "Range", "Hands", "Primary Hand", "Secondary Hand",
"Left Finger", "Right Finger", "Chest", "Legs", "Feet", "Waist", "Ammo" }; "Left Finger", "Right Finger", "Chest", "Legs", "Feet", "Waist", "Ammo" };
const ItemInst* item1 = nullptr;
const Item_Struct* item2 = nullptr; const ItemInst* inst = nullptr;
const Item_Struct* item = nullptr;
bool is2Hweapon = false; bool is2Hweapon = false;
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i)
{ std::string item_link;
Client::TextLink linker;
linker.SetLinkType(linker.linkItemInst);
linker.SetClientVersion(c->GetClientVersion());
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) {
if((i == MainSecondary) && is2Hweapon) { if((i == MainSecondary) && is2Hweapon) {
continue; continue;
} }
item1 = b->CastToBot()->GetBotItem(i); inst = b->CastToBot()->GetBotItem(i);
if(item1) if (inst)
item2 = item1->GetItem(); item = inst->GetItem();
else else
item2 = nullptr; item = nullptr;
if(!TempErrorMessage.empty()) { if(!TempErrorMessage.empty()) {
c->Message(13, "Database Error: %s", TempErrorMessage.c_str()); c->Message(13, "Database Error: %s", TempErrorMessage.c_str());
return; return;
} }
if(item2 == nullptr) { if(item == nullptr) {
c->Message(15, "I need something for my %s (Item %i)", equipped[i], i); c->Message(15, "I need something for my %s (Item %i)", equipped[i], i);
continue; continue;
} }
if((i == MainPrimary) && ((item2->ItemType == ItemType2HSlash) || (item2->ItemType == ItemType2HBlunt) || (item2->ItemType == ItemType2HPiercing))) { if((i == MainPrimary) && ((item->ItemType == ItemType2HSlash) || (item->ItemType == ItemType2HBlunt) || (item->ItemType == ItemType2HPiercing))) {
is2Hweapon = true; is2Hweapon = true;
} }
char* link_core = nullptr;
std::string link_base;
// I could not find a difference between the criteria positive code and the criteria negative code.. // I could not find a difference between the criteria positive code and the criteria negative code..
// ..so, I deleted the check (criteria: i = { MainCharm, MainRange, MainPrimary, MainSecondary, MainAmmo }) // ..so, I deleted the check (old criteria: i = { MainCharm, MainRange, MainPrimary, MainSecondary, MainAmmo })
linker.SetItemInst(inst);
c->MakeItemLink( item_link = linker.GenerateLink();
link_core,
item2,
item1->GetAugmentItemID(0),
item1->GetAugmentItemID(1),
item1->GetAugmentItemID(2),
item1->GetAugmentItemID(3),
item1->GetAugmentItemID(4),
item1->GetAugmentItemID(5)
);
if (link_core) c->Message(15, "Using %s in my %s (Item %i)", item_link.c_str(), equipped[i], i);
link_base = StringFormat("%c%s%s%c", 0x12, link_core, item2->Name, 0x12);
else
link_base = "<CLIENT VERSION ERROR>";
c->Message(15, "Using %s in my %s (Item %i)", link_base.c_str(), equipped[i], i);
safe_delete_array(link_core);
} }
} }
else { else {

View File

@ -8258,3 +8258,236 @@ void Client::SendColoredText(uint32 color, std::string message)
safe_delete(outapp); safe_delete(outapp);
} }
//
// class Client::TextLink
//
std::string Client::TextLink::GenerateLink()
{
m_Link.clear();
m_LinkBody.clear();
m_LinkText.clear();
generate_body();
generate_text();
if (m_LinkBody.length() && m_LinkText.length()) {
m_Link.append(StringFormat("%c", 0x12));
m_Link.append(m_LinkBody);
m_Link.append(m_LinkText);
m_Link.append(StringFormat("%c", 0x12));
}
if ((m_Link.length() == 0) || (m_Link.length() > 250)) {
m_Error = true;
m_Link = "<LINKER ERROR>";
_log(CHANNELS__ERROR, "TextLink::GenerateLink() failed to generate a useable text link (LinkType: %i, Lengths: {l: %u, b: %u, t: %u})",
m_LinkType, m_Link.length(), m_LinkBody.length(), m_LinkText.length());
}
return m_Link;
}
const char* Client::TextLink::GetLink()
{
if (m_Link.length() == 0)
return nullptr;
return m_Link.c_str();
}
const char* Client::TextLink::GetLinkBody()
{
if (m_LinkBody.length() == 0)
return nullptr;
return m_LinkBody.c_str();
}
const char* Client::TextLink::GetLinkText()
{
if (m_LinkText.length() == 0)
return nullptr;
return m_LinkText.c_str();
}
std::string Client::TextLink::GetLinkString()
{
if (m_Link.length() == 0)
return "";
return m_Link;
}
std::string Client::TextLink::GetLinkBodyString()
{
if (m_LinkBody.length() == 0)
return "";
return m_LinkBody;
}
std::string Client::TextLink::GetLinkTextString()
{
if (m_LinkText.length() == 0)
return "";
return m_LinkText;
}
void Client::TextLink::Reset()
{
m_LinkType = linkBlank;
m_ItemData = nullptr;
m_LootData = nullptr;
m_ItemInst = nullptr;
m_ProxyItemID = NOT_USED;
m_ProxyText = nullptr;
m_TaskUse = false;
m_Link.clear();
m_LinkBody.clear();
m_LinkText.clear();
m_ClientVersion = EQClientUnknown;
m_Error = false;
}
void Client::TextLink::generate_body()
{
enum { field_0 = 0, field_1, field_2, field_3, field_4, field_5, field_6, field_7, field_8, field_9, field_10, field_11, field_12, field_13 };
static const int field_count = 14;
static const bool field_use[_EQClientCount][field_count] = {
// 6.2: MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X"
// SoF: MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X"
// RoF: MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X"
// RoF2: MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%1X" "%04X" "%1X" "%05X" "%08X"
//(RoF2) %01x %05x %05x %05x %05x %05x %05x %05x %01x %01x %04x %01x %05x %08x
{ true, true, true, true, true, true, true, true, true, true, true, true, true, true }, // EQClientUnknown
{ true, true, true, true, true, true, true, false, false, true, true, true, false, true }, // EQClient6.2
{ true, true, true, true, true, true, true, false, false, true, true, true, false, true }, // EQClientTitanium
{ true, true, true, true, true, true, true, false, false, true, true, true, true, true }, // EQClientSoF
{ true, true, true, true, true, true, true, false, false, true, true, true, true, true }, // EQClientSoD
{ true, true, true, true, true, true, true, false, false, true, true, true, true, true }, // EQClientUnderfoot
{ true, true, true, true, true, true, true, true, false, true, true, true, true, true }, // EQClientRoF
{ true, true, true, true, true, true, true, true, true, true, true, true, true, true } // EQClientRoF2
};
/*%01X*/ uint8 unknown_0 = NOT_USED;
/*%05X*/ uint32 item_id = NOT_USED;
/*%05X*/ uint32 augment_0 = NOT_USED;
/*%05X*/ uint32 augment_1 = NOT_USED;
/*%05X*/ uint32 augment_2 = NOT_USED;
/*%05X*/ uint32 augment_3 = NOT_USED;
/*%05X*/ uint32 augment_4 = NOT_USED;
/*%05X*/ uint32 augment_5 = NOT_USED;
/*%01X*/ uint8 unknown_8 = NOT_USED;
/*%01X*/ uint8 unknown_9 = NOT_USED;
/*%04X*/ uint32 unknown_10 = NOT_USED;
/*%01X*/ uint8 unknown_11 = NOT_USED;
/*%05X*/ uint32 unknown_12 = NOT_USED;
/*%08X*/ int hash = NOT_USED;
switch (m_LinkType) {
case linkBlank:
break;
case linkItemData:
if (m_ItemData != nullptr) {
item_id = m_ItemData->ID;
// TODO: add hash call
}
break;
case linkLootItem:
if (m_LootData != nullptr) {
const Item_Struct* item_data = database.GetItem(m_LootData->item_id);
if (item_data == nullptr) { break; }
item_id = item_data->ID;
augment_0 = m_LootData->aug_1;
augment_1 = m_LootData->aug_2;
augment_2 = m_LootData->aug_3;
augment_3 = m_LootData->aug_4;
augment_4 = m_LootData->aug_5;
augment_5 = m_LootData->aug_6;
// TODO: add hash call
}
break;
case linkItemInst:
if (m_ItemInst != nullptr) {
if (m_ItemInst->GetItem() == nullptr) { break; }
item_id = m_ItemInst->GetItem()->ID;
augment_0 = m_ItemInst->GetAugmentItemID(0);
augment_1 = m_ItemInst->GetAugmentItemID(1);
augment_2 = m_ItemInst->GetAugmentItemID(2);
augment_3 = m_ItemInst->GetAugmentItemID(3);
augment_4 = m_ItemInst->GetAugmentItemID(4);
augment_5 = m_ItemInst->GetAugmentItemID(5);
// TODO: add hash call
}
break;
default:
break;
}
if (m_ProxyItemID != NOT_USED) {
item_id = m_ProxyItemID;
}
if (m_TaskUse) {
hash = 0x0000000014505DC2;
}
if (field_use[m_ClientVersion][field_0]) { m_LinkBody.append(StringFormat("%01x", unknown_0)); }
if (field_use[m_ClientVersion][field_1]) { m_LinkBody.append(StringFormat("%05x", item_id)); }
if (field_use[m_ClientVersion][field_2]) { m_LinkBody.append(StringFormat("%05x", augment_0)); }
if (field_use[m_ClientVersion][field_3]) { m_LinkBody.append(StringFormat("%05x", augment_1)); }
if (field_use[m_ClientVersion][field_4]) { m_LinkBody.append(StringFormat("%05x", augment_2)); }
if (field_use[m_ClientVersion][field_5]) { m_LinkBody.append(StringFormat("%05x", augment_3)); }
if (field_use[m_ClientVersion][field_6]) { m_LinkBody.append(StringFormat("%05x", augment_4)); }
if (field_use[m_ClientVersion][field_7]) { m_LinkBody.append(StringFormat("%05x", augment_5)); }
if (field_use[m_ClientVersion][field_8]) { m_LinkBody.append(StringFormat("%01x", unknown_8)); }
if (field_use[m_ClientVersion][field_9]) { m_LinkBody.append(StringFormat("%01x", unknown_9)); }
if (field_use[m_ClientVersion][field_10]) { m_LinkBody.append(StringFormat("%04x", unknown_10)); }
if (field_use[m_ClientVersion][field_11]) { m_LinkBody.append(StringFormat("%01x", unknown_11)); }
if (field_use[m_ClientVersion][field_12]) { m_LinkBody.append(StringFormat("%05x", unknown_12)); }
if (field_use[m_ClientVersion][field_13]) { m_LinkBody.append(StringFormat("%08x", hash)); }
}
void Client::TextLink::generate_text()
{
if (m_ProxyText != nullptr) {
m_LinkText = m_ProxyText;
return;
}
switch (m_LinkType) {
case linkBlank:
break;
case linkItemData:
if (m_ItemData != nullptr) {
m_LinkText = m_ItemData->Name;
return;
}
break;
case linkLootItem:
if (m_LootData != nullptr) {
const Item_Struct* item_data = database.GetItem(m_LootData->item_id);
if (item_data != nullptr) {
m_LinkText = item_data->Name;
return;
}
}
break;
case linkItemInst:
if (m_ItemInst != nullptr) {
if (m_ItemInst->GetItem() != nullptr) {
m_LinkText = m_ItemInst->GetItem()->Name;
return;
}
}
break;
default:
break;
}
m_LinkText = "null";
}

View File

@ -815,12 +815,57 @@ public:
void SetStats(uint8 type,int16 set_val); void SetStats(uint8 type,int16 set_val);
void IncStats(uint8 type,int16 increase_val); void IncStats(uint8 type,int16 increase_val);
void DropItem(int16 slot_id); void DropItem(int16 slot_id);
bool MakeItemLink(char* &ret_link, const Item_Struct* item, uint32 aug0=0, uint32 aug1=0, uint32 aug2=0, uint32 aug3=0, uint32 aug4=0, uint32 aug5=0, uint8 evolving=0, uint8 evolvedlevel=0);
bool MakeItemLink(char* &ret_link, const ItemInst* inst); //
bool MakeTaskLink(char* &ret_link); // class Client::TextLink
bool MakeBlankLink(char* &ret_link); //
static bool MakeBlankLink_(char* &ret_link); class TextLink {
int GetItemLinkHash(const ItemInst* inst); public:
enum LinkType { linkBlank = 0, linkItemData, linkLootItem, linkItemInst };
TextLink() { Reset(); }
void SetLinkType(LinkType linkType) { m_LinkType = linkType; }
void SetItemData(const Item_Struct* itemData) { m_ItemData = itemData; }
void SetLootData(const ServerLootItem_Struct* lootData) { m_LootData = lootData; }
void SetItemInst(const ItemInst* itemInst) { m_ItemInst = itemInst; }
void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } // mainly for saylinks..but, not limited to
void SetProxyText(const char* proxyText) { m_ProxyText = proxyText; } // overrides standard text use
void SetTaskUse() { m_TaskUse = true; }
void SetClientVersion(EQClientVersion clientVersion) { m_ClientVersion = EQLimits::ValidateClientVersion(clientVersion); }
std::string GenerateLink();
bool LinkError() { return m_Error; }
const char* GetLink(); // contains full format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
const char* GetLinkBody(); // contains format: '<LinkBody>'
const char* GetLinkText(); // contains format: '<LinkText>'
std::string GetLinkString();
std::string GetLinkBodyString();
std::string GetLinkTextString();
void Reset();
private:
void generate_body();
void generate_text();
int m_LinkType;
const Item_Struct* m_ItemData;
const ServerLootItem_Struct* m_LootData;
const ItemInst* m_ItemInst;
uint32 m_ProxyItemID;
const char* m_ProxyText;
bool m_TaskUse;
std::string m_Link;
std::string m_LinkBody;
std::string m_LinkText;
EQClientVersion m_ClientVersion;
bool m_Error;
};
int GetItemLinkHash(const ItemInst* inst); // move to Item_Struct..or make use of the pre-calculated database field
void SendItemLink(const ItemInst* inst, bool sendtoall=false); void SendItemLink(const ItemInst* inst, bool sendtoall=false);
void SendLootItemInPacket(const ItemInst* inst, int16 slot_id); void SendLootItemInPacket(const ItemInst* inst, int16 slot_id);
void SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type); void SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type);

View File

@ -2615,117 +2615,93 @@ void command_peekinv(Client *c, const Seperator *sep)
} }
Client* targetClient = c->GetTarget()->CastToClient(); Client* targetClient = c->GetTarget()->CastToClient();
const ItemInst* instMain = nullptr; const ItemInst* inst_main = nullptr;
const ItemInst* instSub = nullptr; const ItemInst* inst_sub = nullptr;
const Item_Struct* itemData = nullptr; const Item_Struct* item_data = nullptr;
char* itemLinkCore = nullptr; std::string item_link;
std::string itemLink; Client::TextLink linker;
linker.SetLinkType(linker.linkItemInst);
linker.SetClientVersion(c->GetClientVersion());
c->Message(0, "Displaying inventory for %s...", targetClient->GetName()); c->Message(0, "Displaying inventory for %s...", targetClient->GetName());
// worn // worn
for (int16 indexMain = EmuConstants::EQUIPMENT_BEGIN; (scopeWhere & peekWorn) && (indexMain <= EmuConstants::EQUIPMENT_END); ++indexMain) { for (int16 indexMain = EmuConstants::EQUIPMENT_BEGIN; (scopeWhere & peekWorn) && (indexMain <= EmuConstants::EQUIPMENT_END); ++indexMain) {
instMain = targetClient->GetInv().GetItem(indexMain); inst_main = targetClient->GetInv().GetItem(indexMain);
itemData = (instMain ? instMain->GetItem() : nullptr); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_main);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instMain);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null"); c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
c->Message((itemData == 0), "WornSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges()));
safe_delete_array(itemLinkCore);
} }
if ((scopeWhere & peekWorn) && (targetClient->GetClientVersion() >= EQClientSoF)) { if ((scopeWhere & peekWorn) && (targetClient->GetClientVersion() >= EQClientSoF)) {
instMain = targetClient->GetInv().GetItem(MainPowerSource); inst_main = targetClient->GetInv().GetItem(MainPowerSource);
itemData = (instMain ? instMain->GetItem() : nullptr); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_main);
if (itemData)
c->MakeItemLink(itemLinkCore, instMain);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), "WornSlot: %i, Item: %i (%s), Charges: %i", item_link = linker.GenerateLink();
MainPowerSource, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
MainPowerSource, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
} }
// inv // inv
for (int16 indexMain = EmuConstants::GENERAL_BEGIN; (scopeWhere & peekInv) && (indexMain <= EmuConstants::GENERAL_END); ++indexMain) { for (int16 indexMain = EmuConstants::GENERAL_BEGIN; (scopeWhere & peekInv) && (indexMain <= EmuConstants::GENERAL_END); ++indexMain) {
instMain = targetClient->GetInv().GetItem(indexMain); inst_main = targetClient->GetInv().GetItem(indexMain);
itemData = (instMain ? instMain->GetItem() : nullptr); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_main);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instMain);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), "InvSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), "InvSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_BEGIN; instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
instSub = instMain->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
itemData = (instSub ? instSub->GetItem() : nullptr); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_sub);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instSub);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
// cursor // cursor
if (scopeWhere & peekCursor) { if (scopeWhere & peekCursor) {
if (targetClient->GetInv().CursorEmpty()) { if (targetClient->GetInv().CursorEmpty()) {
linker.SetItemInst(nullptr);
item_link = linker.GenerateLink();
c->Message(1, "CursorSlot: %i, Item: %i (%s), Charges: %i", c->Message(1, "CursorSlot: %i, Item: %i (%s), Charges: %i",
MainCursor, 0, "null", 0); MainCursor, 0, item_link.c_str(), 0);
} }
else { else {
int cursorDepth = 0; int cursorDepth = 0;
for (iter_queue it = targetClient->GetInv().cursor_begin(); (it != targetClient->GetInv().cursor_end()); ++it, ++cursorDepth) { for (iter_queue it = targetClient->GetInv().cursor_begin(); (it != targetClient->GetInv().cursor_end()); ++it, ++cursorDepth) {
instMain = *it; inst_main = *it;
itemData = (instMain ? instMain->GetItem() : nullptr); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_main);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instMain);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i",
MainCursor, cursorDepth, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i",
MainCursor, cursorDepth, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_BEGIN; (cursorDepth == 0) && instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { for (uint8 indexSub = SUB_BEGIN; (cursorDepth == 0) && inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
instSub = instMain->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
itemData = (instSub ? instSub->GetItem() : nullptr); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_sub);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instSub);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(MainCursor, indexSub), MainCursor, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(MainCursor, indexSub), MainCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
} }
@ -2733,116 +2709,81 @@ void command_peekinv(Client *c, const Seperator *sep)
// trib // trib
for (int16 indexMain = EmuConstants::TRIBUTE_BEGIN; (scopeWhere & peekTrib) && (indexMain <= EmuConstants::TRIBUTE_END); ++indexMain) { for (int16 indexMain = EmuConstants::TRIBUTE_BEGIN; (scopeWhere & peekTrib) && (indexMain <= EmuConstants::TRIBUTE_END); ++indexMain) {
instMain = targetClient->GetInv().GetItem(indexMain); inst_main = targetClient->GetInv().GetItem(indexMain);
itemData = (instMain ? instMain->GetItem() : nullptr); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_main);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instMain);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), "TributeSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), "TributeSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
} }
// bank // bank
for (int16 indexMain = EmuConstants::BANK_BEGIN; (scopeWhere & peekBank) && (indexMain <= EmuConstants::BANK_END); ++indexMain) { for (int16 indexMain = EmuConstants::BANK_BEGIN; (scopeWhere & peekBank) && (indexMain <= EmuConstants::BANK_END); ++indexMain) {
instMain = targetClient->GetInv().GetItem(indexMain); inst_main = targetClient->GetInv().GetItem(indexMain);
itemData = (instMain ? instMain->GetItem() : nullptr); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_main);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instMain);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null" );
c->Message((itemData == 0), "BankSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), "BankSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_BEGIN; instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
instSub = instMain->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
itemData = (instSub ? instSub->GetItem() : nullptr); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_sub);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instSub);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
for (int16 indexMain = EmuConstants::SHARED_BANK_BEGIN; (scopeWhere & peekBank) && (indexMain <= EmuConstants::SHARED_BANK_END); ++indexMain) { for (int16 indexMain = EmuConstants::SHARED_BANK_BEGIN; (scopeWhere & peekBank) && (indexMain <= EmuConstants::SHARED_BANK_END); ++indexMain) {
instMain = targetClient->GetInv().GetItem(indexMain); inst_main = targetClient->GetInv().GetItem(indexMain);
itemData = (instMain ? instMain->GetItem() : nullptr); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_main);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instMain);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null"); c->Message((item_data == nullptr), "SharedBankSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
c->Message((itemData == 0), "SharedBankSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges()));
safe_delete_array(itemLinkCore); for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub);
for (uint8 indexSub = SUB_BEGIN; instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { item_link = linker.GenerateLink();
instSub = instMain->GetItem(indexSub);
itemData = (instSub ? instSub->GetItem() : nullptr);
itemLinkCore = nullptr;
if (itemData) c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
c->MakeItemLink(itemLinkCore, instSub); Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges()));
safe_delete_array(itemLinkCore);
} }
} }
// trade // trade
for (int16 indexMain = EmuConstants::TRADE_BEGIN; (scopeWhere & peekTrade) && (indexMain <= EmuConstants::TRADE_END); ++indexMain) { for (int16 indexMain = EmuConstants::TRADE_BEGIN; (scopeWhere & peekTrade) && (indexMain <= EmuConstants::TRADE_END); ++indexMain) {
instMain = targetClient->GetInv().GetItem(indexMain); inst_main = targetClient->GetInv().GetItem(indexMain);
itemData = (instMain ? instMain->GetItem() : nullptr); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_main);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instMain);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), "TradeSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), "TradeSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_BEGIN; instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
instSub = instMain->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
itemData = (instSub ? instSub->GetItem() : nullptr); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_sub);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instSub);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
@ -2857,34 +2798,24 @@ void command_peekinv(Client *c, const Seperator *sep)
c->Message(0, "[WorldObject DBID: %i (entityid: %i)]", objectTradeskill->GetDBID(), objectTradeskill->GetID()); c->Message(0, "[WorldObject DBID: %i (entityid: %i)]", objectTradeskill->GetDBID(), objectTradeskill->GetID());
for (int16 indexMain = MAIN_BEGIN; indexMain < EmuConstants::MAP_WORLD_SIZE; ++indexMain) { for (int16 indexMain = MAIN_BEGIN; indexMain < EmuConstants::MAP_WORLD_SIZE; ++indexMain) {
instMain = objectTradeskill->GetItem(indexMain); inst_main = objectTradeskill->GetItem(indexMain);
itemData = (instMain ? instMain->GetItem() : nullptr); item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_main);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instMain);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instMain->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), "WorldSlot: %i, Item: %i (%s), Charges: %i",
(EmuConstants::WORLD_BEGIN + indexMain), ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instMain->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), "WorldSlot: %i, Item: %i (%s), Charges: %i",
(EmuConstants::WORLD_BEGIN + indexMain), ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_BEGIN; instMain && instMain->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) { for (uint8 indexSub = SUB_BEGIN; inst_main && inst_main->IsType(ItemClassContainer) && (indexSub < EmuConstants::ITEM_CONTAINER_SIZE); ++indexSub) {
instSub = instMain->GetItem(indexSub); inst_sub = inst_main->GetItem(indexSub);
itemData = (instSub ? instSub->GetItem() : nullptr); item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
itemLinkCore = nullptr; linker.SetItemInst(inst_sub);
if (itemData) item_link = linker.GenerateLink();
c->MakeItemLink(itemLinkCore, instSub);
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, instSub->GetItem()->Name, 0x12) : "null");
c->Message((itemData == 0), " WorldBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
INVALID_INDEX, indexMain, indexSub, ((itemData == 0) ? 0 : itemData->ID), itemLink.c_str(), ((itemData == 0) ? 0 : instSub->GetCharges()));
safe_delete_array(itemLinkCore); c->Message((item_data == nullptr), " WorldBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
INVALID_INDEX, indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
} }
} }
} }
@ -5640,22 +5571,19 @@ void command_itemsearch(Client *c, const Seperator *sep)
const char *search_criteria=sep->argplus[1]; const char *search_criteria=sep->argplus[1];
const Item_Struct* item = nullptr; const Item_Struct* item = nullptr;
std::string item_link;
Client::TextLink linker;
linker.SetLinkType(linker.linkItemData);
linker.SetClientVersion(c->GetClientVersion());
if (Seperator::IsNumber(search_criteria)) { if (Seperator::IsNumber(search_criteria)) {
item = database.GetItem(atoi(search_criteria)); item = database.GetItem(atoi(search_criteria));
if (item) { if (item) {
char* link_core = nullptr; linker.SetItemData(item);
std::string link_base;
c->MakeItemLink(link_core, item); item_link = linker.GenerateLink();
if (link_core) c->Message(0, "%u: %s", item->ID, item_link.c_str());
link_base = StringFormat("%c%s%s%c", 0x12, link_core, item->Name, 0x12);
else
link_base = "<CLIENT VERSION ERROR>";
c->Message(0, "%i: %s", (int)item->ID, link_base.c_str());
safe_delete_array(link_core);
} }
else { else {
c->Message(0, "Item #%s not found", search_criteria); c->Message(0, "Item #%s not found", search_criteria);
@ -5676,19 +5604,12 @@ void command_itemsearch(Client *c, const Seperator *sep)
strupr(sName); strupr(sName);
pdest = strstr(sName, sCriteria); pdest = strstr(sName, sCriteria);
if (pdest != nullptr) { if (pdest != nullptr) {
char* link_core = nullptr; linker.SetItemData(item);
std::string link_base;
c->MakeItemLink(link_core, item); item_link = linker.GenerateLink();
if (link_core) c->Message(0, "%u: %s", item->ID, item_link.c_str());
link_base = StringFormat("%c%s%s%c", 0x12, link_core, item->Name, 0x12);
else
link_base = "<CLIENT VERSION ERROR>";
c->Message(0, "%i: %s", (int)item->ID, link_base.c_str());
safe_delete_array(link_core);
++count; ++count;
} }

View File

@ -1254,33 +1254,38 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
} }
} }
if (GetPlayerKillItem() != -1){ if (GetPlayerKillItem() != -1) {
SetPlayerKillItemID(0); SetPlayerKillItemID(0);
} }
/* Send message with item link to groups and such */ /* Send message with item link to groups and such */
char *link = 0, *link2 = 0; //just like a db query :-) Client::TextLink linker;
client->MakeItemLink(link2, inst); linker.SetLinkType(linker.linkItemInst);
MakeAnyLenString(&link, "%c" "%s" "%s" "%c", linker.SetItemInst(inst);
0x12, linker.SetClientVersion(client->GetClientVersion());
link2,
item->Name, auto item_link = linker.GenerateLink();
0x12);
safe_delete_array(link2); client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, item_link.c_str());
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, link);
if(!IsPlayerCorpse()) { if(!IsPlayerCorpse()) {
// When sending to multiple/unknown client types, we set for the highest client..
// ..which is processed when 'EQClientUnknown,' or default value, is selected.
// This should help with any current issues..or it may create more! O.o
linker.SetClientVersion(EQClientUnknown);
item_link = linker.GenerateLink();
Group *g = client->GetGroup(); Group *g = client->GetGroup();
if(g != nullptr) { if(g != nullptr) {
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), link); g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
} else { }
else {
Raid *r = client->GetRaid(); Raid *r = client->GetRaid();
if(r != nullptr) { if(r != nullptr) {
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), link); r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
} }
} }
} }
safe_delete_array(link);
} }
else { else {
SendEndLootErrorPacket(client); SendEndLootErrorPacket(client);

View File

@ -1027,7 +1027,8 @@ void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type)
} }
} }
bool Client::MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint8 evolving, uint8 evolvedlevel) { // TODO: needs clean-up to save references
bool MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint8 evolving, uint8 evolvedlevel) {
//we're sending back the entire "link", minus the null characters & item name //we're sending back the entire "link", minus the null characters & item name
//that way, we can use it for regular links & Task links //that way, we can use it for regular links & Task links
//note: initiator needs to pass us ret_link //note: initiator needs to pass us ret_link
@ -1058,7 +1059,8 @@ bool Client::MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0,
// into it further to determine the cause..but, the function is setup to accept the parameters. // into it further to determine the cause..but, the function is setup to accept the parameters.
// Note: some links appear with '00000' in front of the name..so, it's likely we need to send // Note: some links appear with '00000' in front of the name..so, it's likely we need to send
// some additional information when certain parameters are true -U // some additional information when certain parameters are true -U
switch (GetClientVersion()) { //switch (GetClientVersion()) {
switch (0) {
case EQClientRoF2: case EQClientRoF2:
// This operator contains 14 parameter masks..but, only 13 parameter values. // This operator contains 14 parameter masks..but, only 13 parameter values.
// Even so, the client link appears ok... Need to figure out the discrepancy -U // Even so, the client link appears ok... Need to figure out the discrepancy -U
@ -1134,76 +1136,6 @@ bool Client::MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0,
} }
} }
bool Client::MakeItemLink(char* &ret_link, const ItemInst *inst) {
if (!inst)
return false;
return MakeItemLink(
ret_link,
inst->GetItem(),
inst->GetAugmentItemID(0),
inst->GetAugmentItemID(1),
inst->GetAugmentItemID(2),
inst->GetAugmentItemID(3),
inst->GetAugmentItemID(4),
inst->GetAugmentItemID(5),
inst->IsEvolving(),
inst->GetEvolveLvl()
);
}
bool Client::MakeTaskLink(char* &ret_link)
{
switch (GetClientVersion()) {
case EQClientRoF2:
MakeAnyLenString(&ret_link, "00000000000000000000000000000000000000000014505DC2");
return true;
case EQClientRoF:
MakeAnyLenString(&ret_link, "0000000000000000000000000000000000000000014505DC2");
return true;
case EQClientUnderfoot:
case EQClientSoD:
case EQClientSoF:
MakeAnyLenString(&ret_link, "00000000000000000000000000000000000014505DC2");
return true;
case EQClientTitanium:
MakeAnyLenString(&ret_link, "000000000000000000000000000000014505DC2");
return true;
case EQClient62:
default:
return false;
}
}
bool Client::MakeBlankLink(char* &ret_link)
{
switch (GetClientVersion()) {
case EQClientRoF2:
MakeAnyLenString(&ret_link, "00000000000000000000000000000000000000000000000000");
return true;
case EQClientRoF:
MakeAnyLenString(&ret_link, "0000000000000000000000000000000000000000000000000");
return true;
case EQClientUnderfoot:
case EQClientSoD:
case EQClientSoF:
MakeAnyLenString(&ret_link, "00000000000000000000000000000000000000000000");
return true;
case EQClientTitanium:
MakeAnyLenString(&ret_link, "000000000000000000000000000000000000000");
return true;
case EQClient62:
default:
return false;
}
}
bool Client::MakeBlankLink_(char* &ret_link)
{
MakeAnyLenString(&ret_link, "00000000000000000000000000000000000000000000000000"); // should be same as newest/longest client in local operator
return true;
}
int Client::GetItemLinkHash(const ItemInst* inst) { int Client::GetItemLinkHash(const ItemInst* inst) {
//pre-Titanium: http://eqitems.13th-floor.org/phpBB2/viewtopic.php?t=70&postdays=0&postorder=asc //pre-Titanium: http://eqitems.13th-floor.org/phpBB2/viewtopic.php?t=70&postdays=0&postorder=asc
//Titanium: http://eqitems.13th-floor.org/phpBB2/viewtopic.php?t=145 //Titanium: http://eqitems.13th-floor.org/phpBB2/viewtopic.php?t=145
@ -1292,6 +1224,7 @@ int Client::GetItemLinkHash(const ItemInst* inst) {
return hash; return hash;
} }
// This appears to still be in use... The core of this should be incorporated into class Client::TextLink
void Client::SendItemLink(const ItemInst* inst, bool send_to_all) void Client::SendItemLink(const ItemInst* inst, bool send_to_all)
{ {
/* /*

View File

@ -512,14 +512,14 @@ void NPC::QueryLoot(Client* to)
continue; continue;
} }
char* itemLinkCore = nullptr; Client::TextLink linker;
std::string itemLink; linker.SetLinkType(linker.linkItemData);
linker.SetItemData(item);
linker.SetClientVersion(to->GetClientVersion());
to->MakeItemLink(itemLinkCore, item); auto item_link = linker.GenerateLink();
itemLink = (itemLinkCore ? StringFormat("%c%s%s%c", 0x12, itemLinkCore, item->Name, 0x12) : "null");
to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", itemLink.c_str(), item->ID, (*cur)->min_level, (*cur)->max_level); to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", item_link.c_str(), item->ID, (*cur)->min_level, (*cur)->max_level);
safe_delete_array(itemLinkCore);
} }
to->Message(0, "%i items on %s.", x, GetName()); to->Message(0, "%i items on %s.", x, GetName());

View File

@ -1227,15 +1227,18 @@ void QuestManager::settime(uint8 new_hour, uint8 new_min) {
void QuestManager::itemlink(int item_id) { void QuestManager::itemlink(int item_id) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
if (initiator) { if (initiator) {
const ItemInst* inst = database.CreateItem(item_id); const Item_Struct* item = database.GetItem(item_id);
char* link = 0; if (item == nullptr)
if (inst == nullptr)
return; return;
if (initiator->MakeItemLink(link, inst))
initiator->Message(0, "%s tells you, %c%s%s%c", owner->GetCleanName(), Client::TextLink linker;
0x12, link, inst->GetItem()->Name, 0x12); linker.SetLinkType(linker.linkItemData);
safe_delete_array(link); linker.SetItemData(item);
safe_delete(inst); linker.SetClientVersion(initiator->GetClientVersion());
auto item_link = linker.GenerateLink();
initiator->Message(0, "%s tells you, %s", owner->GetCleanName(), item_link.c_str());
} }
} }
@ -2463,17 +2466,19 @@ uint32 QuestManager::MerchantCountItem(uint32 NPCid, uint32 itemid) {
// Item Link for use in Variables - "my $example_link = quest::varlink(item_id);" // Item Link for use in Variables - "my $example_link = quest::varlink(item_id);"
const char* QuestManager::varlink(char* perltext, int item_id) { const char* QuestManager::varlink(char* perltext, int item_id) {
QuestManagerCurrentQuestVars(); QuestManagerCurrentQuestVars();
const ItemInst* inst = database.CreateItem(item_id); const Item_Struct* item = database.GetItem(item_id);
if (!inst) if (!item)
return "INVALID ITEM ID IN VARLINK"; return "INVALID ITEM ID IN VARLINK";
char* link = 0;
char* tempstr = 0; Client::TextLink linker;
// already uses Client::operator-based item link method linker.SetLinkType(linker.linkItemData);
if (initiator->MakeItemLink(link, inst)) { // make a link to the item linker.SetItemData(item);
snprintf(perltext, 250, "%c%s%s%c", 0x12, link, inst->GetItem()->Name, 0x12); if (initiator)
} linker.SetClientVersion(initiator->GetClientVersion());
safe_delete_array(link); // MakeItemLink() uses new also
safe_delete(inst); auto item_link = linker.GenerateLink();
strcpy(perltext, item_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink()
return perltext; return perltext;
} }
@ -2659,33 +2664,15 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
sayid = sayid + 500000; sayid = sayid + 500000;
//Create the say link as an item link hash //Create the say link as an item link hash
char* link_core = nullptr; Client::TextLink linker;
std::string say_link; linker.SetProxyItemID(sayid);
linker.SetProxyText(LinkName);
if (initiator)
linker.SetClientVersion(initiator->GetClientVersion());
if (initiator) { auto say_link = linker.GenerateLink();
initiator->MakeBlankLink(link_core); strcpy(Phrase, say_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink()
if (link_core)
say_link = StringFormat("%c%06x%s%s%c", 0x12, sayid, link_core, LinkName, 0x12);
else
say_link = "<CLIENT VERSION ERROR>";
}
else { // If no initiator, create an RoF2 saylink, since older clients handle RoF2 ones better than RoF2 handles older ones.
Client::MakeBlankLink_(link_core); // Note: this is a global operator
say_link = StringFormat("%c%06x%s%s%c", 0x12, sayid, link_core, LinkName, 0x12);
}
safe_delete_array(link_core);
if (say_link.length() > 250)
strcpy(Phrase, "<SAYLINK OVER-LENGTH ERROR>");
else if (say_link.length() == 0)
strcpy(Phrase, "<SAYLINK NULL-LENGTH ERROR>");
else
strcpy(Phrase, say_link.c_str());
// Why do we have '(char*)Phrase' as an argument and then return it?
// The current behavior of this function doesn't allow recursive action
return Phrase; return Phrase;
} }

View File

@ -2770,29 +2770,18 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN
} }
if(ItemID) { if(ItemID) {
char* link_core = nullptr; const Item_Struct* reward_item = database.GetItem(ItemID);
std::string reward_link;
c->MakeTaskLink(link_core); Client::TextLink linker;
linker.SetLinkType(linker.linkItemData);
linker.SetItemData(reward_item);
linker.SetClientVersion(c->GetClientVersion());
linker.SetTaskUse();
if (strlen(Tasks[TaskID]->Reward) != 0)
linker.SetProxyText(Tasks[TaskID]->Reward);
if (link_core && (strlen(Tasks[TaskID]->Reward) != 0)) { auto reward_link = linker.GenerateLink();
reward_link = StringFormat("%c%06x%s%s%c", 0x12, ItemID, link_core, Tasks[TaskID]->Reward, 0x12); RewardText += reward_link.c_str();
}
else if (link_core) {
const Item_Struct* Item = database.GetItem(ItemID);
if (Item)
reward_link = StringFormat("%c%06x%s%s%c", 0x12, ItemID, link_core, Item->Name, 0x12);
else
reward_link = "<ITEM ID ERROR>";
}
else {
reward_link = "<CLIENT VERSION ERROR>";
}
if(reward_link.length() != 0)
RewardText += reward_link.c_str();
safe_delete_array(link_core);
} }
else { else {
RewardText += Tasks[TaskID]->Reward; RewardText += Tasks[TaskID]->Reward;