Page 1 of 1

Adding LS upon character creation.

Posted: Tue Jul 19, 2016 10:30 pm
by Masamushia
Hello,

I recently started my server and have been digging through these forums like a madman but I've reached wits end here and I could really use some help, if possible.

I am trying to add a linkshell to a new character upon creation. I was using this post as reference but I've tried at least 4 different variations of the code in this post to no avail. (viewtopic.php?f=20&t=2256)

I am not even getting any errors with this script added, just.. the linkshell is not added upon creation of the character. Is this still "up to date" and working with current builds of Darkstar Servers?

The last one I tried was:

luabaseenitty.cpp:

Code: Select all

inline int32 CLuaBaseEntity::AddLinkpearl(lua_State* L)
{
    DSP_DEBUG_BREAK_IF(m_PBaseEntity->objtype == TYPE_NPC);

    const int8* linkshellName = lua_tostring(L, 1);
    const int8* Query = "SELECT name FROM linkshells WHERE name='%s'";
    int32 ret = Sql_Query(SqlHandle, Query, linkshellName);

    if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
    {
        CCharEntity* PChar = (CCharEntity*)m_PBaseEntity;
        uint8 invSlotID = charutils::AddItem(PChar, LOC_INVENTORY, 515, 1);
        CItem* PItem = PChar->getStorage(LOC_INVENTORY)->GetItem(invSlotID);

        if (PItem != NULL)
        {
            std::string qStr = ("UPDATE char_inventory SET signature='");
            qStr += linkshellName;
            qStr += "' WHERE charid = " + std::to_string(PChar->id);
            qStr += " AND itemId = 515 AND signature = ''";
            Sql_Query(SqlHandle, qStr.c_str());

            Query = "SELECT linkshellid,color FROM linkshells WHERE name='%s'";
            ret = Sql_Query(SqlHandle, Query, linkshellName);
            if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
            {
                CItemLinkshell* PLinkshell = NULL;

                // Update item with name & color //
                int8 EncodedString[16];
                EncodeStringLinkshell((int8*)linkshellName, EncodedString);
                PItem->setSignature(EncodedString);
                ((CItemLinkshell*)PItem)->SetLSID(Sql_GetUIntData(SqlHandle, 0));
                ((CItemLinkshell*)PItem)->SetLSColor(Sql_GetIntData(SqlHandle, 1));

                // auto-equip it //
                PItem->setSubType(ITEM_LOCKED);
                PChar->equip[SLOT_LINK] = invSlotID;
                PChar->equipLoc[SLOT_LINK] = LOC_INVENTORY;
                PLinkshell = (CItemLinkshell*)PItem;
                if (PLinkshell)
                    linkshell::AddOnlineMember(PChar, PLinkshell);
            }
        }
    }

    return 1;
}
luautils.cpp:

Code: Select all

   lua_register(LuaHandle,"isValidLS",luautils::isValidLS);

Code: Select all

/************************************************************************
*                                                                       *
*  Check if a given linkshell exists by checking the name in database   *
*                                                                       *
************************************************************************/

int32 isValidLS(lua_State* L)
{
    const int8* linkshellName = lua_tostring(L, 1);
    const int8* Query = "SELECT name FROM linkshells WHERE name='%s'";
    int32 ret = Sql_Query(SqlHandle, Query, linkshellName);

    if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
    {
        lua_pushboolean(L, true);
    }
    else
    {
        lua_pushboolean(L, false);
    }
    return 1;
}
luautils.h:

Code: Select all

   int32 isValidLS(lua_State*);
player.lua:

