Skip to content

Repository files navigation

MCProcessControl

面向 Paper 服务端的 Lua 活动流程控制插件

为大型庆典 / 活动流程设计的「脚本式」控制方案:每个 .lua 脚本就是一个完整的事件流程,可以按时间、按条件、按管理员手动指令自动执行控制台命令、喊话、传送、发物品等操作,管理员不再需要人工喊话和逐个传送玩家。

特性

  • 内置 Lua 解释器:集成 luaj,随插件打包(已重定位,不污染服务器类路径),开箱即用。
  • 脚本式流程控制:一个脚本 = 一个活动流程,可随时 /flow start / /flow stop 启停。
  • 四种触发方式
    1. 控制台命令 —— 脚本内直接执行服务器控制台级命令。
    2. 时间触发 —— 每天定点 / 指定日期单次 / 游戏内时间。
    3. 条件触发 —— 周期性检查自定义条件,满足时执行(一次性或边沿触发)。
    4. 手动触发 —— 管理员 /flow fire 手动触发脚本内注册的触发点。
  • 自动运维:全服广播 / Title / ActionBar / 音效 / 集体传送 / 集体发物品。
  • 可靠错误处理:定时任务出错自动取消防止刷屏;命令触发出错即时反馈给执行者。
  • 权限组mcprocesscontrol.admin 权限组及细化子权限。

