Skip to content

Commit

Permalink
feat: load supplementary config/ftbranks-pack.snbt file
Browse files Browse the repository at this point in the history
Intended to augment existing ranks from ranks.snbt with pack-specific
settings, to be created by modpack makers, and independent from the
server admin settings.
  • Loading branch information
desht committed Oct 7, 2024
1 parent f672201 commit 634969f
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ private static int refreshReadme(CommandSourceStack source) {
return 1;
}

private static Component makeRankNameClicky(Rank rank) {
private static Component makeRankNameClicky(Rank rank) {
boolean isDef = rank.getCondition().isDefaultCondition();
return Component.literal(rank.getName())
.withStyle(isDef ? ChatFormatting.AQUA : ChatFormatting.YELLOW)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dev.ftb.mods.ftbranks.impl;

import dev.architectury.platform.Platform;
import net.minecraft.server.MinecraftServer;

import java.nio.file.Path;
import java.util.function.Function;

public enum RankFileSource {
SERVER(server -> server.getWorldPath(RankManagerImpl.FOLDER_NAME).resolve("ranks.snbt")),
MODPACK(server -> Platform.getConfigFolder().resolve("ftbranks-pack.snbt"));

private final Function<MinecraftServer, Path> pathFunction;

RankFileSource(Function<MinecraftServer, Path> pathFunction) {
this.pathFunction = pathFunction;
}

public Path getPath(MinecraftServer server) {
return pathFunction.apply(server);
}
}
19 changes: 12 additions & 7 deletions common/src/main/java/dev/ftb/mods/ftbranks/impl/RankImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,27 @@ public class RankImpl implements Rank, Comparable<RankImpl> {
private final Map<String, PermissionValue> permissions = new LinkedHashMap<>();
private final String name;
private final int power;
private final RankFileSource source;
@NotNull
private RankCondition condition;

public static RankImpl create(RankManagerImpl manager, String id, String name, int power, @NotNull RankCondition condition) {
return new RankImpl(manager, id, name, power, condition);
public static RankImpl create(RankManagerImpl manager, String id, String name, int power, @NotNull RankCondition condition, RankFileSource source) {
return new RankImpl(manager, id, name, power, condition, source);
}

public static RankImpl create(RankManagerImpl manager, String id, String name, int power) {
RankImpl rank = new RankImpl(manager, id, name, power, AlwaysActiveCondition.INSTANCE);
public static RankImpl create(RankManagerImpl manager, String id, String name, int power, RankFileSource source) {
RankImpl rank = new RankImpl(manager, id, name, power, AlwaysActiveCondition.INSTANCE, source);
rank.setCondition(new DefaultCondition(rank));
return rank;
}

private RankImpl(RankManagerImpl manager, String id, String name, int power, @NotNull RankCondition condition) {
private RankImpl(RankManagerImpl manager, String id, String name, int power, @NotNull RankCondition condition, RankFileSource source) {
this.manager = manager;
this.id = id;
this.name = name;
this.power = power;
this.condition = condition;
this.source = source;
}

@Override
Expand Down Expand Up @@ -152,9 +154,9 @@ public Collection<String> getPermissions() {
return nodes;
}

public static RankImpl readSNBT(RankManagerImpl manager, String rankId, SNBTCompoundTag tag) throws RankException {
public static RankImpl readSNBT(RankManagerImpl manager, String rankId, SNBTCompoundTag tag, RankFileSource source) throws RankException {
String displayName = tag.getString("name").isEmpty() ? rankId : tag.getString("name");
RankImpl rank = create(manager, rankId, displayName, tag.getInt("power"));
RankImpl rank = create(manager, rankId, displayName, tag.getInt("power"), source);

if (tag.contains("condition")) {
rank.setCondition(manager.createCondition(rank, tag.get("condition")));
Expand Down Expand Up @@ -198,4 +200,7 @@ public SNBTCompoundTag writeSNBT() {
return res;
}

public RankFileSource getSource() {
return source;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class RankManagerImpl implements RankManager {
private final Path rankFile;
private final Path playerFile;

private boolean shouldSaveRanks;
private boolean shouldSaveRanks;
private boolean shouldSavePlayers;

private Map<String, RankImpl> ranks;
Expand Down Expand Up @@ -81,7 +81,7 @@ public Optional<Rank> getRank(String id) {
@Override
public RankImpl createRank(String id, String name, int power) {
deleteRank(id);
RankImpl rank = RankImpl.create(this, id, name, power);
RankImpl rank = RankImpl.create(this, id, name, power, RankFileSource.SERVER);
ranks.put(id, rank);
rebuildSortedRanks();
markRanksDirty();
Expand Down Expand Up @@ -194,21 +194,9 @@ public void reload() throws Exception {
}

Map<String, RankImpl> tempRanks = new LinkedHashMap<>();
SNBTCompoundTag rankFileTag = SNBT.read(rankFile);
if (rankFileTag != null) {
for (String rankId : rankFileTag.getAllKeys()) {
try {
RankImpl rank = RankImpl.readSNBT(this, rankId, rankFileTag.getCompound(rankId));
tempRanks.put(rank.getId(), rank);
} catch (RankException e) {
FTBRanks.LOGGER.error("Failed to read rank {} from SNBT: {}", rankId, e.getMessage());
}
}
if (tempRanks.isEmpty()) {
FTBRanks.LOGGER.warn("No ranks found!");
}
} else {
throw new RuntimeException("ranks.snbt failed to load! check your server log for errors");
readRankFile(RankFileSource.SERVER, tempRanks);
if (Files.exists(RankFileSource.MODPACK.getPath(server))) {
readRankFile(RankFileSource.MODPACK, tempRanks);
}

Map<UUID, PlayerRankData> tempPlayerData = new LinkedHashMap<>();
Expand All @@ -233,20 +221,43 @@ public void reload() throws Exception {

PlayerNameFormatting.refreshPlayerNames();

FTBRanks.LOGGER.info("Loaded " + ranks.size() + " ranks");
FTBRanks.LOGGER.info("Loaded {} ranks", ranks.size());
}

private void readRankFile(RankFileSource source, Map<String, RankImpl> rankMap) {
Path inputFile = source.getPath(server);
SNBTCompoundTag rankFileTag = SNBT.read(inputFile);
if (rankFileTag != null) {
int size = rankMap.size();
for (String rankId : rankFileTag.getAllKeys()) {
try {
RankImpl rank = RankImpl.readSNBT(this, rankId, rankFileTag.getCompound(rankId), source);
if (rankMap.putIfAbsent(rank.getId(), rank) != null) {
FTBRanks.LOGGER.warn("Conflicting rank ID '{}' detected while reading {}, ignoring", rank.getId(), inputFile);
}
} catch (RankException e) {
FTBRanks.LOGGER.error("Failed to read rank ID '{}' from {}: {}", rankId, inputFile, e.getMessage());
}
}
if (rankMap.size() == size) {
FTBRanks.LOGGER.warn("No ranks found in {}!", inputFile);
}
} else {
throw new RuntimeException(inputFile + " failed to load! check your server log for errors");
}
}

private void createDefaultRanks() {
ranks = new LinkedHashMap<>();

RankImpl memberRank = RankImpl.create(this, "member", "Member", 1, AlwaysActiveCondition.INSTANCE);
RankImpl memberRank = RankImpl.create(this, "member", "Member", 1, AlwaysActiveCondition.INSTANCE, RankFileSource.SERVER);
ranks.put("member", memberRank);

RankImpl vipRank = RankImpl.create(this, "vip", "VIP", 50);
RankImpl vipRank = RankImpl.create(this, "vip", "VIP", 50, RankFileSource.SERVER);
vipRank.setPermission("ftbranks.name_format", StringPermissionValue.of("&bVIP {name}"));
ranks.put("vip", vipRank);

RankImpl adminRank = RankImpl.create(this, "admin", "Admin", 1000, new OPCondition());
RankImpl adminRank = RankImpl.create(this, "admin", "Admin", 1000, new OPCondition(), RankFileSource.SERVER);
adminRank.setPermission("ftbranks.name_format", StringPermissionValue.of("&2{name}"));
ranks.put("admin", adminRank);

Expand Down Expand Up @@ -312,13 +323,16 @@ void load() throws Exception {

void saveRanksNow() {
if (shouldSaveRanks) {
SNBTCompoundTag tag = new SNBTCompoundTag();
Map<RankFileSource,SNBTCompoundTag> map = new EnumMap<>(RankFileSource.class);
for (RankImpl rank : ranks.values()) {
tag.put(rank.getId(), rank.writeSNBT());
}
if (!SNBT.write(rankFile, tag)) {
FTBRanks.LOGGER.warn("Failed to save ranks.snbt!");
map.computeIfAbsent(rank.getSource(), k -> new SNBTCompoundTag())
.put(rank.getId(), rank.writeSNBT());
}
map.forEach((source, tag) -> {
if (!SNBT.write(source.getPath(server), tag)) {
FTBRanks.LOGGER.warn("Failed to save {}}!", source.getPath(server));
}
});
shouldSaveRanks = false;
}
}
Expand Down

0 comments on commit 634969f

Please sign in to comment.