Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import org.apache.tools.ant.filters.ReplaceTokens

plugins {
id 'com.gradleup.shadow' version '9.0.0-beta17'
id 'org.cadixdev.licenser' version '0.6.1' apply false
id 'dev.architectury.loom' version '1.9-SNAPSHOT' apply false
id 'com.gradleup.shadow' version '9.4.1'
id 'dev.yumi.gradle.licenser' version '3.0.1' apply false
id 'dev.architectury.loom' version '1.14.+' apply false
id 'gg.essential.multi-version.root' apply false
id 'org.ajoberstar.grgit' version '5.3.2'
id 'maven-publish'
Expand All @@ -13,7 +13,7 @@ plugins {
group 'net.william278'
version "$ext.plugin_version${versionMetadata()}"
description "$ext.plugin_description"
defaultTasks 'licenseFormat', 'build'
defaultTasks 'applyLicenses', 'build'

ext {
set 'version', version.toString()
Expand Down Expand Up @@ -63,16 +63,15 @@ allprojects {
}

apply plugin: 'com.gradleup.shadow'
apply plugin: 'org.cadixdev.licenser'
apply plugin: 'dev.yumi.gradle.licenser'
apply plugin: 'java'

compileJava.options.encoding = 'UTF-8'
compileJava.options.release.set 17
compileJava.options.release.set 21
javadoc.options.encoding = 'UTF-8'
javadoc.options.addStringOption('Xdoclint:none', '-quiet')

repositories {
mavenLocal()
mavenCentral()
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
maven { url 'https://repo.papermc.io/repository/maven-public/' }
Expand All @@ -96,9 +95,8 @@ allprojects {
}

license {
header = rootProject.file('HEADER')
include '**/*.java'
newLine = true
rule(rootProject.file('HEADER'))
include('**/*.java')
}

test {
Expand Down Expand Up @@ -127,7 +125,7 @@ subprojects {
} else {
name += "-${project.name.capitalize()}"
}
archivesBaseName = name
base.archivesName = name

// Fabric-specific configuration
if (project.parent?.name?.equals('fabric')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public void loadMetrics() {
try {
final Metrics metrics = new Metrics(this, BSTATS_PLUGIN_ID);
metrics.addCustomChart(new SimplePie("is_cross_server",
() -> settings.getCrossServer().isEnabled() ? "true" : "false")
() -> Boolean.toString(settings.getCrossServer().isEnabled()))
);
metrics.addCustomChart(new SimplePie("language",
() -> settings.getLanguage().toLowerCase(Locale.ENGLISH))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,4 @@ protected static PermissionDefault getPermissionDefault(boolean isOperatorComman
return isOperatorCommand ? PermissionDefault.OP : PermissionDefault.TRUE;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ public HuskClaims getPlugin() {
return plugin;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ SELECT COUNT(*)
return 0;
}


private int getTotalClaims() {
try (Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement("""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,12 @@ public void run() {

final GracefulScheduling scheduler = getScheduler();

if (e instanceof Entity entity) {
scheduled = scheduler.entitySpecificScheduler(entity).run(runnable, null);
} else if (e instanceof Location location) {
scheduled = scheduler.regionSpecificScheduler(location).run(runnable);
} else if (e instanceof Chunk chunk) {
scheduled = scheduler.regionSpecificScheduler(chunk.getWorld(), chunk.getX(), chunk.getZ()).run(runnable);
} else {
scheduled = scheduler.globalRegionalScheduler().run(runnable);
switch (e) {
case Entity entity -> scheduled = scheduler.entitySpecificScheduler(entity).run(runnable, null);
case Location location -> scheduled = scheduler.regionSpecificScheduler(location).run(runnable);
case Chunk chunk ->
scheduled = scheduler.regionSpecificScheduler(chunk.getWorld(), chunk.getX(), chunk.getZ()).run(runnable);
case null, default -> scheduled = scheduler.globalRegionalScheduler().run(runnable);
}
}

Expand Down
50 changes: 23 additions & 27 deletions common/src/main/java/net/william278/huskclaims/claim/Claim.java
Original file line number Diff line number Diff line change
Expand Up @@ -325,17 +325,16 @@ public void setTagTrustLevel(@NotNull TrustTag tag, @NotNull TrustLevel level) {
* @since 1.0
*/
public void setTrustLevel(@NotNull Trustable trustable, @NotNull TrustLevel level) {
if (trustable instanceof User user) {
setUserTrustLevel(user.getUuid(), level);
} else if (trustable instanceof UserGroup group) {
if (isAdminClaim()) {
throw new IllegalArgumentException("Cannot set group trust level in admin claim");
switch (trustable) {
case User user -> setUserTrustLevel(user.getUuid(), level);
case UserGroup group -> {
if (isAdminClaim()) {
throw new IllegalArgumentException("Cannot set group trust level in admin claim");
}
setGroupTrustLevel(group, level);
}
setGroupTrustLevel(group, level);
} else if (trustable instanceof TrustTag tag) {
setTagTrustLevel(tag, level);
} else {
throw new IllegalArgumentException("Trustable must be a User, UserGroup, or TrustTag");
case TrustTag tag -> setTagTrustLevel(tag, level);
default -> throw new IllegalArgumentException("Trustable must be a User, UserGroup, or TrustTag");
}
}

Expand All @@ -347,15 +346,14 @@ public void setTrustLevel(@NotNull Trustable trustable, @NotNull TrustLevel leve
* @since 1.0
*/
public void removeTrustLevel(@NotNull Trustable trustable, @NotNull ClaimWorld world) {
if (trustable instanceof User user) {
trustedUsers.remove(user.getUuid());
world.cacheUser(user);
} else if (trustable instanceof UserGroup group) {
trustedGroups.remove(group.name());
} else if (trustable instanceof TrustTag tag) {
trustedTags.remove(tag.getName());
} else {
throw new IllegalArgumentException("Trustable must be a User, UserGroup, or TrustTag");
switch (trustable) {
case User user -> {
trustedUsers.remove(user.getUuid());
world.cacheUser(user);
}
case UserGroup group -> trustedGroups.remove(group.name());
case TrustTag tag -> trustedTags.remove(tag.getName());
default -> throw new IllegalArgumentException("Trustable must be a User, UserGroup, or TrustTag");
}
}

Expand Down Expand Up @@ -441,14 +439,12 @@ public Optional<TrustLevel> getUserTrustLevel(@NotNull User user, @NotNull HuskC
* @since 1.0
*/
public Optional<TrustLevel> getTrustLevel(@NotNull Trustable trustable, @NotNull HuskClaims plugin) {
if (trustable instanceof User user) {
return getUserTrustLevel(user, plugin);
} else if (trustable instanceof UserGroup group) {
return getGroupTrustLevel(group.name(), plugin);
} else if (trustable instanceof TrustTag tag) {
return getTagTrustLevel(tag.getName(), plugin);
}
throw new IllegalArgumentException("Trustable must be a User, UserGroup, or TrustedTag");
return switch (trustable) {
case User user -> getUserTrustLevel(user, plugin);
case UserGroup group -> getGroupTrustLevel(group.name(), plugin);
case TrustTag tag -> getTagTrustLevel(tag.getName(), plugin);
default -> throw new IllegalArgumentException("Trustable must be a User, UserGroup, or TrustedTag");
};
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,20 @@ default void userTransferClaim(@NotNull OnlineUser user, @NotNull Claim claim,
return;
}

// Validate the new owner has enough available claim blocks to receive the claim.
// Without this check, /transferclaim + /unclaim can be used to generate free blocks:
// the original owner is refunded on transfer, but if the new owner's available
// balance is never debited, unclaiming gives them a refund for blocks they
// never paid for. See claim block accounting in ClaimBlocksManager#editClaimBlocks.
final long surfaceArea = claim.getRegion().getSurfaceArea();
final long newOwnerAvailable = getPlugin().getClaimBlocks(newOwner.getUuid());
if (newOwnerAvailable < surfaceArea) {
getPlugin().getLocales().getLocale("error_not_enough_claim_blocks",
Long.toString(surfaceArea - newOwnerAvailable))
.ifPresent(user::sendMessage);
return;
}

// Transfer claim
getPlugin().fireTransferClaimEvent(user, claim, claimWorld, newOwner, (event) -> {
// Cache user, send message, invalidate source user/admin claim list cache
Expand All @@ -272,16 +286,18 @@ default void userTransferClaim(@NotNull OnlineUser user, @NotNull Claim claim,
getPlugin().invalidateClaimListCache(claim.getOwner().orElse(null));

// Adjust claim blocks for both users to maintain proper accounting
final long surfaceArea = claim.getRegion().getSurfaceArea();
claim.getOwner().flatMap(claimWorld::getUser).ifPresent(originalOwner -> {
// Return available blocks to original owner and reduce their spent blocks
getPlugin().editClaimBlocks(
originalOwner, ClaimBlocksManager.ClaimBlockSource.CLAIM_TRANSFER_AWAY, (blocks) -> blocks + surfaceArea);
getPlugin().editSpentClaimBlocks(
originalOwner, ClaimBlocksManager.ClaimBlockSource.CLAIM_TRANSFER_AWAY, (blocks) -> blocks - surfaceArea);
});
// Set the new owner's spent blocks so unclaim accounting works correctly
// Debit the new owner's available blocks and increase their spent counter
// so unclaim accounting works correctly and no blocks are duplicated.
claimWorld.getUser(newOwner.getUuid()).ifPresent(owner -> {
getPlugin().editClaimBlocks(
owner, ClaimBlocksManager.ClaimBlockSource.CLAIM_CREATED, (blocks) -> blocks - surfaceArea);
getPlugin().editSpentClaimBlocks(
owner, ClaimBlocksManager.ClaimBlockSource.CLAIM_CREATED, (blocks) -> blocks + surfaceArea);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ default void deleteClaim(@NotNull ClaimWorld claimWorld, @NotNull Claim claim) {
getPlugin().runQueued(() -> getPlugin().getDatabase().updateClaimWorld(claimWorld));

// Adjust the owner's claim block count
claim.getOwner().flatMap(claimWorld::getUser).ifPresent(user -> {
claim.getOwner().ifPresent(ownerUuid -> {
final User user = claimWorld.getUser(ownerUuid)
.orElseGet(() -> User.of(ownerUuid, ownerUuid.toString()));
getPlugin().editClaimBlocks(
user, ClaimBlocksManager.ClaimBlockSource.CLAIM_DELETED, (blocks -> blocks + surfaceArea));
getPlugin().editSpentClaimBlocks(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,4 @@ private double getBlockPrice(long amount) {
return amount * Math.max(0.0, plugin.getSettings().getHooks().getEconomy().getCostPerBlock());
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ private void handleFlagsCommand(@NotNull OnlineUser executor, @NotNull String ac

private void handleSetClaimFlag(@NotNull OnlineUser onlineUser, @Nullable Claim claim,
@NotNull ClaimWorld world, @NotNull String[] args) {
final Optional<OperationType> operationType = parseOperationTypeArg(args, 0);
final Optional<OperationType> operationType = parseOperationTypeArg(args);
if (operationType.isEmpty()) {
plugin.getLocales().getLocale("error_invalid_syntax", getUsage())
.ifPresent(onlineUser::sendMessage);
Expand All @@ -122,7 +122,7 @@ private void handleSetClaimFlag(@NotNull OnlineUser onlineUser, @Nullable Claim
}
plugin.getDatabase().updateClaimWorld(world);

// Send flag list on correct page to indicated the update
// Send flag list on correct page to indicate the update
final double changedIndex = plugin.getOperationListener()
.getRegisteredOperationTypes().stream()
.filter(op -> canManageFlag(onlineUser, op)).toList().indexOf(type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ public interface Executable {

void onExecuted(@NotNull CommandUser executor, @NotNull String[] args);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public String getName() {
if (aliases.isEmpty()) {
throw new IllegalStateException("Primary alias of command node is blank");
}
return aliases.get(0);
return aliases.getFirst();
}

protected Optional<User> resolveUser(@NotNull CommandUser executor, @NotNull String[] args) {
Expand Down Expand Up @@ -150,8 +150,8 @@ protected Optional<Position> parsePositionArgs(@NotNull String[] args, int index
return Optional.empty();
}

protected Optional<OperationType> parseOperationTypeArg(@NotNull String[] args, int index) {
return parseStringArg(args, index).flatMap(arg -> plugin.getOperationListener().getOperationType(arg));
protected Optional<OperationType> parseOperationTypeArg(@NotNull String[] args) {
return parseStringArg(args, 0).flatMap(arg -> plugin.getOperationListener().getOperationType(arg));
}

protected Optional<Long> parseClaimBlocksArg(@NotNull String[] args, int index) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private String getClaimHeaderDetails(@NotNull Claim claim, @NotNull ClaimWorld w
Integer.toString(claim.getRegion().getLongestEdge()),
Integer.toString(claim.getRegion().getShortestEdge()),
Integer.toString(claim.getChildren().size()),
Integer.toString(claim.getTrustedUsers().keySet().size()),
Integer.toString(claim.getTrustedUsers().size()),
claim.getCreationTime().map(t -> t.format(DateTimeFormatter.ISO_LOCAL_DATE)).orElse(na)
).orElse(ownerName);
}
Expand All @@ -88,7 +88,7 @@ private String getChildClaimHeaderDetails(@NotNull Claim claim, @NotNull ClaimWo
Long.toString(claim.getRegion().getSurfaceArea()),
Integer.toString(claim.getRegion().getLongestEdge()),
Integer.toString(claim.getRegion().getShortestEdge()),
Integer.toString(claim.getTrustedUsers().keySet().size()),
Integer.toString(claim.getTrustedUsers().size()),
plugin.getLocales().getRawLocale(String.format("child_claims_inherit_%srestricted",
claim.isInheritParent() ? "un" : "")).orElse(Boolean.toString(claim.isInheritParent())),
claim.getCreationTime().map(t -> t.format(DateTimeFormatter.ISO_LOCAL_DATE)).orElse(na)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,4 @@ default List<String> suggest(@NotNull CommandUser user, @NotNull String[] args)
@Nullable
UUID getGroupOwner(@NotNull OnlineUser user);


}
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,4 @@ public void execute(@NotNull CommandUser executor, @NotNull String[] args) {
});
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public class Locales implements PaginatedListProvider {

protected static final String DEFAULT_LOCALE = "en-gb";

// The raw set of locales loaded from yaml
// The raw set of locales loaded from YAML
Map<String, String> locales = Maps.newTreeMap();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ public static class SentinelSettings {
}
}


@Comment("Claim flags & world settings")
private ClaimSettings claims = new ClaimSettings();

Expand Down Expand Up @@ -600,7 +599,6 @@ public static class HuskTownsHookSettings {
private boolean enabled = true;
}


private EconomyHookSettings economy = new EconomyHookSettings();

@Getter
Expand Down Expand Up @@ -645,7 +643,6 @@ public static class GeyserSettings {
private boolean enabled = true;
}


private MapHookSettings map = new MapHookSettings();

@Getter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class TrustLevels {
""";

private List<TrustLevel> trustLevels = Lists.newArrayList(
// Permission trust (manage trustees, make sub-divisions, etc.)
// Permission trust (manage trustees, make subdivisions, etc.)
TrustLevel.builder()
.id("manage")
.weight(400)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ public static List<Migration> getOrderedMigrations() {
}

public static int getLatestVersion() {
return getOrderedMigrations().get(getOrderedMigrations().size() - 1).getVersion();
return getOrderedMigrations().getLast().getVersion();
}
}

Expand Down
Loading
Loading