mirror of
https://github.com/array-in-a-matrix/brainwine.git
synced 2025-04-02 11:11:58 -04:00
Moved chunk code to ChunkManager
This commit is contained in:
parent
8b9c978d1b
commit
565301f528
2 changed files with 141 additions and 95 deletions
|
@ -7,6 +7,12 @@ import java.io.FileInputStream;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
@ -17,6 +23,7 @@ import org.msgpack.jackson.dataformat.MessagePackFactory;
|
|||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
|
||||
import brainwine.gameserver.entity.player.Player;
|
||||
import brainwine.gameserver.serialization.BlockDeserializer;
|
||||
import brainwine.gameserver.serialization.BlockSerializer;
|
||||
import brainwine.gameserver.util.ZipUtils;
|
||||
|
@ -29,6 +36,7 @@ public class ChunkManager {
|
|||
.registerModule(new SimpleModule()
|
||||
.addDeserializer(Block.class, BlockDeserializer.INSTANCE)
|
||||
.addSerializer(BlockSerializer.INSTANCE));
|
||||
private final Map<Integer, Chunk> chunks = new HashMap<>();
|
||||
private final Zone zone;
|
||||
private final File blocksFile;
|
||||
private RandomAccessFile file;
|
||||
|
@ -84,32 +92,35 @@ public class ChunkManager {
|
|||
}
|
||||
}
|
||||
|
||||
public Chunk loadChunk(int index) {
|
||||
try {
|
||||
if(file == null) {
|
||||
file = new RandomAccessFile(blocksFile, "rw");
|
||||
}
|
||||
|
||||
file.seek(dataOffset + index * allocSize);
|
||||
byte[] bytes = new byte[file.readShort()];
|
||||
file.read(bytes);
|
||||
return mapper.readValue(ZipUtils.inflateBytes(bytes), Chunk.class);
|
||||
} catch(Exception e) {
|
||||
logger.error("Could not load chunk {} of zone {}", index, zone.getDocumentId(), e);
|
||||
}
|
||||
public void saveChunks() {
|
||||
List<Chunk> inactiveChunks = new ArrayList<>();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void saveModifiedChunks() {
|
||||
for(Chunk chunk : zone.getChunks()) {
|
||||
if(chunk.isModified()) {
|
||||
saveChunk(chunk);
|
||||
}
|
||||
|
||||
boolean active = false;
|
||||
|
||||
for(Player player : zone.getPlayers()) {
|
||||
if(player.isChunkActive(chunk)) {
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!active) {
|
||||
inactiveChunks.add(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
for(Chunk chunk : inactiveChunks) {
|
||||
chunks.remove(getChunkIndex(chunk.getX(), chunk.getY()));
|
||||
zone.onChunkUnloaded(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveChunk(Chunk chunk) {
|
||||
private void saveChunk(Chunk chunk) {
|
||||
int index = zone.getChunkIndex(chunk.getX(), chunk.getY());
|
||||
|
||||
try {
|
||||
|
@ -131,4 +142,68 @@ public class ChunkManager {
|
|||
logger.error("Could not save chunk {} of zone {}", index, zone.getDocumentId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private Chunk loadChunk(int index) {
|
||||
try {
|
||||
if(file == null) {
|
||||
file = new RandomAccessFile(blocksFile, "rw");
|
||||
}
|
||||
|
||||
file.seek(dataOffset + index * allocSize);
|
||||
byte[] bytes = new byte[file.readShort()];
|
||||
file.read(bytes);
|
||||
return mapper.readValue(ZipUtils.inflateBytes(bytes), Chunk.class);
|
||||
} catch(Exception e) {
|
||||
logger.error("Could not load chunk {} of zone {}", index, zone.getDocumentId(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void putChunk(int index, Chunk chunk) {
|
||||
if(!chunks.containsKey(index) && isChunkIndexInBounds(index)) {
|
||||
chunk.setModified(true);
|
||||
chunks.put(index, chunk);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isChunkLoaded(int x, int y) {
|
||||
return isChunkLoaded(getChunkIndex(x, y));
|
||||
}
|
||||
|
||||
public boolean isChunkLoaded(int index) {
|
||||
return chunks.containsKey(index);
|
||||
}
|
||||
|
||||
public boolean isChunkIndexInBounds(int index) {
|
||||
return index >= 0 && index < zone.getNumChunksWidth() * zone.getNumChunksHeight();
|
||||
}
|
||||
|
||||
public int getChunkIndex(int x, int y) {
|
||||
return y / zone.getChunkHeight() * zone.getNumChunksWidth() + x / zone.getChunkWidth();
|
||||
}
|
||||
|
||||
public Chunk getChunk(int x, int y) {
|
||||
return getChunk(getChunkIndex(x, y));
|
||||
}
|
||||
|
||||
public Chunk getChunk(int index) {
|
||||
if(!isChunkIndexInBounds(index)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Chunk chunk = chunks.get(index);
|
||||
|
||||
if(chunk == null) {
|
||||
chunk = loadChunk(index);
|
||||
chunks.put(index, chunk);
|
||||
zone.onChunkLoaded(chunk);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public Collection<Chunk> getChunks() {
|
||||
return Collections.unmodifiableCollection(chunks.values());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,8 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
@ -71,7 +69,6 @@ public class Zone {
|
|||
private final Set<Integer> pendingSunlight = new HashSet<>();
|
||||
private final Map<Integer, Entity> entities = new HashMap<>();
|
||||
private final List<Player> players = new ArrayList<>();
|
||||
private final Map<Integer, Chunk> chunks = new HashMap<>();
|
||||
private final Map<String, Integer> dungeons = new HashMap<>();
|
||||
private final Map<Integer, MetaBlock> metaBlocks = new HashMap<>();
|
||||
private final Map<Integer, MetaBlock> globalMetaBlocks = new HashMap<>();
|
||||
|
@ -144,11 +141,6 @@ public class Zone {
|
|||
}
|
||||
}
|
||||
|
||||
public void saveModifiedChunks() {
|
||||
chunkManager.saveModifiedChunks();
|
||||
removeInactiveChunks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to each player in this zone.
|
||||
*
|
||||
|
@ -678,75 +670,8 @@ public class Zone {
|
|||
return x >= 0 && y >= 0 && x < width && y < height;
|
||||
}
|
||||
|
||||
private void removeInactiveChunks() {
|
||||
Iterator<Entry<Integer, Chunk>> iterator = chunks.entrySet().iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
Entry<Integer, Chunk> entry = iterator.next();
|
||||
Chunk chunk = entry.getValue();
|
||||
boolean active = false;
|
||||
|
||||
for(Player player : players) {
|
||||
if(player.isChunkActive(chunk)) {
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!active) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isChunkIndexInBounds(int index) {
|
||||
return index >= 0 && index < numChunksWidth * numChunksHeight;
|
||||
}
|
||||
|
||||
public boolean isChunkLoaded(int x, int y) {
|
||||
return isChunkLoaded(getChunkIndex(x, y));
|
||||
}
|
||||
|
||||
public boolean isChunkLoaded(int index) {
|
||||
return chunks.containsKey(index);
|
||||
}
|
||||
|
||||
public void putChunk(int index, Chunk chunk) {
|
||||
if(!chunks.containsKey(index) && isChunkIndexInBounds(index)) {
|
||||
chunk.setModified(true);
|
||||
chunks.put(index, chunk);
|
||||
}
|
||||
}
|
||||
|
||||
public int getChunkIndex(int x, int y) {
|
||||
return y / chunkHeight * numChunksWidth + x / chunkWidth;
|
||||
}
|
||||
|
||||
public Chunk getChunk(int x, int y) {
|
||||
return getChunk(getChunkIndex(x, y));
|
||||
}
|
||||
|
||||
public Chunk getChunk(int index) {
|
||||
if(!isChunkIndexInBounds(index)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Chunk chunk = chunks.get(index);
|
||||
|
||||
if(chunk == null) {
|
||||
chunk = chunkManager.loadChunk(index);
|
||||
tryRecalculatePendingSunlight(chunk);
|
||||
chunks.put(index, chunk);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public Collection<Chunk> getChunks() {
|
||||
return chunks.values();
|
||||
}
|
||||
|
||||
private void tryRecalculatePendingSunlight(Chunk chunk) {
|
||||
protected void onChunkLoaded(Chunk chunk) {
|
||||
// Update sunlight
|
||||
if(!pendingSunlight.isEmpty()) {
|
||||
int chunkX = chunk.getX();
|
||||
|
||||
|
@ -757,6 +682,52 @@ public class Zone {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO more chunk related thingies, such as surface calculations,
|
||||
// entity spawning and block indexing
|
||||
}
|
||||
|
||||
protected void onChunkUnloaded(Chunk chunk) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public void saveChunks() {
|
||||
chunkManager.saveChunks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Should only be called by zone gen.
|
||||
*/
|
||||
public void putChunk(int index, Chunk chunk) {
|
||||
chunkManager.putChunk(index, chunk);
|
||||
}
|
||||
|
||||
public boolean isChunkLoaded(int x, int y) {
|
||||
return chunkManager.isChunkLoaded(x, y);
|
||||
}
|
||||
|
||||
public boolean isChunkLoaded(int index) {
|
||||
return chunkManager.isChunkLoaded(index);
|
||||
}
|
||||
|
||||
public boolean isChunkIndexInBounds(int index) {
|
||||
return chunkManager.isChunkIndexInBounds(index);
|
||||
}
|
||||
|
||||
public int getChunkIndex(int x, int y) {
|
||||
return chunkManager.getChunkIndex(x, y);
|
||||
}
|
||||
|
||||
public Chunk getChunk(int x, int y) {
|
||||
return chunkManager.getChunk(x, y);
|
||||
}
|
||||
|
||||
public Chunk getChunk(int index) {
|
||||
return chunkManager.getChunk(index);
|
||||
}
|
||||
|
||||
public Collection<Chunk> getChunks() {
|
||||
return chunkManager.getChunks();
|
||||
}
|
||||
|
||||
public void setSurface(int x, int surface) {
|
||||
|
|
Loading…
Add table
Reference in a new issue