Welcome to AC Web.
Results 1 to 6 of 6
  1. #1

    How to save a variable's state


    REGISTER! (FREE)
    Registered members see less ads
    and also gain access to other great features.
    Hey, I was wondering how to save a variable's state and not quite sure.
    For example let's say I'm working on player.h class and simply adding a variable, doesn't really matter which.
    But not on each different player reference used the variable will go back to it's initial state, how would I save the state?

    Hope I made myself clear enough, thanks.

  2. #2


    Join Date
    Nov 2015
    Location
    Library of Elchea
    Posts
    663
    Once a player logs out most of their data gets stored in the database and deleted from the world.

    The saving is done using the CHAR_UPD_CHARACTER prepared statement, you could modify this update statement and add more columns to it (and to the table you're updating), or you could write a simple OnSave hook inside a player script and save the variable that way.
    You will also have to modify the Player::OnSave method if you're saving the data through prepared statements.
    That covers saving.

    Loading is done using the CHAR_SEL_CHARACTER prepared statement, and the Player::LoadFromDB method.
    Again, you could load and store the data with a simple OnLogin hook.


    If you need further assistance, please specify exactly what you're trying to achieve.
    Last edited by Loud21; 10-31-2019 at 09:03 PM.

  3. #3
    Quote Originally Posted by Loud21 View Post
    Once a player logs out most of their data gets stored in the database and deleted from the world.

    The saving is done using the CHAR_UPD_CHARACTER prepared statement, you could modify this update statement and add more columns to it (and to the table you're updating), or you could write a simple OnSave hook inside a player script and save the variable that way.
    You will also have to modify the Player::OnSave method if you're saving the data through prepared statements.
    That covers saving.

    Loading is done using the CHAR_SEL_CHARACTER prepared statement, and the Player::LoadFromDB method.
    Again, you could load and store the data with a simple OnLogin hook.


    If you need further assistance, please specify exactly what you're trying to achieve.
    Yes I have suspected this is the case, I just didn't knew how to work on it.
    Generally, if it's somehow possible to do everything using a simple OnLogin hook that would be fantastic.

    I didn't really manage to go deep with the CHAR_UPD_CHARACTER and CHAR_SEL_CHARACTER and understand completely how it works.
    I believe a simple example would be enough for me, for example I'd want to add a boolean variable to the player, and when 'x' occurs change it's state and save it. E.g when a player logs in change the boolean to true/false and then save it.

    Can you please direct me to the correct approach?

    Thanks for the reply!

  4. #4


    Join Date
    Nov 2015
    Location
    Library of Elchea
    Posts
    663
    If you're changing the state of the bool to true every time a player logs in, there's no real need to save it, you could just keep setting it to true on each login.

    But if the onLogin example was, well, just an example, here's a simple script that will save and load the boolean.
    Code:
    class PS_bool_on_login : public PlayerScript
    {
    public:
        PS_bool_on_login() : PlayerScript("PS_bool_on_login") {}
    
        // load value
        void OnLogin(Player* player, bool firstLogin)
        {
            auto result = CharacterDatabase.PQuery("SELECT column FROM table WHERE guid=%u", player->GetGUID().GetCounter());
            if (result)
                player->m_yourBool = result->Fetch()[0].GetBool();
        }
    
        //save value
        void OnLogout(Player* player)
        {
            CharacterDatabase.PExecute("UPDATE column SET table=%u WHERE guid=%u", player->m_yourBool, player->GetCounter()->GetGUID());
        }
    };
    You will have to rename the column and table to match the names of the column and table which you're using to store the data, and also figure out a way to initially set the value of your bool when a certain event is triggered.
    You could also replace OnLogout with OnSave, however OnSave gets called a lot more often than OnLogout, so replacing these would result in more queries being ran overall.

    You could also use use this line at the place where you initially set the value of your bool, that way it will instantly save, and afterwards, only needs to be re-loaded into the world when an onLogin event is triggered.
    Code:
    CharacterDatabase.PQuery("UPDATE column SET table=%u WHERE guid=%u", player->m_yourBool, player->GetCounter()->GetGUID());

  5. #5
    Quote Originally Posted by Loud21 View Post
    If you're changing the state of the bool to true every time a player logs in, there's no real need to save it, you could just keep setting it to true on each login.

    But if the onLogin example was, well, just an example, here's a simple script that will save and load the boolean.
    Code:
    class PS_bool_on_login : public PlayerScript
    {
    public:
        PS_bool_on_login() : PlayerScript("PS_bool_on_login") {}
    
        // load value
        void OnLogin(Player* player, bool firstLogin)
        {
            auto result = CharacterDatabase.PQuery("SELECT column FROM table WHERE guid=%u", player->GetGUID().GetCounter());
            if (result)
                player->m_yourBool = result->Fetch()[0].GetBool();
        }
    
        //save value
        void OnLogout(Player* player)
        {
            CharacterDatabase.PExecute("UPDATE column SET table=%u WHERE guid=%u", player->m_yourBool, player->GetCounter()->GetGUID());
        }
    };
    You will have to rename the column and table to match the names of the column and table which you're using to store the data, and also figure out a way to initially set the value of your bool when a certain event is triggered.
    You could also replace OnLogout with OnSave, however OnSave gets called a lot more often than OnLogout, so replacing these would result in more queries being ran overall.

    You could also use use this line at the place where you initially set the value of your bool, that way it will instantly save, and afterwards, only needs to be re-loaded into the world when an onLogin event is triggered.
    Code:
    CharacterDatabase.PQuery("UPDATE column SET table=%u WHERE guid=%u", player->m_yourBool, player->GetCounter()->GetGUID());
    Splendid! Exactly what I was looking for. Obviously the save and load of the same value was just for the example's purpose, but that's enough for me to understand.

    Thanks a lot! Appreciate that.

  6. #6

    REGISTER! (FREE)
    Registered members see less ads
    and also gain access to other great features.
    if you want to favor speed and efficieny use new prepared statements and look how queryholder works for players

    loading:
    https://github.com/ElunaLuaEngine/El...ndler.cpp#L195
    https://github.com/ElunaLuaEngine/El...yer.cpp#L17712
    https://github.com/ElunaLuaEngine/El...yer.cpp#L24904

    saving:

    https://github.com/ElunaLuaEngine/El...yer.cpp#L19582
    https://github.com/ElunaLuaEngine/El...yer.cpp#L20129

    utilize the transaction in Player::SaveToDB, don't fill up the db async threads


    on other note maybe trinity should add SQLTransaction param to PlayerScript::OnSave

 

 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •