2024-10-28 21:47:51 +00:00
/ *
*
* ConfigManager
*
* This class is the central configuration file manager for all other classes and acts as a utility class for other classes to use .
* 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.FileNotFoundException ;
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 com.google.gson.JsonSyntaxException ;
import java.util.List ;
import org.apache.commons.io.FileUtils ;
import java.util.ArrayList ;
2024-12-06 03:37:27 +00:00
import java.util.HashMap ;
2024-10-28 21:47:51 +00:00
2025-01-02 03:47:50 +00:00
import jesse.keeblarcraft.Keeblarcraft ;
2024-11-29 09:00:14 +00:00
import net.minecraft.nbt.NbtCompound ;
import net.minecraft.nbt.NbtIo ;
import net.minecraft.nbt.NbtList ;
2024-10-28 21:47:51 +00:00
public class ConfigManager {
// Pedantic empty constructor
2025-01-02 03:47:50 +00:00
private static final String GLOBAL_CONFIG = " config/keeblarcraft/ " ;
2024-10-28 21:47:51 +00:00
public ConfigManager ( ) { }
2025-01-02 03:47:50 +00:00
// Get a File reference to a file that is created on disk
private File GetFile ( String confFile ) {
File file = null ;
2025-01-03 04:05:16 +00:00
System . out . println ( " Get file called for " + GLOBAL_CONFIG + confFile ) ;
2025-01-02 03:47:50 +00:00
try {
file = new File ( GLOBAL_CONFIG + confFile ) ;
} catch ( Exception e ) { }
return file ;
}
// Returns the parent path to a given input.
// Ex: /home/Downloads/file.txt will return /home/Downloads/
// Ex: /home/Downloads will return /home/
// Ex: / will return /
private String GetPathOfFile ( String file ) {
String pathToFile = " " ;
if ( file ! = null ) {
for ( int i = file . length ( ) - 1 ; i > = 0 ; i - - ) {
if ( file . charAt ( i ) ! = File . separatorChar ) {
continue ;
}
else {
// Trim and break
pathToFile = file . substring ( 0 , i ) ;
break ;
}
}
}
return pathToFile ;
}
// Creates a directory and all necessary parent directories listed in dirname (under global config area)
public Boolean CreateDirectory ( String dirName ) {
Boolean success = false ;
File directory = GetFile ( dirName ) ;
2024-10-28 21:47:51 +00:00
2025-01-02 03:47:50 +00:00
try {
if ( directory ! = null ) {
if ( ! directory . exists ( ) )
{
success = directory . mkdirs ( ) ;
} else if ( directory . isDirectory ( ) ) {
success = true ;
} else {
System . out . println ( " Directory " + dirName + " is an already existing file! " ) ;
}
}
} catch ( Exception e ) {
System . out . println ( " Failed to create directory with name " + dirName ) ;
e . printStackTrace ( ) ;
}
return success ;
}
2024-10-28 21:47:51 +00:00
2025-01-02 03:47:50 +00:00
// Create a file on the disk
public Boolean CreateFile ( String fileName ) {
Boolean success = false ;
File file = GetFile ( fileName ) ;
String parentDir = GetPathOfFile ( fileName ) ;
// CreateDirectory will verify that the parent directories exist & at least the parent directory is in fact a directory
if ( file ! = null & & ! file . exists ( ) & & CreateDirectory ( parentDir ) ) {
2024-10-28 21:47:51 +00:00
try {
2025-01-02 03:47:50 +00:00
success = file . createNewFile ( ) ;
} catch ( Exception e ) {
System . out . println ( " Failed to create file " + fileName ) ;
e . printStackTrace ( ) ;
2024-10-28 21:47:51 +00:00
}
} else {
2025-01-02 03:47:50 +00:00
System . out . println ( " CreateFile failed to finish. File may have been null (empty string input, unlikely), or parent directories could not be created/have overlapped name " ) ;
success = false ;
2024-10-28 21:47:51 +00:00
}
2025-01-02 03:47:50 +00:00
return success ;
2024-10-28 21:47:51 +00:00
}
2025-01-02 03:47:50 +00:00
public Boolean DeleteFile ( String fileName ) {
Boolean success = false ;
File file = GetFile ( fileName ) ;
2024-10-28 21:47:51 +00:00
2025-01-02 03:47:50 +00:00
success = ! file . exists ( ) ;
2024-10-28 21:47:51 +00:00
2025-01-02 03:47:50 +00:00
if ( ! success ) {
2024-10-28 21:47:51 +00:00
try {
2025-01-02 03:47:50 +00:00
success = file . delete ( ) ;
} catch ( Exception e ) {
System . out . println ( " Failed to delete file " + fileName ) ;
e . printStackTrace ( ) ;
2024-10-28 21:47:51 +00:00
}
}
2025-01-02 03:47:50 +00:00
return success ;
2024-10-28 21:47:51 +00:00
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn WriteNbtListToFile
///
/// @param[in] fileName is the file location to write to
///
/// @param[in] key is the compound key type to store
///
/// @param[in] data is the NbtList to write
///
/// @brief Writes NbtList data to disk
/////////////////////////////////////////////////////////////////////////////
2024-12-06 03:37:27 +00:00
public void WriteNbtListToFile ( String fileName , String key , NbtList data ) {
2024-11-29 09:00:14 +00:00
fileName = " config/keeblarcraft/ " + fileName ;
2025-01-02 03:47:50 +00:00
File file = GetFile ( fileName ) ;
2024-12-06 03:37:27 +00:00
if ( ! file . exists ( ) ) {
file . getParentFile ( ) . mkdirs ( ) ;
}
2024-11-29 09:00:14 +00:00
try {
2024-12-06 03:37:27 +00:00
NbtCompound compound = new NbtCompound ( ) ;
compound . put ( key , data ) ;
NbtIo . writeCompressed ( compound , file ) ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn ReadAllNbtListFromDirectory
///
/// @param[in] dir is the directory path to read from
///
/// @param[in] listType is the NBT Compound list type
///
/// @brief Reads in NBTList data from a directory; using file names as key.
/// If a file is read in correctly, the file is deleted
///
/// @return A map of NbtList data with the key being the file name (minus ext)
/////////////////////////////////////////////////////////////////////////////
2024-12-06 03:37:27 +00:00
public HashMap < String , NbtList > ReadAllNbtListFromDirectory ( String dir , int listType ) {
HashMap < String , NbtList > list = new HashMap < String , NbtList > ( ) ;
dir = " config/keeblarcraft/ " + dir ;
2025-01-02 03:47:50 +00:00
File directory = GetFile ( dir ) ;
2024-12-06 03:37:27 +00:00
File [ ] files = directory . listFiles ( ) ;
if ( files ! = null ) {
for ( File file : files ) {
String key = file . getName ( ) . substring ( 0 , file . getName ( ) . length ( ) - 4 ) ;
NbtList nbtList = ReadNbtListFromFile ( file , key , listType ) ;
if ( nbtList ! = null ) {
// Subtract out '.nbt' from name
list . put ( key , nbtList ) ;
file . delete ( ) ;
}
2024-11-29 09:00:14 +00:00
}
2024-12-06 03:37:27 +00:00
}
return list ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn ReadNbtListFromFile
///
/// @param[in] file handler object to read nbt list data from
///
/// @param[in] key for the nbt compound object
///
/// @param[in] listType is the NBT Compound list type
///
/// @brief Reads in NBTList data from a single file
///
/// @return NbtList data
/////////////////////////////////////////////////////////////////////////////
2024-12-06 03:37:27 +00:00
public NbtList ReadNbtListFromFile ( File file , String key , int listType ) {
NbtList list = null ;
try {
NbtCompound c = NbtIo . readCompressed ( file ) ;
list = c . getList ( key , listType ) ;
} catch ( Exception e ) {
2024-11-29 09:00:14 +00:00
e . printStackTrace ( ) ;
}
2024-12-06 03:37:27 +00:00
return list ;
2024-11-29 09:00:14 +00:00
}
2024-10-28 21:47:51 +00:00
// 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 ;
FileWriter file ;
try {
2025-01-02 03:47:50 +00:00
file = new FileWriter ( GetFile ( fileName ) ) ;
2024-10-28 21:47:51 +00:00
switch ( mode ) {
case " w " :
file . write ( data ) ;
ret = true ;
break ;
case " a " :
file . append ( data ) ;
ret = true ;
break ;
default :
2025-01-02 03:47:50 +00:00
Keeblarcraft . LOGGER . debug ( " Invalid mode to WriteToFile!! " ) ;
2024-10-28 21:47:51 +00:00
break ;
}
file . close ( ) ;
} catch ( IOException e ) {
2025-01-02 03:47:50 +00:00
e . printStackTrace ( ) ;
Keeblarcraft . LOGGER . error ( " Could not open file " + fileName + " to write to it! Possible permissions issue?? " ) ;
2024-10-28 21:47:51 +00:00
}
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
2025-01-02 03:47:50 +00:00
public void WriteToJsonFile ( String fileName , Object data ) {
2024-10-28 21:47:51 +00:00
Gson gson = new GsonBuilder ( ) . setPrettyPrinting ( ) . create ( ) ;
try {
2025-01-02 03:47:50 +00:00
FileWriter writer = new FileWriter ( GetFile ( fileName ) ) ;
2024-10-28 21:47:51 +00:00
gson . toJson ( data , writer ) ;
writer . flush ( ) ;
writer . close ( ) ;
} catch ( JsonIOException | IOException e ) {
2025-01-02 03:47:50 +00:00
Keeblarcraft . LOGGER . error ( " Could not successfully write to json file [ " + fileName + " ] " ) ;
2024-10-28 21:47:51 +00:00
}
}
// GetJsonStringFromFile
//
// Retrieves json file and converts to desired object. Returns JsonSyntaxException if file could not be fitted to class input
public < T > T GetJsonObjectFromFile ( String fileName , Class < T > classToConvertTo ) throws JsonSyntaxException {
Gson gson = new Gson ( ) ;
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 {
2025-01-02 03:47:50 +00:00
File file = GetFile ( fileName ) ;
2024-10-28 21:47:51 +00:00
ret = FileUtils . readFileToString ( file , " UTF-8 " ) ;
2025-01-02 03:47:50 +00:00
} catch ( Exception e ) {
System . out . println ( " Caught an exception in retrieving JSON Object from file " + fileName ) ;
2025-01-18 08:10:58 +00:00
// throw new JsonSyntaxException("");
2024-10-28 21:47:51 +00:00
}
return gson . fromJson ( ret , classToConvertTo ) ;
}
public Boolean DoesFileExist ( String fileName ) {
2025-01-02 03:47:50 +00:00
return GetFile ( fileName ) ! = null ;
2024-10-28 21:47:51 +00:00
}
public Boolean DoesDirectoryExist ( String dirName ) {
2025-01-02 03:47:50 +00:00
File file = GetFile ( dirName ) ;
return file ! = null & & file . isDirectory ( ) ;
2024-10-28 21:47:51 +00:00
}
2025-01-02 03:47:50 +00:00
public Boolean DeleteDirectory ( String dirName ) {
return DeleteFile ( dirName ) ;
2024-10-28 21:47:51 +00:00
}
// 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
2025-01-02 03:47:50 +00:00
public List < String > GetFileLines ( String fileName ) {
2024-10-28 21:47:51 +00:00
List < String > ret = new ArrayList < String > ( ) ;
try {
2025-01-02 03:47:50 +00:00
return Files . readLines ( GetFile ( fileName ) , Charsets . UTF_8 ) ;
2024-10-28 21:47:51 +00:00
} catch ( IOException e ) {
ret . clear ( ) ;
}
return ret ;
}
}