Commit 2d537ea0 authored by nanahira's avatar nanahira

fixup comments

parent 58d57563
Pipeline #43216 failed with stages
in 72 minutes and 32 seconds
...@@ -97,14 +97,22 @@ npm start ...@@ -97,14 +97,22 @@ npm start
## 🔧 Configuration ## 🔧 Configuration
Key configuration options (see `config.example.yaml` for full list): Configuration meaning source of truth:
- `src/config.ts` is the canonical place for all config keys and their meanings.
- Use the comments in `src/config.ts` to understand what each field does.
- `config.example.yaml` is generated from `src/config.ts` defaults for quick editing.
- All config values are loaded as strings; follow each field's format note in `src/config.ts`.
- Format examples used in `src/config.ts`: comma-separated lists, integer strings, and explicit time units (`ms` or `s`).
Commonly used options:
- `WELCOME`: Welcome message shown to players joining rooms - `WELCOME`: Welcome message shown to players joining rooms
- `RECONNECT_TIMEOUT`: Disconnect timeout before reconnect expires (default: 180000ms) - `RECONNECT_TIMEOUT`: Disconnect timeout before reconnect expires (default: 180000ms)
- `NO_RECONNECT`: Set to disable reconnect feature - `ENABLE_RECONNECT`: Reconnect feature switch (default enabled)
- Standard YGOPro settings (port, timeout, banlist, etc.) - Standard YGOPro settings (port, timeout, banlist, etc.)
After modifying `src/config.ts`, regenerate the example config: After modifying defaults in `src/config.ts`, regenerate the example config:
```bash ```bash
npm run gen:config-example npm run gen:config-example
``` ```
......
...@@ -20,7 +20,7 @@ DECK_SIDE_MAX: "15" ...@@ -20,7 +20,7 @@ DECK_SIDE_MAX: "15"
DECK_MAX_COPIES: "3" DECK_MAX_COPIES: "3"
OCGCORE_DEBUG_LOG: "" OCGCORE_DEBUG_LOG: ""
WELCOME: "" WELCOME: ""
NO_RECONNECT: "" ENABLE_RECONNECT: "1"
RECONNECT_TIMEOUT: "180000" RECONNECT_TIMEOUT: "180000"
HOSTINFO_LFLIST: "0" HOSTINFO_LFLIST: "0"
HOSTINFO_RULE: "0" HOSTINFO_RULE: "0"
......
...@@ -2,6 +2,7 @@ import { Context } from '../app'; ...@@ -2,6 +2,7 @@ import { Context } from '../app';
import { Client } from './client'; import { Client } from './client';
import * as ipaddr from 'ipaddr.js'; import * as ipaddr from 'ipaddr.js';
import { convertStringArray } from '../utility/convert-string-array'; import { convertStringArray } from '../utility/convert-string-array';
import { parseConfigBoolean } from '../utility/parse-config-boolean';
export class IpResolver { export class IpResolver {
private logger = this.ctx.createLogger('IpResolver'); private logger = this.ctx.createLogger('IpResolver');
...@@ -110,9 +111,8 @@ export class IpResolver { ...@@ -110,9 +111,8 @@ export class IpResolver {
client.isLocal = isLocal; client.isLocal = isLocal;
// Increment count for new IP // Increment count for new IP
const noConnectCountLimit = this.ctx.getConfig( const noConnectCountLimit = parseConfigBoolean(
'NO_CONNECT_COUNT_LIMIT', this.ctx.getConfig('NO_CONNECT_COUNT_LIMIT', ''),
'',
); );
let connectCount = this.connectedIpCount.get(newIp) || 0; let connectCount = this.connectedIpCount.get(newIp) || 0;
......
...@@ -8,30 +8,62 @@ export type HostinfoOptions = { ...@@ -8,30 +8,62 @@ export type HostinfoOptions = {
}; };
export const defaultConfig = { export const defaultConfig = {
// Bind address. Use '::' to listen on all IPv4/IPv6 interfaces.
HOST: '::', HOST: '::',
// Main server port for YGOPro clients. Format: integer string.
PORT: '7911', PORT: '7911',
// Redis connection URL. Format: URL string. Empty means disabled.
REDIS_URL: '', REDIS_URL: '',
// Log level. Format: lowercase string (e.g. info/debug/warn/error).
LOG_LEVEL: 'info', LOG_LEVEL: 'info',
// WebSocket port. Format: integer string. '0' means do not open a separate WS port.
WS_PORT: '0', WS_PORT: '0',
// SSL certificate directory path. Format: filesystem path string.
SSL_PATH: '', SSL_PATH: '',
// SSL certificate file name. Format: file name string.
SSL_CERT: '', SSL_CERT: '',
// SSL private key file name. Format: file name string.
SSL_KEY: '', SSL_KEY: '',
// Trusted proxies for real IP parsing. Format: comma-separated CIDR list.
TRUSTED_PROXIES: '127.0.0.0/8,::1/128', TRUSTED_PROXIES: '127.0.0.0/8,::1/128',
// Disable per-IP connection count limit.
// Boolean parse rule (default false): ''/'0'/'false'/'null' => false, otherwise true.
NO_CONNECT_COUNT_LIMIT: '', NO_CONNECT_COUNT_LIMIT: '',
// Restrict accepted YGOPro version. Format: version string; empty means no restriction.
YGOPRO_VERSION: '', YGOPRO_VERSION: '',
// Additional accepted versions. Format: comma-separated version strings.
ALT_VERSIONS: '', ALT_VERSIONS: '',
// Proxy URL for outbound HTTP(S) requests.
// Format: proxy URL string (e.g. http://127.0.0.1:7890). Empty means no proxy.
USE_PROXY: '', USE_PROXY: '',
// YGOPro resource directory (scripts, DB, etc.). Format: filesystem path string.
YGOPRO_PATH: './ygopro', YGOPRO_PATH: './ygopro',
// Extra script directory. Format: filesystem path string. Empty means disabled.
EXTRA_SCRIPT_PATH: '', EXTRA_SCRIPT_PATH: '',
// Main deck minimum size. Format: integer string.
DECK_MAIN_MIN: '40', DECK_MAIN_MIN: '40',
// Main deck maximum size. Format: integer string.
DECK_MAIN_MAX: '60', DECK_MAIN_MAX: '60',
// Extra deck maximum size. Format: integer string.
DECK_EXTRA_MAX: '15', DECK_EXTRA_MAX: '15',
// Side deck maximum size. Format: integer string.
DECK_SIDE_MAX: '15', DECK_SIDE_MAX: '15',
// Max copies per card name. Format: integer string.
DECK_MAX_COPIES: '3', DECK_MAX_COPIES: '3',
// Enable ocgcore debug logs.
// Boolean parse rule (default false): ''/'0'/'false'/'null' => false, otherwise true.
OCGCORE_DEBUG_LOG: '', OCGCORE_DEBUG_LOG: '',
// Welcome message sent when players join. Format: plain string.
WELCOME: '', WELCOME: '',
NO_RECONNECT: '', // Enable reconnect feature.
// Boolean parse rule (default true): only '0'/'false'/'null' => false, otherwise true.
// Note: with default-true parsing, empty string is treated as true.
ENABLE_RECONNECT: '1',
// Reconnect timeout after disconnect. Format: integer string in milliseconds (ms).
RECONNECT_TIMEOUT: '180000', RECONNECT_TIMEOUT: '180000',
// Room hostinfo defaults expanded into HOSTINFO_* keys.
// Format: each HOSTINFO_* value is a string; numeric fields use integer strings.
// Unit note: HOSTINFO_TIME_LIMIT is in seconds (s).
...(Object.fromEntries( ...(Object.fromEntries(
Object.entries(DefaultHostinfo).map(([key, value]) => [ Object.entries(DefaultHostinfo).map(([key, value]) => [
`HOSTINFO_${key.toUpperCase()}`, `HOSTINFO_${key.toUpperCase()}`,
......
...@@ -30,6 +30,7 @@ import { RoomManager } from '../room/room-manager'; ...@@ -30,6 +30,7 @@ import { RoomManager } from '../room/room-manager';
import { getSpecificFields } from '../utility/metadata'; import { getSpecificFields } from '../utility/metadata';
import { YGOProCtosDisconnect } from '../utility/ygopro-ctos-disconnect'; import { YGOProCtosDisconnect } from '../utility/ygopro-ctos-disconnect';
import { isUpdateDeckPayloadEqual } from '../utility/deck-compare'; import { isUpdateDeckPayloadEqual } from '../utility/deck-compare';
import { parseConfigBoolean } from '../utility/parse-config-boolean';
interface DisconnectInfo { interface DisconnectInfo {
roomName: string; roomName: string;
...@@ -59,8 +60,8 @@ export class Reconnect { ...@@ -59,8 +60,8 @@ export class Reconnect {
); // 超时时间,单位:毫秒(默认 180000ms = 3分钟) ); // 超时时间,单位:毫秒(默认 180000ms = 3分钟)
constructor(private ctx: Context) { constructor(private ctx: Context) {
// 检查是否禁用断线重连 // 检查是否启用断线重连(默认启用)
if (this.ctx.getConfig('NO_RECONNECT', '')) { if (!parseConfigBoolean(this.ctx.getConfig('ENABLE_RECONNECT', ''), true)) {
return; return;
} }
......
...@@ -89,6 +89,7 @@ import { shuffleDecksBySeed } from '../utility/shuffle-decks-by-seed'; ...@@ -89,6 +89,7 @@ import { shuffleDecksBySeed } from '../utility/shuffle-decks-by-seed';
import { isUpdateMessage } from '../utility/is-update-message'; import { isUpdateMessage } from '../utility/is-update-message';
import { getMessageIdentifier } from '../utility/get-message-identifier'; import { getMessageIdentifier } from '../utility/get-message-identifier';
import { canIncreaseTime } from '../utility/can-increase-time'; import { canIncreaseTime } from '../utility/can-increase-time';
import { parseConfigBoolean } from '../utility/parse-config-boolean';
import { TimerState } from './timer-state'; import { TimerState } from './timer-state';
import { makeArray } from 'aragami/dist/src/utility/utility'; import { makeArray } from 'aragami/dist/src/utility/utility';
...@@ -1267,7 +1268,7 @@ export class Room { ...@@ -1267,7 +1268,7 @@ export class Room {
this.ocgcore.message$.subscribe((msg) => { this.ocgcore.message$.subscribe((msg) => {
if ( if (
msg.type === OcgcoreMessageType.DebugMessage && msg.type === OcgcoreMessageType.DebugMessage &&
!this.ctx.getConfig('OCGCORE_DEBUG_LOG', '') !parseConfigBoolean(this.ctx.getConfig('OCGCORE_DEBUG_LOG', ''))
) { ) {
return; return;
} }
......
export function parseConfigBoolean(
value: unknown,
defaultValue = false,
): boolean {
if (typeof value === 'boolean') {
return value;
}
if (typeof value === 'number') {
return value !== 0;
}
if (typeof value === 'string') {
const normalized = value.trim().toLowerCase();
if (defaultValue) {
return !(
normalized === '0' ||
normalized === 'false' ||
normalized === 'null'
);
}
return !(
normalized === '' ||
normalized === '0' ||
normalized === 'false' ||
normalized === 'null'
);
}
if (value == null) {
return defaultValue;
}
return Boolean(value);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment