use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeCommon by SpongePowered.
the class SpongeBlockSnapshot method restore.
@Override
public boolean restore(boolean force, BlockChangeFlag flag) {
if (!SpongeImpl.getGame().getServer().getWorld(this.worldUniqueId).isPresent()) {
return false;
}
WorldServer world = (WorldServer) SpongeImpl.getGame().getServer().getWorld(this.worldUniqueId).get();
final IMixinWorldServer mixinWorldServer = (IMixinWorldServer) world;
// this way we guarantee an exit.
try (PhaseContext<?> context = BlockPhase.State.RESTORING_BLOCKS.createPhaseContext().buildAndSwitch()) {
BlockPos pos = VecHelper.toBlockPos(this.pos);
IBlockState current = world.getBlockState(pos);
IBlockState replaced = (IBlockState) this.blockState;
if (!force && (current.getBlock() != replaced.getBlock() || current.getBlock().getMetaFromState(current) != replaced.getBlock().getMetaFromState(replaced))) {
return false;
}
// Prevent Shulker Boxes from dropping when restoring BlockSnapshot
if (current.getBlock().getClass() == BlockShulkerBox.class) {
world.removeTileEntity(pos);
}
mixinWorldServer.setBlockState(pos, replaced, flag);
world.getPlayerChunkMap().markBlockForUpdate(pos);
if (this.compound != null) {
final TileEntity te = world.getTileEntity(pos);
if (te != null) {
te.readFromNBT(this.compound);
te.markDirty();
}
}
return true;
}
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeForge by SpongePowered.
the class MixinMinecraftServer method stopServer.
/**
* @author Zidane - Chris Sanders
* @reason Overwrite to take control of the stopping process and direct to WorldManager
*/
@Overwrite
public void stopServer() {
LOGGER.info("Stopping server");
// Sponge Start - Force player profile cache save
((MinecraftServer) (Object) this).getPlayerProfileCache().save();
final MinecraftServer server = (MinecraftServer) (Object) this;
if (server.getNetworkSystem() != null) {
server.getNetworkSystem().terminateEndpoints();
}
if (server.getPlayerList() != null) {
LOGGER.info("Saving players");
server.getPlayerList().saveAllPlayerData();
server.getPlayerList().removeAllPlayers();
}
if (server.worlds != null) {
LOGGER.info("Saving worlds");
for (WorldServer worldserver : server.worlds) {
if (worldserver != null) {
worldserver.disableLevelSaving = false;
}
}
server.saveAllWorlds(false);
for (WorldServer worldserver1 : server.worlds) {
if (worldserver1 != null) {
// Turn off Async Lighting
if (SpongeImpl.getGlobalConfig().getConfig().getModules().useOptimizations() && SpongeImpl.getGlobalConfig().getConfig().getOptimizations().useAsyncLighting()) {
((IMixinWorldServer) worldserver1).getLightingExecutor().shutdown();
try {
((IMixinWorldServer) worldserver1).getLightingExecutor().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
((IMixinWorldServer) worldserver1).getLightingExecutor().shutdownNow();
}
}
// Direct to WorldManager for unload
WorldManager.unloadWorld(worldserver1, false);
// Sponge End
worldserver1.flush();
}
}
}
if (usageSnooper.isSnooperRunning()) {
this.usageSnooper.stopSnooper();
}
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeForge by SpongePowered.
the class MixinDimensionManager method getIDs.
/**
* Gets loaded dimension ids
* @param check Check for leaked worlds
* @return An array of loaded dimension ids
*/
@Overwrite
public static Integer[] getIDs(boolean check) {
if (check) {
final List<WorldServer> candidateLeakedWorlds = new ArrayList<>(WorldManager.getWeakWorldMap().values());
candidateLeakedWorlds.removeAll(WorldManager.getWorlds());
leakedWorlds.addAll(candidateLeakedWorlds.stream().map(System::identityHashCode).collect(Collectors.toList()));
for (WorldServer worldServer : WorldManager.getWorlds()) {
final int hashCode = System.identityHashCode(worldServer);
final int leakCount = leakedWorlds.count(hashCode);
// Log every 5 loops
if (leakCount > 0 && leakCount % 5 == 0) {
SpongeImpl.getLogger().warn("World [{}] (DIM{}) (HASH: {}) may have leaked. Encountered [{}] times", worldServer.getWorldInfo().getWorldName(), ((IMixinWorldServer) worldServer).getDimensionId(), hashCode, leakCount);
}
}
}
return getIDs();
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeVanilla by SpongePowered.
the class MixinMinecraftServer method updateTimeLightAndEntities.
/**
* @author Zidane
* @reason Handles ticking the additional worlds loaded by Sponge.
*/
@Overwrite
public void updateTimeLightAndEntities() {
this.profiler.startSection("jobs");
synchronized (this.futureTaskQueue) {
while (!this.futureTaskQueue.isEmpty()) {
Util.runTask(this.futureTaskQueue.poll(), LOGGER);
}
}
this.profiler.endStartSection("levels");
// Sponge: Tick chunk loader
tickChunkLoader();
// Sponge start - Iterate over all our dimensions
for (final ObjectIterator<Int2ObjectMap.Entry<WorldServer>> it = WorldManager.worldsIterator(); it.hasNext(); ) {
Int2ObjectMap.Entry<WorldServer> entry = it.next();
final WorldServer worldServer = entry.getValue();
// Sponge end
long i = System.nanoTime();
if (entry.getIntKey() == 0 || this.getAllowNether()) {
// Sponge start - copy from SpongeCommon MixinMinecraftServer
IMixinWorldServer spongeWorld = (IMixinWorldServer) worldServer;
if (spongeWorld.getChunkGCTickInterval() > 0) {
spongeWorld.doChunkGC();
}
// Sponge end
this.profiler.startSection(worldServer.getWorldInfo().getWorldName());
if (this.tickCounter % 20 == 0) {
this.profiler.startSection("timeSync");
this.playerList.sendPacketToAllPlayersInDimension(new SPacketTimeUpdate(worldServer.getTotalWorldTime(), worldServer.getWorldTime(), worldServer.getGameRules().getBoolean("doDaylightCycle")), ((IMixinWorldServer) worldServer).getDimensionId());
this.profiler.endSection();
}
this.profiler.startSection("tick");
try {
worldServer.tick();
} catch (Throwable throwable1) {
CrashReport crashreport = CrashReport.makeCrashReport(throwable1, "Exception ticking world");
worldServer.addWorldInfoToCrashReport(crashreport);
throw new ReportedException(crashreport);
}
try {
worldServer.updateEntities();
} catch (Throwable throwable) {
CrashReport crashreport1 = CrashReport.makeCrashReport(throwable, "Exception ticking world entities");
worldServer.addWorldInfoToCrashReport(crashreport1);
throw new ReportedException(crashreport1);
}
this.profiler.endSection();
this.profiler.startSection("tracker");
// Sponge start - copy from SpongeCommon MixinMinecraftServer
if (spongeWorld.getChunkGCTickInterval() > 0) {
worldServer.getChunkProvider().tick();
}
// Sponge end
worldServer.getEntityTracker().tick();
this.profiler.endSection();
this.profiler.endSection();
}
// Sponge start - Write tick times to our custom map
this.worldTickTimes.get(entry.getIntKey())[this.tickCounter % 100] = System.nanoTime() - i;
// Sponge end
}
// Sponge start - Unload requested worlds
this.profiler.endStartSection("dim_unloading");
WorldManager.unloadQueuedWorlds();
// Sponge end
this.profiler.endStartSection("connection");
this.getNetworkSystem().networkTick();
this.profiler.endStartSection("players");
this.playerList.onTick();
this.profiler.endStartSection("tickables");
for (int k = 0; k < this.tickables.size(); ++k) {
this.tickables.get(k).update();
}
this.profiler.endSection();
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeVanilla by SpongePowered.
the class MixinMinecraftServer method stopServer.
/**
* @author Zidane - Chris Sanders
*/
@Overwrite
public void stopServer() {
// stopServer is called from both the shutdown hook AND the finally statement in the main game loop, no reason to do this twice..
if (skipServerStop) {
return;
}
skipServerStop = true;
LOGGER.info("Stopping server");
spongeVanilla.onServerStopping();
final MinecraftServer server = (MinecraftServer) (Object) this;
// Sponge Start - Force player profile cache save
server.getPlayerProfileCache().save();
if (this.getNetworkSystem() != null) {
this.getNetworkSystem().terminateEndpoints();
}
if (this.playerList != null) {
LOGGER.info("Saving players");
this.playerList.saveAllPlayerData();
this.playerList.removeAllPlayers();
}
if (server.worlds != null) {
LOGGER.info("Saving worlds");
for (WorldServer worldserver : server.worlds) {
if (worldserver != null) {
worldserver.disableLevelSaving = false;
}
}
server.saveAllWorlds(false);
for (WorldServer worldserver1 : server.worlds) {
if (worldserver1 != null) {
// Turn off Async Lighting
if (SpongeImpl.getGlobalConfig().getConfig().getModules().useOptimizations() && SpongeImpl.getGlobalConfig().getConfig().getOptimizations().useAsyncLighting()) {
((IMixinWorldServer) worldserver1).getLightingExecutor().shutdown();
try {
((IMixinWorldServer) worldserver1).getLightingExecutor().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
((IMixinWorldServer) worldserver1).getLightingExecutor().shutdownNow();
}
}
WorldManager.unloadWorld(worldserver1, false);
}
}
if (this.usageSnooper.isSnooperRunning()) {
this.usageSnooper.stopSnooper();
}
}
}
Aggregations