From 9d0f319c026d89d84747c5571b3596d9800d5fd2 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 20 May 2022 21:11:58 +0200 Subject: [PATCH] Add cg_drawfps + fixes --- data/ui_scripts/hud_info/hud.lua | 2 + data/ui_scripts/stats/__init__.lua | 242 ++++++++++----------- src/client/component/fps.cpp | 48 ++-- src/client/component/stats.cpp | 19 +- src/client/component/ui_scripting.cpp | 7 +- src/client/game/symbols.hpp | 2 +- src/client/resources/ui_scripts/common.lua | 58 +++-- 7 files changed, 193 insertions(+), 185 deletions(-) diff --git a/data/ui_scripts/hud_info/hud.lua b/data/ui_scripts/hud_info/hud.lua index ffc8dc07..15f59b5b 100644 --- a/data/ui_scripts/hud_info/hud.lua +++ b/data/ui_scripts/hud_info/hud.lua @@ -93,6 +93,7 @@ function infoelement(data) local value = LUI.UIText.new({ left = left + 5, top = textoffsety, + font = labelfont.Font, height = textheight, leftAnchor = true, topAnchor = true, @@ -156,3 +157,4 @@ LUI.onmenuopen("mp_hud", function(hud) hud.static:addElement(infobar) end) + diff --git a/data/ui_scripts/stats/__init__.lua b/data/ui_scripts/stats/__init__.lua index 9975bfe5..1de7894a 100644 --- a/data/ui_scripts/stats/__init__.lua +++ b/data/ui_scripts/stats/__init__.lua @@ -1,5 +1,5 @@ if (game:issingleplayer() or not Engine.InFrontend()) then - return + return end game:addlocalizedstring("LUA_MENU_STATS", "Stats") @@ -7,11 +7,15 @@ game:addlocalizedstring("LUA_MENU_STATS_DESC", "Edit player stats settings.") game:addlocalizedstring("LUA_MENU_UNLOCKALL_ITEMS", "Unlock all items") game:addlocalizedstring("LUA_MENU_UNLOCKALL_ITEMS_DESC", - "Whether items should be locked based on the player's stats or always unlocked.") + "Whether items should be locked based on the player's stats or always unlocked.") + +game:addlocalizedstring("LUA_MENU_UNLOCKALL_LOOT", "Unlock all loot") +game:addlocalizedstring("LUA_MENU_UNLOCKALL_LOOT_DESC", + "Whether loot should be locked based on the player's stats or always unlocked.") game:addlocalizedstring("LUA_MENU_UNLOCKALL_CLASSES", "Unlock all classes") game:addlocalizedstring("LUA_MENU_UNLOCKALL_CLASSES_DESC", - "Whether classes should be locked based on the player's stats or always unlocked.") + "Whether classes should be locked based on the player's stats or always unlocked.") game:addlocalizedstring("LUA_MENU_PRESTIGE", "Prestige") game:addlocalizedstring("LUA_MENU_PRESTIGE_DESC", "Edit prestige level.") @@ -25,166 +29,152 @@ game:addlocalizedstring("LUA_MENU_SETTINGS", "Settings") game:addlocalizedstring("LUA_MENU_EDIT_STATS", "Edit Stats") function createdivider(menu, text) - local element = LUI.UIElement.new({ - leftAnchor = true, - rightAnchor = true, - left = 0, - right = 0, - topAnchor = true, - bottomAnchor = false, - top = 0, - bottom = 33.33 - }) + local element = LUI.UIElement.new({ + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + topAnchor = true, + bottomAnchor = false, + top = 0, + bottom = 33.33 + }) - element.scrollingToNext = true - element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { - title_bar_text = Engine.ToUpperCase(Engine.Localize(text)) - })) + element.scrollingToNext = true + element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { + title_bar_text = Engine.ToUpperCase(Engine.Localize(text)) + })) - menu.list:addElement(element) + menu.list:addElement(element) end local personalizationbutton = LUI.MPLobbyBase.AddPersonalizationButton LUI.MPLobbyBase.AddPersonalizationButton = function(menu) - personalizationbutton(menu) - menu:AddButton("@LUA_MENU_STATS", function() - LUI.FlowManager.RequestAddMenu(nil, "stats_menu") - end) + personalizationbutton(menu) + menu:AddButton("@LUA_MENU_STATS", function() + LUI.FlowManager.RequestAddMenu(nil, "stats_menu") + end) end LUI.MenuBuilder.registerType("stats_menu", function(a1) - local menu = LUI.MenuTemplate.new(a1, { - menu_title = Engine.ToUpperCase(Engine.Localize("@LUA_MENU_STATS")), - menu_width = luiglobals.GenericMenuDims.OptionMenuWidth - }) + local menu = LUI.MenuTemplate.new(a1, { + menu_title = Engine.ToUpperCase(Engine.Localize("@LUA_MENU_STATS")), + menu_width = luiglobals.GenericMenuDims.OptionMenuWidth + }) - createdivider(menu, "@LUA_MENU_SETTINGS") + createdivider(menu, "@LUA_MENU_SETTINGS") - LUI.Options.CreateOptionButton(menu, "cg_unlockall_items", "@LUA_MENU_UNLOCKALL_ITEMS", - "@LUA_MENU_UNLOCKALL_ITEMS_DESC", {{ - text = "@LUA_MENU_ENABLED", - value = true - }, { - text = "@LUA_MENU_DISABLED", - value = false - }}, nil, nil) + LUI.Options.CreateOptionButton(menu, "cg_unlockall_items", "@LUA_MENU_UNLOCKALL_ITEMS", + "@LUA_MENU_UNLOCKALL_ITEMS_DESC", {{ + text = "@LUA_MENU_ENABLED", + value = true + }, { + text = "@LUA_MENU_DISABLED", + value = false + }}, nil, nil) - LUI.Options.CreateOptionButton(menu, "cg_unlockall_classes", "@LUA_MENU_UNLOCKALL_CLASSES", - "@LUA_MENU_UNLOCKALL_CLASSES_DESC", {{ - text = "@LUA_MENU_ENABLED", - value = true - }, { - text = "@LUA_MENU_DISABLED", - value = false - }}, nil, nil) + LUI.Options.CreateOptionButton(menu, "cg_unlockall_loot", "@LUA_MENU_UNLOCKALL_LOOT", + "@LUA_MENU_UNLOCKALL_LOOT_DESC", {{ + text = "@LUA_MENU_ENABLED", + value = true + }, { + text = "@LUA_MENU_DISABLED", + value = false + }}, nil, nil) - createdivider(menu, "@LUA_MENU_EDIT_STATS") + LUI.Options.CreateOptionButton(menu, "cg_unlockall_classes", "@LUA_MENU_UNLOCKALL_CLASSES", + "@LUA_MENU_UNLOCKALL_CLASSES_DESC", {{ + text = "@LUA_MENU_ENABLED", + value = true + }, { + text = "@LUA_MENU_DISABLED", + value = false + }}, nil, nil) - local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 - local experience = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "experience") or 0 - local rank = luiglobals.Lobby.GetRankForXP(experience, prestige) + createdivider(menu, "@LUA_MENU_EDIT_STATS") - local saved = true - local prestigevalue = prestige - local rankvalue = rank - local rankbutton = nil + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local experience = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "experience") or 0 + local rank = Lobby.GetRankForXP(experience, prestige) - prestigeeditbutton(menu, function(value) - prestigevalue = value - saved = false - end) + prestigeeditbutton(menu, function(value) + Engine.SetPlayerData(0, CoD.StatsGroup.Ranked, "prestige", tonumber(value)) + end) - rankbutton = rankeditbutton(menu, function(value) - rankvalue = value - saved = false - end) + rankeditbutton(menu, function(value) + local rank = tonumber(value) + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local experience = rank == 0 and 0 or Rank.GetRankMaxXP(tonumber(value) - 1, prestige) - local savebutton = menu:AddButton("@LUA_MENU_SAVE", function() - Engine.SetPlayerData(0, CoD.StatsGroup.Ranked, "prestige", tonumber(prestigevalue)) + Engine.SetPlayerData(0, CoD.StatsGroup.Ranked, "experience", experience) + end) - local rank = tonumber(rankvalue) - local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 - local experience = rank == 0 and 0 or luiglobals.Rank.GetRankMaxXP(tonumber(rankvalue) - 1, prestige) + LUI.Options.InitScrollingList(menu.list, nil) + LUI.Options.AddOptionTextInfo(menu) - Engine.SetPlayerData(0, CoD.StatsGroup.Ranked, "experience", experience) + menu:AddBackButton() - saved = true - end, nil, nil, nil, { - desc_text = Engine.Localize("LUA_MENU_SAVE_DESC") - }) - - LUI.Options.InitScrollingList(menu.list, nil) - LUI.Options.AddOptionTextInfo(menu) - - menu:AddBackButton(function() - if (saved) then - LUI.FlowManager.RequestLeaveMenu(menu) - return - end - - LUI.yesnopopup({ - title = Engine.Localize("@MENU_NOTICE"), - text = Engine.Localize("@LUA_MENU_UNSAVED_CHANGES"), - callback = function(result) - if (result) then - LUI.FlowManager.RequestLeaveMenu(menu) - end - end - }) - end) - - return menu + return menu end) function prestigeeditbutton(menu, callback) - local options = {} - local max = luiglobals.Lobby.GetMaxPrestigeLevel() - local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local options = {} + local max = Lobby.GetMaxPrestigeLevel() + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 - for i = 0, max do - game:addlocalizedstring("LUA_MENU_" .. i, i .. "") + for i = 0, max do + game:addlocalizedstring("LUA_MENU_" .. i, i .. "") - table.insert(options, { - text = "@" .. i, - value = i .. "" - }) - end + table.insert(options, { + text = "@" .. i, + value = i .. "" + }) + end - Engine.SetDvarFromString("ui_prestige_level", prestige .. "") + Engine.SetDvarFromString("ui_prestige_level", prestige .. "") - LUI.Options.CreateOptionButton(menu, "ui_prestige_level", "@LUA_MENU_PRESTIGE", "@LUA_MENU_PRESTIGE_DESC", options, - nil, nil, callback) + LUI.Options.CreateOptionButton(menu, "ui_prestige_level", "@LUA_MENU_PRESTIGE", "@LUA_MENU_PRESTIGE_DESC", options, + nil, nil, callback) end function rankeditbutton(menu, callback) - local options = {} - local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 - local experience = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "experience") or 0 + local options = {} + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local experience = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "experience") or 0 - local rank = luiglobals.Lobby.GetRankForXP(experience, prestige) - local max = luiglobals.Rank.GetMaxRank(prestige) - local maxprestige = luiglobals.Lobby.GetMaxPrestigeLevel() + local rank = Lobby.GetRankForXP(experience, prestige) + local max = Rank.GetMaxRank(prestige) + local maxprestige = Lobby.GetMaxPrestigeLevel() - for i = 0, max do - game:addlocalizedstring("LUA_MENU_" .. i, i .. "") + for i = 0, max do + game:addlocalizedstring("LUA_MENU_" .. i, i .. "") - table.insert(options, { - text = "@" .. (i + 1), - value = i .. "" - }) - end + table.insert(options, { + text = "@" .. (i + 1), + value = i .. "" + }) + end - Engine.SetDvarFromString("ui_rank_level_", rank .. "") + Engine.SetDvarFromString("ui_rank_level_", rank .. "") - return LUI.Options.CreateOptionButton(menu, "ui_rank_level_", "@LUA_MENU_RANK", "@LUA_MENU_RANK_DESC", options, nil, - nil, callback) + return LUI.Options.CreateOptionButton(menu, "ui_rank_level_", "@LUA_MENU_RANK", "@LUA_MENU_RANK_DESC", options, nil, + nil, callback) end -local isclasslocked = luiglobals.Cac.IsCustomClassLocked -luiglobals.Cac.IsCustomClassLocked = function(...) - if (Engine.GetDvarBool("cg_unlockall_classes")) then - return false - end +local isclasslocked = Cac.IsCustomClassLocked +Cac.IsCustomClassLocked = function(...) + if (Engine.GetDvarBool("cg_unlockall_classes")) then + return false + end - return isclasslocked(table.unpack({...})) + return isclasslocked(...) +end + +local getlockstate = Engine.GetItemLockState +Engine.GetItemLockState = function(...) + local status, state, msg = getlockstate(...) + if (state == Cac.ItemLockStatus.NotInInventory and Engine.GetDvarBool("cg_unlockall_loot")) then + return "Unlocked", 0, "" + end + return status, state, msg end diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index ac219e3b..795b1071 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -5,6 +5,7 @@ #include "game/game.hpp" #include "game/dvars.hpp" +#include "dvars.hpp" #include #include @@ -87,8 +88,6 @@ namespace fps cg_perf.previous_ms = cg_perf.current_ms; perf_calc_fps(&cg_perf, cg_perf.frame_ms); - - utils::hook::invoke(SELECT_VALUE(0x1405487A0, 0x1406575A0)); } void cg_draw_fps() @@ -98,14 +97,17 @@ namespace fps const auto fps = fps::get_fps(); const auto font = game::R_RegisterFont("fonts/fira_mono_regular.ttf", 25); - const auto fps_string = utils::string::va("%i", fps); + if (font) + { + const auto fps_string = utils::string::va("%i", fps); - const auto x = (game::ScrPlace_GetViewPlacement()->realViewportSize[0] - 15.0f) - game::R_TextWidth( - fps_string, 0x7FFFFFFF, font); - const auto y = font->pixelHeight + 10.f; + const auto x = (game::ScrPlace_GetViewPlacement()->realViewportSize[0] - 15.0f) - + game::R_TextWidth(fps_string, 0x7FFFFFFF, font); + const auto y = font->pixelHeight + 10.f; - const auto fps_color = fps >= 60 ? fps_color_good : (fps >= 30 ? fps_color_ok : fps_color_bad); - game::R_AddCmdDrawText(fps_string, 0x7FFFFFFF, font, x, y, 1.f, 1.f, 0.0f, fps_color, 6); + const auto fps_color = fps >= 60 ? fps_color_good : (fps >= 30 ? fps_color_ok : fps_color_bad); + game::R_AddCmdDrawText(fps_string, 0x7FFFFFFF, font, x, y, 1.f, 1.f, 0.0f, fps_color, 6); + } } } @@ -124,8 +126,7 @@ namespace fps } } - game::dvar_t* cg_draw_fps_register_stub(const char* name, const char** _enum, const int value, unsigned int /*flags*/, - const char* desc) + game::dvar_t* cg_draw_fps_register_stub() { cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, "Draw frames per second"); return cg_drawfps; @@ -151,22 +152,31 @@ namespace fps // fps setup cg_perf.perf_start = std::chrono::high_resolution_clock::now(); - utils::hook::call(SELECT_VALUE(0x14018D261, 0x14025B747), &perf_update); - // change cg_drawfps flags to saved - utils::hook::call(SELECT_VALUE(0x140139F48, 0x140222A46), &cg_draw_fps_register_stub); + utils::hook::jump(SELECT_VALUE(0, 0x343847_b), utils::hook::assemble([](utils::hook::assembler& a) + { + a.pushad64(); + a.call_aligned(perf_update); + a.popad64(); + + a.call(0x702250_b); + a.mov(edx, 3); + a.xor_(ecx, ecx); + a.jmp(0x343853_b); + }), true); + + // Don't register cg_drawfps + utils::hook::nop(0x31D74F_b, 0x1C); + utils::hook::nop(0x31D76F_b, 0x7); scheduler::loop(cg_draw_fps, scheduler::pipeline::renderer); - if (game::environment::is_sp()) - { - cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, "Draw frames per second"); - } + cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, "Draw frames per second"); if (game::environment::is_mp()) { // fix ping value - utils::hook::nop(0x14025AC41, 2); + utils::hook::nop(0x342C6C_b, 2); cg_drawping = dvars::register_int("cg_drawPing", 0, 0, 1, game::DVAR_FLAG_SAVED, "Choose to draw ping"); @@ -179,4 +189,4 @@ namespace fps }; } -//REGISTER_COMPONENT(fps::component) +REGISTER_COMPONENT(fps::component) diff --git a/src/client/component/stats.cpp b/src/client/component/stats.cpp index 2684feb1..d5ac9cc2 100644 --- a/src/client/component/stats.cpp +++ b/src/client/component/stats.cpp @@ -41,16 +41,6 @@ namespace stats return is_item_unlocked_hook2.invoke(a1, a2, a3, a4, a5, a6); } - int is_item_unlocked_stub3(int a1) - { - if (cg_unlock_all_items->current.enabled) - { - return 0; - } - - return is_item_unlocked_hook3.invoke(a1); - } - int is_item_unlocked() { return 0; @@ -75,14 +65,15 @@ namespace stats } else { + is_item_unlocked_hook.create(0x19E6E0_b, is_item_unlocked_stub); + is_item_unlocked_hook2.create(0x19E070_b, is_item_unlocked_stub2); + cg_unlock_all_items = dvars::register_bool("cg_unlockall_items", false, game::DVAR_FLAG_SAVED, "Whether items should be locked based on the player's stats or always unlocked."); dvars::register_bool("cg_unlockall_classes", false, game::DVAR_FLAG_SAVED, "Whether classes should be locked based on the player's stats or always unlocked."); - - is_item_unlocked_hook.create(0x19E6E0_b, is_item_unlocked_stub); - is_item_unlocked_hook2.create(0x19E070_b, is_item_unlocked_stub2); - is_item_unlocked_hook3.create(0x19D390_b, is_item_unlocked_stub3); + dvars::register_bool("cg_unlockall_loot", false, game::DVAR_FLAG_SAVED, + "Whether loot should be locked based on the player's stats or always unlocked."); } } }; diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index 75b89a0b..a096119b 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace ui_scripting { @@ -35,6 +36,8 @@ namespace ui_scripting utils::hook::detour hks_load_hook; utils::hook::detour db_find_xasset_header_hook; + const auto lui_common = utils::nt::load_resource(LUI_COMMON); + struct script { std::string name; @@ -185,7 +188,7 @@ namespace ui_scripting game_type["getping"] = [](const game&) { - //return *::game::mp::ping; + return *::game::mp::ping; }; game_type["issingleplayer"] = [](const game&) @@ -218,6 +221,8 @@ namespace ui_scripting lua["table"]["unpack"] = lua["unpack"]; lua["luiglobals"] = lua; + load_script("lui_common", lui_common); + load_scripts("h1-mod/ui_scripts/"); load_scripts("data/ui_scripts/"); } diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index b9016cbf..dd1d750a 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -252,7 +252,7 @@ namespace game WEAK symbol svs_numclients{0x0, 0x2DC338C}; WEAK symbol gameTime{0x0, 0x0}; - WEAK symbol ping{0x0, 0x0}; + WEAK symbol ping{0x0, 0x2ECCF40}; WEAK symbol sv_serverId_value{0x0, 0x0}; diff --git a/src/client/resources/ui_scripts/common.lua b/src/client/resources/ui_scripts/common.lua index e073be2e..a2579707 100644 --- a/src/client/resources/ui_scripts/common.lua +++ b/src/client/resources/ui_scripts/common.lua @@ -1,6 +1,30 @@ -menucallbacks = {} -originalmenus = {} -stack = {} +local menucallbacks = {} +local originalmenus = {} +local stack = {} + +function getchildren(element) + local children = {} + local first = element:getFirstChild() + + while (first) do + table.insert(children, first) + first = first:getNextSibling() + end + + return children +end + +function printchildtree(element, indent, last) + indent = indent or "" + + print(indent .. "+- " .. element.id .. " " .. (element:getText() or "")) + indent = indent .. (last and " " or "| ") + + local children = getchildren(element) + for i = 1, #children do + printchildtree(children[i], indent, i == #children) + end +end LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event) local oncancel = stack.oncancel @@ -14,9 +38,7 @@ LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event) end }) - local listchildren = popup:getChildById("LUIHorizontalList"):getchildren() - local children = listchildren[2]:getchildren() - popup.text = children[2] + popup.text = popup:getLastChild():getPreviousSibling():getPreviousSibling() stack = { ret = popup @@ -76,10 +98,10 @@ LUI.onmenuopen = function(name, callback) originalmenus[name] = LUI.MenuBuilder.m_types_build[name] LUI.MenuBuilder.m_types_build[name] = function(...) local args = {...} - local menu = originalmenus[name](table.unpack(args)) + local menu = originalmenus[name](unpack(args)) - for k, v in luiglobals.next, menucallbacks[name] do - v(menu, table.unpack(args)) + for k, v in next, menucallbacks[name] do + v(menu, unpack(args)) end return menu @@ -136,7 +158,7 @@ LUI.openpopupmenu = function(menu, args) end LUI.yesnopopup = function(data) - for k, v in luiglobals.next, data do + for k, v in next, data do stack[k] = v end LUI.FlowManager.RequestPopupMenu(nil, "generic_yes_no_popup_") @@ -144,21 +166,9 @@ LUI.yesnopopup = function(data) end LUI.confirmationpopup = function(data) - for k, v in luiglobals.next, data do + for k, v in next, data do stack[k] = v end LUI.FlowManager.RequestPopupMenu(nil, "generic_confirmation_popup_") return stack.ret -end - -function userdata_:getchildren() - local children = {} - local first = self:getFirstChild() - - while (first) do - table.insert(children, first) - first = first:getNextSibling() - end - - return children -end +end \ No newline at end of file