Skip to content

Commit 0544fff

Browse files
committed
More server auth impl and fixes
1 parent 44c6e44 commit 0544fff

File tree

8 files changed

+349
-128
lines changed

8 files changed

+349
-128
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.cloudburstmc.api.event.player;
2+
3+
import org.cloudburstmc.api.event.Cancellable;
4+
import org.cloudburstmc.api.player.Player;
5+
6+
public final class PlayerToggleCrawlEvent extends PlayerEvent implements Cancellable {
7+
8+
private final boolean isCrawling;
9+
10+
public PlayerToggleCrawlEvent(Player player, boolean isCrawling) {
11+
super(player);
12+
this.isCrawling = isCrawling;
13+
}
14+
15+
public boolean isCrawling() {
16+
return this.isCrawling;
17+
}
18+
}

api/src/main/java/org/cloudburstmc/api/level/Level.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,6 @@ default ItemStack useBreakOn(Vector3i pos, ItemStack item, Player player, boolea
8585

8686
ItemStack useBreakOn(Vector3i pos, Direction face, ItemStack item, Player player, boolean createParticles);
8787

88-
default ItemStack useItemOn(Vector3i vector, ItemStack item, Direction face, Vector3f clickPos) {
89-
return this.useItemOn(vector, item, face, clickPos, null);
90-
}
91-
92-
default ItemStack useItemOn(Vector3i vector, ItemStack item, Direction face, Vector3f clickPos, Player player) {
93-
return this.useItemOn(vector, item, face, clickPos, player, true);
94-
}
95-
96-
ItemStack useItemOn(Vector3i vector, ItemStack item, Direction face, Vector3f clickPos, Player player, boolean playSound);
97-
9888
Map<Long, ? extends Player> getPlayers();
9989

10090
int getBiomeId(int x, int z);

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ fastutil-reference-reference-maps = { group = "org.cloudburstmc.fastutil.maps",
5656
fastutil-short-sets = { group = "org.cloudburstmc.fastutil.sets", name = "short-sets", version.ref = "fastutil" }
5757
fastutil-short-object-maps = { group = "org.cloudburstmc.fastutil.maps", name = "short-object-maps", version.ref = "fastutil" }
5858

59-
bedrock-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version = "3.0.0.Beta12-20260209.180455-4" }
59+
bedrock-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version = "3.0.0.Beta12-20260304.203629-5" }
6060
netty-transport-native-epoll = { group = "io.netty", name = "netty-transport-native-epoll", version = "4.1.101.Final" }
6161
netty-transport-native-kqueue = { group = "io.netty", name = "netty-transport-native-kqueue", version = "4.1.101.Final" }
6262
block-state-updater = { group = "org.cloudburstmc", name = "block-state-updater", version = "1.21.110-SNAPSHOT" }

server/src/main/java/org/cloudburstmc/server/container/CloudContainer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ public ItemStack[] addItem(ItemStack... slots) {
306306
ItemStack item = this.getItem(i);
307307
if (item.isEmpty()) {
308308
emptySlots.add(i);
309+
continue;
309310
}
310311

311312
int maxStack = this.itemRegistry.getComponent(item.getType(), ItemComponents.GET_MAX_STACK_SIZE).execute(item);

server/src/main/java/org/cloudburstmc/server/entity/EntityHuman.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,4 +457,11 @@ public void setGliding() {
457457
this.setGliding(true);
458458
}
459459

460+
public boolean isCrawling() {
461+
return this.data.getFlag(CRAWLING);
462+
}
463+
464+
public void setCrawling(boolean value) {
465+
this.data.setFlag(CRAWLING, value);
466+
}
460467
}

server/src/main/java/org/cloudburstmc/server/level/CloudLevel.java

Lines changed: 91 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,96 +1723,106 @@ public void dropExpOrb(Vector3f source, int exp, Vector3f motion, int delay) {
17231723
}
17241724
}
17251725

