Added persistance starmap registry

Your ship position is no longer lost on server restart
This commit is contained in:
LemADEC 2017-05-23 23:46:54 +02:00
parent 90ee55cc81
commit 2cfcad4258
4 changed files with 138 additions and 14 deletions

View file

@ -1,5 +1,6 @@
package cr0s.warpdrive.data;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.WorldServer;
@ -55,6 +56,20 @@ public class GlobalPosition {
return StarMapRegistry.getUniversalCoordinates(dimensionId, x, y, z);
}
public GlobalPosition(final NBTTagCompound tagCompound) {
dimensionId = tagCompound.getInteger("dimensionId");
x = tagCompound.getInteger("x");
y = tagCompound.getInteger("y");
z = tagCompound.getInteger("z");
}
public void writeToNBT(final NBTTagCompound tagCompound) {
tagCompound.setInteger("dimensionId", dimensionId);
tagCompound.setInteger("x", x);
tagCompound.setInteger("y", y);
tagCompound.setInteger("z", z);
}
public boolean equals(final TileEntity tileEntity) {
return dimensionId == tileEntity.getWorldObj().provider.dimensionId
&& x == tileEntity.xCoord && y == tileEntity.yCoord && z == tileEntity.zCoord;

View file

@ -12,11 +12,14 @@ import cr0s.warpdrive.data.StarMapRegistryItem.EnumStarMapEntryType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
@ -26,6 +29,7 @@ import net.minecraft.world.WorldServer;
import net.minecraft.world.gen.ChunkProviderServer;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.util.Constants;
/**
* Registry of all known ships, jumpgates, etc. in the world
@ -309,13 +313,15 @@ public class StarMapRegistry {
WarpDrive.logger.info("Starmap registry (" + registry.size() + " entries after " + trigger + "):");
for (Map.Entry<Integer, CopyOnWriteArraySet<StarMapRegistryItem>> entryDimension : registry.entrySet()) {
String message = "";
StringBuilder message = new StringBuilder();
for (StarMapRegistryItem registryItem : entryDimension.getValue()) {
message += "\n- " + registryItem.type + " '" + registryItem.name + "' @ "
+ registryItem.dimensionId + ": " + registryItem.x + " " + registryItem.y + " " + registryItem.z
+ " with " + registryItem.isolationRate + " isolation rate";
message.append(String.format("\n- %s '%s' @ DIM%d (%d %d %d) with %.3f isolation rate",
registryItem.type, registryItem.name,
registryItem.dimensionId, registryItem.x, registryItem.y, registryItem.z,
registryItem.isolationRate));
}
WarpDrive.logger.info("- " + entryDimension.getValue().size() + " entries in dimension " + entryDimension.getKey() + ": " + message);
WarpDrive.logger.info(String.format("- %d entries in dimension %d: %s",
entryDimension.getValue().size(), entryDimension.getKey(), message.toString()));
}
}
@ -443,4 +449,54 @@ public class StarMapRegistry {
LocalProfiler.stop();
}
public void readFromNBT(NBTTagCompound tagCompound) {
if (tagCompound == null || !tagCompound.hasKey("starMapRegistryItems")) {
registry.clear();
return;
}
// read all entries in a flat structure
final NBTTagList tagList = tagCompound.getTagList("starMapRegistryItems", Constants.NBT.TAG_COMPOUND);
final StarMapRegistryItem[] registryFlat = new StarMapRegistryItem[tagList.tagCount()];
final HashMap<Integer, Integer> sizeDimensions = new HashMap<>();
for(int index = 0; index < tagList.tagCount(); index++) {
final StarMapRegistryItem starMapRegistryItem = new StarMapRegistryItem(tagList.getCompoundTagAt(index));
registryFlat[index] = starMapRegistryItem;
// update stats
Integer count = sizeDimensions.computeIfAbsent(starMapRegistryItem.dimensionId, k -> (Integer) 0);
count++;
sizeDimensions.put(starMapRegistryItem.dimensionId, count);
}
// pre-build the local collections using known stats to avoid re-allocations
final HashMap<Integer, ArrayList<StarMapRegistryItem>> registryLocal = new HashMap<>();
for(Entry<Integer, Integer> entryDimension : sizeDimensions.entrySet()) {
registryLocal.put(entryDimension.getKey(), new ArrayList<>(entryDimension.getValue()));
}
// fill the local collections
for(StarMapRegistryItem starMapRegistryItem : registryFlat) {
registryLocal.get(starMapRegistryItem.dimensionId).add(starMapRegistryItem);
}
// transfer to main one
registry.clear();
for(Entry<Integer, ArrayList<StarMapRegistryItem>> entry : registryLocal.entrySet()) {
registry.put(entry.getKey(), new CopyOnWriteArraySet<>(entry.getValue()));
}
}
public void writeToNBT(final NBTTagCompound tagCompound) {
final NBTTagList tagList = new NBTTagList();
for(CopyOnWriteArraySet<StarMapRegistryItem> starMapRegistryItems : registry.values()) {
for(StarMapRegistryItem starMapRegistryItem : starMapRegistryItems) {
final NBTTagCompound tagCompoundItem = new NBTTagCompound();
starMapRegistryItem.writeToNBT(tagCompoundItem);
tagList.appendTag(tagCompoundItem);
}
}
tagCompound.setTag("starMapRegistryItems", tagList);
}
}

View file

@ -6,6 +6,7 @@ import cr0s.warpdrive.api.IStarMapRegistryTileEntity;
import java.util.HashMap;
import java.util.UUID;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
@ -140,6 +141,47 @@ public class StarMapRegistryItem extends GlobalPosition {
return minX <= x && x <= maxX && minY <= y && y <= maxY && minZ <= z && z <= maxZ;
}
public StarMapRegistryItem(final NBTTagCompound tagCompound) {
super(tagCompound);
type = EnumStarMapEntryType.getByName(tagCompound.getString("type"));
UUID uuidLocal = new UUID(tagCompound.getLong("uuidMost"), tagCompound.getLong("uuidLeast"));
if (uuidLocal.getMostSignificantBits() == 0 && uuidLocal.getLeastSignificantBits() == 0) {
uuidLocal = UUID.randomUUID();
}
uuid = uuidLocal;
maxX = tagCompound.getInteger("maxX");
maxY = tagCompound.getInteger("maxY");
maxZ = tagCompound.getInteger("maxZ");
minX = tagCompound.getInteger("minX");
minY = tagCompound.getInteger("minY");
minZ = tagCompound.getInteger("minZ");
mass = tagCompound.getInteger("mass");
isolationRate = tagCompound.getDouble("isolationRate");
name = tagCompound.getString("name");
}
@Override
public void writeToNBT(final NBTTagCompound tagCompound) {
super.writeToNBT(tagCompound);
tagCompound.setString("type", type.getName());
if (uuid != null) {
tagCompound.setLong("uuidMost", uuid.getMostSignificantBits());
tagCompound.setLong("uuidLeast", uuid.getLeastSignificantBits());
}
tagCompound.setInteger("maxX", maxX);
tagCompound.setInteger("maxY", maxY);
tagCompound.setInteger("maxZ", maxZ);
tagCompound.setInteger("minX", minX);
tagCompound.setInteger("minY", minY);
tagCompound.setInteger("minZ", minZ);
tagCompound.setInteger("mass", mass);
tagCompound.setDouble("isolationRate", isolationRate);
if (name != null && !name.isEmpty()) {
tagCompound.setString("name", name);
}
}
@Override
public int hashCode() {
return dimensionId << 24 + (x >> 10) << 12 + y << 10 + (z >> 10);

View file

@ -1,5 +1,6 @@
package cr0s.warpdrive.event;
import cr0s.warpdrive.Commons;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.ChunkData;
@ -37,10 +38,14 @@ public class ChunkHandler {
return;
}
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
WarpDrive.logger.info(String.format("World %s load",
WarpDrive.logger.info(String.format("World %s load.",
event.world.provider.getDimensionName()));
}
// @TODO load star map
// load star map
final String filename = String.format("%s/%s.dat", event.world.getSaveHandler().getWorldDirectory().getPath(), WarpDrive.MODID);
final NBTTagCompound tagCompound = Commons.readNBTFromFile(filename);
WarpDrive.starMap.readFromNBT(tagCompound);
}
// (server side only)
@ -52,7 +57,7 @@ public class ChunkHandler {
event.getChunk().getChunkCoordIntPair()));
}
ChunkData chunkData = getChunkData(event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition);
final ChunkData chunkData = getChunkData(event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition);
chunkData.load(event.getData());
}
@ -66,7 +71,7 @@ public class ChunkHandler {
event.getChunk().getChunkCoordIntPair()));
}
ChunkData chunkData = getChunkData(event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition);
final ChunkData chunkData = getChunkData(event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition);
chunkData.load(new NBTTagCompound());
}
}
@ -91,7 +96,7 @@ public class ChunkHandler {
event.world.provider.getDimensionName(),
event.getChunk().getChunkCoordIntPair()));
}
ChunkData chunkData = getChunkData(event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition);
final ChunkData chunkData = getChunkData(event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition);
chunkData.save(event.getData());
}
@ -102,10 +107,15 @@ public class ChunkHandler {
return;
}
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
WarpDrive.logger.info(String.format("World %s saved",
WarpDrive.logger.info(String.format("World %s saved.",
event.world.provider.getDimensionName()));
}
// @TODO save star map
// save star map
final String filename = String.format("%s/%s.dat", event.world.getSaveHandler().getWorldDirectory().getPath(), WarpDrive.MODID);
final NBTTagCompound tagCompound = new NBTTagCompound();
WarpDrive.starMap.writeToNBT(tagCompound);
Commons.writeNBTToFile(filename, tagCompound);
}
@SubscribeEvent
@ -116,7 +126,7 @@ public class ChunkHandler {
}
// get dimension data
Map<Long, ChunkData> mapRegistryItems = registry.get(event.world.provider.dimensionId);
final Map<Long, ChunkData> mapRegistryItems = registry.get(event.world.provider.dimensionId);
if (mapRegistryItems != null) {
// unload chunks during shutdown
for (ChunkData chunkData : mapRegistryItems.values()) {
@ -129,6 +139,7 @@ public class ChunkHandler {
if (event.world.isRemote || event.world.provider.dimensionId != 0) {
return;
}
// @TODO unload star map
}
@ -248,7 +259,7 @@ public class ChunkHandler {
return true;
}
chunkData.updateTick(world);
ChunkCoordIntPair chunkCoordIntPair = chunkData.getChunkCoords();
final ChunkCoordIntPair chunkCoordIntPair = chunkData.getChunkCoords();
// skip chunks with unloaded neighbours
if ( isLoaded(mapRegistryItems, chunkCoordIntPair.chunkXPos + 1, chunkCoordIntPair.chunkZPos)
&& isLoaded(mapRegistryItems, chunkCoordIntPair.chunkXPos - 1, chunkCoordIntPair.chunkZPos)