pluginiPlugin

API 使用指南

在你的插件中集成 Inn API

安装

Gradle Kotlin DSL(build.gradle.kts):

repositories {
    maven("https://repo.hiusers.com/releases")
}
 
dependencies {
    compileOnly("api:Inn:1.4.2-api")
}

Gradle Groovy DSL(build.gradle):

repositories {
    maven { url "https://repo.hiusers.com/releases" }
}
 
dependencies {
    compileOnly 'api:Inn:1.4.2-api'
}

获取入口

import com.hiusers.mc.inn.Inn
 
val inn = Inn.api()                 // InnAPI
val homeAPI = inn.getHomeAPI()
val inviteAPI = inn.getInviteAPI()
val menuAPI = inn.getMenuAPI()
val spawnAPI = inn.getSpawnAPI()
val playerProfileAPI = inn.getPlayerProfileAPI()
val flagAPI = inn.getFlagAPI()

接口总览

InnAPI

/**
 * 插件统一入口。通过它获取各子系统 API。
 */
interface InnAPI {
    /** 家园核心能力(创建/加载/传送/权限/访客/查询) */
    fun getHomeAPI(): HomeAPI
 
    /** 跨服邀请与结果通知(依赖 Redis 时可跨服) */
    fun getInviteAPI(): InviteAPI
 
    /** 打开各类功能菜单(后台封装 UI) */
    fun getMenuAPI(): MenuAPI
 
    /** 出生点设置与传送 */
    fun getSpawnAPI(): SpawnAPI
 
    /** 玩家名与 UUID 互查 */
    fun getPlayerProfileAPI(): PlayerProfileAPI
 
    /** Flag 权限管理(精细化权限控制) */
    fun getFlagAPI(): FlagAPI
}

HomeAPI(家园核心)

/**
 * 家园系统核心 API:生命周期管理、权限与访客、传送与世界加载等。
 */
interface HomeAPI {
    /** 读取模板配置(用于确定出生点/边界/规则等) */
    fun getTemplateConfig(templateId: String): TemplateConfig?
 
    /** 查询某服是否还可分配家园(上限由调用方传入) */
    fun haveHomeSpace(serverName: String, maxHomeCount: Int): Boolean
 
    /** 创建家园(复制模板 -> 准备路径;不保证立刻加载世界) */
    fun createHome(ownerUid: UUID, homeName: String, templateId: String): Boolean
 
    /** 删除家园(异步,若世界已加载会先卸载再删除) */
    fun deleteHome(ownerUid: UUID, homeName: String): CompletableFuture<Boolean>
 
    /** 获取家园详情(含访客与权限) */
    fun getHomeProfile(ownerUid: UUID, homeName: String): HomeProfile?
 
    /** 获取家园摘要(用于列表/导航) */
    fun getHomeSummary(ownerUid: UUID, homeName: String): HomeSummary?
 
    /** 是否为该家园的受邀访客 */
    fun isHomeVisitor(ownerUid: UUID, homeName: String, visitorUid: UUID): Boolean
 
    /** 获取玩家所有家园摘要 */
    fun getPlayerHomes(ownerUid: UUID): List<HomeSummary>
 
    /** 按玩家名获取家园名(便于命令补全) */
    fun getPlayerHomeNames(playerName: String): List<String>
 
    /** 是否拥有家园(可指定家园名做精确判断) */
    fun hasHome(playerUid: UUID, homeName: String? = null): Boolean
 
    /** 是否为家园世界(Inn 管理的世界) */
    fun isHomeWorld(world: World): Boolean
 
    /** 从家园世界反查归属信息 (ownerUid, homeName) */
    fun getHomeInfo(world: World): Pair<UUID, String>?
 
    /** 设置家园是否公开(公开则陌生人可基础访问) */
    fun setHomePublic(ownerUid: UUID, homeName: String, isPublic: Boolean): Boolean
 
