37
37
import org .bukkit .inventory .ItemFlag ;
38
38
import org .bukkit .inventory .ItemStack ;
39
39
import org .bukkit .inventory .meta .ItemMeta ;
40
- import org .eclipse . jdt . annotation .Nullable ;
40
+ import org .jetbrains . annotations .Nullable ;
41
41
42
42
import java .io .IOException ;
43
43
import java .io .NotSerializableException ;
@@ -91,11 +91,6 @@ public static class OldItemData {
91
91
@ Deprecated
92
92
public static final boolean itemDataValues = false ;
93
93
94
- /**
95
- * ItemStack, which is used for everything but serialization.
96
- */
97
- transient ItemStack stack ;
98
-
99
94
/**
100
95
* Type of the item as Bukkit material. Serialized manually.
101
96
*/
@@ -105,14 +100,18 @@ public static class OldItemData {
105
100
* If this represents all possible items.
106
101
*/
107
102
boolean isAnything ;
108
-
103
+
104
+ /**
105
+ * ItemStack, which is used for everything but serialization.
106
+ */
107
+ transient @ Nullable ItemStack stack ;
108
+
109
109
/**
110
110
* When this ItemData represents a block, this contains information to
111
111
* allow comparing it against other blocks.
112
112
*/
113
- @ Nullable
114
- BlockValues blockValues ;
115
-
113
+ @ Nullable BlockValues blockValues ;
114
+
116
115
/**
117
116
* Whether this represents an item (that definitely cannot have
118
117
* block states) or a block, which might have them.
@@ -140,32 +139,39 @@ public static class OldItemData {
140
139
141
140
public ItemData (Material type , @ Nullable String tags ) {
142
141
this .type = type ;
143
-
144
- this .stack = new ItemStack (type );
145
- this .blockValues = BlockCompat .INSTANCE .getBlockValues (stack );
142
+
143
+ if (type .isItem ())
144
+ this .stack = new ItemStack (type );
145
+ this .blockValues = BlockCompat .INSTANCE .getBlockValues (type );
146
146
if (tags != null ) {
147
147
applyTags (tags );
148
148
}
149
149
}
150
150
151
151
public ItemData (Material type , int amount ) {
152
152
this .type = type ;
153
- this .stack = new ItemStack (type , Math .abs (amount ));
154
- this .blockValues = BlockCompat .INSTANCE .getBlockValues (stack );
153
+ if (type .isItem ())
154
+ this .stack = new ItemStack (type , Math .abs (amount ));
155
+ this .blockValues = BlockCompat .INSTANCE .getBlockValues (type );
155
156
}
156
157
157
158
public ItemData (Material type ) {
158
159
this (type , 1 );
159
160
}
160
161
161
162
public ItemData (ItemData data ) {
162
- this .stack = data .stack . clone ();
163
+ this .stack = data .stack != null ? data . stack . clone () : null ;
163
164
this .type = data .type ;
164
165
this .blockValues = data .blockValues ;
165
166
this .isAlias = data .isAlias ;
166
167
this .plain = data .plain ;
167
168
this .itemFlags = data .itemFlags ;
168
169
}
170
+
171
+ public ItemData (Material material , @ Nullable BlockValues values ) {
172
+ this .type = material ;
173
+ this .blockValues = values ;
174
+ }
169
175
170
176
public ItemData (ItemStack stack , @ Nullable BlockValues values ) {
171
177
this .stack = stack ;
@@ -200,7 +206,8 @@ public ItemData(BlockState blockState) {
200
206
201
207
public ItemData (BlockData blockData ) {
202
208
this .type = blockData .getMaterial ();
203
- this .stack = new ItemStack (type );
209
+ if (type .isItem ())
210
+ this .stack = new ItemStack (type );
204
211
this .blockValues = BlockCompat .INSTANCE .getBlockValues (blockData );
205
212
}
206
213
@@ -227,13 +234,12 @@ public boolean isOfType(@Nullable ItemStack item) {
227
234
if (type != item .getType ())
228
235
return false ; // Obvious mismatch
229
236
230
- if (itemFlags != 0 ) { // Either stack has tags (or durability)
237
+ if (stack != null && itemFlags != 0 ) { // Either stack has tags (or durability)
231
238
if (ItemUtils .getDamage (stack ) != ItemUtils .getDamage (item ))
232
239
return false ; // On 1.12 and below, damage is not in meta
233
240
if (stack .hasItemMeta () == item .hasItemMeta ()) // Compare ItemMeta as in isSimilar() of ItemStack
234
- return stack .hasItemMeta () ? itemFactory .equals (stack .getItemMeta (), item .getItemMeta ()) : true ;
235
- else
236
- return false ;
241
+ return !stack .hasItemMeta () || itemFactory .equals (stack .getItemMeta (), item .getItemMeta ());
242
+ return false ;
237
243
}
238
244
return true ;
239
245
}
@@ -249,7 +255,7 @@ public String toString() {
249
255
250
256
public String toString (final boolean debug , final boolean plural ) {
251
257
StringBuilder builder = new StringBuilder (Aliases .getMaterialName (this , plural ));
252
- ItemMeta meta = stack .getItemMeta ();
258
+ ItemMeta meta = stack != null ? stack .getItemMeta () : null ;
253
259
if (meta != null && meta .hasDisplayName ()) {
254
260
builder .append (" " ).append (m_named ).append (" " );
255
261
builder .append (meta .getDisplayName ());
@@ -282,7 +288,7 @@ public boolean equals(final @Nullable Object obj) {
282
288
@ Override
283
289
public int hashCode () {
284
290
int hash = type .hashCode (); // Has collisions, but probably not too many of them
285
- if (blockValues == null || ( blockValues != null && blockValues .isDefault () )) {
291
+ if (blockValues == null || blockValues .isDefault ()) {
286
292
hash = hash * 37 + 1 ;
287
293
}
288
294
return hash ;
@@ -351,7 +357,7 @@ public MatchQuality matchAlias(ItemData item) {
351
357
}
352
358
353
359
// See if we need to compare item metas (excluding durability)
354
- if (quality .isAtLeast (MatchQuality .SAME_ITEM ) && stack .hasItemMeta () || item . stack .hasItemMeta ()) { // Item meta checks could lower this
360
+ if (quality .isAtLeast (MatchQuality .SAME_ITEM ) && this .hasItemMeta () || item .hasItemMeta ()) { // Item meta checks could lower this
355
361
MatchQuality metaQuality = compareItemMetas (getItemMeta (), item .getItemMeta ());
356
362
357
363
// If given item doesn't care about meta, promote to SAME_ITEM
@@ -489,9 +495,13 @@ public ItemData intersection(final ItemData other) {
489
495
* It is not a copy, so please be careful.
490
496
* @return Item stack.
491
497
*/
492
- public ItemStack getStack () {
498
+ public @ Nullable ItemStack getStack () {
493
499
return stack ;
494
500
}
501
+
502
+ private boolean hasItemMeta () {
503
+ return stack != null && stack .hasItemMeta ();
504
+ }
495
505
496
506
@ Override
497
507
public ItemData clone () {
@@ -508,7 +518,7 @@ public BlockValues getBlockValues() {
508
518
}
509
519
510
520
public ItemMeta getItemMeta () {
511
- ItemMeta meta = stack .getItemMeta ();
521
+ ItemMeta meta = stack != null ? stack .getItemMeta () : null ;
512
522
if (meta == null ) { // AIR has null item meta!
513
523
meta = itemFactory .getItemMeta (Material .STONE );
514
524
}
@@ -517,17 +527,23 @@ public ItemMeta getItemMeta() {
517
527
}
518
528
519
529
public void setItemMeta (ItemMeta meta ) {
530
+ if (stack == null )
531
+ return ;
520
532
stack .setItemMeta (meta );
521
533
isAlias = false ; // This is no longer exact alias
522
534
plain = false ; // This is no longer a plain item
523
535
itemFlags |= ItemFlags .CHANGED_TAGS ;
524
536
}
525
537
526
538
public int getDurability () {
539
+ if (stack == null )
540
+ return 0 ; // no damage?
527
541
return ItemUtils .getDamage (stack );
528
542
}
529
543
530
544
public void setDurability (int durability ) {
545
+ if (stack == null )
546
+ return ;
531
547
ItemUtils .setDamage (stack , durability );
532
548
isAlias = false ; // Change happened
533
549
plain = false ; // This is no longer a plain item
@@ -567,7 +583,7 @@ public boolean matchPlain(ItemData other) {
567
583
public Fields serialize () throws NotSerializableException {
568
584
Fields fields = new Fields (this ); // ItemStack is transient, will be ignored
569
585
fields .putPrimitive ("id" , type .ordinal ());
570
- fields .putObject ("meta" , stack .getItemMeta ());
586
+ fields .putObject ("meta" , stack != null ? stack .getItemMeta () : null );
571
587
return fields ;
572
588
}
573
589
@@ -579,8 +595,10 @@ public void deserialize(Fields fields) throws StreamCorruptedException, NotSeria
579
595
ItemMeta meta = fields .getAndRemoveObject ("meta" , ItemMeta .class );
580
596
581
597
// Initialize ItemStack
582
- this .stack = new ItemStack (type );
583
- stack .setItemMeta (meta ); // Just set meta to it
598
+ if (meta != null && type .isItem ()) {
599
+ this .stack = new ItemStack (type );
600
+ stack .setItemMeta (meta ); // Just set meta to it
601
+ }
584
602
585
603
fields .setFields (this ); // Everything but ItemStack and Material
586
604
}
@@ -598,17 +616,17 @@ public void deserialize(Fields fields) throws StreamCorruptedException, NotSeria
598
616
*/
599
617
public ItemData aliasCopy () {
600
618
ItemData data = new ItemData ();
601
- data .stack = new ItemStack (type , 1 );
602
-
603
- if (stack .hasItemMeta ()) {
604
- ItemMeta meta = stack .getItemMeta (); // Creates a copy
605
- meta .setDisplayName (null ); // Clear display name
606
- if (!itemFactory .getItemMeta (type ).equals (meta )) // there may be different tags (e.g. potions)
607
- data .itemFlags |= ItemFlags .CHANGED_TAGS ;
608
- data .stack .setItemMeta (meta );
619
+ if (stack != null ) {
620
+ data .stack = new ItemStack (type , 1 );
621
+ if (stack .hasItemMeta ()) {
622
+ ItemMeta meta = stack .getItemMeta (); // Creates a copy
623
+ meta .setDisplayName (null ); // Clear display name
624
+ if (!itemFactory .getItemMeta (type ).equals (meta )) // there may be different tags (e.g. potions)
625
+ data .itemFlags |= ItemFlags .CHANGED_TAGS ;
626
+ data .stack .setItemMeta (meta );
627
+ }
628
+ ItemUtils .setDamage (data .stack , 0 ); // Set to undamaged
609
629
}
610
- ItemUtils .setDamage (data .stack , 0 ); // Set to undamaged
611
-
612
630
data .type = type ;
613
631
data .blockValues = blockValues ;
614
632
data .itemForm = itemForm ;
@@ -620,6 +638,8 @@ public ItemData aliasCopy() {
620
638
* @param tags Tags in Mojang's JSON format.
621
639
*/
622
640
public void applyTags (String tags ) {
641
+ if (stack == null )
642
+ return ;
623
643
BukkitUnsafe .modifyItemStack (stack , tags );
624
644
itemFlags |= ItemFlags .CHANGED_TAGS ;
625
645
}
0 commit comments