Skip to content

Commit 9c7dcb6

Browse files
committed
feat: implement version upgrade framework with support for multiple Minecraft versions
1 parent 013de39 commit 9c7dcb6

19 files changed

Lines changed: 3028 additions & 20 deletions

addon-bridge-core/src/main/java/net/easecation/bridge/core/AddonParser.java

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import net.easecation.bridge.core.dto.block.v1_21_60.BlockDefinitions;
66
import net.easecation.bridge.core.dto.entity.v1_21_60.Entity;
77
import net.easecation.bridge.core.dto.item.v1_21_60.Item;
8+
import net.easecation.bridge.core.versioned.VersionedDtoLoader;
89

910
import java.io.File;
1011
import java.io.IOException;
@@ -24,6 +25,7 @@
2425
*/
2526
public class AddonParser {
2627
private static final ObjectMapper MAPPER = createObjectMapper();
28+
private final VersionedDtoLoader dtoLoader = new VersionedDtoLoader(MAPPER);
2729
private final BridgeLogger log;
2830

2931
public AddonParser(BridgeLogger log) {
@@ -34,6 +36,7 @@ public AddonParser(BridgeLogger log) {
3436
@Override public void debug(String msg) { System.out.println("[DEBUG] " + msg); }
3537
@Override public void trace(String msg) { System.out.println("[TRACE] " + msg); }
3638
};
39+
this.dtoLoader.setLogger(this.log);
3740
}
3841

3942
private static ObjectMapper createObjectMapper() {
@@ -159,8 +162,11 @@ private AddonPack parseZipPack(File zipFile) throws IOException {
159162
// Parse wrapper: {"format_version": "1.21.60", "minecraft:block": {...}}
160163
Map<String, Object> wrapper = MAPPER.readValue(json, Map.class);
161164
if (wrapper.containsKey("minecraft:block")) {
165+
String formatVersion = (String) wrapper.get("format_version");
162166
Object blockData = wrapper.get("minecraft:block");
163-
BlockDefinitions blockDef = MAPPER.convertValue(blockData, BlockDefinitions.class);
167+
168+
// Load and upgrade to latest version
169+
BlockDefinitions blockDef = dtoLoader.loadBlock(blockData, formatVersion);
164170
blocks.add(BlockDef.fromDTO(blockDef));
165171
}
166172
} catch (Exception e) {
@@ -184,8 +190,17 @@ private AddonPack parseZipPack(File zipFile) throws IOException {
184190
// Parse wrapper: {"format_version": "1.21.60", "minecraft:entity": {...}}
185191
Map<String, Object> wrapper = MAPPER.readValue(json, Map.class);
186192
if (wrapper.containsKey("minecraft:entity")) {
193+
String formatVersion = (String) wrapper.get("format_version");
187194
Object entityData = wrapper.get("minecraft:entity");
188-
Entity entityDto = MAPPER.convertValue(entityData, Entity.class);
195+
196+
// Load and upgrade to latest version
197+
Entity entityDto = dtoLoader.loadEntity(entityData, formatVersion);
198+
try {
199+
String entityJson = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(entityDto);
200+
log.info(String.format("Final upgraded Entity DTO as JSON:\n%s", entityJson));
201+
} catch (Exception e) {
202+
log.warning("Failed to serialize Entity DTO to JSON: " + e.getMessage());
203+
}
189204
entities.add(EntityDef.fromDTO(entityDto));
190205
entityParsedCount++;
191206
} else {
@@ -204,7 +219,7 @@ private AddonPack parseZipPack(File zipFile) throws IOException {
204219
log.info("Entity parsing: found " + entityFileCount + " files, successfully parsed " + entityParsedCount);
205220
}
206221

207-
// Parse items (including Netease edition items) - using v1_21_60 DTO
222+
// Parse items (including Netease edition items)
208223
List<ItemDef> items = new ArrayList<>();
209224
entries = zip.entries();
210225
while (entries.hasMoreElements()) {
@@ -214,11 +229,16 @@ private AddonPack parseZipPack(File zipFile) throws IOException {
214229
try (InputStream is = zip.getInputStream(entry)) {
215230
String json = new String(is.readAllBytes(), StandardCharsets.UTF_8);
216231

217-
// Parse using Jackson to v1_21_60.Item DTO
218-
Item item = MAPPER.readValue(json, Item.class);
232+
// Parse as Map to extract format_version
233+
Map<String, Object> itemMap = MAPPER.readValue(json, Map.class);
234+
String formatVersion = (String) itemMap.get("format_version");
235+
236+
// Load and upgrade to latest version (ItemsDefinition)
237+
net.easecation.bridge.core.dto.item.v1_21_60.ItemsDefinition itemsDef =
238+
dtoLoader.loadItem(itemMap, formatVersion);
219239

220-
// Convert to ItemDef (using latest version)
221-
ItemDef itemDef = ItemDef.fromDTO(item);
240+
// Convert to ItemDef (using latest version Item from ItemsDefinition)
241+
ItemDef itemDef = ItemDef.fromDTO(itemsDef.minecraft_item());
222242
items.add(itemDef);
223243
} catch (Exception e) {
224244
log.debug("Failed to parse item: " + name + " - " + e.getMessage());
@@ -261,8 +281,11 @@ private AddonPack parseDirectoryPack(Path packRoot) throws IOException {
261281
String json = Files.readString(blockFile, StandardCharsets.UTF_8);
262282
Map<String, Object> wrapper = MAPPER.readValue(json, Map.class);
263283
if (wrapper.containsKey("minecraft:block")) {
284+
String formatVersion = (String) wrapper.get("format_version");
264285
Object blockData = wrapper.get("minecraft:block");
265-
BlockDefinitions blockDef = MAPPER.convertValue(blockData, BlockDefinitions.class);
286+
287+
// Load and upgrade to latest version
288+
BlockDefinitions blockDef = dtoLoader.loadBlock(blockData, formatVersion);
266289
blocks.add(BlockDef.fromDTO(blockDef));
267290
}
268291
} catch (Exception e) {
@@ -280,8 +303,11 @@ private AddonPack parseDirectoryPack(Path packRoot) throws IOException {
280303
String json = Files.readString(blockFile, StandardCharsets.UTF_8);
281304
Map<String, Object> wrapper = MAPPER.readValue(json, Map.class);
282305
if (wrapper.containsKey("minecraft:block")) {
306+
String formatVersion = (String) wrapper.get("format_version");
283307
Object blockData = wrapper.get("minecraft:block");
284-
BlockDefinitions blockDef = MAPPER.convertValue(blockData, BlockDefinitions.class);
308+
309+
// Load and upgrade to latest version
310+
BlockDefinitions blockDef = dtoLoader.loadBlock(blockData, formatVersion);
285311
blocks.add(BlockDef.fromDTO(blockDef));
286312
}
287313
} catch (Exception e) {
@@ -304,8 +330,17 @@ private AddonPack parseDirectoryPack(Path packRoot) throws IOException {
304330
String json = Files.readString(entityFile, StandardCharsets.UTF_8);
305331
Map<String, Object> wrapper = MAPPER.readValue(json, Map.class);
306332
if (wrapper.containsKey("minecraft:entity")) {
333+
String formatVersion = (String) wrapper.get("format_version");
307334
Object entityData = wrapper.get("minecraft:entity");
308-
Entity entityDto = MAPPER.convertValue(entityData, Entity.class);
335+
336+
// Load and upgrade to latest version
337+
Entity entityDto = dtoLoader.loadEntity(entityData, formatVersion);
338+
try {
339+
String entityJson = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(entityDto);
340+
log.info(String.format("Final upgraded Entity DTO as JSON:\n%s", entityJson));
341+
} catch (Exception e) {
342+
log.warning("Failed to serialize Entity DTO to JSON: " + e.getMessage());
343+
}
309344
entities.add(EntityDef.fromDTO(entityDto));
310345
entityParsedCount[0]++;
311346
} else {
@@ -333,9 +368,17 @@ private AddonPack parseDirectoryPack(Path packRoot) throws IOException {
333368
.forEach(itemFile -> {
334369
try {
335370
String json = Files.readString(itemFile, StandardCharsets.UTF_8);
336-
// Parse using Jackson to v1_21_60.Item DTO
337-
Item item = MAPPER.readValue(json, Item.class);
338-
ItemDef itemDef = ItemDef.fromDTO(item);
371+
372+
// Parse as Map to extract format_version
373+
Map<String, Object> itemMap = MAPPER.readValue(json, Map.class);
374+
String formatVersion = (String) itemMap.get("format_version");
375+
376+
// Load and upgrade to latest version (ItemsDefinition)
377+
net.easecation.bridge.core.dto.item.v1_21_60.ItemsDefinition itemsDef =
378+
dtoLoader.loadItem(itemMap, formatVersion);
379+
380+
// Convert to ItemDef (using latest version Item from ItemsDefinition)
381+
ItemDef itemDef = ItemDef.fromDTO(itemsDef.minecraft_item());
339382
items.add(itemDef);
340383
} catch (Exception e) {
341384
log.debug("Failed to parse item: " + itemFile + " - " + e.getMessage());
@@ -350,9 +393,17 @@ private AddonPack parseDirectoryPack(Path packRoot) throws IOException {
350393
.forEach(itemFile -> {
351394
try {
352395
String json = Files.readString(itemFile, StandardCharsets.UTF_8);
353-
// Parse using Jackson to v1_21_60.Item DTO
354-
Item item = MAPPER.readValue(json, Item.class);
355-
ItemDef itemDef = ItemDef.fromDTO(item);
396+
397+
// Parse as Map to extract format_version
398+
Map<String, Object> itemMap = MAPPER.readValue(json, Map.class);
399+
String formatVersion = (String) itemMap.get("format_version");
400+
401+
// Load and upgrade to latest version (ItemsDefinition)
402+
net.easecation.bridge.core.dto.item.v1_21_60.ItemsDefinition itemsDef =
403+
dtoLoader.loadItem(itemMap, formatVersion);
404+
405+
// Convert to ItemDef (using latest version Item from ItemsDefinition)
406+
ItemDef itemDef = ItemDef.fromDTO(itemsDef.minecraft_item());
356407
items.add(itemDef);
357408
} catch (Exception e) {
358409
log.debug("Failed to parse Netease item: " + itemFile + " - " + e.getMessage());

addon-bridge-core/src/main/java/net/easecation/bridge/core/versioned/FormatVersion.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ public int hashCode() {
7272
return Objects.hash(major, minor, patch);
7373
}
7474

75-
// Common versions as constants
75+
// Common versions as constants (matching version-mapping.json)
7676
public static final FormatVersion V1_19_0 = new FormatVersion(1, 19, 0);
7777
public static final FormatVersion V1_19_40 = new FormatVersion(1, 19, 40);
78-
public static final FormatVersion V1_19_80 = new FormatVersion(1, 19, 80);
79-
public static final FormatVersion V1_20_0 = new FormatVersion(1, 20, 0);
78+
public static final FormatVersion V1_19_50 = new FormatVersion(1, 19, 50);
79+
public static final FormatVersion V1_20_10 = new FormatVersion(1, 20, 10);
8080
public static final FormatVersion V1_20_41 = new FormatVersion(1, 20, 41);
8181
public static final FormatVersion V1_20_81 = new FormatVersion(1, 20, 81);
82-
public static final FormatVersion V1_21_20 = new FormatVersion(1, 21, 20);
82+
public static final FormatVersion V1_21_50 = new FormatVersion(1, 21, 50);
8383
public static final FormatVersion V1_21_60 = new FormatVersion(1, 21, 60);
8484

8585
// Default version (latest)

0 commit comments

Comments
 (0)