diff --git a/.git-hooks/pre-commit b/.git-hooks/pre-commit index 8b45be1ff0..d234525d79 100644 --- a/.git-hooks/pre-commit +++ b/.git-hooks/pre-commit @@ -2,18 +2,11 @@ echo "[pre-commit check]" -STAGED_FILES=$(git --no-pager diff --name-only --staged --line-prefix=$(git rev-parse --show-toplevel)/ | paste -sd ',') - -if [ ! -z "$STAGED_FILES" ] +echo -n "Checking code format with spotless: " +mvn spotless:check > /tmp/spotless.out 2>&1 +RETURN_VALUE=$? +if [ $RETURN_VALUE -gt 0 ] then - echo -n "Checking code format with spotless: " - mvn spotless:check -DspotlessFiles=$STAGED_FILES > /tmp/spotless.out 2>&1 - RETURN_VALUE=$? - if [ $RETURN_VALUE -gt 0 ] - then - echo "Please run 'mvn spotless:check' for more details or 'mvn spotless:apply' to automatically fix the violations." - fi - exit $RETURN_VALUE + echo "Please run 'mvn spotless:check' for more details or 'mvn spotless:apply' to automatically fix the violations." fi - -exit 0 \ No newline at end of file +exit $RETURN_VALUE \ No newline at end of file diff --git a/pom.xml b/pom.xml index 00da5b7a76..44a3833445 100644 --- a/pom.xml +++ b/pom.xml @@ -105,7 +105,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.12.1 @@ -184,7 +184,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.40.0 + 2.43.0 @@ -313,7 +313,7 @@ org.postgresql postgresql - 42.6.0 + 42.7.2 compile @@ -321,7 +321,7 @@ com.sk89q.worldedit worldedit-core - 7.2.17 + 7.2.19 provided @@ -335,7 +335,7 @@ com.sk89q.worldedit worldedit-bukkit - 7.2.17 + 7.2.19 provided diff --git a/src/main/java/city/norain/slimefun4/EnvironmentChecker.java b/src/main/java/city/norain/slimefun4/EnvironmentChecker.java index 46c1f42320..f44cd80c7c 100644 --- a/src/main/java/city/norain/slimefun4/EnvironmentChecker.java +++ b/src/main/java/city/norain/slimefun4/EnvironmentChecker.java @@ -8,8 +8,8 @@ import org.bukkit.Bukkit; class EnvironmentChecker { - private static final List UNSUPPORTED_PLUGINS = - List.of("BedrockTechnology", "SlimefunFix", "SlimefunBugFixer", "Slimefunbookfix", "MiraiMC"); + private static final List UNSUPPORTED_PLUGINS = List.of( + "BedrockTechnology", "SlimefunFix", "SlimefunBugFixer", "Slimefunbookfix", "PlaceItemsOnGroundRebuilt"); static boolean checkIncompatiblePlugins(@Nonnull Logger logger) { List plugins = UNSUPPORTED_PLUGINS.stream() diff --git a/src/main/java/city/norain/slimefun4/SlimefunExtended.java b/src/main/java/city/norain/slimefun4/SlimefunExtended.java index 691a6d8861..e743da823f 100644 --- a/src/main/java/city/norain/slimefun4/SlimefunExtended.java +++ b/src/main/java/city/norain/slimefun4/SlimefunExtended.java @@ -22,7 +22,19 @@ public static boolean checkEnvironment(@Nonnull Slimefun sf) { return false; } - return !EnvironmentChecker.checkIncompatiblePlugins(sf.getLogger()); + if (Slimefun.getConfigManager().isBypassEnvironmentCheck()) { + sf.getLogger().log(Level.WARNING, "#######################################################"); + sf.getLogger().log(Level.WARNING, ""); + sf.getLogger().log(Level.WARNING, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + sf.getLogger().log(Level.WARNING, "检测到你禁用了环境兼容性检查!"); + sf.getLogger().log(Level.WARNING, "未通过兼容性检查将无法受到反馈支持."); + sf.getLogger().log(Level.WARNING, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + sf.getLogger().log(Level.WARNING, ""); + sf.getLogger().log(Level.WARNING, "#######################################################"); + return true; + } else { + return !EnvironmentChecker.checkIncompatiblePlugins(sf.getLogger()); + } } public static void register(@Nonnull Slimefun sf) { diff --git a/src/main/java/city/norain/slimefun4/utils/SimpleTimer.java b/src/main/java/city/norain/slimefun4/utils/SimpleTimer.java new file mode 100644 index 0000000000..6d6342ace7 --- /dev/null +++ b/src/main/java/city/norain/slimefun4/utils/SimpleTimer.java @@ -0,0 +1,35 @@ +package city.norain.slimefun4.utils; + +import java.time.Duration; +import java.time.LocalDateTime; + +public class SimpleTimer { + private final LocalDateTime startTime; + private Duration snapshot = null; + + public SimpleTimer() { + startTime = LocalDateTime.now(); + } + + public Duration duration() { + var duration = Duration.between(startTime, LocalDateTime.now()); + snapshot = duration; + return duration; + } + + public String durationStr() { + if (snapshot == null) { + snapshot = duration(); + } + + return String.format("%d:%02d:%02d", snapshot.toHours(), snapshot.toMinutesPart(), snapshot.toSecondsPart()); + } + + public boolean isTimeout(Duration duration) { + if (snapshot == null) { + return false; + } + + return snapshot.compareTo(duration) > 0; + } +} diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlCommonAdapter.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlCommonAdapter.java index 781ba5d789..8d3ebe53ff 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlCommonAdapter.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlCommonAdapter.java @@ -1,15 +1,15 @@ package com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon; +import city.norain.slimefun4.utils.SimpleTimer; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.IDataSourceAdapter; import com.xzavier0722.mc.plugin.slimefun4.storage.common.DataScope; import com.xzavier0722.mc.plugin.slimefun4.storage.common.RecordSet; import com.zaxxer.hikari.HikariDataSource; import io.github.thebusybiscuit.slimefun4.core.debug.Debug; import io.github.thebusybiscuit.slimefun4.core.debug.TestCase; -import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import java.sql.SQLException; +import java.time.Duration; import java.util.List; -import java.util.logging.Level; public abstract class SqlCommonAdapter implements IDataSourceAdapter { protected HikariDataSource ds; @@ -24,25 +24,29 @@ public void prepare(T config) { } protected void executeSql(String sql) { + var timer = new SimpleTimer(); + try (var conn = ds.getConnection()) { SqlUtils.execSql(conn, sql); } catch (SQLException e) { - if (Debug.hasTestCase(TestCase.DATABASE)) { - throw new IllegalStateException("An exception thrown while executing sql: " + sql, e); - } else { - Slimefun.logger().log(Level.WARNING, "在操作数据库出现了问题, 原始 SQL 语句: {0}", sql); + throw new IllegalStateException("An exception thrown while executing sql: " + sql, e); + } finally { + if (timer.isTimeout(Duration.ofSeconds(2))) { // FIXME: hardcode slow sql check duration + Debug.log(TestCase.DATABASE, "Detected slow sql costs {}, sql: {}", timer.durationStr(), sql); } } } protected List executeQuery(String sql) { + var timer = new SimpleTimer(); + try (var conn = ds.getConnection()) { return SqlUtils.execQuery(conn, sql); } catch (SQLException e) { - if (Debug.hasTestCase(TestCase.DATABASE)) { - throw new IllegalStateException("An exception thrown while executing sql: " + sql, e); - } else { - throw new IllegalStateException("在操作数据库出现了问题, 原始 SQL 语句: " + sql); + throw new IllegalStateException("An exception thrown while executing sql: " + sql, e); + } finally { + if (timer.isTimeout(Duration.ofSeconds(2))) { // FIXME: hardcode slow sql check duration + Debug.log(TestCase.DATABASE, "Detected slow sql costs {}, sql: {}", timer.durationStr(), sql); } } } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlCommonConfig.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlCommonConfig.java index 31b8001a0d..30447042a3 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlCommonConfig.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlCommonConfig.java @@ -2,8 +2,6 @@ import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; -import java.util.Properties; -import java.util.concurrent.TimeUnit; public abstract class SqlCommonConfig implements ISqlCommonConfig { protected final String host; @@ -48,30 +46,18 @@ public HikariDataSource createDataSource() { config.setPassword(passwd); } - config.setMaximumPoolSize(Math.max(Runtime.getRuntime().availableProcessors(), maxConnection)); - config.setMaxLifetime(TimeUnit.MINUTES.toMillis(10)); - config.setLeakDetectionThreshold(TimeUnit.MINUTES.toMillis(1)); - - config.setDataSourceProperties(getProperties()); + config.setMaximumPoolSize(maxConnection); + config.setLeakDetectionThreshold(3000); + config.addDataSourceProperty("useLocalSessionState", "true"); + config.addDataSourceProperty("rewriteBatchedStatements", "true"); + config.addDataSourceProperty("cacheResultSetMetadata", "true"); + config.addDataSourceProperty("cacheServerConfiguration", "true"); + config.addDataSourceProperty("elideSetAutoCommits", "true"); + config.addDataSourceProperty("maintainTimeStats", "false"); return new HikariDataSource(config); } - private static Properties getProperties() { - var props = new Properties(); - props.setProperty("dataSource.cachePrepStmts", "true"); - props.setProperty("dataSource.prepStmtCacheSize", "250"); - props.setProperty("dataSource.prepStmtCacheSqlLimit", "2048"); - props.setProperty("dataSource.useServerPrepStmts", "true"); - props.setProperty("dataSource.useLocalSessionState", "true"); - props.setProperty("dataSource.rewriteBatchedStatements", "true"); - props.setProperty("dataSource.cacheResultSetMetadata", "true"); - props.setProperty("dataSource.cacheServerConfiguration", "true"); - props.setProperty("dataSource.elideSetAutoCommits", "true"); - props.setProperty("dataSource.maintainTimeStats", "false"); - return props; - } - public String tablePrefix() { return tablePrefix; } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlUtils.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlUtils.java index d3ed2b8c23..02cab7d1d2 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlUtils.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlUtils.java @@ -28,8 +28,6 @@ import com.xzavier0722.mc.plugin.slimefun4.storage.common.FieldMapper; import com.xzavier0722.mc.plugin.slimefun4.storage.common.RecordSet; import io.github.bakedlibs.dough.collections.Pair; -import io.github.thebusybiscuit.slimefun4.core.debug.Debug; -import io.github.thebusybiscuit.slimefun4.core.debug.TestCase; import java.sql.Connection; import java.sql.ResultSetMetaData; import java.sql.SQLException; @@ -122,8 +120,6 @@ public static String toSqlValStr(FieldKey key, String val) { } public static List execQuery(Connection conn, String sql) throws SQLException { - Debug.log(TestCase.DATABASE, "Prepare execute sql query: {}", sql); - try (var stmt = conn.createStatement()) { try (var result = stmt.executeQuery(sql)) { List re = null; @@ -148,16 +144,12 @@ public static List execQuery(Connection conn, String sql) throws SQLE } public static void execSql(Connection conn, String sql) throws SQLException { - Debug.log(TestCase.DATABASE, "Prepare execute sql statement: {}", sql); - try (var stmt = conn.createStatement()) { stmt.execute(sql); } } public static int execUpdate(Connection conn, String sql) throws SQLException { - Debug.log(TestCase.DATABASE, "Prepare execute update statement: {}", sql); - try (var stmt = conn.createStatement()) { return stmt.executeUpdate(sql); } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlite/SqliteAdapter.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlite/SqliteAdapter.java index fcc3f4de93..90e1379e57 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlite/SqliteAdapter.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlite/SqliteAdapter.java @@ -15,13 +15,17 @@ import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_RESEARCH_KEY; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_SLIMEFUN_ID; +import city.norain.slimefun4.utils.SimpleTimer; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlCommonAdapter; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlUtils; import com.xzavier0722.mc.plugin.slimefun4.storage.common.DataScope; import com.xzavier0722.mc.plugin.slimefun4.storage.common.DataType; import com.xzavier0722.mc.plugin.slimefun4.storage.common.RecordKey; import com.xzavier0722.mc.plugin.slimefun4.storage.common.RecordSet; +import io.github.thebusybiscuit.slimefun4.core.debug.Debug; +import io.github.thebusybiscuit.slimefun4.core.debug.TestCase; import java.sql.SQLException; +import java.time.Duration; import java.util.List; public class SqliteAdapter extends SqlCommonAdapter { @@ -316,10 +320,15 @@ public synchronized void executeSql(String sql) { } private synchronized int executeUpdate(String sql) { + var timer = new SimpleTimer(); try (var conn = ds.getConnection()) { return SqlUtils.execUpdate(conn, sql); } catch (SQLException e) { throw new IllegalStateException("An exception thrown while executing sql: " + sql, e); + } finally { + if (timer.isTimeout(Duration.ofSeconds(2))) { // FIXME: hardcode slow sql check duration + Debug.log(TestCase.DATABASE, "Detected slow sql costs {}, sql: {}", timer.durationStr(), sql); + } } } } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlite/SqliteConfig.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlite/SqliteConfig.java index a71b05dfe4..df28a6da4e 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlite/SqliteConfig.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlite/SqliteConfig.java @@ -3,8 +3,6 @@ import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.ISqlCommonConfig; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; -import java.util.Properties; -import java.util.concurrent.TimeUnit; public record SqliteConfig(String path, int maxConnection) implements ISqlCommonConfig { public HikariDataSource createDataSource() { @@ -13,16 +11,7 @@ public HikariDataSource createDataSource() { config.setJdbcUrl(jdbcUrl()); config.setPoolName("SlimefunHikariPool"); config.setMaximumPoolSize(maxConnection); - - config.setMaxLifetime(TimeUnit.MINUTES.toMillis(10)); - - var props = new Properties(); - props.setProperty("dataSource.cachePrepStmts", "true"); - props.setProperty("dataSource.prepStmtCacheSize", "250"); - props.setProperty("dataSource.prepStmtCacheSqlLimit", "2048"); - props.setProperty("dataSource.maintainTimeStats", "false"); - - config.setDataSourceProperties(props); + config.setLeakDetectionThreshold(3000); return new HikariDataSource(config); } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/ADataController.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/ADataController.java index ca9b67a09d..354b7466ec 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/ADataController.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/ADataController.java @@ -8,8 +8,6 @@ import com.xzavier0722.mc.plugin.slimefun4.storage.common.ScopeKey; import com.xzavier0722.mc.plugin.slimefun4.storage.task.DatabaseThreadFactory; import com.xzavier0722.mc.plugin.slimefun4.storage.task.QueuedWriteTask; -import io.github.thebusybiscuit.slimefun4.core.debug.Debug; -import io.github.thebusybiscuit.slimefun4.core.debug.TestCase; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import java.util.List; import java.util.Map; @@ -76,29 +74,17 @@ public void shutdown() { } protected void scheduleDeleteTask(ScopeKey scopeKey, RecordKey key, boolean forceScopeKey) { - Debug.log(TestCase.DATABASE, "Scheduled remove task for key = {}", key); - scheduleWriteTask( scopeKey, key, () -> { dataAdapter.deleteData(key); - Debug.log(TestCase.DATABASE, "Data from key {} deleted.", key); }, forceScopeKey); } protected void scheduleWriteTask(ScopeKey scopeKey, RecordKey key, RecordSet data, boolean forceScopeKey) { - Debug.log(TestCase.DATABASE, "Scheduled write task for key = {}, record set = {}", key, data.getAll()); - - scheduleWriteTask( - scopeKey, - key, - () -> { - dataAdapter.setData(key, data); - Debug.log(TestCase.DATABASE, "Data from key {} set, with record set {}", key, data.getAll()); - }, - forceScopeKey); + scheduleWriteTask(scopeKey, key, () -> dataAdapter.setData(key, data), forceScopeKey); } protected void scheduleWriteTask(ScopeKey scopeKey, RecordKey key, Runnable task, boolean forceScopeKey) { diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java index 777a6bd949..27685e2ff5 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java @@ -415,7 +415,6 @@ private void loadChunkData(SlimefunChunkData chunkData) { if (chunkData.isDataLoaded()) { return; } - getData(key) .forEach(data -> chunkData.setCacheInternal( data.get(FieldKey.DATA_KEY), @@ -593,6 +592,21 @@ public Set getAllLoadedChunkData(World world) { return re; } + public void removeFromAllChunkInWorld(World world, String key) { + var req = new RecordKey(DataScope.CHUNK_DATA); + req.addCondition(FieldKey.CHUNK, world.getName() + ";%"); + req.addCondition(FieldKey.DATA_KEY, key); + deleteData(req); + getAllLoadedChunkData(world).forEach(data -> data.removeData(key)); + } + + public void removeFromAllChunkInWorldAsync(World world, String key, Runnable onFinishedCallback) { + scheduleWriteTask(() -> { + removeFromAllChunkInWorld(world, key); + onFinishedCallback.run(); + }); + } + private void scheduleDelayedBlockInvUpdate(SlimefunBlockData blockData, int slot) { var scopeKey = new LocationKey(DataScope.NONE, blockData.getLocation()); var reqKey = new RecordKey(DataScope.BLOCK_INVENTORY); @@ -729,7 +743,7 @@ private SlimefunChunkData getChunkDataCache(Chunk chunk, boolean createOnNotExis } private void deleteChunkAndBlockDataDirectly(String cKey) { - var req = new RecordKey(DataScope.BLOCK_DATA); + var req = new RecordKey(DataScope.BLOCK_RECORD); req.addCondition(FieldKey.CHUNK, cKey); deleteData(req); diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/migrator/BlockStorageMigrator.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/migrator/BlockStorageMigrator.java index 0627990e31..0700d6b20f 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/migrator/BlockStorageMigrator.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/migrator/BlockStorageMigrator.java @@ -11,12 +11,14 @@ import java.nio.file.StandardCopyOption; import java.util.Map; import java.util.logging.Level; +import lombok.Getter; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; public class BlockStorageMigrator implements IMigrator { + @Getter private static final BlockStorageMigrator instance = new BlockStorageMigrator(); private static final File invFolder = new File("data-storage/Slimefun/stored-inventories/"); @@ -27,10 +29,6 @@ public class BlockStorageMigrator implements IMigrator { private BlockStorageMigrator() {} - public static BlockStorageMigrator getInstance() { - return instance; - } - @Override public String getName() { return "BlockStorage"; diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/LocationUtils.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/LocationUtils.java index 72945573db..db03bc4585 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/LocationUtils.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/LocationUtils.java @@ -39,7 +39,7 @@ public static boolean isSameLoc(Location l1, Location l2) { public static Chunk toChunk(World w, String cKey) { var loc = cKey.split(";")[1].split(":"); - return w.getChunkAt(Integer.parseInt(loc[0]), Integer.parseInt(loc[1])); + return w.getChunkAt(Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), false); } public static boolean isSameWorld(World w1, World w2) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotCardinallyRotatable.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotCardinallyRotatable.java new file mode 100644 index 0000000000..a4ebd320c8 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotCardinallyRotatable.java @@ -0,0 +1,25 @@ +package io.github.thebusybiscuit.slimefun4.core.attributes; + +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import org.bukkit.block.BlockFace; + +/** + * Implement this interface for any {@link SlimefunItem} to prevent + * that {@link SlimefunItem} from being rotated to + * {@link BlockFace}.NORTH + * {@link BlockFace}.EAST + * {@link BlockFace}.SOUTH + * {@link BlockFace}.WEST + * + * @author Ddggdd135 + * + */ +public interface NotCardinallyRotatable extends ItemAttribute { + default BlockFace getRotation(double angle) { + if (0 < angle && angle <= 90) return BlockFace.SOUTH_WEST; + else if (90 < angle && angle <= 180) return BlockFace.NORTH_WEST; + else if (-180 <= angle && angle <= -90) return BlockFace.NORTH_EAST; + else if (-90 < angle && angle <= 0) return BlockFace.SOUTH_EAST; + throw new IllegalArgumentException("angle must be number from -180 to 180"); + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotDiagonallyRotatable.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotDiagonallyRotatable.java new file mode 100644 index 0000000000..478dfee1b5 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotDiagonallyRotatable.java @@ -0,0 +1,25 @@ +package io.github.thebusybiscuit.slimefun4.core.attributes; + +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import org.bukkit.block.BlockFace; + +/** + * Implement this interface for any {@link SlimefunItem} to prevent + * that {@link SlimefunItem} from being rotated to + * {@link BlockFace}.NORTH_EAST + * {@link BlockFace}.NORTH_WEST + * {@link BlockFace}.SOUTH_EAST + * {@link BlockFace}.SOUTH_WEST + * + * @author Ddggdd135 + * + */ +public interface NotDiagonallyRotatable extends ItemAttribute { + default BlockFace getRotation(double angle) { + if (-45 < angle && angle <= 45) return BlockFace.SOUTH; + else if (45 < angle && angle <= 135) return BlockFace.WEST; + else if (135 < Math.abs(angle) && Math.abs(angle) <= 180) return BlockFace.NORTH; + else if (-135 < angle && angle <= -45) return BlockFace.EAST; + throw new IllegalArgumentException("angle must be number from -180 to 180"); + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotRotatable.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotRotatable.java new file mode 100644 index 0000000000..b8b9f26f89 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/NotRotatable.java @@ -0,0 +1,17 @@ +package io.github.thebusybiscuit.slimefun4.core.attributes; + +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import org.bukkit.block.BlockFace; + +/** + * Implement this interface for any {@link SlimefunItem} to prevent + * that {@link SlimefunItem} from being rotated. + * + * @author Ddggdd135 + * + */ +public interface NotRotatable extends ItemAttribute { + default BlockFace getRotation() { + return BlockFace.NORTH; + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunTabCompleter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunTabCompleter.java index 7feb962fa0..b3ee3a0ee5 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunTabCompleter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/SlimefunTabCompleter.java @@ -12,9 +12,11 @@ import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; +import org.bukkit.generator.WorldInfo; class SlimefunTabCompleter implements TabCompleter { @@ -38,6 +40,11 @@ public List onTabComplete(CommandSender sender, Command cmd, String labe .map(SlimefunItem::getId) .collect(Collectors.toList()); return createReturnList(list, args[1]); + } else if (args[0].equalsIgnoreCase("cleardata")) { + List list = new ArrayList<>( + Bukkit.getWorlds().stream().map(WorldInfo::getName).toList()); + list.add("*"); + return createReturnList(list, args[1]); } return null; } else if (args.length == 3) { @@ -55,6 +62,8 @@ public List onTabComplete(CommandSender sender, Command cmd, String labe } return createReturnList(suggestions, args[2]); + } else if (args[0].equalsIgnoreCase("cleardata")) { + return createReturnList(List.of("block", "oil", "*"), args[2]); } else { // Returning null will make it fallback to the default arguments (all online players) return null; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/ClearDataCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/ClearDataCommand.java new file mode 100644 index 0000000000..6201a7e79b --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/ClearDataCommand.java @@ -0,0 +1,99 @@ +package io.github.thebusybiscuit.slimefun4.core.commands.subcommands; + +import com.xzavier0722.mc.plugin.slimefun4.storage.controller.BlockDataController; +import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; +import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand; +import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; +import org.bukkit.*; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; + +public class ClearDataCommand extends SubCommand { + public static final List ValidClearTypes = List.of("block", "oil"); + + @ParametersAreNonnullByDefault + public ClearDataCommand(Slimefun plugin, SlimefunCommand cmd) { + super(plugin, cmd, "cleardata", false); + } + + @Override + public void onExecute(@Nonnull CommandSender sender, @Nonnull String[] args) { + if (sender.hasPermission("slimefun.command.cleardata") || sender instanceof ConsoleCommandSender) { + if (args.length == 4 && args[3].equalsIgnoreCase("confirm")) { + List worlds = new ArrayList<>(); + List clearTypes = new ArrayList<>(); + String block = Slimefun.getLocalization().getMessage("commands.cleardata.block"); + String oil = Slimefun.getLocalization().getMessage("commands.cleardata.oil"); + BlockDataController controller = Slimefun.getDatabaseManager().getBlockDataController(); + if (args[1].equals("*")) { + worlds.addAll(Bukkit.getWorlds()); + } else { + World toAdd = Bukkit.getWorld(args[1]); + if (toAdd == null) { + Slimefun.getLocalization().sendMessage(sender, "commands.cleardata.worldNotFound", true); + return; + } + } + + if (args[2].equals("*")) { + clearTypes.addAll(ValidClearTypes); + } else if (ValidClearTypes.contains(args[2])) { + clearTypes.add(args[2]); + } + + for (World world : worlds) { + for (String cleartype : clearTypes) { + if (cleartype.equals("block")) { + controller.removeAllDataInWorldAsync( + world, + () -> Slimefun.runSync(() -> Slimefun.getLocalization() + .sendMessage(sender, "commands.cleardata.success", true, msg -> msg.replace( + "{0}", world.getName()) + .replace("{1}", block)))); + } else if (cleartype.equals("oil")) { + GEOResource oilresource = null; + for (GEOResource resource : + Slimefun.getRegistry().getGEOResources().values()) { + if (resource.getKey() + .toString() + .equals(new NamespacedKey(Slimefun.instance(), "oil").toString())) { + oilresource = resource; + } + } + controller.removeFromAllChunkInWorldAsync( + world, + oilresource.getKey().toString().replace(":", "-"), + () -> Slimefun.runSync(() -> Slimefun.getLocalization() + .sendMessage(sender, "commands.cleardata.success", true, msg -> msg.replace( + "{0}", world.getName()) + .replace("{1}", oil)))); + } + } + } + return; + } else if (args.length == 3) { + Slimefun.getLocalization().sendMessage(sender, "commands.cleardata.confirm", true); + return; + } + Slimefun.getLocalization() + .sendMessage( + sender, + "messages.usage", + true, + msg -> msg.replace("%usage%", "/sf cleardata ")); + } else { + Slimefun.getLocalization().sendMessage(sender, "messages.no-permission", true); + } + } + + @Nonnull + @Override + public String getDescription() { + return "commands.cleardata.description"; + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SlimefunSubCommands.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SlimefunSubCommands.java index 497ae5562f..4a211cef09 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SlimefunSubCommands.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SlimefunSubCommands.java @@ -46,6 +46,7 @@ public static Collection getAllCommands(@Nonnull SlimefunCommand cmd commands.add(new BlockDataCommand(plugin, cmd)); commands.add(new BanItemCommand(plugin, cmd)); commands.add(new UnbanItemCommand(plugin, cmd)); + commands.add(new ClearDataCommand(plugin, cmd)); return commands; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java index b73c744cae..193f5c8ee4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java @@ -85,6 +85,11 @@ public void onExecute(@Nonnull CommandSender sender, @Nonnull String[] args) { .append("\n请不要将此版本信息截图到 Discord/Github 反馈 Bug" + "\n优先到汉化页面反馈" + "\n") .color(ChatColor.RED); + if (Slimefun.getConfigManager().isBypassEnvironmentCheck()) { + builder.append("\n").event((HoverEvent) null); + builder.append("\n已禁用环境兼容性检查").color(ChatColor.RED); + } + builder.append("\n").event((HoverEvent) null); addPluginVersions(builder); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/config/SlimefunConfigManager.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/config/SlimefunConfigManager.java index 67299d764e..f7d045f755 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/config/SlimefunConfigManager.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/config/SlimefunConfigManager.java @@ -65,6 +65,9 @@ public class SlimefunConfigManager { @Getter private boolean researchAutoConvert; + @Getter + private boolean bypassEnvironmentCheck; + public SlimefunConfigManager(@Nonnull Slimefun plugin) { Validate.notNull(plugin, "The Plugin instance cannot be null"); @@ -114,6 +117,7 @@ public boolean load(boolean reload) { showVanillaRecipes = pluginConfig.getBoolean("guide.show-vanilla-recipes"); showHiddenItemGroupsInSearch = pluginConfig.getBoolean("guide.show-hidden-item-groups-in-search"); autoUpdate = pluginConfig.getBoolean("options.auto-update"); + bypassEnvironmentCheck = pluginConfig.getBoolean("options.bypass-environment-check"); researchesConfig.setDefaultValue("researches.currency-cost-convert-rate", 25.0); researchCurrencyCostConvertRate = researchesConfig.getDouble("researches.currency-cost-convert-rate"); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java index 48e3d33bc6..0c7363a966 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java @@ -190,6 +190,9 @@ public void tick(@Nonnull Block b, SlimefunBlockData blockData) { for (Location node : outputNodes) { int frequency = getFrequency(node); + if (frequency == -1) { + continue; + } if (frequency != lastFrequency && lastFrequency != -1) { output.merge(lastFrequency, list, (prev, next) -> { @@ -227,18 +230,18 @@ public void tick(@Nonnull Block b, SlimefunBlockData blockData) { private static int getFrequency(@Nonnull Location node) { var data = StorageCacheUtils.getBlock(node); if (data == null) { - return 0; + return -1; } if (!data.isDataLoaded()) { StorageCacheUtils.requestLoad(data); - return 0; + return -1; } String frequency = data.getData("frequency"); if (frequency == null) { - return 0; + return -1; } else if (!CommonPatterns.NUMERIC.matcher(frequency).matches()) { Slimefun.logger() .log( @@ -253,7 +256,7 @@ private static int getFrequency(@Nonnull Location node) { + node.getBlockZ() + "): " + frequency); - return 0; + return -1; } else { return Integer.parseInt(frequency); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java index a64354d6c9..42b34889aa 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/BackupService.java @@ -10,7 +10,6 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.logging.Level; @@ -130,17 +129,20 @@ private void addDirectory(@Nonnull ZipOutputStream output, @Nonnull File directo * An {@link IOException} is thrown if a {@link File} could not be deleted */ private void purgeBackups(@Nonnull List backups) throws IOException { - Collections.sort(backups, (a, b) -> { - LocalDateTime time1 = - LocalDateTime.parse(a.getName().substring(0, a.getName().length() - 4), format); - LocalDateTime time2 = - LocalDateTime.parse(b.getName().substring(0, b.getName().length() - 4), format); - - return time2.compareTo(time1); - }); - - for (int i = backups.size() - MAX_BACKUPS; i > 0; i--) { - Files.delete(backups.get(i).toPath()); + var matchedBackup = backups.stream() + .filter(f -> f.getName().matches("^\\d{4}-\\d{2}-\\d{2}-\\d{2}-\\d{2}$")) + .sorted((a, b) -> { + LocalDateTime time1 = LocalDateTime.parse( + a.getName().substring(0, a.getName().length() - 4), format); + LocalDateTime time2 = LocalDateTime.parse( + b.getName().substring(0, b.getName().length() - 4), format); + + return time2.compareTo(time1); + }) + .toList(); + + for (int i = matchedBackup.size() - MAX_BACKUPS; i > 0; i--) { + Files.delete(matchedBackup.get(i).toPath()); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java index 821cc9021f..031931e5ab 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java @@ -462,17 +462,19 @@ public void onDisable() { Bukkit.getScheduler().cancelTasks(this); // Finishes all started movements/removals of block data - try { - ticker.halt(); - ticker.run(); - } catch (Exception x) { - getLogger() - .log( - Level.SEVERE, - x, - () -> "Something went wrong while disabling the ticker task for Slimefun v" - + getDescription().getVersion()); - } + ticker.setPaused(true); + ticker.halt(); + /**try { + * ticker.halt(); + * ticker.run(); + * } catch (Exception x) { + * getLogger() + * .log( + * Level.SEVERE, + * x, + * () -> "Something went wrong while disabling the ticker task for Slimefun v" + * + getDescription().getVersion()); + * }*/ // Kill our Profiler Threads profiler.kill(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java index 340137fa85..274925d1c6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java @@ -14,6 +14,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; @@ -65,7 +66,8 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, RecipeDisplayItem { +public class ProgrammableAndroid extends SlimefunItem + implements InventoryBlock, RecipeDisplayItem, NotDiagonallyRotatable { private static final List POSSIBLE_ROTATIONS = Arrays.asList(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/ArmorAutoCrafter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/ArmorAutoCrafter.java index 4a4fd602ac..1db215b68e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/ArmorAutoCrafter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/ArmorAutoCrafter.java @@ -3,6 +3,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.ArmorForge; import javax.annotation.ParametersAreNonnullByDefault; import org.bukkit.inventory.ItemStack; @@ -19,7 +20,7 @@ * @see SlimefunItemRecipe * */ -public class ArmorAutoCrafter extends SlimefunAutoCrafter { +public class ArmorAutoCrafter extends SlimefunAutoCrafter implements NotDiagonallyRotatable { @ParametersAreNonnullByDefault public ArmorAutoCrafter(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/EnhancedAutoCrafter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/EnhancedAutoCrafter.java index f4f273c415..9c8d72a952 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/EnhancedAutoCrafter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/EnhancedAutoCrafter.java @@ -3,6 +3,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.implementation.items.multiblocks.EnhancedCraftingTable; import io.github.thebusybiscuit.slimefun4.implementation.listeners.AutoCrafterListener; import javax.annotation.ParametersAreNonnullByDefault; @@ -20,7 +21,7 @@ * @see AutoCrafterListener * */ -public class EnhancedAutoCrafter extends SlimefunAutoCrafter { +public class EnhancedAutoCrafter extends SlimefunAutoCrafter implements NotDiagonallyRotatable { @ParametersAreNonnullByDefault public EnhancedAutoCrafter(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/VanillaAutoCrafter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/VanillaAutoCrafter.java index 05d0a930e4..a141837ee0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/VanillaAutoCrafter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/autocrafters/VanillaAutoCrafter.java @@ -6,6 +6,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.core.services.MinecraftRecipeService; import io.github.thebusybiscuit.slimefun4.core.services.sounds.SoundEffect; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; @@ -47,7 +48,7 @@ * @see VanillaRecipe * */ -public class VanillaAutoCrafter extends AbstractAutoCrafter { +public class VanillaAutoCrafter extends AbstractAutoCrafter implements NotDiagonallyRotatable { @ParametersAreNonnullByDefault public VanillaAutoCrafter(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoConnectorNode.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoConnectorNode.java index 197f436a16..821214896c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoConnectorNode.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoConnectorNode.java @@ -3,6 +3,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotRotatable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; @@ -23,7 +24,7 @@ * @see CargoNet * */ -public class CargoConnectorNode extends SimpleSlimefunItem { +public class CargoConnectorNode extends SimpleSlimefunItem implements NotRotatable { @ParametersAreNonnullByDefault public CargoConnectorNode( diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoManager.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoManager.java index ecb79840bb..967f2e4a27 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoManager.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/CargoManager.java @@ -8,6 +8,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotRotatable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet; @@ -21,7 +22,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -public class CargoManager extends SlimefunItem implements HologramOwner { +public class CargoManager extends SlimefunItem implements HologramOwner, NotRotatable { @ParametersAreNonnullByDefault public CargoManager(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/TrashCan.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/TrashCan.java index cbe8c0c503..1b24c6aa63 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/TrashCan.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/TrashCan.java @@ -6,6 +6,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotRotatable; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import javax.annotation.ParametersAreNonnullByDefault; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; @@ -23,7 +24,7 @@ * @author TheBusyBiscuit * */ -public class TrashCan extends SlimefunItem implements InventoryBlock { +public class TrashCan extends SlimefunItem implements InventoryBlock, NotRotatable { private final int[] border = {0, 1, 2, 3, 5, 4, 6, 7, 8, 9, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}; private final ItemStack background = new CustomItemStack(Material.RED_STAINED_GLASS_PANE, " "); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyConnector.java index 17446db456..3793dae395 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyConnector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyConnector.java @@ -5,6 +5,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotRotatable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; @@ -25,7 +26,7 @@ * @see EnergyNetComponent * */ -public class EnergyConnector extends SimpleSlimefunItem implements EnergyNetComponent { +public class EnergyConnector extends SimpleSlimefunItem implements EnergyNetComponent, NotRotatable { @ParametersAreNonnullByDefault public EnergyConnector( diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java index 857006de0a..fd79a39c8e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java @@ -7,6 +7,7 @@ import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotRotatable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNet; @@ -28,7 +29,7 @@ * @see EnergyNetComponent * */ -public class EnergyRegulator extends SlimefunItem implements HologramOwner { +public class EnergyRegulator extends SlimefunItem implements HologramOwner, NotRotatable { @ParametersAreNonnullByDefault public EnergyRegulator(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CoalGenerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CoalGenerator.java index d67c53058f..f44b2d1ffa 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CoalGenerator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CoalGenerator.java @@ -3,6 +3,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; @@ -11,7 +12,7 @@ import org.bukkit.Tag; import org.bukkit.inventory.ItemStack; -public class CoalGenerator extends AGenerator { +public class CoalGenerator extends AGenerator implements NotDiagonallyRotatable { @ParametersAreNonnullByDefault public CoalGenerator(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CombustionGenerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CombustionGenerator.java index d34e7c0354..e3704158e7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CombustionGenerator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CombustionGenerator.java @@ -3,6 +3,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import javax.annotation.ParametersAreNonnullByDefault; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; @@ -10,7 +11,7 @@ import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -public class CombustionGenerator extends AGenerator { +public class CombustionGenerator extends AGenerator implements NotDiagonallyRotatable { @ParametersAreNonnullByDefault public CombustionGenerator(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/LavaGenerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/LavaGenerator.java index d5024f5458..965ff85d61 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/LavaGenerator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/LavaGenerator.java @@ -3,13 +3,14 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import javax.annotation.ParametersAreNonnullByDefault; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -public class LavaGenerator extends AGenerator { +public class LavaGenerator extends AGenerator implements NotDiagonallyRotatable { @ParametersAreNonnullByDefault public LavaGenerator(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/MagnesiumGenerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/MagnesiumGenerator.java index 073d3387bb..ea3a4852cc 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/MagnesiumGenerator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/MagnesiumGenerator.java @@ -3,6 +3,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import javax.annotation.ParametersAreNonnullByDefault; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; @@ -10,7 +11,7 @@ import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -public class MagnesiumGenerator extends AGenerator { +public class MagnesiumGenerator extends AGenerator implements NotDiagonallyRotatable { @ParametersAreNonnullByDefault public MagnesiumGenerator(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricPress.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricPress.java index 863f6f85cb..505d4a1a7a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricPress.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricPress.java @@ -5,6 +5,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; @@ -20,7 +21,7 @@ * @author TheBusyBiscuit * */ -public class ElectricPress extends AContainer implements RecipeDisplayItem { +public class ElectricPress extends AContainer implements RecipeDisplayItem, NotDiagonallyRotatable { @ParametersAreNonnullByDefault public ElectricPress(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/ExpCollector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/ExpCollector.java index 70d2bb904d..8b9b5c0887 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/ExpCollector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/ExpCollector.java @@ -9,6 +9,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; @@ -36,7 +37,7 @@ * @author TheBusyBiscuit * */ -public class ExpCollector extends SlimefunItem implements InventoryBlock, EnergyNetComponent { +public class ExpCollector extends SlimefunItem implements InventoryBlock, EnergyNetComponent, NotDiagonallyRotatable { private final int[] border = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java index 1bc1f2b338..c100c8aca7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java @@ -12,10 +12,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; -import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; -import io.github.thebusybiscuit.slimefun4.core.attributes.HologramOwner; -import io.github.thebusybiscuit.slimefun4.core.attributes.MachineProcessHolder; -import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; +import io.github.thebusybiscuit.slimefun4.core.attributes.*; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.machines.MachineProcessor; @@ -56,7 +53,8 @@ public class GEOMiner extends SlimefunItem EnergyNetComponent, InventoryBlock, HologramOwner, - MachineProcessHolder { + MachineProcessHolder, + NotDiagonallyRotatable { private static final int[] BORDER = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 26, 27, 35, 36, 44, 45, 53 diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOScanner.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOScanner.java index d86d235a32..ac5ccaec46 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOScanner.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOScanner.java @@ -4,6 +4,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; @@ -14,7 +15,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -public class GEOScanner extends SimpleSlimefunItem { +public class GEOScanner extends SimpleSlimefunItem implements NotDiagonallyRotatable { public GEOScanner(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(itemGroup, item, recipeType, recipe); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/OilPump.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/OilPump.java index e28d88dfdd..6b5d9b0545 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/OilPump.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/OilPump.java @@ -5,6 +5,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; @@ -24,7 +25,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -public class OilPump extends AContainer implements RecipeDisplayItem { +public class OilPump extends AContainer implements RecipeDisplayItem, NotDiagonallyRotatable { private final GEOResource oil; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSControlPanel.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSControlPanel.java index 950bedfc76..ea0cd06f6a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSControlPanel.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSControlPanel.java @@ -4,6 +4,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; @@ -14,7 +15,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -public class GPSControlPanel extends SimpleSlimefunItem { +public class GPSControlPanel extends SimpleSlimefunItem implements NotDiagonallyRotatable { @ParametersAreNonnullByDefault public GPSControlPanel(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSTransmitter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSTransmitter.java index dd532beb26..eb8603509c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSTransmitter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/GPSTransmitter.java @@ -7,6 +7,7 @@ import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; @@ -23,7 +24,8 @@ import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; -public abstract class GPSTransmitter extends SimpleSlimefunItem implements EnergyNetComponent { +public abstract class GPSTransmitter extends SimpleSlimefunItem + implements EnergyNetComponent, NotDiagonallyRotatable { private final int capacity; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java index 63a6f60d1d..0b67a5e0a2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java @@ -9,7 +9,10 @@ import io.github.thebusybiscuit.slimefun4.api.events.SlimefunBlockBreakEvent; import io.github.thebusybiscuit.slimefun4.api.events.SlimefunBlockPlaceEvent; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotCardinallyRotatable; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotDiagonallyRotatable; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotRotatable; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ToolUseHandler; @@ -27,8 +30,8 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Rotatable; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -116,13 +119,42 @@ public void onBlockPlace(BlockPlaceEvent e) { if (!sfItem.canUse(e.getPlayer(), true)) { e.setCancelled(true); } else { + if (e.getBlock().getBlockData() instanceof Rotatable rotatable + && !(rotatable.getRotation() == BlockFace.UP || rotatable.getRotation() == BlockFace.DOWN)) { + BlockFace rotation = null; + + if (sfItem instanceof NotCardinallyRotatable && sfItem instanceof NotDiagonallyRotatable) { + rotation = BlockFace.NORTH; + } else if (sfItem instanceof NotRotatable notRotatable) { + rotation = notRotatable.getRotation(); + } else if (sfItem instanceof NotCardinallyRotatable notRotatable) { + rotation = notRotatable.getRotation( + e.getPlayer().getLocation().getYaw()); + } else if (sfItem instanceof NotDiagonallyRotatable notRotatable) { + rotation = notRotatable.getRotation( + e.getPlayer().getLocation().getYaw()); + } + + if (rotation != null) { + rotatable.setRotation(rotation); + e.getBlock().setBlockData(rotatable); + } + } var placeEvent = new SlimefunBlockPlaceEvent(e.getPlayer(), item, e.getBlock(), sfItem); Bukkit.getPluginManager().callEvent(placeEvent); - Slimefun.getDatabaseManager() - .getBlockDataController() - .createBlock(e.getBlock().getLocation(), sfItem.getId()); - sfItem.callItemHandler(BlockPlaceHandler.class, handler -> handler.onPlayerPlace(e)); + if (placeEvent.isCancelled()) { + e.setCancelled(true); + } else { + if (Slimefun.getBlockDataService().isTileEntity(e.getBlock().getType())) { + Slimefun.getBlockDataService().setBlockData(e.getBlock(), sfItem.getId()); + } + + Slimefun.getDatabaseManager() + .getBlockDataController() + .createBlock(e.getBlock().getLocation(), sfItem.getId()); + sfItem.callItemHandler(BlockPlaceHandler.class, handler -> handler.onPlayerPlace(e)); + } } } } @@ -330,27 +362,28 @@ public void onResult(SlimefunBlockData result) { */ @ParametersAreNonnullByDefault private void checkForSensitiveBlocks(Block block, Integer count, boolean isDropItems) { - if (count >= Bukkit.getServer().getMaxChainedNeighborUpdates()) { - return; - } - - BlockState state = block.getState(); - // We set the block to air to make use of BlockData#isSupported. - block.setType(Material.AIR, false); - for (BlockFace face : CARDINAL_BLOCKFACES) { - if (!isSupported(block.getRelative(face).getBlockData(), block.getRelative(face))) { - Block relative = block.getRelative(face); - if (!isDropItems) { - for (ItemStack drop : relative.getDrops()) { - block.getWorld().dropItemNaturally(relative.getLocation(), drop); - } - } - checkForSensitiveBlocks(relative, ++count, isDropItems); - } - } - // Set the BlockData back: this makes it so containers and spawners drop correctly. This is a hacky fix. - block.setBlockData(state.getBlockData(), false); - state.update(true, false); + /**if (count >= Bukkit.getServer().getMaxChainedNeighborUpdates()) { + * return; + * } + * + * BlockState state = block.getState(); + * // We set the block to air to make use of BlockData#isSupported. + * block.setType(Material.AIR, false); + * for (BlockFace face : CARDINAL_BLOCKFACES) { + * if (!isSupported(block.getRelative(face).getBlockData(), block.getRelative(face))) { + * Block relative = block.getRelative(face); + * if (!isDropItems) { + * for (ItemStack drop : relative.getDrops()) { + * block.getWorld().dropItemNaturally(relative.getLocation(), drop); + * } + * } + * checkForSensitiveBlocks(relative, ++count, isDropItems); + * } + * } + * // Set the BlockData back: this makes it so containers and spawners drop correctly. This is a hacky fix. + * block.setBlockData(state.getBlockData(), false); + * state.update(true, false); + */ } /** diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java index b5de686b58..4398191eee 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java @@ -97,6 +97,9 @@ public void onResult(SlimefunBlockData result) { block.setType(Material.AIR); } } + + // Don't move my machine :| + case ENDERMAN -> e.setCancelled(true); } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c77d960358..ecf77ee0ac 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -10,11 +10,12 @@ # language - 粘液科技文本语言 (不包括物品) # enable-translations - 多语言功能 # backwards-compatibility - 物品向后兼容模式, 关闭后物品会使用新版物品系统 -# 将会提升服务器性能 +# 将会提升性能 # log-duplicate-block-entries - 是否输出发现重复方块的警告 # burn-players-when-radioactive - 是否在当玩家暴露在辐射中时灼烧玩家 # drop-excess-sf-give-items - 是否在背包已满时使用命令给予 Slimefun 物品直接掉落溢出的物品 # backup-data - 自动备份数据 +# bypass-environment-check - 跳过兼容性检查 (注意: 打开后将不予接受问题反馈) options: auto-update: true chat-prefix: '&a&lSlimefun 4 &7> ' @@ -35,6 +36,7 @@ options: drop-excess-sf-give-items: false backup-data: true drop-block-creative: true + bypass-environment-check: false guide: # 是否在指南中展示原版物品合成配方 diff --git a/src/main/resources/languages/zh-CN/messages.yml b/src/main/resources/languages/zh-CN/messages.yml index 82224b2ba5..004b84933b 100644 --- a/src/main/resources/languages/zh-CN/messages.yml +++ b/src/main/resources/languages/zh-CN/messages.yml @@ -11,6 +11,13 @@ commands: stats: 查看玩家的统计数据 transform: 将物品转换为英文物品 id: 获取手持物品的 Slimefun ID + cleardata: + description: 清理世界数据 + success: '&a已清除&c {0} &a的&c {1} &a数据' + block: 方块 + oil: 石油 + worldNotFound: '&c未找到世界' + confirm: '&e 输入命令/sf cleardata confirm 来确认操作 &c此操作不可恢复!' banitem: description: 禁用 Slimefun 物品 success: '&a禁用成功' @@ -145,6 +152,10 @@ guide: wiki: '&3Wiki 编辑者' resourcepack: '&c材质制作者' translator: '&9翻译者' + +actionbar: + radiation: '&6辐射暴露等级:&c%level%&7/&e100' + messages: android-no-permission: "&c你的机器人在某个你没有权限的领地/地皮中无法工作, 机器人已自动暂停运行." transform: