Is there a way to tell if the client closed gracefully?

I’m running into an issue where it would be very useful to know if the last time the client shut down, it did so gracefully - not the result of a hard error somewhere.

Timeout, logout, exit game - all of that seems to be fine.

But sometimes the game crashes.

Can anyone think of a way to detect when this has happened reliably from within the game on the next login?

The question seems to indicate you want the game to run in full debug mode all the time with addons somehow hooked into the process. Something that’s unlikely to happen.

Maybe if you let us know the problem you are trying so solve in detail rather than the answer you want to solve you might get more options… might :wink:

local frame = CreateFrame("Frame")
frame:RegisterEvent("PLAYER_LOGIN")
frame:RegisterEvent("PLAYER_LOGOUT")
frame:SetScript("OnEvent", function(__, event)
    if event == "PLAYER_LOGIN" then
        if myAddonSavedVariable.gracefullyQuit == false then
            -- could be a crash, probably just alt-f4
        end
        myAddonSavedVariable.gracefullyQuit = false
    elseif event == "PLAYER_LOGOUT" then
        myAddonSavedVariable.gracefullyQuit = true
    end
end

Bingo.

I converged on a far more complex version of this, but this is elegant and small.

Thanks Dahk.

@Fizzlemizz

I have my answer, but I’ll give you the 50,000 foot overview.

My system uses a prefix to classify macros by context so that they can be loaded in contextual situations accurately. I’ve got a system in place that limits the length of those prefixes to 2 characters.

In order for that to work properly, the macros have to be offloaded and reloaded between characters or “load everything for my character’s class” might load in stuff for the wrong class because the game crashed while a Warrior was up and restarted on a Druid.

If I KNOW the game crashed, there’s a relatively easy fix (I just back up into part of the setup function and store the currently loaded macros and have the “wrong” macros currently loaded stored with a note to retrieve them when back on that character that you were on when it crashed).

In the event of a crash, this setting won’t actually get saved to disk as nothing is saved until after PLAYER_LOGOUT.

1 Like

Good to see.

Because what I’m altering is the macro library in game, THAT is updated immediately. Because I’m saving a list of the global macros in that library at logout, THAT is only updated on a good close.

I can test going in if they match.

If they do NOT then the client closed ungracefully.

That’s a little different from what Dahk said and you’re right, his solution might not work (I have trouble visualizing it, but I think you’re right).

But testing a persistent status set at graceful close against a persistent status that’s set in real-time does give me a solid way of checking.

It occurred to me, too, that for general use, there could be a macro set aside in the macro library where you’d store something that you could test much the same way if it comes up in a non-macro-related addon.

More to the point, in the event a crash it would have already been set to true from the previous good exit.

Unless you’re going to force a reloadui each time you set it to false.

1 Like

They are right, my method wouldn’t work because the saved variables are not going to update to reflect the changes.

I wonder if it could be done with a cvar.

If you are worried about a routine being interrupted, you could just take a more transactional approach to the workload.

  • Store all values inside a table
  • Read from that table all you wish, until its time to make a transaction
  • Start the transaction by making a duplicate of the table
  • Manipulate the duplicate table as much as you wish
  • Commit the transaction by overwriting the original table with the new one.

If anything goes wrong before the commit, it will be as if nothing happened.

I’m already doing all that, but there’s a piece I have no control over.

That “real time” update to the macro library.

If that gets interrupted, I need to know or the prefixes will need to have some element of spec, class, racial, and individual identifiers.

I think I have it handled.

It’s a little more baroque than your solution, but it looks like it’ll work.

I keep a list of all the macros “in use” and compare it to the macros in the library. If there’s a discrepancy, I back up into the addon setup routine and prompt the user appropriately.

check the value on login, then set the value to false.
set it to true on a clean logout

this way its always false unless you cleanly logout.

edit: that wont work either will it. it will keep the true value from the previous clean shutdown because the false value didnt get written in the crash.

theres no api to force an sv save is there? even if there was it would only be written to the sandbox and not the actual disk so a crash would still mean a loss of data

youd need something server side.

yeah, thats probably about the best you can do, and at least you know it will work under all circumstances.