Better ping & fps counter

This commit is contained in:
Federico Cecchetto 2022-03-05 18:29:33 +01:00
parent 815786e3bf
commit 26640a977f
7 changed files with 378 additions and 7 deletions

View File

@ -0,0 +1,6 @@
if (game:issingleplayer()) then
return
end
require("settings")
require("hud")

View File

@ -0,0 +1,163 @@
local mphud = luiglobals.require("LUI.mp_hud.MPHud")
local barheight = 18
local textheight = 13
local textoffsety = barheight / 2 - textheight / 2
function createinfobar()
local infobar = LUI.UIElement.new({
left = 180,
top = 5,
height = barheight,
width = 70,
leftAnchor = true,
topAnchor = true
})
infobar:registerAnimationState("hud_on", {
alpha = 1
})
infobar:registerAnimationState("hud_off", {
alpha = 0
})
return infobar
end
function populateinfobar(infobar)
elementoffset = 0
if (Engine.GetDvarBool("cg_infobar_fps")) then
infobar:addElement(infoelement({
label = "FPS: ",
getvalue = function()
return game:getfps()
end,
width = 70,
interval = 100
}))
end
if (Engine.GetDvarBool("cg_infobar_ping")) then
infobar:addElement(infoelement({
label = "Latency: ",
getvalue = function()
return game:getping() .. " ms"
end,
width = 115,
interval = 100
}))
end
end
function infoelement(data)
local container = LUI.UIElement.new({
bottomAnchor = true,
leftAnchor = true,
topAnchor = true,
width = data.width,
left = elementoffset
})
elementoffset = elementoffset + data.width + 10
local background = LUI.UIImage.new({
bottomAnchor = true,
leftAnchor = true,
topAnchor = true,
rightAnchor = true,
color = {
r = 0.3,
g = 0.3,
b = 0.3,
},
material = luiglobals.RegisterMaterial("distort_hud_bkgnd_ui_blur")
})
local labelfont = luiglobals.RegisterFont("fonts/bodyFontBold", textheight)
local label = LUI.UIText.new({
left = 5,
top = textoffsety + 1,
font = labelfont,
height = textheight,
leftAnchor = true,
topAnchor = true,
color = {
r = 0.8,
g = 0.8,
b = 0.8,
}
})
label:setText(data.label)
local _, _, left = luiglobals.GetTextDimensions(data.label, labelfont, textheight)
local value = LUI.UIText.new({
left = left + 5,
top = textoffsety,
font = luiglobals.RegisterFont("fonts/bodyFont", textheight),
height = textheight + 1,
leftAnchor = true,
topAnchor = true,
color = {
r = 0.6,
g = 0.6,
b = 0.6,
}
})
value:addElement(LUI.UITimer.new(data.interval, "update"))
value:setText(data.getvalue())
value:addEventHandler("update", function()
value:setText(data.getvalue())
end)
container:addElement(background)
container:addElement(label)
container:addElement(value)
return container
end
local updatehudvisibility = mphud.updateHudVisibility
mphud.updateHudVisibility = function(a1, a2)
updatehudvisibility(a1, a2)
local root = Engine.GetLuiRoot()
local menus = root:AnyActiveMenusInStack()
local infobar = root.infobar
if (not infobar) then
return
end
if (menus) then
infobar:animateToState("hud_off")
else
infobar:animateToState("hud_on")
end
end
local mphud = LUI.MenuBuilder.m_types_build["mp_hud"]
LUI.MenuBuilder.m_types_build["mp_hud"] = function()
local hud = mphud()
if (Engine.InFrontend()) then
return hud
end
local infobar = createinfobar()
local root = Engine.GetLuiRoot()
root.infobar = infobar
populateinfobar(infobar)
root:registerEventHandler("update_hud_infobar_settings", function()
infobar:removeAllChildren()
populateinfobar(infobar)
end)
hud.static:addElement(infobar)
return hud
end

View File

