V21 offline

His Dad [08-07-16 - 04:03]
V21 offline
Filename
Delete-Account.lua
Delete-Character.lua
HistOffline.lua
data/data.lua
data/de.lua
data/en-data.lua
data/en.lua
data/fr.lua
history.lua
diff --git a/Delete-Account.lua b/Delete-Account.lua
new file mode 100644
index 0000000..2d31fae
--- /dev/null
+++ b/Delete-Account.lua
@@ -0,0 +1,170 @@
+-- Licence: MIT Licence
+-- Some code from the luatz project (MIT Licence)
+--[[
+Utility to delete old Accounts
+
+]]
+
+
+
+-- Configuration ==========
+local dateformat = "%Y-%m-%d, %H:%M"
+local dateformat_log = "%Y-%m-%d-%H-%M-%S"
+
+--iup.SetGlobal("UTF8MODE","YES")
+-- ========================
+version= "21"
+require( "iuplua" )
+require( "iupluacontrols" )
+dofile "../../SavedVariables/History.lua"
+
+function dump(o)
+   if type(o) == 'table' then
+      local s = '{ '
+      for k,v in pairs(o) do
+         if type(k) ~= 'number' then k = '"'..k..'"' end
+         s = s .. '['..k..'] = ' .. dump(v) .. ','
+      end
+      return s .. '} '
+   else
+      return tostring(o)
+   end
+end
+
+
+-- Minimally effective quoting
+function quote(astring)
+    local quoted1 = string.gsub(astring,'\"', '\\"')
+    local quoted2 = '"' .. string.gsub(quoted1,"%'", "\\'") .. '"'
+	local linefeed = string.gsub(quoted2,"\n", "\\n")
+	return linefeed
+end
+
+
+function write_saved(o)
+--	local escaped
+   if type(o) == 'table' then
+      local s = '{\n'
+      for k,v in pairs(o) do
+         if type(k) ~= 'number' then
+		 k = '"'..k..'"'
+		 end
+         s = s .. '['..k..'] = ' .. write_saved(v) .. ',\n'
+      end
+      return s .. '}\n'
+   elseif
+		type(o) == 'string' then
+		return quote(o)
+   else
+		return tostring(o)
+   end
+end
+
+
+
+accounts_list = {}		-- String list for selection dialog
+naccounts = 0
+for i,j in pairs(History_SV["Default"]) do
+    print(i)
+	lang = j["$AccountWide"].lang
+	print(lang)
+	table.insert(accounts_list, i)
+end
+
+if lang == nil then
+lang = "en"
+end
+
+local path = "./data/" .. lang .. ".lua"
+dofile (path)
+
+
+
+
+function select_account()
+	local selected
+		if naccounts > 0 then
+			selected = iup.ListDialog (1, L.ChooseAccounttoDelete,
+					naccounts,	--Size
+					accounts_list,
+					1, --Initial
+					1,naccounts	--MaxCol MaxLine
+					)
+
+			if selected <0 then
+				return nil		-- Cancelled
+			else
+				return accounts_list[selected+1]
+			end
+		else
+		return accounts_list[1]		-- only 1 account, no need for Dialog
+		end
+end
+
+--[[  -- Need two or more accounts
+if naccounts < 2  then
+	iup.Message("",L.NoAccount)
+	iup.Close()
+	os.exit()
+end
+
+--]]
+
+
+-- Create dialog to choose account
+account=select_account()
+-- Not selected, quit.
+if account == nil then
+	iup.Close()
+	os.exit()
+end
+
+
+confirm=  iup.messagedlg{
+  dialogtype = "QUESTION",
+  buttons = "OKCANCEL",
+  buttondefault = 2,
+  title = L.Delete .. "  " .. L.Account,
+  value = L.Delete .. " " .. account
+  }
+
+confirm:popup()
+-- Button "1" is OK.
+
+if iup.GetAttribute(confirm, "BUTTONRESPONSE") ~= "1" then
+print ("Cancelled")
+--	iup.Close()
+--	os.exit()
+end
+
+backfile=os.date("History-"..dateformat_log .. ".lua")
+-- os.execute( "md ..\\..\\SavedVariables\\History_Bak" )  -- fails silently if already exists.
+-- os.execute("copy  ..\\..\\SavedVariables\\History.lua ..\\..\\SavedVariables\\History_Bak\\" .. backfile)
+
+print ("Deleted")
+
+newf = assert(io.open("../../SavedVariables/History.new", "w"))
+-- ==============
+
+--Dump it back out
+newf:write("History_SV=" .. write_saved(History_SV))
+newf:close()
+
+--[[
+-- ============== Setup storage for old characters.
+archivef = io.open("../../SavedVariables/History.Archive", "r")
+if archivef ==nil then	--create empty file
+	archivef = io.open("../../SavedVariables/History.Archive", "w")
+	archivef:write("Archive = {} \n")
+end
+
+archivef:close()
+dofile "../../SavedVariables/History.Archive"
+
+-- newf = assert(io.open("../../SavedVariables/History.new", "w"))
+-- ==============
+--]]
+
+--Dump it back out
+-- newf:write("History_SV=" .. write_saved(History_SV))
+-- newf:close()
diff --git a/Delete-Character.lua b/Delete-Character.lua
new file mode 100644
index 0000000..bbbc0fc
--- /dev/null
+++ b/Delete-Character.lua
@@ -0,0 +1,94 @@
+-- Licence: MIT Licence
+-- Some code from the luatz project (MIT Licence)
+--[[
+Utility to delete old chars
+
+]]
+
+
+
+-- Configuration ==========
+local dateformat = "%Y-%m-%d, %H:%M"
+local dateformat_log = "%Y-%m-%d-%H-%M-%S"
+local FG_Colour_Not_Complete = "#FFB67D"
+local FG_Colour_Complete = "#000000"
+local BG_Colour_Not_Complete = "#FFB67D"
+local BG_Colour_Complete = "#A4FF5A"
+local Colour_Heading_Complete = "#58FA58"
+
+--iup.SetGlobal("UTF8MODE","YES")
+-- ========================
+version= "21"
+require( "iuplua" )
+require( "iupluacontrols" )
+dofile "../../SavedVariables/History.lua"
+
+function dump(o)
+   if type(o) == 'table' then
+      local s = '{ '
+      for k,v in pairs(o) do
+         if type(k) ~= 'number' then k = '"'..k..'"' end
+         s = s .. '['..k..'] = ' .. dump(v) .. ','
+      end
+      return s .. '} '
+   else
+      return tostring(o)
+   end
+end
+
+
+-- Minimally effective quoting
+function quote(astring)
+	return '"' .. string.gsub(astring,"%'", "\\'") .. '"'
+end
+
+
+function write_saved(o)
+--	local escaped
+   if type(o) == 'table' then
+      local s = '{\n'
+      for k,v in pairs(o) do
+         if type(k) ~= 'number' then
+		 k = '"'..k..'"'
+		 end
+         s = s .. '['..k..'] = ' .. write_saved(v) .. ',\n'
+      end
+      return s .. '}\n'
+   elseif
+		type(o) == 'string' then
+		return quote(o)
+   else
+		return tostring(o)
+   end
+end
+
+
+backfile=os.date("History-"..dateformat_log .. ".lua")
+os.execute( "md ..\\..\\SavedVariables\\History_Bak" )  -- fails silently if already exists.
+os.execute("copy  ..\\..\\SavedVariables\\History.lua ..\\..\\SavedVariables\\History_Bak\\" .. backfile)
+
+
+newf = assert(io.open("../../SavedVariables/History.new", "w"))
+-- ==============
+
+--Dump it back out
+-- newf:write("History_SV=" .. write_saved(History_SV))
+-- newf:close()
+--[[
+-- ============== Setup storage for old characters.
+archivef = io.open("../../SavedVariables/History.Archive", "r")
+if archivef ==nil then	--create empty file
+	archivef = io.open("../../SavedVariables/History.Archive", "w")
+	archivef:write("Archive = {} \n")
+end
+
+archivef:close()
+dofile "../../SavedVariables/History.Archive"
+
+-- newf = assert(io.open("../../SavedVariables/History.new", "w"))
+-- ==============
+--]]
+
+--Dump it back out
+-- newf:write("History_SV=" .. write_saved(History_SV))
+-- newf:close()
diff --git a/HistOffline.lua b/HistOffline.lua
index 458b627..2c7da23 100644
--- a/HistOffline.lua
+++ b/HistOffline.lua
@@ -12,30 +12,13 @@ local Colour_Heading_Complete = "#58FA58"

 --iup.SetGlobal("UTF8MODE","YES")
 -- ========================
