param: network

This param shows the throughput in kb/s for each interface or for
user specified interfaces
pull/1290/head
flightlessmango 1 month ago
parent 66d5ce43d2
commit a4862f5461

@ -428,6 +428,7 @@ Parameters that are enabled by default have to be explicitly disabled. These (cu
| `wine` | Show current Wine or Proton version in use |
| `winesync` | Show wine sync method in use |
| `present_mode` | Shows current vulkan [present mode](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPresentModeKHR.html) or vsync status in opengl |
| `network` | Show network interfaces tx and rx kb/s. You can specify interface with `network=eth0` |
Example: `MANGOHUD_CONFIG=cpu_temp,gpu_temp,position=top-right,height=500,font_size=32`
Because comma is also used as option delimiter and needs to be escaped for values with a backslash, you can use `+` like `MANGOHUD_CONFIG=fps_limit=60+30+0` instead.

@ -212,6 +212,14 @@ frame_timing
## example: Track:;{title};By:;{artist};From:;{album}
# media_player_format=title,artist,album
### Network interface throughput
# network
## Network can take arguments but it's not required.
## without arguments it shows all interfaces
## arguments set which interfaces will be displayed
# network=eth0,wlo1
### Change the hud font size
# font_size=24
# font_scale=1.0

@ -98,6 +98,7 @@ void HudElements::convert_colors(const struct overlay_params& params)
HUDElements.colors.fps_value_med = convert(params.fps_color[1]);
HUDElements.colors.fps_value_high = convert(params.fps_color[2]);
HUDElements.colors.text_outline = convert(params.text_outline_color);
HUDElements.colors.network = convert(params.network_color);
ImGuiStyle& style = ImGui::GetStyle();
style.Colors[ImGuiCol_PlotLines] = convert(params.frametime_color);
@ -1442,6 +1443,39 @@ void HudElements::present_mode() {
ImGui::PopFont();
}
void HudElements::network() {
if (HUDElements.net && HUDElements.net->should_reset)
HUDElements.net.reset(new Net);
if (!HUDElements.net)
HUDElements.net = std::make_unique<Net>();
ImguiNextColumnFirstItem();
HUDElements.TextColored(HUDElements.colors.network, "%s", "NET");
ImGui::TableNextColumn();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", "TX");
ImGui::TableNextColumn();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", "RX");
for (auto& iface : HUDElements.net->interfaces){
ImGui::TableNextRow();
ImGui::TableNextColumn();
HUDElements.TextColored(HUDElements.colors.network, "%s", iface.name.c_str());
ImGui::TableNextColumn();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.0f", iface.txBps / 1000.f);
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
HUDElements.TextColored(HUDElements.colors.text, "KB/s");
ImGui::PopFont();
ImGui::TableNextColumn();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.0f", iface.rxBps / 1000.f);
ImGui::SameLine(0,1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
HUDElements.TextColored(HUDElements.colors.text, "KB/s");
ImGui::PopFont();
}
}
void HudElements::sort_elements(const std::pair<std::string, std::string>& option) {
const auto& param = option.first;
const auto& value = option.second;
@ -1488,7 +1522,8 @@ void HudElements::sort_elements(const std::pair<std::string, std::string>& optio
{"hdr", {hdr}},
{"refresh_rate", {refresh_rate}},
{"winesync", {winesync}},
{"present_mode", {present_mode}}
{"present_mode", {present_mode}},
{"network", {network}}
};
@ -1614,6 +1649,8 @@ void HudElements::legacy_elements(){
ordered_functions.push_back({winesync, "winesync", value});
if (params->enabled[OVERLAY_PARAM_ENABLED_present_mode])
ordered_functions.push_back({present_mode, "present_mode", value});
if (!params->network.empty())
ordered_functions.push_back({network, "network", value});
}

@ -8,6 +8,8 @@
#include "winesync.h"
#include "vulkan/vulkan.h"
#include <array>
#include "net.h"
#include "overlay_params.h"
struct Function {
std::function<void()> run; // Using std::function instead of a raw function pointer for more flexibility
@ -50,6 +52,7 @@ class HudElements{
int hdr_status = 0;
int refresh = 0;
std::unique_ptr<WineSync> winesync_ptr = nullptr;
std::unique_ptr<Net> net = nullptr;
void sort_elements(const std::pair<std::string, std::string>& option);
void legacy_elements();
@ -95,6 +98,7 @@ class HudElements{
static void refresh_rate();
static void winesync();
static void present_mode();
static void network();
void convert_colors(const struct overlay_params& params);
void convert_colors(bool do_conv, const struct overlay_params& params);
@ -122,7 +126,8 @@ class HudElements{
fps_value_low,
fps_value_med,
fps_value_high,
text_outline;
text_outline,
network;
} colors {};
void TextColored(ImVec4 col, const char *fmt, ...);

@ -91,7 +91,8 @@ if is_unixy
'device.cpp',
'amdgpu.cpp',
'intel.cpp',
'msm.cpp'
'msm.cpp',
'net.cpp'
)
opengl_files = files(

@ -0,0 +1,58 @@
#include "net.h"
#include "hud_elements.h"
Net::Net() {
should_reset = false;
fs::path net_dir(NETDIR);
if (fs::exists(net_dir) && fs::is_directory(net_dir)) {
for (const auto& entry : fs::directory_iterator(net_dir)) {
if (fs::is_directory(entry.status())) {
auto val = entry.path().filename().string();
if (val == "lo")
continue;
if (!HUDElements.params->network.empty() && HUDElements.params->network.front() == "1") {
interfaces.push_back({entry.path().filename().string(), 0, 0});
} else if (!HUDElements.params->network.empty()){
auto it = std::find(HUDElements.params->network.begin(), HUDElements.params->network.end(), val);
if (it != HUDElements.params->network.end())
interfaces.push_back({entry.path().filename().string(), 0, 0});
}
}
}
}
if (interfaces.empty())
SPDLOG_ERROR("Network: couldn't find any interfaces");
}
void Net::update() {
if (!interfaces.empty()) {
for (auto& iface : interfaces) {
// path to tx_bytes and rx_bytes
std::string txfile = (NETDIR + iface.name + TXFILE);
std::string rxfile = (NETDIR + iface.name + RXFILE);
// amount of bytes at previous update
uint64_t prevTx = iface.txBytes;
uint64_t prevRx = iface.rxBytes;
// current amount of bytes
iface.txBytes = std::stoll(read_line(txfile));
iface.rxBytes = std::stoll(read_line(rxfile));
auto now = std::chrono::steady_clock::now();
// calculate the bytes per second since last update
iface.txBps = calculateThroughput(iface.txBytes, prevTx, iface.previousTime, now);
iface.rxBps = calculateThroughput(iface.rxBytes, prevRx, iface.previousTime, now);
iface.previousTime = now;
}
}
}
uint64_t Net::calculateThroughput(long long currentBytes, long long previousBytes,
std::chrono::steady_clock::time_point previousTime,
std::chrono::steady_clock::time_point currentTime) {
std::chrono::duration<double> elapsed = (currentTime - previousTime);
return static_cast<long long>((currentBytes - previousBytes) / elapsed.count());
}

@ -0,0 +1,46 @@
#pragma once
#include <vector>
#include <string>
#include <stdint.h>
#include "filesystem.h"
#include "file_utils.h"
#include <spdlog/spdlog.h>
#include <iostream>
namespace fs = ghc::filesystem;
#ifndef NETDIR
#define NETDIR "/sys/class/net/"
#endif
#ifndef TXFILE
#define TXFILE "/statistics/tx_bytes"
#endif
#ifndef RXFILE
#define RXFILE "/statistics/rx_bytes"
#endif
class Net {
public:
bool should_reset = false;
struct interface {
std::string name;
uint64_t txBytes;
uint64_t rxBytes;
uint64_t txBps;
uint64_t rxBps;
std::chrono::steady_clock::time_point previousTime;
};
Net();
void update();
std::vector<interface> interfaces = {};
private:
uint64_t calculateThroughput(long long currentBytes, long long previousBytes,
std::chrono::steady_clock::time_point previousTime,
std::chrono::steady_clock::time_point currentTime);
};
extern std::unique_ptr<Net> net;

@ -26,6 +26,7 @@
#include "fps_metrics.h"
#include "intel.h"
#include "msm.h"
#include "net.h"
#ifdef __linux__
#include <libgen.h>
@ -268,6 +269,7 @@ void update_hud_info_with_frametime(struct swapchain_stats& sw_stats, const stru
hw_update_thread->update(&params, vendorID);
if (fpsmetrics) fpsmetrics->update_thread();
if (HUDElements.net) HUDElements.net->update();
sw_stats.fps = 1000000000.0 * sw_stats.n_frames_since_update / elapsed;

@ -483,6 +483,7 @@ parse_fps_metrics(const char *str){
#define parse_text_color(s) parse_color(s)
#define parse_media_player_color(s) parse_color(s)
#define parse_wine_color(s) parse_color(s)
#define parse_network_color(s) parse_color(s)
#define parse_gpu_load_color(s) parse_load_color(s)
#define parse_cpu_load_color(s) parse_load_color(s)
#define parse_gpu_load_value(s) parse_load_value(s)
@ -498,6 +499,7 @@ parse_fps_metrics(const char *str){
#define parse_text_outline_color(s) parse_color(s)
#define parse_text_outline_thickness(s) parse_float(s)
#define parse_device_battery(s) parse_str_tokenize(s)
#define parse_network(s) parse_str_tokenize(s)
static bool
parse_help(const char *str)
@ -752,6 +754,7 @@ static void set_param_defaults(struct overlay_params *params){
params->background_color = 0x020202;
params->text_color = 0xffffff;
params->media_player_color = 0xffffff;
params->network_color = 0xd66077;
params->media_player_name = "";
params->font_scale = 1.0f;
params->wine_color = 0xeb5b5b;
@ -869,7 +872,7 @@ parse_overlay_config(struct overlay_params *params,
params->font_scale_media_player = 0.55f;
// Convert from 0xRRGGBB to ImGui's format
std::array<unsigned *, 22> colors = {
std::array<unsigned *, 23> colors = {
&params->cpu_color,
&params->gpu_color,
&params->vram_color,
@ -892,6 +895,7 @@ parse_overlay_config(struct overlay_params *params,
&params->fps_color[1],
&params->fps_color[2],
&params->text_outline_color,
&params->network_color,
};
for (auto color : colors){
@ -995,6 +999,8 @@ parse_overlay_config(struct overlay_params *params,
mangoapp_cv.notify_one();
g_fsrSharpness = params->fsr_steam_sharpness;
#endif
if (HUDElements.net)
HUDElements.net->should_reset = true;
}
bool parse_preset_config(int preset, struct overlay_params *params){

@ -161,6 +161,7 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_CUSTOM(text_color) \
OVERLAY_PARAM_CUSTOM(wine_color) \
OVERLAY_PARAM_CUSTOM(battery_color) \
OVERLAY_PARAM_CUSTOM(network_color) \
OVERLAY_PARAM_CUSTOM(alpha) \
OVERLAY_PARAM_CUSTOM(log_duration) \
OVERLAY_PARAM_CUSTOM(pci_dev) \
@ -194,6 +195,7 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_CUSTOM(fps_text) \
OVERLAY_PARAM_CUSTOM(device_battery) \
OVERLAY_PARAM_CUSTOM(fps_metrics) \
OVERLAY_PARAM_CUSTOM(network) \
enum overlay_param_position {
LAYER_POSITION_TOP_LEFT,
@ -266,7 +268,9 @@ struct overlay_params {
enum gl_size_query gl_size_query {GL_SIZE_DRAWABLE};
bool gl_dont_flip {false};
int64_t log_duration, log_interval;
unsigned cpu_color, gpu_color, vram_color, ram_color, engine_color, io_color, frametime_color, background_color, text_color, wine_color, battery_color;
unsigned cpu_color, gpu_color, vram_color, ram_color,
engine_color, io_color, frametime_color, background_color,
text_color, wine_color, battery_color, network_color;
std::vector<unsigned> gpu_load_color;
std::vector<unsigned> cpu_load_color;
std::vector<unsigned> gpu_load_value;
@ -316,6 +320,7 @@ struct overlay_params {
float text_outline_thickness;
std::vector<std::string> device_battery;
std::vector<std::string> fps_metrics;
std::vector<std::string> network;
};
const extern char *overlay_param_names[];

Loading…
Cancel
Save