Fix Splatfest team image when converting presence embed to PNG/JPEG/WEBP

This commit is contained in:
Samuel Elliott 2024-01-07 09:39:23 +00:00
parent b5d86bf2d6
commit 6fd0f3f2f1
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
5 changed files with 35 additions and 7 deletions

14
package-lock.json generated
View File

@ -43,6 +43,7 @@
"@types/discord-rpc": "^4.0.8",
"@types/eventsource": "^1.1.15",
"@types/express": "^4.17.21",
"@types/mime-types": "^2.1.4",
"@types/node": "^18.18.10",
"@types/node-notifier": "^8.0.5",
"@types/node-persist": "^3.1.6",
@ -51,6 +52,7 @@
"@types/yargs": "^17.0.31",
"electron": "^26.6.0",
"electron-builder": "^24.6.4",
"mime-types": "^2.1.35",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-native-web": "^0.19.9",
@ -4242,6 +4244,12 @@
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
"dev": true
},
"node_modules/@types/mime-types": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz",
"integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==",
"dev": true
},
"node_modules/@types/ms": {
"version": "0.7.31",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
@ -14725,6 +14733,12 @@
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==",
"dev": true
},
"@types/mime-types": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz",
"integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==",
"dev": true
},
"@types/ms": {
"version": "0.7.31",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",

View File

@ -67,6 +67,7 @@
"@types/discord-rpc": "^4.0.8",
"@types/eventsource": "^1.1.15",
"@types/express": "^4.17.21",
"@types/mime-types": "^2.1.4",
"@types/node": "^18.18.10",
"@types/node-notifier": "^8.0.5",
"@types/node-persist": "^3.1.6",
@ -75,6 +76,7 @@
"@types/yargs": "^17.0.31",
"electron": "^26.6.0",
"electron-builder": "^24.6.4",
"mime-types": "^2.1.35",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-native-web": "^0.19.9",

View File

@ -6,6 +6,7 @@ import { createHash } from 'node:crypto';
import express, { Request, Response } from 'express';
import { fetch } from 'undici';
import * as persist from 'node-persist';
import mimetypes from 'mime-types';
import { BankaraMatchSetting_schedule, CoopRule, CoopSetting_schedule, DetailFestRecordDetailResult, DetailVotingStatusResult, FestMatchSetting_schedule, FestRecordResult, FestState, FestTeam_schedule, FestTeam_votingStatus, FestVoteState, Fest_schedule, FriendListResult, FriendOnlineState, Friend_friendList, GraphQLSuccessResponse, KnownRequestId, LeagueMatchSetting_schedule, RegularMatchSetting_schedule, StageScheduleResult, XMatchSetting_schedule } from 'splatnet3-types/splatnet3';
import type { Arguments as ParentArguments } from '../cli.js';
import { git, product, version } from '../util/product.js';
@ -1189,7 +1190,7 @@ class Server extends HttpServer {
const result = await this.handlePresenceRequest(req, null, presence_user_nsaid);
const {theme, friend_code, transparent, width} = getUserEmbedOptionsFromRequest(req);
const {theme, friend_code, transparent, width, options} = getUserEmbedOptionsFromRequest(req);
const etag = createHash('sha256').update(JSON.stringify({
result,
@ -1197,6 +1198,7 @@ class Server extends HttpServer {
friend_code,
transparent,
width,
options,
v: version + '-' + git?.revision,
})).digest('base64url');
@ -1208,7 +1210,7 @@ class Server extends HttpServer {
const url_map = await this.getImages(result, this.getResourceBaseUrls(req));
const svg = renderUserEmbedSvg(result, url_map, theme, friend_code, 1, transparent, width);
const svg = renderUserEmbedSvg(result, url_map, theme, friend_code, options, 1, transparent, width);
const [image, type] = await renderUserEmbedImage(svg, format);
res.setHeader('Content-Type', type);
@ -1361,11 +1363,13 @@ class Server extends HttpServer {
.replace(/(\/|^)\.\.(\/|$)/g, '$1...$2') +
(path.extname(pathname) ? '' : '.jpeg');
const type = (mimetypes.lookup(path.extname(pathname) || '.jpeg') || 'image/jpeg').split(';')[0];
const promise = this.promise_image.get(dir + '/' + name) ?? Promise.resolve().then(async () => {
try {
if (return_image_data) {
const data = await fs.readFile(path.join(dir, name));
return [name, data, 'image/jpeg'] as const;
return [name, data, type] as const;
}
await fs.stat(path.join(dir, name));
@ -1384,7 +1388,7 @@ class Server extends HttpServer {
debug('Downloaded image %s', name);
if (return_image_data) {
return [name, data, 'image/jpeg'] as const;
return [name, data, type] as const;
}
return name;

View File

@ -1,3 +1,4 @@
import mimetypes from 'mime-types';
import { FestVoteState } from 'splatnet3-types/splatnet3';
import type { Arguments as ParentArguments } from '../util.js';
import createDebug from '../../util/debug.js';
@ -80,7 +81,10 @@ export async function handler(argv: ArgumentsCamelCase<Arguments>) {
const response = await fetch(url);
const data = new Uint8Array(await response.arrayBuffer());
url_map[url] = [url, data, 'image/jpeg'];
const type = (mimetypes.contentType(response.headers.get('Content-Type') ?? 'application/octet-stream')
|| 'application/octet-stream').split(';')[0];
url_map[url] = [url, data, type];
}));
const svg = renderUserEmbedSvg(result, url_map, theme, argv.friendCode, {

View File

@ -2,6 +2,7 @@ import * as os from 'node:os';
import * as net from 'node:net';
import express, { Request, Response } from 'express';
import { createHash } from 'node:crypto';
import mimetypes from 'mime-types';
import { FestVoteState } from 'splatnet3-types/splatnet3';
import type { Arguments as ParentArguments } from '../util.js';
import createDebug from '../../util/debug.js';
@ -123,7 +124,7 @@ class Server extends HttpServer {
const image_urls = [result.friend.imageUri];
if ('imageUri' in result.friend.presence.game) image_urls.push(result.friend.presence.game.imageUri);
if (options.show_splatoon3_fest_team && result.splatoon3_fest_team?.image.url) image_urls.push(result.splatoon3_fest_team.image.url);
if (options.show_splatoon3_fest_team && result.splatoon3_fest_team?.myVoteState === FestVoteState.VOTED) image_urls.push(result.splatoon3_fest_team.image.url);
const url_map: Record<string, readonly [name: string, data: Uint8Array, type: string]> = {};
@ -132,7 +133,10 @@ class Server extends HttpServer {
const response = await fetch(url);
const data = new Uint8Array(await response.arrayBuffer());
url_map[url] = [url, data, 'image/jpeg'];
const type = (mimetypes.contentType(response.headers.get('Content-Type') ?? 'application/octet-stream')
|| 'application/octet-stream').split(';')[0];
url_map[url] = [url, data, type];
}));
const svg = renderUserEmbedSvg(result, url_map, theme, friend_code, options, 1, transparent, width);