174 lines
5.7 KiB
Rust
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,
|
|
})
|
|
}
|