From a355f13bb37e0182184c0ed831b2110cde7b4e38 Mon Sep 17 00:00:00 2001 From: jkibbels Date: Sat, 3 Aug 2024 13:11:33 -0400 Subject: [PATCH] Added ability to flash to and from json configuration file. Handling of notes works as well to test this --- .../keeblarcraft/Commands/NoteCommands.java | 14 ++++-- .../keeblarcraft/ConfigMgr/ConfigManager.java | 48 ++++++++++++------ .../JsonClassObjects/PlayerNote.java | 49 +++++++++++++++++-- 3 files changed, 88 insertions(+), 23 deletions(-) diff --git a/src/main/java/jesse/keeblarcraft/Commands/NoteCommands.java b/src/main/java/jesse/keeblarcraft/Commands/NoteCommands.java index 33e158f..ff9f632 100644 --- a/src/main/java/jesse/keeblarcraft/Commands/NoteCommands.java +++ b/src/main/java/jesse/keeblarcraft/Commands/NoteCommands.java @@ -1,5 +1,7 @@ package jesse.keeblarcraft.Commands; +import java.util.UUID; + import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; @@ -7,6 +9,7 @@ import com.mojang.brigadier.context.CommandContext; import com.mojang.datafixers.Products.P1; import jesse.keeblarcraft.ConfigMgr.ConfigManager; +import jesse.keeblarcraft.JsonClassObjects.PlayerNote; import jesse.keeblarcraft.Utils.ChatUtil; import jesse.keeblarcraft.Utils.CustomExceptions.DIRECTORY_CREATE_EXCEPTION; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; @@ -88,13 +91,18 @@ public class NoteCommands { // // Adds a new note based on the string value provided by the player. The note is labeled in the background based on the portion // of the story they are currently in as well to help provide filtering methods later on - private int AddNote(String value, CommandContext context) { - int ret = -1; + private Integer AddNote(String value, CommandContext context) { + Integer ret = -1; if (context.getSource().isExecutedByPlayer()) { ServerPlayerEntity player = context.getSource().getPlayer(); - notesConfig.AddToKey(player.getUuidAsString(), value); + + // Note mgmt + PlayerNote note = new PlayerNote(player.getUuidAsString()); + note.AddNote(value, 1, 1, 1, 1); ChatUtil.SendPlayerMsg(player, "New note logged to entry! View notes any time with /notegui"); + + ret = 0; } else { System.out.println("Only a player can execute this command!"); } diff --git a/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java b/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java index 8000a42..c5cf80a 100644 --- a/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java +++ b/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java @@ -13,6 +13,7 @@ package jesse.keeblarcraft.ConfigMgr; import java.io.FileWriter; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import com.google.common.base.Charsets; @@ -20,7 +21,12 @@ import com.google.common.io.Files; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonIOException; +import com.google.gson.JsonSyntaxException; + import java.util.List; + +import org.apache.commons.io.FileUtils; + import java.util.ArrayList; // Import all custom exceptions @@ -121,36 +127,46 @@ public class ConfigManager { // top-level key. // // NOTE: THIS DOES NOT SAFE UPDATE THE KEY OBJECT. PRE-EXISTING DATA WILL BE DELETED FOREVER - public void WriteToJsonFile(String fileName, String key, Object data, String mode) throws FILE_WRITE_EXCEPTION { + public void WriteToJsonFile(String fileName, Object data) throws FILE_WRITE_EXCEPTION { Gson gson = new GsonBuilder().setPrettyPrinting().create(); try { - gson.toJson(data, new FileWriter(fileName)); + FileWriter writer = new FileWriter(fileName); + gson.toJson(data, writer); + writer.flush(); + writer.close(); } catch (JsonIOException | IOException e) { + System.out.println("Could not successfully write to json file"); throw new FILE_WRITE_EXCEPTION(); } } // GetJsonStringFromFile // - // Retrieves a json formatted string from the file based on key. Returns empty string if not found - public Object GetJsonObjectFromFile(String key, String fileName, Object jsonObject) { - Object ret = jsonObject.getClass(); + // Retrieves json file and converts to desired object. Returns JsonSyntaxException if file could not be fitted to class input + public T GetJsonObjectFromFile(String fileName, Class classToConvertTo) throws JsonSyntaxException { Gson gson = new Gson(); - // Step 1: Get file as 1 constant string + String ret = ""; + + // hot fix: Not sure how to return "false" for invalid conversion when I'm forced to convert or just catch... Look into a better + // return value in the future - but for now throw JsonSyntaxException no matter what exception is caught try { File file = new File(fileName); - if (file.exists()) { - String str = file.toString(); - ret = gson.fromJson(str, jsonObject.getClass()); - } else { - System.out.println("File does not exist. Cannot convert to json"); - } - - } catch (Exception e) { - System.out.println("Something went wrong when converting json file object to object"); + ret = FileUtils.readFileToString(file, "UTF-8"); + } catch (NullPointerException e) { + System.out.println("nullptr exception"); + throw new JsonSyntaxException(""); + } catch (FileNotFoundException e) { + System.out.println("file not found"); + throw new JsonSyntaxException(""); + } catch (java.nio.charset.UnsupportedCharsetException e) { + System.out.println("charset issue"); + throw new JsonSyntaxException(""); + } catch (IOException e) { + System.out.println("io exception"); + throw new JsonSyntaxException(""); } - return ret; + return gson.fromJson(ret, classToConvertTo); } public Boolean DoesFileExist(String fileName) { diff --git a/src/main/java/jesse/keeblarcraft/JsonClassObjects/PlayerNote.java b/src/main/java/jesse/keeblarcraft/JsonClassObjects/PlayerNote.java index 828dba5..99539fa 100644 --- a/src/main/java/jesse/keeblarcraft/JsonClassObjects/PlayerNote.java +++ b/src/main/java/jesse/keeblarcraft/JsonClassObjects/PlayerNote.java @@ -12,6 +12,7 @@ import java.util.HashMap; import java.util.Map.Entry; import jesse.keeblarcraft.ConfigMgr.ConfigManager; +import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION; public class PlayerNote { @@ -66,15 +67,45 @@ public class PlayerNote { NoteFile thisNote = new NoteFile(); ConfigManager config = new ConfigManager(); + class TestClass { + String testString; + } + + // PlayerNote + // + // String uuid - The uuid of the player (used in searching for existing notes file and writing to it) public PlayerNote(String uuid) { - /// TODO: Below code needs to be tested first - /// TODO: It's possible the below code may prove to be incredibly slow on large files and should probably - /// TODO: introduce a secondary load method where it only finds the file pointer and doesn't bother returning file contents as well - thisNote = (NoteFile) config.GetJsonObjectFromFile(uuid, uuid, NoteFile.class); + + // DEVELOPER NOTE: + // If you are testing this part of the code, please be reminded that anonymous testing starts a new + // player instance everytime you launch. This means the UUID CAN CHANGE when you launch the + // game! This is not an issue with proper registered accounts in production + Boolean existingFile = false; + try { + thisNote = config.GetJsonObjectFromFile("notes/" + uuid + ".json", NoteFile.class); + existingFile = true; + } catch (Exception e) { + // Do nothing. This means the file does not exist + } + + // In the event the above code failed out, this means a new file has to be created for the player's uuid + if (!existingFile) + { + System.out.println("Trying to create new file"); + try { + thisNote.uuid = uuid; + FlashConfig(); + } catch (Exception e) { + System.out.println("Could not write to file"); + } + } else { + System.out.println("Moving on"); + } // It's possible the above code will return a blank class if a file doesn't exist. This will make // a new file with this players uuid if ("".equals(thisNote.uuid)) { + System.out.println("Assigning new config file for this uuid. No previous existing"); thisNote.uuid = uuid; } } @@ -82,6 +113,8 @@ public class PlayerNote { public void AddNote(String newNote, long minecraftDay, long systemTime, long storyChapter, long storyPart) { Integer noteKey = thisNote.noteMap.size() + 1; thisNote.noteMap.put(noteKey, new NoteMetadata(newNote, noteKey, minecraftDay, systemTime, storyChapter, storyPart)); + + FlashConfig(); ///TODO: This might be really unnecessary and may only be required on clean up as opposed to everytime the command is run } public void DeleteNote(Integer noteId) { @@ -104,4 +137,12 @@ public class PlayerNote { return ret; } + + public void FlashConfig() { + try { + config.WriteToJsonFile("notes/" + thisNote.uuid.toString() + ".json", thisNote); + } catch (FILE_WRITE_EXCEPTION e) { + System.out.println("Could not flash notes configuration file"); + } + } }