Committing incomplete work on the WIP WastelandModTools.

master
James T. Martin 2020-11-23 13:45:03 -08:00
parent e4ec1995da
commit f7f37a18f8
Signed by: james
GPG Key ID: 4B7F3DA9351E577C
47 changed files with 1407 additions and 151 deletions

25
modtools/build.gradle Normal file
View File

@ -0,0 +1,25 @@
plugins {
id 'java-library'
}
group 'me.jamestmartin'
version '0.1.0'
sourceCompatibility = 8
repositories {
mavenCentral()
maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' }
maven {
url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
content {
includeGroup 'org.bukkit'
includeGroup 'org.spigotmc'
}
}
}
dependencies {
compileOnly 'org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT'
}

View File

@ -6,6 +6,8 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import me.jamestmartin.wasteland.manual.config.ManualSection;
public class CommandManual implements CommandExecutor {
private final String manualName;
private final ManualSection manual;

View File

@ -2,9 +2,9 @@ package me.jamestmartin.wasteland.manual;
import org.bukkit.plugin.java.JavaPlugin;
import me.jamestmartin.wasteland.Substate;
import me.jamestmartin.wasteland.manual.config.ManualConfig;
public class ManualState implements Substate {
public class ManualState {
private final CommandManual commandRules;
private final CommandManual commandFaq;
@ -13,13 +13,11 @@ public class ManualState implements Substate {
this.commandFaq = new CommandManual("faq", config.getFaq());
}
@Override
public void register(JavaPlugin plugin) {
plugin.getCommand("rules").setExecutor(commandRules);
plugin.getCommand("faq").setExecutor(commandFaq);
}
@Override
public void unregister(JavaPlugin plugin) {
plugin.getCommand("rules").setExecutor(null);
plugin.getCommand("faq").setExecutor(null);

View File

@ -1,4 +1,4 @@
package me.jamestmartin.wasteland.manual;
package me.jamestmartin.wasteland.manual.config;
public class ManualConfig {
private final ManualSection rules;

View File

@ -0,0 +1,49 @@
package me.jamestmartin.wasteland.manual.config;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.bukkit.configuration.ConfigurationSection;
public class ManualConfigParser {
public static ManualConfig parse(ConfigurationSection c) {
ManualSection rules = new ManualSection(
"The Server Rules",
parseManualSectionList(castToSectionList(c.getMapList("rules"))));
ManualSection faq = new ManualSection(
"Frequently Asked Questions",
parseManualSectionList(castToSectionList(c.getMapList("faq"))));
return new ManualConfig(rules, faq);
}
private static ManualSection parseManualSection(Map<?, ?> c) {
String summary = (String) c.get("summary");
Optional<String> details = Optional.ofNullable((String) c.get("details"));
List<ManualSection> subsections = parseManualSectionList(castToSectionList(c.get("sections")));
return new ManualSection(summary, details, subsections);
}
private static List<Map<?, ?>> castToSectionList(Object x) {
if (x == null) {
return null;
}
return ((List<?>) x).stream().map(xx -> (Map<?, ?>) xx).collect(Collectors.toUnmodifiableList());
}
public static List<ManualSection> parseManualSectionList(List<Map<?, ?>> list) {
List<ManualSection> sections = new ArrayList<>();
if (list == null) {
return sections;
}
for (Map<?, ?> section : list) {
sections.add(parseManualSection(section));
}
return sections;
}
}

View File

@ -1,4 +1,4 @@
package me.jamestmartin.wasteland.manual;
package me.jamestmartin.wasteland.manual.config;
import java.util.List;
import java.util.Optional;

View File

@ -0,0 +1,96 @@
package me.jamestmartin.wasteland.modtools;
import org.bukkit.plugin.java.JavaPlugin;
import me.jamestmartin.wasteland.manual.ManualState;
import me.jamestmartin.wasteland.modtools.commands.CommandBan;
import me.jamestmartin.wasteland.modtools.commands.CommandBans;
import me.jamestmartin.wasteland.modtools.commands.CommandInfractions;
import me.jamestmartin.wasteland.modtools.commands.CommandKick;
import me.jamestmartin.wasteland.modtools.commands.CommandMute;
import me.jamestmartin.wasteland.modtools.commands.CommandMutes;
import me.jamestmartin.wasteland.modtools.commands.CommandUnban;
import me.jamestmartin.wasteland.modtools.commands.CommandUnmute;
import me.jamestmartin.wasteland.modtools.commands.CommandWarn;
import me.jamestmartin.wasteland.modtools.config.ModToolsConfig;
import me.jamestmartin.wasteland.modtools.infraction.InfractionStore;
import me.jamestmartin.wasteland.modtools.log.CommandModLog;
import me.jamestmartin.wasteland.offlineplayer.CommandLastSeen;
import me.jamestmartin.wasteland.offlineplayer.CommandUUID;
class ModToolsState {
private final ManualState manualState;
private final CommandBan commandBan;
private final CommandBans commandBans;
private final CommandInfractions commandInfractions;
private final CommandKick commandKick;
private final CommandLastSeen commandLastSeen;
private final CommandModLog commandModLog;
private final CommandMute commandMute;
private final CommandMutes commandMutes;
private final CommandUnban commandUnban;
private final CommandUnmute commandUnmute;
private final CommandUUID commandUUID;
private final CommandWarn commandWarn;
public ModToolsState(ModToolsConfig config) {
this.manualState = new ManualState(config.getManuals());
// TODO
InfractionStore store = null;
this.commandBan = new CommandBan(store, config.getDurations().getBansConfig());
this.commandBans = new CommandBans();
this.commandInfractions = new CommandInfractions();
this.commandKick = new CommandKick(store);
this.commandLastSeen = new CommandLastSeen();
this.commandModLog = new CommandModLog();
this.commandMute = new CommandMute(store, config.getDurations().getMutesConfig());
this.commandMutes = new CommandMutes();
this.commandUnban = new CommandUnban();
this.commandUnmute = new CommandUnmute();
this.commandUUID = new CommandUUID();
this.commandWarn = new CommandWarn(store);
}
public void register(JavaPlugin plugin) {
manualState.register(plugin);
plugin.getCommand("ban").setExecutor(commandBan);
plugin.getCommand("bans").setExecutor(commandBans);
plugin.getCommand("infractions").setExecutor(commandInfractions);
plugin.getCommand("kick").setExecutor(commandKick);
plugin.getCommand("lastseen").setExecutor(commandLastSeen);
plugin.getCommand("modlog").setExecutor(commandModLog);
plugin.getCommand("mute").setExecutor(commandMute);
plugin.getCommand("mutes").setExecutor(commandMutes);
plugin.getCommand("unban").setExecutor(commandUnban);
plugin.getCommand("unmute").setExecutor(commandUnmute);
plugin.getCommand("uuid").setExecutor(commandUUID);
plugin.getCommand("warn").setExecutor(commandWarn);
}
public void unregister(JavaPlugin plugin) {
manualState.unregister(plugin);
plugin.getCommand("ban").setExecutor(null);
plugin.getCommand("bans").setExecutor(null);
plugin.getCommand("infractions").setExecutor(null);
plugin.getCommand("kick").setExecutor(null);
plugin.getCommand("lastseen").setExecutor(null);
plugin.getCommand("modlog").setExecutor(null);
plugin.getCommand("mute").setExecutor(null);
plugin.getCommand("mutes").setExecutor(null);
plugin.getCommand("unban").setExecutor(null);
plugin.getCommand("unmute").setExecutor(null);
plugin.getCommand("uuid").setExecutor(null);
plugin.getCommand("warn").setExecutor(null);
disable(plugin);
}
public void disable(JavaPlugin plugin) {
}
}

View File

@ -0,0 +1,53 @@
package me.jamestmartin.wasteland.modtools;
import org.bukkit.plugin.java.JavaPlugin;
import me.jamestmartin.wasteland.modtools.commands.CommandWMT;
import me.jamestmartin.wasteland.modtools.config.ConfigParser;
public class WastelandModTools extends JavaPlugin {
private static WastelandModTools instance;
private ModToolsState state;
public static WastelandModTools getInstance() {
return instance;
}
@Override
public void onEnable() {
instance = this;
saveDefaultConfig();
load();
// This command doesn't depend on any config,
// so we don't need to register/unregister it when we reload.
getCommand("wmt").setExecutor(new CommandWMT(this));
}
@Override
public void onDisable() {
state.disable(this);
instance = null;
}
private void load() {
state = new ModToolsState(ConfigParser.parse(getConfig()));
state.register(this);
}
private void unload() {
state.unregister(this);
state = null;
}
public void reload() {
getLogger().info("Reloading...");
saveDefaultConfig();
reloadConfig();
unload();
load();
getLogger().info("Done.");
}
}

View File

@ -0,0 +1,29 @@
package me.jamestmartin.wasteland.modtools.commands;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.jamestmartin.wasteland.modtools.config.DurationsConfig;
import me.jamestmartin.wasteland.modtools.infraction.Infraction;
import me.jamestmartin.wasteland.modtools.infraction.InfractionStore;
import me.jamestmartin.wasteland.modtools.infraction.InfractionType;
public class CommandBan extends CommandIssueInfraction {
public CommandBan(InfractionStore store, DurationsConfig durations) {
super(store, durations);
}
@Override
protected InfractionType getType() {
return InfractionType.BAN;
}
@Override
protected void applyInfraction(CommandSender sender, Infraction infraction) {
Player recipient = infraction.getRecipient().getPlayer();
if (recipient != null) {
recipient.kickPlayer(infraction.getMessage());
}
sender.sendMessage(infraction.getRecipient().getName() + " has been banned for " + infraction.getDuration().toStringLong() + ".");
}
}

View File

@ -0,0 +1,15 @@
package me.jamestmartin.wasteland.modtools.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class CommandBans implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -0,0 +1,15 @@
package me.jamestmartin.wasteland.modtools.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class CommandInfractions implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -0,0 +1,72 @@
package me.jamestmartin.wasteland.modtools.commands;
import java.util.Optional;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.jamestmartin.wasteland.modtools.config.DurationsConfig;
import me.jamestmartin.wasteland.modtools.infraction.Duration;
import me.jamestmartin.wasteland.modtools.infraction.Infraction;
import me.jamestmartin.wasteland.modtools.infraction.InfractionStore;
import me.jamestmartin.wasteland.modtools.infraction.InfractionType;
abstract class CommandIssueInfraction implements CommandExecutor {
protected final InfractionStore store;
protected final DurationsConfig durations;
public CommandIssueInfraction(InfractionStore store, DurationsConfig durations) {
this.store = store;
this.durations = durations;
}
public CommandIssueInfraction(InfractionStore store) {
if (getType().hasDuration()) {
throw new IllegalArgumentException("Must pass durations for infraction type which has duration");
}
this.store = store;
this.durations = null;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Duration maxDuration = durations != null ? durations.getMaximumBanDuration(sender) : Duration.INFINITY;
if (maxDuration.getSeconds().map(x -> x == 0).orElse(false)) {
sender.sendMessage("You have permission to issue infractions, but can only issue infractions of duration 0!");
sender.sendMessage("No infraction will be issued.");
return true;
}
Player issuer = sender instanceof Player ? (Player) sender : null;
Optional<Infraction> maybe = parseArgs(getType(), issuer, args);
if (maybe.isEmpty()) {
// TOOD: better error messages
sender.sendMessage("Invalid syntax.");
return false;
}
Infraction infraction = maybe.get();
if (infraction.getDuration().compareTo(maxDuration) == 1) {
sender.sendMessage("You are not allowed you issue an infraction of duration " + infraction.getDuration() + ".");
sender.sendMessage("The maximum infraction duration you can issue is " + maxDuration + ".");
sender.sendMessage("No infraction will be issued.");
return true;
}
applyInfraction(sender, infraction);
store.addInfraction(infraction);
return false;
}
protected abstract InfractionType getType();
protected abstract void applyInfraction(CommandSender sender, Infraction infraction);
private static Optional<Infraction> parseArgs(InfractionType type, OfflinePlayer issuer, String[] args) {
// TODO
return null;
}
}

View File

@ -0,0 +1,31 @@
package me.jamestmartin.wasteland.modtools.commands;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.jamestmartin.wasteland.modtools.infraction.Infraction;
import me.jamestmartin.wasteland.modtools.infraction.InfractionStore;
import me.jamestmartin.wasteland.modtools.infraction.InfractionType;
public class CommandKick extends CommandIssueInfraction {
public CommandKick(InfractionStore store) {
super(store);
}
@Override
protected InfractionType getType() {
return InfractionType.KICK;
}
@Override
protected void applyInfraction(CommandSender sender, Infraction infraction) {
Player player = infraction.getRecipient().getPlayer();
if (player == null) {
sender.sendMessage("That player is not online!");
sender.sendMessage("Infraction logged anyway.");
return;
}
player.kickPlayer(infraction.getMessage());
}
}

View File

@ -0,0 +1,30 @@
package me.jamestmartin.wasteland.modtools.commands;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.jamestmartin.wasteland.modtools.config.DurationsConfig;
import me.jamestmartin.wasteland.modtools.infraction.Infraction;
import me.jamestmartin.wasteland.modtools.infraction.InfractionStore;
import me.jamestmartin.wasteland.modtools.infraction.InfractionType;
public class CommandMute extends CommandIssueInfraction {
public CommandMute(InfractionStore store, DurationsConfig durations) {
super(store, durations);
}
@Override
protected InfractionType getType() {
return InfractionType.MUTE;
}
@Override
protected void applyInfraction(CommandSender sender, Infraction infraction) {
Player player = infraction.getRecipient().getPlayer();
if (player != null) {
player.sendMessage(infraction.getMessage());
}
sender.sendMessage(infraction.getRecipient().getName() + " has been muted for " + infraction.getDuration().toStringLong() + ".");
}
}

View File

@ -0,0 +1,15 @@
package me.jamestmartin.wasteland.modtools.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class CommandMutes implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -0,0 +1,46 @@
package me.jamestmartin.wasteland.modtools.commands;
import java.util.Optional;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.jamestmartin.wasteland.modtools.infraction.Infraction;
import me.jamestmartin.wasteland.modtools.infraction.InfractionStore;
import me.jamestmartin.wasteland.modtools.infraction.InfractionType;
public abstract class CommandRemoveInfraction implements CommandExecutor {
protected final InfractionStore store;
public CommandRemoveInfraction(InfractionStore store) {
this.store = store;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Player issuer = sender instanceof Player ? (Player) sender : null;
Optional<Infraction> maybe = parseArgs(getType(), issuer, args);
if (maybe.isEmpty()) {
// TOOD: better error messages
sender.sendMessage("Invalid syntax.");
return false;
}
Infraction infraction = maybe.get();
applyInfraction(sender, infraction);
store.addInfraction(infraction);
return false;
}
protected abstract InfractionType getType();
protected abstract void applyInfraction(CommandSender sender, Infraction infraction);
private static Optional<Infraction> parseArgs(InfractionType type, OfflinePlayer issuer, String[] args) {
// TODO
return null;
}
}

View File

@ -0,0 +1,15 @@
package me.jamestmartin.wasteland.modtools.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class CommandUnban implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -0,0 +1,15 @@
package me.jamestmartin.wasteland.modtools.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class CommandUnmute implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -0,0 +1,44 @@
package me.jamestmartin.wasteland.modtools.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import me.jamestmartin.wasteland.modtools.WastelandModTools;
public class CommandWMT implements CommandExecutor {
private final WastelandModTools instance;
public CommandWMT(WastelandModTools instance) {
this.instance = instance;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length < 1) {
sender.sendMessage("Not enough arguments.");
return false;
}
if (args.length > 1) {
sender.sendMessage("Too many arguments.");
return false;
}
if (!args[0].equals("reload")) {
sender.sendMessage("Unknown subcommand: " + args[0]);
return false;
}
if (!sender.hasPermission("wasteland.modtools.reload")) {
sender.sendMessage("You do not have permission to reload Wasteland ModTools.");
}
sender.sendMessage("Reloading...");
instance.reload();
sender.sendMessage("Done.");
return true;
}
}

View File

@ -0,0 +1,29 @@
package me.jamestmartin.wasteland.modtools.commands;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.jamestmartin.wasteland.modtools.infraction.Infraction;
import me.jamestmartin.wasteland.modtools.infraction.InfractionStore;
import me.jamestmartin.wasteland.modtools.infraction.InfractionType;
public class CommandWarn extends CommandIssueInfraction {
public CommandWarn(InfractionStore store) {
super(store);
}
@Override
protected InfractionType getType() {
return InfractionType.WARN;
}
@Override
protected void applyInfraction(CommandSender sender, Infraction infraction) {
Player player = infraction.getRecipient().getPlayer();
if (player != null) {
player.sendMessage(infraction.getMessage());
}
sender.sendMessage(infraction.getRecipient().getName() + " has been warned.");
}
}

View File

@ -0,0 +1,48 @@
package me.jamestmartin.wasteland.modtools.config;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.configuration.ConfigurationSection;
import me.jamestmartin.wasteland.manual.config.ManualConfig;
import me.jamestmartin.wasteland.manual.config.ManualConfigParser;
import me.jamestmartin.wasteland.modtools.infraction.Duration;
public class ConfigParser {
public static ModToolsConfig parse(ConfigurationSection c) {
ManualConfig manualConfig = ManualConfigParser.parse(c.getConfigurationSection("manuals"));
DurationsConfigs durationsConfig = parseDurationsConfig(c.getConfigurationSection("permissions"));
return new ModToolsConfig(manualConfig, durationsConfig);
}
private static DurationsConfigs parseDurationsConfig(ConfigurationSection c) {
Map<String, Duration> maximumBans = new HashMap<>();
Map<String, Duration> maximumMutes = new HashMap<>();
if (c.isString("ban")) {
maximumBans.put("", Duration.parse(c.getString("ban")).get());
}
if (c.isString("mute")) {
maximumMutes.put("", Duration.parse(c.getString("mute")).get());
}
for (String key : c.getKeys(false)) {
if (c.isString(key)) {
continue;
}
DurationsConfigs sub = parseDurationsConfig(c.getConfigurationSection(key));
for (Entry<String, Duration> ban : sub.getBansConfig().getMaximumDurations().entrySet()) {
maximumBans.put(key + "." + ban.getKey(), ban.getValue());
}
for (Entry<String, Duration> mute : sub.getMutesConfig().getMaximumDurations().entrySet()) {
maximumMutes.put(key + "." + mute.getKey(), mute.getValue());
}
}
return new DurationsConfigs(new DurationsConfig(maximumBans), new DurationsConfig(maximumMutes));
}
}

View File

@ -0,0 +1,29 @@
package me.jamestmartin.wasteland.modtools.config;
import java.util.Map;
import org.bukkit.command.CommandSender;
import me.jamestmartin.wasteland.modtools.infraction.Duration;
public class DurationsConfig {
private final Map<String, Duration> maxima;
public DurationsConfig(Map<String, Duration> maxima) {
this.maxima = maxima;
}
public Map<String, Duration> getMaximumDurations() {
return maxima;
}
public Duration getMaximumBanDuration(CommandSender moderator) {
Duration duration = maxima.getOrDefault("default", Duration.ZERO);
for (String perm : maxima.keySet()) {
if (moderator.hasPermission(perm)) {
duration = duration.max(maxima.get(perm));
}
}
return duration;
}
}

View File

@ -0,0 +1,19 @@
package me.jamestmartin.wasteland.modtools.config;
public class DurationsConfigs {
private final DurationsConfig bansConfig;
private final DurationsConfig mutesConfig;
public DurationsConfigs(DurationsConfig bansConfig, DurationsConfig mutesConfig) {
this.bansConfig = bansConfig;
this.mutesConfig = mutesConfig;
}
public DurationsConfig getBansConfig() {
return bansConfig;
}
public DurationsConfig getMutesConfig() {
return mutesConfig;
}
}

View File

@ -0,0 +1,21 @@
package me.jamestmartin.wasteland.modtools.config;
import me.jamestmartin.wasteland.manual.config.ManualConfig;
public class ModToolsConfig {
private final ManualConfig manuals;
private final DurationsConfigs durations;
public ModToolsConfig(ManualConfig manuals, DurationsConfigs durations) {
this.manuals = manuals;
this.durations = durations;
}
public ManualConfig getManuals() {
return manuals;
}
public DurationsConfigs getDurations() {
return durations;
}
}

View File

@ -0,0 +1,173 @@
package me.jamestmartin.wasteland.modtools.infraction;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public class Duration implements Comparable<Duration> {
public static final Duration ZERO = new Duration(0);
public static final Duration INFINITY = new Duration();
/** Durations of "none" are infinite. */
private final Optional<Long> seconds;
private Duration() {
this.seconds = Optional.empty();
}
private Duration(Optional<Long> seconds) {
this.seconds = seconds;
}
public Duration(long seconds) {
this.seconds = Optional.of(seconds);
}
public Optional<Long> getSeconds() {
return seconds;
}
public Duration max(Duration other) {
return new Duration(this.seconds.flatMap(x -> other.seconds.map(y -> Math.max(x, y))));
}
public static Optional<Duration> parse(String str) {
if (str.equals("0")) {
return Optional.of(ZERO);
}
if (str.equals("forever")) {
return Optional.of(INFINITY);
}
return DurationParts.parse(str).map(DurationParts::toDuration);
}
private Optional<DurationParts> toParts() {
if (seconds.isEmpty()) {
return Optional.empty();
}
long secs = seconds.get();
// Find the greatest prefix that gives an exact value.
List<DurationSuffix> suffixes = List.of(DurationSuffix.values());
Collections.reverse(suffixes);
DurationSuffix s = null;
for (DurationSuffix suffix : suffixes) {
if (secs % suffix.getSeconds() == 0) {
s = suffix;
}
}
return Optional.of(new DurationParts(secs / s.getSeconds(), s));
}
@Override
public String toString() {
return toParts().map(DurationParts::toString).orElse("forever");
}
public String toStringLong() {
return toParts().map(DurationParts::toStringLong).orElse("forever");
}
private static class DurationParts {
public final long value;
public final DurationSuffix suffix;
public DurationParts(long value, DurationSuffix suffix) {
this.value = value;
this.suffix = suffix;
}
public Duration toDuration() {
return new Duration(value * suffix.getSeconds());
}
@Override
public String toString() {
return value + suffix.toString();
}
public String toStringLong() {
return value + " " + suffix.toStingLong();
}
public static Optional<DurationParts> parse(String str) {
if (str.length() < 2) {
return Optional.empty();
}
Optional<DurationSuffix> suffix = DurationSuffix.fromChar(str.charAt(str.length() - 1));
if (suffix.isEmpty()) {
return Optional.empty();
}
String valueStr = str.substring(0, str.length() - 1);
if (!valueStr.matches("\\d+")) {
return Optional.empty();
}
return Optional.of(new DurationParts(Long.parseLong(valueStr), suffix.get()));
}
}
private static enum DurationSuffix {
SECONDS('s', "seconds", 1),
MINUTES('m', "minutes", 60),
HOURS('h', "hours", 3600),
DAYS('d', "days", 86400),
WEEKS('w', "weeks", 604800),
MONTHS('M', "months", 2628000),
YEARS('y', "years", 31540000);
private final char character;
private final String longName;
private final long seconds;
private DurationSuffix(char character, String longName, long seconds) {
this.character = character;
this.longName = longName;
this.seconds = seconds;
}
public long getSeconds() {
return seconds;
}
public char toChar() {
return character;
}
@Override
public String toString() {
return String.valueOf(toChar());
}
public String toStingLong() {
return longName;
}
public static Optional<DurationSuffix> fromChar(char c) {
for (DurationSuffix suffix : DurationSuffix.values()) {
if (suffix.character == c) {
return Optional.of(suffix);
}
}
return Optional.empty();
}
}
@Override
public int compareTo(Duration other) {
if (getSeconds().isEmpty() && other.getSeconds().isEmpty()) {
return 0;
}
if (getSeconds().isEmpty()) {
return 1;
}
if (other.getSeconds().isEmpty()) {
return -1;
}
return Long.compare(getSeconds().get(), other.getSeconds().get());
}
}

View File

@ -0,0 +1,58 @@
package me.jamestmartin.wasteland.modtools.infraction;
import java.util.Date;
import org.bukkit.OfflinePlayer;
public class Infraction {
private final InfractionType type;
private final OfflinePlayer issuer;
private final OfflinePlayer recipient;
private final Date issued;
private final Duration duration;
private final String rule;
private final String reason;
public Infraction(InfractionType type, OfflinePlayer issuer, OfflinePlayer recipient, Date issued, Duration duration, String rule, String reason) {
this.type = type;
this.issuer = issuer;
this.recipient = recipient;
this.issued = issued;
this.duration = duration;
this.rule = rule;
this.reason = reason;
}
public InfractionType getType() {
return type;
}
public OfflinePlayer getIssuer() {
return issuer;
}
public OfflinePlayer getRecipient() {
return recipient;
}
public Date getIssued() {
return issued;
}
public Duration getDuration() {
return duration;
}
public String getRule() {
return rule;
}
public String getReason() {
return reason;
}
public String getMessage() {
// TODO
return null;
}
}

View File

@ -0,0 +1,25 @@
package me.jamestmartin.wasteland.modtools.infraction;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
public interface InfractionProvider {
Set<Infraction> getActiveInfractions(Optional<UUID> player, Optional<InfractionType> type);
default Set<Infraction> getActiveInfractions() {
return getActiveInfractions(Optional.empty(), Optional.empty());
}
default Set<Infraction> getActiveInfractions(UUID player) {
return getActiveInfractions(Optional.of(player), Optional.empty());
}
default Set<Infraction> getActiveInfractions(UUID player, InfractionType type) {
return getActiveInfractions(Optional.of(player), Optional.of(type));
}
default Set<Infraction> getActiveInfractions(InfractionType type) {
return getActiveInfractions(Optional.empty(), Optional.of(type));
}
}

View File

@ -0,0 +1,8 @@
package me.jamestmartin.wasteland.modtools.infraction;
import org.bukkit.OfflinePlayer;
public interface InfractionStore extends InfractionProvider {
void addInfraction(Infraction infraction);
void removeInfractions(OfflinePlayer player, InfractionType type);
}

View File

@ -0,0 +1,18 @@
package me.jamestmartin.wasteland.modtools.infraction;
public enum InfractionType {
BAN(true),
KICK(false),
MUTE(true),
WARN(false);
private final boolean hasduration;
private InfractionType(boolean hasDuration) {
this.hasduration = hasDuration;
}
public boolean hasDuration() {
return hasduration;
}
}

View File

@ -0,0 +1,15 @@
package me.jamestmartin.wasteland.modtools.log;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class CommandModLog implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -0,0 +1,67 @@
package me.jamestmartin.wasteland.modtools.log;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import me.jamestmartin.wasteland.modtools.infraction.Duration;
import me.jamestmartin.wasteland.modtools.infraction.Infraction;
import me.jamestmartin.wasteland.modtools.infraction.InfractionType;
public interface ModLogProvider {
Set<Infraction> getInfractions(
Duration duration,
Optional<UUID> issuer,
Optional<UUID> recipient,
Optional<InfractionType> type
);
default Set<Infraction> getInfractions() {
return getInfractions(Duration.INFINITY);
}
default Set<Infraction> getInfractions(InfractionType type) {
return getInfractions(Duration.INFINITY, type);
}
default Set<Infraction> getInfractions(Duration duration) {
return getInfractions(duration, Optional.empty(), Optional.empty(), Optional.empty());
}
default Set<Infraction> getInfractions(Duration duration, InfractionType type) {
return getInfractions(duration, Optional.empty(), Optional.empty(), Optional.of(type));
}
default Set<Infraction> getInfractionsIssuedTo(UUID player) {
return getInfractionsIssuedTo(Duration.INFINITY, player);
}
default Set<Infraction> getInfractionsIssuedTo(UUID player, InfractionType type) {
return getInfractionsIssuedTo(Duration.INFINITY, player, type);
}
default Set<Infraction> getInfractionsIssuedTo(Duration duration, UUID player) {
return getInfractions(duration, Optional.empty(), Optional.of(player), Optional.empty());
}
default Set<Infraction> getInfractionsIssuedTo(Duration duration, UUID player, InfractionType type) {
return getInfractions(duration, Optional.empty(), Optional.of(player), Optional.of(type));
}
default Set<Infraction> getInfractionsIssuedBy(UUID player) {
return getInfractionsIssuedBy(Duration.INFINITY, player);
}
default Set<Infraction> getInfractionsIssuedBy(UUID player, InfractionType type) {
return getInfractionsIssuedBy(Duration.INFINITY, player, type);
}
default Set<Infraction> getInfractionsIssuedBy(Duration duration, UUID player) {
return getInfractions(duration, Optional.of(player), Optional.empty(), Optional.empty());
}
default Set<Infraction> getInfractionsIssuedBy(Duration duration, UUID player, InfractionType type) {
return getInfractions(duration, Optional.of(player), Optional.empty(), Optional.of(type));
}
}

View File

@ -0,0 +1,7 @@
package me.jamestmartin.wasteland.modtools.log;
import me.jamestmartin.wasteland.modtools.infraction.Infraction;
public interface ModLogStore extends ModLogProvider {
void addInfraction(Infraction infraction);
}

View File

@ -0,0 +1,15 @@
package me.jamestmartin.wasteland.offlineplayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class CommandLastSeen implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -0,0 +1,15 @@
package me.jamestmartin.wasteland.offlineplayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class CommandUUID implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -0,0 +1,11 @@
package me.jamestmartin.wasteland.offlineplayer;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
public interface OfflinePlayerProvider {
Map<UUID, Date> getNameUUIDs(String playerName);
Date getFirstSeen(UUID player);
Date getLastSeen(UUID player);
}

View File

@ -0,0 +1,7 @@
package me.jamestmartin.wasteland.offlineplayer;
import org.bukkit.entity.Player;
public interface OfflinePlayerStore extends OfflinePlayerProvider {
void logPlayer(Player player);
}

View File

@ -0,0 +1,69 @@
manuals:
rules:
- summary: Be civil and respectful.
sections:
- summary: If you start getting angry or frustrated, take a break!
- summary: Do not harass other players.
- summary: Do not use slurs.
- summary: Do not advertise.
- summary: Do not spam.
- summary: Avoid excessive swearing.
details: 'What is "excessive" is determined by moderator discretion.'
- summary: Be independent and mature.
sections:
- summary: This is a server intended for adults.
details: You will not be banned for being <16 per se, but acting like a child will get you banned no matter how old you are.
- summary: RTFM (Read The Field Manual).
details: Try to answer questions for yourself (e.g. with `/faq`) before asking them.
- summary: Do not whine or beg.
- summary: Do not ask moderators to cheat.
details: They don't have the ability to, anyway.
- summary: Play fairly.
sections:
- summary: Do not use hacks.
details: Hacks are the use of a client or mod designed for cheating.
- summary: Do not use exploits.
details: Exploits are the use of bugs to gain an unfair advantage (e.g. item duplication) or e.g. bypass protection plugins.
- summary: Do not use cheats.
details: Do not use x-ray resource packs or any other form of cheating.
- summary: Use your power appropriately.
details: Use moderator tools and ranks strictly for their intended purpose.
- summary: Only use authorized mods.
details: Refer to the authorized mods list to see which mods are permitted. If you'd like to use a mod not on that list, you **must ask the administrator(s)** before using it.
- summary: Stick to the game.
sections:
- summary: Keep the chat SFW.
- summary: Avoid discussing politics, religion, and the news.
details: This is not strictly forbidden, but these discussions may be shut down by moderator discretion.
- summary: Do not ask for personal information.
details: This includes real name, age, and location.
- summary: Do not share anyone else's personal information.
details: This includes their real name, age, and location.
- summary: Avoid sharing your own personal information.
details: You may share your own real name, age, or location, but not e.g. your address or phone number.
faq:
- summary: Nothing to see here.
details: The server administrator has not set an FAQ.
# Set the maximum durations for which moderators are allowed to mute or ban,
# based on their permission nodes.
permissions:
# The default durations for people with permission to mute/ban, but with no specific duration permission set.
# Set this to 0 if you want to require a more specific permission be to set to allow mutes and bans.
wasteland.modtools.ban.issue:
ban: forever
wasteland.modtools.mute.issue:
mute: forever
# You will not want to leave this section here if you will not be using Wasteland's rank system,
# or don't intend to use the officer rank system for staff ranks.
wasteland.rank:
ltcol:
mute: 3h
ban: 3h
col:
mute: 3d
ban: 3d
bgen:
mute: forever
ban: forever

View File

@ -0,0 +1,193 @@
name: WastelandModTools
author: HuskFodder
main: me.jamestmartin.wasteland.modtools.WastelandModTools
version: 0.1.0
api-version: 1.16
commands:
modlog:
description: See the list of recent actions taken by moderators.
usage: "Usage: /<command> [<duration>]"
permission: wasteland.modtools.log
permission-message: You do not have permission to view the moderator log.
infractions:
description: See the list of infractions against the rules a player has committed.
usage: "Usage: /<infractions> <player> [<duration>]"
permission: wasteland.modtools.infractions
permission-message: You do not have permission to view players' infractions against the rules.
uuid:
description: Get the UUID(s) of players who have had a name on this server.
usage: "Usage: /<command> <player name>"
permission: wasteland.modtools.uuid
permission-message: You do not have permission to view player UUIDs.
lastseen:
description: Get the last time the player with that name or UUID was seen.
usage: "Usage: /<command> <player name or UUID>"
permission: wasteland.modtools.lastseen
permission-message: You do not have permission to view when a player was last seen.
rules:
description: "Read the server rules. You can view more information about a specific rule using `/rules #`."
usage: "Usage: /<command> [<section>] [<player>]"
permission: wasteland.manual.rules
permission-message: You do not have permission to read the server rules.
faq:
description: "Read the server FAQ. You can view more information about a specific topic using `/faq #`."
usage: "Usage: /<command> [<section>] [<player>]"
permission: wasteland.manual.faq
permission-message: You do not have permission to read the server FAQ.
ban:
description: Ban a player from the server, preventing them from joining again.
usage: "Usage: /<command> <player> <duration> [<rule>] [<reason> ...]"
permission: wasteland.modtools.ban.issue
permission-message: You do not have permission to ban players.
unban:
description: Unban a player, allowing them to join again.
usage: "Usage: /<command> <player> [<reason> ...]"
permission: wasteland.modtools.ban.pardon
permission-message: You do not have permission to unban players.
bans:
description: See the list of all players currently banned from the server.
usage: "Usage: /<command> [<player>]"
permission: wasteland.modtools.ban.list
permission-message: You do not have permission to list banned players.
kick:
description: Kick a player from the server.
usage: "Usage: /<command> <player> [<rule>] [<reason> ...]"
permission: wasteland.modtools.kick
permission-message: You do not have permission to kick players.
mute:
description: Mute a player, preventing them from talking.
usage: "Usage: /<command> <player> <duration> [<rule>] [<reason> ...]"
permission: wasteland.modtools.mute.issue
permission-message: You do not have permission to mute players.
unmute:
description: Unmute a player, allowing them to talk again.
usage: "Usage: /<command> <player> [<reason> ...]"
permission: wasteland.modtools.mute.pardon
permission-message: You do not have permission to unmute players.
mutes:
description: See the list of all players currently muted on the server.
usage: "Usage: /<command> [<player>]"
permission: wasteland.modtools.mutes.list
permission-message: You do not have permission to list muted players.
warn:
description: Give a player an official (logged) warning.
usage: "Usage: /<command> <player> [<rule>] [<reason> ...]"
permission: wasteland.modtools.warn
permission-message: You do not have permission to issue warnings to players.
permissions:
wasteland.modtools:
description: Allows you full access to the moderator tools.
default: op
children:
wasteland.modtools.uuid: true
wasteland.modtools.lastseen: true
wasteland.modtools.log: true
wasteland.modtools.actions: true
wasteland.modtools.log:
description: Allows you to view the log of moderator actions.
default: op
children:
wasteland.modtools.infractions: true
wasteland.modtools.ban.list: true
wasteland.modtools.mute.list: true
wasteland.modtools.warn.list: true
wasteland.modtools.infractions:
description: Allows you to see the list of infractions against the rules a player has committed.
default: op
wasteland.modtools.uuid:
description: Allows you to see the UUIDs of players with a given name on this server.
default: op
wasteland.modtools.lastseen:
description: Allows you to see the first and last time a player was seen on this server.
default: op
wasteland.modtools.actions:
description: Allows you to perform any moderator action.
default: op
children:
wasteland.manual.show-other: true
wasteland.modtools.ban: true
wasteland.modtools.kick: true
wasteland.modtools.mute: true
wasteland.modtools.warn: true
wasteland.manual:
description: Allows you to read any manual.
default: op
children:
wasteland.manual.rules: true
wasteland.manual.faq: true
wasteland.manual.show-other:
description: Allows you to forcibly show any manual to someone else.
default: op
children:
wasteland.manual.rules.show-other: true
wasteland.manual.faq.show-other: true
wasteland.manual.rules:
description: Allows you to read the server rules.
default: true
wasteland.manual.rules.show-other:
description: Allows you to forcibly show the server rules to someone else.
default: op
children:
wasteland.manual.rules: true
wasteland.manual.faq:
description: Allows you to read the FAQ.
default: true
wasteland.manual.faq.show-other:
description: Allows you to forcibly show the FAQ to someone else.
default: op
children:
wasteland.manual.faq: true
wasteland.modtools.ban:
description: Allows you to ban or unban a player, or list active bans.
default: op
children:
wasteland.modtools.ban.issue: true
wasteland.modtools.ban.list: true
wasteland.modtools.ban.pardon: true
wasteland.modtools.ban.issue:
description: Allows you to issue bans.
default: op
wasteland.modtools.ban.list:
description: Allows you to list all active bans.
default: op
wasteland.modtools.ban.pardon:
description: Allows you to remove bans.
default: op
wasteland.modtools.kick:
desription: Allows you to kick players.
default: op
wasteland.modtools.mute:
description: Allows you to mute or unmute a player, or list active mutes.
default: op
children:
wasteland.modtools.mute.issue: true
wasteland.modtools.mute.list: true
wasteland.modtools.mute.pardon: true
wasteland.modtools.mute.issue:
description: Allows you to issue mutes.
default: op
wasteland.modtools.mute.list:
description: Allows you to list active mutes.
default: op
wasteland.modtools.mute.pardon:
description: Allows you to remove mutes.
default: op
wasteland.modtools.warn:
description: Allows you to issue a warning against a player.
default: op

View File

@ -22,6 +22,10 @@ class CommandWP implements CommandExecutor {
return false;
}
if (!sender.hasPermission("wasteland.permissions.reload")) {
sender.sendMessage("You do not have permission to reload Wasteland Permissions' config.");
}
WastelandPermissions.getInstance().reload();
sender.sendMessage("Reloaded Wasteland Permissions' configuration.");

View File

@ -30,6 +30,10 @@ public class ConfigParser {
}
private static Map<String, Group> parseGroups(ConfigurationSection c) {
if (c == null) {
return Map.of();
}
Map<String, GroupConfig> groupConfigs = new HashMap<>();
for (String group : c.getKeys(false)) {
groupConfigs.put(group, parseGroup(group, c.getConfigurationSection(group)));
@ -88,6 +92,10 @@ public class ConfigParser {
private static Map<UUID, PlayerGroup> parsePlayers(Map<String, Group> groups, ConfigurationSection c) {
Map<UUID, PlayerGroup> players = new HashMap<>();
if (c == null) {
return players;
}
for (String uuidStr : c.getKeys(false)) {
UUID uuid = UUID.fromString(uuidStr);
players.put(uuid, parsePlayer(groups, uuidStr, c.getConfigurationSection(uuidStr)));
@ -103,11 +111,18 @@ public class ConfigParser {
}
private static PseudoGroupConfig parsePseudoGroup(List<String> inherits, ConfigurationSection permissions) {
if (inherits == null) {
inherits = List.of();
}
return new PseudoGroupConfig(inherits, parsePermissions(permissions));
}
private static Map<String, Boolean> parsePermissions(ConfigurationSection c) {
Map<String, Boolean> permissions = new HashMap<>();
if (c == null) {
return permissions;
}
for (String node : c.getKeys(false)) {
if (c.isBoolean(node)) {
permissions.put(node, c.getBoolean(node));

View File

@ -9,7 +9,7 @@ commands:
description: Manage the Wasteland Permissions plugin.
usage: "Usage: /<command> [reload]"
permission: wasteland.permissions
permission-message: You do not have permission to reload Wasteland Permission' config.
permission-message: You do not have permission to manage Wasteland Permissions.
permissions:
wasteland.permissions:

View File

@ -1,2 +1,2 @@
rootProject.name = 'wasteland-all'
include 'wasteland', 'permissions'
include 'wasteland', 'permissions', 'modtools'

View File

@ -3,7 +3,6 @@ package me.jamestmartin.wasteland;
import me.jamestmartin.wasteland.chat.ChatConfig;
import me.jamestmartin.wasteland.kills.KillsConfig;
import me.jamestmartin.wasteland.kit.KitConfig;
import me.jamestmartin.wasteland.manual.ManualConfig;
import me.jamestmartin.wasteland.ranks.AllRanks;
import me.jamestmartin.wasteland.spawns.SpawnsConfig;
@ -14,7 +13,6 @@ public class WastelandConfig {
private final AllRanks ranks;
private final SpawnsConfig spawnsConfig;
private final KitConfig kitConfig;
private final ManualConfig manualConfig;
public WastelandConfig(
String databaseFilename,
@ -22,15 +20,13 @@ public class WastelandConfig {
KillsConfig killsConfig,
AllRanks ranks,
SpawnsConfig spawnsConfig,
KitConfig kitConfig,
ManualConfig manualConfig) {
KitConfig kitConfig) {
this.databaseFilename = databaseFilename;
this.chatConfig = chatConfig;
this.killsConfig = killsConfig;
this.ranks = ranks;
this.spawnsConfig = spawnsConfig;
this.kitConfig = kitConfig;
this.manualConfig = manualConfig;
}
public String getDatabaseFilename() {
@ -56,8 +52,4 @@ public class WastelandConfig {
public KitConfig getKitConfig() {
return kitConfig;
}
public ManualConfig getManualConfig() {
return manualConfig;
}
}

View File

@ -8,7 +8,6 @@ import org.bukkit.plugin.java.JavaPlugin;
import me.jamestmartin.wasteland.chat.ChatState;
import me.jamestmartin.wasteland.kills.KillsState;
import me.jamestmartin.wasteland.kit.KitState;
import me.jamestmartin.wasteland.manual.ManualState;
import me.jamestmartin.wasteland.ranks.PermissionsPlayerRankProvider;
import me.jamestmartin.wasteland.ranks.PlayerRankProvider;
import me.jamestmartin.wasteland.ranks.RanksState;
@ -25,7 +24,6 @@ public class WastelandState implements Substate {
private final RanksState ranksState;
private final SpawnsState spawnsState;
private final KitState kitState;
private final ManualState manualState;
public WastelandState(WastelandConfig config) throws IOException, ClassNotFoundException, SQLException {
this.commandWasteland = new CommandWasteland();
@ -37,7 +35,6 @@ public class WastelandState implements Substate {
this.killsState = new KillsState(config.getKillsConfig(), ranksState.getPlayerKillsStore(), rankProvider);
this.spawnsState = new SpawnsState(config.getSpawnsConfig());
this.kitState = new KitState(config.getKitConfig(), storeState.getKitStore());
this.manualState = new ManualState(config.getManualConfig());
}
private Substate[] getSubstates() {
@ -48,7 +45,6 @@ public class WastelandState implements Substate {
ranksState,
spawnsState,
kitState,
manualState,
};
return substates;
}

View File

@ -9,8 +9,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@ -26,8 +24,6 @@ import me.jamestmartin.wasteland.WastelandConfig;
import me.jamestmartin.wasteland.chat.ChatConfig;
import me.jamestmartin.wasteland.kills.KillsConfig;
import me.jamestmartin.wasteland.kit.KitConfig;
import me.jamestmartin.wasteland.manual.ManualConfig;
import me.jamestmartin.wasteland.manual.ManualSection;
import me.jamestmartin.wasteland.ranks.AllRanks;
import me.jamestmartin.wasteland.ranks.EnlistedRank;
import me.jamestmartin.wasteland.ranks.EnlistedRanks;
@ -51,22 +47,13 @@ public class ConfigParser {
ConfigurationSection officerSection = c.getConfigurationSection("officer");
AllRanks ranks = parseRanks(enlistedSection, officerSection);
ManualSection rules = new ManualSection(
"The Server Rules",
parseManualSectionList(castToSectionList(c.getMapList("rules"))));
ManualSection faq = new ManualSection(
"Frequently Asked Questions",
parseManualSectionList(castToSectionList(c.getMapList("faq"))));
ManualConfig manualConfig = new ManualConfig(rules, faq);
return new WastelandConfig(
databaseFilename,
chatConfig,
killsConfig,
ranks,
spawnsConfig,
kitConfig,
manualConfig);
kitConfig);
}
private static ChatConfig parseChatConfig(ConfigurationSection c) {
@ -321,34 +308,6 @@ public class ConfigParser {
return new KitConfig(kitPeriod, kitTools, kitItems);
}
public static ManualSection parseManualSection(Map<?, ?> c) {
String summary = (String) c.get("summary");
Optional<String> details = Optional.ofNullable((String) c.get("details"));
List<ManualSection> subsections = parseManualSectionList(castToSectionList(c.get("sections")));
return new ManualSection(summary, details, subsections);
}
private static List<Map<?, ?>> castToSectionList(Object x) {
if (x == null) {
return null;
}
return ((List<?>) x).stream().map(xx -> (Map<?, ?>) xx).collect(Collectors.toUnmodifiableList());
}
public static List<ManualSection> parseManualSectionList(List<Map<?, ?>> list) {
List<ManualSection> sections = new ArrayList<>();
if (list == null) {
return sections;
}
for (Map<?, ?> section : list) {
sections.add(parseManualSection(section));
}
return sections;
}
/** Orphaned method. */
private static Optional<ChatColor> readColor(ConfigurationSection c, String path) {
return (Optional<ChatColor>) Optional.ofNullable(c.getString(path)).map(ChatColor::valueOf);

View File

@ -365,51 +365,4 @@ kit:
# A random quantity will be chosen depending on how many kits the player has received.
# The item type will not be dropped if the quantity chosen is less than one eighth of the maximum.
items:
ROTTEN_FLESH: 32
rules:
- summary: Be civil and respectful.
sections:
- summary: If you start getting angry or frustrated, take a break!
- summary: Do not harass other players.
- summary: Do not use slurs.
- summary: Do not advertise.
- summary: Do not spam.
- summary: Avoid excessive swearing.
details: 'What is "excessive" is determined by moderator discretion.'
- summary: Be independent and mature.
sections:
- summary: This is a server intended for adults.
details: You will not be banned for being <16 per se, but acting like a child will get you banned no matter how old you are.
- summary: RTFM (Read The Field Manual).
details: Try to answer questions for yourself (e.g. with `/faq`) before asking them.
- summary: Do not whine or beg.
- summary: Do not ask moderators to cheat.
details: They don't have the ability to, anyway.
- summary: Play fairly.
sections:
- summary: Do not use hacks.
details: Hacks are the use of a client or mod designed for cheating.
- summary: Do not use exploits.
details: Exploits are the use of bugs to gain an unfair advantage (e.g. item duplication) or e.g. bypass protection plugins.
- summary: Do not use cheats.
details: Do not use x-ray resource packs or any other form of cheating.
- summary: Use your power appropriately.
details: Use moderator tools and ranks strictly for their intended purpose.
- summary: Only use authorized mods.
details: Refer to the authorized mods list to see which mods are permitted. If you'd like to use a mod not on that list, you **must ask the administrator(s)** before using it.
- summary: Stick to the game.
sections:
- summary: Keep the chat SFW.
- summary: Avoid discussing politics, religion, and the news.
details: This is not strictly forbidden, but these discussions may be shut down by moderator discretion.
- summary: Do not ask for personal information.
details: This includes real name, age, and location.
- summary: Do not share anyone else's personal information.
details: This includes their real name, age, and location.
- summary: Avoid sharing your own personal information.
details: You may share your own real name, age, or location, but not e.g. your address or phone number.
faq:
- summary: Nothing to see here.
details: The server administrator has not set an FAQ.
ROTTEN_FLESH: 32

View File

@ -56,17 +56,6 @@ commands:
usage: "Usage: /<command>"
permission: wasteland.kit
permission-message: You do not have permission to receive a starter kit.
rules:
description: "Read the server rules. You can view more information about a specific rule using `/rules #`."
usage: "Usage: /<command> [<section>] [<player>]"
permission: wasteland.manual.rules
permission-message: You do not have permission to read the server rules.
faq:
description: "Read the server FAQ. You can view more information about a specific topic using `/faq #`."
usage: "Usage: /<command> [<section>] [<player>]"
permission: wasteland.manual.faq
permission-message: You do not have permission to read the server FAQ.
permissions:
wasteland.reload:
@ -128,32 +117,3 @@ permissions:
wasteland.kit:
description: Allows you to receive a starter kit.
default: true
wasteland.manual:
description: Allows you to read any manual.
default: op
children:
wasteland.manual.rules: true
wasteland.manual.faq: true
wasteland.manual.show-other:
description: Allows you to forcibly show any manual to someone else.
default: op
children:
wasteland.manual.rules.show-other: true
wasteland.manual.faq.show-other: true
wasteland.manual.rules:
description: Allows you to read the server rules.
default: true
wasteland.manual.rules.show-other:
description: Allows you to forcibly show the server rules to someone else.
default: op
children:
wasteland.manual.rules: true
wasteland.manual.faq:
description: Allows you to read the FAQ.
default: true
wasteland.manual.faq.show-other:
description: Allows you to forcibly show the FAQ to someone else.
default: op
children:
wasteland.manual.faq: true