mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
优化区块读写性能
This commit is contained in:
@@ -4,11 +4,11 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
maven("https://jitpack.io/")
|
maven("https://jitpack.io/")
|
||||||
maven("https://repo.momirealms.net/releases/")
|
maven("https://repo.momirealms.net/releases/")
|
||||||
maven("https://libraries.minecraft.net/")
|
maven("https://libraries.minecraft.net/")
|
||||||
maven("https://repo.papermc.io/repository/maven-public/")
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
mavenCentral()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -60,6 +60,8 @@ dependencies {
|
|||||||
compileOnly("org.ahocorasick:ahocorasick:${rootProject.properties["ahocorasick_version"]}")
|
compileOnly("org.ahocorasick:ahocorasick:${rootProject.properties["ahocorasick_version"]}")
|
||||||
// authlib
|
// authlib
|
||||||
compileOnly("com.mojang:authlib:${rootProject.properties["authlib_version"]}")
|
compileOnly("com.mojang:authlib:${rootProject.properties["authlib_version"]}")
|
||||||
|
// concurrentutil
|
||||||
|
compileOnly("ca.spottedleaf:concurrentutil:${rootProject.properties["concurrent_util_version"]}")
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
|
|||||||
@@ -30,5 +30,4 @@ public class ZaphkielSource implements ExternalItemSource<ItemStack> {
|
|||||||
public String id(ItemStack item) {
|
public String id(ItemStack item) {
|
||||||
return Zaphkiel.INSTANCE.api().getItemHandler().getItemId(item);
|
return Zaphkiel.INSTANCE.api().getItemHandler().getItemId(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ dependencies {
|
|||||||
implementation(project(":bukkit:compatibility:legacy"))
|
implementation(project(":bukkit:compatibility:legacy"))
|
||||||
implementation(project(":common-files"))
|
implementation(project(":common-files"))
|
||||||
|
|
||||||
|
// concurrentutil
|
||||||
|
implementation(files("${rootProject.rootDir}/libs/concurrentutil-${rootProject.properties["concurrent_util_version"]}.jar"))
|
||||||
|
|
||||||
implementation("net.momirealms:sparrow-util:${rootProject.properties["sparrow_util_version"]}")
|
implementation("net.momirealms:sparrow-util:${rootProject.properties["sparrow_util_version"]}")
|
||||||
implementation("net.momirealms:antigrieflib:${rootProject.properties["anti_grief_version"]}")
|
implementation("net.momirealms:antigrieflib:${rootProject.properties["anti_grief_version"]}")
|
||||||
implementation("net.momirealms:craft-engine-nms-helper:${rootProject.properties["nms_helper_version"]}")
|
implementation("net.momirealms:craft-engine-nms-helper:${rootProject.properties["nms_helper_version"]}")
|
||||||
@@ -77,5 +80,6 @@ tasks {
|
|||||||
relocate("com.google.common.jimfs", "net.momirealms.craftengine.libraries.jimfs")
|
relocate("com.google.common.jimfs", "net.momirealms.craftengine.libraries.jimfs")
|
||||||
relocate("org.apache.commons", "net.momirealms.craftengine.libraries.commons")
|
relocate("org.apache.commons", "net.momirealms.craftengine.libraries.commons")
|
||||||
relocate("io.leangen.geantyref", "net.momirealms.craftengine.libraries.geantyref")
|
relocate("io.leangen.geantyref", "net.momirealms.craftengine.libraries.geantyref")
|
||||||
|
relocate("ca.spottedleaf.concurrentutil", "net.momirealms.craftengine.libraries.concurrentutil")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ dependencies {
|
|||||||
implementation(project(":bukkit:compatibility:legacy"))
|
implementation(project(":bukkit:compatibility:legacy"))
|
||||||
implementation(project(":common-files"))
|
implementation(project(":common-files"))
|
||||||
|
|
||||||
|
// concurrentutil
|
||||||
|
implementation(files("${rootProject.rootDir}/libs/concurrentutil-${rootProject.properties["concurrent_util_version"]}.jar"))
|
||||||
|
|
||||||
implementation("net.momirealms:sparrow-util:${rootProject.properties["sparrow_util_version"]}")
|
implementation("net.momirealms:sparrow-util:${rootProject.properties["sparrow_util_version"]}")
|
||||||
implementation("net.momirealms:antigrieflib:${rootProject.properties["anti_grief_version"]}")
|
implementation("net.momirealms:antigrieflib:${rootProject.properties["anti_grief_version"]}")
|
||||||
implementation("net.momirealms:craft-engine-nms-helper-mojmap:${rootProject.properties["nms_helper_version"]}")
|
implementation("net.momirealms:craft-engine-nms-helper-mojmap:${rootProject.properties["nms_helper_version"]}")
|
||||||
@@ -150,5 +153,6 @@ tasks {
|
|||||||
relocate("com.google.common.jimfs", "net.momirealms.craftengine.libraries.jimfs")
|
relocate("com.google.common.jimfs", "net.momirealms.craftengine.libraries.jimfs")
|
||||||
relocate("org.apache.commons", "net.momirealms.craftengine.libraries.commons")
|
relocate("org.apache.commons", "net.momirealms.craftengine.libraries.commons")
|
||||||
relocate("io.leangen.geantyref", "net.momirealms.craftengine.libraries.geantyref")
|
relocate("io.leangen.geantyref", "net.momirealms.craftengine.libraries.geantyref")
|
||||||
|
relocate("ca.spottedleaf.concurrentutil", "net.momirealms.craftengine.libraries.concurrentutil")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
|||||||
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIdFinder;
|
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIdFinder;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20;
|
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20_5;
|
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20_5;
|
||||||
|
import net.momirealms.craftengine.bukkit.plugin.reflection.leaves.LeavesReflections;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.LeavesReflections;
|
|
||||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.LibraryReflections;
|
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.LibraryReflections;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
|
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
||||||
@@ -213,6 +213,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
|||||||
registerNMSPacketConsumer(PacketConsumers.LOGIN_FINISHED, NetworkReflections.clazz$ClientboundLoginFinishedPacket);
|
registerNMSPacketConsumer(PacketConsumers.LOGIN_FINISHED, NetworkReflections.clazz$ClientboundLoginFinishedPacket);
|
||||||
registerNMSPacketConsumer(PacketConsumers.UPDATE_TAGS, NetworkReflections.clazz$ClientboundUpdateTagsPacket);
|
registerNMSPacketConsumer(PacketConsumers.UPDATE_TAGS, NetworkReflections.clazz$ClientboundUpdateTagsPacket);
|
||||||
registerNMSPacketConsumer(PacketConsumers.CONTAINER_CLICK_1_21_5, VersionHelper.isOrAbove1_21_5() ? NetworkReflections.clazz$ServerboundContainerClickPacket : null);
|
registerNMSPacketConsumer(PacketConsumers.CONTAINER_CLICK_1_21_5, VersionHelper.isOrAbove1_21_5() ? NetworkReflections.clazz$ServerboundContainerClickPacket : null);
|
||||||
|
registerS2CByteBufPacketConsumer(PacketConsumers.FORGET_LEVEL_CHUNK, this.packetIds.clientboundForgetLevelChunkPacket());
|
||||||
registerS2CByteBufPacketConsumer(PacketConsumers.LEVEL_CHUNK_WITH_LIGHT, this.packetIds.clientboundLevelChunkWithLightPacket());
|
registerS2CByteBufPacketConsumer(PacketConsumers.LEVEL_CHUNK_WITH_LIGHT, this.packetIds.clientboundLevelChunkWithLightPacket());
|
||||||
registerS2CByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
|
registerS2CByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
|
||||||
registerS2CByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
|
registerS2CByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
|
||||||
|
|||||||
@@ -64,10 +64,7 @@ import net.momirealms.craftengine.core.plugin.logger.Debugger;
|
|||||||
import net.momirealms.craftengine.core.plugin.network.*;
|
import net.momirealms.craftengine.core.plugin.network.*;
|
||||||
import net.momirealms.craftengine.core.plugin.text.component.ComponentProvider;
|
import net.momirealms.craftengine.core.plugin.text.component.ComponentProvider;
|
||||||
import net.momirealms.craftengine.core.util.*;
|
import net.momirealms.craftengine.core.util.*;
|
||||||
import net.momirealms.craftengine.core.world.BlockHitResult;
|
import net.momirealms.craftengine.core.world.*;
|
||||||
import net.momirealms.craftengine.core.world.BlockPos;
|
|
||||||
import net.momirealms.craftengine.core.world.EntityHitResult;
|
|
||||||
import net.momirealms.craftengine.core.world.WorldEvents;
|
|
||||||
import net.momirealms.craftengine.core.world.chunk.Palette;
|
import net.momirealms.craftengine.core.world.chunk.Palette;
|
||||||
import net.momirealms.craftengine.core.world.chunk.PalettedContainer;
|
import net.momirealms.craftengine.core.world.chunk.PalettedContainer;
|
||||||
import net.momirealms.craftengine.core.world.chunk.packet.BlockEntityData;
|
import net.momirealms.craftengine.core.world.chunk.packet.BlockEntityData;
|
||||||
@@ -75,6 +72,7 @@ import net.momirealms.craftengine.core.world.chunk.packet.MCSection;
|
|||||||
import net.momirealms.craftengine.core.world.collision.AABB;
|
import net.momirealms.craftengine.core.world.collision.AABB;
|
||||||
import net.momirealms.sparrow.nbt.Tag;
|
import net.momirealms.sparrow.nbt.Tag;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@@ -261,12 +259,29 @@ public class PacketConsumers {
|
|||||||
return MOD_BLOCK_STATE_MAPPINGS[stateId];
|
return MOD_BLOCK_STATE_MAPPINGS[stateId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> FORGET_LEVEL_CHUNK = (user, event) -> {
|
||||||
|
try {
|
||||||
|
FriendlyByteBuf buf = event.getBuffer();
|
||||||
|
if (VersionHelper.isOrAbove1_20_2()) {
|
||||||
|
long chunkPos = buf.readLong();
|
||||||
|
user.setChunkTrackStatus(new ChunkPos(chunkPos), false);
|
||||||
|
} else {
|
||||||
|
int x = buf.readInt();
|
||||||
|
int y = buf.readInt();
|
||||||
|
user.setChunkTrackStatus(ChunkPos.of(x, y), false);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
CraftEngine.instance().logger().warn("Failed to handle ClientboundForgetLevelChunkPacket", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> LEVEL_CHUNK_WITH_LIGHT = (user, event) -> {
|
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> LEVEL_CHUNK_WITH_LIGHT = (user, event) -> {
|
||||||
try {
|
try {
|
||||||
BukkitServerPlayer player = (BukkitServerPlayer) user;
|
BukkitServerPlayer player = (BukkitServerPlayer) user;
|
||||||
FriendlyByteBuf buf = event.getBuffer();
|
FriendlyByteBuf buf = event.getBuffer();
|
||||||
int chunkX = buf.readInt();
|
int chunkX = buf.readInt();
|
||||||
int chunkZ = buf.readInt();
|
int chunkZ = buf.readInt();
|
||||||
|
player.setChunkTrackStatus(ChunkPos.of(chunkX, chunkZ), true);
|
||||||
boolean named = !VersionHelper.isOrAbove1_20_2();
|
boolean named = !VersionHelper.isOrAbove1_20_2();
|
||||||
// ClientboundLevelChunkPacketData
|
// ClientboundLevelChunkPacketData
|
||||||
int heightmapsCount = 0;
|
int heightmapsCount = 0;
|
||||||
@@ -1262,6 +1277,7 @@ public class PacketConsumers {
|
|||||||
int sectionCount = (world.getMaxHeight() - world.getMinHeight()) / 16;
|
int sectionCount = (world.getMaxHeight() - world.getMinHeight()) / 16;
|
||||||
player.setClientSideSectionCount(sectionCount);
|
player.setClientSideSectionCount(sectionCount);
|
||||||
player.setClientSideDimension(Key.of(location.toString()));
|
player.setClientSideDimension(Key.of(location.toString()));
|
||||||
|
player.clearTrackedChunks();
|
||||||
} else {
|
} else {
|
||||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundRespawnPacket: World " + location + " does not exist");
|
CraftEngine.instance().logger().warn("Failed to handle ClientboundRespawnPacket: World " + location + " does not exist");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,4 +67,6 @@ public interface PacketIds {
|
|||||||
int serverboundInteractPacket();
|
int serverboundInteractPacket();
|
||||||
|
|
||||||
int clientboundUpdateRecipesPacket();
|
int clientboundUpdateRecipesPacket();
|
||||||
|
|
||||||
|
int clientboundForgetLevelChunkPacket();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,4 +169,9 @@ public class PacketIds1_20 implements PacketIds {
|
|||||||
public int clientboundUpdateAdvancementsPacket() {
|
public int clientboundUpdateAdvancementsPacket() {
|
||||||
return PacketIdFinder.clientboundByClazz(NetworkReflections.clazz$ClientboundUpdateAdvancementsPacket);
|
return PacketIdFinder.clientboundByClazz(NetworkReflections.clazz$ClientboundUpdateAdvancementsPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int clientboundForgetLevelChunkPacket() {
|
||||||
|
return PacketIdFinder.clientboundByClazz(NetworkReflections.clazz$ClientboundForgetLevelChunkPacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,4 +168,9 @@ public class PacketIds1_20_5 implements PacketIds {
|
|||||||
public int serverboundInteractPacket() {
|
public int serverboundInteractPacket() {
|
||||||
return PacketIdFinder.serverboundByName("minecraft:interact");
|
return PacketIdFinder.serverboundByName("minecraft:interact");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int clientboundForgetLevelChunkPacket() {
|
||||||
|
return PacketIdFinder.clientboundByName("minecraft:forget_level_chunk");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.momirealms.craftengine.bukkit.plugin.reflection.minecraft;
|
package net.momirealms.craftengine.bukkit.plugin.reflection.leaves;
|
||||||
|
|
||||||
//import net.momirealms.craftengine.core.util.MiscUtils;
|
//import net.momirealms.craftengine.core.util.MiscUtils;
|
||||||
//import net.momirealms.craftengine.core.util.ReflectionUtils;
|
//import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||||
@@ -1665,4 +1665,11 @@ public final class NetworkReflections {
|
|||||||
),
|
),
|
||||||
VersionHelper.isOrAbove1_21_5()
|
VersionHelper.isOrAbove1_21_5()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public static final Class<?> clazz$ClientboundForgetLevelChunkPacket = requireNonNull(
|
||||||
|
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||||
|
"network.protocol.game.PacketPlayOutUnloadChunk",
|
||||||
|
"network.protocol.game.ClientboundForgetLevelChunkPacket"
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import net.momirealms.craftengine.core.util.Direction;
|
|||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
import net.momirealms.craftengine.core.world.BlockPos;
|
import net.momirealms.craftengine.core.world.BlockPos;
|
||||||
|
import net.momirealms.craftengine.core.world.ChunkPos;
|
||||||
import net.momirealms.craftengine.core.world.World;
|
import net.momirealms.craftengine.core.world.World;
|
||||||
import net.momirealms.craftengine.core.world.WorldEvents;
|
import net.momirealms.craftengine.core.world.WorldEvents;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
@@ -109,7 +110,11 @@ public class BukkitServerPlayer extends Player {
|
|||||||
private double cachedInteractionRange;
|
private double cachedInteractionRange;
|
||||||
// cooldown data
|
// cooldown data
|
||||||
private CooldownData cooldownData;
|
private CooldownData cooldownData;
|
||||||
|
// tracked chunks
|
||||||
|
private final Set<ChunkPos> trackedChunks = Collections.synchronizedSet(new HashSet<>());
|
||||||
|
// relighted chunks
|
||||||
|
private final Set<ChunkPos> relightedChunks = Collections.synchronizedSet(new HashSet<>());
|
||||||
|
// entity view
|
||||||
private final Map<Integer, EntityPacketHandler> entityTypeView = new ConcurrentHashMap<>();
|
private final Map<Integer, EntityPacketHandler> entityTypeView = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public BukkitServerPlayer(BukkitCraftEngine plugin, @Nullable Channel channel) {
|
public BukkitServerPlayer(BukkitCraftEngine plugin, @Nullable Channel channel) {
|
||||||
@@ -497,9 +502,6 @@ public class BukkitServerPlayer extends Player {
|
|||||||
Item<ItemStack> tool = getItemInHand(InteractionHand.MAIN_HAND);
|
Item<ItemStack> tool = getItemInHand(InteractionHand.MAIN_HAND);
|
||||||
boolean isCorrectTool = FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(tool.getLiteralObject(), blockState);
|
boolean isCorrectTool = FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(tool.getLiteralObject(), blockState);
|
||||||
// 如果自定义方块在服务端侧未使用正确的工具,那么需要还原挖掘速度
|
// 如果自定义方块在服务端侧未使用正确的工具,那么需要还原挖掘速度
|
||||||
if (!isCorrectTool) {
|
|
||||||
progress *= (10f / 3f);
|
|
||||||
}
|
|
||||||
if (!BlockStateUtils.isCorrectTool(customState, tool)) {
|
if (!BlockStateUtils.isCorrectTool(customState, tool)) {
|
||||||
progress *= customState.settings().incorrectToolSpeed();
|
progress *= customState.settings().incorrectToolSpeed();
|
||||||
}
|
}
|
||||||
@@ -1032,4 +1034,23 @@ public class BukkitServerPlayer extends Player {
|
|||||||
public CooldownData cooldown() {
|
public CooldownData cooldown() {
|
||||||
return this.cooldownData;
|
return this.cooldownData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChunkTracked(ChunkPos chunkPos) {
|
||||||
|
return this.trackedChunks.contains(chunkPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setChunkTrackStatus(ChunkPos chunkPos, boolean tracked) {
|
||||||
|
if (tracked) {
|
||||||
|
this.trackedChunks.add(chunkPos);
|
||||||
|
} else {
|
||||||
|
this.trackedChunks.remove(chunkPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearTrackedChunks() {
|
||||||
|
this.trackedChunks.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.momirealms.craftengine.bukkit.world;
|
package net.momirealms.craftengine.bukkit.world;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||||
import net.momirealms.craftengine.bukkit.plugin.injector.WorldStorageInjector;
|
import net.momirealms.craftengine.bukkit.plugin.injector.WorldStorageInjector;
|
||||||
@@ -29,7 +30,6 @@ import org.bukkit.event.world.*;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -53,7 +53,7 @@ public class BukkitWorldManager implements WorldManager, Listener {
|
|||||||
public BukkitWorldManager(BukkitCraftEngine plugin) {
|
public BukkitWorldManager(BukkitCraftEngine plugin) {
|
||||||
instance = this;
|
instance = this;
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.worlds = new HashMap<>();
|
this.worlds = new Object2ObjectOpenHashMap<>(32, 0.5f);
|
||||||
this.storageAdaptor = new DefaultStorageAdaptor();
|
this.storageAdaptor = new DefaultStorageAdaptor();
|
||||||
for (World world : Bukkit.getWorlds()) {
|
for (World world : Bukkit.getWorlds()) {
|
||||||
this.worlds.put(world.getUID(), new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor));
|
this.worlds.put(world.getUID(), new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor));
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ dependencies {
|
|||||||
compileOnly("com.mojang:brigadier:${rootProject.properties["mojang_brigadier_version"]}")
|
compileOnly("com.mojang:brigadier:${rootProject.properties["mojang_brigadier_version"]}")
|
||||||
// authlib
|
// authlib
|
||||||
compileOnly("com.mojang:authlib:${rootProject.properties["authlib_version"]}")
|
compileOnly("com.mojang:authlib:${rootProject.properties["authlib_version"]}")
|
||||||
|
// concurrentutil
|
||||||
|
compileOnly("ca.spottedleaf:concurrentutil:${rootProject.properties["concurrent_util_version"]}")
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ import net.momirealms.craftengine.core.util.Key;
|
|||||||
import net.momirealms.craftengine.core.world.BlockPos;
|
import net.momirealms.craftengine.core.world.BlockPos;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class Player extends AbstractEntity implements NetWorkUser {
|
public abstract class Player extends AbstractEntity implements NetWorkUser {
|
||||||
private static final Key TYPE = Key.of("minecraft:player");
|
private static final Key TYPE = Key.of("minecraft:player");
|
||||||
|
|
||||||
@@ -26,10 +24,6 @@ public abstract class Player extends AbstractEntity implements NetWorkUser {
|
|||||||
@Override
|
@Override
|
||||||
public abstract Object serverPlayer();
|
public abstract Object serverPlayer();
|
||||||
|
|
||||||
public abstract void sendPackets(List<Object> packet, boolean immediately);
|
|
||||||
|
|
||||||
public abstract void sendPackets(List<Object> packet, boolean immediately, Runnable sendListener);
|
|
||||||
|
|
||||||
public abstract float getDestroyProgress(Object blockState, BlockPos pos);
|
public abstract float getDestroyProgress(Object blockState, BlockPos pos);
|
||||||
|
|
||||||
public abstract void setClientSideCanBreakBlock(boolean canBreak);
|
public abstract void setClientSideCanBreakBlock(boolean canBreak);
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ import io.netty.channel.ChannelHandler;
|
|||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.momirealms.craftengine.core.plugin.Plugin;
|
import net.momirealms.craftengine.core.plugin.Plugin;
|
||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
import net.momirealms.craftengine.core.world.ChunkPos;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -38,6 +40,10 @@ public interface NetWorkUser {
|
|||||||
|
|
||||||
void sendPacket(Object packet, boolean immediately, Runnable sendListener);
|
void sendPacket(Object packet, boolean immediately, Runnable sendListener);
|
||||||
|
|
||||||
|
void sendPackets(List<Object> packet, boolean immediately);
|
||||||
|
|
||||||
|
void sendPackets(List<Object> packet, boolean immediately, Runnable sendListener);
|
||||||
|
|
||||||
void sendCustomPayload(Key channel, byte[] data);
|
void sendCustomPayload(Key channel, byte[] data);
|
||||||
|
|
||||||
void kick(Component message);
|
void kick(Component message);
|
||||||
@@ -71,4 +77,10 @@ public interface NetWorkUser {
|
|||||||
void setShouldProcessFinishConfiguration(boolean shouldProcess);
|
void setShouldProcessFinishConfiguration(boolean shouldProcess);
|
||||||
|
|
||||||
boolean shouldProcessFinishConfiguration();
|
boolean shouldProcessFinishConfiguration();
|
||||||
|
|
||||||
|
boolean isChunkTracked(ChunkPos chunkPos);
|
||||||
|
|
||||||
|
void setChunkTrackStatus(ChunkPos chunkPos, boolean tracked);
|
||||||
|
|
||||||
|
void clearTrackedChunks();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package net.momirealms.craftengine.core.world;
|
package net.momirealms.craftengine.core.world;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable;
|
||||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
import net.momirealms.craftengine.core.world.chunk.CEChunk;
|
import net.momirealms.craftengine.core.world.chunk.CEChunk;
|
||||||
@@ -10,17 +10,14 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
||||||
|
|
||||||
public abstract class CEWorld {
|
public abstract class CEWorld {
|
||||||
public static final String REGION_DIRECTORY = "craftengine";
|
public static final String REGION_DIRECTORY = "craftengine";
|
||||||
protected final World world;
|
protected final World world;
|
||||||
protected final Map<Long, CEChunk> loadedChunkMap;
|
protected final ConcurrentLong2ReferenceChainedHashTable<CEChunk> loadedChunkMap;
|
||||||
protected final WorldDataStorage worldDataStorage;
|
protected final WorldDataStorage worldDataStorage;
|
||||||
protected final ReentrantReadWriteLock loadedChunkMapLock = new ReentrantReadWriteLock();
|
|
||||||
protected final WorldHeight worldHeightAccessor;
|
protected final WorldHeight worldHeightAccessor;
|
||||||
protected final Set<SectionPos> updatedSectionSet = ConcurrentHashMap.newKeySet(128);
|
protected final Set<SectionPos> updatedSectionSet = ConcurrentHashMap.newKeySet(128);
|
||||||
|
|
||||||
@@ -29,7 +26,7 @@ public abstract class CEWorld {
|
|||||||
|
|
||||||
public CEWorld(World world, StorageAdaptor adaptor) {
|
public CEWorld(World world, StorageAdaptor adaptor) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.loadedChunkMap = new Long2ObjectOpenHashMap<>(1024, 0.5f);
|
this.loadedChunkMap = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(1024, 0.5f);
|
||||||
this.worldDataStorage = adaptor.adapt(world);
|
this.worldDataStorage = adaptor.adapt(world);
|
||||||
this.worldHeightAccessor = world.worldHeight();
|
this.worldHeightAccessor = world.worldHeight();
|
||||||
this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS;
|
this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS;
|
||||||
@@ -37,16 +34,15 @@ public abstract class CEWorld {
|
|||||||
|
|
||||||
public CEWorld(World world, WorldDataStorage dataStorage) {
|
public CEWorld(World world, WorldDataStorage dataStorage) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.loadedChunkMap = new Long2ObjectOpenHashMap<>(1024, 0.5f);
|
this.loadedChunkMap = ConcurrentLong2ReferenceChainedHashTable.createWithCapacity(1024, 0.5f);
|
||||||
this.worldDataStorage = dataStorage;
|
this.worldDataStorage = dataStorage;
|
||||||
this.worldHeightAccessor = world.worldHeight();
|
this.worldHeightAccessor = world.worldHeight();
|
||||||
this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS;
|
this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
this.loadedChunkMapLock.readLock().lock();
|
|
||||||
try {
|
try {
|
||||||
for (Map.Entry<Long, CEChunk> entry : this.loadedChunkMap.entrySet()) {
|
for (ConcurrentLong2ReferenceChainedHashTable.TableEntry<CEChunk> entry : this.loadedChunkMap.entrySet()) {
|
||||||
CEChunk chunk = entry.getValue();
|
CEChunk chunk = entry.getValue();
|
||||||
if (chunk.dirty()) {
|
if (chunk.dirty()) {
|
||||||
worldDataStorage.writeChunkAt(new ChunkPos(entry.getKey()), chunk);
|
worldDataStorage.writeChunkAt(new ChunkPos(entry.getKey()), chunk);
|
||||||
@@ -55,8 +51,6 @@ public abstract class CEWorld {
|
|||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CraftEngine.instance().logger().warn("Failed to save world chunks", e);
|
CraftEngine.instance().logger().warn("Failed to save world chunks", e);
|
||||||
} finally {
|
|
||||||
this.loadedChunkMapLock.readLock().unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,44 +59,24 @@ public abstract class CEWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isChunkLoaded(final long chunkPos) {
|
public boolean isChunkLoaded(final long chunkPos) {
|
||||||
this.loadedChunkMapLock.readLock().lock();
|
return loadedChunkMap.containsKey(chunkPos);
|
||||||
try {
|
|
||||||
return loadedChunkMap.containsKey(chunkPos);
|
|
||||||
} finally {
|
|
||||||
this.loadedChunkMapLock.readLock().unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLoadedChunk(CEChunk chunk) {
|
public void addLoadedChunk(CEChunk chunk) {
|
||||||
this.loadedChunkMapLock.writeLock().lock();
|
this.loadedChunkMap.put(chunk.chunkPos().longKey(), chunk);
|
||||||
try {
|
|
||||||
this.loadedChunkMap.put(chunk.chunkPos().longKey(), chunk);
|
|
||||||
} finally {
|
|
||||||
this.loadedChunkMapLock.writeLock().unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeLoadedChunk(CEChunk chunk) {
|
public void removeLoadedChunk(CEChunk chunk) {
|
||||||
this.loadedChunkMapLock.writeLock().lock();
|
this.loadedChunkMap.remove(chunk.chunkPos().longKey());
|
||||||
try {
|
if (this.lastChunk == chunk) {
|
||||||
this.loadedChunkMap.remove(chunk.chunkPos().longKey());
|
this.lastChunk = null;
|
||||||
if (this.lastChunk == chunk) {
|
this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS;
|
||||||
this.lastChunk = null;
|
|
||||||
this.lastChunkPos = ChunkPos.INVALID_CHUNK_POS;
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
this.loadedChunkMapLock.writeLock().unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public CEChunk getChunkAtIfLoaded(long chunkPos) {
|
public CEChunk getChunkAtIfLoaded(long chunkPos) {
|
||||||
this.loadedChunkMapLock.readLock().lock();
|
return getChunkAtIfLoadedMainThread(chunkPos);
|
||||||
try {
|
|
||||||
return getChunkAtIfLoadedMainThread(chunkPos);
|
|
||||||
} finally {
|
|
||||||
this.loadedChunkMapLock.readLock().unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ amazon_awssdk_version=2.31.23
|
|||||||
amazon_awssdk_eventstream_version=1.0.1
|
amazon_awssdk_eventstream_version=1.0.1
|
||||||
jimfs_version=1.3.0
|
jimfs_version=1.3.0
|
||||||
authlib_version=6.0.58
|
authlib_version=6.0.58
|
||||||
|
concurrent_util_version=0.0.3
|
||||||
|
|
||||||
# Proxy settings
|
# Proxy settings
|
||||||
#systemProp.socks.proxyHost=127.0.0.1
|
#systemProp.socks.proxyHost=127.0.0.1
|
||||||
|
|||||||
Binary file not shown.
BIN
libs/concurrentutil-0.0.3.jar
Normal file
BIN
libs/concurrentutil-0.0.3.jar
Normal file
Binary file not shown.
Reference in New Issue
Block a user