PatchBukkit/rust/src/java/native_callbacks/world.rs
Alexander Medvedev e1fb278af0 fix: ci
2026-08-19 11:56:13 +02:00

174 lines
5.7 KiB
Rust

use crate::{
java::native_callbacks::CALLBACK_CONTEXT,
proto::patchbukkit::world::{
GetBlockDataRequest, GetBlockDataResponse, SetBlockDataRequest, SpawnParticleRequest,
},
};
pub fn ffi_native_bridge_get_block_data_impl(
request: GetBlockDataRequest,
) -> Option<GetBlockDataResponse> {
let ctx = CALLBACK_CONTEXT.get()?;
let uuid_str = &request.world_uuid.as_ref()?.value;
let world_uuid = uuid::Uuid::parse_str(uuid_str).ok()?;
let worlds = ctx.plugin_context.server.worlds.load_full();
let world = worlds
.iter()
.find(|w| w.uuid == world_uuid)
.cloned()
.or_else(|| worlds.first().cloned())?;
let pos = pumpkin_util::math::position::BlockPos::new(request.x, request.y, request.z);
let state_id = world.get_block_state(&pos).id;
let block = pumpkin_data::Block::from_state_id(state_id);
let key = block.name;
let block_state = if key.starts_with("minecraft:") {
key.to_string()
} else {
format!("minecraft:{key}")
};
Some(GetBlockDataResponse { block_state })
}
pub fn ffi_native_bridge_set_block_data_impl(request: SetBlockDataRequest) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
let uuid_str = &request.world_uuid.as_ref()?.value;
let world_uuid = uuid::Uuid::parse_str(uuid_str).ok()?;
let worlds = ctx.plugin_context.server.worlds.load_full();
let world = worlds
.iter()
.find(|w| w.uuid == world_uuid)
.cloned()
.or_else(|| worlds.first().cloned())?;
let pos = pumpkin_util::math::position::BlockPos::new(request.x, request.y, request.z);
let block_state_str = request.block_state;
let clean_key = block_state_str
.split('[')
.next()
.unwrap_or(&block_state_str)
.trim_start_matches("minecraft:");
let state_id = if let Some(b) = pumpkin_data::Block::from_registry_key(clean_key) {
b.default_state.id
} else {
pumpkin_data::BlockStateId::new_or_air(0)
};
ctx.runtime.spawn(async move {
world
.set_block_state(&pos, state_id, pumpkin::world::BlockFlags::NOTIFY_ALL)
.await;
});
Some(())
}
pub fn ffi_native_bridge_spawn_particle_impl(_request: SpawnParticleRequest) -> Option<()> {
Some(())
}
pub fn ffi_native_bridge_get_worlds_impl(
_request: crate::proto::patchbukkit::common::EmptyRequest,
) -> Option<crate::proto::patchbukkit::world::GetWorldsResponse> {
let ctx = CALLBACK_CONTEXT.get()?;
let worlds = ctx.plugin_context.server.worlds.load_full();
let world_uuids = worlds
.iter()
.map(|w| crate::proto::patchbukkit::common::Uuid {
value: w.uuid.to_string(),
})
.collect();
Some(crate::proto::patchbukkit::world::GetWorldsResponse { world_uuids })
}
pub fn ffi_native_bridge_get_world_border_impl(
request: crate::proto::patchbukkit::world::GetWorldBorderRequest,
) -> Option<crate::proto::patchbukkit::world::WorldBorderData> {
let ctx = CALLBACK_CONTEXT.get()?;
let uuid_str = &request.world_uuid.as_ref()?.value;
let world_uuid = uuid::Uuid::parse_str(uuid_str).ok()?;
let worlds = ctx.plugin_context.server.worlds.load_full();
let world = worlds
.iter()
.find(|w| w.uuid == world_uuid)
.cloned()
.or_else(|| worlds.first().cloned())?;
let wb = world.worldborder.blocking_lock();
Some(crate::proto::patchbukkit::world::WorldBorderData {
center_x: wb.center_x,
center_z: wb.center_z,
size: wb.old_diameter,
target_size: wb.new_diameter,
speed: wb.speed,
warning_time: wb.warning_time,
warning_blocks: wb.warning_blocks,
damage_per_block: wb.damage_per_block as f64,
damage_buffer: wb.buffer as f64,
max_center_coordinate: wb.portal_teleport_boundary,
})
}
pub fn ffi_native_bridge_set_world_border_impl(
request: crate::proto::patchbukkit::world::SetWorldBorderRequest,
) -> Option<()> {
let ctx = CALLBACK_CONTEXT.get()?;
let uuid_str = &request.world_uuid.as_ref()?.value;
let world_uuid = uuid::Uuid::parse_str(uuid_str).ok()?;
let border_data = request.border?;
let worlds = ctx.plugin_context.server.worlds.load_full();
let world = worlds
.iter()
.find(|w| w.uuid == world_uuid)
.cloned()
.or_else(|| worlds.first().cloned())?;
let mut wb = world.worldborder.blocking_lock();
wb.center_x = border_data.center_x;
wb.center_z = border_data.center_z;
wb.old_diameter = border_data.size;
wb.new_diameter = border_data.target_size;
wb.speed = border_data.speed;
wb.warning_time = border_data.warning_time;
wb.warning_blocks = border_data.warning_blocks;
wb.damage_per_block = border_data.damage_per_block as f32;
wb.buffer = border_data.damage_buffer as f32;
wb.portal_teleport_boundary = border_data.max_center_coordinate;
Some(())
}
pub fn ffi_native_bridge_get_world_info_impl(
request: crate::proto::patchbukkit::world::GetWorldInfoRequest,
) -> Option<crate::proto::patchbukkit::world::GetWorldInfoResponse> {
let ctx = CALLBACK_CONTEXT.get()?;
let uuid_str = &request.world_uuid.as_ref()?.value;
let world_uuid = uuid::Uuid::parse_str(uuid_str).ok()?;
let worlds = ctx.plugin_context.server.worlds.load_full();
let world = worlds
.iter()
.find(|w| w.uuid == world_uuid)
.cloned()
.or_else(|| worlds.first().cloned())?;
let min_height = world.dimension.min_y;
let height = world.dimension.height;
let max_height = min_height + height;
Some(crate::proto::patchbukkit::world::GetWorldInfoResponse {
min_height,
max_height,
height,
seed: 0,
})
}