From 1a081cb204bc1f6564db2e5502f10fc05a9a325e Mon Sep 17 00:00:00 2001 From: Dmitry Luk Date: Thu, 9 May 2024 23:36:21 +0400 Subject: [PATCH] refactor: close #190 & code cleanup --- .idea/codeStyles/Project.xml | 5 +- .../allaymc/api/block/type/BlockState.java | 2 +- .../api/block/type/BlockTypeBuilder.java | 2 +- .../allaymc/api/client/data/LoginData.java | 83 +++--- .../interfaces/ComponentProvider.java | 17 +- .../api/container/BaseContainerHolder.java | 7 +- .../api/entity/attribute/AttributeType.java | 16 +- .../main/java/org/allaymc/api/i18n/I18n.java | 18 +- .../item/component/common/ItemAttributes.java | 2 +- .../org/allaymc/api/item/type/ItemType.java | 5 +- .../org/allaymc/api/utils/Identifier.java | 16 +- .../java/org/allaymc/api/world/Dimension.java | 46 ++- .../allaymc/api/world/chunk/ChunkSection.java | 14 +- .../allaymc/api/world/palette/Palette.java | 93 +++---- .../java/org/allaymc/server/AllayServer.java | 57 ++-- .../common/BlockAttributeComponentImpl.java | 12 +- .../common/BlockBaseComponentImpl.java | 20 +- .../BlockEntityHolderComponentImpl.java | 13 +- .../server/block/type/AllayBlockType.java | 123 ++++---- .../BlockEntityBarrelBaseComponentImpl.java | 13 +- .../BlockEntityChestBaseComponentImpl.java | 13 +- .../common/BlockEntityBaseComponentImpl.java | 18 +- ...ockEntityContainerHolderComponentImpl.java | 15 +- .../type/AllayBlockEntityType.java | 9 +- .../storage/AllayCachedPlayerStorage.java | 1 - .../storage/AllayNBTFilePlayerStorage.java | 6 +- .../server/command/AllayCommandRegistry.java | 2 +- .../processor/ContainerActionProcessor.java | 13 +- .../ContainerActionProcessorHolder.java | 14 +- .../CraftCreativeActionProcessor.java | 12 +- .../processor/CraftRecipeActionProcessor.java | 18 +- .../CraftResultDeprecatedActionProcessor.java | 10 +- .../processor/CreateActionProcessor.java | 10 +- .../processor/DestroyActionProcessor.java | 10 +- .../processor/DropActionProcessor.java | 34 +-- .../processor/SwapActionProcessor.java | 10 +- .../TransferItemActionProcessor.java | 18 +- .../AllayVanillaItemMetaBlockStateBiMap.java | 6 +- .../common/EntityAttributeComponentImpl.java | 19 +- .../common/EntityBaseComponentImpl.java | 78 ++---- .../EntityContainerHolderComponentImpl.java | 6 +- .../common/EntityDamageComponentImpl.java | 6 +- .../item/EntityItemBaseComponentImpl.java | 42 +-- .../player/EntityPlayerBaseComponentImpl.java | 7 +- ...ityPlayerContainerHolderComponentImpl.java | 15 +- ...ityPlayerContainerViewerComponentImpl.java | 12 +- .../EntityPlayerDamageComponentImpl.java | 4 + .../EntityPlayerNetworkComponentImpl.java | 23 +- .../entity/effect/AllayEffectRegistry.java | 2 +- .../registry/AllayEntityTypeRegistry.java | 24 +- .../server/entity/type/AllayEntityType.java | 19 +- .../allaymc/server/i18n/AllayI18nLoader.java | 13 +- .../AllayVanillaItemAttributeRegistry.java | 4 +- .../air/ItemAirBaseComponentImpl.java | 2 +- .../common/ItemAttributeComponentImpl.java | 18 +- .../common/ItemBaseComponentImpl.java | 106 +++---- .../enchantment/AllayEnchantmentRegistry.java | 2 +- .../item/recipe/AllayRecipeRegistry.java | 10 +- .../registry/AllayCreativeItemRegistry.java | 2 +- .../item/registry/AllayItemTypeRegistry.java | 35 ++- .../server/pack/AllayPackRegistry.java | 8 +- .../allaymc/server/pack/PackEncryptor.java | 11 +- .../server/pack/loader/ZipPackLoader.java | 1 - .../server/perm/tree/AllayPermNode.java | 8 +- .../server/perm/tree/AllayPermTree.java | 29 +- .../server/plugin/AllayPluginManager.java | 16 +- .../server/plugin/DefaultPluginSource.java | 14 +- .../allaymc/server/plugin/js/JsPlugin.java | 2 +- .../utils/ComponentClassCacheUtils.java | 6 +- .../allaymc/server/world/AllayDimension.java | 5 +- .../org/allaymc/server/world/AllayWorld.java | 54 ++-- .../allaymc/server/world/AllayWorldPool.java | 15 +- .../world/biome/AllayBiomeTypeRegistry.java | 6 +- .../server/world/chunk/AllayChunk.java | 43 +-- .../server/world/chunk/AllayUnsafeChunk.java | 89 +++--- .../world/generator/FlatWorldGenerator.java | 12 +- .../world/generator/JeGeneratorLoader.java | 14 +- .../service/AllayBlockUpdateService.java | 55 ++-- .../world/service/AllayChunkService.java | 37 +-- .../service/AllayEntityPhysicsService.java | 11 +- .../world/service/AllayEntityService.java | 13 +- .../storage/AllayLevelDBWorldStorage.java | 262 +++++++++--------- .../AllayNonPersistentWorldStorage.java | 20 +- .../world/storage/LevelDBChunkSerializer.java | 84 +++--- 84 files changed, 947 insertions(+), 1100 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 47e66e82d..73c656f2f 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,14 +1,15 @@ - + \ No newline at end of file diff --git a/Allay-API/src/main/java/org/allaymc/api/block/type/BlockState.java b/Allay-API/src/main/java/org/allaymc/api/block/type/BlockState.java index b6b85d6f0..f3f61d192 100644 --- a/Allay-API/src/main/java/org/allaymc/api/block/type/BlockState.java +++ b/Allay-API/src/main/java/org/allaymc/api/block/type/BlockState.java @@ -42,7 +42,7 @@ public interface BlockState { ItemStack toItemStack(); - //TODO: 确认是否只需要实现BlockDefinition::getRuntimeId(), 现有实现较为复杂且低效 + // TODO: Confirm if only need to implement BlockDefinition::getRuntimeId(), the existing implementation is quite complex and inefficient default SimpleBlockDefinition toNetworkBlockDefinition() { var statesBuilder = NbtMap.builder(); for (var propertyValue : getPropertyValues().values()) { diff --git a/Allay-API/src/main/java/org/allaymc/api/block/type/BlockTypeBuilder.java b/Allay-API/src/main/java/org/allaymc/api/block/type/BlockTypeBuilder.java index 1164df05f..21de2d4f2 100644 --- a/Allay-API/src/main/java/org/allaymc/api/block/type/BlockTypeBuilder.java +++ b/Allay-API/src/main/java/org/allaymc/api/block/type/BlockTypeBuilder.java @@ -7,8 +7,8 @@ import org.allaymc.api.block.component.common.CustomBlockComponent; import org.allaymc.api.block.property.type.BlockPropertyType; import org.allaymc.api.blockentity.type.BlockEntityType; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.data.VanillaBlockId; +import org.allaymc.api.utils.Identifier; import java.util.HashMap; import java.util.List; diff --git a/Allay-API/src/main/java/org/allaymc/api/client/data/LoginData.java b/Allay-API/src/main/java/org/allaymc/api/client/data/LoginData.java index 59e23720b..04ea2db5b 100644 --- a/Allay-API/src/main/java/org/allaymc/api/client/data/LoginData.java +++ b/Allay-API/src/main/java/org/allaymc/api/client/data/LoginData.java @@ -6,6 +6,7 @@ import com.google.gson.JsonObject; import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; import org.allaymc.api.client.skin.Image; @@ -28,12 +29,15 @@ * * @author LucGamesYT | daoge_cmd */ -@ToString + @Getter @Builder +@ToString +@EqualsAndHashCode @AllArgsConstructor public class LoginData { private static final Gson GSON = new Gson(); + private boolean xboxAuthenticated; private String displayName; private String xuid; @@ -61,30 +65,33 @@ private void decodeChainData(List chainData) { } for (String chain : chainData) { - JsonObject chainMap = decodeToken(chain); - if (chainMap == null) { - continue; - } - if (chainMap.has("extraData")) { - JsonObject extraData = (JsonObject) chainMap.get("extraData"); - this.displayName = extraData.get("displayName").getAsString(); - this.uuid = UUID.fromString(extraData.get("identity").getAsString()); - this.xuid = extraData.get("XUID").getAsString(); + var chainMap = decodeToken(chain); + if (chainMap != null) { + if (chainMap.has("extraData")) { + JsonObject extraData = (JsonObject) chainMap.get("extraData"); + this.displayName = extraData.get("displayName").getAsString(); + this.uuid = UUID.fromString(extraData.get("identity").getAsString()); + this.xuid = extraData.get("XUID").getAsString(); + } + this.identityPublicKey = chainMap.get("identityPublicKey").getAsString(); } - this.identityPublicKey = chainMap.get("identityPublicKey").getAsString(); } } private void decodeSkinData(String skinData) { - JsonObject skinMap = decodeToken(skinData); - if (skinMap.has("DeviceModel") && skinMap.has("DeviceId") && - skinMap.has("ClientRandomId") && skinMap.has("DeviceOS") && skinMap.has("GuiScale")) { - String deviceModel = skinMap.get("DeviceModel").getAsString(); - String deviceId = skinMap.get("DeviceId").getAsString(); - long clientId = skinMap.get("ClientRandomId").getAsLong(); - int deviceOS = skinMap.get("DeviceOS").getAsInt(); - int uiProfile = skinMap.get("UIProfile").getAsInt(); + var skinMap = decodeToken(skinData); + if (skinMap.has("DeviceModel") && + skinMap.has("DeviceId") && + skinMap.has("ClientRandomId") && + skinMap.has("DeviceOS") && + skinMap.has("GuiScale") + ) { + var deviceModel = skinMap.get("DeviceModel").getAsString(); + var deviceId = skinMap.get("DeviceId").getAsString(); + var clientId = skinMap.get("ClientRandomId").getAsLong(); + var deviceOS = skinMap.get("DeviceOS").getAsInt(); + var uiProfile = skinMap.get("UIProfile").getAsInt(); this.deviceInfo = new DeviceInfo(deviceModel, deviceId, clientId, Device.getDevice(deviceOS), UIProfile.getById(uiProfile)); } @@ -165,19 +172,17 @@ private void decodeSkinData(String skinData) { } private JsonObject decodeToken(String token) { - String[] tokenSplit = token.split("\\."); - if (tokenSplit.length < 2) { - throw new IllegalArgumentException("Invalid token length"); - } + var tokenSplit = token.split("\\."); + if (tokenSplit.length < 2) throw new IllegalArgumentException("Invalid token length"); return GSON.fromJson(new String(Base64.getDecoder().decode(tokenSplit[1]), StandardCharsets.UTF_8), JsonObject.class); } private Image getImage(JsonObject skinMap, String name) { if (skinMap.has(name + "Data")) { - byte[] skinImage = Base64.getDecoder().decode(skinMap.get(name + "Data").getAsString()); + var skinImage = Base64.getDecoder().decode(skinMap.get(name + "Data").getAsString()); if (skinMap.has(name + "ImageHeight") && skinMap.has(name + "ImageWidth")) { - int width = skinMap.get(name + "ImageWidth").getAsInt(); - int height = skinMap.get(name + "ImageHeight").getAsInt(); + var width = skinMap.get(name + "ImageWidth").getAsInt(); + var height = skinMap.get(name + "ImageHeight").getAsInt(); return new Image(width, height, skinImage); } else { return Image.getImage(skinImage); @@ -187,28 +192,28 @@ private Image getImage(JsonObject skinMap, String name) { } private SkinAnimation getSkinAnimationData(JsonObject animationData) { - byte[] data = Base64.getDecoder().decode(animationData.get("Image").getAsString()); - int width = animationData.get("ImageWidth").getAsInt(); - int height = animationData.get("ImageHeight").getAsInt(); - float frames = animationData.get("Frames").getAsFloat(); - int type = animationData.get("Type").getAsInt(); - int expression = animationData.get("AnimationExpression").getAsInt(); + var data = Base64.getDecoder().decode(animationData.get("Image").getAsString()); + var width = animationData.get("ImageWidth").getAsInt(); + var height = animationData.get("ImageHeight").getAsInt(); + var frames = animationData.get("Frames").getAsFloat(); + var type = animationData.get("Type").getAsInt(); + var expression = animationData.get("AnimationExpression").getAsInt(); return new SkinAnimation(new Image(width, height, data), type, frames, expression); } private PersonaPiece getPersonaPiece(JsonObject personaPiece) { - String pieceId = personaPiece.get("PieceId").getAsString(); - String pieceType = personaPiece.get("PieceType").getAsString(); - String packId = personaPiece.get("PackId").getAsString(); - String productId = personaPiece.get("ProductId").getAsString(); - boolean isDefault = personaPiece.get("IsDefault").getAsBoolean(); + var pieceId = personaPiece.get("PieceId").getAsString(); + var pieceType = personaPiece.get("PieceType").getAsString(); + var packId = personaPiece.get("PackId").getAsString(); + var productId = personaPiece.get("ProductId").getAsString(); + var isDefault = personaPiece.get("IsDefault").getAsBoolean(); return new PersonaPiece(pieceId, pieceType, packId, productId, isDefault); } private PersonaPieceTint getPersonaPieceTint(JsonObject personaPiceTint) { - String pieceType = personaPiceTint.get("PieceType").getAsString(); + var pieceType = personaPiceTint.get("PieceType").getAsString(); List colors = new ArrayList<>(); - for (JsonElement element : personaPiceTint.getAsJsonArray("Colors")) { + for (var element : personaPiceTint.getAsJsonArray("Colors")) { colors.add(element.getAsString()); } return new PersonaPieceTint(pieceType, colors); diff --git a/Allay-API/src/main/java/org/allaymc/api/component/interfaces/ComponentProvider.java b/Allay-API/src/main/java/org/allaymc/api/component/interfaces/ComponentProvider.java index 3b27d433c..ab8fba1a2 100644 --- a/Allay-API/src/main/java/org/allaymc/api/component/interfaces/ComponentProvider.java +++ b/Allay-API/src/main/java/org/allaymc/api/component/interfaces/ComponentProvider.java @@ -1,10 +1,12 @@ package org.allaymc.api.component.interfaces; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.SneakyThrows; -import org.allaymc.api.utils.Identifier; +import lombok.ToString; import org.allaymc.api.component.annotation.ComponentIdentifier; +import org.allaymc.api.utils.Identifier; import java.util.HashMap; import java.util.List; @@ -43,12 +45,6 @@ static

