Skip to content

Commit 5168bfc

Browse files
committed
Add blockIdMapping supported by forges block-id registry in the level.dat file of the world
1 parent a6bf0ae commit 5168bfc

File tree

8 files changed

+163
-47
lines changed

8 files changed

+163
-47
lines changed

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockIdConfig.java

Lines changed: 108 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
public class BlockIdConfig implements BlockIdMapper {
3939

4040
private ConfigurationLoader<? extends ConfigurationNode> autopoulationConfigLoader;
41-
private Map<BlockIDMeta, BlockState> mappings;
41+
private Map<BlockNumeralIDMeta, BlockState> numeralMappings;
42+
private Map<BlockIDMeta, BlockState> idMappings;
4243

4344
public BlockIdConfig(ConfigurationNode node) {
4445
this(node, null);
@@ -47,29 +48,39 @@ public BlockIdConfig(ConfigurationNode node) {
4748
public BlockIdConfig(ConfigurationNode node, ConfigurationLoader<? extends ConfigurationNode> autopoulationConfigLoader) {
4849
this.autopoulationConfigLoader = autopoulationConfigLoader;
4950

50-
mappings = new HashMap<>();
51+
numeralMappings = new HashMap<>();
52+
idMappings = new HashMap<>();
5153

5254
for (Entry<Object, ? extends ConfigurationNode> e : node.getChildrenMap().entrySet()){
5355
String key = e.getKey().toString();
5456
String value = e.getValue().getString();
5557

5658
try {
57-
int splitIndex = key.indexOf(':');
58-
int blockId, blockMeta;
59-
if (splitIndex > 0 && splitIndex < key.length() - 1) {
60-
blockId = Integer.parseInt(key.substring(0, splitIndex));
61-
blockMeta = Integer.parseInt(key.substring(splitIndex + 1));
62-
} else {
63-
blockId = Integer.parseInt(key);
64-
blockMeta = 0;
65-
}
59+
int splitIndex = key.lastIndexOf(':');
6660

67-
BlockIDMeta idmeta = new BlockIDMeta(blockId, blockMeta);
68-
BlockState state = BlockState.fromString(value);
61+
if (splitIndex <= 0 || splitIndex >= key.length() - 1) {
62+
Logger.global.logWarning("Loading BlockIdConfig: Failed to parse blockid:meta from key '" + key + "'");
63+
continue;
64+
}
6965

70-
if (blockId == 0) state = BlockState.AIR; //use the static field to increase render speed (== comparison)
66+
String blockId = key.substring(0, splitIndex);
67+
int blockNumeralId;
68+
try {
69+
blockNumeralId = Integer.parseInt(blockId);
70+
} catch (NumberFormatException ex) {
71+
blockNumeralId = -1;
72+
}
73+
int blockMeta = Integer.parseInt(key.substring(splitIndex + 1));
74+
BlockState state = BlockState.fromString(value);
7175

72-
mappings.put(idmeta, state);
76+
if (blockNumeralId >= 0) {
77+
BlockNumeralIDMeta idmeta = new BlockNumeralIDMeta(blockNumeralId, blockMeta);
78+
if (blockNumeralId == 0) state = BlockState.AIR; //use the static field to increase render speed (== comparison)
79+
numeralMappings.put(idmeta, state);
80+
} else {
81+
BlockIDMeta idmeta = new BlockIDMeta(blockId, blockMeta);
82+
idMappings.put(idmeta, state);
83+
}
7384
} catch (NumberFormatException ex) {
7485
Logger.global.logWarning("Loading BlockIdConfig: Failed to parse blockid:meta from key '" + key + "'");
7586
} catch (IllegalArgumentException ex) {
@@ -79,22 +90,22 @@ public BlockIdConfig(ConfigurationNode node, ConfigurationLoader<? extends Confi
7990
}
8091

8192
@Override
82-
public BlockState get(int id, int meta) {
83-
if (id == 0) return BlockState.AIR;
93+
public BlockState get(int numeralId, int meta) {
94+
if (numeralId == 0) return BlockState.AIR;
8495

85-
BlockIDMeta idmeta = new BlockIDMeta(id, meta);
86-
BlockState state = mappings.get(idmeta);
96+
BlockNumeralIDMeta numidmeta = new BlockNumeralIDMeta(numeralId, meta);
97+
BlockState state = numeralMappings.get(numidmeta);
8798

8899
if (state == null) {
89-
state = mappings.getOrDefault(new BlockIDMeta(id, 0), BlockState.MISSING); //meta-fallback
100+
state = numeralMappings.getOrDefault(new BlockNumeralIDMeta(numeralId, 0), BlockState.MISSING); //meta-fallback
90101

91102
if (autopoulationConfigLoader != null) {
92-
mappings.put(idmeta, state);
103+
numeralMappings.put(numidmeta, state);
93104

94105
synchronized (autopoulationConfigLoader) {
95106
try {
96107
ConfigurationNode node = autopoulationConfigLoader.load();
97-
node.getNode(id + ":" + meta).setValue(state.toString());
108+
node.getNode(numeralId + ":" + meta).setValue(state.toString());
98109
autopoulationConfigLoader.save(node);
99110
} catch (IOException ex) {
100111
Logger.global.noFloodError("blockidconf-autopopulate-ioex", "Failed to auto-populate BlockIdConfig!", ex);
@@ -105,12 +116,50 @@ public BlockState get(int id, int meta) {
105116

106117
return state;
107118
}
119+
120+
@Override
121+
public BlockState get(String id, int numeralId, int meta) {
122+
if (numeralId == 0) return BlockState.AIR;
123+
124+
BlockIDMeta idmeta = new BlockIDMeta(id, meta);
125+
BlockState state = idMappings.get(idmeta);
126+
if (state == null) {
127+
BlockNumeralIDMeta numidmeta = new BlockNumeralIDMeta(numeralId, meta);
128+
state = numeralMappings.get(numidmeta);
129+
if (state == null) {
130+
131+
state = idMappings.get(new BlockIDMeta(id, 0));
132+
if (state == null) {
133+
state = numeralMappings.get(new BlockNumeralIDMeta(numeralId, 0));
134+
if (state == null) state = new BlockState(id);
135+
}
136+
137+
if (autopoulationConfigLoader != null) {
138+
idMappings.put(idmeta, state);
139+
numeralMappings.put(numidmeta, state);
140+
141+
synchronized (autopoulationConfigLoader) {
142+
try {
143+
ConfigurationNode node = autopoulationConfigLoader.load();
144+
node.getNode(id + ":" + meta).setValue(state.toString());
145+
autopoulationConfigLoader.save(node);
146+
} catch (IOException ex) {
147+
Logger.global.noFloodError("blockidconf-autopopulate-ioex", "Failed to auto-populate BlockIdConfig!", ex);
148+
}
149+
}
150+
}
151+
152+
}
153+
}
154+
155+
return state;
156+
}
108157

109-
class BlockIDMeta {
158+
class BlockNumeralIDMeta {
110159
private final int id;
111160
private final int meta;
112161

113-
public BlockIDMeta(int id, int meta) {
162+
public BlockNumeralIDMeta(int id, int meta) {
114163
this.id = id;
115164
this.meta = meta;
116165
}
@@ -125,14 +174,47 @@ public int getMeta() {
125174

126175
@Override
127176
public int hashCode() {
128-
return id * 0xFFFF + meta;
177+
return id * 16 + meta;
178+
}
179+
180+
@Override
181+
public boolean equals(Object obj) {
182+
if (obj instanceof BlockNumeralIDMeta) {
183+
BlockNumeralIDMeta other = (BlockNumeralIDMeta) obj;
184+
return other.id == id && other.meta == meta;
185+
}
186+
187+
return false;
188+
}
189+
}
190+
191+
class BlockIDMeta {
192+
private final String id;
193+
private final int meta;
194+
195+
public BlockIDMeta(String id, int meta) {
196+
this.id = id;
197+
this.meta = meta;
198+
}
199+
200+
public String getId() {
201+
return id;
202+
}
203+
204+
public int getMeta() {
205+
return meta;
206+
}
207+
208+
@Override
209+
public int hashCode() {
210+
return id.hashCode() * 16 + meta;
129211
}
130212

131213
@Override
132214
public boolean equals(Object obj) {
133215
if (obj instanceof BlockIDMeta) {
134216
BlockIDMeta other = (BlockIDMeta) obj;
135-
return other.id == id && other.meta == meta;
217+
return other.id.equals(id) && other.meta == meta;
136218
}
137219

138220
return false;

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/BlockPropertiesConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ public BlockPropertiesConfig(ConfigurationNode node, ResourcePack resourcePack,
6868
try {
6969
BlockState bsKey = BlockState.fromString(key);
7070
BlockProperties bsValue = new BlockProperties(
71-
e.getValue().getNode("culling").getBoolean(false),
72-
e.getValue().getNode("occluding").getBoolean(false),
71+
e.getValue().getNode("culling").getBoolean(true),
72+
e.getValue().getNode("occluding").getBoolean(true),
7373
e.getValue().getNode("flammable").getBoolean(false)
7474
);
7575
BlockStateMapping<BlockProperties> mapping = new BlockStateMapping<>(bsKey, bsValue);

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/config/ConfigManager.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public void loadResourceConfigs(ResourcePack resourcePack) throws IOException {
154154
blockIdsConfigNode = joinFromResourcePack(resourcePack, "blockIds.json", blockIdsConfigNode);
155155
blockIdConfig = new BlockIdConfig(
156156
blockIdsConfigNode,
157-
null //getLoader(makeAutogen(getBlockIdConfigFile()))
157+
getLoader(makeAutogen(getBlockIdConfigFile()))
158158
);
159159

160160
//load blockProperties.json from resources, config-folder and resourcepack
@@ -170,7 +170,7 @@ public void loadResourceConfigs(ResourcePack resourcePack) throws IOException {
170170
blockPropertiesConfig = new BlockPropertiesConfig(
171171
blockPropertiesConfigNode,
172172
resourcePack,
173-
null //getLoader(makeAutogen(getBlockPropertiesConfigFile()))
173+
getLoader(makeAutogen(getBlockPropertiesConfigFile()))
174174
);
175175

176176
//load biomes.json from resources, config-folder and resourcepack
@@ -185,7 +185,7 @@ public void loadResourceConfigs(ResourcePack resourcePack) throws IOException {
185185
biomeConfigNode = joinFromResourcePack(resourcePack, "biomes.json", biomeConfigNode);
186186
biomeConfig = new BiomeConfig(
187187
biomeConfigNode,
188-
null //getLoader(makeAutogen(getBiomeConfigFile()))
188+
getLoader(makeAutogen(getBiomeConfigFile()))
189189
);
190190
}
191191

@@ -255,13 +255,11 @@ private ConfigurationNode loadOrCreate(File configFile, URL defaultConfig, URL d
255255
return configNode;
256256
}
257257

258-
/*
259258
private File makeAutogen(File file) throws IOException {
260-
File autogenFile = file.getCanonicalFile().toPath().getParent().resolve("generated").resolve(file.getName()).toFile();
259+
File autogenFile = file.getCanonicalFile().toPath().getParent().resolve("missing-configs").resolve(file.getName()).toFile();
261260
autogenFile.getParentFile().mkdirs();
262261
return autogenFile;
263262
}
264-
*/
265263

266264
private ConfigurationLoader<? extends ConfigurationNode> getLoader(String filename, InputStream is){
267265
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/ChunkAnvil112.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,12 @@ public BlockState getBlockState(Vector3i pos) {
149149

150150
int blockData = getByteHalf(this.data[blockHalfByteIndex], largeHalf);
151151

152-
BlockState blockState = blockIdMapper.get(blockId, blockData);
153-
154-
return blockState;
152+
String forgeIdMapping = getWorld().getForgeBlockIdMapping(blockId);
153+
if (forgeIdMapping != null) {
154+
return blockIdMapper.get(forgeIdMapping, blockId, blockData);
155+
} else {
156+
return blockIdMapper.get(blockId, blockData);
157+
}
155158
}
156159

157160
public String getBlockIdMeta(Vector3i pos) {
@@ -169,8 +172,9 @@ public String getBlockIdMeta(Vector3i pos) {
169172
}
170173

171174
int blockData = getByteHalf(this.data[blockHalfByteIndex], largeHalf);
175+
String forgeIdMapping = getWorld().getForgeBlockIdMapping(blockId);
172176

173-
return blockId + ":" + blockData;
177+
return blockId + ":" + blockData + " " + forgeIdMapping;
174178
}
175179

176180
public LightData getLightData(Vector3i pos) {

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAWorld.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
import java.util.ArrayList;
3636
import java.util.Collection;
3737
import java.util.Collections;
38+
import java.util.HashMap;
3839
import java.util.List;
40+
import java.util.Map;
3941
import java.util.Objects;
4042
import java.util.UUID;
4143
import java.util.concurrent.ExecutionException;
@@ -71,6 +73,7 @@
7173
import de.bluecolored.bluemap.core.world.LightData;
7274
import de.bluecolored.bluemap.core.world.World;
7375
import net.querz.nbt.CompoundTag;
76+
import net.querz.nbt.ListTag;
7477
import net.querz.nbt.NBTUtil;
7578
import net.querz.nbt.Tag;
7679
import net.querz.nbt.mca.CompressionType;
@@ -105,6 +108,8 @@ public class MCAWorld implements World {
105108
private BlockPropertiesMapper blockPropertiesMapper;
106109
private BiomeMapper biomeMapper;
107110

111+
private Map<Integer, String> forgeBlockMappings;
112+
108113
private MCAWorld(
109114
Path worldFolder,
110115
UUID uuid,
@@ -125,8 +130,10 @@ private MCAWorld(
125130
this.blockIdMapper = blockIdMapper;
126131
this.blockPropertiesMapper = blockPropertiesMapper;
127132
this.biomeMapper = biomeMapper;
133+
134+
this.forgeBlockMappings = new HashMap<>();
128135
}
129-
136+
130137
public BlockState getBlockState(Vector3i pos) {
131138
try {
132139

@@ -335,6 +342,10 @@ public void setBiomeMapper(BiomeMapper biomeMapper) {
335342
public Path getWorldFolder() {
336343
return worldFolder;
337344
}
345+
346+
public String getForgeBlockIdMapping(int id) {
347+
return forgeBlockMappings.get(id);
348+
}
338349

339350
private Path getRegionFolder() {
340351
return worldFolder.resolve("region");
@@ -360,7 +371,8 @@ public static MCAWorld load(Path worldFolder, UUID uuid, BlockIdMapper blockIdMa
360371

361372

362373
CHUNK_CACHE.invalidateAll();
363-
return new MCAWorld(
374+
375+
MCAWorld world = new MCAWorld(
364376
worldFolder,
365377
uuid,
366378
name,
@@ -371,6 +383,21 @@ public static MCAWorld load(Path worldFolder, UUID uuid, BlockIdMapper blockIdMa
371383
blockPropertiesMapper,
372384
biomeIdMapper
373385
);
386+
387+
try {
388+
ListTag<? extends Tag<?>> blockIdReg = level.getCompoundTag("FML").getCompoundTag("Registries").getCompoundTag("minecraft:blocks").getListTag("ids");
389+
for (Tag<?> tag : blockIdReg) {
390+
if (tag instanceof CompoundTag) {
391+
CompoundTag entry = (CompoundTag) tag;
392+
String blockId = entry.getString("K");
393+
int numeralId = entry.getInt("V");
394+
395+
world.forgeBlockMappings.put(numeralId, blockId);
396+
}
397+
}
398+
} catch (NullPointerException ignore) {}
399+
400+
return world;
374401
} catch (ClassCastException | NullPointerException ex) {
375402
throw new IOException("Invaid level.dat format!", ex);
376403
}

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/mapping/BlockIdMapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@
2626

2727
import de.bluecolored.bluemap.core.world.BlockState;
2828

29-
@FunctionalInterface
3029
public interface BlockIdMapper {
3130

3231
BlockState get(int id, int meta);
32+
33+
BlockState get(String id, int numeralId, int meta);
3334

3435
}

BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resourcepack/BlockStateResource.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ public Collection<TransformedBlockModelResource> getModels(BlockState blockState
8686
models.add(variant.getModel(pos));
8787
}
8888
}
89+
90+
//fallback to first variant
91+
if (models.isEmpty() && !variants.isEmpty()) {
92+
models.add(variants.get(0).getModel(pos));
93+
}
8994

9095
return models;
9196
}

0 commit comments

Comments
 (0)