Skip to content

Complete MCScript server implementation with plugins and CPE support - #60

Closed
perronosaurio wants to merge 19 commits into
masterfrom
claude/fervent-keller-38r7qx
Closed

perronosaurio wants to merge 19 commits into
masterfrom
claude/fervent-keller-38r7qx

Conversation

@perronosaurio

Copy link
Copy Markdown
Owner

This is a complete implementation of MCScript, a ClassiCube/Minecraft Classic server written in JavaScript with support for the Classic Protocol Extension (CPE).

Summary

This PR introduces the full MCScript server codebase, including core server functionality, protocol implementation, plugin system, and a comprehensive set of built-in plugins. The server supports multiple levels, custom blocks, CPE extensions, and most features are implemented as loadable plugins.

Key Changes

Core Server Infrastructure:

  • lib/server.js - Main server class managing players, levels, commands, and plugins
  • lib/player.js - Player entity with position, permissions, CPE support, and block selection
  • lib/network/connection.js - TCP/WebSocket connection handling and packet decoding
  • lib/network/websocket.js - RFC 6455 WebSocket implementation for web clients
  • lib/protocol/packets.js - Classic protocol and CPE packet definitions
  • lib/protocol/cp437.js - Code page 437 encoding/decoding for classic strings

Level and Block Management:

  • lib/level/level.js - Level class with block storage, environment properties, and NBT serialization
  • lib/level/manager.js - Level loading, saving, generation, and backup management
  • lib/level/generators.js - World generators (flat, noise-based terrain)
  • lib/blocks.js - Block definitions, names, and custom block support
  • lib/block-permissions.js - Per-rank block placement/deletion permissions

Plugin System:

  • lib/plugins/manager.js - Plugin loader with dependency resolution and lifecycle management
  • lib/plugins/template.js - Template for creating new plugins
  • lib/plugins/installer.js - Plugin installation from GitHub

Command System:

  • lib/commands/manager.js - Command registry with permission checking
  • lib/commands/core.js - Core commands (help, plugins, ranks, etc.)

Storage and Configuration:

  • lib/storage/player-db.js - Player record persistence
  • lib/storage/json-store.js - Atomic JSON file storage
  • lib/config.js - Configuration loading with environment variable overrides
  • lib/ranks.js - Rank system with permission levels

Utilities:

  • lib/util/text.js - Color code handling and text utilities
  • lib/util/logger.js - Logging with file output and ANSI colors
  • lib/util/nbt.js - NBT format reader/writer for ClassicWorld files
  • lib/events.js - Event bus with priorities and cancellable events
  • lib/heartbeat.js - ClassiCube server list heartbeat
  • lib/cpe-extras.js - CPE CustomModels and CustomParticles helpers

Built-in Plugins:

  • plugins/core-essentials/ - Basic commands (spawn, teleport, models, AFK, etc.)
  • plugins/core-building/ - Drawing tools (cuboid, sphere, line, undo/redo, block history)
  • plugins/core-moderation/ - Ranks, kicks, bans, mutes, anti-spam
  • plugins/core-worlds/ - Level management (create, load, environment customization)
  • plugins/core-blocks/ - Custom block definitions
  • plugins/physics/ - Block physics (sand/gravel falling, water/lava flow)
  • plugins/warps/ - Teleport points and homes
  • plugins/zones/ - Protected building areas
  • plugins/portals/ - Portals and message blocks
  • plugins/bots/ - NPC bots with AI
  • plugins/economy/ - Money system with shop
  • plugins/announcer/ - Periodic announcements
  • plugins/effects/ - Particle effects and cinematic bars
  • plugins/custom-models/ - Custom 3D models
  • plugins/minigames/ - Parkour, TNT Wars, CTF, Zombie Survival
  • plugins/relay-irc/ - IRC chat bridge
  • `plugins/relay

https://claude.ai/code/session_01NCzvaK6Q28R8Xtq7FGpGvo

The old workflow deployed every push of any branch to an FTP host.
It now runs npm ci, lint and tests on Node 20 and 22.
- Own packet codec (sizes verified against the ClassiCube client) with 30 CPE
  extensions: CustomBlocks, BlockDefinitions(Ext), BulkBlockUpdate, FastMap,
  EnvColors, EnvMapAspect, ExtPlayerList v2, HeldBlock, SelectionCuboid, ...
- WebSocket support on the same port for the web client
- Multiple levels in ClassicWorld (.cw) format, MCGalaxy .lvl and legacy
  level.dat import, world generators, autosave and backups
- Ranks, block permissions, player database, name verification, heartbeat
- Command manager and plugin manager with hot load/unload/reload
- Fixes old bugs: everyone was op, /kick crash, map sent before auth checks,
  entity id overflow, missing CPE negotiation
- No runtime dependencies; node:test unit and integration tests
core-essentials, core-moderation, core-worlds, core-building, core-blocks,
warps, zones, portals, bots, announcer, relay-irc, relay-discord and a
documented example plugin.
- Per-connection packet sizes: block ids up to 767 (two-array map transfer,
  BulkBlockUpdate high bits) and 32-bit entity coordinates for levels
  bigger than 1023 blocks; levels are stored with BlockArray2 like ClassiCube
- Fix SetInventoryOrder field order (block, then order)
- Optional SQLite player database (node:sqlite) that imports players.json
- /sudo to run a command as another player
- Verified against a real ClassiCube 1.3.8 client built from source
- /pinstall installs a plugin from a URL (GitHub links supported) or an npm
  package (without running install scripts); /puninstall moves it aside
- physics: falling sand/gravel, flowing water and lava, sponges, stone from
  water + lava, and on level 2 grass growth and TNT chain explosions
- Block changes are logged to disk per level: /about and the new
  /undoplayer keep working after a restart
- economy plugin: /money, /pay, /baltop, /eco, /shop and /buy (ranks,
  titles, colors and personal levels)
- Levels can have owners who can always build (/map owner)
- web-panel plugin (disabled by default): token protected browser panel
  with players, levels, live log and console
- Parkour (start, checkpoints, finish, timer, records), TNT Wars,
  Capture the Flag and Zombie Survival with rounds, teams, scoreboard,
  economy rewards and arena restore
- New blockPermission event lets plugins override block permissions
- Temporary model changes (setModel(model, false))
…fyAction and ToggleBlockList

- Protocol support (float fields, 8 new packets) and player/server APIs:
  defineModel, defineParticle/spawnParticles, setCinematic,
  sendPluginMessage, toggleBlockList; pluginMessage and notifyAction events
- effects plugin: particle presets, /effect, /cinematic, /blocklist
- custom-models plugin: example models (cube, spinner, bighead) and
  JSON models from config/plugins/custom-models
- Verified in a real ClassiCube client
- /write draws text with blocks using a built-in 5x7 font
- README and docs/PLUGINS.md cover the new plugins, events and APIs
Players: /back /ascend /descend /tpa /kill /clear /roll /8ball /hug /high5
/faq /news /view /top /search /blocks /pclients /whonick /tcolor /send
/inbox /loginmessage /logoutmessage /emotes /ccols /modelscale /entityrot
/lastcmd, plus (emote) replacements in chat.

Moderation: /warn /xban /temprank /report /whitelist /moveall /moderate
/voice /opchat /adminchat (# and + prefixes) /rankmsg /baninfo /banedit
/follow /p2p /patrol /rankinfo /playeredit /limit /oprules.

Levels: /copylvl /renamelvl /resizelvl /lockdown /reload /fixgrass /unflood.

Building: /hollow /outline /pyramid /tree /torus /spheroid /maze /rainbow
/drill /center /mirror /spin /mark /bind /mode /calculate.

Other: /plugin, /restart, /give, /take, /explode, /slap.
@perronosaurio
perronosaurio force-pushed the claude/fervent-keller-38r7qx branch from 5324b36 to 2a148ba Compare September 29, 2026 19:26
- Drop Node 20 (end of life); CI now runs on Node 22, 24 and 26 with
  current actions, read-only permissions and npm audit. Add Dependabot.
- Keep player names and plugin data keys such as __proto__ from
  polluting object prototypes.
- Limit connections per IP, cap WebSocket messages at 64 KB and reject
  unmasked frames. An exception in a packet handler kicks that player
  instead of stopping the server; async event handler errors are logged.
- Send heartbeats whenever verifyNames is on, so name verification also
  works on servers that are not public.
- /pinstall: HTTPS only (except localhost), stop reading after 2 MB,
  validate npm package specs and plugin names.
- New installs no longer make the original authors owners or list the
  server publicly by default.
Rewrite the README with install, hosting, updating and troubleshooting
guides.
The old server in src/ and client.js has not been used since the rewrite.
levels/level.dat made every fresh install start on the 2019 map; an old
level.dat copied in by hand is still converted on the first start.
Also trim .gitignore to what the project creates and add .editorconfig
and .gitattributes.
/pdisable and /penable (also /plugin disable|enable) unload or load a
plugin and store the choice in disabledPlugins, so it holds after a
restart. /plugins shows which ones are off.

The web panel now follows the ClassiCube forum layout: banner, breadcrumb
bar, category blocks with alternating rows and a statistics footer. Its
plugin list shows every plugin on disk with a Turn on / Turn off link.
Pushing a v* tag runs the tests and creates a release with a zip and a
tar.gz and the matching CHANGELOG section as notes (docs/RELEASING.md).
The server asks GitHub for the latest release when it starts and says so
in the console if there is a newer one (checkForUpdates).

Add issue and pull request templates.
It only printed an 'old plugin format' warning on every start.
The bundled level.dat is gone, so the test was always skipped.
@perronosaurio
perronosaurio deleted the claude/fervent-keller-38r7qx branch September 29, 2026 19:54

Copy link
Copy Markdown
Owner Author

Closing in favour of #61, which has the same commits on the revival-2026 branch.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant