15
15
import org .bukkit .inventory .meta .ItemMeta ;
16
16
17
17
import java .util .ArrayList ;
18
+ import java .util .HashMap ;
19
+ import java .util .Map ;
18
20
19
21
public final class Message {
20
22
public final BaseComponent inner ;
@@ -33,63 +35,75 @@ public Message appendFormat(Internationalization i18n, String template, Object..
33
35
}
34
36
35
37
public Message append (ItemStack item ) {
36
- return append (item , "{itemName} *{amount}" );
38
+ return append ("{itemName} *{amount}" , item );
37
39
}
38
40
41
+ /**
42
+ * supported syntax
43
+ * {itemName}: when cursor hovered on, item will be displayed, item at index=0
44
+ * {itemName:idx}: the number indicates the index of the item in items list
45
+ * {amount}: a number, item at index=0
46
+ * {amount:idx}: a number, item at index=idx (e.g {amount:0})
47
+ *
48
+ * @param template the template string
49
+ * @param items item list
50
+ * @return the Message
51
+ */
52
+ public Message append (String template , ItemStack ... items ) {
53
+ if (items == null || items .length == 0 ) return this ;
54
+ Map <String , BaseComponent > varMap = new HashMap <>();
55
+ for (int i = 0 ; i < items .length ; i ++) {
56
+ ItemStack clone = items [i ].clone ();
57
+ boolean hasCustomName = clone .hasItemMeta () && clone .getItemMeta ().hasDisplayName ();
58
+ BaseComponent cmp = hasCustomName ? new TextComponent (clone .getItemMeta ().getDisplayName ()) : I16rItemName .getUnlocalizedName (clone );
59
+ cmp .setHoverEvent (new HoverEvent (HoverEvent .Action .SHOW_ITEM , new BaseComponent []{new TextComponent (getItemJsonStripped (clone ))}));
60
+ varMap .put (String .format ("{amount:%d}" , i ), new TextComponent (Integer .toString (clone .getAmount ())));
61
+ varMap .put (String .format ("{itemName:%d}" , i ), cmp );
62
+ if (i == 0 ) {
63
+ varMap .put ("{amount}" , new TextComponent (Integer .toString (clone .getAmount ())));
64
+ varMap .put ("{itemName}" , cmp );
65
+ }
66
+ }
67
+
68
+ String remTemplate = template ;
69
+ while (remTemplate .length () > 0 ) {
70
+ int idx = remTemplate .length ();
71
+ String var = null ;
72
+ for (String v : varMap .keySet ()) {
73
+ int t = remTemplate .indexOf (v );
74
+ if (t >= 0 && t < idx ) {
75
+ idx = t ;
76
+ var = v ;
77
+ }
78
+ }
79
+
80
+ if (idx == -1 ) break ; // no more variables left
81
+ if (idx == 0 ) {
82
+ remTemplate = remTemplate .substring (var .length ());
83
+ append (varMap .get (var ));
84
+ }
85
+ if (idx > 0 ) {
86
+ append (remTemplate .substring (0 , idx ));
87
+ remTemplate = remTemplate .substring (idx );
88
+ }
89
+ }
90
+ if (remTemplate .length () > 0 ) append (remTemplate );
91
+ return this ;
92
+ }
93
+
94
+ /**
95
+ * @deprecated old buggy method, will be removed in the future
96
+ */
39
97
public Message append (ItemStack item , String display ) {
40
98
item = item .clone ();
41
99
boolean rawName = !(item .hasItemMeta () && item .getItemMeta ().hasDisplayName ());
42
100
BaseComponent nameComponent = rawName ? I16rItemName .getUnlocalizedName (item ) : new TextComponent (item .getItemMeta ().getDisplayName ());
43
101
BaseComponent result ;
44
- String itemJson = "" ;
45
- if (item .hasItemMeta () && item .getItemMeta () instanceof BookMeta ) {
46
- itemJson = ReflectionUtil .convertItemStackToJson (removeBookContent (item ));
47
- } else if (item .hasItemMeta () && item .getItemMeta () instanceof BlockStateMeta ) {
48
- BlockStateMeta blockStateMeta = (BlockStateMeta ) item .getItemMeta ();
49
- try {
50
- if (blockStateMeta .hasBlockState () && blockStateMeta .getBlockState () instanceof InventoryHolder ) {
51
- InventoryHolder inventoryHolder = (InventoryHolder ) blockStateMeta .getBlockState ();
52
- ArrayList <ItemStack > items = new ArrayList <>();
53
- for (int i = 0 ; i < inventoryHolder .getInventory ().getSize (); i ++) {
54
- ItemStack itemStack = inventoryHolder .getInventory ().getItem (i );
55
- if (itemStack != null && itemStack .getType () != Material .AIR ) {
56
- if (items .size () < 5 ) {
57
- if (itemStack .hasItemMeta ()) {
58
- if (itemStack .getItemMeta ().hasLore ()) {
59
- ItemMeta meta = itemStack .getItemMeta ();
60
- meta .setLore (new ArrayList <String >());
61
- itemStack .setItemMeta (meta );
62
- }
63
- if (itemStack .getItemMeta () instanceof BookMeta ) {
64
- itemStack = removeBookContent (itemStack );
65
- }
66
- }
67
- items .add (itemStack );
68
- } else {
69
- items .add (new ItemStack (Material .STONE ));
70
- }
71
- }
72
- }
73
- inventoryHolder .getInventory ().clear ();
74
- for (int i = 0 ; i < items .size (); i ++) {
75
- inventoryHolder .getInventory ().setItem (i , items .get (i ));
76
- }
77
- blockStateMeta .setBlockState ((BlockState ) inventoryHolder );
78
- item .setItemMeta (blockStateMeta );
79
- itemJson = ReflectionUtil .convertItemStackToJson (item );
80
- } else {
81
- itemJson = ReflectionUtil .convertItemStackToJson (item );
82
- }
83
- } catch (IllegalStateException e ) {
84
- itemJson = ReflectionUtil .convertItemStackToJson (item );
85
- }
86
- } else {
87
- itemJson = ReflectionUtil .convertItemStackToJson (item );
88
- }
102
+ String itemJson = getItemJsonStripped (item );
103
+
89
104
HoverEvent ev = new HoverEvent (HoverEvent .Action .SHOW_ITEM , new BaseComponent []{new TextComponent (itemJson )});
90
105
nameComponent .setHoverEvent (ev );
91
106
92
-
93
107
if ("{itemName}" .equals (display )) {
94
108
result = nameComponent ;
95
109
} else {
@@ -134,6 +148,55 @@ public Message broadcast(String permission) {
134
148
return this ;
135
149
}
136
150
151
+ private String getItemJsonStripped (ItemStack item ) {
152
+ ItemStack cloned = item .clone ();
153
+ if (cloned .hasItemMeta () && cloned .getItemMeta () instanceof BookMeta ) {
154
+ return ReflectionUtil .convertItemStackToJson (removeBookContent (cloned ));
155
+ }
156
+ if (cloned .hasItemMeta () && cloned .getItemMeta () instanceof BlockStateMeta ) {
157
+ BlockStateMeta blockStateMeta = (BlockStateMeta ) cloned .getItemMeta ();
158
+ if (blockStateMeta .hasBlockState () && blockStateMeta .getBlockState () instanceof InventoryHolder ) {
159
+ InventoryHolder inventoryHolder = (InventoryHolder ) blockStateMeta .getBlockState ();
160
+ ArrayList <ItemStack > items = new ArrayList <>();
161
+ for (int i = 0 ; i < inventoryHolder .getInventory ().getSize (); i ++) {
162
+ ItemStack itemStack = inventoryHolder .getInventory ().getItem (i );
163
+ if (itemStack != null && itemStack .getType () != Material .AIR ) {
164
+ if (items .size () < 5 ) {
165
+ if (itemStack .hasItemMeta ()) {
166
+ if (itemStack .getItemMeta ().hasLore ()) {
167
+ ItemMeta meta = itemStack .getItemMeta ();
168
+ meta .setLore (new ArrayList <String >());
169
+ itemStack .setItemMeta (meta );
170
+ }
171
+ if (itemStack .getItemMeta () instanceof BookMeta ) {
172
+ itemStack = removeBookContent (itemStack );
173
+ }
174
+ }
175
+ items .add (itemStack );
176
+ } else {
177
+ items .add (new ItemStack (Material .STONE ));
178
+ }
179
+ }
180
+ }
181
+ inventoryHolder .getInventory ().clear ();
182
+ for (int i = 0 ; i < items .size (); i ++) {
183
+ inventoryHolder .getInventory ().setItem (i , items .get (i ));
184
+ }
185
+ blockStateMeta .setBlockState ((BlockState ) inventoryHolder );
186
+ cloned .setItemMeta (blockStateMeta );
187
+ return ReflectionUtil .convertItemStackToJson (cloned );
188
+ }
189
+ }
190
+ return ReflectionUtil .convertItemStackToJson (cloned );
191
+ }
192
+
193
+ /**
194
+ * Get a clone of the item where all book pages are removed
195
+ * if not a book, then the same item is returned
196
+ *
197
+ * @param item the book
198
+ * @return book without contents.
199
+ */
137
200
public ItemStack removeBookContent (ItemStack item ) {
138
201
if (item .hasItemMeta () && item .getItemMeta () instanceof BookMeta ) {
139
202
ItemStack itemStack = item .clone ();
0 commit comments