Skip to content

Commit

Permalink
Support mel.board.portal2.sr
Browse files Browse the repository at this point in the history
  • Loading branch information
NeKzor committed May 13, 2024
1 parent 5197acf commit e350425
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 80 deletions.
12 changes: 12 additions & 0 deletions docker/volumes/initdb/_init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,18 @@ CREATE TABLE videos (
demo_is_host INT,
demo_metadata TEXT,
demo_requires_repair INT NOT NULL DEFAULT 0,
board_source INT NOT NULL DEFAULT 0,
board_source_domain VARCHAR(32) AS (
IF(
board_source = 0,
NULL,
IF(
board_source = 1,
'board.portal2.sr',
'mel.board.portal2.sr'
)
)
) STORED,
board_changelog_id INT,
board_profile_number VARCHAR(32),
board_rank INT,
Expand Down
11 changes: 11 additions & 0 deletions src/bot/commands/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ const validateUrl = (urlString: string) => {
return isNaN(id) ? null : `https://board.portal2.sr/getDemo?id=${id}`;
}

// Input/Output: https://mel.board.portal2.sr/getDemo?id=234826

if (
url.origin === 'https://mel.board.portal2.sr' &&
url.pathname === '/getDemo' &&
url.search.startsWith('?id=')
) {
const id = parseInt(url.search.slice(4), 10);
return isNaN(id) ? null : `https://mel.board.portal2.sr/getDemo?id=${id}`;
}

// Input: https://autorender.portal2.sr/video.html?v=234826
// Output: https://board.portal2.sr/getDemo?id=234826

Expand Down
5 changes: 3 additions & 2 deletions src/bot/commands/vid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ createCommand({
user_id: string;
views: number;
share_id: string;
source: string;
}[];
}

Expand All @@ -99,14 +100,14 @@ createCommand({

const map = escapeMaskedLink(video.map);
const mapLink = escapeMaskedLink(
`https://board.portal2.sr/chamber/${video.map_id}`,
`https://${video.source}/chamber/${video.map_id}`,
);

const time = escapeMaskedLink(formatCmTime(video.time));
const videoLink = `${AUTORENDER_PUBLIC_URI}/videos/${video.share_id}`;

const playerName = escapeMaskedLink(video.user);
const profileLink = `https://board.portal2.sr/profile/${video.user_id}`;
const profileLink = `https://${video.source}/profile/${video.user_id}`;

await bot.helpers.editOriginalInteractionResponse(
interaction.token,
Expand Down
4 changes: 2 additions & 2 deletions src/bot/deno.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"tasks": {
"dev": "deno run --import-map=../import_map.json --unstable-kv --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/kv,/logs/bot,worker.ts --allow-write=/kv,/logs/bot --allow-net=discord.com,gateway.discord.gg,gateway-us-east1-b.discord.gg,gateway-us-east1-c.discord.gg,gateway-us-east1-d.discord.gg,deno.land,cdn.discord.com,cdn.discordapp.com,board.portal2.sr,autorender.server --watch main.ts",
"prod": "deno run --import-map=../import_map.json --unstable-kv --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/kv,/logs/bot,worker.ts --allow-write=/kv,/logs/bot --allow-net=discord.com,gateway.discord.gg,gateway-us-east1-b.discord.gg,gateway-us-east1-c.discord.gg,gateway-us-east1-d.discord.gg,deno.land,cdn.discord.com,cdn.discordapp.com,board.portal2.sr,autorender.server main.ts"
"dev": "deno run --import-map=../import_map.json --unstable-kv --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/kv,/logs/bot,worker.ts --allow-write=/kv,/logs/bot --allow-net=discord.com,gateway.discord.gg,gateway-us-east1-b.discord.gg,gateway-us-east1-c.discord.gg,gateway-us-east1-d.discord.gg,deno.land,cdn.discord.com,cdn.discordapp.com,board.portal2.sr,mel.board.portal2.sr,autorender.server --watch main.ts",
"prod": "deno run --import-map=../import_map.json --unstable-kv --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/kv,/logs/bot,worker.ts --allow-write=/kv,/logs/bot --allow-net=discord.com,gateway.discord.gg,gateway-us-east1-b.discord.gg,gateway-us-east1-c.discord.gg,gateway-us-east1-d.discord.gg,deno.land,cdn.discord.com,cdn.discordapp.com,board.portal2.sr,mel.board.portal2.sr,autorender.server main.ts"
},
"fmt": {
"useTabs": false,
Expand Down
8 changes: 6 additions & 2 deletions src/server/app/views/Status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ type QueuedVideo =
};

type AutorenderVideo =
& Pick<Video, 'share_id' | 'title' | 'created_at' | 'pending' | 'render_node' | 'board_changelog_id'>
& Pick<
Video,
'share_id' | 'title' | 'created_at' | 'pending' | 'render_node' | 'board_source_domain' | 'board_changelog_id'
>
& {
rendered_by_username: string | null;
};
Expand Down Expand Up @@ -93,6 +96,7 @@ export const loader: DataLoader = async ({ context }) => {
, videos.created_at
, videos.pending
, videos.render_node
, videos.board_source_domain
, videos.board_changelog_id
, renderer.username as rendered_by_username
from videos
Expand Down Expand Up @@ -359,7 +363,7 @@ export const Status = () => {
<td className={tw`px-6 py-4`}>
<a
className={tw`font-medium text-blue-600 dark:text-blue-400 hover:underline`}
href={`https://board.portal2.sr/changelog?id=${video.board_changelog_id}`}
href={`https://${video.board_source_domain}/changelog?id=${video.board_changelog_id}`}
target='_blank'
>
{video.board_changelog_id}
Expand Down
10 changes: 5 additions & 5 deletions src/server/app/views/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export const VideoView = () => {
<a
className={tw`font-medium text-blue-600 dark:text-blue-400 hover:underline`}
href={data.board_changelog_id !== null
? `https://board.portal2.sr/chamber/${data.best_time_id}`
? `https://${data.board_source_domain}/chamber/${data.best_time_id}`
: `https://steamcommunity.com/workshop/filedetails/?id=${data.workshop_file_id}`}
target='_blank'
>
Expand All @@ -255,7 +255,7 @@ export const VideoView = () => {
<a
className={tw`font-medium text-blue-600 dark:text-blue-400 hover:underline`}
href={data.board_changelog_id !== null
? `https://board.portal2.sr/profile/${data.demo_steam_id}`
? `https://${data.board_source_domain}/profile/${data.demo_steam_id}`
: `https://steamcommunity.com/profiles/${data.demo_steam_id}`}
target='_blank'
>
Expand All @@ -269,7 +269,7 @@ export const VideoView = () => {
<a
className={tw`font-medium text-blue-600 dark:text-blue-400 hover:underline`}
href={data.board_changelog_id !== null
? `https://board.portal2.sr/profile/${data.demo_partner_steam_id}`
? `https://${data.board_source_domain}/profile/${data.demo_partner_steam_id}`
: `https://steamcommunity.com/profiles/${data.demo_partner_steam_id}`}
target='_blank'
>
Expand All @@ -283,7 +283,7 @@ export const VideoView = () => {
? (
<a
className={tw`font-medium text-blue-600 dark:text-blue-400 hover:underline`}
href={`https://board.portal2.sr/changelog?id=${data.board_changelog_id}`}
href={`https://${data.board_source_domain}/changelog?id=${data.board_changelog_id}`}
target='_blank'
>
{formatCmTime(data.demo_time_score)}
Expand All @@ -296,7 +296,7 @@ export const VideoView = () => {
<div>
<a
className={tw`font-medium text-blue-600 dark:text-blue-400 hover:underline`}
href={`https://board.portal2.sr/changelog?id=${data.board_changelog_id}`}
href={`https://${data.board_source_domain}/changelog?id=${data.board_changelog_id}`}
target='_blank'
>
View Changelog
Expand Down
6 changes: 3 additions & 3 deletions src/server/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
"prod": "deno task stale & deno task board & deno task processing & deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,app/assets,/logs/server,/storage --allow-write=/logs/server,/storage --allow-run=ffprobe --allow-net main.ts",
"test": "deno test --import-map=../import_map.json --allow-net --allow-read --allow-env --unsafely-ignore-certificate-errors=autorender.portal2.local",
"perm": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example --allow-net=autorender.database:3307 tasks/perm.ts",
"migrate": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/logs/server/migrate_info.log,/logs/server/migrate_error.log,/storage --allow-write=/logs/server/migrate_info.log,/logs/server/migrate_error.log --allow-write=/logs/server/migrate_info.log,/logs/server/migrate_error.log,/storage --allow-net=autorender.database:3307,autorender.portal2.sr,board.portal2.sr tasks/migrate.ts",
"migrate": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/logs/server/migrate_info.log,/logs/server/migrate_error.log,/storage --allow-write=/logs/server/migrate_info.log,/logs/server/migrate_error.log --allow-write=/logs/server/migrate_info.log,/logs/server/migrate_error.log,/storage --allow-net=autorender.database:3307,autorender.portal2.sr,board.portal2.sr,mel.board.portal2.sr tasks/migrate.ts",
"stale": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/logs/server/stale_info.log,/logs/server/stale_error.log --allow-write=/logs/server/stale_info.log,/logs/server/stale_error.log --allow-net=autorender.database:3307 tasks/stale.ts",
"dev:stale": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/logs/server/stale_info.log,/logs/server/stale_error.log --allow-write=/logs/server/stale_info.log,/logs/server/stale_error.log --allow-net=autorender.database:3307 --watch tasks/stale.ts",
"board": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/logs/server/board_info.log,/logs/server/board_error.log,/storage --allow-write=/logs/server/board_info.log,/logs/server/board_error.log,/storage --allow-net=autorender.database:3307,board.portal2.sr,board.nekz.me tasks/board.ts",
"dev:board": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/logs/server/board_info.log,/logs/server/board_error.log,/storage --allow-write=/logs/server/board_info.log,/logs/server/board_error.log,/storage --allow-net=autorender.database:3307,board.portal2.sr,board.nekz.me --watch tasks/board.ts",
"board": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/logs/server/board_info.log,/logs/server/board_error.log,/storage --allow-write=/logs/server/board_info.log,/logs/server/board_error.log,/storage --allow-net=autorender.database:3307,board.portal2.sr,mel.board.portal2.sr tasks/board.ts",
"dev:board": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/logs/server/board_info.log,/logs/server/board_error.log,/storage --allow-write=/logs/server/board_info.log,/logs/server/board_error.log,/storage --allow-net=autorender.database:3307,board.portal2.sr,mel.board.portal2.sr --watch tasks/board.ts",
"processing": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/logs/server/processing_info.log,/logs/server/processing_error.log,/storage --allow-write=/logs/server/processing_info.log,/logs/server/processing_error.log,/storage --allow-net=autorender.database:3307 --allow-run=ffprobe,ffmpeg tasks/processing.ts",
"dev:processing": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/logs/server/processing_info.log,/logs/server/processing_error.log,/storage --allow-write=/logs/server/processing_info.log,/logs/server/processing_error.log,/storage --allow-net=autorender.database:3307 --allow-run=ffprobe,ffmpeg --watch tasks/processing.ts",
"id": "deno run --import-map=../import_map.json --no-prompt --allow-env --allow-read=.env,.env.defaults,.env.example,/storage --allow-net=autorender.database:3307 tasks/id.ts"
Expand Down
36 changes: 28 additions & 8 deletions src/server/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
AccessToken,
AuditSource,
AuditType,
BoardSource,
DiscordUser,
FixedDemoStatus,
Game,
Expand Down Expand Up @@ -60,6 +61,7 @@ import {
import { rateLimits } from './rate_limits.ts';
import { fetchDemo, getChangelog } from './tasks/portal2_sr.ts';
import { insertVideo } from './tasks/board_insert.ts';
import { fetchMelDemo } from './tasks/mel.ts';

const SERVER_HOST = Deno.env.get('SERVER_HOST')!;
const SERVER_PORT = parseInt(Deno.env.get('SERVER_PORT')!, 10);
Expand Down Expand Up @@ -756,6 +758,7 @@ apiV1
Video,
| 'video_id'
| 'share_id'
| 'board_source'
| 'board_changelog_id'
| 'file_name'
| 'created_at'
Expand All @@ -764,6 +767,7 @@ apiV1
>(
`select BIN_TO_UUID(video_id) as video_id
, share_id
, board_source
, board_changelog_id
, file_name
, created_at
Expand All @@ -783,7 +787,8 @@ apiV1
}

if (video.board_changelog_id) {
const { demo, originalFilename } = await fetchDemo(video.board_changelog_id);
const demoFetcher = video.board_source === BoardSource.Mel ? fetchMelDemo : fetchDemo;
const { demo, originalFilename } = await demoFetcher(video.board_changelog_id);
const filePath = getDemoFilePath(video.video_id);

{
Expand Down Expand Up @@ -978,7 +983,8 @@ apiV1
const videos = await db.query<Pick<Video, 'board_changelog_id'>>(
`select board_changelog_id
from videos
where board_changelog_id in (${ids.map(() => '?')})
where board_source = ${BoardSource.Portal2}
and board_changelog_id in (${ids.map(() => '?')})
and video_url is not null`,
ids,
);
Expand All @@ -989,12 +995,19 @@ apiV1
})
// Get the video of a leaderboard run.
.get('/video/:boardChangelogId(\\d+)/video', async (ctx) => {
const source = Number(ctx.request.url.searchParams.get('source')) ?? BoardSource.Portal2;
if (isNaN(source) || ![BoardSource.Portal2, BoardSource.Mel].includes(source)) {
return Err(ctx, Status.BadRequest, 'Bad value for source parameter.');
}

const [video] = await db.query<Pick<Video, 'video_url'>>(
`select video_url
from videos
where board_changelog_id = ?
where board_source = ?
and board_changelog_id = ?
and video_url is not null`,
[
source,
ctx.params.boardChangelogId,
],
);
Expand Down Expand Up @@ -1023,20 +1036,22 @@ apiV1
user_id: string;
views: number;
share_id: string;
source: string;
}[];
}

type VideoSelect =
& Pick<
Video,
| 'comment'
| 'created_at'
| 'board_source_domain'
| 'board_changelog_id'
| 'board_rank'
| 'demo_time_score'
| 'demo_player_name'
| 'board_profile_number'
| 'views'
| 'comment'
| 'share_id'
>
& Pick<MapModel, 'alias' | 'best_time_id'>;
Expand All @@ -1056,6 +1071,7 @@ apiV1
user_id: video.board_profile_number,
views: video.views,
share_id: video.share_id,
source: video.board_source_domain,
};
};

Expand All @@ -1064,6 +1080,7 @@ apiV1
if (!query.length) {
const videos = await db.query<VideoSelect>(
`select videos.created_at
, videos.board_source_domain
, videos.board_changelog_id
, videos.board_rank
, videos.demo_time_score
Expand Down Expand Up @@ -1226,6 +1243,7 @@ apiV1

const videos = await db.query<VideoSelect>(
`select videos.created_at
, videos.board_source_domain
, videos.board_changelog_id
, videos.board_rank
, videos.demo_time_score
Expand Down Expand Up @@ -2209,9 +2227,10 @@ router.get('/storage/demos/:share_id/:fixed(fixed)?', async (ctx) => {
}

try {
const [video] = await db.query<Pick<Video, 'video_id' | 'file_name' | 'board_changelog_id'>>(
const [video] = await db.query<Pick<Video, 'video_id' | 'file_name' | 'board_source_domain' | 'board_changelog_id'>>(
`select BIN_TO_UUID(video_id) as video_id
, file_name
, board_source_domain
, board_changelog_id
from videos
where share_id = ?`,
Expand All @@ -2224,7 +2243,7 @@ router.get('/storage/demos/:share_id/:fixed(fixed)?', async (ctx) => {
}

if (video.board_changelog_id) {
return ctx.response.redirect(`https://board.portal2.sr/getDemo?id=${video.board_changelog_id}`);
return ctx.response.redirect(`https://${video.board_source_domain}/getDemo?id=${video.board_changelog_id}`);
}

const requestedFixedDemo = ctx.params.fixed !== undefined;
Expand Down Expand Up @@ -2372,7 +2391,8 @@ router.get('/video.html', useSession, async (ctx) => {
const [video] = await db.query<Pick<Video, 'share_id'>>(
`select share_id
from videos
where board_changelog_id = ?`,
where board_source = ${BoardSource.Portal2}
and board_changelog_id = ?`,
[
changelogId,
],
Expand All @@ -2388,7 +2408,7 @@ router.get('/video.html', useSession, async (ctx) => {
return Err(ctx, Status.NotFound, 'Unable to fetch changelog entry.');
}

const shareId = await insertVideo(entry);
const shareId = await insertVideo(BoardSource.Portal2, entry);
if (!shareId) {
return Err(ctx, Status.NotFound, 'Unable to create video.');
}
Expand Down
35 changes: 32 additions & 3 deletions src/server/tasks/board.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@
*
* SPDX-License-Identifier: MIT
*
* This checks if there are any videos to render from board.portal2.sr.
* This checks if there are any videos to render from board.portal2.sr and mel.board.portal2.sr.
*/

import 'dotenv/load.ts';
import { db } from '../db.ts';
import { PendingStatus } from '~/shared/models.ts';
import { BoardSource, PendingStatus } from '~/shared/models.ts';
import { installLogger, logger } from '../logger.ts';
import { getChangelog } from './portal2_sr.ts';
import { insertVideo } from './board_insert.ts';
import { getMelChangelog } from './mel.ts';

const BOARD_INTEGRATION_UPDATE_INTERVAL = 60 * 1_000;
const BOARD_INTEGRATION_START_DATE = '2023-08-25';
const MEL_BOARD_INTEGRATION_START_DATE = '2024-05-12';

const FAILED_RENDER_MIN_RETRY_MINUTES = 15;
const FAILED_RENDER_MAX_RETRY_MINUTES = 60;
Expand Down Expand Up @@ -43,7 +45,28 @@ const checkChangelogUpdates = async () => {
continue;
}

await insertVideo(entry);
await insertVideo(BoardSource.Portal2, entry);
}
};

const checkMelChangelogUpdates = async () => {
const changelog = await getMelChangelog({
endRank: 1,
maxDaysAgo: 1,
banned: 0,
pending: 0,
});

if (!changelog) {
return;
}

for (const entry of changelog) {
if (entry.time_gained.slice(0, 10) < MEL_BOARD_INTEGRATION_START_DATE) {
continue;
}

await insertVideo(BoardSource.Mel, entry);
}
};

Expand Down Expand Up @@ -89,6 +112,12 @@ const update = async () => {
logger.error(err);
}

try {
await checkMelChangelogUpdates();
} catch (err) {
logger.error(err);
}

try {
await resetFailedAutorenders();
} catch (err) {
Expand Down
Loading

0 comments on commit e350425

Please sign in to comment.