1414import net .easecation .bridge .adapter .easecation .entity .EntityDataDriven ;
1515import net .easecation .bridge .core .*;
1616import org .itxtech .synapseapi .multiprotocol .utils .AvailableEntityIdentifiersPalette ;
17+ import org .itxtech .synapseapi .multiprotocol .utils .CreativeItemsPalette ;
1718
1819import java .util .ArrayList ;
1920import 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