package co.forsaken.projectindigo.utils;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.security.CodeSource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import co.forsaken.projectindigo.IndigoLauncher;
import co.forsaken.projectindigo.gui.components.Label;
import co.forsaken.projectindigo.log.LogEvent.LogType;
import co.forsaken.projectindigo.log.LogManager;
public class Utils {
public static enum OS {
WINDOWS, UNIX, MACOSX, OTHER,
}
private static Logger logger = Logger.getLogger("launcher");
public static String getDefInstallPath() {
try {
CodeSource codeSource = Utils.class.getProtectionDomain().getCodeSource();
File jarFile;
jarFile = new File(codeSource.getLocation().toURI().getPath());
return jarFile.getParentFile().getPath();
} catch (URISyntaxException e) {
logger.log(Level.WARNING, e.getMessage());
}
logger.log(Level.WARNING, "Failed to get path for current directory - falling back to user's home directory.");
return System.getProperty("user.dir") + "//" + getTitle() + "_install";
}
private static String getTitle() {
return IndigoLauncher.TITLE.toLowerCase().replaceAll(" ", "_");
}
public static Object[] prepareMessageForMinecraftLog(String text) {
LogType type = null; // The log message type
String message = null; // The log message
if (text.contains("[INFO] [STDERR]")) {
message = text.substring(text.indexOf("[INFO] [STDERR]"));
type = LogType.WARN;
} else if (text.contains("[INFO]")) {
message = text.substring(text.indexOf("[INFO]"));
if (message.contains("CONFLICT")) {
type = LogType.ERROR;
} else if (message.contains("overwriting existing item")) {
type = LogType.WARN;
} else {
type = LogType.INFO;
}
} else if (text.contains("[WARNING]")) {
message = text.substring(text.indexOf("[WARNING]"));
type = LogType.WARN;
} else if (text.contains("WARNING:")) {
message = text.substring(text.indexOf("WARNING:"));
type = LogType.WARN;
} else if (text.contains("INFO:")) {
message = text.substring(text.indexOf("INFO:"));
type = LogType.INFO;
} else if (text.contains("Exception")) {
message = text;
type = LogType.ERROR;
} else if (text.contains("[SEVERE]")) {
message = text.substring(text.indexOf("[SEVERE]"));
type = LogType.ERROR;
} else if (text.contains("[Sound Library Loader/ERROR]")) {
message = text.substring(text.indexOf("[Sound Library Loader/ERROR]"));
type = LogType.ERROR;
} else if (text.contains("[Sound Library Loader/WARN]")) {
message = text.substring(text.indexOf("[Sound Library Loader/WARN]"));
type = LogType.WARN;
} else if (text.contains("[Sound Library Loader/INFO]")) {
message = text.substring(text.indexOf("[Sound Library Loader/INFO]"));
type = LogType.INFO;
} else if (text.contains("[MCO Availability Checker #1/ERROR]")) {
message = text.substring(text.indexOf("[MCO Availability Checker #1/ERROR]"));
type = LogType.ERROR;
} else if (text.contains("[MCO Availability Checker #1/WARN]")) {
message = text.substring(text.indexOf("[MCO Availability Checker #1/WARN]"));
type = LogType.WARN;
} else if (text.contains("[MCO Availability Checker #1/INFO]")) {
message = text.substring(text.indexOf("[MCO Availability Checker #1/INFO]"));
type = LogType.INFO;
} else if (text.contains("[Client thread/ERROR]")) {
message = text.substring(text.indexOf("[Client thread/ERROR]"));
type = LogType.ERROR;
} else if (text.contains("[Client thread/WARN]")) {
message = text.substring(text.indexOf("[Client thread/WARN]"));
type = LogType.WARN;
} else if (text.contains("[Client thread/INFO]")) {
message = text.substring(text.indexOf("[Client thread/INFO]"));
type = LogType.INFO;
} else if (text.contains("[Server thread/ERROR]")) {
message = text.substring(text.indexOf("[Server thread/ERROR]"));
type = LogType.ERROR;
} else if (text.contains("[Server thread/WARN]")) {
message = text.substring(text.indexOf("[Server thread/WARN]"));
type = LogType.WARN;
} else if (text.contains("[Server thread/INFO]")) {
message = text.substring(text.indexOf("[Server thread/INFO]"));
type = LogType.INFO;
} else if (text.contains("[main/ERROR]")) {
message = text.substring(text.indexOf("[main/ERROR]"));
type = LogType.ERROR;
} else if (text.contains("[main/WARN]")) {
message = text.substring(text.indexOf("[main/WARN]"));
type = LogType.WARN;
} else if (text.contains("[main/INFO]")) {
message = text.substring(text.indexOf("[main/INFO]"));
type = LogType.INFO;
} else {
message = text;
type = LogType.INFO;
}
return new Object[] { type, message };
}
public static String getSHA1(File file) {
if (!file.exists()) {
LogManager.error("Cannot get SHA-1 hash of " + file.getAbsolutePath() + " as it doesn't exist");
return "0"; // File doesn't exists so MD5 is nothing
}
StringBuffer sb = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
FileInputStream fis = new FileInputStream(file);
byte[] dataBytes = new byte[1024];
int nread = 0;
while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
}
byte[] mdbytes = md.digest();
sb = new StringBuffer();
for (int i = 0; i < mdbytes.length; i++) {
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
}
if (fis != null) {
fis.close();
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
public static String getDynamicStorageLocation() {
switch (getCurrentOS()) {
case WINDOWS:
return System.getenv("APPDATA") + "/" + getTitle() + "/";
case MACOSX:
return System.getProperty("user.home") + "/Library/Application Support/" + getTitle() + "/";
case UNIX:
return System.getProperty("user.home") + "/." + getTitle() + "/";
default:
return getDefInstallPath() + "/temp/";
}
}
public static String getJavaDelimiter() {
switch (getCurrentOS()) {
case WINDOWS:
return ";";
case UNIX:
return ":";
case MACOSX:
return ":";
default:
return ";";
}
}
public static int getMaximumWindowWidth() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension dim = toolkit.getScreenSize();
return dim.width;
}
public static int getMaximumWindowHeight() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension dim = toolkit.getScreenSize();
return dim.height;
}
public static OS getCurrentOS() {
String osString = System.getProperty("os.name").toLowerCase();
if (osString.contains("win")) {
return OS.WINDOWS;
} else if (osString.contains("nix") || osString.contains("nux")) {
return OS.UNIX;
} else if (osString.contains("mac")) {
return OS.MACOSX;
} else {
return OS.OTHER;
}
}
public static void removeMetaInf(String filePath) {
File inputFile = new File(filePath, "minecraft.jar");
File outputTmpFile = new File(filePath, "minecraft.jar.tmp");
try {
JarInputStream input = new JarInputStream(new FileInputStream(inputFile));
JarOutputStream output = new JarOutputStream(new FileOutputStream(outputTmpFile));
JarEntry entry;
while ((entry = input.getNextJarEntry()) != null) {
if (entry.getName().contains("META-INF")) {
continue;
}
output.putNextEntry(entry);
byte buffer[] = new byte[1024];
int amo;
while ((amo = input.read(buffer, 0, 1024)) != -1) {
output.write(buffer, 0, amo);
}
output.closeEntry();
}
input.close();
output.close();
if (!inputFile.delete()) {
logger.log(Level.SEVERE, "Failed to delete Minecraft.jar.");
return;
}
outputTmpFile.renameTo(inputFile);
} catch (FileNotFoundException e) {
logger.log(Level.WARNING, e.getMessage());
} catch (IOException e) {
logger.log(Level.WARNING, e.getMessage());
}
}
public static String readURL(String urlString) throws Exception {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
return buffer.toString();
} finally {
if (reader != null) reader.close();
}
}
public static BufferedImage loadCachedImage(String path) {
try {
return ImageIO.read(new File(path));
} catch (Exception e) {}
return null;
}
public static int[][] getDynamicTableCoords(int totalAreaWidth, int totalAreaHeight, int numData) {
int numPerRow = 3;
int[][] tableCoords = Utils.getTableCoords(numPerRow, totalAreaWidth, totalAreaHeight, numData);
while (tableCoords[tableCoords.length - 1][1] + tableCoords[tableCoords.length - 1][3] > totalAreaHeight) {
numPerRow++;
tableCoords = Utils.getTableCoords(numPerRow, totalAreaWidth, totalAreaHeight, numData);
}
return tableCoords;
}
public static final int MAX_TILE_WIDTH = 250;
private static int[][] getTableCoords(int numPerRow, int totalAreaWidth, int totalAreaHeight, int numData) {
int[][] table = new int[numData][4];
int tileWidth = (int) ((double) (totalAreaWidth / numPerRow) * 0.6D);
if (tileWidth > MAX_TILE_WIDTH) {
tileWidth = MAX_TILE_WIDTH;
}
int cellPaddingX = (totalAreaWidth - tileWidth) / numPerRow;
int cellPaddingY = cellPaddingX / 3;
int tileHeight = tileWidth;
int numRows = numData / numPerRow;
int modX = cellPaddingX / 5;
for (int i = 0; i < numData; i++) {
int row = (i / numPerRow);
int col = (i % numPerRow);
int numColOnCurrRow = (numRows == row ? numData % numPerRow : numPerRow);
table[i] = new int[] { modX + (totalAreaWidth / 2) + (tileWidth * col) + (((cellPaddingX / 2) * col)) - (((tileWidth + (cellPaddingX / 2)) * numColOnCurrRow) / 2), (tileHeight * row) + ((cellPaddingY * row) / 2), tileWidth, tileHeight };
}
return table;
}
public static String getClassContainer(Class<?> c) {
if (c == null) { throw new NullPointerException("The Class passed to this method may not be null"); }
try {
while (c.isMemberClass() || c.isAnonymousClass()) {
c = c.getEnclosingClass(); // Get the actual enclosing file
}
if (c.getProtectionDomain().getCodeSource() == null) {
// This is a proxy or other dynamically generated class, and has
// no physical container,
// so just return null.
return null;
}
String packageRoot;
try {
// This is the full path to THIS file, but we need to get the
// package root.
String thisClass = c.getResource(c.getSimpleName() + ".class").toString();
packageRoot = replaceLast(thisClass, Pattern.quote(c.getName().replaceAll("\\.", "/") + ".class"), "");
if (packageRoot.endsWith("!/")) {
packageRoot = replaceLast(packageRoot, "!/", "");
}
} catch (Exception e) {
// Hmm, ok, try this then
packageRoot = c.getProtectionDomain().getCodeSource().getLocation().toString();
}
packageRoot = URLDecoder.decode(packageRoot, "UTF-8");
return packageRoot;
} catch (Exception e) {
throw new RuntimeException("While interrogating " + c.getName() + ", an unexpected exception was thrown.", e);
}
}
public static String replaceLast(String text, String regex, String replacement) {
return text.replaceFirst("(?s)" + regex + "(?!.*?" + regex + ")", replacement);
}
public static String getArch() {
if (is64Bit()) {
return "64";
} else {
return "32";
}
}
public static boolean is64Bit() {
return System.getProperty("sun.arch.data.model").contains("64");
}
public static String getRedirectedUrl(String url) throws MalformedURLException, IOException {
HttpURLConnection connection;
String finalUrl = url;
do {
connection = (HttpURLConnection) new URL(finalUrl).openConnection();
connection.setInstanceFollowRedirects(false);
connection.setUseCaches(false);
connection.setRequestMethod("GET");
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode >= 300 && responseCode < 400) {
String redirectedUrl = connection.getHeaderField("Location");
if (redirectedUrl == null) break;
finalUrl = redirectedUrl;
} else break;
} while (connection.getResponseCode() != HttpURLConnection.HTTP_OK);
connection.disconnect();
return finalUrl.replaceAll(" ", "%20");
}
public static int getLabelWidth(Label label) {
FontRenderContext frc = new FontRenderContext(label.getFont().getTransform(), true, true);
return (int) (label.getFont().getStringBounds(label.getText(), frc).getWidth()) + ((1 * label.getText().length()) / 2);
}
}