    /** 访问权限判断:公开/访客/本人 均视为可访问 */
    fun canAccessHome(visitorUid: UUID, ownerUid: UUID, homeName: String): Boolean
 
    /** 获取访客列表(含权限);家园不存在返回 null */
    fun getHomeVisitors(ownerUid: UUID, homeName: String): List<HomeVisitor>?
 
    /** 添加家园访客 */
    fun addHomeVisitor(ownerUid: UUID, homeName: String, targetUid: UUID): Boolean
 
    /** 将玩家从访客中移除(并清除其权限) */
    fun removeHomeVisitor(ownerUid: UUID, homeName: String, targetUid: UUID): Boolean
 
    /** 卸载家园世界(异步),不会删除数据 */
    fun unloadWorld(ownerUid: UUID, homeName: String): CompletableFuture<Boolean>
 
    /** 卸载指定世界(异步) */
    fun unloadWorld(world: World): CompletableFuture<Boolean>
 
    /** 加载家园世界(仅本地,异步) */
    fun loadWorld(ownerUid: UUID, homeName: String): CompletableFuture<World?>
 
    /**
     * 确保世界已加载(异步)。如启用 Redis,可请求目标服预加载并等待结果(默认超时约 10s)。
     */
    fun ensureWorldLoaded(ownerUid: UUID, homeName: String, playerUid: UUID): CompletableFuture<Boolean>
 
    /** 设置家园边界(null 表示关闭) */
    fun setHomeBorder(ownerUid: UUID, homeName: String, borderSize: Double?)
 
    /** 获取家园当前边界大小,未设置时返回 0 */
    fun getHomeBorder(ownerUid: UUID, homeName: String): Double
 
    /** 基于现有边界增加指定大小,返回调整后的边界值(未设置视作 0) */
    fun addHomeBorder(ownerUid: UUID, homeName: String, amount: Double): Double
 
    /** 基于现有边界减少指定大小,返回调整后的边界值(未设置视作 0) */
    fun reduceHomeBorder(ownerUid: UUID, homeName: String, amount: Double): Double
 
    /** 传送玩家到家园(会先 ensureWorldLoaded) */
    fun teleportToHome(proxyPlayer: ProxyPlayer, ownerUid: UUID, homeName: String): CompletableFuture<Boolean>
 
    /** 被邀请可访问的家园列表(可选按名称过滤) */
    fun getAccessibleHomes(playerUid: UUID, homeName: String? = null): List<HomeSummary>
 
    /** 公共家园列表(可选按名称过滤) */
    fun getPublicHomes(homeName: String? = null): List<HomeSummary>
 
    /** 切换公开/私有 */
    fun toggleHomePublic(ownerUid: UUID, homeName: String)
 
    /** 根据玩家所在世界获取当前家园摘要 */
    fun getHomeSummaryByPlayer(proxyPlayer: ProxyPlayer): HomeSummary?
 
    /** 玩家是否处于家园世界中 */
    fun isInHomeWorld(proxyPlayer: ProxyPlayer): Boolean
 
    /** 更新家园最后加载时间(内部统计/清理使用) */
    fun updateHomeLastLoadTime(world: World)
 
    /** 清理 N 天未加载的家园(策略由实现方定义) */
    fun cleanExpiredHomes(days: Int)
}

InviteAPI(邀请)

/**
 * 家园邀请 API:邀请/接受/拒绝与跨服通知。
 */
interface InviteAPI {
    /** 通知被邀请玩家(可用于跨服在线提醒) */
    fun notifyPlayerInvite(homeInviteNotify: HomeInviteNotify)
 
    /** 通知邀请发起者处理结果(接受/拒绝/超时等) */
    fun notifySenderResult(homeInviteResult: HomeInviteResult)
 
    /** 发送家园邀请(receiverName 为玩家名) */
    fun sendHomeInvite(sender: ProxyPlayer, receiverName: String, ownerUid: UUID, homeName: String): Boolean
 
