外观
扩展与平台投影 API 类型参考
本页是 API baseline 1.3 候选源码的扩展与平台投影公开签名。先阅读第三方插件接入教程;普通 Bukkit 插件与启动期内部扩展是两种不同入口,不要混用。
版本边界
正式交付 1.0.8 与 1.0.12 候选并不等价。依赖版本必须与服务器实际 JAR 配套,并重新编译、在目标服务端验收。
PlatformProjectionSink.kt
kotlin
package cn.sealplugins.attributes.api.platform
/** Bounded collector; acceptance does not apply an entity mutation until the batch is committed. */
public interface PlatformProjectionSink {
public fun accept(intent: PlatformProjectionIntent): ProjectionAcceptance
}
public enum class ProjectionAcceptance {
ACCEPTED,
LIMIT_EXCEEDED,
NAMESPACE_MISMATCH,
INVALID_INTENT,
OWNER_EXPIRED,
}PlatformProjectionIntent.kt
kotlin
package cn.sealplugins.attributes.api.platform
import cn.sealplugins.attributes.api.internal.requireNamespacedId
import cn.sealplugins.attributes.api.internal.requireFinite
/** One validated platform-neutral numeric projection owned by an extension namespace. */
public class PlatformProjectionIntent(
projectionId: String,
public val target: PlatformProjectionTarget,
public val operation: PlatformProjectionOperation,
amount: Double,
) {
public val projectionId: String = requireNamespacedId(projectionId, "projectionId")
public val amount: Double = requireFinite(amount, "projection amount")
init {
if (operation == PlatformProjectionOperation.REMOVE) {
require(this.amount == 0.0) { "REMOVE projection intents must use amount 0" }
}
}
}
/** V1 platform targets deliberately form an allowlist instead of exposing platform classes. */
public enum class PlatformProjectionTarget {
MAX_HEALTH,
MOVEMENT_SPEED,
}
public enum class PlatformProjectionOperation {
UPSERT_ADD,
UPSERT_TOTAL_PERCENT,
REMOVE,
}PlatformProjectionContext.kt
kotlin
package cn.sealplugins.attributes.api.platform
import cn.sealplugins.attributes.api.ApiLimits
import cn.sealplugins.attributes.api.definition.AttributeId
import cn.sealplugins.attributes.api.internal.immutableSet
import cn.sealplugins.attributes.api.subject.AttributeSnapshot
import cn.sealplugins.attributes.api.subject.SubjectKey
import java.util.Optional
/** Immutable committed snapshot transition provided to a platform extension. */
public class PlatformProjectionContext(
public val subject: SubjectKey,
public val current: AttributeSnapshot,
previous: Optional<AttributeSnapshot>,
changedAttributes: Collection<AttributeId>,
) {
public val previous: Optional<AttributeSnapshot> = previous
public val changedAttributes: Set<AttributeId> = immutableSet(
changedAttributes,
ApiLimits.MAX_ATTRIBUTES_PER_SNAPSHOT,
"changed attributes",
)
init {
require(current.state.key == subject) { "current snapshot must belong to subject" }
require(this.previous.map { it.state.key == subject }.orElse(true)) {
"previous snapshot must belong to subject"
}
}
}PlatformExtension.kt
kotlin
package cn.sealplugins.attributes.api.platform
import cn.sealplugins.attributes.api.internal.requireNamespacedId
import cn.sealplugins.attributes.api.internal.requirePriority
/**
* Controlled platform projection extension registered during startup.
*
* Projection runs synchronously after a committed snapshot transition on that subject's
* platform-approved execution context, ordered by `priority`, provider namespace and extension
* ID. The extension receives no platform object and must use only the provided immutable context
* and [sink]; I/O, mutable global reads and reentrant SealAttributes mutations are forbidden. The
* sink buffers a bounded atomic batch. If the extension throws, returns an invalid intent or
* exceeds the limit, its whole batch is discarded and diagnosed; other extensions still run.
*/
public interface PlatformExtension {
public fun id(): String
public fun priority(): Int
public fun project(context: PlatformProjectionContext, sink: PlatformProjectionSink)
}
public object PlatformExtensionContract {
@JvmStatic
public fun requireId(value: String): String = requireNamespacedId(value, "platform extension id")
@JvmStatic
public fun validatePriority(value: Int): Int = requirePriority(value)
}SealAttributeExtension.kt
kotlin
package cn.sealplugins.attributes.api.extension
import cn.sealplugins.attributes.api.definition.DefinitionRegistry
/**
* Startup-only entry point for one trusted attribute pack loaded from SealAttributes/extensions.
*
* Implementations are discovered through the standard JVM service-provider file for this
* interface. One JAR contains exactly one entry point and owns one provider namespace.
*/
public interface SealAttributeExtension {
/** Canonical namespace owned by every definition and behavior in this pack. */
public fun providerId(): String
/** SealAttributes API baseline required by this pack. */
public fun apiBaseline(): String
/** Registers every definition and behavior before the Core registry freezes. */
public fun register(registry: DefinitionRegistry)
}