Skip to content

Commit

Permalink
Add admin command for modifying flags, close #94
Browse files Browse the repository at this point in the history
  • Loading branch information
WiIIiam278 committed Apr 22, 2024
1 parent 0814944 commit 89cbc1d
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ public class ClaimWorld {
private ConcurrentMap<UUID, String> userCache;
@Expose
@SerializedName("wilderness_flags")
private ArrayList<OperationType> wildernessFlags;
private Set<OperationType> wildernessFlags;

private ClaimWorld(@NotNull HuskClaims plugin) {
this.id = 0;
this.claims = Sets.newCopyOnWriteArraySet();
this.userCache = Maps.newConcurrentMap();
this.wildernessFlags = Lists.newArrayList(plugin.getSettings().getClaims().getWildernessRules());
this.wildernessFlags = Sets.newHashSet(plugin.getSettings().getClaims().getWildernessRules());
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.william278.cloplib.operation.OperationType;
import net.william278.desertwell.about.AboutMenu;
import net.william278.desertwell.util.UpdateChecker;
import net.william278.huskclaims.HuskClaims;
import net.william278.huskclaims.claim.Claim;
import net.william278.huskclaims.claim.ClaimWorld;
import net.william278.huskclaims.config.Locales;
import net.william278.huskclaims.hook.HuskHomesHook;
import net.william278.huskclaims.hook.Importer;
Expand Down Expand Up @@ -54,6 +57,7 @@ public class HuskClaimsCommand extends Command implements TabCompletable {
"about", false,
"help", false,
"teleport", true,
"flags", true,
"logs", true,
"status", true,
"import", true,
Expand Down Expand Up @@ -109,6 +113,7 @@ public void execute(@NotNull CommandUser executor, @NotNull String[] args) {
getCommandList(executor).getNearestValidPage(parseIntArg(args, 1).orElse(1))
);
case "teleport" -> handleTeleportCommand(executor, removeFirstArg(args));
case "flags" -> handleFlagsCommand(executor, removeFirstArg(args));
case "logs" -> handleLogsCommand(executor, removeFirstArg(args));
case "status" -> {
getPlugin().getLocales().getLocale("system_status_header").ifPresent(executor::sendMessage);
Expand Down Expand Up @@ -207,14 +212,14 @@ private void handleLogsCommand(@NotNull CommandUser executor, @NotNull String[]
final Locales locales = plugin.getLocales();
final String userName = user.getUser().getName();
final PaginatedList list = PaginatedList.of(auditLog
.stream().map(
entry -> locales.getRawLocale("audit_log_row",
DateTimeFormatter.ofPattern("dd MMM, yyyy HH:mm").format(entry.timestamp()),
Locales.escapeText(entry.entry().getAction().getFormattedName()),
entry.entry().getUser() != null ? Locales.escapeText(entry.entry().getUser().getName()) : "",
entry.entry().getMessage() != null ? Locales.escapeText(entry.entry().getMessage()) : ""
).orElse("")
).toList(),
.stream().map(
entry -> locales.getRawLocale("audit_log_row",
DateTimeFormatter.ofPattern("dd MMM, yyyy HH:mm").format(entry.timestamp()),
Locales.escapeText(entry.entry().getAction().getFormattedName()),
entry.entry().getUser() != null ? Locales.escapeText(entry.entry().getUser().getName()) : "",
entry.entry().getMessage() != null ? Locales.escapeText(entry.entry().getMessage()) : ""
).orElse("")
).toList(),
locales.getBaseList(ITEMS_PER_LIST_PAGE)
.setItemSeparator("\n").setCommand("/%s logs %s".formatted(getName(), userName))
.setHeaderFormat(locales.getRawLocale("audit_log_header",
Expand All @@ -240,6 +245,68 @@ private void handleTeleportCommand(@NotNull CommandUser executor, @NotNull Strin
);
}

private void handleFlagsCommand(@NotNull CommandUser executor, @NotNull String[] args) {
if (!(executor instanceof OnlineUser online)) {
plugin.getLocales().getLocale("error_invalid_syntax", "/%s flags [flag] <true/false>")
.ifPresent(executor::sendMessage);
return;
}

final Optional<ClaimWorld> optionalWorld = plugin.getClaimWorld(online.getWorld());
if (optionalWorld.isEmpty()) {
plugin.getLocales().getLocale("world_not_claimable")
.ifPresent(online::sendMessage);
return;
}
final ClaimWorld world = optionalWorld.get();
this.handleClaimFlagsCommand(online, world.getClaimAt(online.getPosition()).orElse(null), world, args);
}

private void handleClaimFlagsCommand(@NotNull OnlineUser onlineUser, @Nullable Claim claim,
@NotNull ClaimWorld world, @NotNull String[] args) {
final Optional<OperationType> type = parseOperationTypeArg(args, 0);
if (type.isEmpty()) {
this.sendClaimFlagsList(onlineUser, claim, world);
return;
}

// Parse operation type
final OperationType operationType = type.get();
final boolean value = parseBooleanArg(args, 1).orElse(claim == null
? world.getWildernessFlags().contains(operationType)
: claim.getDefaultFlags().contains(operationType));

// Update flags
final Collection<OperationType> types = claim == null ? world.getWildernessFlags() : claim.getDefaultFlags();
if (value) {
types.add(operationType);
} else {
types.remove(operationType);
}
plugin.getDatabase().updateClaimWorld(world);

// Send flag list to indicated update
this.sendClaimFlagsList(onlineUser, claim, world);
}

private void sendClaimFlagsList(@NotNull OnlineUser onlineUser, @Nullable Claim claim,
@NotNull ClaimWorld world) {
if (claim != null) {
plugin.getLocales().getLocale("claim_flags_header", claim.getOwnerName(world, plugin))
.ifPresent(onlineUser::sendMessage);
} else {
plugin.getLocales().getLocale("claim_flags_header_wilderness", world.getName(plugin))
.ifPresent(onlineUser::sendMessage);
}

onlineUser.sendMessage(plugin.getLocales().format(Arrays.stream(OperationType.values())
.map(op -> plugin.getLocales().getRawLocale("claim_flag_%s"
.formatted((claim == null ? world.getWildernessFlags() : claim.getDefaultFlags())
.contains(op) ? "enabled" : "disabled"),
WordUtils.capitalizeFully(op.name().replaceAll("_", " "))
).orElse(op.name())).collect(Collectors.joining(plugin.getLocales().getListJoiner()))));
}

@NotNull
private PaginatedList getCommandList(@NotNull CommandUser executor) {
final Locales locales = plugin.getLocales();
Expand Down
11 changes: 11 additions & 0 deletions common/src/main/java/net/william278/huskclaims/command/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.google.common.collect.Maps;
import lombok.Getter;
import lombok.Setter;
import net.william278.cloplib.operation.OperationType;
import net.william278.huskclaims.HuskClaims;
import net.william278.huskclaims.position.Position;
import net.william278.huskclaims.position.World;
Expand Down Expand Up @@ -149,6 +150,16 @@ 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 -> {
try {
return Optional.of(OperationType.valueOf(arg.toUpperCase(Locale.ENGLISH)));
} catch (IllegalArgumentException e) {
return Optional.empty();
}
});
}

protected Optional<Integer> parseIntArg(@NotNull String[] args, int index) {
return parseStringArg(args, index).flatMap(arg -> {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public static class SentinelSettings {
@Configuration
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class ClaimSettings {
@Comment("Default flags for regular claims")
@Comment("Default flags for new regular claims")
private List<OperationType> defaultFlags = List.of(
OperationType.PLAYER_DAMAGE_MONSTER,
OperationType.EXPLOSION_DAMAGE_ENTITY,
Expand All @@ -178,7 +178,7 @@ public static class ClaimSettings {
OperationType.PASSIVE_MOB_SPAWN
);

@Comment("Default flags for admin claims")
@Comment("Default flags for new admin claims")
private List<OperationType> adminFlags = List.of(
OperationType.PLAYER_DAMAGE_MONSTER,
OperationType.EXPLOSION_DAMAGE_ENTITY,
Expand All @@ -192,7 +192,8 @@ public static class ClaimSettings {
ClaimingMode.values() // Allow all claiming modes
);

@Comment("Default flags for the wilderness (outside claims)")
@Comment({"Default flags for the wilderness (outside claims)",
"To modify existing worlds, use /huskclaims flag <flag> <true/false> while standing outside a claim."})
private List<OperationType> wildernessRules = List.of(
OperationType.values() // Allow all operation types
);
Expand Down
4 changes: 4 additions & 0 deletions common/src/main/resources/locales/en-gb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ locales:
command_list_row: '[%1%](#00fb9a italic show_text=&#00fb9a&%1%\n&7%2% suggest_command=%1%) [%3%](gray show_text=&7%4% suggest_command=%1%)'
audit_log_header: '[HuskClaims](#00fb9a bold) [| Audit Logs for %1%:](#00fb9a)\n'
audit_log_row: '[%1%](gray) [%2%](#00fb9a) [%3%](#ff304f) [%4%](gray)'
claim_flags_header: '[Claim flags for %1%''s claim:](#00fb9a)\n'
claim_flags_wilderness_header: '[Claim flags for the wilderness of world %1%:](#00fb9a)\n'
claim_flag_enabled: '[%1%](#00fb9a show_text=&7Click to disable run_command=/huskclaims flags %1% false)'
claim_flag_disabled: '[%1%](#ff7e5e show_text=&7Click to enable run_command=/huskclaims flags %1% true)'
untrust_command_description: 'Revoke a trustee''s claim access.'
trustlist_command_description: 'View a list of claim trustees.'
group_command_description: 'Create and manage groups of players.'
Expand Down
4 changes: 4 additions & 0 deletions common/src/main/resources/locales/ro-ro.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ locales:
command_list_row: '[%1%](#00fb9a italic show_text=&#00fb9a&%1%\n&7%2% suggest_command=%1%) [%3%](gray show_text=&7%4% suggest_command=%1%)'
audit_log_header: '[HuskClaims](#00fb9a bold) [| Jurnaluri de activitate pentru %1%:](#00fb9a)\n'
audit_log_row: '[%1%](gray) [%2%](#00fb9a) [%3%](#ff304f) [%4%](gray)'
claim_flags_header: '[Claim flags for %1%''s claim:](#00fb9a)\n'
claim_flags_wilderness_header: '[Claim flags for the wilderness of world %1%:](#00fb9a)\n'
claim_flag_enabled: '[%1%](#00fb9a show_text=&7Click to disable run_command=/huskclaims flags %1% false)'
claim_flag_disabled: '[%1%](#ff7e5e show_text=&7Click to enable run_command=/huskclaims flags %1% true)'
untrust_command_description: 'Revocă accesul revendicării unui administrator.'
trustlist_command_description: 'Vezi lista de administratori ale revendicării.'
group_command_description: 'Creează și gestionează grupuri de jucători.'
Expand Down
4 changes: 4 additions & 0 deletions common/src/main/resources/locales/ru-ru.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ locales:
command_list_row: '[%1%](#00fb9a italic show_text=&#00fb9a&%1%\n&7%2% suggest_command=%1%) [%3%](gray show_text=&7%4% suggest_command=%1%)'
audit_log_header: '[HuskClaims](#00fb9a bold) [| Логи Аудита для игрока %1%:](#00fb9a)\n'
audit_log_row: '[%1%](gray) [%2%](#00fb9a) [%3%](#ff304f) [%4%](gray)'
claim_flags_header: '[Claim flags for %1%''s claim:](#00fb9a)\n'
claim_flags_wilderness_header: '[Claim flags for the wilderness of world %1%:](#00fb9a)\n'
claim_flag_enabled: '[%1%](#00fb9a show_text=&7Click to disable run_command=/huskclaims flags %1% false)'
claim_flag_disabled: '[%1%](#ff7e5e show_text=&7Click to enable run_command=/huskclaims flags %1% true)'
untrust_command_description: 'Отозвать право доверия у игрока.'
trustlist_command_description: 'Показать список доверенных лиц.'
group_command_description: 'Создание и управление группами игроков и их прав.'
Expand Down
4 changes: 4 additions & 0 deletions common/src/main/resources/locales/zh-cn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ locales:
command_list_row: '[%1%](#00fb9a italic show_text=&#00fb9a&%1%\n&7%2% suggest_command=%1%) [%3%](gray show_text=&7%4% suggest_command=%1%)'
audit_log_header: '[HuskClaims](#00fb9a bold) [| %1% 的审核日志:](#00fb9a)\n'
audit_log_row: '[%1%](gray) [%2%](#00fb9a) [%3%](#ff304f) [%4%](gray)'
claim_flags_header: '[Claim flags for %1%''s claim:](#00fb9a)\n'
claim_flags_wilderness_header: '[Claim flags for the wilderness of world %1%:](#00fb9a)\n'
claim_flag_enabled: '[%1%](#00fb9a show_text=&7Click to disable run_command=/huskclaims flags %1% false)'
claim_flag_disabled: '[%1%](#ff7e5e show_text=&7Click to enable run_command=/huskclaims flags %1% true)'
untrust_command_description: '撤销信任者的领地访问权限.'
trustlist_command_description: '查看领地信任者列表.'
group_command_description: '创建和管理玩家组.'
Expand Down
6 changes: 6 additions & 0 deletions docs/Commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,12 @@ This is a table of HuskClaims commands, how to use them, their required permissi
<td><code>huskclaims.command.huskclaims.teleport</code></td>
<td align="center">❌</td>
</tr>
<tr>
<td><code>/huskclaims flags [flag] [true/false]</code></td>
<td>Set the value of a flag in a claim, or the world's wilderness.</td>
<td><code>huskclaims.command.huskclaims.flags</code></td>
<td align="center">❌</td>
</tr>
<tr>
<td><code>/huskclaims logs &lt;username&gt;</code></td>
<td>View audit logs for a player, such as claim block transaction receipts.</td>
Expand Down
12 changes: 11 additions & 1 deletion docs/Operation-Groups.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,14 @@ operation_groups:
```
</details>
Whether an Operation Group is the default in a claim depends on whether the `allowed_operations` of the group are also present in the `default_flags` list in the config.
Whether an Operation Group is the default in a claim depends on whether the `allowed_operations` of the group are also present in the `default_flags` list in the config.

## Fine-Grained Admin Flag Management
> **Note:** This is a powerful command, only intended for use by admins. Create operation group commands to let users manage flags in a user-friendly way within claims.

The `/huskclaims flags` admin command exposes a way for admins to fine-tune the allowed operation group settings within a claim. Run the command to bring up a list of enabled operation types in the claim you are standing in.

To modify a flag while standing in a claim, use `/huskclaims flags [operation_type] <true/false>`, or click the operation type in the list to toggle it.

### Adjusting the flags outside of claims
You can also can adjust the value of flags outside of claims (the "Wilderness") by using `/huskclaims flags` while standing outside a claim.

0 comments on commit 89cbc1d

Please sign in to comment.