    /** 接受邀请(根据 inviteId 处理) */
    fun acceptHomeInvite(proxyPlayer: ProxyPlayer, inviteId: String): Boolean
 
    /** 拒绝邀请 */
    fun rejectHomeInvite(proxyPlayer: ProxyPlayer, inviteId: String): Boolean
 
    /** 清理本地过期的邀请缓存 */
    fun cleanExpiredInvites()
}

说明:HomeInviteNotifyHomeInviteResult 来源于 Redis 通知模型,作为跨服邀请的消息载体。

/**
 * 菜单 API:打开内置功能菜单(实现方负责 UI 渲染)。
 */
interface MenuAPI {
    /** 家园管理菜单(边界/公开/删除等) */
    fun openHomeManager(player: Player, homeName: String)
 
    /** 访客与权限管理菜单 */
    fun openHomeVisitorManager(player: Player, homeName: String)
 
    /** 公共家园列表(可按名称过滤) */
    fun openPublicHomes(player: Player, homeName: String? = null)
 
    /** 我可访问的家园列表(受邀请) */
    fun openAccessibleHomes(player: Player, homeName: String? = null)
}

SpawnAPI(出生点)

/**
 * 出生点 API:设置/查询/传送。
 */
interface SpawnAPI {
    /** 将全服出生点设置为玩家当前位置 */
    fun setSpawn(proxyPlayer: ProxyPlayer)
 
    /** 获取出生点信息(服务器名/世界与坐标) */
    fun getSpawnProfile(): SpawnProfile?
 
    /** 传送玩家到出生点(返回是否成功) */
    fun teleportToSpawn(proxyPlayer: ProxyPlayer): Boolean
}

PlayerProfileAPI(玩家档案)

/**
 * 玩家档案 API:名与 UUID 的互查。
 */
interface PlayerProfileAPI {
    /** 通过 UUID 查玩家名 */
    fun getNameByUid(uid: UUID): String?
 
    /** 通过玩家名查 UUID(重名/大小写差异由实现决定) */
    fun getUidByName(name: String): UUID?
}

FlagAPI(Flag 权限管理)

/**
 * Flag 权限管理 API:提供精细化的权限检查功能。
 */
interface FlagAPI {
    /** 检查玩家是否拥有指定 flag 权限 */
    fun hasFlag(player: Player, ownerUid: UUID, homeName: String, flagType: FlagType): Boolean
 
    /** 检查玩家是否拥有指定 flag 权限(使用玩家UUID) */
    fun hasFlag(playerUid: UUID, ownerUid: UUID, homeName: String, flagType: FlagType): Boolean
 
    /** 获取家园的 flag 配置 */
    fun getFlag(ownerUid: UUID, homeName: String, flagType: FlagType): Flag
 
    /** 获取家园的所有 flag 配置 */
    fun getAllFlags(ownerUid: UUID, homeName: String): Map<FlagType, Flag>
 
    /** 设置家园的 flag 配置 */
    fun setFlag(ownerUid: UUID, homeName: String, flagType: FlagType, invited: Boolean, public: Boolean): Boolean
 
    /** 重置 flag 为默认值 */
    fun resetFlag(ownerUid: UUID, homeName: String, flagType: FlagType): Boolean
 
    /** 切换全局 flag 配置状态 */
    fun toggleFlag(ownerUid: UUID, homeName: String, flagType: FlagType, isInvited: Boolean): Boolean
 
    // ==================== 访客个人 Flag 权限 ====================
 
    /** 获取访客在家园中拥有的所有 flag 权限 */
    fun getVisitorFlags(ownerUid: UUID, homeName: String, visitorUid: UUID): Map<FlagType, Boolean>
 
    /** 检查访客是否拥有指定 flag 权限 */
    fun hasVisitorFlag(ownerUid: UUID, homeName: String, visitorUid: UUID, flagType: FlagType): Boolean
 
