add entity attributes

This commit is contained in:
Alexander Medvedev 2026-08-15 18:41:36 +02:00
parent 2f91c555a4
commit d6a49a2451
5 changed files with 450 additions and 8 deletions

56
v0.1/attributes.wit Normal file
View File

@ -0,0 +1,56 @@
package pumpkin:plugin@0.1.0;
interface attributes {
enum attribute {
air-drag-modifier,
armor,
armor-toughness,
attack-damage,
attack-knockback,
attack-speed,
below-name-distance,
block-break-speed,
block-interaction-range,
bounciness,
burning-time,
camera-distance,
explosion-knockback-resistance,
entity-interaction-range,
fall-damage-multiplier,
flying-speed,
follow-range,
friction-modifier,
gravity,
jump-strength,
knockback-resistance,
luck,
max-absorption,
max-health,
mining-efficiency,
movement-efficiency,
movement-speed,
name-tag-distance,
oxygen-bonus,
safe-fall-distance,
scale,
sneaking-speed,
spawn-reinforcements,
step-height,
submerged-mining-speed,
sweeping-damage-ratio,
tempt-range,
water-movement-efficiency,
waypoint-transmit-range,
waypoint-receive-range,
}
enum modifier-operation {
add,
multiply-base,
multiply-total,
}
record attribute-modifier {
id: string,
amount: f64,
operation: modifier-operation,
}
}

View File

