[UNTESTED] Committing for historical reasons. Started to add SOME structure to code (though not done and needs refactoring). Have untested code and a thought at how starting up mod will be

This commit is contained in:
jkibbels 2024-07-28 20:13:48 -04:00
parent b8bcee9d7b
commit edd33c05fa
9 changed files with 766 additions and 17 deletions

View File

@ -12,7 +12,6 @@ import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import jesse.keeblarcraft.Commands.ShortcutCommands;
public class CustomCommandManager {
// Intentionally empty constructor since at object definition time it may not be possible to register commands
@ -36,10 +35,12 @@ public class CustomCommandManager {
// CUSTOM COMMAND CLASS OBJECTS BELOW
ShortcutCommands shortcuts = new ShortcutCommands();
NoteCommands noteCommands = new NoteCommands();
// REGISTER COMMANDS BELOW
System.out.println("REGISTERING CUSTOM COMMAND EXTENSIONS BELOW");
shortcuts.RegisterShortcutCommands();
noteCommands.RegisterNoteCommands();
}

View File

@ -0,0 +1,132 @@
package jesse.keeblarcraft.Commands;
public class FactionCommands {
// Register function for commands
public void RegisterFactionCommands() {
}
/// PRIVATE HANDLERS BELOW
private int CreateFaction() {
int retValue = -1;
return retValue;
}
private int DeleteFaction() {
int retValue = -1;
return retValue;
}
private int AddPlayerToFaction() {
int retValue = -1;
return retValue;
}
private int KickPlayerFromFaction() {
int retValue = -1;
return retValue;
}
private int PromotePlayerInFaction() {
int retValue = -1;
return retValue;
}
private int DemotePlayerInFaction() {
int retValue = -1;
return retValue;
}
private int SetPlayerRoleInFaction() {
int retValue = -1;
return retValue;
}
private int DeclareFactionBase() {
int retValue = -1;
return retValue;
}
// admin only
private int SetFactionPower() {
int retValue = -1;
return retValue;
}
private int DeclareFactionEvent() {
int retValue = -1;
return retValue;
}
private int DeclareEnemyFaction() {
int retValue = -1;
return retValue;
}
private int DeclareAlliedFaction() {
int retValue = -1;
return retValue;
}
private int DeclareNeutralFaction() {
int retValue = -1;
return retValue;
}
private int ListAllFactions() {
int retValue = -1;
return retValue;
}
private int RegisterFactionChatChannel() {
int retValue = -1;
return retValue;
}
// admin only
private int DeleteFactionChatChannel() {
int retValue = -1;
return retValue;
}
private int DepositToFactionBank() {
int retValue = -1;
return retValue;
}
private int WithdrawFromFactionBank() {
int retValue = -1;
return retValue;
}
private int FactionBankBalance() {
int retValue = -1;
return retValue;
}
private int ListFactionBankTransactions() {
int retValue = -1;
return retValue;
}
}

View File

@ -0,0 +1,135 @@
package jesse.keeblarcraft.Commands;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.datafixers.Products.P1;
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.Utils.ChatUtil;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
public class NoteCommands {
// IMPORTANT NOTE:
//
// Each player will retain their own private file of notes inside a "notes" directory inside the overall mod config directory
ConfigManager notesConfig = new ConfigManager();
String NOTES_GLOBAL_DIRECTORY = ""; // The overall "notes" dir inside cfg folder
public NoteCommands() {
// Check if directory exists
if (notesConfig.DoesDirectoryExist(NOTES_GLOBAL_DIRECTORY) == false) {
// Attempt to create the directory
if (notesConfig.CreateDirectory(NOTES_GLOBAL_DIRECTORY) == true) {
System.out.println("Created notes directory successfully!"); //TODO: Success!
} else {
System.out.println("ERROR: Notes directory FAILED to create!! Permissions missing to create directory!"); //TODO: Critical failure
}
} else {
System.out.println("Notes directory already exists. Skipping creation..."); //TODO: Success!
}
}
public void RegisterNoteCommands() {
// Command: "/addnote note goes here"
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("addnote")
.then(CommandManager.argument("value", StringArgumentType.greedyString())
.executes(context -> AddNote(StringArgumentType.getString(context, "value"), context))));
});
// Command: "/delnote noteIdHere"
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
// dispatcher.register(CommandManager.literal("delnote")
// .then(CommandManager.argument("value", StringArgumentType.greedyString())
// .executes(context -> AddNote(StringArgumentType.getString(context, "value"), context))));
// });
// Command: "/purgenotes"
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("purgenotes")
.then(CommandManager.argument("value", StringArgumentType.greedyString())
.executes(context -> PurgeAllNotes(StringArgumentType.getString(context, "value"), context))));
});
// Command: "/modifynote noteIdHere"
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("editnote")
.then(CommandManager.argument("value", IntegerArgumentType.integer())
.executes(context -> ModifyNote(IntegerArgumentType.getInteger(context, "value"), context))));
});
// Command Root: "/delnote noteIdHere"
// Aliases: "/rmnote", "/deletenote"
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
final var rootDeleteCmd = dispatcher.register(CommandManager.literal("delnote")
.then(CommandManager.argument("value", IntegerArgumentType.integer())
.executes(context -> DeleteNote(IntegerArgumentType.getInteger(context, "value"), context))));
// Alias redirects
dispatcher.register(CommandManager.literal("rmnote").redirect(rootDeleteCmd));
dispatcher.register(CommandManager.literal("deletenote").redirect(rootDeleteCmd));
});
}
/// COMMAND HANDLERS BELOW
// AddNote
//
// 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<ServerCommandSource> context) {
int ret = -1;
if (context.getSource().isExecutedByPlayer()) {
ServerPlayerEntity player = context.getSource().getPlayer();
notesConfig.AddToKey(player.getUuidAsString(), value);
ChatUtil.SendPlayerMsg(player, "New note logged to entry! View notes any time with /notegui");
} else {
System.out.println("Only a player can execute this command!");
}
return ret;
}
private int DeleteNote(int value, CommandContext<ServerCommandSource> context) {
int ret = -1;
return ret;
}
private int ModifyNote(int value, CommandContext<ServerCommandSource> context) {
int ret = -1;
return ret;
}
private int PurgeAllNotes(String value, CommandContext<ServerCommandSource> context) {
int ret = -1;
return ret;
}
private int ListNotes(String value, CommandContext<ServerCommandSource> context) {
int ret = -1;
return ret;
}
private int OpenNoteGui(String value, CommandContext<ServerCommandSource> context) {
int ret = -1;
return ret;
}
private int FilterForNote(String value, CommandContext<ServerCommandSource> context) {
int ret = -1;
return ret;
}
}