@ -0,0 +1,156 @@
local pcoptions = luiglobals.require("LUI.PCOptions")
game:addlocalizedstring("LUA_MENU_FPS", "FPS Counter")
game:addlocalizedstring("LUA_MENU_FPS_DESC", "Show FPS Counter")
game:addlocalizedstring("LUA_MENU_LATENCY", "Server Latency")
game:addlocalizedstring("LUA_MENU_LATENCY_DESC", "Show server latency")
pcoptions.VideoOptionsFeeder = function()
local items = {
pcoptions.OptionFactory(
"ui_r_displayMode",
"@LUA_MENU_DISPLAY_MODE",
nil,
{
{
text = "@LUA_MENU_MODE_FULLSCREEN",
value = "fullscreen"
},
{
text = "@LUA_MENU_MODE_WINDOWED_NO_BORDER",
value = "windowed_no_border"
},
{
text = "@LUA_MENU_MODE_WINDOWED",
value = "windowed"
}
},
nil,
true
),
pcoptions.SliderOptionFactory(
"profileMenuOption_blacklevel",
"@MENU_BRIGHTNESS",
"@MENU_BRIGHTNESS_DESC1",
luiglobals.SliderBounds.PCBrightness.Min,
luiglobals.SliderBounds.PCBrightness.Max,
luiglobals.SliderBounds.PCBrightness.Step,
function(element)
element:processEvent({
name = "brightness_over",
immediate = true
})
end,
function(element)
element:processEvent({
name = "brightness_up",
immediate = true
})
end,
true,
nil,
"brightness_updated"
),
pcoptions.OptionFactoryProfileData(
"renderColorBlind",
"profile_toggleRenderColorBlind",
"@LUA_MENU_COLORBLIND_FILTER",
"@LUA_MENU_COLOR_BLIND_DESC",
{
{
text = "@LUA_MENU_ENABLED",
value = true
},
{
text = "@LUA_MENU_DISABLED",
value = false
}
},
nil,
false
)
}
if Engine.IsMultiplayer() and not Engine.IsZombiesMode() then
table.insert(items, pcoptions.OptionFactory(
"cg_paintballFx",
"@LUA_MENU_PAINTBALL",
"@LUA_MENU_PAINTBALL_DESC",
{
{
text = "@LUA_MENU_ENABLED",
value = true
},
{
text = "@LUA_MENU_DISABLED",
value = false
}
},
nil,
false,
false
))
end
table.insert(items, pcoptions.OptionFactory(
"cg_infobar_ping",
"@LUA_MENU_LATENCY",
"@LUA_MENU_LATENCY_DESC",
{
{
text = "@LUA_MENU_ENABLED",
value = true
},
{
text = "@LUA_MENU_DISABLED",
value = false
}
},
function()
Engine.GetLuiRoot():processEvent({
name = "update_hud_infobar_settings"
})
end,
false,
false
))
table.insert(items, pcoptions.OptionFactory(
"cg_infobar_fps",
"@LUA_MENU_FPS",
"@LUA_MENU_FPS_DESC",
{
{
text = "@LUA_MENU_ENABLED",
value = true
},
{
text = "@LUA_MENU_DISABLED",
value = false
}
},
function()
Engine.GetLuiRoot():processEvent({
name = "update_hud_infobar_settings"
})
end,
false,
false
))
table.insert(items, {
type = "UIGenericButton",
id = "option_advanced_video",
properties = {
style = luiglobals.GenericButtonSettings.Styles.GlassButton,
button_text = Engine.Localize("@LUA_MENU_ADVANCED_VIDEO"),
desc_text = "",
button_action_func = pcoptions.ButtonMenuAction,
text_align_without_content = LUI.Alignment.Left,
menu = "advanced_video"
}
})
return items
end

View File