环境要求

  • Paper 26.2+(api-version: 26.2
  • Java 25+

构建

gradle shadowJar
# 产物:build/libs/MCProcessControl-1.0.0.jar

安装

  1. build/libs/MCProcessControl-1.0.0.jar 放入服务器的 plugins/ 目录。
  2. 启动服务器。首次启动会自动生成示例脚本 plugins/MCProcessControl/scripts/example.lua
  3. 编辑脚本,执行 /flow reload 生效。

命令

命令 说明
/flow reload 重载全部脚本(有错误会逐个列出)
/flow list 列出已加载脚本及其触发点
/flow start <脚本> 启动指定脚本
/flow stop <脚本> 停止指定脚本(取消其所有定时任务)
/flow fire <脚本> <触发点> 手动触发脚本内的触发点

权限

权限节点 说明 默认
mcprocesscontrol.admin 管理员权限组,包含以下全部子权限 op
mcprocesscontrol.reload 重载脚本 op
mcprocesscontrol.list 查看脚本列表 op
mcprocesscontrol.start 启动脚本 op
mcprocesscontrol.stop 停止脚本 op
mcprocesscontrol.fire 手动触发触发点 op

控制台不受权限限制;玩家拥有 mcprocesscontrol.admin 或对应子权限即可执行对应子命令。

Lua API

脚本内通过全局对象 flow 调用所有接口。每个脚本必须定义 main() 函数,插件加载脚本时会执行它(在其中注册触发点、定时任务等)。

function main()
  -- 在这里注册触发点、定时任务、条件检测
end

控制台命令 / 消息

方法 说明
flow.command(cmd) 以控制台身份执行服务器命令(flow.console 为别名)
flow.broadcast(msg) 全服广播消息
flow.tellraw(json) 按 Minecraft tellraw JSON 格式向全服发送富文本消息(支持颜色 / 加粗 / 点击 / 悬浮等,支持对象或数组)
flow.title(title, subtitle) 全服发送 Title
flow.actionbar(msg) 全服发送 ActionBar
flow.sound(name) 全服播放音效(如 entity_firework_rocket_launch
flow.log(msg) 输出到服务器控制台日志

时间调度

方法 说明
flow.after(ticks, fn) 延迟 ticks(20 tick = 1 秒)后执行一次,返回任务 id
flow.every(ticks, fn) ticks 重复执行,返回任务 id
flow.at("HH:MM", fn) 每天该时刻执行一次
flow.atOnce("yyyy-MM-dd HH:mm", fn) 指定日期时间单次执行
flow.atMinecraft(hour, fn) 游戏内时间(Minecraft 时,0-23)执行一次
flow.cancel(id) 取消任务
flow.cancelAll() 取消本脚本全部任务

条件触发

方法 说明
flow.when(condFn, checkTicks, actionFn) checkTicks 检查一次 condFn,为真时执行 actionFn 一次并自动取消
flow.whenever(condFn, checkTicks, actionFn) 边沿触发:条件由假变真时执行 actionFn

手动触发

方法 说明
flow.trigger(name, fn) 注册触发点,管理员用 /flow fire <脚本> <name> 触发
flow.fire(name) 脚本内触发另一个触发点

玩家 / 服务器查询

方法 说明
flow.onlineCount() 在线玩家数
flow.players() 在线玩家名数组(可用 ipairs 遍历)
flow.player(name) 获取玩家对象(见下)

批量玩家操作

方法 说明
flow.teleportAll(world, x, y, z) 传送所有在线玩家到指定坐标
flow.giveAll(material, count) 给所有在线玩家发放物品(如 firework_rocket

玩家对象 flow.player(name) 返回

方法 说明
p.name() 玩家名
p.online() 是否在线
p.send(msg) 向该玩家发送消息
p.teleport(world, x, y, z) 传送该玩家
p.execute(cmd) 以该玩家身份执行命令
p.x() / p.y() / p.z() / p.world() 坐标与世界,离线时返回 nil

完整示例

function main()
  -- 手动触发点:/flow fire example start
  flow.trigger("start", function()
    flow.broadcast("§6活动正式开始!")
    flow.title("活动开始", "§a欢迎参加")
    flow.sound("entity_firework_rocket_launch")
    flow.teleportAll("world", 0, 64, 0)
    flow.giveAll("firework_rocket", 10)
  end)

  -- 倒计时 10 秒后自动开始(注意 local 声明与赋值要分行,见注意事项)
  flow.trigger("countdown", function()
    local n = 10
    local task
    task = flow.every(20, function()
      n = n - 1
      flow.actionbar("§e活动将在 §b" .. n .. " §e秒后开始")
      if n <= 0 then
        flow.cancel(task)
        flow.fire("start")
      end
    end)
  end)

  -- 每天晚上 19:00 自动开始倒计时
  flow.at("19:00", function()
    flow.fire("countdown")
  end)

  -- 在线人数达到 20 人时提醒一次
  flow.when(function()
    return flow.onlineCount() >= 20
  end, 40, function()
    flow.broadcast("§e在线人数已达 20 人!")
  end)

  -- VIP 玩家上线时提醒(边沿触发)
  flow.whenever(function()
    return flow.player("Starset_").online()
  end, 20, function()
    flow.broadcast("§bVIP 玩家上线了!")
  end)

  -- tellraw 富文本广播(可点击跳转官网)
  flow.trigger("announce", function()
    flow.tellraw('{"text":"点击进入官网","color":"aqua","bold":true,"clickEvent":{"action":"open_url","value":"https://example.com"}}')
  end)
end

注意事项

  • 脚本位置plugins/MCProcessControl/scripts/*.lua,改完执行 /flow reload
  • luaj upvalue 陷阱:闭包引用局部变量时,local x 的声明与赋值必须分行写,否则闭包内读到 nil
    local task           -- 先声明
    task = flow.every(20, function() ... flow.cancel(task) ... end)   -- 再赋值
  • 错误处理:定时 / 条件任务内部出错会自动取消该任务并写控制台日志;/flow fire 触发出错会把错误消息直接反馈给执行者。
  • 线程模型:所有 Lua 回调均在服务器主线程串行执行,无需担心并发问题,但请勿在回调中执行阻塞操作。
  • 世界名flow.teleportAll / flow.player(...):teleport 中的世界名请使用真实世界名称(如默认主世界 world)。

许可

本项目基于 GNU General Public License v3 发布,详见 LICENSE

About

通过严格的Lua脚本控制Minecraft活动流程。

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages