mirror of
https://github.com/SikongJueluo/kubejs-utils.git
synced 2025-11-18 19:37:50 +08:00
6.8 KiB
6.8 KiB
AreaControl 脚本 MDocs
1. 概述
AreaControl 是一个为 Minecraft 服务器设计的强大区域管理工具,通过 KubeJS 实现。它允许管理员在游戏世界中定义一个特殊区域,并对进入该区域的玩家施加特定的规则,例如自动切换游戏模式、限制物品使用等。
该脚本的核心设计理念是 高性能 与 易用性。它采用事件驱动和多种优化技术,确保在不牺牲服务器性能的前提下,提供稳定可靠的功能。本文档将为您提供从安装、使用到二次开发的全方位指南。
2. 功能特性
- 自动模式切换:玩家进入指定区域时,自动切换为冒险或旁观模式;离开时恢复为生存模式。
- 动态白名单:所有功能仅对白名单内的玩家生效,管理员可通过命令随时增删玩家。
- 物品冷却系统:可以为区域内的玩家设置统一的物品使用冷却时间。
- 实时启/禁用:管理员可通过一条简单命令,在不重启服务器的情况下,全局启用或禁用所有功能。
- 二维平面检测:区域检测仅基于水平坐标(X 和 Z 轴),忽略玩家的高度(Y 轴),适用于各种地形。
- 高性能设计:基于事件驱动,无不必要的循环(tick-polling),确保对服务器的性能影响降至最低。
- 配置持久化:所有配置(如区域中心、半径、白名单)都会自动保存,服务器重启后无需重新设置。
3. 用户指南
本节面向服务器管理员和普通用户,指导您如何安装和使用 AreaControl。
3.1. 安装
- 确保您的 Minecraft 服务器已经正确安装了 KubeJS Mod。
- 将编译后的
areacontrol.js脚本文件放置在服务器的kubejs/server_scripts/目录下。 - 重新启动服务器或在游戏内执行
/kubejs reload server_scripts。
脚本加载后将自动初始化,默认在世界中心 (0, 0) 创建一个半径为 50 格的区域。
3.2. 管理命令
您可以在游戏内通过 areacontrol 系列命令来管理脚本。所有命令都需要管理员权限。
/areacontrol status:查看脚本当前配置。/areacontrol toggle:全局启用或禁用功能。/areacontrol setcenter:将当前位置设为区域中心。/areacontrol setradius <半径>:设置区域半径。/areacontrol whitelist <add|remove|list> [玩家名]:管理白名单。
4. 开发者参考:技术与定制
本节面向希望理解其工作原理或进行二次开发的开发者。
4.1. 开发环境与构建
本项目使用 TypeScript 编写,以获得更强的类型安全和代码可维护性。
- 源码目录:所有服务器端脚本的 TypeScript 源文件位于
src/server_scripts/目录下。 - 编译:在发布或测试前,需要将 TypeScript (
.ts) 文件编译为 KubeJS 可识别的 JavaScript (.js) 文件。- 单次编译:执行
npm run tsc或npx tsc --project tsconfig.server.json。 - 监视模式:在开发过程中,建议使用监视模式,它会在文件发生变化时自动重新编译。执行
npm run watch::server即可。
- 单次编译:执行
- 类型定义:项目依赖于 KubeJS Probe 生成的类型定义,位于
types/probe-types/目录,这为开发提供了完整的代码提示和类型检查。
4.2. 设计理念
事件驱动架构
脚本不使用高开销的 tick 轮询,而是监听特定玩家事件来触发逻辑。
PlayerEvents.loggedIn: 玩家登录时加入检查。PlayerEvents.loggedOut: 玩家登出时清理其缓存数据。PlayerEvents.tick: 降频使用,每秒检查一次玩家位置。ItemEvents.use: 在玩家使用物品时触发冷却逻辑。
// 示例:利用类型定义,精确捕获事件和玩家对象
ItemEvents.use((event: Internal.ItemUseEvent) => {
const { player } = event;
if (player && shouldApplyCooldown(player)) {
// ...
}
});
分层与状态缓存
为避免不必要的操作,脚本采用分层检查和状态缓存。
- 一级过滤:检查脚本是否启用、玩家是否在白名单内。
- 二级检查(降频):每秒检查一次玩家是否在区域内。
- 三级处理(状态驱动):仅当玩家跨越区域边界时,才执行核心操作并更新缓存。
// playerStates 缓存玩家的当前状态,并提供类型安全
const playerStates = new Map<string, { inArea: boolean }>();
function optimizedPlayerCheck(player: Internal.Player): void {
const currentState = playerStates.get(player.uuid) ?? { inArea: false };
const isInArea = isPlayerInArea(player);
if (currentState.inArea !== isInArea) {
handleGameModeChange(player, isInArea);
playerStates.set(player.uuid, { inArea: isInArea });
}
}
4.3. 核心算法
快速边界检测
脚本通过预计算区域的边界框(Bounding Box)来实现高效的位置判断。
// 1. 初始化时预计算边界
function updateBounds(center: Internal.Vec3i, radius: number): void {
bounds.minX = center.x - radius;
bounds.maxX = center.x + radius;
bounds.minZ = center.z - radius;
bounds.maxZ = center.z + radius;
}
// 2. 运行时进行高效比较
function isPlayerInArea(player: Internal.Player): boolean {
const pos = player.blockPosition();
return pos.x >= bounds.minX && pos.x <= bounds.maxX &&
pos.z >= bounds.minZ && pos.z <= bounds.maxZ;
}
内存自动清理
通过监听 PlayerEvents.loggedOut 事件,自动从 playerStates 缓存中删除下线玩家的数据,防止内存泄漏。
4.4. 数据结构
我们使用 TypeScript 的 interface 来定义核心数据结构,确保类型安全。
配置 (AreaControlConfig)
interface AreaControlConfig {
enabled: boolean;
center: { x: number; y: number; z: number };
radius: number;
whitelist: string[];
mode: 'adventure' | 'spectator';
cooldownTime: number; // In ticks
}
缓存 (PlayerState)
interface PlayerState {
inArea: boolean;
}
// 最终的缓存结构
const playerStates: Map<string, PlayerState>; // Key: Player UUID
4.5. 定制化
调整检查频率
默认检查频率是每秒一次(20 ticks)。您可以根据服务器需求调整此值。
// 在 PlayerEvents.tick 监听器中调整
PlayerEvents.tick((event: Internal.PlayerTickEvent) => {
const player = event.player;
// 将 20 修改为您希望的检查间隔(ticks)
if (player.age % 20 === 0) {
optimizedPlayerCheck(player);
}
});
- 建议值:
10(半秒一次,响应快),40(两秒一次,开销低)。不建议低于10。