Skip to content

Commit dfb4ece

Browse files
committed
v8.4.0
Titles Now uses Player#setPlayerListHeaderFooter() for sendTabList() XMaterial Added 1.16+ getId() support. Removed the material version as it wasn't really that useful. Removed glazed terracotta data values because they were unused. Fixed potted flower materials for pre-1.13 Fixed spruce and dark oak leaves material for pre-1.13 XBlock setBlock() now supports all the legacy materials.
1 parent 286e2ea commit dfb4ece

File tree

7 files changed

+458
-356
lines changed

7 files changed

+458
-356
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.cryptomorin</groupId>
88
<artifactId>XSeries</artifactId>
9-
<version>8.3.0</version>
9+
<version>8.4.0</version>
1010

1111
<name>XSeries</name>
1212
<description>A set of utilities for Minecraft plugins</description>

src/main/java/com/cryptomorin/xseries/XBlock.java

Lines changed: 153 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@
2525
import org.bukkit.DyeColor;
2626
import org.bukkit.Material;
2727
import org.bukkit.TreeSpecies;
28+
import org.bukkit.block.Banner;
2829
import org.bukkit.block.Block;
2930
import org.bukkit.block.BlockFace;
3031
import org.bukkit.block.BlockState;
3132
import org.bukkit.inventory.InventoryHolder;
3233
import org.bukkit.material.*;
3334

35+
import javax.annotation.Nonnull;
3436
import javax.annotation.Nullable;
3537
import java.util.*;
3638

@@ -62,10 +64,26 @@ public final class XBlock {
6264
));
6365
public static final byte CAKE_SLICES = 6;
6466
private static final boolean ISFLAT = XMaterial.supports(13);
67+
private static final Map<XMaterial, XMaterial> ITEM_TO_BLOCK = new EnumMap<>(XMaterial.class);
6568