View File

@ -1,8 +1,9 @@
/*
*
* ShortcutCommands
*
* A class that simplifies some of the current vanilla commands with shortcut commands in the game
*
* A class that simplifies some of the current vanilla commands with shortcut commands in the game. You may remember an old plugin
* called "Essentials" (Or EssentialsEx in a later version) -> This file is re-creating a portion of that plugin but in mod-format
*/
package jesse.keeblarcraft.Commands;
@ -10,31 +11,62 @@ package jesse.keeblarcraft.Commands;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.context.CommandContext;
import jesse.keeblarcraft.Utils.ChatUtil;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.entity.player.PlayerAbilities;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
public class ShortcutCommands {
float DEFAULT_FLIGHT_SPEED = 0.05f; // Minecraft operates on a 0.0 -> 1.0 scale; with each .01 making a difference in speed. 0.05 is creative flight speed
float SPEED_SCALAR = 20.0f; // For clamping speed down to half of its max output (So 0.5 will be max speed on a system that goes up in 0.05'ths)
public void RegisterShortcutCommands()
{
// Abstract handling "value" to parse gamemodes 0-2 (survival; creative; spectator)
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("gm")
.then(CommandManager.argument("value", IntegerArgumentType.integer())
.executes(context -> CreativeShortcut(IntegerArgumentType.getInteger(context, "value"), context))));
.executes(context -> GamemodeShortcut(IntegerArgumentType.getInteger(context, "value"), context))));
});
// Fly command ///TODO: Is this just being condensed into the FlightSpeedShortcut fn?
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("fly")
.executes(context -> { FlightShortcut(context);
return 0;
}));
});
// Fly command with speed
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("fly")
.then(CommandManager.argument("value", IntegerArgumentType.integer())
.executes(context -> FlightSpeedShortcut(IntegerArgumentType.getInteger(context, "value"), context))));
});
///TODO: Read TODO on function
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
// dispatcher.register(CommandManager.literal("walk")
// .then(CommandManager.argument("value", IntegerArgumentType.integer())
// .executes(context -> WalkSpeedShortcut(IntegerArgumentType.getInteger(context, "value"), context))));
// });
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("heal")
.executes(context -> { HealShortcut(context);
return 0;
}));
});
}
/// Command handlers below
private int CreativeShortcut(int value, CommandContext<ServerCommandSource> context)
private int GamemodeShortcut(int value, CommandContext<ServerCommandSource> context)
{
int retValue = -1;
context.getSource().sendMessage(Text.literal("You sent value: " + value));
if (context.getSource().isExecutedByPlayer()) {
ServerPlayerEntity player = context.getSource().getPlayer();
@ -42,7 +74,6 @@ public class ShortcutCommands {
if(player.hasPermissionLevel(4)) {
switch(value) {
case 0:
/// TODO: Add type checking & permission
player.changeGameMode(net.minecraft.world.GameMode.SURVIVAL);
player.sendMessage(Text.literal("Changing your game mode to SURVIVAL"));
retValue = 0;
@ -74,5 +105,106 @@ public class ShortcutCommands {
return retValue;
}
private int FlightShortcut(CommandContext<ServerCommandSource> context) {
int retValue = -1;
if (context.getSource().isExecutedByPlayer()) {
ServerPlayerEntity player = context.getSource().getPlayer();
if (player.hasPermissionLevel(4)) {
PlayerAbilities abilities = player.getAbilities();
abilities.flying = !abilities.flying; // Toggle flying
abilities.setFlySpeed(DEFAULT_FLIGHT_SPEED); // It seems flight speed is on a 0-1 scale
player.sendAbilitiesUpdate();
ChatUtil.SendPlayerMsg(player, "You can now fly! Flight speed is " + abilities.getFlySpeed());
} else {
player.sendMessage(Text.literal("You do not have permission for this command"));
}
}
return retValue;
}
private int FlightSpeedShortcut(int value, CommandContext<ServerCommandSource> context) {
int retValue = -1;
if (context.getSource().isExecutedByPlayer()) {
ServerPlayerEntity player = context.getSource().getPlayer();
if (player.hasPermissionLevel(4)) {
PlayerAbilities abilities = player.getAbilities();
if (value >= 1 && value <= 10) {
abilities.allowFlying = true;
abilities.setFlySpeed((float) (value / SPEED_SCALAR)); // Dividing by 20f yields max clamp value of 0.5 since MC does 0.0-> 1.0 flight. 0.1 flight is too fast!
player.sendAbilitiesUpdate();
ChatUtil.SendPlayerMsg(player, "Flight speed set to " + (value));
} else {
player.sendMessage(Text.literal("Only values from 1-10 are accepted"));
}
} else {
player.sendMessage(Text.literal("You do not have permission for this command"));
}
}
return retValue;
}
///TODO: There is a bug with walk speed that causes the players speed to behave weirdly despite the value. It's either a crawl or mach 10
///TODO: It's possible that the player may need to die first to reset speed; and reloading in the debugger does not count as resetting values. This
///TODO: code may actually work; but I just did not die first in between testing speed changes.
// private int WalkSpeedShortcut(int value, CommandContext<ServerCommandSource> context) {
// int retValue = -1;
// if (context.getSource().isExecutedByPlayer()) {
// ServerPlayerEntity player = context.getSource().getPlayer();
// if (player.hasPermissionLevel(4)) {
// PlayerAbilities abilities = player.getAbilities();
// if (value >= 1 && value <= 10) {
// abilities.setWalkSpeed((float) 1.0f);
// player.sendAbilitiesUpdate();
// ChatUtil.SendPlayerMsg(player, "Set walk speed to " + (value));
// } else {
// player.sendMessage(Text.literal("Only values from 1-10 are accepted"));
// }
// } else {
// player.sendMessage(Text.literal("You do not have permission for this command"));
// }
// }
// return retValue;
// }
// TODO: Add when we can find where in the API to fill players hunger level
// private int FeedShortcut(CommandContext<ServerCommandSource> context) {
// int retValue = -1;
// if (context.getSource().isExecutedByPlayer()) {
// ServerPlayerEntity player = context.getSource().getPlayer();
// if (player.hasPermissionLevel(4)) {
// } else {
// player.sendMessage(Text.literal("You do not have permission for this command"));
// }
// }
// return retValue;
// }
private int HealShortcut(CommandContext<ServerCommandSource> context) {
int retValue = -1;
if (context.getSource().isExecutedByPlayer()) {
ServerPlayerEntity player = context.getSource().getPlayer();
if (player.hasPermissionLevel(4)) {
player.setHealth(player.getMaxHealth());
ChatUtil.SendPlayerMsg(player, "Healed!");
} else {
player.sendMessage(Text.literal("You do not have permission for this command"));
}
}
return retValue;
}
}

View File

@ -6,10 +6,175 @@
* It is typical to define this class as a general object (not static instance) for each class in single-threaded actions. If you need
* a special function or action from this class; it is recommended to add it to this class and not make your own.
*
*
*/
package jesse.keeblarcraft.ConfigMgr;
import java.io.FileWriter;
import java.io.File;
import java.io.IOException;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonIOException;
import java.util.List;
import java.util.ArrayList;
// Import all custom exceptions
import jesse.keeblarcraft.Utils.CustomExceptions.*;
public class ConfigManager {
// Pedantic empty constructor
public ConfigManager() {}
// CreateFile
//
// Returns true if file is created, will return false if file cannot be created or already exists
public Boolean CreateFile(String fileName) throws FILE_CREATE_EXCEPTION {
Boolean ret = false;
File file = new File(fileName);
// Check 1: Does the file already exist?
ret = !file.exists();
// Check 2: If the file does not exist, attempt to create it
if (ret == false) {
try {
ret = file.createNewFile();
} catch (IOException e) {
// The file could not be created
throw new FILE_CREATE_EXCEPTION();
}
}
return ret;
}
// DeleteFile
//
// Returns true if file is deleted, false if could not be deleted or does not exist
public Boolean DeleteFile(String fileName) throws FILE_DELETE_EXCEPTION {
Boolean ret = false;
File file = new File(fileName);
// Step 1: Does file exist?
ret = file.exists();
// Step 2: If file exists, attempt to delete
if (ret == true) {
try {
ret = file.delete();
} catch (SecurityException e) {
throw new FILE_DELETE_EXCEPTION();
}
}
return ret;
}
// WriteToFile
//
// Will write or append to file (valid modes: "w" or "a") if file is available. Returns false if not
public Boolean WriteToFile(String fileName, String data, String mode) {
Boolean ret = false;
return ret;
}
// WriteToJsonFile
//
// Will write to or append to a json file. It will search if the key exists first & update the field;
// or add a new entry. It should be noted that json objects *can* be buried inside each other. It is
// considered best (and only) practice to call the "GetJsonStringFromFile" function first from this
// class and simply iterate to what you would need and then update the entire entry alongside the
// 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 {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
try {
gson.toJson(data, new FileWriter(fileName));
} catch (JsonIOException | IOException e) {
throw new FILE_WRITE_EXCEPTION();
}
}
// GetJsonStringFromFile
//
// Retrieves a json formatted string from the file based on key. Returns empty string if not found
public String GetJsonStringFromFile(String fileName, String key) {
String ret = "";
return ret;
}
public Boolean DoesFileExist(String fileName) {
Boolean ret = false;
return ret;
}
public Boolean DoesDirectoryExist(String dirName) {
Boolean ret = false;
return ret;
}
public Boolean CreateDirectory(String dirName) throws DIRECTORY_CREATE_EXCEPTION {
Boolean ret = false;
File dir = new File(dirName);
try {
if (dir.exists()) {
ret = dir.mkdirs();
}
} catch (Exception e) {
throw new DIRECTORY_CREATE_EXCEPTION();
}
return ret;
}
public Boolean DeleteDirectory(String dirName) throws DIRECTORY_DELETE_EXCEPTION {
Boolean ret = false;
File dir = new File(dirName);
try {
ret = dir.delete();
} catch (Exception e) {
throw new DIRECTORY_DELETE_EXCEPTION();
}
return ret;
}
// AddToKey
//
// Adds new text to a key if found inside the config
public String AddToKey(String key, String newInfo) {
String ret = "";
return ret;
}
// GetFile
//
// Returns a file as an arraylist of all the lines in the file. Generally only used for testing
//
// NOTE: Returns UTF-8 Encoding of file
public List<String> GetFile(String fileName) {
List<String> ret = new ArrayList<String>();
try {
return Files.readLines(new File(fileName), Charsets.UTF_8);
} catch (IOException e) {
ret.clear();
}
return ret;
}
}

View File

@ -16,6 +16,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jesse.keeblarcraft.Commands.CustomCommandManager;
import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_DUAL_DEFINITION;
import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION;
import jesse.keeblarcraft.Utils.Setup;
// import com.mojang.brigadier.Command;
@ -27,6 +30,8 @@ public class Keeblarcraft implements ModInitializer {
public static final Logger LOGGER = LoggerFactory.getLogger("keeblarcraft");
CustomCommandManager cmdMgr = new CustomCommandManager();
Setup setup = Setup.GetInstance();
@Override
public void onInitialize() {
// This code runs as soon as Minecraft is in a mod-load-ready state.
@ -36,10 +41,16 @@ public class Keeblarcraft implements ModInitializer {
LOGGER.info("Hello Fabric world!");
cmdMgr.RegisterCustomCommands();
// I can't tell if this is required or not; and if it is I imagine it comes before I register the custom commands
// Command<ServerCommandSource> command = context -> {
// ServerCommandSource source = context.getSource();
// return 0;
// };
if (setup != null) {
try {
setup.RunSetup();
} catch (SETUP_FAILED_EXCEPTION e) {
System.out.println("ERROR. Setup failed to initialize environment. Mod likely does not have read/write permissions inside area. Mod will now close out.");
e.printStackTrace();
}
} else {
// Program exit. Dual definition of setup somehow happened!
System.out.println("Dual definition of singleton attempted! Out of order initialization?");
}
}
}

View File

@ -8,4 +8,13 @@
package jesse.keeblarcraft.Utils;
public class ChatUtil { }
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
public class ChatUtil {
// Helpful print wrapper function
static public void SendPlayerMsg(ServerPlayerEntity player, String text) {
player.sendMessage(Text.literal(text));
}
}

View File

@ -0,0 +1,18 @@
package jesse.keeblarcraft.Utils;
public class CustomExceptions {
// File exceptions
public static class FILE_CREATE_EXCEPTION extends Exception {}
public static class FILE_WRITE_EXCEPTION extends Exception {}
public static class FILE_DELETE_EXCEPTION extends Exception {}
// Directory exceptions
public static class DIRECTORY_DELETE_EXCEPTION extends Exception {}
public static class DIRECTORY_CREATE_EXCEPTION extends Exception {}
public static class DIRECTORY_MOVE_EXCEPTION extends Exception {}
// Setup exceptions
public static class SETUP_NO_WRITE_EXCEPTION extends Exception {}
public static class SETUP_NO_READ_EXCEPTION extends Exception {}
public static class SETUP_FAILED_EXCEPTION extends Exception {}
}

View File

@ -0,0 +1,146 @@
/*
*
* Setup.java
*
* Setup is a singleton object that runs on the initial mod setup to run critical checks to make sure the mod
* is allowed to do things on the users filesystem (reading conf files, writing conf files, etc). It's quite
* important for the mod to know this!
*
*/
package jesse.keeblarcraft.Utils;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.spongepowered.include.com.google.common.io.Files;
import java.util.List;
import java.util.ArrayList;
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.Utils.CustomExceptions.DIRECTORY_CREATE_EXCEPTION;
import jesse.keeblarcraft.Utils.CustomExceptions.DIRECTORY_DELETE_EXCEPTION;
import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION;
// Singleton class is designed to help the mod set itself up and create all the important things. It does two things:
//
// Thing 1: If on initial setup of mod for first time; creates all necessary directories and files.
// Doing this helps the mod know if it has permissions to do things, or if it shouldn't even bother!
// Some functionality is disabled if the mod can't access the hard drive in various ways.
//
// Thing 2: On any sequential startup; it checks to make sure all the directories exist & replaces missing ones.
// It will also do a state-check of the system to make sure we will have permissions to read & write.
// If we do not have these, or only partial - then functionality may be disabled for runtime performance
public final class Setup {
private static Setup static_inst;
public Setup() {
System.out.println("Running system setup and checks...");
}
// Returns the singleton object
public static Setup GetInstance() {
if (static_inst == null) {
static_inst = new Setup();
}
return static_inst;
}
/// Unit testing functions below
public static Boolean has_read = false;
public static Boolean has_write = false;
// First time setup variables
private static final List<String> DIRECTORY_LIST = new ArrayList<String>() {{
add("notes"); // Expect 1 file per player!
add("factions"); // Expect 1 file per faction!
add("story"); // Expect 1 file per story chapter!
add("commands"); // Expect 1 file per command that's configurable!
add("events"); // Expect 1 file per event that is configurable!
}};
// These will be top-level config files above the directories this mod creates
private static final List<String> FILE_LIST = new ArrayList<String>() {{
add("story.json"); // Big config file, determines when players can do certain things at different story levels
add("factions.json"); // General configuration file for factions stuff
add("events.json"); // General configuration file for story events!
add("general.json"); // The super general configuration file! (May be removed)
}};
// RunChecks()
//
// Checks if we are able to create necessary directories and run reading over the file system for the current
// directory this mod is maintained in. This will return false if any checks fail; but individual checks can
// be accessed in class variables (above)
public Boolean RunChecks() {
ConfigManager conf = new ConfigManager();
// Create directory check
try {
has_write = conf.CreateDirectory("test_dir");
} catch (DIRECTORY_CREATE_EXCEPTION e) {
has_write = false; // No read access
}
// Write to disk then read that data back
if (has_write) {
try {
has_write = conf.CreateFile("test_dir/note.txt");
has_write = conf.WriteToFile("test_dir/note.txt", "test_write_read", "w");
List<String> lines = conf.GetFile("test_dir/note.txt");
if (lines.size() == 0) {
has_read = false;
}
} catch (Exception e) {
has_read = false;
}
}
// Delete directory if created (it's a temporary dir)
if (has_write) {
try {
has_write = conf.DeleteDirectory("test_dir");
} catch (DIRECTORY_DELETE_EXCEPTION e) {
has_write = false;
}
}
return has_write && has_read;
}
// RunSetup
//
// Primary function call that will execute when mod starts up
public Boolean RunSetup() throws SETUP_FAILED_EXCEPTION {
Boolean ret = false;
// Setup can only complete if it has guarenteed we have read & write permissions
if (ret = RunChecks()) {
try {
// Create necessary directories
ConfigManager conf = new ConfigManager();
for (Integer i = 0; i < DIRECTORY_LIST.size(); i++) {
if ( ! conf.DoesDirectoryExist(DIRECTORY_LIST.get(i))) {
conf.CreateDirectory(DIRECTORY_LIST.get(i));
}
}
// Create necessary files
for (Integer i = 0; i < FILE_LIST.size(); i++) {
if ( ! conf.DoesFileExist(DIRECTORY_LIST.get(i))) {
conf.CreateFile(FILE_LIST.get(i));
}
}
} catch (Exception e) {
throw new SETUP_FAILED_EXCEPTION();
}
} else {
throw new SETUP_FAILED_EXCEPTION();
}
return ret;
}
}