Skip to content

Commit d9e65a8

Browse files
author
Meta Construct
committed
display map thumbnail as bg again
1 parent 4f278e5 commit d9e65a8

File tree

5 files changed

+68
-3
lines changed

5 files changed

+68
-3
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ dist
77
data
88
build
99
resources/game-server-status/style.css
10+
cache
1011

1112
# Our files
1213
.env
@@ -15,4 +16,4 @@ resources/game-server-status/style.css
1516
!*.example.json
1617
deploy.sh
1718
markov_data.txt
18-
metaconcord.db
19+
metaconcord.db

app/services/webapp/api/game-server-status.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@ import GameServer from "@/app/services/gamebridge/GameServer.js";
33
import nodeHtmlToImage from "node-html-to-image";
44
import path from "path";
55
import pug from "pug";
6+
import { access, mkdir, readFile, writeFile } from "fs/promises";
7+
import { constants as fs_constants } from "fs";
8+
import mime from "mime";
9+
10+
const cacheFolder = path.join(process.cwd(), "cache", "map-thumbnails");
11+
12+
const imageToDataURL = async filePath => {
13+
const mimeType = mime.getType(filePath);
14+
if (!mimeType) throw new Error("No MIME type from path?");
15+
16+
const base64 = await readFile(filePath, { encoding: "base64" });
17+
return `data:${mimeType};base64,${base64}`;
18+
};
619

720
export default async (webApp: WebApp): Promise<void> => {
821
webApp.app.get("/server-status/:id{/:bruh}", async (req, res) => {
@@ -25,11 +38,56 @@ export default async (webApp: WebApp): Promise<void> => {
2538
!req.headers.accept ||
2639
req.headers["user-agent"]?.includes("+https://discordapp.com");
2740

41+
// #region Map Thumbnail
42+
const mapThumbnail = server.status.mapThumbnail;
43+
const workshopMap = server.workshopMap;
44+
let thumbFilepath: string | undefined = undefined;
45+
if (mapThumbnail?.match(/^https?:\/\//) && workshopMap) {
46+
await access(cacheFolder, fs_constants.F_OK).catch(() =>
47+
mkdir(cacheFolder, { recursive: true })
48+
);
49+
50+
const _thumbFilepath = path.join(cacheFolder, `${workshopMap.id}`);
51+
let hasFile = true;
52+
// have to assume these are the only extensions we expect...
53+
for (const ext of [".webp", ".jpg", ".jpeg", ".png", ".gif"]) {
54+
await access(_thumbFilepath + ext, fs_constants.F_OK).catch(() => {
55+
hasFile = false;
56+
});
57+
if (hasFile) {
58+
thumbFilepath = _thumbFilepath + ext;
59+
break;
60+
}
61+
}
62+
if (!thumbFilepath) {
63+
try {
64+
const response = await fetch(mapThumbnail);
65+
if (response.ok) {
66+
const contentType = response.headers.get("content-type");
67+
if (!contentType) throw new Error("No content-type");
68+
69+
const ext = mime.getExtension(contentType);
70+
if (!ext) throw new Error("No extension");
71+
72+
thumbFilepath = [_thumbFilepath, ext.toLowerCase()].join(".");
73+
74+
const buffer = Buffer.from(await response.arrayBuffer());
75+
await writeFile(thumbFilepath, buffer);
76+
}
77+
} catch (err) {}
78+
}
79+
} else {
80+
thumbFilepath = mapThumbnail as string;
81+
}
82+
const mapThumbnail64 = await imageToDataURL(thumbFilepath);
83+
// #endregion
84+
2885
const html = pug.renderFile(
2986
path.join(process.cwd(), "resources/game-server-status/view.pug"),
3087
{
3188
server,
3289
image: !!discordBot,
90+
mapThumbnail64,
3391
}
3492
);
3593
if (discordBot) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"graphql-request": "^5.0.0",
4141
"irc-upd": "^0.11.0",
4242
"jsonwebtoken": "^9.0.0",
43+
"mime": "^4.1.0",
4344
"node-html-to-image": "^5.0.0",
4445
"node-schedule": "^2.1.1",
4546
"node-ssh": "^13.0.0",

resources/game-server-status/view.pug

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ html(lang="en")
1717
justify-content: center;
1818
}
1919
body
20-
main(style=`background-image: url(${mapThumbnail})`)
20+
main(style=`background-image: url(${mapThumbnail64})`)
2121
ul.playerlist
2222
each player in server.status.players
2323
li.player(class={ 'is-admin': player.isAdmin, 'is-banned': player.isBanned, 'is-afk': player.isAfk, 'is-pirate': player.isPirate })
2424
a(title="View profile", href=player.accountId ? `https://steamcommunity.com/profiles/[U:1:${player.accountId}]` : "#", target="_blank")
2525
if (player.avatar)
2626
img.avatar(src=player.avatar)
27-
span.nick #{player.nick}
27+
span.nick #{player.nick}

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3551,6 +3551,11 @@ mime-types@^3.0.0, mime-types@^3.0.1:
35513551
dependencies:
35523552
mime-db "^1.54.0"
35533553

3554+
mime@^4.1.0:
3555+
version "4.1.0"
3556+
resolved "https://registry.yarnpkg.com/mime/-/mime-4.1.0.tgz#ec55df7aa21832a36d44f0bbee5c04639b27802f"
3557+
integrity sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==
3558+
35543559
mimic-response@^3.1.0:
35553560
version "3.1.0"
35563561
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"

0 commit comments

Comments
 (0)