topmenu.lua

main 284 lines · 7.4 KB Raw
Alex Alex Commit Client Upload Part 2 19/10/2026 00:06
1-- private variables
2local topMenu
3local fpsUpdateEvent = nil
4local statusUpdateEvent = nil
5
6-- private functions
7local function addButton(id, description, icon, callback, panel, toggle, front, index)
8 local class
9 if toggle then
10 class = 'TopToggleButton'
11 else
12 class = 'TopButton'
13 end
14
15 if topMenu.reverseButtons then
16 front = not front
17 end
18
19 local button = panel:getChildById(id)
20 if not button then
21 button = g_ui.createWidget(class)
22 if front then
23 panel:insertChild(1, button)
24 else
25 panel:addChild(button)
26 end
27 end
28 button:setId(id)
29 button:setTooltip(description)
30 button:setIcon(resolvepath(icon, 3))
31 button.onMouseRelease = function(widget, mousePos, mouseButton)
32 if widget:containsPoint(mousePos) and mouseButton ~= MouseMidButton and mouseButton ~= MouseTouch then
33 callback()
34 return true
35 end
36 end
37 button.onTouchRelease = button.onMouseRelease
38 if not button.index and type(index) == 'number' then
39 button.index = index
40 end
41 return button
42end
43
44-- public functions
45function init()
46 connect(g_game, { onGameStart = online,
47 onGameEnd = offline,
48 onPingBack = updatePing })
49
50 topMenu = g_ui.createWidget('TopMenu', g_ui.getRootWidget())
51 g_keyboard.bindKeyDown('Ctrl+Shift+T', toggle)
52
53 if g_game.isOnline() then
54 scheduleEvent(online, 10)
55 end
56
57 updateFps()
58 updateStatus()
59end
60
61function terminate()
62 disconnect(g_game, { onGameStart = online,
63 onGameEnd = offline,
64 onPingBack = updatePing })
65 removeEvent(fpsUpdateEvent)
66 removeEvent(statusUpdateEvent)
67
68 g_keyboard.unbindKeyDown('Ctrl+Shift+T')
69 topMenu:destroy()
70end
71
72function online()
73 if topMenu.hideIngame then
74 hide()
75 else
76 modules.game_interface.getRootPanel():addAnchor(AnchorTop, 'topMenu', AnchorBottom)
77 end
78 if topMenu.onlineLabel then
79 topMenu.onlineLabel:hide()
80 end
81
82 showGameButtons()
83
84 if topMenu.pingLabel then
85 addEvent(function()
86 if modules.client_options.getOption('showPing') and (g_game.getFeature(GameClientPing) or g_game.getFeature(GameExtendedClientPing)) then
87 topMenu.pingLabel:show()
88 else
89 topMenu.pingLabel:hide()
90 end
91 end)
92 end
93end
94
95function offline()
96 if topMenu.hideIngame then
97 show()
98 end
99 if topMenu.onlineLabel then
100 topMenu.onlineLabel:show()
101 end
102
103 hideGameButtons()
104 if topMenu.pingLabel then
105 topMenu.pingLabel:hide()
106 end
107 updateStatus()
108end
109
110function updateFps()
111 if not topMenu.fpsLabel then return end
112 fpsUpdateEvent = scheduleEvent(updateFps, 500)
113 text = 'FPS: ' .. g_app.getFps()
114 topMenu.fpsLabel:setText(text)
115end
116
117function updatePing(ping)
118 if not topMenu.pingLabel then return end
119 if g_proxy and g_proxy.getPing() > 0 then
120 ping = g_proxy.getPing()
121 end
122
123 local text = 'Ping: '
124 local color
125 if ping < 0 then
126 text = text .. "??"
127 color = 'yellow'
128 else
129 text = text .. ping .. ' ms'
130 if ping >= 500 then
131 color = 'red'
132 elseif ping >= 250 then
133 color = 'yellow'
134 else
135 color = 'green'
136 end
137 end
138 topMenu.pingLabel:setColor(color)
139 topMenu.pingLabel:setText(text)
140end
141
142function setPingVisible(enable)
143 if not topMenu.pingLabel then return end
144 topMenu.pingLabel:setVisible(enable)
145end
146
147function setFpsVisible(enable)
148 if not topMenu.fpsLabel then return end
149 topMenu.fpsLabel:setVisible(enable)
150end
151
152function addLeftButton(id, description, icon, callback, front, index)
153 return addButton(id, description, icon, callback, topMenu.leftButtonsPanel, false, front, index)
154end
155
156function addLeftToggleButton(id, description, icon, callback, front, index)
157 return addButton(id, description, icon, callback, topMenu.leftButtonsPanel, true, front, index)
158end
159
160function addRightButton(id, description, icon, callback, front, index)
161 return addButton(id, description, icon, callback, topMenu.rightButtonsPanel, false, front, index)
162end
163
164function addRightToggleButton(id, description, icon, callback, front, index)
165 return addButton(id, description, icon, callback, topMenu.rightButtonsPanel, true, front, index)
166end
167
168function addLeftGameButton(id, description, icon, callback, front, index)
169 local button = addButton(id, description, icon, callback, topMenu.leftGameButtonsPanel, false, front, index)
170 if modules.game_buttons then
171 modules.game_buttons.takeButton(button)
172 end
173 return button
174end
175
176function addLeftGameToggleButton(id, description, icon, callback, front, index)
177 local button = addButton(id, description, icon, callback, topMenu.leftGameButtonsPanel, true, front, index)
178 if modules.game_buttons then
179 modules.game_buttons.takeButton(button)
180 end
181 return button
182end
183
184function addRightGameButton(id, description, icon, callback, front, index)
185 local button = addButton(id, description, icon, callback, topMenu.rightGameButtonsPanel, false, front, index)
186 if modules.game_buttons then
187 modules.game_buttons.takeButton(button)
188 end
189 return button
190end
191
192function addRightGameToggleButton(id, description, icon, callback, front, index)
193 local button = addButton(id, description, icon, callback, topMenu.rightGameButtonsPanel, true, front, index)
194 if modules.game_buttons then
195 modules.game_buttons.takeButton(button)
196 end
197 return button
198end
199
200function showGameButtons()
201 topMenu.leftGameButtonsPanel:show()
202 topMenu.rightGameButtonsPanel:show()
203 if modules.game_buttons then
204 modules.game_buttons.takeButtons(topMenu.leftGameButtonsPanel:getChildren())
205 modules.game_buttons.takeButtons(topMenu.rightGameButtonsPanel:getChildren())
206 end
207end
208
209function hideGameButtons()
210 topMenu.leftGameButtonsPanel:hide()
211 topMenu.rightGameButtonsPanel:hide()
212end
213
214function getButton(id)
215 return topMenu:recursiveGetChildById(id)
216end
217
218function getTopMenu()
219 return topMenu
220end
221
222function toggle()
223 if not topMenu then
224 return
225 end
226
227 if topMenu:isVisible() then
228 hide()
229 else
230 show()
231 end
232end
233
234function hide()
235 topMenu:hide()
236 if not topMenu.hideIngame then
237 modules.game_interface.getRootPanel():addAnchor(AnchorTop, 'parent', AnchorTop)
238 end
239 if modules.game_stats then
240 modules.game_stats.show()
241 end
242end
243
244function show()
245 topMenu:show()
246 if not topMenu.hideIngame then
247 modules.game_interface.getRootPanel():addAnchor(AnchorTop, 'topMenu', AnchorBottom)
248 end
249 if modules.game_stats then
250 modules.game_stats.hide()
251 end
252end
253
254function updateStatus()
255 removeEvent(statusUpdateEvent)
256 if not Services or not Services.status or Services.status:len() < 4 then return end
257 if not topMenu.onlineLabel then return end
258 if g_game.isOnline() then return end
259 HTTP.postJSON(Services.status, {type="cacheinfo"}, function(data, err)
260 if err then
261 g_logger.warning("HTTP error for " .. Services.status .. ": " .. err)
262 statusUpdateEvent = scheduleEvent(updateStatus, 5000)
263 return
264 end
265 if topMenu.onlineLabel then
266 if data.online then
267 topMenu.onlineLabel:setText(data.online)
268 elseif data.playersonline then
269 topMenu.onlineLabel:setText(data.playersonline .. " players online")
270 end
271 end
272 if data.discord_online and topMenu.discordLabel then
273 topMenu.discordLabel:setText(data.discord_online)
274 end
275 if data.discord_link and topMenu.discordLabel and topMenu.discord then
276 local discordOnClick = function()
277 g_platform.openUrl(data.discord_link)
278 end
279 topMenu.discordLabel.onClick = discordOnClick
280 topMenu.discord.onClick = discordOnClick
281 end
282 statusUpdateEvent = scheduleEvent(updateStatus, 60000)
283 end)
284end
Top