mirror of
https://github.com/diangogav/EDOpro-server-ts
synced 2026-08-24 00:23:05 -04:00
* chore(dependencies): update various package versions in package-lock.json * feat(windbot): playable edison bots and format-scoped random pools Edison bots join the botlist under short names that fit the utf16[20] pass field. Botlist entries gain a format tag; random bot selection resolves a pool from the join tokens (mirroring the room's rule-tier precedence) so a format room can no longer roll a bot with an illegal deck. Bot names are validated against the pass-field budget at boot, and the bot-request failure path delivers its JOINERROR before the canonical room teardown destroys the sockets. * feat(ban-list): deterministic alias resolution with load-time format aliases Format banlists carry an explicit alias captured from their formats/<dir> path at load time. Alias resolution tries the alias field, then the exact normalized name, and only then the substring scan — now tie-broken by shortest normalized name instead of load order, with a memoized warning on ambiguity. Adds getFirstOCGIndex so OCG-list tokens stop hardcoding index 0. * fix(room): rule-mapping clamps, state coherence, and boot-order hardening The lp clamp compared a NaN (parseInt over the whole token) so lp0 started duels at 0 LP; clamps now act on the extracted number. The edison rule set is shared between its two tokens. The room's DuelState label and its state object now always transition together: waiting() sets both and resets isStart/ready flags, and setDuelFinished disposes the OCGCore before delegating — the ocgcore-error rewind no longer leaks the core, lies to the room list, or leaves a stale TRY_START armed. Missing banlist aliases warn once instead of silently mislabeling rooms. Windbot bootstrap moved before socket init so a bad botlist aborts pre-listen, and the never-initialized registry fallback composes the full base chain. * feat(room): exact-string pairing joins and (name,password) room identity Empty-password commands made purely of recognized tokens become pairing joins: they route to a waiting same-command room with a free seat, an empty password, and a compatible league — or create a fresh room. They never land in a dueling or full room. A disconnected pairing player who re-sends the bare command is first matched as a legitimate reconnector (same predicate as findReconnectingPlayer) before the pairing scan runs. Non-pairing joins now identify a room by the exact (name, password) pair: a mismatched pair creates its own room instead of rejecting, so a passwordless pairing room no longer blocks passworded rooms that share its name. Spectating a room mid-duel with the correct password is unchanged. docs/join-commands.md is the reference for the whole command system.
102 lines
4 KiB
Docker
102 lines
4 KiB
Docker
# syntax=docker/dockerfile:1
|
|
# Stage 1: Clone repositories and assemble resources
|
|
FROM public.ecr.aws/docker/library/node:24.11.0-bullseye-slim AS resources-builder
|
|
|
|
RUN apt-get update -y && \
|
|
apt-get install -y --no-install-recommends wget git ca-certificates jq && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
WORKDIR /build
|
|
|
|
# Resource layout is owned by scripts/clone_repositories.sh + scripts/setup_resources.sh — the
|
|
# single source of truth, shared with local dev (README) and the runtime refresh
|
|
# loop (entrypoint). This produces /build/resources/releases/<id> and a current symlink.
|
|
COPY scripts/ ./scripts/
|
|
# resources.manifest.json = public base (+ the shipped example). The private override is
|
|
# NOT part of the build — it is provided at runtime, so the seed is public-only.
|
|
COPY resources.manifest*.json ./
|
|
# Assemble the PUBLIC resource seed so the server boots immediately. Private sources are
|
|
# fetched at runtime by the entrypoint's updater (mounted private override + a token from
|
|
# the container env); no token ever touches the build.
|
|
RUN bash scripts/clone_repositories.sh && bash scripts/setup_resources.sh
|
|
|
|
|
|
# Stage 2: Build CoreIntegrator (C++)
|
|
FROM public.ecr.aws/docker/library/node:24.11.0-bullseye-slim AS core-builder
|
|
|
|
RUN apt-get update -y && \
|
|
apt-get install -y --no-install-recommends \
|
|
g++ make cmake pkg-config \
|
|
libboost-system-dev \
|
|
libsqlite3-dev \
|
|
libjsoncpp-dev \
|
|
nlohmann-json3-dev \
|
|
libcurl4-openssl-dev && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
WORKDIR /app
|
|
|
|
COPY ./core .
|
|
|
|
RUN cmake -B build -S . -DCMAKE_BUILD_TYPE=Release && \
|
|
cmake --build build
|
|
|
|
|
|
# Stage 3: Build Node.js server
|
|
FROM public.ecr.aws/docker/library/node:24.11.0-bullseye AS server-builder
|
|
|
|
WORKDIR /server
|
|
|
|
COPY package.json package-lock.json ./
|
|
RUN npm ci
|
|
|
|
RUN git clone --depth 1 https://github.com/diangogav/evolution-types.git ./src/evolution-types
|
|
|
|
COPY . .
|
|
|
|
RUN npm run build && \
|
|
npm prune --production
|
|
|
|
|
|
# Stage 4: Final image
|
|
FROM public.ecr.aws/docker/library/node:24.11.0-slim
|
|
|
|
RUN apt-get update && \
|
|
apt-get install -y --no-install-recommends curl wget git ca-certificates jq liblua5.3-dev libsqlite3-dev libevent-dev dumb-init && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
WORKDIR /app
|
|
|
|
# Server
|
|
COPY --from=server-builder /server/dist ./
|
|
COPY --from=server-builder /server/package.json ./package.json
|
|
COPY --from=server-builder /server/node_modules ./node_modules
|
|
|
|
# WindBot botlist (read at boot by FileBotlistRepository when ENABLE_WINDBOT=true).
|
|
# tsc only emits dist/, so config/ must be copied explicitly or the server crashes
|
|
# at boot with ENOENT when windbot is enabled. Replace botlist.example.json with a
|
|
# curated botlist whose deck names match the WindBot image's bots.json.
|
|
# IMPORTANT: every entry MUST also carry a "format" tag ("tcg" / "jtp" / "edison")
|
|
# matching resolveBotPool's pools. Format-scoped random join commands (e.g.
|
|
# "pre,ai", "ed,ai", "jtp,ai") call pickRandom(format) — a curated botlist without
|
|
# "format" tags makes that lookup return null for every user of those commands
|
|
# (JOINERROR). See config/botlist.example.json for the reference shape.
|
|
COPY --from=server-builder /server/config ./config
|
|
|
|
# CoreIntegrator binaries
|
|
COPY --from=core-builder /app/libocgcore.so ./core/libocgcore.so
|
|
COPY --from=core-builder /app/CoreIntegrator ./core/CoreIntegrator
|
|
|
|
# All resources (assembled in Stage 1): releases/<id> + current symlink — the
|
|
# baked seed so the server boots immediately. The entrypoint's background loop
|
|
# then refreshes resources/current in place and the in-memory reload picks it up.
|
|
COPY --from=resources-builder /build/resources ./resources
|
|
|
|
# Provisioning scripts (scripts/) + the PUBLIC manifest — reused by the runtime updater loop.
|
|
# The private override is not baked in: mount it at runtime (-v .../resources.manifest.private.json
|
|
# :/app/resources.manifest.private.json) and pass a read-only token via the container env
|
|
# (--env-file); the entrypoint sets up git-credentials before the loop clones private sources.
|
|
COPY scripts/ ./scripts/
|
|
COPY resources.manifest*.json ./
|
|
|
|
CMD ["dumb-init", "bash", "scripts/entrypoint.sh"]
|