1726-
public ItemStack useItemOn(Vector3i vector, ItemStack item, Direction face, Vector3f clickPos) {
1727-
return this.useItemOn(vector, item, face, clickPos, null);
1728-
}
1729-
1730-
public ItemStack useItemOn(Vector3i vector, ItemStack item, Direction face, Vector3f clickPos, Player player) {
1731-
return this.useItemOn(vector, item, face, clickPos, player, true);
1732-
}
1733-
1734-
1735-
public ItemStack useItemOn(Vector3i vector, ItemStack item, Direction face, Vector3f clickPos, Player player, boolean playSound) {
1736-
if (item == null || item.isEmpty()) {
1737-
item = ItemStack.EMPTY;
1738-
}
1739-
Block target = this.getBlock(vector);
1726+
/**
1727+
* Attempts to interact with the target block.
1728+
* Does not require an item in hand.
1729+
*
1730+
* @return true if the block consumed the interaction
1731+
*/
1732+
public boolean tryUseBlock(Block target, Block side, Direction face, ItemStack item, Player player) {
17401733
ComponentMap targetBehaviors = target.getComponents();
1741-
Block block = target.getSide(face);
1742-
ComponentMap behaviors = block.getComponents();
1743-
Vector3i blockPos = block.getPosition();
1744-
1745-
if (blockPos.getY() >= 320 || blockPos.getY() < -64) {
1746-
return null;
1747-
}
17481734

1749-
if (target.getState().getType() == BlockTypes.AIR) {
1750-
return null;
1751-
}
1752-
1753-
ComponentMap itemBehaviors = item.isEmpty() ? null : this.itemRegistry.getComponents(item.getType());
17541735
if (player != null) {
17551736
PlayerInteractEvent ev = new PlayerInteractEvent(player, item, target, face, PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK);
1756-
17571737
if (player.getGamemode() == GameMode.SPECTATOR) {
17581738
ev.setCancelled();
17591739
}
17601740

17611741
if (!player.isOp() && isInSpawnRadius(target.getPosition())) {
17621742
ev.setCancelled();
17631743
}
1764-
17651744
this.server.getEventManager().fire(ev);
1766-
if (!ev.isCancelled()) {
1767-
targetBehaviors.get(BlockComponents.ON_TICK).execute(target, new Random());
17681745

1769-
boolean blockUsed = (!player.isSneaking() || player.getInventory().getSelectedItem().isEmpty()) && targetBehaviors.get(BlockComponents.CAN_BE_USED).execute(target) && targetBehaviors.get(BlockComponents.USE).execute(target, player, face);
1770-
if (blockUsed) { //TODO: update the item from the behavior
1771-
if (this.itemRegistry.getComponent(item.getType(), ItemComponents.IS_TOOL).execute(item) && item.get(ItemKeys.DAMAGE) >= itemBehaviors.get(ItemComponents.GET_MAX_DAMAGE).execute(item)) {
1772-
item = ItemStack.EMPTY;
1773-
}
1774-
return item;
1775-
}
1776-
1777-
boolean itemCanBeUsed = itemBehaviors != null && itemBehaviors.get(ItemComponents.CAN_BE_USED).execute(item);
1778-
if (itemCanBeUsed) {
1779-
var result = itemBehaviors.get(ItemComponents.USE_ON).execute(item, player, target.getPosition(), face, clickPos);
1780-
// if (item.getCount() <= 0) {
1781-
// item = ItemStack.AIR;
1782-
// return item;
1783-
// }
1784-
item = Objects.requireNonNullElse(result, ItemStack.EMPTY);
1785-
}
1786-
} else {
1787-
if (item.getType() == ItemTypes.BUCKET && item.get(ItemKeys.BUCKET_DATA) == Bucket.WATER) {
1788-
((CloudLevel) player.getLevel()).sendBlocks(new Player[]{player}, new Block[]{new CloudBlock(this, block.getPosition(), new BlockState[]{BlockStates.AIR, BlockStates.AIR})}, UpdateBlockPacket.FLAG_ALL_PRIORITY);
1746+
if (ev.isCancelled()) {
1747+
if (!item.isEmpty() && item.getType() == ItemTypes.BUCKET && item.get(ItemKeys.BUCKET_DATA) == Bucket.WATER) {
1748+
sendBlocks(new Player[]{player}, new Block[]{new CloudBlock(this, side.getPosition(), new BlockState[]{BlockStates.AIR, BlockStates.AIR})}, UpdateBlockPacket.FLAG_ALL_PRIORITY);
17891749
}
1790-
return null;
1791-
}
1792-
} else if (targetBehaviors.get(BlockComponents.CAN_BE_USED).execute(target) && targetBehaviors.get(BlockComponents.USE).execute(target, null, face)) {
1793-
if (this.itemRegistry.getComponent(item.getType(), ItemComponents.IS_TOOL).execute(item) &&
1794-
item.get(ItemKeys.DAMAGE) >= itemBehaviors.get(ItemComponents.GET_MAX_DAMAGE).execute(item)) {
1795-
item = ItemStack.EMPTY; //TODO: update the item from the behavior
1750+
return false;
17961751
}
1797-
return item;
1752+
1753+
targetBehaviors.get(BlockComponents.ON_TICK).execute(target, new Random());
1754+
1755+
boolean canUse = (!player.isSneaking() || player.getInventory().getSelectedItem().isEmpty()) && targetBehaviors.get(BlockComponents.CAN_BE_USED).execute(target);
1756+
return canUse && targetBehaviors.get(BlockComponents.USE).execute(target, player, face);
1757+
} else {
1758+
return targetBehaviors.get(BlockComponents.CAN_BE_USED).execute(target) && targetBehaviors.get(BlockComponents.USE).execute(target, null, face);
1759+
}
1760+
}
1761+
1762+
/**
1763+
* Attempts to activate the item's USE_ON handler against the target block.
1764+
* Requires a non-empty item.
1765+
*
1766+
* @return the updated ItemStack if the item was consumed/used, or null if not handled
1767+
*/
1768+
public ItemStack tryUseItem(Block target, Direction face, Vector3f clickPos, ItemStack item, Player player) {
1769+
ComponentMap itemBehaviors = this.itemRegistry.getComponents(item.getType());
1770+
if (itemBehaviors == null || !itemBehaviors.get(ItemComponents.CAN_BE_USED).execute(item)) {
1771+
return null;
1772+
}
1773+
1774+
ItemStack result = itemBehaviors.get(ItemComponents.USE_ON).execute(item, player, target.getPosition(), face, clickPos);
1775+
return Objects.requireNonNullElse(result, item);
1776+
}
1777+
1778+
/**
1779+
* Attempts to activate an item used in the air.
1780+
* Calls the item's {@code USE_ON} handler with the player's own position as the notional target.
1781+
*
1782+
* @return the updated {@link ItemStack} if the item was consumed/activated, or {@code null} if not handled
1783+
*/
1784+
public ItemStack tryActivateItem(ItemStack item, Player player) {
1785+
ComponentMap itemBehaviors = this.itemRegistry.getComponents(item.getType());
1786+
if (itemBehaviors == null || !itemBehaviors.get(ItemComponents.CAN_BE_USED).execute(item)) {
1787+
return null;
17981788
}
1789+
1790+
Vector3i playerBlockPos = player.getPosition().toInt();
1791+
ItemStack result = itemBehaviors.get(ItemComponents.USE_ON).execute(item, player, playerBlockPos, null, null);
1792+
return Objects.requireNonNullElse(result, item);
1793+
}
1794+
1795+
/**
1796+
* Attempts to place a block from the held item against the target block.
1797+
* Requires a non-empty item.
1798+
*
1799+
* @return the updated ItemStack after placement, or null if placement was rejected
1800+
*/
1801+
public ItemStack tryPlaceBlock(Block target, Block side, Direction face, Vector3f clickPos, ItemStack item, Player player, boolean playSound) {
1802+
ComponentMap itemBehaviors = this.itemRegistry.getComponents(item.getType());
1803+
if (itemBehaviors == null) {
1804+
return null;
1805+
}
1806+
17991807
@SuppressWarnings("unchecked")
18001808
BlockState hand = ((Optional<BlockState>) itemBehaviors.get(ItemComponents.GET_BLOCK).execute(item)).orElse(null);
1801-
18021809
if (hand == null) {
18031810
return null;
18041811
}
18051812

1806-
if (!(this.blockRegistry.getComponent(block.getState().getType(), BlockComponents.REPLACEABLE).get()
1807-
|| (hand.hasTag(BlockTags.SLAB) && (block.getState().hasTag(BlockTags.SLAB) || target.getState().hasTag(BlockTags.SLAB))))) {
1813+
Vector3i blockPos = side.getPosition();
1814+
if (!(this.blockRegistry.getComponent(side.getState().getType(), BlockComponents.REPLACEABLE).get()
1815+
|| (hand.hasTag(BlockTags.SLAB) && (side.getState().hasTag(BlockTags.SLAB) || target.getState().hasTag(BlockTags.SLAB))))) {
18081816
return null;
18091817
}
18101818

1819+
Block block = side;
18111820
if (this.blockRegistry.getComponent(target.getState().getType(), BlockComponents.REPLACEABLE).get()) {
18121821
block = target;
1822+
blockPos = block.getPosition();
18131823
}
18141824

1815-
var handBehaviors = this.blockRegistry.getComponents(hand.getType());
1825+
ComponentMap handBehaviors = this.blockRegistry.getComponents(hand.getType());
18161826
AxisAlignedBB handBB = handBehaviors.get(BlockComponents.GET_BOUNDING_BOX).execute(hand);
18171827

18181828
if (!handBehaviors.get(BlockComponents.CAN_PASS_THROUGH).execute(hand) && handBB != null) {
@@ -1842,7 +1852,7 @@ public ItemStack useItemOn(Vector3i vector, ItemStack item, Direction face, Vect
18421852
}
18431853

18441854
if (realCount > 0) {
1845-
return null; // Entity in block
1855+
return null;
18461856
}
18471857
}
18481858

@@ -1851,69 +1861,63 @@ public ItemStack useItemOn(Vector3i vector, ItemStack item, Direction face, Vect
18511861
if (player.getGamemode() == GameMode.ADVENTURE && !itemRegistry.getComponent(item.getType(), ItemComponents.CAN_BE_PLACED_ON).execute(item, target)) {
18521862
event.setCancelled();
18531863
}
1864+
18541865
if (!player.isOp() && isInSpawnRadius(target.getPosition())) {
18551866
event.setCancelled();
18561867
}
1868+
18571869
this.server.getEventManager().fire(event);
18581870
if (event.isCancelled()) {
18591871
return null;
18601872
}
18611873
}
18621874

1863-
// Behavior liquidBehavior = block.getState().getBehavior();
1864-
var blockBehaviors = blockRegistry.getComponents(block.getState().getType());
1875+
ComponentMap blockBehaviors = blockRegistry.getComponents(block.getState().getType());
18651876
BlockState air = block.getExtra();
1877+
Vector3i waterlogPos = null;
18661878

1867-
Vector3i pos = null;
1868-
1869-
// TODO Water logging?
1870-
if (air == BlockStates.AIR && this.blockRegistry.getComponent(block.getState().getType(), BlockComponents.LIQUID).get() && this.blockRegistry.getComponent(block.getState().getType(), BlockComponents.USES_WATERLOGGING).get()
1871-
&& (block.getState().ensureTrait(BlockTraits.FLUID_LEVEL) == 0) // Remove this line when MCPE-33345 is resolved
1879+
// TODO: Water logging
1880+
if (air == BlockStates.AIR
1881+
&& this.blockRegistry.getComponent(block.getState().getType(), BlockComponents.LIQUID).get()
1882+
&& this.blockRegistry.getComponent(block.getState().getType(), BlockComponents.USES_WATERLOGGING).get()
1883+
&& (block.getState().ensureTrait(BlockTraits.FLUID_LEVEL) == 0) // Remove when MCPE-33345 is resolved
18721884
) {
1873-
pos = block.getPosition();
1874-
1885+
waterlogPos = block.getPosition();
18751886
block.set(block.getState(), 1, false, false);
18761887
block.set(air, false, false);
1877-
18781888
this.scheduleUpdate(block, 1);
18791889
}
18801890

18811891
try {
18821892
if (!handBehaviors.get(BlockComponents.ON_PLACE).execute(hand, player, block.getPosition(), face, clickPos)) {
1883-
if (pos != null) {
1884-
this.setBlockState(pos, 0, block.getState(), false, false);
1885-
this.setBlockState(pos, 1, air, false, false);
1893+
if (waterlogPos != null) {
1894+
this.setBlockState(waterlogPos, 0, block.getState(), false, false);
1895+
this.setBlockState(waterlogPos, 1, air, false, false);
18861896
}
18871897
return null;
18881898
}
18891899
} catch (Exception e) {
1890-
if (pos != null) {
1891-
this.setBlockState(pos, 0, block.getState(), false, false);
1892-
this.setBlockState(pos, 1, air, false, false);
1900+
if (waterlogPos != null) {
1901+
this.setBlockState(waterlogPos, 0, block.getState(), false, false);
1902+
this.setBlockState(waterlogPos, 1, air, false, false);
18931903
}
18941904
throw e;
18951905
}
18961906

1897-
if (player != null) {
1898-
if (!player.isCreative()) {
1899-
item = item.decreaseCount();
1900-
}
1907+
if (player != null && !player.isCreative()) {
1908+
item = item.decreaseCount();
19011909
}
19021910

19031911
if (playSound) {
19041912
this.addLevelSoundEvent(block.getPosition(), SoundEvent.PLACE, CloudBlockRegistry.REGISTRY.getRuntimeId(hand));
19051913
}
19061914

1907-
if (item.getCount() <= 0) {
1908-
item = ItemStack.EMPTY;
1909-
}
1910-
return item;
1915+
return item.getCount() <= 0 ? ItemStack.EMPTY : item;
19111916
}
19121917

19131918
public boolean isInSpawnRadius(Vector3i vector3) {
19141919
int distance = this.server.getSpawnRadius();
19151920
if (distance > -1) {
1916-
19171921
Vector2i t = vector3.toVector2(true);
19181922
Vector2i s = this.getSpawnLocation().toInt().toVector2(true);
19191923
return t.distance(s) <= distance;

server/src/main/java/org/cloudburstmc/server/network/inventory/ItemStackRequestActionHandler.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,16 @@ public void handleAction(ItemStackRequestAction action) {
5353
case DROP -> handleDrop((DropAction) action);
5454
case DESTROY -> handleDestroy((DestroyAction) action);
5555
case CRAFT_CREATIVE -> handleCraftCreative((CraftCreativeAction) action);
56-
case CRAFT_RESULTS_DEPRECATED, CREATE, CONSUME -> {
56+
case MINE_BLOCK, CRAFT_RESULTS_DEPRECATED, CREATE, CONSUME -> {
5757
}
58-
default -> log.debug("Unhandled inventory action type: {}", action.getType());
58+
case CRAFT_RECIPE, CRAFT_RECIPE_AUTO, CRAFT_RECIPE_OPTIONAL,
59+
CRAFT_REPAIR_AND_DISENCHANT,
60+
CRAFT_LOOM, CRAFT_NON_IMPLEMENTED_DEPRECATED,
61+
BEACON_PAYMENT, LAB_TABLE_COMBINE -> {
62+
log.debug("Unimplemented inventory action type {} for {}", action.getType(), player.getName());
63+
requestFailed = true;
64+
}
65+
default -> log.debug("Unknown inventory action type: {}", action.getType());
5966
}
6067
} catch (Exception e) {
6168
log.warn("Failed to handle inventory action {} for {}: {}",

0 commit comments

Comments
 (0)