Code: Select all

    if (isValidLS(("you_linkshell_name") then
        if not(player:hasItem(515)) then
            player:AddLinkpearl("you_linkshell_name");
        end
    end
I also tried Mizzy's version of it on page 3 but that didn't work for me either.

Re: Adding LS upon character creation.

Posted: Tue Jul 19, 2016 10:49 pm
by kjLotus
doesn't look like it'd be broken

did you create the linkshell first?
did you put it in the right place in player.lua?

Re: Adding LS upon character creation.

Posted: Wed Jul 20, 2016 10:23 pm
by Masamushia
Sorry for the late response. Okay, so I just scrapped it and tried again once more.

Everything I have listed below in code tags is 100% what is in the script.

lua.baseentity.cpp

Code: Select all

inline int32 CLuaBaseEntity::AddLinkpearl(lua_State* L)
{
    DSP_DEBUG_BREAK_IF(m_PBaseEntity->objtype == TYPE_NPC);

    const int8* linkshellName = lua_tostring(L, 1);
    const int8* Query = "SELECT name FROM linkshells WHERE name='%s'";
    int32 ret = Sql_Query(SqlHandle, Query, linkshellName);

    if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
    {
        CCharEntity* PChar = (CCharEntity*)m_PBaseEntity;
        uint8 invSlotID = charutils::AddItem(PChar, LOC_INVENTORY, 515, 1);
        CItem* PItem = PChar->getStorage(LOC_INVENTORY)->GetItem(invSlotID);

        if (PItem != NULL)
        {
            std::string qStr = ("UPDATE char_inventory SET signature='");
            qStr += linkshellName;
            qStr += "' WHERE charid = " + std::to_string(PChar->id);
            qStr += " AND itemId = 515 AND signature = ''";
            Sql_Query(SqlHandle, qStr.c_str());

            Query = "SELECT linkshellid,color FROM linkshells WHERE name='%s'";
            ret = Sql_Query(SqlHandle, Query, linkshellName);
            if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
            {
                CItemLinkshell* PLinkshell = NULL;

                // Update item with name & color //
                int8 EncodedString[16];
                EncodeStringLinkshell((int8*)linkshellName, EncodedString);
                PItem->setSignature(EncodedString);
                ((CItemLinkshell*)PItem)->SetLSID(Sql_GetUIntData(SqlHandle, 0));
                ((CItemLinkshell*)PItem)->SetLSColor(Sql_GetIntData(SqlHandle, 1));

               
          }
    }

    return 1;
}
lua_baseentity.h

Code: Select all

	int32 AddLinkpearl(lua_State* L);

luautils.cpp

Code: Select all

   lua_register(LuaHandle,"isValidLS",luautils::isValidLS);

Code: Select all

/************************************************************************
*                                                                       *
*  Check if a given linkshell exists by checking the name in database   *
*                                                                       *
************************************************************************/

int32 isValidLS(lua_State* L)
{
    const int8* linkshellName = lua_tostring(L, 1);
    const int8* Query = "SELECT name FROM linkshells WHERE name='%s'";
    int32 ret = Sql_Query(SqlHandle, Query, linkshellName);

    if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
    {
        lua_pushboolean(L, true);
    }
    else
    {
        lua_pushboolean(L, false);
    }
    return 1;
}

luatils.h

Code: Select all

   int32 isValidLS(lua_State*);
player.lua

Code: Select all

	-- Adds Percolation Linkshell
	    if (isValidLS(("you_linkshell_name") then
        if not(player:hasItem(515)) then
            player:AddLinkpearl("you_linkshell_name");
        end
    end
When I went to run the game server I got errors.

luautils::onspawn: error loading module for the player.lua. Line 327 expected a ) near then.

The above code under player.lua are lines 326-331.

I then changed it to, which I think is right...?

Code: Select all

	-- Adds Percolation Linkshell
	    if (isValidLS(("you_linkshell_name"))) then
        if not(player:hasItem(515)) then
            player:AddLinkpearl("you_linkshell_name");
        end
    end
Adding 2 more )) to close the parenthesis marks. With those changes, the errors went away in the game server. The linkshell is created and I can verify this from Navcat.
Linkshellid 3, Percolation, 65280, blank, (Null), 0, 0.

Upon creating a character and logging in I get the error luautils::ongamein: script player.lua line 327: attempt to call global 'isValidLS' (a nil value)

Okay... so I tried changing the script in luautils.h to

Code: Select all

    int32 isValidLS(lua_State* L);		// Checks if LS is valid.
Since the code in luautils.cpp had isValidLS(lua_State* L) it made sense to me to add in the * L in luautils.h. Maybe not though? I'm very new to scripting. Regardless, it didn't make a difference.

Also changed player.lua to

Code: Select all

	-- Adds Percolation Linkshell
	    if (isValidLS(("Percolation"))) then
        if not(player:hasItem(515)) then
            player:AddLinkpearl("Percolation");
        end
    end
Got the same error. Upon creating yet another character and logging in I get the error luautils::ongamein: script player.lua line 327: attempt to call global 'isValidLS' (a nil value)

Sigh. :(

Edit: You asked me if I put it in the right spot in player.lua

I place it here, underneath the "function CharCreate(player)" section:

Code: Select all

    ----- End settings.lua Perks -----

    -- SET START GIL
    --[[For some intermittent reason m_ZoneList ends up empty on characters, which is
    possibly also why they lose key items.  When that happens, CharCreate will be run and
    they end up losing their gil to the code below.  Added a conditional to hopefully
    prevent that until the bug is fixed.  Used the if instead of addGil to prevent abuse
    on servers with very high values of START_GIL, I guess.]]
    if (player:getGil() < START_GIL) then
       player:setGil(START_GIL);
    end

    -- ADD ADVENTURER COUPON
    player:addItem(0x218);

    --SET TITLE
    player:addTitle(NEW_ADVENTURER);
	
	-- Adds Percolation Linkshell
	    if (isValidLS(("Percolation"))) then
        if not(player:hasItem(515)) then
            player:AddLinkpearl("Percolation");
        end
    end
	
    -- Needs Moghouse Intro
    player:setVar("MoghouseExplication",1);
   end

function onPlayerLevelUp(player)
end

Re: Adding LS upon character creation.

Posted: Wed Jul 20, 2016 10:53 pm
by kjLotus
did you rebuild the server?

registering the isValidLS function looks right, but it's not going to do anything if you don't rebuild the server

Re: Adding LS upon character creation.

Posted: Sat Jul 23, 2016 10:06 am
by TeoTwawki
Just an fyi:

Code: Select all

if (isValidLS(("Percolation"))) then
should be

Code: Select all

if (isValidLS("Percolation")) then
because that particular prob with the parenthesis wasn't that you needed 2 more, ist that you had to many on the wrong side.

That won't effect the problem of it being nil. thats telling you the function straight up didn't exist when you tried to call it.

Re: Adding LS upon character creation.

Posted: Mon Aug 22, 2016 7:49 pm
by sekigah
Hey guys. Sorry if this is a necro but I used the code and it compiled and added the LS to the new player.

The problem is the color is off and when they equip it, the LS errors out.

Any ideas?

I'm assuming its found here:

Code: Select all

inline int32 CLuaBaseEntity::AddLinkpearl(lua_State* L)
{
    DSP_DEBUG_BREAK_IF(m_PBaseEntity->objtype == TYPE_NPC);

    const int8* linkshellName = lua_tostring(L, 1);
    const int8* Query = "SELECT name FROM linkshells WHERE name='%s'";
    int32 ret = Sql_Query(SqlHandle, Query, linkshellName);

    if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
    {
        CCharEntity* PChar = (CCharEntity*)m_PBaseEntity;
        uint8 invSlotID = charutils::AddItem(PChar, LOC_INVENTORY, 515, 1);
        CItem* PItem = PChar->getStorage(LOC_INVENTORY)->GetItem(invSlotID);

        if (PItem != NULL)
        {
            std::string qStr = ("UPDATE char_inventory SET signature='");
            qStr += linkshellName;
            qStr += "' WHERE charid = " + std::to_string(PChar->id);
            qStr += " AND itemId = 515 AND signature = ''";
            Sql_Query(SqlHandle, qStr.c_str());

            Query = "SELECT linkshellid,color FROM linkshells WHERE name='%s'";
            ret = Sql_Query(SqlHandle, Query, linkshellName);
            if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0 && Sql_NextRow(SqlHandle) == SQL_SUCCESS)
            {
                CItemLinkshell* PLinkshell = NULL;

                // Update item with name & color //
                int8 EncodedString[16];
                EncodeStringLinkshell((int8*)linkshellName, EncodedString);
                PItem->setSignature(EncodedString);
                ((CItemLinkshell*)PItem)->SetLSID(Sql_GetUIntData(SqlHandle, 0));
                ((CItemLinkshell*)PItem)->SetLSColor(Sql_GetIntData(SqlHandle, 1));

               
          }
    }

    return 1;
}
The line in question being:

Code: Select all

                ((CItemLinkshell*)PItem)->SetLSColor(Sql_GetIntData(SqlHandle, 1));
With the way the SQL table is structured, I'm assuming this is pulling from the wrong column. Assuming this should be 3?

Re: Adding LS upon character creation.

Posted: Mon Aug 22, 2016 8:17 pm
by kjLotus
that's saying "select the 1st column from the query" (zero based, of course), and the query's columns are "linkshellid, color" - so 1 is correct

Re: Adding LS upon character creation.

Posted: Wed Aug 24, 2016 11:04 am
by sekigah
I guess there was a DB update because my columns are:

linkshellid, name, color, poster, message, messagetime, postrights

https://github.com/DarkstarProject/dark ... shells.sql

So it should be this in my case?

((CItemLinkshell*)PItem)->SetLSColor(Sql_GetIntData(SqlHandle, 2));

Re: Adding LS upon character creation.

Posted: Wed Aug 24, 2016 7:23 pm
by kjLotus
No, it's not the index of the columns of the table, it's the index of the column of the sql query "SELECT linkshellid,color FROM linkshells WHERE name='%s'"