@ -1,6 +1,9 @@
#include <std_include.hpp> #include <std_include.hpp>
#include "loader/component_loader.hpp" #include "loader/component_loader.hpp"
#include "scheduler.hpp" #include "scheduler.hpp"
#include "fps.hpp"
#include "localized_strings.hpp"
#include "game/game.hpp" #include "game/game.hpp"
#include "game/dvars.hpp" #include "game/dvars.hpp"
@ -91,11 +94,10 @@ namespace fps
void cg_draw_fps() void cg_draw_fps()
{ {
const auto* draw_fps = game::Dvar_FindVar("cg_drawFPS"); const auto* draw_fps = game::Dvar_FindVar("cg_drawFPS");
if (draw_fps && draw_fps->current.integer > 0 /*&& game::CL_IsCgameInitialized()*/)
if (draw_fps && draw_fps->current.integer > 0)
{ {
const auto fps = static_cast<std::int32_t>(static_cast<float>(1000.0f / static_cast<float>(cg_perf. const auto fps = fps::get_fps();
average))
+ 9.313225746154785e-10);
auto* font = game::R_RegisterFont("fonts/consolefont"); auto* font = game::R_RegisterFont("fonts/consolefont");
if (!font) return; if (!font) return;
@ -119,12 +121,10 @@ namespace fps
const auto* draw_ping = game::Dvar_FindVar("cg_drawPing"); const auto* draw_ping = game::Dvar_FindVar("cg_drawPing");
if (draw_ping && draw_ping->current.integer > 0 && game::CL_IsCgameInitialized()) if (draw_ping && draw_ping->current.integer > 0 && game::CL_IsCgameInitialized())
{ {
const auto ping = *reinterpret_cast<int*>(0x1417E6A84);
auto* font = game::R_RegisterFont("fonts/consolefont"); auto* font = game::R_RegisterFont("fonts/consolefont");
if (!font) return; if (!font) return;
auto* const ping_string = utils::string::va("Ping: %i", ping); auto* const ping_string = utils::string::va("Ping: %i", *game::mp::ping);
const auto scale = 1.0f; const auto scale = 1.0f;
@ -144,6 +144,13 @@ namespace fps
} }
} }
int get_fps()
{
return static_cast<std::int32_t>(static_cast<float>(1000.0f / static_cast<float>(cg_perf.
average))
+ 9.313225746154785e-10);
}
class component final : public component_interface class component final : public component_interface
{ {
public: public:
@ -170,6 +177,9 @@ namespace fps
game::Dvar_RegisterInt("cg_drawPing", 0, 0, 1, game::DVAR_FLAG_SAVED, "Choose to draw ping"); game::Dvar_RegisterInt("cg_drawPing", 0, 0, 1, game::DVAR_FLAG_SAVED, "Choose to draw ping");
scheduler::loop(cg_draw_ping, scheduler::pipeline::renderer); scheduler::loop(cg_draw_ping, scheduler::pipeline::renderer);
} }
game::Dvar_RegisterBool("cg_infobar_ping", false, game::DVAR_FLAG_SAVED, "Show server latency");
game::Dvar_RegisterBool("cg_infobar_fps", false, game::DVAR_FLAG_SAVED, "Show FPS counter");
} }
}; };
} }

View File

@ -0,0 +1,6 @@
#pragma once
namespace fps
{
int get_fps();
}

View File

@ -276,6 +276,8 @@ namespace game
WEAK symbol<int> gameTime{0, 0x144959C2C}; WEAK symbol<int> gameTime{0, 0x144959C2C};
WEAK symbol<int> serverTime{0, 0x1496C4B00}; WEAK symbol<int> serverTime{0, 0x1496C4B00};
WEAK symbol<int> ping{0, 0x1417E6A84};
WEAK symbol<int> sv_serverId_value{0, 0x1488A9A60}; WEAK symbol<int> sv_serverId_value{0, 0x1488A9A60};
WEAK symbol<char> virtualLobby_loaded{0, 0x1417E161D}; WEAK symbol<char> virtualLobby_loaded{0, 0x1417E161D};

View File

@ -7,6 +7,8 @@
#include "../../../component/ui_scripting.hpp" #include "../../../component/ui_scripting.hpp"
#include "../../../component/command.hpp" #include "../../../component/command.hpp"
#include "../../../component/fps.hpp"
#include "../../../component/localized_strings.hpp"
#include "component/game_console.hpp" #include "component/game_console.hpp"
#include "component/scheduler.hpp" #include "component/scheduler.hpp"
@ -39,6 +41,32 @@ namespace ui_scripting::lua
return scheduler.add(callback, milliseconds, false); return scheduler.add(callback, milliseconds, false);
}; };
game_type["getfps"] = [](const game&)
{
return fps::get_fps();
};
game_type["getping"] = [](const game&)
{
return *::game::mp::ping;
};
game_type["issingleplayer"] = [](const game&)
{
return ::game::environment::is_sp();
};
game_type["ismultiplayer"] = [](const game&)
{
return ::game::environment::is_mp();
};
game_type["addlocalizedstring"] = [](const game&, const std::string& string,
const std::string& value)
{
localized_strings::override(string, value);
};
auto userdata_type = state.new_usertype<userdata>("userdata_"); auto userdata_type = state.new_usertype<userdata>("userdata_");
userdata_type["new"] = sol::property( userdata_type["new"] = sol::property(