Skip to content

Commit

Permalink
Experimentally adapted to support 1.13+'s new block format i.e. name …
Browse files Browse the repository at this point in the history
…+ states (nbt tags) instead of name + val (1~15).
  • Loading branch information
meow committed Jan 8, 2020
1 parent bcb4505 commit 47251af
Show file tree
Hide file tree
Showing 45 changed files with 5,800 additions and 439 deletions.
12 changes: 6 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ android {
applicationId 'rbq2012.blocktopograph'
minSdkVersion 16
targetSdkVersion 28
versionCode 1080900
versionName "1.8.9"
versionCode 1090000
versionName "1.9.0"
vectorDrawables.useSupportLibrary = true
}
dataBinding {
Expand Down Expand Up @@ -43,14 +43,14 @@ dependencies {
implementation 'com.github.woxthebox:draglistview:1.6.3'
implementation 'com.andreabaccega:android-edittext-validator:1.3.5'
//core is the new recommended alias for analytics
implementation 'com.google.firebase:firebase-core:17.0.0'
implementation 'com.google.firebase:firebase-core:17.2.1'
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
implementation 'org.jetbrains:annotations-java5:15.0'
implementation 'com.tomergoldst.android:tooltips:1.0.10'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha08'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.2.0-alpha03'
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
//implementation 'com.github.MikeOrtiz:TouchImageView:2.1.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
import androidx.fragment.app.Fragment;

import com.litl.leveldb.DB;
import com.mithrilmania.blocktopograph.block.KnownBlockRepr;
import com.mithrilmania.blocktopograph.databinding.ActivityCreateWorldBinding;
import com.mithrilmania.blocktopograph.flat.EditFlatFragment;
import com.mithrilmania.blocktopograph.flat.FlatLayers;
import com.mithrilmania.blocktopograph.flat.Layer;
import com.mithrilmania.blocktopograph.map.Biome;
import com.mithrilmania.blocktopograph.map.KnownBlock;
import com.mithrilmania.blocktopograph.nbt.InventoryHolder;
import com.mithrilmania.blocktopograph.nbt.ItemTag;
import com.mithrilmania.blocktopograph.nbt.Keys;
Expand Down Expand Up @@ -217,10 +217,10 @@ protected Boolean doInBackground(Void... voids) {
if (lsize != 4) mIsVanillaFlat = false;
else {
Layer ltest = layers.get(0);
mIsVanillaFlat = ltest.block == KnownBlock.B_31_2_TALLGRASS_GRASS && ltest.amount == 1
&& (ltest = layers.get(1)).block == KnownBlock.B_2_0_GRASS && ltest.amount == 1
&& (ltest = layers.get(2)).block == KnownBlock.B_3_0_DIRT && ltest.amount == 29
&& (ltest = layers.get(3)).block == KnownBlock.B_7_0_BEDROCK && ltest.amount == 1;
mIsVanillaFlat = ltest.block == KnownBlockRepr.B_31_2_TALLGRASS_GRASS && ltest.amount == 1
&& (ltest = layers.get(1)).block == KnownBlockRepr.B_2_0_GRASS && ltest.amount == 1
&& (ltest = layers.get(2)).block == KnownBlockRepr.B_3_0_DIRT && ltest.amount == 29
&& (ltest = layers.get(3)).block == KnownBlockRepr.B_7_0_BEDROCK && ltest.amount == 1;
}
Layer[] alayers = new Layer[lsize < 3 ? 3 : lsize];
for (int i = 0; i < lsize; i++) {
Expand Down
126 changes: 65 additions & 61 deletions app/src/main/java/com/mithrilmania/blocktopograph/WorldData.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,21 @@
import android.annotation.SuppressLint;
import android.util.LruCache;

import androidx.annotation.Nullable;

import com.litl.leveldb.DB;
import com.litl.leveldb.Iterator;
import com.mithrilmania.blocktopograph.block.BlockRegistry;
import com.mithrilmania.blocktopograph.chunk.Chunk;
import com.mithrilmania.blocktopograph.chunk.ChunkTag;
import com.mithrilmania.blocktopograph.map.Block;
import com.mithrilmania.blocktopograph.chunk.Version;
import com.mithrilmania.blocktopograph.map.Dimension;
import com.mithrilmania.blocktopograph.map.KnownBlock;
import com.mithrilmania.blocktopograph.map.UnknownBlock;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* Wrapper around level.dat world spec en levelDB database.
*/
Expand All @@ -39,7 +34,7 @@ public class WorldData {

public WorldData(World world) {
this.world = new WeakReference<>(world);
this.mBlockRegistry = new BlockRegistry();
this.mBlockRegistry = new BlockRegistry(2048);
}

static String bytesToHex(byte[] bytes, int start, int end) {
Expand Down Expand Up @@ -165,15 +160,22 @@ public void removeChunkData(int x, int z, ChunkTag type, Dimension dimension, by
db.delete(getChunkDataKey(x, z, type, dimension, subChunk, asSubChunk));
}

public Chunk getChunk(int cX, int cZ, Dimension dimension, boolean createIfMissing, Version createOfVersion) {
Key key = new Key(cX, cZ, dimension);
key.createIfMissng = createIfMissing;
key.createOfVersion = createOfVersion;
return chunks.get(key);
}

public Chunk getChunk(int cX, int cZ, Dimension dimension) {
Key key = new Key(cX, cZ, dimension);
return chunks.get(key);
}

// Avoid using cache for stream like operations.
// Caller shall lock cache before operation and invalidate cache afterwards.
public Chunk getChunkStreaming(int cx, int cz, Dimension dimension) {
return Chunk.create(this, cx, cz, dimension);
public Chunk getChunkStreaming(int cx, int cz, Dimension dimension, boolean createIfMissing, Version createOfVersion) {
return Chunk.create(this, cx, cz, dimension, createIfMissing, createOfVersion);
}

public void resetCache() {
Expand Down Expand Up @@ -223,14 +225,16 @@ protected void entryRemoved(boolean evicted, Key key, Chunk oldValue, Chunk newV
protected Chunk create(Key key) {
WorldData worldData = this.worldData.get();
if (worldData == null) return null;
return Chunk.create(worldData, key.x, key.z, key.dim);
return Chunk.create(worldData, key.x, key.z, key.dim, key.createIfMissng, key.createOfVersion);
}
}

static class Key {

public int x, z;
Dimension dim;
public Dimension dim;
public boolean createIfMissng;
public Version createOfVersion;

Key(int x, int z, Dimension dim) {
this.x = x;
Expand Down Expand Up @@ -276,52 +280,52 @@ public WorldDBLoadException(String msg) {
}
}

public static class BlockRegistry {

private List<UnknownBlock> mUnknownBlocks;
private HashMap<String, UnknownBlock[]> mUnknownBlocksIndex;

BlockRegistry() {
mUnknownBlocks = new ArrayList<>(256);
mUnknownBlocksIndex = new HashMap<>(256);
}

@NotNull
public Block resolveBlock(@NonNull String name, int val) {

// Only "minecraft" namespace or no namespace allowed.
int dotPos = name.indexOf(':');
if (dotPos != -1) {
if (!name.substring(0, dotPos).equals("minecraft")) return KnownBlock.B_0_0_AIR;
name = name.substring(dotPos + 1);
}
Block block = KnownBlock.getBlockNew(name, val);
if (block != null) return block;

// Unknown block.
UnknownBlock[] unks = mUnknownBlocksIndex.get(name);
if (unks == null) {
unks = new UnknownBlock[16];
mUnknownBlocksIndex.put(name, unks);
}
if (val < 0 || val > 15) return KnownBlock.B_0_0_AIR;
UnknownBlock unk = unks[val];
if (unk == null) {
unk = new UnknownBlock(mUnknownBlocks.size() + (256 << 8) - 1, name, val);
unks[val] = unk;
mUnknownBlocks.add(unk);
}
return unk;
}

@Nullable
public Block getBlockByRuntimeId(int runtimeId) {
Block block = KnownBlock.getBlock(runtimeId);
if (block != null) return block;
int index = runtimeId - (256 << 8);
if (index < 0 || index >= mUnknownBlocks.size()) return null;
return mUnknownBlocks.get(runtimeId);
}
}
// public static class BlockRegistry {
//
// private List<UnknownBlock> mUnknownBlocks;
// private HashMap<String, UnknownBlock[]> mUnknownBlocksIndex;
//
// BlockRegistry() {
// mUnknownBlocks = new ArrayList<>(256);
// mUnknownBlocksIndex = new HashMap<>(256);
// }
//
// @NotNull
// public Block resolveBlock(@NonNull String name, int val) {
//
// // Only "minecraft" namespace or no namespace allowed.
// int dotPos = name.indexOf(':');
// if (dotPos != -1) {
// if (!name.substring(0, dotPos).equals("minecraft")) return KnownBlockRepr.B_0_0_AIR;
// name = name.substring(dotPos + 1);
// }
// Block block = KnownBlockRepr.getBlockNew(name, val);
// if (block != null) return block;
//
// // Unknown block.
// UnknownBlock[] unks = mUnknownBlocksIndex.get(name);
// if (unks == null) {
// unks = new UnknownBlock[16];
// mUnknownBlocksIndex.put(name, unks);
// }
// if (val < 0 || val > 15) return KnownBlockRepr.B_0_0_AIR;
// UnknownBlock unk = unks[val];
// if (unk == null) {
// unk = new UnknownBlock(mUnknownBlocks.size() + (256 << 8) - 1, name, val);
// unks[val] = unk;
// mUnknownBlocks.add(unk);
// }
// return unk;
// }
//
// @Nullable
// public Block getBlockByRuntimeId(int runtimeId) {
// Block block = KnownBlockRepr.getBlock(runtimeId);
// if (block != null) return block;
// int index = runtimeId - (256 << 8);
// if (index < 0 || index >= mUnknownBlocks.size()) return null;
// return mUnknownBlocks.get(runtimeId);
// }
// }

}
84 changes: 84 additions & 0 deletions app/src/main/java/com/mithrilmania/blocktopograph/block/Block.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.mithrilmania.blocktopograph.block;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.mithrilmania.blocktopograph.nbt.tags.CompoundTag;
import com.mithrilmania.blocktopograph.nbt.tags.Tag;

import java.util.ArrayList;

public class Block {

@NonNull
private BlockType blockType;

@Nullable
private KnownBlockRepr legacyBlock;

@NonNull
private CompoundTag states;

private int version;

Block(@NonNull BlockType blockType, @NonNull CompoundTag states, int version) {
this.blockType = blockType;
this.states = states;
this.version = version;
legacyBlock = BlockWithStatesToLegacyBlockMapper.getBestRepr(this);
if (legacyBlock == null) legacyBlock = KnownBlockRepr.guessBlockNew(blockType.getName());
}

Block(@NonNull BlockType blockType, @NonNull KnownBlockRepr legacyBlock, int version) {
this.blockType = blockType;
this.states = new CompoundTag("", new ArrayList<>());
this.version = version;
this.legacyBlock = legacyBlock;
}

@NonNull
public String getMinecraftBlockTypeNoPrefix() {
String name = blockType.getName();
int index = name.indexOf(':');
if (index != -1 && name.substring(0, index).equals("minecraft"))
name = name.substring(index + 1);
return name;
}

@NonNull
public String getBlockType() {
return blockType.getName();
}

public int getVersion() {
return version;
}

public boolean isOfSameType(Block block) {
return blockType == block.blockType;
}

public Tag getState(String key) {
return states.getChildTagByKey(key);
}

@Nullable
public KnownBlockRepr getLegacyBlock() {
return legacyBlock;
}

@NonNull
public CompoundTag getStates() {
return states;
}

@Override
public boolean equals(@Nullable Object obj) {
if (!(obj instanceof Block)) return false;
Block another = (Block) obj;
// Ref compare.
if (blockType != another.blockType) return false;
return states.equals(another.states);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.mithrilmania.blocktopograph.block;

import androidx.annotation.NonNull;

import com.mithrilmania.blocktopograph.nbt.tags.CompoundTag;

import java.util.Hashtable;
import java.util.Map;

public class BlockRegistry {

private int limitedTypes;
private Map<String, BlockType> blockTypes;

public BlockRegistry() {
blockTypes = new Hashtable<>(1024);
}

public BlockRegistry(int limitedTypes) {
this();
this.limitedTypes = limitedTypes;
}

@NonNull
private BlockType getBlockType(String name) {
BlockType ret = blockTypes.get(name);
if (ret == null) {
ret = new BlockType(name);
if (limitedTypes > 0 && blockTypes.size() >= limitedTypes)
throw new RuntimeException("Block types exceeds your set limit.");
blockTypes.put(name, ret);
}
return ret;
}

@NonNull
public Block createBlock(@NonNull String name, @NonNull CompoundTag states, int version) {
return new Block(getBlockType(name), states, version);
}

@NonNull
public Block createBlock(@NonNull KnownBlockRepr legacyBlock) {
return new Block(getBlockType(legacyBlock.str), legacyBlock, 1);
}

}
Loading

0 comments on commit 47251af

Please sign in to comment.