66-
private XBlock() {
69+
static {
70+
ITEM_TO_BLOCK.put(XMaterial.MELON_SLICE, XMaterial.MELON_STEM);
71+
ITEM_TO_BLOCK.put(XMaterial.MELON_SEEDS, XMaterial.MELON_STEM);
72+
73+
ITEM_TO_BLOCK.put(XMaterial.CARROT_ON_A_STICK, XMaterial.CARROTS);
74+
ITEM_TO_BLOCK.put(XMaterial.GOLDEN_CARROT, XMaterial.CARROTS);
75+
ITEM_TO_BLOCK.put(XMaterial.CARROT, XMaterial.CARROTS);
76+
77+
ITEM_TO_BLOCK.put(XMaterial.POTATO, XMaterial.POTATOES);
78+
ITEM_TO_BLOCK.put(XMaterial.BAKED_POTATO, XMaterial.POTATOES);
79+
ITEM_TO_BLOCK.put(XMaterial.POISONOUS_POTATO, XMaterial.POTATOES);
80+
81+
ITEM_TO_BLOCK.put(XMaterial.PUMPKIN_SEEDS, XMaterial.PUMPKIN_STEM);
82+
ITEM_TO_BLOCK.put(XMaterial.PUMPKIN_PIE, XMaterial.PUMPKIN);
6783
}
6884

85+
private XBlock() { }
86+
6987
public static boolean isLit(Block block) {
7088
if (ISFLAT) {
7189
if (!(block.getBlockData() instanceof org.bukkit.block.data.Lightable)) return false;
@@ -213,25 +231,114 @@ public static boolean setDirection(Block block, BlockFace facing) {
213231
return false;
214232
}
215233

234+
public static boolean setType(@Nonnull Block block, @Nullable XMaterial material) {
235+
Objects.requireNonNull(block, "Cannot set type of null block");
236+
if (material == null) material = XMaterial.AIR;
237+
XMaterial smartConversion = ITEM_TO_BLOCK.get(material);
238+
if (smartConversion != null) material = smartConversion;
239+
if (material.parseMaterial() == null) return false;
216240

217-
private static String getMetaString(XMaterial material) {
218-
return material.name().substring(0, material.name().indexOf('_'));
219-
}
220-
221-
public static boolean setType(Block block, XMaterial material) {
222241
block.setType(material.parseMaterial());
223242
if (XMaterial.supports(13)) return false;
224243

244+
String parsedName = material.parseMaterial().name();
245+
if (parsedName.endsWith("_ITEM")) {
246+
String blockName = parsedName.substring(0, parsedName.length() - "_ITEM".length());
247+
Material blockMaterial = Objects.requireNonNull(Material.getMaterial(blockName),
248+
() -> "Could not find block material for item '" + parsedName + "' as '" + blockName + '\'');
249+
block.setType(blockMaterial);
250+
} else if (parsedName.contains("CAKE")) {
251+
Material blockMaterial = Material.getMaterial("CAKE_BLOCK");
252+
block.setType(blockMaterial);
253+
}
254+
255+
LegacyMaterial legacyMaterial = LegacyMaterial.getMaterial(parsedName);
256+
if (legacyMaterial == LegacyMaterial.BANNER) block.setType(LegacyMaterial.STANDING_BANNER.material);
257+
LegacyMaterial.Handling handling = legacyMaterial == null ? null : legacyMaterial.handling;
258+
225259
BlockState state = block.getState();
226-
MaterialData data = state.getData();
227260
boolean update = false;
228261

229-
if (data instanceof Wood) {
230-
Wood wood = (Wood) data;
231-
wood.setSpecies(TreeSpecies.valueOf(getMetaString(material)));
262+
if (handling == LegacyMaterial.Handling.COLORABLE) {
263+
if (state instanceof Banner) {
264+
Banner banner = (Banner) state;
265+
String xName = material.name();
266+
int colorIndex = xName.indexOf('_');
267+
String color = xName.substring(0, colorIndex);
268+
if (color.equals("LIGHT")) color = xName.substring(0, "LIGHT_".length() + 4);
269+
270+
banner.setBaseColor(DyeColor.valueOf(color));
271+
} else state.setRawData(material.getData());
232272
update = true;
233-
} else if (data instanceof Colorable) {
234-
((Colorable) data).setColor(DyeColor.valueOf(getMetaString(material)));
273+
} else if (handling == LegacyMaterial.Handling.WOOD_SPECIES) {
274+
// Wood doesn't exist in 1.8
275+
// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/material/Wood.java?until=7d83cba0f2575112577ed7a091ed8a193bfc261a&untilPath=src%2Fmain%2Fjava%2Forg%2Fbukkit%2Fmaterial%2FWood.java
276+
// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/TreeSpecies.java
277+
278+
String name = material.name();
279+
int firstIndicator = name.indexOf('_');
280+
if (firstIndicator < 0) return false;
281+
String woodType = name.substring(0, firstIndicator);
282+
283+
TreeSpecies species;
284+
switch (woodType) {
285+
case "OAK":
286+
species = TreeSpecies.GENERIC;
287+
break;
288+
case "DARK":
289+
species = TreeSpecies.DARK_OAK;
290+
break;
291+
case "SPRUCE":
292+
species = TreeSpecies.REDWOOD;
293+
break;
294+
default: {
295+
try {
296+
species = TreeSpecies.valueOf(woodType);
297+
} catch (IllegalArgumentException ex) {
298+
throw new AssertionError("Unknown material " + legacyMaterial + " for wood species");
299+
}
300+
}
301+
}
302+
303+
// Doesn't handle stairs, slabs, fence and fence gates as they had their own separate materials.
304+
boolean firstType = false;
305+
switch (legacyMaterial) {
306+
case WOOD:
307+
case WOOD_DOUBLE_STEP:
308+
state.setRawData(species.getData());
309+
update = true;
310+
break;
311+
case LOG:
312+
case LEAVES:
313+
firstType = true;
314+
// fall through to next switch statement below
315+
case LOG_2:
316+
case LEAVES_2:
317+
switch (species) {
318+
case GENERIC:
319+
case REDWOOD:
320+
case BIRCH:
321+
case JUNGLE:
322+
if (!firstType) throw new AssertionError("Invalid tree species " + species + " for block type" + legacyMaterial + ", use block type 2 instead");
323+
break;
324+
case ACACIA:
325+
case DARK_OAK:
326+
if (firstType) throw new AssertionError("Invalid tree species " + species + " for block type 2 " + legacyMaterial + ", use block type instead");
327+
break;
328+
}
329+
state.setRawData((byte) ((state.getRawData() & 0xC) | (species.getData() & 0x3)));
330+
update = true;
331+
break;
332+
case SAPLING:
333+
case WOOD_STEP:
334+
state.setRawData((byte) ((state.getRawData() & 0x8) | species.getData()));
335+
update = true;
336+
break;
337+
default:
338+
throw new AssertionError("Unknown block type " + legacyMaterial + " for tree species: " + species);
339+
}
340+
} else if (material.getData() != 0) {
341+
state.setRawData(material.getData());
235342
update = true;
236343
}
237344

@@ -423,20 +530,6 @@ public static int addCakeSlices(Block block, int slices) {
423530
}
424531
}
425532

426-
public static boolean setWooden(Block block, XMaterial species) {
427-
block.setType(species.parseMaterial());
428-
if (ISFLAT) return true;
429-
430-
TreeSpecies type = species == XMaterial.SPRUCE_LOG ? TreeSpecies.REDWOOD :
431-
TreeSpecies.valueOf(getMetaString(species));
432-
433-
BlockState state = block.getState();
434-
MaterialData data = state.getData();
435-
((Wood) data).setSpecies(type);
436-
state.update(true);
437-
return true;
438-
}
439-
440533
public static void setEnderPearlOnFrame(Block endPortalFrame, boolean eye) {
441534
BlockState state = endPortalFrame.getState();
442535
if (ISFLAT) {
@@ -638,6 +731,40 @@ private static boolean isMaterial(Block block, BlockMaterial... materials) {
638731
return false;
639732
}
640733

734+
private enum LegacyMaterial {
735+
// Colorable
736+
STANDING_BANNER(Handling.COLORABLE), WALL_BANNER(Handling.COLORABLE), BANNER(Handling.COLORABLE),
737+
CARPET(Handling.COLORABLE), WOOL(Handling.COLORABLE), STAINED_CLAY(Handling.COLORABLE),
738+
STAINED_GLASS(Handling.COLORABLE), STAINED_GLASS_PANE(Handling.COLORABLE), THIN_GLASS(Handling.COLORABLE),
739+
740+
// Wood Species
741+
WOOD(Handling.WOOD_SPECIES), WOOD_STEP(Handling.WOOD_SPECIES), WOOD_DOUBLE_STEP(Handling.WOOD_SPECIES),
742+
LEAVES(Handling.WOOD_SPECIES), LEAVES_2(Handling.WOOD_SPECIES),
743+
LOG(Handling.WOOD_SPECIES), LOG_2(Handling.WOOD_SPECIES),
744+
SAPLING(Handling.WOOD_SPECIES);
745+
746+
private static final Map<String, LegacyMaterial> LOOKUP = new HashMap<>();
747+
748+
static {
749+
for (LegacyMaterial legacyMaterial : values()) {
750+
LOOKUP.put(legacyMaterial.name(), legacyMaterial);
751+
}
752+
}
753+
754+
private final Material material = Material.getMaterial(name());
755+
private final Handling handling;
756+
757+
LegacyMaterial(Handling handling) {
758+
this.handling = handling;
759+
}
760+
761+
private static LegacyMaterial getMaterial(String name) {
762+
return LOOKUP.get(name);
763+
}
764+
765+
private enum Handling {COLORABLE, WOOD_SPECIES;}
766+
}
767+
641768
/**
642769
* An enum with cached legacy materials which can be used when comparing blocks with blocks and blocks with items.
643770
*

0 commit comments

Comments
 (0)