nwnxee / unified

Binaries available under the Releases tab on Github
https://nwnxee.github.io/unified
GNU General Public License v3.0
131 stars 92 forks source link

NWNX_Creature_RunEquip Segfaults if called right after item creation #1663

Open Aschent89 opened 1 year ago

Aschent89 commented 1 year ago

This server crash seems to be new as of .35+ as my use of NWNX_Creature_RunEquip had no issues prior to upgrading.

In practice, I would run NWNX_Creature_RunEquip in a few spots similar to below:

        object oOriginal = GetItemInSlot(INVENTORY_SLOT_CLOAK, oPC);
        object oNew      = CopyItemAndModify(oOriginal, ITEM_APPR_TYPE_SIMPLE_MODEL, 0, nNewValue, TRUE);
        if (!GetIsObjectValid(oNew))
        {
            SendMessageToPC(oPC, "Something went wrong, aborting.");
            return;
        }
        DestroyObject(oOriginal);
                // NWNX_Creature_RunEquip HERE
        SendMessageToPC(oPC, "Appearance #: " + IntToString(nNewValue));

Doing the above would result in a server crash (backtrace below). The temp solution to this is to lock the NWNX_Creature_RunEquip behind a separate function that includes a DelayCommand:

void _equip(object oPC, object oItem, int nSlot) { NWNX_Creature_RunEquip(oPC, oItem, nSlot); }

Backtrace:

   /home/aschent/unified/Binaries/NWNX_Core.so(_ZN7NWNXLib8Platform13GetStackTraceB5cxx11Eh+0x64) [0x7f802565d484]
    /home/aschent/unified/Binaries/NWNX_Core.so(nwnx_signal_handler+0xd7) [0x7f802560cfc7]
    /lib/x86_64-linux-gnu/libc.so.6(+0x430c0) [0x7f80250730c0]
    ./nwserver-linux(_ZN8CNWSItem9GetWeightEv+0x9) [0x7f8025bdab79]
    ./nwserver-linux(_ZN15CItemRepository23CalculateContentsWeightEv+0x80) [0x7f8025bdac40]
    ./nwserver-linux(_ZN12CNWSCreature25ComputeTotalWeightCarriedEv+0x1b) [0x7f8025b2aadb]
    ./nwserver-linux(_ZN12CNWSCreature22UpdateEncumbranceStateEi+0x19c) [0x7f8025b68a4c]
    ./nwserver-linux(_ZN12CNWSCreature11AcquireItemEPP8CNWSItemjjhhii+0x102) [0x7f8025b6a432]
    /home/aschent/unified/Binaries/NWNX_Events.so(+0x73b95) [0x7f801cbe9b95]
    ./nwserver-linux(_ZN25CNWVirtualMachineCommands31ExecuteCommandCopyItemAndModifyEii+0x2f2) [0x7f8025d6aeb2]
    ./nwserver-linux(_ZN15CVirtualMachine11ExecuteCodeEPiSt10shared_ptrI9DataBlockEP31CVirtualMachineDebuggingContext+0x143d) [0x7f80260edb3d]
    ./nwserver-linux(_ZN15CVirtualMachine13RunScriptFileEi+0x9d) [0x7f80260eec2d]
    ./nwserver-linux(_ZN15CVirtualMachine9RunScriptEP10CExoStringjii+0x16d) [0x7f80260eef9d]
    ./nwserver-linux(_ZN25CNWVirtualMachineCommands27ExecuteCommandExecuteScriptEii+0xb0) [0x7f8025d332a0]
    ./nwserver-linux(_ZN15CVirtualMachine11ExecuteCodeEPiSt10shared_ptrI9DataBlockEP31CVirtualMachineDebuggingContext+0x143d) [0x7f80260edb3d]
    ./nwserver-linux(_ZN15CVirtualMachine13RunScriptFileEi+0x9d) [0x7f80260eec2d]
    ./nwserver-linux(_ZN15CVirtualMachine9RunScriptEP10CExoStringjii+0x16d) [0x7f80260eef9d]
    ./nwserver-linux(_ZN11CNWSMessage28HandlePlayerToServerNuiEventEP10CNWSPlayerh+0x4ba) [0x7f8025d1043a]
    ./nwserver-linux(_ZN11CNWSMessage27HandlePlayerToServerMessageEjPhj+0x160) [0x7f8025d12c90]
    ./nwserver-linux(_ZN21CServerExoAppInternal13HandleMessageEjPhji+0x9f) [0x7f8025c7a37f]
Darsiniux commented 1 month ago

What about using vanilla nwn functions to equip?

    int iSlots = INVENTORY_SLOT_HEAD & INVENTORY_SLOT_BOOTS & INVENTORY_SLOT_ARMS & INVENTORY_SLOT_BELT & INVENTORY_SLOT_CARMOUR &
                 INVENTORY_SLOT_CHEST & INVENTORY_SLOT_CLOAK & INVENTORY_SLOT_CWEAPON_B & INVENTORY_SLOT_CWEAPON_L & INVENTORY_SLOT_CWEAPON_R &
                 INVENTORY_SLOT_LEFTHAND & INVENTORY_SLOT_LEFTRING & INVENTORY_SLOT_NECK & INVENTORY_SLOT_RIGHTRING & INVENTORY_SLOT_RIGHTHAND;
    object oSlot = GetItemInSlot(iSlots, GetEnteringObject());

    // Unequip & Re-Equip all items to fix nwnx_haste bug.
    AssignCommand(oPC, ActionUnequipItem(oSlot));
    AssignCommand(oPC, ActionEquipItem(oSlot, iSlots));