From a804a6e98b89edde595c010cc714ff6b40465391 Mon Sep 17 00:00:00 2001 From: Dunemask Date: Sat, 10 Feb 2024 17:36:18 -0700 Subject: [PATCH 1/9] [FEATURE] Cleaned up terminal display --- .../sub-controllers/console-controller.js | 10 +++++--- lib/k8s/server-create.js | 2 +- lib/routes/middlewares/auth-middleware.js | 1 - package.json | 4 ++-- src/components/servers/RconDialog.jsx | 17 ++++++------- src/components/servers/RconView.jsx | 24 ++++++++++++++----- src/css/rcon.css | 3 +-- 7 files changed, 36 insertions(+), 25 deletions(-) diff --git a/lib/controllers/sub-controllers/console-controller.js b/lib/controllers/sub-controllers/console-controller.js index 6713960..b272f03 100644 --- a/lib/controllers/sub-controllers/console-controller.js +++ b/lib/controllers/sub-controllers/console-controller.js @@ -26,9 +26,13 @@ export async function webConsoleLogs(socket) { const log = new k8s.Log(kc); const logStream = new stream.PassThrough(); - logStream.on("data", (chunk) => - socket.emit("push", Buffer.from(chunk).toString()), - ); + var logstreamBuffer = ""; + logStream.on("data", (chunk) => { + const bufferString = Buffer.from(chunk).toString(); + if (!bufferString.includes("\n")) return (logstreamBuffer += bufferString); + const clientChunks = `${logstreamBuffer}${bufferString}`.split("\n"); + for (var c of clientChunks) socket.emit("push", c); + }); log .log(namespace, mcsPods[0], containerName, logStream, { follow: true, diff --git a/lib/k8s/server-create.js b/lib/k8s/server-create.js index 004fd03..30e21fa 100644 --- a/lib/k8s/server-create.js +++ b/lib/k8s/server-create.js @@ -67,7 +67,7 @@ function createBackupSecret(serverSpec) { `endpoint = ${backupHost}`, `acl = private`, `no_check_bucket = true`, - `no_check_container = true` + `no_check_container = true`, ].join("\n"); backupYaml.data["rclone.conf"] = Buffer.from(rcloneConfig).toString("base64"); return backupYaml; diff --git a/lib/routes/middlewares/auth-middleware.js b/lib/routes/middlewares/auth-middleware.js index 0a73234..8f4318f 100644 --- a/lib/routes/middlewares/auth-middleware.js +++ b/lib/routes/middlewares/auth-middleware.js @@ -17,7 +17,6 @@ const cairoAuthenticate = async (token) => { // Middleware const cairoAuthHandler = (req, res, next) => { if (!req.token) return res.status(401).send("Cairo auth required!"); - VERB("AUTH", `${MCL_CAIRO_URL}/api/user/info`); cairoAuthenticate(req.token) .then((authData) => (req.cairoId = authData.id)) .then(() => next()) diff --git a/package.json b/package.json index 353c74d..1ac30f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minecluster", - "version": "0.0.1-alpha.0", + "version": "0.0.1-alpha.1", "description": "Minecraft Server management using Kubernetes", "type": "module", "scripts": { @@ -8,7 +8,7 @@ "start": "node dist/app.js", "dev:server": "nodemon dist/app.js", "dev:react": "vite", - "kub": "nodemon lib/k8s.js", + "lint": "npx prettier -w src lib vite.config.js", "start:dev": "concurrently -k \"MCL_DEV_PORT=52025 npm run dev:server\" \" MCL_VITE_DEV_PORT=52000 MCL_VITE_BACKEND_URL=http://localhost:52025 npm run dev:react\" -n s,v -p -c green,yellow", "start:dev:garden": "concurrently -k \"npm run dev:server\" \"npm run dev:react\" -n s,v -p -c green,yellow" }, diff --git a/src/components/servers/RconDialog.jsx b/src/components/servers/RconDialog.jsx index 579b97b..ad69761 100644 --- a/src/components/servers/RconDialog.jsx +++ b/src/components/servers/RconDialog.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from "react"; +import { useState } from "react"; import useMediaQuery from "@mui/material/useMediaQuery"; import { useTheme } from "@mui/material/styles"; import Button from "@mui/material/Button"; @@ -19,22 +19,19 @@ export default function RconDialog(props) { const { server, open, dialogToggle } = props; const { name: serverName, id: serverId } = server ?? {}; const theme = useTheme(); - const fullScreen = useMediaQuery(theme.breakpoints.down("sm")); + const fullScreen = useMediaQuery(theme.breakpoints.down("md")); return ( - + RCON - {serverName} - + diff --git a/src/components/servers/RconView.jsx b/src/components/servers/RconView.jsx index 24f87ee..d6112bd 100644 --- a/src/components/servers/RconView.jsx +++ b/src/components/servers/RconView.jsx @@ -2,6 +2,7 @@ import { useState, useEffect, useRef } from "react"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; import TextField from "@mui/material/TextField"; +import Typography from "@mui/material/Typography"; import RconSocket from "./RconSocket.js"; import "@mcl/css/rcon.css"; @@ -39,16 +40,27 @@ export default function RconView(props) { } return ( - -
+ + {logs.map((v, k) => ( - {v} -
+ {v}
))} -
- + + Date: Sat, 10 Feb 2024 17:47:07 -0700 Subject: [PATCH 2/9] [FEATURE] Cleaned up terminal display --- src/components/servers/RconView.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/servers/RconView.jsx b/src/components/servers/RconView.jsx index d6112bd..cf503b2 100644 --- a/src/components/servers/RconView.jsx +++ b/src/components/servers/RconView.jsx @@ -49,6 +49,7 @@ export default function RconView(props) { backgroundColor: "rgba(0,0,0,.815)", color: "white", borderRadius: "4px", + width:"100%" }} > {logs.map((v, k) => ( From beca266eef6cf6ed7b7c4f460f0c3c8c62c09a4f Mon Sep 17 00:00:00 2001 From: Dunemask Date: Sat, 10 Feb 2024 18:10:29 -0700 Subject: [PATCH 3/9] [FEATURE] Cleaned up terminal display --- src/components/servers/RconView.jsx | 33 ++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/components/servers/RconView.jsx b/src/components/servers/RconView.jsx index cf503b2..8bbccbd 100644 --- a/src/components/servers/RconView.jsx +++ b/src/components/servers/RconView.jsx @@ -2,10 +2,21 @@ import { useState, useEffect, useRef } from "react"; import Box from "@mui/material/Box"; import Button from "@mui/material/Button"; import TextField from "@mui/material/TextField"; +import Skeleton from "@mui/material/Skeleton"; import Typography from "@mui/material/Typography"; import RconSocket from "./RconSocket.js"; import "@mcl/css/rcon.css"; +function RconLogSkeleton() { + return ( + + ); +} + export default function RconView(props) { const { serverId } = props; const logsRef = useRef(0); @@ -49,18 +60,21 @@ export default function RconView(props) { backgroundColor: "rgba(0,0,0,.815)", color: "white", borderRadius: "4px", - width:"100%" + width: "100%", }} > - {logs.map((v, k) => ( - - {v} - - ))} + {logs.length === 0 && + [...Array(20).keys()].map((_v, i) => )} + {logs.length > 0 && + logs.map((v, k) => ( + + {v} + + ))} {rcon && rcon.rconLive && !rcon.rconError && ( - + )} {!(rcon && rcon.rconLive && !rcon.rconError) && ( From 99c735a6fd3bc2376e338829c82633ea735ecad5 Mon Sep 17 00:00:00 2001 From: Dunemask Date: Sat, 10 Feb 2024 18:13:06 -0700 Subject: [PATCH 4/9] [FEATURE] Addditional Filetypes for editor --- src/components/files/FilePreview.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/files/FilePreview.jsx b/src/components/files/FilePreview.jsx index 0241cf5..3d9cc7e 100644 --- a/src/components/files/FilePreview.jsx +++ b/src/components/files/FilePreview.jsx @@ -10,7 +10,7 @@ import Toolbar from "@mui/material/Toolbar"; import TextEditor from "./TextEditor.jsx"; import { cairoAuthHeader } from "@mcl/util/auth.js"; -const textFileTypes = ["properties", "txt", "yaml", "yml", "json", "env"]; +const textFileTypes = ["properties", "txt", "yaml", "yml", "json", "env", "toml", "tml", "text"]; const imageFileTypes = ["png", "jpeg", "jpg"]; export const supportedFileTypes = [...textFileTypes, ...imageFileTypes]; From 9b7539664ec20d39fdc65436328ca95d1b8c6318 Mon Sep 17 00:00:00 2001 From: Dunemask Date: Sat, 10 Feb 2024 18:15:25 -0700 Subject: [PATCH 5/9] [FEATURE] Addditional Filetypes for editor --- src/components/files/FilePreview.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/files/FilePreview.jsx b/src/components/files/FilePreview.jsx index 3d9cc7e..62df10a 100644 --- a/src/components/files/FilePreview.jsx +++ b/src/components/files/FilePreview.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect, memo } from "react"; +import { useState, useEffect } from "react"; import useMediaQuery from "@mui/material/useMediaQuery"; import { useTheme } from "@mui/material/styles"; import Button from "@mui/material/Button"; From 39369fe41af717bbb46c6f004845b081a87c63c5 Mon Sep 17 00:00:00 2001 From: Dunemask Date: Sat, 10 Feb 2024 18:24:14 -0700 Subject: [PATCH 6/9] [FIX] Don't display non text files in previewer --- src/components/files/FilePreview.jsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/files/FilePreview.jsx b/src/components/files/FilePreview.jsx index 62df10a..c6e1002 100644 --- a/src/components/files/FilePreview.jsx +++ b/src/components/files/FilePreview.jsx @@ -10,7 +10,17 @@ import Toolbar from "@mui/material/Toolbar"; import TextEditor from "./TextEditor.jsx"; import { cairoAuthHeader } from "@mcl/util/auth.js"; -const textFileTypes = ["properties", "txt", "yaml", "yml", "json", "env", "toml", "tml", "text"]; +const textFileTypes = [ + "properties", + "txt", + "yaml", + "yml", + "json", + "env", + "toml", + "tml", + "text", +]; const imageFileTypes = ["png", "jpeg", "jpg"]; export const supportedFileTypes = [...textFileTypes, ...imageFileTypes]; @@ -44,6 +54,7 @@ export default function FilePreview(props) { } async function onSave() { + if (!isTextFile) return; const formData = new FormData(); const blob = new Blob([modifiedText], { type: "plain/text" }); formData.append("file", blob, name); @@ -77,7 +88,7 @@ export default function FilePreview(props) { {name} - + {isTextFile && }