Map> toM return map; } - T provide(ComponentInitInfo info); - - Class getComponentClass(); - - @SneakyThrows - static Identifier findComponentIdentifier(Class clazz) { Identifier identifier = null; while (identifier == null) { @@ -60,7 +56,6 @@ static Identifier findComponentIdentifier(Class clazz) { } @SneakyThrows - static Identifier findComponentIdentifierInCertainClass(Class clazz) { for (var field : clazz.getDeclaredFields()) { if (field.isAnnotationPresent(ComponentIdentifier.class) && Identifier.class == field.getType() && isStatic(field.getModifiers())) { @@ -71,12 +66,16 @@ static Identifier findComponentIdentifierInCertainClass(Class clazz) { return null; } - @SneakyThrows + T provide(ComponentInitInfo info); + + Class getComponentClass(); default Identifier findComponentIdentifier() { return findComponentIdentifier(getComponentClass()); } + @ToString + @EqualsAndHashCode @AllArgsConstructor class SimpleComponentProvider implements ComponentProvider { private Function provider; diff --git a/Allay-API/src/main/java/org/allaymc/api/container/BaseContainerHolder.java b/Allay-API/src/main/java/org/allaymc/api/container/BaseContainerHolder.java index cf7da4227..1c69b095a 100644 --- a/Allay-API/src/main/java/org/allaymc/api/container/BaseContainerHolder.java +++ b/Allay-API/src/main/java/org/allaymc/api/container/BaseContainerHolder.java @@ -1,5 +1,6 @@ package org.allaymc.api.container; +import lombok.NoArgsConstructor; import org.allaymc.api.utils.exception.ContainerException; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.jetbrains.annotations.UnmodifiableView; @@ -13,15 +14,13 @@ * * @author daoge_cmd */ +@NoArgsConstructor public class BaseContainerHolder implements ContainerHolder { protected final Map, Container> typeToContainer = new HashMap<>(); protected final Map> slotTypeToFullType = new HashMap<>(); - public BaseContainerHolder() { - } - public BaseContainerHolder(Container... containers) { - for (Container container : containers) { + for (var container : containers) { this.addContainer(container); } } diff --git a/Allay-API/src/main/java/org/allaymc/api/entity/attribute/AttributeType.java b/Allay-API/src/main/java/org/allaymc/api/entity/attribute/AttributeType.java index 0730e5449..3e6cf1224 100644 --- a/Allay-API/src/main/java/org/allaymc/api/entity/attribute/AttributeType.java +++ b/Allay-API/src/main/java/org/allaymc/api/entity/attribute/AttributeType.java @@ -1,5 +1,8 @@ package org.allaymc.api.entity.attribute; +import lombok.AllArgsConstructor; +import lombok.Getter; + import java.util.HashMap; import java.util.Map; @@ -8,6 +11,8 @@ * * @author JukeboxMC | daoge_cmd */ +@Getter +@AllArgsConstructor public enum AttributeType { //Base Entity @@ -46,18 +51,11 @@ public enum AttributeType { private final float maxValue; private final float defaultValue; - AttributeType(String key, float minValue, float maxValue, float defaultValue) { - this.key = key; - this.minValue = minValue; - this.maxValue = maxValue; - this.defaultValue = defaultValue; + public static AttributeType byKey(String key) { + return KEY_LOOK_UP.get(key); } public Attribute newAttributeInstance() { return new Attribute(this.key, this.minValue, this.maxValue, this.defaultValue, this.defaultValue); } - - public static AttributeType byKey(String key) { - return KEY_LOOK_UP.get(key); - } } diff --git a/Allay-API/src/main/java/org/allaymc/api/i18n/I18n.java b/Allay-API/src/main/java/org/allaymc/api/i18n/I18n.java index 7e13fd441..c7be517fe 100644 --- a/Allay-API/src/main/java/org/allaymc/api/i18n/I18n.java +++ b/Allay-API/src/main/java/org/allaymc/api/i18n/I18n.java @@ -13,13 +13,17 @@ public interface I18n { LangCode FALLBACK_LANG = LangCode.en_US; + String VANILLA_LANG_NAMESPACE = "minecraft"; + ApiInstanceHolder I18N = ApiInstanceHolder.create(); static I18n get() { return I18N.get(); } - String VANILLA_LANG_NAMESPACE = "minecraft"; + static boolean isValidKeyCharacter(char character) { + return character == '_' || character == '-' || character >= 'a' && character <= 'z' || character >= 'A' && character <= 'Z' || character >= '0' && character <= '9' || character == '.' || character == ':'; + } String tr(LangCode langCode, @MayContainTrKey String tr, String... args); @@ -41,13 +45,9 @@ default String tr(@MayContainTrKey String tr) { return tr(getDefaultLangCode(), tr); } - void setDefaultLangCode(LangCode langCode); - LangCode getDefaultLangCode(); - record KeyInfo(int startIndex, int endIndex, int colonIndex, String key, boolean hasStarter) { - public static final KeyInfo EMPTY = new KeyInfo(-1, -1, -1, null, false); - } + void setDefaultLangCode(LangCode langCode); KeyInfo findI18nKey(@MayContainTrKey String str); @@ -73,7 +73,7 @@ default Pair toClientFriendlyStyle0(LangCode langCode, @MayCont if (VANILLA_LANG_NAMESPACE.equals(namespace)) { String left; if (keyInfo.hasStarter) { - // 保留 '%' + // Keep '%' left = tr.substring(0, keyInfo.startIndex + 1); } else { left = ""; @@ -85,7 +85,7 @@ default Pair toClientFriendlyStyle0(LangCode langCode, @MayCont } - static boolean isValidKeyCharacter(char character) { - return character == '_' || character == '-' || character >= 'a' && character <= 'z' || character >= 'A' && character <= 'Z' || character >= '0' && character <= '9' || character == '.' || character == ':'; + record KeyInfo(int startIndex, int endIndex, int colonIndex, String key, boolean hasStarter) { + public static final KeyInfo EMPTY = new KeyInfo(-1, -1, -1, null, false); } } diff --git a/Allay-API/src/main/java/org/allaymc/api/item/component/common/ItemAttributes.java b/Allay-API/src/main/java/org/allaymc/api/item/component/common/ItemAttributes.java index 7eaff5eda..330cb5e61 100644 --- a/Allay-API/src/main/java/org/allaymc/api/item/component/common/ItemAttributes.java +++ b/Allay-API/src/main/java/org/allaymc/api/item/component/common/ItemAttributes.java @@ -80,7 +80,7 @@ public static ItemAttributes fromJson(String json) { return JSONUtils.from(json, ItemAttributes.class); } - //TODO: test + // TODO: test public static ItemAttributes fromNBT(NbtMap nbt) { return ItemAttributes .builder() diff --git a/Allay-API/src/main/java/org/allaymc/api/item/type/ItemType.java b/Allay-API/src/main/java/org/allaymc/api/item/type/ItemType.java index 4ecd50ee4..438248b8e 100644 --- a/Allay-API/src/main/java/org/allaymc/api/item/type/ItemType.java +++ b/Allay-API/src/main/java/org/allaymc/api/item/type/ItemType.java @@ -1,14 +1,14 @@ package org.allaymc.api.item.type; import org.allaymc.api.block.type.BlockType; -import org.allaymc.api.utils.Identified; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.interfaces.ComponentProvider; import org.allaymc.api.item.ItemStack; import org.allaymc.api.item.component.ItemComponent; import org.allaymc.api.item.init.ItemStackInitInfo; import org.allaymc.api.item.init.SimpleItemStackInitInfo; import org.allaymc.api.item.tag.ItemTag; +import org.allaymc.api.utils.Identified; +import org.allaymc.api.utils.Identifier; import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition; import org.cloudburstmc.protocol.bedrock.data.definitions.SimpleItemDefinition; import org.jetbrains.annotations.Unmodifiable; @@ -43,7 +43,6 @@ default ItemDefinition toNetworkDefinition() { return new SimpleItemDefinition(getIdentifier().toString(), getRuntimeId(), false); } - @Unmodifiable Set getItemTags(); diff --git a/Allay-API/src/main/java/org/allaymc/api/utils/Identifier.java b/Allay-API/src/main/java/org/allaymc/api/utils/Identifier.java index c44b8edbf..8b20f2580 100644 --- a/Allay-API/src/main/java/org/allaymc/api/utils/Identifier.java +++ b/Allay-API/src/main/java/org/allaymc/api/utils/Identifier.java @@ -34,24 +34,12 @@ public Identifier(String namespace, String path) { throw new InvalidIdentifierException("Non [A-Za-z0-9/._-] character in path of location: " + this.namespace + NAMESPACE_SEPARATOR + this.path); } + @Override public String toString() { return this.namespace + NAMESPACE_SEPARATOR + this.path; } - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o instanceof Identifier lv) { - return this.namespace.equals(lv.namespace) && this.path.equals(lv.path); - } - return false; - } - - public int hashCode() { - return 31 * this.namespace.hashCode() + this.path.hashCode(); - } - + @SuppressWarnings("MethodDoesntCallSuperMethod") @Override public Identifier clone() { return new Identifier(namespace, path); diff --git a/Allay-API/src/main/java/org/allaymc/api/world/Dimension.java b/Allay-API/src/main/java/org/allaymc/api/world/Dimension.java index dbcc7fe83..d6b4cdf9b 100644 --- a/Allay-API/src/main/java/org/allaymc/api/world/Dimension.java +++ b/Allay-API/src/main/java/org/allaymc/api/world/Dimension.java @@ -16,6 +16,7 @@ import org.allaymc.api.world.service.ChunkService; import org.allaymc.api.world.service.EntityPhysicsService; import org.allaymc.api.world.service.EntityService; +import org.apache.commons.lang3.ArrayUtils; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.LevelEventType; @@ -43,6 +44,15 @@ */ public interface Dimension { + static UpdateBlockPacket createBlockUpdatePacket(BlockState blockState, int x, int y, int z, int layer) { + var updateBlockPacket = new UpdateBlockPacket(); + updateBlockPacket.setBlockPosition(Vector3i.from(x, y, z)); + updateBlockPacket.setDefinition(blockState.toNetworkBlockDefinitionRuntime()); + updateBlockPacket.setDataLayer(layer); + updateBlockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); + return updateBlockPacket; + } + void tick(long currentTick); void close(); @@ -83,13 +93,15 @@ default Entity getEntityByRuntimeId(long runtimeId) { } default void addPlayer(EntityPlayer player) { - addPlayer(player, () -> {}); + addPlayer(player, () -> { + }); } void addPlayer(EntityPlayer player, Runnable runnable); default void removePlayer(EntityPlayer player) { - removePlayer(player, () -> {}); + removePlayer(player, () -> { + }); } void removePlayer(EntityPlayer player, Runnable runnable); @@ -97,15 +109,6 @@ default void removePlayer(EntityPlayer player) { @UnmodifiableView Set getPlayers(); - static UpdateBlockPacket createBlockUpdatePacket(BlockState blockState, int x, int y, int z, int layer) { - var updateBlockPacket = new UpdateBlockPacket(); - updateBlockPacket.setBlockPosition(Vector3i.from(x, y, z)); - updateBlockPacket.setDefinition(blockState.toNetworkBlockDefinitionRuntime()); - updateBlockPacket.setDataLayer(layer); - updateBlockPacket.getFlags().addAll(UpdateBlockPacket.FLAG_ALL_PRIORITY); - return updateBlockPacket; - } - default void setBlockState(int x, int y, int z, BlockState blockState) { setBlockState(x, y, z, blockState, 0, true, true); } @@ -229,7 +232,6 @@ default BlockState[][][] getBlockStates(int x, int y, int z, int sizeX, int size return blockStates; } - default BlockState[][][] getCollidingBlocks(AABBfc aabb) { return getCollidingBlocks(aabb, 0); } @@ -248,7 +250,7 @@ default BlockState[][][] getCollidingBlocks(AABBfc aabb, int layer, boolean igno var blockStates = getBlockStates(minX, minY, minZ, maxX - minX, maxY - minY, maxZ - minZ, layer); boolean notEmpty = false; if (!ignoreCollision) { - //过滤掉没有碰撞的方块 + // Filter out the blocks that are not colliding for (int x = 0; x < blockStates.length; x++) { for (int y = 0; y < blockStates[x].length; y++) { for (int z = 0; z < blockStates[x][y].length; z++) { @@ -282,18 +284,7 @@ default void updateAroundIgnoreFace(int x, int y, int z, BlockFace... ignoreFace default void updateAroundIgnoreFace(Vector3ic pos, BlockFace... ignoreFaces) { for (var face : BlockFace.values()) { - if (ignoreFaces != null && ignoreFaces.length > 0) { - var ignore = false; - for (var ignoreFace : ignoreFaces) { - if (ignoreFace == face) { - ignore = true; - break; - } - } - if (ignore) { - continue; - } - } + if (ArrayUtils.contains(ignoreFaces, face)) continue; updateAtFace(pos, face); } } @@ -320,10 +311,11 @@ default void updateAtFace(Vector3ic pos, BlockFace face) { } /** - * Traverse all the blockstate around a pos,In the order of
DOWN->UP>NORTH->SOUTH->WEST->EAST + * Traverse all the BlockState around a pos,In the order of
DOWN->UP>NORTH->SOUTH->WEST->EAST * * @param pos The specified pos - * @return An array of neighbour blockstate + * + * @return An array of neighbour BlockState */ default BlockStateWithPos[] getNeighboursBlockState(Vector3ic pos) { return getNeighboursBlockState(pos.x(), pos.y(), pos.z()); diff --git a/Allay-API/src/main/java/org/allaymc/api/world/chunk/ChunkSection.java b/Allay-API/src/main/java/org/allaymc/api/world/chunk/ChunkSection.java index bcd949dee..edd2df7da 100644 --- a/Allay-API/src/main/java/org/allaymc/api/world/chunk/ChunkSection.java +++ b/Allay-API/src/main/java/org/allaymc/api/world/chunk/ChunkSection.java @@ -18,11 +18,13 @@ * @author Cool_Loong */ @NotThreadSafe -public record ChunkSection(byte sectionY, - Palette[] blockLayer, - Palette biomes, - NibbleArray blockLights, - NibbleArray skyLights) { +public record ChunkSection( + byte sectionY, + Palette[] blockLayer, + Palette biomes, + NibbleArray blockLights, + NibbleArray skyLights +) { public static final int LAYER_COUNT = 2; public static final int VERSION = 9; @@ -79,7 +81,7 @@ public boolean isEmpty() { public void writeToNetwork(ByteBuf byteBuf) { byteBuf.writeByte(VERSION); - //block layer count + // block layer count byteBuf.writeByte(LAYER_COUNT); byteBuf.writeByte(sectionY & 0xFF); diff --git a/Allay-API/src/main/java/org/allaymc/api/world/palette/Palette.java b/Allay-API/src/main/java/org/allaymc/api/world/palette/Palette.java index 8bbac77bf..87c395707 100644 --- a/Allay-API/src/main/java/org/allaymc/api/world/palette/Palette.java +++ b/Allay-API/src/main/java/org/allaymc/api/world/palette/Palette.java @@ -4,9 +4,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; -import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.objects.ReferenceArrayList; -import org.allaymc.api.datastruct.SemVersion; import org.allaymc.api.utils.HashUtils; import org.allaymc.api.utils.PaletteUtils; import org.allaymc.api.world.bitarray.BitArray; @@ -15,7 +13,6 @@ import org.cloudburstmc.blockstateupdater.BlockStateUpdaters; import org.cloudburstmc.blockstateupdater.util.tagupdater.CompoundTagUpdaterContext; import org.cloudburstmc.nbt.NBTInputStream; -import org.cloudburstmc.nbt.NBTOutputStream; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtUtils; import org.cloudburstmc.nbt.util.stream.LittleEndianDataInputStream; @@ -51,6 +48,22 @@ public Palette(V first, List palette, BitArrayVersion version) { this.palette.add(first); } + private static boolean hasCopyLastFlag(short header) { + return (header >> 1) == 0x7F; + } + + private static int getPaletteHeader(BitArrayVersion version, boolean runtime) { + return (version.bits << 1) | (runtime ? 1 : 0); + } + + private static BitArrayVersion getVersionFromPaletteHeader(short header) { + return BitArrayVersion.get(header >> 1, true); + } + + private static boolean isPersistent(short header) { + return (header & 1) == 0; + } + public V get(int index) { return this.palette.get(this.bitArray.get(index)); } @@ -80,9 +93,9 @@ public void writeToStoragePersistent(ByteBuf byteBuf, PersistentDataSerializer seri } public void readFromStorageRuntime(ByteBuf byteBuf, RuntimeDataDeserializer deserializer, Palette last) { - final short header = byteBuf.readUnsignedByte(); - + var header = byteBuf.readUnsignedByte(); if (hasCopyLastFlag(header)) { last.copyTo(this); return; } - final BitArrayVersion version = Palette.getVersionFromPaletteHeader(header); + var version = Palette.getVersionFromPaletteHeader(header); if (version == BitArrayVersion.V0) { this.bitArray = version.createArray(Chunk.SECTION_SIZE, null); this.palette.clear(); @@ -120,24 +132,24 @@ public void readFromStorageRuntime(ByteBuf byteBuf, RuntimeDataDeserializer d readWords(byteBuf, version); - final int paletteSize = byteBuf.readIntLE(); + var paletteSize = byteBuf.readIntLE(); for (int i = 0; i < paletteSize; i++) this.palette.add(deserializer.deserialize(byteBuf.readIntLE())); } public void readFromStoragePersistent(ByteBuf byteBuf, RuntimeDataDeserializer deserializer) { - try (final ByteBufInputStream bufInputStream = new ByteBufInputStream(byteBuf); - final LittleEndianDataInputStream input = new LittleEndianDataInputStream(bufInputStream); - final NBTInputStream nbtInputStream = new NBTInputStream(input)) { - final BitArrayVersion bversion = readBitArrayVersion(byteBuf); - if (bversion == BitArrayVersion.V0) { - this.bitArray = bversion.createArray(Chunk.SECTION_SIZE, null); + try (var bufInputStream = new ByteBufInputStream(byteBuf); + var input = new LittleEndianDataInputStream(bufInputStream); + var nbtInputStream = new NBTInputStream(input)) { + var bitVersion = readBitArrayVersion(byteBuf); + if (bitVersion == BitArrayVersion.V0) { + this.bitArray = bitVersion.createArray(Chunk.SECTION_SIZE, null); this.palette.clear(); addBlockPalette(byteBuf, deserializer, input, nbtInputStream); this.onResize(BitArrayVersion.V2); return; } - readWords(byteBuf, bversion); - final int paletteSize = byteBuf.readIntLE(); + readWords(byteBuf, bitVersion); + var paletteSize = byteBuf.readIntLE(); for (int i = 0; i < paletteSize; i++) { addBlockPalette(byteBuf, deserializer, input, nbtInputStream); } @@ -150,12 +162,12 @@ private void addBlockPalette(ByteBuf byteBuf, RuntimeDataDeserializer deserializer, LittleEndianDataInputStream input, NBTInputStream nbtInputStream) throws IOException { - Pair p = PaletteUtils.fastReadBlockHash(input, byteBuf); - if (p.left() == null) { - NbtMap oldNbtMap = (NbtMap) nbtInputStream.readTag(); - SemVersion semVersion = p.right(); - int version = CompoundTagUpdaterContext.makeVersion(semVersion.major(), semVersion.minor(), semVersion.patch()); - NbtMap newNbtMap = BlockStateUpdaters.updateBlockState(oldNbtMap, version); + var pair = PaletteUtils.fastReadBlockHash(input, byteBuf); + if (pair.left() == null) { + var oldNbtMap = (NbtMap) nbtInputStream.readTag(); + var semVersion = pair.right(); + var version = CompoundTagUpdaterContext.makeVersion(semVersion.major(), semVersion.minor(), semVersion.patch()); + var newNbtMap = BlockStateUpdaters.updateBlockState(oldNbtMap, version); var states = new TreeMap<>(newNbtMap.getCompound("states")); var tag = NbtMap.builder() .putString("name", newNbtMap.getString("name")) @@ -163,20 +175,20 @@ private void addBlockPalette(ByteBuf byteBuf, .build(); this.palette.add(deserializer.deserialize(HashUtils.fnv1a_32_nbt(tag))); } else { - this.palette.add(deserializer.deserialize(p.left())); + this.palette.add(deserializer.deserialize(pair.left())); } } public int paletteIndexFor(V value) { - int index = this.palette.indexOf(value); + var index = this.palette.indexOf(value); if (index != -1) return index; index = this.palette.size(); this.palette.add(value); - final BitArrayVersion version = this.bitArray.version(); + var version = this.bitArray.version(); if (index > version.maxEntryValue) { - final BitArrayVersion next = version.next; + var next = version.next; if (next != null) this.onResize(next); } @@ -198,10 +210,6 @@ public void copyTo(Palette palette) { palette.palette.addAll(this.palette); } - private static boolean hasCopyLastFlag(short header) { - return (header >> 1) == 0x7F; - } - private boolean writeLast(ByteBuf byteBuf, Palette last) { if (last != null && last.palette.equals(this.palette)) { byteBuf.writeByte(COPY_LAST_FLAG_HEADER); @@ -228,15 +236,14 @@ private void writeWords(ByteBuf byteBuf, RuntimeDataSerializer serializer) { } } - private BitArrayVersion readBitArrayVersion(ByteBuf byteBuf) { - short header = byteBuf.readUnsignedByte(); + var header = byteBuf.readUnsignedByte(); return Palette.getVersionFromPaletteHeader(header); } private void readWords(ByteBuf byteBuf, BitArrayVersion version) { - final int wordCount = version.getWordsForSize(Chunk.SECTION_SIZE); - final int[] words = new int[wordCount]; + var wordCount = version.getWordsForSize(Chunk.SECTION_SIZE); + var words = new int[wordCount]; for (int i = 0; i < wordCount; i++) words[i] = byteBuf.readIntLE(); this.bitArray = version.createArray(Chunk.SECTION_SIZE, words); @@ -244,25 +251,13 @@ private void readWords(ByteBuf byteBuf, BitArrayVersion version) { } private void onResize(BitArrayVersion version) { - final BitArray newBitArray = version.createArray(Chunk.SECTION_SIZE); + var newBitArray = version.createArray(Chunk.SECTION_SIZE); for (int i = 0; i < Chunk.SECTION_SIZE; i++) newBitArray.set(i, this.bitArray.get(i)); this.bitArray = newBitArray; } - private static int getPaletteHeader(BitArrayVersion version, boolean runtime) { - return (version.bits << 1) | (runtime ? 1 : 0); - } - - private static BitArrayVersion getVersionFromPaletteHeader(short header) { - return BitArrayVersion.get(header >> 1, true); - } - - private static boolean isPersistent(short header) { - return (header & 1) == 0; - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/Allay-Server/src/main/java/org/allaymc/server/AllayServer.java b/Allay-Server/src/main/java/org/allaymc/server/AllayServer.java index c624cb00d..9fcc7175f 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/AllayServer.java +++ b/Allay-Server/src/main/java/org/allaymc/server/AllayServer.java @@ -62,18 +62,17 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import static org.allaymc.api.entity.type.EntityTypes.PLAYER_TYPE; @Slf4j public final class AllayServer implements Server { + private static final CommandOriginData SERVER_COMMAND_ORIGIN_DATA = new CommandOriginData(CommandOriginType.DEDICATED_SERVER, UUID.randomUUID(), "", 0); + + private static volatile AllayServer instance; + private final boolean DEBUG = Server.SETTINGS.genericSettings().debug(); private final Map players = new ConcurrentHashMap<>(); @Getter @@ -83,8 +82,8 @@ public final class AllayServer implements Server { @Getter private final PlayerStorage playerStorage = Server.SETTINGS.storageSettings().savePlayerData() ? - new AllayNBTFilePlayerStorage(Path.of("players")) : - AllayEmptyPlayerStorage.INSTANCE; + new AllayNBTFilePlayerStorage(Path.of("players")) : + AllayEmptyPlayerStorage.INSTANCE; // Thread pool for executing CPU-intensive tasks @Getter private final ThreadPoolExecutor computeThreadPool = new ThreadPoolExecutor( @@ -102,23 +101,7 @@ public final class AllayServer implements Server { @Getter private final ExecutorService virtualThreadPool = Executors.newVirtualThreadPerTaskExecutor(); @Getter - private CommandRegistry commandRegistry; - @Getter - private PluginManager pluginManager; - @Getter - private Scheduler scheduler; - @Getter - private NetworkServer networkServer; - private Thread terminalConsoleThread; - private AllayTerminalConsole terminalConsole; - private static volatile AllayServer instance; - private long nextPlayerDataAutoSaveTime = 0; - @Getter private final EventBus eventBus = new AllayEventBus(Executors.newVirtualThreadPerTaskExecutor()); - @Getter - private ScoreboardService scoreboardService; - @Getter - private long startTime; private final BanInfo banInfo = ConfigManager.create(BanInfo.class, it -> { it.withConfigurer(new YamlSnakeYamlConfigurer()); // specify configurer implementation, optionally additional serdes packages it.withBindFile("ban-info.yml"); // specify Path, File or pathname @@ -133,7 +116,17 @@ public final class AllayServer implements Server { it.saveDefaults(); // save file if it does not exist it.load(true); // load and save to update comments/new fields }); - + @Getter + private CommandRegistry commandRegistry; + @Getter + private PluginManager pluginManager; + @Getter + private Scheduler scheduler; + @Getter + private NetworkServer networkServer; + private Thread terminalConsoleThread; + private AllayTerminalConsole terminalConsole; + private long nextPlayerDataAutoSaveTime = 0; private final GameLoop gameLoop = GameLoop.builder() .loopCountPerSec(20) .onTick(gameLoop -> { @@ -144,6 +137,10 @@ public final class AllayServer implements Server { } }) .build(); + @Getter + private ScoreboardService scoreboardService; + @Getter + private long startTime; private AllayServer() {} @@ -161,9 +158,9 @@ public static AllayServer getInstance() { @SneakyThrows @Override public void start(long timeMillis) { - LoggerContext ctx = (LoggerContext) LogManager.getContext(false); - Configuration log4jConfig = ctx.getConfiguration(); - LoggerConfig loggerConfig = log4jConfig.getLoggerConfig(org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME); + var ctx = (LoggerContext) LogManager.getContext(false); + var log4jConfig = ctx.getConfiguration(); + var loggerConfig = log4jConfig.getLoggerConfig(org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME); if (DEBUG && Level.TRACE.isLessSpecificThan(loggerConfig.getLevel())) { loggerConfig.setLevel(Level.TRACE); ctx.updateLoggers(); @@ -481,7 +478,7 @@ public void sendTr(String key, boolean forceTranslatedByClient, String... args) @Override public void sendCommandOutputs(CommandSender sender, int status, TrContainer... outputs) { for (var output : outputs) { - log.info("[" + sender.getCommandSenderName() + "] " + (status <= 0 ? "§c" : "") + I18n.get().tr(output.str(), output.args())); + log.info("[{}] {}{}", sender.getCommandSenderName(), status <= 0 ? "§c" : "", I18n.get().tr(output.str(), output.args())); } } @@ -495,8 +492,6 @@ public String getCommandSenderName() { return "Server"; } - private static final CommandOriginData SERVER_COMMAND_ORIGIN_DATA = new CommandOriginData(CommandOriginType.DEDICATED_SERVER, UUID.randomUUID(), "", 0); - @Override public CommandOriginData getCommandOriginData() { return SERVER_COMMAND_ORIGIN_DATA; diff --git a/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockAttributeComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockAttributeComponentImpl.java index cddfd48a8..03af393c5 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockAttributeComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockAttributeComponentImpl.java @@ -5,11 +5,11 @@ import org.allaymc.api.block.registry.VanillaBlockAttributeRegistry; import org.allaymc.api.block.type.BlockState; import org.allaymc.api.block.type.BlockType; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.data.VanillaBlockId; import org.allaymc.api.datastruct.collections.nb.Int2ObjectNonBlockingMap; import org.allaymc.api.math.voxelshape.VoxelShape; +import org.allaymc.api.utils.Identifier; import java.util.HashMap; import java.util.Map; @@ -29,14 +29,14 @@ public class BlockAttributeComponentImpl implements BlockAttributeComponent { protected static final BlockAttributeComponentImpl DEFAULT = BlockAttributeComponentImpl.ofGlobalStatic(BlockAttributes.DEFAULT); protected Function attributeAccessor; - public static BlockAttributeComponentImpl ofDefault() { - return DEFAULT; - } - protected BlockAttributeComponentImpl(Function attributeAccessor) { this.attributeAccessor = attributeAccessor; } + public static BlockAttributeComponentImpl ofDefault() { + return DEFAULT; + } + public static BlockAttributeComponentImpl ofGlobalStatic(BlockAttributes attributes) { return new BlockAttributeComponentImpl(state -> attributes); } @@ -106,8 +106,8 @@ public BlockAttributes apply(BlockState blockState) { private static class LazyLoaderAttributeAccessor implements Function { - private Map lazyLoadAttributeMap; private final Function, Map> lazyLoader; + private Map lazyLoadAttributeMap; public LazyLoaderAttributeAccessor(Function, Map> lazyLoader) { this.lazyLoader = lazyLoader; diff --git a/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockBaseComponentImpl.java index dee09b51e..210ad77e6 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockBaseComponentImpl.java @@ -1,5 +1,8 @@ package org.allaymc.server.block.component.common; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; import org.allaymc.api.block.BlockBehavior; import org.allaymc.api.block.component.common.BlockBaseComponent; import org.allaymc.api.block.component.event.BlockOnInteractEvent; @@ -11,12 +14,12 @@ import org.allaymc.api.block.function.Place; import org.allaymc.api.block.type.BlockState; import org.allaymc.api.block.type.BlockType; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.component.annotation.Manager; import org.allaymc.api.component.interfaces.ComponentManager; import org.allaymc.api.entity.interfaces.EntityPlayer; import org.allaymc.api.item.ItemStack; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.world.Dimension; import org.joml.Vector3fc; import org.joml.Vector3ic; @@ -26,6 +29,8 @@ * * @author daoge_cmd */ +@ToString +@EqualsAndHashCode(onlyExplicitlyIncluded = true) public class BlockBaseComponentImpl implements BlockBaseComponent { @ComponentIdentifier @@ -34,29 +39,24 @@ public class BlockBaseComponentImpl implements BlockBaseComponent { @Manager protected ComponentManager manager; + @Getter + @EqualsAndHashCode.Include protected BlockType blockType; public BlockBaseComponentImpl(BlockType blockType) { this.blockType = blockType; } - @Override - public BlockType getBlockType() { - return blockType; - } - @Override public void onNeighborUpdate(Vector3ic updated, Vector3ic neighbor, BlockFace face, Dimension dimension) { manager.callEvent(new BlockOnNeighborUpdateEvent(updated, neighbor, face, dimension)); } @Override - public void onRandomUpdate(BlockStateWithPos blockState) { - } + public void onRandomUpdate(BlockStateWithPos blockState) {} @Override - public void onScheduledUpdate(BlockStateWithPos blockState) { - } + public void onScheduledUpdate(BlockStateWithPos blockState) {} @Override public boolean place(EntityPlayer player, Dimension dimension, BlockState blockState, Vector3ic targetBlockPos, Vector3ic placeBlockPos, Vector3fc clickPos, BlockFace blockFace) { diff --git a/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockEntityHolderComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockEntityHolderComponentImpl.java index 9bc2c99a0..cf48676f6 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockEntityHolderComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/block/component/common/BlockEntityHolderComponentImpl.java @@ -1,5 +1,8 @@ package org.allaymc.server.block.component.common; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.block.component.common.BlockEntityHolderComponent; import org.allaymc.api.block.component.event.BlockOnInteractEvent; @@ -8,10 +11,10 @@ import org.allaymc.api.block.component.event.BlockOnReplaceEvent; import org.allaymc.api.blockentity.BlockEntity; import org.allaymc.api.blockentity.type.BlockEntityType; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.eventbus.EventHandler; import org.allaymc.api.math.position.Position3i; +import org.allaymc.api.utils.Identifier; /** * Allay Project 2023/9/15 @@ -19,10 +22,13 @@ * @author daoge_cmd */ @Slf4j +@ToString +@EqualsAndHashCode public class BlockEntityHolderComponentImpl implements BlockEntityHolderComponent { @ComponentIdentifier public static final Identifier IDENTIFIER = new Identifier("minecraft:block_entity_holder_component"); + @Getter protected final BlockEntityType blockEntityType; public BlockEntityHolderComponentImpl(BlockEntityType blockEntityType) { @@ -62,9 +68,4 @@ private void onInteract(BlockOnInteractEvent event) { var blockEntity = getBlockEntity(pos.x(), pos.y(), pos.z(), event.getDimension()); blockEntity.onInteract(event); } - - @Override - public BlockEntityType getBlockEntityType() { - return blockEntityType; - } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/block/type/AllayBlockType.java b/Allay-Server/src/main/java/org/allaymc/server/block/type/AllayBlockType.java index abb1e5191..f0a4b54d8 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/block/type/AllayBlockType.java +++ b/Allay-Server/src/main/java/org/allaymc/server/block/type/AllayBlockType.java @@ -4,7 +4,9 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.ToString; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.block.BlockBehavior; import org.allaymc.api.block.component.BlockComponent; @@ -19,7 +21,6 @@ import org.allaymc.api.block.type.BlockType; import org.allaymc.api.block.type.BlockTypeBuilder; import org.allaymc.api.blockentity.type.BlockEntityType; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.interfaces.Component; import org.allaymc.api.component.interfaces.ComponentProvider; import org.allaymc.api.data.VanillaBlockId; @@ -32,6 +33,7 @@ import org.allaymc.api.network.ProtocolInfo; import org.allaymc.api.utils.BlockAndItemIdMapper; import org.allaymc.api.utils.HashUtils; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.utils.exception.BlockComponentInjectException; import org.allaymc.server.block.component.common.BlockAttributeComponentImpl; import org.allaymc.server.block.component.common.BlockBaseComponentImpl; @@ -53,29 +55,19 @@ * * @author daoge_cmd | Cool_Loong */ +@ToString +@EqualsAndHashCode(onlyExplicitlyIncluded = true) public final class AllayBlockType implements BlockType { - public static long computeSpecialValue(BlockPropertyType.BlockPropertyValue[] propertyValues) { - byte specialValueBits = 0; - for (var value : propertyValues) specialValueBits += value.getPropertyType().getBitSize(); - return computeSpecialValue(specialValueBits, propertyValues); - } - - public static long computeSpecialValue(byte specialValueBits, BlockPropertyType.BlockPropertyValue[] propertyValues) { - long specialValue = 0; - for (var value : propertyValues) { - specialValue |= ((long) value.getIndex()) << (specialValueBits - value.getPropertyType().getBitSize()); - specialValueBits -= value.getPropertyType().getBitSize(); - } - return specialValue; - } - @Getter + @EqualsAndHashCode.Include private final Class interfaceClass; @Getter private final List components; @Getter + @EqualsAndHashCode.Include private final Map> properties; @Getter + @EqualsAndHashCode.Include private final Identifier identifier; @Getter private final Map blockStateHashMap; @@ -84,20 +76,22 @@ public static long computeSpecialValue(byte specialValueBits, BlockPropertyType. private final Map specialValueMap; @Getter private final byte specialValueBits; - + @EqualsAndHashCode.Include + private final ItemType blockItemType; private Class injectedClass; @Getter private BlockState defaultState; - private ItemType blockItemType; private Map hashToMeta; @Getter private T blockBehavior; - private AllayBlockType(Class interfaceClass, - List components, - Map> properties, - Identifier identifier, - ItemType blockItemType) { + private AllayBlockType( + Class interfaceClass, + List components, + Map> properties, + Identifier identifier, + ItemType blockItemType + ) { this.interfaceClass = interfaceClass; this.components = components; this.properties = Collections.unmodifiableMap(properties); @@ -119,6 +113,21 @@ private AllayBlockType(Class interfaceClass, } } + public static long computeSpecialValue(BlockPropertyType.BlockPropertyValue[] propertyValues) { + byte specialValueBits = 0; + for (var value : propertyValues) specialValueBits += value.getPropertyType().getBitSize(); + return computeSpecialValue(specialValueBits, propertyValues); + } + + public static long computeSpecialValue(byte specialValueBits, BlockPropertyType.BlockPropertyValue[] propertyValues) { + long specialValue = 0; + for (var value : propertyValues) { + specialValue |= ((long) value.getIndex()) << (specialValueBits - value.getPropertyType().getBitSize()); + specialValueBits -= value.getPropertyType().getBitSize(); + } + return specialValue; + } + public static BlockTypeBuilder builder(Class interfaceClass) { return new Builder<>(interfaceClass); } @@ -136,7 +145,7 @@ public BlockState ofState(List> pr @Override @UnmodifiableView public Collection getAllStates() { - //blockStateHashMap is unmodifiableMap,so values is unmodifiableCollection + // blockStateHashMap is unmodifiableMap, so values is unmodifiableCollection return blockStateHashMap.values(); } @@ -149,8 +158,7 @@ private Map initStates() { } var blockStates = new Int2ObjectOpenHashMap(); - // to keep track of next element in each of - // the n arrays + // to keep track of next element in each of the n arrays int[] indices = new int[size]; // initialize with first element's index @@ -174,12 +182,10 @@ private Map initStates() { next--; } - // no such array is found so no more - // combinations left + // no such array is found so no more combinations left if (next < 0) break; - // if found move to next element in that - // array + // if found move to next element in that array indices[next]++; // for all arrays to the right of this @@ -189,10 +195,12 @@ private Map initStates() { indices[i] = 0; } } - int defaultStateHash = HashUtils.computeBlockStateHash(this.identifier, properties.values().stream().map(p -> p.tryCreateValue(p.getDefaultValue())).collect(Collectors.toList())); - for (var s : blockStates.values()) { - if (s.blockStateHash() == defaultStateHash) { - this.defaultState = s; + int defaultStateHash = HashUtils.computeBlockStateHash(this.identifier, properties.values().stream() + .map(p -> p.tryCreateValue(p.getDefaultValue())) + .collect(Collectors.toList())); + for (var blockState : blockStates.values()) { + if (blockState.blockStateHash() == defaultStateHash) { + this.defaultState = blockState; break; } } @@ -200,19 +208,28 @@ private Map initStates() { } /** - * Each {@link AllayBlockState} is a singleton, stored in the {@link AllayBlockStateHashPalette AllayBlockPaletteRegistry}, which means you can directly use == to compare whether two Block States are equal + * Each {@link AllayBlockState} is a singleton, stored in the {@link AllayBlockStateHashPalette AllayBlockPaletteRegistry}, + * which means you can directly use == to compare whether two Block States are equal */ - record AllayBlockState(BlockType blockType, - BlockPropertyType.BlockPropertyValue[] blockPropertyValues, - NbtMap blockStateTag, - int blockStateHash, - long specialValue) implements BlockState { + record AllayBlockState( + BlockType blockType, + BlockPropertyType.BlockPropertyValue[] blockPropertyValues, + NbtMap blockStateTag, + int blockStateHash, + long specialValue + ) implements BlockState { public AllayBlockState(BlockType blockType, BlockPropertyType.BlockPropertyValue[] propertyValues, int blockStateHash) { - this(blockType, + this( + blockType, propertyValues, buildBlockStateTag(blockType, propertyValues), blockStateHash, - AllayBlockType.computeSpecialValue(propertyValues)); + AllayBlockType.computeSpecialValue(propertyValues) + ); + } + + public AllayBlockState(BlockType blockType, BlockPropertyType.BlockPropertyValue[] propertyValues) { + this(blockType, propertyValues, HashUtils.computeBlockStateHash(blockType.getIdentifier(), Arrays.stream(propertyValues).toList())); } private static NbtMap buildBlockStateTag(BlockType blockType, BlockPropertyType.BlockPropertyValue[] propertyValues) { @@ -222,17 +239,11 @@ private static NbtMap buildBlockStateTag(BlockType blockType, BlockPropertyTy states.put(value.getPropertyType().getName(), value.getSerializedValue()); } - var tag = NbtMap.builder() + return NbtMap.builder() .putString("name", blockType.getIdentifier().toString()) .putCompound("states", NbtMap.fromMap(states)) .putInt("version", ProtocolInfo.BLOCK_STATE_VERSION) .build(); - - return tag; - } - - public AllayBlockState(BlockType blockType, BlockPropertyType.BlockPropertyValue[] propertyValues) { - this(blockType, propertyValues, HashUtils.computeBlockStateHash(blockType.getIdentifier(), Arrays.stream(propertyValues).toList())); } @Override @@ -437,9 +448,10 @@ public AllayBlockType build() { listComponents.add(BlockAttributeComponentImpl.ofDefault()); List> componentProviders = listComponents.stream().map(singleton -> { var currentClass = singleton.getClass(); - //For anonymous class, we give it's super class to component provider - //So that injector can work with anonymous class - //Because anonymous class classes cannot be used directly as field types during the dynamic class generation phase + // For anonymous class, we give it's super class to component provider + // So that injector can work with anonymous class + // Because anonymous class classes cannot be used directly + // as field types during the dynamic class generation phase return ComponentProvider.of(initInfo -> singleton, currentClass.isAnonymousClass() ? currentClass.getSuperclass() : currentClass); }).collect(Collectors.toList()); try { @@ -462,16 +474,17 @@ private void prepareItemType() { var itemId = BlockAndItemIdMapper.blockIdToActualBlockItemId(identifier); itemType = ItemTypeRegistry.getRegistry().get(itemId); if (itemType == null) { - // 没有显式注册对应的方块物品,自动注册一个进去 + // No corresponding block item explicitly registered, automatically registering one itemType = ItemTypeBuilder .builder(ItemStack.class) .identifier(itemId) .build(); hardItemType = itemType; } else { - // 已提前注册了额外的方块物品,添加"item."前缀 + // Additional block items have already been pre-registered, adding the 'item' prefix var hardItemId = new Identifier(itemId.namespace(), BlockAndItemIdMapper.NAMING_CONFLICT_PATH_PREFIX + itemId.path()); - // allay会提前注册好原版中具有"item."前缀的方块物品,所以说我们再确认一下有没有这个id的物品 + // allay will pre-register block items with the prefix 'item' + // in the original version, so let's double-check if there is an item with this ID hardItemType = ItemTypeRegistry.getRegistry().get(hardItemId); if (hardItemType == null) { hardItemType = ItemTypeBuilder diff --git a/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/barrel/BlockEntityBarrelBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/barrel/BlockEntityBarrelBaseComponentImpl.java index 22147f881..df8f7d33a 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/barrel/BlockEntityBarrelBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/barrel/BlockEntityBarrelBaseComponentImpl.java @@ -1,5 +1,7 @@ package org.allaymc.server.blockentity.component.barrel; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.allaymc.api.blockentity.component.common.BlockEntityContainerHolderComponent; import org.allaymc.api.blockentity.init.BlockEntityInitInfo; import org.allaymc.api.blockentity.interfaces.BlockEntityBarrel; @@ -9,13 +11,13 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtType; -import java.util.Objects; - /** * Allay Project 2023/12/6 * * @author daoge_cmd */ +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) public class BlockEntityBarrelBaseComponentImpl extends BlockEntityBaseComponentImpl { @Dependency private BlockEntityContainerHolderComponent containerHolderComponent; @@ -27,8 +29,9 @@ public BlockEntityBarrelBaseComponentImpl(BlockEntityInitInfo @Override public void loadNBT(NbtMap nbt) { super.loadNBT(nbt); - if (nbt.containsKey("Items")) - Objects.requireNonNull(containerHolderComponent.getContainer(FullContainerType.BARREL)).loadNBT(nbt.getList("Items", NbtType.COMPOUND)); + nbt.listenForList("Items", NbtType.COMPOUND, items -> + containerHolderComponent.getContainer(FullContainerType.BARREL).loadNBT(nbt.getList("Items", NbtType.COMPOUND)) + ); } @Override @@ -36,7 +39,7 @@ public NbtMap saveNBT() { return super.saveNBT().toBuilder().putList( "Items", NbtType.COMPOUND, - Objects.requireNonNull(containerHolderComponent.getContainer(FullContainerType.BARREL)).saveNBT() + containerHolderComponent.getContainer(FullContainerType.BARREL).saveNBT() ).build(); } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/chest/BlockEntityChestBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/chest/BlockEntityChestBaseComponentImpl.java index 77c1b0a31..4fd4ef17b 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/chest/BlockEntityChestBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/chest/BlockEntityChestBaseComponentImpl.java @@ -1,5 +1,7 @@ package org.allaymc.server.blockentity.component.chest; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.allaymc.api.blockentity.component.common.BlockEntityContainerHolderComponent; import org.allaymc.api.blockentity.init.BlockEntityInitInfo; import org.allaymc.api.blockentity.interfaces.BlockEntityChest; @@ -13,13 +15,13 @@ import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.packet.BlockEventPacket; -import java.util.Objects; - /** * Allay Project 2023/12/6 * * @author daoge_cmd */ +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) public class BlockEntityChestBaseComponentImpl extends BlockEntityBaseComponentImpl { @Dependency private BlockEntityContainerHolderComponent containerHolderComponent; @@ -77,8 +79,9 @@ public void onInitFinish(ComponentInitInfo initInfo) { @Override public void loadNBT(NbtMap nbt) { super.loadNBT(nbt); - if (nbt.containsKey("Items")) - Objects.requireNonNull(containerHolderComponent.getContainer(FullContainerType.CHEST)).loadNBT(nbt.getList("Items", NbtType.COMPOUND)); + nbt.listenForList("Items", NbtType.COMPOUND, items -> + containerHolderComponent.getContainer(FullContainerType.CHEST).loadNBT(nbt.getList("Items", NbtType.COMPOUND)) + ); } @Override @@ -86,7 +89,7 @@ public NbtMap saveNBT() { return super.saveNBT().toBuilder().putList( "Items", NbtType.COMPOUND, - Objects.requireNonNull(containerHolderComponent.getContainer(FullContainerType.CHEST)).saveNBT() + containerHolderComponent.getContainer(FullContainerType.CHEST).saveNBT() ).build(); } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityBaseComponentImpl.java index 8d811cd3a..f5406fbad 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityBaseComponentImpl.java @@ -1,5 +1,8 @@ package org.allaymc.server.blockentity.component.common; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; import org.allaymc.api.block.component.event.BlockOnInteractEvent; import org.allaymc.api.block.component.event.BlockOnNeighborUpdateEvent; import org.allaymc.api.block.component.event.BlockOnPlaceEvent; @@ -10,13 +13,13 @@ import org.allaymc.api.blockentity.component.event.BlockEntitySaveNBTEvent; import org.allaymc.api.blockentity.init.BlockEntityInitInfo; import org.allaymc.api.blockentity.type.BlockEntityType; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.component.annotation.Manager; import org.allaymc.api.component.interfaces.ComponentInitInfo; import org.allaymc.api.component.interfaces.ComponentManager; import org.allaymc.api.math.position.Position3i; import org.allaymc.api.math.position.Position3ic; +import org.allaymc.api.utils.Identifier; import org.cloudburstmc.nbt.NbtMap; /** @@ -24,14 +27,18 @@ * * @author daoge_cmd */ +@ToString +@EqualsAndHashCode public class BlockEntityBaseComponentImpl implements BlockEntityBaseComponent { @ComponentIdentifier public static final Identifier IDENTIFIER = new Identifier("minecraft:block_entity_base_component"); @Manager + @EqualsAndHashCode.Exclude protected ComponentManager manager; protected BlockEntityType blockEntityType; + @Getter protected Position3ic position; protected String customName = ""; @@ -50,11 +57,6 @@ public BlockEntityType getBlockEntityType() { return blockEntityType; } - @Override - public Position3ic getPosition() { - return position; - } - @Override public NbtMap saveNBT() { var builder = NbtMap.builder() @@ -71,9 +73,7 @@ public NbtMap saveNBT() { @Override public void loadNBT(NbtMap nbt) { - if (nbt.containsKey("CustomName")) { - this.customName = nbt.getString("CustomName"); - } + nbt.listenForString("CustomName", customName -> this.customName = customName); var pos = new Position3i(position); pos.x = nbt.getInt("x", position.x()); pos.y = nbt.getInt("y", position.y()); diff --git a/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityContainerHolderComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityContainerHolderComponentImpl.java index f8f016b93..d7a2c93a9 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityContainerHolderComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/blockentity/component/common/BlockEntityContainerHolderComponentImpl.java @@ -1,11 +1,14 @@ package org.allaymc.server.blockentity.component.common; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; import org.allaymc.api.block.component.event.BlockOnInteractEvent; import org.allaymc.api.block.component.event.BlockOnReplaceEvent; import org.allaymc.api.blockentity.component.common.BlockEntityBaseComponent; import org.allaymc.api.blockentity.component.common.BlockEntityContainerHolderComponent; import org.allaymc.api.blockentity.component.event.BlockEntityLoadNBTEvent; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.component.annotation.Dependency; import org.allaymc.api.container.Container; @@ -13,6 +16,7 @@ import org.allaymc.api.entity.init.SimpleEntityInitInfo; import org.allaymc.api.entity.type.EntityTypes; import org.allaymc.api.eventbus.EventHandler; +import org.allaymc.api.utils.Identifier; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import java.util.Objects; @@ -25,12 +29,16 @@ * * @author daoge_cmd */ +@ToString +@EqualsAndHashCode public class BlockEntityContainerHolderComponentImpl implements BlockEntityContainerHolderComponent { @ComponentIdentifier protected static final Identifier IDENTIFIER = new Identifier("minecraft:block_entity_inventory_holder_component"); + @Setter protected Container container; @Dependency + @EqualsAndHashCode.Exclude protected BlockEntityBaseComponent baseComponent; public BlockEntityContainerHolderComponentImpl(Supplier containerSupplier) { @@ -52,11 +60,6 @@ public T getContainer() { return (T) container; } - @Override - public void setContainer(Container container) { - this.container = container; - } - @EventHandler private void onNBTLoaded(BlockEntityLoadNBTEvent event) { container.setBlockPos(baseComponent.getPosition()); diff --git a/Allay-Server/src/main/java/org/allaymc/server/blockentity/type/AllayBlockEntityType.java b/Allay-Server/src/main/java/org/allaymc/server/blockentity/type/AllayBlockEntityType.java index 18b3c089d..4db703f8b 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/blockentity/type/AllayBlockEntityType.java +++ b/Allay-Server/src/main/java/org/allaymc/server/blockentity/type/AllayBlockEntityType.java @@ -1,7 +1,9 @@ package org.allaymc.server.blockentity.type; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.SneakyThrows; +import lombok.ToString; import me.sunlan.fastreflection.FastConstructor; import me.sunlan.fastreflection.FastMemberLoader; import org.allaymc.api.blockentity.BlockEntity; @@ -10,10 +12,10 @@ import org.allaymc.api.blockentity.registry.BlockEntityTypeRegistry; import org.allaymc.api.blockentity.type.BlockEntityType; import org.allaymc.api.blockentity.type.BlockEntityTypeBuilder; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.interfaces.Component; import org.allaymc.api.component.interfaces.ComponentInitInfo; import org.allaymc.api.component.interfaces.ComponentProvider; +import org.allaymc.api.utils.Identifier; import org.allaymc.server.Allay; import org.allaymc.server.block.type.BlockTypeBuildException; import org.allaymc.server.blockentity.component.common.BlockEntityBaseComponentImpl; @@ -33,14 +35,19 @@ * * @author daoge_cmd */ +@ToString +@EqualsAndHashCode(onlyExplicitlyIncluded = true) public class AllayBlockEntityType implements BlockEntityType { protected final FastConstructor constructor; + @EqualsAndHashCode.Include protected Class interfaceClass; protected Class injectedClass; @Getter + @EqualsAndHashCode.Include protected List> componentProviders; @Getter + @EqualsAndHashCode.Include protected String name; @SneakyThrows diff --git a/Allay-Server/src/main/java/org/allaymc/server/client/storage/AllayCachedPlayerStorage.java b/Allay-Server/src/main/java/org/allaymc/server/client/storage/AllayCachedPlayerStorage.java index f8028df0e..ce3c30024 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/client/storage/AllayCachedPlayerStorage.java +++ b/Allay-Server/src/main/java/org/allaymc/server/client/storage/AllayCachedPlayerStorage.java @@ -79,5 +79,4 @@ protected static class DataEntry { long createTick; PlayerData playerData; } - } diff --git a/Allay-Server/src/main/java/org/allaymc/server/client/storage/AllayNBTFilePlayerStorage.java b/Allay-Server/src/main/java/org/allaymc/server/client/storage/AllayNBTFilePlayerStorage.java index 61b161e2b..05294446d 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/client/storage/AllayNBTFilePlayerStorage.java +++ b/Allay-Server/src/main/java/org/allaymc/server/client/storage/AllayNBTFilePlayerStorage.java @@ -37,7 +37,7 @@ public PlayerData readPlayerData(UUID uuid) { try (var reader = NbtUtils.createGZIPReader(Files.newInputStream(path))) { return PlayerData.fromNBT((NbtMap) reader.readTag()); } catch (IOException e) { - log.error("Error while reading player data " + uuid, e); + log.error("Error while reading player data {}", uuid, e); return PlayerData.createEmpty(); } } @@ -49,7 +49,7 @@ public void savePlayerData(UUID uuid, PlayerData playerData) { var oldPath = path.resolveSibling(uuid + "_old.nbt"); if (Files.exists(oldPath)) { // The old file - log.warn("Undeleted tmp player data file is found, which may caused by incorrect shutdown. File: " + oldPath); + log.warn("Undeleted tmp player data file is found, which may caused by incorrect shutdown. File: {}", oldPath); Files.delete(oldPath); } if (Files.exists(path)) { @@ -61,7 +61,7 @@ public void savePlayerData(UUID uuid, PlayerData playerData) { } catch (IOException e) { // error, rename uuid_old.nbt file to uuid.nbt Files.move(oldPath, path); - log.error("Error while writing player data " + uuid, e); + log.error("Error while writing player data {}", uuid, e); } // delete uuid_old.nbt file Files.deleteIfExists(oldPath); diff --git a/Allay-Server/src/main/java/org/allaymc/server/command/AllayCommandRegistry.java b/Allay-Server/src/main/java/org/allaymc/server/command/AllayCommandRegistry.java index 8df78c221..da1ce1d9b 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/command/AllayCommandRegistry.java +++ b/Allay-Server/src/main/java/org/allaymc/server/command/AllayCommandRegistry.java @@ -95,7 +95,7 @@ public CommandResult execute(CommandSender sender, String cmd) { sender.handleResult(result); return result; } catch (Throwable t) { - log.error("Error while execute command " + cmdName, t); + log.error("Error while execute command {}", cmdName, t); sender.sendTr(TextFormat.RED + "%" + TrKeys.M_COMMANDS_GENERIC_EXCEPTION); return CommandResult.fail(); } diff --git a/Allay-Server/src/main/java/org/allaymc/server/container/processor/ContainerActionProcessor.java b/Allay-Server/src/main/java/org/allaymc/server/container/processor/ContainerActionProcessor.java index 83215b56c..26126366d 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/container/processor/ContainerActionProcessor.java +++ b/Allay-Server/src/main/java/org/allaymc/server/container/processor/ContainerActionProcessor.java @@ -14,8 +14,6 @@ */ public interface ContainerActionProcessor { - ItemStackRequestActionType getType(); - ActionResponse ERROR_RESPONSE = new ActionResponse(false, List.of()); /** @@ -24,18 +22,23 @@ public interface ContainerActionProcessor { * @param currentActionIndex the index of the action in the request * @param actions all actions in the request * @param dataPool a map that can be used to store data between actions + * * @return the response to the action */ ActionResponse handle(T action, EntityPlayer player, int currentActionIndex, ItemStackRequestAction[] actions, Map dataPool); + ItemStackRequestActionType getType(); + default ActionResponse error() { return ERROR_RESPONSE; } default boolean failToValidateStackNetworkId(int expectedSNID, int clientSNID) { - //若客户端发来的stackNetworkId小于0,说明客户端保证数据无误并要求遵从服务端的数据 - //这通常发生在当一个ItemStackRequest中有多个action时且多个action有相同的source/destination container - //第一个action检查完id后后面的action就不需要重复检查了 + // If the stackNetworkId sent by the client is less than 0, it indicates that the client ensures + // the data integrity and requests compliance with the server's data. + // This usually happens when an ItemStackRequest contains multiple actions and + // multiple actions have the same source/destination container. + // The subsequent actions do not need to repeat the check after the first action has checked the id. return clientSNID > 0 && expectedSNID != clientSNID; } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/container/processor/ContainerActionProcessorHolder.java b/Allay-Server/src/main/java/org/allaymc/server/container/processor/ContainerActionProcessorHolder.java index dd3f36f40..5a17e258f 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/container/processor/ContainerActionProcessorHolder.java +++ b/Allay-Server/src/main/java/org/allaymc/server/container/processor/ContainerActionProcessorHolder.java @@ -11,13 +11,6 @@ * @author daoge_cmd */ public interface ContainerActionProcessorHolder { - > R getProcessor(ItemStackRequestActionType type); - - void registerProcessor(ContainerActionProcessor processor); - - @UnmodifiableView - Map> getProcessors(); - static void registerDefaultContainerActionProcessors(ContainerActionProcessorHolder holder) { holder.registerProcessor(new CraftCreativeActionProcessor()); holder.registerProcessor(new PlaceActionProcessor()); @@ -30,4 +23,11 @@ static void registerDefaultContainerActionProcessors(ContainerActionProcessorHol holder.registerProcessor(new CreateActionProcessor()); holder.registerProcessor(new CraftResultDeprecatedActionProcessor()); } + + > R getProcessor(ItemStackRequestActionType type); + + void registerProcessor(ContainerActionProcessor processor); + + @UnmodifiableView + Map> getProcessors(); } diff --git a/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftCreativeActionProcessor.java b/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftCreativeActionProcessor.java index 7ec5572fc..77b41eff8 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftCreativeActionProcessor.java +++ b/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftCreativeActionProcessor.java @@ -17,11 +17,6 @@ */ @Slf4j public class CraftCreativeActionProcessor implements ContainerActionProcessor { - @Override - public ItemStackRequestActionType getType() { - return ItemStackRequestActionType.CRAFT_CREATIVE; - } - @Override public ActionResponse handle(CraftCreativeAction action, EntityPlayer player, int currentActionIndex, ItemStackRequestAction[] actions, Map dataPool) { var item = CreativeItemRegistry.getRegistry().get(action.getCreativeItemNetworkId() - 1); @@ -32,7 +27,12 @@ public ActionResponse handle(CraftCreativeAction action, EntityPlayer player, in item = item.copy(true); item.setCount(item.getItemAttributes().maxStackSize()); player.getContainer(FullContainerType.CREATED_OUTPUT).setItemStack(0, item); - //从创造物品栏拿东西不需要响应 + // No response is needed when taking items from the creative inventory. return null; } + + @Override + public ItemStackRequestActionType getType() { + return ItemStackRequestActionType.CRAFT_CREATIVE; + } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftRecipeActionProcessor.java b/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftRecipeActionProcessor.java index 7cbe88be6..3f00996ed 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftRecipeActionProcessor.java +++ b/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftRecipeActionProcessor.java @@ -5,7 +5,6 @@ import org.allaymc.api.container.impl.CraftingContainer; import org.allaymc.api.entity.interfaces.EntityPlayer; import org.allaymc.api.item.recipe.RecipeRegistry; -import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ConsumeAction; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.CraftRecipeAction; import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action.ItemStackRequestAction; @@ -38,21 +37,23 @@ public ActionResponse handle(CraftRecipeAction action, EntityPlayer player, int var input = craftingContainer.createCraftingInput(); var matched = recipe.match(input); if (!matched) { - log.warn("Mismatched recipe! Network id: " + recipe.getNetworkId()); + log.warn("Mismatched recipe! Network id: {}", recipe.getNetworkId()); return error(); } else { dataPool.put(RECIPE_DATA_KEY, recipe); // Validate the consume action count which client sent - // 还有一部分检查被放在了ConsumeActionProcessor里面(例如消耗物品数量检查) + // Some checks are placed inside the ConsumeActionProcessor (such as checking the quantity of consumed items) var consumeActions = findAllConsumeActions(actions, currentActionIndex + 1); var consumeActionCountNeeded = craftingContainer.calculateShouldConsumedItemCount(); if (consumeActions.size() != consumeActionCountNeeded) { - log.warn("Mismatched consume action count! Expected: " + consumeActionCountNeeded + ", Actual: " + consumeActions.size()); + log.warn("Mismatched consume action count! Expected: {}, Actual: {}", consumeActionCountNeeded, consumeActions.size()); return error(); } if (recipe.getOutputs().length == 1) { - // 若配方输出物品为1,客户端将不会发送CreateAction,此时我们直接在CraftRecipeAction输出物品到CREATED_OUTPUT - // 若配方输出物品为多个,客户端将会发送CreateAction,此时我们将在CreateActionProcessor里面输出物品到CREATED_OUTPUT + // If the recipe output is 1 item, the client will not send a CreateAction. + // In this case, we directly output the item to CREATED_OUTPUT in the CraftRecipeAction + // If the recipe output is multiple items, the client will send a CreateAction. + // In this case, we will output the items to CREATED_OUTPUT inside the CreateActionProcessor var output = recipe.getOutputs()[0]; var createdOutput = player.getContainer(CREATED_OUTPUT); createdOutput.setItemStack(0, output); @@ -67,10 +68,9 @@ public ItemStackRequestActionType getType() { } protected List findAllConsumeActions(ItemStackRequestAction[] actions, int startIndex) { - var found = new ArrayList(); + List found = new ArrayList<>(); for (int i = startIndex; i < actions.length; i++) { - var action = actions[i]; - if (action instanceof ConsumeAction consumeAction) { + if (actions[i] instanceof ConsumeAction consumeAction) { found.add(consumeAction); } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftResultDeprecatedActionProcessor.java b/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftResultDeprecatedActionProcessor.java index 22c1edc68..c912e6106 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftResultDeprecatedActionProcessor.java +++ b/Allay-Server/src/main/java/org/allaymc/server/container/processor/CraftResultDeprecatedActionProcessor.java @@ -12,14 +12,14 @@ * * @author daoge_cmd */ -public class CraftResultDeprecatedActionProcessor implements ContainerActionProcessor{ +public class CraftResultDeprecatedActionProcessor implements ContainerActionProcessor { @Override - public ItemStackRequestActionType getType() { - return ItemStackRequestActionType.CRAFT_RESULTS_DEPRECATED; + public ActionResponse handle(CraftResultsDeprecatedAction action, EntityPlayer player, int currentActionIndex, ItemStackRequestAction[] actions, Map dataPool) { + return null; } @Override - public ActionResponse handle(CraftResultsDeprecatedAction action, EntityPlayer player, int currentActionIndex, ItemStackRequestAction[] actions, Map dataPool) { - return null; + public ItemStackRequestActionType getType() { + return ItemStackRequestActionType.CRAFT_RESULTS_DEPRECATED; } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/container/processor/CreateActionProcessor.java b/Allay-Server/src/main/java/org/allaymc/server/container/processor/CreateActionProcessor.java index 133c74072..4006fac9e 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/container/processor/CreateActionProcessor.java +++ b/Allay-Server/src/main/java/org/allaymc/server/container/processor/CreateActionProcessor.java @@ -19,11 +19,6 @@ */ @Slf4j public class CreateActionProcessor implements ContainerActionProcessor { - @Override - public ItemStackRequestActionType getType() { - return ItemStackRequestActionType.CREATE; - } - @Override public ActionResponse handle(CreateAction action, EntityPlayer player, int currentActionIndex, ItemStackRequestAction[] actions, Map dataPool) { Recipe recipe = (Recipe) dataPool.get(RECIPE_DATA_KEY); @@ -36,4 +31,9 @@ public ActionResponse handle(CreateAction action, EntityPlayer player, int curre createdOutput.setItemStack(0, output); return null; } + + @Override + public ItemStackRequestActionType getType() { + return ItemStackRequestActionType.CREATE; + } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/container/processor/DestroyActionProcessor.java b/Allay-Server/src/main/java/org/allaymc/server/container/processor/DestroyActionProcessor.java index b73d105d4..98eecd2fe 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/container/processor/DestroyActionProcessor.java +++ b/Allay-Server/src/main/java/org/allaymc/server/container/processor/DestroyActionProcessor.java @@ -22,11 +22,6 @@ */ @Slf4j public class DestroyActionProcessor implements ContainerActionProcessor { - @Override - public ItemStackRequestActionType getType() { - return ItemStackRequestActionType.DESTROY; - } - @Override public ActionResponse handle(DestroyAction action, EntityPlayer player, int currentActionIndex, ItemStackRequestAction[] actions, Map dataPool) { if (player.getGameType() != GameType.CREATIVE) { @@ -75,4 +70,9 @@ public ActionResponse handle(DestroyAction action, EntityPlayer player, int curr ) ); } + + @Override + public ItemStackRequestActionType getType() { + return ItemStackRequestActionType.DESTROY; + } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/container/processor/DropActionProcessor.java b/Allay-Server/src/main/java/org/allaymc/server/container/processor/DropActionProcessor.java index 7f1dced33..5db987de2 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/container/processor/DropActionProcessor.java +++ b/Allay-Server/src/main/java/org/allaymc/server/container/processor/DropActionProcessor.java @@ -21,11 +21,6 @@ */ @Slf4j public class DropActionProcessor implements ContainerActionProcessor { - @Override - public ItemStackRequestActionType getType() { - return ItemStackRequestActionType.DROP; - } - @Override public ActionResponse handle(DropAction action, EntityPlayer player, int currentActionIndex, ItemStackRequestAction[] actions, Map dataPool) { Container container = player.getReachableContainerBySlotType(action.getSource().getContainer()); @@ -48,21 +43,26 @@ public ActionResponse handle(DropAction action, EntityPlayer player, int current item = container.getItemStack(slot); return new ActionResponse( true, - Collections.singletonList( - new ItemStackResponseContainer( - container.getSlotType(slot), - Collections.singletonList( - new ItemStackResponseSlot( - container.toNetworkSlotIndex(slot), - container.toNetworkSlotIndex(slot), - item.getCount(), - item.getStackNetworkId(), - item.getCustomName(), - item.getDurability() - ) + Collections.singletonList( + new ItemStackResponseContainer( + container.getSlotType(slot), + Collections.singletonList( + new ItemStackResponseSlot( + container.toNetworkSlotIndex(slot), + container.toNetworkSlotIndex(slot), + item.getCount(), + item.getStackNetworkId(), + item.getCustomName(), + item.getDurability() ) ) ) + ) ); } + + @Override + public ItemStackRequestActionType getType() { + return ItemStackRequestActionType.DROP; + } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/container/processor/SwapActionProcessor.java b/Allay-Server/src/main/java/org/allaymc/server/container/processor/SwapActionProcessor.java index 71f72f97a..a1d7339a7 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/container/processor/SwapActionProcessor.java +++ b/Allay-Server/src/main/java/org/allaymc/server/container/processor/SwapActionProcessor.java @@ -20,11 +20,6 @@ */ @Slf4j public class SwapActionProcessor implements ContainerActionProcessor { - @Override - public ItemStackRequestActionType getType() { - return ItemStackRequestActionType.SWAP; - } - @Override public ActionResponse handle(SwapAction action, EntityPlayer player, int currentActionIndex, ItemStackRequestAction[] actions, Map dataPool) { Container sourceContainer = player.getReachableContainerBySlotType(action.getSource().getContainer()); @@ -75,4 +70,9 @@ public ActionResponse handle(SwapAction action, EntityPlayer player, int current ) ); } + + @Override + public ItemStackRequestActionType getType() { + return ItemStackRequestActionType.SWAP; + } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/container/processor/TransferItemActionProcessor.java b/Allay-Server/src/main/java/org/allaymc/server/container/processor/TransferItemActionProcessor.java index 4c65bf6c7..d2de553c8 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/container/processor/TransferItemActionProcessor.java +++ b/Allay-Server/src/main/java/org/allaymc/server/container/processor/TransferItemActionProcessor.java @@ -61,35 +61,37 @@ public ActionResponse handle(T action, EntityPlayer player, int currentActionInd ItemStack resultSourItem; ItemStack resultDestItem; if (sourItem.getCount() == count) { - //第一种:全部拿走 + // Scenario 1: Take all items resultSourItem = Container.EMPTY_SLOT_PLACE_HOLDER; source.setItemStack(sourceSlot, resultSourItem); if (destItem.getItemType() != AIR_TYPE) { resultDestItem = destItem; - //目标物品不为空,直接添加数量,目标物品网络堆栈id不变 + // If the target item is not empty, simply add the quantity. The target item's network stack id remains unchanged resultDestItem.setCount(destItem.getCount() + count); destination.onSlotChange(destinationSlot); } else { - //目标物品为空,直接移动原有堆栈到新位置,网络堆栈id使用源物品的网络堆栈id(相当于换个位置) + // If the target item is empty, move the existing stack to the new position. + // The network stack id of the target item remains the same as + // the source item's network stack id (essentially shifting positions). if (source.getContainerType() == FullContainerType.CREATED_OUTPUT) { - //HACK: 若是从CREATED_OUTPUT拿出的,需要服务端自行新建个网络堆栈id + // HACK: If taken from CREATED_OUTPUT, the server needs to create a new network stack id. sourItem = sourItem.copy(true); } resultDestItem = sourItem; destination.setItemStack(destinationSlot, resultDestItem); } } else { - //第二种:拿走一部分 + // Scenario 2: Take a portion resultSourItem = sourItem; resultSourItem.setCount(resultSourItem.getCount() - count); source.onSlotChange(sourceSlot); if (destItem.getItemType() != AIR_TYPE) { - //目标物品不为空 + // If the target item is not empty resultDestItem = destItem; resultDestItem.setCount(destItem.getCount() + count); destination.onSlotChange(destinationSlot); } else { - //目标物品为空,为分出来的子物品堆栈新建网络堆栈id + // If the target item is empty, create a new network stack id for the split-off sub-item stack resultDestItem = sourItem.copy(true); resultDestItem.setCount(count); destination.setItemStack(destinationSlot, resultDestItem); @@ -109,7 +111,7 @@ public ActionResponse handle(T action, EntityPlayer player, int currentActionInd ) ) ); - //CREATED_OUTPUT不需要发响应(mjの奇妙hack) + // No response is needed for CREATED_OUTPUT (mj's strange hack). if (source.getContainerType() != FullContainerType.CREATED_OUTPUT) { return new ActionResponse( true, diff --git a/Allay-Server/src/main/java/org/allaymc/server/data/AllayVanillaItemMetaBlockStateBiMap.java b/Allay-Server/src/main/java/org/allaymc/server/data/AllayVanillaItemMetaBlockStateBiMap.java index f39c65f69..7b839d716 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/data/AllayVanillaItemMetaBlockStateBiMap.java +++ b/Allay-Server/src/main/java/org/allaymc/server/data/AllayVanillaItemMetaBlockStateBiMap.java @@ -6,10 +6,10 @@ import org.allaymc.api.block.palette.BlockStateHashPalette; import org.allaymc.api.block.type.BlockState; import org.allaymc.api.block.type.BlockType; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.data.VanillaItemMetaBlockStateBiMap; import org.allaymc.api.item.registry.ItemTypeRegistry; import org.allaymc.api.item.type.ItemType; +import org.allaymc.api.utils.Identifier; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtUtils; @@ -57,7 +57,7 @@ public Function getMetaToBlockStateMapper(ItemType itemT if (map != null) { return map::get; } else { - return unused -> itemType.getBlockType().getDefaultState(); + return $ -> itemType.getBlockType().getDefaultState(); } } @@ -67,7 +67,7 @@ public Function getBlockStateHashToMetaMapper(BlockType blo if (map != null) { return map::get; } else { - return unused -> 0; + return $ -> 0; } } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityAttributeComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityAttributeComponentImpl.java index 811dcd4d3..8bb09d87d 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityAttributeComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityAttributeComponentImpl.java @@ -1,6 +1,7 @@ package org.allaymc.server.entity.component.common; -import org.allaymc.api.utils.Identifier; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.component.annotation.ComponentedObject; import org.allaymc.api.component.annotation.Dependency; @@ -12,7 +13,7 @@ import org.allaymc.api.entity.component.event.EntitySaveNBTEvent; import org.allaymc.api.entity.component.player.EntityPlayerNetworkComponent; import org.allaymc.api.eventbus.EventHandler; -import org.cloudburstmc.nbt.NbtMap; +import org.allaymc.api.utils.Identifier; import org.cloudburstmc.nbt.NbtType; import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket; @@ -30,6 +31,8 @@ * * @author daoge_cmd */ +@ToString +@EqualsAndHashCode public class EntityAttributeComponentImpl implements EntityAttributeComponent { @ComponentIdentifier @@ -49,13 +52,13 @@ public EntityAttributeComponentImpl(List attributeTypes) { @EventHandler private void onLoadNBT(EntityLoadNBTEvent event) { var nbt = event.getNbt(); - if (nbt.containsKey("Attributes")) { - for (NbtMap compound : nbt.getList("Attributes", NbtType.COMPOUND)) { + nbt.listenForList("Attributes", NbtType.COMPOUND, attributesNbt -> { + attributesNbt.forEach(compound -> { var attribute = Attribute.fromNBT(compound); attributes.put(AttributeType.byKey(attribute.getKey()), attribute); - } + }); sendAttributesToClient(); - } + }); } @EventHandler @@ -105,9 +108,7 @@ public void sendAttributesToClient() { if (networkComponent == null) return; var updateAttributesPacket = new UpdateAttributesPacket(); updateAttributesPacket.setRuntimeEntityId(entity.getRuntimeId()); - for (Attribute attribute : attributes.values()) { - updateAttributesPacket.getAttributes().add(attribute.toNetwork()); - } + attributes.values().forEach(attribute -> updateAttributesPacket.getAttributes().add(attribute.toNetwork())); updateAttributesPacket.setTick(entity.getWorld().getTick()); networkComponent.sendPacket(updateAttributesPacket); } diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityBaseComponentImpl.java index 9523202af..f99e09061 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityBaseComponentImpl.java @@ -1,9 +1,11 @@ package org.allaymc.server.entity.component.common; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.Setter; +import lombok.ToString; import lombok.extern.slf4j.Slf4j; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.command.CommandSender; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.component.annotation.ComponentedObject; @@ -32,6 +34,7 @@ import org.allaymc.api.perm.DefaultPermissions; import org.allaymc.api.perm.tree.PermTree; import org.allaymc.api.server.Server; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.utils.MathUtils; import org.allaymc.api.world.Dimension; import org.allaymc.api.world.World; @@ -93,6 +96,8 @@ * @author daoge_cmd */ @Slf4j +@ToString +@EqualsAndHashCode(onlyExplicitlyIncluded = true) public class EntityBaseComponentImpl implements EntityBaseComponent { @ComponentIdentifier @@ -102,14 +107,19 @@ public class EntityBaseComponentImpl implements EntityBaseComp protected static final AtomicLong RUNTIME_ID_COUNTER = new AtomicLong(0); + private static final CommandOriginData ENTITY_COMMAND_ORIGIN_DATA = new CommandOriginData(CommandOriginType.ENTITY, UUID.randomUUID(), "", 0); + + @Getter protected final Location3f location; protected final Location3f locLastSent = new Location3f(0, 0, 0, null); @Getter protected final long runtimeId = RUNTIME_ID_COUNTER.getAndIncrement(); + @Getter + protected final Metadata metadata; // Will be reset in method loadUniqueId() @Getter + @EqualsAndHashCode.Include protected long uniqueId = Long.MAX_VALUE; - protected final Metadata metadata; @Manager protected ComponentManager manager; @ComponentedObject @@ -119,15 +129,21 @@ public class EntityBaseComponentImpl implements EntityBaseComp protected EntityType entityType; protected Map viewers = new Long2ObjectOpenHashMap<>(); protected Map effects = new HashMap<>(); + @Getter protected Vector3f motion = new Vector3f(); + @Getter protected boolean onGround = true; protected boolean willBeDespawnedNextTick = false; protected boolean willBeSpawnedNextTick = false; + @Getter protected boolean spawned; + @Getter protected boolean dead; protected int deadTimer; + @Getter protected float fallDistance = 0f; @Getter + @Setter protected String displayName; protected Set tags = new HashSet<>(); @@ -224,16 +240,6 @@ public EntityType getEntityType() { return entityType; } - @Override - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - @Override - public Location3fc getLocation() { - return location; - } - public void setLocation(Location3fc location) { setLocation(location, true); } @@ -260,11 +266,6 @@ public World getWorld() { return location.dimension.getWorld(); } - @Override - public boolean isDead() { - return dead; - } - @Override public void despawn() { getDimension().getEntityService().removeEntity(thisEntity); @@ -281,11 +282,6 @@ public void setWillBeDespawnedNextTick(boolean willBeDespawnedNextTick) { this.willBeDespawnedNextTick = willBeDespawnedNextTick; } - @Override - public boolean isSpawned() { - return spawned; - } - @Override @ApiStatus.Internal public void setSpawned(boolean spawned) { @@ -295,7 +291,7 @@ public void setSpawned(boolean spawned) { @Override public boolean canBeSpawned() { return location.x != Integer.MAX_VALUE && location.y != Integer.MAX_VALUE && location.z != Integer.MAX_VALUE && - location.dimension != null && !spawned && !willBeSpawnedNextTick; + location.dimension != null && !spawned && !willBeSpawnedNextTick; } @Override @@ -377,11 +373,6 @@ protected void teleportOverDimension(Location3fc target) { }); } - @Override - public Metadata getMetadata() { - return metadata; - } - @Override public void sendEntityData(EntityDataType... dataTypes) { if (viewers.isEmpty()) return; @@ -423,21 +414,11 @@ public void setHasEntityCollision(boolean hasEntityCollision) { return Collections.unmodifiableMap(viewers); } - @Override - public Vector3fc getMotion() { - return motion; - } - @Override public void setMotion(Vector3fc motion) { this.motion = new Vector3f(motion); } - @Override - public boolean isOnGround() { - return onGround; - } - @Override public void setOnGround(boolean onGround) { this.onGround = onGround; @@ -452,7 +433,7 @@ public void setHasGravity(boolean hasGravity) { @Override public void knockback(Vector3fc source) { - var resistance = 0.6f; + var resistance = AttributeType.KNOCKBACK_RESISTANCE.getDefaultValue(); if (attributeComponent != null) { resistance = attributeComponent.getAttributeValue(AttributeType.KNOCKBACK_RESISTANCE); } @@ -656,16 +637,12 @@ public void loadNBT(NbtMap nbt) { location.setPitch(rot.y); } if (nbt.containsKey("Motion")) { - // What? mot! var mot = readVector3f(nbt, "Motion", "dx", "dy", "dz"); motion.set(mot); } - if (nbt.containsKey("OnGround")) { - onGround = nbt.getBoolean("OnGround"); - } - if (nbt.containsKey("Tags")) { - tags.addAll(nbt.getList("Tags", NbtType.STRING)); - } + nbt.listenForBoolean("OnGround", onGround -> this.onGround = onGround); + nbt.listenForList("Tags", NbtType.STRING, tags -> this.tags.addAll(tags)); + loadUniqueId(nbt); var event = new EntityLoadNBTEvent(nbt); manager.callEvent(event); @@ -679,11 +656,6 @@ protected void loadUniqueId(NbtMap nbt) { uniqueId = UUID.randomUUID().getMostSignificantBits(); } - @Override - public float getFallDistance() { - return fallDistance; - } - @Override public void onFall() { var event = new org.allaymc.api.eventbus.event.world.entity.EntityFallEvent(thisEntity, fallDistance); @@ -763,10 +735,8 @@ public String getCommandSenderName() { return getDisplayName(); } - private static final CommandOriginData ENTITY_COMMAND_ORIGIN_DATA = new CommandOriginData(CommandOriginType.ENTITY, UUID.randomUUID(), "", 0); - @Override - public CommandOriginData getCommandOriginData(){ + public CommandOriginData getCommandOriginData() { return ENTITY_COMMAND_ORIGIN_DATA; } diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityContainerHolderComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityContainerHolderComponentImpl.java index f9e73f227..7e091e12d 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityContainerHolderComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityContainerHolderComponentImpl.java @@ -1,11 +1,12 @@ package org.allaymc.server.entity.component.common; -import org.allaymc.api.utils.Identifier; +import lombok.NoArgsConstructor; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.container.BaseContainerHolder; import org.allaymc.api.container.Container; import org.allaymc.api.container.FullContainerType; import org.allaymc.api.entity.component.common.EntityContainerHolderComponent; +import org.allaymc.api.utils.Identifier; import org.jetbrains.annotations.UnmodifiableView; import java.util.Map; @@ -15,13 +16,12 @@ * * @author daoge_cmd */ +@NoArgsConstructor public class EntityContainerHolderComponentImpl extends BaseContainerHolder implements EntityContainerHolderComponent { @ComponentIdentifier protected static final Identifier IDENTIFIER = new Identifier("minecraft:entity_inventory_holder_component"); - public EntityContainerHolderComponentImpl() {} - public EntityContainerHolderComponentImpl(Container... containers) { super(containers); } diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityDamageComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityDamageComponentImpl.java index 8b9842b39..db18500d7 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityDamageComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/common/EntityDamageComponentImpl.java @@ -1,7 +1,8 @@ package org.allaymc.server.entity.component.common; +import lombok.EqualsAndHashCode; import lombok.Getter; -import org.allaymc.api.utils.Identifier; +import lombok.ToString; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.component.annotation.ComponentedObject; import org.allaymc.api.component.annotation.Dependency; @@ -12,6 +13,7 @@ import org.allaymc.api.entity.component.event.EntityFallEvent; import org.allaymc.api.entity.damage.DamageContainer; import org.allaymc.api.eventbus.EventHandler; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.world.gamerule.GameRule; import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType; import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket; @@ -21,6 +23,8 @@ * * @author daoge_cmd */ +@ToString +@EqualsAndHashCode public class EntityDamageComponentImpl implements EntityDamageComponent { @ComponentIdentifier diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/item/EntityItemBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/item/EntityItemBaseComponentImpl.java index 9765274e8..83d2e3e0f 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/item/EntityItemBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/item/EntityItemBaseComponentImpl.java @@ -1,5 +1,9 @@ package org.allaymc.server.entity.component.item; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; import org.allaymc.api.entity.Entity; import org.allaymc.api.entity.component.item.EntityItemBaseComponent; import org.allaymc.api.entity.init.EntityInitInfo; @@ -22,9 +26,14 @@ * * @author daoge_cmd */ +@Setter +@Getter +@ToString +@EqualsAndHashCode(callSuper = true) public class EntityItemBaseComponentImpl extends EntityBaseComponentImpl implements EntityItemBaseComponent { public static final int MAX_AGE = 6000; + protected ItemStack itemStack; protected int pickupDelay = 10; protected int age; @@ -88,38 +97,7 @@ public NbtMap saveNBT() { @Override public void loadNBT(NbtMap nbt) { super.loadNBT(nbt); - if (nbt.containsKey("Item")) - itemStack = fromNBT(nbt.getCompound("Item")); - } - - @Override - public ItemStack getItemStack() { - return itemStack; - } - - @Override - public void setItemStack(ItemStack itemStack) { - this.itemStack = itemStack; - } - - @Override - public int getPickupDelay() { - return pickupDelay; - } - - @Override - public void setPickupDelay(int delay) { - this.pickupDelay = delay; - } - - @Override - public int getAge() { - return age; - } - - @Override - public void setAge(int age) { - this.age = age; + nbt.listenForCompound("Item", item -> itemStack = fromNBT(item)); } @Override diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerBaseComponentImpl.java index 8457e83bb..6c8b3c797 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerBaseComponentImpl.java @@ -2,8 +2,10 @@ import com.google.common.base.Preconditions; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.client.data.Abilities; import org.allaymc.api.client.data.AdventureSettings; @@ -75,6 +77,7 @@ * @author daoge_cmd */ @Slf4j +@ToString(callSuper = true) public class EntityPlayerBaseComponentImpl extends EntityBaseComponentImpl implements EntityPlayerBaseComponent { @Dependency @@ -636,6 +639,7 @@ public CustomForm removeServerSettingForm(int id) { public void showForm(Form form) { if (this.forms.size() > 100) { networkComponent.disconnect("Possible DoS vulnerability: More Than 100 FormWindow sent to client already."); + return; } var packet = new ModalFormRequestPacket(); var id = assignFormId(); @@ -700,8 +704,7 @@ public void removeScoreboardLine(ScoreboardLine line) { SetScorePacket pk = new SetScorePacket(); pk.setAction(SetScorePacket.Action.REMOVE); var networkInfo = line.toNetworkInfo(); - if (networkInfo != null) - pk.getInfos().add(networkInfo); + if (networkInfo != null) pk.getInfos().add(networkInfo); networkComponent.sendPacket(pk); var scorer = new PlayerScorer(thisEntity); diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerHolderComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerHolderComponentImpl.java index 9207f8aa2..dfeb45919 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerHolderComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerHolderComponentImpl.java @@ -1,8 +1,16 @@ package org.allaymc.server.entity.component.player; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.allaymc.api.component.annotation.ComponentedObject; import org.allaymc.api.component.interfaces.ComponentInitInfo; -import org.allaymc.api.container.impl.*; +import org.allaymc.api.container.impl.CraftingGridContainer; +import org.allaymc.api.container.impl.CraftingTableContainer; +import org.allaymc.api.container.impl.PlayerArmorContainer; +import org.allaymc.api.container.impl.PlayerCreatedOutputContainer; +import org.allaymc.api.container.impl.PlayerCursorContainer; +import org.allaymc.api.container.impl.PlayerInventoryContainer; +import org.allaymc.api.container.impl.PlayerOffhandContainer; import org.allaymc.api.entity.component.player.EntityPlayerContainerHolderComponent; import org.allaymc.api.entity.interfaces.EntityPlayer; import org.allaymc.server.entity.component.common.EntityContainerHolderComponentImpl; @@ -12,13 +20,16 @@ * * @author daoge_cmd */ +@ToString +@EqualsAndHashCode(callSuper = false) public class EntityPlayerContainerHolderComponentImpl extends EntityContainerHolderComponentImpl implements EntityPlayerContainerHolderComponent { @ComponentedObject private EntityPlayer player; public EntityPlayerContainerHolderComponentImpl() { - super(new PlayerCursorContainer(), + super( + new PlayerCursorContainer(), new PlayerCreatedOutputContainer(), new PlayerArmorContainer(), new PlayerOffhandContainer(), diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerViewerComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerViewerComponentImpl.java index 3980f2a9d..e07a5024a 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerViewerComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerContainerViewerComponentImpl.java @@ -4,7 +4,8 @@ import com.google.common.collect.HashBiMap; import it.unimi.dsi.fastutil.bytes.Byte2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import org.allaymc.api.utils.Identifier; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.component.annotation.Dependency; import org.allaymc.api.container.Container; @@ -14,6 +15,7 @@ import org.allaymc.api.entity.component.common.EntityContainerViewerComponent; import org.allaymc.api.entity.component.player.EntityPlayerBaseComponent; import org.allaymc.api.entity.component.player.EntityPlayerNetworkComponent; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.utils.MathUtils; import org.cloudburstmc.math.vector.Vector3i; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerSlotType; @@ -30,7 +32,9 @@ * Allay Project 2023/9/23 * * @author daoge_cmd - */ // + */ +@ToString +@EqualsAndHashCode(onlyExplicitlyIncluded = true) public class EntityPlayerContainerViewerComponentImpl implements EntityContainerViewerComponent { @ComponentIdentifier @@ -38,6 +42,7 @@ public class EntityPlayerContainerViewerComponentImpl implements EntityContainer protected byte idCounter = 1; @Dependency + @EqualsAndHashCode.Include protected EntityPlayerBaseComponent baseComponent; @Dependency protected EntityPlayerNetworkComponent networkComponent; @@ -107,7 +112,7 @@ public void onOpen(byte assignedId, Container container) { typeToContainer.put(container.getContainerType(), container); container.getContainerType().heldSlotTypes().forEach(slotType -> slotTypeToFullType.put(slotType, container.getContainerType())); - //We should send the container's contents to client if the container is not held by the entity + // We should send the container's contents to client if the container is not held by the entity if (containerHolderComponent.getContainer(containerType) == null) { sendContents(container); } @@ -143,7 +148,6 @@ public T getOpenedContainerBySlotType(ContainerSlotType sl } @Override - public Container getOpenedContainer(byte id) { return idToContainer.get(id); } diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerDamageComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerDamageComponentImpl.java index e435d0296..c5204389d 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerDamageComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerDamageComponentImpl.java @@ -1,5 +1,7 @@ package org.allaymc.server.entity.component.player; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.allaymc.api.component.annotation.Dependency; import org.allaymc.api.entity.component.player.EntityPlayerBaseComponent; import org.allaymc.api.entity.damage.DamageContainer; @@ -11,6 +13,8 @@ * * @author daoge_cmd */ +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) public class EntityPlayerDamageComponentImpl extends EntityDamageComponentImpl { @Dependency protected EntityPlayerBaseComponent baseComponent; diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerNetworkComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerNetworkComponentImpl.java index 19745dce0..efc222498 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerNetworkComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/component/player/EntityPlayerNetworkComponentImpl.java @@ -1,11 +1,11 @@ package org.allaymc.server.entity.component.player; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.block.registry.BlockTypeRegistry; -import org.allaymc.api.entity.component.player.EntityPlayerContainerHolderComponent; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.client.data.LoginData; import org.allaymc.api.client.storage.PlayerData; import org.allaymc.api.component.annotation.ComponentIdentifier; @@ -30,6 +30,7 @@ import org.allaymc.api.network.processor.PacketProcessorHolder; import org.allaymc.api.pack.PackRegistry; import org.allaymc.api.server.Server; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.world.Dimension; import org.allaymc.api.world.biome.BiomeTypeRegistry; import org.allaymc.server.network.processor.AllayPacketProcessorHolder; @@ -73,11 +74,17 @@ * @author daoge_cmd */ @Slf4j +@ToString +@EqualsAndHashCode(onlyExplicitlyIncluded = true) public class EntityPlayerNetworkComponentImpl implements EntityPlayerNetworkComponent { @ComponentIdentifier public static final Identifier IDENTIFIER = new Identifier("minecraft:player_network_component"); + protected final Server server = Server.getInstance(); + @Getter + protected final PacketProcessorHolder packetProcessorHolder = new AllayPacketProcessorHolder(); + @Getter protected boolean loggedIn = false; @Getter @@ -93,17 +100,13 @@ public class EntityPlayerNetworkComponentImpl implements EntityPlayerNetworkComp protected String disconnectReason = null; protected boolean hideDisconnectReason = false; protected AtomicInteger doFirstSpawnChunkThreshold = new AtomicInteger(Server.SETTINGS.worldSettings().doFirstSpawnChunkThreshold()); - - protected final Server server = Server.getInstance(); - @Getter - protected final PacketProcessorHolder packetProcessorHolder = new AllayPacketProcessorHolder(); - @Manager protected ComponentManager manager; @ComponentedObject protected EntityPlayer player; @Getter @Setter + @EqualsAndHashCode.Include protected LoginData loginData; @Getter @Setter @@ -160,7 +163,7 @@ public void setClientSession(BedrockServerSession session) { public PacketSignal handlePacket(BedrockPacket packet) { var processor = packetProcessorHolder.getProcessor(packet); if (processor == null) { - log.warn("Received a packet without packet handler: " + packet); + log.warn("Received a packet without packet handler: {}", packet); return PacketSignal.HANDLED; } if (processor.handleAsync(player, packet) != PacketSignal.HANDLED) { @@ -364,8 +367,8 @@ protected void validateAndSetSpawnPoint(PlayerData playerData) { Location3ic spawnPoint; var spawnWorld = server.getWorldPool().getWorld(playerData.getSpawnPointWorldName()); if (spawnWorld == null) { - // 出生点所在的世界不存在 - // 使用全局出生点替代 + // The world where the point of respawn is located does not exist + // The world with a universal point of respawn does not exist spawnPoint = server.getWorldPool().getGlobalSpawnPoint(); playerData.setSpawnPoint(spawnPoint); playerData.setSpawnPointWorldName(spawnPoint.dimension().getWorld().getWorldData().getName()); diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/effect/AllayEffectRegistry.java b/Allay-Server/src/main/java/org/allaymc/server/entity/effect/AllayEffectRegistry.java index 10bea3029..5f02518fd 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/effect/AllayEffectRegistry.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/effect/AllayEffectRegistry.java @@ -4,11 +4,11 @@ import lombok.extern.slf4j.Slf4j; import me.tongfei.progressbar.ConsoleProgressBarConsumer; import me.tongfei.progressbar.ProgressBar; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.entity.effect.EffectRegistry; import org.allaymc.api.entity.effect.EffectType; import org.allaymc.api.i18n.I18n; import org.allaymc.api.registry.SimpleDoubleKeyMappedRegistry; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.utils.ReflectionUtils; import java.util.HashMap; diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/registry/AllayEntityTypeRegistry.java b/Allay-Server/src/main/java/org/allaymc/server/entity/registry/AllayEntityTypeRegistry.java index 7e031379e..b37feaf65 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/registry/AllayEntityTypeRegistry.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/registry/AllayEntityTypeRegistry.java @@ -4,12 +4,12 @@ import lombok.extern.slf4j.Slf4j; import me.tongfei.progressbar.ConsoleProgressBarConsumer; import me.tongfei.progressbar.ProgressBar; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.entity.registry.EntityTypeRegistry; import org.allaymc.api.entity.type.EntityType; import org.allaymc.api.i18n.I18n; import org.allaymc.api.i18n.TrKeys; import org.allaymc.api.registry.SimpleMappedRegistry; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.utils.ReflectionUtils; import org.allaymc.server.entity.type.EntityTypeDefaultInitializer; import org.allaymc.server.entity.type.EntityTypeInitializer; @@ -38,6 +38,17 @@ public AllayEntityTypeRegistry() { loadVanillaEntityIdentifierTag(); } + private static void callInitializer(Method method, ProgressBar progressBar) { + try { + method.invoke(null); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } finally { + if (progressBar != null) + progressBar.step(); + } + } + @SneakyThrows public void init() { log.info(I18n.get().tr(TrKeys.A_ENTITYTYPE_LOADING)); @@ -55,17 +66,6 @@ public void init() { log.info(I18n.get().tr(TrKeys.A_ENTITYTYPE_LOADED, defaultInitializers.size())); } - private static void callInitializer(Method method, ProgressBar progressBar) { - try { - method.invoke(null); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } finally { - if (progressBar != null) - progressBar.step(); - } - } - @SneakyThrows private void loadVanillaEntityIdentifierTag() { //TODO: Support custom entity diff --git a/Allay-Server/src/main/java/org/allaymc/server/entity/type/AllayEntityType.java b/Allay-Server/src/main/java/org/allaymc/server/entity/type/AllayEntityType.java index 28dbd177b..c32027f30 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/entity/type/AllayEntityType.java +++ b/Allay-Server/src/main/java/org/allaymc/server/entity/type/AllayEntityType.java @@ -1,9 +1,9 @@ package org.allaymc.server.entity.type; +import lombok.Getter; import lombok.SneakyThrows; import me.sunlan.fastreflection.FastConstructor; import me.sunlan.fastreflection.FastMemberLoader; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.interfaces.Component; import org.allaymc.api.component.interfaces.ComponentInitInfo; import org.allaymc.api.component.interfaces.ComponentProvider; @@ -14,6 +14,7 @@ import org.allaymc.api.entity.registry.EntityTypeRegistry; import org.allaymc.api.entity.type.EntityType; import org.allaymc.api.entity.type.EntityTypeBuilder; +import org.allaymc.api.utils.Identifier; import org.allaymc.server.Allay; import org.allaymc.server.block.type.BlockTypeBuildException; import org.allaymc.server.component.injector.AllayComponentInjector; @@ -34,7 +35,9 @@ public class AllayEntityType implements EntityType { protected final FastConstructor constructor; protected Class interfaceClass; protected Class injectedClass; + @Getter protected List> componentProviders; + @Getter protected Identifier identifier; @SneakyThrows @@ -57,9 +60,8 @@ protected AllayEntityType(Class interfaceClass, this.constructor = FastConstructor.create(injectedClass.getConstructor(ComponentInitInfo.class), fastMemberLoader, false); } - @Override - public List> getComponentProviders() { - return componentProviders; + public static EntityTypeBuilder builder(Class interfaceClass) { + return new Builder<>(interfaceClass); } @SneakyThrows @@ -69,15 +71,6 @@ public T createEntity(EntityInitInfo info) { return (T) constructor.invoke(info); } - @Override - public Identifier getIdentifier() { - return identifier; - } - - public static EntityTypeBuilder builder(Class interfaceClass) { - return new Builder<>(interfaceClass); - } - public static class Builder implements EntityTypeBuilder { protected Class interfaceClass; protected Map> componentProviders = new HashMap<>(); diff --git a/Allay-Server/src/main/java/org/allaymc/server/i18n/AllayI18nLoader.java b/Allay-Server/src/main/java/org/allaymc/server/i18n/AllayI18nLoader.java index 652755b98..bc818dff1 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/i18n/AllayI18nLoader.java +++ b/Allay-Server/src/main/java/org/allaymc/server/i18n/AllayI18nLoader.java @@ -1,19 +1,12 @@ package org.allaymc.server.i18n; -import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; import org.allaymc.api.i18n.I18nLoader; import org.allaymc.api.i18n.LangCode; import org.allaymc.api.utils.JSONUtils; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.StringReader; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -26,11 +19,11 @@ public class AllayI18nLoader implements I18nLoader { @Override public Map getLangMap(LangCode langCode) { - try (var input = Objects.requireNonNull(AllayI18nLoader.class.getResourceAsStream("/lang/" + langCode.name() + ".json"));) { + try (var input = Objects.requireNonNull(AllayI18nLoader.class.getResourceAsStream("/lang/" + langCode.name() + ".json"))) { TypeToken> typeToken = new TypeToken<>() { }; - byte[] bytes = input.readAllBytes(); - return JSONUtils.fromLenient(new String(bytes, StandardCharsets.UTF_8),typeToken); + var bytes = input.readAllBytes(); + return JSONUtils.fromLenient(new String(bytes, StandardCharsets.UTF_8), typeToken); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/Allay-Server/src/main/java/org/allaymc/server/item/attribute/AllayVanillaItemAttributeRegistry.java b/Allay-Server/src/main/java/org/allaymc/server/item/attribute/AllayVanillaItemAttributeRegistry.java index a441bd2c7..c02784f0f 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/item/attribute/AllayVanillaItemAttributeRegistry.java +++ b/Allay-Server/src/main/java/org/allaymc/server/item/attribute/AllayVanillaItemAttributeRegistry.java @@ -59,10 +59,10 @@ public Map load(Void input) { VanillaItemId type; try { var typeName = AllayStringUtils.fastTwoPartSplit(dataEntry.getString("name"), ":", "")[1] - .replace(".","_").toUpperCase(); + .replace(".", "_").toUpperCase(); type = VanillaItemId.valueOf(typeName); } catch (IllegalArgumentException ignore) { - log.error("Unknown item name: " + dataEntry.getString("name")); + log.error("Unknown item name: {}", dataEntry.getString("name")); continue; } var itemAttributes = ItemAttributes.fromNBT(dataEntry); diff --git a/Allay-Server/src/main/java/org/allaymc/server/item/component/air/ItemAirBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/item/component/air/ItemAirBaseComponentImpl.java index dfa0a446a..9f0fdfda8 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/item/component/air/ItemAirBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/item/component/air/ItemAirBaseComponentImpl.java @@ -14,7 +14,7 @@ */ public class ItemAirBaseComponentImpl extends ItemBaseComponentImpl { - static SimpleItemStackInitInfo AIR_TYPE_INIT_INFO = + private static final SimpleItemStackInitInfo AIR_TYPE_INIT_INFO = SimpleItemStackInitInfo .builder() .autoAssignStackNetworkId(false) diff --git a/Allay-Server/src/main/java/org/allaymc/server/item/component/common/ItemAttributeComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/item/component/common/ItemAttributeComponentImpl.java index 2c3aa5978..a3949f8c4 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/item/component/common/ItemAttributeComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/item/component/common/ItemAttributeComponentImpl.java @@ -1,33 +1,35 @@ package org.allaymc.server.item.component.common; -import org.allaymc.api.utils.Identifier; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.item.component.common.ItemAttributeComponent; import org.allaymc.api.item.component.common.ItemAttributes; +import org.allaymc.api.utils.Identifier; /** * Allay Project 2023/5/20 * * @author daoge_cmd */ +@ToString +@EqualsAndHashCode public class ItemAttributeComponentImpl implements ItemAttributeComponent { @ComponentIdentifier public static final Identifier IDENTIFIER = new Identifier("minecraft:item_attribute_component"); + protected static final ItemAttributeComponentImpl DEFAULT = new ItemAttributeComponentImpl(ItemAttributes.DEFAULT); + @Getter protected ItemAttributes itemAttributes; - public static ItemAttributeComponentImpl ofDefault() { - return DEFAULT; - } - public ItemAttributeComponentImpl(ItemAttributes itemAttributes) { this.itemAttributes = itemAttributes; } - @Override - public ItemAttributes getItemAttributes() { - return itemAttributes; + public static ItemAttributeComponentImpl ofDefault() { + return DEFAULT; } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/item/component/common/ItemBaseComponentImpl.java b/Allay-Server/src/main/java/org/allaymc/server/item/component/common/ItemBaseComponentImpl.java index 2eddad382..3148ec6d7 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/item/component/common/ItemBaseComponentImpl.java +++ b/Allay-Server/src/main/java/org/allaymc/server/item/component/common/ItemBaseComponentImpl.java @@ -1,10 +1,12 @@ package org.allaymc.server.item.component.common; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.block.data.BlockFace; import org.allaymc.api.block.type.BlockState; import org.allaymc.api.block.type.BlockType; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.component.annotation.ComponentIdentifier; import org.allaymc.api.component.annotation.ComponentedObject; import org.allaymc.api.component.annotation.Dependency; @@ -21,6 +23,7 @@ import org.allaymc.api.item.init.SimpleItemStackInitInfo; import org.allaymc.api.item.type.ItemType; import org.allaymc.api.item.type.ItemTypes; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.world.Dimension; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; @@ -41,6 +44,8 @@ * @author daoge_cmd */ @Slf4j +@ToString +//@EqualsAndHashCode // TODO: need fix because this break shift + click public class ItemBaseComponentImpl implements ItemBaseComponent { @ComponentIdentifier @@ -48,24 +53,30 @@ public class ItemBaseComponentImpl implements ItemBaseCompo private static int STACK_NETWORK_ID_COUNTER = 1; - public static int getCurrentStackNetworkIdCounter() { - return STACK_NETWORK_ID_COUNTER; - } - @Dependency protected ItemAttributeComponent attributeComponent; @ComponentedObject protected T thisItemStack; - protected ItemType itemType; + @Getter protected int count; + @Getter protected int meta; + @Getter protected int durability; + @Setter + @Getter protected String customName = ""; + @Setter + @Getter protected List lore = new ArrayList<>(); protected Map enchantments = new HashMap<>(); //TODO: item lock type + @Setter + @Getter protected NbtMap customNBTContent = NbtMap.EMPTY; + @Setter + @Getter protected int stackNetworkId; public ItemBaseComponentImpl(ItemStackInitInfo initInfo) { @@ -82,6 +93,10 @@ public ItemBaseComponentImpl(ItemStackInitInfo initInfo) { } } + public static int getCurrentStackNetworkIdCounter() { + return STACK_NETWORK_ID_COUNTER; + } + @Override public void onInitFinish(ComponentInitInfo initInfo) { loadExtraTag(((ItemStackInitInfo) initInfo).extraTag()); @@ -95,12 +110,10 @@ public void loadExtraTag(NbtMap extraTag) { this.customName = displayTag.getString("Name"); this.lore = extraTag.getList("Lore", NbtType.STRING); } - if (extraTag.containsKey("ench")) { - extraTag.getList("ench", NbtType.COMPOUND).forEach(tag -> { - var enchantment = EnchantmentHelper.fromNBT(tag); - this.enchantments.put(enchantment.getType(), enchantment); - }); - } + extraTag.listenForList("ench", NbtType.COMPOUND, tags -> tags.forEach(tag -> { + var enchantment = EnchantmentHelper.fromNBT(tag); + this.enchantments.put(enchantment.getType(), enchantment); + })); } @Override @@ -108,22 +121,12 @@ public ItemType getItemType() { return itemType; } - @Override - public int getCount() { - return count; - } - @Override public void setCount(int count) { if (count < 0) throw new IllegalArgumentException("count cannot be negative"); this.count = count; } - @Override - public int getMeta() { - return meta; - } - @Override public void setMeta(int meta) { if (meta < 0) @@ -131,11 +134,6 @@ public void setMeta(int meta) { this.meta = meta; } - @Override - public int getDurability() { - return durability; - } - @Override public void setDurability(int durability) { if (durability < 0) @@ -143,26 +141,6 @@ public void setDurability(int durability) { this.durability = durability; } - @Override - public String getCustomName() { - return customName; - } - - @Override - public void setCustomName(String customName) { - this.customName = customName; - } - - @Override - public List getLore() { - return lore; - } - - @Override - public void setLore(List lore) { - this.lore = lore; - } - @Override public BlockState toBlockState() { return itemType.getBlockType() == null ? @@ -189,16 +167,6 @@ public ItemData toNetworkItemData() { } } - @Override - public int getStackNetworkId() { - return stackNetworkId; - } - - @Override - public void setStackNetworkId(int newStackNetworkId) { - this.stackNetworkId = newStackNetworkId; - } - @Override public int assignNewStackNetworkId() { stackNetworkId = STACK_NETWORK_ID_COUNTER++; @@ -221,7 +189,6 @@ public ItemStack copy(boolean newStackNetworkId) { } @Override - public NbtMap saveExtraTag() { NbtMapBuilder nbtBuilder = NbtMap.builder(); if (durability != 0) { @@ -245,24 +212,14 @@ public NbtMap saveExtraTag() { } nbtBuilder.putList("ench", NbtType.COMPOUND, enchantmentNBT); } + //TODO: item lock type // Custom NBT content nbtBuilder.putAll(customNBTContent); - return nbtBuilder.isEmpty() ? null : nbtBuilder.build(); } - @Override - public NbtMap getCustomNBTContent() { - return customNBTContent; - } - - @Override - public void setCustomNBTContent(NbtMap customNBTContent) { - this.customNBTContent = customNBTContent; - } - @Override public boolean useItemOn( EntityPlayer player, @@ -294,12 +251,11 @@ protected void tryConsumeItem(EntityPlayer player) { } protected boolean hasEntityCollision(Dimension dimension, Vector3ic placePos, BlockState blockState) { - var block_aabb = blockState.getBehavior().getBlockAttributes(blockState) - .computeOffsetVoxelShape( - placePos.x(), - placePos.y(), - placePos.z() - ); + var block_aabb = blockState.getBehavior().getBlockAttributes(blockState).computeOffsetVoxelShape( + placePos.x(), + placePos.y(), + placePos.z() + ); return !dimension.getEntityPhysicsService().computeCollidingEntities(block_aabb).isEmpty(); } diff --git a/Allay-Server/src/main/java/org/allaymc/server/item/enchantment/AllayEnchantmentRegistry.java b/Allay-Server/src/main/java/org/allaymc/server/item/enchantment/AllayEnchantmentRegistry.java index c967a1287..9de3b16ff 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/item/enchantment/AllayEnchantmentRegistry.java +++ b/Allay-Server/src/main/java/org/allaymc/server/item/enchantment/AllayEnchantmentRegistry.java @@ -4,11 +4,11 @@ import lombok.extern.slf4j.Slf4j; import me.tongfei.progressbar.ConsoleProgressBarConsumer; import me.tongfei.progressbar.ProgressBar; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.i18n.I18n; import org.allaymc.api.item.enchantment.EnchantmentRegistry; import org.allaymc.api.item.enchantment.EnchantmentType; import org.allaymc.api.registry.SimpleDoubleKeyMappedRegistry; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.utils.ReflectionUtils; import java.util.concurrent.ConcurrentHashMap; diff --git a/Allay-Server/src/main/java/org/allaymc/server/item/recipe/AllayRecipeRegistry.java b/Allay-Server/src/main/java/org/allaymc/server/item/recipe/AllayRecipeRegistry.java index b4e6e84d0..c4b362b87 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/item/recipe/AllayRecipeRegistry.java +++ b/Allay-Server/src/main/java/org/allaymc/server/item/recipe/AllayRecipeRegistry.java @@ -6,7 +6,6 @@ import lombok.extern.slf4j.Slf4j; import me.tongfei.progressbar.ConsoleProgressBarConsumer; import me.tongfei.progressbar.ProgressBar; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.data.VanillaItemTags; import org.allaymc.api.item.ItemStack; import org.allaymc.api.item.descriptor.ComplexAliasDescriptor; @@ -21,6 +20,7 @@ import org.allaymc.api.item.recipe.ShapelessRecipe; import org.allaymc.api.item.registry.ItemTypeRegistry; import org.allaymc.api.utils.AllayNbtUtils; +import org.allaymc.api.utils.Identifier; import org.allaymc.server.item.type.AllayItemType; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.CraftingDataType; @@ -68,10 +68,12 @@ public void registerVanillaRecipes() { switch (CraftingDataType.byId(obj.get("type").getAsInt())) { case SHAPELESS -> registerShapeless(parseShapeless(obj)); case SHAPED -> registerShaped(parseShaped(obj)); - case FURNACE, FURNACE_DATA, MULTI, SHULKER_BOX, SHAPELESS_CHEMISTRY, SHAPED_CHEMISTRY, SMITHING_TRANSFORM, SMITHING_TRIM -> { + case FURNACE, FURNACE_DATA, MULTI, SHULKER_BOX, SHAPELESS_CHEMISTRY, SHAPED_CHEMISTRY, + SMITHING_TRANSFORM, SMITHING_TRIM -> { // TODO } - default -> throw new IllegalStateException("Unexpected value: " + CraftingDataType.byId(obj.get("type").getAsInt())); + default -> + throw new IllegalStateException("Unexpected value: " + CraftingDataType.byId(obj.get("type").getAsInt())); } // furnace recipes don't have both id and uuid @@ -146,7 +148,7 @@ private List parseOutputs(JsonObject obj) { } private ItemDescriptor parseItemDescriptor(JsonObject jsonObject) { - return switch(jsonObject.get("type").getAsString()) { + return switch (jsonObject.get("type").getAsString()) { case "default" -> { var itemId = new Identifier(jsonObject.get("itemId").getAsString()); var itemType = ItemTypeRegistry.getRegistry().get(itemId); diff --git a/Allay-Server/src/main/java/org/allaymc/server/item/registry/AllayCreativeItemRegistry.java b/Allay-Server/src/main/java/org/allaymc/server/item/registry/AllayCreativeItemRegistry.java index ae3728bba..67cf63e62 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/item/registry/AllayCreativeItemRegistry.java +++ b/Allay-Server/src/main/java/org/allaymc/server/item/registry/AllayCreativeItemRegistry.java @@ -2,7 +2,6 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.i18n.I18n; import org.allaymc.api.i18n.TrKeys; import org.allaymc.api.item.ItemStack; @@ -11,6 +10,7 @@ import org.allaymc.api.item.registry.ItemTypeRegistry; import org.allaymc.api.registry.RegistryLoader; import org.allaymc.api.registry.SimpleMappedRegistry; +import org.allaymc.api.utils.Identifier; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtUtils; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; diff --git a/Allay-Server/src/main/java/org/allaymc/server/item/registry/AllayItemTypeRegistry.java b/Allay-Server/src/main/java/org/allaymc/server/item/registry/AllayItemTypeRegistry.java index d276e2684..f35bee0ce 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/item/registry/AllayItemTypeRegistry.java +++ b/Allay-Server/src/main/java/org/allaymc/server/item/registry/AllayItemTypeRegistry.java @@ -1,15 +1,16 @@ package org.allaymc.server.item.registry; +import lombok.Getter; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import me.tongfei.progressbar.ConsoleProgressBarConsumer; import me.tongfei.progressbar.ProgressBar; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.i18n.I18n; import org.allaymc.api.i18n.TrKeys; import org.allaymc.api.item.registry.ItemTypeRegistry; import org.allaymc.api.item.type.ItemType; import org.allaymc.api.registry.SimpleMappedRegistry; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.utils.ReflectionUtils; import org.allaymc.server.item.type.ItemTypeDefaultInitializer; import org.allaymc.server.item.type.ItemTypeInitializer; @@ -29,10 +30,24 @@ */ @Slf4j public class AllayItemTypeRegistry extends SimpleMappedRegistry, Map>> implements ItemTypeRegistry { + @Getter + private final List itemDefinitions = new ArrayList<>(); + public AllayItemTypeRegistry() { super(null, input -> new ConcurrentHashMap<>()); } + private static void callInitializer(Method method, ProgressBar progressBar) { + try { + method.invoke(null); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } finally { + if (progressBar != null) + progressBar.step(); + } + } + @SneakyThrows public void init() { log.info(I18n.get().tr(TrKeys.A_ITEMTYPE_LOADING)); @@ -51,24 +66,6 @@ public void init() { log.info(I18n.get().tr(TrKeys.A_ITEMTYPE_LOADED, defaultInitializers.size())); } - private static void callInitializer(Method method, ProgressBar progressBar) { - try { - method.invoke(null); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } finally { - if (progressBar != null) - progressBar.step(); - } - } - - private final List itemDefinitions = new ArrayList<>(); - - @Override - public List getItemDefinitions() { - return itemDefinitions; - } - @Override public void rebuildDefinitionList() { itemDefinitions.clear(); diff --git a/Allay-Server/src/main/java/org/allaymc/server/pack/AllayPackRegistry.java b/Allay-Server/src/main/java/org/allaymc/server/pack/AllayPackRegistry.java index abe743cff..4487034f8 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/pack/AllayPackRegistry.java +++ b/Allay-Server/src/main/java/org/allaymc/server/pack/AllayPackRegistry.java @@ -21,7 +21,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; /** diff --git a/Allay-Server/src/main/java/org/allaymc/server/pack/PackEncryptor.java b/Allay-Server/src/main/java/org/allaymc/server/pack/PackEncryptor.java index efd3730c5..8ac3a3850 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/pack/PackEncryptor.java +++ b/Allay-Server/src/main/java/org/allaymc/server/pack/PackEncryptor.java @@ -27,7 +27,7 @@ * Allay Project 2024/2/7 * * @author daoge_cmd - * + *

* An util for encrypting pack */ @Slf4j @@ -37,9 +37,12 @@ public final class PackEncryptor { .serializeNulls() // NOTICE: Null should be serialized! .setLenient() .create(); + private static final int KEY_LENGTH = 32; + private static final byte[] VERSION = new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}; private static final byte[] MAGIC = new byte[]{(byte) 0xFC, (byte) 0xB9, (byte) 0xCF, (byte) 0x9B}; + private static final List EXCLUDED_FILES = List.of("manifest.json", "pack_icon.png", "bug_pack_icon.png"); public static String encrypt(Path inputPath, Path outputPath) { @@ -203,7 +206,9 @@ private static void createDirectoryRoot(ZipEntry zipEntry, ZipOutputStream outpu outputStream.closeEntry(); } - public record Content(List content) {} + public record Content(List content) { + } - public record ContentEntry(String path, String key) {} + public record ContentEntry(String path, String key) { + } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/pack/loader/ZipPackLoader.java b/Allay-Server/src/main/java/org/allaymc/server/pack/loader/ZipPackLoader.java index 2dc660a60..a79ff1428 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/pack/loader/ZipPackLoader.java +++ b/Allay-Server/src/main/java/org/allaymc/server/pack/loader/ZipPackLoader.java @@ -69,7 +69,6 @@ public void forEachIn(Path path, Consumer consumer, boolean recurse) { var entries = this.zipFile.entries(); while (entries.hasMoreElements()) { var entry = entries.nextElement(); - var entryPath = Path.of(entry.getName()); if (entryPath.getParent().equals(path)) consumer.accept(entryPath); if (entry.isDirectory()) this.forEachIn(entryPath, consumer, true); diff --git a/Allay-Server/src/main/java/org/allaymc/server/perm/tree/AllayPermNode.java b/Allay-Server/src/main/java/org/allaymc/server/perm/tree/AllayPermNode.java index 385980ac4..0472c79b9 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/perm/tree/AllayPermNode.java +++ b/Allay-Server/src/main/java/org/allaymc/server/perm/tree/AllayPermNode.java @@ -29,12 +29,8 @@ public String getFullName() { } protected String getFullName0(PermNode node, String str) { - if (node.isRoot()) { - return str; - } - if (!str.isEmpty()) { - str = "." + str; - } + if (node.isRoot()) return str; + if (!str.isEmpty()) str = "." + str; str = node.getName() + str; return getFullName0(node.getParent(), str); } diff --git a/Allay-Server/src/main/java/org/allaymc/server/perm/tree/AllayPermTree.java b/Allay-Server/src/main/java/org/allaymc/server/perm/tree/AllayPermTree.java index 227f0230a..da4c74798 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/perm/tree/AllayPermTree.java +++ b/Allay-Server/src/main/java/org/allaymc/server/perm/tree/AllayPermTree.java @@ -1,6 +1,8 @@ package org.allaymc.server.perm.tree; +import lombok.AccessLevel; import lombok.Getter; +import lombok.RequiredArgsConstructor; import org.allaymc.api.perm.tree.PermNode; import org.allaymc.api.perm.tree.PermTree; import org.allaymc.api.utils.AllayStringUtils; @@ -24,16 +26,13 @@ * @author daoge_cmd */ @Getter +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class AllayPermTree implements PermTree { + protected final String name; @Getter protected PermTree parent; protected PermNode root = new AllayRootPermNode("ROOT"); protected Map> listeners = new HashMap<>(); - protected final String name; - - protected AllayPermTree(String name) { - this.name = name; - } public static PermTree create(String name) { return new AllayPermTree(name); @@ -72,17 +71,13 @@ public void notifyAllPermListeners() { @Override public boolean hasPerm(String perm) { - if (parent != null && parent.hasPerm(perm)) { - return true; - } + if (parent != null && parent.hasPerm(perm)) return true; var spilt = new LinkedList<>(AllayStringUtils.fastSplit(perm, ".")); var node = root; while (!spilt.isEmpty()) { var nodeName = spilt.pop(); var hasMatch = false; - if (node.getLeaves().isEmpty()) { - return false; - } + if (node.getLeaves().isEmpty()) return false; for (var leaf : node.getLeaves()) { if (leaf.canMatch(nodeName)) { node = leaf; @@ -90,18 +85,14 @@ public boolean hasPerm(String perm) { break; } } - if (!hasMatch) { - return false; - } + if (!hasMatch) return false; } return true; } @Override public PermTree addPerm(String perm, boolean callListener) { - if (parent != null && parent.hasPerm(perm)) { - return this; - } + if (parent != null && parent.hasPerm(perm)) return this; var spilt = new LinkedList<>(AllayStringUtils.fastSplit(perm, ".")); var node = root; while (!spilt.isEmpty()) { @@ -150,9 +141,7 @@ public PermTree removePerm(String perm, boolean callListener) { } } } - if (!hasMatch) { - return this; - } + if (!hasMatch) return this; } return this; } diff --git a/Allay-Server/src/main/java/org/allaymc/server/plugin/AllayPluginManager.java b/Allay-Server/src/main/java/org/allaymc/server/plugin/AllayPluginManager.java index cf4e7e496..8f2cdaf0c 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/plugin/AllayPluginManager.java +++ b/Allay-Server/src/main/java/org/allaymc/server/plugin/AllayPluginManager.java @@ -5,12 +5,22 @@ import org.allaymc.api.datastruct.dag.HashDirectedAcyclicGraph; import org.allaymc.api.i18n.I18n; import org.allaymc.api.i18n.TrKeys; -import org.allaymc.api.plugin.*; +import org.allaymc.api.plugin.PluginContainer; +import org.allaymc.api.plugin.PluginDescriptor; +import org.allaymc.api.plugin.PluginLoader; +import org.allaymc.api.plugin.PluginManager; +import org.allaymc.api.plugin.PluginSource; import org.allaymc.server.plugin.jar.JarPluginLoader; import org.allaymc.server.plugin.js.JsPluginLoader; import java.nio.file.Path; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * Allay Project 2024/2/8 @@ -111,7 +121,7 @@ protected void checkCircularDependencies(Map try { dag.setBefore(name, descriptor.getName());//set ref } catch (DAGCycleException e) { - log.error("Circular dependencies appear in plugin {}: " + e.getMessage() + "The plugin will skip loading!", descriptor.getName()); + log.error("Circular dependencies appear in plugin {}: {} The plugin will skip loading!", descriptor.getName(), e.getMessage()); dag.remove(descriptor.getName()); } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/plugin/DefaultPluginSource.java b/Allay-Server/src/main/java/org/allaymc/server/plugin/DefaultPluginSource.java index b80800459..cceca589c 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/plugin/DefaultPluginSource.java +++ b/Allay-Server/src/main/java/org/allaymc/server/plugin/DefaultPluginSource.java @@ -17,6 +17,12 @@ public class DefaultPluginSource implements PluginSource { public static final Path DEFAULT_PLUGIN_FOLDER = Path.of("plugins"); + @SneakyThrows + public DefaultPluginSource() { + if (!Files.exists(DEFAULT_PLUGIN_FOLDER)) + Files.createDirectory(DEFAULT_PLUGIN_FOLDER); + } + @SneakyThrows public static Path getOrCreateDataFolder(String pluginName) { var dataFolder = DEFAULT_PLUGIN_FOLDER.resolve(pluginName); @@ -26,16 +32,10 @@ public static Path getOrCreateDataFolder(String pluginName) { return dataFolder; } - @SneakyThrows - public DefaultPluginSource() { - if (!Files.exists(DEFAULT_PLUGIN_FOLDER)) - Files.createDirectory(DEFAULT_PLUGIN_FOLDER); - } - @SneakyThrows @Override public Set find() { - try(var stream = Files.list(DEFAULT_PLUGIN_FOLDER)) { + try (var stream = Files.list(DEFAULT_PLUGIN_FOLDER)) { return stream.collect(Collectors.toSet()); } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/plugin/js/JsPlugin.java b/Allay-Server/src/main/java/org/allaymc/server/plugin/js/JsPlugin.java index e8b35ba3a..06af5c181 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/plugin/js/JsPlugin.java +++ b/Allay-Server/src/main/java/org/allaymc/server/plugin/js/JsPlugin.java @@ -44,7 +44,7 @@ public void onLoad() { .allowExperimentalOptions(true) .option("js.esm-eval-returns-exports", "true"); if (chromeDebugPort > 0) { - logger.info("Debug mode for js plugin " + pluginContainer.descriptor().getName() + " is enabled. Port: " + chromeDebugPort); + logger.info("Debug mode for js plugin {} is enabled. Port: {}", pluginContainer.descriptor().getName(), chromeDebugPort); // Debug mode is enabled cbd.option("inspect", String.valueOf(chromeDebugPort)) .option("inspect.Path", pluginContainer.descriptor().getName()) diff --git a/Allay-Server/src/main/java/org/allaymc/server/utils/ComponentClassCacheUtils.java b/Allay-Server/src/main/java/org/allaymc/server/utils/ComponentClassCacheUtils.java index 492fd395d..b7ecca18a 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/utils/ComponentClassCacheUtils.java +++ b/Allay-Server/src/main/java/org/allaymc/server/utils/ComponentClassCacheUtils.java @@ -101,13 +101,11 @@ public static void readCacheMapping() { public static Class getCacheClass(Class interfaceClass) { String s = CACHE_MAP.get(interfaceClass.getSimpleName()); + if (s == null) return null; try { - if (s == null) { - return null; - } return (Class) Allay.EXTRA_RESOURCE_CLASS_LOADER.loadClass(s); } catch (ClassNotFoundException ignore) { - CACHE_MAP.remove(s);//remove old cache entry + CACHE_MAP.remove(s); // remove old cache entry return null; } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/AllayDimension.java b/Allay-Server/src/main/java/org/allaymc/server/world/AllayDimension.java index cdc85fc7b..b1e766185 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/AllayDimension.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/AllayDimension.java @@ -86,6 +86,9 @@ public Set getPlayers() { @Override public String toString() { - return "world=" + this.world.getWorldData().getName() + " dimId=" + this.dimensionInfo.dimensionId(); + return "AllayDimension{" + + "world=" + world.getWorldData().getName() + + ", dimensionInfo=" + dimensionInfo.dimensionId() + + '}'; } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorld.java b/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorld.java index 4132cb6ce..2f4678523 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorld.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorld.java @@ -22,11 +22,7 @@ import org.cloudburstmc.protocol.bedrock.packet.SetTimePacket; import org.jetbrains.annotations.UnmodifiableView; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Queue; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -36,8 +32,9 @@ */ @Slf4j public class AllayWorld implements World { - protected record PacketQueueEntry(EntityPlayer player, BedrockPacket packet) { - } + public static final long TIME_SENDING_INTERVAL = 12 * 20; + + public static final int MAX_PACKETS_HANDLE_COUNT_AT_ONCE = Server.SETTINGS.networkSettings().maxSyncedPacketsHandleCountAtOnce(); protected final Queue packetQueue = PlatformDependent.newMpscQueue(); protected final AtomicBoolean networkLock = new AtomicBoolean(false); @@ -56,8 +53,6 @@ protected record PacketQueueEntry(EntityPlayer player, BedrockPacket packet) { protected final Thread thread; protected final Thread networkThread; protected long nextTimeSendTick; - public static final long TIME_SENDING_INTERVAL = 12 * 20; - public static final int MAX_PACKETS_HANDLE_COUNT_AT_ONCE = Server.SETTINGS.networkSettings().maxSyncedPacketsHandleCountAtOnce(); public AllayWorld(WorldStorage worldStorage) { this.worldStorage = worldStorage; @@ -66,25 +61,24 @@ public AllayWorld(WorldStorage worldStorage) { if (worldStorage instanceof NativeFileWorldStorage nativeFileWorldStorage) { this.worldData.setName(nativeFileWorldStorage.getWorldFolderPath().toFile().getName()); } - this.gameLoop = GameLoop.builder() - .onTick(gameLoop -> { - if (!Server.getInstance().isRunning()) { - gameLoop.stop(); - return; - } - while (!networkLock.compareAndSet(false, true)) { - // Spin - // We don't use Thread.yield() here, because we don't want to block the world main thread - } - try { - tick(gameLoop.getTick()); - } catch (Throwable throwable) { - log.error("Error while ticking level " + this.getWorldData().getName(), throwable); - } finally { - networkLock.set(false); - } - }) - .build(); + this.gameLoop = GameLoop.builder().onTick(gameLoop -> { + if (!Server.getInstance().isRunning()) { + gameLoop.stop(); + return; + } + //noinspection StatementWithEmptyBody + while (!networkLock.compareAndSet(false, true)) { + // Spin + // We don't use Thread.yield() here, because we don't want to block the world main thread + } + try { + tick(gameLoop.getTick()); + } catch (Throwable throwable) { + log.error("Error while ticking level {}", this.getWorldData().getName(), throwable); + } finally { + networkLock.set(false); + } + }).build(); this.thread = Thread.ofPlatform() .name("World Thread - " + this.getWorldData().getName()) .unstarted(gameLoop::startLoop); @@ -115,7 +109,7 @@ protected void networkTick() { // So we handle disconnect after we handled all other packets handlePlayersDisconnect(); } catch (Throwable throwable) { - log.error("Error while handling sync packet in world " + this.getWorldData().getName(), throwable); + log.error("Error while handling sync packet in world {}", this.getWorldData().getName(), throwable); } finally { networkLock.set(false); } @@ -246,4 +240,6 @@ public void close() { saveWorldData(); getWorldStorage().close(); } + + protected record PacketQueueEntry(EntityPlayer player, BedrockPacket packet) {} } diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorldPool.java b/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorldPool.java index 612d97415..ba5c413a4 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorldPool.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/AllayWorldPool.java @@ -3,6 +3,7 @@ import com.google.common.collect.Sets; import eu.okaeri.configs.ConfigManager; import eu.okaeri.configs.yaml.snakeyaml.YamlSnakeYamlConfigurer; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.eventbus.event.server.misc.WorldLoadEvent; import org.allaymc.api.i18n.I18n; @@ -33,19 +34,17 @@ public final class AllayWorldPool implements WorldPool { public static final Path WORLDS_FOLDER = Path.of("worlds"); public static final String SETTINGS_FILE_NAME = "world-settings.yml"; + private static final Set ALL_WORLDS_LISTENERS = Sets.newConcurrentHashSet(); + private final Map worlds = new ConcurrentHashMap<>(); + @Getter private WorldSettings worldConfig; public AllayWorldPool() { loadWorldConfig(); } - @Override - public WorldSettings getWorldConfig() { - return worldConfig; - } - @Override public void loadWorlds() { worldConfig.worlds().forEach(this::loadWorld); @@ -111,8 +110,8 @@ private void loadWorldConfig() { it.load(true); // load and save to update comments/new fields }); int changeNumber = 0; - for (var f : Objects.requireNonNull(WORLDS_FOLDER.toFile().listFiles(File::isDirectory))) { - if (!worldConfig.worlds().containsKey(f.getName())) { + for (var file : Objects.requireNonNull(WORLDS_FOLDER.toFile().listFiles(File::isDirectory))) { + if (!worldConfig.worlds().containsKey(file.getName())) { WorldSettings.WorldEntry worldEntry = WorldSettings.WorldEntry.builder() .enable(true) .overworld(new WorldSettings.WorldEntry.DimensionSettings("VOID", "")) @@ -120,7 +119,7 @@ private void loadWorldConfig() { .theEnd(null) .storageType("LEVELDB") .build(); - worldConfig.worlds().put(f.getName(), worldEntry); + worldConfig.worlds().put(file.getName(), worldEntry); changeNumber++; } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/biome/AllayBiomeTypeRegistry.java b/Allay-Server/src/main/java/org/allaymc/server/world/biome/AllayBiomeTypeRegistry.java index 1fe4d7332..21e88eee7 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/biome/AllayBiomeTypeRegistry.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/biome/AllayBiomeTypeRegistry.java @@ -10,8 +10,8 @@ import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtUtils; -import java.io.InputStream; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; /** @@ -30,8 +30,8 @@ public AllayBiomeTypeRegistry() { @SneakyThrows private void loadVanillaBiomeDefinition() { - try (InputStream stream = AllayBiomeTypeRegistry.class.getClassLoader().getResourceAsStream("biome_definitions.nbt")) { - assert stream != null; + try (var stream = AllayBiomeTypeRegistry.class.getClassLoader().getResourceAsStream("biome_definitions.nbt")) { + Objects.requireNonNull(stream); biomeDefinition = MutableNbtMap.from((NbtMap) NbtUtils.createGZIPReader(stream).readTag()); int i = 0; for (var biome : biomeDefinition.entrySet()) { diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/chunk/AllayChunk.java b/Allay-Server/src/main/java/org/allaymc/server/world/chunk/AllayChunk.java index cda3f5d7c..1dcc55ebd 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/chunk/AllayChunk.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/chunk/AllayChunk.java @@ -7,6 +7,7 @@ import io.netty.buffer.Unpooled; import io.netty.util.internal.PlatformDependent; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.block.type.BlockState; import org.allaymc.api.blockentity.BlockEntity; @@ -14,12 +15,7 @@ import org.allaymc.api.world.Dimension; import org.allaymc.api.world.DimensionInfo; import org.allaymc.api.world.biome.BiomeType; -import org.allaymc.api.world.chunk.Chunk; -import org.allaymc.api.world.chunk.ChunkLoader; -import org.allaymc.api.world.chunk.ChunkSection; -import org.allaymc.api.world.chunk.ChunkState; -import org.allaymc.api.world.chunk.UnsafeChunk; -import org.allaymc.api.world.chunk.UnsafeChunkOperate; +import org.allaymc.api.world.chunk.*; import org.cloudburstmc.nbt.NbtUtils; import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket; import org.cloudburstmc.protocol.bedrock.packet.LevelChunkPacket; @@ -28,12 +24,7 @@ import javax.annotation.concurrent.ThreadSafe; import java.io.IOException; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Objects; -import java.util.Queue; -import java.util.Set; +import java.util.*; import java.util.concurrent.locks.StampedLock; import java.util.function.Predicate; @@ -44,23 +35,15 @@ */ @ThreadSafe @Slf4j +@RequiredArgsConstructor public class AllayChunk implements Chunk { protected final AllayUnsafeChunk unsafeChunk; - protected final StampedLock blockLock; - protected final StampedLock heightAndBiomeLock; - protected final StampedLock lightLock; - protected final Set chunkLoaders; - protected final Queue chunkPacketQueue; - - public AllayChunk(AllayUnsafeChunk unsafeChunk) { - this.unsafeChunk = unsafeChunk; - this.blockLock = new StampedLock(); - this.heightAndBiomeLock = new StampedLock(); - this.lightLock = new StampedLock(); - this.chunkPacketQueue = PlatformDependent.newMpscQueue(); - // No need to use concurrent-safe set as addChunkLoader() & removeChunkLoader() are only used in AllayChunkService which is single-thread - this.chunkLoaders = new ObjectOpenHashSet<>(); - } + protected final StampedLock blockLock = new StampedLock(); + protected final StampedLock heightAndBiomeLock = new StampedLock(); + protected final StampedLock lightLock = new StampedLock(); + // No need to use concurrent-safe set as addChunkLoader() & removeChunkLoader() are only used in AllayChunkService which is single-thread + protected final Set chunkLoaders = new ObjectOpenHashSet<>(); + protected final Queue chunkPacketQueue = PlatformDependent.newMpscQueue(); private static void checkXZ(int x, int z) { Preconditions.checkArgument(x >= 0 && x <= 15); @@ -383,7 +366,7 @@ private void fillNullSections() { try { for (int i = getDimensionInfo().minSectionY(); i <= getDimensionInfo().maxSectionY(); i++) { if (unsafeChunk.getSection(i) == null) { - unsafeChunk.getSections()[i - getDimensionInfo().minSectionY()] = new ChunkSection((byte)i); + unsafeChunk.getSections()[i - getDimensionInfo().minSectionY()] = new ChunkSection((byte) i); } } } finally { @@ -397,7 +380,7 @@ private ByteBuf writeToNetwork() { writeToNetwork0(byteBuf); return byteBuf; } catch (Throwable t) { - log.error("Error while encoding chunk(x=" + getX() + ", z=" + getZ() + ")!", t); + log.error("Error while encoding chunk(x={}, z={})!", getX(), getZ(), t); byteBuf.release(); throw t; } @@ -423,7 +406,7 @@ private void writeToNetwork0(ByteBuf byteBuf) { writer.writeTag(blockEntity.saveNBT()); } } catch (IOException e) { - log.error("Error while encoding block entities in chunk(x=" + getX() + ", z=" + getZ() + ")!", e); + log.error("Error while encoding block entities in chunk(x={}, z={})!", getX(), getZ(), e); } } } diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/chunk/AllayUnsafeChunk.java b/Allay-Server/src/main/java/org/allaymc/server/world/chunk/AllayUnsafeChunk.java index 9fa043879..424600662 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/chunk/AllayUnsafeChunk.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/chunk/AllayUnsafeChunk.java @@ -27,11 +27,7 @@ import org.jetbrains.annotations.UnmodifiableView; import javax.annotation.concurrent.NotThreadSafe; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import static org.allaymc.api.block.type.BlockTypes.AIR_TYPE; @@ -40,14 +36,22 @@ @AllArgsConstructor(access = AccessLevel.PRIVATE) public class AllayUnsafeChunk implements UnsafeChunk { private static final AtomicReferenceFieldUpdater STATE_FIELD = AtomicReferenceFieldUpdater.newUpdater(AllayUnsafeChunk.class, ChunkState.class, "state"); - protected volatile ChunkState state; + + @Getter protected final int x; + @Getter protected final int z; + + @Getter protected final DimensionInfo dimensionInfo; protected final ChunkSection[] sections; protected final HeightMap heightMap; protected final Map entities; protected final Map blockEntities; + + @Getter + protected volatile ChunkState state; + protected List entityNbtList; protected List blockEntityNbtList; @@ -66,6 +70,11 @@ public static Builder builder() { return new Builder(); } + private static void checkXZ(int x, int z) { + Preconditions.checkArgument(x >= 0 && x <= 15); + Preconditions.checkArgument(z >= 0 && z <= 15); + } + @Override public void beforeSetChunk(Dimension dimension) { if (blockEntityNbtList != null && !blockEntityNbtList.isEmpty()) { @@ -92,26 +101,12 @@ public void afterSetChunk(Dimension dimension) { } } - @Override - public void setState(ChunkState next) { - ChunkState curr; - do { - curr = STATE_FIELD.get(this); - Preconditions.checkState(curr.ordinal() <= next.ordinal(), "invalid state transition: %s => %s", curr, next); - } while (!STATE_FIELD.compareAndSet(this, curr, next)); - } - private void checkXYZ(int x, int y, int z) { Preconditions.checkArgument(x >= 0 && x <= 15); Preconditions.checkArgument(y >= dimensionInfo.minHeight() && y <= dimensionInfo.maxHeight()); Preconditions.checkArgument(z >= 0 && z <= 15); } - private static void checkXZ(int x, int z) { - Preconditions.checkArgument(x >= 0 && x <= 15); - Preconditions.checkArgument(z >= 0 && z <= 15); - } - @Override @ApiStatus.Internal public ChunkSection[] getSections() { @@ -119,7 +114,6 @@ public ChunkSection[] getSections() { } @ApiStatus.Internal - public ChunkSection getSection(int sectionY) { Preconditions.checkArgument(sectionY >= -32 && sectionY <= 31); return sections[sectionY - this.getDimensionInfo().minSectionY()]; @@ -138,10 +132,6 @@ public ChunkSection getOrCreateSection(int sectionY) { return sections[offsetY]; } - //基岩版3d-data保存heightMap是以0为索引保存的,所以这里需要减去/加上世界最小值,详情查看 - //Bedrock Edition 3d-data saves the height map start from index of 0, so need to subtract/add the world minimum height here, see for details: - //https://github.com/bedrock-dev/bedrock-level/blob/main/src/include/data_3d.h#L115 - @UnmodifiableView @Override public Collection getSectionBlockEntities(int sectionY) { @@ -156,6 +146,11 @@ public Collection getSectionBlockEntities(int sectionY) { return Collections.unmodifiableCollection(sectionBlockEntities); } + /** + * Bedrock Edition 3d-data saves the height map start from index of 0, so need to subtract/add the world minimum height here + *

+ * More details + */ public int getHeight(int x, int z) { Preconditions.checkArgument(x >= 0 && x <= 15); Preconditions.checkArgument(z >= 0 && z <= 15); @@ -235,7 +230,6 @@ public void addEntity(Entity entity) { entities.put(entity.getRuntimeId(), entity); } - public Entity removeEntity(long runtimeId) { return entities.remove(runtimeId); } @@ -278,34 +272,27 @@ public Chunk toSafeChunk() { return new AllayChunk(this); } - public ChunkState getState() { - return state; - } - - public int getX() { - return x; - } - - public int getZ() { - return z; - } - - public DimensionInfo getDimensionInfo() { - return dimensionInfo; + @Override + public void setState(ChunkState next) { + ChunkState curr; + do { + curr = STATE_FIELD.get(this); + Preconditions.checkState(curr.ordinal() <= next.ordinal(), "invalid state transition: %s => %s", curr, next); + } while (!STATE_FIELD.compareAndSet(this, curr, next)); } @Getter public static class Builder { - ChunkState state; - int chunkZ; - int chunkX; - DimensionInfo dimensionInfo; - ChunkSection[] sections; - HeightMap heightMap; - Map entities; - Map blockEntities; - List entitiyList; - List blockEntitiyList; + private ChunkState state; + private int chunkZ; + private int chunkX; + private DimensionInfo dimensionInfo; + private ChunkSection[] sections; + private HeightMap heightMap; + private Map entities; + private Map blockEntities; + private List entitiyList; + private List blockEntitiyList; public Builder chunkX(int chunkX) { this.chunkX = chunkX; @@ -355,7 +342,6 @@ public AllayUnsafeChunk build() { if (entities == null) entities = new Long2ObjectNonBlockingMap<>(); if (blockEntities == null) blockEntities = new Int2ObjectNonBlockingMap<>(); return new AllayUnsafeChunk( - state, chunkX, chunkZ, dimensionInfo, @@ -363,6 +349,7 @@ public AllayUnsafeChunk build() { heightMap, entities, blockEntities, + state, entitiyList, blockEntitiyList ); diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/generator/FlatWorldGenerator.java b/Allay-Server/src/main/java/org/allaymc/server/world/generator/FlatWorldGenerator.java index f3d79536c..151710175 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/generator/FlatWorldGenerator.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/generator/FlatWorldGenerator.java @@ -2,17 +2,15 @@ import org.allaymc.api.block.registry.BlockTypeRegistry; import org.allaymc.api.block.type.BlockState; -import org.allaymc.api.utils.Identifier; import org.allaymc.api.utils.AllayStringUtils; +import org.allaymc.api.utils.Identifier; import org.allaymc.api.world.generator.ChunkGenerateContext; import org.allaymc.api.world.generator.WorldGenerator; import org.allaymc.api.world.generator.WorldGeneratorType; import java.util.ArrayList; -import static org.allaymc.api.block.type.BlockTypes.BEDROCK_TYPE; -import static org.allaymc.api.block.type.BlockTypes.DIRT_TYPE; -import static org.allaymc.api.block.type.BlockTypes.GRASS_BLOCK_TYPE; +import static org.allaymc.api.block.type.BlockTypes.*; /** * Allay Project 2023/7/8 @@ -31,14 +29,12 @@ public FlatWorldGenerator(String preset) { protected void parsePreset() { var list = new ArrayList(); if (preset.isBlank()) { - var bedrock = BEDROCK_TYPE.getDefaultState(); - var grass = GRASS_BLOCK_TYPE.getDefaultState(); + list.add(BEDROCK_TYPE.getDefaultState()); var dirt = DIRT_TYPE.getDefaultState(); - list.add(bedrock); list.add(dirt); list.add(dirt); list.add(dirt); - list.add(grass); + list.add(GRASS_BLOCK_TYPE.getDefaultState()); } else { for (var layer : AllayStringUtils.fastSplit(preset, ";")) { var entry = AllayStringUtils.fastTwoPartSplit(layer, "x", ""); diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/generator/JeGeneratorLoader.java b/Allay-Server/src/main/java/org/allaymc/server/world/generator/JeGeneratorLoader.java index ff563a739..de15da092 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/generator/JeGeneratorLoader.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/generator/JeGeneratorLoader.java @@ -16,17 +16,18 @@ import java.util.concurrent.atomic.AtomicBoolean; public final class JeGeneratorLoader { - private static final AtomicBoolean loaded = new AtomicBoolean(false); public static final String WORK_PATH = "jegenerator"; + + private static final AtomicBoolean loaded = new AtomicBoolean(false); + private static MethodHandle OVERWORLD; private static MethodHandle NETHER; private static MethodHandle THE_END; + @SuppressWarnings("ResultOfMethodCallIgnored") public static void setup() { File file = Path.of(WORK_PATH).toFile(); - if (!file.exists()) { - file.mkdirs(); - } + if (!file.exists()) file.mkdirs(); Paperclip.setup(Allay.EXTRA_RESOURCE_CLASS_LOADER, new String[]{WORK_PATH, "--noconsole", "--nogui", "--universe=jegenerator"}); try { final Class JeGeneratorMain = Class.forName("org.allaymc.jegenerator.JeGeneratorMain", true, Allay.EXTRA_RESOURCE_CLASS_LOADER); @@ -46,7 +47,10 @@ public static void setup() { } public static void waitStart() { - Utils.spinUntil(() -> !System.getProperties().getOrDefault("complete_start", false).equals("true"), Duration.of(20, ChronoUnit.MILLIS)); + Utils.spinUntil( + () -> !System.getProperties().getOrDefault("complete_start", false).equals("true"), + Duration.of(20, ChronoUnit.MILLIS) + ); } public static WorldGenerator getJeGenerator(DimensionInfo info) { diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayBlockUpdateService.java b/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayBlockUpdateService.java index c64143f7d..d60a043b8 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayBlockUpdateService.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayBlockUpdateService.java @@ -1,64 +1,60 @@ package org.allaymc.server.world.service; +import lombok.RequiredArgsConstructor; import org.allaymc.api.block.data.BlockFace; import org.allaymc.api.block.data.BlockStateWithPos; -import org.allaymc.api.block.type.BlockState; import org.allaymc.api.math.position.Position3i; import org.allaymc.api.world.Dimension; import org.allaymc.api.world.service.BlockUpdateService; import org.joml.Vector3ic; import java.time.Duration; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.Map; -import java.util.Queue; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; +@RequiredArgsConstructor public class AllayBlockUpdateService implements BlockUpdateService { public static final int MAX_NU_PER_TICK = 65535; - protected final Dimension dimension; - protected final Map scheduledUpdates; - protected final Queue neighborUpdates; - public AllayBlockUpdateService(Dimension dimension) { - this.dimension = dimension; - this.scheduledUpdates = new ConcurrentHashMap<>(); - this.neighborUpdates = new LinkedList<>(); - } + protected final Dimension dimension; + protected final Map scheduledUpdates = new ConcurrentHashMap<>(); + protected final Queue neighborUpdates = new LinkedList<>(); @Override public void tick(long tick) { - ArrayList positions = new ArrayList<>(scheduledUpdates.size() / 4); + List positions = new ArrayList<>(scheduledUpdates.size() / 4); for (var entry : scheduledUpdates.entrySet()) { if (entry.getValue() <= tick) { positions.add(entry.getKey()); scheduledUpdates.remove(entry.getKey()); } } - for (var p : positions) { - BlockState layer0 = dimension.getBlockState(p); - BlockState layer1 = dimension.getBlockState(p, 1); - BlockStateWithPos b0 = new BlockStateWithPos(layer0, new Position3i(p, dimension), 0); + for (var pos : positions) { + var layer0 = dimension.getBlockState(pos); + var b0 = new BlockStateWithPos(layer0, new Position3i(pos, dimension), 0); layer0.getBehavior().onScheduledUpdate(b0); + + var layer1 = dimension.getBlockState(pos, 1); if (layer1.getBlockAttributes().isLiquid()) { - BlockStateWithPos b1 = new BlockStateWithPos(layer1, new Position3i(p, dimension), 1); + var b1 = new BlockStateWithPos(layer1, new Position3i(pos, dimension), 1); layer1.getBehavior().onScheduledUpdate(b1); } } - int c = 0; - while (!neighborUpdates.isEmpty() && c < MAX_NU_PER_TICK) { - var u = neighborUpdates.poll(); - var pos = u.pos; - var neighborPos = u.neighborPos; - var blockFace = u.blockFace; - BlockState layer0 = dimension.getBlockState(pos); - BlockState layer1 = dimension.getBlockState(pos, 1); + int count = 0; + while (!neighborUpdates.isEmpty() && count < MAX_NU_PER_TICK) { + var neighborUpdate = neighborUpdates.poll(); + var pos = neighborUpdate.pos; + var neighborPos = neighborUpdate.neighborPos; + var blockFace = neighborUpdate.blockFace; + + var layer0 = dimension.getBlockState(pos); layer0.getBehavior().onNeighborUpdate(pos, neighborPos, blockFace, dimension); + + var layer1 = dimension.getBlockState(pos, 1); if (layer1.getBlockAttributes().isLiquid()) { layer1.getBehavior().onNeighborUpdate(pos, neighborPos, blockFace, dimension); } - c++; + count++; } } @@ -72,6 +68,5 @@ public void neighborBlockUpdate(Vector3ic pos, Vector3ic neighborPos, BlockFace neighborUpdates.add(new NeighborUpdate(pos, neighborPos, blockFace)); } - protected record NeighborUpdate(Vector3ic pos, Vector3ic neighborPos, BlockFace blockFace) { - } + protected record NeighborUpdate(Vector3ic pos, Vector3ic neighborPos, BlockFace blockFace) {} } diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayChunkService.java b/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayChunkService.java index aa2acd742..da23bcccf 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayChunkService.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayChunkService.java @@ -1,11 +1,7 @@ package org.allaymc.server.world.service; import com.google.common.collect.Sets; -import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue; -import it.unimi.dsi.fastutil.longs.LongComparator; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import it.unimi.dsi.fastutil.longs.*; import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.annotation.SlowOperation; @@ -24,13 +20,7 @@ import org.jetbrains.annotations.UnmodifiableView; import org.joml.Vector3i; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -100,7 +90,7 @@ private void removeUnusedChunks() { // Add unused chunk to the clear countdown map for (var entry : loadedChunks.entrySet()) { - Long chunkHash = entry.getKey(); + var chunkHash = entry.getKey(); var loadedChunk = entry.getValue(); if (loadedChunk.getChunkLoaderCount() == 0 && !keepLoadingChunks.contains(chunkHash) && !unusedChunkClearCountDown.containsKey(chunkHash)) { unusedChunkClearCountDown.put(chunkHash, Server.SETTINGS.worldSettings().removeUnneededChunkCycle()); @@ -151,13 +141,11 @@ public CompletableFuture getOrLoadChunk(int x, int z) { @Override public CompletableFuture> getOrLoadRangedChunk(int x, int z, int range) { - // The set used to store CompletableFutures Set> futureSet = new HashSet<>(); for (int dx = -range; dx <= range; dx++) { for (int dz = -range; dz <= range; dz++) { if (dx * dx + dz * dz <= range * range) { - // Get or load each chunk and add the returned CompletableFuture to the set futureSet.add(getOrLoadChunk(x + dx, z + dz)); } } @@ -196,11 +184,7 @@ public CompletableFuture loadChunk(int x, int z) { return prepareChunk; }) ); - if (presentValue == null) { - return future; - } else { - return presentValue; - } + return presentValue == null ? future : presentValue; } @Override @@ -282,9 +266,7 @@ public void unloadChunk(int x, int z) { public void unloadChunk(long chunkHash) { var chunk = getChunk(chunkHash); - if (chunk == null) { - return; - } + if (chunk == null) return; loadedChunks.remove(chunkHash); chunk.save(worldStorage); chunk.getEntities().forEach((runtimeId, entity) -> { @@ -325,10 +307,11 @@ private final class ChunkLoaderManager { public int compare(long chunkHash1, long chunkHash2) { Vector3i floor = MathUtils.floor(chunkLoader.getLocation()); var loaderChunkX = floor.x >> 4; - var loaderChunkZ = floor.z >> 4; var chunkDX1 = loaderChunkX - HashUtils.getXFromHashXZ(chunkHash1); - var chunkDZ1 = loaderChunkZ - HashUtils.getZFromHashXZ(chunkHash1); var chunkDX2 = loaderChunkX - HashUtils.getXFromHashXZ(chunkHash2); + + var loaderChunkZ = floor.z >> 4; + var chunkDZ1 = loaderChunkZ - HashUtils.getZFromHashXZ(chunkHash1); var chunkDZ2 = loaderChunkZ - HashUtils.getZFromHashXZ(chunkHash2); // Compare distance to loader return Integer.compare( @@ -359,7 +342,7 @@ public void onRemoved() { public void tick() { if (!chunkLoader.isLoaderActive()) return; long currentLoaderChunkPosHashed; - Vector3i floor = MathUtils.floor(chunkLoader.getLocation()); + var floor = MathUtils.floor(chunkLoader.getLocation()); if ((currentLoaderChunkPosHashed = HashUtils.hashXZ(floor.x >> 4, floor.z >> 4)) != lastLoaderChunkPosHashed) { lastLoaderChunkPosHashed = currentLoaderChunkPosHashed; updateInRadiusChunks(floor); @@ -386,7 +369,7 @@ private void updateInRadiusChunks(Vector3i currentPos) { } private void removeOutOfRadiusChunks() { - Sets.SetView difference = Sets.difference(sentChunks, inRadiusChunks); + var difference = Sets.difference(sentChunks, inRadiusChunks); // Unload chunks out of range chunkLoader.onChunkOutOfRange(difference); // The intersection of sentChunks and inRadiusChunks diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayEntityPhysicsService.java b/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayEntityPhysicsService.java index 69920209a..17f75330b 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayEntityPhysicsService.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayEntityPhysicsService.java @@ -22,17 +22,10 @@ import org.joml.primitives.AABBf; import org.joml.primitives.AABBfc; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; +import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; -import static java.lang.Math.abs; -import static java.lang.Math.floor; -import static java.lang.Math.max; -import static java.lang.Math.min; +import static java.lang.Math.*; import static org.allaymc.api.block.component.common.BlockAttributes.DEFAULT_FRICTION; import static org.allaymc.api.block.type.BlockTypes.AIR_TYPE; import static org.allaymc.api.utils.MathUtils.isInRange; diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayEntityService.java b/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayEntityService.java index 6469ddd18..5d5dbce00 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayEntityService.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/service/AllayEntityService.java @@ -1,6 +1,7 @@ package org.allaymc.server.world.service; import io.netty.util.internal.PlatformDependent; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.entity.Entity; import org.allaymc.api.eventbus.event.world.entity.EntityDespawnEvent; @@ -17,14 +18,11 @@ * @author Cool_Loong */ @Slf4j +@RequiredArgsConstructor public class AllayEntityService implements EntityService { protected final EntityPhysicsService entityPhysicsService; protected final Queue entityUpdateOperationQueue = PlatformDependent.newMpscQueue(); - public AllayEntityService(EntityPhysicsService entityPhysicsService) { - this.entityPhysicsService = entityPhysicsService; - } - @Override public void tick() { while (!entityUpdateOperationQueue.isEmpty()) { @@ -67,7 +65,7 @@ private void addEntityImmediately(Entity entity) { @Override public void addEntity(Entity entity, Runnable callback) { if (!entity.canBeSpawned()) { - log.warn("Trying to add an entity twice! Entity: " + entity); + log.warn("Trying to add an entity twice! Entity: {}", entity); return; } entity.setWillBeSpawnedNextTick(true); @@ -81,7 +79,7 @@ public void addEntity(Entity entity, Runnable callback) { @Override public void removeEntity(Entity entity, Runnable callback) { if (entity.willBeDespawnedNextTick()) { - log.warn("Trying to remove an entity twice! Entity: " + entity); + log.warn("Trying to remove an entity twice! Entity: {}", entity); return; } entity.setWillBeDespawnedNextTick(true); @@ -97,6 +95,5 @@ protected enum EntityUpdateType { REMOVE } - protected record EntityUpdateOperation(Entity entity, EntityUpdateType type, Runnable callback) { - } + protected record EntityUpdateOperation(Entity entity, EntityUpdateType type, Runnable callback) {} } diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/storage/AllayLevelDBWorldStorage.java b/Allay-Server/src/main/java/org/allaymc/server/world/storage/AllayLevelDBWorldStorage.java index 387a82a44..b6ac073b2 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/storage/AllayLevelDBWorldStorage.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/storage/AllayLevelDBWorldStorage.java @@ -1,6 +1,7 @@ package org.allaymc.server.world.storage; import io.netty.buffer.Unpooled; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.datastruct.SemVersion; import org.allaymc.api.server.Server; @@ -15,23 +16,15 @@ import org.allaymc.api.world.storage.NativeFileWorldStorage; import org.allaymc.server.utils.LevelDBKeyUtils; import org.allaymc.server.world.chunk.AllayUnsafeChunk; -import org.cloudburstmc.nbt.NBTInputStream; import org.cloudburstmc.nbt.NbtMap; -import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.nbt.NbtUtils; import org.cloudburstmc.protocol.bedrock.data.GameType; import org.iq80.leveldb.CompressionType; import org.iq80.leveldb.DB; import org.iq80.leveldb.Options; -import org.iq80.leveldb.WriteBatch; import org.joml.Vector3i; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -45,8 +38,11 @@ */ @Slf4j public class AllayLevelDBWorldStorage implements NativeFileWorldStorage { + private static final byte[] levelDatMagic = new byte[]{10, 0, 0, 0, 68, 11, 0, 0}; + private final Path path; private final DB db; + @Getter private WorldData worldDataCache; public AllayLevelDBWorldStorage(Path path) throws WorldStorageException { @@ -57,15 +53,16 @@ public AllayLevelDBWorldStorage(Path path) throws WorldStorageException { ); } + @SuppressWarnings("ResultOfMethodCallIgnored") public AllayLevelDBWorldStorage(Path path, Options options) throws WorldStorageException { - String worldName = path.getName(path.getNameCount() - 1).toString(); - File file = path.toFile(); + var worldName = path.getName(path.getNameCount() - 1).toString(); + var file = path.toFile(); if (!file.exists()) file.mkdirs(); this.path = path; worldDataCache = readWorldData(); if (worldDataCache == null) initWorldData(worldName); - File dbFolder = path.resolve("db").toFile(); + var dbFolder = path.resolve("db").toFile(); try { if (!dbFolder.exists()) dbFolder.mkdirs(); db = net.daporkchop.ldbjni.LevelDB.PROVIDER.open(dbFolder, options); @@ -75,7 +72,7 @@ public AllayLevelDBWorldStorage(Path path, Options options) throws WorldStorageE } private void initWorldData(String worldName) { - File levelDat = path.resolve("level.dat").toFile(); + var levelDat = path.resolve("level.dat").toFile(); try { // noinspection ResultOfMethodCallIgnored levelDat.createNewFile(); @@ -92,18 +89,18 @@ private void initWorldData(String worldName) { @Override public CompletableFuture readChunk(int x, int z, DimensionInfo dimensionInfo) throws WorldStorageException { return CompletableFuture.supplyAsync(() -> { - AllayUnsafeChunk.Builder builder = AllayUnsafeChunk.builder() + var builder = AllayUnsafeChunk.builder() .chunkX(x) .chunkZ(z) .dimensionInfo(dimensionInfo); - byte[] versionValue = this.db.get(LevelDBKeyUtils.VERSION.getKey(x, z, dimensionInfo)); + var versionValue = this.db.get(LevelDBKeyUtils.VERSION.getKey(x, z, dimensionInfo)); if (versionValue == null) { versionValue = this.db.get(LevelDBKeyUtils.LEGACY_VERSION.getKey(x, z, dimensionInfo)); } if (versionValue == null) { return builder.build().toSafeChunk(); } - byte[] finalized = this.db.get(LevelDBKeyUtils.CHUNK_FINALIZED_STATE.getKey(x, z, dimensionInfo)); + var finalized = this.db.get(LevelDBKeyUtils.CHUNK_FINALIZED_STATE.getKey(x, z, dimensionInfo)); if (finalized == null) { builder.state(ChunkState.FINISHED); } else { @@ -117,7 +114,7 @@ public CompletableFuture readChunk(int x, int z, DimensionInfo dimensionI @Override public CompletableFuture writeChunk(Chunk chunk) throws WorldStorageException { return CompletableFuture.runAsync(() -> { - try (WriteBatch writeBatch = this.db.createWriteBatch()) { + try (var writeBatch = this.db.createWriteBatch()) { chunk.batchProcess(c -> LevelDBChunkSerializer.INSTANCE.serialize(writeBatch, c)); this.db.write(writeBatch); } catch (IOException e) { @@ -126,12 +123,10 @@ public CompletableFuture writeChunk(Chunk chunk) throws WorldStorageExcept }, Server.getInstance().getVirtualThreadPool()); } - private static final byte[] levelDatMagic = new byte[]{10, 0, 0, 0, 68, 11, 0, 0}; - @Override public boolean containChunk(int x, int z, DimensionInfo dimensionInfo) { for (int ySection = dimensionInfo.minSectionY(); ySection <= dimensionInfo.maxSectionY(); ySection++) { - byte[] bytes = db.get(LevelDBKeyUtils.CHUNK_SECTION_PREFIX.getKey(x, z, ySection, dimensionInfo)); + var bytes = db.get(LevelDBKeyUtils.CHUNK_SECTION_PREFIX.getKey(x, z, ySection, dimensionInfo)); if (bytes != null) { return true; } @@ -142,7 +137,7 @@ public boolean containChunk(int x, int z, DimensionInfo dimensionInfo) { @Override public synchronized void writeWorldData(WorldData worldData) { - File levelDat = path.resolve("level.dat").toFile(); + var levelDat = path.resolve("level.dat").toFile(); try (var output = new FileOutputStream(levelDat)) { if (levelDat.exists()) { Files.copy(path.resolve("level.dat"), path.resolve("level.dat_old"), StandardCopyOption.REPLACE_EXISTING); @@ -158,76 +153,76 @@ public synchronized void writeWorldData(WorldData worldData) { @Override public synchronized WorldData readWorldData() throws WorldStorageException { - File levelDat = path.resolve("level.dat").toFile(); + var levelDat = path.resolve("level.dat").toFile(); if (!levelDat.exists()) return null; try (var input = new FileInputStream(levelDat)) { //The first 8 bytes are magic number input.skip(8); - NBTInputStream readerLE = NbtUtils.createReaderLE(new ByteArrayInputStream(input.readAllBytes())); - NbtMap d = (NbtMap) readerLE.readTag(); + var readerLE = NbtUtils.createReaderLE(new ByteArrayInputStream(input.readAllBytes())); + var tag = (NbtMap) readerLE.readTag(); readerLE.close(); - NbtMap abilities = d.getCompound("abilities"); - NbtMap experiments = d.getCompound("experiments"); - GameRules gameRules = new GameRules(); - gameRules.put(GameRule.COMMAND_BLOCK_OUTPUT, d.getBoolean("commandblockoutput")); - gameRules.put(GameRule.COMMAND_BLOCKS_ENABLED, d.getBoolean("commandblocksenabled")); - gameRules.put(GameRule.DO_DAYLIGHT_CYCLE, d.getBoolean("dodaylightcycle")); - gameRules.put(GameRule.DO_ENTITY_DROPS, d.getBoolean("doentitydrops")); - gameRules.put(GameRule.DO_FIRE_TICK, d.getBoolean("dofiretick")); - gameRules.put(GameRule.DO_IMMEDIATE_RESPAWN, d.getBoolean("doimmediaterespawn")); - gameRules.put(GameRule.DO_INSOMNIA, d.getBoolean("doinsomnia")); - gameRules.put(GameRule.DO_LIMITED_CRAFTING, d.getBoolean("dolimitedcrafting")); - gameRules.put(GameRule.DO_MOB_LOOT, d.getBoolean("domobloot")); - gameRules.put(GameRule.DO_MOB_SPAWNING, d.getBoolean("domobspawning")); - gameRules.put(GameRule.DO_TILE_DROPS, d.getBoolean("dotiledrops")); - gameRules.put(GameRule.DO_WEATHER_CYCLE, d.getBoolean("doweathercycle")); - gameRules.put(GameRule.DROWNING_DAMAGE, d.getBoolean("drowningdamage")); - gameRules.put(GameRule.FALL_DAMAGE, d.getBoolean("falldamage")); - gameRules.put(GameRule.FIRE_DAMAGE, d.getBoolean("firedamage")); - gameRules.put(GameRule.FREEZE_DAMAGE, d.getBoolean("freezedamage")); - gameRules.put(GameRule.FUNCTION_COMMAND_LIMIT, d.getInt("functioncommandlimit")); - gameRules.put(GameRule.KEEP_INVENTORY, d.getBoolean("keepinventory")); - gameRules.put(GameRule.MAX_COMMAND_CHAIN_LENGTH, d.getInt("maxcommandchainlength")); - gameRules.put(GameRule.MOB_GRIEFING, d.getBoolean("mobgriefing")); - gameRules.put(GameRule.NATURAL_REGENERATION, d.getBoolean("naturalregeneration")); - gameRules.put(GameRule.PVP, d.getBoolean("pvp")); - gameRules.put(GameRule.RESPAWN_BLOCKS_EXPLODE, d.getBoolean("respawnblocksexplode")); - gameRules.put(GameRule.SEND_COMMAND_FEEDBACK, d.getBoolean("sendcommandfeedback")); - gameRules.put(GameRule.SHOW_BORDER_EFFECT, d.getBoolean("showbordereffect")); - gameRules.put(GameRule.SHOW_COORDINATES, d.getBoolean("showcoordinates")); - gameRules.put(GameRule.SHOW_DEATH_MESSAGES, d.getBoolean("showdeathmessages")); - gameRules.put(GameRule.SHOW_TAGS, d.getBoolean("showtags")); - gameRules.put(GameRule.SPAWN_RADIUS, d.getInt("spawnradius")); - gameRules.put(GameRule.TNT_EXPLODES, d.getBoolean("tntexplodes")); + var abilities = tag.getCompound("abilities"); + var experiments = tag.getCompound("experiments"); + var gameRules = new GameRules(); + gameRules.put(GameRule.COMMAND_BLOCK_OUTPUT, tag.getBoolean("commandblockoutput")); + gameRules.put(GameRule.COMMAND_BLOCKS_ENABLED, tag.getBoolean("commandblocksenabled")); + gameRules.put(GameRule.DO_DAYLIGHT_CYCLE, tag.getBoolean("dodaylightcycle")); + gameRules.put(GameRule.DO_ENTITY_DROPS, tag.getBoolean("doentitydrops")); + gameRules.put(GameRule.DO_FIRE_TICK, tag.getBoolean("dofiretick")); + gameRules.put(GameRule.DO_IMMEDIATE_RESPAWN, tag.getBoolean("doimmediaterespawn")); + gameRules.put(GameRule.DO_INSOMNIA, tag.getBoolean("doinsomnia")); + gameRules.put(GameRule.DO_LIMITED_CRAFTING, tag.getBoolean("dolimitedcrafting")); + gameRules.put(GameRule.DO_MOB_LOOT, tag.getBoolean("domobloot")); + gameRules.put(GameRule.DO_MOB_SPAWNING, tag.getBoolean("domobspawning")); + gameRules.put(GameRule.DO_TILE_DROPS, tag.getBoolean("dotiledrops")); + gameRules.put(GameRule.DO_WEATHER_CYCLE, tag.getBoolean("doweathercycle")); + gameRules.put(GameRule.DROWNING_DAMAGE, tag.getBoolean("drowningdamage")); + gameRules.put(GameRule.FALL_DAMAGE, tag.getBoolean("falldamage")); + gameRules.put(GameRule.FIRE_DAMAGE, tag.getBoolean("firedamage")); + gameRules.put(GameRule.FREEZE_DAMAGE, tag.getBoolean("freezedamage")); + gameRules.put(GameRule.FUNCTION_COMMAND_LIMIT, tag.getInt("functioncommandlimit")); + gameRules.put(GameRule.KEEP_INVENTORY, tag.getBoolean("keepinventory")); + gameRules.put(GameRule.MAX_COMMAND_CHAIN_LENGTH, tag.getInt("maxcommandchainlength")); + gameRules.put(GameRule.MOB_GRIEFING, tag.getBoolean("mobgriefing")); + gameRules.put(GameRule.NATURAL_REGENERATION, tag.getBoolean("naturalregeneration")); + gameRules.put(GameRule.PVP, tag.getBoolean("pvp")); + gameRules.put(GameRule.RESPAWN_BLOCKS_EXPLODE, tag.getBoolean("respawnblocksexplode")); + gameRules.put(GameRule.SEND_COMMAND_FEEDBACK, tag.getBoolean("sendcommandfeedback")); + gameRules.put(GameRule.SHOW_BORDER_EFFECT, tag.getBoolean("showbordereffect")); + gameRules.put(GameRule.SHOW_COORDINATES, tag.getBoolean("showcoordinates")); + gameRules.put(GameRule.SHOW_DEATH_MESSAGES, tag.getBoolean("showdeathmessages")); + gameRules.put(GameRule.SHOW_TAGS, tag.getBoolean("showtags")); + gameRules.put(GameRule.SPAWN_RADIUS, tag.getInt("spawnradius")); + gameRules.put(GameRule.TNT_EXPLODES, tag.getBoolean("tntexplodes")); return WorldData.builder() - .biomeOverride(d.getString("BiomeOverride")) - .centerMapsToOrigin(d.getBoolean("CenterMapsToOrigin")) - .confirmedPlatformLockedContent(d.getBoolean("ConfirmedPlatformLockedContent")) - .difficulty(Difficulty.from(d.getInt("Difficulty"))) - .flatWorldLayers(d.getString("FlatWorldLayers")) - .forceGameType(d.getBoolean("ForceGameType")) - .gameType(GameType.from(d.getInt("GameType"))) - .generator(d.getInt("Generator")) - .inventoryVersion(d.getString("InventoryVersion")) - .LANBroadcast(d.getBoolean("LANBroadcast")) - .LANBroadcastIntent(d.getBoolean("LANBroadcastIntent")) - .lastPlayed(d.getLong("LastPlayed")) - .name(d.getString("LevelName")) - .limitedWorldOriginPoint(new Vector3i(d.getInt("LimitedWorldOriginX"), d.getInt("LimitedWorldOriginY"), d.getInt("LimitedWorldOriginZ"))) - .minimumCompatibleClientVersion(SemVersion.from(d.getIntArray("MinimumCompatibleClientVersion"))) - .multiplayerGame(d.getBoolean("MultiplayerGame")) - .multiplayerGameIntent(d.getBoolean("MultiplayerGameIntent")) - .netherScale(d.getInt("NetherScale")) - .networkVersion(d.getInt("NetworkVersion")) - .platform(d.getInt("Platform")) - .platformBroadcastIntent(d.getInt("PlatformBroadcastIntent")) - .randomSeed(d.getLong("RandomSeed")) - .spawnV1Villagers(d.getBoolean("SpawnV1Villagers")) - .spawnPoint(new Vector3i(d.getInt("SpawnX"), d.getInt("SpawnY"), d.getInt("SpawnZ"))) - .storageVersion(d.getInt("StorageVersion")) - .time(d.getLong("Time")) - .worldVersion(d.getInt("WorldVersion")) - .XBLBroadcastIntent(d.getInt("XBLBroadcastIntent")) + .biomeOverride(tag.getString("BiomeOverride")) + .centerMapsToOrigin(tag.getBoolean("CenterMapsToOrigin")) + .confirmedPlatformLockedContent(tag.getBoolean("ConfirmedPlatformLockedContent")) + .difficulty(Difficulty.from(tag.getInt("Difficulty"))) + .flatWorldLayers(tag.getString("FlatWorldLayers")) + .forceGameType(tag.getBoolean("ForceGameType")) + .gameType(GameType.from(tag.getInt("GameType"))) + .generator(tag.getInt("Generator")) + .inventoryVersion(tag.getString("InventoryVersion")) + .LANBroadcast(tag.getBoolean("LANBroadcast")) + .LANBroadcastIntent(tag.getBoolean("LANBroadcastIntent")) + .lastPlayed(tag.getLong("LastPlayed")) + .name(tag.getString("LevelName")) + .limitedWorldOriginPoint(new Vector3i(tag.getInt("LimitedWorldOriginX"), tag.getInt("LimitedWorldOriginY"), tag.getInt("LimitedWorldOriginZ"))) + .minimumCompatibleClientVersion(SemVersion.from(tag.getIntArray("MinimumCompatibleClientVersion"))) + .multiplayerGame(tag.getBoolean("MultiplayerGame")) + .multiplayerGameIntent(tag.getBoolean("MultiplayerGameIntent")) + .netherScale(tag.getInt("NetherScale")) + .networkVersion(tag.getInt("NetworkVersion")) + .platform(tag.getInt("Platform")) + .platformBroadcastIntent(tag.getInt("PlatformBroadcastIntent")) + .randomSeed(tag.getLong("RandomSeed")) + .spawnV1Villagers(tag.getBoolean("SpawnV1Villagers")) + .spawnPoint(new Vector3i(tag.getInt("SpawnX"), tag.getInt("SpawnY"), tag.getInt("SpawnZ"))) + .storageVersion(tag.getInt("StorageVersion")) + .time(tag.getLong("Time")) + .worldVersion(tag.getInt("WorldVersion")) + .XBLBroadcastIntent(tag.getInt("XBLBroadcastIntent")) .abilities(WorldData.Abilities.builder() .attackMobs(abilities.getBoolean("attackmobs")) .attackPlayers(abilities.getBoolean("attackplayers")) @@ -245,17 +240,17 @@ public synchronized WorldData readWorldData() throws WorldStorageException { .teleport(abilities.getBoolean("teleport")) .walkSpeed(abilities.getFloat("walkSpeed")) .build()) - .baseGameVersion(d.getString("baseGameVersion")) - .bonusChestEnabled(d.getBoolean("bonusChestEnabled")) - .bonusChestSpawned(d.getBoolean("bonusChestSpawned")) - .cheatsEnabled(d.getBoolean("cheatsEnabled")) - .commandsEnabled(d.getBoolean("commandsEnabled")) + .baseGameVersion(tag.getString("baseGameVersion")) + .bonusChestEnabled(tag.getBoolean("bonusChestEnabled")) + .bonusChestSpawned(tag.getBoolean("bonusChestSpawned")) + .cheatsEnabled(tag.getBoolean("cheatsEnabled")) + .commandsEnabled(tag.getBoolean("commandsEnabled")) .gameRules(gameRules) - .currentTick(d.getLong("currentTick")) - .daylightCycle(d.getInt("daylightCycle")) - .editorWorldType(d.getInt("editorWorldType")) - .eduOffer(d.getInt("eduOffer")) - .educationFeaturesEnabled(d.getBoolean("educationFeaturesEnabled")) + .currentTick(tag.getLong("currentTick")) + .daylightCycle(tag.getInt("daylightCycle")) + .editorWorldType(tag.getInt("editorWorldType")) + .eduOffer(tag.getInt("eduOffer")) + .educationFeaturesEnabled(tag.getBoolean("educationFeaturesEnabled")) .experiments(WorldData.Experiments.builder() .cameras(experiments.getBoolean("cameras")) .dataDrivenBiomes(experiments.getBoolean("data_driven_biomes")) @@ -266,37 +261,37 @@ public synchronized WorldData readWorldData() throws WorldStorageException { .upcomingCreatorFeatures(experiments.getBoolean("upcoming_creator_features")) .villagerTradesRebalance(experiments.getBoolean("villager_trades_rebalance")) .build()) - .hasBeenLoadedInCreative(d.getBoolean("hasBeenLoadedInCreative")) - .hasLockedBehaviorPack(d.getBoolean("hasLockedBehaviorPack")) - .hasLockedResourcePack(d.getBoolean("hasLockedResourcePack")) - .immutableWorld(d.getBoolean("immutableWorld")) - .isCreatedInEditor(d.getBoolean("isCreatedInEditor")) - .isExportedFromEditor(d.getBoolean("isExportedFromEditor")) - .isFromLockedTemplate(d.getBoolean("isFromLockedTemplate")) - .isFromWorldTemplate(d.getBoolean("isFromWorldTemplate")) - .isRandomSeedAllowed(d.getBoolean("isRandomSeedAllowed")) - .isSingleUseWorld(d.getBoolean("isSingleUseWorld")) - .isWorldTemplateOptionLocked(d.getBoolean("isWorldTemplateOptionLocked")) - .lastOpenedWithVersion(SemVersion.from(d.getIntArray("lastOpenedWithVersion"))) - .lightningLevel(d.getFloat("lightningLevel")) - .lightningTime(d.getInt("lightningTime")) - .limitedWorldDepth(d.getInt("limitedWorldDepth")) - .limitedWorldWidth(d.getInt("limitedWorldWidth")) - .permissionsLevel(d.getInt("permissionsLevel")) - .playerPermissionsLevel(d.getInt("playerPermissionsLevel")) - .playersSleepingPercentage(d.getInt("playerssleepingpercentage")) - .prid(d.getString("prid")) - .rainLevel(d.getFloat("rainLevel")) - .rainTime(d.getInt("rainTime")) - .randomTickSpeed(d.getInt("randomtickspeed")) - .recipesUnlock(d.getBoolean("recipesunlock")) - .requiresCopiedPackRemovalCheck(d.getBoolean("requiresCopiedPackRemovalCheck")) - .serverChunkTickRange(d.getInt("serverChunkTickRange")) - .spawnMobs(d.getBoolean("spawnMobs")) - .startWithMapEnabled(d.getBoolean("startWithMapEnabled")) - .texturePacksRequired(d.getBoolean("texturePacksRequired")) - .useMsaGamertagsOnly(d.getBoolean("useMsaGamertagsOnly")) - .worldStartCount(d.getLong("worldStartCount")) + .hasBeenLoadedInCreative(tag.getBoolean("hasBeenLoadedInCreative")) + .hasLockedBehaviorPack(tag.getBoolean("hasLockedBehaviorPack")) + .hasLockedResourcePack(tag.getBoolean("hasLockedResourcePack")) + .immutableWorld(tag.getBoolean("immutableWorld")) + .isCreatedInEditor(tag.getBoolean("isCreatedInEditor")) + .isExportedFromEditor(tag.getBoolean("isExportedFromEditor")) + .isFromLockedTemplate(tag.getBoolean("isFromLockedTemplate")) + .isFromWorldTemplate(tag.getBoolean("isFromWorldTemplate")) + .isRandomSeedAllowed(tag.getBoolean("isRandomSeedAllowed")) + .isSingleUseWorld(tag.getBoolean("isSingleUseWorld")) + .isWorldTemplateOptionLocked(tag.getBoolean("isWorldTemplateOptionLocked")) + .lastOpenedWithVersion(SemVersion.from(tag.getIntArray("lastOpenedWithVersion"))) + .lightningLevel(tag.getFloat("lightningLevel")) + .lightningTime(tag.getInt("lightningTime")) + .limitedWorldDepth(tag.getInt("limitedWorldDepth")) + .limitedWorldWidth(tag.getInt("limitedWorldWidth")) + .permissionsLevel(tag.getInt("permissionsLevel")) + .playerPermissionsLevel(tag.getInt("playerPermissionsLevel")) + .playersSleepingPercentage(tag.getInt("playerssleepingpercentage")) + .prid(tag.getString("prid")) + .rainLevel(tag.getFloat("rainLevel")) + .rainTime(tag.getInt("rainTime")) + .randomTickSpeed(tag.getInt("randomtickspeed")) + .recipesUnlock(tag.getBoolean("recipesunlock")) + .requiresCopiedPackRemovalCheck(tag.getBoolean("requiresCopiedPackRemovalCheck")) + .serverChunkTickRange(tag.getInt("serverChunkTickRange")) + .spawnMobs(tag.getBoolean("spawnMobs")) + .startWithMapEnabled(tag.getBoolean("startWithMapEnabled")) + .texturePacksRequired(tag.getBoolean("texturePacksRequired")) + .useMsaGamertagsOnly(tag.getBoolean("useMsaGamertagsOnly")) + .worldStartCount(tag.getLong("worldStartCount")) .worldPolicies(WorldData.WorldPolicies.builder().build()) .build(); } catch (FileNotFoundException e) { @@ -308,11 +303,6 @@ public synchronized WorldData readWorldData() throws WorldStorageException { throw new RuntimeException("level.dat is null!"); } - @Override - public WorldData getWorldDataCache() { - return worldDataCache; - } - public void close() { try { this.db.close(); @@ -323,8 +313,7 @@ public void close() { } private NbtMap createWorldDataNBT(WorldData worldData) { - NbtMapBuilder builder = NbtMap.builder(); - + var builder = NbtMap.builder(); builder.putString("BiomeOverride", worldData.getBiomeOverride()); builder.putBoolean("CenterMapsToOrigin", worldData.isCenterMapsToOrigin()); builder.putBoolean("ConfirmedPlatformLockedContent", worldData.isConfirmedPlatformLockedContent()); @@ -357,7 +346,7 @@ private NbtMap createWorldDataNBT(WorldData worldData) { builder.putLong("Time", worldData.getTime()); builder.putInt("WorldVersion", worldData.getWorldVersion()); builder.putInt("XBLBroadcastIntent", worldData.getXBLBroadcastIntent()); - NbtMap abilities = NbtMap.builder() + var abilities = NbtMap.builder() .putBoolean("attackmobs", worldData.getAbilities().isAttackMobs()) .putBoolean("attackplayers", worldData.getAbilities().isAttackPlayers()) .putBoolean("build", worldData.getAbilities().isBuild()) @@ -374,7 +363,9 @@ private NbtMap createWorldDataNBT(WorldData worldData) { .putFloat("flySpeed", worldData.getAbilities().getFlySpeed()) .putFloat("walkSpeed", worldData.getAbilities().getWalkSpeed()) .build(); - NbtMap experiments = NbtMap.builder() + builder.put("abilities", abilities); + + var experiments = NbtMap.builder() .putBoolean("cameras", worldData.getExperiments().isCameras()) .putBoolean("data_driven_biomes", worldData.getExperiments().isDataDrivenBiomes()) .putBoolean("data_driven_items", worldData.getExperiments().isDataDrivenItems()) @@ -385,7 +376,6 @@ private NbtMap createWorldDataNBT(WorldData worldData) { .putBoolean("upcoming_creator_features", worldData.getExperiments().isUpcomingCreatorFeatures()) .putBoolean("villager_trades_rebalance", worldData.getExperiments().isVillagerTradesRebalance()) .build(); - builder.put("abilities", abilities); builder.put("experiments", experiments); builder.putBoolean("bonusChestEnabled", worldData.isBonusChestEnabled()); diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/storage/AllayNonPersistentWorldStorage.java b/Allay-Server/src/main/java/org/allaymc/server/world/storage/AllayNonPersistentWorldStorage.java index 1277c6a04..2818c2060 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/storage/AllayNonPersistentWorldStorage.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/storage/AllayNonPersistentWorldStorage.java @@ -27,7 +27,7 @@ * Allay Project 2023/7/1 * * @author daoge_cmd - * + *

* TODO: optimize it for better memory footprint */ @NotThreadSafe @@ -43,23 +43,23 @@ public AllayNonPersistentWorldStorage() { @Override public CompletableFuture readChunk(int x, int z, DimensionInfo dimensionInfo) { - Dimension dimension = Server.getInstance().getWorldPool().getWorld(worldData.getName()).getDimension(dimensionInfo.dimensionId()); - long l = HashUtils.hashXZ(x, z); - var chunk = chunks.get(l); + var dimension = Server.getInstance().getWorldPool().getWorld(worldData.getName()).getDimension(dimensionInfo.dimensionId()); + var hash = HashUtils.hashXZ(x, z); + var chunk = chunks.get(hash); if (chunk == null) { chunk = AllayUnsafeChunk.builder().emptyChunk(x, z, dimensionInfo).toSafeChunk(); } - readEntities(l).stream().map(nbt -> EntityHelper.fromNBT(dimension, nbt)).forEach(e -> dimension.getEntityService().addEntity(e)); - readBlockEntities(l).stream().map(nbt -> BlockEntityHelper.fromNBT(dimension, nbt)).forEach(chunk::addBlockEntity); + readEntities(hash).stream().map(nbt -> EntityHelper.fromNBT(dimension, nbt)).forEach(e -> dimension.getEntityService().addEntity(e)); + readBlockEntities(hash).stream().map(nbt -> BlockEntityHelper.fromNBT(dimension, nbt)).forEach(chunk::addBlockEntity); return CompletableFuture.completedFuture(chunk); } @Override public CompletableFuture writeChunk(Chunk chunk) { - long l = HashUtils.hashXZ(chunk.getX(), chunk.getZ()); - chunks.put(l, chunk); - writeEntities(l, chunk.getEntities().values()); - writeBlockEntities(l, chunk.getBlockEntities().values()); + var hashXZ = HashUtils.hashXZ(chunk.getX(), chunk.getZ()); + chunks.put(hashXZ, chunk); + writeEntities(hashXZ, chunk.getEntities().values()); + writeBlockEntities(hashXZ, chunk.getBlockEntities().values()); return CompletableFuture.completedFuture(null); } diff --git a/Allay-Server/src/main/java/org/allaymc/server/world/storage/LevelDBChunkSerializer.java b/Allay-Server/src/main/java/org/allaymc/server/world/storage/LevelDBChunkSerializer.java index 6f0eed988..751715a26 100644 --- a/Allay-Server/src/main/java/org/allaymc/server/world/storage/LevelDBChunkSerializer.java +++ b/Allay-Server/src/main/java/org/allaymc/server/world/storage/LevelDBChunkSerializer.java @@ -4,15 +4,14 @@ import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufOutputStream; import io.netty.buffer.Unpooled; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.allaymc.api.block.palette.BlockStateHashPalette; import org.allaymc.api.block.type.BlockState; -import org.allaymc.api.blockentity.BlockEntity; import org.allaymc.api.data.VanillaBiomeId; -import org.allaymc.api.entity.Entity; import org.allaymc.api.entity.interfaces.EntityPlayer; import org.allaymc.api.utils.Utils; -import org.allaymc.api.world.DimensionInfo; import org.allaymc.api.world.biome.BiomeType; import org.allaymc.api.world.chunk.ChunkSection; import org.allaymc.api.world.chunk.UnsafeChunk; @@ -31,7 +30,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.List; import static org.allaymc.api.block.type.BlockTypes.AIR_TYPE; @@ -43,12 +41,10 @@ * @author Cool_Loong */ @Slf4j +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class LevelDBChunkSerializer { public static final LevelDBChunkSerializer INSTANCE = new LevelDBChunkSerializer(); - private LevelDBChunkSerializer() { - } - public void serialize(WriteBatch writeBatch, UnsafeChunk chunk) { serializeBlock(writeBatch, chunk); writeBatch.put(LevelDBKeyUtils.VERSION.getKey(chunk.getX(), chunk.getZ(), chunk.getDimensionInfo()), new byte[]{UnsafeChunk.CHUNK_VERSION}); @@ -86,23 +82,21 @@ private void serializeBlock(WriteBatch writeBatch, UnsafeChunk chunk) { //serialize chunk section private void deserializeBlock(DB db, AllayUnsafeChunk.Builder builder) { - DimensionInfo dimensionInfo = builder.getDimensionInfo(); - ChunkSection[] sections = new ChunkSection[dimensionInfo.chunkSectionSize()]; + var dimensionInfo = builder.getDimensionInfo(); + var sections = new ChunkSection[dimensionInfo.chunkSectionSize()]; var minSectionY = dimensionInfo.minSectionY(); for (int ySection = minSectionY; ySection <= dimensionInfo.maxSectionY(); ySection++) { - byte[] bytes = db.get(LevelDBKeyUtils.CHUNK_SECTION_PREFIX.getKey(builder.getChunkX(), builder.getChunkZ(), ySection, dimensionInfo)); + var bytes = db.get(LevelDBKeyUtils.CHUNK_SECTION_PREFIX.getKey(builder.getChunkX(), builder.getChunkZ(), ySection, dimensionInfo)); if (bytes == null) continue; - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.ioBuffer(bytes.length); + var byteBuf = ByteBufAllocator.DEFAULT.ioBuffer(bytes.length); try { byteBuf.writeBytes(bytes); - byte subChunkVersion = byteBuf.readByte(); + var subChunkVersion = byteBuf.readByte(); int layers = 2; switch (subChunkVersion) { case 9, 8: - layers = byteBuf.readByte();//layers - if (subChunkVersion == 9) { - byteBuf.readByte();//sectionY not use - } + layers = byteBuf.readByte(); // layers + if (subChunkVersion == 9) byteBuf.readByte(); // sectionY not use case 1: ChunkSection section; if (layers <= 2) { @@ -114,9 +108,9 @@ private void deserializeBlock(DB db, AllayUnsafeChunk.Builder builder) { } for (int layer = 0; layer < layers; layer++) { section.blockLayer()[layer].readFromStoragePersistent(byteBuf, hash -> { - BlockState blockState = BlockStateHashPalette.getRegistry().get(hash); + var blockState = BlockStateHashPalette.getRegistry().get(hash); if (blockState == null) { - log.error("Unknown block state hash: " + hash); + log.error("Unknown block state hash: {}", hash); blockState = UNKNOWN_TYPE.getDefaultState(); } return blockState; @@ -126,25 +120,21 @@ private void deserializeBlock(DB db, AllayUnsafeChunk.Builder builder) { break; } } finally { - if (byteBuf != null) { - byteBuf.release(); - } + byteBuf.release(); } } builder.sections(sections); } - //write biomeAndHeight private void serializeHeightAndBiome(WriteBatch writeBatch, UnsafeChunk chunk) { - //Write biomeAndHeight - ByteBuf heightAndBiomesBuffer = ByteBufAllocator.DEFAULT.ioBuffer(); + var heightAndBiomesBuffer = ByteBufAllocator.DEFAULT.ioBuffer(); try { - for (short height : chunk.getHeightArray()) { + for (var height : chunk.getHeightArray()) { heightAndBiomesBuffer.writeShortLE(height); } Palette lastPalette = null; for (int y = chunk.getDimensionInfo().minSectionY(); y <= chunk.getDimensionInfo().maxSectionY(); y++) { - ChunkSection section = chunk.getSection(y); + var section = chunk.getSection(y); if (section == null) continue; section.biomes().writeToStorageRuntime(heightAndBiomesBuffer, BiomeType::getId, lastPalette); lastPalette = section.biomes(); @@ -159,10 +149,10 @@ private void serializeHeightAndBiome(WriteBatch writeBatch, UnsafeChunk chunk) { private void deserializeHeightAndBiome(DB db, AllayUnsafeChunk.Builder builder) { ByteBuf heightAndBiomesBuffer = null; try { - byte[] bytes = db.get(LevelDBKeyUtils.DATA_3D.getKey(builder.getChunkX(), builder.getChunkZ(), builder.getDimensionInfo())); + var bytes = db.get(LevelDBKeyUtils.DATA_3D.getKey(builder.getChunkX(), builder.getChunkZ(), builder.getDimensionInfo())); if (bytes != null) { heightAndBiomesBuffer = Unpooled.wrappedBuffer(bytes); - short[] heights = new short[256]; + var heights = new short[256]; for (int i = 0; i < 256; i++) { heights[i] = heightAndBiomesBuffer.readShortLE(); } @@ -170,17 +160,17 @@ private void deserializeHeightAndBiome(DB db, AllayUnsafeChunk.Builder builder) Palette lastPalette = null; var minSectionY = builder.getDimensionInfo().minSectionY(); for (int y = minSectionY; y <= builder.getDimensionInfo().maxSectionY(); y++) { - ChunkSection section = builder.getSections()[y - minSectionY]; + var section = builder.getSections()[y - minSectionY]; if (section == null) continue; section.biomes().readFromStorageRuntime(heightAndBiomesBuffer, this::getBiomeByIdNonNull, lastPalette); lastPalette = section.biomes(); } return; } - byte[] bytes2D = db.get(LevelDBKeyUtils.DATA_2D.getKey(builder.getChunkX(), builder.getChunkZ(), builder.getDimensionInfo())); + var bytes2D = db.get(LevelDBKeyUtils.DATA_2D.getKey(builder.getChunkX(), builder.getChunkZ(), builder.getDimensionInfo())); if (bytes2D == null) return; heightAndBiomesBuffer = Unpooled.wrappedBuffer(bytes2D); - short[] heights = new short[256]; + var heights = new short[256]; for (int i = 0; i < 256; i++) { heights[i] = heightAndBiomesBuffer.readShortLE(); } @@ -209,13 +199,13 @@ private void deserializeHeightAndBiome(DB db, AllayUnsafeChunk.Builder builder) } private void deserializeEntityAndBlockEntity(DB db, AllayUnsafeChunk.Builder builder) { - DimensionInfo dimensionInfo = builder.getDimensionInfo(); - byte[] tileBytes = db.get(LevelDBKeyUtils.BLOCK_ENTITIES.getKey(builder.getChunkX(), builder.getChunkZ(), dimensionInfo)); + var dimensionInfo = builder.getDimensionInfo(); + var tileBytes = db.get(LevelDBKeyUtils.BLOCK_ENTITIES.getKey(builder.getChunkX(), builder.getChunkZ(), dimensionInfo)); if (tileBytes != null) { builder.blockEntities(deserializeNbtTagsFromBytes(tileBytes)); } - byte[] key = LevelDBKeyUtils.ENTITIES.getKey(builder.getChunkX(), builder.getChunkZ(), dimensionInfo); - byte[] entityBytes = db.get(key); + var key = LevelDBKeyUtils.ENTITIES.getKey(builder.getChunkX(), builder.getChunkZ(), dimensionInfo); + var entityBytes = db.get(key); if (entityBytes != null) { builder.entities(deserializeNbtTagsFromBytes(entityBytes)); } @@ -223,7 +213,7 @@ private void deserializeEntityAndBlockEntity(DB db, AllayUnsafeChunk.Builder bui private List deserializeNbtTagsFromBytes(byte[] bytes) { List tags = new ArrayList<>(); - try (BufferedInputStream stream = new BufferedInputStream(new ByteArrayInputStream(bytes))) { + try (var stream = new BufferedInputStream(new ByteArrayInputStream(bytes))) { while (stream.available() > 0) { tags.add((NbtMap) NbtUtils.createReaderLE(stream).readTag()); } @@ -235,14 +225,14 @@ private List deserializeNbtTagsFromBytes(byte[] bytes) { private void serializeEntityAndBlockEntity(WriteBatch writeBatch, UnsafeChunk chunk) { //Write blockEntities - Collection blockEntities = chunk.getBlockEntities().values(); - ByteBuf tileBuffer = ByteBufAllocator.DEFAULT.ioBuffer(); + var blockEntities = chunk.getBlockEntities().values(); + var tileBuffer = ByteBufAllocator.DEFAULT.ioBuffer(); try (var bufStream = new ByteBufOutputStream(tileBuffer)) { - byte[] key = LevelDBKeyUtils.BLOCK_ENTITIES.getKey(chunk.getX(), chunk.getZ(), chunk.getDimensionInfo()); + var key = LevelDBKeyUtils.BLOCK_ENTITIES.getKey(chunk.getX(), chunk.getZ(), chunk.getDimensionInfo()); if (blockEntities.isEmpty()) { writeBatch.delete(key); } else { - for (BlockEntity blockEntity : blockEntities) { + for (var blockEntity : blockEntities) { NBTOutputStream writerLE = NbtUtils.createWriterLE(bufStream); writerLE.writeTag(blockEntity.saveNBT()); } @@ -254,18 +244,18 @@ private void serializeEntityAndBlockEntity(WriteBatch writeBatch, UnsafeChunk ch tileBuffer.release(); } - Collection entities = chunk.getEntities().values(); - ByteBuf entityBuffer = ByteBufAllocator.DEFAULT.ioBuffer(); + var entities = chunk.getEntities().values(); + var entityBuffer = ByteBufAllocator.DEFAULT.ioBuffer(); try (var bufStream = new ByteBufOutputStream(entityBuffer)) { - byte[] key = LevelDBKeyUtils.ENTITIES.getKey(chunk.getX(), chunk.getZ(), chunk.getDimensionInfo()); + var key = LevelDBKeyUtils.ENTITIES.getKey(chunk.getX(), chunk.getZ(), chunk.getDimensionInfo()); if (entities.isEmpty()) { writeBatch.delete(key); return; } - for (Entity e : entities) { - if (e instanceof EntityPlayer) continue; - NBTOutputStream writerLE = NbtUtils.createWriterLE(bufStream); - writerLE.writeTag(e.saveNBT()); + for (var entity : entities) { + if (entity instanceof EntityPlayer) continue; + var writerLE = NbtUtils.createWriterLE(bufStream); + writerLE.writeTag(entity.saveNBT()); } writeBatch.put(key, Utils.convertByteBuf2Array(entityBuffer)); } catch (IOException e) {