Refactored spatial dimension data into a helper class.

This commit is contained in:
Sebastian Hartte
2020-06-13 13:07:15 +02:00
parent 2b36df9ebf
commit 5ec9600177
5 changed files with 101 additions and 18 deletions
@@ -0,0 +1,45 @@
package appeng.spatial;
import io.netty.buffer.Unpooled;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable;
/**
* Helps with encoding and decoding the extra data we attach to the
* spatial {@link net.minecraft.world.dimension.DimensionType} as "extra data".
* Keep in mind this data will also be sent to the client unless
* {@link net.minecraftforge.common.ModDimension#write(PacketBuffer, boolean)} is overridden.
*/
public final class SpatialDimensionExtraData {
private static final int FORMAT_VERSION = 1;
private static final int OFFSET_VERSION = 0;
private static final int OFFSET_CONTENT_SIZE = 1;
private SpatialDimensionExtraData() {
}
public static PacketBuffer create(BlockPos contentSize) {
PacketBuffer extraData = new PacketBuffer(Unpooled.buffer());
extraData.writeByte(FORMAT_VERSION);
extraData.writeBlockPos(contentSize);
// Cut the buffer to minimal size
extraData.capacity(extraData.writerIndex());
return extraData;
}
private static boolean checkVersion(PacketBuffer data){
return data.getByte(OFFSET_VERSION) == FORMAT_VERSION;
}
public static BlockPos getContentSize(@Nullable PacketBuffer data) {
if (data == null || !checkVersion(data)) {
return BlockPos.ZERO;
}
data.readerIndex(OFFSET_CONTENT_SIZE);
return data.readBlockPos();
}
}
@@ -0,0 +1,130 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2017, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.spatial;
import appeng.api.storage.ISpatialDimension;
import appeng.core.AELog;
import appeng.core.AppEng;
import net.minecraft.network.PacketBuffer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
public class SpatialDimensionManager implements ISpatialDimension
{
private static final String DIM_ID_PREFIX = "spatial_";
@Override
public ServerWorld getWorld(DimensionType cellDim) {
return DimensionManager.getWorld(getServer(), cellDim, true, true);
}
@Override
public DimensionType createNewCellDimension(BlockPos contentSize)
{
ResourceLocation dimKey = findFreeDimensionId();
AELog.info("Allocating storage cell dimension '%s' for %d", dimKey);
PacketBuffer extraData = SpatialDimensionExtraData.create(contentSize);
return DimensionManager.registerDimension(dimKey, StorageCellModDimension.INSTANCE, extraData, true);
}
/**
* Tries finding the next free storage cell dimension ID based on the currently registered storage
* cell dimensions.
*/
private ResourceLocation findFreeDimensionId() {
int maxId = 0;
for (DimensionType dimensionType : DimensionType.getAll()) {
ResourceLocation regName = dimensionType.getRegistryName();
if (regName == null || !AppEng.MOD_ID.equals(regName.getNamespace())) {
continue;
}
String path = regName.getPath();
if (!path.startsWith(DIM_ID_PREFIX)) {
continue;
}
try {
String numericIdPart = path.substring(DIM_ID_PREFIX.length());
maxId = Math.max(Integer.parseUnsignedInt(numericIdPart), maxId);
} catch (NumberFormatException e) {
AELog.warn("Unparsable storage cell dimension id '%s'", path, e);
}
}
++maxId;
return new ResourceLocation(AppEng.MOD_ID, DIM_ID_PREFIX + maxId);
}
@Override
public void deleteCellDimension( DimensionType cellDim )
{
AELog.info("Unregistering storage cell dimension %s", cellDim.getRegistryName());
MinecraftServer server = getServer();
ServerWorld world = DimensionManager.getWorld(server, cellDim, false, false);
if (world != null) {
DimensionManager.unloadWorld(world);
}
DimensionManager.unloadWorlds(server, true);
DimensionManager.unregisterDimension(cellDim.getId());
}
@Override
public boolean isCellDimension( DimensionType cellDim )
{
// Check if the cell dimension type is even registered
if (cellDim.getRegistryName() == null || !cellDim.getRegistryName().equals(DimensionType.getKey(cellDim))) {
return false;
}
return cellDim.getModType() instanceof StorageCellModDimension;
}
@Override
public BlockPos getCellDimensionOrigin( DimensionType cellDim )
{
return StorageCellDimension.REGION_CENTER;
}
@Override
public BlockPos getCellContentSize( DimensionType cellDim )
{
if (!(cellDim.getModType() instanceof StorageCellModDimension)) {
return BlockPos.ZERO;
}
return SpatialDimensionExtraData.getContentSize(cellDim.getData());
}
private static MinecraftServer getServer() {
return ServerLifecycleHooks.getCurrentServer();
}
}
@@ -43,7 +43,7 @@ public class StorageCellDimension extends Dimension
// A region file is 512x512 blocks (32x32 chunks),
// to avoid creating the 4 regions around 0,0,0,
// we move the origin to the middle of region 0,0
public static final BlockPos REGION_CENTER = new BlockPos(512 / 2, 61, 512 / 2);
public static final BlockPos REGION_CENTER = new BlockPos(512 / 2, 64, 512 / 2);
public StorageCellDimension(World world, DimensionType dimensionType) {
// FIXME: check light value