forked from github-mirror/CoreProtect
Merge branch 'master' of github.com:PlayPro/CoreProtect
This commit is contained in:
commit
80a0f24e10
21 files changed
+124
-61
No files matched your search
+22
-7
@@ -21,15 +21,30 @@ Secondary configuration files override the value specified in config.yml. If you
|
||||
To disable logging for specific users, blocks or commands, simply do the following:
|
||||
|
||||
1. In the CoreProtect plugin directory, create a file named `blacklist.txt`.
|
||||
2. Enter the names of the users (or commands) you'd like to disable logging for (each username on a new line).
|
||||
2. Enter the names of the users, commands, blocks, or entities you'd like to disable logging for (each entry on a new line).
|
||||
3. Either restart your server, or type "/co reload" in-game.
|
||||
|
||||
This can be used to disable logging for non-player users, such as "#creeper". For example, if you'd like to disable logging for the user "Notch", TNT explosions, stone blocks, and the "/help" command, the blacklist.txt file would look like this:
|
||||
The blacklist supports disabling logs for:
|
||||
- Users, which includes Players and non-player users, such as "#creeper"
|
||||
- Commands, such as `/help`
|
||||
- Blocks, such as minecraft:stone. Only `block` actions are affected.
|
||||
- Entities, such as minecraft:creeper, which will disable logging the death for that entity. *Note: renamed entities will be logged even if blacklisted.*
|
||||
- Filters can also be specified for a particular user, by using the `@` symbol after the specific item, block, or entity namespaced ID. The format is `id@user`. This will filter all `block`, `kill`, `item` and `container` actions involving that particular block, item or mob, only when caused by the specified player or non-player user.
|
||||
- Items and container actions are only affected by filtered blacklist entries, not by generic item or block IDs.
|
||||
|
||||
*Please note that you must include the namespace (e.g. minecraft:) for blocks, entities and items.*
|
||||
|
||||
An example blacklist.txt file would look like this:
|
||||
|
||||
```text
|
||||
Notch
|
||||
#tnt
|
||||
/help
|
||||
minecraft:stone
|
||||
Notch # User
|
||||
#tnt # TNT explosions
|
||||
/help # Help command
|
||||
minecraft:stone # Stone blocks
|
||||
minecraft:creeper # Creeper entity
|
||||
minecraft:shears@#dispenser # Shears being dispensed
|
||||
```
|
||||
|
||||
*Please note that to disable logging for blocks, CoreProtect v23+ is required, and you must include the namespace. For example, to disable logging for dirt, you must add it as "minecraft:dirt".*
|
||||
|
||||
*Please note that to disable logging for blocks, CoreProtect v23+ is required.*
|
||||
*To disable logging for entities or to use filtering, CoreProtect v23.4+ is required.*
|
||||
@@ -8,6 +8,7 @@ import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -23,6 +24,7 @@ import org.bukkit.plugin.PluginManager;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import net.coreprotect.database.Database;
|
||||
@@ -65,6 +67,10 @@ public class ConfigHandler extends Queue {
|
||||
public static String prefixConfig = "co_";
|
||||
public static int maximumPoolSize = 10;
|
||||
|
||||
public static final String BLACKLIST_COMMENT_SEPARATOR = "#";
|
||||
public static final String BLACKLIST_FILTER_SEPARATOR = "@";
|
||||
public static final String BLACKLIST_FILENAME = "blacklist.txt";
|
||||
|
||||
public static HikariDataSource hikariDataSource = null;
|
||||
public static final CentralProcessor processorInfo = SystemUtils.getProcessorInfo();
|
||||
public static final boolean isSpigot = VersionUtils.isSpigot();
|
||||
@@ -100,6 +106,7 @@ public class ConfigHandler extends Queue {
|
||||
public static Map<String, int[]> rollbackHash = syncMap();
|
||||
public static Map<String, Boolean> inspecting = syncMap();
|
||||
public static Map<String, Boolean> blacklist = syncMap();
|
||||
public static Map<String, HashSet<String>> FilteredBlacklist = syncMap();
|
||||
public static Map<String, Integer> loggingChest = syncMap();
|
||||
public static Map<String, Integer> loggingItem = syncMap();
|
||||
public static ConcurrentHashMap<String, List<Object>> transactingChest = new ConcurrentHashMap<>();
|
||||
@@ -152,23 +159,53 @@ public class ConfigHandler extends Queue {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBlacklisted(String user){
|
||||
return ConfigHandler.blacklist.containsKey(user.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public static boolean isBlacklisted(String user, String object){
|
||||
if (ConfigHandler.blacklist.containsKey(object) || ConfigHandler.blacklist.containsKey(user.toLowerCase(Locale.ROOT))){
|
||||
return true;
|
||||
}
|
||||
return isFilterBlacklisted(user, object);
|
||||
}
|
||||
|
||||
public static boolean isFilterBlacklisted(String user, String object){
|
||||
HashSet <String> blUserSet = FilteredBlacklist.get(object);
|
||||
if (blUserSet == null){
|
||||
return false;
|
||||
}
|
||||
return blUserSet.contains(user.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
private static void loadBlacklist() {
|
||||
try {
|
||||
ConfigHandler.blacklist.clear();
|
||||
String blacklist = ConfigHandler.path + "blacklist.txt";
|
||||
boolean exists = (new File(blacklist)).exists();
|
||||
if (exists) {
|
||||
RandomAccessFile blfile = new RandomAccessFile(blacklist, "rw");
|
||||
long blc = blfile.length();
|
||||
if (blc > 0) {
|
||||
while (blfile.getFilePointer() < blfile.length()) {
|
||||
String blacklistUser = blfile.readLine().replaceAll(" ", "").toLowerCase(Locale.ROOT);
|
||||
if (blacklistUser.length() > 0) {
|
||||
ConfigHandler.blacklist.put(blacklistUser, true);
|
||||
}
|
||||
ConfigHandler.FilteredBlacklist.clear();
|
||||
|
||||
File file = new File(ConfigHandler.path, BLACKLIST_FILENAME);
|
||||
if (!file.exists()){
|
||||
return;
|
||||
}
|
||||
try (RandomAccessFile blfile = new RandomAccessFile(file, "r")){
|
||||
if (blfile.length() == 0){
|
||||
return;
|
||||
}
|
||||
String blLine;
|
||||
while (( blLine = blfile.readLine()) != null ) {
|
||||
blLine = blLine.replace(" ", "").toLowerCase(Locale.ROOT).split(BLACKLIST_COMMENT_SEPARATOR)[0];
|
||||
if (blLine.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String[] blSplit = blLine.split(BLACKLIST_FILTER_SEPARATOR);
|
||||
if (blSplit.length == 1){
|
||||
ConfigHandler.blacklist.put(blLine, true);
|
||||
} else {
|
||||
ConfigHandler.FilteredBlacklist.
|
||||
computeIfAbsent(blSplit[0], k-> new HashSet<>())
|
||||
.add(blSplit[1]);
|
||||
}
|
||||
}
|
||||
blfile.close();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
@@ -26,10 +26,6 @@ public class BlockBreakLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int type, int data, List<Object> meta, String blockData, String overrideData) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || location == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Material checkType = net.coreprotect.utility.MaterialUtils.getType(type);
|
||||
if (checkType == null) {
|
||||
return;
|
||||
@@ -38,7 +34,7 @@ public class BlockBreakLogger {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConfigHandler.blacklist.get(checkType.getKey().toString()) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user, checkType.getKey().toString())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,6 @@ public class BlockPlaceLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, int replacedType, int replacedData, Material forceType, int forceData, boolean force, List<Object> meta, String blockData, String replaceBlockData) {
|
||||
try {
|
||||
if (user == null || ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Material type = block.getType();
|
||||
if (blockData == null && (forceType == null || (!forceType.equals(Material.WATER)) && (!forceType.equals(Material.LAVA)))) {
|
||||
blockData = block.getBlockData().getAsString();
|
||||
@@ -58,7 +54,7 @@ public class BlockPlaceLogger {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConfigHandler.blacklist.get(type.getKey().toString()) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user, type.getKey().toString())){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public class ChatLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, long time, Location location, String user, String message) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user)) {
|
||||
return;
|
||||
}
|
||||
int x = location.getBlockX();
|
||||
|
||||
@@ -22,10 +22,10 @@ public class CommandLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, long time, Location location, String user, String message) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user)) {
|
||||
return;
|
||||
}
|
||||
if (ConfigHandler.blacklist.get(((message + " ").split(" "))[0].toLowerCase(Locale.ROOT)) != null) {
|
||||
if (ConfigHandler.isBlacklisted(((message + " ").split(" "))[0])) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ public class ContainerLogger extends Queue {
|
||||
|
||||
protected static void logTransaction(PreparedStatement preparedStmt, int batchCount, String user, Material type, String faceData, ItemStack[] items, int action, Location location) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user)) {
|
||||
return;
|
||||
}
|
||||
boolean success = false;
|
||||
@@ -218,6 +218,10 @@ public class ContainerLogger extends Queue {
|
||||
if (item != null) {
|
||||
if (item.getAmount() > 0 && !BlockUtils.isAir(item.getType())) {
|
||||
// Object[] metadata = new Object[] { slot, item.getItemMeta() };
|
||||
if (ConfigHandler.isFilterBlacklisted(user, item.getType().getKey().toString())){
|
||||
continue;
|
||||
}
|
||||
|
||||
List<List<Map<String, Object>>> metadata = ItemMetaHandler.serialize(item, type, faceData, slot);
|
||||
if (metadata.size() == 0) {
|
||||
metadata = null;
|
||||
@@ -232,6 +236,7 @@ public class ContainerLogger extends Queue {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int userId = UserStatement.getId(preparedStmt, event.getUser(), true);
|
||||
Location eventLocation = event.getLocation();
|
||||
int wid = WorldUtils.getWorldId(eventLocation.getWorld().getName());
|
||||
|
||||
@@ -3,11 +3,11 @@ package net.coreprotect.database.logger;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.config.Config;
|
||||
@@ -27,7 +27,18 @@ public class EntityKillLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block, List<Object> data, int type) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user)){
|
||||
return;
|
||||
}
|
||||
|
||||
EntityType checkType = net.coreprotect.utility.EntityUtils.getEntityType(type);
|
||||
if (checkType == null) {
|
||||
return;
|
||||
}
|
||||
// Ignore blacklist if the entity has a custom name
|
||||
// data[4] contains custom name data
|
||||
if (ConfigHandler.isBlacklisted(user, checkType.getKey().toString()) &&
|
||||
!(data.size() > 4 && data.get(4) != null)){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public class ItemLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, Location location, int offset, String user) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -124,6 +124,10 @@ public class ItemLogger {
|
||||
for (ItemStack item : items) {
|
||||
if (item != null && item.getAmount() > 0 && !BlockUtils.isAir(item.getType())) {
|
||||
// Object[] metadata = new Object[] { slot, item.getItemMeta() };
|
||||
if (ConfigHandler.isFilterBlacklisted(user, item.getType().getKey().toString())){
|
||||
continue;
|
||||
}
|
||||
|
||||
List<List<Map<String, Object>>> data = ItemMetaHandler.serialize(item, null, null, 0);
|
||||
if (data.size() == 0) {
|
||||
data = null;
|
||||
|
||||
@@ -26,7 +26,7 @@ public class PlayerInteractLogger {
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, Material blockType) {
|
||||
try {
|
||||
int type = MaterialUtils.getBlockId(blockType.name(), true);
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || MaterialUtils.getType(type).equals(Material.AIR) || MaterialUtils.getType(type).equals(Material.CAVE_AIR)) {
|
||||
if (ConfigHandler.isBlacklisted(user) || MaterialUtils.getType(type).equals(Material.AIR) || MaterialUtils.getType(type).equals(Material.CAVE_AIR)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public class PlayerKillLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, BlockState block, String player) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public class PlayerSessionLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int time, int action) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user)) {
|
||||
return;
|
||||
}
|
||||
int x = location.getBlockX();
|
||||
|
||||
@@ -22,7 +22,7 @@ public class SignTextLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, int batchCount, String user, Location location, int action, int color, int colorSecondary, int data, boolean isWaxed, boolean isFront, String line1, String line2, String line3, String line4, String line5, String line6, String line7, String line8, int timeOffset) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public class SkullBreakLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || block == null) {
|
||||
if (ConfigHandler.isBlacklisted(user) || block == null) {
|
||||
return;
|
||||
}
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
|
||||
@@ -21,7 +21,7 @@ public class SkullPlaceLogger {
|
||||
|
||||
public static void log(PreparedStatement preparedStmt, PreparedStatement preparedStmt2, int batchCount, String user, BlockState block, int replaceType, int replaceData) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null || block == null) {
|
||||
if (ConfigHandler.isBlacklisted(user) || block == null) {
|
||||
return;
|
||||
}
|
||||
int time = (int) (System.currentTimeMillis() / 1000L);
|
||||
|
||||
@@ -15,7 +15,7 @@ public class UsernameLogger {
|
||||
|
||||
public static void log(Connection connection, String user, String uuid, int configUsernames, int time) {
|
||||
try {
|
||||
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
|
||||
if (ConfigHandler.isBlacklisted(user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,27 +32,13 @@ public final class PlayerBucketEmptyListener extends Queue implements Listener {
|
||||
}
|
||||
|
||||
if (!event.isCancelled() && Config.getConfig(world).BUCKETS && inspect == 0) {
|
||||
Block block = event.getBlockClicked();
|
||||
Block block = event.getBlock();
|
||||
BlockData blockData = block.getBlockData();
|
||||
Material type = Material.WATER;
|
||||
if (event.getBucket().equals(Material.LAVA_BUCKET)) {
|
||||
type = Material.LAVA;
|
||||
}
|
||||
|
||||
boolean getRelative = true;
|
||||
if (blockData instanceof Waterlogged) {
|
||||
if (type.equals(Material.WATER)) {
|
||||
boolean isWaterlogged = ((Waterlogged) blockData).isWaterlogged();
|
||||
if (!isWaterlogged) {
|
||||
getRelative = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getRelative) {
|
||||
block = block.getRelative(event.getBlockFace());
|
||||
blockData = block.getBlockData();
|
||||
}
|
||||
|
||||
BlockState blockState = block.getState();
|
||||
int worldId = WorldUtils.getWorldId(block.getWorld().getName());
|
||||
int unixTimestamp = (int) (System.currentTimeMillis() / 1000L);
|
||||
|
||||
@@ -19,7 +19,7 @@ public final class PlayerBucketFillListener extends Queue implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
protected void onPlayerBucketFill(PlayerBucketFillEvent event) {
|
||||
String player = event.getPlayer().getName();
|
||||
Block block = event.getBlockClicked();
|
||||
Block block = event.getBlock();
|
||||
World world = block.getWorld();
|
||||
Material type = block.getType();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.coreprotect.listener.player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
@@ -595,9 +596,11 @@ public final class PlayerInteractListener extends Queue implements Listener {
|
||||
}
|
||||
|
||||
if (event.useItemInHand() != Event.Result.DENY) {
|
||||
List<Material> entityBlockTypes = Arrays.asList(Material.ARMOR_STAND, Material.END_CRYSTAL, Material.BOW, Material.CROSSBOW, Material.TRIDENT, Material.EXPERIENCE_BOTTLE, Material.SPLASH_POTION, Material.LINGERING_POTION, Material.ENDER_PEARL, Material.FIREWORK_ROCKET, Material.EGG, Material.SNOWBALL);
|
||||
List<Material> entityBlockTypes = new ArrayList<>(Arrays.asList(Material.ARMOR_STAND, Material.END_CRYSTAL, Material.BOW, Material.CROSSBOW, Material.TRIDENT, Material.EXPERIENCE_BOTTLE, Material.SPLASH_POTION, Material.LINGERING_POTION, Material.ENDER_PEARL, Material.FIREWORK_ROCKET, Material.EGG, Material.SNOWBALL));
|
||||
try {
|
||||
entityBlockTypes.add(Material.valueOf("WIND_CHARGE"));
|
||||
entityBlockTypes.add(Material.valueOf("BLUE_EGG"));
|
||||
entityBlockTypes.add(Material.valueOf("BROWN_EGG"));
|
||||
}
|
||||
catch (Exception e) {
|
||||
// not running MC 1.21+
|
||||
|
||||
@@ -68,7 +68,7 @@ public final class ProjectileLaunchListener extends Queue implements Listener {
|
||||
String name = pair.getKey();
|
||||
Object[] data = pair.getValue();
|
||||
ItemStack itemStack = (ItemStack) data[3];
|
||||
Material entityMaterial = EntityUtils.getEntityMaterial(event.getEntityType());
|
||||
Material entityMaterial = EntityUtils.getEntityMaterial(event.getEntity());
|
||||
boolean isBow = BOWS.contains(itemStack.getType());
|
||||
if ((data[1].equals(key) || data[2].equals(key)) && (entityMaterial == itemStack.getType() || (itemStack.getType() == Material.LINGERING_POTION && entityMaterial == Material.SPLASH_POTION) || isBow)) {
|
||||
boolean thrownItem = (itemStack.getType() != Material.FIREWORK_ROCKET && !isBow);
|
||||
|
||||
@@ -3,11 +3,13 @@ package net.coreprotect.utility;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import net.coreprotect.bukkit.BukkitAdapter;
|
||||
import net.coreprotect.config.ConfigHandler;
|
||||
import net.coreprotect.consumer.Queue;
|
||||
import org.bukkit.entity.ThrowableProjectile;
|
||||
|
||||
public class EntityUtils extends Queue {
|
||||
|
||||
@@ -50,6 +52,14 @@ public class EntityUtils extends Queue {
|
||||
return id;
|
||||
}
|
||||
|
||||
public static Material getEntityMaterial(final Entity entity) {
|
||||
if (entity instanceof ThrowableProjectile) {
|
||||
return ((ThrowableProjectile) entity).getItem().getType();
|
||||
}
|
||||
|
||||
return getEntityMaterial(entity.getType());
|
||||
}
|
||||
|
||||
public static Material getEntityMaterial(EntityType type) {
|
||||
switch (type.name()) {
|
||||
case "ARMOR_STAND":
|
||||
|
||||
Reference in new issue
Block a user