From 11cb9ce00a1b15bfd11f3cac4c2b22e625b4e28b Mon Sep 17 00:00:00 2001 From: Dusk-92 Date: Tue, 9 Jun 2026 11:23:40 +0200 Subject: [PATCH] Add files via upload --- Build.bat | 1 + Payload/Data/Interface/GlueXML/AutoLogin.lua | 1019 ++++++ Payload/Data/Interface/GlueXML/AutoLogin.xml | 249 ++ Payload/Data/Interface/GlueXML/GlueXML.toc | 25 + Payload/Interface/Addons/SuperAPI/README.md | 22 + .../Interface/Addons/SuperAPI/SuperAPI.lua | 151 + .../Interface/Addons/SuperAPI/SuperAPI.toc | 25 + .../Addons/SuperAPI/SuperAPIOptions.lua | 210 ++ .../libs/AceAddon-2.0/AceAddon-2.0.lua | 1129 +++++++ .../libs/AceConsole-2.0/AceConsole-2.0.lua | 1920 ++++++++++++ .../SuperAPI/libs/AceDB-2.0/AceDB-2.0.lua | 1539 +++++++++ .../libs/AceDebug-2.0/AceDebug-2.0.lua | 245 ++ .../libs/AceEvent-2.0/AceEvent-2.0.lua | 973 ++++++ .../SuperAPI/libs/AceHook-2.1/AceHook-2.1.lua | 569 ++++ .../SuperAPI/libs/AceLibrary/AceLibrary.lua | 757 +++++ .../libs/AceLocale-2.2/AceLocale-2.2.lua | 538 ++++ .../AceModuleCore-2.0/AceModuleCore-2.0.lua | 462 +++ .../SuperAPI/libs/AceOO-2.0/AceOO-2.0.lua | 1006 ++++++ .../SuperAPI/libs/Dewdrop/Dewdrop-2.0.lua | 2602 +++++++++++++++ .../libs/FuBarPlugin/FuBarPlugin-2.0.lua | 1480 +++++++++ .../SuperAPI/libs/Tablet/Tablet-2.0.lua | 2784 +++++++++++++++++ .../Addons/UnitXP_SP3_Addon/Bindings.xml | 71 + .../Addons/UnitXP_SP3_Addon/README.md | 2 + .../UnitXP_SP3_Addon/UnitXP_SP3_Addon.lua | 1042 ++++++ .../UnitXP_SP3_Addon/UnitXP_SP3_Addon.toc | 14 + .../UnitXP_SP3_Addon/UnitXP_SP3_Addon.xml | 856 +++++ .../UnitXP_SP3_Addon/libs/AceCore-3.0.lua | 209 ++ .../UnitXP_SP3_Addon/libs/AceHook-3.0.lua | 540 ++++ .../libs/CallbackHandler-1.0.lua | 280 ++ .../UnitXP_SP3_Addon/libs/LibDBIcon-1.0.lua | 487 +++ .../libs/LibDataBroker-1.1.lua | 90 + .../Addons/UnitXP_SP3_Addon/libs/LibStub.lua | 33 + .../Addons/nampowersettings/Localization.lua | 371 +++ .../nampowersettings/NampowerSettings.toc | 27 + .../Addons/nampowersettings/README.md | 12 + .../Addons/nampowersettings/helper.lua | 952 ++++++ .../Interface/Addons/nampowersettings/img.png | Bin 0 -> 18926 bytes .../libs/AceAddon-2.0/AceAddon-2.0.lua | 1129 +++++++ .../libs/AceConsole-2.0/AceConsole-2.0.lua | 1920 ++++++++++++ .../libs/AceDB-2.0/AceDB-2.0.lua | 1539 +++++++++ .../libs/AceDebug-2.0/AceDebug-2.0.lua | 245 ++ .../libs/AceEvent-2.0/AceEvent-2.0.lua | 973 ++++++ .../libs/AceHook-2.1/AceHook-2.1.lua | 569 ++++ .../libs/AceLibrary/AceLibrary.lua | 757 +++++ .../libs/AceLocale-2.2/AceLocale-2.2.lua | 538 ++++ .../AceModuleCore-2.0/AceModuleCore-2.0.lua | 462 +++ .../libs/AceOO-2.0/AceOO-2.0.lua | 1006 ++++++ .../libs/Dewdrop/Dewdrop-2.0.lua | 2602 +++++++++++++++ .../libs/FuBarPlugin/FuBarPlugin-2.0.lua | 1480 +++++++++ .../libs/Tablet/Tablet-2.0.lua | 2784 +++++++++++++++++ .../Addons/nampowersettings/settings.lua | 1296 ++++++++ .../Addons/perfboostsettings/Bindings.xml | 26 + .../Addons/perfboostsettings/GUIDE.md | 82 + .../perfboostsettings/PerfBoostSettings.toc | 23 + .../Addons/perfboostsettings/README.md | 95 + .../Addons/perfboostsettings/img.png | Bin 0 -> 118988 bytes .../libs/AceAddon-2.0/AceAddon-2.0.lua | 1129 +++++++ .../libs/AceConsole-2.0/AceConsole-2.0.lua | 1920 ++++++++++++ .../libs/AceDB-2.0/AceDB-2.0.lua | 1539 +++++++++ .../libs/AceDebug-2.0/AceDebug-2.0.lua | 245 ++ .../libs/AceEvent-2.0/AceEvent-2.0.lua | 973 ++++++ .../libs/AceHook-2.1/AceHook-2.1.lua | 569 ++++ .../libs/AceLibrary/AceLibrary.lua | 757 +++++ .../libs/AceLocale-2.2/AceLocale-2.2.lua | 538 ++++ .../AceModuleCore-2.0/AceModuleCore-2.0.lua | 462 +++ .../libs/AceOO-2.0/AceOO-2.0.lua | 1006 ++++++ .../libs/Dewdrop/Dewdrop-2.0.lua | 2602 +++++++++++++++ .../libs/FuBarPlugin/FuBarPlugin-2.0.lua | 1480 +++++++++ .../libs/Tablet/Tablet-2.0.lua | 2784 +++++++++++++++++ .../Addons/perfboostsettings/settings.lua | 982 ++++++ Payload/SuperWoWhook.dll | Bin 0 -> 129024 bytes Payload/UnitXP_SP3.dll | Bin 0 -> 202240 bytes Payload/VanillaFixes.exe | Bin 0 -> 88576 bytes Payload/VanillaHelpers.dll | Bin 0 -> 254976 bytes Payload/VfPatcher.dll | Bin 0 -> 72704 bytes Payload/WeirdUtils/bigcursor.dll | Bin 0 -> 14848 bytes Payload/WeirdUtils/customassets.dll | Bin 0 -> 16384 bytes Payload/WeirdUtils/logsessions.dll | Bin 0 -> 14848 bytes Payload/WeirdUtils/minimapicons.dll | Bin 0 -> 142848 bytes Payload/WeirdUtils/pngscreenshots.dll | Bin 0 -> 16896 bytes Payload/WeirdUtils/transmogfix.dll | Bin 0 -> 12800 bytes Payload/WeirdUtils/weirdperformance.dll | Bin 0 -> 162816 bytes Payload/WeirdUtils/worldmarkers.dll | Bin 0 -> 487936 bytes Payload/dxvk.conf | 87 + Payload/nampower.dll | Bin 0 -> 1010176 bytes Payload/no1600x1200.dll | Bin 0 -> 104960 bytes Payload/perf_boost.dll | Bin 0 -> 578560 bytes PurpleWowLogo.ico | Bin 0 -> 266169 bytes setup_tool.py | 703 +++++ vanilla-tweaks.exe | Bin 0 -> 5920384 bytes 90 files changed, 57994 insertions(+) create mode 100644 Build.bat create mode 100644 Payload/Data/Interface/GlueXML/AutoLogin.lua create mode 100644 Payload/Data/Interface/GlueXML/AutoLogin.xml create mode 100644 Payload/Data/Interface/GlueXML/GlueXML.toc create mode 100644 Payload/Interface/Addons/SuperAPI/README.md create mode 100644 Payload/Interface/Addons/SuperAPI/SuperAPI.lua create mode 100644 Payload/Interface/Addons/SuperAPI/SuperAPI.toc create mode 100644 Payload/Interface/Addons/SuperAPI/SuperAPIOptions.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/AceAddon-2.0/AceAddon-2.0.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/AceConsole-2.0/AceConsole-2.0.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/AceDB-2.0/AceDB-2.0.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/AceDebug-2.0/AceDebug-2.0.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/AceEvent-2.0/AceEvent-2.0.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/AceHook-2.1/AceHook-2.1.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/AceLibrary/AceLibrary.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/AceLocale-2.2/AceLocale-2.2.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/AceModuleCore-2.0/AceModuleCore-2.0.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/AceOO-2.0/AceOO-2.0.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/Dewdrop/Dewdrop-2.0.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/FuBarPlugin/FuBarPlugin-2.0.lua create mode 100644 Payload/Interface/Addons/SuperAPI/libs/Tablet/Tablet-2.0.lua create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/Bindings.xml create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/README.md create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/UnitXP_SP3_Addon.lua create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/UnitXP_SP3_Addon.toc create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/UnitXP_SP3_Addon.xml create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/libs/AceCore-3.0.lua create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/libs/AceHook-3.0.lua create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/libs/CallbackHandler-1.0.lua create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/libs/LibDBIcon-1.0.lua create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/libs/LibDataBroker-1.1.lua create mode 100644 Payload/Interface/Addons/UnitXP_SP3_Addon/libs/LibStub.lua create mode 100644 Payload/Interface/Addons/nampowersettings/Localization.lua create mode 100644 Payload/Interface/Addons/nampowersettings/NampowerSettings.toc create mode 100644 Payload/Interface/Addons/nampowersettings/README.md create mode 100644 Payload/Interface/Addons/nampowersettings/helper.lua create mode 100644 Payload/Interface/Addons/nampowersettings/img.png create mode 100644 Payload/Interface/Addons/nampowersettings/libs/AceAddon-2.0/AceAddon-2.0.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/AceConsole-2.0/AceConsole-2.0.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/AceDB-2.0/AceDB-2.0.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/AceDebug-2.0/AceDebug-2.0.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/AceEvent-2.0/AceEvent-2.0.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/AceHook-2.1/AceHook-2.1.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/AceLibrary/AceLibrary.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/AceLocale-2.2/AceLocale-2.2.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/AceModuleCore-2.0/AceModuleCore-2.0.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/AceOO-2.0/AceOO-2.0.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/Dewdrop/Dewdrop-2.0.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/FuBarPlugin/FuBarPlugin-2.0.lua create mode 100644 Payload/Interface/Addons/nampowersettings/libs/Tablet/Tablet-2.0.lua create mode 100644 Payload/Interface/Addons/nampowersettings/settings.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/Bindings.xml create mode 100644 Payload/Interface/Addons/perfboostsettings/GUIDE.md create mode 100644 Payload/Interface/Addons/perfboostsettings/PerfBoostSettings.toc create mode 100644 Payload/Interface/Addons/perfboostsettings/README.md create mode 100644 Payload/Interface/Addons/perfboostsettings/img.png create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/AceAddon-2.0/AceAddon-2.0.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/AceConsole-2.0/AceConsole-2.0.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/AceDB-2.0/AceDB-2.0.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/AceDebug-2.0/AceDebug-2.0.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/AceEvent-2.0/AceEvent-2.0.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/AceHook-2.1/AceHook-2.1.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/AceLibrary/AceLibrary.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/AceLocale-2.2/AceLocale-2.2.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/AceModuleCore-2.0/AceModuleCore-2.0.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/AceOO-2.0/AceOO-2.0.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/Dewdrop/Dewdrop-2.0.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/FuBarPlugin/FuBarPlugin-2.0.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/libs/Tablet/Tablet-2.0.lua create mode 100644 Payload/Interface/Addons/perfboostsettings/settings.lua create mode 100644 Payload/SuperWoWhook.dll create mode 100644 Payload/UnitXP_SP3.dll create mode 100644 Payload/VanillaFixes.exe create mode 100644 Payload/VanillaHelpers.dll create mode 100644 Payload/VfPatcher.dll create mode 100644 Payload/WeirdUtils/bigcursor.dll create mode 100644 Payload/WeirdUtils/customassets.dll create mode 100644 Payload/WeirdUtils/logsessions.dll create mode 100644 Payload/WeirdUtils/minimapicons.dll create mode 100644 Payload/WeirdUtils/pngscreenshots.dll create mode 100644 Payload/WeirdUtils/transmogfix.dll create mode 100644 Payload/WeirdUtils/weirdperformance.dll create mode 100644 Payload/WeirdUtils/worldmarkers.dll create mode 100644 Payload/dxvk.conf create mode 100644 Payload/nampower.dll create mode 100644 Payload/no1600x1200.dll create mode 100644 Payload/perf_boost.dll create mode 100644 PurpleWowLogo.ico create mode 100644 setup_tool.py create mode 100644 vanilla-tweaks.exe diff --git a/Build.bat b/Build.bat new file mode 100644 index 0000000..add8f9d --- /dev/null +++ b/Build.bat @@ -0,0 +1 @@ +pyinstaller --noconsole --onefile --add-data "Payload;Payload" --add-data "vanilla-tweaks.exe;." setup_tool.py \ No newline at end of file diff --git a/Payload/Data/Interface/GlueXML/AutoLogin.lua b/Payload/Data/Interface/GlueXML/AutoLogin.lua new file mode 100644 index 0000000..979af09 --- /dev/null +++ b/Payload/Data/Interface/GlueXML/AutoLogin.lua @@ -0,0 +1,1019 @@ +-------- +-- setup +-------- + +-- toto, make cancelling a login clear LoginManager.auto_char_button_pressed = true + +local _G = _G or getfenv(0) +local PASSWORD_MASK = "***************" + +local L = {} + +L["enUS"] = { + -- localize the Left value + class = { + ["Druid"] = "Druid", + ["Hunter"] = "Hunter", + ["Mage"] = "Mage", + ["Paladin"] = "Paladin", + ["Priest"] = "Priest", + ["Rogue"] = "Rogue", + ["Shaman"] = "Shaman", + ["Warrior"] = "Warrior", + ["Warlock"] = "Warlock", + }, + -- localize the Right value + ["SelectAccount"] = "Select account", + ["RemoveAccount"] = "Remove account", + ["LockAccounts"] = "Lock", + ["StreamerMode"] = "Streamer", + ["EncryptMode"] = "Encrypt", + ["LockCharacters"] = "Lock Characters", + ["NoDeps"] = "|cff77ff00Turtle AutoLogin|r requires Nampower 3.2.0+ or SuperWoW 1.4+ to operate.", +} + +L["ruRU"] = { + -- localize the Left value + class = { + ["Друид"] = "Druid", + ["Охотник"] = "Hunter", + ["Маг"] = "Mage", + ["Паладин"] = "Paladin", + ["Жрец"] = "Priest", + ["Разбойник"] = "Rogue", + ["Шаман"] = "Shaman", + ["Воин"] = "Warrior", + ["Чернокнижник"] = "Warlock", + }, + -- localize the Right value + ["SelectAccount"] = "Выберите аккаунт", + ["RemoveAccount"] = "Удалить аккаунт", + ["LockAccounts"] = "Блок.", + ["StreamerMode"] = "Стример", + ["EncryptMode"] = "Шифр.", + ["LockCharacters"] = "Заблокировать персонажей", + ["NoDeps"] = "|cff77ff00Turtle AutoLogin|r требует Nampower 3.2.0+ или SuperWoW 1.4+ для работы.", +} + +L = L[GetLocale()] or L["enUS"] + +local has_nampower = EncryptPassword and EncryptedServerLogin +local has_superwow = (ImportFile and ExportFile) or (SUPERWOW_VERSION and tonumber(SUPERWOW_VERSION) >= 1.4) +local has_encryption = false +local encryption_missing_key = false +if has_nampower then + local ok, err = pcall(EncryptPassword, "test") + if ok then + has_encryption = true + elseif string.find(err or "", "WOW_ENCRYPTION_KEY is not set") then + encryption_missing_key = true + end +end + +if not has_nampower and not has_superwow then + GlueDialogTypes["AL_NO_DEPS"] = { + text = L["NoDeps"], + button1 = TEXT(OKAY), + showAlert = 1, + } + + GlueDialog_Show("AL_NO_DEPS") + return +end + +GlueDialogTypes["AL_CANT_DECRYPT"] = { + text = "This account's password is encrypted but decryption is not available.\nPlease re-enter your password to save it again.", + button1 = TEXT(OKAY), + showAlert = 1, +} + +local CLASS_COLORS = { + ["Druid"] = { r = 1.00, g = 0.49, b = 0.04, colorStr = "ffFF7C0A" }, + ["Mage"] = { r = 0.25, g = 0.78, b = 0.92, colorStr = "ff3FC7EB" }, + ["Hunter"] = { r = 0.67, g = 0.83, b = 0.45, colorStr = "ffAAD372" }, + ["Paladin"] = { r = 0.96, g = 0.55, b = 0.73, colorStr = "ffF48CBA" }, + ["Priest"] = { r = 1.00, g = 1.00, b = 1.00, colorStr = "ffFFFFFF" }, + ["Rogue"] = { r = 1.00, g = 0.96, b = 0.41, colorStr = "ffFFF468" }, + ["Shaman"] = { r = 0.00, g = 0.44, b = 0.87, colorStr = "ff0070DD" }, + ["Warlock"] = { r = 0.53, g = 0.53, b = 0.93, colorStr = "ff8788EE" }, + ["Warrior"] = { r = 0.78, g = 0.61, b = 0.43, colorStr = "ffC69B6D" }, +} + +LoginManager = {} +LoginManager.State = {} +LoginManager.SelectedAcct = nil +LoginManager.CurrentPage = 0 +LoginManager.PageSize = 9 +LoginManager.LimitReached = false +LoginManager.from_login_screen = false +LoginManager.has_nampower = has_nampower +LoginManager.has_superwow = has_superwow + +-------- + +------- +-- util +------- + +-- Move the element at 'index' upward by one position. +local function moveIndexUp(list, index) + if index > 1 then + local item = table.remove(list, index) + table.insert(list, index - 1, item) + end +end + +-- Move the element at 'index' downward by one position. +local function moveIndexDown(list, index) + if list[index] and list[index+1] then + local item = table.remove(list, index) + table.insert(list, index + 1, item) + end +end +------- + +--------- +-- serial +--------- +local Serialize = { + serializeValue = function (self,val,indent) + local t = type(val) + if t == "string" then + return string.format("%q", val) + elseif t == "number" or t == "boolean" then + return tostring(val) + elseif t == "table" then + return self:serializeTable(val,indent) + else + return '""' + end + end, + serializeTable = function (self,tbl,indent) + indent = indent or "" + local nextIndent = indent .. " " + local result = {} + table.insert(result, "{\n") + for k, v in pairs(tbl) do + local key + if type(k) == "string" and string.find(k, "^[_%a][_%w]*$") then + key = k + else + key = "[" .. self:serializeValue(k, nextIndent) .. "]" + end + table.insert(result, nextIndent .. key .. " = " .. self:serializeValue(v, nextIndent) .. ",\n") + end + table.insert(result, indent .. "}") + return table.concat(result) + end, +} +--------- + +--------------- +-- LoginManager +--------------- + +function LoginManager:ToFile(file,value) + local v = Serialize:serializeValue(value) + if v ~= '""' then + ExportFile(file, Serialize:serializeValue(value," ")) + return true + end + return false +end + +function LoginManager:FromFile(file) + local contents = ImportFile(file) + if contents then + local chunk,err = loadstring("return " .. contents) + if not err then + return chunk() + end + end + return false +end + +function LoginManager:HideSideButtons() + local hide_frames = { + "AccountLoginTurtleWebsite", + "AccountLoginTurtleArmory", + "AccountLoginTurtleKnowledgeDatabase", + "AccountLoginTurtleCommunityForum", + "AccountLoginTurtleDiscord", + "AccountLoginTurtleReddit", + "AccountLoginCinematicsButton", + -- "AccountLoginCreditsButton", + } + for _,frame in ipairs(hide_frames) do + if _G[frame] then _G[frame]:Hide() end + end +end + +function LoginManager:MakeExtraAccountButtons() + -- make account up/down/lock buttons + local button_size = 26 + for i=1,self.PageSize do + local acctButton = _G["AutologinAccountButton"..i] + if not acctButton.up then + -- Create the Up button + local upButton = CreateFrame("Button", acctButton:GetName().."Up", acctButton) + upButton:SetWidth(button_size) + upButton:SetHeight(button_size) + upButton:SetPoint("TOPRIGHT", acctButton, "TOPRIGHT", -30, 1) + upButton:SetHitRectInsets(1, 1, 1, 1) + upButton:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollUp-Up") + upButton:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollUp-Down") + upButton:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight", "ADD") + + upButton:SetScript("OnClick", function() + moveIndexUp(self.State.accounts, this:GetParent():GetID()) + LoginManager:UpdateUI() + end) + upButton:SetScript("OnEnter", function() + this:GetParent():LockHighlight() + end) + upButton:SetScript("OnLeave", function() + if this:GetParent():GetID() ~= self.SelectedAcct then + this:GetParent():UnlockHighlight() + end + end) + acctButton.up = upButton + end + + if not acctButton.down then + -- Create the Down button + local downButton = CreateFrame("Button", acctButton:GetName().."Down", acctButton) + downButton:SetWidth(button_size) + downButton:SetHeight(button_size) + downButton:SetPoint("TOP", acctButton.up, "BOTTOM", 0, 8) + downButton:SetHitRectInsets(1, 1, 1, 1) + downButton:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up") + downButton:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down") + downButton:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight", "ADD") + + downButton:SetScript("OnClick", function() + moveIndexDown(self.State.accounts, this:GetParent():GetID()) + LoginManager:UpdateUI() + end) + downButton:SetScript("OnEnter", function() + this:GetParent():LockHighlight() + end) + downButton:SetScript("OnLeave", function() + if this:GetParent():GetID() ~= self.SelectedAcct then + this:GetParent():UnlockHighlight() + end + end) + acctButton.down = downButton + end + + if not acctButton.char then + -- Create the Char button + local charButton = CreateFrame("Button", acctButton:GetName().."Char", acctButton, "GlueButtonSmallTemplate") + charButton:SetWidth(40) + charButton:SetHeight(35) + charButton:SetPoint("RIGHT", acctButton, "RIGHT", -50, 8) + charButton:SetHitRectInsets(1, 1, 1, 1) + + charButton:SetScript("OnClick", function() + LoginManager:SelectAccount(this:GetParent():GetID()) + LoginManager.auto_char_button_pressed = true + AccountLogin_Login() + end) + charButton:SetScript("OnEnter", function() + this:GetParent():LockHighlight() + end) + charButton:SetScript("OnLeave", function() + if this:GetParent():GetID() ~= self.SelectedAcct then + this:GetParent():UnlockHighlight() + end + end) + acctButton.char = charButton + end + end + + local quitButton = _G["AccountLoginExitButton"] + if has_nampower and not quitButton.encrypt then + local encryptButton = CreateFrame("Button", "ButtonAccountButtonsEncrypt", quitButton, "GlueButtonSmallTemplate") + encryptButton:SetWidth(150) + encryptButton:SetHeight(35) + encryptButton:SetPoint("RIGHT", quitButton, "LEFT", 4, 0) + + encryptButton:SetText(L["EncryptMode"]) + encryptButton:SetWidth(encryptButton:GetFontString():GetStringWidth() + 50) + + encryptButton:SetScript("OnClick", function() + if encryption_missing_key then return end + LoginManager.State.encrypt_passwords = not LoginManager.State.encrypt_passwords + this:Show() + LoginManager:SaveAccounts() + LoginManager:UpdateUI() + end) + if encryption_missing_key then + encryptButton:SetScript("OnEnter", function() + GlueTooltip_SetOwner(nil, encryptButton, 0, 0) + GlueTooltip:ClearAllPoints() + GlueTooltip:SetPoint("BOTTOM", encryptButton, "TOP", 0, 4) + GlueTooltip_SetText("Set environment variable\n|cffffd100WOW_ENCRYPTION_KEY|r to enable.", nil, 1, 1, 1) + end) + encryptButton:SetScript("OnLeave", function() + GlueTooltip:Hide() + end) + end + quitButton.encrypt = encryptButton + end + + if not quitButton.lock then + local lockButton = CreateFrame("Button", "ButtonAccountButtonsLock", quitButton, "GlueButtonSmallTemplate") + lockButton:SetWidth(150) + lockButton:SetHeight(35) + lockButton:SetPoint("RIGHT", (quitButton.encrypt or quitButton), "LEFT", 4, 0) + + lockButton:SetText(L["LockAccounts"]) + lockButton:SetWidth(lockButton:GetFontString():GetStringWidth() + 50) + + lockButton:SetScript("OnClick", function() + LoginManager.State.account_buttons_locked = not LoginManager.State.account_buttons_locked + this:Show() + LoginManager:SaveAccounts() + + LoginManager:UpdateUI() + end) + quitButton.lock = lockButton + end + + if not quitButton.streamer then + local streamerButton = CreateFrame("Button", "ButtonAccountButtonsStreamer", quitButton, "GlueButtonSmallTemplate") + streamerButton:SetWidth(150) + streamerButton:SetHeight(35) + streamerButton:SetPoint("RIGHT", quitButton.lock, "LEFT", 4, 0) + + streamerButton:SetText(L["StreamerMode"]) + streamerButton:SetWidth(streamerButton:GetFontString():GetStringWidth() + 50) + + streamerButton:SetScript("OnClick", function() + LoginManager.State.account_buttons_streamer = not LoginManager.State.account_buttons_streamer + this:Show() + + LoginManager:UpdateUI() + end) + quitButton.streamer = streamerButton + end + + if not AccountLoginAccountEdit.cover then + -- Create the account input cover for streaming mode + local cover = CreateFrame("Frame", nil, AccountLoginAccountEdit) + cover:SetFrameLevel(AccountLoginAccountEdit:GetFrameLevel() + 10) + + cover:SetWidth(AccountLoginAccountEdit:GetWidth()-15) + cover:SetHeight(AccountLoginAccountEdit:GetHeight()-15) + cover:SetPoint("TOPLEFT",AccountLoginAccountEdit,"TOPLEFT", 10, -6) + + local tex = cover:CreateTexture() + tex:SetAllPoints(cover) + tex:SetTexture(0, 0, 0, 1) -- RGBA: Black, 80% opaque + + AccountLoginAccountEdit.cover = cover + end +end + +-- Strangely when you login and cancel the program scrubs the string you used for the password from _anywhere_ it finds it. +-- Essentially it deletes the immutable string itself. We avoid this by storing the password string in memory with a +-- leading prefix and clip it at use-time. : = plaintext, :encrypted: = encrypted (nampower). +function LoginManager:LoadAccounts() + self.State.accounts = {} + self.State.last = nil + + local login_data = ImportFile("logins") + local file = self:FromFile("logins") + if file then + if file.accounts then self.State.accounts = file.accounts end + if file.last then self.State.last = file.last end + if file.account_buttons_locked then self.State.account_buttons_locked = file.account_buttons_locked end + if file.account_buttons_streamer then self.State.account_buttons_streamer = file.account_buttons_streamer end + if has_encryption and file.encrypt_passwords ~= nil then + self.State.encrypt_passwords = file.encrypt_passwords + elseif has_encryption then + self.State.encrypt_passwords = true + end + return true + elseif login_data then -- old format + for label,account,password,character,auto,last in string.gfind(login_data, "label:(%S*) account:(%S+) password(:%S+) character:(%S*) auto:(%S*) last:(%S*)\n") do + if auto == "true" then auto = true else auto = false end + table.insert(self.State.accounts, { --[[ label = label, ]] account = account, password = password, character = character, auto = auto }) + end + return true + end + -- no saved passwords? check the old style account string storage + if not next(self.State.accounts) then + local val = GetSavedAccountName() + for n, p, c in string.gfind(val, "(%S+) (%S+) *(%d*);") do + if (c == "") then c = "-" end + + -- Decompress duplicate passwords + if (string.find(p, "~%d") == 1) then + p = self.State.accounts[tonumber(string.sub(p, 2, 3))].password + end + + table.insert(self.State.accounts, { account = n, password = p }) + end + return true + end + return false +end + +function LoginManager:SaveAccounts(by_login) + if by_login then + local account = AccountLoginAccountEdit:GetText() + local password = AccountLoginPasswordEdit:GetText() + + -- only try to overwrite a password when there is one to overwrite! + if (account and account ~= "" and password and password ~= "" and password ~= PASSWORD_MASK) then + local stored = ":"..password + if self.State.encrypt_passwords then + local ok, encrypted = pcall(EncryptPassword, password) + if ok then stored = encrypted end + end + local exists = false + for i = 1, table.getn(self.State.accounts) do + if (self.State.accounts[i].account == account) then + exists = true + self.State.accounts[i].password = stored + break + end + end + if (not exists) then + self.pending_account = { account = account, password = stored } + end + end + end + + return self:ToFile("logins", self.State) +end + +function LoginManager:SaveLabel() + self:SaveAccounts(true) + self:UpdateUI() +end + +function LoginManager:SelectAccount(idx) + local i = self.CurrentPage * self.PageSize + idx; + local act = self.State.accounts[i].account + local pwd = self.State.accounts[i].password + + AccountLoginAccountEdit:SetText(act) + if string.find(pwd, "^:encrypted:") then + AccountLoginPasswordEdit:SetText(PASSWORD_MASK) + else + AccountLoginPasswordEdit:SetText(string.sub(pwd, 2)) + end + LoginManager:OnNameUpdate(act) +end + +function LoginManager:OnNameUpdate(name) + self.SelectedAcct = nil + for i = 1, table.getn(self.State.accounts) do + if (self.State.accounts[i].account == name) then self.SelectedAcct = i end + end + if (self.SelectedAcct) then + self.CurrentPage = math.floor((self.SelectedAcct - 1) / self.PageSize) + end + self:UpdateUI() +end + +function LoginManager:UpdateUI() + if AccountLoginUI:IsVisible() then + self:MakeExtraAccountButtons() + self:HideSideButtons() + AccountLoginSaveAccountName:Hide() + self:UpdateLoginUI() + elseif CharacterSelectUI:IsVisible() then + self:UpdateCharacterUI() + end +end + +function LoginManager:UpdateLoginUI() + local total = table.getn(self.State.accounts) + local pageIndices = {} + local skip = self.CurrentPage * self.PageSize; + + AutologinSelectAccountText:SetText(L["SelectAccount"]) + AutologinRemoveAccountButton:SetText(L["RemoveAccount"]) + + local streamer = self.State.account_buttons_streamer + if AccountLoginAccountEdit.cover then + if streamer then + AccountLoginAccountEdit.cover:Show() + else + AccountLoginAccountEdit.cover:Hide() + end + end + + for i = 1, self.PageSize do + local button = _G["AutologinAccountButton" .. i] + local acct_id = skip + i + button:UnlockHighlight() + if (acct_id > total) then + button:Hide() + else + local r = self.State.accounts[acct_id] + local selected = self.SelectedAcct == acct_id + + local acc_str = r.account + if streamer then + acc_str = string.sub(acc_str,1,1) .. string.rep('*',5) .. string.sub(acc_str,-2) + end + _G["AutologinAccountButton" .. i .. "ButtonTextName"]:SetText(acc_str) + + -- get save class, show character login name using class info and whether we're in streamer mode + local class_str = r.class or "-----" + local chr_str = streamer and class_str or r.character + local class_clr = r.class and L.class[class_str] and CLASS_COLORS[L.class[class_str]].colorStr + + if class_clr then + chr_str = class_clr and ("|c" .. class_clr .. chr_str .. "|r") + end + + button.char:SetText(chr_str or "") + button.char:SetWidth(button.char:GetFontString():GetStringWidth() + 20) + + if self.State.account_buttons_locked or acct_id == table.getn(self.State.accounts) then + button.down:Hide() + else + button.down:Show() + end + if self.State.account_buttons_locked or acct_id == 1 then + button.up:Hide() + else + button.up:Show() + end + if not r.character or r.character == "" then + button.char:Hide() + else + button.char:Show() + end + if selected then + button:LockHighlight() + end + button:Show() + + end + end + + local lockButton = _G["ButtonAccountButtonsLock"] + if lockButton then + if self.State.account_buttons_locked then + lockButton:GetNormalTexture():SetVertexColor(0.5,0.5,0.5) + lockButton:SetTextColor(0.5,0.5,0.5) + else + lockButton:GetNormalTexture():SetVertexColor(1,1,1) + lockButton:SetTextColor(1,0.78,0) + end + end + local streamerButton = _G["ButtonAccountButtonsStreamer"] + if streamerButton then + if self.State.account_buttons_streamer then + streamerButton:GetNormalTexture():SetVertexColor(0.5,0.5,0.5) + streamerButton:SetTextColor(0.5,0.5,0.5) + else + streamerButton:GetNormalTexture():SetVertexColor(1,1,1) + streamerButton:SetTextColor(1,0.78,0) + end + end + local encryptButton = _G["ButtonAccountButtonsEncrypt"] + if encryptButton then + if encryption_missing_key then + encryptButton:GetNormalTexture():SetVertexColor(0.3,0.3,0.3) + encryptButton:SetTextColor(0.7,0.15,0.15) + elseif self.State.encrypt_passwords then + encryptButton:GetNormalTexture():SetVertexColor(0.5,0.5,0.5) + encryptButton:SetTextColor(0.5,0.5,0.5) + else + encryptButton:GetNormalTexture():SetVertexColor(1,1,1) + encryptButton:SetTextColor(1,0.78,0) + end + end + + local removeButton = _G["AutologinRemoveAccountButton"] + if removeButton then + if self.State.account_buttons_locked then + removeButton:Hide() + else + removeButton:Show() + end + end +end + +function LoginManager:UpdateCharacterUI() + local numChars = GetNumCharacters() + local index = 1 + for _,char in ipairs(LoginManager.realm_chars) do + local zone = char.zone + + local button = _G["CharSelectCharacterButton"..index] + if ( not char.name ) then + button:SetText("ERROR - Tell Jeremy") + else + button:UnlockHighlight() + if ( not char.zone ) then + zone = "" + end + local classColor = L.class[char.class] and CLASS_COLORS[L.class[char.class]].colorStr or "ffFFFFFF" + + _G["CharSelectCharacterButton"..index.."ButtonTextName"]:SetText(char.name) + _G["CharSelectCharacterButton"..index.."ButtonTextInfo"]:SetText( + format(TEXT(char.ghost and CHARACTER_SELECT_INFO_GHOST or CHARACTER_SELECT_INFO), char.level, "|c" .. classColor .. char.class .. "|r") + ) + _G["CharSelectCharacterButton"..index.."ButtonTextLocation"]:SetText(zone) + end + + if (char.id == CharacterSelect.selectedIndex) then + button:LockHighlight() + end + + if LoginManager.char_buttons_locked then + button.up:Hide() + button.down:Hide() + else + button.up:Show() + button.down:Show() + end + + index = index + 1 + if ( index > MAX_CHARACTERS_DISPLAYED ) then + break + end + end + + local lockButton = _G["ButtonCharButtonsLock"] + if lockButton then + if self.char_buttons_locked then + lockButton:GetNormalTexture():SetVertexColor(0.5,0.5,0.5) + lockButton:SetTextColor(0.5,0.5,0.5) + else + lockButton:GetNormalTexture():SetVertexColor(1,1,1) + lockButton:SetTextColor(1,0.78,0) + end + end +end + +function LoginManager:OnLogin() + local name = AccountLoginAccountEdit:GetText() + local password = AccountLoginPasswordEdit:GetText() + + self.State.last = self.SelectedAcct + self:SaveAccounts(true) + self:OnNameUpdate(name) + self.from_login_screen = true + + if self.SelectedAcct and self.State.accounts[self.SelectedAcct] then + local stored = self.State.accounts[self.SelectedAcct].password + if string.find(stored, "^:encrypted:") then + if not has_encryption then + GlueDialog_Show("AL_CANT_DECRYPT") + return + end + EncryptedServerLogin(name, stored) + return + end + end + DefaultServerLogin(name, password) +end + +function LoginManager:RemoveAccount() + if not next(LoginManager.State.accounts) or not LoginManager.SelectedAcct then return end + + table.remove(LoginManager.State.accounts, LoginManager.SelectedAcct) + LoginManager:SaveAccounts() + AccountLoginAccountEdit:SetText("") + AccountLoginPasswordEdit:SetText("") + + if (LoginManager.CurrentPage > 0 and LoginManager.CurrentPage * LoginManager.PageSize > + table.getn(LoginManager.State) - 1) then + LoginManager.CurrentPage = LoginManager.CurrentPage - 1 + end + + LoginManager:UpdateUI() +end + +function LoginManager:NextPage() + if ((self.CurrentPage + 1) * self.PageSize > + table.getn(self.State.accounts) - 1) then return end + self.CurrentPage = self.CurrentPage + 1 + self:UpdateUI() +end + +function LoginManager:PrevPage() + if (self.CurrentPage == 0) then return end + self.CurrentPage = self.CurrentPage - 1 + self:UpdateUI() +end + +function LoginManager:OnCharactersLoad() + + self:LoadAccounts() + + if self.pending_account and self.pending_account.account and self.pending_account.account ~= "" + and self.pending_account.password and self.pending_account.password ~= "" then + table.insert(self.State.accounts, self.pending_account) + self:SaveAccounts() + end + self.pending_account = nil + + -- make up/down/auto buttons + for i=1,10 do + local charButton = _G["CharSelectCharacterButton"..i] + if not charButton.up then + -- Create the Up button + local upButton = CreateFrame("Button", charButton:GetName().."Up", charButton) + upButton:SetWidth(32) + upButton:SetHeight(32) + upButton:SetPoint("TOPRIGHT", charButton, "TOPRIGHT", -30, 0) + upButton:SetHitRectInsets(1, 1, 1, 1) + upButton:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollUp-Up") + upButton:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollUp-Down") + upButton:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight", "ADD") + + upButton:SetScript("OnClick", function() + moveIndexUp(LoginManager.realm_chars, this:GetParent():GetID()) + LoginManager:UpdateUI() + end) + upButton:SetScript("OnEnter", function() + this:GetParent():LockHighlight() + end) + upButton:SetScript("OnLeave", function() + if this:GetParent():GetID() ~= CharacterSelect.selectedIndex then + this:GetParent():UnlockHighlight() + end + end) + charButton.up = upButton + end + + if not charButton.down then + -- Create the Down button + local downButton = CreateFrame("Button", charButton:GetName().."Down", charButton) + downButton:SetWidth(32) + downButton:SetHeight(32) + downButton:SetPoint("TOP", charButton.up, "BOTTOM", 0, 8) + downButton:SetHitRectInsets(1, 1, 1, 1) + downButton:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up") + downButton:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Down") + downButton:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight", "ADD") + + downButton:SetScript("OnClick", function() + moveIndexDown(LoginManager.realm_chars, this:GetParent():GetID()) + LoginManager:UpdateUI() + end) + downButton:SetScript("OnEnter", function() + this:GetParent():LockHighlight() + end) + downButton:SetScript("OnLeave", function() + if this:GetParent():GetID() ~= CharacterSelect.selectedIndex then + this:GetParent():UnlockHighlight() + end + end) + charButton.down = downButton + end + end + + local addonsButton = _G["CharacterSelectAddonsButton"] + if not addonsButton.lock then + -- Create the Lock button + local lockButton = CreateFrame("Button", "ButtonCharButtonsLock", addonsButton, "GlueButtonSmallTemplate") + lockButton:SetWidth(150) + lockButton:SetHeight(35) + lockButton:SetPoint("LEFT", addonsButton, "RIGHT", 4, 0) + + lockButton:SetText(L["LockCharacters"]) + lockButton:SetWidth(lockButton:GetFontString():GetStringWidth() + 50) + + lockButton:SetScript("OnClick", function() + LoginManager.char_buttons_locked = not LoginManager.char_buttons_locked + this:Show() + LoginManager:SaveAccounts() + + LoginManager:UpdateUI() + end) + addonsButton.lock = lockButton + end + + self.realm = GetServerName() + self.realm_chars = {} + for c = 1, GetNumCharacters() do + local name, race, class, level, zone, fileString, gender, ghost = GetCharacterInfo(c) + self.realm_chars[c] = { id = c, name = name, race = race, class = class, level = level, zone = zone, fileString = fileString, gender = gender, ghost = ghost } + end + + if not self.from_login_screen then + -- handle case that we came from a char logout, iow determine what account we're using based on characters + -- this matters when we're multiboxing or have auto-login enabled + local function SetIdx() + for i,account in ipairs(self.State.accounts) do + for saved_realm,saved_chars in pairs(account.characters or {}) do + if saved_realm == self.realm then + for _,schar in pairs(saved_chars.order) do + for _,rchar in pairs(self.realm_chars) do + if schar.name == rchar.name then + self.SelectedAcct = i + return + end + end + end + end + end + end + end + SetIdx() + end + + -- reconcile given chars with saved chars + local acct = self.State.accounts[self.SelectedAcct] + if acct and acct.characters then + for saved_realm,saved_chars in pairs(acct.characters or {}) do + if saved_realm == self.realm then + self.char_buttons_locked = saved_chars.char_buttons_locked + + local orderRank = {} + local rank = 1 + for _, item in ipairs(saved_chars.order or {}) do + orderRank[item.id] = rank + rank = rank + 1 + end + + -- Reorder primaryList in place using table.sort with a custom comparator. + table.sort(LoginManager.realm_chars, function(a, b) + local ra = orderRank[a.id] or 10000 + local rb = orderRank[b.id] or 10000 + return ra < rb + end) + + local numChars = GetNumCharacters() + if numChars > 0 then + CharacterSelect_SelectCharacter(math.min(saved_chars.last or 1, numChars)) + if self.auto_char_button_pressed then + self.auto_char_button_pressed = false + EnterWorld() + end + end + + break + end + end + end + + self:UpdateUI() +end + +function LoginManager:EnterWorld() + -- save live state + + if self.realm and self.SelectedAcct and self.State.accounts[self.SelectedAcct] then + local acct = self.State.accounts[self.SelectedAcct] + acct.characters = acct.characters or {} + acct.characters[self.realm] = acct.characters[self.realm] or {} + + local chars = acct.characters[self.realm] + chars.last = CharacterSelect.selectedIndex or 1 + chars.order = {} + for i,char in ipairs(LoginManager.realm_chars) do + table.insert(chars.order, { id = char.id, name = char.name }) + end + chars.char_buttons_locked = self.char_buttons_locked or nil + local name, race, class, _level, zone, _race2, _gender, _isGhost = GetCharacterInfo(chars.last) + + acct.character = name + acct.class = class + acct.race = race + acct.zone = zone + end + self:SaveAccounts() + + EnterWorld() +end + +--------------- + +---------- +-- buttons +---------- +function AutologinAccountButton_OnClick(button) + if button == "LeftButton" then + LoginManager:SelectAccount(this:GetID()) + end +end + +function AutologinAccountButton_OnDoubleClick() + LoginManager:SelectAccount(this:GetID()) + AccountLogin_Login() +end + +function AutologinRemoveAccountButton_OnClick() + LoginManager:RemoveAccount() +end +---------- + +-------- +-- hooks +-------- +local orig_AccountLogin_OnLoad = AccountLogin_OnLoad +AccountLogin_OnLoad = function (a1,a2,a3,a4,a5,a6,a7,a8,a9) + if orig_AccountLogin_OnLoad then orig_AccountLogin_OnLoad(a1,a2,a3,a4,a5,a6,a7,a8,a9) end + + LoginManager:LoadAccounts() +end + +local orig_AccountLogin_OnShow = AccountLogin_OnShow +AccountLogin_OnShow = function (a1,a2,a3,a4,a5,a6,a7,a8,a9) + + if orig_AccountLogin_OnShow then orig_AccountLogin_OnShow(a1,a2,a3,a4,a5,a6,a7,a8,a9) end + + if not LoginManager.State.accounts then LoginManager:LoadAccounts() end + + if LoginManager.State.last and LoginManager.State.accounts[LoginManager.State.last] then + LoginManager:SelectAccount(LoginManager.State.last) + end + + LoginManager:UpdateUI() +end + +local orig_AccountLoginAccountEdit_OnTextChanged = AccountLoginAccountEdit:GetScript("OnTextChanged") +AccountLoginAccountEdit:SetScript("OnTextChanged", function (a1,a2,a3,a4,a5,a6,a7,a8,a9) + orig_AccountLoginAccountEdit_OnTextChanged(a1,a2,a3,a4,a5,a6,a7,a8,a9) + LoginManager:OnNameUpdate(this:GetText()) +end) + +local orig_AccountLogin_Login = AccountLogin_Login +AccountLogin_Login = function (a1,a2,a3,a4,a5,a6,a7,a8,a9) + LoginManager:OnLogin() + -- if we got this far it's our show, take over + -- if orig_AccountLogin_Login then orig_AccountLogin_Login(a1,a2,a3,a4,a5,a6,a7,a8,a9) end +end + +-------- + +local orig_CharacterSelectButton_OnClick = CharacterSelectButton_OnClick +CharacterSelectButton_OnClick = function (a1,a2,a3,a4,a5,a6,a7,a8,a9) + -- orig_CharacterSelectButton_OnClick(a1,a2,a3,a4,a5,a6,a7,a8,a9) + local id = this:GetID() + local sorted_id = LoginManager.realm_chars[id].id + if ( sorted_id ~= CharacterSelect.selectedIndex ) then + CharacterSelect_SelectCharacter(sorted_id) + end + LoginManager:UpdateUI() +end + +local orig_CharacterSelectButton_OnDoubleClick = CharacterSelectButton_OnDoubleClick +CharacterSelectButton_OnDoubleClick = function (a1,a2,a3,a4,a5,a6,a7,a8,a9) + -- orig_CharacterSelectButton_OnDoubleClick(a1,a2,a3,a4,a5,a6,a7,a8,a9) + local id = this:GetID() + local sorted_id = LoginManager.realm_chars[id].id + if ( sorted_id ~= CharacterSelect.selectedIndex ) then + CharacterSelect_SelectCharacter(sorted_id) + end + CharacterSelect_EnterWorld() +end + +local orig_CharacterSelect_OnKeyDown = CharacterSelect_OnKeyDown +CharacterSelect_OnKeyDown = function (a1,a2,a3,a4,a5,a6,a7,a8,a9) + local numChars = GetNumCharacters() + local button_index + for i,char in ipairs(LoginManager.realm_chars) do + if char.id == this.selectedIndex then + button_index = i + break + end + end + + if ( arg1 == "UP" or arg1 == "LEFT" ) then + if ( numChars > 1 ) then + if ( button_index > 1 ) then + _G["CharSelectCharacterButton" .. (button_index - 1)]:Click() + else + _G["CharSelectCharacterButton" .. numChars]:Click() + end + end + elseif ( arg1 == "DOWN" or arg1 == "RIGHT" ) then + if ( numChars > 1 ) then + if ( button_index < GetNumCharacters() ) then + _G["CharSelectCharacterButton" .. (button_index + 1)]:Click() + else + _G["CharSelectCharacterButton" .. 1]:Click() + end + end + else + orig_CharacterSelect_OnKeyDown(a1,a2,a3,a4,a5,a6,a7,a8,a9) + end +end + +local orig_CharacterSelect_OnEvent = CharacterSelect_OnEvent +CharacterSelect_OnEvent = function (a1,a2,a3,a4,a5,a6,a7,a8,a9) + if orig_CharacterSelect_OnEvent then orig_CharacterSelect_OnEvent(a1,a2,a3,a4,a5,a6,a7,a8,a9) end + if event == "CHARACTER_LIST_UPDATE" then + LoginManager:OnCharactersLoad() + end +end + +local orig_CharacterSelect_EnterWorld = CharacterSelect_EnterWorld +CharacterSelect_EnterWorld = function (a1,a2,a3,a4,a5,a6,a7,a8,a9) + LoginManager:EnterWorld() +end +-------- + diff --git a/Payload/Data/Interface/GlueXML/AutoLogin.xml b/Payload/Data/Interface/GlueXML/AutoLogin.xml new file mode 100644 index 0000000..65c7d0c --- /dev/null +++ b/Payload/Data/Interface/GlueXML/AutoLogin.xml @@ -0,0 +1,249 @@ + +