language supports, file fix

This commit is contained in:
Stachelbeere1248 2023-12-21 11:12:09 +01:00
parent 58fba8a916
commit 53e313d2ce
Signed by: Stachelbeere1248
SSH key fingerprint: SHA256:IozEKdw2dB8TZxkpPdMxcWSoWTIMwoLaCcZJ1AJnY2o
14 changed files with 201 additions and 86 deletions

View file

@ -3,4 +3,4 @@ org.gradle.jvmargs=-Xmx2g
baseGroup = com.github.stachelbeere1248.zombiesutils
mcVersion = 1.8.9
modid = zombiesutils
version = 1.2.3
version = 1.2.4-PREVIEW_1

View file

@ -31,7 +31,7 @@ public class ZombiesUtils {
logger = event.getModLog();
ZombiesUtilsConfig.config = new Configuration(
event.getSuggestedConfigurationFile(),
"1.2.0"
"1.2.4"
);
ZombiesUtilsConfig.load();
}

View file

@ -1,88 +1,102 @@
package com.github.stachelbeere1248.zombiesutils.config;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.utils.LanguageSupport;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
public class ZombiesUtilsConfig {
public static Configuration config;
private static boolean slaToggle;
private static boolean slaShortener;
private static boolean shortSpawntime;
private static Property slaToggle;
private static Property slaShortener;
private static Property shortSpawntime;
private static String chatMacro;
private static String defaultCategory;
private static short waveOffset;
private static Property chatMacro;
private static Property defaultCategory;
private static Property waveOffset;
private static Property language;
public static void load() {
ZombiesUtils.getInstance().getLogger().debug("Loading config...");
config.load();
ZombiesUtils.getInstance().getLogger().debug("Config loaded.");
slaToggle = config.getBoolean(
"SLA Launcher",
language = config.get(
Configuration.CATEGORY_GENERAL,
"Language",
"EN",
"Your Hypixel language",
LanguageSupport.Languages.list()
);
slaToggle = config.get(
Configuration.CATEGORY_GENERAL,
"SLA Launcher",
false,
"Should SLA be started when a game starts?"
);
slaShortener = config.getBoolean(
"shortened SLA",
slaShortener = config.get(
Configuration.CATEGORY_GENERAL,
"shortened SLA",
true,
"If on, inactive windows / rooms will not show"
);
chatMacro = config.getString(
"Chat Macro",
chatMacro = config.get(
Configuration.CATEGORY_GENERAL,
"Chat Macro",
"T",
"The Text to be sent when pressing the chat-macro hotkey"
);
defaultCategory = config.getString(
"Default Category",
defaultCategory = config.get(
Configuration.CATEGORY_GENERAL,
"Default Category",
"general",
"name of the category to be selected unless specified using /runCategory"
);
waveOffset = (short) config.getInt(
waveOffset = config.get(
Configuration.CATEGORY_GENERAL,
"RL-mode offset",
Configuration.CATEGORY_GENERAL,
-28,
"ticks to be added to the wave spawn time",
-200,
200,
"ticks to be added to the wave spawn time"
200
);
shortSpawntime = config.getBoolean(
"passed wave spawns",
shortSpawntime = config.get(
Configuration.CATEGORY_GENERAL,
"passed wave spawns",
true,
"Display spawn-time for passed waves"
);
}
public static short getWaveOffset() {
return waveOffset;
return (short) waveOffset.getInt();
}
public static boolean isSlaToggled() {
return slaToggle;
return slaToggle.getBoolean();
}
public static boolean isSlaShortened() {
return slaShortener;
return slaShortener.getBoolean();
}
public static boolean isSpawntimeNotShortened() {
return shortSpawntime;
return shortSpawntime.getBoolean();
}
public static String getChatMacro() {
return chatMacro;
return chatMacro.getString();
}
public static String getDefaultCategory() {
return defaultCategory;
return defaultCategory.getString();
}
public static LanguageSupport.Languages getLanguage() {
return LanguageSupport.Languages.valueOf(language.getString());
}
@SubscribeEvent

View file

@ -3,6 +3,7 @@ package com.github.stachelbeere1248.zombiesutils.handlers;
import com.github.stachelbeere1248.zombiesutils.game.Difficulty;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.timer.Timer;
import com.github.stachelbeere1248.zombiesutils.utils.LanguageSupport;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.jetbrains.annotations.NotNull;
@ -22,12 +23,10 @@ public class ChatHandler {
GameMode gameMode = Timer.getInstance().get().getGameMode();
if (message.contains(":")) return;
if (message.contains("Hard Difficulty") || message.contains("困难") || message.contains("困難")) {
if (LanguageSupport.containsHard(message)) {
gameMode.changeDifficulty(Difficulty.HARD);
} else if (message.contains("RIP") || message.contains("安息")) {
} else if (LanguageSupport.containsRIP(message)) {
gameMode.changeDifficulty(Difficulty.RIP);
}
}
}

View file

@ -2,6 +2,7 @@ package com.github.stachelbeere1248.zombiesutils.mixin;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.timer.Timer;
import com.github.stachelbeere1248.zombiesutils.utils.LanguageSupport;
import com.github.stachelbeere1248.zombiesutils.utils.Scoreboard;
import net.minecraft.client.Minecraft;
import net.minecraft.client.network.NetHandlerPlayClient;
@ -76,7 +77,7 @@ public class MixinNetHandlerPlayClient {
Timer.getInstance().ifPresent(timer -> {
if (Scoreboard.isNotZombies()) return;
if (message.equals("§aYou Win!")) {
if (LanguageSupport.zombies_utils$isWin(message)) {
switch (timer.getGameMode().getMap()) {
case DEAD_END:
case BAD_BLOOD:
@ -88,7 +89,7 @@ public class MixinNetHandlerPlayClient {
Timer.dropInstances();
break;
}
} else if (message.equals("§cGame Over!")) Timer.dropInstances();
} else if (LanguageSupport.zombies_utils$isLoss(message)) Timer.dropInstances();
});
}

View file

@ -11,6 +11,7 @@ import com.github.stachelbeere1248.zombiesutils.timer.recorder.files.GameFile;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import net.minecraftforge.common.MinecraftForge;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
@ -74,7 +75,12 @@ public class Timer {
return;
}
try {
record(passedRound, roundTime, gameTime);
} catch (Exception e) {
ZombiesUtils.getInstance().getLogger().error(ExceptionUtils.getStackTrace(e));
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Error saving splits"));
}
passedRoundsTickSum = gameTime;
round = passedRound;
@ -90,9 +96,10 @@ public class Timer {
if (passedRound == (byte) 1) pbTracking = true;
try {
gameFile.setSegment(passedRound, roundTime);
RecordManager.compareSegment(passedRound, roundTime, category);
if (pbTracking) RecordManager.compareBest(passedRound, gameTime, category);
gameFile.setSegment(passedRound, roundTime);
} catch (IndexOutOfBoundsException exception) {
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(
String.format("Split not recorded. (invalid round parsed from scoreboard: %s)", passedRound)

View file

@ -3,6 +3,7 @@ package com.github.stachelbeere1248.zombiesutils.timer.recorder;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.data.CategoryData;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.files.CategoryFile;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import org.apache.commons.io.FileUtils;
import org.jetbrains.annotations.NotNull;
@ -12,44 +13,45 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FileManager {
private static CategoryData readDataFromFile(@NotNull File file) throws FileNotFoundException {
private static CategoryData readDataFromFile(@NotNull File file) throws FileNotFoundException, JsonSyntaxException {
if (!file.exists()) throw new FileNotFoundException();
String dataJson;
Gson gson = new Gson();
try {
dataJson = FileUtils.readFileToString(file, StandardCharsets.UTF_16);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (dataJson == null || dataJson.trim().isEmpty()) throw new JsonSyntaxException("File empty");
return gson.fromJson(dataJson, CategoryData.class);
}
public static void createDataFile(@NotNull SplitsFile splitsFile) {
public static void createDataFile(@NotNull SplitsFile file, ISplitsData data) {
try {
//noinspection ResultOfMethodCallIgnored
splitsFile.getParentFile().mkdirs();
file.getParentFile().mkdirs();
//noinspection ResultOfMethodCallIgnored
splitsFile.createNewFile();
writeDataToFile(splitsFile);
file.createNewFile();
writeDataToFile(file, data);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void writeDataToFile(SplitsFile splitsFile) throws IOException {
FileUtils.writeStringToFile(splitsFile, splitsFile.getData().toJSON(), StandardCharsets.UTF_16);
public static void writeDataToFile(SplitsFile file, @NotNull ISplitsData data) throws IOException {
FileUtils.writeStringToFile(file, data.toJSON(), StandardCharsets.UTF_16);
}
@NotNull
public static CategoryData categoryReadOrCreate(CategoryFile file) {
CategoryData data;
try {
data = FileManager.readDataFromFile(file);
} catch (FileNotFoundException ignored) {
} catch (FileNotFoundException | JsonSyntaxException ignored) {
data = new CategoryData(file.getGameMode().getMap());
FileManager.createDataFile(file);
FileManager.createDataFile(file, data);
}
return data;
}

View file

@ -13,5 +13,4 @@ public abstract class SplitsFile extends File {
super(category, child);
}
abstract public ISplitsData getData();
}

View file

@ -11,7 +11,7 @@ public class CategoryData implements ISplitsData {
private final short[] bestSegments; //in ticks, max ~27 min
private final int[] personalBests; //in ticks,
public CategoryData(@NotNull Map map) {
public CategoryData(@NotNull Map map) throws IllegalStateException {
switch (map) {
case ALIEN_ARCADIUM:
bestSegments = new short[105];
@ -29,10 +29,10 @@ public class CategoryData implements ISplitsData {
Arrays.fill(personalBests, 0);
}
@Override
@Override @NotNull
public String toJSON() {
Gson gson = new Gson();
return gson.toJson(this);
return gson.toJson(this, CategoryData.class);
}
public short getBestSegment(int index) {

View file

@ -10,7 +10,7 @@ import java.util.Arrays;
public class GameData implements ISplitsData {
private final short[] segments;
public GameData(@NotNull Map map) {
public GameData(@NotNull Map map) throws IllegalStateException {
switch (map) {
case ALIEN_ARCADIUM:
segments = new short[105];
@ -25,7 +25,7 @@ public class GameData implements ISplitsData {
Arrays.fill(segments, (short) 0);
}
@Override
@Override @NotNull
public String toJSON() {
Gson gson = new Gson();
return gson.toJson(this.segments);

View file

@ -1,14 +1,16 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder.files;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.FileManager;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.ISplitsData;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.SplitsFile;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.data.CategoryData;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
public class CategoryFile extends SplitsFile {
private final CategoryData data;
@ -19,20 +21,21 @@ public class CategoryFile extends SplitsFile {
// Content encoded in StandardCharsets.UTF_16
super(category, gameMode.getMap() + "_" + gameMode.getDifficulty() + ".times");
this.gameMode = gameMode;
data = FileManager.categoryReadOrCreate(this);
this.data = FileManager.categoryReadOrCreate(this);
}
public short getBestSegment(int round) {
return data.getBestSegment(round - 1);
return this.data.getBestSegment(round - 1);
}
public void setBestSegment(int round, short ticks) {
data.setBestSegment(round - 1, ticks);
this.data.setBestSegment(round - 1, ticks);
try {
FileManager.writeDataToFile(this);
} catch (IOException e) {
throw new RuntimeException(e);
FileManager.writeDataToFile(this, this.data);
} catch (Exception e) {
ZombiesUtils.getInstance().getLogger().error(ExceptionUtils.getStackTrace(e));
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Error saving segment to splits-file. Please Contact Stachelbeere1248."));
}
}
@ -41,12 +44,13 @@ public class CategoryFile extends SplitsFile {
}
public void setPersonalBest(int round, int ticks) {
data.setPersonalBest(round - 1, ticks);
this.data.setPersonalBest(round - 1, ticks);
try {
FileManager.writeDataToFile(this);
} catch (IOException e) {
throw new RuntimeException(e);
FileManager.writeDataToFile(this, this.data);
} catch (Exception e) {
ZombiesUtils.getInstance().getLogger().error(ExceptionUtils.getStackTrace(e));
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Error saving pb to splits-file. Please Contact Stachelbeere1248."));
}
}
@ -54,8 +58,4 @@ public class CategoryFile extends SplitsFile {
return gameMode;
}
@Override
public ISplitsData getData() {
return data;
}
}

View file

@ -1,15 +1,17 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder.files;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.FileManager;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.ISplitsData;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.SplitsFile;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.data.GameData;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
@ -18,28 +20,25 @@ public class GameFile extends SplitsFile {
private final GameData data;
public GameFile(String serverNumber, Map map) {
super(new File("zombies", "runs"), formattedTime() + "_" + serverNumber + ".seg");
data = new GameData(map);
FileManager.createDataFile(this);
super("zombies" + File.separator + "runs", formattedTime() + "_" + serverNumber + ".seg");
this.data = new GameData(map);
FileManager.createDataFile(this, this.data);
}
private static @NotNull String formattedTime() {
@NotNull
private static String formattedTime() {
final LocalDateTime dateTime = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES);
return dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME).replace(':', '-').replaceFirst("T", "_");
}
public void setSegment(int round, short ticks) {
data.setSegment(round - 1, ticks);
this.data.setSegment(round - 1, ticks);
try {
FileManager.writeDataToFile(this);
} catch (IOException e) {
throw new RuntimeException(e);
FileManager.writeDataToFile(this, this.data);
} catch (Exception e) {
ZombiesUtils.getInstance().getLogger().error(ExceptionUtils.getStackTrace(e));
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Error saving segment to run-file. Please Contact Stachelbeere1248."));
}
}
@Override
public ISplitsData getData() {
return data;
}
}

View file

@ -0,0 +1,93 @@
package com.github.stachelbeere1248.zombiesutils.utils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;
import java.util.regex.Pattern;
@SuppressWarnings("SpellCheckingInspection")
public class LanguageSupport {
private static final EnumMap<Languages, Pattern> scoreboardRound = scoreboardRoundMap();
private static final EnumMap<Languages, Pattern> scoreboardMap = scoreboardMapMap();
public static boolean zombies_utils$isLoss(@NotNull String input) {
final String[] words = {
"§cGame Over!",
"§cPartie terminée!",
"§cDas Spiel ist vorbei!"
};
return Arrays.asList(words).contains(input);
}
public static boolean zombies_utils$isWin(@NotNull String input) {
final String[] words = {
"§aYou Win!",
"§aVous avez gagné!",
"§aDu gewinnst!"
};
return Arrays.asList(words).contains(input);
}
public static boolean containsHard(@NotNull String input) {
final String[] words = {
"Hard Difficulty",
"Difficulté Hard",
"Hard Schwierigkeitsgrad",
"困难",
"困難"
};
return Arrays.stream(words).anyMatch(input::contains);
}
public static boolean containsRIP(@NotNull String input) {
final String[] words = {
"RIP Difficulty",
"Difficulté RIP",
"RIP Schwierigkeitsgrad",
"安息"
};
return Arrays.stream(words).anyMatch(input::contains);
}
private static @NotNull EnumMap<Languages, Pattern> scoreboardRoundMap() {
final EnumMap<Languages, Pattern> newMap = new EnumMap<>(Languages.class);
newMap.put(Languages.EN, Pattern.compile("Round ([0-9]{1,3})"));
newMap.put(Languages.FR, Pattern.compile("Manche ([0-9]{1,3})"));
newMap.put(Languages.DE, Pattern.compile("Runde ([0-9]{1,3})"));
return newMap;
}
private static @NotNull EnumMap<Languages, Pattern> scoreboardMapMap() {
final EnumMap<Languages, Pattern> newMap = new EnumMap<>(Languages.class);
newMap.put(Languages.EN, Pattern.compile("Map:.*(Dead End|Bad Blood|Alien Arcadium)"));
newMap.put(Languages.FR, Pattern.compile("Carte:.*(Dead End|Bad Blood|Alien Arcadium)"));
newMap.put(Languages.DE, Pattern.compile("Karte:.*(Dead End|Bad Blood|Alien Arcadium)"));
return newMap;
}
public static Pattern roundPattern(Languages lang) {
return scoreboardRound.get(lang);
}
public static Pattern mapPattern(Languages lang) {
return scoreboardMap.get(lang);
}
public enum Languages {
EN,
FR,
DE;
public static String @NotNull [] list() {
List<String> langs = new ArrayList<>();
for (Languages language: Languages.values()
) {
langs.add(language.toString());
}
return langs.toArray(new String[1]);
}
}
}

View file

@ -1,6 +1,7 @@
package com.github.stachelbeere1248.zombiesutils.utils;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.config.ZombiesUtilsConfig;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@ -20,9 +21,7 @@ public class Scoreboard {
@SuppressWarnings("UnnecessaryUnicodeEscape")
private static final Pattern SIDEBAR_EMOJI_PATTERN = Pattern.compile("[\uD83D\uDD2B\uD83C\uDF6B\uD83D\uDCA3\uD83D\uDC7D\uD83D\uDD2E\uD83D\uDC0D\uD83D\uDC7E\uD83C\uDF20\uD83C\uDF6D\u26BD\uD83C\uDFC0\uD83D\uDC79\uD83C\uDF81\uD83C\uDF89\uD83C\uDF82]+");
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("§[0-9A-FK-ORZ]", Pattern.CASE_INSENSITIVE);
private static final Pattern ROUND_LINE_PATTERN = Pattern.compile("(Round )([0-9]{1,3})");
private static final Pattern SERVER_NUMBER_PATTERN = Pattern.compile(".*([mLM][0-9A-Z]+)");
private static final Pattern MAP_PATTERN = Pattern.compile("Map:.*(Dead End|Bad Blood|Alien Arcadium)");
private static String title = null;
private static List<String> lines = null;
@ -68,8 +67,9 @@ public class Scoreboard {
} catch (IndexOutOfBoundsException | NullPointerException ignored) {
return 0;
}
final Pattern ROUND_LINE_PATTERN = LanguageSupport.roundPattern(ZombiesUtilsConfig.getLanguage());
String string = ROUND_LINE_PATTERN.matcher(line).replaceAll("$2");
String string = ROUND_LINE_PATTERN.matcher(line).replaceAll("$1");
byte round;
try {
@ -105,6 +105,7 @@ public class Scoreboard {
return Optional.empty();
}
}
final Pattern MAP_PATTERN = LanguageSupport.mapPattern(ZombiesUtilsConfig.getLanguage());
String mapString = MAP_PATTERN.matcher(line).replaceAll("$1");
switch (mapString) {
case "Dead End":