diff options
| author | Raven Szewczyk <git@eigenraven.me> | 2024-05-24 19:50:35 +0100 |
|---|---|---|
| committer | Raven Szewczyk <git@eigenraven.me> | 2024-05-24 19:50:35 +0100 |
| commit | 6d1b2216464d4dad449ac6fcfec476832224a55e (patch) | |
| tree | 526a0c15f7056313c80e6c0386e025e9b3f61781 /src/main/java/gtPlusPlus/core/util | |
| parent | b5d35f40afa606ed1b07061dad82e0521a59c186 (diff) | |
| download | GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.tar.gz GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.tar.bz2 GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.zip | |
Merge addon sources
Diffstat (limited to 'src/main/java/gtPlusPlus/core/util')
25 files changed, 6070 insertions, 0 deletions
diff --git a/src/main/java/gtPlusPlus/core/util/MovingAverageLong.java b/src/main/java/gtPlusPlus/core/util/MovingAverageLong.java new file mode 100644 index 0000000000..7111fbd5e1 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/util/MovingAverageLong.java @@ -0,0 +1,59 @@ +package gtPlusPlus.core.util; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; + +import net.minecraft.nbt.NBTTagCompound; + +public class MovingAverageLong { + + private final long[] storage; + private int ptr; + + public MovingAverageLong(int sampleSize) { + storage = new long[sampleSize]; + } + + public void set(long average) { + Arrays.fill(storage, average); + } + + public void sample(long data) { + storage[ptr] = data; + ptr = (ptr + 1) % storage.length; + } + + public long get() { + BigInteger result = BigInteger.ZERO; + for (long l : storage) { + result = result.add(BigInteger.valueOf(l)); + } + return result.divide(BigInteger.valueOf(storage.length)) + .longValue(); + } + + public void write(NBTTagCompound tagCompound, String key) { + ByteBuffer buf = ByteBuffer.allocate(storage.length * Long.BYTES) + .order(ByteOrder.nativeOrder()); + buf.asLongBuffer() + .put(storage); + tagCompound.setByteArray(key, buf.array()); + } + + /** + * if read failed, the internal states would not be changed. + * + * @return true if successful, false otherwise. + */ + public boolean read(NBTTagCompound tagCompound, String key) { + ByteBuffer buf = ByteBuffer.wrap(tagCompound.getByteArray(key)); + if (buf.remaining() != storage.length * Long.BYTES) + // not very good... + return false; + buf.asLongBuffer() + .get(storage); + return true; + } +} diff --git a/src/main/java/gtPlusPlus/core/util/Utils.java b/src/main/java/gtPlusPlus/core/util/Utils.java new file mode 100644 index 0000000000..610cc4f8fa --- /dev/null +++ b/src/main/java/gtPlusPlus/core/util/Utils.java @@ -0,0 +1,436 @@ +package gtPlusPlus.core.util; + +import java.awt.Color; +import java.io.File; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.IChatComponent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.EnumHelper; +import net.minecraftforge.fluids.FluidContainerRegistry; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; + +import org.apache.commons.lang3.EnumUtils; + +import cpw.mods.fml.common.FMLCommonHandler; +import gregtech.api.GregTech_API; +import gregtech.api.enums.TC_Aspects; +import gregtech.api.enums.TC_Aspects.TC_AspectStack; +import gregtech.api.util.GT_LanguageManager; +import gregtech.api.util.GT_Log; +import gregtech.api.util.GT_Utility; +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.core.item.ModItems; +import gtPlusPlus.core.lib.CORE; +import gtPlusPlus.core.util.minecraft.FluidUtils; +import gtPlusPlus.core.util.minecraft.ItemUtils; +import gtPlusPlus.core.util.minecraft.NBTUtils; +import ic2.core.Ic2Items; +import ic2.core.init.InternalName; +import ic2.core.item.resources.ItemCell; + +public class Utils { + + public static boolean isServer() { + return FMLCommonHandler.instance() + .getEffectiveSide() + .isServer(); + } + + public static boolean isClient() { + return FMLCommonHandler.instance() + .getEffectiveSide() + .isClient(); + } + + public static TC_AspectStack getTcAspectStack(final TC_Aspects aspect, final long size) { + return getTcAspectStack(aspect.name(), (int) size); + } + + public static TC_AspectStack getTcAspectStack(final String aspect, final long size) { + return getTcAspectStack(aspect, (int) size); + } + + public static TC_AspectStack getTcAspectStack(final TC_Aspects aspect, final int size) { + return getTcAspectStack(aspect.name(), size); + } + + public static TC_AspectStack getTcAspectStack(final String aspect, final int size) { + + TC_AspectStack returnValue = null; + + if (aspect.equalsIgnoreCase("COGNITIO")) { + // Adds in Compat for older GT Versions which Misspell aspects. + try { + if (EnumUtils.isValidEnum(TC_Aspects.class, "COGNITIO")) { + Logger.WARNING("TC Aspect found - " + aspect); + returnValue = new TC_AspectStack(TC_Aspects.valueOf("COGNITIO"), size); + } else { + Logger.INFO( + "Fallback TC Aspect found - " + aspect + + " - PLEASE UPDATE GREGTECH TO A NEWER VERSION TO REMOVE THIS MESSAGE - THIS IS NOT AN ERROR"); + returnValue = new TC_AspectStack(TC_Aspects.valueOf("COGNITO"), size); + } + } catch (final NoSuchFieldError r) { + Logger.INFO("Invalid Thaumcraft Aspects - Report this issue to Alkalus"); + } + } else if (aspect.equalsIgnoreCase("EXANIMUS")) { + // Adds in Compat for older GT Versions which Misspell aspects. + try { + if (EnumUtils.isValidEnum(TC_Aspects.class, "EXANIMUS")) { + Logger.WARNING("TC Aspect found - " + aspect); + returnValue = new TC_AspectStack(TC_Aspects.valueOf("EXANIMUS"), size); + } else { + Logger.INFO( + "Fallback TC Aspect found - " + aspect + + " - PLEASE UPDATE GREGTECH TO A NEWER VERSION TO REMOVE THIS MESSAGE - THIS IS NOT AN ERROR"); + returnValue = new TC_AspectStack(TC_Aspects.valueOf("EXAMINIS"), size); + } + } catch (final NoSuchFieldError r) { + Logger.INFO("Invalid Thaumcraft Aspects - Report this issue to Alkalus"); + } + + } else if (aspect.equalsIgnoreCase("PRAECANTATIO")) { + // Adds in Compat for older GT Versions which Misspell aspects. + try { + if (EnumUtils.isValidEnum(TC_Aspects.class, "PRAECANTATIO")) { + Logger.WARNING("TC Aspect found - " + aspect); + returnValue = new TC_AspectStack(TC_Aspects.valueOf("PRAECANTATIO"), size); + } else { + Logger.INFO( + "Fallback TC Aspect found - " + aspect + + " - PLEASE UPDATE GREGTECH TO A NEWER VERSION TO REMOVE THIS MESSAGE - THIS IS NOT AN ERROR"); + returnValue = new TC_AspectStack(TC_Aspects.valueOf("PRAECANTIO"), size); + } + } catch (final NoSuchFieldError r) { + Logger.INFO("Invalid Thaumcraft Aspects - Report this issue to Alkalus"); + } + } else { + Logger.WARNING("TC Aspect found - " + aspect); + returnValue = new TC_AspectStack(TC_Aspects.valueOf(aspect), size); + } + + return returnValue; + } + + // Register an event to both busses. + public static void registerEvent(Object o) { + MinecraftForge.EVENT_BUS.register(o); + FMLCommonHandler.instance() + .bus() + .register(o); + } + + // Send a message to all players on the server + public static void sendServerMessage(final String translationKey) { + sendServerMessage(new ChatComponentText(translationKey)); + } + + // Send a message to all players on the server + public static void sendServerMessage(final IChatComponent chatComponent) { + MinecraftServer.getServer() + .getConfigurationManager() + .sendChatMsg(chatComponent); + } + + /** + * Returns if that Liquid is IC2Steam. + */ + public static boolean isIC2Steam(final FluidStack aFluid) { + if (aFluid == null) { + return false; + } + return aFluid.isFluidEqual(getIC2Steam(1)); + } + + /** + * Returns a Liquid Stack with given amount of IC2Steam. + */ + public static FluidStack getIC2Steam(final long aAmount) { + return FluidRegistry.getFluidStack("ic2steam", (int) aAmount); + } + + public static int rgbtoHexValue(final int r, final int g, final int b) { + if ((r > 255) || (g > 255) || (b > 255) || (r < 0) || (g < 0) || (b < 0)) { + return 0; + } + final Color c = new Color(r, g, b); + String temp = Integer.toHexString(c.getRGB() & 0xFFFFFF) + .toUpperCase(); + temp = Utils.appenedHexNotationToString(temp); + return Integer.decode(temp); + } + + /* + * http://javadevnotes.com/java-left-pad-string-with-zeros-examples + */ + public static String padWithZerosLefts(final String originalString, final int length) { + final StringBuilder sb = new StringBuilder(); + while ((sb.length() + originalString.length()) < length) { + sb.append('0'); + } + sb.append(originalString); + return sb.toString(); + } + + /* + * Original Code by Chandana Napagoda - https://cnapagoda.blogspot.com.au/2011/03/java-hex-color-code-generator. + * html + */ + public static Map<Integer, String> hexColourGeneratorRandom(final int colorCount) { + final HashMap<Integer, String> hexColorMap = new HashMap<>(); + for (int a = 0; a < colorCount; a++) { + String code = "" + (int) (Math.random() * 256); + code = code + code + code; + final int i = Integer.parseInt(code); + hexColorMap.put( + a, + Integer.toHexString(0x1000000 | i) + .substring(1) + .toUpperCase()); + Logger.WARNING( + "" + Integer.toHexString(0x1000000 | i) + .substring(1) + .toUpperCase()); + } + return hexColorMap; + } + + public static String appenedHexNotationToString(final Object hexAsStringOrInt) { + final String hexChar = "0x"; + String result; + if (hexAsStringOrInt.getClass() == String.class) { + + if (((String) hexAsStringOrInt).length() != 6) { + final String temp = padWithZerosLefts((String) hexAsStringOrInt, 6); + } + result = hexChar + hexAsStringOrInt; + return result; + } else if (hexAsStringOrInt.getClass() == Integer.class) { + String aa = String.valueOf(hexAsStringOrInt); + if (aa.length() != 6) { + result = padWithZerosLefts(aa, 6); + } else { + result = hexChar + hexAsStringOrInt; + } + return result; + } else { + return null; + } + } + + public static File getMcDir() { + if (Utils.isClient()) { + if (Minecraft.getMinecraft() != null) { + return Minecraft.getMinecraft().mcDataDir; + } + } + return new File("."); + } + + private static short cellID = 15; + + public static ItemStack createInternalNameAndFluidCell(final String s) { + Logger.WARNING("1"); + final InternalName yourName = EnumHelper.addEnum(InternalName.class, s, new Class[0], new Object[0]); + Logger.WARNING("2 " + yourName.name()); + final ItemCell item = (ItemCell) Ic2Items.cell.getItem(); + Logger.WARNING("3 " + item.getUnlocalizedName()); + try { + Logger.WARNING("4"); + final Class<? extends ItemCell> clz = item.getClass(); + Logger.WARNING("5 " + clz.getSimpleName()); + final Method methode = clz.getDeclaredMethod("addCell", int.class, InternalName.class, Block[].class); + Logger.WARNING("6 " + methode.getName()); + methode.setAccessible(true); + Logger.WARNING("7 " + methode.isAccessible()); + final ItemStack temp = (ItemStack) methode.invoke(item, cellID++, yourName, new Block[0]); + Logger.WARNING("Successfully created " + temp.getDisplayName() + "s."); + FluidContainerRegistry.registerFluidContainer( + FluidUtils.getFluidStack(s.toLowerCase(), 1000), + temp.copy(), + Ic2Items.cell.copy()); + ItemUtils.addItemToOreDictionary(temp.copy(), "cell" + s); + return temp; + } catch (final Exception e) { + e.printStackTrace(); + } + return null; + } + + public static String sanitizeString(final String input, final char[] dontRemove) { + + // List of characters to remove + final HashSet<Character> toRemoveSet = new HashSet<>(); + Collections.addAll( + toRemoveSet, + ' ', + '-', + '_', + '~', + '?', + '!', + '@', + '#', + '$', + '%', + '^', + '&', + '*', + '(', + ')', + '{', + '}', + '[', + ']'); + + // Remove characters from the toRemoveSet if they are in dontRemove + for (char e : dontRemove) { + toRemoveSet.remove(e); + } + + // Construct a sanitized string + StringBuilder sanitized = new StringBuilder(); + for (char c : input.toCharArray()) { + if (!toRemoveSet.contains(c)) { + sanitized.append(c); + } + } + + return sanitized.toString(); + } + + public static String sanitizeString(final String input) { + String temp; + String output; + + temp = input.replace(" ", ""); + temp = temp.replace("-", ""); + temp = temp.replace("_", ""); + temp = temp.replace("?", ""); + temp = temp.replace("!", ""); + temp = temp.replace("@", ""); + temp = temp.replace("#", ""); + temp = temp.replace("(", ""); + temp = temp.replace(")", ""); + temp = temp.replace("{", ""); + temp = temp.replace("}", ""); + temp = temp.replace("[", ""); + temp = temp.replace("]", ""); + temp = temp.replace(" ", ""); + output = temp; + return output; + } + + public static String sanitizeStringKeepBrackets(final String input) { + String temp; + String output; + + temp = input.replace(" ", ""); + temp = temp.replace("-", ""); + temp = temp.replace("_", ""); + temp = temp.replace("?", ""); + temp = temp.replace("!", ""); + temp = temp.replace("@", ""); + temp = temp.replace("#", ""); + temp = temp.replace(" ", ""); + output = temp; + return output; + } + + public static String addBookTitleLocalization(final String aTitle) { + return GT_LanguageManager + .addStringLocalization("Book." + aTitle + ".Name", aTitle, !GregTech_API.sPostloadFinished); + } + + public static String[] addBookPagesLocalization(final String aTitle, final String[] aPages) { + String[] aLocalizationPages = new String[aPages.length]; + for (byte i = 0; i < aPages.length; i = (byte) (i + 1)) { + aLocalizationPages[i] = GT_LanguageManager.addStringLocalization( + "Book." + aTitle + ".Page" + ((i < 10) ? "0" + i : Byte.valueOf(i)), + aPages[i], + !GregTech_API.sPostloadFinished); + } + return aLocalizationPages; + } + + public static ItemStack getWrittenBook(ItemStack book, int ID, String mapping, String title, String author, + String[] pages) { + + if (GT_Utility.isStringInvalid(mapping)) { + return null; + } + + ItemStack stack = CORE.sBookList.get(mapping); + if (stack != null) { + return GT_Utility.copyAmount(1L, stack); + } + + if (GT_Utility.isStringInvalid(title) || GT_Utility.isStringInvalid(author) || pages.length <= 0) { + return null; + } + + stack = (book == null) ? new ItemStack(ModItems.itemCustomBook, 1, ID) : book; + + NBTTagCompound NBT = new NBTTagCompound(); + String localizationTitle = addBookTitleLocalization(title); + NBT.setString("title", localizationTitle); + NBT.setString("author", author); + + NBTTagList NBTList = new NBTTagList(); + String[] localizationPages = addBookPagesLocalization(title, pages); + + for (byte i = 0; i < pages.length; i++) { + pages[i] = localizationPages[i].replaceAll("<BR>", "\n"); + if (i < 48) { + if (pages[i].length() < 256) { + NBTList.appendTag(new NBTTagString(pages[i])); + } else { + Logger.INFO("WARNING: String for written Book too long! -> " + pages[i]); + GT_Log.err.println("WARNING: String for written Book too long! -> " + pages[i]); + } + } else { + Logger.INFO("WARNING: Too much Pages for written Book! -> " + title); + GT_Log.err.println("WARNING: Too much Pages for written Book! -> " + title); + break; + } + } + + String credits = String.format( + "Credits to %s for writing this Book. This was Book Nr. %d at its creation. Gotta get 'em all!", + author, + ID); + NBTList.appendTag(new NBTTagString(credits)); + NBT.setTag("pages", NBTList); + + stack.setTagCompound(NBT); + + String logMessage = String.format( + "GT++_Mod: Added Book to Book++ List - Mapping: '%s' - Name: '%s' - Author: '%s'", + mapping, + title, + author); + GT_Log.out.println(logMessage); + + NBTUtils.createIntegerTagCompound(stack, "stats", "mMeta", ID); + CORE.sBookList.put(mapping, stack); + + Logger.INFO(String.format("Creating book: %s by %s. Using Meta %d.", title, author, ID)); + + return GT_Utility.copy(stack); + } + +} diff --git a/src/main/java/gtPlusPlus/core/util/data/AES.java b/src/main/java/gtPlusPlus/core/util/data/AES.java new file mode 100644 index 0000000000..85f20a3367 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/util/data/AES.java @@ -0,0 +1,135 @@ +package gtPlusPlus.core.util.data; + +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Base64; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +public class AES { + + private final String secret; + + private final SecretKeySpec secretKey; + + private final byte[] key; + + public AES() { + + this("Darkness In Their Hearts"); + } + + public AES(String aSecret) { + + secret = aSecret; + + key = getBytes(getHashedString(secret)); + + secretKey = generateKey(key); + } + + private static String getHashedString(String aString) { + + return toHexString(getSHA(aString)); + } + + private static byte[] getSHA(String input) { + + MessageDigest md; + + try { + + md = MessageDigest.getInstance("SHA-256"); + + return md.digest(input.getBytes(StandardCharsets.UTF_8)); + + } catch (NoSuchAlgorithmException e) { + + e.printStackTrace(); + } + + return new byte[] {}; + } + + private static String toHexString(byte[] hash) { + + BigInteger number = new BigInteger(1, hash); + + StringBuilder hexString = new StringBuilder(number.toString(16)); + + while (hexString.length() < 32) { + + hexString.insert(0, '0'); + } + + return hexString.toString(); + } + + private byte[] getBytes(String aKey) { + + byte[] aKeyData; + + MessageDigest sha; + + try { + + sha = MessageDigest.getInstance("SHA-256"); + + return sha.digest(aKey.getBytes(StandardCharsets.UTF_8)); + + } catch (NoSuchAlgorithmException e1) { + + e1.printStackTrace(); + + try { + + aKeyData = aKey.getBytes("UTF-8"); + + sha = MessageDigest.getInstance("SHA-1"); + + aKeyData = sha.digest(key); + + aKeyData = Arrays.copyOf(key, 16); + + return aKeyData; + + } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { + + e.printStackTrace(); + + } + } + + return new byte[] {}; + } + + private SecretKeySpec generateKey(byte[] aKey) { + + return new SecretKeySpec(aKey, "AES"); + } + + public String decode(String strToDecrypt) { + + try { + + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); + + cipher.init(Cipher.DECRYPT_MODE, secretKey); + + return new String( + cipher.doFinal( + Base64.getDecoder() + .decode(strToDecrypt))); + + } catch (Exception ignored) { + + } + + return null; + } +} diff --git a/src/main/java/gtPlusPlus/core/util/data/ArrayUtils.java b/src/main/java/gtPlusPlus/core/util/data/ArrayUtils.java new file mode 100644 index 0000000000..d5ab990917 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/util/data/ArrayUtils.java @@ -0,0 +1,44 @@ +package gtPlusPlus.core.util.data; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import net.minecraft.item.ItemStack; + +public class ArrayUtils { + + public static <V> V[] insertElementAtIndex(V[] aArray, int aIndex, V aObjectToInsert) { + V[] newArray = Arrays.copyOf(aArray, aArray.length + 1); + for (int i = 0; i < aIndex; i++) { + newArray[i] = aArray[i]; + } + newArray[aIndex] = aObjectToInsert; + for (int i = (aIndex + 1); i < newArray.length; i++) { + newArray[i] = aArray[i - 1]; + } + return newArray; + } + + public static Object[] removeNulls(final Object[] v) { + List<Object> list = new ArrayList<>(Arrays.asList(v)); + list.removeAll(Collections.singleton((Object) null)); + return list.toArray(new Object[list.size()]); + } + + public static ItemStack[] removeNulls(final ItemStack[] v) { + List<ItemStack> list = new ArrayList<>(Arrays.asList(v)); + list.removeAll(Collections.singleton((ItemStack) null)); + return list.toArray(new ItemStack[list.size()]); + } + + public static String toString(Object[] aArray, String string) { + return org.apache.commons.lang3.ArrayUtils.toString(aArray, string); + } + + public static String toString(Object[] aArray) { + return org.apache.commons.lang3.ArrayUtils.toString(aArray); + } + +} diff --git a/src/main/java/gtPlusPlus/core/util/data/FileUtils.java b/src/main/java/gtPlusPlus/core/util/data/FileUtils.java new file mode 100644 index 0000000000..b2e5d04375 --- /dev/null +++ b/src/main/java/gtPlusPlus/core/util/data/FileUtils.java @@ -0,0 +1,112 @@ +package gtPlusPlus.core.util.data; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.List; + +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.core.util.Utils; + +public class FileUtils { + + private static final Charset utf8 = StandardCharsets.UTF_8; + + public static boolean doesFileExist(File f) { + if (f != null && f.exists() && !f.isDirectory()) { + return true; + } + return false; + } + + public static File createFile(String path, String filename, String extension) { + File file = new File(Utils.getMcDir(), path + filename + extension); + return createFile(file); + } + + public static File createFile(File aFile) { + boolean blnCreated = false; + Logger.INFO("Trying to use path " + aFile.getPath()); + try { + Logger.INFO("Trying to use path " + aFile.getCanonicalPath()); + Logger.INFO("Trying to use absolute path " + aFile.getAbsolutePath()); + blnCreated = aFile.createNewFile(); + } catch (IOException ioe) { + Logger.INFO("Error while creating a new empty file :" + ioe); + return null; + } + return blnCreated ? aFile : null; + } + + public static File getFile(String filename, String extension) { + return getFile("", filename, extension); + } + + public static File getFile(String path, String filename, String extension) { + if (path == null || path.length() <= 0) { + path = ""; + } else { + path = path + "/"; + } + if (filename == null || filename.length() <= 0) { + return null; + } + if (extension == null || extension.length() <= 0) { + extension = ".txt"; + } else { + extension = "." + extension; + } + File file = new File(Utils.getMcDir(), path + filename + extension); + boolean doesExist = doesFileExist(file); + + if (doesExist) { + Logger.INFO("Found File: " + file.getAbsolutePath()); + return file; + } else { + Logger.INFO("Creating file, as it was not found."); + return createFile(path, filename, extension); + } + } + + public static void appendListToFile(File file, List<String> content) { + try { + long oldSize; + long newSize; + if (doesFileExist(file)) { + Path p = Paths.get(file.getPath()); + if (p != null && Files.isWritable(p)) { + oldSize = Files.size(p); + try { + Files.write(p, content, utf8, StandardOpenOption.APPEND); + } catch (IOException e) { + e.printStackTrace(); + } + newSize = Files.size(p); + } + } + } catch (IOException ignored) {} + } + + /** + * Reads the contents of a file line by line to a List of Strings using the default encoding for the VM. The file is + * always closed. + * + * @param file the file to read, must not be {@code null} + * @return the list of Strings representing each line in the fi |
