| name | dominion-addon-dev |
| description | Develop Dominion addon plugins using the DominionAPI. Use when creating new Dominion addon plugins, writing code that interacts with the Dominion land-claim system, listening to Dominion events, operating on dominion/group/member data via Providers, registering custom flags, or checking privilege/environment flags within dominions. Also use when setting up Gradle/Maven build files for DominionAPI dependency, creating plugin.yml for Dominion addons, or debugging Dominion API integration issues. |
| compatibility | ["DominionProtect"] |
Dominion Addon Development Skill
You are an expert developer for Dominion addon plugins (Minecraft Paper/Spigot).
Dominion is a land-claim protection plugin; addons extend it using the DominionAPI.
Key References
Project Setup
Gradle (Kotlin DSL) — Recommended
repositories {
mavenLocal()
mavenCentral()
maven("https://oss.sonatype.org/content/groups/public")
maven("https://repo.papermc.io/repository/maven-public/")
maven("https://jitpack.io")
}
dependencies {
compileOnly("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT")
compileOnly("cn.lunadeer:DominionAPI:4.7.3")
}
Gradle (Groovy)
dependencies {
compileOnly 'cn.lunadeer:DominionAPI:4.7.3'
}
Maven
<dependency>
<groupId>cn.lunadeer</groupId>
<artifactId>DominionAPI</artifactId>
<version>4.7.3</version>
<scope>provided</scope>
</dependency>
plugin.yml Requirements
The addon's plugin.yml MUST include Dominion in the depend list:
name: YourAddonPlugin
version: '1.0.0'
main: com.example.yourplugin.YourPlugin
api-version: '1.20'
depend:
- Dominion
Set folia-supported: true if your addon supports Folia.
Getting the API Instance
Always obtain DominionAPI in onEnable() after verifying the Dominion plugin is loaded:
import cn.lunadeer.dominion.api.DominionAPI;
public final class YourPlugin extends JavaPlugin {
private DominionAPI dominionAPI;
@Override
public void onEnable() {
if (Bukkit.getPluginManager().isPluginEnabled("Dominion")) {
dominionAPI = DominionAPI.getInstance();
getLogger().info("DominionAPI loaded successfully");
} else {
throw new IllegalStateException("Dominion plugin is not enabled.");
}
getServer().getPluginManager().registerEvents(this, this);
}
}
Core API Patterns
1. Query Dominion Data (Read-Only)
Use DominionAPI methods for all read operations — they read from cache and are safe on any thread.
DominionDTO dom = dominionAPI.getDominion(player.getLocation());
DominionDTO dom = dominionAPI.getDominion("myDominion");
DominionDTO dom = dominionAPI.getDominion(42);
DominionDTO current = dominionAPI.getPlayerCurrentDominion(player);
List<DominionDTO> owned = dominionAPI.getAllDominionsOfPlayer(player.getUniqueId());
PlayerDTO playerDTO = dominionAPI.getPlayer(player.getUniqueId());
MemberDTO member = dominionAPI.getMember(dom, player);
GroupDTO group = dominionAPI.getGroup(member);
2. Check Flags
boolean canBuild = dominionAPI.checkPrivilegeFlag(location, priFlag, player);
boolean canBuild = dominionAPI.checkPrivilegeFlagSilence(location, priFlag, player);
boolean hasFire = dominionAPI.checkEnvironmentFlag(location, envFlag);
Important (since 4.5.0): Always prefer the Location-based overloads over DominionDTO-based overloads. The Location-based methods also check world-wide flags.
3. Modify Data via Providers
All data modifications MUST go through Providers to ensure consistency and trigger events.
Provider methods are asynchronous and return CompletableFuture.
The operator parameter controls permission checks:
- Pass a
Player to enforce permission checks
- Pass
Bukkit.getConsoleSender() to bypass permission checks (console-level access)
DominionProvider domProvider = dominionAPI.getDominionProvider();
CompletableFuture<DominionDTO> future = domProvider.createDominion(
Bukkit.getConsoleSender(),
"newDominion",
playerUUID,
world,
new CuboidDTO(x1,y1,z1, x2,y2,z2),
null,
false
);
DominionDTO created = future.get();
GroupProvider groupProvider = dominionAPI.getGroupProvider();
MemberProvider memberProvider = dominionAPI.getMemberProvider();
4. Listen to Dominion Events
Register listeners the standard Bukkit way. All events extend CallableEvent.
import cn.lunadeer.dominion.events.dominion.DominionCreateEvent;
import cn.lunadeer.dominion.events.member.MemberAddedEvent;
public class MyListener implements Listener {
@EventHandler
public void onDominionCreate(DominionCreateEvent event) {
if (event.isCancelled()) return;
}
@EventHandler
public void onMemberAdded(MemberAddedEvent event) {
if (event.isCancelled()) return;
event.afterAdded(memberDTO -> {
if (memberDTO == null) return;
DominionDTO dominion = event.getDominion();
Player player = Bukkit.getPlayer(memberDTO.getPlayerUUID());
if (player != null) {
player.teleportAsync(dominion.getTpLocation());
}
});
}
}
Key event categories:
| Package | Events |
|---|
cn.lunadeer.dominion.events | PlayerMoveInDominionEvent, PlayerMoveOutDominionEvent, PlayerCrossDominionBorderEvent, FlagRegisterEvent |
cn.lunadeer.dominion.events.dominion | DominionCreateEvent, DominionDeleteEvent |
cn.lunadeer.dominion.events.dominion.modify | DominionRenameEvent, DominionSizeChangeEvent, DominionSetEnvFlagEvent, DominionSetGuestFlagEvent, DominionSetMapColorEvent, DominionSetMessageEvent, DominionSetTpLocationEvent, DominionTransferEvent |
cn.lunadeer.dominion.events.group | GroupCreateEvent, GroupDeleteEvent, GroupRenamedEvent, GroupSetFlagEvent, GroupAddMemberEvent, GroupRemoveMemberEvent |
cn.lunadeer.dominion.events.member | MemberAddedEvent, MemberRemovedEvent, MemberSetFlagEvent |
Data operation events (like DominionCreateEvent, MemberAddedEvent) process the actual data after all listeners run. Use provided callback methods (e.g., event.afterAdded(...)) to access results.
5. Register Custom Flags (since 4.7.0)
Two flag types exist:
EnvFlag — environment flags (not player-specific, e.g., weather control)
PriFlag — privilege flags (player-specific, e.g., can-build)
import cn.lunadeer.dominion.api.dtos.flag.EnvFlag;
import cn.lunadeer.dominion.api.dtos.flag.PriFlag;
import cn.lunadeer.dominion.api.dtos.flag.Flags;
public static EnvFlag NO_RAIN = new EnvFlag(
"no_rain",
"No Rain",
"Prevents rain in this dominion.",
false,
true,
Material.SUNFLOWER
);
public static PriFlag CUSTOM_ACTION = new PriFlag(
"custom_action",
"Custom Action",
"Allows custom action in dominion.",
false,
true,
Material.RED_BED
);
Flags.registerEnvFlag(NO_RAIN);
Flags.registerPriFlag(CUSTOM_ACTION);
Flags.applyNewCustomFlags();
DTO Quick Reference
| DTO | Key Methods |
|---|
DominionDTO | getId(), getName(), getOwner(), getWorld(), getCuboid(), getTpLocation(), getEnvFlagValue(flag), getGuestFlagValue(flag), getGroups(), getMembers(), getParentDomId(), getJoinMessage(), getLeaveMessage() |
PlayerDTO | getId(), getUuid(), getLastKnownName(), getSkinUrl(), getUiPreference() |
MemberDTO | getId(), getPlayerUUID(), getDomID(), getGroupId(), getFlagValue(flag), getPlayer() |
GroupDTO | getId(), getDomID(), getNamePlain(), getNameRaw(), getFlagValue(flag), getMembers() |
CuboidDTO | getPos1(), getPos2(), x1()..z2(), xLength(), yLength(), zLength(), getSquare(), getVolume(), contain(...), intersectWith(...) |
Rules
- DominionAPI is a
compileOnly / provided dependency — never shade it into your jar.
- Always verify
Dominion is enabled before calling DominionAPI.getInstance().
- Use
Location-based flag checks over DominionDTO-based ones (since 4.5.0) to include world-wide flags.
- All Provider operations are async (
CompletableFuture) — handle appropriately.
- Event callbacks (e.g.,
afterAdded) run after actual data processing — use them for post-operation logic.
- Custom flag names must be unique and contain no spaces.
- Call
Flags.applyNewCustomFlags() after registering all custom flags.
- Never modify DTO data directly — always use Providers for writes.
- Paper API 1.20.1+ is the minimum supported version.
- The plugin must declare
depend: [Dominion] in plugin.yml.