adding game tracking

This commit is contained in:
Stachelbeere1248 2023-11-29 22:46:41 +01:00
parent 1a888e0457
commit c30f4c3731
20 changed files with 294 additions and 167 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.0
version = 1.2.1

View file

@ -2,6 +2,7 @@ package com.github.stachelbeere1248.zombiesutils;
import com.github.stachelbeere1248.zombiesutils.commands.CategoryCommand;
import com.github.stachelbeere1248.zombiesutils.commands.SlaCommand;
import com.github.stachelbeere1248.zombiesutils.commands.ZombiesUtilsCommand;
import com.github.stachelbeere1248.zombiesutils.config.Hotkeys;
import com.github.stachelbeere1248.zombiesutils.config.ZombiesUtilsConfig;
import com.github.stachelbeere1248.zombiesutils.handlers.ChatHandler;
@ -49,6 +50,7 @@ public class ZombiesUtils {
ClientCommandHandler.instance.registerCommand(new CategoryCommand());
ClientCommandHandler.instance.registerCommand(new SlaCommand());
ClientCommandHandler.instance.registerCommand(new ZombiesUtilsCommand());
hotkeys.registerAll();
}

View file

@ -1,6 +1,5 @@
package com.github.stachelbeere1248.zombiesutils.handlers;
import com.github.stachelbeere1248.zombiesutils.ZombiesUtils;
import com.github.stachelbeere1248.zombiesutils.game.Difficulty;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.timer.Timer;

View file

