Skip to content

Commit 6e34636

Browse files
committed
Notify: show server count at startup, tell user if lobby can be reached
1 parent 77f29ed commit 6e34636

File tree

3 files changed

+73
-24
lines changed

3 files changed

+73
-24
lines changed

src/game_addrs.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ namespace Game
101101

102102
inline fn_stdcall_1arg_int Sumo_CheckRacerUnlocked = nullptr;
103103

104+
inline const char* SumoNet_OnlineUserName = nullptr;
105+
104106
// 2d sprite drawing
105107
inline fn_1arg sprSetFontPriority = nullptr;
106108
inline fn_1arg sprSetPrintFont = nullptr;
@@ -225,6 +227,8 @@ namespace Game
225227

226228
Sumo_CheckRacerUnlocked = Module::fn_ptr<fn_stdcall_1arg_int>(0xE8410);
227229

230+
SumoNet_OnlineUserName = Module::exe_ptr<const char>(0x430C20);
231+
228232
sprSetFontPriority = Module::fn_ptr<fn_1arg>(0x2CCB0);
229233
sprSetPrintFont = Module::fn_ptr<fn_1arg>(0x2CA60);
230234
sprSetFontColor = Module::fn_ptr<fn_1arg>(0x2CCA0);

src/overlay/notifications.hpp

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ inline std::chrono::seconds displayDuration = std::chrono::seconds(7);
77

88
inline ImVec2 notificationSize = { 600, 100 };
99
inline float notificationSpacing = 10.0f;
10+
inline float notificationTextScale = 1.5f;
1011

1112
class Notifications
1213
{
@@ -15,16 +16,17 @@ class Notifications
1516
{
1617
std::string message;
1718
std::chrono::time_point<std::chrono::steady_clock> timestamp;
19+
int minDisplaySeconds;
1820
};
1921

2022
std::deque<Notification> notifications;
2123
std::mutex notificationsMutex;
2224

2325
public:
24-
void add(const std::string& message)
26+
void add(const std::string& message, int minDisplaySeconds = 0)
2527
{
2628
std::lock_guard<std::mutex> lock(notificationsMutex);
27-
notifications.push_back({ message, std::chrono::steady_clock::now() });
29+
notifications.push_back({ message, std::chrono::steady_clock::now(), minDisplaySeconds });
2830

2931
if (notifications.size() > maxNotifications)
3032
notifications.pop_front();
@@ -36,8 +38,20 @@ class Notifications
3638
auto now = std::chrono::steady_clock::now();
3739
{
3840
std::lock_guard<std::mutex> lock(notificationsMutex);
39-
while (!notifications.empty() && now - notifications.front().timestamp > displayDuration)
41+
42+
while (!notifications.empty())
43+
{
44+
auto& front = notifications.front();
45+
46+
auto duration = displayDuration;
47+
if (front.minDisplaySeconds > 0)
48+
duration = std::chrono::seconds(front.minDisplaySeconds);
49+
50+
if (now - front.timestamp <= duration) // notif time hasn't elapsed yet?
51+
break;
52+
4053
notifications.pop_front();
54+
}
4155
}
4256

4357
ImVec2 screenSize = ImGui::GetIO().DisplaySize;
@@ -50,39 +64,43 @@ class Notifications
5064
borderWidth = 0;
5165

5266
float startX = screenSize.x - notificationSize.x - borderWidth - 10.f; // 10px padding from the right
53-
float startY = (screenSize.y / 4.0f) - (notifications.size() * (notificationSize.y + notificationSpacing) / 2.0f);
67+
float curY = (screenSize.y / 4.0f) - (notifications.size() * (notificationSize.y + notificationSpacing) / 2.0f);
5468

5569
std::lock_guard<std::mutex> lock(notificationsMutex);
5670

5771
for (size_t i = 0; i < notifications.size(); ++i)
5872
{
73+
auto windowSize = notificationSize;
5974
const auto& notification = notifications[i];
6075

61-
float posY = startY + i * (notificationSize.y + notificationSpacing);
62-
ImGui::SetNextWindowPos(ImVec2(startX, posY));
63-
ImGui::SetNextWindowSize(notificationSize);
76+
ImGui::SetNextWindowPos(ImVec2(startX, curY));
77+
78+
curY += windowSize.y + notificationSpacing;
6479

6580
std::string windowName = "Notification " + std::to_string(i);
6681
ImGui::Begin(windowName.c_str(), nullptr, ImGuiWindowFlags_NoDecoration |
6782
ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs |
6883
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing);
6984

70-
ImGui::SetWindowFontScale(1.5f);
85+
ImGui::SetWindowFontScale(notificationTextScale);
86+
ImVec2 textSize = ImGui::CalcTextSize(notification.message.c_str(), nullptr, true, windowSize.x - 20.0f); // Account for padding
87+
88+
// Adjust window height if text is larger than current window height
89+
if (textSize.y + 40.0f > windowSize.y)
90+
windowSize.y = textSize.y + 40.0f;
7191

72-
// Calculate offsets to center text
73-
ImVec2 textSize = ImGui::CalcTextSize(notification.message.c_str());
74-
float offsetX = (notificationSize.x - textSize.x) / 2.0f;
75-
float offsetY = (notificationSize.y - textSize.y) / 2.0f;
92+
ImGui::SetWindowSize(windowSize);
7693

77-
// Padding
78-
float paddingX = 10.0f;
79-
float paddingY = 5.0f;
94+
// Center text with padding
95+
float paddingX = 10.0f, paddingY = 5.0f;
96+
float offsetX = (windowSize.x - textSize.x) / 2.0f;
97+
float offsetY = (windowSize.y - textSize.y) / 2.0f;
8098
offsetX = max(offsetX, paddingX);
8199
offsetY = max(offsetY, paddingY);
82100

83-
// Position cursor for centered text
84101
ImGui::SetCursorPos(ImVec2(offsetX, offsetY));
85102
ImGui::TextWrapped("%s", notification.message.c_str());
103+
86104
ImGui::End();
87105
}
88106
}

src/overlay/server_notifications.cpp

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class ServerUpdater
3737
Json::Value previousServers;
3838
std::mutex dataMutex;
3939

40+
int numServerUpdates = 0;
41+
4042
void monitorServers()
4143
{
4244
while (running)
@@ -57,6 +59,8 @@ class ServerUpdater
5759
// Save the current state as the previous state for the next check
5860
std::lock_guard<std::mutex> lock(dataMutex);
5961
previousServers = currentServers;
62+
63+
numServerUpdates++;
6064
}
6165
}
6266
catch (const std::exception& e)
@@ -149,25 +153,48 @@ class ServerUpdater
149153
}
150154
}
151155

