use of net.minecraft.ReportedException in project SpongeCommon by SpongePowered.
the class SpongeWorldManager method prepareWorld.
private ServerLevel prepareWorld(final ServerLevel world, final boolean isDebugGeneration) {
final boolean isDefaultWorld = Level.OVERWORLD.equals(world.dimension());
final PrimaryLevelData levelData = (PrimaryLevelData) world.getLevelData();
if (isDefaultWorld) {
// Initialize scoreboard data. This will hook to the ServerScoreboard, needs to be made multi-world aware
((MinecraftServerAccessor) this.server).accessor$readScoreboard(world.getDataStorage());
((MinecraftServerAccessor) this.server).accessor$commandStorage(new CommandStorage(world.getDataStorage()));
}
final boolean isInitialized = levelData.isInitialized();
SpongeCommon.post(SpongeEventFactory.createLoadWorldEvent(PhaseTracker.getCauseStackManager().currentCause(), (org.spongepowered.api.world.server.ServerWorld) world, isInitialized));
PlatformHooks.INSTANCE.getWorldHooks().postLoadWorld(world);
// Set the view distance back on it's self to trigger the logic
((PrimaryLevelDataBridge) world.getLevelData()).bridge$viewDistance().ifPresent(v -> ((PrimaryLevelDataBridge) world.getLevelData()).bridge$setViewDistance(v));
world.getWorldBorder().applySettings(levelData.getWorldBorder());
if (!isInitialized) {
try {
final boolean hasSpawnAlready = ((PrimaryLevelDataBridge) world.getLevelData()).bridge$customSpawnPosition();
if (!hasSpawnAlready) {
if (isDefaultWorld || ((ServerWorldProperties) world.getLevelData()).performsSpawnLogic()) {
MinecraftServerAccessor.invoker$setInitialSpawn(world, levelData, levelData.worldGenSettings().generateBonusChest(), isDebugGeneration, !isDebugGeneration);
} else if (Level.END.equals(world.dimension())) {
((PrimaryLevelData) world.getLevelData()).setSpawn(ServerLevel.END_SPAWN_POINT, 0);
}
} else {
Features.BONUS_CHEST.place(world, world.getChunkSource().getGenerator(), world.random, new BlockPos(levelData.getXSpawn(), levelData.getYSpawn(), levelData.getZSpawn()));
}
levelData.setInitialized(true);
if (isDebugGeneration) {
((MinecraftServerAccessor) this.server).invoker$setupDebugLevel(levelData);
}
} catch (final Throwable throwable) {
final CrashReport crashReport = CrashReport.forThrowable(throwable, "Exception initializing world '" + world.dimension().location() + "'");
try {
world.fillReportDetails(crashReport);
} catch (final Throwable ignore) {
}
throw new ReportedException(crashReport);
}
levelData.setInitialized(true);
}
// Initialize PlayerData in PlayerList, add WorldBorder listener. We change the method in PlayerList to handle per-world border
this.server.getPlayerList().setLevel(world);
if (levelData.getCustomBossEvents() != null) {
((ServerLevelBridge) world).bridge$getBossBarManager().load(levelData.getCustomBossEvents());
}
return world;
}
use of net.minecraft.ReportedException in project SpongeCommon by SpongePowered.
the class ServerLevelMixin_Tracker method shadow$neighborChanged.
@Override
public void shadow$neighborChanged(final BlockPos pos, final Block blockIn, final BlockPos fromPos) {
final BlockPos immutableTarget = pos.immutable();
final BlockPos immutableFrom = fromPos.immutable();
// Sponge Start - Check asynchronicity,
// if not on the server thread and we're a server world, we've got problems...
final PhaseTracker server = PhaseTracker.SERVER;
if (server.getSidedThread() != Thread.currentThread()) {
// lol no, report the block change properly
new PrettyPrinter(60).add("Illegal Async PhaseTracker Access").centre().hr().addWrapped(PhasePrinter.ASYNC_TRACKER_ACCESS).add().add(new Exception("Async Block Notifcation Detected")).log(SpongeCommon.logger(), Level.ERROR);
// Maybe? I don't think this is wise to try and sync back a notification on the main thread.
return;
}
// world that Sponge isn't directly managing, so we'll just ignore trying to record on those.
if (this.bridge$isFake()) {
// If we're fake, well, we could effectively call this without recording on worlds we don't
// want to care about.
super.shadow$neighborChanged(immutableTarget, blockIn, immutableFrom);
return;
}
// Otherwise, we continue with recording, maybe.
final LevelChunk targetChunk = this.shadow$getChunkAt(immutableTarget);
final BlockState targetBlockState = targetChunk.getBlockState(immutableTarget);
// Sponge - Shortcircuit if the block has no neighbor logic
if (!((TrackableBlockBridge) targetBlockState.getBlock()).bridge$overridesNeighborNotificationLogic()) {
return;
}
// Sponge End
// Sponge start - prepare notification
final PhaseContext<@NonNull ?> peek = server.getPhaseContext();
// try { // Vanilla - We need to push the effect transactor so that it always pops
try {
final Supplier<ServerLevel> worldSupplier = VolumeStreamUtils.createWeaklyReferencedSupplier((ServerLevel) (Object) this, "ServerWorld");
final net.minecraft.world.level.block.entity.@Nullable BlockEntity existingTile = targetChunk.getBlockEntity(immutableTarget, LevelChunk.EntityCreationType.CHECK);
peek.getTransactor().logNeighborNotification(worldSupplier, immutableFrom, blockIn, immutableTarget, targetBlockState, existingTile);
peek.associateNeighborStateNotifier(immutableFrom, targetBlockState.getBlock(), immutableTarget, ((ServerLevel) (Object) this), PlayerTracker.Type.NOTIFIER);
// Sponge End
targetBlockState.neighborChanged(((ServerLevel) (Object) this), immutableTarget, blockIn, immutableFrom, false);
} catch (final Throwable throwable) {
final CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception while updating neighbours");
final CrashReportCategory crashreportcategory = crashreport.addCategory("Block being updated");
crashreportcategory.setDetail("Source block type", () -> {
try {
return String.format("ID #%d (%s // %s)", Registry.BLOCK.getId(blockIn), blockIn.getDescriptionId(), blockIn.getClass().getCanonicalName());
} catch (final Throwable var2) {
return "ID #" + Registry.BLOCK.getId(blockIn);
}
});
CrashReportCategory.populateBlockDetails(crashreportcategory, immutableTarget, targetBlockState);
throw new ReportedException(crashreport);
}
}
Aggregations