mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-23 00:49:20 +00:00
@@ -18,6 +18,7 @@ dependencies {
|
|||||||
implementation(project(":core"))
|
implementation(project(":core"))
|
||||||
implementation(project(":bukkit"))
|
implementation(project(":bukkit"))
|
||||||
implementation(project(":bukkit:legacy"))
|
implementation(project(":bukkit:legacy"))
|
||||||
|
implementation(project(":bukkit:compatibility"))
|
||||||
|
|
||||||
implementation("net.kyori:adventure-platform-bukkit:${rootProject.properties["adventure_platform_version"]}")
|
implementation("net.kyori:adventure-platform-bukkit:${rootProject.properties["adventure_platform_version"]}")
|
||||||
implementation("com.saicone.rtag:rtag-item:${rootProject.properties["rtag_version"]}")
|
implementation("com.saicone.rtag:rtag-item:${rootProject.properties["rtag_version"]}")
|
||||||
|
|||||||
@@ -92,8 +92,6 @@ resource-pack:
|
|||||||
suffix: "minecraft/items"
|
suffix: "minecraft/items"
|
||||||
- type: parent_path_suffix
|
- type: parent_path_suffix
|
||||||
suffix: "minecraft/models/item"
|
suffix: "minecraft/models/item"
|
||||||
- type: parent_path_suffix
|
|
||||||
suffix: "minecraft/atlases"
|
|
||||||
resolution:
|
resolution:
|
||||||
type: merge_json
|
type: merge_json
|
||||||
deeply: true
|
deeply: true
|
||||||
@@ -117,6 +115,11 @@ resource-pack:
|
|||||||
resolution:
|
resolution:
|
||||||
type: merge_json
|
type: merge_json
|
||||||
deeply: false
|
deeply: false
|
||||||
|
- term:
|
||||||
|
type: parent_path_suffix
|
||||||
|
suffix: "minecraft/atlases"
|
||||||
|
resolution:
|
||||||
|
type: merge_atlas
|
||||||
|
|
||||||
item:
|
item:
|
||||||
# Add a <!i> tag on item name and lore
|
# Add a <!i> tag on item name and lore
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
items:
|
items:
|
||||||
default:chinese_lantern:
|
default:chinese_lantern:
|
||||||
material: paper
|
material: paper
|
||||||
custom-model-data: 3001
|
custom-model-data: 3000
|
||||||
data:
|
data:
|
||||||
item-name: "<!i><i18n:item.chinese_lantern>"
|
item-name: "<!i><i18n:item.chinese_lantern>"
|
||||||
model:
|
model:
|
||||||
|
|||||||
@@ -57,3 +57,4 @@ categories:
|
|||||||
list:
|
list:
|
||||||
- default:chinese_lantern
|
- default:chinese_lantern
|
||||||
- default:fairy_flower
|
- default:fairy_flower
|
||||||
|
- default:reed
|
||||||
@@ -2,6 +2,7 @@ i18n:
|
|||||||
en:
|
en:
|
||||||
item.chinese_lantern: "Chinese Lantern"
|
item.chinese_lantern: "Chinese Lantern"
|
||||||
item.fairy_flower: "Fairy Flower"
|
item.fairy_flower: "Fairy Flower"
|
||||||
|
item.reed: "Reed"
|
||||||
item.bench: "Bench"
|
item.bench: "Bench"
|
||||||
item.table_lamp: "Table Lamp"
|
item.table_lamp: "Table Lamp"
|
||||||
item.wooden_chair: "Wooden Chair"
|
item.wooden_chair: "Wooden Chair"
|
||||||
@@ -36,6 +37,7 @@ i18n:
|
|||||||
zh_cn:
|
zh_cn:
|
||||||
item.chinese_lantern: "灯笼"
|
item.chinese_lantern: "灯笼"
|
||||||
item.fairy_flower: "仙灵花"
|
item.fairy_flower: "仙灵花"
|
||||||
|
item.reed: "芦苇"
|
||||||
item.bench: "长椅"
|
item.bench: "长椅"
|
||||||
item.table_lamp: "台灯"
|
item.table_lamp: "台灯"
|
||||||
item.wooden_chair: "木椅"
|
item.wooden_chair: "木椅"
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ items:
|
|||||||
# To prevent errors, we use tree feature from vanilla here
|
# To prevent errors, we use tree feature from vanilla here
|
||||||
feature: minecraft:fancy_oak
|
feature: minecraft:fancy_oak
|
||||||
bone-meal-success-chance: 0.45
|
bone-meal-success-chance: 0.45
|
||||||
tags:
|
bottom-block-tags:
|
||||||
- minecraft:dirt
|
- minecraft:dirt
|
||||||
- minecraft:farmland
|
- minecraft:farmland
|
||||||
- minecraft:sand
|
- minecraft:sand
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
items:
|
items:
|
||||||
default:fairy_flower:
|
default:fairy_flower:
|
||||||
material: paper
|
material: paper
|
||||||
custom-model-data: 3000
|
custom-model-data: 3001
|
||||||
data:
|
data:
|
||||||
item-name: "<!i><i18n:item.fairy_flower>"
|
item-name: "<!i><i18n:item.fairy_flower>"
|
||||||
model:
|
model:
|
||||||
@@ -11,6 +11,18 @@ items:
|
|||||||
behavior:
|
behavior:
|
||||||
type: block_item
|
type: block_item
|
||||||
block: default:fairy_flower
|
block: default:fairy_flower
|
||||||
|
default:reed:
|
||||||
|
material: paper
|
||||||
|
custom-model-data: 3002
|
||||||
|
data:
|
||||||
|
item-name: "<!i><i18n:item.reed>"
|
||||||
|
model:
|
||||||
|
template: default:model/simplified_generated
|
||||||
|
arguments:
|
||||||
|
path: "minecraft:item/custom/reed"
|
||||||
|
behavior:
|
||||||
|
type: liquid_collision_block_item
|
||||||
|
block: default:reed
|
||||||
blocks:
|
blocks:
|
||||||
default:fairy_flower:
|
default:fairy_flower:
|
||||||
settings:
|
settings:
|
||||||
@@ -19,6 +31,7 @@ blocks:
|
|||||||
- default:sound/grass
|
- default:sound/grass
|
||||||
overrides:
|
overrides:
|
||||||
item: default:fairy_flower
|
item: default:fairy_flower
|
||||||
|
push-reaction: DESTROY
|
||||||
behavior:
|
behavior:
|
||||||
type: bush_block
|
type: bush_block
|
||||||
loot:
|
loot:
|
||||||
@@ -27,7 +40,7 @@ blocks:
|
|||||||
item: default:fairy_flower
|
item: default:fairy_flower
|
||||||
state:
|
state:
|
||||||
id: 0
|
id: 0
|
||||||
state: tripwire:0
|
state: sugar_cane:0
|
||||||
models:
|
models:
|
||||||
- path: "minecraft:block/custom/fairy_flower_1"
|
- path: "minecraft:block/custom/fairy_flower_1"
|
||||||
weight: 100
|
weight: 100
|
||||||
@@ -49,3 +62,23 @@ blocks:
|
|||||||
parent: "minecraft:block/custom/fairy_flower_1"
|
parent: "minecraft:block/custom/fairy_flower_1"
|
||||||
textures:
|
textures:
|
||||||
"0": "minecraft:block/custom/fairy_flower_4"
|
"0": "minecraft:block/custom/fairy_flower_4"
|
||||||
|
default:reed:
|
||||||
|
settings:
|
||||||
|
template:
|
||||||
|
- default:hardness/none
|
||||||
|
- default:sound/grass
|
||||||
|
overrides:
|
||||||
|
item: default:reed
|
||||||
|
push-reaction: DESTROY
|
||||||
|
behavior:
|
||||||
|
type: on_liquid_block
|
||||||
|
liquid-type: water
|
||||||
|
loot:
|
||||||
|
template: "default:loot_table/basic"
|
||||||
|
arguments:
|
||||||
|
item: default:reed
|
||||||
|
state:
|
||||||
|
id: 1
|
||||||
|
state: sugar_cane:1
|
||||||
|
model:
|
||||||
|
path: "minecraft:block/custom/reed"
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
"from": [7, 28, 7],
|
"from": [7, 28, 7],
|
||||||
"to": [9, 30, 9],
|
"to": [9, 30, 9],
|
||||||
"rotation": {"angle": 0, "axis": "y", "origin": [7, 28, 7]},
|
"rotation": {"angle": 0, "axis": "y", "origin": [7, 28, 7]},
|
||||||
|
"shade": false,
|
||||||
"faces": {
|
"faces": {
|
||||||
"north": {"uv": [15, 0, 16, 1], "texture": "#0"},
|
"north": {"uv": [15, 0, 16, 1], "texture": "#0"},
|
||||||
"east": {"uv": [15, 0, 16, 1], "texture": "#0"},
|
"east": {"uv": [15, 0, 16, 1], "texture": "#0"},
|
||||||
@@ -43,15 +44,5 @@
|
|||||||
"down": {"uv": [15, 0, 16, 1], "texture": "#0"}
|
"down": {"uv": [15, 0, 16, 1], "texture": "#0"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"display": {
|
|
||||||
"head": {
|
|
||||||
"translation": [0, 18.5, 0]
|
|
||||||
},
|
|
||||||
"fixed": {
|
|
||||||
"rotation": [-90, 0, 0],
|
|
||||||
"translation": [0, 0, -15],
|
|
||||||
"scale": [2, 2, 2]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"ambientocclusion": false,
|
||||||
|
"textures": {
|
||||||
|
"0": "block/custom/reed",
|
||||||
|
"particle": "block/custom/reed"
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"from": [-0.5, -3, 0.25],
|
||||||
|
"to": [19.5, 29, 0.25],
|
||||||
|
"shade": false,
|
||||||
|
"rotation": {"angle": -45, "axis": "y", "origin": [-0.5, -3, 2.25]},
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [0, 0, 10, 16], "texture": "#0"},
|
||||||
|
"east": {"uv": [0, 0, 0, 16], "texture": "#0"},
|
||||||
|
"south": {"uv": [0, 0, 10, 16], "texture": "#0"},
|
||||||
|
"west": {"uv": [0, 0, 0, 16], "texture": "#0"},
|
||||||
|
"up": {"uv": [0, 0, 0, 10], "rotation": 270, "texture": "#0"},
|
||||||
|
"down": {"uv": [0, 0, 0, 10], "rotation": 90, "texture": "#0"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": [2, -3, 14.75],
|
||||||
|
"to": [22, 29, 14.75],
|
||||||
|
"shade": false,
|
||||||
|
"rotation": {"angle": 45, "axis": "y", "origin": [2, -3, 16.75]},
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [0, 0, 10, 16], "texture": "#0"},
|
||||||
|
"east": {"uv": [0, 0, 0, 16], "texture": "#0"},
|
||||||
|
"south": {"uv": [0, 0, 10, 16], "texture": "#0"},
|
||||||
|
"west": {"uv": [0, 0, 0, 16], "texture": "#0"},
|
||||||
|
"up": {"uv": [0, 0, 0, 10], "rotation": 270, "texture": "#0"},
|
||||||
|
"down": {"uv": [0, 0, 0, 10], "rotation": 90, "texture": "#0"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"texture_size": [64, 64],
|
|
||||||
"textures": {
|
"textures": {
|
||||||
"0": "item/custom/bench",
|
"0": "item/custom/bench",
|
||||||
"particle": "item/custom/bench"
|
"particle": "item/custom/bench"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"texture_size": [32, 32],
|
|
||||||
"textures": {
|
"textures": {
|
||||||
"0": "item/custom/table_lamp",
|
"0": "item/custom/table_lamp",
|
||||||
"particle": "item/custom/table_lamp"
|
"particle": "item/custom/table_lamp"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
"texture_size": [32, 32],
|
|
||||||
"textures": {
|
"textures": {
|
||||||
"0": "item/custom/wooden_chair",
|
"0": "item/custom/wooden_chair",
|
||||||
"particle": "item/custom/wooden_chair"
|
"particle": "item/custom/wooden_chair"
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 695 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
@@ -15,6 +15,7 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
compileOnly(project(":core"))
|
compileOnly(project(":core"))
|
||||||
compileOnly(project(":shared"))
|
compileOnly(project(":shared"))
|
||||||
|
compileOnly(project(":bukkit:compatibility"))
|
||||||
compileOnly(project(":bukkit:legacy"))
|
compileOnly(project(":bukkit:legacy"))
|
||||||
// Anti Grief
|
// Anti Grief
|
||||||
compileOnly("com.github.Xiao-MoMi:AntiGriefLib:${rootProject.properties["anti_grief_version"]}")
|
compileOnly("com.github.Xiao-MoMi:AntiGriefLib:${rootProject.properties["anti_grief_version"]}")
|
||||||
|
|||||||
28
bukkit/compatibility/build.gradle.kts
Normal file
28
bukkit/compatibility/build.gradle.kts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
|
maven("https://r.irepo.space/maven/")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly(project(":core"))
|
||||||
|
// Platform
|
||||||
|
compileOnly("dev.folia:folia-api:${rootProject.properties["paper_version"]}-R0.1-SNAPSHOT")
|
||||||
|
// NeigeItems
|
||||||
|
compileOnly("pers.neige.neigeitems:NeigeItems:1.21.42")
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
|
toolchain {
|
||||||
|
languageVersion = JavaLanguageVersion.of(21)
|
||||||
|
}
|
||||||
|
withSourcesJar()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<JavaCompile> {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
options.release.set(21)
|
||||||
|
dependsOn(tasks.clean)
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package net.momirealms.craftengine.bukkit.compatibility.item;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.core.item.ExternalItemProvider;
|
||||||
|
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import pers.neige.neigeitems.manager.ItemManager;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class NeigeItemsProvider implements ExternalItemProvider<ItemStack> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String plugin() {
|
||||||
|
return "NeigeItems";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack build(String id, ItemBuildContext context) {
|
||||||
|
return ItemManager.INSTANCE.getItemStack(id, Optional.ofNullable(context.player()).map(it -> (Player) it.platformPlayer()).orElse(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,12 +5,12 @@ import net.momirealms.craftengine.core.util.Key;
|
|||||||
import net.momirealms.craftengine.shared.block.EmptyBlockBehavior;
|
import net.momirealms.craftengine.shared.block.EmptyBlockBehavior;
|
||||||
|
|
||||||
public class BukkitBlockBehaviors extends BlockBehaviors {
|
public class BukkitBlockBehaviors extends BlockBehaviors {
|
||||||
public static final Key EMPTY = Key.from("craftengine:empty");
|
|
||||||
public static final Key BUSH_BLOCK = Key.from("craftengine:bush_block");
|
public static final Key BUSH_BLOCK = Key.from("craftengine:bush_block");
|
||||||
public static final Key FALLING_BLOCK = Key.from("craftengine:falling_block");
|
public static final Key FALLING_BLOCK = Key.from("craftengine:falling_block");
|
||||||
public static final Key LEAVES_BLOCK = Key.from("craftengine:leaves_block");
|
public static final Key LEAVES_BLOCK = Key.from("craftengine:leaves_block");
|
||||||
public static final Key STRIPPABLE_BLOCK = Key.from("craftengine:strippable_block");
|
public static final Key STRIPPABLE_BLOCK = Key.from("craftengine:strippable_block");
|
||||||
public static final Key SAPLING_BLOCK = Key.from("craftengine:sapling_block");
|
public static final Key SAPLING_BLOCK = Key.from("craftengine:sapling_block");
|
||||||
|
public static final Key ON_LIQUID_BLOCK = Key.from("craftengine:on_liquid_block");
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
|
register(EMPTY, (block, args) -> EmptyBlockBehavior.INSTANCE);
|
||||||
@@ -19,5 +19,6 @@ public class BukkitBlockBehaviors extends BlockBehaviors {
|
|||||||
register(LEAVES_BLOCK, LeavesBlockBehavior.FACTORY);
|
register(LEAVES_BLOCK, LeavesBlockBehavior.FACTORY);
|
||||||
register(STRIPPABLE_BLOCK, StrippableBlockBehavior.FACTORY);
|
register(STRIPPABLE_BLOCK, StrippableBlockBehavior.FACTORY);
|
||||||
register(SAPLING_BLOCK, SaplingBlockBehavior.FACTORY);
|
register(SAPLING_BLOCK, SaplingBlockBehavior.FACTORY);
|
||||||
|
register(ON_LIQUID_BLOCK, OnLiquidBlockBehavior.FACTORY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,9 @@ public class BushBlockBehavior extends BlockBehavior {
|
|||||||
public static class Factory implements BlockBehaviorFactory {
|
public static class Factory implements BlockBehaviorFactory {
|
||||||
@Override
|
@Override
|
||||||
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||||
if (arguments.containsKey("tags")) {
|
if (arguments.containsKey("bottom-block-tags")) {
|
||||||
|
return new BushBlockBehavior(MiscUtils.getAsStringList(arguments.get("bottom-block-tags")).stream().map(it -> BlockTags.getOrCreate(Key.of(it))).toList());
|
||||||
|
} else if (arguments.containsKey("tags")) {
|
||||||
return new BushBlockBehavior(MiscUtils.getAsStringList(arguments.get("tags")).stream().map(it -> BlockTags.getOrCreate(Key.of(it))).toList());
|
return new BushBlockBehavior(MiscUtils.getAsStringList(arguments.get("tags")).stream().map(it -> BlockTags.getOrCreate(Key.of(it))).toList());
|
||||||
} else {
|
} else {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
@@ -100,7 +102,7 @@ public class BushBlockBehavior extends BlockBehavior {
|
|||||||
return mayPlaceOn(belowState, world, belowPos);
|
return mayPlaceOn(belowState, world, belowPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean mayPlaceOn(Object belowState, Object world, Object blockPos) throws ReflectiveOperationException {
|
protected boolean mayPlaceOn(Object belowState, Object world, Object belowPos) throws ReflectiveOperationException {
|
||||||
for (Object tag : this.tagsCanSurviveOn) {
|
for (Object tag : this.tagsCanSurviveOn) {
|
||||||
if ((boolean) Reflections.method$BlockStateBase$hasTag.invoke(belowState, tag)) {
|
if ((boolean) Reflections.method$BlockStateBase$hasTag.invoke(belowState, tag)) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package net.momirealms.craftengine.bukkit.block.behavior;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||||
|
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||||
|
import net.momirealms.craftengine.core.block.behavior.BlockBehaviorFactory;
|
||||||
|
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||||
|
import net.momirealms.craftengine.shared.block.BlockBehavior;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class OnLiquidBlockBehavior extends BushBlockBehavior {
|
||||||
|
public static final Factory FACTORY = new Factory();
|
||||||
|
private final boolean onWater;
|
||||||
|
private final boolean onLava;
|
||||||
|
|
||||||
|
public OnLiquidBlockBehavior(List<Object> tagsCanSurviveOn, boolean onWater, boolean onLava) {
|
||||||
|
super(tagsCanSurviveOn);
|
||||||
|
this.onWater = onWater;
|
||||||
|
this.onLava = onLava;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onWater() {
|
||||||
|
return this.onWater;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onLava() {
|
||||||
|
return this.onLava;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Factory implements BlockBehaviorFactory {
|
||||||
|
@Override
|
||||||
|
public BlockBehavior create(CustomBlock block, Map<String, Object> arguments) {
|
||||||
|
List<String> liquidTypes = MiscUtils.getAsStringList(arguments.getOrDefault("liquid-type", List.of("water")));
|
||||||
|
return new OnLiquidBlockBehavior(List.of(), liquidTypes.contains("water"), liquidTypes.contains("lava"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean mayPlaceOn(Object belowState, Object world, Object belowPos) throws ReflectiveOperationException {
|
||||||
|
Object fluidState = Reflections.method$Level$getFluidState.invoke(world, belowPos);
|
||||||
|
Object fluidStateAbove = Reflections.method$Level$getFluidState.invoke(world, LocationUtils.above(belowPos));
|
||||||
|
if (Reflections.method$FluidState$getType.invoke(fluidStateAbove) != Reflections.instance$Fluids$EMPTY) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.onWater && (Reflections.method$FluidState$getType.invoke(fluidState) == Reflections.instance$Fluids$WATER || Reflections.field$StateHolder$owner.get(belowState) == Reflections.instance$Blocks$ICE)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (this.onLava && Reflections.method$FluidState$getType.invoke(fluidState) == Reflections.instance$Fluids$LAVA) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
package net.momirealms.craftengine.bukkit.entity.furniture;
|
package net.momirealms.craftengine.bukkit.entity.furniture;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
|
||||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||||
import net.momirealms.craftengine.bukkit.util.EntityUtils;
|
import net.momirealms.craftengine.bukkit.util.EntityUtils;
|
||||||
import net.momirealms.craftengine.core.entity.furniture.*;
|
import net.momirealms.craftengine.core.entity.furniture.*;
|
||||||
@@ -37,11 +35,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
|
|||||||
|
|
||||||
private final Map<Integer, LoadedFurniture> furnitureByBaseEntityId = new ConcurrentHashMap<>(256, 0.5f);
|
private final Map<Integer, LoadedFurniture> furnitureByBaseEntityId = new ConcurrentHashMap<>(256, 0.5f);
|
||||||
private final Map<Integer, LoadedFurniture> furnitureByInteractionEntityId = new ConcurrentHashMap<>(512, 0.5f);
|
private final Map<Integer, LoadedFurniture> furnitureByInteractionEntityId = new ConcurrentHashMap<>(512, 0.5f);
|
||||||
private final Map<Integer, int[]> baseEntity2SubEntities = new ConcurrentHashMap<>(256, 0.5f);
|
|
||||||
|
|
||||||
// Delay furniture cache remove for about 4-5 ticks
|
|
||||||
private static final int DELAYED_TICK = 5;
|
|
||||||
private final IntSet[] delayedRemove = new IntSet[DELAYED_TICK];
|
|
||||||
// Event listeners
|
// Event listeners
|
||||||
private final Listener dismountListener;
|
private final Listener dismountListener;
|
||||||
private final FurnitureEventListener furnitureEventListener;
|
private final FurnitureEventListener furnitureEventListener;
|
||||||
@@ -56,9 +49,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
|
|||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.furnitureEventListener = new FurnitureEventListener(this);
|
this.furnitureEventListener = new FurnitureEventListener(this);
|
||||||
this.dismountListener = VersionHelper.isVersionNewerThan1_20_3() ? new DismountListener1_20_3(this) : new DismountListener1_20(this::handleDismount);
|
this.dismountListener = VersionHelper.isVersionNewerThan1_20_3() ? new DismountListener1_20_3(this) : new DismountListener1_20(this::handleDismount);
|
||||||
for (int i = 0; i < DELAYED_TICK; i++) {
|
|
||||||
this.delayedRemove[i] = new IntOpenHashSet();
|
|
||||||
}
|
|
||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,18 +161,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
IntSet first = this.delayedRemove[0];
|
|
||||||
for (int i : first) {
|
|
||||||
// unloaded furniture might be loaded again
|
|
||||||
LoadedFurniture furniture = getLoadedFurnitureByBaseEntityId(i);
|
|
||||||
if (furniture == null)
|
|
||||||
this.baseEntity2SubEntities.remove(i);
|
|
||||||
}
|
|
||||||
first.clear();
|
|
||||||
for (int i = 1; i < DELAYED_TICK; i++) {
|
|
||||||
this.delayedRemove[i - 1] = this.delayedRemove[i];
|
|
||||||
}
|
|
||||||
this.delayedRemove[DELAYED_TICK-1] = first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -224,12 +202,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
|
|||||||
return Optional.ofNullable(this.byId.get(id));
|
return Optional.ofNullable(this.byId.get(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public int[] getSubEntityIdsByBaseEntityId(int entityId) {
|
|
||||||
return this.baseEntity2SubEntities.get(entityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFurnitureBaseEntity(int entityId) {
|
public boolean isFurnitureBaseEntity(int entityId) {
|
||||||
return this.furnitureByBaseEntityId.containsKey(entityId);
|
return this.furnitureByBaseEntityId.containsKey(entityId);
|
||||||
@@ -253,7 +225,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
|
|||||||
for (int sub : furniture.interactionEntityIds()) {
|
for (int sub : furniture.interactionEntityIds()) {
|
||||||
this.furnitureByInteractionEntityId.remove(sub);
|
this.furnitureByInteractionEntityId.remove(sub);
|
||||||
}
|
}
|
||||||
this.delayedRemove[DELAYED_TICK-1].add(id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,6 +241,7 @@ public class BukkitFurnitureManager implements FurnitureManager {
|
|||||||
if (previous != null) return;
|
if (previous != null) return;
|
||||||
LoadedFurniture furniture = addNewFurniture(display, customFurniture, getAnchorType(entity, customFurniture));
|
LoadedFurniture furniture = addNewFurniture(display, customFurniture, getAnchorType(entity, customFurniture));
|
||||||
for (Player player : display.getTrackedPlayers()) {
|
for (Player player : display.getTrackedPlayers()) {
|
||||||
|
this.plugin.adapt(player).furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.subEntityIds());
|
||||||
this.plugin.networkManager().sendPacket(player, furniture.spawnPacket());
|
this.plugin.networkManager().sendPacket(player, furniture.spawnPacket());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -316,7 +288,6 @@ public class BukkitFurnitureManager implements FurnitureManager {
|
|||||||
private synchronized LoadedFurniture addNewFurniture(ItemDisplay display, CustomFurniture furniture, AnchorType anchorType) {
|
private synchronized LoadedFurniture addNewFurniture(ItemDisplay display, CustomFurniture furniture, AnchorType anchorType) {
|
||||||
LoadedFurniture loadedFurniture = new LoadedFurniture(display, furniture, anchorType);
|
LoadedFurniture loadedFurniture = new LoadedFurniture(display, furniture, anchorType);
|
||||||
this.furnitureByBaseEntityId.put(loadedFurniture.baseEntityId(), loadedFurniture);
|
this.furnitureByBaseEntityId.put(loadedFurniture.baseEntityId(), loadedFurniture);
|
||||||
this.baseEntity2SubEntities.put(loadedFurniture.baseEntityId(), loadedFurniture.subEntityIds());
|
|
||||||
for (int entityId : loadedFurniture.interactionEntityIds()) {
|
for (int entityId : loadedFurniture.interactionEntityIds()) {
|
||||||
this.furnitureByInteractionEntityId.put(entityId, loadedFurniture);
|
this.furnitureByInteractionEntityId.put(entityId, loadedFurniture);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ public class FurnitureEventListener implements Listener {
|
|||||||
this.manager.handleEntityUnload(event.getEntity());
|
this.manager.handleEntityUnload(event.getEntity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(ignoreCancelled = true)
|
||||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ public class LoadedFurniture {
|
|||||||
private final WeakReference<Entity> baseEntity;
|
private final WeakReference<Entity> baseEntity;
|
||||||
private final int baseEntityId;
|
private final int baseEntityId;
|
||||||
// includes elements + interactions
|
// includes elements + interactions
|
||||||
private final int[] subEntityIds;
|
private final List<Integer> subEntityIds;
|
||||||
// interactions
|
// interactions
|
||||||
private final int[] interactionEntityIds;
|
private final List<Integer> interactionEntityIds;
|
||||||
// seats
|
// seats
|
||||||
private final Set<Vector3f> occupiedSeats = Collections.synchronizedSet(new HashSet<>());
|
private final Set<Vector3f> occupiedSeats = Collections.synchronizedSet(new HashSet<>());
|
||||||
private final Vector<Entity> seats = new Vector<>();
|
private final Vector<Entity> seats = new Vector<>();
|
||||||
@@ -73,14 +73,9 @@ public class LoadedFurniture {
|
|||||||
interactionEntityIds.add(entityId);
|
interactionEntityIds.add(entityId);
|
||||||
this.hitBoxes.put(entityId, hitBox);
|
this.hitBoxes.put(entityId, hitBox);
|
||||||
}
|
}
|
||||||
this.subEntityIds = new int[entityIds.size()];
|
this.subEntityIds = entityIds;
|
||||||
for (int i = 0; i < entityIds.size(); ++i) {
|
this.interactionEntityIds = interactionEntityIds;
|
||||||
this.subEntityIds[i] = entityIds.get(i);
|
this.resetSpawnPackets();
|
||||||
}
|
|
||||||
this.interactionEntityIds = new int[interactionEntityIds.size()];
|
|
||||||
for (int i = 0; i < interactionEntityIds.size(); ++i) {
|
|
||||||
this.interactionEntityIds[i] = interactionEntityIds.get(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetSpawnPackets() {
|
private void resetSpawnPackets() {
|
||||||
@@ -148,13 +143,6 @@ public class LoadedFurniture {
|
|||||||
this.location = location;
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object spawnPacket() {
|
|
||||||
if (this.cachedSpawnPacket == null) {
|
|
||||||
this.resetSpawnPackets();
|
|
||||||
}
|
|
||||||
return this.cachedSpawnPacket;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Entity baseEntity() {
|
public Entity baseEntity() {
|
||||||
Entity entity = baseEntity.get();
|
Entity entity = baseEntity.get();
|
||||||
@@ -235,11 +223,11 @@ public class LoadedFurniture {
|
|||||||
return baseEntityId;
|
return baseEntityId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] interactionEntityIds() {
|
public List<Integer> interactionEntityIds() {
|
||||||
return interactionEntityIds;
|
return interactionEntityIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] subEntityIds() {
|
public List<Integer> subEntityIds() {
|
||||||
return this.subEntityIds;
|
return this.subEntityIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,4 +274,8 @@ public class LoadedFurniture {
|
|||||||
this.addSeatEntity(seatEntity);
|
this.addSeatEntity(seatEntity);
|
||||||
seatEntity.addPassenger(player);
|
seatEntity.addPassenger(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @NotNull Object spawnPacket() {
|
||||||
|
return cachedSpawnPacket;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package net.momirealms.craftengine.bukkit.item;
|
package net.momirealms.craftengine.bukkit.item;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.bukkit.compatibility.item.NeigeItemsProvider;
|
||||||
import net.momirealms.craftengine.bukkit.item.behavior.AxeItemBehavior;
|
import net.momirealms.craftengine.bukkit.item.behavior.AxeItemBehavior;
|
||||||
import net.momirealms.craftengine.bukkit.item.behavior.BoneMealBehavior;
|
|
||||||
import net.momirealms.craftengine.bukkit.item.behavior.BucketItemBehavior;
|
import net.momirealms.craftengine.bukkit.item.behavior.BucketItemBehavior;
|
||||||
import net.momirealms.craftengine.bukkit.item.behavior.WaterBucketItemBehavior;
|
import net.momirealms.craftengine.bukkit.item.behavior.WaterBucketItemBehavior;
|
||||||
import net.momirealms.craftengine.bukkit.item.factory.BukkitItemFactory;
|
import net.momirealms.craftengine.bukkit.item.factory.BukkitItemFactory;
|
||||||
@@ -50,7 +50,6 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
registerVanillaItemExtraBehavior(AxeItemBehavior.INSTANCE, ItemKeys.AXES);
|
registerVanillaItemExtraBehavior(AxeItemBehavior.INSTANCE, ItemKeys.AXES);
|
||||||
registerVanillaItemExtraBehavior(WaterBucketItemBehavior.INSTANCE, ItemKeys.WATER_BUCKETS);
|
registerVanillaItemExtraBehavior(WaterBucketItemBehavior.INSTANCE, ItemKeys.WATER_BUCKETS);
|
||||||
registerVanillaItemExtraBehavior(BucketItemBehavior.INSTANCE, ItemKeys.BUCKET);
|
registerVanillaItemExtraBehavior(BucketItemBehavior.INSTANCE, ItemKeys.BUCKET);
|
||||||
registerVanillaItemExtraBehavior(BoneMealBehavior.INSTANCE, ItemKeys.BONE_MEAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BukkitItemManager instance;
|
private static BukkitItemManager instance;
|
||||||
@@ -71,8 +70,15 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delayedInit() {
|
public void delayedInit() {
|
||||||
Bukkit.getPluginManager().registerEvents(this.itemEventListener, plugin.bootstrap());
|
Bukkit.getPluginManager().registerEvents(this.itemEventListener, this.plugin.bootstrap());
|
||||||
Bukkit.getPluginManager().registerEvents(this.debugStickListener, plugin.bootstrap());
|
Bukkit.getPluginManager().registerEvents(this.debugStickListener, this.plugin.bootstrap());
|
||||||
|
this.hookExternalPlugins();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hookExternalPlugins() {
|
||||||
|
if (this.plugin.isPluginEnabled("NeigeItems")) {
|
||||||
|
registerExternalItemProvider(new NeigeItemsProvider());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public class BlockItemBehavior extends ItemBehavior {
|
|||||||
|
|
||||||
BlockPos pos = placeContext.getClickedPos();
|
BlockPos pos = placeContext.getClickedPos();
|
||||||
BlockPos againstPos = placeContext.getAgainstPos();
|
BlockPos againstPos = placeContext.getAgainstPos();
|
||||||
World world = (World) placeContext.getLevel().getHandle();
|
World world = (World) placeContext.getLevel().platformWorld();
|
||||||
Location placeLocation = new Location(world, pos.x(), pos.y(), pos.z());
|
Location placeLocation = new Location(world, pos.x(), pos.y(), pos.z());
|
||||||
|
|
||||||
Block bukkitBlock = world.getBlockAt(placeLocation);
|
Block bukkitBlock = world.getBlockAt(placeLocation);
|
||||||
@@ -151,7 +151,7 @@ public class BlockItemBehavior extends ItemBehavior {
|
|||||||
Object blockState = state.customBlockState().handle();
|
Object blockState = state.customBlockState().handle();
|
||||||
Object blockPos = LocationUtils.toBlockPos(context.getClickedPos());
|
Object blockPos = LocationUtils.toBlockPos(context.getClickedPos());
|
||||||
Object voxelShape = Reflections.method$CollisionContext$of.invoke(null, player);
|
Object voxelShape = Reflections.method$CollisionContext$of.invoke(null, player);
|
||||||
Object world = Reflections.field$CraftWorld$ServerLevel.get(context.getLevel().getHandle());
|
Object world = Reflections.field$CraftWorld$ServerLevel.get(context.getLevel().platformWorld());
|
||||||
boolean defaultReturn = ((!this.checkStatePlacement() || (boolean) Reflections.method$BlockStateBase$canSurvive.invoke(blockState, world, blockPos))
|
boolean defaultReturn = ((!this.checkStatePlacement() || (boolean) Reflections.method$BlockStateBase$canSurvive.invoke(blockState, world, blockPos))
|
||||||
&& (boolean) Reflections.method$ServerLevel$checkEntityCollision.invoke(world, blockState, player, voxelShape, blockPos, true));
|
&& (boolean) Reflections.method$ServerLevel$checkEntityCollision.invoke(world, blockState, player, voxelShape, blockPos, true));
|
||||||
Block block = (Block) Reflections.method$CraftBlock$at.invoke(null, world, blockPos);
|
Block block = (Block) Reflections.method$CraftBlock$at.invoke(null, world, blockPos);
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
package net.momirealms.craftengine.bukkit.item.behavior;
|
|
||||||
|
|
||||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
|
||||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
|
||||||
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory;
|
|
||||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
|
||||||
import net.momirealms.craftengine.core.pack.Pack;
|
|
||||||
import net.momirealms.craftengine.core.util.Key;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class BoneMealBehavior extends ItemBehavior {
|
|
||||||
public static final BoneMealBehavior INSTANCE = new BoneMealBehavior();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InteractionResult useOnBlock(UseOnContext context) {
|
|
||||||
return super.useOnBlock(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Factory implements ItemBehaviorFactory {
|
|
||||||
@Override
|
|
||||||
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,16 +5,17 @@ import net.momirealms.craftengine.core.item.behavior.ItemBehaviors;
|
|||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
|
||||||
public class BukkitItemBehaviors extends ItemBehaviors {
|
public class BukkitItemBehaviors extends ItemBehaviors {
|
||||||
public static final Key EMPTY = Key.from("craftengine:empty");
|
|
||||||
public static final Key BLOCK_ITEM = Key.from("craftengine:block_item");
|
public static final Key BLOCK_ITEM = Key.from("craftengine:block_item");
|
||||||
|
public static final Key ON_LIQUID_BLOCK_ITEM = Key.from("craftengine:liquid_collision_block_item");
|
||||||
public static final Key FURNITURE_ITEM = Key.from("craftengine:furniture_item");
|
public static final Key FURNITURE_ITEM = Key.from("craftengine:furniture_item");
|
||||||
public static final Key AXE_ITEM = Key.from("craftengine:axe_item");
|
public static final Key AXE_ITEM = Key.from("craftengine:axe_item");
|
||||||
public static final Key WATER_BUCKET_ITEM = Key.from("craftengine:water_bucket_item");
|
public static final Key WATER_BUCKET_ITEM = Key.from("craftengine:water_bucket_item");
|
||||||
public static final Key BUCKET_ITEM = Key.from("craftengine:bucket_item");
|
public static final Key BUCKET_ITEM = Key.from("craftengine:bucket_item");
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
register(EMPTY, (pack, path, args, id) -> EmptyItemBehavior.INSTANCE);
|
register(EMPTY, EmptyItemBehavior.FACTORY);
|
||||||
register(BLOCK_ITEM, BlockItemBehavior.FACTORY);
|
register(BLOCK_ITEM, BlockItemBehavior.FACTORY);
|
||||||
|
register(ON_LIQUID_BLOCK_ITEM, LiquidCollisionBlockItemBehavior.FACTORY);
|
||||||
register(FURNITURE_ITEM, FurnitureItemBehavior.FACTORY);
|
register(FURNITURE_ITEM, FurnitureItemBehavior.FACTORY);
|
||||||
register(AXE_ITEM, AxeItemBehavior.FACTORY);
|
register(AXE_ITEM, AxeItemBehavior.FACTORY);
|
||||||
register(WATER_BUCKET_ITEM, WaterBucketItemBehavior.FACTORY);
|
register(WATER_BUCKET_ITEM, WaterBucketItemBehavior.FACTORY);
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class FurnitureItemBehavior extends ItemBehavior {
|
|||||||
|
|
||||||
// trigger event
|
// trigger event
|
||||||
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) player.platformPlayer();
|
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) player.platformPlayer();
|
||||||
World world = (World) context.getLevel().getHandle();
|
World world = (World) context.getLevel().platformWorld();
|
||||||
|
|
||||||
// get position and rotation for placement
|
// get position and rotation for placement
|
||||||
Vec3d finalPlacePosition;
|
Vec3d finalPlacePosition;
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package net.momirealms.craftengine.bukkit.item.behavior;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||||
|
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||||
|
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||||
|
import net.momirealms.craftengine.core.entity.player.Player;
|
||||||
|
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||||
|
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory;
|
||||||
|
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||||
|
import net.momirealms.craftengine.core.pack.Pack;
|
||||||
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
|
import net.momirealms.craftengine.core.util.Direction;
|
||||||
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||||
|
import net.momirealms.craftengine.core.world.BlockHitResult;
|
||||||
|
import net.momirealms.craftengine.core.world.BlockPos;
|
||||||
|
import net.momirealms.craftengine.core.world.Vec3d;
|
||||||
|
import net.momirealms.craftengine.core.world.World;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LiquidCollisionBlockItemBehavior extends BlockItemBehavior {
|
||||||
|
public static final Factory FACTORY = new Factory();
|
||||||
|
private final int offsetY;
|
||||||
|
|
||||||
|
public LiquidCollisionBlockItemBehavior(Key blockId, int offsetY) {
|
||||||
|
super(blockId);
|
||||||
|
this.offsetY = offsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractionResult useOnBlock(UseOnContext context) {
|
||||||
|
return use(context.getLevel(), context.getPlayer(), context.getHand());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractionResult use(World world, Player player, InteractionHand hand) {
|
||||||
|
try {
|
||||||
|
Object blockHitResult = Reflections.method$Item$getPlayerPOVHitResult.invoke(null, world.serverWorld(), player.serverPlayer(), Reflections.instance$ClipContext$Fluid$SOURCE_ONLY);
|
||||||
|
Object blockPos = Reflections.field$BlockHitResul$blockPos.get(blockHitResult);
|
||||||
|
BlockPos above = new BlockPos(Reflections.field$Vec3i$x.getInt(blockPos), Reflections.field$Vec3i$y.getInt(blockPos) + offsetY, Reflections.field$Vec3i$z.getInt(blockPos));
|
||||||
|
Direction direction = Direction.values()[(int) Reflections.method$Direction$ordinal.invoke(Reflections.field$BlockHitResul$direction.get(blockHitResult))];
|
||||||
|
boolean miss = Reflections.field$BlockHitResul$miss.getBoolean(blockHitResult);
|
||||||
|
Vec3d hitPos = LocationUtils.fromVec(Reflections.field$HitResult$location.get(blockHitResult));
|
||||||
|
if (miss) {
|
||||||
|
return super.useOnBlock(new UseOnContext(player, hand, BlockHitResult.miss(hitPos, direction, above)));
|
||||||
|
} else {
|
||||||
|
boolean inside = Reflections.field$BlockHitResul$inside.getBoolean(blockHitResult);
|
||||||
|
return super.useOnBlock(new UseOnContext(player, hand, new BlockHitResult(hitPos, direction, above, inside)));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
CraftEngine.instance().logger().warn("Error handling use", e);
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Factory implements ItemBehaviorFactory {
|
||||||
|
@Override
|
||||||
|
public ItemBehavior create(Pack pack, Path path, Key key, Map<String, Object> arguments) {
|
||||||
|
Object id = arguments.get("block");
|
||||||
|
if (id == null) {
|
||||||
|
throw new IllegalArgumentException("Missing required parameter 'block' for on_liquid_block_item behavior");
|
||||||
|
}
|
||||||
|
int offset = MiscUtils.getAsInt(arguments.getOrDefault("y-offset", 1));
|
||||||
|
if (id instanceof Map<?, ?> map) {
|
||||||
|
BukkitBlockManager.instance().parseSection(pack, path, key, MiscUtils.castToMap(map, false));
|
||||||
|
return new LiquidCollisionBlockItemBehavior(key, offset);
|
||||||
|
} else {
|
||||||
|
return new LiquidCollisionBlockItemBehavior(Key.of(id.toString()), offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -299,7 +299,7 @@ public class ComponentItemFactory extends BukkitItemFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemWrapper<ItemStack> merge(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
|
protected ItemWrapper<ItemStack> mergeCopy(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
|
||||||
Object itemStack1 = item1.getLiteralObject();
|
Object itemStack1 = item1.getLiteralObject();
|
||||||
Object itemStack2 = item2.getLiteralObject();
|
Object itemStack2 = item2.getLiteralObject();
|
||||||
try {
|
try {
|
||||||
@@ -311,4 +311,17 @@ public class ComponentItemFactory extends BukkitItemFactory {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void merge(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
|
||||||
|
// load previous changes on nms items
|
||||||
|
item1.load();
|
||||||
|
Object itemStack1 = item1.getLiteralObject();
|
||||||
|
Object itemStack2 = item2.getLiteralObject();
|
||||||
|
try {
|
||||||
|
Reflections.method$ItemStack$applyComponents.invoke(itemStack1, Reflections.method$ItemStack$getComponentsPatch.invoke(itemStack2));
|
||||||
|
} catch (Exception e) {
|
||||||
|
plugin.logger().warn("Failed to merge item", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -234,11 +234,18 @@ public class UniversalItemFactory extends BukkitItemFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ItemWrapper<ItemStack> merge(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
|
protected ItemWrapper<ItemStack> mergeCopy(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
|
||||||
Object itemStack = ItemObject.copy(item2.getLiteralObject());
|
Object itemStack = ItemObject.copy(item2.getLiteralObject());
|
||||||
ItemObject.setCustomDataTag(itemStack, TagCompound.clone(ItemObject.getCustomDataTag(item1.getLiteralObject())));
|
ItemObject.setCustomDataTag(itemStack, TagCompound.clone(ItemObject.getCustomDataTag(item1.getLiteralObject())));
|
||||||
// one more step than vanilla
|
// one more step than vanilla
|
||||||
TagCompound.merge(ItemObject.getCustomDataTag(itemStack), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true);
|
TagCompound.merge(ItemObject.getCustomDataTag(itemStack), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true);
|
||||||
return new RTagItemWrapper(new RtagItem(ItemObject.asCraftMirror(itemStack)), item2.count());
|
return new RTagItemWrapper(new RtagItem(ItemObject.asCraftMirror(itemStack)), item2.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void merge(ItemWrapper<ItemStack> item1, ItemWrapper<ItemStack> item2) {
|
||||||
|
// load previous changes on nms items
|
||||||
|
item1.load();
|
||||||
|
TagCompound.merge(ItemObject.getCustomDataTag(item1.getLiteralObject()), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -44,8 +44,10 @@ public class DebugAppearanceStateUsageCommand extends BukkitCommandFeature<Comma
|
|||||||
List<Integer> appearances = blockManager.blockAppearanceArranger().get(baseBlockId);
|
List<Integer> appearances = blockManager.blockAppearanceArranger().get(baseBlockId);
|
||||||
if (appearances == null) return;
|
if (appearances == null) return;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
Component component = Component.text(baseBlockId + ": ");
|
Component block = Component.text(baseBlockId + ": ");
|
||||||
List<Component> children = new ArrayList<>();
|
plugin().senderFactory().wrap(context.sender()).sendMessage(block);
|
||||||
|
|
||||||
|
List<Component> batch = new ArrayList<>();
|
||||||
for (int appearance : appearances) {
|
for (int appearance : appearances) {
|
||||||
Component text = Component.text("|");
|
Component text = Component.text("|");
|
||||||
List<Integer> reals = blockManager.appearanceToRealStates(appearance);
|
List<Integer> reals = blockManager.appearanceToRealStates(appearance);
|
||||||
@@ -64,11 +66,19 @@ public class DebugAppearanceStateUsageCommand extends BukkitCommandFeature<Comma
|
|||||||
}
|
}
|
||||||
text = text.color(NamedTextColor.RED).hoverEvent(HoverEvent.showText(hover.children(hoverChildren)));
|
text = text.color(NamedTextColor.RED).hoverEvent(HoverEvent.showText(hover.children(hoverChildren)));
|
||||||
}
|
}
|
||||||
children.add(text);
|
batch.add(text);
|
||||||
i++;
|
i++;
|
||||||
|
if (batch.size() == 100) {
|
||||||
|
plugin().senderFactory().wrap(context.sender())
|
||||||
|
.sendMessage(Component.text("").children(batch));
|
||||||
|
batch.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!batch.isEmpty()) {
|
||||||
|
plugin().senderFactory().wrap(context.sender())
|
||||||
|
.sendMessage(Component.text("").children(batch));
|
||||||
|
batch.clear();
|
||||||
}
|
}
|
||||||
plugin().senderFactory().wrap(context.sender())
|
|
||||||
.sendMessage(component.children(children));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,22 +44,32 @@ public class DebugRealStateUsageCommand extends BukkitCommandFeature<CommandSend
|
|||||||
List<Integer> reals = blockManager.realBlockArranger().get(baseBlockId);
|
List<Integer> reals = blockManager.realBlockArranger().get(baseBlockId);
|
||||||
if (reals == null) return;
|
if (reals == null) return;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
Component component = Component.text(baseBlockId + ": ");
|
Component block = Component.text(baseBlockId + ": ");
|
||||||
List<Component> children = new ArrayList<>();
|
plugin().senderFactory().wrap(context.sender()).sendMessage(block);
|
||||||
|
|
||||||
|
List<Component> batch = new ArrayList<>(100);
|
||||||
for (int real : reals) {
|
for (int real : reals) {
|
||||||
ImmutableBlockState state = blockManager.getImmutableBlockStateUnsafe(real);
|
ImmutableBlockState state = blockManager.getImmutableBlockStateUnsafe(real);
|
||||||
if (state.isEmpty()) {
|
if (state.isEmpty()) {
|
||||||
Component hover = Component.text("craftengine:" + baseBlockId.value() + "_" + i).color(NamedTextColor.GREEN);
|
Component hover = Component.text("craftengine:" + baseBlockId.value() + "_" + i).color(NamedTextColor.GREEN);
|
||||||
children.add(Component.text("|").color(NamedTextColor.GREEN).hoverEvent(HoverEvent.showText(hover)));
|
batch.add(Component.text("|").color(NamedTextColor.GREEN).hoverEvent(HoverEvent.showText(hover)));
|
||||||
} else {
|
} else {
|
||||||
Component hover = Component.text("craftengine:" + baseBlockId.value() + "_" + i).color(NamedTextColor.RED);
|
Component hover = Component.text("craftengine:" + baseBlockId.value() + "_" + i).color(NamedTextColor.RED);
|
||||||
hover = hover.append(Component.newline()).append(Component.text(state.toString()).color(NamedTextColor.GRAY));
|
hover = hover.append(Component.newline()).append(Component.text(state.toString()).color(NamedTextColor.GRAY));
|
||||||
children.add(Component.text("|").color(NamedTextColor.RED).hoverEvent(HoverEvent.showText(hover)));
|
batch.add(Component.text("|").color(NamedTextColor.RED).hoverEvent(HoverEvent.showText(hover)));
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
if (batch.size() == 100) {
|
||||||
|
plugin().senderFactory().wrap(context.sender())
|
||||||
|
.sendMessage(Component.text("").children(batch));
|
||||||
|
batch.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!batch.isEmpty()) {
|
||||||
|
plugin().senderFactory().wrap(context.sender())
|
||||||
|
.sendMessage(Component.text("").children(batch));
|
||||||
|
batch.clear();
|
||||||
}
|
}
|
||||||
plugin().senderFactory().wrap(context.sender())
|
|
||||||
.sendMessage(component.children(children));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component;
|
|||||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
|
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
|
||||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
@@ -50,6 +51,8 @@ public class DebugTargetBlockCommand extends BukkitCommandFeature<CommandSender>
|
|||||||
if (immutableBlockState != null) {
|
if (immutableBlockState != null) {
|
||||||
sender.sendMessage(Component.text(immutableBlockState.toString()));
|
sender.sendMessage(Component.text(immutableBlockState.toString()));
|
||||||
}
|
}
|
||||||
|
ImmutableBlockState dataInCache = plugin().worldManager().getWorld(block.getWorld().getUID()).getBlockStateAtIfLoaded(LocationUtils.toBlockPos(block.getLocation()));
|
||||||
|
sender.sendMessage(Component.text("cache-state: " + !dataInCache.isEmpty()));
|
||||||
try {
|
try {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<Object> tags = (Set<Object>) Reflections.field$Holder$Reference$tags.get(holder);
|
Set<Object> tags = (Set<Object>) Reflections.field$Holder$Reference$tags.get(holder);
|
||||||
|
|||||||
@@ -125,6 +125,9 @@ public class BukkitNetworkManager implements NetworkManager, Listener {
|
|||||||
registerNMSPacketConsumer(PacketConsumers.MOVE_ENTITY, Reflections.clazz$ClientboundMoveEntityPacket$Pos);
|
registerNMSPacketConsumer(PacketConsumers.MOVE_ENTITY, Reflections.clazz$ClientboundMoveEntityPacket$Pos);
|
||||||
registerNMSPacketConsumer(PacketConsumers.PICK_ITEM_FROM_ENTITY, Reflections.clazz$ServerboundPickItemFromEntityPacket);
|
registerNMSPacketConsumer(PacketConsumers.PICK_ITEM_FROM_ENTITY, Reflections.clazz$ServerboundPickItemFromEntityPacket);
|
||||||
registerNMSPacketConsumer(PacketConsumers.SOUND, Reflections.clazz$ClientboundSoundPacket);
|
registerNMSPacketConsumer(PacketConsumers.SOUND, Reflections.clazz$ClientboundSoundPacket);
|
||||||
|
registerNMSPacketConsumer(PacketConsumers.CHAT, Reflections.clazz$ServerboundChatPacket);
|
||||||
|
registerNMSPacketConsumer(PacketConsumers.RENAME_ITEM, Reflections.clazz$ServerboundRenameItemPacket);
|
||||||
|
registerNMSPacketConsumer(PacketConsumers.SIGN_UPDATE, Reflections.clazz$ServerboundSignUpdatePacket);
|
||||||
registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
|
registerByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
|
||||||
registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
|
registerByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
|
||||||
registerByteBufPacketConsumer(PacketConsumers.LEVEL_PARTICLE, this.packetIds.clientboundLevelParticlesPacket());
|
registerByteBufPacketConsumer(PacketConsumers.LEVEL_PARTICLE, this.packetIds.clientboundLevelParticlesPacket());
|
||||||
@@ -265,6 +268,28 @@ public class BukkitNetworkManager implements NetworkManager, Listener {
|
|||||||
this.packetsConsumer.accept(player.serverPlayer(), packet);
|
this.packetsConsumer.accept(player.serverPlayer(), packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void receivePacket(@NotNull NetWorkUser player, Object packet) {
|
||||||
|
Channel channel = player.nettyChannel();
|
||||||
|
if (channel.isOpen()) {
|
||||||
|
List<String> handlerNames = channel.pipeline().names();
|
||||||
|
if (handlerNames.contains("via-encoder")) {
|
||||||
|
channel.pipeline().context("via-decoder").fireChannelRead(packet);
|
||||||
|
} else if (handlerNames.contains("ps_decoder_transformer")) {
|
||||||
|
channel.pipeline().context("ps_decoder_transformer").fireChannelRead(packet);
|
||||||
|
} else if (handlerNames.contains("decompress")) {
|
||||||
|
channel.pipeline().context("decompress").fireChannelRead(packet);
|
||||||
|
} else {
|
||||||
|
if (handlerNames.contains("decrypt")) {
|
||||||
|
channel.pipeline().context("decrypt").fireChannelRead(packet);
|
||||||
|
} else {
|
||||||
|
channel.pipeline().context("splitter").fireChannelRead(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
((ByteBuf) packet).release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void injectServerChannel(Channel serverChannel) {
|
private void injectServerChannel(Channel serverChannel) {
|
||||||
ChannelPipeline pipeline = serverChannel.pipeline();
|
ChannelPipeline pipeline = serverChannel.pipeline();
|
||||||
ChannelHandler connectionHandler = pipeline.get(CONNECTION_HANDLER_NAME);
|
ChannelHandler connectionHandler = pipeline.get(CONNECTION_HANDLER_NAME);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
|||||||
import net.momirealms.craftengine.bukkit.util.*;
|
import net.momirealms.craftengine.bukkit.util.*;
|
||||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||||
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
import net.momirealms.craftengine.core.entity.player.InteractionHand;
|
||||||
|
import net.momirealms.craftengine.core.font.ImageManager;
|
||||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
import net.momirealms.craftengine.core.plugin.config.ConfigManager;
|
import net.momirealms.craftengine.core.plugin.config.ConfigManager;
|
||||||
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
|
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
|
||||||
@@ -32,10 +33,9 @@ import org.bukkit.util.RayTraceResult;
|
|||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class PacketConsumers {
|
public class PacketConsumers {
|
||||||
private static int[] mappings;
|
private static int[] mappings;
|
||||||
@@ -344,7 +344,7 @@ public class PacketConsumers {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundSetCreativeModeSlotPacket", e);
|
CraftEngine.instance().logger().warn("Failed to handle ServerboundSetCreativeModeSlotPacket", e);
|
||||||
}
|
}
|
||||||
}, (World) player.level().getHandle(), (MCUtils.fastFloor(player.x())) >> 4, (MCUtils.fastFloor(player.z())) >> 4);
|
}, (World) player.level().platformWorld(), (MCUtils.fastFloor(player.x())) >> 4, (MCUtils.fastFloor(player.z())) >> 4);
|
||||||
} else {
|
} else {
|
||||||
handleSetCreativeSlotPacketOnMainThread(player, packet);
|
handleSetCreativeSlotPacketOnMainThread(player, packet);
|
||||||
}
|
}
|
||||||
@@ -532,6 +532,7 @@ public class PacketConsumers {
|
|||||||
int entityId = (int) Reflections.field$ClientboundAddEntityPacket$entityId.get(packet);
|
int entityId = (int) Reflections.field$ClientboundAddEntityPacket$entityId.get(packet);
|
||||||
LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(entityId);
|
LoadedFurniture furniture = BukkitFurnitureManager.instance().getLoadedFurnitureByBaseEntityId(entityId);
|
||||||
if (furniture != null) {
|
if (furniture != null) {
|
||||||
|
user.furnitureView().computeIfAbsent(furniture.baseEntityId(), k -> new ArrayList<>()).addAll(furniture.subEntityIds());
|
||||||
user.sendPacket(furniture.spawnPacket(), false);
|
user.sendPacket(furniture.spawnPacket(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -566,7 +567,7 @@ public class PacketConsumers {
|
|||||||
try {
|
try {
|
||||||
IntList intList = (IntList) Reflections.field$ClientboundRemoveEntitiesPacket$entityIds.get(packet);
|
IntList intList = (IntList) Reflections.field$ClientboundRemoveEntitiesPacket$entityIds.get(packet);
|
||||||
for (int i = 0, size = intList.size(); i < size; i++) {
|
for (int i = 0, size = intList.size(); i < size; i++) {
|
||||||
int[] entities = BukkitFurnitureManager.instance().getSubEntityIdsByBaseEntityId(intList.getInt(i));
|
List<Integer> entities = user.furnitureView().remove(intList.getInt(i));
|
||||||
if (entities == null) continue;
|
if (entities == null) continue;
|
||||||
for (int entityId : entities) {
|
for (int entityId : entities) {
|
||||||
intList.add(entityId);
|
intList.add(entityId);
|
||||||
@@ -661,4 +662,92 @@ public class PacketConsumers {
|
|||||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundSoundPacket", e);
|
CraftEngine.instance().logger().warn("Failed to handle ClientboundSoundPacket", e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// we handle it on packet level to prevent it from being captured by plugins (most are chat plugins)
|
||||||
|
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> CHAT = (user, event, packet) -> {
|
||||||
|
try {
|
||||||
|
String message = (String) Reflections.field$ServerboundChatPacket$message.get(packet);
|
||||||
|
if (message != null && !message.isEmpty()) {
|
||||||
|
ImageManager manager = CraftEngine.instance().imageManager();
|
||||||
|
if (!manager.isDefaultFontInUse()) return;
|
||||||
|
runIfContainsIllegalCharacter(message, manager, (s) -> {
|
||||||
|
event.setCancelled(true);
|
||||||
|
try {
|
||||||
|
Object newPacket = Reflections.constructor$ServerboundChatPacket.newInstance(
|
||||||
|
s,
|
||||||
|
Reflections.field$ServerboundChatPacket$timeStamp.get(packet),
|
||||||
|
Reflections.field$ServerboundChatPacket$salt.get(packet),
|
||||||
|
Reflections.field$ServerboundChatPacket$signature.get(packet),
|
||||||
|
Reflections.field$ServerboundChatPacket$lastSeenMessages.get(packet)
|
||||||
|
);
|
||||||
|
user.receivePacket(newPacket);
|
||||||
|
} catch (Exception e) {
|
||||||
|
CraftEngine.instance().logger().warn("Failed to create replaced chat packet", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
CraftEngine.instance().logger().warn("Failed to handle ServerboundChatPacket", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// we handle it on packet level to prevent it from being captured by plugins
|
||||||
|
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> RENAME_ITEM = (user, event, packet) -> {
|
||||||
|
try {
|
||||||
|
String message = (String) Reflections.field$ServerboundRenameItemPacket$name.get(packet);
|
||||||
|
if (message != null && !message.isEmpty()) {
|
||||||
|
ImageManager manager = CraftEngine.instance().imageManager();
|
||||||
|
if (!manager.isDefaultFontInUse()) return;
|
||||||
|
runIfContainsIllegalCharacter(message, manager, (s) -> {
|
||||||
|
try {
|
||||||
|
Reflections.field$ServerboundRenameItemPacket$name.set(packet, s);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
CraftEngine.instance().logger().warn("Failed to replace chat", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
CraftEngine.instance().logger().warn("Failed to handle ServerboundRenameItemPacket", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// we handle it on packet level to prevent it from being captured by plugins
|
||||||
|
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> SIGN_UPDATE = (user, event, packet) -> {
|
||||||
|
try {
|
||||||
|
String[] lines = (String[]) Reflections.field$ServerboundSignUpdatePacket$lines.get(packet);
|
||||||
|
ImageManager manager = CraftEngine.instance().imageManager();
|
||||||
|
if (!manager.isDefaultFontInUse()) return;
|
||||||
|
for (int i = 0; i < lines.length; i++) {
|
||||||
|
String line = lines[i];
|
||||||
|
if (line != null && !line.isEmpty()) {
|
||||||
|
try {
|
||||||
|
int lineIndex = i;
|
||||||
|
runIfContainsIllegalCharacter(line, manager, (s) -> lines[lineIndex] = s);
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
CraftEngine.instance().logger().warn("Failed to handle ServerboundSignUpdatePacket", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static void runIfContainsIllegalCharacter(String string, ImageManager manager, Consumer<String> callback) {
|
||||||
|
char[] chars = string.toCharArray();
|
||||||
|
int[] codepoints = CharacterUtils.charsToCodePoints(chars);
|
||||||
|
int[] newCodepoints = new int[codepoints.length];
|
||||||
|
boolean hasIllegal = false;
|
||||||
|
for (int i = 0; i < codepoints.length; i++) {
|
||||||
|
int codepoint = codepoints[i];
|
||||||
|
if (!manager.isIllegalCharacter(codepoint)) {
|
||||||
|
newCodepoints[i] = codepoint;
|
||||||
|
} else {
|
||||||
|
newCodepoints[i] = '*';
|
||||||
|
hasIllegal = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasIllegal) {
|
||||||
|
callback.accept(new String(newCodepoints, 0, newCodepoints.length));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,20 +16,23 @@ import net.momirealms.craftengine.core.plugin.network.ConnectionState;
|
|||||||
import net.momirealms.craftengine.core.util.Direction;
|
import net.momirealms.craftengine.core.util.Direction;
|
||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
import net.momirealms.craftengine.core.world.BlockPos;
|
|
||||||
import net.momirealms.craftengine.core.world.Vec3d;
|
|
||||||
import net.momirealms.craftengine.core.world.World;
|
import net.momirealms.craftengine.core.world.World;
|
||||||
|
import net.momirealms.craftengine.core.world.*;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.PlayerInventory;
|
import org.bukkit.inventory.PlayerInventory;
|
||||||
import org.bukkit.util.RayTraceResult;
|
import org.bukkit.util.RayTraceResult;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.lang.ref.Reference;
|
import java.lang.ref.Reference;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public class BukkitServerPlayer extends Player {
|
public class BukkitServerPlayer extends Player {
|
||||||
private final Channel channel;
|
private final Channel channel;
|
||||||
@@ -60,6 +63,8 @@ public class BukkitServerPlayer extends Player {
|
|||||||
|
|
||||||
private Key lastUsedRecipe = null;
|
private Key lastUsedRecipe = null;
|
||||||
|
|
||||||
|
private Map<Integer, List<Integer>> furnitureView = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public BukkitServerPlayer(BukkitCraftEngine plugin, Channel channel) {
|
public BukkitServerPlayer(BukkitCraftEngine plugin, Channel channel) {
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
@@ -201,11 +206,41 @@ public class BukkitServerPlayer extends Player {
|
|||||||
platformPlayer().closeInventory();
|
platformPlayer().closeInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO DO NOT USE BUKKIT API
|
||||||
|
@Override
|
||||||
|
public BlockHitResult rayTrace(double distance, FluidCollisionRule collisionRule) {
|
||||||
|
RayTraceResult result = platformPlayer().rayTraceBlocks(distance, FluidUtils.toCollisionRule(collisionRule));
|
||||||
|
if (result == null) {
|
||||||
|
Location eyeLocation = platformPlayer().getEyeLocation();
|
||||||
|
Location targetLocation = eyeLocation.clone();
|
||||||
|
targetLocation.add(eyeLocation.getDirection().multiply(distance));
|
||||||
|
return BlockHitResult.miss(new Vec3d(eyeLocation.getX(), eyeLocation.getY(), eyeLocation.getZ()),
|
||||||
|
Direction.getApproximateNearest(eyeLocation.getX() - targetLocation.getX(), eyeLocation.getY() - targetLocation.getY(), eyeLocation.getZ() - targetLocation.getZ()),
|
||||||
|
new BlockPos(targetLocation.getBlockX(), targetLocation.getBlockY(), targetLocation.getBlockZ())
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Vector hitPos = result.getHitPosition();
|
||||||
|
Block hitBlock = result.getHitBlock();
|
||||||
|
Location hitBlockLocation = hitBlock.getLocation();
|
||||||
|
return new BlockHitResult(
|
||||||
|
new Vec3d(hitPos.getX(), hitPos.getY(), hitPos.getZ()),
|
||||||
|
DirectionUtils.toDirection(result.getHitBlockFace()),
|
||||||
|
new BlockPos(hitBlockLocation.getBlockX(), hitBlockLocation.getBlockY(), hitBlockLocation.getBlockZ()),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendPacket(Object packet, boolean immediately) {
|
public void sendPacket(Object packet, boolean immediately) {
|
||||||
this.plugin.networkManager().sendPacket(this, packet, immediately);
|
this.plugin.networkManager().sendPacket(this, packet, immediately);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receivePacket(Object packet) {
|
||||||
|
this.plugin.networkManager().receivePacket(this, packet);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConnectionState decoderState() {
|
public ConnectionState decoderState() {
|
||||||
return decoderState;
|
return decoderState;
|
||||||
@@ -553,6 +588,11 @@ public class BukkitServerPlayer extends Player {
|
|||||||
return playerRef.get();
|
return playerRef.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Integer, List<Integer>> furnitureView() {
|
||||||
|
return this.furnitureView;
|
||||||
|
}
|
||||||
|
|
||||||
public void setResendSound() {
|
public void setResendSound() {
|
||||||
resentSoundTick = gameTicks();
|
resentSoundTick = gameTicks();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package net.momirealms.craftengine.bukkit.util;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.core.world.FluidCollisionRule;
|
||||||
|
import org.bukkit.FluidCollisionMode;
|
||||||
|
|
||||||
|
public class FluidUtils {
|
||||||
|
|
||||||
|
private FluidUtils() {}
|
||||||
|
|
||||||
|
public static FluidCollisionMode toCollisionRule(FluidCollisionRule rule) {
|
||||||
|
switch (rule) {
|
||||||
|
case NONE -> {
|
||||||
|
return FluidCollisionMode.NEVER;
|
||||||
|
}
|
||||||
|
case ALWAYS -> {
|
||||||
|
return FluidCollisionMode.ALWAYS;
|
||||||
|
}
|
||||||
|
case SOURCE_ONLY -> {
|
||||||
|
return FluidCollisionMode.SOURCE_ONLY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FluidCollisionMode.NEVER;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,14 @@ public class LocationUtils {
|
|||||||
return new Vec3d(loc.getX(), loc.getY(), loc.getZ());
|
return new Vec3d(loc.getX(), loc.getY(), loc.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vec3d fromVec(Object vec) throws ReflectiveOperationException {
|
||||||
|
return new Vec3d(
|
||||||
|
Reflections.field$Vec3$x.getDouble(vec),
|
||||||
|
Reflections.field$Vec3$y.getDouble(vec),
|
||||||
|
Reflections.field$Vec3$z.getDouble(vec)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static Object toBlockPos(BlockPos pos) {
|
public static Object toBlockPos(BlockPos pos) {
|
||||||
try {
|
try {
|
||||||
return Reflections.constructor$BlockPos.newInstance(pos.x(), pos.y(), pos.z());
|
return Reflections.constructor$BlockPos.newInstance(pos.x(), pos.y(), pos.z());
|
||||||
@@ -21,6 +29,14 @@ public class LocationUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Object above(Object blockPos) throws ReflectiveOperationException {
|
||||||
|
return toBlockPos(
|
||||||
|
Reflections.field$Vec3i$x.getInt(blockPos),
|
||||||
|
Reflections.field$Vec3i$y.getInt(blockPos) + 1,
|
||||||
|
Reflections.field$Vec3i$z.getInt(blockPos)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static Object toBlockPos(int x, int y, int z) {
|
public static Object toBlockPos(int x, int y, int z) {
|
||||||
try {
|
try {
|
||||||
return Reflections.constructor$BlockPos.newInstance(x, y, z);
|
return Reflections.constructor$BlockPos.newInstance(x, y, z);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import io.netty.channel.ChannelFuture;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||||
import io.netty.handler.codec.MessageToByteEncoder;
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -26,6 +27,7 @@ import sun.misc.Unsafe;
|
|||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@@ -134,9 +136,7 @@ public class Reflections {
|
|||||||
);
|
);
|
||||||
|
|
||||||
public static final Constructor<?> constructor$ClientboundSystemChatPacket = requireNonNull(
|
public static final Constructor<?> constructor$ClientboundSystemChatPacket = requireNonNull(
|
||||||
ReflectionUtils.getConstructor(
|
ReflectionUtils.getConstructor(clazz$ClientboundSystemChatPacket, clazz$Component, boolean.class)
|
||||||
clazz$ClientboundSystemChatPacket, clazz$Component, boolean.class
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final Field field$ClientboundSystemChatPacket$overlay = requireNonNull(
|
public static final Field field$ClientboundSystemChatPacket$overlay = requireNonNull(
|
||||||
@@ -189,6 +189,11 @@ public class Reflections {
|
|||||||
clazz$ClientboundSystemChatPacket, clazz$Component, 0
|
clazz$ClientboundSystemChatPacket, clazz$Component, 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static final Field field$ClientboundSystemChatPacket$adventure$content =
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$ClientboundSystemChatPacket, Component.class, 0
|
||||||
|
);
|
||||||
|
|
||||||
public static final Field field$ClientboundSystemChatPacket$text =
|
public static final Field field$ClientboundSystemChatPacket$text =
|
||||||
ReflectionUtils.getDeclaredField(
|
ReflectionUtils.getDeclaredField(
|
||||||
clazz$ClientboundSystemChatPacket, String.class, 0
|
clazz$ClientboundSystemChatPacket, String.class, 0
|
||||||
@@ -1455,6 +1460,12 @@ public class Reflections {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static final Method method$Direction$ordinal = requireNonNull(
|
||||||
|
ReflectionUtils.getMethod(
|
||||||
|
clazz$Direction, new String[]{"ordinal"}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
public static final Method method$Direction$values = requireNonNull(
|
public static final Method method$Direction$values = requireNonNull(
|
||||||
ReflectionUtils.getStaticMethod(
|
ReflectionUtils.getStaticMethod(
|
||||||
clazz$Direction, clazz$Direction.arrayType()
|
clazz$Direction, clazz$Direction.arrayType()
|
||||||
@@ -3326,6 +3337,7 @@ public class Reflections {
|
|||||||
public static final Object instance$Blocks$STONE;
|
public static final Object instance$Blocks$STONE;
|
||||||
public static final Object instance$Blocks$STONE$defaultState;
|
public static final Object instance$Blocks$STONE$defaultState;
|
||||||
public static final Object instance$Blocks$FIRE;
|
public static final Object instance$Blocks$FIRE;
|
||||||
|
public static final Object instance$Blocks$ICE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
@@ -3337,6 +3349,8 @@ public class Reflections {
|
|||||||
Object stone = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "stone");
|
Object stone = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "stone");
|
||||||
instance$Blocks$STONE = method$Registry$get.invoke(instance$BuiltInRegistries$BLOCK, stone);
|
instance$Blocks$STONE = method$Registry$get.invoke(instance$BuiltInRegistries$BLOCK, stone);
|
||||||
instance$Blocks$STONE$defaultState = method$Block$defaultBlockState.invoke(instance$Blocks$STONE);
|
instance$Blocks$STONE$defaultState = method$Block$defaultBlockState.invoke(instance$Blocks$STONE);
|
||||||
|
Object ice = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "ice");
|
||||||
|
instance$Blocks$ICE = method$Registry$get.invoke(instance$BuiltInRegistries$BLOCK, ice);
|
||||||
} catch (ReflectiveOperationException e) {
|
} catch (ReflectiveOperationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@@ -3862,11 +3876,17 @@ public class Reflections {
|
|||||||
);
|
);
|
||||||
|
|
||||||
public static final Object instance$Fluids$WATER;
|
public static final Object instance$Fluids$WATER;
|
||||||
|
public static final Object instance$Fluids$LAVA;
|
||||||
|
public static final Object instance$Fluids$EMPTY;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
Object waterId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "water");
|
Object waterId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "water");
|
||||||
instance$Fluids$WATER = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, waterId);
|
instance$Fluids$WATER = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, waterId);
|
||||||
|
Object lavaId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "lava");
|
||||||
|
instance$Fluids$LAVA = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, lavaId);
|
||||||
|
Object emptyId = method$ResourceLocation$fromNamespaceAndPath.invoke(null, "minecraft", "empty");
|
||||||
|
instance$Fluids$EMPTY = method$Registry$get.invoke(instance$BuiltInRegistries$FLUID, emptyId);
|
||||||
} catch (ReflectiveOperationException e) {
|
} catch (ReflectiveOperationException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@@ -5015,4 +5035,170 @@ public class Reflections {
|
|||||||
clazz$ItemStack, clazz$Item
|
clazz$ItemStack, clazz$Item
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static final Class<?> clazz$BlockHitResult = requireNonNull(
|
||||||
|
ReflectionUtils.getClazz(
|
||||||
|
BukkitReflectionUtils.assembleMCClass("world.phys.BlockHitResult"),
|
||||||
|
BukkitReflectionUtils.assembleMCClass("world.phys.MovingObjectPositionBlock")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Class<?> clazz$ClipContext$Fluid = requireNonNull(
|
||||||
|
ReflectionUtils.getClazz(
|
||||||
|
BukkitReflectionUtils.assembleMCClass("world.level.ClipContext$Fluid"),
|
||||||
|
BukkitReflectionUtils.assembleMCClass("world.level.RayTrace$FluidCollisionOption")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Method method$ClipContext$Fluid$values = requireNonNull(
|
||||||
|
ReflectionUtils.getStaticMethod(
|
||||||
|
clazz$ClipContext$Fluid, clazz$ClipContext$Fluid.arrayType()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Object instance$ClipContext$Fluid$NONE;
|
||||||
|
public static final Object instance$ClipContext$Fluid$SOURCE_ONLY;
|
||||||
|
public static final Object instance$ClipContext$Fluid$ANY;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
Object[] values = (Object[]) method$ClipContext$Fluid$values.invoke(null);
|
||||||
|
instance$ClipContext$Fluid$NONE = values[0];
|
||||||
|
instance$ClipContext$Fluid$SOURCE_ONLY = values[1];
|
||||||
|
instance$ClipContext$Fluid$ANY = values[2];
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Method method$Item$getPlayerPOVHitResult = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredMethod(
|
||||||
|
clazz$Item, clazz$BlockHitResult, clazz$Level, clazz$Player, clazz$ClipContext$Fluid
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Method method$BlockHitResult$withPosition = requireNonNull(
|
||||||
|
ReflectionUtils.getMethod(
|
||||||
|
clazz$BlockHitResult, clazz$BlockHitResult, clazz$BlockPos
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$BlockHitResul$blockPos = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$BlockHitResult, clazz$BlockPos, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$BlockHitResul$direction = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$BlockHitResult, clazz$Direction, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$BlockHitResul$miss = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$BlockHitResult, boolean.class, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$BlockHitResul$inside = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$BlockHitResult, boolean.class, 1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Class<?> clazz$HitResult = requireNonNull(
|
||||||
|
ReflectionUtils.getClazz(
|
||||||
|
BukkitReflectionUtils.assembleMCClass("world.phys.HitResult"),
|
||||||
|
BukkitReflectionUtils.assembleMCClass("world.phys.MovingObjectPosition")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$HitResult$location = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$HitResult, clazz$Vec3, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Class<?> clazz$MessageSignature = requireNonNull(
|
||||||
|
ReflectionUtils.getClazz(
|
||||||
|
BukkitReflectionUtils.assembleMCClass("network.chat.MessageSignature")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Class<?> clazz$LastSeenMessages$Update = requireNonNull(
|
||||||
|
ReflectionUtils.getClazz(
|
||||||
|
BukkitReflectionUtils.assembleMCClass("network.chat.LastSeenMessages$Update"),
|
||||||
|
BukkitReflectionUtils.assembleMCClass("network.chat.LastSeenMessages$b")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Class<?> clazz$ServerboundChatPacket = requireNonNull(
|
||||||
|
ReflectionUtils.getClazz(
|
||||||
|
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundChatPacket"),
|
||||||
|
BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInChat")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Constructor<?> constructor$ServerboundChatPacket = requireNonNull(
|
||||||
|
ReflectionUtils.getConstructor(
|
||||||
|
clazz$ServerboundChatPacket, String.class, Instant.class, long.class, clazz$MessageSignature, clazz$LastSeenMessages$Update
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$ServerboundChatPacket$message = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$ServerboundChatPacket, String.class, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$ServerboundChatPacket$timeStamp = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$ServerboundChatPacket, Instant.class, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$ServerboundChatPacket$salt = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$ServerboundChatPacket, long.class, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$ServerboundChatPacket$signature = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$ServerboundChatPacket, clazz$MessageSignature, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$ServerboundChatPacket$lastSeenMessages = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$ServerboundChatPacket, clazz$LastSeenMessages$Update, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Class<?> clazz$ServerboundRenameItemPacket = requireNonNull(
|
||||||
|
ReflectionUtils.getClazz(
|
||||||
|
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundRenameItemPacket"),
|
||||||
|
BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInItemName")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$ServerboundRenameItemPacket$name = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$ServerboundRenameItemPacket, String.class, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Class<?> clazz$ServerboundSignUpdatePacket = requireNonNull(
|
||||||
|
ReflectionUtils.getClazz(
|
||||||
|
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ServerboundSignUpdatePacket"),
|
||||||
|
BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayInUpdateSign")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final Field field$ServerboundSignUpdatePacket$lines = requireNonNull(
|
||||||
|
ReflectionUtils.getDeclaredField(
|
||||||
|
clazz$ServerboundSignUpdatePacket, String[].class, 0
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class BukkitCEWorld extends CEWorld {
|
|||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (ConfigManager.enableLightSystem()) {
|
if (ConfigManager.enableLightSystem()) {
|
||||||
LightUtils.updateChunkLight((org.bukkit.World) world.getHandle(), SectionPosUtils.toMap(super.updatedSectionPositions, world.worldHeight().getMinSection() - 1, world.worldHeight().getMaxSection() + 1));
|
LightUtils.updateChunkLight((org.bukkit.World) world.platformWorld(), SectionPosUtils.toMap(super.updatedSectionPositions, world.worldHeight().getMinSection() - 1, world.worldHeight().getMaxSection() + 1));
|
||||||
super.updatedSectionPositions.clear();
|
super.updatedSectionPositions.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.world;
|
|||||||
|
|
||||||
import net.momirealms.craftengine.bukkit.util.EntityUtils;
|
import net.momirealms.craftengine.bukkit.util.EntityUtils;
|
||||||
import net.momirealms.craftengine.bukkit.util.ItemUtils;
|
import net.momirealms.craftengine.bukkit.util.ItemUtils;
|
||||||
|
import net.momirealms.craftengine.bukkit.util.Reflections;
|
||||||
import net.momirealms.craftengine.core.item.Item;
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
@@ -28,36 +29,45 @@ public class BukkitWorld implements World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public org.bukkit.World getHandle() {
|
public org.bukkit.World platformWorld() {
|
||||||
return world.get();
|
return world.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object serverWorld() {
|
||||||
|
try {
|
||||||
|
return Reflections.field$CraftWorld$ServerLevel.get(platformWorld());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to get server world", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WorldHeight worldHeight() {
|
public WorldHeight worldHeight() {
|
||||||
if (this.worldHeight == null) {
|
if (this.worldHeight == null) {
|
||||||
this.worldHeight = WorldHeight.create(getHandle().getMinHeight(), getHandle().getMaxHeight() - getHandle().getMinHeight());
|
this.worldHeight = WorldHeight.create(platformWorld().getMinHeight(), platformWorld().getMaxHeight() - platformWorld().getMinHeight());
|
||||||
}
|
}
|
||||||
return this.worldHeight;
|
return this.worldHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WorldBlock getBlockAt(int x, int y, int z) {
|
public WorldBlock getBlockAt(int x, int y, int z) {
|
||||||
return new BukkitWorldBlock(getHandle().getBlockAt(x, y, z));
|
return new BukkitWorldBlock(platformWorld().getBlockAt(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String name() {
|
public String name() {
|
||||||
return getHandle().getName();
|
return platformWorld().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path directory() {
|
public Path directory() {
|
||||||
return getHandle().getWorldFolder().toPath();
|
return platformWorld().getWorldFolder().toPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID uuid() {
|
public UUID uuid() {
|
||||||
return getHandle().getUID();
|
return platformWorld().getUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -65,16 +75,16 @@ public class BukkitWorld implements World {
|
|||||||
ItemStack itemStack = (ItemStack) item.load();
|
ItemStack itemStack = (ItemStack) item.load();
|
||||||
if (ItemUtils.isEmpty(itemStack)) return;
|
if (ItemUtils.isEmpty(itemStack)) return;
|
||||||
if (VersionHelper.isVersionNewerThan1_21_2()) {
|
if (VersionHelper.isVersionNewerThan1_21_2()) {
|
||||||
getHandle().dropItemNaturally(new Location(null, location.x(), location.y(), location.z()), (ItemStack) item.getItem());
|
platformWorld().dropItemNaturally(new Location(null, location.x(), location.y(), location.z()), (ItemStack) item.getItem());
|
||||||
} else {
|
} else {
|
||||||
getHandle().dropItemNaturally(new Location(null, location.x() - 0.5, location.y() - 0.5, location.z() - 0.5), (ItemStack) item.getItem());
|
platformWorld().dropItemNaturally(new Location(null, location.x() - 0.5, location.y() - 0.5, location.z() - 0.5), (ItemStack) item.getItem());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dropExp(Vec3d location, int amount) {
|
public void dropExp(Vec3d location, int amount) {
|
||||||
if (amount <= 0) return;
|
if (amount <= 0) return;
|
||||||
EntityUtils.spawnEntity(getHandle(), new Location(getHandle(), location.x(), location.y(), location.z()), EntityType.EXPERIENCE_ORB, (e) -> {
|
EntityUtils.spawnEntity(platformWorld(), new Location(platformWorld(), location.x(), location.y(), location.z()), EntityType.EXPERIENCE_ORB, (e) -> {
|
||||||
ExperienceOrb orb = (ExperienceOrb) e;
|
ExperienceOrb orb = (ExperienceOrb) e;
|
||||||
orb.setExperience(amount);
|
orb.setExperience(amount);
|
||||||
});
|
});
|
||||||
@@ -82,6 +92,6 @@ public class BukkitWorld implements World {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playBlockSound(Vec3d location, Key sound, float volume, float pitch) {
|
public void playBlockSound(Vec3d location, Key sound, float volume, float pitch) {
|
||||||
getHandle().playSound(new Location(null, location.x(), location.y(), location.z()), sound.toString(), SoundCategory.BLOCKS, volume, pitch);
|
platformWorld().playSound(new Location(null, location.x(), location.y(), location.z()), sound.toString(), SoundCategory.BLOCKS, volume, pitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class BlockBehaviors {
|
public class BlockBehaviors {
|
||||||
|
public static final Key EMPTY = Key.from("craftengine:empty");
|
||||||
|
|
||||||
public static void register(Key key, BlockBehaviorFactory factory) {
|
public static void register(Key key, BlockBehaviorFactory factory) {
|
||||||
Holder.Reference<BlockBehaviorFactory> holder = ((WritableRegistry<BlockBehaviorFactory>) BuiltInRegistries.BLOCK_BEHAVIOR_FACTORY)
|
Holder.Reference<BlockBehaviorFactory> holder = ((WritableRegistry<BlockBehaviorFactory>) BuiltInRegistries.BLOCK_BEHAVIOR_FACTORY)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import net.momirealms.craftengine.core.plugin.Reloadable;
|
|||||||
import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser;
|
import net.momirealms.craftengine.core.plugin.config.ConfigSectionParser;
|
||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface FurnitureManager extends Reloadable, ConfigSectionParser {
|
public interface FurnitureManager extends Reloadable, ConfigSectionParser {
|
||||||
@@ -25,8 +24,5 @@ public interface FurnitureManager extends Reloadable, ConfigSectionParser {
|
|||||||
|
|
||||||
Optional<CustomFurniture> getFurniture(Key id);
|
Optional<CustomFurniture> getFurniture(Key id);
|
||||||
|
|
||||||
@Nullable
|
|
||||||
int[] getSubEntityIdsByBaseEntityId(int entityId);
|
|
||||||
|
|
||||||
boolean isFurnitureBaseEntity(int entityId);
|
boolean isFurnitureBaseEntity(int entityId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import net.momirealms.craftengine.core.entity.Entity;
|
|||||||
import net.momirealms.craftengine.core.item.Item;
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
import net.momirealms.craftengine.core.world.BlockHitResult;
|
||||||
import net.momirealms.craftengine.core.world.BlockPos;
|
import net.momirealms.craftengine.core.world.BlockPos;
|
||||||
|
import net.momirealms.craftengine.core.world.FluidCollisionRule;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public abstract class Player extends Entity implements NetWorkUser {
|
public abstract class Player extends Entity implements NetWorkUser {
|
||||||
@@ -68,4 +70,6 @@ public abstract class Player extends Entity implements NetWorkUser {
|
|||||||
public abstract void giveItem(Item<?> item);
|
public abstract void giveItem(Item<?> item);
|
||||||
|
|
||||||
public abstract void closeInventory();
|
public abstract void closeInventory();
|
||||||
|
|
||||||
|
public abstract BlockHitResult rayTrace(double distance, FluidCollisionRule collisionRule);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package net.momirealms.craftengine.core.font;
|
|||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
@@ -19,6 +20,10 @@ public class Font {
|
|||||||
return this.idToCodepoint.containsKey(codepoint);
|
return this.idToCodepoint.containsKey(codepoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Collection<Integer> codepointsInUse() {
|
||||||
|
return Collections.unmodifiableCollection(this.idToCodepoint.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
public BitmapImage getImageByCodepoint(int codepoint) {
|
public BitmapImage getImageByCodepoint(int codepoint) {
|
||||||
return this.idToCodepoint.get(codepoint);
|
return this.idToCodepoint.get(codepoint);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,18 @@ import java.util.function.BiFunction;
|
|||||||
|
|
||||||
public interface ImageManager extends Reloadable, ConfigSectionParser {
|
public interface ImageManager extends Reloadable, ConfigSectionParser {
|
||||||
String CONFIG_SECTION_NAME = "images";
|
String CONFIG_SECTION_NAME = "images";
|
||||||
|
Key DEFAULT_FONT = Key.of("minecraft:default");
|
||||||
|
|
||||||
default String sectionId() {
|
default String sectionId() {
|
||||||
return CONFIG_SECTION_NAME;
|
return CONFIG_SECTION_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void delayedLoad();
|
||||||
|
|
||||||
|
boolean isDefaultFontInUse();
|
||||||
|
|
||||||
|
boolean isIllegalCharacter(int codepoint);
|
||||||
|
|
||||||
Collection<Font> fontsInUse();
|
Collection<Font> fontsInUse();
|
||||||
|
|
||||||
Optional<BitmapImage> bitmapImageByCodepoint(Key font, int codepoint);
|
Optional<BitmapImage> bitmapImageByCodepoint(Key font, int codepoint);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public class ImageManagerImpl implements ImageManager {
|
|||||||
private final HashMap<Key, Font> fonts = new HashMap<>();
|
private final HashMap<Key, Font> fonts = new HashMap<>();
|
||||||
// namespace:id image
|
// namespace:id image
|
||||||
private final HashMap<Key, BitmapImage> images = new HashMap<>();
|
private final HashMap<Key, BitmapImage> images = new HashMap<>();
|
||||||
|
private final Set<Integer> illegalChars = new HashSet<>();
|
||||||
|
|
||||||
private OffsetFont offsetFont;
|
private OffsetFont offsetFont;
|
||||||
|
|
||||||
@@ -36,6 +37,24 @@ public class ImageManagerImpl implements ImageManager {
|
|||||||
public void unload() {
|
public void unload() {
|
||||||
this.fonts.clear();
|
this.fonts.clear();
|
||||||
this.images.clear();
|
this.images.clear();
|
||||||
|
this.illegalChars.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delayedLoad() {
|
||||||
|
Optional.ofNullable(this.fonts.get(DEFAULT_FONT)).ifPresent(font -> {
|
||||||
|
this.illegalChars.addAll(font.codepointsInUse());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDefaultFontInUse() {
|
||||||
|
return !this.illegalChars.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIllegalCharacter(int codepoint) {
|
||||||
|
return this.illegalChars.contains(codepoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -280,7 +280,13 @@ public class AbstractItem<W extends ItemWrapper<I>, I> implements Item<I> {
|
|||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
@Override
|
@Override
|
||||||
public Item<I> merge(Item<?> another) {
|
public Item<I> mergeCopy(Item<?> another) {
|
||||||
return new AbstractItem<>(this.factory, this.factory.merge(this.item, ((AbstractItem) another).item));
|
return new AbstractItem<>(this.factory, this.factory.mergeCopy(this.item, ((AbstractItem) another).item));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
@Override
|
||||||
|
public void merge(Item<I> another) {
|
||||||
|
this.factory.merge(this.item, ((AbstractItem) another).item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
protected static final List<Key> VANILLA_ITEMS = new ArrayList<>();
|
protected static final List<Key> VANILLA_ITEMS = new ArrayList<>();
|
||||||
protected static final Map<Key, List<Holder<Key>>> VANILLA_ITEM_TAGS = new HashMap<>();
|
protected static final Map<Key, List<Holder<Key>>> VANILLA_ITEM_TAGS = new HashMap<>();
|
||||||
|
|
||||||
|
protected final Map<String, ExternalItemProvider<I>> externalItemProviders = new HashMap<>();
|
||||||
protected final Map<String, Function<Object, ItemModifier<I>>> dataFunctions = new HashMap<>();
|
protected final Map<String, Function<Object, ItemModifier<I>>> dataFunctions = new HashMap<>();
|
||||||
protected final Map<Key, CustomItem<I>> customItems = new HashMap<>();
|
protected final Map<Key, CustomItem<I>> customItems = new HashMap<>();
|
||||||
protected final Map<Key, List<Holder<Key>>> customItemTags;
|
protected final Map<Key, List<Holder<Key>>> customItemTags;
|
||||||
@@ -47,6 +48,18 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExternalItemProvider<I> getExternalItemProvider(String name) {
|
||||||
|
return this.externalItemProviders.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean registerExternalItemProvider(ExternalItemProvider<I> externalItemProvider) {
|
||||||
|
if (this.externalItemProviders.containsKey(externalItemProvider.plugin())) return false;
|
||||||
|
this.externalItemProviders.put(externalItemProvider.plugin(), externalItemProvider);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unload() {
|
public void unload() {
|
||||||
super.clearModelsToGenerate();
|
super.clearModelsToGenerate();
|
||||||
@@ -165,6 +178,13 @@ public abstract class AbstractItemManager<I> extends AbstractModelGenerator impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void registerFunctions() {
|
private void registerFunctions() {
|
||||||
|
registerDataFunction((obj) -> {
|
||||||
|
Map<String, Object> data = MiscUtils.castToMap(obj, false);
|
||||||
|
String plugin = data.get("plugin").toString();
|
||||||
|
String id = data.get("id").toString();
|
||||||
|
ExternalItemProvider<I> provider = AbstractItemManager.this.getExternalItemProvider(plugin);
|
||||||
|
return new ExternalModifier<>(id, Objects.requireNonNull(provider, "Item provider " + plugin + " not found"));
|
||||||
|
}, "external");
|
||||||
registerDataFunction((obj) -> {
|
registerDataFunction((obj) -> {
|
||||||
String name = obj.toString();
|
String name = obj.toString();
|
||||||
return new DisplayNameModifier<>(name);
|
return new DisplayNameModifier<>(name);
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package net.momirealms.craftengine.core.item;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public interface ExternalItemProvider<I> {
|
||||||
|
|
||||||
|
String plugin();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
I build(String id, ItemBuildContext context);
|
||||||
|
}
|
||||||
@@ -117,5 +117,7 @@ public interface Item<I> {
|
|||||||
|
|
||||||
Object getLiteralObject();
|
Object getLiteralObject();
|
||||||
|
|
||||||
Item<I> merge(Item<?> another);
|
Item<I> mergeCopy(Item<?> another);
|
||||||
|
|
||||||
|
void merge(Item<I> another);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,5 +112,7 @@ public abstract class ItemFactory<P extends Plugin, W extends ItemWrapper<I>, I>
|
|||||||
|
|
||||||
protected abstract Optional<Integer> repairCost(ItemWrapper<I> item);
|
protected abstract Optional<Integer> repairCost(ItemWrapper<I> item);
|
||||||
|
|
||||||
protected abstract ItemWrapper<I> merge(ItemWrapper<I> item1, ItemWrapper<I> item2);
|
protected abstract ItemWrapper<I> mergeCopy(ItemWrapper<I> item1, ItemWrapper<I> item2);
|
||||||
|
|
||||||
|
protected abstract void merge(ItemWrapper<I> item1, ItemWrapper<I> item2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ public interface ItemManager<T> extends Reloadable, ModelGenerator, ConfigSectio
|
|||||||
|
|
||||||
Key customItemId(T itemStack);
|
Key customItemId(T itemStack);
|
||||||
|
|
||||||
|
ExternalItemProvider<T> getExternalItemProvider(String name);
|
||||||
|
|
||||||
|
boolean registerExternalItemProvider(ExternalItemProvider<T> externalItemProvider);
|
||||||
|
|
||||||
Optional<CustomItem<T>> getCustomItem(Key key);
|
Optional<CustomItem<T>> getCustomItem(Key key);
|
||||||
|
|
||||||
Optional<List<ItemBehavior>> getItemBehavior(Key key);
|
Optional<List<ItemBehavior>> getItemBehavior(Key key);
|
||||||
|
|||||||
@@ -1,5 +1,20 @@
|
|||||||
package net.momirealms.craftengine.core.item.behavior;
|
package net.momirealms.craftengine.core.item.behavior;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.core.pack.Pack;
|
||||||
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class EmptyItemBehavior extends ItemBehavior {
|
public class EmptyItemBehavior extends ItemBehavior {
|
||||||
|
public static final Factory FACTORY = new Factory();
|
||||||
public static final EmptyItemBehavior INSTANCE = new EmptyItemBehavior();
|
public static final EmptyItemBehavior INSTANCE = new EmptyItemBehavior();
|
||||||
|
|
||||||
|
public static class Factory implements ItemBehaviorFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.nio.file.Path;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ItemBehaviors {
|
public class ItemBehaviors {
|
||||||
|
public static final Key EMPTY = Key.from("craftengine:empty");
|
||||||
|
|
||||||
public static void register(Key key, ItemBehaviorFactory factory) {
|
public static void register(Key key, ItemBehaviorFactory factory) {
|
||||||
Holder.Reference<ItemBehaviorFactory> holder = ((WritableRegistry<ItemBehaviorFactory>) BuiltInRegistries.ITEM_BEHAVIOR_FACTORY)
|
Holder.Reference<ItemBehaviorFactory> holder = ((WritableRegistry<ItemBehaviorFactory>) BuiltInRegistries.ITEM_BEHAVIOR_FACTORY)
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package net.momirealms.craftengine.core.item.modifier;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.core.item.ExternalItemProvider;
|
||||||
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
|
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||||
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
|
|
||||||
|
public class ExternalModifier<I> implements ItemModifier<I> {
|
||||||
|
private final String id;
|
||||||
|
private final ExternalItemProvider<I> provider;
|
||||||
|
|
||||||
|
public ExternalModifier(String id, ExternalItemProvider<I> provider) {
|
||||||
|
this.id = id;
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String name() {
|
||||||
|
return "external";
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void apply(Item<I> item, ItemBuildContext context) {
|
||||||
|
I another = this.provider.build(id, context);
|
||||||
|
if (another == null) {
|
||||||
|
CraftEngine.instance().logger().warn("'" + id + "' could not be found in " + provider.plugin());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Item<I> anotherWrapped = (Item<I>) CraftEngine.instance().itemManager().wrap(another);
|
||||||
|
item.merge(anotherWrapped);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -96,7 +96,7 @@ public class CustomSmithingTransformRecipe<T> implements Recipe<T> {
|
|||||||
Item<T> wrappedResult = (Item<T>) CraftEngine.instance().itemManager().wrap(result);
|
Item<T> wrappedResult = (Item<T>) CraftEngine.instance().itemManager().wrap(result);
|
||||||
Item<T> finalResult = wrappedResult;
|
Item<T> finalResult = wrappedResult;
|
||||||
if (this.mergeComponents) {
|
if (this.mergeComponents) {
|
||||||
finalResult = base.merge(wrappedResult);
|
finalResult = base.mergeCopy(wrappedResult);
|
||||||
}
|
}
|
||||||
for (ItemDataProcessor processor : this.processors) {
|
for (ItemDataProcessor processor : this.processors) {
|
||||||
processor.accept(base, wrappedResult, finalResult);
|
processor.accept(base, wrappedResult, finalResult);
|
||||||
|
|||||||
@@ -320,14 +320,17 @@ public abstract class AbstractPackManager implements PackManager {
|
|||||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/stripped_palm_log.png");
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/stripped_palm_log.png");
|
||||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/stripped_palm_log_top.png");
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/stripped_palm_log_top.png");
|
||||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/palm_leaves.png");
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/palm_leaves.png");
|
||||||
// fairy flower
|
// plants
|
||||||
plugin.saveResource("resources/default/configuration/fairy_flower.yml");
|
plugin.saveResource("resources/default/configuration/plants.yml");
|
||||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/fairy_flower_1.png");
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/fairy_flower_1.png");
|
||||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/fairy_flower_2.png");
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/fairy_flower_2.png");
|
||||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/fairy_flower_3.png");
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/fairy_flower_3.png");
|
||||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/fairy_flower_4.png");
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/fairy_flower_4.png");
|
||||||
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/block/custom/reed.png");
|
||||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/fairy_flower.png");
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/fairy_flower.png");
|
||||||
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/item/custom/reed.png");
|
||||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/block/custom/fairy_flower_1.json");
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/block/custom/fairy_flower_1.json");
|
||||||
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/block/custom/reed.json");
|
||||||
// furniture
|
// furniture
|
||||||
plugin.saveResource("resources/default/configuration/furniture.yml");
|
plugin.saveResource("resources/default/configuration/furniture.yml");
|
||||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/item/custom/table_lamp.json");
|
plugin.saveResource("resources/default/resourcepack/assets/minecraft/models/item/custom/table_lamp.json");
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package net.momirealms.craftengine.core.pack.conflict.resolution;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
|
import net.momirealms.craftengine.core.util.GsonHelper;
|
||||||
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class MergeAltasResolution implements Resolution {
|
||||||
|
public static final Factory FACTORY = new Factory();
|
||||||
|
public static final MergeAltasResolution INSTANCE = new MergeAltasResolution();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(Path existing, Path conflict) {
|
||||||
|
try {
|
||||||
|
JsonObject j1 = GsonHelper.readJsonFile(existing).getAsJsonObject();
|
||||||
|
JsonObject j2 = GsonHelper.readJsonFile(conflict).getAsJsonObject();
|
||||||
|
JsonObject j3 = new JsonObject();
|
||||||
|
JsonArray ja1 = j1.getAsJsonArray("sources");
|
||||||
|
JsonArray ja2 = j2.getAsJsonArray("sources");
|
||||||
|
JsonArray ja3 = new JsonArray();
|
||||||
|
HashSet<String> elements = new HashSet<>();
|
||||||
|
for (JsonElement je : ja1) {
|
||||||
|
if (elements.add(je.getAsString())) {
|
||||||
|
ja3.add(je);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (JsonElement je : ja2) {
|
||||||
|
if (elements.add(je.getAsString())) {
|
||||||
|
ja3.add(je);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
j3.add("sources", ja3);
|
||||||
|
GsonHelper.writeJsonFile(j3, existing);
|
||||||
|
} catch (IOException e) {
|
||||||
|
CraftEngine.instance().logger().severe("Failed to merge json when resolving file conflicts", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Key type() {
|
||||||
|
return Resolutions.MERGE_ATLAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Factory implements ResolutionFactory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Resolution create(Map<String, Object> arguments) {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ import java.util.Map;
|
|||||||
public class Resolutions {
|
public class Resolutions {
|
||||||
public static final Key RETAIN_MATCHING = Key.of("craftengine:retain_matching");
|
public static final Key RETAIN_MATCHING = Key.of("craftengine:retain_matching");
|
||||||
public static final Key MERGE_JSON = Key.of("craftengine:merge_json");
|
public static final Key MERGE_JSON = Key.of("craftengine:merge_json");
|
||||||
|
public static final Key MERGE_ATLAS = Key.of("craftengine:merge_atlas");
|
||||||
public static final Key CONDITIONAL = Key.of("craftengine:conditional");
|
public static final Key CONDITIONAL = Key.of("craftengine:conditional");
|
||||||
public static final Key MERGE_PACK_MCMETA = Key.of("craftengine:merge_pack_mcmeta");
|
public static final Key MERGE_PACK_MCMETA = Key.of("craftengine:merge_pack_mcmeta");
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ public class Resolutions {
|
|||||||
register(MERGE_JSON, MergeJsonResolution.FACTORY);
|
register(MERGE_JSON, MergeJsonResolution.FACTORY);
|
||||||
register(CONDITIONAL, ConditionalResolution.FACTORY);
|
register(CONDITIONAL, ConditionalResolution.FACTORY);
|
||||||
register(MERGE_PACK_MCMETA, MergePackMcMetaResolution.FACTORY);
|
register(MERGE_PACK_MCMETA, MergePackMcMetaResolution.FACTORY);
|
||||||
|
register(MERGE_ATLAS, MergeAltasResolution.FACTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void register(Key key, ResolutionFactory factory) {
|
public static void register(Key key, ResolutionFactory factory) {
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ public abstract class CraftEngine implements Plugin {
|
|||||||
this.blockManager.delayedLoad();
|
this.blockManager.delayedLoad();
|
||||||
this.itemBrowserManager.delayedLoad();
|
this.itemBrowserManager.delayedLoad();
|
||||||
this.soundManager.delayedLoad();
|
this.soundManager.delayedLoad();
|
||||||
|
this.imageManager.delayedLoad();
|
||||||
if (ConfigManager.debug()) {
|
if (ConfigManager.debug()) {
|
||||||
this.debugger = (s) -> logger.info("[Debug] " + s.get());
|
this.debugger = (s) -> logger.info("[Debug] " + s.get());
|
||||||
} else {
|
} else {
|
||||||
@@ -126,11 +127,11 @@ public abstract class CraftEngine implements Plugin {
|
|||||||
// delay the reload so other plugins can register some parsers
|
// delay the reload so other plugins can register some parsers
|
||||||
this.scheduler.sync().runDelayed(() -> {
|
this.scheduler.sync().runDelayed(() -> {
|
||||||
this.registerParsers();
|
this.registerParsers();
|
||||||
|
this.itemManager.delayedInit();
|
||||||
this.reload();
|
this.reload();
|
||||||
this.guiManager.delayedInit();
|
this.guiManager.delayedInit();
|
||||||
this.recipeManager.delayedInit();
|
this.recipeManager.delayedInit();
|
||||||
this.blockManager.delayedInit();
|
this.blockManager.delayedInit();
|
||||||
this.itemManager.delayedInit();
|
|
||||||
this.worldManager.delayedInit();
|
this.worldManager.delayedInit();
|
||||||
this.packManager.delayedInit();
|
this.packManager.delayedInit();
|
||||||
this.furnitureManager.delayedInit();
|
this.furnitureManager.delayedInit();
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import net.momirealms.craftengine.core.plugin.Plugin;
|
|||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface NetWorkUser {
|
public interface NetWorkUser {
|
||||||
boolean isOnline();
|
boolean isOnline();
|
||||||
|
|
||||||
@@ -16,6 +19,8 @@ public interface NetWorkUser {
|
|||||||
|
|
||||||
void sendPacket(Object packet, boolean immediately);
|
void sendPacket(Object packet, boolean immediately);
|
||||||
|
|
||||||
|
void receivePacket(Object packet);
|
||||||
|
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
ConnectionState decoderState();
|
ConnectionState decoderState();
|
||||||
|
|
||||||
@@ -29,4 +34,6 @@ public interface NetWorkUser {
|
|||||||
Object serverPlayer();
|
Object serverPlayer();
|
||||||
|
|
||||||
Object platformPlayer();
|
Object platformPlayer();
|
||||||
|
|
||||||
|
Map<Integer, List<Integer>> furnitureView();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,6 +182,21 @@ public enum Direction {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Direction getApproximateNearest(double x, double y, double z) {
|
||||||
|
Direction nearestDirection = null;
|
||||||
|
double maxDotProduct = -Double.MAX_VALUE;
|
||||||
|
for (Direction direction : Direction.values()) {
|
||||||
|
double dotProduct = x * direction.vec.x() +
|
||||||
|
y * direction.vec.y() +
|
||||||
|
z * direction.vec.z();
|
||||||
|
if (dotProduct > maxDotProduct) {
|
||||||
|
maxDotProduct = dotProduct;
|
||||||
|
nearestDirection = direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nearestDirection;
|
||||||
|
}
|
||||||
|
|
||||||
public static Direction from3DDataValue(int id) {
|
public static Direction from3DDataValue(int id) {
|
||||||
return BY_3D_DATA[Math.abs(id % BY_3D_DATA.length)];
|
return BY_3D_DATA[Math.abs(id % BY_3D_DATA.length)];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package net.momirealms.craftengine.core.world;
|
||||||
|
|
||||||
|
public enum FluidCollisionRule {
|
||||||
|
NONE,
|
||||||
|
SOURCE_ONLY,
|
||||||
|
ALWAYS
|
||||||
|
}
|
||||||
@@ -8,7 +8,9 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public interface World {
|
public interface World {
|
||||||
|
|
||||||
Object getHandle();
|
Object platformWorld();
|
||||||
|
|
||||||
|
Object serverWorld();
|
||||||
|
|
||||||
WorldHeight worldHeight();
|
WorldHeight worldHeight();
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import net.momirealms.craftengine.shared.block.*;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class CraftEngineBlock extends Block implements BehaviorHolder, ShapeHolder, NoteBlockIndicator, Fallable, BonemealableBlock {
|
public class CraftEngineBlock extends Block implements BehaviorHolder, ShapeHolder, NoteBlockIndicator, Fallable, BonemealableBlock {
|
||||||
private static final PaperWeightStoneBlockShape STONE = new PaperWeightStoneBlockShape(Blocks.STONE.defaultBlockState());
|
private static final StoneBlockShape STONE = new StoneBlockShape(Blocks.STONE.defaultBlockState());
|
||||||
private boolean isNoteBlock;
|
private boolean isNoteBlock;
|
||||||
public ObjectHolder<BlockBehavior> behaviorHolder;
|
public ObjectHolder<BlockBehavior> behaviorHolder;
|
||||||
public ObjectHolder<BlockShape> shapeHolder;
|
public ObjectHolder<BlockShape> shapeHolder;
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.momirealms.craftengine.shared.block.BlockShape;
|
import net.momirealms.craftengine.shared.block.BlockShape;
|
||||||
|
|
||||||
public class PaperWeightStoneBlockShape implements BlockShape {
|
public class StoneBlockShape implements BlockShape {
|
||||||
private final BlockState rawBlockState;
|
private final BlockState rawBlockState;
|
||||||
|
|
||||||
public PaperWeightStoneBlockShape(BlockState rawBlockState) {
|
public StoneBlockShape(BlockState rawBlockState) {
|
||||||
this.rawBlockState = rawBlockState;
|
this.rawBlockState = rawBlockState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3,6 +3,7 @@ include(":shared")
|
|||||||
include(":core")
|
include(":core")
|
||||||
include(":bukkit")
|
include(":bukkit")
|
||||||
include(":bukkit:legacy")
|
include(":bukkit:legacy")
|
||||||
|
include(":bukkit:compatibility")
|
||||||
include(":bukkit-loader")
|
include(":bukkit-loader")
|
||||||
include(":server-mod")
|
include(":server-mod")
|
||||||
pluginManagement {
|
pluginManagement {
|
||||||
|
|||||||
Reference in New Issue
Block a user