feat: add game server monitoring support

- Added a new `/games` route in `monitorRoute.js` to fetch all supported games.
- Implemented `getAllGames` method in `monitorController.js` using the `gamedig` library.
- Introduced `useFetchMonitorGames` hook in `monitorHooks.js` to fetch game data in the frontend.
- Updated `UptimeCreate` page to support game server monitoring:
  - Added a new monitor type `"game"`.
  - Dynamically fetches and displays game options using the new `/games` API.
- Removed hardcoded `GAMES` object and replaced it with dynamic fetching from the backend.
- Updated `NetworkService.js` with a new `getMonitorGames` method for API calls.

This update introduces game server monitoring functionality, allowing users to monitor game servers dynamically.
This commit is contained in:
Burak Arslan committed 2025-08-03 13:19:55 +03:00
1 parent b53650a50f
commit 281cbbc30f
6 files changed
+67 -3455

No files matched your search

+23
View File
@@ -202,6 +202,25 @@ const useFetchStatsByMonitorId = ({
return [monitor, audits, isLoading, networkError];
};
const useFetchMonitorGames = ({ setGames, updateTrigger }) => {
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const fetchGames = async () => {
try {
setIsLoading(true);
const res = await networkService.getMonitorGames();
setGames(res.data.data);
} catch (error) {
createToast({ body: error.message });
} finally {
setIsLoading(false);
}
};
fetchGames();
}, [setGames, updateTrigger]);
return [isLoading];
};
const useFetchMonitorById = ({ monitorId, setMonitor, updateTrigger }) => {
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
@@ -360,6 +379,9 @@ const useUpdateMonitor = () => {
...((monitor.type === "port" || monitor.type === "game") && {
port: monitor.port,
}),
...(monitor.type == "game" && {
gameId: monitor.gameId,
}),
...(monitor.type === "hardware" && {
thresholds: monitor.thresholds,
secret: monitor.secret,
@@ -532,4 +554,5 @@ export {
useDeleteMonitorStats,
useCreateBulkMonitors,
useExportMonitors,
useFetchMonitorGames,
};
+15 -5
View File
@@ -41,10 +41,9 @@ import {
useUpdateMonitor,
usePauseMonitor,
useFetchMonitorById,
useFetchMonitorGames,
} from "../../../Hooks/monitorHooks";
import { GAMES } from "../../../Utils/games";
/**
* Parses a URL string and returns a URL object.
*
@@ -83,6 +82,7 @@ const UptimeCreate = ({ isClone = false }) => {
const [isOpen, setIsOpen] = useState(false);
const [useAdvancedMatching, setUseAdvancedMatching] = useState(false);
const [updateTrigger, setUpdateTrigger] = useState(false);
const [games, setGames] = useState({});
const triggerUpdate = () => {
setUpdateTrigger(!updateTrigger);
};
@@ -91,12 +91,22 @@ const UptimeCreate = ({ isClone = false }) => {
const [notifications, notificationsAreLoading, notificationsError] =
useGetNotificationsByTeamId();
const { determineState, statusColor } = useMonitorUtils();
// Network
const [isLoading] = useFetchMonitorById({
// Fetch monitor details
const [isFetchingMonitor] = useFetchMonitorById({
monitorId,
setMonitor,
updateTrigger: true,
});
// Fetch games
const [isFetchingGames] = useFetchMonitorGames({
setGames,
triggerUpdate: true,
});
// Combine the loading states
const isLoading = isFetchingMonitor || isFetchingGames;
const [createMonitor, isCreating] = useCreateMonitor();
const [pauseMonitor, isPausing] = usePauseMonitor({});
const [deleteMonitor, isDeleting] = useDeleteMonitor();
@@ -116,7 +126,7 @@ const UptimeCreate = ({ isClone = false }) => {
{ _id: 5, name: t("time.fiveMinutes") },
];
const GAMELIST = Object.entries(GAMES).map(([key, value]) => ({
const GAMELIST = Object.entries(games).map(([key, value]) => ({
_id: key,
name: value.name,
}));
+14
View File
@@ -74,6 +74,20 @@ class NetworkService {
}
}
/**
* Fetch the games associated with a monitor
*
* @async
* @returns {Promise<AxiosResponse>} The response from the axios GET request.
*/
async getMonitorGames() {
return this.axiosInstance.get(`/monitors/games`, {
headers: {
"Content-Type": "application/json",
},
});
}
/**
*
* ************************************
File diff suppressed because it is too large. Load diff
@@ -15,6 +15,7 @@ import {
import sslChecker from "ssl-checker";
import { fetchMonitorCertificate } from "./controllerUtils.js";
import BaseController from "./baseController.js";
import { games } from "gamedig";
const SERVICE_NAME = "monitorController";
class MonitorController extends BaseController {
@@ -441,6 +442,17 @@ class MonitorController extends BaseController {
SERVICE_NAME,
"exportMonitorsToCSV"
);
getAllGames = this.asyncHandler(
async (req, res) => {
return res.success({
msg: "OK",
data: games,
});
},
SERVICE_NAME,
"getAllGames"
);
}
export default MonitorController;
+3
View File
@@ -25,6 +25,9 @@ class MonitorRoutes {
// Hardware routes
this.router.get("/hardware/details/:monitorId", this.monitorController.getHardwareDetailsById);
// Game routes
this.router.get("/games", this.monitorController.getAllGames);
// General monitor routes
this.router.post("/pause/:monitorId", isAllowed(["admin", "superadmin"]), this.monitorController.pauseMonitor);
this.router.get("/stats/:monitorId", this.monitorController.getMonitorStatsById);