Skip to content

Commit

Permalink
Merge pull request #122 from mircokroon/bugfixes
Browse files Browse the repository at this point in the history
Bugfixes
  • Loading branch information
mircokroon authored Feb 21, 2021
2 parents 02f81aa + a594929 commit e81cc88
Show file tree
Hide file tree
Showing 13 changed files with 172 additions and 86 deletions.
1 change: 1 addition & 0 deletions src/main/java/game/data/LevelData.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public void save() throws IOException {
new DoubleTag(playerPosition.getY() * 1.0),
new DoubleTag(playerPosition.getZ() * 1.0)
)));
player.add("Dimension", new StringTag(WorldManager.getInstance().getDimension().toString()));

// set the world spawn to match the last known player location
data.add("SpawnX", new IntTag(playerPosition.getX()));
Expand Down
22 changes: 13 additions & 9 deletions src/main/java/game/data/WorldManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static util.ExceptionHandling.attempt;

/**
* Manage the world, including saving, parsing and updating the GUI.
*/
public class WorldManager {
private static final int INIT_SAVE_DELAY = 5 * 1000;
private static final int SAVE_DELAY = 15 * 1000;
private static final int SAVE_DELAY = 12 * 1000;
private static WorldManager instance;
private final LevelData levelData;
private final MapRegistry mapRegistry;
Expand Down Expand Up @@ -156,12 +158,7 @@ public void outlineExistingChunks() {
}
existingLoaded.add(this.dimension);

Stream<McaFile> files = null;
try {
files = McaFile.getFiles(dimension, true);
} catch (IOException e) {
e.printStackTrace();
}
Stream<McaFile> files = McaFile.getFiles(this.playerPosition, dimension, 16);

GuiManager.outlineExistingChunks(
files.flatMap(el -> el.getChunkPositions(this.dimension).stream()).collect(Collectors.toList())
Expand Down Expand Up @@ -216,7 +213,6 @@ public void startSaveService() {
isStarted = true;

this.start();
this.chunkFactory.start();
}

/**
Expand Down Expand Up @@ -356,7 +352,7 @@ public void setDimensionCodec(DimensionCodec codec) {
public void start() {
ThreadFactory namedThreadFactory = r -> new Thread(r, "World Save Service");
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1, namedThreadFactory);
executor.scheduleWithFixedDelay(this::save, INIT_SAVE_DELAY, SAVE_DELAY, TimeUnit.MILLISECONDS);
executor.scheduleWithFixedDelay(() -> attempt(this::save), INIT_SAVE_DELAY, SAVE_DELAY, TimeUnit.MILLISECONDS);
}


Expand Down Expand Up @@ -592,5 +588,13 @@ public void unloadEntities(CoordinateDim2D coord) {
this.entityRegistry.unloadChunk(coord);
this.chunkFactory.unloadChunk(coord);
}

public int countActiveChunks() {
int total = 0;
for (Region r : regions.values()) {
total += r.countChunks();
}
return total;
}
}

2 changes: 0 additions & 2 deletions src/main/java/game/data/chunk/ChunkEntities.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ public void addTileEntity(Coordinate3D location, SpecificTag tag) {
}
}



// get offset location
Coordinate3D offset = location.offsetGlobal();

Expand Down
9 changes: 2 additions & 7 deletions src/main/java/game/data/chunk/ChunkFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public ChunkFactory() {
public void clear() {
this.tileEntities = new ConcurrentHashMap<>();
this.unparsedChunks = new ConcurrentLinkedQueue<>();

this.executor = Executors.newSingleThreadExecutor(r -> new Thread(r, "Chunk Parser Service"));;
}

/**
Expand Down Expand Up @@ -81,13 +83,6 @@ public void addChunk(DataTypeProvider provider) {
}
}

/**
* Periodically check if there are unparsed chunks, and if so, parse them.
*/
public void start() {
executor = Executors.newSingleThreadExecutor(r -> new Thread(r, "Chunk Parser Service"));
}

private void parse() {
ChunkParserPair parsePair;
while ((parsePair = getUnparsedChunk()) != null) {
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/game/data/coordinates/CoordinateDouble3D.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,13 @@ public double getY() {
public double getZ() {
return z;
}

@Override
public String toString() {
return "CoordinateDouble3D{" +
"x=" + x +
", y=" + y +
", z=" + z +
'}';
}
}
106 changes: 63 additions & 43 deletions src/main/java/game/data/entity/EntityRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,54 +11,62 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.stream.Collectors;

import static util.ExceptionHandling.attempt;

public class EntityRegistry {

Map<CoordinateDim2D, Set<Entity>> perChunk;
Map<Integer, Entity> entities;
private final Map<CoordinateDim2D, Set<Entity>> perChunk;
private final Map<Integer, Entity> entities;
private final WorldManager worldManager;

WorldManager worldManager;
private final ExecutorService executor;

public EntityRegistry(WorldManager manager) {
this.worldManager = manager;
this.perChunk = new ConcurrentHashMap<>();
this.entities = new ConcurrentHashMap<>();
}

this.executor = Executors.newSingleThreadExecutor(r -> new Thread(r, "Entity Parser Service"));;
}
/**
* Add a new entity.
*/
public void addEntity(DataTypeProvider provider, Function<DataTypeProvider, Entity> parser) {
Entity ent = parser.apply(provider);
entities.put(ent.getId(), ent);

ent.registerOnLocationChange((oldPos, newPos) -> {
CoordinateDim2D oldChunk = oldPos == null ? null : oldPos.globalToDimChunk();
CoordinateDim2D newChunk = newPos.globalToDimChunk();

// if they're the same, just mark the chunk as unsaved
if (oldPos == newPos) {
markUnsaved(newChunk);
return;
}
this.executor.execute(() -> attempt(() -> {
Entity ent = parser.apply(provider);
entities.put(ent.getId(), ent);

ent.registerOnLocationChange((oldPos, newPos) -> {
CoordinateDim2D oldChunk = oldPos == null ? null : oldPos.globalToDimChunk();
CoordinateDim2D newChunk = newPos.globalToDimChunk();

// if they're the same, just mark the chunk as unsaved
if (oldPos == newPos) {
markUnsaved(newChunk);
return;
}

Set<Entity> entities = oldChunk == null ? null : perChunk.get(oldChunk);
if (entities != null) {
entities.remove(ent);
Set<Entity> entities = oldChunk == null ? null : perChunk.get(oldChunk);
if (entities != null) {
entities.remove(ent);

if (entities.isEmpty()) {
perChunk.remove(oldChunk);
if (entities.isEmpty()) {
perChunk.remove(oldChunk);
}
}
}

Set<Entity> set = perChunk.computeIfAbsent(newChunk, (k) -> ConcurrentHashMap.newKeySet());
set.add(ent);
Set<Entity> set = perChunk.computeIfAbsent(newChunk, (k) -> ConcurrentHashMap.newKeySet());
set.add(ent);

markUnsaved(newChunk);
markUnsaved(newChunk);

});
});
}));
}

private void markUnsaved(CoordinateDim2D coord) {
Expand All @@ -84,27 +92,33 @@ public void unloadChunk(CoordinateDim2D location) {


public void addMetadata(DataTypeProvider provider) {
Entity ent = entities.get(provider.readVarInt());
this.executor.execute(() -> attempt(() -> {
Entity ent = entities.get(provider.readVarInt());

if (ent != null) {
ent.parseMetadata(provider);
}
if (ent != null) {
ent.parseMetadata(provider);
}
}));
}

public void updatePositionRelative(DataTypeProvider provider) {
Entity ent = entities.get(provider.readVarInt());
this.executor.execute(() -> attempt(() -> {
Entity ent = entities.get(provider.readVarInt());

if (ent != null) {
ent.incrementPosition(provider.readShort(), provider.readShort(), provider.readShort());
}
if (ent != null) {
ent.incrementPosition(provider.readShort(), provider.readShort(), provider.readShort());
}
}));
}

public void updatePositionAbsolute(DataTypeProvider provider) {
Entity ent = entities.get(provider.readVarInt());
this.executor.execute(() -> attempt(() -> {
Entity ent = entities.get(provider.readVarInt());

if (ent != null) {
ent.readPosition(provider);
}
if (ent != null) {
ent.readPosition(provider);
}
}));
}

public List<SpecificTag> getEntitiesNbt(CoordinateDim2D location) {
Expand All @@ -123,11 +137,17 @@ public void reset() {
}

public void addEquipment(DataTypeProvider provider) {
int id = provider.readVarInt();
Entity ent = entities.get(id);
this.executor.execute(() -> attempt(() -> {
int id = provider.readVarInt();
Entity ent = entities.get(id);

if (ent != null) {
ent.addEquipment(provider);
}
if (ent != null) {
ent.addEquipment(provider);
}
}));
}

public int countActiveEntities() {
return this.entities.size();
}
}
4 changes: 3 additions & 1 deletion src/main/java/game/data/entity/specific/ItemFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ class ItemFrameMetaData extends MetaData_1_13 {

@Override
public void addNbtTags(CompoundTag nbt) {
nbt.add("Item", item.toNbt());
if (item != null) {
nbt.add("Item", item.toNbt());
}
nbt.add("ItemRotation", new IntTag(rotation));
}

Expand Down
40 changes: 27 additions & 13 deletions src/main/java/game/data/maps/MapRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,24 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static util.ExceptionHandling.attempt;

/**
* Handle storing of the map item.
*/
public class MapRegistry {
String registryFileName = "idcounts.dat";
Path dataDir = PathUtils.toPath(Config.getWorldOutputDir(), "data");
File registryFile = Paths.get(dataDir.toString(), registryFileName).toFile();
private final String registryFileName = "idcounts.dat";
private final Path dataDir = PathUtils.toPath(Config.getWorldOutputDir(), "data");
private final File registryFile = Paths.get(dataDir.toString(), registryFileName).toFile();

private final Map<Integer, PlayerMap> maps;
private final Set<Integer> updatedSince;
private int maxMapId = 0;

Map<Integer, PlayerMap> maps;
Set<Integer> updatedSince;
int maxMapId = 0;
private final ExecutorService executor;

public MapRegistry() {
this.maps = new ConcurrentHashMap<>();
Expand All @@ -40,6 +46,8 @@ public MapRegistry() {
e.printStackTrace();
// if we can't read it, thats fine, we'll use maxId = 0
}

this.executor = Executors.newSingleThreadExecutor(r -> new Thread(r, "Map Parser Service"));;
}

/**
Expand Down Expand Up @@ -83,13 +91,19 @@ public void save() throws IOException {
* Read map from network packet to class.
*/
public void readMap(DataTypeProvider provider) {
int mapId = provider.readVarInt();
this.updatedSince.add(mapId);
if (mapId > maxMapId) {
maxMapId = mapId;
}
executor.execute(() -> attempt(() -> {
int mapId = provider.readVarInt();
this.updatedSince.add(mapId);
if (mapId > maxMapId) {
maxMapId = mapId;
}

PlayerMap map = maps.computeIfAbsent(mapId, PlayerMap::getVersioned);
map.parse(provider);
}));
}

PlayerMap map = maps.computeIfAbsent(mapId, PlayerMap::getVersioned);
map.parse(provider);
public int countActiveMaps() {
return this.maps.size();
}
}
4 changes: 4 additions & 0 deletions src/main/java/game/data/region/Region.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,8 @@ public McaFile toFile(Coordinate2D playerPos) {
public void touch() {
this.updatedSinceLastWrite = true;
}

public int countChunks() {
return this.chunks.size();
}
}
Loading

0 comments on commit e81cc88

Please sign in to comment.