1
0
mirror of https://github.com/plan-player-analytics/Plan.git synced 2025-01-12 19:30:44 +01:00

Added World Alias Regex setting

This allows grouping worlds together by matching a regex and avoiding thousands of lines if
some plugin generates worlds automatically.

Affects issues:
- Close 
This commit is contained in:
Risto Lahtela 2021-07-24 11:39:28 +03:00
parent a2cface3e0
commit 13cbca6639
6 changed files with 87 additions and 19 deletions
Plan/common/src/main
java/com/djrapitops/plan/settings/config
resources/assets/plan

View File

@ -30,13 +30,12 @@ import com.djrapitops.plan.settings.locale.lang.HtmlLang;
import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorContext;
import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plan.utilities.logging.ErrorLogger;
import dagger.Lazy; import dagger.Lazy;
import org.apache.commons.lang3.StringUtils;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.*;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -54,6 +53,8 @@ public class WorldAliasSettings {
private final Processing processing; private final Processing processing;
private final ErrorLogger errorLogger; private final ErrorLogger errorLogger;
private List<String[]> regexRules;
@Inject @Inject
public WorldAliasSettings( public WorldAliasSettings(
Lazy<PlanConfig> config, Lazy<PlanConfig> config,
@ -70,10 +71,35 @@ public class WorldAliasSettings {
percentageFormatter = () -> formatters.get().percentage(); percentageFormatter = () -> formatters.get().percentage();
} }
private ConfigNode getAliasSection() { private ConfigNode getAliasListNode() {
return config.get().get(DisplaySettings.WORLD_ALIASES); return config.get().get(DisplaySettings.WORLD_ALIASES);
} }
private List<String[]> getRegexRules() {
if (regexRules == null) {
regexRules = new ArrayList<>();
for (String regexRule : config.get().getStringList("World_aliases.Regex")) {
regexRules.add(StringUtils.split(regexRule, ":", 2));
}
}
return regexRules;
}
private Optional<String> getAlias(String world) {
for (String[] regexRule : getRegexRules()) {
String alias = regexRule[0];
String regex = regexRule[1];
if (world.matches(regex)) {
return Optional.of(alias);
}
}
String alias = getAliasListNode().getString(world);
if (alias == null || alias.isEmpty()) {
return Optional.empty();
}
return Optional.of(alias);
}
/** /**
* Adds a new World to the config section. * Adds a new World to the config section.
* <p> * <p>
@ -83,9 +109,9 @@ public class WorldAliasSettings {
*/ */
public void addWorld(String world) { public void addWorld(String world) {
if (world == null || world.isEmpty()) throw new IllegalArgumentException("Attempted to save empty world alias"); if (world == null || world.isEmpty()) throw new IllegalArgumentException("Attempted to save empty world alias");
if (getAlias(world).isPresent()) return;
ConfigNode aliasSect = getAliasSection(); ConfigNode aliasSect = getAliasListNode();
String previousValue = aliasSect.getString(world); String previousValue = aliasSect.getString(world);
if (previousValue == null || previousValue.isEmpty()) { if (previousValue == null || previousValue.isEmpty()) {
aliasSect.set(world, world); aliasSect.set(world, world);
@ -111,18 +137,17 @@ public class WorldAliasSettings {
entry -> entry.getValue().getTotal() // GMTimes.getTotal entry -> entry.getValue().getTotal() // GMTimes.getTotal
)); ));
ConfigNode aliases = getAliasSection();
Map<String, Long> playtimePerAlias = new HashMap<>(); Map<String, Long> playtimePerAlias = new HashMap<>();
for (Map.Entry<String, Long> entry : playtimePerWorld.entrySet()) { for (Map.Entry<String, Long> entry : playtimePerWorld.entrySet()) {
String worldName = entry.getKey(); String worldName = entry.getKey();
long playtime = entry.getValue(); long playtime = entry.getValue();
if (worldName != null && !aliases.contains(worldName)) { Optional<String> foundAlias = getAlias(worldName);
if (!foundAlias.isPresent()) {
addWorld(worldName); addWorld(worldName);
} }
String alias = aliases.getString(worldName); String alias = foundAlias.orElse(worldName);
playtimePerAlias.put(alias, playtimePerAlias.getOrDefault(alias, 0L) + playtime); playtimePerAlias.put(alias, playtimePerAlias.getOrDefault(alias, 0L) + playtime);
} }
@ -130,8 +155,6 @@ public class WorldAliasSettings {
} }
public Map<String, GMTimes> getGMTimesPerAlias(WorldTimes worldTimes) { public Map<String, GMTimes> getGMTimesPerAlias(WorldTimes worldTimes) {
ConfigNode aliases = getAliasSection();
Map<String, GMTimes> gmTimesPerAlias = new HashMap<>(); Map<String, GMTimes> gmTimesPerAlias = new HashMap<>();
String[] gms = GMTimes.getGMKeyArray(); String[] gms = GMTimes.getGMKeyArray();
@ -140,11 +163,12 @@ public class WorldAliasSettings {
String worldName = entry.getKey(); String worldName = entry.getKey();
GMTimes gmTimes = entry.getValue(); GMTimes gmTimes = entry.getValue();
if (!aliases.contains(worldName)) { Optional<String> foundAlias = getAlias(worldName);
if (!foundAlias.isPresent()) {
addWorld(worldName); addWorld(worldName);
} }
String alias = aliases.getString(worldName); String alias = foundAlias.orElse(worldName);
GMTimes aliasGMTimes = gmTimesPerAlias.getOrDefault(alias, new GMTimes()); GMTimes aliasGMTimes = gmTimesPerAlias.getOrDefault(alias, new GMTimes());
for (String gm : gms) { for (String gm : gms) {
@ -162,9 +186,8 @@ public class WorldAliasSettings {
} }
WorldTimes worldTimes = foundWorldTimes.orElseGet(WorldTimes::new); WorldTimes worldTimes = foundWorldTimes.orElseGet(WorldTimes::new);
ConfigNode aliases = getAliasSection();
return worldTimes.getCurrentWorld() return worldTimes.getCurrentWorld()
.map(currentWorld -> "Current: " + (aliases.contains(currentWorld) ? aliases.getString(currentWorld) : currentWorld)) .map(currentWorld -> "Current: " + getAlias(currentWorld).orElse(currentWorld))
.orElse("Current: " + locale.get().getString(GenericLang.UNAVAILABLE)); .orElse("Current: " + locale.get().getString(GenericLang.UNAVAILABLE));
} }

View File

@ -57,6 +57,37 @@ public interface ConfigChange {
} }
} }
class MoveLevelDown implements ConfigChange {
final String oldPath;
final String newPath;
public MoveLevelDown(String oldPath, String newPath) {
this.oldPath = oldPath;
this.newPath = newPath;
}
@Override
public boolean hasBeenApplied(Config config) {
return !config.getNode(oldPath).isPresent() || config.getNode(newPath).isPresent();
}
@Override
public synchronized void apply(Config config) {
if (!config.moveChild(oldPath, "Temp." + oldPath)) {
throw new IllegalStateException("Failed to move config node from '" + oldPath + "' to 'Temp." + oldPath + "' while moving to '" + newPath + "'");
}
if (!config.moveChild("Temp." + oldPath, newPath)) {
throw new IllegalStateException("Failed to move config node from 'Temp." + oldPath + "' to '" + newPath + "' while moving from '" + oldPath + "'");
}
}
@Override
public String getAppliedMessage() {
return "Moved " + oldPath + " to " + newPath;
}
}
class Copied extends Removed { class Copied extends Removed {
final String newPath; final String newPath;

View File

@ -148,6 +148,8 @@ public class ConfigUpdater {
new ConfigChange.Removed("Database.H2.User"), new ConfigChange.Removed("Database.H2.User"),
new ConfigChange.Removed("Database.H2.Password"), new ConfigChange.Removed("Database.H2.Password"),
new ConfigChange.Removed("Database.H2"), new ConfigChange.Removed("Database.H2"),
new ConfigChange.MoveLevelDown("World_aliases", "World_aliases.List")
}; };
} }

