From cddaf2c5157049984421759b7065f14edb5cf1ee Mon Sep 17 00:00:00 2001 From: sindoring Date: Sat, 18 Jul 2026 16:08:08 +0400 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B0=20=D0=B2?= =?UTF-8?q?=D0=BD=D1=82=D1=83=D1=80=D0=B8=20=D0=B8=D0=B3=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/moonwell/src/MoonWell.cpp | 24 +++++ .../Interface/GlueXML/CharacterSelect.lua | 6 ++ .../AddOns/MoonWellClient/MoonWellClient.lua | 95 +++++++++++-------- .../AddOns/MoonWellClient/MoonWellClient.toc | 5 +- 4 files changed, 89 insertions(+), 41 deletions(-) diff --git a/modules/moonwell/src/MoonWell.cpp b/modules/moonwell/src/MoonWell.cpp index e7857aa..cf01755 100644 --- a/modules/moonwell/src/MoonWell.cpp +++ b/modules/moonwell/src/MoonWell.cpp @@ -7,6 +7,7 @@ #include "core/Logger.hpp" #include "core/Mem.hpp" +#include "runtime/LuaBindings.hpp" #include "runtime/ModuleInstall.hpp" #include @@ -20,6 +21,26 @@ namespace moonwell { namespace { + constexpr uint32_t kTraitorFlag = 0x40000000u; + bool g_loginCharacterIsTraitor = false; + + int __cdecl SetLoginCharacterFlags(void* state) + { + uint32_t flags = 0; + if (state && wxl::runtime::lua::IsNumber(state, 1)) + flags = static_cast(wxl::runtime::lua::ToNumber(state, 1)); + + g_loginCharacterIsTraitor = (flags & kTraitorFlag) != 0; + wxl::runtime::lua::PushBoolean(state, g_loginCharacterIsTraitor ? 1 : 0); + return 1; + } + + int __cdecl IsTraitor(void* state) + { + wxl::runtime::lua::PushBoolean(state, g_loginCharacterIsTraitor ? 1 : 0); + return 1; + } + struct Patch { const char* name; @@ -196,6 +217,9 @@ namespace moonwell { Registration() { + wxl::runtime::lua::RegisterFunction( + "MoonWellSetLoginCharacterFlags", &SetLoginCharacterFlags); + wxl::runtime::lua::RegisterFunction("MoonWellIsTraitor", &IsTraitor); wxl::runtime::modules::RegisterBoot("moonwell", &InstallBoot); wxl::runtime::modules::Register("moonwell-log-flush", &InstallRuntimeLogFlush); } diff --git a/src/Data/ruRU/patch-ruRU-4/Interface/GlueXML/CharacterSelect.lua b/src/Data/ruRU/patch-ruRU-4/Interface/GlueXML/CharacterSelect.lua index ee82a6c..a9d404f 100644 --- a/src/Data/ruRU/patch-ruRU-4/Interface/GlueXML/CharacterSelect.lua +++ b/src/Data/ruRU/patch-ruRU-4/Interface/GlueXML/CharacterSelect.lua @@ -1139,6 +1139,12 @@ end function CharacterSelect_EnterWorld() PlaySound("gsCharacterSelectionEnterWorld"); StopGlueAmbience(); + -- Persist the server-provided game-mode bit across the GlueXML -> FrameXML + -- Lua-state transition. WarcraftXL owns the value for this Wow.exe process. + if ( type(MoonWellSetLoginCharacterFlags) == "function" ) then + local info = { GetCharacterInfo(CharacterSelect.selectedIndex) }; + MoonWellSetLoginCharacterFlags(info[11] or 0); + end EnterWorld(); end diff --git a/src/Data/ruRU/patch-ruRU-5/Interface/AddOns/MoonWellClient/MoonWellClient.lua b/src/Data/ruRU/patch-ruRU-5/Interface/AddOns/MoonWellClient/MoonWellClient.lua index 908e84b..d6a917a 100644 --- a/src/Data/ruRU/patch-ruRU-5/Interface/AddOns/MoonWellClient/MoonWellClient.lua +++ b/src/Data/ruRU/patch-ruRU-5/Interface/AddOns/MoonWellClient/MoonWellClient.lua @@ -1,62 +1,81 @@ --- ============================================================================ --- MoonWell Client --- Server integration: game modes, traitor faction display --- ============================================================================ +-- MoonWell client game-mode integration. +-- WarcraftXL retains the selected character's server-provided charFlags while +-- WoW replaces the GlueXML Lua state with the in-world FrameXML state. --- Global flag read by FrameXML files to decide which faction icon to show. --- true = show opposite faction icon (traitor) --- false = show real faction icon (normal) MoonWell_IsTraitor = false --- ============================================================================ --- AIO handler — called by server on login --- Server: AIO:Handle(player, "MoonWellClient", "Init", gameMode) --- gameMode: 0 = normal, 1 = traitor --- ============================================================================ - -if not AIO then - return -end - -local Handler = AIO.AddHandlers("MoonWellClient", {}) - -local function MoonWell_RefreshFactionIcons() - -- Portrait PvP icon +local function RefreshFactionIcons() if PlayerFrame_UpdatePvPStatus then PlayerFrame_UpdatePvPStatus() end - -- DragonUI PvP micro button: SetupPVPButton() runs on load before AIO responds, - -- so we refresh its DragonUIPVPIcon texture directly after Init. + + if PVPFrame and PVPFrame:IsShown() and PVPFrame_Update then + PVPFrame_Update() + end + if BattlefieldFrame and BattlefieldFrame:IsShown() and BattlefieldFrame_Update then + BattlefieldFrame_Update() + end + if PVPMicroButton and PVPMicroButton.DragonUIPVPIcon then local factionGroup = UnitFactionGroup("player") if factionGroup then local displayFaction = MoonWell_IsTraitor and (factionGroup == "Alliance" and "Horde" or "Alliance") or factionGroup - local microTexture = "Interface\\AddOns\\DragonUI\\Textures\\Micromenu\\micropvp" + local texture = "Interface\\AddOns\\DragonUI\\Textures\\Micromenu\\micropvp" local icon = PVPMicroButton.DragonUIPVPIcon + local highlight = PVPMicroButton:GetHighlightTexture() + if displayFaction == "Alliance" then - icon:SetTexture(microTexture) + icon:SetTexture(texture) icon:SetTexCoord(0, 118/256, 0, 151/256) + if highlight then + highlight:SetTexture(texture) + highlight:SetTexCoord(0, 118/256, 0, 151/256) + end elseif displayFaction == "Horde" then - icon:SetTexture(microTexture) + icon:SetTexture(texture) icon:SetTexCoord(118/256, 236/256, 0, 151/256) - end - local hl = PVPMicroButton:GetHighlightTexture() - if hl then - if displayFaction == "Alliance" then - hl:SetTexture(microTexture) - hl:SetTexCoord(0, 118/256, 0, 151/256) - elseif displayFaction == "Horde" then - hl:SetTexture(microTexture) - hl:SetTexCoord(118/256, 236/256, 0, 151/256) + if highlight then + highlight:SetTexture(texture) + highlight:SetTexCoord(118/256, 236/256, 0, 151/256) end end end end end -function Handler.Init(_, mode) - MoonWell_IsTraitor = (tonumber(mode) == 1) - MoonWell_RefreshFactionIcons() +local function ReadNativeGameMode() + if type(MoonWellIsTraitor) ~= "function" then + return false + end + + MoonWell_IsTraitor = MoonWellIsTraitor() and true or false + RefreshFactionIcons() + return true end + +local events = CreateFrame("Frame") +events:RegisterEvent("PLAYER_LOGIN") +events:RegisterEvent("PLAYER_ENTERING_WORLD") +events:RegisterEvent("UNIT_FACTION") +events:SetScript("OnEvent", function(self, event, unit) + if event ~= "UNIT_FACTION" or unit == "player" then + ReadNativeGameMode() + end +end) + +-- WarcraftXL may publish its Lua globals shortly after addons are loaded. +-- Lua 5.1/WotLK has no C_Timer, so retry cheaply until the native API appears. +local elapsedTotal = 0 +events:SetScript("OnUpdate", function(self, elapsed) + elapsedTotal = elapsedTotal + elapsed + if elapsedTotal < 0.25 then + return + end + elapsedTotal = 0 + + if ReadNativeGameMode() then + self:SetScript("OnUpdate", nil) + end +end) diff --git a/src/Data/ruRU/patch-ruRU-5/Interface/AddOns/MoonWellClient/MoonWellClient.toc b/src/Data/ruRU/patch-ruRU-5/Interface/AddOns/MoonWellClient/MoonWellClient.toc index e8f1919..e7ac2b3 100644 --- a/src/Data/ruRU/patch-ruRU-5/Interface/AddOns/MoonWellClient/MoonWellClient.toc +++ b/src/Data/ruRU/patch-ruRU-5/Interface/AddOns/MoonWellClient/MoonWellClient.toc @@ -1,10 +1,9 @@ ## Interface: 30300 ## Title: MoonWell Client -## Notes: MoonWell server integration — game modes, traitor faction display -## Version: 1.0.0 +## Notes: Native WarcraftXL game-mode and traitor faction display +## Version: 2.0.0 ## Author: MoonWell ## SavedVariables: MoonWellClientDB -## Dependencies: AIO_Client ## DefaultState: Enabled ## X-Hidden: 1