use of org.checkerframework.checker.nullness.qual.Nullable in project SpongeCommon by SpongePowered.
the class SpongeBlockEntityArchetype method apply.
@Override
public Optional<BlockEntity> apply(final ServerLocation location) {
final BlockState currentState = location.block();
final Block currentBlock = ((net.minecraft.world.level.block.state.BlockState) currentState).getBlock();
final Block newBlock = ((net.minecraft.world.level.block.state.BlockState) this.blockState).getBlock();
final Level minecraftWorld = (net.minecraft.world.level.Level) location.world();
final BlockPos blockpos = VecHelper.toBlockPos(location);
if (currentBlock != newBlock) {
((org.spongepowered.api.world.World) minecraftWorld).setBlock(blockpos.getX(), blockpos.getY(), blockpos.getZ(), this.blockState, BlockChangeFlags.ALL);
}
final CompoundTag compound = this.compound.copy();
final net.minecraft.world.level.block.entity.@Nullable BlockEntity tileEntity = minecraftWorld.getBlockEntity(blockpos);
if (tileEntity == null) {
return Optional.empty();
}
compound.putInt(Constants.TileEntity.X_POS, blockpos.getX());
compound.putInt(Constants.TileEntity.Y_POS, blockpos.getY());
compound.putInt(Constants.TileEntity.Z_POS, blockpos.getZ());
tileEntity.load((net.minecraft.world.level.block.state.BlockState) currentState, compound);
tileEntity.clearCache();
return Optional.of((org.spongepowered.api.block.entity.BlockEntity) tileEntity);
}
use of org.checkerframework.checker.nullness.qual.Nullable in project SpongeCommon by SpongePowered.
the class SpongeEventManager method createRegistration.
@SuppressWarnings({ "unchecked", "rawtypes" })
private static <T extends Event> RegisteredListener<T> createRegistration(final PluginContainer plugin, final Type eventType, final Order order, final boolean beforeModifications, final EventListener<? super T> handler) {
@Nullable Type genericType = null;
final Class<?> erased = GenericTypeReflector.erase(eventType);
if (GenericEvent.class.isAssignableFrom(erased)) {
genericType = TypeTokenUtil.typeArgumentFromSupertype(eventType, GenericEvent.class, 0);
}
return new RegisteredListener(plugin, new EventType(erased, genericType), order, handler, beforeModifications);
}
use of org.checkerframework.checker.nullness.qual.Nullable in project SpongeCommon by SpongePowered.
the class PhaseTracker method popCauseFrame.
@Override
public void popCauseFrame(final StackFrame oldFrame) {
checkNotNull(oldFrame, "oldFrame");
this.enforceMainThread();
@Nullable final SpongeCauseStackFrame frame = this.frames.peek();
if (frame != oldFrame) {
// If the given frame is not the top frame then some form of
// corruption of the stack has occurred and we do our best to correct
// it.
// If the target frame is still in the stack then we can pop frames
// off the stack until we reach it, otherwise we have no choice but
// to simply throw an error.
int offset = -1;
int i = 0;
for (final SpongeCauseStackFrame f : this.frames) {
if (f == oldFrame) {
offset = i;
break;
}
i++;
}
if (!PhaseTracker.DEBUG_CAUSE_FRAMES && offset == -1) {
// that was erroneously popped.
throw new IllegalStateException("Cause Stack Frame Corruption! Attempted to pop a frame that was not on the stack.");
}
final PrettyPrinter printer = new PrettyPrinter(100).add("Cause Stack Frame Corruption!").centre().hr().add("Found %d frames left on the stack. Clearing them all.", new Object[] { offset + 1 });
if (!PhaseTracker.DEBUG_CAUSE_FRAMES) {
printer.add().add("Please add -Dsponge.debugcauseframes=true to your startup flags to enable further debugging output.");
SpongeCommon.logger().warn(" Add -Dsponge.debugcauseframes to your startup flags to enable further debugging output.");
} else {
printer.add().add("Attempting to pop frame:").add(frame.stackDebug).add().add("Frames being popped are:").add(((SpongeCauseStackFrame) oldFrame).stackDebug);
}
while (offset >= 0) {
@Nullable final SpongeCauseStackFrame f = this.frames.peek();
if (PhaseTracker.DEBUG_CAUSE_FRAMES && offset > 0) {
printer.add(" Stack frame in position %d :", new Object[] { offset });
printer.add(f.stackDebug);
}
this.popCauseFrame(f);
offset--;
}
printer.trace(System.err, SpongeCommon.logger(), Level.ERROR);
if (offset == -1) {
// so we throw an exception.
throw new IllegalStateException("Cause Stack Frame Corruption! Attempted to pop a frame that was not on the stack.");
}
return;
}
this.frames.pop();
// Remove new values
for (final Map.Entry<EventContextKey<?>, Object> entry : frame.getOriginalContextDelta().entrySet()) {
this.cached_ctx = null;
if (entry.getValue() == null) {
// wasn't present before, remove
this.ctx.remove(entry.getKey());
} else {
// was there, replace
this.ctx.put(entry.getKey(), entry.getValue());
}
}
// If there were any objects left on the stack then we pop them off
while (this.cause.size() > this.min_depth) {
final int index = this.cause.size();
// there was a duplicate cause pushed prior to the frame being popped.
if (this.duplicateCauses.length > index) {
// At this point, we now need to "clean" the duplicate causes array of duplicates
// to avoid potentially pruning earlier frame's potentially duplicate causes.
// And of course, reset the number of duplicates in the entry.
this.duplicateCauses[index] = 0;
}
this.cause.pop();
// and clear the cached causes
this.cached_cause = null;
}
this.min_depth = frame.old_min_depth;
final int size = this.cause.size();
if (this.duplicateCauses.length > size) {
// Then set the last cause index to whatever the size of the entry was at the time.
this.duplicateCauses[size] = frame.lastCauseSize;
}
// finally, return the frame to the pool
if (this.framePool.size() < PhaseTracker.MAX_POOL_SIZE) {
// cache it, but also call clear so we remove references to
// other objects that may go out of scope
frame.clear();
this.framePool.push(frame);
}
}
use of org.checkerframework.checker.nullness.qual.Nullable in project SpongeCommon by SpongePowered.
the class PhaseTracker method completePhase.
@SuppressWarnings({ "rawtypes", "unused", "try" })
void completePhase(final PhaseContext<?> context) {
if (context.createdTracker != this && Thread.currentThread() != this.getSidedThread()) {
// 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 Change Detected")).log(SpongeCommon.logger(), Level.ERROR);
return;
}
final PhaseContext<?> currentContext = this.stack.peek();
final IPhaseState<?> state = currentContext.state;
final boolean isEmpty = this.stack.isEmpty();
if (isEmpty) {
// The random occurrence that we're told to complete a phase
// while a world is being changed unknowingly.
PhasePrinter.printEmptyStackOnCompletion(currentContext);
return;
}
if (context.state != state) {
PhasePrinter.printIncorrectPhaseCompletion(this.stack, context.state, state);
// The phase on the top of the stack was most likely never completed.
// Since we don't know when and where completePhase was intended to be called for it,
// we simply pop it to allow processing to continue (somewhat) as normal
this.stack.pop();
return;
}
if (SpongeConfigs.getCommon().get().phaseTracker.verbose) {
if (this.stack.checkForRunaways(GeneralPhase.Post.UNWINDING, null)) {
// This printing is to detect possibilities of a phase not being cleared properly
// and resulting in a "runaway" phase state accumulation.
PhasePrinter.printRunAwayPhaseCompletion(this.stack, state);
}
}
final boolean hasCaptures = currentContext.hasCaptures();
try (@Nullable final UnwindingPhaseContext unwinding = UnwindingPhaseContext.unwind(currentContext, hasCaptures)) {
// a new list of capture lists
try {
// loss of objects
if (hasCaptures) {
((IPhaseState) state).unwind(currentContext);
}
} catch (final Exception e) {
PhasePrinter.printMessageWithCaughtException(this.stack, "Exception Exiting Phase", "Something happened when trying to unwind", state, currentContext, e);
}
} catch (final Exception e) {
PhasePrinter.printMessageWithCaughtException(this.stack, "Exception Post Dispatching Phase", "Something happened when trying to post dispatch state", state, currentContext, e);
}
this.checkPhaseContextProcessed(state, currentContext);
// If pop is called, the Deque will already throw an exception if there is no element
// so it's an error properly handled.
this.stack.pop();
}
use of org.checkerframework.checker.nullness.qual.Nullable in project SpongeCommon by SpongePowered.
the class PhaseTracker method validateBlockForNeighborNotification.
public static Block validateBlockForNeighborNotification(final ServerLevel worldServer, final BlockPos pos, @Nullable Block blockIn, final BlockPos otherPos, final LevelChunk chunk) {
if (blockIn == null) {
// If the block is null, check with the PhaseState to see if it can perform a safe way
final PhaseContext<?> currentContext = PhaseTracker.getInstance().getPhaseContext();
final PhaseTrackerCategory trackerConfig = SpongeConfigs.getCommon().get().phaseTracker;
if (currentContext.state == TickPhase.Tick.TILE_ENTITY) {
// Try to save ourselves
@Nullable final BlockEntity source = (BlockEntity) currentContext.getSource();
@Nullable final BlockEntityType<?> type = Optional.ofNullable(source).map(BlockEntity::getType).orElse(null);
if (type != null) {
@Nullable ResourceLocation id = BlockEntityType.getKey(type);
if (id == null) {
id = new ResourceLocation(source.getClass().getCanonicalName());
}
final Map<String, Boolean> autoFixedTiles = trackerConfig.autoFixNullSourceBlockProvidingBlockEntities;
final boolean contained = autoFixedTiles.containsKey(type.toString());
// based on whether the source is the same as the TileEntity.
if (!contained) {
autoFixedTiles.put(id.toString(), pos.equals(source.getBlockPos()));
}
final boolean useTile = contained && autoFixedTiles.get(id.toString());
if (useTile) {
blockIn = source.getBlockState().getBlock();
} else {
blockIn = (pos.getX() >> 4 == chunk.getPos().x && pos.getZ() >> 4 == chunk.getPos().z) ? chunk.getBlockState(pos).getBlock() : worldServer.getBlockState(pos).getBlock();
}
if (!contained && trackerConfig.reportNullSourceBlocksOnNeighborNotifications) {
PhasePrinter.printNullSourceBlockWithTile(pos, blockIn, otherPos, id, useTile, new NullPointerException("Null Source Block For TileEntity Neighbor Notification"));
}
} else {
blockIn = (pos.getX() >> 4 == chunk.getPos().x && pos.getZ() >> 4 == chunk.getPos().z) ? chunk.getBlockState(pos).getBlock() : worldServer.getBlockState(pos).getBlock();
if (trackerConfig.reportNullSourceBlocksOnNeighborNotifications) {
PhasePrinter.printNullSourceBlockNeighborNotificationWithNoTileSource(pos, blockIn, otherPos, new NullPointerException("Null Source Block For Neighbor Notification"));
}
}
} else {
blockIn = (pos.getX() >> 4 == chunk.getPos().x && pos.getZ() >> 4 == chunk.getPos().z) ? chunk.getBlockState(pos).getBlock() : worldServer.getBlockState(pos).getBlock();
if (trackerConfig.reportNullSourceBlocksOnNeighborNotifications) {
PhasePrinter.printNullSourceForBlock(worldServer, pos, blockIn, otherPos, new NullPointerException("Null Source Block For Neighbor Notification"));
}
}
}
return blockIn;
}
Aggregations