View File

@ -43,7 +43,7 @@ public class DisplaySettings {
public static final Setting<String> CMD_COLOR_MAIN = new StringSetting("Display_options.Command_colors.Main"); public static final Setting<String> CMD_COLOR_MAIN = new StringSetting("Display_options.Command_colors.Main");
public static final Setting<String> CMD_COLOR_SECONDARY = new StringSetting("Display_options.Command_colors.Secondary"); public static final Setting<String> CMD_COLOR_SECONDARY = new StringSetting("Display_options.Command_colors.Secondary");
public static final Setting<String> CMD_COLOR_TERTIARY = new StringSetting("Display_options.Command_colors.Highlight"); public static final Setting<String> CMD_COLOR_TERTIARY = new StringSetting("Display_options.Command_colors.Highlight");
public static final Setting<ConfigNode> WORLD_ALIASES = new Setting<ConfigNode>("World_aliases", ConfigNode.class) { public static final Setting<ConfigNode> WORLD_ALIASES = new Setting<ConfigNode>("World_aliases.List", ConfigNode.class) {
@Override @Override
public ConfigNode getValueFrom(ConfigNode node) { public ConfigNode getValueFrom(ConfigNode node) {
return node.getNode(path).orElseGet(() -> node.addNode(path)); return node.getNode(path).orElseGet(() -> node.addNode(path));

View File

@ -180,7 +180,13 @@ Formatting:
# World aliases can be used to rename worlds and to combine multiple worlds into a group. # World aliases can be used to rename worlds and to combine multiple worlds into a group.
# ----------------------------------------------------- # -----------------------------------------------------
World_aliases: World_aliases:
world: world # List of world names: aliases, case sensitive. Set alias of two worlds to same one to group them.
# Automatically generated, if regex matches world will not be added here.
List:
world: world
# List of - "alias:regex" rules, Set alias of multiple worlds that match regex to group them
Regex:
- "Alias for world:^abc$"
# ----------------------------------------------------- # -----------------------------------------------------
# These settings will make Plan write .js, .css, .json and .html files to some location on disk. # These settings will make Plan write .js, .css, .json and .html files to some location on disk.
# Relative path will render to /plugins/Plan/path # Relative path will render to /plugins/Plan/path

View File

@ -185,7 +185,13 @@ Formatting:
# World aliases can be used to rename worlds and to combine multiple worlds into a group. # World aliases can be used to rename worlds and to combine multiple worlds into a group.
# ----------------------------------------------------- # -----------------------------------------------------
World_aliases: World_aliases:
world: world # List of world names: aliases, case sensitive. Set alias of two worlds to same one to group them.
# Automatically generated, if regex matches world will not be added here.
List:
world: world
# List of - "alias:regex" rules, Set alias of multiple worlds that match regex to group them
Regex:
- "Alias for world:^abc$"
# ----------------------------------------------------- # -----------------------------------------------------
# These settings will make Plan write .js, .css, .json and .html files to some location on disk. # These settings will make Plan write .js, .css, .json and .html files to some location on disk.
# Relative path will render to /plugins/Plan/path # Relative path will render to /plugins/Plan/path