use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeCommon by SpongePowered.
the class MixinMinecraftServer method saveAllWorlds.
/**
* @author blood - June 2nd, 2016
*
* @reason To allow per-world auto-save tick intervals or disable auto-saving entirely
*
* @param dontLog Whether to log during saving
*/
@Overwrite
public void saveAllWorlds(boolean dontLog) {
if (!this.enableSaving) {
return;
}
for (WorldServer worldserver : this.worlds) {
if (worldserver != null && !worldserver.disableLevelSaving) {
// Sponge start - check auto save interval in world config
if (this.isDedicatedServer() && this.isServerRunning()) {
final IMixinWorldServer spongeWorld = (IMixinWorldServer) worldserver;
final int autoSaveInterval = spongeWorld.getActiveConfig().getConfig().getWorld().getAutoSaveInterval();
final boolean logAutoSave = spongeWorld.getActiveConfig().getConfig().getLogging().worldAutoSaveLogging();
if (autoSaveInterval <= 0 || ((WorldProperties) worldserver.getWorldInfo()).getSerializationBehavior() != SerializationBehaviors.AUTOMATIC) {
if (logAutoSave) {
LOGGER.warn("Auto-saving has been disabled for level \'" + worldserver.getWorldInfo().getWorldName() + "\'/" + worldserver.provider.getDimensionType().getName() + ". " + "No chunk data will be auto-saved - to re-enable auto-saving set 'auto-save-interval' to a value greater than" + " zero in the corresponding world config.");
}
continue;
}
if (this.tickCounter % autoSaveInterval != 0) {
continue;
}
if (logAutoSave) {
LOGGER.info("Auto-saving chunks for level \'" + worldserver.getWorldInfo().getWorldName() + "\'/" + worldserver.provider.getDimensionType().getName());
}
} else if (!dontLog) {
LOGGER.info("Saving chunks for level \'" + worldserver.getWorldInfo().getWorldName() + "\'/" + worldserver.provider.getDimensionType().getName());
}
// Sponge end
try {
WorldManager.saveWorld(worldserver, false);
} catch (MinecraftException ex) {
ex.printStackTrace();
}
}
}
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer 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(IMixinWorldServer world, WorldServer.ServerBlockEventList list, Object obj, BlockPos pos, Block blockIn, int eventId, int eventParam) {
boolean extending = (eventId == 0);
final IBlockState blockstate = ((net.minecraft.world.World) world).getBlockState(pos);
EnumFacing direction = blockstate.getValue(BlockDirectional.FACING);
final LocatableBlock locatable = LocatableBlock.builder().location(new Location<>((World) world, pos.getX(), pos.getY(), pos.getZ())).state((BlockState) blockstate).build();
// Sets toss out duplicate values (even though there shouldn't be any)
HashSet<Location<org.spongepowered.api.world.World>> locations = new HashSet<>();
locations.add(new Location<>((World) world, pos.getX(), pos.getY(), pos.getZ()));
BlockPistonStructureHelper movedBlocks = new BlockPistonStructureHelper((WorldServer) world, pos, direction, extending);
// calculates blocks to be moved
movedBlocks.canMove();
Stream.concat(movedBlocks.getBlocksToMove().stream(), movedBlocks.getBlocksToDestroy().stream()).map(block -> new Location<>((World) 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.getBlocksToDestroy().isEmpty()) {
final List<BlockPos> movedPositions = movedBlocks.getBlocksToMove();
BlockPos offsetPos;
// If there are no blocks to move, add the offset of piston
if (movedPositions.isEmpty()) {
offsetPos = pos.offset(direction);
} else {
// Add the offset of last block set to move
offsetPos = movedPositions.get(movedPositions.size() - 1).offset(direction);
}
locations.add(new Location<>((World) world, offsetPos.getX(), offsetPos.getY(), offsetPos.getZ()));
}
try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
if (extending) {
Sponge.getCauseStackManager().addContext(EventContextKeys.PISTON_EXTEND, world.asSpongeWorld());
} else {
Sponge.getCauseStackManager().addContext(EventContextKeys.PISTON_RETRACT, world.asSpongeWorld());
}
return SpongeCommonEventFactory.callChangeBlockEventPre(world, ImmutableList.copyOf(locations), locatable).isCancelled();
}
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeCommon by SpongePowered.
the class MixinBlock method onDropBlockAsItemWithChanceHead.
// This method can be called directly by pistons, mods, etc. so the hook must go here
@Inject(method = "dropBlockAsItemWithChance", at = @At(value = "HEAD"), cancellable = true)
public void onDropBlockAsItemWithChanceHead(net.minecraft.world.World worldIn, BlockPos pos, IBlockState state, float chance, int fortune, CallbackInfo ci) {
if (!((IMixinWorld) worldIn).isFake()) {
if (PhaseTracker.getInstance().getCurrentState() == BlockPhase.State.RESTORING_BLOCKS) {
ci.cancel();
return;
}
final IMixinWorldServer mixinWorld = (IMixinWorldServer) worldIn;
final PhaseTracker phaseTracker = PhaseTracker.getInstance();
final IPhaseState<?> currentState = phaseTracker.getCurrentState();
final boolean shouldEnterBlockDropPhase = !phaseTracker.getCurrentContext().isCapturingBlockItemDrops() && !currentState.alreadyCapturingItemSpawns() && !currentState.isWorldGeneration();
if (shouldEnterBlockDropPhase) {
// TODO: Change source to LocatableBlock
PhaseContext<?> context = BlockPhase.State.BLOCK_DROP_ITEMS.createPhaseContext().source(mixinWorld.createSpongeBlockSnapshot(state, state, pos, BlockChangeFlags.PHYSICS_OBSERVER));
// unused, to be removed and re-located when phase context is cleaned up
// .add(NamedCause.of(InternalNamedCauses.General.BLOCK_BREAK_FORTUNE, fortune))
// .add(NamedCause.of(InternalNamedCauses.General.BLOCK_BREAK_POSITION, pos));
// use current notifier and owner if available
User notifier = phaseTracker.getCurrentContext().getNotifier().orElse(null);
User owner = phaseTracker.getCurrentContext().getOwner().orElse(null);
if (notifier != null) {
context.notifier(notifier);
}
if (owner != null) {
context.owner(owner);
}
context.buildAndSwitch();
}
}
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeCommon by SpongePowered.
the class MixinBlockDispenser method onDispenseHead.
@Inject(method = "dispense", at = @At(value = "HEAD"))
public void onDispenseHead(World worldIn, BlockPos pos, CallbackInfo ci) {
final IBlockState state = worldIn.getBlockState(pos);
final SpongeBlockSnapshot spongeBlockSnapshot = ((IMixinWorldServer) worldIn).createSpongeBlockSnapshot(state, state, pos, BlockChangeFlags.ALL);
final IMixinChunk mixinChunk = (IMixinChunk) worldIn.getChunkFromBlockCoords(pos);
this.context = BlockPhase.State.DISPENSE.createPhaseContext().source(spongeBlockSnapshot).owner(() -> mixinChunk.getBlockOwner(pos)).notifier(() -> mixinChunk.getBlockNotifier(pos)).buildAndSwitch();
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeCommon by SpongePowered.
the class PacketState method spawnEntity.
/**
* Defaulted method for packet phase states to spawn an entity directly.
* This should be overridden by all packet phase states that are handling spawns
* customarily with contexts and such. Captured entities are handled in
* their respective {@link PacketState#unwind(PhaseContext)}s.
*
* @param context
* @param entity
* @param chunkX
* @param chunkZ
* @return True if the entity was spawned
*/
public boolean spawnEntity(P context, Entity entity, int chunkX, int chunkZ) {
final net.minecraft.entity.Entity minecraftEntity = (net.minecraft.entity.Entity) entity;
final WorldServer minecraftWorld = (WorldServer) minecraftEntity.world;
final Player player = context.getSource(Player.class).orElseThrow(TrackingUtil.throwWithContext("Expected to be capturing a player", context));
final ArrayList<Entity> entities = new ArrayList<>(1);
entities.add(entity);
try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
Sponge.getCauseStackManager().pushCause(player);
Sponge.getCauseStackManager().addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.PLACEMENT);
Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, player);
Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, player);
final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
SpongeImpl.postEvent(event);
if (!event.isCancelled()) {
for (Entity newEntity : event.getEntities()) {
EntityUtil.toMixin(newEntity).setCreator(player.getUniqueId());
((IMixinWorldServer) minecraftWorld).forceSpawnEntity(newEntity);
}
return true;
}
}
return false;
}
Aggregations