    /** 给访客添加 flag 权限 */
    fun addVisitorFlag(ownerUid: UUID, homeName: String, visitorUid: UUID, flagType: FlagType): Boolean
 
    /** 移除访客的 flag 权限 */
    fun removeVisitorFlag(ownerUid: UUID, homeName: String, visitorUid: UUID, flagType: FlagType): Boolean
 
    /** 切换访客的 flag 权限状态 */
    fun toggleVisitorFlag(ownerUid: UUID, homeName: String, visitorUid: UUID, flagType: FlagType): Boolean
}

事件(Bukkit/TabooLib 事件总线)

/** 家园创建完成(可用于发放奖励/初始化逻辑) */
class HomeCreateEvent(val homeProfile: HomeProfile) : BukkitProxyEvent()
 
/** 玩家进入家园(可做欢迎提示/统计) */
class HomeIntoEvent(val proxyPlayer: ProxyPlayer, val homeSummary: HomeSummary) : BukkitProxyEvent()
 
/** 家园世界加载完成(ownerUid 指向家园归属) */
class HomeLoadEvent(val ownerUid: UUID, val world: World) : BukkitProxyEvent()
 
/** 访客被移除(可做反馈或补偿) */
class HomeKickEvent(val ownerUid: UUID, val targetUid: UUID) : BukkitProxyEvent()
 
/** 家园公开状态变更 */
class HomeUpdatePublicEvent(val ownerUid: UUID, val isPublic: Boolean) : BukkitProxyEvent()
 
/** 家园边界变更(null 表示关闭边界) */
class HomeBorderUpdateEvent(val homeSummary: HomeSummary, val borderSize: Double?) : BukkitProxyEvent()

监听示例:

import com.hiusers.mc.inn.api.event.HomeCreateEvent
import taboolib.common.platform.event.SubscribeEvent
 
object MyListener {
    @SubscribeEvent
    fun onHomeCreate(e: HomeCreateEvent) {
        val profile = e.homeProfile
        // TODO: 自定义处理
    }
}

数据模型(DTO & 枚举)

/** 家园摘要(用于列表与卡片) */
data class HomeSummary(
    val homeId: Long,              // 家园 ID
    val ownerName: String?,        // 拥有者玩家名(可空)
    val ownerUid: UUID,            // 拥有者 UUID
    val homeName: String,          // 家园名称
    val templateId: String,        // 使用的模板 ID
    val serverName: String,        // 所在服务器
    val isPublic: Boolean,         // 是否公开
    val visitorCount: Int,         // 访客数量
    val borderSize: Double?,       // 边界大小(米),null 表示无边界
    val lastLoadTime: LocalDateTime? // 最近加载时间
)
 
/** 家园详情(含访客与权限) */
data class HomeProfile(
    val homeId: Long,
    val ownerUid: UUID,
    val homeName: String,
    val templateId: String,
    val serverName: String,
    val isPublic: Boolean,
    val createTime: LocalDateTime, // 创建时间
    val visitors: List<HomeVisitor>,
    val borderSize: Double?,
    val lastLoadTime: LocalDateTime?
)
 
/** 家园访客信息 */
data class HomeVisitor(
    val playerName: String?,       // 访客名(可空)
    val playerUid: UUID,           // 访客 UUID
    val addedTime: LocalDateTime   // 加入时间
)
 
/** 全服出生点信息 */
data class SpawnProfile(
    val serverName: String,
    val world: String,
    val x: Double,
    val y: Double,
    val z: Double,
    val yaw: Float,
    val pitch: Float
)
 
/** 模板配置聚合(出生点/边界/规则) */
data class TemplateConfig(
    val border: BorderNode = BorderNode(),
    val spawn: SpawnNode? = null,
    val rule: RuleNode = RuleNode(),
    val portal: PortalNode = PortalNode(),
    val creator: CreatorNode = CreatorNode()
)
 
