CUser::AddApplySkillBuff(user, skill);
auto charName = args.at(0); // character name
auto skillId = std::stoi(args.at(1));
auto skillLevel = std::stoi(args.at(2));
auto user = CWorld::FindUser(charName.c_str());
if (!user) {
std::stringstream output_format;
output_format << "Character " << charName << " not found";
output = output_format.str();
return 0; // Exit if user is not found
}
auto skill = CGameData::GetSkillInfo(skillId, skillLevel);
if (!skill) {
std::stringstream output_format;
output_format << "Skill with ID " << skillId << " and level " << skillLevel << " not found";
output = output_format.str();
return 0; // Exit if skill is not found
}
// Prepare the SkillUseOutgoing packet
SkillUseOutgoing outgoing{};
outgoing.senderId = user->connection.object.id;
outgoing.targetId = user->connection.object.id;
outgoing.skillId = skill->skillId;
outgoing.skillLv = skill->skillLv;
// Send the skill usage packet to the user
Helpers::Send(user, &outgoing, sizeof(SkillUseOutgoing));
// Apply the skill buff
CUser::AddApplySkillBuff(user, skill);
EnterCriticalSection(&user->applySkills.cs);
// Start from the first node after the sentinel tail
auto node = user->applySkills.sentinel.tail;
node = node->next; // Move to the first node
user->applySkills.sentinel.head = node;
int index = 0; // Index to track the skill position in the list
bool skillFound = false;
while (node && node != user->applySkills.sentinel.tail)
{
auto skillIn = reinterpret_cast<CSkill*>(node);
// Check if the skill matches
if (skillIn->skillId == skill->skillId && skillIn->skillLv == skill->skillLv)
{
skillFound = true;
// Correctly set the id for addBuff
SkillApplyOutgoing addBuff{};
addBuff.id = index; // Send the matching skill's index
addBuff.skillId = skill->skillId;
addBuff.skillLv = skill->skillLv;
Helpers::Send(user, &addBuff, sizeof(SkillApplyOutgoing));
break;
}
node = node->next; // Move to the next node
user->applySkills.sentinel.head = node;
index++; // Increment index
}
LeaveCriticalSection(&user->applySkills.cs);
if (!skillFound)
{
std::stringstream output_format;
output_format << "Skill " << skillId << " (Level " << skillLevel << ") could not be applied for " << charName;
output = output_format.str();
return 0; // Exit after reporting error
}
// Output a success message
std::stringstream output_format;
output_format << "Skill " << skillId << " (Level " << skillLevel << ") triggered for " << charName;
output = output_format.str();
return 0;
Skill 287 (Level 1) could not be applied for Character
I don't see it sending that packet.Will this sends Packet 0x50D on its own or do I have to do it by myself?
auto charName = args.at(0); // character name
auto skillId = std::stoi(args.at(1));
auto skillLevel = std::stoi(args.at(2));
auto user = CWorld::FindUser(charName.c_str());
if (!user) {
std::stringstream output_format;
output_format << "Character " << charName << " not found";
output = output_format.str();
return 0; // Exit if user is not found
}
auto skill = CGameData::GetSkillInfo(skillId, skillLevel);
if (!skill) {
std::stringstream output_format;
output_format << "Skill with ID " << skillId << " and level " << skillLevel << " not found";
output = output_format.str();
return 0; // Exit if skill is not found
}
if (!CUser::UseItemSkill(user, skill)) {
std::stringstream output_format;
output_format << "Skill " << skillId << " (Level " << skillLevel << ") could not be applied for " << charName;
output = output_format.str();
return 0; // Exit after reporting error
}
// Output a success message
std::stringstream output_format;
output_format << "Skill " << skillId << " (Level " << skillLevel << ") triggered for " << charName;
output = output_format.str();
return 0;
void item_remake_handler(CUser* user, ItemRemakeIncoming* incoming)
{
}
pushad
push esi // packet
push edi // user
call item_remake_handler
add esp,0x8
popad
jmp u0x47A018
如何操作?我以为该文件已附加到我的上一条消息中。
我现在可以把它放进去并使用它吗?我们还需要调试吗?[用户=129]@nurum[/用户]
这是我删除之前 repo 中的源代码。
void item_remake_handler(CUser* user, ItemRemakeIncoming* incoming) {
// Check items in the specified slots
auto* item1 = user->inventory[incoming->bag1][incoming->slot1];
auto* item2 = user->inventory[incoming->bag2][incoming->slot2];
auto* item3 = user->inventory[incoming->bag3][incoming->slot3];
// Ensure all items are present
if (!item1 || !item2 || !item3) {
Helpers::SendNotice("LOG: One or more items are missing.");
return;
}
// Ensure all items have the same ID
if (item1->itemInfo->itemId != item2->itemInfo->itemId ||
item1->itemInfo->itemId != item3->itemInfo->itemId) {
Helpers::SendNotice("LOG: Items do not match.");
return;
}
// Handle specific item creation
ItemInfo* resultItem = nullptr;
if (item1->itemInfo->itemId == 72001) {
int resultType = 72;
int resultTypeId = 2;
resultItem = CGameData::GetItemInfo(resultType, resultTypeId);
if (resultItem) {
std::string resultLog = "LOG: Created result item with Type: " +
std::to_string(resultType) + ", TypeID: " + std::to_string(resultTypeId);
Helpers::SendNotice(resultLog.c_str());
}
else {
Helpers::SendNotice("LOG: Failed to create result item.");
return;
}
}
else {
Helpers::SendNotice("LOG: Item ID does not match special handling conditions.");
ItemRemakeOutgoing outgoing{};
outgoing.result = ItemRemakeResult::Failure;
Helpers::Send(user, &outgoing, sizeof(ItemRemakeOutgoing));
return;
}
uint8_t bag = 1; // Result item bag
uint8_t slot = -1; // Result item slot
while (bag <= user->bagsUnlocked) {
slot = Helpers::GetFreeItemSlot(user, bag);
if (slot != -1) {
if (CUser::ItemCreate(user, resultItem, 1)) {
break;
}
}
++bag;
}
// Validate the resulting item placement
auto* findResult = user->inventory[bag][slot];
if (!findResult) {
Helpers::SendNotice("LOG: Result item was not created.");
return;
}
// Transfer the details of the first item to the result
findResult->gems = item1->gems;
findResult->craftName = item1->craftName;
findResult->quality = item1->quality;
// Assign the findResult back to the inventory
user->inventory[bag][slot] = findResult;
//Log the inventory[bag][slot] if already have its gems, craftname and quality
Helpers::ItemRemove(user, item1->itemInfo->itemId, 1);
Helpers::ItemRemove(user, item2->itemInfo->itemId, 1);
Helpers::ItemRemove(user, item3->itemInfo->itemId, 1);
// Send outgoing packet with result details
ItemRemakeOutgoing outgoing{};
outgoing.result = ItemRemakeResult::Success;
outgoing.bag = bag;
outgoing.slot = slot;
outgoing.type = resultItem->type;
outgoing.typeId = resultItem->typeId;
outgoing.gems = findResult->gems;
outgoing.count = findResult->count;
outgoing.craftName = findResult->craftName;
Helpers::Send(user, &outgoing, sizeof(ItemRemakeOutgoing));
GameLogItemRemakeIncoming remakeLog(user, findResult, item1->uniqueId, item2->uniqueId, item3->uniqueId);
Helpers::SendGameLog(&remakeLog, sizeof(GameLogItemRemakeIncoming));
Helpers::SendNotice("LOG: Handler completed successfully.");
}
Can I ask why the item gems, craftname and quality is not persistent?