use of net.minecraft.server.level.ServerLevel in project SpongeCommon by SpongePowered.
the class PrimaryLevelDataMixin method bridge$world.
@Override
@Nullable
public ServerLevel bridge$world() {
if (!Sponge.isServerAvailable()) {
return null;
}
final ServerLevel world = SpongeCommon.server().getLevel(SpongeWorldManager.createRegistryKey(this.impl$key));
if (world == null) {
return null;
}
final ServerLevelData levelData = (ServerLevelData) world.getLevelData();
if (levelData != this) {
return null;
}
return world;
}
use of net.minecraft.server.level.ServerLevel in project SpongeCommon by SpongePowered.
the class SpongeBlockSnapshot method restore.
@Override
public boolean restore(final boolean force, final BlockChangeFlag flag) {
// TODO - rewrite with the PhaseTracker being the hook or use SpongeImplHooks to do the restore.
final Optional<ServerLevel> optionalWorld = Optional.ofNullable(this.world.get());
if (!optionalWorld.isPresent()) {
return false;
}
final ServerLevel world = optionalWorld.get();
// this way we guarantee an exit.
try (final PhaseContext<?> context = BlockPhase.State.RESTORING_BLOCKS.createPhaseContext(PhaseTracker.SERVER)) {
context.buildAndSwitch();
final BlockPos pos = VecHelper.toBlockPos(this.pos);
if (!net.minecraft.world.level.Level.isInWorldBounds(pos)) {
// Invalid position. Inline this check
return false;
}
final net.minecraft.world.level.block.state.BlockState current = world.getBlockState(pos);
final net.minecraft.world.level.block.state.BlockState replaced = (net.minecraft.world.level.block.state.BlockState) this.blockState;
if (!force && (current.getBlock() != replaced.getBlock() || current != replaced)) {
return false;
}
// being created during block change removals
if (!current.is(((net.minecraft.world.level.block.state.BlockState) this.blockState).getBlock())) {
world.removeBlockEntity(pos);
}
world.setBlock(pos, replaced, BlockChangeFlagManager.andNotifyClients(flag).getRawFlag());
if (this.compound != null) {
@Nullable BlockEntity te = world.getBlockEntity(pos);
if (te != null) {
te.load((net.minecraft.world.level.block.state.BlockState) this.blockState, this.compound);
} else {
// In cases like this, we need to directly just say "fuck it" and deserialize from the compound directly.
try {
te = BlockEntity.loadStatic((net.minecraft.world.level.block.state.BlockState) this.blockState, this.compound);
if (te != null) {
world.getChunk(pos).setBlockEntity(pos, te);
}
} catch (final Exception e) {
// Seriously? The mod should be broken then.
final PrettyPrinter printer = new PrettyPrinter(60).add("Unable to restore").centre().hr().add("A mod is not correctly deserializing a TileEntity that is being restored. ").addWrapped(60, "Note that this is not the fault of Sponge. Sponge is understanding that " + "a block is supposed to have a TileEntity, but the mod is breaking the contract" + "on how to re-create the tile entity. Please open an issue with the offending mod.").add("Here's the provided compound:");
printer.add();
try {
printer.addWrapped(80, "%s : %s", "This compound", this.compound);
} catch (final Throwable error) {
printer.addWrapped(80, "Unable to get the string of this compound. Printing out some of the entries to better assist");
}
printer.add().add("Desired World: " + this.worldKey).add("Position: " + this.pos).add("Desired BlockState: " + this.blockState);
printer.add();
printer.log(SpongeCommon.logger(), Level.ERROR);
// I mean, I guess. the block was set up, but not the tile entity.
return true;
}
}
if (te != null) {
te.setChanged();
}
}
// Finally, mark the location as being updated.
world.getChunkSource().blockChanged(pos);
return true;
}
}
use of net.minecraft.server.level.ServerLevel in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method fireCreateMapEvent.
public static Optional<MapInfo> fireCreateMapEvent(final Cause cause, final Set<Value<?>> values) {
final ServerLevel defaultWorld = (ServerLevel) Sponge.server().worldManager().defaultWorld();
final MapIdTrackerBridge mapIdTrackerBridge = (MapIdTrackerBridge) defaultWorld.getDataStorage().computeIfAbsent(MapIndex::new, Constants.Map.MAP_INDEX_DATA_NAME);
final int id = mapIdTrackerBridge.bridge$getHighestMapId().orElse(-1) + 1;
final String s = Constants.Map.MAP_PREFIX + id;
final MapItemSavedData mapData = new MapItemSavedData(s);
// Set default to prevent NPEs
mapData.dimension = Level.OVERWORLD;
final MapInfo mapInfo = (MapInfo) mapData;
for (final Value<?> value : values) {
mapInfo.offer(value);
}
final CreateMapEvent event = SpongeEventFactory.createCreateMapEvent(cause, mapInfo);
SpongeCommon.post(event);
if (event.isCancelled()) {
return Optional.empty();
}
// Advance map id.
final int mcId = defaultWorld.getFreeMapId();
if (id != mcId) {
// TODO: REMOVE OR replace for Integer.MAX_VALUE
SpongeCommon.logger().warn("Map size corruption, vanilla only allows " + Integer.MAX_VALUE + "! " + "Expected next number was not equal to the true next number.");
SpongeCommon.logger().warn("Expected: " + id + ". Got: " + mcId);
SpongeCommon.logger().warn("Automatically cancelling map creation");
mapIdTrackerBridge.bridge$setHighestMapId(id - 1);
return Optional.empty();
}
defaultWorld.setMapData(mapData);
((SpongeMapStorage) Sponge.server().mapStorage()).addMapInfo(mapInfo);
return Optional.of(mapInfo);
}
use of net.minecraft.server.level.ServerLevel in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method handlePistonEvent.
/**
* This simulates the blocks a piston moves and calls the event for saner
* debugging.
*
* @return if the event was cancelled
*/
public static boolean handlePistonEvent(final TrackedWorldBridge world, final BlockPos pos, final net.minecraft.world.level.block.state.BlockState blockstate, final int eventId) {
final boolean extending = (eventId == 0);
final net.minecraft.core.Direction direction = blockstate.getValue(DirectionalBlock.FACING);
final LocatableBlock locatable = new SpongeLocatableBlockBuilder().world((ServerWorld) world).state((BlockState) blockstate).position(pos.getX(), pos.getY(), pos.getZ()).build();
// Sets toss out duplicate values (even though there shouldn't be any)
final HashSet<ServerLocation> locations = new HashSet<>();
locations.add(ServerLocation.of((ServerWorld) world, pos.getX(), pos.getY(), pos.getZ()));
final PistonStructureResolver movedBlocks = new PistonStructureResolver((ServerLevel) world, pos, direction, extending);
// calculates blocks to be moved
movedBlocks.resolve();
Stream.concat(movedBlocks.getToPush().stream(), movedBlocks.getToDestroy().stream()).map(block -> ServerLocation.of((ServerWorld) world, block.getX(), block.getY(), block.getZ())).collect(// SUPER
Collectors.toCollection(() -> locations));
// If the piston is extending and there are no blocks to destroy, add the offset location for protection purposes
if (extending && movedBlocks.getToDestroy().isEmpty()) {
final List<BlockPos> movedPositions = movedBlocks.getToPush();
final BlockPos offsetPos;
// If there are no blocks to move, add the offset of piston
if (movedPositions.isEmpty()) {
offsetPos = pos.relative(direction);
} else {
// Add the offset of last block set to move
offsetPos = movedPositions.get(movedPositions.size() - 1).relative(direction);
}
locations.add(ServerLocation.of((ServerWorld) world, offsetPos.getX(), offsetPos.getY(), offsetPos.getZ()));
}
try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) {
if (extending) {
frame.addContext(EventContextKeys.PISTON_EXTEND, (ServerWorld) world);
} else {
frame.addContext(EventContextKeys.PISTON_RETRACT, (ServerWorld) world);
}
return SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) world, ImmutableList.copyOf(locations), locatable).isCancelled();
}
}
use of net.minecraft.server.level.ServerLevel in project SpongeCommon by SpongePowered.
the class SpongeWorldManager method unloadWorld.
@Override
public CompletableFuture<Boolean> unloadWorld(final ResourceKey key) {
final net.minecraft.resources.ResourceKey<Level> registryKey = SpongeWorldManager.createRegistryKey(Objects.requireNonNull(key, "key"));
if (Level.OVERWORLD.equals(registryKey)) {
return CompletableFuture.completedFuture(false);
}
final ServerLevel world = this.worlds.get(registryKey);
if (world == null) {
return CompletableFuture.completedFuture(false);
}
return this.unloadWorld((org.spongepowered.api.world.server.ServerWorld) world);
}
Aggregations