/** 世界边界设置 */
data class BorderNode(
    val enable: Boolean = false,
    val range: Double = 100.0,
    val damageAmount: Double = 5.0,
    val damageBuffer: Double = 0.0,
    val warningDistance: Int = 0,
    val warningTime: Int = 0
)
 
/** 出生点坐标(世界名由调用处注入) */
data class SpawnNode(
    val x: Double = 0.0,
    val y: Double = 0.0,
    val z: Double = 0.0,
    val yaw: Double = 0.0,
    val pitch: Double = 0.0
)
 
/** 世界规则(Bukkit GameRule 等) */
data class RuleNode(
    val difficulty: String = "NORMAL",
    val gameMode: String = "SURVIVAL",
    val keepInventory: Boolean = false,
    val pvp: Boolean = true,
    val gameRules: Map<String, Any> = emptyMap(),
    val respawn: Boolean = false
)
 
/** 传送门配置 */
data class PortalNode(
    val nether: PortalRuleNode = PortalRuleNode(),
    val end: PortalRuleNode = PortalRuleNode()
)
 
/** 传送门规则节点 */
data class PortalRuleNode(
    val allow: Boolean = true,
    val to: String? = null
)
 
/** 世界创建配置 */
data class CreatorNode(
    val enable: Boolean = false,
    val environment: String = "NORMAL",
    val biome: String = "DEFAULT",
    val void: VoidNode = VoidNode()
)
 
/** 虚空世界配置 */
data class VoidNode(
    val enable: Boolean = false,
    val block: VoidPlatformNode = VoidPlatformNode()
)
 
/** 虚空平台配置 */
data class VoidPlatformNode(
    // 具体字段根据实际实现定义
)
 
/** Flag 配置 */
data class Flag(
    val type: FlagType,
    val invited: Boolean,  // 受邀玩家是否可以执行该操作
    val public: Boolean    // 公共访客是否可以执行该操作
)
 