@ -561,6 +561,226 @@ interface player {
is-trusted-skin: bool, is-trusted-skin: bool,
} }
/// Protocol-level disconnect reasons for Minecraft Bedrock Edition.
enum bedrock-disconnect-reason {
unknown,
cant-connect-no-internet,
no-permissions,
unrecoverable-error,
third-party-blocked,
third-party-no-internet,
third-party-bad-ip,
third-party-no-server-or-server-locked,
version-mismatch,
skin-issue,
invite-session-not-found,
edu-level-settings-missing,
local-server-not-found,
legacy-disconnect,
user-leave-game-attempted,
platform-locked-skins-error,
realms-world-unassigned,
realms-server-cant-connect,
realms-server-hidden,
realms-server-disabled-beta,
realms-server-disabled,
cross-platform-disabled,
cant-connect,
session-not-found,
client-settings-incompatible-with-server,
server-full,
invalid-platform-skin,
edition-version-mismatch,
edition-mismatch,
level-newer-than-exe-version,
no-fail-occurred,
banned-skin,
timeout,
server-not-found,
outdated-server,
outdated-client,
no-premium-platform,
multiplayer-disabled,
no-wifi,
world-corruption,
no-reason,
disconnected,
invalid-player,
logged-in-other-location,
server-id-conflict,
not-allowed,
not-authenticated,
invalid-tenant,
unknown-packet,
unexpected-packet,
invalid-command-request-packet,
host-suspended,
login-packet-no-request,
login-packet-no-cert,
missing-client,
kicked,
kicked-for-exploit,
kicked-for-idle,
resource-pack-problem,
incompatible-pack,
out-of-storage,
invalid-level,
disconnect-packet,
block-mismatch,
invalid-heights,
invalid-widths,
connection-lost,
zombie-connection,
shutdown,
reason-not-set,
loading-state-timeout,
resource-pack-loading-failed,
searching-for-session-loading-screen-failed,
nether-net-protocol-version,
subsystem-status-error,
empty-auth-from-discovery,
empty-url-from-discovery,
expired-auth-from-discovery,
unknown-signal-service-sign-in-failure,
xbl-join-lobby-failure,
unspecified-client-instance-disconnection,
nether-net-session-not-found,
nether-net-create-peer-connection,
nether-net-ice,
nether-net-connect-request,
nether-net-connect-response,
nether-net-negotiation-timeout,
nether-net-inactivity-timeout,
stale-connection-being-replaced,
realms-session-not-found,
bad-packet,
nether-net-failed-to-create-offer,
nether-net-failed-to-create-answer,
nether-net-failed-to-set-local-description,
nether-net-failed-to-set-remote-description,
nether-net-negotiation-timeout-waiting-for-response,
nether-net-negotiation-timeout-waiting-for-accept,
nether-net-incoming-connection-ignored,
nether-net-signaling-parsing-failure,
nether-net-signaling-unknown-error,
nether-net-signaling-unicast-delivery-failed,
nether-net-signaling-broadcast-delivery-failed,
nether-net-signaling-generic-delivery-failed,
editor-mismatch-editor-world,
editor-mismatch-vanilla-world,
world-transfer-not-primary-client,
request-server-shutdown,
client-game-setup-cancelled,
client-game-setup-failed,
no-venue,
nether-net-signaling-signin-failed,
session-access-denied,
service-signin-issue,
nether-net-no-signaling-channel,
nether-net-not-logged-in,
nether-net-client-signaling-error,
sub-client-login-disabled,
deep-link-trying-to-open-demo-world-while-signed-in,
async-join-task-denied,
realms-timeline-required,
guest-without-host,
failed-to-join-experience,
nether-net-data-channel-closed,
discovery-environment-mismatch,
host-without-keys,
host-signed-out,
script-watchdog-exception,
script-memory-limit-exceeded,
storage-low-during-gameplay,
storage-full-during-gameplay,
level-storage-corruption,
edition-mismatch-vanilla-to-edu,
edition-mismatch-edu-to-vanilla,
editor-mismatch-editor-to-vanilla,
editor-mismatch-vanilla-to-editor,
deny-listed,
nonce-missing,
nonce-not-found,
nonce-expired,
nonce-not-valid,
host-disconnected,
editor-join-intent-policy-failure,
nether-net-identity-not-allowed,
invalid-name,
expired-token,
host-accepts-no-type-of-auth,
not-authenticated-fast-fail,
editor-not-allowed,
}
/// Policy for tearing down the player's network connection.
enum socket-teardown-policy {
/// Send the disconnect packet and gracefully close the connection.
graceful,
/// Send the disconnect packet and close the socket immediately.
immediate-close,
/// Terminate the connection immediately without sending any disconnect packet.
drop-connection,
}
/// Options for disconnecting a Java Edition player.
record java-kick-options {
/// The formatted text component displayed on the Java disconnect screen.
reason: text-component,
/// Whether to log the kick in the server console (default: true).
log-to-console: bool,
/// How the connection is closed (default: graceful).
teardown-policy: socket-teardown-policy,
}
/// Options for disconnecting a Bedrock Edition player.
record bedrock-kick-options {
/// Protocol level disconnect code (default: kicked).
reason: bedrock-disconnect-reason,
/// Message displayed on the Bedrock disconnect screen (default: "").
message: string,
/// Whether to suppress the disconnect message on the client screen (default: false).
skip-message: bool,
/// Filtered message string for safety/parental filters (default: "").
filtered-message: string,
/// Whether to log the kick in the server console (default: true).
log-to-console: bool,
/// How the connection is closed (default: graceful).
teardown-policy: socket-teardown-policy,
}
/// Options for banning a player.
record ban-player-options {
/// Ban reason displayed to the player and stored in the ban list.
reason: option<text-component>,
/// Source or authority responsible for the ban (default: "Plugin").
source: option<string>,
/// Ban expiration in RFC-3339 format, if temporary.
expires-at-utc: option<string>,
/// Ban duration in seconds from now, if temporary.
duration-seconds: option<u64>,
/// Whether to immediately kick the player if currently online (default: true).
kick-if-online: bool,
/// Whether to log the ban action to the server console (default: true).
log-to-console: bool,
}
/// Options for banning an IP address.
record ban-ip-options {
/// Ban reason stored in the IP ban list.
reason: option<text-component>,
/// Source or authority responsible for the ban (default: "Plugin").
source: option<string>,
/// Ban expiration in RFC-3339 format, if temporary.
expires-at-utc: option<string>,
/// Ban duration in seconds from now, if temporary.
duration-seconds: option<u64>,
/// Whether to immediately kick all online players with this IP (default: true).
kick-matching-players: bool,
/// Whether to log the IP ban action to the server console (default: true).
log-to-console: bool,
}
/// A handle to a player on the server. /// A handle to a player on the server.
resource player { resource player {
/// Returns the player as an entity. /// Returns the player as an entity.
@ -642,18 +862,16 @@ interface player {
teleport: func (position: position, yaw: option<f32>, pitch: option<f32>, %world: %world); teleport: func (position: position, yaw: option<f32>, pitch: option<f32>, %world: %world);
/// Teleports the player to another world at a specific position. /// Teleports the player to another world at a specific position.
teleport-world: func (world-ref: %world, position: position, yaw: option<f32>, pitch: option<f32>); teleport-world: func (world-ref: %world, position: position, yaw: option<f32>, pitch: option<f32>);
/// Kicks the player from the server with the specified reason.
kick: func (message: text-component);
/// Forces the player to respawn. /// Forces the player to respawn.
respawn: func (); respawn: func ();
/// Opens a GUI for the player. /// Opens a GUI for the player.
open-gui: func (gui-ref: gui); open-gui: func (gui-ref: gui);
/// Bans the player with an optional reason. /// Bans the player with the specified options.
ban: func (reason: option<text-component>); ban: func (options: ban-player-options);
/// Bans the player's IP address with an optional reason. /// Bans the player's IP address with the specified options.
ban-ip: func (reason: option<text-component>); ban-ip: func (options: ban-ip-options);
/// Transfers the player to another server. /// Transfers the player to another server.
transfer: func (host: string, port: u16); transfer: func (host: string, port: u16);
@ -946,6 +1164,9 @@ interface player {
/// Clears all custom resource packs for the Java player. /// Clears all custom resource packs for the Java player.
clear-resource-packs: func(); clear-resource-packs: func();
/// Kicks the Java player with the specified options.
kick: func(options: java-kick-options);
} }
/// A handle to a player connected via the Bedrock Edition. /// A handle to a player connected via the Bedrock Edition.
@ -987,6 +1208,9 @@ interface player {
/// Sends resource packs information to the Bedrock player. /// Sends resource packs information to the Bedrock player.
send-resource-packs-info: func(info: bedrock-resource-packs-info); send-resource-packs-info: func(info: bedrock-resource-packs-info);
/// Kicks the Bedrock player with the specified options.
kick: func(options: bedrock-kick-options);
} }
/// Returns a list of all players in a specific world. /// Returns a list of all players in a specific world.

View File

@ -45,8 +45,10 @@ world plugin {
import status-effect; import status-effect;
/// Provides block entity types and instances. /// Provides block entity types and instances.
import block-entity; import block-entity;
// Provides 1 : 1 inter-plugin communication /// Provides 1 : 1 inter-plugin communication
import ipc; import ipc;
/// Provides entity attribute types and modifiers.
import attributes;
/// Provides player management. /// Provides player management.
import player; import player;

View File

@ -1,10 +1,119 @@
interface server { interface server {
use player.{player}; use player.{player, ban-player-options, ban-ip-options};
use common.{game-mode}; use common.{game-mode};
use %world.{%world}; use %world.{%world};
use text.{text-component}; use text.{text-component};
use uuid.{uuid}; use uuid.{uuid};
use recipe.{recipe-manager}; use recipe.{recipe-manager};
use permission.{permission-level};
/// Represents an operator entry in the ops configuration.
record op-entry {
uuid: uuid,
name: string,
level: permission-level,
bypasses-player-limit: bool,
}
/// Interface for querying and managing server operators.
resource op-manager {
/// Checks if a player UUID is currently an operator.
is-op: func(id: uuid) -> bool;
/// Retrieves the operator entry for a player UUID, if present.
get-op: func(id: uuid) -> option<op-entry>;
/// Gets the effective permission level for a player UUID (returns zero if not op).
get-permission-level: func(id: uuid) -> permission-level;
/// Grants operator status to a player (online or offline) with the specified level and bypass setting.
op-player: func(name: string, id: uuid, level: permission-level, bypasses-player-limit: bool);
/// Revokes operator status from a player (online or offline). Returns true if the player was previously op.
deop-player: func(id: uuid) -> bool;
/// Returns a list of all operator entries on the server.
list-ops: func() -> list<op-entry>;
}
/// Represents a banned player entry in the ban list.
record banned-player-entry {
uuid: uuid,
name: string,
created: string,
source: string,
expires: option<string>,
reason: string,
}
/// Represents a banned IP entry in the IP ban list.
record banned-ip-entry {
ip: string,
created: string,
source: string,
expires: option<string>,
reason: string,
}
/// Global manager for player and IP bans.
resource ban-manager {
/// Checks if a player UUID is currently banned.
is-player-banned: func(id: uuid) -> bool;
/// Retrieves the ban entry for a player UUID, if banned.
get-player-ban: func(id: uuid) -> option<banned-player-entry>;
/// Bans a player by name and UUID with the specified options (works for online and offline players).
ban-player: func(name: string, id: uuid, options: ban-player-options);
/// Removes a player ban by UUID. Returns true if the player was banned.
unban-player: func(id: uuid) -> bool;
/// Returns all currently active player bans.
list-player-bans: func() -> list<banned-player-entry>;
/// Checks if an IP address is currently banned.
is-ip-banned: func(ip: string) -> bool;
/// Retrieves the ban entry for an IP address, if banned.
get-ip-ban: func(ip: string) -> option<banned-ip-entry>;
/// Bans an IP address with the specified options.
ban-ip: func(ip: string, options: ban-ip-options);
/// Removes an IP ban. Returns true if the IP was banned.
unban-ip: func(ip: string) -> bool;
/// Returns all currently active IP bans.
list-ip-bans: func() -> list<banned-ip-entry>;
}
/// Represents a player entry in the server whitelist.
record whitelist-entry {
uuid: uuid,
name: string,
}
/// Global manager for the server whitelist.
resource whitelist-manager {
/// Returns whether the whitelist is currently enabled.
is-enabled: func() -> bool;
/// Enables or disables the server whitelist. If enabled and enforce-whitelist is set, kicks non-whitelisted players.
set-enabled: func(enabled: bool);
/// Checks if a player UUID is on the whitelist.
is-whitelisted: func(id: uuid) -> bool;
/// Adds a player to the whitelist (online or offline). Returns true if newly added.
add-player: func(name: string, id: uuid) -> bool;
/// Removes a player from the whitelist. Returns true if the player was on the whitelist.
remove-player: func(id: uuid) -> bool;
/// Returns all whitelisted player entries.
list-entries: func() -> list<whitelist-entry>;
}
/// Represents the difficulty setting of a Minecraft server. /// Represents the difficulty setting of a Minecraft server.
enum difficulty { enum difficulty {
@ -118,5 +227,14 @@ interface server {
/// Returns the recipe manager to register custom recipes. /// Returns the recipe manager to register custom recipes.
get-recipe-manager: func() -> recipe-manager; get-recipe-manager: func() -> recipe-manager;
/// Returns the operator manager to query or modify server operators.
get-op-manager: func() -> op-manager;
/// Returns the global ban manager for querying and modifying player and IP bans.
get-ban-manager: func() -> ban-manager;
/// Returns the global whitelist manager for querying and modifying the server whitelist.
get-whitelist-manager: func() -> whitelist-manager;
} }
} }

View File

@ -7,9 +7,23 @@ interface %world {
use sounds.{sound}; use sounds.{sound};
use entity-types.{entity-type}; use entity-types.{entity-type};
use biomes.{biome}; use biomes.{biome};
use attributes.{attribute, modifier-operation, attribute-modifier};
use item-stack.{item-stack};
use uuid.{uuid}; use uuid.{uuid};
/// Equipment slots available on living entities (mobs, armor stands, players).
enum equipment-slot {
main-hand,
off-hand,
feet,
legs,
chest,
head,
body,
saddle,
}
/// Defines how a block reacts when pushed by a piston. /// Defines how a block reacts when pushed by a piston.
enum piston-behavior { enum piston-behavior {
/// Normal behavior; the block can be pushed and pulled. /// Normal behavior; the block can be pushed and pulled.
@ -224,6 +238,34 @@ interface %world {
get-absorption: func() -> f32; get-absorption: func() -> f32;
set-absorption: func(amount: f32); set-absorption: func(amount: f32);
// Attributes
/// Returns the computed value of the specified attribute for this entity.
get-attribute-value: func(attr: attribute) -> f64;
/// Returns the base value of the specified attribute for this entity.
get-attribute-base: func(attr: attribute) -> f64;
/// Sets the base value of the specified attribute for this entity.
set-attribute-base: func(attr: attribute, value: f64);
/// Adds or replaces an attribute modifier for the specified attribute.
add-attribute-modifier: func(attr: attribute, modifier: attribute-modifier);
/// Removes an attribute modifier by its identifier.
remove-attribute-modifier: func(attr: attribute, id: string);
/// Returns all attribute modifiers currently attached to the specified attribute.
get-attribute-modifiers: func(attr: attribute) -> list<attribute-modifier>;
/// Resets the specified attribute to its default base value with no modifiers.
reset-attribute: func(attr: attribute);
/// Resets all attributes on this entity to their default base values and removes all modifiers.
reset-all-attributes: func();
// Equipment
/// Gets the item currently equipped in the specified slot, if any.
get-equipment: func(slot: equipment-slot) -> option<item-stack>;
/// Sets the item equipped in the specified slot and broadcasts the change to tracking clients.
set-equipment: func(slot: equipment-slot, stack: option<item-stack>);
/// Clears all equipment on this entity and broadcasts the removal.
clear-equipment: func();
get-age: func() -> s32; get-age: func() -> s32;
set-age: func(age: s32); set-age: func(age: s32);