diff --git a/.gitignore b/.gitignore index 8656ef4..77740cd 100644 --- a/.gitignore +++ b/.gitignore @@ -48,4 +48,5 @@ source_visual.ppm source_visual.mp4 # Leftover from tests +tmp/ *.tmp.sqlite3 diff --git a/build.gradle.kts b/build.gradle.kts index de28151..fdbfe03 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -44,6 +44,7 @@ object DepData { const val SANS_ORM_VERSION = "3.17" const val SLF4J_VERSION = "1.7.25" const val BSTATS_VERSION = "3.0.2" + const val SORMULA_VERSION = "4.3" // Directories const val TEST_SERVER_DIR = "run" @@ -106,6 +107,8 @@ tasks { dependencies { exclude(dependency("org.slf4j:slf4j-api")) + exclude(dependency("org.slf4j:slf4j-simple")) + exclude(dependency("org.apache:log4j")) exclude(dependency("org.xerial:sqlite-jdbc")) exclude(dependency("org.jetbrains:annotations")) } @@ -116,6 +119,7 @@ tasks { relocate("org.eclipse", "claimchunk.dependency.org.eclipse") relocate("org.osgi", "claimchunk.dependency.org.osgi") relocate("org.bstats", "claimchunk.dependency.org.bstats") + relocate("org.sormula", "claimchunk.dependency.org.sormula") } register("cleanTests") { @@ -131,7 +135,7 @@ tasks { "junit.jupiter.testinstance.lifecycle.default" to "per_class" ) -// finalizedBy("cleanTests") + finalizedBy("cleanTests") } clean { @@ -313,6 +317,7 @@ dependencies { implementation("javax.transaction:transaction-api:${DepData.JAVAX_TRANSACTION_VERSION}") implementation("com.github.h-thurow:q2o:${DepData.SANS_ORM_VERSION}") implementation("org.bstats:bstats-bukkit:${DepData.BSTATS_VERSION}") + implementation("org.sormula:sormula:${DepData.SORMULA_VERSION}") testImplementation("org.slf4j:slf4j-simple:${DepData.SLF4J_VERSION}") testImplementation("org.junit.jupiter:junit-jupiter:${DepData.JUNIT_VERSION}") diff --git a/src/main/java/claimchunk/dependency/de/goldmensch/commanddispatcher/command/SmartCommand.java b/src/main/java/claimchunk/dependency/de/goldmensch/commanddispatcher/command/SmartCommand.java index 611d84d..511112a 100644 --- a/src/main/java/claimchunk/dependency/de/goldmensch/commanddispatcher/command/SmartCommand.java +++ b/src/main/java/claimchunk/dependency/de/goldmensch/commanddispatcher/command/SmartCommand.java @@ -13,7 +13,6 @@ import org.bukkit.command.TabExecutor; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.*; @@ -131,7 +130,7 @@ public boolean onCommand( */ @Override @ApiStatus.Internal - public @Nullable List onTabComplete( + public @NotNull List onTabComplete( @NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, diff --git a/src/main/java/com/cjburkey/claimchunk/ClaimChunk.java b/src/main/java/com/cjburkey/claimchunk/ClaimChunk.java index e2fa5db..2efce07 100644 --- a/src/main/java/com/cjburkey/claimchunk/ClaimChunk.java +++ b/src/main/java/com/cjburkey/claimchunk/ClaimChunk.java @@ -245,7 +245,7 @@ boolean checkBStats(Metrics metrics) { Field metricsEnabledField = MetricsBase.class.getDeclaredField("enabled"); metricsEnabledField.setAccessible(true); - return metricsBaseField.getBoolean(metricsBase); + return metricsEnabledField.getBoolean(metricsBase); } catch (Exception e) { Utils.warn( "Failed to detect whether user has bStats enabled globally: " + e.getMessage()); @@ -427,7 +427,10 @@ private void initAnonymousData() { // Only show this once, since it's not considered debug spam! getConfig().set("log.showExtraInfoOnAnonymousMetrics", false); + saveConfig(); } + } else { + Utils.log("bStats is disabled, so it is NOT sending any data!"); } } catch (Exception e) { Utils.err("Failed to initialize anonymous metrics collection: %s", e.getMessage()); diff --git a/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqLiteTableMigrationManager.java b/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqLiteTableMigrationManager.java index aae25ff..df99d99 100644 --- a/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqLiteTableMigrationManager.java +++ b/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqLiteTableMigrationManager.java @@ -101,6 +101,6 @@ SELECT COUNT(*) FROM pragma_table_info(?) WHERE name=? } // Whenever a column is added or moved or transformed or whatever, add a - // method here to perform that transformation and call it in initialize_tables. + // method here to perform that transformation and call in the `go` method. } diff --git a/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqLiteWrapper.java b/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqLiteWrapper.java index 06f2afe..29fb97e 100644 --- a/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqLiteWrapper.java +++ b/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqLiteWrapper.java @@ -16,7 +16,6 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.SQLWarning; import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -317,8 +316,6 @@ public void clearPermissionFlags( + " AND " + clauses; - System.out.println(where); - SqlClosure.sqlExecute( connection -> { try (PreparedStatement statement = @@ -356,13 +353,12 @@ public List getAllPlayers() { try (PreparedStatement statement = connection.prepareStatement( """ - SELECT * - FROM permission_flags - WHERE chunk_id=-1 - """)) { + SELECT * + FROM permission_flags + WHERE chunk_id=-1 + """)) { ResultSet resultSet = statement.executeQuery(); while (resultSet.next()) { - UUID playerUuid = UUID.fromString(resultSet.getString("player_uuid")); String otherPlyUuid = resultSet.getString("other_player_uuid"); String flagName = resultSet.getString("flag_name"); @@ -370,7 +366,10 @@ public List getAllPlayers() { FullPlayerData thisPly = playerData.get(playerUuid); if (thisPly == null) { - throw new RuntimeException("Failed to load player " + playerUuid + " for permission " + flagName); + Utils.err( + "Failed to load player %s for permission %s", + playerUuid, flagName); + continue; } UUID otherPly = null; @@ -421,11 +420,11 @@ public Collection getAllChunks() { try (PreparedStatement statement = connection.prepareStatement( """ - SELECT * FROM permission_flags - LEFT JOIN chunk_data - ON permission_flags.chunk_id=chunk_data.chunk_id - WHERE permission_flags.chunk_id!=-1 - """)) { + SELECT * FROM permission_flags + LEFT JOIN chunk_data + ON permission_flags.chunk_id=chunk_data.chunk_id + WHERE permission_flags.chunk_id!=-1 + """)) { ResultSet resultSet = statement.executeQuery(); while (resultSet.next()) { String playerUuid = resultSet.getString("player_uuid"); @@ -448,9 +447,10 @@ public Collection getAllChunks() { DataChunk chunk = chunks.get(Objects.requireNonNull(chunkPos)); if (chunk == null) { - throw new RuntimeException( - "Tried to load permissions for unclaimed chunk at " - + chunkPos); + Utils.err( + "Tried to load permissions for unclaimed chunk at %s", + chunkPos); + continue; } UUID otherPlayer = null; @@ -485,6 +485,7 @@ private int setChunkPosParams( return worldParameterNum + 3; } + @SuppressWarnings("SameParameterValue") private String chunkIdQuery(String sql) { return SELECT_CHUNK_ID_SQL_PATTERN.matcher(sql).replaceAll(SELECT_CHUNK_ID_SQL); } diff --git a/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqlClaimedChunk.java b/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqlClaimedChunk.java new file mode 100644 index 0000000..fa97e15 --- /dev/null +++ b/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqlClaimedChunk.java @@ -0,0 +1,21 @@ +package com.cjburkey.claimchunk.data.sqlite; + +import com.cjburkey.claimchunk.chunk.ChunkPos; + +import org.sormula.annotation.Column; +import org.sormula.annotation.ImplicitType; +import org.sormula.annotation.Row; + +import java.util.UUID; + +@Row(tableName = "claimed_chunks") +public class SqlClaimedChunk { + + @Column(primaryKey = true, name = "chunk_pos") + @ImplicitType(translator = Translators.ChunkPosTranslator.class) + public ChunkPos chunkPos; + + @Column(name = "owner_uuid") + @ImplicitType(translator = Translators.UUIDTranslator.class) + public UUID chunkOwner; +} diff --git a/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqlDataPlayer.java b/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqlDataPlayer.java index 2a3892b..9634f47 100644 --- a/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqlDataPlayer.java +++ b/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqlDataPlayer.java @@ -1,28 +1,37 @@ package com.cjburkey.claimchunk.data.sqlite; +import org.sormula.annotation.Row; + import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; @Table(name = "player_data") +@Row(tableName = "player_data") public class SqlDataPlayer { @Id @Column(name = "player_uuid") + @org.sormula.annotation.Column(primaryKey = true, name = "player_uuid") public String uuid; @Column(name = "last_ign") + @org.sormula.annotation.Column(name = "lastIgn") public String lastIgn; @Column(name = "chunk_name") + @org.sormula.annotation.Column(name = "chunk_name") public String chunkName; @Column(name = "last_online_time") + @org.sormula.annotation.Column(name = "last_online_time") public long lastOnlineTime; @Column(name = "alerts_enabled") + @org.sormula.annotation.Column(name = "alerts_enabled") public boolean alert; @Column(name = "extra_max_claims") + @org.sormula.annotation.Column(name = "extra_max_claims") public int extraMaxClaims; } diff --git a/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqlFlagEntry.java b/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqlFlagEntry.java new file mode 100644 index 0000000..2e326ee --- /dev/null +++ b/src/main/java/com/cjburkey/claimchunk/data/sqlite/SqlFlagEntry.java @@ -0,0 +1,32 @@ +package com.cjburkey.claimchunk.data.sqlite; + +import com.cjburkey.claimchunk.chunk.ChunkPos; + +import org.jetbrains.annotations.Nullable; +import org.sormula.annotation.Column; +import org.sormula.annotation.ImplicitType; +import org.sormula.annotation.Row; + +import java.util.UUID; + +@Row(tableName = "flag_permissions") +public class SqlFlagEntry { + + @Column(name = "player_uuid") + @ImplicitType(translator = Translators.UUIDTranslator.class) + public UUID playerUUID; + + @Column(name = "other_player_uuid") + @ImplicitType(translator = Translators.UUIDTranslator.class) + public @Nullable UUID otherPlayerUUID; + + @Column(name = "chunk_pos") + @ImplicitType(translator = Translators.ChunkPosTranslator.class) + public @Nullable ChunkPos chunkPos; + + @Column(name = "flag_name") + public String flagName; + + @Column(name = "allow_deny") + public boolean allowDeny; +} diff --git a/src/main/java/com/cjburkey/claimchunk/data/sqlite/Translators.java b/src/main/java/com/cjburkey/claimchunk/data/sqlite/Translators.java new file mode 100644 index 0000000..a8fd75f --- /dev/null +++ b/src/main/java/com/cjburkey/claimchunk/data/sqlite/Translators.java @@ -0,0 +1,59 @@ +package com.cjburkey.claimchunk.data.sqlite; + +import com.cjburkey.claimchunk.chunk.ChunkPos; + +import org.sormula.translator.TypeTranslator; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.UUID; + +public final class Translators { + + public record UUIDTranslator() implements TypeTranslator { + @Override + public UUID read(ResultSet resultSet, int columnIndex) throws Exception { + String str = resultSet.getString(columnIndex); + if (str.isEmpty()) { + return null; + } + + return UUID.fromString(str); + } + + @Override + public void write(PreparedStatement preparedStatement, int parameterIndex, UUID parameter) + throws Exception { + preparedStatement.setString( + parameterIndex, parameter != null ? parameter.toString() : ""); + } + } + + public record ChunkPosTranslator() implements TypeTranslator { + @Override + public ChunkPos read(ResultSet resultSet, int columnIndex) throws Exception { + String val = resultSet.getString(columnIndex); + if (val.isEmpty()) { + return null; + } + + String[] str = val.split(","); + String world = str[0]; + int x = Integer.parseInt(str[1]); + int z = Integer.parseInt(str[2]); + return new ChunkPos(world, x, z); + } + + @Override + public void write( + PreparedStatement preparedStatement, int parameterIndex, ChunkPos parameter) + throws Exception { + preparedStatement.setString( + parameterIndex, + parameter != null + ? String.format( + "%s,%s,%s", parameter.world(), parameter.x(), parameter.z()) + : ""); + } + } +} diff --git a/src/main/java/com/cjburkey/claimchunk/i18n/V2JsonMessages.java b/src/main/java/com/cjburkey/claimchunk/i18n/V2JsonMessages.java index 5751dc8..1d07a29 100644 --- a/src/main/java/com/cjburkey/claimchunk/i18n/V2JsonMessages.java +++ b/src/main/java/com/cjburkey/claimchunk/i18n/V2JsonMessages.java @@ -280,6 +280,7 @@ &r&fpermissions in your chunk(s) public String cmdClaim = "Claim the chunk you're standing in"; public String cmdHelp = "Display ClaimChunk help (for [command], if supplied)"; public String cmdInfo = "Display information about the current chunk"; + public String cmdGui = "Open the ClaimChunk GUI"; public String cmdList = "Display a paginated list of all your claims in the world"; public String cmdName = "Change the name that appears when someone enters your land"; public String cmdReload = "Reload the config for ClaimChunk"; diff --git a/src/main/java/com/cjburkey/claimchunk/smartcommand/CCBukkitCommand.java b/src/main/java/com/cjburkey/claimchunk/smartcommand/CCBukkitCommand.java index 2a6987a..04b94f4 100644 --- a/src/main/java/com/cjburkey/claimchunk/smartcommand/CCBukkitCommand.java +++ b/src/main/java/com/cjburkey/claimchunk/smartcommand/CCBukkitCommand.java @@ -49,8 +49,7 @@ public void registerCommand() { @Override public @NotNull List tabComplete( @NotNull CommandSender sender, @NotNull String alias, String[] args) { - // Is this ok? - return Objects.requireNonNull(baseCommand.onTabComplete(sender, this, alias, args)); + return baseCommand.onTabComplete(sender, this, alias, args); } @Override diff --git a/src/main/java/com/cjburkey/claimchunk/smartcommand/CCSubCommand.java b/src/main/java/com/cjburkey/claimchunk/smartcommand/CCSubCommand.java index 880d76d..4a4c885 100644 --- a/src/main/java/com/cjburkey/claimchunk/smartcommand/CCSubCommand.java +++ b/src/main/java/com/cjburkey/claimchunk/smartcommand/CCSubCommand.java @@ -86,7 +86,7 @@ public int getMaxArguments() { * /claimchunk}). * @param executor The subcommand executor. * @param args The raw string arguments passed by the executor. - * @return Whether this subcommand's usage should be displayed. + * @return Whether this subcommand was provided correctly. Return FALSE to display usage! */ public abstract boolean onCall( @NotNull String cmdUsed, @NotNull CommandSender executor, @NotNull String[] args); diff --git a/src/main/java/com/cjburkey/claimchunk/smartcommand/ClaimChunkBaseCommand.java b/src/main/java/com/cjburkey/claimchunk/smartcommand/ClaimChunkBaseCommand.java index 49e852e..b18fd3d 100644 --- a/src/main/java/com/cjburkey/claimchunk/smartcommand/ClaimChunkBaseCommand.java +++ b/src/main/java/com/cjburkey/claimchunk/smartcommand/ClaimChunkBaseCommand.java @@ -101,6 +101,8 @@ public ClaimChunkBaseCommand(ClaimChunk claimChunk) { new CommandStr(new HelpCmd(claimChunk, this), "help"), // `/chunk info` new CommandStr(new InfoCmd(claimChunk), "info"), + // `/chunk gui` + new CommandStr(new GuiCmd(claimChunk), "gui"), // `/chunk list` new CommandStr(new ListCmd(claimChunk), "list"), // `/chunk name` diff --git a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/AccessCmd.java b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/AccessCmd.java deleted file mode 100644 index 73840e6..0000000 --- a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/AccessCmd.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.cjburkey.claimchunk.smartcommand.sub.ply; - -import claimchunk.dependency.de.goldmensch.commanddispatcher.Executor; - -import com.cjburkey.claimchunk.ClaimChunk; -import com.cjburkey.claimchunk.smartcommand.CCSubCommand; - -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -/** - * @since 0.0.24 - */ -@Deprecated -public class AccessCmd extends CCSubCommand { - - private static final String[] nonPlayerArguments = - new String[] { - "break", - "place", - "doors", - "redstone", - "interactVehicles", - "interactEntities", - "interactBlocks", - "useContainers", - "allChunks" - }; - - public AccessCmd(ClaimChunk claimChunk) { - // TODO: CREATE `/chunk admin access ` to allow listing from - // console as well - super(claimChunk, Executor.PLAYER, true, "player", "access"); - } - - @Override - public @Nullable String getDescription() { - return claimChunk.getMessages().cmdAccess; - } - - @Override - public CCArg[] getPermittedArguments() { - return new CCArg[] { - new CCArg(claimChunk.getMessages().argPlayer, CCAutoComplete.OFFLINE_PLAYER), - new CCArg(claimChunk.getMessages().argBreak, CCAutoComplete.PERMISSION), - new CCArg(claimChunk.getMessages().argPlace, CCAutoComplete.PERMISSION), - new CCArg(claimChunk.getMessages().argDoors, CCAutoComplete.PERMISSION), - new CCArg(claimChunk.getMessages().argRedstone, CCAutoComplete.PERMISSION), - new CCArg(claimChunk.getMessages().argInteractVehicles, CCAutoComplete.PERMISSION), - new CCArg(claimChunk.getMessages().argInteractEntities, CCAutoComplete.PERMISSION), - new CCArg(claimChunk.getMessages().argInteractBlocks, CCAutoComplete.PERMISSION), - new CCArg(claimChunk.getMessages().argUseContainers, CCAutoComplete.PERMISSION), - new CCArg(claimChunk.getMessages().argAllChunks, CCAutoComplete.PERMISSION) - }; - } - - @Override - public int getRequiredArguments() { - return 1; - } - - @Override - public boolean onCall(@NotNull String cmdUsed, @NotNull CommandSender executor, String[] args) { - var player = (Player) executor; - if (1 <= args.length) { - String[] newAccessors = args[0].split(","); - Map nonPlayerArgs = - parseNonPlayerArgs(Arrays.copyOfRange(args, 1, args.length)); - if (nonPlayerArgs != null) { - claimChunk.getMainHandler().accessChunk(player, newAccessors, nonPlayerArgs); - } else { - return false; - } - return true; - } - return false; - } - - private Map parseNonPlayerArgs(String[] args) { - HashMap arguments = new HashMap<>(); - - String localizedBooleanTrue = claimChunk.getMessages().argTypeBoolTrue; - String localizedBooleanFalse = claimChunk.getMessages().argTypeBoolFalse; - - for (String arg : args) { - String[] argParts = arg.split(":"); - - if (argParts.length == 2 - && argParts[0] != null - && argParts[1] != null - && Arrays.stream(nonPlayerArguments) - .anyMatch(argParts[0]::equalsIgnoreCase) // argParts[0] is one of the - // expected arguments - && (argParts[1].equalsIgnoreCase(localizedBooleanTrue) - || argParts[1].equalsIgnoreCase( - localizedBooleanFalse)) // argParts[1] is a valid boolean - ) { - arguments.put(argParts[0], argParts[1].equalsIgnoreCase(localizedBooleanTrue)); - } else { - return null; - } - } - return arguments; - } -} diff --git a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/CheckAccessCmd.java b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/GuiCmd.java similarity index 50% rename from src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/CheckAccessCmd.java rename to src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/GuiCmd.java index 3f73e42..d446d80 100644 --- a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/CheckAccessCmd.java +++ b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/GuiCmd.java @@ -3,6 +3,7 @@ import claimchunk.dependency.de.goldmensch.commanddispatcher.Executor; import com.cjburkey.claimchunk.ClaimChunk; +import com.cjburkey.claimchunk.gui.screens.MainMenu; import com.cjburkey.claimchunk.smartcommand.CCSubCommand; import org.bukkit.command.CommandSender; @@ -11,25 +12,22 @@ import org.jetbrains.annotations.Nullable; /** - * @since 0.0.24 + * @since 0.0.26 */ -@Deprecated -public class CheckAccessCmd extends CCSubCommand { +public class GuiCmd extends CCSubCommand { - public CheckAccessCmd(ClaimChunk claimChunk) { - super(claimChunk, Executor.PLAYER, true, "player", "access"); + public GuiCmd(ClaimChunk claimChunk) { + super(claimChunk, Executor.PLAYER, true, "player"); } @Override public @Nullable String getDescription() { - return claimChunk.getMessages().cmdCheckAccess; + return claimChunk.getMessages().cmdGui; } @Override public CCArg[] getPermittedArguments() { - return new CCArg[] { - new CCArg(claimChunk.getMessages().argPlayer, CCAutoComplete.OFFLINE_PLAYER) - }; + return new CCArg[0]; } @Override @@ -39,13 +37,7 @@ public int getRequiredArguments() { @Override public boolean onCall(@NotNull String cmdUsed, @NotNull CommandSender executor, String[] args) { - if (1 <= args.length) { - // User is requesting permissions for a particular player - claimChunk.getMainHandler().checkAccess((Player) executor, args[0]); - } else { - // User is requesting all players with permissions on the chunk - claimChunk.getMainHandler().checkAccess((Player) executor); - } + claimChunk.getGuiHandler().openOrRefreshGui(new MainMenu(claimChunk, (Player) executor)); return true; } } diff --git a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/RevokeAccessCmd.java b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/RevokeAccessCmd.java deleted file mode 100644 index 4454ec0..0000000 --- a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/RevokeAccessCmd.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.cjburkey.claimchunk.smartcommand.sub.ply; - -import claimchunk.dependency.de.goldmensch.commanddispatcher.Executor; - -import com.cjburkey.claimchunk.ClaimChunk; -import com.cjburkey.claimchunk.smartcommand.CCSubCommand; - -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * @since 0.0.24 - */ -@Deprecated -public class RevokeAccessCmd extends CCSubCommand { - - public RevokeAccessCmd(ClaimChunk claimChunk) { - super(claimChunk, Executor.PLAYER, true, "player", "access"); - } - - @Override - public @Nullable String getDescription() { - return claimChunk.getMessages().cmdRevokeAccess; - } - - @Override - public CCArg[] getPermittedArguments() { - return new CCArg[] { - new CCArg(claimChunk.getMessages().argPlayer, CCAutoComplete.OFFLINE_PLAYER), - new CCArg(claimChunk.getMessages().argAllChunks, CCAutoComplete.BOOLEAN) - }; - } - - @Override - public int getRequiredArguments() { - return 1; - } - - @Override - public boolean onCall(@NotNull String cmdUsed, @NotNull CommandSender executor, String[] args) { - String localizedBooleanTrue = claimChunk.getMessages().argTypeBoolTrue; - String localizedBooleanFalse = claimChunk.getMessages().argTypeBoolFalse; - - if (1 <= args.length) { - String[] playersToRevoke = args[0].split(","); - boolean allChunks = false; - if (2 <= args.length - && (args[1].equalsIgnoreCase(localizedBooleanTrue) - || args[1].equalsIgnoreCase(localizedBooleanFalse))) { - allChunks = args[1].equalsIgnoreCase(localizedBooleanTrue); - } - - claimChunk.getMainHandler().revokeAccess((Player) executor, playersToRevoke, allChunks); - return true; - } - return false; - } -} diff --git a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CCPlyAccessCmd.java b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CCPlyAccessCmd.java index 97bca55..3746aa4 100644 --- a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CCPlyAccessCmd.java +++ b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CCPlyAccessCmd.java @@ -3,34 +3,88 @@ import claimchunk.dependency.de.goldmensch.commanddispatcher.Executor; import com.cjburkey.claimchunk.ClaimChunk; +import com.cjburkey.claimchunk.chunk.ChunkPos; import com.cjburkey.claimchunk.smartcommand.CCSubCommand; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.UUID; public abstract class CCPlyAccessCmd extends CCSubCommand { - public final boolean isForPly; - public final boolean isForChunk; + public final boolean forPlayer; + public final boolean forChunk; - public CCPlyAccessCmd(@NotNull ClaimChunk claimChunk, boolean isForPly, boolean isForChunk) { + public CCPlyAccessCmd(@NotNull ClaimChunk claimChunk, boolean forPlayer, boolean forChunk) { super(claimChunk, Executor.PLAYER, true, "player", "access"); - this.isForPly = isForPly; - this.isForChunk = isForChunk; + this.forPlayer = forPlayer; + this.forChunk = forChunk; } + protected abstract boolean handleAccess( + @NotNull Player caller, + @Nullable UUID otherPlayer, + @Nullable ChunkPos chunkPos, + @NotNull String[] arguments); + @Override public abstract @NotNull String getDescription(); @Override public CCArg[] getPermittedArguments() { - if (isForPly) { - return new CCArg[] {new CCArg("otherPlayer", CCAutoComplete.OFFLINE_PLAYER)}; + var perm = new CCArg("permissions", CCAutoComplete.PERMISSION); + if (forPlayer) { + return new CCArg[] {new CCArg("otherPlayer", CCAutoComplete.OFFLINE_PLAYER), perm}; } - return new CCArg[0]; + return new CCArg[] {perm}; } @Override public int getRequiredArguments() { - return isForPly ? 1 : 0; + return forPlayer ? 2 : 1; + } + + @Override + public boolean onCall( + @NotNull String cmdUsed, @NotNull CommandSender executor, @NotNull String[] args) { + Player caller = (Player) executor; + + UUID otherPlayer = null; + if (forPlayer) { + String plyName = args[0]; + args = Arrays.copyOfRange(args, 1, args.length); + otherPlayer = claimChunk.getPlayerHandler().getUUID(plyName); + if (otherPlayer == null) { + messagePly(caller, claimChunk.getMessages().noPlayer); + return true; + } + } + + ChunkPos chunkPos = forChunk ? new ChunkPos(caller.getLocation().getChunk()) : null; + return handleAccess(caller, otherPlayer, chunkPos, args); + } + + protected final @NotNull String describe( + @NotNull String plyChunk, + @NotNull String ply, + @NotNull String chunk, + @NotNull String global) { + if (forPlayer) { + if (forChunk) { + return plyChunk; + } else { + return ply; + } + } else { + if (forChunk) { + return chunk; + } else { + return global; + } + } } } diff --git a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdClearPermFlag.java b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdClearPermFlag.java index 0368ce4..c29634c 100644 --- a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdClearPermFlag.java +++ b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdClearPermFlag.java @@ -1,43 +1,40 @@ package com.cjburkey.claimchunk.smartcommand.sub.ply.flags; import com.cjburkey.claimchunk.ClaimChunk; +import com.cjburkey.claimchunk.chunk.ChunkPos; import com.cjburkey.claimchunk.i18n.V2JsonMessages; -import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; /** * @since 0.0.26 */ public class CmdClearPermFlag extends CCPlyAccessCmd { - public CmdClearPermFlag(@NotNull ClaimChunk claimChunk, boolean isForPly, boolean isForChunk) { - super(claimChunk, isForPly, isForChunk); + public CmdClearPermFlag(@NotNull ClaimChunk claimChunk, boolean forPlayer, boolean forChunk) { + super(claimChunk, forPlayer, forChunk); } @Override - public @NotNull String getDescription() { - V2JsonMessages msg = claimChunk.getMessages(); - if (isForPly) { - if (isForChunk) { - return msg.cmdPermFlagPlyChunkClear; - } else { - return msg.cmdPermFlagPlyClear; - } - } else { - if (isForChunk) { - return msg.cmdPermFlagChunkClear; - } else { - return msg.cmdPermFlagGlobalClear; - } - } + protected boolean handleAccess( + @NotNull Player caller, + @Nullable UUID otherPlayer, + @Nullable ChunkPos chunkPos, + @NotNull String[] arguments) { + return true; } @Override - public boolean onCall( - @NotNull String cmdUsed, @NotNull CommandSender executor, @NotNull String[] args) { - // TODO: DO THIS - - return false; + public @NotNull String getDescription() { + V2JsonMessages msg = claimChunk.getMessages(); + return describe( + msg.cmdPermFlagPlyChunkClear, + msg.cmdPermFlagPlyClear, + msg.cmdPermFlagChunkClear, + msg.cmdPermFlagGlobalClear); } } diff --git a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdSetPermFlag.java b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdSetPermFlag.java index 51ce057..3a3a81b 100644 --- a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdSetPermFlag.java +++ b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdSetPermFlag.java @@ -1,43 +1,40 @@ package com.cjburkey.claimchunk.smartcommand.sub.ply.flags; import com.cjburkey.claimchunk.ClaimChunk; +import com.cjburkey.claimchunk.chunk.ChunkPos; import com.cjburkey.claimchunk.i18n.V2JsonMessages; -import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; /** * @since 0.0.26 */ public class CmdSetPermFlag extends CCPlyAccessCmd { - public CmdSetPermFlag(@NotNull ClaimChunk claimChunk, boolean isForPly, boolean isForChunk) { - super(claimChunk, isForPly, isForChunk); + public CmdSetPermFlag(@NotNull ClaimChunk claimChunk, boolean forPlayer, boolean forChunk) { + super(claimChunk, forPlayer, forChunk); } @Override - public @NotNull String getDescription() { - V2JsonMessages msg = claimChunk.getMessages(); - if (isForPly) { - if (isForChunk) { - return msg.cmdPermFlagPlyChunkSet; - } else { - return msg.cmdPermFlagPlySet; - } - } else { - if (isForChunk) { - return msg.cmdPermFlagChunkSet; - } else { - return msg.cmdPermFlagGlobalSet; - } - } + protected boolean handleAccess( + @NotNull Player caller, + @Nullable UUID otherPlayer, + @Nullable ChunkPos chunkPos, + @NotNull String[] arguments) { + return true; } @Override - public boolean onCall( - @NotNull String cmdUsed, @NotNull CommandSender executor, @NotNull String[] args) { - // TODO: DO THIS - - return false; + public @NotNull String getDescription() { + V2JsonMessages msg = claimChunk.getMessages(); + return describe( + msg.cmdPermFlagPlyChunkSet, + msg.cmdPermFlagPlySet, + msg.cmdPermFlagChunkSet, + msg.cmdPermFlagGlobalSet); } } diff --git a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdViewPermFlag.java b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdViewPermFlag.java index c45fe33..ae9673d 100644 --- a/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdViewPermFlag.java +++ b/src/main/java/com/cjburkey/claimchunk/smartcommand/sub/ply/flags/CmdViewPermFlag.java @@ -1,43 +1,40 @@ package com.cjburkey.claimchunk.smartcommand.sub.ply.flags; import com.cjburkey.claimchunk.ClaimChunk; +import com.cjburkey.claimchunk.chunk.ChunkPos; import com.cjburkey.claimchunk.i18n.V2JsonMessages; -import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; /** * @since 0.0.26 */ public class CmdViewPermFlag extends CCPlyAccessCmd { - public CmdViewPermFlag(@NotNull ClaimChunk claimChunk, boolean isForPly, boolean isForChunk) { - super(claimChunk, isForPly, isForChunk); + public CmdViewPermFlag(@NotNull ClaimChunk claimChunk, boolean forPlayer, boolean forChunk) { + super(claimChunk, forPlayer, forChunk); } @Override - public @NotNull String getDescription() { - V2JsonMessages msg = claimChunk.getMessages(); - if (isForPly) { - if (isForChunk) { - return msg.cmdPermFlagPlyChunkList; - } else { - return msg.cmdPermFlagPlyList; - } - } else { - if (isForChunk) { - return msg.cmdPermFlagChunkList; - } else { - return msg.cmdPermFlagGlobalList; - } - } + protected boolean handleAccess( + @NotNull Player caller, + @Nullable UUID otherPlayer, + @Nullable ChunkPos chunkPos, + @NotNull String[] arguments) { + return true; } @Override - public boolean onCall( - @NotNull String cmdUsed, @NotNull CommandSender executor, @NotNull String[] args) { - // TODO: DO THIS - - return false; + public @NotNull String getDescription() { + V2JsonMessages msg = claimChunk.getMessages(); + return describe( + msg.cmdPermFlagPlyChunkList, + msg.cmdPermFlagPlyList, + msg.cmdPermFlagChunkList, + msg.cmdPermFlagGlobalList); } } diff --git a/src/test/java/com/cjburkey/claimchunk/TestSQLPlease.java b/src/test/java/com/cjburkey/claimchunk/TestSQLPlease.java index ad7a484..429bc5d 100644 --- a/src/test/java/com/cjburkey/claimchunk/TestSQLPlease.java +++ b/src/test/java/com/cjburkey/claimchunk/TestSQLPlease.java @@ -7,7 +7,9 @@ import com.cjburkey.claimchunk.data.sqlite.SqLiteTableMigrationManager; import com.cjburkey.claimchunk.data.sqlite.SqLiteWrapper; import com.cjburkey.claimchunk.player.FullPlayerData; + import org.junit.jupiter.api.Test; + import java.io.File; import java.util.Collection; import java.util.HashMap; @@ -26,8 +28,6 @@ void ensureColumnExistsMethodWorks() { assertFalse(SqLiteTableMigrationManager.tableExists("bob_the_builder_no_we_cant")); assertFalse(SqLiteTableMigrationManager.columnExists("chunk_hell", "permission_bits")); assertFalse(SqLiteTableMigrationManager.columnExists("player_data", "fake_col")); - - } } @@ -45,6 +45,7 @@ void test0026BasicsWork() { FullPlayerData examplePlayer2 = new FullPlayerData( UUID.randomUUID(), "HisBrother", "Tommy Boy", 63425, false, 3); + UUID haterPlayer = UUID.randomUUID(); wrapper.sql.addPlayer(examplePlayer1); wrapper.sql.addPlayer(examplePlayer2); @@ -64,8 +65,7 @@ void test0026BasicsWork() { } // Try to clear a flag { - wrapper.sql.clearPermissionFlags( - examplePlayer1.player, null, null, "doThatClear"); + wrapper.sql.clearPermissionFlags(examplePlayer1.player, null, null, "doThatClear"); } { HashMap p = new HashMap<>(); @@ -92,6 +92,13 @@ void test0026BasicsWork() { wrapper.sql.setPermissionFlags( examplePlayer1.player, examplePlayer2.player, null, p); } + // Added flags for nonexistent player shouldn't be loaded + { + HashMap p = new HashMap<>(); + p.put("iShouldntExist", true); + wrapper.sql.setPermissionFlags(haterPlayer, examplePlayer2.player, null, p); + wrapper.sql.setPermissionFlags(haterPlayer, null, null, p); + } List loadedPlayers = wrapper.sql.getAllPlayers(); Collection loadedChunks = wrapper.sql.getAllChunks();