@ -29,7 +29,7 @@ public class MixinNetHandlerPlayClient {
}
@Unique
private void zombies_utils$handleSound(@NotNull S29PacketSoundEffect packet) {
if (Scoreboard.isZombies()) return;
if (Scoreboard.isNotZombies()) return;
final String soundEffect = packet.getSoundName();
if (!(
soundEffect.equals("mob.wither.spawn")
@ -74,7 +74,7 @@ public class MixinNetHandlerPlayClient {
final String message = packet.getMessage().getUnformattedText().trim();
Timer.getInstance().ifPresent(timer -> {
if (Scoreboard.isZombies()) return;
if (Scoreboard.isNotZombies()) return;
if (message.equals("§aYou Win!")) {
switch (timer.getGameMode().getMap()) {

View file

@ -43,7 +43,7 @@ public class RenderGameOverlayHandler {
}
private void renderTime(long timerTicks) {
if (Scoreboard.isZombies()) return;
if (Scoreboard.isNotZombies()) return;
final String time = getTimeString(timerTicks);
final int width = fontRenderer.getStringWidth(time);
@ -75,6 +75,8 @@ public class RenderGameOverlayHandler {
}
}
private void renderSpawnTime(byte @NotNull [] waveTimes, short roundTicks) {
if (Scoreboard.isNotZombies()) return;
final int length = waveTimes.length + 1;
int heightIndex = 0;
int color = 0xFFFF55;

View file

@ -1,7 +1,7 @@
package com.github.stachelbeere1248.zombiesutils.timer;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.Category;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.TimesFile;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.files.CategoryFile;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import org.jetbrains.annotations.Contract;
@ -16,10 +16,10 @@ public class RecordManager {
@SuppressWarnings("OptionalGetWithoutIsPresent")
final TimesFile timesFile = category.getByGameMode(Timer.getInstance().get().getGameMode());
short bestSegment = timesFile.getBestSegment(round);
final CategoryFile categoryFile = category.getByGameMode(Timer.getInstance().get().getGameMode());
short bestSegment = categoryFile.getBestSegment(round);
if (bestSegment == (short) 0) {
timesFile.setBestSegment(round, roundTime);
categoryFile.setBestSegment(round, roundTime);
segmentMessage += "\n§e§l***§6§l NEW BEST SEGMENT! §e§l***";
final String timeString = formattedTime(roundTime);
@ -27,7 +27,7 @@ public class RecordManager {
} else {
if (roundTime<bestSegment) {
segmentMessage += "\n§e§l***§6§l NEW BEST SEGMENT! §e§l***";
timesFile.setBestSegment(round, roundTime);
categoryFile.setBestSegment(round, roundTime);
}
final String timeString = formattedTime(roundTime);
segmentMessage += "\n§cRound " + round + "§e took §a" + timeString + " §9" + formattedDelta(roundTime,bestSegment);
@ -41,10 +41,10 @@ public class RecordManager {
;
@SuppressWarnings("OptionalGetWithoutIsPresent")
final TimesFile timesFile = category.getByGameMode(Timer.getInstance().get().getGameMode());
int personalBest = timesFile.getPersonalBest(round);
final CategoryFile categoryFile = category.getByGameMode(Timer.getInstance().get().getGameMode());
int personalBest = categoryFile.getPersonalBest(round);
if (personalBest == 0) {
timesFile.setPersonalBest(round, gameTime);
categoryFile.setPersonalBest(round, gameTime);
bestMessage += "\n§e§l***§6§l NEW PERSONAL BEST! §e§l***";
final String timeString = formattedTime(gameTime);
@ -52,7 +52,7 @@ public class RecordManager {
} else {
if (gameTime<personalBest) {
bestMessage += "\n§e§l***§6§l NEW PERSONAL BEST! §e§l***";
timesFile.setPersonalBest(round, gameTime);
categoryFile.setPersonalBest(round, gameTime);
}
final String timeString = formattedTime(gameTime);

View file

@ -6,6 +6,8 @@ import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.github.stachelbeere1248.zombiesutils.game.sla.SLA;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.Category;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.FileManager;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.files.GameFile;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ChatComponentText;
import org.jetbrains.annotations.NotNull;
@ -20,6 +22,7 @@ public class Timer {
private int passedRoundsTickSum = 0;
private final String serverNumber;
public Category category;
private final GameFile gameFile;
private boolean pbTracking = false;
private int round;
@ -35,6 +38,8 @@ public class Timer {
else throw new RuntimeException("invalid servernumber");
this.category = new Category();
this.gameFile = new GameFile(serverNumber.trim(),map);
this.gameMode = new GameMode(map);
this.round = round;
if (ZombiesUtilsConfig.isSlaToggled()) SLA.instance = new SLA(map);
@ -66,6 +71,7 @@ public class Timer {
if (passedRound == (byte) 1) pbTracking = true;
try {
FileManager.
RecordManager.compareSegment(passedRound, roundTime, category);
if (pbTracking) RecordManager.compareBest(passedRound, gameTime, category);
} catch (IndexOutOfBoundsException exception) {

View file

@ -5,39 +5,41 @@ import com.github.stachelbeere1248.zombiesutils.game.Difficulty;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.github.stachelbeere1248.zombiesutils.timer.Timer;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.files.CategoryFile;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public class Category {
private static String selectedCategory = ZombiesUtilsConfig.getDefaultCategory();
public final TimesFile[] timesFiles = new TimesFile[7];
public final CategoryFile[] categoryFiles = new CategoryFile[7];
private final String name;
public Category() {
timesFiles[0] = new TimesFile(selectedCategory, new GameMode(Map.DEAD_END));
timesFiles[1] = new TimesFile(selectedCategory, new GameMode(Map.DEAD_END, Difficulty.HARD));
timesFiles[2] = new TimesFile(selectedCategory, new GameMode(Map.DEAD_END, Difficulty.RIP));
final File category = new File("zombies" + File.separator + "splits" + File.separator + selectedCategory);
categoryFiles[0] = new CategoryFile(category, new GameMode(Map.DEAD_END));
categoryFiles[1] = new CategoryFile(category, new GameMode(Map.DEAD_END, Difficulty.HARD));
categoryFiles[2] = new CategoryFile(category, new GameMode(Map.DEAD_END, Difficulty.RIP));
timesFiles[3] = new TimesFile(selectedCategory, new GameMode(Map.BAD_BLOOD));
timesFiles[4] = new TimesFile(selectedCategory, new GameMode(Map.BAD_BLOOD, Difficulty.HARD));
timesFiles[5] = new TimesFile(selectedCategory, new GameMode(Map.BAD_BLOOD, Difficulty.RIP));
categoryFiles[3] = new CategoryFile(category, new GameMode(Map.BAD_BLOOD));
categoryFiles[4] = new CategoryFile(category, new GameMode(Map.BAD_BLOOD, Difficulty.HARD));
categoryFiles[5] = new CategoryFile(category, new GameMode(Map.BAD_BLOOD, Difficulty.RIP));
timesFiles[6] = new TimesFile(selectedCategory, new GameMode(Map.ALIEN_ARCADIUM));
name = selectedCategory;
categoryFiles[6] = new CategoryFile(category, new GameMode(Map.ALIEN_ARCADIUM));
this.name = Category.selectedCategory;
}
public TimesFile getByGameMode(@NotNull GameMode gameMode) {
if (gameMode.is(Map.DEAD_END, Difficulty.NORMAL)) return timesFiles[0];
else if (gameMode.is(Map.BAD_BLOOD, Difficulty.NORMAL)) return timesFiles[3];
else if (gameMode.is(Map.ALIEN_ARCADIUM, Difficulty.NORMAL)) return timesFiles[6];
public CategoryFile getByGameMode(@NotNull GameMode gameMode) {
if (gameMode.is(Map.DEAD_END, Difficulty.NORMAL)) return categoryFiles[0];
else if (gameMode.is(Map.BAD_BLOOD, Difficulty.NORMAL)) return categoryFiles[3];
else if (gameMode.is(Map.ALIEN_ARCADIUM, Difficulty.NORMAL)) return categoryFiles[6];
else if (gameMode.is(Map.DEAD_END, Difficulty.HARD)) return timesFiles[1];
else if (gameMode.is(Map.DEAD_END, Difficulty.RIP)) return timesFiles[2];
else if (gameMode.is(Map.DEAD_END, Difficulty.HARD)) return categoryFiles[1];
else if (gameMode.is(Map.DEAD_END, Difficulty.RIP)) return categoryFiles[2];
else if (gameMode.is(Map.BAD_BLOOD, Difficulty.HARD)) return timesFiles[4];
else if (gameMode.is(Map.BAD_BLOOD, Difficulty.RIP)) return timesFiles[5];
else if (gameMode.is(Map.BAD_BLOOD, Difficulty.HARD)) return categoryFiles[4];
else if (gameMode.is(Map.BAD_BLOOD, Difficulty.RIP)) return categoryFiles[5];
else throw new IllegalStateException("Unexpected value: " + gameMode);
}

View file

@ -1,39 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.google.gson.Gson;
import java.util.Arrays;
public class FileData{
private final short[] bestSegments; //in ticks, max ~27 min
private final int[] personalBests; //in ticks,
public FileData(Map map) {
if (map == Map.ALIEN_ARCADIUM) {
bestSegments = new short[105];
personalBests = new int[105];
} else {
bestSegments = new short[30];
personalBests = new int[30];
}
Arrays.fill(bestSegments, (short) 0);
Arrays.fill(personalBests, 0);
}
public String getAsJsonString() {
Gson gson = new Gson();
return gson.toJson(this, FileData.class);
}
public short getBestSegment(int index) {
return bestSegments[index];
}
public int getPersonalBest(int index) {
return personalBests[index];
}
void setBestSegment(int index, short ticks) {
bestSegments[index] = ticks;
}
void setPersonalBest(int index, int ticks) {
personalBests[index] = ticks;
}
}

View file

@ -0,0 +1,53 @@
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 org.apache.commons.io.FileUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FileManager {
private static CategoryData readDataFromFile(@NotNull File file) throws FileNotFoundException {
if (!file.exists()) throw new FileNotFoundException();
String dataJson;
Gson gson = new Gson();
try {
dataJson = FileUtils.readFileToString(file, StandardCharsets.US_ASCII);
} catch (IOException e) {
throw new RuntimeException(e);
}
return gson.fromJson(dataJson, CategoryData.class);
}
public static void createDataFile(ISplitsData splitsData, @NotNull SplitsFile splitsFile) {
try {
//noinspection ResultOfMethodCallIgnored
splitsFile.getParentFile().mkdirs();
//noinspection ResultOfMethodCallIgnored
splitsFile.createNewFile();
writeDataToFile(splitsData, splitsFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void writeDataToFile(@NotNull ISplitsData splitsData, SplitsFile splitsFile) throws IOException {
FileUtils.writeStringToFile(splitsFile, splitsData.toJSON(), StandardCharsets.US_ASCII);
}
public static CategoryData categoryReadOrCreate(CategoryFile file) {
CategoryData data;
try {
data = FileManager.readDataFromFile(file);
} catch (FileNotFoundException ignored) {
data = new CategoryData(file.getGameMode().getMap());
FileManager.createDataFile(data, file);
}
return data;
}
}

View file

@ -0,0 +1,5 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
public interface ISplitsData {
String toJSON();
}

View file

@ -0,0 +1,15 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public abstract class SplitsFile extends File {
public SplitsFile(String parent, @NotNull String child) {
super(parent, child);
}
public SplitsFile(File category, String child) {
super(category, child);
}
abstract public ISplitsData getData();
}

View file

@ -1,38 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder;
import com.github.stachelbeere1248.zombiesutils.game.GameMode;
import com.github.stachelbeere1248.zombiesutils.utils.FileManager;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public class TimesFile extends File {
private final FileData fileData;
private final GameMode gameMode;
public TimesFile(String category, @NotNull GameMode gameMode) {
// Game-directory -> custom category -> file named "MAP_DIFFICULTY.times"
// Content encoded in StandardCharsets.UTF_16
super("zombies" + File.separator + "splits" + File.separator + category,gameMode.getMap() + "_" + gameMode.getDifficulty() + ".times");
this.gameMode = gameMode;
fileData = FileManager.readOrCreate(this);
}
public short getBestSegment(int round) {
return fileData.getBestSegment(round-1);
}
public void setBestSegment(int round, short ticks) {
fileData.setBestSegment(round-1, ticks);
FileManager.writeDataToFile(fileData,this);
}
public int getPersonalBest(int round) {
return fileData.getPersonalBest(round-1);
}
public void setPersonalBest(int round, int ticks) {
fileData.setPersonalBest(round-1, ticks);
FileManager.writeDataToFile(fileData,this);
}
public GameMode getGameMode() {
return gameMode;
}
}

View file

@ -0,0 +1,47 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder.data;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.ISplitsData;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
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) {
switch (map) {
case ALIEN_ARCADIUM:
bestSegments = new short[105];
personalBests = new int[105];
break;
case DEAD_END: case BAD_BLOOD:
bestSegments = new short[30];
personalBests = new int[30];
break;
default:
throw new IllegalStateException("Not a map: " + map);
}
Arrays.fill(bestSegments, (short) 0);
Arrays.fill(personalBests, 0);
}
@Override
public String toJSON() {
Gson gson = new Gson();
return gson.toJson(this, CategoryData.class);
}
public short getBestSegment(int index) {
return bestSegments[index];
}
public int getPersonalBest(int index) {
return personalBests[index];
}
public void setBestSegment(int index, short ticks) {
bestSegments[index] = ticks;
}
public void setPersonalBest(int index, int ticks) {
personalBests[index] = ticks;
}
}

View file

@ -0,0 +1,38 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder.data;
import com.github.stachelbeere1248.zombiesutils.game.Map;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.ISplitsData;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public class GameData implements ISplitsData {
private final short[] segments;
public GameData(@NotNull Map map) {
switch (map) {
case ALIEN_ARCADIUM:
segments = new short[105];
break;
case DEAD_END: case BAD_BLOOD:
segments = new short[30];
break;
default:
throw new IllegalStateException("Not a map: " + map);
}
Arrays.fill(segments, (short) 0);
}
@Override
public String toJSON() {
StringBuilder JSON = new StringBuilder("[");
for (short segment: segments) {
JSON.append(segment + ',');
}
JSON.setCharAt(JSON.length()-1,']');
return JSON.toString();
}
public void setSegment(int index, short ticks) {
segments[index] = ticks;
}
}

View file

@ -0,0 +1,51 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder.files;
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 org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
public class CategoryFile extends SplitsFile {
private final CategoryData data;
private final GameMode gameMode;
public CategoryFile(File category, @NotNull GameMode gameMode) {
// Game-directory -> custom category -> file named "MAP_DIFFICULTY.times"
// Content encoded in StandardCharsets.UTF_16
super(category,gameMode.getMap() + "_" + gameMode.getDifficulty() + ".times");
this.gameMode = gameMode;
data = FileManager.categoryReadOrCreate(this);
}
public short getBestSegment(int round) {
return data.getBestSegment(round-1);
}
public void setBestSegment(int round, short ticks) {
data.setBestSegment(round-1, ticks);
try { FileManager.writeDataToFile(data,this); }
catch (IOException e) { throw new RuntimeException(e); }
}
public int getPersonalBest(int round) {
return data.getPersonalBest(round-1);
}
public void setPersonalBest(int round, int ticks) {
data.setPersonalBest(round-1, ticks);
try { FileManager.writeDataToFile(data,this); }
catch (IOException e) { throw new RuntimeException(e); }
}
public GameMode getGameMode() {
return gameMode;
}
@Override
public ISplitsData getData() {
return data;
}
}

View file

@ -0,0 +1,41 @@
package com.github.stachelbeere1248.zombiesutils.timer.recorder.files;
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 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;
public class GameFile extends SplitsFile {
private final GameData data;
public GameFile(String serverNumber, Map map) {
super("zombies" + File.separator + "runs", formattedTime() + "_" + serverNumber + ".times");
data = new GameData(map);
}
private static @NotNull String formattedTime() {
final LocalDateTime dateTime = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES);
return dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
public void setSegment(int round, short ticks) {
data.setSegment(round-1, ticks);
try { FileManager.writeDataToFile(data,this); }
catch (IOException e) { throw new RuntimeException(e); }
}
@Override
public ISplitsData getData() {
return data;
}
}

View file

@ -1,57 +0,0 @@
package com.github.stachelbeere1248.zombiesutils.utils;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.FileData;
import com.github.stachelbeere1248.zombiesutils.timer.recorder.TimesFile;
import com.google.gson.Gson;
import org.apache.commons.io.FileUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FileManager {
private static FileData readDataFromFile(@NotNull File file) throws FileNotFoundException {
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);
}
return gson.fromJson(dataJson, FileData.class);
}
private static void createDataFile(FileData fileData, @NotNull File file) {
try {
//noinspection ResultOfMethodCallIgnored
file.getParentFile().mkdirs();
//noinspection ResultOfMethodCallIgnored
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
writeDataToFile(fileData, file);
}
public static void writeDataToFile(@NotNull FileData fileData, File file) {
try {
FileUtils.writeStringToFile(file, fileData.getAsJsonString(), StandardCharsets.UTF_16);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static FileData readOrCreate(TimesFile file) {
FileData data;
try {
data = FileManager.readDataFromFile(file);
} catch (FileNotFoundException ignored) {
data = new FileData(file.getGameMode().getMap());
FileManager.createDataFile(data, file);
}
return data;
}
}

View file

@ -114,7 +114,7 @@ public class Scoreboard {
public static int getLineCount() {
return lines.size();
}
public static boolean isZombies() {
public static boolean isNotZombies() {
return (!"ZOMBIES".equals(title));
}
}

View file

@ -6,7 +6,7 @@
"version": "${version}",
"mcversion": "${mcversion}",
"url": "https://github.com/Stachelbeere1248/zombies-utils",
"updateUrl": "",
"updateUrl": "https://github.com/Stachelbeere1248/zombies-utils/releases",
"authorList": [
"Stachelbeere1248"
],