-version= "18"
+version= "21"
 require( "iuplua" )
 require( "iupluacontrols" )
 dofile "../../SavedVariables/History.lua"
 dofile "./data/data.lua"	--Achievement to Grid lookup, language independent

---os.execute( "md ..\\..\\SavedVariables\\History_Bak" )  -- fails silently if already exists.

---os.execute("copy  ..\\..\\SavedVariables\\History.lua ..\\..\\SavedVariables\\History_Bak\\History.lua")
-
---[[
--- ============== Setup storage for old characters.
-archivef = io.open("../../SavedVariables/History.Archive", "r")
-if archivef ==nil then	--create empty file
-	archivef = io.open("../../SavedVariables/History.Archive", "w")
-	archivef:write("Archive = {} \n")
-end
-
-archivef:close()
-dofile "../../SavedVariables/History.Archive"
-
--- newf = assert(io.open("../../SavedVariables/History.new", "w"))
--- ==============
---]]


 function dump(o)
@@ -54,7 +37,10 @@ end

 -- Minimally effective quoting
 function quote(astring)
-	return '"' .. string.gsub(astring,"%'", "\\'") .. '"'
+    local quoted1 = string.gsub(astring,'\"', '\\"')
+    local quoted2 = '"' .. string.gsub(quoted1,"%'", "\\'") .. '"'
+	local linefeed = string.gsub(quoted2,"\n", "\\n")
+	return linefeed
 end


@@ -113,12 +99,12 @@ end

 accounts = {}
 accounts_list = {}		-- String list for selection dialog
+playerNames = {}		-- Get name from ID.
 naccounts = 0
 for i,_ in pairs(History_SV["Default"]) do
 	accounts[i] = {}