/** Flag 类型枚举 */
enum class FlagType(
    val key: String,
    val material: Material,
    val defaultValue: Boolean,
    val enable: Boolean = true
) {
    // 玩家行为相关
    ANIMAL_KILLING("animal_killing", Material.COOKED_BEEF, true, true),
    ANVIL("anvil", Material.ANVIL, true, true),
    BEACON("beacon", Material.BEACON, true, true),
    BED("bed", Material.RED_BED, true, true),
    BREAK("break", Material.IRON_PICKAXE, true, true),
    BREW("brew", Material.BREWING_STAND, true, true),
    BUTTON("button", Material.STONE_BUTTON, true, true),
    CAKE("cake", Material.CAKE, true, true),
    COMPARER("comparer", Material.COMPARATOR, true, true),
    CRAFTER("crafter", Material.CRAFTER, true, true),
    CRAFT("craft", Material.CRAFTING_TABLE, true, true),
    DOOR("door", Material.OAK_DOOR, true, true),
    DRAGON_EGG("dragon_egg", Material.DRAGON_EGG, true, true),
    DROP_ITEM("drop_item", Material.IRON_INGOT, true, true),
    DYE("dye", Material.LIGHT_BLUE_DYE, true, true),
    EDIT_SIGN("edit_sign", Material.OAK_SIGN, true, true),
    ENCHANT("enchant", Material.ENCHANTING_TABLE, true, true),
    ENDER_PEARL("ender_pearl", Material.ENDER_PEARL, true, true),
    FEED("feed", Material.WHEAT, true, true),
    FLY("fly", Material.ELYTRA, true, false),
    GLOW("glow", Material.SPECTRAL_ARROW, true, true),
    HARVEST("harvest", Material.WHEAT, true, true),
    HONEY("honey", Material.HONEY_BOTTLE, true, true),
    HOOK("hook", Material.FISHING_ROD, true, true),
    IGNITE("ignite", Material.FLINT_AND_STEEL, true, true),
    ITEM_FRAME_INTERACTIVE("item_frame_interactive", Material.ITEM_FRAME, true, true),
    JUKEBOX("jukebox", Material.JUKEBOX, true, true),
    LEASH("leash", Material.LEAD, true, true),
    LECTERN("lectern", Material.LECTERN, true, true),
    LEVER("lever", Material.LEVER, true, true),
    MONSTER_KILLING("monster_killing", Material.IRON_SWORD, true, true),
    NOTE_BLOCK("note_block", Material.NOTE_BLOCK, true, true),
    PICK_UP("pick_up", Material.DIAMOND_PICKAXE, true, true),
    PLACE("place", Material.GRASS_BLOCK, true, true),
    MOVE("move", Material.LEATHER_BOOTS, true, true),
    PRESSURE("pressure", Material.STONE_PRESSURE_PLATE, true, true),
    PVP("pvp", Material.DIAMOND_SWORD, true, true),
    REPEATER("repeater", Material.REPEATER, true, true),
    ANCHOR("anchor", Material.RESPAWN_ANCHOR, true, true),
    RIDING("riding", Material.SADDLE, true, true),
    SHEAR("shear", Material.SHEARS, true, true),
    SHOOT("shoot", Material.BOW, true, true),
    SOWING("sowing", Material.WHEAT_SEEDS, true, true),
    CONTAINER("container", Material.CHEST, true, true),
    HOPPER("hopper", Material.HOPPER, true, true),
    TELEPORT("teleport", Material.ENDER_EYE, true, true),
    EGG("egg", Material.EGG, true, true),
    VEHICLE_DESTROY("vehicle_destroy", Material.IRON_AXE, true, true),
    VEHICLE_SPAWN("vehicle_spawn", Material.MINECART, true, true),
    VILLAGER_KILLING("villager_killing", Material.WOODEN_SWORD, true, true),
    TRADE("trade", Material.EMERALD, true, true);
 
    companion object {
        /** 根据 key 获取 FlagType */
        fun fromKey(key: String): FlagType?
    }
}

使用示例

创建家园并传送:

import com.hiusers.mc.inn.Inn
import taboolib.common.platform.ProxyPlayer
import java.util.UUID
 
fun createAndGo(player: ProxyPlayer, homeName: String, templateId: String) {
    val homeAPI = Inn.api().getHomeAPI()
    val ok = homeAPI.createHome(player.uniqueId, homeName, templateId)
    if (ok) {
        homeAPI.teleportToHome(player, player.uniqueId, homeName)
    }
}

添加访客:

import com.hiusers.mc.inn.Inn
import java.util.UUID
 
fun addVisitor(owner: UUID, homeName: String, target: UUID) {
    Inn.api().getHomeAPI().addHomeVisitor(owner, homeName, target)
}

使用 Flag 权限:

import com.hiusers.mc.inn.Inn
import com.hiusers.mc.inn.api.flag.FlagType
import org.bukkit.entity.Player
import java.util.UUID
 
fun checkBuildPermission(player: Player, ownerUid: UUID, homeName: String): Boolean {
    val flagAPI = Inn.api().getFlagAPI()
    return flagAPI.hasFlag(player, ownerUid, homeName, FlagType.PLACE) &&
           flagAPI.hasFlag(player, ownerUid, homeName, FlagType.BREAK)
}
 
fun setFlagPermission(ownerUid: UUID, homeName: String) {
    val flagAPI = Inn.api().getFlagAPI()
    // 设置受邀玩家可以放置和破坏方块,公共访客不可以
    flagAPI.setFlag(ownerUid, homeName, FlagType.PLACE, invited = true, public = false)
    flagAPI.setFlag(ownerUid, homeName, FlagType.BREAK, invited = true, public = false)
}

On this page