跳到主要内容

为什么用云公会

公会插件看起来就是「建公会、拉人、存钱」,难的是那些多人同时操作的时候:两个副会长同时提领,资金会不会变成负数?公会只剩一个空位,两个人同时点加入会不会超员? 两个子服上的成员同时打开仓库,物品会不会复制?下面逐项说明云公会怎么处理这些情况。

重点一览​

需求CloudGuild 云公会
扣公会资金一条 UPDATE … SET funds = funds - ? WHERE id = ? AND funds >= ?,不够就影响 0 行、直接失败,不会变成负数
人数上限人数检查写在加人的同一条条件更新里;成员表以玩家 UUID 为主键,一个玩家不可能同时在两个公会
跨服只用 MySQL:变动写进事件表,其他子服每秒读取一次,不需要 Redis、也不需要在代理端安装插件
主线程所有数据库操作都在独立线程池;变量、伤害判断只读内存缓存
公会聊天 / 任务 / 增益全部内置,增益直接使用原版药水与原版属性
职位职位数量、权重、人数上限、每项权限都能在 config.yml 自定义
共享仓库每一页同一时间只有一个人能打开,所有子服共用一把锁

每一笔资金、每一个名额都由数据库一步判定​

云公会里所有「会扣东西」或「有上限」的操作,都是一条带条件的更新或一个数据库事务,影响 0 行就是失败,不会先读再写:

操作在同一步里检查的条件
提领、改名、发公告、升级增益、宣战公会资金 ≥ 花费
升级公会目前等级没变、资金 ≥ 花费、活跃 ≥ 需求、成员数 ≥ 需求
加入公会(申请通过、邀请、直接加入)公会还存在、玩家还没有公会、成员数 < 上限
升职 / 降职 / 指定职位对方的职位没有被别人先改掉、新职位的人数没满
商店购买贡献 ≥ 价格、本期购买次数 < 限购(同一个事务,任一项不满足整笔还原)
存钱存钱的人还是这个公会的成员(不是的话,扣掉的钱退回)
审核申请两位管理同时点「同意」,只有一位拿得到这份申请
每日签到同一天只会成功一次,跨服也一样

MySQL 在多个子服同时写入时偶尔会回报死锁,云公会会自动把整个事务重做(最多 5 次),玩家只会看到成功或失败,不会看到一半的结果。

只要 MySQL 就能跨服​

多个子服连同一个数据库,sync.enabled: auto 就会自动开启跨服同步:

  • 每个变动(公会资料、成员、聊天、同盟、增益、战争、公告、提示消息)写进数据库的事件表,其他子服每 sync.interval-ticks(默认 20 tick = 1 秒)读取一次。
  • 玩家不在线时变动也不会漏掉:上线时直接从数据库读取最新资料;另外每 60 秒整批刷新一次缓存。
  • 不需要 Redis,也不需要 BungeeCord 插件消息频道(只有「跨服回据点」时用代理端的 Connect 把玩家送过去)。
  • 每日结算(维护费与活跃衰减)、任务奖励、公会战开战与结算公告,都由第一个抢到的子服执行一次,不会重复。

详见 跨服设置。

不占主线程​

  • 所有 SQL 都在插件自己的数据库线程池执行,结果再回到玩家所在的线程处理(Folia 使用对应的区域调度器)。
  • 全部公会、在线成员、同盟关系、增益与进行中的战争都放在内存缓存里,PlaceholderAPI 变量只读缓存;排行榜的排序结果额外缓存 5 秒,计分板每秒读很多次排行变量也没有负担。
  • 任务进度先在内存里累积,每 5 秒用一个事务写入一次,挖矿、打怪这种高频事件不会每次都写数据库。
  • 需要读数据库的菜单(成员列表、银行记录、任务进度……)先在后台载入,再在玩家的线程画出来。

功能全部内置​

功能云公会的做法
公会聊天/cg c 公会频道、/cg ac 同盟频道、聊天开头打 # 直接发到公会,跨服即时;管理员可以监听,见 聊天与公告
公会任务击杀、挖掘、放置、钓鱼、存钱、签到、在线 7 种类型,每日 / 每周重置,全员累积、只发一次奖励,见 公会任务
公会增益原版药水效果(无限时间)与原版属性修饰(最大生命、攻击伤害……),不需要 AttributePlus 之类的属性插件,见 公会增益
公会商店用个人贡献兑换物品或执行指令,可以限购;管理员手拿物品一条指令上架,见 公会商店
公会仓库每页一把全服共用的锁,见 公会仓库
公会据点依等级可以有好几个据点,跨服传送,见 公会据点
公会战宣战 → 准备时间 → 开战计分 → 自动结算,见 同盟、敌对与公会战

增益给过哪些效果会记在玩家身上,离开公会、重开服务器后都能正确移除,不会误删信标或药水等其他来源的效果。

自定义职位,每项权限分开设​

职位写在 config.yml 的 ranks:名称、权重、人数上限、权限清单都能改,想要「财务」「外交官」这种只开放部分权限的职位,加一段就好。 权限共有 16 项(邀请、审核、踢人、升职、降职、公告、据点、升级、设定、外交、宣战、增益、提领、仓库、商店、任务),见 职位与等级。

  • 只能管理权重比自己低的成员。
  • 两位管理同时改同一个人的职位时,只有一位会成功,另一位提示「资料刚被其他人修改了」。

共享仓库不会复制物品​

公会仓库的每一页,同一时间只有一位成员能打开,这把锁放在数据库里,所有子服共用:

  • 别人(包括别的子服上的人)正在用这一页时,提示「這頁倉庫有其他成員正在使用(可能在其他子服)」。
  • 每次打开都用新的锁代号,连点或关掉马上再开,也拿不到还没存回的那一把锁。
  • 打开期间每 20 秒延长一次锁;子服当机时锁 60 秒后自动失效,重开时也会放掉自己留下的锁。
  • 锁已经失效(例如数据库中断太久,锁过期后被别人拿走)时,仓库会被关闭、这次的变更不会写入,避免盖掉别人的变更;这次放进去的物品退还给玩家,不会凭空消失。

玩家文字不能夹带指令​

申请留言、公告、公会介绍、公会聊天这些玩家自己输入的文字,< > \ 一律换成全角字符,玩家写不出 MiniMessage 的点击、悬停标签,无法伪造「点一下就执行指令」的消息。见 玩家文字的安全处理。

宣战制公会战​

公会战不是「随时可以互砍」,而是有明确的开始与结束:宣战(扣公会资金)→ 准备时间 → 开战(双方成员互相击杀计分,任何子服都算)→ 时间到自动结算。 胜方得到奖励资金、活跃,并从败方资金抢走一定百分比;平手不发奖励。不能对同盟宣战,同一对公会之间有宣战冷却。见 同盟、敌对与公会战。

云界面画面​

装了 云界面 CloudUI 时,/cg 打开全屏的公会主页:左边是公会资讯与升级进度,中间是成员名册,右边是签到、银行、商店、任务等功能按钮。 签到、升级、切换聊天频道、回据点直接在画面上完成。见 云界面公会。