跳到主要内容

开发者 API

其他插件可以通过 CloudGuildAPI 查询玩家的公会、增减公会资金与成员贡献,或监听公会事件(例如接违禁词、发成就、给奖励)。

所有类都在 dev.cloudplugins.guild.api 包里:

类用途
CloudGuildAPI入口:查询、增减数值、打开公会主页
GuildInfo一个公会的唯读快照
GuildCreateEvent 等 8 个事件见下方 事件

引入​

把云公会的 jar 加进编译依赖(只在编译时使用,不要打包进你的插件),例如 Gradle:

dependencies {
compileOnly files('libs/CloudGuild.jar') // 资源中心下载的云公会 jar
}

plugin.yml 加上软依赖,确保云公会先载入(没装也能正常启动):

softdepend: [CloudGuild]

快速开始​

import dev.cloudplugins.guild.api.CloudGuildAPI;
import dev.cloudplugins.guild.api.GuildInfo;

if (CloudGuildAPI.available()) {
CloudGuildAPI.guildOf(player.getUniqueId()).ifPresent(g -> {
player.sendMessage("你的公会:" + g.name() + " Lv." + g.level());
// 打赢副本:给公会 500 资金、给自己 20 贡献
CloudGuildAPI.addFunds(g.id(), 500, "MyDungeon");
CloudGuildAPI.addContribution(player.getUniqueId(), 20);
});
}
先检查 available()

云公会没安装、被停用或还没启动完成时,available() 返回 false,这时调用其他方法会抛出 IllegalStateException。

CloudGuildAPI​

查询​

查询都读内存缓存,不查数据库,可以在主线程频繁调用。成员资料只有在线玩家一定准确。

方法返回说明
available()boolean云公会能不能用
guildOf(UUID player)Optional<GuildInfo>玩家的公会(在线玩家);没有公会时 empty
guild(int id)Optional<GuildInfo>依编号找公会
find(String nameOrTag)Optional<GuildInfo>依名称或标签找公会(不分大小写、忽略颜色代码)
guilds()List<GuildInfo>所有公会
rank(UUID player)Optional<String>职位 id(config.yml ranks 的键);没有公会时 empty
contribution(UUID player)long目前的贡献;不在线或没有公会时 -1
sameGuild(UUID a, UUID b)boolean两位(在线)玩家是不是同一个公会
allied(int guildA, int guildB)boolean两个公会是不是同盟

修改​

修改都是异步的:方法马上返回 CompletableFuture,数据库写入在后台完成。回调在后台线程执行,要碰 Bukkit 的东西(发消息、改背包)请切回主线程(Folia 用对应的调度器)。 资金与活跃修改成功后会通知所有子服(跨服时),在线成员的菜单、变量会跟着更新;贡献的修改会立即更新这个子服的缓存,其他子服在下一次整批刷新(最多 60 秒)时更新。

方法返回说明
addFunds(int guildId, long delta, String reason)CompletableFuture<Long>增减公会资金。减少时资金不够就失败(不会变成负数)。返回新余额,失败时 -1。会写入银行记录(动作「其他插件」,名称是 reason,null 时为 API)
addActivity(int guildId, long delta)CompletableFuture<Void>增减公会活跃(不会小于 0),增加的部分也计入本月活跃
addContribution(UUID player, long delta)CompletableFuture<Boolean>增减成员的贡献(不会小于 0);增加的部分也计入累积与本周贡献。返回这位玩家是不是公会成员
takeContribution(UUID player, long amount)CompletableFuture<Boolean>扣贡献,不够就失败(返回 false),适合拿贡献当货币
open(Player player)void帮玩家打开公会主页(云界面或箱子菜单;没有公会时打开公会列表)
CloudGuildAPI.takeContribution(player.getUniqueId(), 100).thenAccept(ok -> {
if (ok) Bukkit.getScheduler().runTask(plugin, () -> giveReward(player));
else player.sendMessage("贡献不足");
});

GuildInfo​

record GuildInfo(int id, String name, String tag, int level, long funds, long activity, int members, int maxMembers, UUID leader, String leaderName, boolean friendlyFire, long created)

字段说明
id公会编号
name公会名称(可能含 & 颜色代码)
tag标签,没有时 null
level / funds / activity等级 / 资金 / 活跃
members / maxMembers成员数 / 这个等级的人数上限
leader / leaderName会长 UUID / 名称
friendlyFire友伤是否开启
created建立时间(毫秒)

快照不会自动更新,需要最新的值时再调用一次 guildOf / guild。

事件​

事件什么时候可取消方法
GuildCreateEvent玩家要建立公会,扣费之前是(取消后不扣费、不建立)getPlayer()、getName()(可能含颜色)、getTag()(没有时 null)
GuildChatEvent公会 / 同盟频道发言送出之前;可能在非主线程是getPlayer()、getGuildId()、isAlly()、getMessage() / setMessage(String)
GuildDepositEvent成员存钱进公会银行之后否getGuildId()、getPlayer()(UUID)、getAmount()、getBalance()(存入后的资金)
GuildLevelUpEvent公会升级之后否getGuildId()、getGuildName()、getLevel()(新等级)
GuildMemberJoinEvent玩家加入公会之后(直接加入、申请通过、邀请、管理员加入)否getGuildId()、getPlayer()(UUID)、getPlayerName()
GuildMemberLeaveEvent玩家离开公会之后否getGuildId()、getPlayer()(UUID)、getPlayerName()、getReason():LEAVE 退出 / KICK 被踢 / DISBAND 公会解散(这时 getPlayerName() 为 null)
GuildDisbandEvent公会解散之后否getGuildId()、getGuildName()、getBy()(执行解散的人的名称)
GuildWarEndEvent公会战结算之后否getWarId()、getAttacker()、getDefender()、getAttackerKills()、getDefenderKills()、getWinner()(胜方公会编号,0 = 平手)
  • 事件只在发生操作的那个子服触发一次,其他子服不会再触发。
  • GuildCreateEvent 在玩家的线程触发;GuildChatEvent 依聊天来源可能是异步的;其余事件在主线程(Folia 为全局区域线程)触发。
  • 公会解散时,先对每位成员触发 GuildMemberLeaveEvent(DISBAND),再触发 GuildDisbandEvent。

例子:接违禁词、记录公会战​

import dev.cloudplugins.guild.api.CloudGuildAPI;
import dev.cloudplugins.guild.api.GuildChatEvent;
import dev.cloudplugins.guild.api.GuildWarEndEvent;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class GuildHooks implements Listener {
@EventHandler
public void onGuildChat(GuildChatEvent e) {
// 可能在异步线程:只做字符串处理
e.setMessage(e.getMessage().replace("外挂", "**"));
if (e.getMessage().isBlank()) e.setCancelled(true);
}

@EventHandler
public void onWarEnd(GuildWarEndEvent e) {
if (e.getWinner() == 0) return; // 平手
CloudGuildAPI.guild(e.getWinner()).ifPresent(g ->
Bukkit.broadcastMessage("恭喜 " + g.name() + " 赢得公会战!"));
}
}