diff --git a/.github/workflows/pr-checker.yml b/.github/workflows/pr-checker.yml index 199a33dea8..d647ca9eca 100644 --- a/.github/workflows/pr-checker.yml +++ b/.github/workflows/pr-checker.yml @@ -4,7 +4,8 @@ name: Pull Request Checker on: - pull_request: + pull_request_target: + types: [opened, synchronize, reopened] paths: - '.github/workflows/**' - 'src/**' @@ -34,7 +35,7 @@ jobs: cache: 'maven' - name: Codestyle Check - run: mvn -s .mvn/settings.xml -B spotless:check compile --errors + run: mvn -s .mvn/settings.xml -B spotless:check --errors # Setup for the preview build - name: Environment Setup @@ -48,7 +49,7 @@ jobs: sed -i "s/UNOFFICIAL<\/version>/$JAR_VERSION<\/version>/g" pom.xml - name: Build with Maven - run: mvn -s .mvn/settings.xml package --errors + run: mvn -s .mvn/settings.xml package -Dversioning.disable --errors - name: Upload the artifact uses: actions/upload-artifact@v4 diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml index 517c5f609e..26c3727521 100644 --- a/.mvn/extensions.xml +++ b/.mvn/extensions.xml @@ -4,7 +4,7 @@ me.qoomon maven-git-versioning-extension - 9.6.6 + 9.8.1 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 6a91de1890..e5bf91d267 100644 --- a/pom.xml +++ b/pom.xml @@ -139,7 +139,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.5.1 + 3.6.0 @@ -337,7 +337,7 @@ org.postgresql postgresql - 42.7.3 + 42.7.4 compile @@ -345,7 +345,7 @@ com.sk89q.worldedit worldedit-core - 7.2.19 + 7.3.6 provided @@ -359,7 +359,7 @@ com.sk89q.worldedit worldedit-bukkit - 7.2.19 + 7.3.6 provided diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/IDataSourceAdapter.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/IDataSourceAdapter.java index b0caa3c18b..64320ddc17 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/IDataSourceAdapter.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/IDataSourceAdapter.java @@ -6,7 +6,11 @@ import java.util.List; public interface IDataSourceAdapter { - int DATABASE_VERSION = 1; + /** + * 当前数据库架构版本号 + * 在数据库结构有变动时更新 + */ + int DATABASE_VERSION = 2; void prepare(T config); diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/mysql/MysqlAdapter.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/mysql/MysqlAdapter.java index e66305bf4a..998e7908e2 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/mysql/MysqlAdapter.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/mysql/MysqlAdapter.java @@ -14,9 +14,11 @@ import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_PLAYER_UUID; 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 static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_VERSION; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_KEY; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_VALUE; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_UNIVERSAL_TRAITS; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_UNIVERSAL_UUID; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.METADATA_VERSION; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.IDataSourceAdapter; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlCommonAdapter; @@ -26,6 +28,7 @@ import com.xzavier0722.mc.plugin.slimefun4.storage.common.RecordKey; import com.xzavier0722.mc.plugin.slimefun4.storage.common.RecordSet; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import java.text.MessageFormat; import java.util.List; public class MysqlAdapter extends SqlCommonAdapter { @@ -51,8 +54,8 @@ public void initStorage(DataType type) { } } - tableInformationTable = SqlUtils.mapTable(DataScope.TABLE_INFORMATION, config.tablePrefix()); - createTableInformationTable(); + tableMetadataTable = SqlUtils.mapTable(DataScope.TABLE_METADATA, config.tablePrefix()); + createTableMetadataTable(); } @Override @@ -388,18 +391,27 @@ private void createUniversalDataTable() { + ");"); } - private void createTableInformationTable() { - executeSql("CREATE TABLE IF NOT EXISTS " - + tableInformationTable - + "(" - + FIELD_TABLE_VERSION - + " INT UNIQUE NOT NULL DEFAULT '0'" - + ");"); + private void createTableMetadataTable() { + executeSql(MessageFormat.format( + """ + CREATE TABLE IF NOT EXISTS {0} + ( + {1} VARCHAR(100) UNIQUE NOT NULL, + {2} TEXT NOT NULL + ); + """, + tableMetadataTable, FIELD_TABLE_METADATA_KEY, FIELD_TABLE_METADATA_VALUE)); if (Slimefun.isNewlyInstalled()) { - executeSql("INSERT INTO " + tableInformationTable + " (" + FIELD_TABLE_VERSION + ") SELECT '" - + IDataSourceAdapter.DATABASE_VERSION + "' WHERE NOT EXISTS (SELECT 1 FROM " + tableInformationTable - + ")"); + executeSql(MessageFormat.format( + """ + INSERT INTO {0} ({1}, {2}) VALUES ({3}, {4}); + """, + tableMetadataTable, + FIELD_TABLE_METADATA_KEY, + FIELD_TABLE_METADATA_VALUE, + METADATA_VERSION, + IDataSourceAdapter.DATABASE_VERSION)); } } } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/postgresql/PostgreSqlAdapter.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/postgresql/PostgreSqlAdapter.java index 500fda78de..52069084db 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/postgresql/PostgreSqlAdapter.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/postgresql/PostgreSqlAdapter.java @@ -14,9 +14,11 @@ import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_PLAYER_UUID; 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 static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_VERSION; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_KEY; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_VALUE; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_UNIVERSAL_TRAITS; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_UNIVERSAL_UUID; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.METADATA_VERSION; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.IDataSourceAdapter; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlCommonAdapter; @@ -26,6 +28,7 @@ import com.xzavier0722.mc.plugin.slimefun4.storage.common.RecordKey; import com.xzavier0722.mc.plugin.slimefun4.storage.common.RecordSet; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import java.text.MessageFormat; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -53,8 +56,8 @@ public void initStorage(DataType type) { } } - tableInformationTable = SqlUtils.mapTable(DataScope.TABLE_INFORMATION, config.tablePrefix()); - createTableInformationTable(); + tableMetadataTable = SqlUtils.mapTable(DataScope.TABLE_METADATA, config.tablePrefix()); + createTableMetadataTable(); } @Override @@ -404,18 +407,27 @@ private void createUniversalDataTable() { + ");"); } - private void createTableInformationTable() { - executeSql("CREATE TABLE IF NOT EXISTS " - + tableInformationTable - + "(" - + FIELD_TABLE_VERSION - + " INT UNIQUE NOT NULL DEFAULT '0'" - + ");"); + private void createTableMetadataTable() { + executeSql(MessageFormat.format( + """ + CREATE TABLE IF NOT EXISTS {0} + ( + {1} VARCHAR(100) UNIQUE NOT NULL, + {2} TEXT NOT NULL + ); + """, + tableMetadataTable, FIELD_TABLE_METADATA_KEY, FIELD_TABLE_METADATA_VALUE)); if (Slimefun.isNewlyInstalled()) { - executeSql("INSERT INTO " + tableInformationTable + " (" + FIELD_TABLE_VERSION + ") SELECT '" - + IDataSourceAdapter.DATABASE_VERSION + "' WHERE NOT EXISTS (SELECT 1 FROM " + tableInformationTable - + ")"); + executeSql(MessageFormat.format( + """ + INSERT INTO {0} ({1}, {2}) VALUES ({3}, {4}); + """, + tableMetadataTable, + FIELD_TABLE_METADATA_KEY, + FIELD_TABLE_METADATA_VALUE, + METADATA_VERSION, + IDataSourceAdapter.DATABASE_VERSION)); } } } 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 659ca28a0f..4849b10e1a 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,6 +1,9 @@ package com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_KEY; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_VALUE; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_VERSION; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.METADATA_VERSION; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.TABLE_NAME_TABLE_INFORMATION; import city.norain.slimefun4.timings.entry.SQLEntry; @@ -10,6 +13,7 @@ import com.xzavier0722.mc.plugin.slimefun4.storage.common.RecordSet; import com.xzavier0722.mc.plugin.slimefun4.storage.patch.DatabasePatch; import com.xzavier0722.mc.plugin.slimefun4.storage.patch.DatabasePatchV1; +import com.xzavier0722.mc.plugin.slimefun4.storage.patch.DatabasePatchV2; import com.zaxxer.hikari.HikariDataSource; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import java.sql.SQLException; @@ -26,7 +30,7 @@ public abstract class SqlCommonAdapter implements ID chunkDataTable, blockInvTable, universalInvTable; - protected String tableInformationTable; + protected String tableMetadataTable; protected T config; @Override @@ -73,7 +77,7 @@ protected String mapTable(DataScope scope) { case UNIVERSAL_INVENTORY -> universalInvTable; case UNIVERSAL_RECORD -> universalRecordTable; case UNIVERSAL_DATA -> universalDataTable; - case TABLE_INFORMATION -> tableInformationTable; + case TABLE_METADATA -> tableMetadataTable; case NONE -> throw new IllegalArgumentException("NONE cannot be a storage data scope!"); }; } @@ -93,28 +97,47 @@ public void shutdown() { universalInvTable = null; universalDataTable = null; universalRecordTable = null; + tableMetadataTable = null; } public int getDatabaseVersion() { - var query = executeQuery("SELECT (" + FIELD_TABLE_VERSION + ") FROM " - + (tableInformationTable == null ? TABLE_NAME_TABLE_INFORMATION : tableInformationTable)); + if (Slimefun.isNewlyInstalled()) { + return IDataSourceAdapter.DATABASE_VERSION; + } + + var query = executeQuery(String.format( + "SELECT (%s) FROM %s WHERE %s='%s';", + FIELD_TABLE_METADATA_VALUE, tableMetadataTable, FIELD_TABLE_METADATA_KEY, METADATA_VERSION)); if (query.isEmpty()) { - return 0; + try { + var prefix = config instanceof SqlCommonConfig sqc ? sqc.tablePrefix() : ""; + var fallbackQuery = executeQuery( + "SELECT (" + FIELD_TABLE_VERSION + ") FROM " + (prefix + TABLE_NAME_TABLE_INFORMATION)); + + if (fallbackQuery.isEmpty()) { + return 0; + } + + return fallbackQuery.getFirst().getInt(null); + } catch (Exception e) { + return 0; + } } else { - return query.getFirst().getInt(FieldKey.TABLE_VERSION); + return query.getFirst().getInt(FieldKey.METADATA_VALUE); } } @Override public void patch() { DatabasePatch patch = null; + var dbVer = getDatabaseVersion(); - switch (getDatabaseVersion()) { - case 0: { - patch = new DatabasePatchV1(); - break; - } + Slimefun.logger().log(Level.INFO, "当前数据库版本 {0}", new Object[] {dbVer}); + + switch (dbVer) { + case 0 -> patch = new DatabasePatchV1(); + case 1 -> patch = new DatabasePatchV2(); } if (patch == null) { @@ -123,7 +146,9 @@ public void patch() { try (var conn = ds.getConnection()) { Slimefun.logger().log(Level.INFO, "正在更新数据库版本至 " + patch.getVersion() + ", 可能需要一段时间..."); - patch.patch(conn.createStatement(), config); + var stmt = conn.createStatement(); + patch.updateVersion(stmt, config); + patch.patch(stmt, config); Slimefun.logger().log(Level.INFO, "更新完成. "); } catch (SQLException e) { Slimefun.logger().log(Level.SEVERE, "更新数据库时出现问题!", e); diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlConstants.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlConstants.java index d4de38093c..5481ee23d1 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlConstants.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/adapter/sqlcommon/SqlConstants.java @@ -12,8 +12,14 @@ public interface SqlConstants { String TABLE_NAME_UNIVERSAL_INVENTORY = "universal_inventory"; String TABLE_NAME_UNIVERSAL_RECORD = "universal_record"; String TABLE_NAME_UNIVERSAL_DATA = "universal_data"; + /** + * @deprecated + * 由于设计不当,该表已被弃用 + */ String TABLE_NAME_TABLE_INFORMATION = "table_information"; + String TABLE_NAME_TABLE_METADATA = "table_metadata"; + String FIELD_PLAYER_UUID = "p_uuid"; String FIELD_PLAYER_NAME = "p_name"; @@ -38,5 +44,14 @@ public interface SqlConstants { String FIELD_UNIVERSAL_TRAITS = "universal_traits"; + /** + * @deprecated + * 由于设计不当,该字段已被弃用 + */ String FIELD_TABLE_VERSION = "table_version"; + + String FIELD_TABLE_METADATA_KEY = "table_metadata_key"; + String FIELD_TABLE_METADATA_VALUE = "table_metadata_value"; + + String METADATA_VERSION = "version"; } 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 679bb0a799..4bbb6f06f4 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 @@ -14,7 +14,8 @@ import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_PLAYER_UUID; 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 static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_VERSION; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_KEY; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_VALUE; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_UNIVERSAL_TRAITS; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_UNIVERSAL_UUID; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.TABLE_NAME_BACKPACK; @@ -25,7 +26,7 @@ import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.TABLE_NAME_CHUNK_DATA; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.TABLE_NAME_PLAYER_PROFILE; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.TABLE_NAME_PLAYER_RESEARCH; -import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.TABLE_NAME_TABLE_INFORMATION; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.TABLE_NAME_TABLE_METADATA; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.TABLE_NAME_UNIVERSAL_DATA; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.TABLE_NAME_UNIVERSAL_INVENTORY; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.TABLE_NAME_UNIVERSAL_RECORD; @@ -67,7 +68,8 @@ public class SqlUtils { fieldMap.put(FieldKey.DATA_VALUE, FIELD_DATA_VALUE); fieldMap.put(FieldKey.UNIVERSAL_UUID, FIELD_UNIVERSAL_UUID); fieldMap.put(FieldKey.UNIVERSAL_TRAITS, FIELD_UNIVERSAL_TRAITS); - fieldMap.put(FieldKey.TABLE_VERSION, FIELD_TABLE_VERSION); + fieldMap.put(FieldKey.METADATA_KEY, FIELD_TABLE_METADATA_KEY); + fieldMap.put(FieldKey.METADATA_VALUE, FIELD_TABLE_METADATA_VALUE); mapper = new FieldMapper<>(fieldMap); } @@ -84,7 +86,7 @@ public static String mapTable(DataScope scope) { case UNIVERSAL_INVENTORY -> TABLE_NAME_UNIVERSAL_INVENTORY; case UNIVERSAL_RECORD -> TABLE_NAME_UNIVERSAL_RECORD; case UNIVERSAL_DATA -> TABLE_NAME_UNIVERSAL_DATA; - case TABLE_INFORMATION -> TABLE_NAME_TABLE_INFORMATION; + case TABLE_METADATA -> TABLE_NAME_TABLE_METADATA; case NONE -> throw new IllegalArgumentException("NONE cannot be a storage data scope!"); }; } 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 c33a6a9cc8..228b74f5a2 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 @@ -14,9 +14,11 @@ import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_PLAYER_UUID; 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 static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_VERSION; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_KEY; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_VALUE; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_UNIVERSAL_TRAITS; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_UNIVERSAL_UUID; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.METADATA_VERSION; import city.norain.slimefun4.timings.entry.SQLEntry; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.IDataSourceAdapter; @@ -28,6 +30,7 @@ import com.xzavier0722.mc.plugin.slimefun4.storage.common.RecordSet; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import java.sql.SQLException; +import java.text.MessageFormat; import java.util.List; public class SqliteAdapter extends SqlCommonAdapter { @@ -38,7 +41,8 @@ public void initStorage(DataType type) { case BLOCK_STORAGE -> createBlockStorageTables(); } - createTableInformationTable(); + tableMetadataTable = SqlUtils.mapTable(DataScope.TABLE_METADATA); + createTableMetadataTable(); } @Override @@ -383,19 +387,27 @@ private void createUniversalDataTable() { + ");"); } - private void createTableInformationTable() { - var table = SqlUtils.mapTable(DataScope.TABLE_INFORMATION); - executeSql("CREATE TABLE IF NOT EXISTS " - + table - + "(" - + FIELD_TABLE_VERSION - + " INT UNIQUE NOT NULL DEFAULT '0'" - + ");"); + private void createTableMetadataTable() { + executeSql(MessageFormat.format( + """ + CREATE TABLE IF NOT EXISTS {0} + ( + {1} VARCHAR(255) UNIQUE NOT NULL, + {2} TEXT NOT NULL + ); + """, + SqlUtils.mapTable(DataScope.TABLE_METADATA), FIELD_TABLE_METADATA_KEY, FIELD_TABLE_METADATA_VALUE)); if (Slimefun.isNewlyInstalled()) { - executeSql("INSERT INTO " + tableInformationTable + " (" + FIELD_TABLE_VERSION + ") SELECT '" - + IDataSourceAdapter.DATABASE_VERSION + "' WHERE NOT EXISTS (SELECT 1 FROM " + tableInformationTable - + ")"); + executeSql(MessageFormat.format( + """ + INSERT INTO {0} ({1}, {2}) VALUES ({3}, {4}); + """, + SqlUtils.mapTable(DataScope.TABLE_METADATA), + FIELD_TABLE_METADATA_KEY, + FIELD_TABLE_METADATA_VALUE, + METADATA_VERSION, + IDataSourceAdapter.DATABASE_VERSION)); } } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/common/DataScope.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/common/DataScope.java index 03a855f0b7..1095e3ac91 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/common/DataScope.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/common/DataScope.java @@ -13,7 +13,7 @@ public enum DataScope { UNIVERSAL_RECORD(new FieldKey[] {FieldKey.UNIVERSAL_UUID}), UNIVERSAL_DATA(new FieldKey[] {FieldKey.UNIVERSAL_UUID, FieldKey.DATA_KEY}), UNIVERSAL_INVENTORY(new FieldKey[] {FieldKey.UNIVERSAL_UUID, FieldKey.INVENTORY_SLOT}), - TABLE_INFORMATION; + TABLE_METADATA; private final FieldKey[] primaryKeys; diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/common/FieldKey.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/common/FieldKey.java index f43fc5be0a..193dbbc727 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/common/FieldKey.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/common/FieldKey.java @@ -29,7 +29,8 @@ public enum FieldKey { UNIVERSAL_TRAITS, - TABLE_VERSION; + METADATA_KEY, + METADATA_VALUE; private final boolean isNumType; diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataConfigWrapper.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataConfigWrapper.java index ba6fa0be8a..fd7f7fcbb1 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataConfigWrapper.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataConfigWrapper.java @@ -14,7 +14,7 @@ public class BlockDataConfigWrapper extends Config { private final SlimefunBlockData blockData; public BlockDataConfigWrapper(SlimefunBlockData blockData) { - super(new File("")); + super(null, null); this.blockData = blockData; } @@ -73,6 +73,10 @@ public void setDefaultValue(@Nonnull String path, @Nullable Object value) { @Override public void setValue(@Nonnull String path, Object value) { + if (value == null) { + blockData.removeData(path); + } + if (!(value instanceof String str)) { throw new NotImplementedException(); } 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 df2eaecf47..70813d0c2c 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 @@ -248,10 +248,10 @@ public SlimefunUniversalBlockData createUniversalBlock(Location l, String sfId) var uuid = UUID.randomUUID(); var uniData = new SlimefunUniversalBlockData(uuid, sfId, l); - uniData.setIsDataLoaded(true); - uniData.initLastPresent(); + uniData.setIsDataLoaded(true); + loadedUniversalData.put(uuid, uniData); var preset = UniversalMenuPreset.getPreset(sfId); @@ -541,13 +541,16 @@ public void getUniversalBlockData(@Nonnull UUID uuid, IAsyncReadCallback getUniversalBlockDataFromCache(@Nonnull Location l) { checkDestroy(); + for (SlimefunUniversalData uniData : loadedUniversalData.values()) { + if (uniData instanceof SlimefunUniversalBlockData ubd + && ubd.isDataLoaded() + && ubd.getLastPresent() != null + && l.equals(ubd.getLastPresent().toLocation())) { + return Optional.of(ubd); + } + } - return loadedUniversalData.values().stream() - .filter(uniData -> uniData instanceof SlimefunUniversalBlockData ubd - && ubd.getLastPresent() != null - && l.equals(ubd.getLastPresent().toLocation())) - .map(data -> (SlimefunUniversalBlockData) data) - .findFirst(); + return Optional.empty(); } /** @@ -727,7 +730,7 @@ public void loadUniversalRecord() { ? new SlimefunUniversalBlockData(uuid, sfId) : new SlimefunUniversalData(uuid, sfId); - traits.forEach(t -> uniData.getTraits().add(t)); + traits.forEach(uniData::addTrait); scheduleReadTask(() -> loadUniversalData(uniData)); }); @@ -857,10 +860,10 @@ public void loadUniversalData(SlimefunUniversalData uniData) { DataUtils.blockDataDebase64(recordSet.get(FieldKey.DATA_VALUE)), false)); - uniData.setIsDataLoaded(true); - loadedUniversalData.putIfAbsent(uniData.getUUID(), uniData); + uniData.setIsDataLoaded(true); + if (uniData.hasTrait(UniversalDataTrait.INVENTORY)) { var menuPreset = UniversalMenuPreset.getPreset(uniData.getSfId()); if (menuPreset != null) { diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/SlimefunUniversalBlockData.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/SlimefunUniversalBlockData.java index 732e1f5155..e0c8b7265a 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/SlimefunUniversalBlockData.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/SlimefunUniversalBlockData.java @@ -38,6 +38,10 @@ public void setLastPresent(Location l) { } public BlockPosition getLastPresent() { + if (!isDataLoaded()) { + return null; + } + var data = getData(UniversalDataTrait.BLOCK.getReservedKey()); if (lastPresent != null) { @@ -60,22 +64,26 @@ public BlockPosition getLastPresent() { } // 修复因使用不一致的文本转换导致的位置无法解析 - try { - var lArr = data.split(","); - var bp = new BlockPosition( - Bukkit.getWorld(lArr[0].replace("[world=", "")), - (int) Double.parseDouble(lArr[1].replace("x=", "")), - (int) Double.parseDouble(lArr[2].replace("y=", "")), - (int) Double.parseDouble(lArr[3].replace("z=", "").replace("]", ""))); - - setTraitData(UniversalDataTrait.BLOCK, LocationUtils.getLocKey(bp.toLocation())); - - return bp; - } catch (Exception x) { - throw new RuntimeException("Unable to fix location " + data + ", it might be broken", x); - } + oldLocationFix(data); } return lastPresent; } + + private void oldLocationFix(String data) { + try { + var lArr = data.split(","); + var bp = new BlockPosition( + Bukkit.getWorld(lArr[0].replace("[world=", "")), + (int) Double.parseDouble(lArr[1].replace("x=", "")), + (int) Double.parseDouble(lArr[2].replace("y=", "")), + (int) Double.parseDouble(lArr[3].replace("z=", "").replace("]", ""))); + + setTraitData(UniversalDataTrait.BLOCK, LocationUtils.getLocKey(bp.toLocation())); + + lastPresent = bp; + } catch (Exception x) { + throw new RuntimeException("Unable to fix location " + data + ", it might be broken", x); + } + } } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/SlimefunUniversalData.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/SlimefunUniversalData.java index baf6d59829..678c90822c 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/SlimefunUniversalData.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/SlimefunUniversalData.java @@ -81,6 +81,10 @@ public UUID getUUID() { return UUID.fromString(getKey()); } + public void addTrait(UniversalDataTrait trait) { + traits.add(trait); + } + public boolean hasTrait(UniversalDataTrait trait) { return traits.contains(trait); } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatch.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatch.java index 2aab164f10..59e9f1e5d8 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatch.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatch.java @@ -1,6 +1,14 @@ package com.xzavier0722.mc.plugin.slimefun4.storage.patch; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_KEY; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_METADATA_VALUE; +import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.METADATA_VERSION; + import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.ISqlCommonConfig; +import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlCommonConfig; +import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlUtils; +import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlite.SqliteConfig; +import com.xzavier0722.mc.plugin.slimefun4.storage.common.DataScope; import java.sql.SQLException; import java.sql.Statement; import lombok.Getter; @@ -9,5 +17,39 @@ public abstract class DatabasePatch { protected int version; + public DatabasePatch(int version) { + this.version = version; + } + + public void updateVersion(Statement stmt, ISqlCommonConfig config) throws SQLException { + var table = SqlUtils.mapTable( + DataScope.TABLE_METADATA, config instanceof SqlCommonConfig scc ? scc.tablePrefix() : ""); + + if (config instanceof SqliteConfig) { + stmt.execute(String.format( + "INSERT INTO %s (%s, %s) VALUES ('%s', '%s') ON CONFLICT(%s) DO UPDATE SET %s='%s'", + table, + FIELD_TABLE_METADATA_KEY, + FIELD_TABLE_METADATA_VALUE, + METADATA_VERSION, + getVersion(), + FIELD_TABLE_METADATA_KEY, + FIELD_TABLE_METADATA_VALUE, + getVersion())); + } else { + stmt.execute(String.format( + "INSERT INTO %s (%s, %s) VALUES ('%s', '%s') ON DUPLICATE KEY UPDATE %s='%s', %s=%s", + table, + FIELD_TABLE_METADATA_KEY, + FIELD_TABLE_METADATA_VALUE, + METADATA_VERSION, + getVersion(), + FIELD_TABLE_METADATA_KEY, + METADATA_VERSION, + FIELD_TABLE_METADATA_VALUE, + getVersion())); + } + } + public abstract void patch(Statement stmt, ISqlCommonConfig config) throws SQLException; } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatchV1.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatchV1.java index 07053e6f8f..1d12cabba4 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatchV1.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatchV1.java @@ -1,36 +1,21 @@ package com.xzavier0722.mc.plugin.slimefun4.storage.patch; import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_INVENTORY_ITEM; -import static com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants.FIELD_TABLE_VERSION; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.mysql.MysqlConfig; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.ISqlCommonConfig; -import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlCommonConfig; import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlUtils; -import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlite.SqliteConfig; import com.xzavier0722.mc.plugin.slimefun4.storage.common.DataScope; import java.sql.SQLException; import java.sql.Statement; public class DatabasePatchV1 extends DatabasePatch { public DatabasePatchV1() { - this.version = 1; + super(1); } @Override public void patch(Statement stmt, ISqlCommonConfig config) throws SQLException { - var table = SqlUtils.mapTable( - DataScope.TABLE_INFORMATION, config instanceof SqlCommonConfig scc ? scc.tablePrefix() : ""); - - if (config instanceof SqliteConfig) { - stmt.execute("INSERT INTO " + table + " (" + FIELD_TABLE_VERSION + ") SELECT " + getVersion() - + " WHERE NOT EXISTS (SELECT 1 FROM " + table + ");"); - stmt.execute("UPDATE " + table + " SET " + FIELD_TABLE_VERSION + " = '1' WHERE rowid = (SELECT rowid FROM " - + table + " LIMIT 1);"); - } else { - stmt.execute("UPDATE " + table + " SET " + FIELD_TABLE_VERSION + " = '1' LIMIT 1"); - } - if (config instanceof MysqlConfig mysqlConf) { var uniInvTable = SqlUtils.mapTable(DataScope.UNIVERSAL_INVENTORY, mysqlConf.tablePrefix()); stmt.execute("ALTER TABLE " + uniInvTable + " MODIFY COLUMN " + FIELD_INVENTORY_ITEM + " TEXT;"); diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatchV2.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatchV2.java new file mode 100644 index 0000000000..9ae086255a --- /dev/null +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/patch/DatabasePatchV2.java @@ -0,0 +1,20 @@ +package com.xzavier0722.mc.plugin.slimefun4.storage.patch; + +import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.ISqlCommonConfig; +import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlCommonConfig; +import com.xzavier0722.mc.plugin.slimefun4.storage.adapter.sqlcommon.SqlConstants; +import java.sql.SQLException; +import java.sql.Statement; + +public class DatabasePatchV2 extends DatabasePatch { + + public DatabasePatchV2() { + super(2); + } + + @Override + public void patch(Statement stmt, ISqlCommonConfig config) throws SQLException { + var tablePrefix = config instanceof SqlCommonConfig scc ? scc.tablePrefix() : ""; + stmt.execute("DROP TABLE IF EXISTS " + tablePrefix + SqlConstants.TABLE_NAME_TABLE_INFORMATION); + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java index 1b5c864062..d5a4d159af 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java @@ -322,7 +322,7 @@ public void onBlockPlace(BlockPlaceEvent e) { ItemStackWrapper wrapper = ItemStackWrapper.wrap(catalyst); List items = ItemStackWrapper.wrapList(inputs); - if (SlimefunUtils.isItemSimilar(wrapper, SlimefunItems.BROKEN_SPAWNER, false, false)) { + if (SlimefunUtils.isItemSimilar(wrapper, SlimefunItems.BROKEN_SPAWNER, false, false, false)) { if (!checkRecipe(SlimefunItems.BROKEN_SPAWNER, items).isPresent()) { return Optional.empty(); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ExplosionsListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ExplosionsListener.java index cb91bdf153..c15d332c07 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ExplosionsListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ExplosionsListener.java @@ -15,6 +15,7 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import org.bukkit.ExplosionResult; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.EntityType; @@ -31,10 +32,8 @@ * calls the explosive part of the {@link BlockBreakHandler}. * * @author TheBusyBiscuit - * * @see BlockBreakHandler * @see WitherProof - * */ public class ExplosionsListener implements Listener { @@ -49,7 +48,8 @@ public void onEntityExplode(EntityExplodeEvent e) { * so we just ignore it. */ if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_21) - && e.getEntityType() == EntityType.WIND_CHARGE) { + && (e.getEntityType() == EntityType.WIND_CHARGE + || e.getEntityType() == EntityType.BREEZE_WIND_CHARGE)) { return; } @@ -58,6 +58,11 @@ public void onEntityExplode(EntityExplodeEvent e) { @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBlockExplode(BlockExplodeEvent e) { + if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_21) + && e.getExplosionResult() == ExplosionResult.TRIGGER_BLOCK) { + return; + } + removeResistantBlocks(e.blockList().iterator()); }