-	accounts[i].names = {}	-- intermediate table for sorting. WIP. Array formatted.
-	accounts[i].names_vet= {}	--subset of names which are >L50
-	accounts[i].name = {}
+	accounts[i].playerIDs = {}	-- intermediate table for sorting. WIP. Array formatted.
+	accounts[i].playerIDs_vet= {}	--subset of names which are >L50
 	naccounts = naccounts +1
 	table.insert(accounts_list, i)
 end
@@ -128,33 +114,23 @@ function write_data()
   newf:write("History_SV=" .. write_saved(History_SV))
   newf:close()
 end
---Dump it back out
--- newf:write("History_SV=" .. write_saved(History_SV))
--- newf:close()
-
-

--- Load up .names, as a first run through. It's a sortable array.
+-- Load up playerIDs, as a first run through. It's a sortable array.
 -- This is used as an indirection to control presentation order
  for acc,_ in pairs (accounts) do
-  for char, _ in pairs(History_SV["Default"][acc]["$AccountWide"]["data"]) do
-      table.insert (accounts[acc].names, char)
-	  accounts[acc].name[char] = {}		-- stub table to hold char data
+  for playerID, _ in pairs(History_SV["Default"][acc]["$AccountWide"]["data"]) do
+      table.insert (accounts[acc].playerIDs, playerID)
+	  accounts[acc].playerIDs[playerID] = {}		-- stub table to hold char data
   end
  end


-function print_old()
-	for i,j in pairs (History_SV["Default"][myaccount]["$AccountWide"]["old"]) do
-		print (i .. " .. " .. dump(j))
-	end
-end

 -- set up some static data


 --[[ ==========================================
-	Iterate over all accounts and chars creating display items
+	Iterate over all accounts and PlayerIDs creating display items
 --]]
  for acc,_ in pairs (accounts) do
   -- ===	Load Language Tables
@@ -288,10 +264,18 @@ end
   --=================  START OF CHARACTER MODE DISPLAY

 -- Creates boxes, stage from names to allow optional sorting in future.
-	for _,char in ipairs(accounts[acc].names) do
-		local me = accounts[acc].name[char]											-- shorter reference: our code
-		local thischar = History_SV["Default"][acc]["$AccountWide"]["data"][char]	-- shorter reference: History DB
+	for _,playerID in ipairs(accounts[acc].playerIDs) do
+		local me = accounts[acc].playerIDs[playerID]											-- shorter reference: our code
+		local thischar = History_SV["Default"][acc]["$AccountWide"]["data"][playerID]	-- shorter reference: History DB
 		-- Pull in some char data for processing
+		if thischar.name == nil  then --	Old Format
+		    print("Old Format  " .. playerID)
+			me.name = playerID
+		else
+			me.name = thischar.name
+		end
+		playerNames[playerID]=me.name
+
 		-- == Gender
 		if thischar.Gender =="M" then
 			me.gender = L.Male
@@ -308,7 +292,7 @@ end
 		else
 			me.levelstr = "V" .. tostring(level -50)
 			me.isvet = true
-			table.insert(accounts[acc].names_vet,char)
+			table.insert(accounts[acc].playerIDs_vet,playerID)
 		end
 		-- == Cumulative TimePlayed
 		me.timeplayed = math.floor(thischar.levels[level].time/60)
@@ -379,7 +363,7 @@ end
 				iup.SetAttribute(me.Grp_box, colour, FG_Colour_Complete)
 				-- Add char to dungeon
 				key = tostring(grp_dat[id].L .. grp_dat[id].C)
-				dung.grp[key][char] = "Y"
+				dung.grp[key][playerID] = "Y"
 			end
 		end

@@ -432,7 +416,7 @@ end
 				iup.SetAttribute(me.Pub_box, colour, FG_Colour_Complete)
 				-- Add char to dungeon
 				local key = tostring(pub_dat[id].L .. pub_dat[id].C)
-				dung.pub[key][char] = "Y"
+				dung.pub[key][playerID] = "Y"
 			end
 		end

@@ -505,7 +489,7 @@ end
 				me.Vet_box:setcell(L,C,dname .. " (" .. Vet_Info[key].count ..")")

 				-- Add char to dungeon
-				dung.vet[key][char] = "Y"
+				dung.vet[key][playerID] = "Y"
 			end
 		end

@@ -563,7 +547,7 @@ end
 				iup.SetAttribute(me.Trials_box, bgcolour, BG_Colour_Complete)
 				end
 				-- Add char to dungeon
-				dung.trials[key][char] = "Y"
+				dung.trials[key][playerID] = "Y"
 			end
 		end

@@ -894,7 +878,7 @@ end
 				iup.SetAttribute(me.DLC_box, colour, FG_Colour_Complete)
 				-- Add char to dungeon
 				key = tostring(DLC_dat[id].L .. DLC_dat[id].C)
-				dung.DLC[key][char] = "Y"
+				dung.DLC[key][playerID] = "Y"
 			end
 		end

@@ -905,7 +889,7 @@ end
 	 -- ====================================
 	--  == Prepare for the character data display tabs
 		me.tab = iup.vbox{
-					["tabtitle"] = char,		-- This vbox will be a tab and the tab text is this
+					["tabtitle"] = me.name,		-- This vbox will be a tab and the tab text is this

 					iup.hbox{		--Top Information bar
 							Alignment = "ACENTER",
@@ -987,7 +971,7 @@ end

 		iup.Append(accounts[acc].char_tabs,me.tab)

-		local panel =(#accounts[acc].names * 90)
+		local panel =(#accounts[acc].playerIDs * 90)
 		if panel < 680  then
 			panel = 680
 		elseif panel >950 then
@@ -1005,7 +989,7 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
 	-- Create Pub Dungeon Character Box=========================

 	dung.Pub_box = {}
-	dung.Pub_box = iup.matrix {numcol=#accounts[acc].names,  numlin=#grp2key, widthdef=90}
+	dung.Pub_box = iup.matrix {numcol=#accounts[acc].playerIDs,  numlin=#grp2key, widthdef=90}
 	--Set Line titles
 	for i,key in ipairs(grp2key) do
 		dung.Pub_box:setcell(i, 0, pub_names[key])
@@ -1014,8 +998,9 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
 	dung.Pub_box:setcell(0,0, L.Location)

 	--Create Columns for Chars
-	for i ,char in ipairs(accounts[acc].names) do
-		dung.Pub_box:setcell(0, i, char)
+	for i ,playerID in ipairs(accounts[acc].playerIDs) do
+	    print(playerID)
+		dung.Pub_box:setcell(0, i, playerNames[playerID])
 	end

 	iup.SetAttribute(dung.Pub_box, "READONLY", "YES")
@@ -1023,8 +1008,8 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
 	-- Populate with character data ============================
 	for line,key in ipairs(grp2key) do		-- over each dungeon
 	    -- does that char exist in the table.
-		for i,char in ipairs(accounts[acc].names) do	-- over each char in order
-			if dung.pub[key][char] == nil then
+		for i,playerID in ipairs(accounts[acc].playerIDs) do	-- over each char in order
+			if dung.pub[key][playerID] == nil then
 				dung.Pub_box:setcell(line,i, "N")
 				iup.SetAttribute(dung.Pub_box,"BGCOLOR" .. tostring(line) .. ":" .. tostring(i), BG_Colour_Not_Complete)
 			else
@@ -1046,7 +1031,7 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
 	-- Create Grp Dungeon Character Box=========================

 	dung.Grp_box = {}
-	dung.Grp_box = iup.matrix {numcol=#accounts[acc].names,  numlin=#grp2key, widthdef=90}
+	dung.Grp_box = iup.matrix {numcol=#accounts[acc].playerIDs,  numlin=#grp2key, widthdef=90}
 	--Set Line titles
 	for i, key in ipairs(grp2key) do
 		dung.Grp_box:setcell(i, 0, grp_names[key])
@@ -1054,8 +1039,8 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
 	--set lines
 	dung.Grp_box:setcell(0,0, L.Location)
 	--Create Columns for Chars
-	for i,char in ipairs(accounts[acc].names) do
-		dung.Grp_box:setcell(0, i, char)
+	for i,playerID in ipairs(accounts[acc].playerIDs) do
+		dung.Grp_box:setcell(0, i, playerNames[playerID])
 	end

 	iup.SetAttribute(dung.Grp_box, "READONLY", "YES")
@@ -1063,8 +1048,8 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
 	-- Populate with character data ============================
 	for line,key in ipairs(grp2key) do		-- over each dungeon
 	    -- does that char exist in the table.
-		for i,char in ipairs(accounts[acc].names) do	-- over each char in order
-			if dung.grp[key][char] == nil then
+		for i,playerID  in ipairs(accounts[acc].playerIDs) do	-- over each char in order
+			if dung.grp[key][playerID] == nil then
 				dung.Grp_box:setcell(line,i, "N")
 				iup.SetAttribute(dung.Grp_box,"BGCOLOR" .. tostring(line) .. ":" .. tostring(i), BG_Colour_Not_Complete)
 			else
@@ -1085,7 +1070,7 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
 	-- Create DLC Dungeon Character Box=========================

 	dung.DLC_box = {}
-	dung.DLC_box = iup.matrix {numcol=#accounts[acc].names,  numlin=#DLC2key, widthdef=100}
+	dung.DLC_box = iup.matrix {numcol=#accounts[acc].playerIDs ,  numlin=#DLC2key, widthdef=100}
 	--Set Line titles
 	for i, key in ipairs(DLC2key) do
 		dung.DLC_box:setcell(i, 0, DLC_Location_names[key])
@@ -1093,8 +1078,8 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
 	--set lines
 	dung.DLC_box:setcell(0,0, L.Location)
 	--Create Columns for Chars
-	for i,char in ipairs(accounts[acc].names) do
-		dung.DLC_box:setcell(0, i, char)
+	for i,playerID in ipairs(accounts[acc].playerIDs ) do
+		dung.DLC_box:setcell(0, i, playerNames[playerID])
 	end

 	iup.SetAttribute(dung.DLC_box, "READONLY", "YES")
@@ -1102,8 +1087,8 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
 	-- Populate with character data ============================
 	for line,key in ipairs(DLC2key) do		-- over each dungeon
 	    -- does that char exist in the table.
-		for i,char in ipairs(accounts[acc].names) do	-- over each char in order
-			if dung.DLC[key][char] == nil then
+		for i,playerID in ipairs(accounts[acc].playerIDs ) do	-- over each char in order
+			if dung.DLC[key][playerID] == nil then
 				dung.DLC_box:setcell(line,i, "N")
 				iup.SetAttribute(dung.DLC_box,"BGCOLOR" .. tostring(line) .. ":" .. tostring(i), BG_Colour_Not_Complete)
 			else
@@ -1125,10 +1110,10 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)



-	if #accounts[acc].names_vet > 0  then  -- skip vet and trials if no eligible chars
+	if #accounts[acc].playerIDs_vet > 0  then  -- skip vet and trials if no eligible chars
 	-- Create Vet Grp Dungeon Character Box=======================
 		dung.Vet_box = {}
-		dung.Vet_box = iup.matrix {numcol=#accounts[acc].names_vet,  numlin=#vet2key, widthdef=90}
+		dung.Vet_box = iup.matrix {numcol=#accounts[acc].playerIDs_vet,  numlin=#vet2key, widthdef=90}
 		--Set Line titles
 		for i,key in ipairs(vet2key) do
 			dung.Vet_box:setcell(i, 0, grp_names[key])
@@ -1138,19 +1123,19 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)

 		local col = 0
 		--Create Columns for Chars
-		for line,char  in ipairs(accounts[acc].names_vet) do
+		for line,playerID  in ipairs(accounts[acc].playerIDs_vet) do
 			col = col +1
 			dung.Vet_box.numcol = col
-			dung.Vet_box:setcell(0, line, char)
+			dung.Vet_box:setcell(0, line, playerNames[playerID])
 		end

 		for line,key in ipairs(vet2key) do		-- over each dungeon
 			-- does that char exist in the table.
-			for i,char in ipairs(accounts[acc].names_vet) do	-- over each char in order
+			for i,playerID  in ipairs(accounts[acc].playerIDs_vet) do	-- over each char in order
 			if dung.vet[key] == nil then
 				print ("key: " .. key .. "  missing")
 			end
-				if dung.vet[key][char] == nil then
+				if dung.vet[key][playerID] == nil then
 					dung.Vet_box:setcell(line,i, "N")
 					iup.SetAttribute(dung.Vet_box,"BGCOLOR" .. tostring(line) .. ":" .. tostring(i), BG_Colour_Not_Complete)
 				else
@@ -1186,18 +1171,18 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)
 		dung.Trials_box:setcell(0,0, L.Location)

 		--Create Columns for Chars
-		for line,char  in ipairs(accounts[acc].names_vet) do
+		for line,playerID  in ipairs(accounts[acc].playerIDs_vet) do
 			dung.Trials_box.numcol = line
-			dung.Trials_box:setcell(0, line, char)
+			dung.Trials_box:setcell(0, line, playerNames[playerID])
 		end

 		for line,key in ipairs(trial2key) do		-- over each dungeon
 			-- does that char exist in the table.
-			for i,char in ipairs(accounts[acc].names_vet) do	-- over each char in order
+			for i,playerID in ipairs(accounts[acc].playerIDs_vet) do	-- over each char in order
 			if dung.trials[key] == nil then
 				print ("key: " .. key .. "  missing")
 			end
-				if dung.trials[key][char] == nil then
+				if dung.trials[key][playerID] == nil then
 					dung.Trials_box:setcell(line,i, "N")
 					iup.SetAttribute(dung.Trials_box,"BGCOLOR" .. tostring(line) .. ":" .. tostring(i), BG_Colour_Not_Complete)
 				else
@@ -1221,8 +1206,14 @@ iup.Append(accounts[acc].char_tabs, accounts[acc].log_tab)

 end -- Accounts

---print_old()

+--Setup menu
+-- Creates main menu with  submenu
+
+menuitem_About= iup.item {title = L.About}
+
+
+menu = iup.menu {menuitem_About}


 function select_account()
@@ -1262,7 +1253,8 @@ if myaccount ~=nil then
 							ngap="3",
 							},
 					title=L.title .. myaccount,
-					size=accounts[myaccount].panelsize
+					size=accounts[myaccount].panelsize,
+					menu=menu
 					}
 	-- Shows dialog in the centre of the screen
 	dlg:showxy(iup.CENTER, iup.CENTER)
diff --git a/data/data.lua b/data/data.lua
index 965d7f2..e608952 100644
--- a/data/data.lua
+++ b/data/data.lua
@@ -106,24 +106,24 @@ vet_dat = {
 --	[]= {L=5, C=4},
 }
 trial_dat = {
---Hel Ra Citadel
+--Hel Ra Citadel Vet
 [870] = {L=1, C=1, key ="11"},
 [991] = {L=1, C=1,key ="11"},
 [1136] = {L=1, C=1, key ="11"},
 [1080] = {L=1, C=1, key ="11"},

---Aetherian Archive
+--Aetherian Archive Vet
 [990] = {L=2, C=1, key ="21"},
 [1137] = {L=2, C=1, key ="21"},
 [1081] = {L=2, C=1, key ="21"},
---Sanctum Ophidia

+--Sanctum Ophidia Vet
 [1123] = {L=3, C=1, key ="31"},
 [1124] = {L=3, C=1, key ="31"},
 [1138] = {L=3, C=1, key ="31"},
 -- Craglorn Trials
 --	[1139] = {L=3, C=1, key ="31"},
---Dragonstar Arena
+--Dragonstar Arena Vet
 [992] = {L=4, C=1, key ="41"},
 [1140] = {L=4, C=1, key ="41"},
 }
diff --git a/data/de.lua b/data/de.lua
index bd7ac91..b7fcb52 100644
--- a/data/de.lua
+++ b/data/de.lua
@@ -78,7 +78,12 @@ DLC_names = {
 		Achievements = "Errungenschaften",
 		TrialLab = "Errungenschaften der Pruefungen. Fuer Details anklicken",
 		DLC="DLC",
-		DLCLab="Downloadable Content"
+		DLCLab="Downloadable Content",
+		Manage = "Manage",
+	    Account = "Account",
+		Char = "Char",
+		About = "About",
+		Delete = "Delete"
 	}

 pub_names = {
diff --git a/data/en-data.lua b/data/en-data.lua
index 2c7a054..29b8de3 100644
--- a/data/en-data.lua
+++ b/data/en-data.lua
@@ -7796,7 +7796,7 @@ Ach_Detail =
 	[991] =
 	{
 		["points"] = 50,
-		["Category_ID"] = 7,
+		["Category_ID"] = 7,   --Not Vet????
 		["name"] = "Hel Ra Citadel Completed",
 		["description"] = "Defeat the Warrior Celestial, freeing him from the Serpent's control.",
 		["Category"] = "Dungeons",
@@ -8057,4 +8057,44 @@ Ach_Detail =
 		["description"] = "Research a Trait for any weapon or armor type.",
 		["Category"] = "Crafting",
 	},
+		[1504] =
+		{
+			["Category"] = "DLC",			-- Non Vet
+			["points"] = 10,
+			["description"] = "Defeat Zatzu the Spine-Breaker, The Mighty Chudan, Xal-Nur the Slaver, and Tree-Minder Na-Kesh in the Ruins of Mazzatun.",
+			["name"] = "Ruins of Mazzatun Vanquisher",
+			["Category_ID"] = 10,
+		},
+		[1505] =
+		{
+			["Category"] = "DLC",        -- Vet
+			["points"] = 10,
+			["description"] = "Defeat Zatzu the Spine-Breaker, The Mighty Chudan, Xal-Nur the Slaver, and Tree-Minder Na-Kesh in Veteran Ruins of Mazzatun.",
+			["name"] = "Ruins of Mazzatun Champion",
+			["Category_ID"] = 10,
+		},
+        [1522] =
+			{
+				["Category"] = "DLC",   --Non Vet
+				["points"] = 10,
+				["description"] = "Defeat Sithera, Khephidaen the Spiderkith, the Votary of Velidreth, Dranos Velador, and Velidreth the Lady of Lace in the Cradle of Shadows.",
+				["name"] = "Cradle of Shadows Vanquisher",
+				["Category_ID"] = 10,
+			},
+		[1529] =
+		{
+			["Category"] = "DLC",		-- Vet
+			["points"] = 50,
+			["description"] = "Complete the listed achievements for Veteran Cradle of Shadows.",
+			["name"] = "Cradle of Shadows Challenger",
+			["Category_ID"] = 10,
+		},
+		[1474] =
+		{
+			["Category"] = "Dungeons", --New Vet
+			["points"] = 50,
+			["description"] = "Defeat the Celestial Warrior in Veteran Hel Ra Citadel, while the Trial is scaled to Champion 160.",
+			["name"] = "Hel Ra Citadel Conqueror",
+			["Category_ID"] = 6,
+		},
 }
\ No newline at end of file
diff --git a/data/en.lua b/data/en.lua
index cc53e88..b936669 100644
--- a/data/en.lua
+++ b/data/en.lua
@@ -76,7 +76,14 @@ DLC_names = {
 		Achievements = "Achievements",
 		TrialLab = "Trial Achievements. Click for Detail",
 		DLC="DLC",
-		DLCLab="Downloadable Content"
+		DLCLab="Downloadable Content",
+		Manage ="Manage",
+	    Account = "Account",
+		Char = "Char",
+		About = "About",
+		Delete = "Delete",
+		NoAccount ="Only 1 account, can't delete that.",
+		ChooseAccounttoDelete = "Choose Account to Delete",
 	}

 pub_names = {
diff --git a/data/fr.lua b/data/fr.lua
index 5a52ce5..f6977a0 100644
--- a/data/fr.lua
+++ b/data/fr.lua
@@ -74,7 +74,12 @@ DLC_names = {
 		Achievements = "Achievements",
 		TrialLab = "Trial Achievements. Click for Detail",
 		DLC="DLC",
-		DLCLab="Downloadable Content"
+		DLCLab="Downloadable Content",
+		Manage = "Manage",
+	    Account = "Account",
+		Char = "Char",
+		About = "About",
+		Delete = "Delete"
 	}

 pub_names = {
diff --git a/history.lua b/history.lua
index 6a6800c..33c7210 100644
--- a/history.lua
+++ b/history.lua
@@ -1,11 +1,12 @@
 hist = {
 	name = "history",
-	version = "20",
+	version = "21",
 	initialised = false,
 	SV={},
 	L={},
 	me = {},
-	player = "",
+	playerName = "",	-- might change
+	playerID = "",  	-- Unique through renames
 	tz_offset =0,
 	debug = false
 }
@@ -25,7 +26,15 @@ local function log(text)

 	table.insert(hist.SV.log,{["TimeStamp"]=GetTimeStamp(),
 							["text"] = text,
-							["Char"] = hist.player,
+							["Char"] = hist.playerName,
+							["CharID"] = hist.playerID,
+							})
+end
+
+local function log_me(text)	-- per char log
+
+	table.insert(hist.me.log,{["TimeStamp"]=GetTimeStamp(),
+							["text"] = text,
 							})
 end

@@ -50,7 +59,7 @@ local function get_start ()	-- get better start date from Achievements
 			hist.me.Created = earliest_time
 		elseif hist.me.Created > earliest_time then		-- Quest was earlier, then reset to earlier
 			if hist.debug then
-					d("Start Time Reset for " .. hist.player)
+					d("Start Time Reset for " .. hist.playerName)
 			end
 			log ("Start Time Reset.")
 			hist.me.Created = earliest_time
@@ -88,7 +97,7 @@ function load_history()
 	local name,points,description,completed,adate,atime
   local cat
   local count = 0
-	for i = 1,1400 do
+	for i = 1,1800 do
 		name,description,points,_,completed,adate,atime= GetAchievementInfo(i)
 		if completed then
 			cat,_,_ =GetCategoryInfoFromAchievementId(i)
@@ -214,9 +223,10 @@ local function gendertext()
 	return "U"
 end
 local function setup_char()
-		log("Set up: " .. hist.player )
-		hist.SV.data[hist.player] = {}		-- initialise data for current char
-		hist.me = hist.SV.data[hist.player]
+		log("Set up: " .. hist.playerName )
+		hist.SV.data[hist.playerID] = {}		-- initialise data for current char, using unique GUID
+		hist.me = hist.SV.data[hist.playerID]
+		hist.me.name=hist.playerName

 		hist.me.Class = zo_strformat("<<C:1>>",GetUnitClass("player"))
 		hist.me.Race = zo_strformat("<<C:1>>",GetUnitRace("player"))
@@ -225,6 +235,7 @@ local function setup_char()
 		hist.me.Alliance = zo_strformat("<<C:1>>",GetAllianceName(GetUnitAlliance("player")))
 		hist.me.ach={}
 		hist.me.maps={}
+		hist.me.log={}
 		hist.me.levels = {}
 		hist.me.levels[hist.me.level] = {
 			begin = GetTimeStamp(),
@@ -236,6 +247,7 @@ local function setup_char()
 		hist.me["LoadTime"] = GetTimeStamp()
 		load_history()
 		get_start()
+		log_me("Started")
 end

 local function Dead()
@@ -262,11 +274,6 @@ local function Dead()
 	end
 end

-local function delete_old ()
-	d("deleted old characters")
-	log("deleted old characters")
-	hist.SV.old = {}
-end

 function hist.Initialise(_, addOnName)
 	if (hist.name ~= addOnName) then return end
@@ -278,7 +285,8 @@ function hist.Initialise(_, addOnName)
 	hist.luatz_ts = luatz_esodate(hist.datestr .." " .. hist.timestr)
 	hist.tz_offset = now - hist.luatz_ts

-	hist.player = GetUnitName("player")
+	hist.playerName = GetUnitName("player")
+	hist.playerID = GetCurrentCharacterId()
 	local level = GetUnitLevel("player") + GetUnitVeteranRank("player")
     -- Load the saved variables
     hist.SV = ZO_SavedVars:NewAccountWide("History_SV", 1, nil, nil)
@@ -293,9 +301,8 @@ function hist.Initialise(_, addOnName)
 		hist.SV.data = {}
 		log("hist.SV.data  created")
 	end
-	if (hist.SV.old == nil ) then
-		hist.SV.old = {}
-		log("hist.SV.old  created")
+	if (hist.SV.old ~= nil) then -- Delete legacy data that we never used anyway
+		hist.SV.old = nil
 	end

 	if (hist.SV.start_version  == nil ) then
@@ -304,61 +311,49 @@ function hist.Initialise(_, addOnName)

 	hist.SV.this_version = hist.version

-
-	if hist.SV.data[hist.player] == nil
-	then
-		setup_char()
-	else	-- data already there
-		-- but is it for the same char?
-
-		hist.me = hist.SV.data[hist.player]
-		if hist.me.level == nil then		-- fix if doesn't exist
-			hist.me.level = level
+	hist.SV.version = nil	-- Old Variable not used
+
+	if hist.SV.data[hist.playerID] == nil then
+	  log("No data found")
+	-- Ok playerID may be nil, but we might still have data under player name
+	-- In which case we rename it, otherwise it is a new char.
+
+		if hist.SV.data[hist.playerName] == nil then
+			--No name, no ID, must be new.
+			setup_char()
+		else
+			-- Ok old name data, fix it.
+			log("New data format, saving " .. hist.playerName .. " as " ..  hist.playerID)
+			hist.SV.data[hist.playerID] = hist.SV.data[hist.playerName]
+			hist.SV.data[hist.playerID].name = hist.playerName
+
+			hist.SV.data[hist.playerName] = nil		-- and on the eighth day God invented Lua
 		end
+	end

-		if 	hist.me.levels == nil then
-		hist.me.levels = {}
-		end
-		if 	hist.me.craft == nil then
-		hist.me.craft  = {}
-		end
-		if hist.me.maps == nil then
-			hist.me.maps = {}
-		end
+	hist.me = hist.SV.data[hist.playerID]
+	if hist.me.level == nil then		-- fix if doesn't exist
+		hist.me.level = level
+	end

-		    if hist.debug then
-					log("Begin Duplicate tests, Saved  -- Calculated" )
-					log("Alliance test: " .. hist.me.Alliance .. " -- " .. zo_strformat("<<C:1>>",GetAllianceName(GetUnitAlliance("player"))))
-					log("Race test: " .. hist.me.Race .. " -- " .. zo_strformat("<<C:1>>",GetUnitRace("player")))
-					log("Class test: "  .. hist.me.Class .. " -- " .. zo_strformat("<<C:1>>",GetUnitClass("player")))
-					log("Gender test: " .. hist.me.Gender .. " -- " .. gendertext())
-					log("Level Lower: " .. hist.me.level .. " -- " .. level)
-			end
-		if 	hist.me.level > level
-	--      hist.me.Alliance  ~=  zo_strformat(GetAllianceName(GetUnitAlliance("player"))) or
-	--		hist.me.Race ~= zo_strformat("<<C:1>>",GetUnitRace("player")) or
-	--		hist.me.Class ~= zo_strformat("<<C:1>>",GetUnitClass("player")) or
-	--		hist.me["Gender"] ~= gendertext() or
-
-			then -- must be different with same name
-			local now = GetTimeStamp()
-			log("Duplicate " .. hist.player .. " Detected, moving to old")
-			hist.SV.old[now] = {}	-- save old with timestamp
-			hist.SV.old[now][hist.player] = {}
-			hist.SV.old[now][hist.player] = hist.SV.data[hist.player]  -- Saved
-			hist.SV.data[hist.player] = nil		-- Poof, gone
-			setup_char()  -- setup defaults
-			hist.SV.data[hist.player].OverWrite = true
-		end
+	if 	hist.me.levels == nil then
+	hist.me.levels = {}
 	end
-	-- Fix bad map var.
-	if type(hist.me.levels[hist.me.level].map) == "table" then
-			hist.me.levels[hist.me.level].map = nil
-			d("History:  Fixed bad map key.")
-			log ("History:  Fixed bad map key.")
+	if 	hist.me.craft == nil then
+	hist.me.craft  = {}
 	end
-
-	-- fix missed level  leveled up with addon disabled
+	if hist.me.maps == nil then
+		hist.me.maps = {}
+	end
+
+	if hist.me.log == nil then	-- special events we want to keep, like name changes
+		hist.me.log = {}
+	end
+
+
+
+
+	-- fix missed level, leveled up with addon disabled


 	if hist.me.level ~=  level then
@@ -397,8 +392,25 @@ function hist.Initialise(_, addOnName)
 		log ("Startup: Timed check on missed achievements.")
 	end

+	if hist.me.name ~= hist.playerName then
+		log("Changed Name, Was " ..  hist.me.name)
+		log_me("Changed Name, Was " ..  hist.me.name)
+		hist.me.name = hist.playerName
+	end

+	if 	hist.me.Race ~= zo_strformat("<<C:1>>",GetUnitRace("player")) then
+		log("Changed Race, Was " .. hist.me.Race)
+		log_me("Changed Race, Was " .. hist.me.Race)
+		hist.me.Race = zo_strformat("<<C:1>>",GetUnitRace("player"))
+	end

+	if 	hist.me.Gender ~= gendertext() then
+		log("Changed Gender, Was " .. hist.me.Gender)
+		log_me("Changed Gender, Was " .. hist.me.Gender)
+		hist.me.Gender = gendertext()
+	end
+
+
 	EVENT_MANAGER:RegisterForEvent(hist.name, EVENT_ACHIEVEMENT_AWARDED, Achievement)
 	EVENT_MANAGER:RegisterForEvent(hist.name, EVENT_LEVEL_UPDATE, levelup)
 	EVENT_MANAGER:RegisterForEvent(hist.name, EVENT_VETERAN_RANK_UPDATE, levelup)
@@ -415,6 +427,5 @@ SLASH_COMMANDS["/histload"] = load_history
 SLASH_COMMANDS["/histfix"] = fix
 SLASH_COMMANDS["/histclear"] = log_clear
 SLASH_COMMANDS["/histstart"] = get_start
-SLASH_COMMANDS["/histdelold"]= delete_old

 EVENT_MANAGER:RegisterForEvent(hist.name, EVENT_ADD_ON_LOADED, hist.Initialise)