Skip to content

feat(instance): align game server list with vanilla multiplayer - #2006

Open
Dainsleif233 wants to merge 3 commits into
UNIkeEN:mainfrom
Dainsleif233:refactor/server-list
Open

Dainsleif233 wants to merge 3 commits into
UNIkeEN:mainfrom
Dainsleif233:refactor/server-list

Conversation

@Dainsleif233

@Dainsleif233 Dainsleif233 commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Checklist

  • Changes have been tested locally and work as expected.
  • All tests in workflows pass successfully.
  • Documentation has been updated if necessary.
  • Code formatting and commit messages align with the project's conventions.
  • Comments have been added for any complex logic or functionality if possible.

This PR is a ..

  • 🆕 New feature
  • 🐞 Bug fix
  • 🛠 Refactoring
  • ⚡️ Performance improvement
  • 🌐 Internationalization
  • 📄 Documentation improvement
  • 🎨 Code style optimization
  • ❓ Other (Please specify below)

Related Issues

  • Resolve [Bug] 无法添加服务器,显示“服务器已存在” #1971 — 服务器列表为空时添加服务器仍提示「服务器已存在」(hidden 条目参与判重、展示却被过滤)
  • The scope of this PR is larger than that bug: the list is realigned with vanilla multiplayer semantics (no IP dedup, reorder, edit, progressive ping, icon cache).

Description

Align the instance game server list with vanilla multiplayer behavior.

Allow duplicate addresses like the in-game server list, key entries by servers.dat index for delete/reorder, add edit + move up/down, ping each server progressively, and cache pinged icons into servers.dat. Drop the hidden-server duplicate check that made empty lists reject adds.

Also guard global keyboard shortcuts when event.key is missing (crash observed while typing in the add-server dialog).

Behavior changes

Area Before After
Add server Reject duplicate IPs (including hidden entries not shown in UI) Append like vanilla; duplicates allowed
Delete By server_addr (removes all matching IPs) By servers.dat index (one entry)
Reorder Not supported Move up / down among visible entries
Edit Not supported Update address / name by index
Ping Full-list query, wait for all results Lazy: full on enter/refresh; only changed entry after add/edit; progressive per-server UI updates via event
Icons In-memory only after ping Persisted to servers.dat (raw base64, vanilla-compatible)
Hidden servers Filtered on list, still blocked add Still hidden in UI (vanilla); no longer block add

MCP API (breaking)

  • delete_game_server: server_addr: String → index: usize
  • add_game_server: returns the new entry index (usize) instead of unit
  • New tools: update_game_server, move_game_server
  • retrieve_game_server_list results include index for each visible entry

External MCP clients that delete by IP need to switch to index (from retrieve_game_server_list).

i18n

All seven locale files updated (General.moveUp / moveDown, AddGameServerModal.header.editTitle, service strings for queryGameServerOnlineStatus / moveGameServer / updateGameServer; removed DUPLICATE_SERVER).

Additional Context

image

Screenshot: instance world server list with add/edit/move actions in the redesigned flow.

Branch: refactor/server-list → Dainsleif233:SJMCL

