Quantcast
Download
(9 Kb)
Download
Updated: 06/02/21 01:38 PM
Pictures
File Info
Compatibility:
Flames of Ambition (6.3.5)
Updated:06/02/21 01:38 PM
Created:03/21/21 11:05 AM
Monthly downloads:83
Total downloads:1,251
Favorites:9
MD5:
Story Saver
Version: 9
by: f1rex [More]
This AddOn saves history of dialogues, subtitles, books/notes and quest items. Saved data can be displayed with /storysaver command or special keybind in settings

AddOn allows you to:
  • Read saved dialogues with all options and previously selected option (if was)
  • Read saved subtitles
  • Read saved books/notes
  • Browse saved quest items
  • Show place of event on map
  • Remove event
  • Remove duplicates
  • Filter events by type
  • Fulltext search of events
  • Sort events

Dependencies:
  • LibGPS
  • LibMapPing (optional, although LibGPS requires LibMapPing)

Cautions:
  • Reading book/note from Lore Library will add new event to history

Purpose:
There are times when simply no time/desire/effort to read dialogues or notes (for example in group dungeons). In this case, you would like not to lose plot thread and be able to restore it later. Or when you just want to remember quest or phrase referenced by NPC. AddOn functionality will help you with this

Plans:
In future i will consider possibility of adding batch deletions and auto-deleting events after a certain number of days have passed
Version 9

- API version update


Version 8

- Minor fixes


Version 7

- Added automatic check for duplicates on new event


Version 6

- Changed character variables schema
- Added quest items event type
- Added manual deduplication
- Improved map functionality (thanks to Alianym)
- Minor improvements and refactoring


Version 5

- Fixed syntax error


Version 4

- Changed max size of book part to 500 characters
- Disabled account variables cleanup


Version 3

- Fixed bug when some books were saving incorrectly (thanks to tiker)


Version 2

- Fixed error during init (thanks to tiker)
Post A Reply Comment Options
Unread 06/02/21, 01:36 PM  
f1rex
AddOn Author - Click to view AddOns

Forum posts: 0
File comments: 15
Uploads: 2
Originally Posted by LoneStar2911
Until another way is implemented, what's the best way to delete entries right now?
Hey, sorry for big delay. For now best way is to filter rows you want to delete and X-E X-E X-E from the top :-)

If you have idea how you see batch-deletion functionality, please share it. I mean interface of course

Thank you
Report comment to moderator  
Reply With Quote
Unread 05/11/21, 04:32 PM  
LoneStar2911
Addon Addict
 
LoneStar2911's Avatar
Premium Member

Forum posts: 138
File comments: 578
Uploads: 0
Until another way is implemented, what's the best way to delete entries right now?
Report comment to moderator  
Reply With Quote
Unread 04/17/21, 01:30 PM  
f1rex
AddOn Author - Click to view AddOns

Forum posts: 0
File comments: 15
Uploads: 2
Originally Posted by tiker
Another thing I noticed but have checked yet...

The latest version is supposed to detect and not add duplicate events. That means that the manual option to remove duplicate events should do nothing (assuming that the latest version is the only version ever used). However, even if the latest version is the only version used, the manual button to remove duplicate events still removes some entries. That means that the automatic and manual duplicate event checking functions are behaving differently. I haven't had time to figure this out yet.
Manual deduplication is for records added before latest version. Duplicate check is simple, but not for dialogues. For dialogues it checks everything - selected option - options and order and body. If anything is not match - event is unique.
Report comment to moderator  
Reply With Quote
Unread 04/16/21, 10:07 AM  
tiker

Forum posts: 0
File comments: 25
Uploads: 0
Another thing I noticed but have checked yet...

The latest version is supposed to detect and not add duplicate events. That means that the manual option to remove duplicate events should do nothing (assuming that the latest version is the only version ever used). However, even if the latest version is the only version used, the manual button to remove duplicate events still removes some entries. That means that the automatic and manual duplicate event checking functions are behaving differently. I haven't had time to figure this out yet.
Report comment to moderator  
Reply With Quote
Unread 04/16/21, 09:45 AM  
f1rex
AddOn Author - Click to view AddOns

Forum posts: 0
File comments: 15
Uploads: 2
Originally Posted by tiker
After some testing, the first part is fixed (below) but there are still a couple of other items to figure out.

First problem (part 1): Last options (Goodbye., Nevermind, etc.) missing:
Caused by what looks to be an assumption that LUA tables are sorted when stored which is incorrect. In my case, take the following example:
Code:
                        ["1618400326-13"] = 
                        {
                            ["optionHashes"] = 
                            {
                                [2] = "1202672317-8",
                                [1] = "2237067526-30",
                            },
                            ["zoneIndex"] = 17,
                            ["y"] = 0.4008920082,
                            ["hash"] = "746736584-19",
                            ["x"] = 0.1428016038,
                        },