156+
int numValid = 0;
157+
152158
// Compare current servers to previous identifiers
153159
for (const auto& server : currentServers)
154160
{
155161
if (server.isMember("HostName") && server.isMember("Platform") && server.isMember("Reachable"))
156162
{
157-
if (server["Reachable"].asBool())
163+
bool reachable = server["Reachable"].asBool();
164+
if (reachable)
165+
{
166+
numValid++;
167+
}
168+
169+
if (numServerUpdates > 0) // have we fetched server info before?
158170
{
159-
std::string identifier = server["HostName"].asString() + "_" + server["Platform"].asString();
171+
auto hostName = server["HostName"].asString();
160172

161-
if (previousIdentifiers.find(identifier) == previousIdentifiers.end())
162-
newServer(server);
173+
if (!hostName.empty())
174+
{
175+
std::string identifier = hostName + "_" + server["Platform"].asString();
176+
bool ourLobby = !strncmp(hostName.c_str(), Game::SumoNet_OnlineUserName, 16);
177+
if (!ourLobby)
178+
{
179+
if (reachable && previousIdentifiers.find(identifier) == previousIdentifiers.end())
180+
Notifications::instance.add(hostName + " started hosting a lobby!");
181+
}
182+
else
183+
{
184+
Notifications::instance.add(reachable ?
185+
"Your lobby is active & accessible!" :
186+
"Your lobby cannot be reached by the master server!\nYou may need to setup port-forwarding for UDP ports 41455/41456/41457.", reachable ? 0 : 20);
187+
}
188+
}
163189
}
164190
}
165191
}
166-
}
167192

168-
void newServer(const Json::Value& server)
169-
{
170-
Notifications::instance.add(server["HostName"].asString() + " started hosting a lobby!");
193+
if (numServerUpdates == 0 && numValid > 0)
194+
{
195+
// First update since game launch and we have some servers, write a notify about it
196+
Notifications::instance.add("There are " + std::to_string(numValid) + " online lobbies active!");
197+
}
171198
}
172199

173200
public:

0 commit comments

Comments
 (0)