-
Notifications
You must be signed in to change notification settings - Fork 0
feat: implement admin web interface #347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
24293ea
feat: add cpp-httplib to vcpkg.json for enhanced HTTP support
ann7415 c36c3f6
feat: add initial CSS styles for improved admin web interface layout
ann7415 b06c2d8
feat: add initial HTML structure for R-Type Admin Dashboard
ann7415 919d65e
feat: implement API interaction and table rendering for admin web int…
ann7415 01c69ce
feat: integrate web-based admin dashboard into server runtime
ann7415 38497b3
feat: implement AdminWebServer for managing sessions and rooms via a …
ann7415 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| /* | ||
| ** EPITECH PROJECT, 2026 | ||
| ** R-Type | ||
| ** File description: | ||
| ** AdminWebServer | ||
| */ | ||
|
|
||
| #pragma once | ||
| #include <algorithm> | ||
| #include <atomic> | ||
| #include <cctype> | ||
| #include <chrono> | ||
| #include <cstdlib> | ||
| #include <functional> | ||
| #include <httplib.h> | ||
| #include <memory> | ||
| #include <nlohmann/json.hpp> | ||
| #include <optional> | ||
| #include <sstream> | ||
| #include <string> | ||
| #include <thread> | ||
| #include <vector> | ||
|
|
||
| #ifndef _WIN32 | ||
| #include <arpa/inet.h> | ||
| #else | ||
| #include <winsock2.h> | ||
| #include <ws2tcpip.h> | ||
| #endif | ||
|
|
||
| #include "ISessionManager.hpp" | ||
| #include "RoomManager.hpp" | ||
|
|
||
| namespace Net::Admin | ||
| { | ||
| /** | ||
| * @class AdminWebServer | ||
| * @brief A simple administrative web server for managing sessions and rooms. | ||
| */ | ||
| class AdminWebServer { | ||
| public: | ||
| /** | ||
| * @brief Constructs a new AdminWebServer object. | ||
| * @param sessions Shared pointer to the session manager. | ||
| * @param rooms Shared pointer to the room manager. | ||
| * @param onShutdown Callback function to be called on server shutdown. | ||
| * @param port Port number for the web server (default is 8082). | ||
| * @param token Authentication token for accessing admin endpoints (default is "admin"). | ||
| */ | ||
| AdminWebServer(std::shared_ptr<Server::ISessionManager> sessions, std::shared_ptr<Engine::RoomManager> rooms, | ||
| std::function<void()> onShutdown, int port = 8082, std::string token = "admin"); | ||
|
ann7415 marked this conversation as resolved.
|
||
|
|
||
| /** | ||
| * @brief Destroys the AdminWebServer object and stops the server if running. | ||
| */ | ||
| ~AdminWebServer(); | ||
|
|
||
| /** | ||
| * @brief Starts the admin web server in a separate thread. | ||
| */ | ||
| void start(); | ||
|
|
||
| /** | ||
| * @brief Stops the admin web server. | ||
| */ | ||
| void stop() noexcept; | ||
|
|
||
| /** | ||
| * @brief Gets the port number the server is running on. | ||
| * @return The port number. | ||
| */ | ||
| [[nodiscard]] int port() const noexcept; | ||
|
|
||
| private: | ||
| void run(); ///> Thread function to run the web server | ||
|
|
||
| std::shared_ptr<Server::ISessionManager> _sessions; ///> Session manager | ||
| std::shared_ptr<Engine::RoomManager> _rooms; ///> Room manager | ||
| std::function<void()> _onShutdown; ///> Shutdown callback | ||
| std::unique_ptr<httplib::Server> _srv; ///> HTTP server instance | ||
|
|
||
| int _port = 8082; ///> Server port | ||
| std::string _token; ///> Authentication token | ||
|
|
||
| std::atomic<bool> _running{false}; ///> Flag indicating if the server is running | ||
| std::thread _thread; ///> Thread for the web server | ||
| }; | ||
| } // namespace Net::Admin | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| function authHeaders() { | ||
| const t = document.getElementById("token").value.trim(); | ||
| return { "Authorization": "Bearer " + t }; | ||
| } | ||
|
|
||
| async function apiGet(path) { | ||
| const r = await fetch(path, { headers: authHeaders() }); | ||
| if (!r.ok) throw new Error(await r.text()); | ||
| return r.json(); | ||
| } | ||
|
|
||
| async function apiPost(path, body) { | ||
| const r = await fetch(path, { | ||
| method: "POST", | ||
| headers: { ...authHeaders(), "Content-Type": "application/json" }, | ||
| body: JSON.stringify(body || {}) | ||
| }); | ||
| if (!r.ok) throw new Error(await r.text()); | ||
| return r.json(); | ||
| } | ||
|
|
||
| function renderTable(el, cols, rows) { | ||
| const t = document.getElementById(el); | ||
| t.innerHTML = ""; | ||
| const thead = document.createElement("tr"); | ||
| cols.forEach(c => { const th = document.createElement("th"); th.textContent = c; thead.appendChild(th); }); | ||
| t.appendChild(thead); | ||
|
|
||
| rows.forEach(r => { | ||
| const tr = document.createElement("tr"); | ||
| cols.forEach(c => { | ||
| const td = document.createElement("td"); | ||
| td.appendChild(r[c] instanceof Node ? r[c] : document.createTextNode(String(r[c] ?? ""))); | ||
| tr.appendChild(td); | ||
| }); | ||
| t.appendChild(tr); | ||
| }); | ||
| } | ||
|
|
||
| async function refreshAll() { | ||
| try { | ||
| const status = await apiGet("/api/status"); | ||
| document.getElementById("status").textContent = JSON.stringify(status, null, 2); | ||
| const rooms = await apiGet("/api/rooms"); | ||
| renderTable("rooms", ["roomId","name","players","maxPlayers"], rooms); | ||
| const sessions = await apiGet("/api/sessions"); | ||
| const rows = sessions.map(s => { | ||
| const kick = document.createElement("button"); | ||
| kick.textContent = "Kick"; | ||
| kick.onclick = async () => { await apiPost("/api/kick", { who: String(s.id) }); await refreshAll(); }; | ||
|
|
||
| const ban = document.createElement("button"); | ||
| ban.textContent = "Ban 60m"; | ||
| ban.onclick = async () => { await apiPost("/api/ban", { who: String(s.id), minutes: 60 }); await refreshAll(); }; | ||
|
|
||
| return { | ||
| id: s.id, | ||
| username: s.username, | ||
| authed: s.authed, | ||
| roomId: s.roomId, | ||
| kick: kick, | ||
| ban: ban | ||
| }; | ||
| }); | ||
| renderTable("sessions", ["id","username","authed","roomId","kick","ban"], rows); | ||
|
|
||
| const bans = await apiGet("/api/bans"); | ||
| renderTable("bans", ["ip","remainingSeconds"], bans); | ||
|
|
||
|
ann7415 marked this conversation as resolved.
|
||
| } catch (e) { | ||
| alert("Error: " + e.message); | ||
| } | ||
| } | ||
|
ann7415 marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| <!doctype html> | ||
| <html> | ||
|
ann7415 marked this conversation as resolved.
|
||
| <head> | ||
| <meta charset="utf-8" /> | ||
| <title>R-Type Admin</title> | ||
| <link rel="stylesheet" href="style.css"> | ||
| </head> | ||
| <body> | ||
| <h1>R-Type Admin Dashboard</h1> | ||
|
|
||
| <section> | ||
| <label>Admin token:</label> | ||
| <input id="token" type="password" placeholder="R_TYPE_ADMIN_TOKEN" /> | ||
| <button onclick="refreshAll()">Refresh</button> | ||
| </section> | ||
|
|
||
| <h2>Status</h2> | ||
| <pre id="status"></pre> | ||
|
|
||
| <h2>Sessions</h2> | ||
| <table id="sessions"></table> | ||
|
|
||
| <h2>Rooms</h2> | ||
| <table id="rooms"></table> | ||
|
|
||
| <h2>Bans</h2> | ||
| <table id="bans"></table> | ||
|
|
||
|
ann7415 marked this conversation as resolved.
|
||
| <script src="app.js"></script> | ||
| </body> | ||
| </html> | ||
|
ann7415 marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| body { font-family: sans-serif; margin: 20px; } | ||
| table { border-collapse: collapse; width: 100%; margin-bottom: 20px; } | ||
| th, td { border: 1px solid #ccc; padding: 6px; } | ||
| th { background: #eee; text-align: left; } | ||
| button { margin-right: 6px; } | ||
| pre { background: #111; color: #0f0; padding: 10px; } | ||
|
ann7415 marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| "sqlite3", | ||
| "openssl", | ||
| "nlohmann-json", | ||
| "lz4" | ||
| "lz4", | ||
| "cpp-httplib" | ||
| ] | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.