From e23f40e343103b01d650a3cb6947785372b4fa9c Mon Sep 17 00:00:00 2001 From: Yugang Zhou Date: Wed, 28 May 2025 22:18:27 +0800 Subject: [PATCH 1/3] feat: Add profile management functionality to NotGrid - Commands: /ng profile save|load|delete , /ng profile list --- README.md | 4 +++ core.lua | 1 + notgrid.toc | 2 +- options.lua | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b806c2a..722eb9e 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ NotGrid is a party and raid frame addon for Vanilla World of Warcraft (1.12.1). Use */notgrid* or */ng* to show the config menu. Use */notgrid grid* to generate a style similar to the original grid. Use */notgrid reset* to restore the default settings. +Use */notgrid profile save * to save current settings as a profile. +Use */notgrid profile load * to load a saved profile. +Use */notgrid profile delete * to delete a saved profile. +Use */notgrid profile list* to show all available profiles. Use / for separating multiple Buffs/Debuffs to track on one icon. Use */ngcast spellname(Rank X)* in macros for mouseover casting. diff --git a/core.lua b/core.lua index affc2a8..b7219f2 100644 --- a/core.lua +++ b/core.lua @@ -1,6 +1,7 @@ local L = AceLibrary("AceLocale-2.2"):new("NotGrid") NotGrid = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0") NotGridOptions = {} -- After the addon is fully initialized WoW will fill this up with its saved variables if any +NotGridProfiles = NotGridProfiles or {} -- This will store the different configuration profiles function NotGrid:OnInitialize() self.HealComm = AceLibrary("HealComm-1.0") diff --git a/notgrid.toc b/notgrid.toc index 546ef94..31076b0 100644 --- a/notgrid.toc +++ b/notgrid.toc @@ -2,7 +2,7 @@ ## Title: NotGrid |cff7fff7f -Ace2-|r ## Notes: It's Not Grid ## Notes-ruRU: Это не Grid -## SavedVariablesPerCharacter: NotGridOptions +## SavedVariablesPerCharacter: NotGridOptions, NotGridProfiles Libs\AceLibrary\AceLibrary.lua Libs\AceLocale-2.2\AceLocale-2.2.lua diff --git a/options.lua b/options.lua index 4acddb9..11cff71 100644 --- a/options.lua +++ b/options.lua @@ -1,5 +1,20 @@ local L = AceLibrary("AceLocale-2.2"):new("NotGrid") +local function deepcopy(orig) + local orig_type = type(orig) + local copy + if orig_type == 'table' then + copy = {} + for orig_key, orig_value in next, orig, nil do + copy[deepcopy(orig_key)] = deepcopy(orig_value) + end + setmetatable(copy, deepcopy(getmetatable(orig))) + else -- number, string, boolean, function + copy = orig + end + return copy +end + local DefaultOptions = { ["version"] = 1.132, -- will be the commit number from now on. ["versionchecking"] = true, @@ -159,6 +174,73 @@ function SlashCmdList.NOTGRID(msg, editbox) NotGrid.o.colorunithealthbarbyclass = false NotGrid.o.colorunithealthbarbgbyclass = true ReloadUI() + elseif type(msg) == "string" and string.find(msg, "^profile") then + local _, args = string.match(msg, "^(profile)%s*(.*)") + local action = "list" + local profileName = nil + + if args and args ~= "" then + local words = {} + for word in string.gmatch(args, "%S+") do + table.insert(words, word) + end + + if words[1] then + action = words[1] + profileName = words[2] + end + end + + if action == "save" then + if profileName then + NotGridProfiles = NotGridProfiles or {} + NotGridProfiles[profileName] = deepcopy(NotGrid.o) + DEFAULT_CHAT_FRAME:AddMessage("NotGrid profile '" .. profileName .. "' saved.") + else + DEFAULT_CHAT_FRAME:AddMessage("Usage: /ng profile save ") + end + elseif action == "load" then + if profileName then + if NotGridProfiles and NotGridProfiles[profileName] then + for k in pairs(NotGrid.o) do NotGrid.o[k] = nil end + for k, v in pairs(NotGridProfiles[profileName]) do NotGrid.o[k] = deepcopy(v) end + NotGrid:SetDefaultOptions() + ReloadUI() + DEFAULT_CHAT_FRAME:AddMessage("NotGrid profile '" .. profileName .. "' loaded.") + else + DEFAULT_CHAT_FRAME:AddMessage("NotGrid profile '" .. profileName .. "' not found.") + end + else + DEFAULT_CHAT_FRAME:AddMessage("Usage: /ng profile load ") + end + elseif action == "delete" then + if profileName then + if NotGridProfiles and NotGridProfiles[profileName] then + NotGridProfiles[profileName] = nil + DEFAULT_CHAT_FRAME:AddMessage("NotGrid profile '" .. profileName .. "' deleted.") + else + DEFAULT_CHAT_FRAME:AddMessage("NotGrid profile '" .. profileName .. "' not found.") + end + else + DEFAULT_CHAT_FRAME:AddMessage("Usage: /ng profile delete ") + end + elseif action == "list" then + NotGridProfiles = NotGridProfiles or {} + local profileCount = 0 + local profileList = "" + for name in pairs(NotGridProfiles) do + if profileList ~= "" then profileList = profileList .. ", " end + profileList = profileList .. name + profileCount = profileCount + 1 + end + if profileCount > 0 then + DEFAULT_CHAT_FRAME:AddMessage("Available NotGrid profiles: " .. profileList) + else + DEFAULT_CHAT_FRAME:AddMessage("No NotGrid profiles saved.") + end + else + DEFAULT_CHAT_FRAME:AddMessage("Invalid profile action. Usage: /ng profile [save|load|delete ] or /ng profile list") + end else NotGridOptionsMenu:Show() end From f7d195f34bbb6e4de6ffa3185a4c9446434fa6e3 Mon Sep 17 00:00:00 2001 From: Yugang Zhou Date: Wed, 9 Jul 2025 15:14:31 +0800 Subject: [PATCH 2/3] feat: Convert profiles from per-character to account-wide - Move NotGridProfiles from SavedVariablesPerCharacter to SavedVariables - Profiles are now shared across all characters on the same account - Update documentation to reflect account-wide functionality - Maintains backward compatibility for existing profile commands --- README.md | 8 ++++---- notgrid.toc | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 722eb9e..c0fcdd9 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@ NotGrid is a party and raid frame addon for Vanilla World of Warcraft (1.12.1). Use */notgrid* or */ng* to show the config menu. Use */notgrid grid* to generate a style similar to the original grid. Use */notgrid reset* to restore the default settings. -Use */notgrid profile save * to save current settings as a profile. -Use */notgrid profile load * to load a saved profile. -Use */notgrid profile delete * to delete a saved profile. -Use */notgrid profile list* to show all available profiles. +Use */notgrid profile save * to save current settings as a profile (account-wide). +Use */notgrid profile load * to load a saved profile (account-wide). +Use */notgrid profile delete * to delete a saved profile (account-wide). +Use */notgrid profile list* to show all available profiles (account-wide). Use / for separating multiple Buffs/Debuffs to track on one icon. Use */ngcast spellname(Rank X)* in macros for mouseover casting. diff --git a/notgrid.toc b/notgrid.toc index 31076b0..9fbed1d 100644 --- a/notgrid.toc +++ b/notgrid.toc @@ -2,7 +2,8 @@ ## Title: NotGrid |cff7fff7f -Ace2-|r ## Notes: It's Not Grid ## Notes-ruRU: Это не Grid -## SavedVariablesPerCharacter: NotGridOptions, NotGridProfiles +## SavedVariablesPerCharacter: NotGridOptions +## SavedVariables: NotGridProfiles Libs\AceLibrary\AceLibrary.lua Libs\AceLocale-2.2\AceLocale-2.2.lua From 70d05ed0084833c5e1c84d04c46795929c87d042 Mon Sep 17 00:00:00 2001 From: Yugang Zhou Date: Mon, 21 Jul 2025 10:28:59 +0800 Subject: [PATCH 3/3] fix: Improve profile system reliability and safety - Move NotGridProfiles initialization to OnEnable for safer timing - Add validation checks to all profile operations (save/load/delete/list) - Remove potentially unsafe profile table resets during operations - Remove unused migration function - Add error handling for uninitialized profile system - Clean up user feedback messages --- core.lua | 7 ++++++- options.lua | 26 ++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/core.lua b/core.lua index b7219f2..785ff89 100644 --- a/core.lua +++ b/core.lua @@ -1,7 +1,7 @@ local L = AceLibrary("AceLocale-2.2"):new("NotGrid") NotGrid = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0") NotGridOptions = {} -- After the addon is fully initialized WoW will fill this up with its saved variables if any -NotGridProfiles = NotGridProfiles or {} -- This will store the different configuration profiles +-- NotGridProfiles will be initialized safely in OnEnable after saved variables are loaded function NotGrid:OnInitialize() self.HealComm = AceLibrary("HealComm-1.0") @@ -21,6 +21,11 @@ function NotGrid:OnInitialize() end function NotGrid:OnEnable() + -- Initialize profiles after saved variables are loaded + if not NotGridProfiles then + NotGridProfiles = {} + end + self.o = NotGridOptions -- Need to wait for addon to be fully initialized and saved variables loaded before I set this self:SetDefaultOptions() -- if NotGridOptions is empty(no saved variables) this will fill it up with defaults self:DoDropDown() diff --git a/options.lua b/options.lua index 11cff71..72c9464 100644 --- a/options.lua +++ b/options.lua @@ -193,7 +193,11 @@ function SlashCmdList.NOTGRID(msg, editbox) if action == "save" then if profileName then - NotGridProfiles = NotGridProfiles or {} + -- Validate that profiles table exists before saving + if not NotGridProfiles then + DEFAULT_CHAT_FRAME:AddMessage("NotGrid: Error - Profile system not initialized!") + return + end NotGridProfiles[profileName] = deepcopy(NotGrid.o) DEFAULT_CHAT_FRAME:AddMessage("NotGrid profile '" .. profileName .. "' saved.") else @@ -201,7 +205,12 @@ function SlashCmdList.NOTGRID(msg, editbox) end elseif action == "load" then if profileName then - if NotGridProfiles and NotGridProfiles[profileName] then + -- Validate that profiles table exists before loading + if not NotGridProfiles then + DEFAULT_CHAT_FRAME:AddMessage("NotGrid: Error - Profile system not initialized!") + return + end + if NotGridProfiles[profileName] then for k in pairs(NotGrid.o) do NotGrid.o[k] = nil end for k, v in pairs(NotGridProfiles[profileName]) do NotGrid.o[k] = deepcopy(v) end NotGrid:SetDefaultOptions() @@ -215,7 +224,12 @@ function SlashCmdList.NOTGRID(msg, editbox) end elseif action == "delete" then if profileName then - if NotGridProfiles and NotGridProfiles[profileName] then + -- Validate that profiles table exists before deleting + if not NotGridProfiles then + DEFAULT_CHAT_FRAME:AddMessage("NotGrid: Error - Profile system not initialized!") + return + end + if NotGridProfiles[profileName] then NotGridProfiles[profileName] = nil DEFAULT_CHAT_FRAME:AddMessage("NotGrid profile '" .. profileName .. "' deleted.") else @@ -225,7 +239,11 @@ function SlashCmdList.NOTGRID(msg, editbox) DEFAULT_CHAT_FRAME:AddMessage("Usage: /ng profile delete ") end elseif action == "list" then - NotGridProfiles = NotGridProfiles or {} + -- Validate that profiles table exists before listing + if not NotGridProfiles then + DEFAULT_CHAT_FRAME:AddMessage("NotGrid: Error - Profile system not initialized!") + return + end local profileCount = 0 local profileList = "" for name in pairs(NotGridProfiles) do