Suggested manual QA:

  1. Add the same address twice → both entries appear.
  2. Move up/down, edit name/address, delete one of the duplicates.
  3. Enter page → all pings fill in as they complete; after add/edit only the new/edited row re-pings.
  4. Confirm in vanilla multiplayer that pinged icons were written to servers.dat.
  5. Optional: hide a server in-game, re-add the same address in SJMCL → should succeed ([Bug] 无法添加服务器,显示“服务器已存在” #1971).

Summary by Sourcery

Align instance game-server management with vanilla multiplayer semantics, including duplicate entries, index-based editing and ordering, progressive status updates, and icon persistence.

New Features:

  • Align the instance server list with vanilla multiplayer behavior by allowing duplicate addresses and supporting index-based entries, editing, and visible-entry reordering.
  • Add progressive server status querying with selective refreshes and persisted vanilla-compatible server icons.

Bug Fixes:

  • Allow adding an address when matching hidden servers exist instead of incorrectly reporting a duplicate.
  • Prevent keyboard shortcut handling from crashing when keydown events omit the event key.

Enhancements:

  • Update the game-server APIs and MCP tools to operate on servers.dat indexes and expose server update, move, and progressive status operations.
  • Improve server list rendering to preserve duplicate entries, display cached icons, and apply incremental ping results.

Chores:

  • Update localized strings for server editing, movement, and status operations while removing duplicate-server messaging.

Allow duplicate addresses like the in-game server list, key entries by
servers.dat index for delete/reorder, add edit + move up/down, ping each
server progressively, and cache pinged icons into servers.dat. Drop the
hidden-server duplicate check that made empty lists reject adds.

Also guard global keyboard shortcuts when event.key is missing.
@github-actions github-actions Bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Sep 21, 2026
@sourcery-ai

sourcery-ai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Aligns Minecraft instance server management with vanilla multiplayer by allowing duplicate entries and indexed operations, adding edit/reorder controls, progressively querying and displaying status, persisting compatible icons, and updating the MCP and localization contracts.

Sequence diagram for progressive game-server status refresh

sequenceDiagram
    participant UI as InstanceWorldsPage
    participant Service as InstanceService
    participant Backend as Tauri commands
    participant Servers as servers.dat
    participant Ping as Minecraft servers

    UI->>Service: retrieveGameServerList(instanceId)
    Service->>Backend: retrieve_game_server_list
    Backend->>Servers: load_servers_info_from_nbt
    Servers-->>Backend: visible entries with index
    Backend-->>Service: local server list
    Service-->>UI: render immediately
    UI->>Service: queryGameServerOnlineStatus(instanceId, indexes)
    Service->>Backend: query_game_server_online_status
    Backend->>Ping: query_servers_online
    loop Each completed ping
        Ping-->>Backend: status and favicon
        Backend-->>UI: instance:game-server-status
        UI->>UI: applyQueriedServers
    end
    Backend->>Servers: persist_server_icons_to_nbt
Loading

Entity relationship diagram for indexed server entries

erDiagram
    SERVERS_DAT_ENTRY {
        usize index PK
        string ip
        string name
        boolean hidden
        string icon
    }
    VISIBLE_SERVER_ROW {
        usize index FK
        string ip
        string name
        boolean online
        uint latency
    }
    SERVERS_DAT_ENTRY ||--o| VISIBLE_SERVER_ROW : "hidden entries excluded"
Loading

Flow diagram for indexed server-list operations

flowchart LR
    List["Visible servers.dat entries"] --> Index["Entry index"]
    Index --> Add["add_game_server\nappend; duplicates allowed"]
    Index --> Edit["update_game_server\nupdate name/address"]
    Index --> Delete["delete_game_server\nremove one entry"]
    Index --> Move["move_game_server\nswap visible neighbors"]
    Add --> List
    Edit --> List
    Delete --> List
    Move --> List
Loading

File-Level Changes

Change Details Files
Reworked server.dat loading and mutation around stable entry indexes while preserving hidden-entry filtering.
  • Expose each visible server’s original servers.dat index.
  • Allow duplicate addresses and return the appended index.
  • Delete, edit, and reorder entries by index, with reordering limited to visible entries.
  • Replace duplicate-server errors with not-found handling.
src-tauri/src/instance/commands.rs
src-tauri/src/instance/helpers/server.rs
src-tauri/src/instance/models/misc.rs
src/models/instance/misc.ts
src/enums/service-error.ts
Added selective, progressive server status querying with vanilla-compatible icon persistence.
  • Support full-list or index-targeted ping requests.
  • Emit a frontend event as each ping completes, including failures.
  • Persist normalized raw-base64 server icons to servers.dat.
  • Mark invalid or failed targets offline with cleared status fields.
src-tauri/src/instance/commands.rs
src-tauri/src/instance/helpers/server.rs
src-tauri/src/lib.rs
src/services/instance.ts
Updated the instance server-list UI and service layer for add, edit, move, indexed delete, and progressive refresh flows.
  • Add edit modal state and indexed update handling.
  • Add move-up/move-down and edit actions with boundary disabling.
  • Load local entries immediately, merge ping results by index, and selectively re-ping added or edited entries.
  • Resolve cached icon formats for display and register/unregister status event listeners.
src/pages/instances/details/[id]/worlds.tsx
src/components/modals/add-game-server-modal.tsx
src/components/common/common-icon-button.tsx
src/services/instance.ts
Expanded the MCP interface and localized UI strings to match the new indexed server-management contract.
  • Change deletion from address to index and return the new index from add.
  • Expose update and move tools with index-based schemas.
  • Add move/edit/service translations and remove duplicate-server messaging across supported locales.
src-tauri/src/intelligence/mcp_server/launcher/tools/instance.rs
src/locales/en.json
src/locales/es.json
src/locales/fr.json
src/locales/ja.json
src/locales/lzh.json
src/locales/zh-Hans.json
src/locales/zh-Hant.json
Hardened global keyboard shortcut matching for incomplete keydown events.
  • Treat a missing or non-string event.key as a non-matching key instead of calling string methods on it.
src/hooks/keyboard-shortcut.ts

Assessment against linked issues

Issue Objective Addressed Explanation
#1971 允许添加与通过“直接连接”使用过的服务器相同地址的服务器,即使该地址对应的条目在服务器列表中被隐藏,也不应错误提示“服务器已存在”。 ✅
#1971 使实例服务器列表的添加、删除和展示行为与原版多人游戏列表一致,允许重复地址并正确区分隐藏条目和可见条目。 ✅

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@Dainsleif233

Copy link
Copy Markdown
Contributor Author

Waiting #1972

Replace mc-server-status with lite-mc-ping (UNIkeEN#1972) while keeping
progressive per-server status events and servers.dat icon cache.
@Dainsleif233
Dainsleif233 marked this pull request as ready for review September 22, 2026 06:13

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/pages/instances/details/[id]/worlds.tsx" line_range="158-161" />
<code_context>
+                .filter((s) => s.isQueried)
+                .map((s) => [s.ip + "|" + s.name, s] as const)
+            );
+            return next.map((s) => {
+              const hit = statusMap.get(s.ip + "|" + s.name);
+              return hit ? hit : s;
+            });
+          });
+        }
</code_context>
<issue_to_address>
**issue (broader_impact):** When a delete or reorder shifts the `servers.dat` positions, `statusMap` returns the previous `GameServerInfo` object instead of the newly loaded object, preserving its stale `index`. Subsequent edit, move, or delete actions therefore target the wrong entry; duplicate entries with the same address and name also collapse into one status-map key.

**Triggers:** When the affected servers have already been queried and the list is reloaded with `preserveStatus: true`, such as after delete or reorder.

**Suggested fix:** Preserve queried status fields while retaining each newly loaded server's current `index` and identity, or key the map by `index` and update shifted entries explicitly.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 1 finding to address first, and the new index-based delete, update, and reorder commands persist changes directly to servers.dat, so a wrong index or stale UI can remove or overwrite a saved server entry. Reverting the code would not restore those entries, although the impact is limited to the affected local server-list records and can be repaired manually.

Blocking findings: src/pages/instances/details/[id]/worlds.tsx:161


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread src/pages/instances/details/[id]/worlds.tsx
Merge only status fields after list reloads so delete/reorder cannot reuse
a stale servers.dat index, and match duplicate address+name pairs in order.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 无法添加服务器,显示“服务器已存在”

1 participant