Repository navigation
Developer API
ByteClans exposes a stable public API that allows developers to build addons and interact with the clan system.
The API is designed to be simple, consistent and backwards-compatible across versions.
final ByteClans api = ByteClans.getAPI();Lookups allow you to retrieve clan and member objects from the cache.
They return null or empty Optional if the player is not in a clan or the clan is not loaded.
final ByteClans api = ByteClans.getAPI();
// by UUID
final Clan clan = api.getClanOrNull(clanUUID);
final Optional<Clan> clan = api.getClan(clanUUID);
// by name
final Clan clan = api.getClanByNameOrNull("warriors");
final Optional<Clan> clan = api.getClanByName("warriors");
// member
final ClanMember member = api.getClanMemberOrNull(playerUUID);
final Optional<ClanMember> member = api.getClanMember(playerUUID);Note: Lookups only return data for clans that are currently loaded in memory.
A clan is loaded when at least one of its members is online.
All manager methods return either a Response<R> or a ResponseContext<V, R>:
-
R— the result enum (e.g.ClanLeaveResult,ClanKickResult) -
V— the returned value when the operation produces one (e.g. the createdClan, the joinedClanMember)
ResponseContext<V, R> extends Response<R> — so result() and success() are always available on both.
// Response<R> — result only
final Response<ClanLeaveResult> response = api.clanMemberManager().leave(member);
response.result(); // ClanLeaveResult enum value
response.success(); // true if SUCCESS, false otherwise
// ResponseContext<V, R> — result + value
final ResponseContext<ClanMember, ClanJoinResult> response = api.clanMemberManager().join(clanPlayer, clan);
response.result(); // ClanJoinResult enum value
response.success(); // true if SUCCESS, false otherwise
response.value(); // the ClanMember that joined — only meaningful when success() is trueManagers allow you to perform operations on clans and members.
final CompletableFuture<ResponseContext<Clan, ClanCreateResult>> response = api.clanManager().createClan(clanPlayer, "warriors");
final Response<ClanDisbandResult> response = api.clanManager().disbandClan(member);final ResponseContext<ClanMember, ClanJoinResult> response = api.clanMemberManager().join(clanPlayer, clan);
final Response<ClanLeaveResult> response = api.clanMemberManager().leave(member);
final Response<ClanKickResult> response = api.clanMemberManager().kick(executor, target);
final Response<ClanTransferResult> response = api.clanMemberManager().transferOwner(executor, target);
final Response<ClanPromoteResult> response = api.clanMemberManager().promote(executor, target);
final Response<ClanDemoteResult> response = api.clanMemberManager().demote(executor, target);
final Response<ClanChangeChatModeResult> response = api.clanMemberManager().changeChatMode(member, ClanChatType.CLAN);final ResponseContext<ClanInvitation, ClanInviteSendResult> response = api.clanInviteManager().send(executor, targetPlayer);
final ResponseContext<ClanInvitation, ClanInviteAcceptResult> response = api.clanInviteManager().accept(clanPlayer);
final ResponseContext<ClanInvitation, ClanInviteDeclineResult> response = api.clanInviteManager().decline(clanPlayer);final Response<ClanPvPModeChangeResult> response = api.clanSettingsManager().changePvPMode(member, ClanPvPMode.FRIENDLY_FIRE);
final Response<ClanStatusChangeResult> response = api.clanSettingsManager().changeInviteStatus(member, ClanInviteState.OPENED);
final Response<ClanRenameDisplayResult> response = api.clanSettingsManager().renameDisplay(member, "<red>Warriors");final Response<Integer> response = api.clanStatisticManager().addKills(clan, 1);
final Response<Integer> response = api.clanStatisticManager().addDeaths(clan, 1);
final Response<Integer> response = api.clanStatisticManager().addDeathAndResetKs(clan, 1);
api.clanStatisticManager().addKillsAndKs(clan, 1, 1);
api.clanStatisticManager().resetKs(clan);ByteClans fires events before and after every operation.
Pre events are cancellable — post events are informational.
All events are located in the team.bytephoria.byteclans.bukkitapi.event package.
| Event | Cancellable | Description |
|---|---|---|
ClanPreCreateAsyncEvent |
✅ | Fired before a clan is created |
ClanPostCreateAsyncEvent |
❌ | Fired after a clan is created |
ClanDisbandEvent |
✅ | Fired when a clan is disbanded |
ClanRenameDisplayEvent |
✅ | Fired when a clan display name is changed |
ClanInviteStatusChangeEvent |
✅ | Fired when the invite state is changed |
ClanPvPModeChangeEvent |
✅ | Fired when the PvP mode is changed |
| Event | Cancellable | Description |
|---|---|---|
ClanMemberJoinEvent |
✅ | Fired when a player joins a clan |
ClanMemberLeaveEvent |
✅ | Fired when a player leaves a clan |
ClanMemberKickEvent |
✅ | Fired when a player is kicked from a clan |
ClanMemberDamageEvent |
✅ | Fired when a clan member damages another |
ClanMemberRoleChangeEvent |
✅ | Fired when a member's role is changed |
ClanPromoteEvent |
✅ | Fired when a member is promoted |
ClanDemoteEvent |
✅ | Fired when a member is demoted |
ClanTransferOwnerEvent |
✅ | Fired when clan ownership is transferred |
| Event | Cancellable | Description |
|---|---|---|
ClanInviteSendEvent |
✅ | Fired when an invite is sent |
ClanPreInviteAcceptEvent |
✅ | Fired before an invite is accepted |
ClanPostInviteAcceptEvent |
❌ | Fired after an invite is accepted |
ClanInviteDeclineEvent |
✅ | Fired when an invite is declined |
@EventHandler
public void onClanPostCreateAsyncEvent(final ClanPostCreateAsyncEvent createAsyncEvent) {
final Clan clan = createAsyncEvent.clan();
final ClanPlayer creator = createAsyncEvent.clanPlayer();
}
@EventHandler
public void onClanDisbandEvent(final ClanDisbandEvent disbandEvent) {
if (someCondition) {
disbandEvent.setCancelled(true);
}
}
@EventHandler
public void onClanMemberKickEvent(final ClanMemberKickEvent kickEvent) {
final ClanMember executor = kickEvent.executor();
final ClanMember target = kickEvent.target();
}Validators allow you to check if a clan name or display name is valid before performing any operation.
final ByteClans api = ByteClans.getAPI();
// validate clan name
final ClanNameValidationResult result = api.clanNameValidator().validate("my clan!");
switch (result) {
case VALID -> // name is valid
case TOO_SHORT -> // name is too short
case TOO_LONG -> // name is too long
case INVALID_CHARACTERS -> // name contains invalid characters
case NAME_TAKEN -> // name is already taken
}
// validate display name
final ClanDisplayNameValidationResult result = api.clanDisplayNameValidator().validate("warriors", "<red>Warriors");
switch (result) {
case VALID -> // display name is valid
case INVALID_CONTENT -> // text does not match the original clan name
case INVALID_CHARACTERS -> // contains invalid characters
}If you need help, feel free to join our Discord.