新增与修复
- 新增菜单文本交互功能:
- 鼠标悬停文本样式。
- 鼠标悬停光标样式。
- 点击菜单元素时播放动画图标。
- 支持通过 MiniMessage 向玩家发送聊天消息。
- 可根据玩家权限显示不同的菜单文本样式。
- 新增内置 CMP 教程文档,支持中文、英文和俄文切换。
- OP 玩家可使用 /cmenu tutorial 在聊天框中获取教程链接。
如果教程无法打开,请在配置文件中重新设置 URL,例如:
也可以直接打开插件文件夹中的 CMP.html。- 新增教程 HTTP 服务的端口、绑定地址和公网 URL 配置。
- 支持通过重载命令重新读取教程配置并重启教程 HTTP 服务。
- 修复教程 HTML 被 Maven 资源过滤错误改写 JavaScript 模板的问题。
- 教程链接改用插件内置 HTTP 服务,不再向 Paper 26.1 发送不受支持的 file: 点击链接。
菜单切换与光标修复
- 修复执行 next-menu 后,菜单悬停和点击可能失效的问题。
- 修复旧菜单的延迟清理任务可能错误移除新菜单状态的问题。
- 为菜单延迟生成和清理任务增加菜单键与会话状态校验,防止旧任务覆盖或清理新菜单。
- 修复菜单切换后光标可能停止移动或位置错误的问题。
- 光标更新现在直接使用 currentPlayerMenus 中记录的当前活动菜单,不再通过摄像机所在世界猜测菜单。
- 光标位置现在根据菜单摄像机的 cameraYaw 和 cameraPitch 计算相对旋转,不再直接使用玩家的绝对视角。
- 新增 PlayerMoveEvent 光标刷新兜底,在 Paper 26.1.2 未正常收到部分旋转更新时继续刷新光标。
- 启用同摄像机菜单刷新路径;当新旧菜单摄像机位置相同时,只替换菜单内容,不重新创建摄像机。
- 使用同摄像机刷新前,会检查旧摄像机是否存在、实体是否有效,以及玩家是否仍然乘坐该摄像机。
- 修复同时启用 next-menu 和 stop-menu.enabled 时,旧逻辑提前移除摄像机造成的黑屏和闪屏。
- next-menu 切换现在会尽可能保留原摄像机,仅替换菜单文本、物品和交互内容,实现无缝菜单切换。
修复
新增功能
- 统一修复 PAPI 变量问题:即使玩家未处于菜单模式,变量仍输出内容的问题已解决
- 菜单按钮新增悬停交互命令
- hover-enter-command – 光标悬停到按钮上时执行
- hover-leave-command – 光标离开按钮时执行
代码:# 悬停触发命令(光标悬停时自动执行) # hover-commands: # - '[player] say 光标悬停在logo上' # - '[console] title %player% actionbar "&a欢迎查看Logo"' # 离开触发命令(光标离开时自动执行) # leave-commands: # - '[player] say 光标离开了logo'- 兼容 CraftEngine 插件的图片使用
菜单动画效果 – 为按钮添加动态视觉效果
支持三种动画类型:
up-down – 上下浮动
left-right – 左右浮动
rotate – 旋转
可自由调节动画速度与幅度
代码:name: "你的按钮文字" x: 0 y: 0 z: 3 # ⬇ 浮动动画配置 floating-animation: enabled: true # 是否启用(必填) type: "up-down" # 动画类型(必填) speed: 1.5 # 动画速度,越大越快(可选,默认 1.0) amplitude: 0.3 # 动画幅度,越大摆动越明显(可选,默认 0.25)
Paper 26.1 兼容性
- 左键点击:修复了在 26.1 版本中左键点击菜单文本无法执行命令的问题。左键挥动事件现在可正常触发。
性能优化
- 内置 SQLite 驱动:将 sqlite-jdbc 直接打包到插件中,防止因服务器环境下载问题导致的加载失败。
- 语言文件缓存:getLangMessage 现已使用缓存读取,减少频繁 IO 操作带来的性能开销。
- 数据库线程安全:为 DatabaseManager 关键方法增加同步控制,降低 SQLite 并发访问风险。
- 状态清理增强:加强玩家退出、被踢、重载及异常场景下的菜单状态清理,降低内存泄漏风险。
修复
新增功能
- 修复菜单文本与光标悬停/点击检测范围不一致的问题(当调整 text-size 和光标 scale 时)
优化
- 光标移动灵敏度配置 sensitivity(1.0 为默认,数值越小移动越慢)
- 光标平滑系数配置 smoothing(0.05-1.0,1.0=无滤波零延迟,越小越丝滑但会有拖手感)
- 文本大小支持无限放大或缩小
- 修复若干已知性能报错
代码:version: "1.4.4" # 不要修改 Debug: false # 是否开启南瓜头 use-pumpkin-overlay: false # 是否以玩家当前所在位置/朝向作为菜单相机坐标 # true -> 忽略菜单 yml 里的 camera-position,用玩家当前脚下 # false -> 使用菜单 yml 里写死的坐标(原有逻辑) use-player-location: false # 是否设置自定义的玩家结束菜单的朝向 exit-camera: yaw: 0.0 pitch: 0.0 # 生物生成限制配置 creature-spawn-limits: enabled: false # 是否启用生物生成限制 radius: 10 # 以菜单为中心的禁止生物生成的半径(方块) # 摄像机视角方块检测配置 camera-block-check: enabled: true radius: 1 # 以玩家为中心的检测半径(方块) # 按钮访问控制配置 button-access-control: # 需要登录才能点击的按钮标识配置 login-required: # 在按钮名称中包含的标识文本 name-tags: - "[需要登录]" - "%img_logo%" # 在按钮键名中包含的标识文本 key-tags: - "login_required" - "%img_logo%" # 防止重复注册的按钮标识配置 no-duplicate-registration: # 在按钮名称中包含的标识文本 name-tags: - "%img_logo%" - "[NO_DUPLICATE_REG]" # 在按钮键名中包含的标识文本 key-tags: - "no_duplicate_reg" - "防止重复注册" # IP绑定安全配置 ip-binding: # 是否启用IP绑定(同一IP只能注册一个账号) enabled: true # 是否严格模式:IP不匹配时直接拒绝登录 # false -> IP不匹配时发出警告但仍允许登录 # true -> IP不匹配时直接拒绝登录 strict: false # 是否允许同一IP的用户登录已注册的账号 allow-same-ip-login: true # 锁定时间(分钟):密码错误多次后锁定 lockout-duration: 5 # 最大登录尝试次数 max-login-attempts: 5 # IP白名单配置 whitelist: # 是否启用IP白名单 enabled: false # 白名单IP列表(支持CIDR格式,如 192.168.1.0/24) ips: [] # - "192.168.1.1" # - "10.0.0.0/8" # IP黑名单配置 blacklist: # 是否启用IP黑名单 enabled: false # 黑名单IP列表(支持CIDR格式,如 192.168.1.0/24) ips: [] # - "192.168.1.100" # - "10.0.0.50" # 管理员IP白名单配置(仅对OP玩家生效) admin-ip-whitelist: # 是否启用管理员IP白名单 enabled: false # 允许登录的IP列表(支持CIDR格式,如 192.168.1.0/24) ips: [] # - "192.168.1.1" # - "10.0.0.0/8" messages: prefix: '&f[&eCustomScreenMenu&f] ' command_blocked: '&c固定视角下无法使用命令!' sound: name: 'music.menu' volume: 1 pitch: 1 # 循环音效 loop: # 是否开启 enabled: true # 每隔多少秒播放一次 duration: 30 # 加入游戏就执行菜单 join-run: enabled: false # 延迟多少秒执行 delay: 3 # 执行的菜单 menu: 'test' commands: - "[console] say 欢迎玩家 %player% 加入游戏!" - "[player] msg %player% 欢迎来到服务器!" - "[op] gamemode survival %player%" cursor-item: material: 'ARROW' custom-model-data: 0 scale: 0.5 # 光标移动灵敏度 (1.0 为默认,数值越小移动越慢) sensitivity: 1.0 # 光标平滑系数 (0.05-1.0,1.0=无滤波零延迟;越小越丝滑但会有拖手感) smoothing: 1.0 # 自定义光标大小 size: x: 1.0 y: 1.0 z: 1.0 # 最大3个X轴 已经为屏幕横向可容纳最大 max-x: 2 # 最大1.5个Y轴 已经为屏幕纵向可容纳最大 max-y: 3 x: 0.0 # X轴偏移 y: 0.0 # Y轴偏移 z-offset: 0.0 # 光标Z轴偏移量 # 光标移动范围限制 movement-range: # 启用自定义光标移动范围限制 enabled: false # 光标在X轴上的最小和最大位置 x: min: -2.0 max: 2.0 # 光标在Y轴上的最小和最大位置 y: min: -3.0 max: 3.0 # 光标默认位置 default-position: # 启用自定义光标默认位置 enabled: false # 光标默认的X和Y坐标 x: 0.0 y: 0.0
[MD] 打字机效果 – 为文本元素添加逐字显示动画 可配置显示速度(字符间隔) 可配置开始延迟(动画开始前等待tick数) 可配置光标字符(文本末尾闪烁光标) 支持热重载,通过 /cmenu reload 生效 悬停音效 – 鼠标悬停文本元素时播放音效 可配置音效名称(支持所有Minecraft音效) 可配置音量和音调 可配置冷却时间(防止音效过于频繁) 无效音效配置时自动回退备用音效 🔧 修复 修复 config.yml 中 join-run 命令占位符不替换问题 无论是否安装 PlaceholderAPI,内置占位符均正确替换 支持: %player% 、 %player_name% 、 %player_uuid% 、 %player_displayname% 、 %player_x% 、 %player_y% 、 %player_z% 、 %player_world% 、 %player_health% 等 ⚡ 优化 线程安全: HoverEnlargeManager 中 HashMap 替换为 ConcurrentHashMap 内存优化: CursorMenuPlugin.getPlayerTextDisplays() 使用 Collections.emptyList() 稳定性: TypewriterEffect 添加 completed 标志防止重复清理 [/MD]
新增功能
全消息自定义 – 所有提示消息现可在 lang.yml 中自由配置
支持热重载,修改后 /cursormenu reload 即可生效
新增 50+ 条可配置消息
分类涵盖:登录、注册、权限、命令、玩家管理、菜单、系统、NPC、WASD 导航
YAML:# ======================================== # CursorMenu 提示信息配置文件 # 该文件包含插件所有的提示信息配置 # 支持热加载,修改后使用 /cursormenu reload 即可生效 # ======================================== # ======================================== # 登录相关提示 # ======================================== login: success: '&a[CursorMenu] 登录成功!' wrong_password: '&c[CursorMenu] 密码错误' empty_password: '&c[CursorMenu] 密码不能为空' user_not_found: '&c[CursorMenu] 用户不存在' locked: '&c[CursorMenu] 账户已被锁定,请稍后再试' too_many_attempts: '&c[CursorMenu] 登录尝试次数过多,请稍后再试' # ======================================== # 注册相关提示 # ======================================== register: success: '&a[CursorMenu] 用户 %player_name% 注册成功!' failed: '&c[CursorMenu] 注册失败,请稍后重试' password_mismatch: '&c[CursorMenu] 两次输入的密码不一致' invalid_password_length: '&c[CursorMenu] 密码长度必须在6-12位之间' weak_password: '&c[CursorMenu] 密码过于简单,请使用更复杂的密码' user_exists: '&c[CursorMenu] 该账户已注册' empty_password: '&c[CursorMenu] 密码不能为空' empty_confirm_password: '&c[CursorMenu] 确认密码不能为空' error: '&c[CursorMenu] 注册失败,请稍后重试' ip_blacklisted: '&c[CursorMenu] 您的IP地址已被禁止注册' ip_not_in_whitelist: '&c[CursorMenu] 您的IP地址不在允许注册的列表中' # ======================================== # 输入相关提示 # ======================================== input: field_set: '&a[CursorMenu] 当前输入字段已设置为: %field%' data_saved: '&a[CursorMenu] %field% 已设置为: %value%' incomplete: '&c[CursorMenu] 请先完成所有输入项' # ======================================== # 密码可见性相关提示 # ======================================== password: visibility_toggled: '&a[CursorMenu] 密码可见性已切换' visibility_shown: '&a[CursorMenu] 密码已显示' visibility_hidden: '&a[CursorMenu] 密码已隐藏' visibility_button_shown: '[密码:隐藏]' visibility_button_hidden: '[密码:显示]' # ======================================== # 权限相关提示 # ======================================== permission: no_permission: '&c[CursorMenu] 你没有权限使用该命令' no_permission_button: '&c[CursorMenu] 你没有权限执行该按钮' no_permission_menu: '&c[CursorMenu] 你没有权限打开该菜单' player_only: '&c[CursorMenu] 仅玩家可用' # ======================================== # 命令相关提示 # ======================================== command: unknown_argument: '&c[CursorMenu] 未知参数' reload: '&a[CursorMenu] 插件重载成功...' reload_complete: '&a[CursorMenu] 插件重载完成!' menu_not_found: '&c[CursorMenu] 菜单 ''%menu%'' 未找到,请检查配置文件!' menu_opened: '&a[CursorMenu] 已为玩家 %player% 打开菜单 %menu%' text_display_opened: '&a[CursorMenu] 已为玩家 %player% 打开文字显示: %text_id%' text_display_not_found: '&c[CursorMenu] 文字显示ID不存在: %text_id%' item_disabled: '&a[CursorMenu] 已关闭物品显示' item_not_found: '&c[CursorMenu] 物品ID不存在: %item_id%' input_menu_hint: '&c[CursorMenu] 输入对应的菜单选项' menu_option_not_found: '&c[CursorMenu] 无该菜单选项' # ======================================== # 玩家管理相关提示 # ======================================== player: not_found: '&c[CursorMenu] 玩家 %player% 不存在或不在线' not_registered: '&c[CursorMenu] 玩家 %player% 不存在于注册列表中' delete_success: '&a[CursorMenu] 玩家 %player% 的注册信息已成功删除,该玩家现在可以重新注册' delete_failed: '&c[CursorMenu] 删除玩家 %player% 的注册信息失败' delete_notify: '&e[CursorMenu] 您的注册信息已被管理员删除,请重新注册' reset_password_success: '&a[CursorMenu] 玩家 %player% 的密码已成功重置' reset_password_failed: '&c[CursorMenu] 重置玩家 %player% 的密码失败' reset_password_notify: '&e[CursorMenu] 您的密码已被管理员重置,请重新登录' # ======================================== # 菜单相关提示 # ======================================== menu: require_login: '&c[CursorMenu] 请先登录后再执行此操作' already_registered: '&c[CursorMenu] 您已注册,请直接登录' condition_not_met: '&c[CursorMenu] 条件不满足,无法执行该操作' cursor_activated: '&a[CursorMenu] 光标菜单已激活!' cursor_deactivated: '&c[CursorMenu] 光标菜单已关闭!' # ======================================== # 系统相关提示 # ======================================== system: ip_warning: '&e[警告] 您的IP与注册时不同!' server_transfer_failed: '&c[CursorMenu] 跨服传送失败: %error%' config_reloaded: '&a[CursorMenu] 配置文件已重新加载' # ======================================== # NPC相关提示 # ======================================== npc: toggle_on: '&a[CursorMenu] NPC创建已启用' toggle_off: '&c[CursorMenu] NPC创建已禁用' status_enabled: '&a[CursorMenu] NPC创建状态: 已启用' status_disabled: '&c[CursorMenu] NPC创建状态: 已禁用' reloaded: '&a[CursorMenu] NPC配置已重载' rotated: '&a[CursorMenu] NPC已旋转 %angle% 度' rotate_usage: '&c[CursorMenu] 用法: /cursormenu npc rotate <角度>' invalid_angle: '&c[CursorMenu] 无效的角度值: %angle%' system_disabled: '&e[CursorMenu] NPC镜像系统未启用(需要安装FancyNpcs插件)' # ======================================== # WASD导航相关提示 # ======================================== wasd: enabled: '&a[CursorMenu] WASD导航已启用' disabled: '&c[CursorMenu] WASD导航已禁用'
安全性更新:
并发安全修复:
- 密码哈希算法升级 - 从不安全的 SHA-256 升级到 BCrypt 加密算法。
- 新注册用户自动使用 BCrypt 加密,旧用户首次登录成功后自动升级密码格式。
- 临时 OP 操作安全性增强 - 改进了 [op] 命令执行的安全机制,确保 OP 状态正确恢复。
代码质量改进:
- 修复非线程安全集合 - 将所有 HashMap/HashSet 替换为线程安全的 ConcurrentHashMap,解决了多线程环境下可能出现的并发问题。
注意事项:
- 新增命令执行工具类 - 统一了命令执行逻辑,支持 [console] 、 [op] 、 [player] 、 [server] 等命令前缀。
- 代码清理 - 清理了重复的导入语句,简化了代码结构。
- 新增支持 1.21.11 版本
- BCrypt 计算比 SHA-256 慢,这是正常的安全特性,无需担心性能问题。
# 1.4.0
##新增功能 / New Features
### NPC镜像系统 / NPC Mirror System
- **新增NPC镜像模块** - 在3D菜单中创建玩家镜像NPC
- 自动同步玩家装备(头盔、胸甲、护腿、靴子、主手、副手)
- 支持SkinsRestorer皮肤同步
- 可配置NPC位置偏移和朝向
- 支持菜单关联配置,可指定哪些菜单启用NPC
- NPC名称支持自定义格式和PlaceholderAPI变量
- 玩家可单独禁用自己的NPC创建
### WASD导航系统 / WASD Navigation System
- **新增WASD导航模块** - 使用键盘导航菜单
- W/S 键上下选择菜单项
- A/D 键左右选择菜单项
- 空格键确认执行命令
- 与原有光标控制系统完全兼容,可同时使用
- 支持菜单关联配置
- 选择时自动放大选中项并播放音效
- 选择冷却机制防止快速连续选择
### PlaceholderAPI变量 / PlaceholderAPI Variables
- **新增WASD导航PAPI变量**
- `%cmp_wasd_menu%` - 当前WASD菜单名称
- `%cmp_wasd_enabled%` - 是否启用WASD导航
- `%cmp_wasd_index%` - 当前选中索引
- `%cmp_wasd_x%` - 当前X坐标
- `%cmp_wasd_y%` - 当前Y坐标
- `%cmp_wasd_z%` - 当前Z坐标
- `%cmp_wasd_location%` - 完整位置信息(格式:菜单名,x,y,z)
- `%cmp_<菜单名>_xyz%` - 指定菜单的坐标
### 新增配置文件 / New Configuration Files
- `npc_config.yml` - NPC镜像系统配置
- 启用/禁用NPC功能
- NPC位置偏移配置
- 菜单关联设置(白名单/黑名单模式)
- 名称显示配置(支持PAPI变量)
- 装备和皮肤同步开关
- `wasd_config.yml` - WASD导航系统配置
- 启用/禁用WASD导航
- 导航阈值配置
- 选择冷却时间
- 音效配置
- 菜单关联设置
- 新增 `wasd-enabled` 选项 - 单独控制每个菜单的WASD导航开关
### 新增软依赖 / New Soft Dependencies
- **FancyNpcs** (可选) - NPC镜像功能必需
- **SkinsRestorer** (可选) - NPC皮肤同步支持