Skip to content

Commit b552928

Browse files
committed
refactor: change load phase to STARTUP and add custom content registration options
1 parent 37739a3 commit b552928

84 files changed

Lines changed: 3453 additions & 218 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
"Bash(gradle installToWorkspaces:*)",
1919
"WebFetch(domain:stackoverflow.com)",
2020
"Bash(npm run:*)",
21-
"Bash(xargs -I {} sh -c 'echo \"\"\"\"=== {} ===\"\"\"\" && head -30 {}')"
21+
"Bash(xargs -I {} sh -c 'echo \"\"\"\"=== {} ===\"\"\"\" && head -30 {}')",
22+
"Bash(jar -tf:*)",
23+
"Bash(javap:*)"
2224
],
2325
"deny": [],
2426
"ask": []

adapter-easecation/src/main/java/net/easecation/bridge/adapter/easecation/EasecationRegistry.java

Lines changed: 149 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import net.easecation.bridge.adapter.easecation.entity.EntityDataDriven;
1515
import net.easecation.bridge.core.*;
1616
import org.itxtech.synapseapi.multiprotocol.utils.AvailableEntityIdentifiersPalette;
17+
import org.itxtech.synapseapi.multiprotocol.utils.CreativeItemsPalette;
1718

1819
import java.util.ArrayList;
1920
import java.util.List;
@@ -33,8 +34,74 @@ public EasecationRegistry(BridgeLogger log) {
3334

3435
@Override
3536
public void registerItems(List<ItemDef> items) {
36-
log.info("[EaseCation] registerItems size=" + items.size());
37-
// TODO: Implement item registration
37+
if (items.isEmpty()) {
38+
return;
39+
}
40+
41+
log.debug("[EaseCation] Starting item registration: " + items.size() + " items");
42+
43+
int successCount = 0;
44+
int failureCount = 0;
45+
46+
for (ItemDef itemDef : items) {
47+
String itemId = itemDef.id();
48+
try {
49+
log.debug("[EaseCation] Processing item: " + itemId);
50+
51+
// 1. Allocate custom item ID
52+
int customItemId = cn.nukkit.item.Items.allocateCustomItemId();
53+
log.debug("[EaseCation] - Allocated custom item ID: " + customItemId);
54+
55+
// 2. Register to ItemDataDriven registry
56+
log.debug("[EaseCation] - Registering to ItemDataDriven registry...");
57+
net.easecation.bridge.adapter.easecation.item.ItemDataDriven.registerItemDef(customItemId, itemDef);
58+
59+
// 3. Build NBT data
60+
log.debug("[EaseCation] - Building NBT data...");
61+
CompoundTag nbt = buildItemNBT(itemDef);
62+
63+
// 4. Register custom item with Nukkit
64+
log.debug("[EaseCation] - Registering custom item to Nukkit...");
65+
cn.nukkit.item.Items.registerCustomItem(
66+
itemId,
67+
customItemId,
68+
net.easecation.bridge.adapter.easecation.item.ItemDataDriven.class,
69+
(meta, count) -> new net.easecation.bridge.adapter.easecation.item.ItemDataDriven(customItemId, meta, count),
70+
nbt
71+
);
72+
73+
// 5. Register to creative mode inventory
74+
log.debug("[EaseCation] - Registering to creative mode inventory...");
75+
CreativeItemsPalette.registerCustomItem(cn.nukkit.item.Item.get(customItemId));
76+
77+
log.debug("[EaseCation] ✓ Successfully registered: " + itemId + " (customItemId=" + customItemId + ")");
78+
successCount++;
79+
80+
} catch (Exception e) {
81+
failureCount++;
82+
log.error("[EaseCation] ✗ Failed to register item: " + itemId);
83+
log.error("[EaseCation] Error type: " + e.getClass().getSimpleName());
84+
log.error("[EaseCation] Error message: " + e.getMessage());
85+
86+
// Log stack trace with more context
87+
log.error("[EaseCation] Stack trace:");
88+
for (StackTraceElement element : e.getStackTrace()) {
89+
log.error("[EaseCation] at " + element.toString());
90+
if (element.getClassName().contains("easecation.bridge")) {
91+
break; // Only show our own code in the stack trace
92+
}
93+
}
94+
95+
// Log item definition details for debugging
96+
if (itemDef.components() != null) {
97+
log.error("[EaseCation] Item has components: YES");
98+
} else {
99+
log.error("[EaseCation] Item has components: NO");
100+
}
101+
}
102+
}
103+
104+
log.info("[EaseCation] Item registration completed - Success: " + successCount + ", Failed: " + failureCount);
38105
}
39106

40107
@Override
@@ -208,6 +275,13 @@ public Capabilities capabilities() {
208275
return CAPS;
209276
}
210277

278+
@Override
279+
public boolean requiresEarlyRegistration() {
280+
// EaseCation平台没有closeRegistry限制,可以在onEnable阶段注册
281+
// 这样更符合插件生命周期的最佳实践
282+
return false;
283+
}
284+
211285
@Override
212286
public void setupResourcePackPushing(List<DeployedPack> deployedPacks, BridgeConfig config, Object plugin) {
213287
if (!(plugin instanceof PluginBase pluginBase)) {
@@ -244,6 +318,11 @@ public void afterAllRegistrations() {
244318
cn.nukkit.item.ItemSerializer.rebuildRuntimeMapping();
245319
log.debug("[EaseCation] ✓ Item runtime mapping rebuilt");
246320

321+
// 缓存物品组件数据包(必须,用于自定义物品)
322+
// 这会缓存所有物品组件定义,用于发送给客户端
323+
org.itxtech.synapseapi.multiprotocol.utils.ItemComponentDefinitions.cachePackets();
324+
log.debug("[EaseCation] ✓ Item component definitions cached");
325+
247326
// 注册自定义实体标识符到网络协议层(必须)
248327
// 这让客户端能够识别和渲染自定义实体
249328
if (!registeredEntityIds.isEmpty()) {
@@ -378,6 +457,74 @@ private CompoundTag buildBlockNBT(BlockDef blockDef, int runtimeId) {
378457
throw new RuntimeException("Failed to build NBT for block " + blockDef.id(), e);
379458
}
380459
}
460+
461+
/**
462+
* Build NBT data for item registration.
463+
* The NBT contains item definition including properties and components.
464+
*
465+
* @param itemDef The item definition
466+
* @return CompoundTag containing the item NBT data
467+
*/
468+
private CompoundTag buildItemNBT(ItemDef itemDef) {
469+
try {
470+
log.trace("[EaseCation] Building NBT for: " + itemDef.id());
471+
472+
// Basic identifier
473+
CompoundTag nbt = new CompoundTag();
474+
nbt.putString("identifier", itemDef.id());
475+
476+
// Menu category (for creative inventory) - same as block implementation
477+
if (itemDef.menuCategory() != null) {
478+
log.trace("[EaseCation] - Adding menu category");
479+
CompoundTag menuCategory = new CompoundTag();
480+
var mc = itemDef.menuCategory();
481+
482+
menuCategory.putString("category", mc.category() != null ? mc.category() : "items");
483+
if (mc.group() != null && !mc.group().isEmpty()) {
484+
menuCategory.putString("group", mc.group());
485+
}
486+
if (mc.isHiddenInCommands() != null) {
487+
menuCategory.putBoolean("is_hidden_in_commands", mc.isHiddenInCommands());
488+
}
489+
490+
nbt.putCompound("menu_category", menuCategory);
491+
} else {
492+
// Default: add default menu_category (category="items")
493+
log.trace("[EaseCation] - Adding default menu category");
494+
nbt.putCompound("menu_category", new CompoundTag()
495+
.putString("category", "items")
496+
.putString("group", "")
497+
.putBoolean("is_hidden_in_commands", false)
498+
);
499+
}
500+
501+
// Add components NBT
502+
if (itemDef.components() != null) {
503+
log.trace("[EaseCation] - Adding components");
504+
try {
505+
CompoundTag componentsNBT = net.easecation.bridge.adapter.easecation.item.ItemComponentsNBT.toNBT(
506+
itemDef, // Pass the full ItemDef (includes menu_category)
507+
itemDef.id()
508+
);
509+
// Merge all component tags into the main NBT
510+
for (String key : componentsNBT.getTags().keySet()) {
511+
nbt.put(key, componentsNBT.get(key));
512+
}
513+
} catch (Exception e) {
514+
log.warning("[EaseCation] - Failed to convert components: " + e.getMessage());
515+
throw new RuntimeException("Failed to convert item components for " + itemDef.id(), e);
516+
}
517+
}
518+
519+
log.trace("[EaseCation] NBT build completed for: " + itemDef.id());
520+
return nbt;
521+
522+
} catch (Exception e) {
523+
log.error("[EaseCation] Failed to build NBT for item: " + itemDef.id());
524+
log.error("[EaseCation] Error: " + e.getClass().getSimpleName() + " - " + e.getMessage());
525+
throw new RuntimeException("Failed to build NBT for item " + itemDef.id(), e);
526+
}
527+
}
381528
}
382529

383530

0 commit comments

Comments
 (0)