Adjust Discord publication and lobby capacity defaults
CI / checks (push) Failing after 7m21s

This commit is contained in:
2026-10-18 17:23:50 -04:00
parent fd00ef5357
commit d715173719
15 changed files with 304 additions and 89 deletions
+7 -1
View File
@@ -27,6 +27,7 @@ import { migratePlayerScoreTotal } from './player-score-total.js';
import { migrateBank } from './bank.js';
import { migrateAfk } from './afk.js';
import { migrateDiscord } from '../discord/schema.js';
import { migrateDiscordPublicationDefaults } from '../discord/publication-defaults.js';
import { migrateBankCredentials } from './bank-credentials.js';
import { migrateTemperatures } from '../hosts/temperatures.js';
import {
@@ -212,7 +213,12 @@ export const migrations: readonly Migration[] = [
mode: 'foreign-keys-off',
run: migrateModerationCaseStates
},
{ version: 37, name: 'Discord boards and availability subscriptions', run: migrateDiscord }
{ version: 37, name: 'Discord boards and availability subscriptions', run: migrateDiscord },
{
version: 38,
name: 'Discord default server publication',
run: migrateDiscordPublicationDefaults
}
];
export const databaseVersion = migrations.length;
+11 -4
View File
@@ -14,6 +14,8 @@ type SourceServer = FleetServer & {
network?: { publicAddress: string | null; publicPort: number | null } | null;
};
export const DEFAULT_DISCORD_LOBBY_CAPACITY = 4;
/** IDs stay short enough for Discord components, even for long registry names. */
export function discordServerKey(name: string): string {
return createHash('sha256').update(name).digest('hex').slice(0, 20);
@@ -69,19 +71,24 @@ export function projectFleet(
settings: DiscordSettings,
now = Date.now()
): DiscordPublicServer[] {
const published = new Set(settings.publishedServers);
const excluded = new Set(settings.excludedServers);
return servers
.flatMap((server): DiscordPublicServer[] => {
if (!published.has(server.name)) return [];
if (excluded.has(server.name)) return [];
const identity = fleetIdentity(server);
if (identity.game !== 't5' && identity.game !== 't6') return [];
const game = identity.game;
const fresh = freshServer(server, now);
const fresh =
freshServer(server, now) &&
(!server.telemetry_after ||
Date.parse(server.last_seen_at ?? '') > Date.parse(server.telemetry_after));
const players =
fresh && Number.isSafeInteger(server.last_players) && server.last_players! >= 0
? server.last_players
: null;
const capacity = players !== null ? currentCapacity(server, now) : null;
// These lobbies have four slots when the live status omits the limit.
// Occupancy still needs fresh, current-process evidence below.
const capacity = currentCapacity(server, now) ?? DEFAULT_DISCORD_LOBBY_CAPACITY;
const state: DiscordPublicServer['state'] =
server.health === 'starting' || server.health === 'provisioning'
? 'starting'
@@ -0,0 +1,24 @@
import type Database from 'better-sqlite3';
/** Replace the old opt-in default while preserving an existing nonempty selection. */
export function migrateDiscordPublicationDefaults(handle: Database.Database): void {
const row = handle.prepare('SELECT value FROM discord_configuration WHERE id=1').get() as
{ value: string } | undefined;
if (!row) return;
const settings = JSON.parse(row.value) as Record<string, unknown>;
if ('excludedServers' in settings) return;
const published = new Set(settings.publishedServers as string[]);
settings.excludedServers = published.size
? (
handle
.prepare('SELECT name FROM servers WHERE destroyed_at IS NULL ORDER BY name')
.all() as { name: string }[]
)
.map((server) => server.name)
.filter((name) => !published.has(name))
: [];
delete settings.publishedServers;
handle
.prepare('UPDATE discord_configuration SET value=? WHERE id=1')
.run(JSON.stringify(settings));
}
+3 -3
View File
@@ -8,7 +8,7 @@ import {
} from '../../leaderboard-efficiency.js';
import { MIN_RECORDED_ROUND } from '../../match-history.js';
import { gameTitle } from '../../ui/server-labels.js';
import { discordServerKey, discordText } from './projection.js';
import { DEFAULT_DISCORD_LOBBY_CAPACITY, discordServerKey, discordText } from './projection.js';
export const BOARD_PAGE_SIZE = 8;
export const BROWSER_PAGE_SIZE = 5;
@@ -65,7 +65,7 @@ function summary(server: DiscordPublicServer): string {
const count =
server.players === null
? 'Players unknown'
: `${server.players}/${server.capacity ?? '?'} players`;
: `${server.players}/${server.capacity ?? DEFAULT_DISCORD_LOBBY_CAPACITY} players`;
return `${count}${server.round === null ? '' : ` · Round ${server.round}`}\n${states[server.state]}`;
}
@@ -250,7 +250,7 @@ export function renderWatchMaps(
export function renderWatchChoice(server: DiscordPublicServer): DiscordMessage {
return discordMessage([
text(
`## Watch ${discordText(server.map)}\nEmpty means zero observed players. Space means fewer players than the current observed capacity. Neither guarantees that a match accepts new players.\nOne DM · Expires in 24 hours`
`## Watch ${discordText(server.map)}\nEmpty means zero observed players. Space means fewer players than the lobby capacity. Neither guarantees that a match accepts new players.\nOne DM · Expires in 24 hours`
),
row(
button('Empty lobby', `ec:w:empty:${discordServerKey(server.mapKey)}`),
+2 -2
View File
@@ -6,7 +6,7 @@ import type {
DiscordSettings
} from '../../discord.js';
import { requireDiscordCredentials } from './config.js';
import { discordText, publicFleet } from './projection.js';
import { DEFAULT_DISCORD_LOBBY_CAPACITY, discordText, publicFleet } from './projection.js';
import { renderBoard } from './render.js';
import { DiscordStore, discordStore, type DiscordJob, type DiscordSubscription } from './store.js';
import { DiscordDeliveryError, DiscordRest, type DiscordTransport } from './transport.js';
@@ -373,7 +373,7 @@ function matchingServer(
function alertMessage(watch: DiscordSubscription, server: DiscordPublicServer): DiscordMessage {
const safe = (value: string) => discordText(value, 100);
return {
content: `🍒 **${safe(server.map)}** ${watch.mode === 'empty' ? 'has an empty lobby' : 'has an open player slot'}: **${safe(server.label)}** (${server.players}/${server.capacity ?? '?'}).\nThis describes occupancy; joining an in-progress game may still be restricted.\nYour one-time map watch is complete. Use /servers to browse or /watch to watch again.`,
content: `🍒 **${safe(server.map)}** ${watch.mode === 'empty' ? 'has an empty lobby' : 'has an open player slot'}: **${safe(server.label)}** (${server.players}/${server.capacity ?? DEFAULT_DISCORD_LOBBY_CAPACITY}).\nThis describes occupancy; joining an in-progress game may still be restricted.\nYour one-time map watch is complete. Use /servers to browse or /watch to watch again.`,
allowed_mentions: { parse: [] }
};
}