The second option "1202672317-8" (which is "Goodbye.") is stored first in the table. When it is displayed by the addon (interface.lua around line 310) it is assumed that the options are in order. To fix, change the following:
Code:
        for i, optionHash in pairs(optionHashes) do
            body = StorySaver:GetAccountCache(eventType, name)[optionHash]
            if i == 1 then
                optionsBody = body
            else
                optionsBody = optionsBody .. '\r\n' .. body
            end
        end
to this:
Code:
		local optionHash = nil
        for i =1, #optionHashes do
			optionHash = optionHashes[i]
            body = StorySaver:GetAccountCache(eventType, name)[optionHash]
            if i == 1 then
                optionsBody = body
            else
                optionsBody = optionsBody .. '\r\n' .. body
            end
        end
First problem (part 2):
Is unknown and may never be figured out. Some of the event tables that should have contained the strings "Goodbye.", etc. dropped the strings from the event option hash tables. Not sure if that was from the migration, from using the option to delete duplicated events, etc. But somewhere else, possibly with past versions, similar code existed but removed the strings. I deleted my saved variables file for this addon to reset it and started over. I have not been able to re-create this part of the issue yet.
Hey, before latest version options like "Goodbye" didn't save. I added it only in last version. Now i have more free time so i will look at your solution. Thank you
Report comment to moderator  
Reply With Quote
Unread 04/16/21, 06:32 AM  
tiker

Forum posts: 0
File comments: 25
Uploads: 0
After some testing, the first part is fixed (below) but there are still a couple of other items to figure out.

First problem (part 1): Last options (Goodbye., Nevermind, etc.) missing:
Caused by what looks to be an assumption that LUA tables are sorted when stored which is incorrect. In my case, take the following example:
Code:
                        ["1618400326-13"] = 
                        {
                            ["optionHashes"] = 
                            {
                                [2] = "1202672317-8",
                                [1] = "2237067526-30",
                            },
                            ["zoneIndex"] = 17,
                            ["y"] = 0.4008920082,
                            ["hash"] = "746736584-19",
                            ["x"] = 0.1428016038,
                        },
The second option "1202672317-8" (which is "Goodbye.") is stored first in the table. When it is displayed by the addon (interface.lua around line 310) it is assumed that the options are in order. To fix, change the following:
Code:
        for i, optionHash in pairs(optionHashes) do
            body = StorySaver:GetAccountCache(eventType, name)[optionHash]
            if i == 1 then
                optionsBody = body
            else
                optionsBody = optionsBody .. '\r\n' .. body
            end
        end
to this:
Code:
		local optionHash = nil
        for i =1, #optionHashes do
			optionHash = optionHashes[i]
            body = StorySaver:GetAccountCache(eventType, name)[optionHash]
            if i == 1 then
                optionsBody = body
            else
                optionsBody = optionsBody .. '\r\n' .. body
            end
        end
First problem (part 2):
Is unknown and may never be figured out. Some of the event tables that should have contained the strings "Goodbye.", etc. dropped the strings from the event option hash tables. Not sure if that was from the migration, from using the option to delete duplicated events, etc. But somewhere else, possibly with past versions, similar code existed but removed the strings. I deleted my saved variables file for this addon to reset it and started over. I have not been able to re-create this part of the issue yet.
Report comment to moderator  
Reply With Quote
Unread 04/09/21, 05:58 PM  
tiker

Forum posts: 0
File comments: 25
Uploads: 0
Found the cause of the bug. I have a partial fix so far but more testing is required.
Report comment to moderator  
Reply With Quote
Unread 04/07/21, 08:28 PM  
tiker

Forum posts: 0
File comments: 25
Uploads: 0
Found a bug.

Talking to NPCs, the last option is usually "Goodbye." or when handing in a quest, the last option is "Nevermind". Story Saver picks this up and looks fine when viewing the history. Duplicates are not created if you keep opening the same window. Once you log out and log back on, if you view the same events, the last option of all events is missing. When talking to the NPC or whatever, the events are re-added again including the last option. Log out and back on again, the last line is missing again.
Report comment to moderator  
Reply With Quote
Unread 04/07/21, 06:47 PM  
tiker

Forum posts: 0
File comments: 25
Uploads: 0
I've been testing it. Looks good so far.
Report comment to moderator  
Reply With Quote
Unread 04/04/21, 01:26 PM  
f1rex
AddOn Author - Click to view AddOns

Forum posts: 0
File comments: 15
Uploads: 2
New version

Today or tomorrow i will upload new version of addon. I have already tested it, but i think that i need more people to test character variables schema migration. If anybody wants to help me - please answer.
Report comment to moderator  
Reply With Quote
Unread 03/26/21, 05:16 AM  
tiker

