9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 09:59:20 +00:00

稍作优化

This commit is contained in:
XiaoMoMi
2025-09-06 06:28:45 +08:00
parent a42f70b941
commit f491335316
2 changed files with 1191 additions and 92 deletions

View File

@@ -1,6 +1,5 @@
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.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.injector.WorldStorageInjector;
@@ -9,6 +8,7 @@ import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.util.ConcurrentUUID2ReferenceChainedHashTable;
import net.momirealms.craftengine.core.world.CEWorld;
import net.momirealms.craftengine.core.world.ChunkPos;
import net.momirealms.craftengine.core.world.SectionPos;
@@ -29,27 +29,21 @@ import org.bukkit.event.world.*;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class BukkitWorldManager implements WorldManager, Listener {
private static BukkitWorldManager instance;
private final BukkitCraftEngine plugin;
private final Map<UUID, CEWorld> worlds;
private CEWorld[] worldArray = new CEWorld[0];
private final ReentrantReadWriteLock worldMapLock = new ReentrantReadWriteLock();
// cache
private UUID lastVisitedUUID;
private CEWorld lastVisitedWorld;
private final ConcurrentUUID2ReferenceChainedHashTable<CEWorld> worlds;
private CEWorld[] worldArray;
private StorageAdaptor storageAdaptor;
private boolean initialized = false;
public BukkitWorldManager(BukkitCraftEngine plugin) {
instance = this;
this.plugin = plugin;
this.worlds = new Object2ObjectOpenHashMap<>(32, 0.5f);
this.worlds = ConcurrentUUID2ReferenceChainedHashTable.createWithCapacity(10, 0.5f);
this.storageAdaptor = new DefaultStorageAdaptor();
for (World world : Bukkit.getWorlds()) {
this.worlds.put(world.getUID(), new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor));
@@ -71,20 +65,7 @@ public class BukkitWorldManager implements WorldManager, Listener {
@Override
public CEWorld getWorld(UUID uuid) {
if (uuid.equals(this.lastVisitedUUID)) {
return this.lastVisitedWorld;
}
this.worldMapLock.readLock().lock();
try {
CEWorld world = worlds.get(uuid);
if (world != null) {
this.lastVisitedUUID = uuid;
this.lastVisitedWorld = world;
}
return world;
} finally {
this.worldMapLock.readLock().unlock();
}
return this.worlds.get(uuid);
}
@Override
@@ -98,23 +79,18 @@ public class BukkitWorldManager implements WorldManager, Listener {
public void delayedInit() {
// load loaded chunks
this.worldMapLock.writeLock().lock();
try {
for (World world : Bukkit.getWorlds()) {
try {
CEWorld ceWorld = this.worlds.computeIfAbsent(world.getUID(), k -> new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor));
for (Chunk chunk : world.getLoadedChunks()) {
handleChunkLoad(ceWorld, chunk);
}
ceWorld.setTicking(true);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Error loading world: " + world.getName(), e);
for (World world : Bukkit.getWorlds()) {
try {
CEWorld ceWorld = this.worlds.computeIfAbsent(world.getUID(), k -> new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor));
for (Chunk chunk : world.getLoadedChunks()) {
handleChunkLoad(ceWorld, chunk);
}
ceWorld.setTicking(true);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Error loading world: " + world.getName(), e);
}
this.resetWorldArray();
} finally {
this.worldMapLock.writeLock().unlock();
}
this.resetWorldArray();
Bukkit.getPluginManager().registerEvents(this, this.plugin.javaPlugin());
this.initialized = true;
}
@@ -147,35 +123,25 @@ public class BukkitWorldManager implements WorldManager, Listener {
@Override
public void loadWorld(net.momirealms.craftengine.core.world.World world) {
this.worldMapLock.writeLock().lock();
try {
if (this.worlds.containsKey(world.uuid())) return;
CEWorld ceWorld = new BukkitCEWorld(world, this.storageAdaptor);
this.worlds.put(world.uuid(), ceWorld);
this.resetWorldArray();
for (Chunk chunk : ((World) world.platformWorld()).getLoadedChunks()) {
handleChunkLoad(ceWorld, chunk);
}
ceWorld.setTicking(true);
} finally {
this.worldMapLock.writeLock().unlock();
if (this.worlds.containsKey(world.uuid())) return;
CEWorld ceWorld = new BukkitCEWorld(world, this.storageAdaptor);
this.worlds.put(world.uuid(), ceWorld);
this.resetWorldArray();
for (Chunk chunk : ((World) world.platformWorld()).getLoadedChunks()) {
handleChunkLoad(ceWorld, chunk);
}
ceWorld.setTicking(true);
}
@Override
public void loadWorld(CEWorld world) {
this.worldMapLock.writeLock().lock();
try {
if (this.worlds.containsKey(world.world().uuid())) return;
this.worlds.put(world.world().uuid(), world);
this.resetWorldArray();
for (Chunk chunk : ((World) world.world().platformWorld()).getLoadedChunks()) {
handleChunkLoad(world, chunk);
}
world.setTicking(true);
} finally {
this.worldMapLock.writeLock().unlock();
if (this.worlds.containsKey(world.world().uuid())) return;
this.worlds.put(world.world().uuid(), world);
this.resetWorldArray();
for (Chunk chunk : ((World) world.world().platformWorld()).getLoadedChunks()) {
handleChunkLoad(world, chunk);
}
world.setTicking(true);
}
@Override
@@ -198,20 +164,11 @@ public class BukkitWorldManager implements WorldManager, Listener {
@Override
public void unloadWorld(net.momirealms.craftengine.core.world.World world) {
CEWorld ceWorld;
this.worldMapLock.writeLock().lock();
try {
ceWorld = this.worlds.remove(world.uuid());
if (ceWorld == null) {
return;
}
if (ceWorld == this.lastVisitedWorld) {
this.lastVisitedWorld = null;
this.lastVisitedUUID = null;
}
this.resetWorldArray();
} finally {
this.worldMapLock.writeLock().unlock();
ceWorld = this.worlds.remove(world.uuid());
if (ceWorld == null) {
return;
}
this.resetWorldArray();
ceWorld.setTicking(false);
for (Chunk chunk : ((World) world.platformWorld()).getLoadedChunks()) {
handleChunkUnload(ceWorld, chunk);
@@ -238,30 +195,18 @@ public class BukkitWorldManager implements WorldManager, Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onChunkLoad(ChunkLoadEvent event) {
this.worldMapLock.readLock().lock();
CEWorld world;
try {
world = worlds.get(event.getWorld().getUID());
if (world == null) {
return;
}
} finally {
this.worldMapLock.readLock().unlock();
CEWorld world = worlds.get(event.getWorld().getUID());
if (world == null) {
return;
}
handleChunkLoad(world, event.getChunk());
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onChunkUnload(ChunkUnloadEvent event) {
CEWorld world;
this.worldMapLock.readLock().lock();
try {
world = worlds.get(event.getWorld().getUID());
if (world == null) {
return;
}
} finally {
this.worldMapLock.readLock().unlock();
CEWorld world = worlds.get(event.getWorld().getUID());
if (world == null) {
return;
}
handleChunkUnload(world, event.getChunk());
}