Skip to content

Commit

Permalink
Re-add ability for town members to claim plots, fix placeholder issues (
Browse files Browse the repository at this point in the history
#369)

* Re-add plot claiming

* Update getting started docs

* Refactor Town object schema, add Options.

* Fixup `#of` call in `LegacyMigrator`

* Fixup questionable test data

* Add unit test for updating schema, fix NPE updating options

* Simplify schema update test

* Bump `runServer` to target 1.20.2

* fixup unnecessary locale check

* Bump runtime dependencies

* sqlite: use `RETURNING`, fix driver API deprecation

* sqlite: fix SQLException due to bad `executeUpdate` call

* papi: Fix wrong claim type check, close #371

* locales: refactor `N/A` use, add `#getNotApplicable`

* papi: fix level-up cost exception at max level, close #372

* bukkit: Make armor stand use require `CONTAINER_OPEN`, close #325

* bukkit: Make `Openable`s (doors, etc.) need `BLOCK_INTERACT`, close #363
  • Loading branch information
WiIIiam278 authored Nov 25, 2023
1 parent 0b907e2 commit de49508
Show file tree
Hide file tree
Showing 30 changed files with 432 additions and 175 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ private HuskTownsExpansion(@NotNull HuskTowns plugin) {
@Override
public String onRequest(@Nullable OfflinePlayer offlinePlayer, @NotNull String params) {
if (!plugin.isLoaded()) {
return plugin.getLocales().getRawLocale("not_applicable").orElse("N/A");
return plugin.getLocales().getNotApplicable();
}

// Ensure the player is online
Expand Down Expand Up @@ -152,14 +152,15 @@ public String onRequest(@Nullable OfflinePlayer offlinePlayer, @NotNull String p
case "town_money" -> plugin.getUserTown(player)
.map(Member::town)
.map(Town::getMoney)
.map(String::valueOf)
.map(plugin::formatMoney)
.orElse(plugin.getLocales().getRawLocale("placeholder_not_in_town")
.orElse("Not in town"));

case "town_level_up_cost" -> plugin.getUserTown(player)
.map(Member::town)
.map(town -> plugin.getLevels().getLevelUpCost(town.getLevel()))
.map(String::valueOf)
.map(town -> town.getLevel() >= plugin.getLevels().getMaxLevel()
? plugin.getLocales().getNotApplicable()
: plugin.formatMoney(plugin.getLevels().getLevelUpCost(town.getLevel())))
.orElse(plugin.getLocales().getRawLocale("placeholder_not_in_town")
.orElse("Not in town"));

Expand Down Expand Up @@ -203,7 +204,7 @@ public String onRequest(@Nullable OfflinePlayer offlinePlayer, @NotNull String p
case "current_location_plot_members" -> plugin.getClaimAt(player.getPosition())
.map(townClaim -> {
final Claim claim = townClaim.claim();
if (claim.getType() == Claim.Type.PLOT) {
if (claim.getType() != Claim.Type.PLOT) {
return plugin.getLocales().getRawLocale("placeholder_not_a_plot")
.orElse("Not a plot");
}
Expand All @@ -218,7 +219,7 @@ public String onRequest(@Nullable OfflinePlayer offlinePlayer, @NotNull String p
case "current_location_plot_managers" -> plugin.getClaimAt(player.getPosition())
.map(townClaim -> {
final Claim claim = townClaim.claim();
if (claim.getType() == Claim.Type.PLOT) {
if (claim.getType() != Claim.Type.PLOT) {
return plugin.getLocales().getRawLocale("placeholder_not_a_plot")
.orElse("Not a plot");
}
Expand All @@ -239,7 +240,7 @@ public String onRequest(@Nullable OfflinePlayer offlinePlayer, @NotNull String p
case "current_location_town_money" -> plugin.getClaimAt(player.getPosition())
.map(TownClaim::town)
.map(Town::getMoney)
.map(String::valueOf)
.map(plugin::formatMoney)
.orElse(plugin.getLocales().getRawLocale("placeholder_not_claimed")
.orElse("Not claimed"));

Expand All @@ -252,8 +253,9 @@ public String onRequest(@Nullable OfflinePlayer offlinePlayer, @NotNull String p

case "current_location_town_level_up_cost" -> plugin.getClaimAt(player.getPosition())
.map(TownClaim::town)
.map(town -> plugin.getLevels().getLevelUpCost(town.getLevel()))
.map(String::valueOf)
.map(town -> town.getLevel() >= plugin.getLevels().getMaxLevel()
? plugin.getLocales().getNotApplicable()
: plugin.formatMoney(plugin.getLevels().getLevelUpCost(town.getLevel())))
.orElse(plugin.getLocales().getRawLocale("placeholder_not_in_town")
.orElse("Not in town"));

Expand Down Expand Up @@ -300,14 +302,17 @@ private String getTownLeaderboard(@NotNull String identifier) {

// Get the leaderboard index and return the sorted list element at the index
try {
final int leaderboardIndex = Math.max(1, Integer.parseInt(identifier.substring(lastUnderscore + 1)));
final int leaderboardIndex = Math.max(1, Integer.parseInt(
identifier.substring(lastUnderscore + 1)
));
final List<Town> towns = getSortedTownList(identifier.substring(0, lastUnderscore));
if (towns == null) {
return null;
}

return towns.size() >= leaderboardIndex ? towns.get(leaderboardIndex - 1).getName()
: plugin.getLocales().getRawLocale("not_applicable").orElse("N/A");
return towns.size() >= leaderboardIndex
? towns.get(leaderboardIndex - 1).getName()
: plugin.getLocales().getNotApplicable();
} catch (NumberFormatException e) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import org.bukkit.FluidCollisionMode;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.Openable;
import org.bukkit.block.data.type.Sign;
import org.bukkit.block.data.type.Switch;
import org.bukkit.entity.Player;
Expand Down Expand Up @@ -65,7 +64,7 @@ default void onPlayerInteract(@NotNull PlayerInteractEvent e) {
if (block != null && e.useInteractedBlock() != Event.Result.DENY) {
if (getListener().handler().cancelOperation(Operation.of(
BukkitUser.adapt(e.getPlayer()),
block.getBlockData() instanceof Openable || block.getState() instanceof InventoryHolder ? Operation.Type.CONTAINER_OPEN
block.getState() instanceof InventoryHolder ? Operation.Type.CONTAINER_OPEN
: getPlugin().getSpecialTypes().isFarmBlock(block.getType().getKey().toString()) ? Operation.Type.FARM_BLOCK_INTERACT
: block.getBlockData() instanceof Switch ? Operation.Type.REDSTONE_INTERACT
: block.getBlockData() instanceof Sign ? Operation.Type.BLOCK_PLACE
Expand Down Expand Up @@ -190,7 +189,7 @@ default void onPlayerInteractEntity(@NotNull PlayerInteractEntityEvent e) {
default void onPlayerArmorStand(@NotNull PlayerArmorStandManipulateEvent e) {
if (getListener().handler().cancelOperation(Operation.of(
BukkitUser.adapt(e.getPlayer()),
Operation.Type.ENTITY_INTERACT,
Operation.Type.CONTAINER_OPEN,
getPosition(e.getRightClicked().getLocation())
))) {
e.setCancelled(true);
Expand Down
1 change: 1 addition & 0 deletions bukkit/src/main/resources/commodore/town.commodore
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ town {
farm;
plot {
members;
claim;
add {
player brigadier:string single_word {
manager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ public class PruningTests {
"100d-Prune", 100L,

// Records that should not be pruned
"90d-Leave", 90L,
"80d-Leave", 80L,
"40d-Leave", 40L,
"0d-Leave", 0L
);
private static final long PRUNE_AFTER_DAYS = 90L;
Expand Down Expand Up @@ -330,6 +330,28 @@ private static Stream<Arguments> getTownAndMayorParameters() {
}
}

@Order(5)
@Nested
@DisplayName("Town Schema Update Tests")
public class TownSchemaUpdateTests {

@Order(1)
@DisplayName("Test Town Schema Update")
@Test
public void testTownSchemaUpdate() {
final String townJson = String.join("\n", readTestData("town_schema_v0.json"));
final Town readTown = plugin.getTownFromJson(townJson);
Assertions.assertNotNull(readTown);
Assertions.assertAll(
() -> Assertions.assertEquals(Town.CURRENT_SCHEMA, readTown.getSchemaVersion()),
() -> Assertions.assertEquals("Test", readTown.getBio().orElseThrow()),
() -> Assertions.assertEquals("Test", readTown.getGreeting().orElseThrow()),
() -> Assertions.assertEquals("Test", readTown.getFarewell().orElseThrow())
);
}

}

@NotNull
private static Player makePlayer() {
final Player player = server.addPlayer();
Expand Down Expand Up @@ -360,4 +382,5 @@ private static List<String> readTestData(@NotNull String fileName) {
}
return townNames;
}

}
16 changes: 16 additions & 0 deletions bukkit/src/test/resources/town_schema_v0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"id": 1,
"name": "Schema0",
"greeting": "Test",
"bio": "Test",
"farewell": "Test",
"members": {},
"rules": {},
"claims": 0,
"level": 1,
"money": 0.0,
"bonuses": {},
"log": {},
"relations": {},
"metadata": {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ public enum Type {
MAKE_CLAIM_REGULAR,
ADD_PLOT_MEMBER,
REMOVE_PLOT_MEMBER,
CLAIM_VACANT_PLOT,
DEPOSIT_MONEY,
WITHDRAW_MONEY,
SET_FLAG_RULE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,9 @@ public void execute(@NotNull CommandUser executor, @NotNull String[] args) {
.map(town -> locales.getRawLocale("town_list_item",
Locales.escapeText(town.getName()),
town.getColorRgb(),
Locales.escapeText(locales.wrapText(town.getBio()
.orElse(plugin.getLocales().getRawLocale("not_applicable")
.orElse("N/A")), 40)),
Locales.escapeText(locales.wrapText(town.getBio().orElse(
plugin.getLocales().getNotApplicable()
), 40)),
Integer.toString(town.getLevel()),
Integer.toString(town.getClaimCount()),
Integer.toString(town.getMaxClaims(plugin)),
Expand Down Expand Up @@ -866,7 +866,7 @@ public void execute(@NotNull CommandUser executor, @NotNull String[] args) {
private static class PlotCommand extends ChildCommand implements TabProvider {

protected PlotCommand(@NotNull Command parent, @NotNull HuskTowns plugin) {
super("plot", List.of(), parent, "<(members)|(<add|remove> <player> [manager])>", plugin);
super("plot", List.of(), parent, "<members|claim|(<add|remove> <player> [manager])>", plugin);
}

@Override
Expand Down Expand Up @@ -898,6 +898,8 @@ public void execute(@NotNull CommandUser executor, @NotNull String[] args) {
}
plugin.getManager().claims().removePlotMember(user, user.getWorld(), user.getChunk(), target.get());
}
case "claim" -> plugin.getManager().claims()
.claimPlot(user, user.getWorld(), user.getChunk());
case "members", "memberlist", "list" -> plugin.getManager().claims()
.listPlotMembers(user, user.getWorld(), user.getChunk());
default -> plugin.getLocales().getLocale("error_invalid_syntax", getUsage())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ public double getMobSpawnerRateBonus(int level) {
/**
* Get the cost required to reach a certain level
*
* @param level the next level
* @return the cost to upgrade from {@code level - 1} to {@code level}
* @param level the current level of the town
* @return the cost to upgrade from {@code level} to {@code level + 1}
*/
@NotNull
public BigDecimal getLevelUpCost(int level) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public static String escapeText(@NotNull String string) {
@NotNull
public String wrapText(@NotNull String string, int wrapAfter) {
if (string.isBlank()) {
return this.getRawLocale("not_applicable").orElse("N/A");
return getNotApplicable();
}
return WordUtils.wrap(string, wrapAfter, "\n", true);
}
Expand All @@ -161,6 +161,11 @@ public String truncateText(@NotNull String string, int truncateAfter) {
return string.length() > truncateAfter ? string.substring(0, truncateAfter) + "…" : string;
}

@NotNull
public String getNotApplicable() {
return getRawLocale("not_applicable").orElse("N/A");
}

@NotNull
public ListOptions.Builder getBaseList(int itemsPerPage) {
return new ListOptions.Builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public class Roles {
"1", List.of(
Privilege.DEPOSIT.id(),
Privilege.CHAT.id(),
Privilege.CLAIM_PLOT.id(),
Privilege.SPAWN.id())
));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public Optional<SavedUser> getUser(@NotNull UUID uuid) {
User.of(uuid, name),
resultSet.getTimestamp("last_login").toLocalDateTime()
.atOffset(OffsetDateTime.now().getOffset()),
plugin.getGson().fromJson(preferences, Preferences.class)
plugin.getPreferencesFromJson(preferences)
));
}
}
Expand All @@ -248,7 +248,7 @@ public Optional<SavedUser> getUser(@NotNull String username) {
User.of(uuid, name),
resultSet.getTimestamp("last_login").toLocalDateTime()
.atOffset(OffsetDateTime.now().getOffset()),
plugin.getGson().fromJson(preferences, Preferences.class)
plugin.getPreferencesFromJson(preferences)
));
}
}
Expand Down Expand Up @@ -276,7 +276,7 @@ public List<SavedUser> getInactiveUsers(long daysInactive) {
User.of(uuid, name),
resultSet.getTimestamp("last_login").toLocalDateTime()
.atOffset(OffsetDateTime.now().getOffset()),
plugin.getGson().fromJson(preferences, Preferences.class)
plugin.getPreferencesFromJson(preferences)
));
}
}
Expand Down Expand Up @@ -345,7 +345,7 @@ public Optional<Town> getTown(int townId) {
final ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
final String data = new String(resultSet.getBytes("data"), StandardCharsets.UTF_8);
final Town town = plugin.getGson().fromJson(data, Town.class);
final Town town = plugin.getTownFromJson(data);
town.setId(resultSet.getInt("id"));
return Optional.of(town);
}
Expand All @@ -366,7 +366,7 @@ public List<Town> getAllTowns() throws IllegalStateException {
final ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
final String data = new String(resultSet.getBytes("data"), StandardCharsets.UTF_8);
final Town town = plugin.getGson().fromJson(data, Town.class);
final Town town = plugin.getTownFromJson(data);
if (town != null) {
town.setId(resultSet.getInt("id"));
towns.add(town);
Expand Down Expand Up @@ -461,7 +461,7 @@ public Map<World, ClaimWorld> getClaimWorlds(@NotNull String server) throws Ille
final World world = World.of(UUID.fromString(resultSet.getString("world_uuid")),
resultSet.getString("world_name"),
resultSet.getString("world_environment"));
final ClaimWorld claimWorld = plugin.getGson().fromJson(data, ClaimWorld.class);
final ClaimWorld claimWorld = plugin.getClaimWorldFromJson(data);
claimWorld.updateId(resultSet.getInt("id"));
if (!plugin.getSettings().isUnclaimableWorld(world)) {
worlds.put(world, claimWorld);
Expand All @@ -487,7 +487,7 @@ public Map<ServerWorld, ClaimWorld> getAllClaimWorlds() throws IllegalStateExcep
final World world = World.of(UUID.fromString(resultSet.getString("world_uuid")),
resultSet.getString("world_name"),
resultSet.getString("world_environment"));
final ClaimWorld claimWorld = plugin.getGson().fromJson(data, ClaimWorld.class);
final ClaimWorld claimWorld = plugin.getClaimWorldFromJson(data);
claimWorld.updateId(resultSet.getInt("id"));
worlds.put(new ServerWorld(resultSet.getString("server_name"), world), claimWorld);
}
Expand Down
Loading

0 comments on commit de49508

Please sign in to comment.