Forum posts: 0
File comments: 25
Uploads: 0
Originally Posted by f1rex
Yes, thats why i added "return" before cache deletion block and broke addon. Now i have removed cache deletion block completely. At least for time. I want to add "refCount" param to account cache to resolve this problem, but i dont know what to do with users who already are using this addon on more than one character.
The issue with a reference counter is that if a character is deleted, books that character has seen will never be deleted.

You may have to forget about deleting the cache like the way it is now. Or move the events to be shared across all characters.
Report comment to moderator  
Reply With Quote
Unread 03/25/21, 02:05 PM  
f1rex
AddOn Author - Click to view AddOns

Forum posts: 0
File comments: 15
Uploads: 2
Re: Re: Re: Investigations!

Originally Posted by Alianym
Originally Posted by f1rex
Warning: Spoiler

Hey, thank you for your post. Anyway LibGPS is used for retrieve global coordinates of player. Maybe you know how to get it without LibGPS?

For now i am trying to do global refactoring of this addon. New feature is coming (deduplication). Variables structure will be changed and i write migration function, but this is dangerous, so i am trying to be careful and test all. Then i will try to do something with map.

About Librarium. It overrides SetupBook function. My AddOn does same. And Librarian too. So question is in order, who did it last. So last will receive all calls of SetupBook function. I am not advanced AddOn creator, just beginner, but i think this is normal behavior. Correct me if i am wrong. Thank you
Hi!
So I use this one for local coordinates:
Code:
GetMapPlayerPosition(unitTag)
Returns: normalizedX, normalizedZ, heading, isShownInCurrentMap
And this for world coordinates:
Code:
GetUnitWorldPosition(unitTag)
Returns: zoneId, worldX, worldY, worldZ
Regarding the Librarium and the SetupBook function, as far as I know you're right. Whoever did it last will receive the calls. I can double-check my code later, but I'm pretty sure I incorporate the SetupBook function into my new version. Which means if mine comes after yours, it'll inherit any changes you made to the function. Haven't looked at how yours does it, but I'll do some more compatibility testing later to make sure they work fine together.
Thank you for your examples.

About SetupBook override chain:
I think there is only one way to avoid conflicts with other addons. We need to check if SetupBook is already overrided by known list of addons (for example LORE_READER.SetupBook == StorySaver.OnBook) and retrieve real "core" SetupBook (YourAddon.coreSetupBook = StorySaver.coreSetupBook). It looks like workaround, but not pretty solution.
Report comment to moderator  
Reply With Quote
Unread 03/25/21, 01:44 PM  
f1rex
AddOn Author - Click to view AddOns

Forum posts: 0
File comments: 15
Uploads: 2
Originally Posted by tiker
New bug:

Events are stored per character. The cache is stored globally. When a single character removes all events for a book, it is removed from the cache. If another character has an event for the book that was deleted, you get an error when trying to read the book (obviously since the cache for the book was deleted).

Code:
bad argument #1 to 'table.concat' (table/struct expected, got nil)
stack traceback:
[C]: in function 'table.concat'
user:/AddOns/StorySaver/Interface.lua:299: in function 'StorySaverInterface:Read'
|caaaaaa<Locals> self = [table:1]{currentSortOrder = T, currentSortKey = "name", automaticallyColorRows = T}, data = [table:2]{name = "The Truth in Sequence: Volume ...", sortIndex = 95, when = "3/23/2021", eventType = 3, zoneName = "The Brass Fortress", eventId = "1616521957-3-3"}, eventData = [table:3]{name = "The Truth in Sequence: Volume ...", medium = 9, zoneIndex = 590, showTitle = T, x = 0.2623027939, y = 1.0371052354, hash = "3872171983-2490"}, title = "The Truth in Sequence: Volume ...", medium = 9, showTitle = T, hash = "3872171983-2490" </Locals>|r
user:/AddOns/StorySaver/Interface.lua:60: in function 'callback'
EsoUI/Libraries/ZO_KeybindStrip/ZO_KeybindStrip.lua:679: in function 'ZO_KeybindStrip:TryHandlingKeybindDown'
|caaaaaa<Locals> self = [table:4]{insertionId = 5, batchUpdating = F, allowDefaultExit = T}, keybind = "UI_SHORTCUT_PRIMARY", buttonOrEtherealDescriptor = ud, keybindButtonDescriptor = [table:5]{keybind = "UI_SHORTCUT_PRIMARY", addedForSceneName = "storySaver", alignment = 3} </Locals>|r
(tail call): ?
(tail call): ?
Yes, thats why i added "return" before cache deletion block and broke addon. Now i have removed cache deletion block completely. At least for time. I want to add "refCount" param to account cache to resolve this problem, but i dont know what to do with users who already are using this addon on more than one character.
Report comment to moderator  
Reply With Quote
Unread 03/25/21, 01:38 PM  
f1rex
AddOn Author - Click to view AddOns

Forum posts: 0
File comments: 15
Uploads: 2
Re: Errors

Originally Posted by LoneStar2911
Got this today upon login, after updating:

Code:
user:/AddOns/StorySaver/StorySaver.lua:71: unexpected symbol near 'for'
Code:
user:/AddOns/StorySaver/Interface.lua:357: attempt to index a nil value
stack traceback:
user:/AddOns/StorySaver/Interface.lua:357: in function 'handler'
user:/AddOns/StorySaver/Interface.lua:364: in function 'StorySaverInterface.SetupCheckableButton'
|caaaaaa<Locals> control = ud, texturePrefix = "EsoUI/Art/MainMenu/menubar_not...", handler = user:/AddOns/StorySaver/Interface.lua:344 </Locals>|r
StorySaverEventListFrameFilterAndSearchSubtitles_Initialized:3: in function '(main chunk)'
|caaaaaa<Locals> self = ud </Locals>|r
Code:
user:/AddOns/StorySaver/Interface.lua:357: attempt to index a nil value
stack traceback:
user:/AddOns/StorySaver/Interface.lua:357: in function 'handler'
user:/AddOns/StorySaver/Interface.lua:364: in function 'StorySaverInterface.SetupCheckableButton'
|caaaaaa<Locals> control = ud, texturePrefix = "EsoUI/Art/MainMenu/menubar_soc...", handler = user:/AddOns/StorySaver/Interface.lua:344 </Locals>|r
StorySaverEventListFrameFilterAndSearchDialogues_Initialized:3: in function '(main chunk)'
|caaaaaa<Locals> self = ud </Locals>|r
Code:
user:/AddOns/StorySaver/Interface.lua:357: attempt to index a nil value
stack traceback:
user:/AddOns/StorySaver/Interface.lua:357: in function 'handler'
user:/AddOns/StorySaver/Interface.lua:364: in function 'StorySaverInterface.SetupCheckableButton'
|caaaaaa<Locals> control = ud, texturePrefix = "EsoUI/Art/MainMenu/menubar_jou...", handler = user:/AddOns/StorySaver/Interface.lua:344 </Locals>|r
StorySaverEventListFrameFilterAndSearchBooks_Initialized:3: in function '(main chunk)'
|caaaaaa<Locals> self = ud </Locals>|r
Hey, fixed it. It was syntax error. Some problems with lua coding.
Report comment to moderator  
Reply With Quote
Unread 03/25/21, 06:15 AM  
tiker

Forum posts: 0
File comments: 25
Uploads: 0
New bug:

Events are stored per character. The cache is stored globally. When a single character removes all events for a book, it is removed from the cache. If another character has an event for the book that was deleted, you get an error when trying to read the book (obviously since the cache for the book was deleted).

Code:
bad argument #1 to 'table.concat' (table/struct expected, got nil)
stack traceback:
[C]: in function 'table.concat'
user:/AddOns/StorySaver/Interface.lua:299: in function 'StorySaverInterface:Read'
|caaaaaa<Locals> self = [table:1]{currentSortOrder = T, currentSortKey = "name", automaticallyColorRows = T}, data = [table:2]{name = "The Truth in Sequence: Volume ...", sortIndex = 95, when = "3/23/2021", eventType = 3, zoneName = "The Brass Fortress", eventId = "1616521957-3-3"}, eventData = [table:3]{name = "The Truth in Sequence: Volume ...", medium = 9, zoneIndex = 590, showTitle = T, x = 0.2623027939, y = 1.0371052354, hash = "3872171983-2490"}, title = "The Truth in Sequence: Volume ...", medium = 9, showTitle = T, hash = "3872171983-2490" </Locals>|r
user:/AddOns/StorySaver/Interface.lua:60: in function 'callback'
EsoUI/Libraries/ZO_KeybindStrip/ZO_KeybindStrip.lua:679: in function 'ZO_KeybindStrip:TryHandlingKeybindDown'
|caaaaaa<Locals> self = [table:4]{insertionId = 5, batchUpdating = F, allowDefaultExit = T}, keybind = "UI_SHORTCUT_PRIMARY", buttonOrEtherealDescriptor = ud, keybindButtonDescriptor = [table:5]{keybind = "UI_SHORTCUT_PRIMARY", addedForSceneName = "storySaver", alignment = 3} </Locals>|r
(tail call): ?
(tail call): ?
Last edited by tiker : 03/25/21 at 06:16 AM.
Report comment to moderator  
Reply With Quote
Post A Reply



Category Jump: