Reconstruct codes

This commit is contained in:
huangyuhui
2016-05-13 18:25:55 +08:00
parent 2862e3a6ee
commit ce721c2e09
297 changed files with 56 additions and 22 deletions

View File

@@ -1,140 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
*
* @author huangyuhui
*/
public class ArrayUtils {
public static <T> boolean isEmpty(T[] array) {
return array == null || array.length <= 0;
}
public static <T> boolean isNotEmpty(T[] array) {
return !isEmpty(array);
}
public static <T> boolean contains(T[] array, T objectToFind) {
return indexOf(array, objectToFind) != -1;
}
public static <T> int indexOf(T[] array, T valueToFind) {
return indexOf(array, valueToFind, 0);
}
public static <T> int indexOf(T[] array, T valueToFind, int startIndex) {
if (array == null)
return -1;
if (startIndex < 0)
startIndex = 0;
for (int i = startIndex; i < array.length; i++)
if (valueToFind.equals(array[i]))
return i;
return -1;
}
public static <T> int lastIndexOf(T[] array, T valueToFind) {
return lastIndexOf(array, valueToFind, 2147483647);
}
public static <T> int lastIndexOf(T[] array, T valueToFind, int startIndex) {
if (array == null)
return -1;
if (startIndex < 0)
return -1;
if (startIndex >= array.length)
startIndex = array.length - 1;
for (int i = startIndex; i >= 0; i--)
if (valueToFind.equals(array[i]))
return i;
return -1;
}
public static ArrayList merge(List a, List b) {
ArrayList al = new ArrayList(a.size() + b.size());
al.addAll(a);
al.addAll(b);
return al;
}
public static <K> K getEnd(K[] k) {
if (k == null)
return null;
else
return k[k.length - 1];
}
public static List tryGetMapWithList(Map map, String key) {
List l = (List) map.get(key);
if (l == null)
map.put(key, l = new ArrayList());
return l;
}
public static <T> int matchArray(T[] a, T[] b) {
for (int i = 0; i < a.length - b.length; i++) {
int j = 1;
for (int k = 0; k < b.length; k++) {
if (b[k].equals(a[(i + k)]))
continue;
j = 0;
break;
}
if (j != 0)
return i;
}
return -1;
}
public static <T> int matchArray(byte[] a, byte[] b) {
for (int i = 0; i < a.length - b.length; i++) {
int j = 1;
for (int k = 0; k < b.length; k++) {
if (b[k] == a[(i + k)])
continue;
j = 0;
break;
}
if (j != 0)
return i;
}
return -1;
}
public static <T> boolean equals(T[] a, T[] b) {
if (a == null && b == null)
return true;
if (a == null || b == null)
return false;
if (a.length != b.length)
return false;
Arrays.sort(a);
Arrays.sort(b);
for (int i = 0; i < a.length; i++)
if (a[i] == null && b[i] != null || a[i] != null && b[i] == null || !a[i].equals(b[i]))
return false;
return true;
}
}

View File

@@ -1,52 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.util.lang.SupportedLocales;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
*
* @author huangyuhui
*/
public final class C {
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
//http://repo1.maven.org/maven2
public static final String URL_PUBLISH = "http://www.mcbbs.net/thread-142335-1-1.html";
public static final String URL_TIEBA = "http://tieba.baidu.com/f?kw=hellominecraftlauncher";
public static final String URL_GITHUB = "https://github.com/huanghongxun/HMCL/issues";
public static final String URL_MINECRAFTFORUM = "http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-tools/1265720-hello-minecraft-launcher-1-9-3-mc-1-7-4-auto";
public static final String FILE_MINECRAFT_VERSIONS = "versions";
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static final String URL_FORGE_LIST = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/json";
public static final String URL_LITELOADER_LIST = "http://dl.liteloader.com/versions/versions.json";
private C() {
}
public static String i18n(String a, Object... format) {
return SupportedLocales.NOW_LOCALE.translate(a, format);
}
}

View File

@@ -1,49 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.util.func.Predicate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
*
* @author huangyuhui
*/
public final class CollectionUtils {
public static <T> ArrayList<T> map(Collection<T> coll, Predicate<T> p) {
ArrayList<T> newColl = new ArrayList<>();
for (T t : coll)
if (p.apply(t))
newColl.add(t);
return newColl;
}
public static <T> boolean removeIf(Collection<T> coll, Predicate<T> p) {
boolean removed = false;
final Iterator<T> each = coll.iterator();
while (each.hasNext())
if (p.apply(each.next())) {
each.remove();
removed = true;
}
return removed;
}
}

View File

@@ -1,90 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import java.io.IOException;
import java.io.OutputStream;
/**
*
* @author huangyuhui
*/
public class DoubleOutputStream extends OutputStream {
private OutputStream a = null;
private OutputStream b = null;
private boolean c = true;
public DoubleOutputStream(OutputStream paramOutputStream1, OutputStream paramOutputStream2) {
this(paramOutputStream1, paramOutputStream2, true);
}
private DoubleOutputStream(OutputStream paramOutputStream1, OutputStream paramOutputStream2, boolean paramBoolean) {
this.a = paramOutputStream1;
this.b = paramOutputStream2;
this.c = true;
}
@Override
public final void write(byte[] arr, int off, int len) throws IOException {
if (this.a != null)
this.a.write(arr, off, len);
if (this.b != null)
this.b.write(arr, off, len);
if (this.c)
flush();
}
@Override
public final void write(byte[] paramArrayOfByte) throws IOException {
if (this.a != null)
this.a.write(paramArrayOfByte);
if (this.b != null)
this.b.write(paramArrayOfByte);
if (this.c)
flush();
}
@Override
public final void write(int paramInt) throws IOException {
if (this.a != null)
this.a.write(paramInt);
if (this.b != null)
this.b.write(paramInt);
if (this.c)
flush();
}
@Override
public final void close() throws IOException {
flush();
if (this.a != null)
this.a.close();
if (this.b != null)
this.b.close();
}
@Override
public final void flush() throws IOException {
if (this.a != null)
this.a.flush();
if (this.b != null)
this.b.flush();
}
}

View File

@@ -1,28 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
/**
*
* @author huangyuhui
* @param <T> EventArgs
*/
public interface Event<T> {
boolean call(Object sender, T t);
}

View File

@@ -1,77 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import java.util.ArrayList;
import org.jackhuang.hellominecraft.util.func.Consumer;
/**
*
* @author huangyuhui
* @param <T> EventArgs
*/
public class EventHandler<T> {
ArrayList<Object> events = new ArrayList<>();
Object sender;
public EventHandler(Object sender) {
this.sender = sender;
}
public void register(Event<T> t) {
if (!events.contains(t))
events.add(t);
}
public void register(Consumer<T> t) {
if (!events.contains(t))
events.add(t);
}
public void register(Runnable t) {
if (!events.contains(t))
events.add(t);
}
public void unregister(Event<T> t) {
events.remove(t);
}
public void unregister(Consumer<T> t) {
events.remove(t);
}
public void unregister(Runnable t) {
events.remove(t);
}
public boolean execute(T x) {
boolean flag = true;
for (Object t : events)
if (t instanceof Event) {
if (!((Event) t).call(sender, x))
flag = false;
} else if (t instanceof Consumer)
((Consumer) t).accept(x);
else if (t instanceof Runnable)
((Runnable) t).run();
return flag;
}
}

View File

@@ -1,61 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import java.util.Map;
/**
*
* @author huangyuhui
*/
public interface IUpdateChecker {
/**
*
*/
void checkOutdate();
/**
* Get the <b>cached</b> newest version number, use "process" method to
* download!
*
* @return the newest version number
*
* @see process
*/
VersionNumber getNewVersion();
/**
* Download the version number synchronously. When you execute this method
* first, should leave "showMessage" false.
*
* @param showMessage If it is requested to warn the user that there is a
* new version.
*
* @return the process observable.
*/
OverridableSwingWorker<VersionNumber> process(boolean showMessage);
/**
* Get the download links.
*
* @return a JSON, which contains the server response.
*/
OverridableSwingWorker<Map<String, String>> requestDownloadLink();
}

View File

@@ -1,49 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.util.func.Consumer;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
/**
*
* @author huangyuhui
*/
public class LauncherPrintStream extends PrintStream {
private final ArrayList<Consumer<String>> printListeners = new ArrayList<>();
public LauncherPrintStream(OutputStream paramOutputStream) {
super(paramOutputStream);
}
@Override
public final void println(String paramString) {
super.println(paramString);
for (Consumer<String> a1 : printListeners)
a1.accept(paramString);
}
public final LauncherPrintStream addPrintListener(Consumer<String> paraml) {
this.printListeners.add(paraml);
return this;
}
}

View File

@@ -1,57 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
/**
*
* @author huang
*/
public class MathUtils {
public static int parseInt(String s, int def) {
try {
return Integer.parseInt(s);
} catch (Exception e) {
return def;
}
}
public static boolean canParseInt(String s) {
try {
Integer.parseInt(s);
return true;
} catch (Exception e) {
return false;
}
}
public static int parseMemory(String s, int def) {
try {
return Integer.parseInt(s);
} catch (Exception e) {
int a = parseInt(s.substring(0, s.length() - 1), def);
if (s.endsWith("g"))
return a * 1024;
else if (s.endsWith("k"))
return a / 1024;
else
return a;
}
}
}

View File

@@ -1,133 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.util.ui.SwingUtils;
import javax.swing.JOptionPane;
/**
* @author huangyuhui
*/
public class MessageBox {
private static final String TITLE = C.i18n("message.info");
/**
* Buttons: OK
*/
public static final int DEFAULT_OPTION = -1;
/**
* Buttons: Yes No
*/
public static final int YES_NO_OPTION = 10;
/**
* Buttons: Yes No Cancel
*/
public static final int YES_NO_CANCEL_OPTION = 11;
/**
* Buttons: OK Cancel
*/
public static final int OK_CANCEL_OPTION = 12;
/**
* User Operation: Yes
*/
public static final int YES_OPTION = 0;
/**
* User Operation: No
*/
public static final int NO_OPTION = 1;
/**
* User Operation: Cancel
*/
public static final int CANCEL_OPTION = 2;
/**
* User Operation: OK
*/
public static final int OK_OPTION = 0;
/**
* User Operation: Closed Message Box
*/
public static final int CLOSED_OPTION = -1;
/**
* Message Box Type: Error
*/
public static final int ERROR_MESSAGE = 0;
/**
* Message Box Type: Info
*/
public static final int INFORMATION_MESSAGE = 1;
/**
* Message Box Type: Warning
*/
public static final int WARNING_MESSAGE = 2;
/**
* Message Box Type: Question
*/
public static final int QUESTION_MESSAGE = 3;
/**
* Message Box Type: Plain
*/
public static final int PLAIN_MESSAGE = -1;
/**
* Show MsgBox with title and options
*
* @param Msg The Message
* @param Title The title of MsgBox.
* @param Option The type of MsgBox.
*
* @return user operation.
*/
public static int Show(String Msg, String Title, int Option) {
switch (Option) {
case YES_NO_OPTION:
case YES_NO_CANCEL_OPTION:
case OK_CANCEL_OPTION:
return SwingUtils.invokeAndWait(() -> JOptionPane.showConfirmDialog(null, Msg, Title, Option - 10));
default:
SwingUtils.invokeAndWait(() -> JOptionPane.showMessageDialog(null, Msg, Title, Option));
}
return 0;
}
/**
* Show MsgBox with options
*
* @param Msg The Message
* @param Option The type of MsgBox.
*
* @return User Operation
*/
public static int Show(String Msg, int Option) {
return Show(Msg, TITLE, Option);
}
/**
* Show Default MsgBox
*
* @param Msg The Message
*
* @return User Operation
*/
public static int Show(String Msg) {
return Show(Msg, TITLE, INFORMATION_MESSAGE);
}
public static int ShowLocalized(String msg) {
return Show(C.i18n(msg));
}
}

View File

@@ -1,195 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.ArrayUtils;
import org.jackhuang.hellominecraft.util.NetUtils;
/**
* @author huangyuhui
*/
public class MinecraftVersionRequest implements Serializable {
public static final int UNKOWN = 0, INVALID = 1, INVALID_JAR = 2,
MODIFIED = 3, OK = 4, NOT_FOUND = 5, UNREADABLE = 6, NOT_FILE = 7;
public int type;
public String version;
public static String getResponse(MinecraftVersionRequest minecraftVersion) {
String text = "";
switch (minecraftVersion.type) {
case MinecraftVersionRequest.INVALID:
text = C.i18n("minecraft.invalid");
break;
case MinecraftVersionRequest.INVALID_JAR:
text = C.i18n("minecraft.invalid_jar");
break;
case MinecraftVersionRequest.NOT_FILE:
text = C.i18n("minecraft.not_a_file");
break;
case MinecraftVersionRequest.NOT_FOUND:
text = C.i18n("minecraft.not_found");
break;
case MinecraftVersionRequest.UNREADABLE:
text = C.i18n("minecraft.not_readable");
break;
case MinecraftVersionRequest.MODIFIED:
text = C.i18n("minecraft.modified") + " ";
case MinecraftVersionRequest.OK:
text += minecraftVersion.version;
break;
case MinecraftVersionRequest.UNKOWN:
default:
text = "???";
break;
}
return text;
}
private static int lessThan32(byte[] b, int x) {
for (; x < b.length; x++)
if (b[x] < 32)
return x;
return -1;
}
private static MinecraftVersionRequest getVersionOfOldMinecraft(ZipFile file, ZipEntry entry) throws IOException {
MinecraftVersionRequest r = new MinecraftVersionRequest();
byte[] tmp = NetUtils.getBytesFromStream(file.getInputStream(entry));
byte[] bytes = "Minecraft Minecraft ".getBytes("ASCII");
int j;
if ((j = ArrayUtils.matchArray(tmp, bytes)) < 0) {
r.type = MinecraftVersionRequest.UNKOWN;
return r;
}
int i = j + bytes.length;
if ((j = lessThan32(tmp, i)) < 0) {
r.type = MinecraftVersionRequest.UNKOWN;
return r;
}
String ver = new String(tmp, i, j - i, "ASCII");
r.version = ver;
r.type = file.getEntry("META-INF/MANIFEST.MF") == null
? MinecraftVersionRequest.MODIFIED : MinecraftVersionRequest.OK;
return r;
}
private static MinecraftVersionRequest getVersionOfNewMinecraft(ZipFile file, ZipEntry entry) throws IOException {
MinecraftVersionRequest r = new MinecraftVersionRequest();
byte[] tmp = NetUtils.getBytesFromStream(file.getInputStream(entry));
byte[] str = "-server.txt".getBytes("ASCII");
int j = ArrayUtils.matchArray(tmp, str);
if (j < 0) {
r.type = MinecraftVersionRequest.UNKOWN;
return r;
}
int i = j + str.length;
i += 11;
j = lessThan32(tmp, i);
if (j < 0) {
r.type = MinecraftVersionRequest.UNKOWN;
return r;
}
r.version = new String(tmp, i, j - i, "ASCII");
char ch = r.version.charAt(0);
// 1.8.1+
if (ch < '0' || ch > '9') {
str = "Can't keep up! Did the system time change, or is the server overloaded?".getBytes("ASCII");
j = ArrayUtils.matchArray(tmp, str);
if (j < 0) {
r.type = MinecraftVersionRequest.UNKOWN;
return r;
}
i = -1;
while (j > 0) {
if (tmp[j] >= 48 && tmp[j] <= 57) {
i = j;
break;
}
j--;
}
if (i == -1) {
r.type = MinecraftVersionRequest.UNKOWN;
return r;
}
int k = i;
if (tmp[i + 1] >= (int) 'a' && tmp[i + 1] <= (int) 'z')
i++;
while (tmp[k] >= 48 && tmp[k] <= 57 || tmp[k] == (int) '-' || tmp[k] == (int) '.' || tmp[k] >= 97 && tmp[k] <= (int) 'z')
k--;
k++;
r.version = new String(tmp, k, i - k + 1);
}
r.type = file.getEntry("META-INF/MANIFEST.MF") == null
? MinecraftVersionRequest.MODIFIED : MinecraftVersionRequest.OK;
return r;
}
public static MinecraftVersionRequest minecraftVersion(File file) {
MinecraftVersionRequest r = new MinecraftVersionRequest();
if (file == null || !file.exists()) {
r.type = MinecraftVersionRequest.NOT_FOUND;
return r;
}
if (!file.isFile()) {
r.type = MinecraftVersionRequest.NOT_FILE;
return r;
}
if (!file.canRead()) {
r.type = MinecraftVersionRequest.UNREADABLE;
return r;
}
ZipFile localZipFile = null;
try {
localZipFile = new ZipFile(file);
ZipEntry minecraft = localZipFile
.getEntry("net/minecraft/client/Minecraft.class");
if (minecraft != null)
return getVersionOfOldMinecraft(localZipFile, minecraft);
ZipEntry main = localZipFile.getEntry("net/minecraft/client/main/Main.class");
ZipEntry minecraftserver = localZipFile.getEntry("net/minecraft/server/MinecraftServer.class");
if ((main != null) && (minecraftserver != null))
return getVersionOfNewMinecraft(localZipFile, minecraftserver);
r.type = MinecraftVersionRequest.INVALID;
return r;
} catch (IOException localException) {
HMCLog.warn("Zip file is invalid", localException);
r.type = MinecraftVersionRequest.INVALID_JAR;
return r;
} finally {
if (localZipFile != null)
try {
localZipFile.close();
} catch (IOException ex) {
HMCLog.warn("Failed to close zip file", ex);
}
}
}
}

View File

@@ -1,160 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.util.Map;
import org.jackhuang.hellominecraft.util.system.IOUtils;
/**
*
* @author huang
*/
public final class NetUtils {
public static byte[] getBytesFromStream(InputStream is) throws IOException {
ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
byte[] arrayOfByte1 = new byte[1024];
int i;
while ((i = is.read(arrayOfByte1)) >= 0)
localByteArrayOutputStream.write(arrayOfByte1, 0, i);
is.close();
return localByteArrayOutputStream.toByteArray();
}
public static String getStreamContent(InputStream is) throws IOException {
return getStreamContent(is, DEFAULT_CHARSET);
}
public static String getStreamContent(InputStream is, String encoding)
throws IOException {
if (is == null)
return null;
StringBuilder sb = new StringBuilder();
try (InputStreamReader br = new InputStreamReader(is, encoding)) {
int len;
char[] buf = new char[16384];
while ((len = br.read(buf)) != -1)
sb.append(buf, 0, len);
}
return sb.toString();
}
public static String get(String url, String encoding) throws IOException {
return getStreamContent(new URL(url).openConnection().getInputStream());
}
public static String get(String url) throws IOException {
return get(url, DEFAULT_CHARSET);
}
public static String get(URL url) throws IOException {
return get(url, Proxy.NO_PROXY);
}
public static String get(URL url, Proxy proxy) throws IOException {
return getStreamContent(url.openConnection(proxy).getInputStream());
}
public static String post(URL u, Map<String, String> params) throws IOException {
StringBuilder sb = new StringBuilder();
if (params != null) {
for (Map.Entry<String, String> e : params.entrySet()) {
sb.append(e.getKey());
sb.append("=");
sb.append(e.getValue());
sb.append("&");
}
sb.deleteCharAt(sb.length() - 1);
}
return post(u, sb.toString());
}
public static String post(URL u, String post) throws IOException {
return post(u, post, "application/x-www-form-urlencoded");
}
public static String post(URL u, String post, String contentType) throws IOException {
return post(u, post, contentType, Proxy.NO_PROXY);
}
public static String post(URL u, String post, String contentType, Proxy proxy) throws IOException {
HttpURLConnection con = (HttpURLConnection) u.openConnection(proxy);
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setDoInput(true);
con.setUseCaches(false);
con.setConnectTimeout(30000);
con.setReadTimeout(30000);
con.setRequestProperty("Content-Type", contentType + "; charset=utf-8");
byte[] bytes = post.getBytes(DEFAULT_CHARSET);
con.setRequestProperty("Content-Length", "" + bytes.length);
con.connect();
OutputStream os = null;
try {
os = con.getOutputStream();
IOUtils.write(bytes, os);
} finally {
IOUtils.closeQuietly(os);
}
String result;
InputStream is = null;
try {
is = con.getInputStream();
result = getStreamContent(is);
} catch (IOException ex) {
IOUtils.closeQuietly(is);
is = con.getErrorStream();
result = getStreamContent(is);
}
con.disconnect();
return result;
}
private static final String DEFAULT_CHARSET = "UTF-8";
public static URL constantURL(String url) {
try {
return new URL(url);
} catch (MalformedURLException ex) {
HMCLog.err("Failed to get url instance: " + url, ex);
return null;
}
}
public static URL concatenateURL(URL url, String query) {
try {
if ((url.getQuery() != null) && (url.getQuery().length() > 0))
return new URL(url.getProtocol(), url.getHost(), url.getPort(), new StringBuilder().append(url.getFile()).append("&").append(query).toString());
return new URL(url.getProtocol(), url.getHost(), url.getPort(), new StringBuilder().append(url.getFile()).append("?").append(query).toString());
} catch (MalformedURLException ex) {
throw new IllegalArgumentException("Could not concatenate given URL with GET arguments!", ex);
}
}
}

View File

@@ -1,80 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.SwingWorker;
import org.jackhuang.hellominecraft.util.func.Consumer;
/**
*
* @author huangyuhui
*/
public abstract class OverridableSwingWorker<T> extends SwingWorker<Void, T> {
List<Consumer<T>> processListeners = new ArrayList<>();
List<Runnable> doneListeners = new ArrayList<>();
protected abstract void work() throws Exception;
@Override
protected void done() {
for (Runnable c : doneListeners)
c.run();
}
@Override
protected Void doInBackground() throws Exception {
work();
return null;
}
public OverridableSwingWorker reg(Consumer<T> c) {
Utils.requireNonNull(c);
processListeners.add(c);
return this;
}
public OverridableSwingWorker regDone(Runnable c) {
Utils.requireNonNull(c);
doneListeners.add(c);
return this;
}
@Override
protected void process(List<T> chunks) {
for (T t : chunks)
for (Consumer<T> c : processListeners)
c.accept(t);
}
final List<T> lastChunks = new ArrayList<>();
protected void send(T... t) {
lastChunks.addAll(Arrays.asList(t));
publish(t);
}
public List<T> justDo() throws Exception {
work();
return lastChunks;
}
}

View File

@@ -1,78 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import java.util.Map;
import java.util.Objects;
/**
*
* @author huangyuhui
* @param <K> K Type
* @param <V> V Type
*/
public class Pair<K, V> implements Map.Entry<K, V> {
public K key;
public V value;
public Pair(K k, V v) {
key = k;
value = v;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public V setValue(V value) {
V t = this.value;
this.value = value;
return t;
}
@Override
public int hashCode() {
int hash = 5;
hash = 29 * hash + Objects.hashCode(this.key);
hash = 29 * hash + Objects.hashCode(this.value);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Pair<?, ?> other = (Pair<?, ?>) obj;
if (!Objects.equals(this.key, other.key))
return false;
return Objects.equals(this.value, other.value);
}
}

View File

@@ -1,253 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import java.awt.Dimension;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.StringTokenizer;
import org.jackhuang.hellominecraft.util.func.Function;
import org.jackhuang.hellominecraft.util.func.Predicate;
/**
*
* @author huang
*/
public final class StrUtils {
public static String substring(String src, int start_idx, int end_idx) {
byte[] b = src.getBytes();
String tgt = "";
for (int i = start_idx; i <= end_idx; i++)
tgt += (char) b[i];
return tgt;
}
public static String makeCommand(List<String> cmd) {
StringBuilder cmdbuf = new StringBuilder(120);
for (int i = 0; i < cmd.size(); i++) {
if (i > 0)
cmdbuf.append(' ');
String s = cmd.get(i);
if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0)
if (s.charAt(0) != '"') {
cmdbuf.append('"');
cmdbuf.append(s);
if (s.endsWith("\\"))
cmdbuf.append("\\");
cmdbuf.append('"');
} else if (s.endsWith("\""))
/*
* The argument has already been quoted.
*/
cmdbuf.append(s);
else
/*
* Unmatched quote for the argument.
*/
throw new IllegalArgumentException();
else
cmdbuf.append(s);
}
String str = cmdbuf.toString();
return str;
}
public static boolean startsWith(String base, String match) {
return base != null && base.startsWith(match);
}
public static boolean startsWithOne(String[] a, String match) {
if (a == null)
return false;
for (String b : a)
if (startsWith(match, b))
return true;
return false;
}
public static boolean startsWithOne(Collection<String> a, String match) {
if (a == null)
return false;
for (String b : a)
if (startsWith(match, b))
return true;
return false;
}
public static boolean equalsOne(String base, String... a) {
for (String s : a)
if (base.equals(s))
return true;
return false;
}
public static boolean containsOne(String base, String... match) {
for (String s : match)
if (base.contains(s))
return true;
return false;
}
public static boolean containsOne(List<String> base, List<String> match) {
for (String a : base)
for (String b : match)
if (a.toLowerCase().contains(b.toLowerCase()))
return true;
return false;
}
public static boolean containsOne(List<String> base, List<String> match, Predicate<String> pred) {
for (String a : base)
for (String b : match)
if (pred.apply(a) && a.toLowerCase().contains(b.toLowerCase()))
return true;
return false;
}
public static int getCharShowTime(String s, char c) {
int res = 0;
for (int i = 0; i < s.length(); i++)
if (s.charAt(i) == c)
res++;
return res;
}
public static String formatVersion(String ver) {
if (isBlank(ver))
return null;
else
for (char ch : ver.toCharArray())
if ((ch < '0' || ch > '9') && ch != '.')
return null;
int i = getCharShowTime(ver, '.');
if (i == 1)
return ver + ".0";
else
return ver;
}
public static String parseParams(String addBefore, Collection paramArrayOfObject, String paramString) {
return parseParams(addBefore, paramArrayOfObject.toArray(), paramString);
}
public static String parseParams(String addBefore, Object[] params, String addAfter) {
return parseParams(t -> addBefore, params, t -> addAfter);
}
public static String parseParams(Function<Object, String> beforeFunc, Object[] params, Function<Object, String> afterFunc) {
if (params == null)
return "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < params.length; i++) {
Object param = params[i];
String addBefore = beforeFunc.apply(param), addAfter = afterFunc.apply(param);
if (i > 0)
sb.append(addAfter).append(addBefore);
if (param == null)
sb.append("null");
else if (param.getClass().isArray()) {
sb.append("[");
if ((param instanceof Object[])) {
Object[] objs = (Object[]) param;
sb.append(parseParams(beforeFunc, objs, afterFunc));
} else
for (int j = 0; j < Array.getLength(param); j++) {
if (j > 0)
sb.append(addAfter);
sb.append(addBefore).append(Array.get(param, j));
}
sb.append("]");
} else
sb.append(addBefore).append(params[i]);
}
return sb.toString();
}
public static boolean equals(String base, String to) {
if (base == null)
return (to == null);
else
return base.equals(to);
}
public static Dimension parseDimension(String str) {
String[] tokenized = tokenize(str, "x,");
if (tokenized.length != 2)
return null;
int i = MathUtils.parseInt(tokenized[0], -1);
int j = MathUtils.parseInt(tokenized[1], -1);
if ((i < 0) || (j < 0))
return null;
return new Dimension(i, j);
}
public static String[] tokenize(String paramString1) {
return tokenize(paramString1, " \t\n\r\f");
}
public static String[] tokenize(String paramString1, String paramString2) {
ArrayList localArrayList = new ArrayList();
StringTokenizer tokenizer = new StringTokenizer(paramString1, paramString2);
while (tokenizer.hasMoreTokens()) {
paramString2 = tokenizer.nextToken();
localArrayList.add(paramString2);
}
return (String[]) localArrayList.toArray(new String[localArrayList.size()]);
}
public static String trimExtension(String filename) {
if ((filename != null) && (filename.length() > 0)) {
int i = filename.lastIndexOf('.');
if ((i > -1) && (i < (filename.length())))
return filename.substring(0, i);
}
return filename;
}
public static boolean isBlank(String s) {
return s == null || s.trim().length() <= 0;
}
public static boolean isNotBlank(String s) {
return !isBlank(s);
}
public static String getStackTrace(Throwable t) {
StringWriter trace = new StringWriter();
PrintWriter writer = new PrintWriter(trace);
t.printStackTrace(writer);
return trace.toString();
}
public static List<Integer> findAllPos(String t, String p) {
ArrayList<Integer> ret = new ArrayList<>();
int i = 0, index;
while ((index = t.indexOf(p, i)) != -1) {
ret.add(index);
i = index + p.length();
}
return ret;
}
}

View File

@@ -1,92 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import java.util.Map;
/**
*
* @author huangyuhui
*/
public final class UpdateChecker implements IUpdateChecker {
public boolean OUT_DATED = false;
public VersionNumber base;
public String versionString;
public String type;
private Map<String, String> download_link = null;
public UpdateChecker(VersionNumber base, String type) {
this.base = base;
this.type = type;
}
VersionNumber value;
@Override
public OverridableSwingWorker<VersionNumber> process(final boolean showMessage) {
return new OverridableSwingWorker() {
@Override
protected void work() throws Exception {
if (value == null) {
versionString = NetUtils.get("http://huangyuhui.duapp.com/info.php?type=" + type);
value = VersionNumber.check(versionString);
}
if (value == null) {
HMCLog.warn("Failed to check update...");
if (showMessage)
MessageBox.Show(C.i18n("update.failed"));
} else if (VersionNumber.isOlder(base, value))
OUT_DATED = true;
if (OUT_DATED)
publish(value);
}
};
}
@Override
public VersionNumber getNewVersion() {
return value;
}
@Override
public synchronized OverridableSwingWorker<Map<String, String>> requestDownloadLink() {
return new OverridableSwingWorker() {
@Override
protected void work() throws Exception {
if (download_link == null)
try {
download_link = C.GSON.fromJson(NetUtils.get("http://huangyuhui.duapp.com/update_link.php?type=" + type), Map.class);
} catch (Exception e) {
HMCLog.warn("Failed to get update link.", e);
}
publish(download_link);
}
};
}
public final EventHandler<VersionNumber> outdated = new EventHandler<>(this);
@Override
public void checkOutdate() {
if (OUT_DATED)
outdated.execute(getNewVersion());
}
}

View File

@@ -1,88 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import com.sun.management.OperatingSystemMXBean;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
/**
* @author huangyuhui
*/
public final class Utils {
@SuppressWarnings("ResultOfObjectAllocationIgnored")
public static boolean isURL(String s) {
try {
new URL(s);
return true;
} catch (MalformedURLException ex) {
return false;
}
}
public static URL[] getURL() {
return ((URLClassLoader) Utils.class.getClassLoader()).getURLs();
}
public static int getSuggestedMemorySize() {
try {
OperatingSystemMXBean osmb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
int memory = (int) (osmb.getTotalPhysicalMemorySize() / 1024 / 1024) / 4;
memory = Math.round((float) memory / 128.0f) * 128;
return memory;
} catch (Throwable t) {
HMCLog.warn("Failed to get total memory size, use 1024MB.", t);
return 1024;
}
}
public static void setClipborad(String text) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text), null);
}
/**
* In order to fight against the permission manager by Minecraft Forge.
*
* @param status exit code
*/
public static void shutdownForcely(int status) throws Exception {
Class z = Class.forName("java.lang.Shutdown");
Method exit = z.getDeclaredMethod("exit", int.class);
exit.setAccessible(true);
exit.invoke(z, status);
}
public static void requireNonNull(Object o) {
if (o == null)
throw new NullPointerException("Oh dear, there is a problem...");
}
public static Object firstNonNull(Object... o) {
for (Object s : o)
if (s != null)
return s;
return null;
}
}

View File

@@ -1,91 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
/**
*
* @author huangyuhui
*/
public final class VersionNumber implements Comparable<VersionNumber> {
public final byte firstVer, secondVer, thirdVer;
public final String version;
public VersionNumber(byte a, byte b, byte c) {
this(a, b, c, null);
}
public VersionNumber(byte a, byte b, byte c, String version) {
firstVer = a;
secondVer = b;
thirdVer = c;
this.version = version;
}
@Override
public String toString() {
return "" + firstVer + '.' + secondVer + '.' + thirdVer;
}
public static VersionNumber check(String data) {
while (!data.isEmpty() && ((data.charAt(0) < '0' || data.charAt(0) > '9') && data.charAt(0) != '.'))
data = data.substring(1);
if (data.isEmpty())
return null;
VersionNumber ur;
String[] ver = data.split("\\.");
if (ver.length >= 3) {
byte v1, v2, v3;
try {
v1 = Byte.parseByte(ver[0]);
v2 = Byte.parseByte(ver[1]);
v3 = Byte.parseByte(ver[2]);
ur = new VersionNumber(v1, v2, v3, data);
return ur;
} catch (Exception e) {
HMCLog.warn("Failed to parse the version", e);
}
}
return null;
}
public static boolean isOlder(VersionNumber a, VersionNumber b) {
if (a.firstVer < b.firstVer)
return true;
else if (a.firstVer == b.firstVer)
if (a.secondVer < b.secondVer)
return true;
else if (a.secondVer == b.secondVer)
if (a.thirdVer < b.thirdVer)
return true;
return false;
}
@Override
public int compareTo(VersionNumber o) {
if (isOlder(this, o))
return -1;
else if (isOlder(o, this))
return 1;
else
return 0;
}
}

View File

@@ -1,105 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.code;
import java.io.UnsupportedEncodingException;
/**
*
* @author huangyuhui
*/
public class Base64 {
public static char[] encode(byte[] data) {
char[] out = new char[((data.length + 2) / 3) * 4];
for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
boolean quad = false;
boolean trip = false;
int val = (0xFF & (int) data[i]);
val <<= 8;
if ((i + 1) < data.length) {
val |= (0xFF & (int) data[i + 1]);
trip = true;
}
val <<= 8;
if ((i + 2) < data.length) {
val |= (0xFF & (int) data[i + 2]);
quad = true;
}
out[index + 3] = ALPHABET[(quad ? (val & 0x3F) : 64)];
val >>= 6;
out[index + 2] = ALPHABET[(trip ? (val & 0x3F) : 64)];
val >>= 6;
out[index + 1] = ALPHABET[val & 0x3F];
val >>= 6;
out[index + 0] = ALPHABET[val & 0x3F];
}
return out;
}
public static char[] encode(String s, String charset) throws UnsupportedEncodingException {
return encode(s.getBytes(charset));
}
public static char[] encode(String s) {
return encode(s.getBytes());
}
public static byte[] decode(char[] data) {
int len = ((data.length + 3) / 4) * 3;
if (data.length > 0 && data[data.length - 1] == '=')
--len;
if (data.length > 1 && data[data.length - 2] == '=')
--len;
byte[] out = new byte[len];
int shift = 0;
int accum = 0;
int index = 0;
for (int ix = 0; ix < data.length; ix++) {
int value = CODES[data[ix] & 0xFF];
if (value >= 0) {
accum <<= 6;
shift += 6;
accum |= value;
if (shift >= 8) {
shift -= 8;
out[index++] = (byte) ((accum >> shift) & 0xff);
}
}
}
if (index != out.length)
throw new Error("miscalculated data length!");
return out;
}
private static final char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
.toCharArray();
private static final byte[] CODES = new byte[256];
static {
for (int i = 0; i < 256; i++)
CODES[i] = -1;
for (int i = 'A'; i <= 'Z'; i++)
CODES[i] = (byte) (i - 'A');
for (int i = 'a'; i <= 'z'; i++)
CODES[i] = (byte) (26 + i - 'a');
for (int i = '0'; i <= '9'; i++)
CODES[i] = (byte) (52 + i - '0');
CODES['+'] = 62;
CODES['/'] = 63;
}
}

View File

@@ -1,43 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.code;
import java.nio.charset.Charset;
public class Charsets {
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
public static final Charset US_ASCII = Charset.forName("US-ASCII");
public static final Charset UTF_16 = Charset.forName("UTF-16");
public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
public static final Charset UTF_8 = Charset.forName("UTF-8");
public static Charset toCharset(Charset charset) {
return charset == null ? Charset.defaultCharset() : charset;
}
public static Charset toCharset(String charset) {
return charset == null ? Charset.defaultCharset() : Charset.forName(charset);
}
}

View File

@@ -1,285 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.code;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
*
* @author huangyuhui
*/
public class DigestUtils {
private static final int STREAM_BUFFER_LENGTH = 1024;
private static byte[] digest(MessageDigest digest, InputStream data)
throws IOException {
return updateDigest(digest, data).digest();
}
public static MessageDigest getDigest(String algorithm) {
try {
return MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException(e);
}
}
public static MessageDigest getMd2Digest() {
return getDigest("MD2");
}
public static MessageDigest getMd5Digest() {
return getDigest("MD5");
}
public static MessageDigest getSha1Digest() {
return getDigest("SHA-1");
}
public static MessageDigest getSha256Digest() {
return getDigest("SHA-256");
}
public static MessageDigest getSha384Digest() {
return getDigest("SHA-384");
}
public static MessageDigest getSha512Digest() {
return getDigest("SHA-512");
}
@Deprecated
public static MessageDigest getShaDigest() {
return getSha1Digest();
}
public static byte[] md2(byte[] data) {
return getMd2Digest().digest(data);
}
public static byte[] md2(InputStream data)
throws IOException {
return digest(getMd2Digest(), data);
}
public static byte[] md2(String data) {
return md2(data.getBytes(Charsets.UTF_8));
}
public static String md2Hex(byte[] data) {
return Hex.encodeHexString(md2(data));
}
public static String md2Hex(InputStream data)
throws IOException {
return Hex.encodeHexString(md2(data));
}
public static String md2Hex(String data) {
return Hex.encodeHexString(md2(data));
}
public static byte[] md5(byte[] data) {
return getMd5Digest().digest(data);
}
public static byte[] md5(InputStream data)
throws IOException {
return digest(getMd5Digest(), data);
}
public static byte[] md5(String data) {
return md5(data.getBytes(Charsets.UTF_8));
}
public static String md5Hex(byte[] data) {
return Hex.encodeHexString(md5(data));
}
public static String md5Hex(InputStream data)
throws IOException {
return Hex.encodeHexString(md5(data));
}
public static String md5Hex(String data) {
return Hex.encodeHexString(md5(data));
}
@Deprecated
public static byte[] sha(byte[] data) {
return sha1(data);
}
@Deprecated
public static byte[] sha(InputStream data)
throws IOException {
return sha1(data);
}
@Deprecated
public static byte[] sha(String data) {
return sha1(data);
}
public static byte[] sha1(byte[] data) {
return getSha1Digest().digest(data);
}
public static byte[] sha1(InputStream data)
throws IOException {
return digest(getSha1Digest(), data);
}
public static byte[] sha1(String data) {
return sha1(data.getBytes(Charsets.UTF_8));
}
public static String sha1Hex(byte[] data) {
return Hex.encodeHexString(sha1(data));
}
public static String sha1Hex(InputStream data)
throws IOException {
return Hex.encodeHexString(sha1(data));
}
public static String sha1Hex(String data) {
return Hex.encodeHexString(sha1(data));
}
public static byte[] sha256(byte[] data) {
return getSha256Digest().digest(data);
}
public static byte[] sha256(InputStream data)
throws IOException {
return digest(getSha256Digest(), data);
}
public static byte[] sha256(String data) {
return sha256(data.getBytes(Charsets.UTF_8));
}
public static String sha256Hex(byte[] data) {
return Hex.encodeHexString(sha256(data));
}
public static String sha256Hex(InputStream data)
throws IOException {
return Hex.encodeHexString(sha256(data));
}
public static String sha256Hex(String data) {
return Hex.encodeHexString(sha256(data));
}
public static byte[] sha384(byte[] data) {
return getSha384Digest().digest(data);
}
public static byte[] sha384(InputStream data)
throws IOException {
return digest(getSha384Digest(), data);
}
public static byte[] sha384(String data) {
return sha384(data.getBytes(Charsets.UTF_8));
}
public static String sha384Hex(byte[] data) {
return Hex.encodeHexString(sha384(data));
}
public static String sha384Hex(InputStream data)
throws IOException {
return Hex.encodeHexString(sha384(data));
}
public static String sha384Hex(String data) {
return Hex.encodeHexString(sha384(data));
}
public static byte[] sha512(byte[] data) {
return getSha512Digest().digest(data);
}
public static byte[] sha512(InputStream data)
throws IOException {
return digest(getSha512Digest(), data);
}
public static byte[] sha512(String data) {
return sha512(data.getBytes(Charsets.UTF_8));
}
public static String sha512Hex(byte[] data) {
return Hex.encodeHexString(sha512(data));
}
public static String sha512Hex(InputStream data)
throws IOException {
return Hex.encodeHexString(sha512(data));
}
public static String sha512Hex(String data) {
return Hex.encodeHexString(sha512(data));
}
@Deprecated
public static String shaHex(byte[] data) {
return sha1Hex(data);
}
@Deprecated
public static String shaHex(InputStream data)
throws IOException {
return sha1Hex(data);
}
@Deprecated
public static String shaHex(String data) {
return sha1Hex(data);
}
public static MessageDigest updateDigest(MessageDigest messageDigest, byte[] valueToDigest) {
messageDigest.update(valueToDigest);
return messageDigest;
}
public static MessageDigest updateDigest(MessageDigest digest, InputStream data)
throws IOException {
byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
while (read > -1) {
digest.update(buffer, 0, read);
read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
}
return digest;
}
public static MessageDigest updateDigest(MessageDigest messageDigest, String valueToDigest) {
messageDigest.update(valueToDigest.getBytes(Charsets.UTF_8));
return messageDigest;
}
}

View File

@@ -1,134 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.code;
import java.nio.charset.Charset;
public class Hex {
public static final Charset DEFAULT_CHARSET = Charsets.UTF_8;
public static final String DEFAULT_CHARSET_NAME = "UTF-8";
private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private final Charset charset;
public static byte[] decodeHex(char[] data) throws Exception {
int len = data.length;
if ((len & 0x1) != 0)
throw new Exception("Odd number of characters.");
byte[] out = new byte[len >> 1];
int i = 0;
for (int j = 0; j < len; i++) {
int f = toDigit(data[j], j) << 4;
j++;
f |= toDigit(data[j], j);
j++;
out[i] = (byte) (f & 0xFF);
}
return out;
}
public static char[] encodeHex(byte[] data) {
return encodeHex(data, true);
}
public static char[] encodeHex(byte[] data, boolean toLowerCase) {
return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
}
protected static char[] encodeHex(byte[] data, char[] toDigits) {
int l = data.length;
char[] out = new char[l << 1];
int i = 0;
for (int j = 0; i < l; i++) {
out[(j++)] = toDigits[((0xF0 & data[i]) >>> 4)];
out[(j++)] = toDigits[(0xF & data[i])];
}
return out;
}
public static String encodeHexString(byte[] data) {
return new String(encodeHex(data));
}
protected static int toDigit(char ch, int index) {
int digit = Character.digit(ch, 16);
if (digit == -1)
throw new IllegalArgumentException("Illegal hexadecimal character " + ch + " at index " + index);
return digit;
}
public Hex() {
this.charset = DEFAULT_CHARSET;
}
public Hex(Charset charset) {
this.charset = charset;
}
public Hex(String charsetName) {
this(Charset.forName(charsetName));
}
public byte[] decode(byte[] array) throws Exception {
return decodeHex(new String(array, getCharset()).toCharArray());
}
public Object decode(Object object) throws Exception {
try {
char[] charArray = (object instanceof String) ? ((String) object).toCharArray() : (char[]) (char[]) object;
return decodeHex(charArray);
} catch (ClassCastException e) {
throw new Exception(e.getMessage(), e);
}
}
public byte[] encode(byte[] array) {
return encodeHexString(array).getBytes(getCharset());
}
public Object encode(Object object)
throws Exception {
try {
byte[] byteArray = (object instanceof String) ? ((String) object).getBytes(getCharset()) : (byte[]) (byte[]) object;
return encodeHex(byteArray);
} catch (ClassCastException e) {
throw new Exception(e.getMessage(), e);
}
}
public Charset getCharset() {
return this.charset;
}
public String getCharsetName() {
return this.charset.name();
}
@Override
public String toString() {
return super.toString() + "[charsetName=" + this.charset + "]";
}
}

View File

@@ -1,26 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.func;
/**
* @author huangyuhui
*/
public interface BiConsumer<V, V2> {
void call(V value, V2 value2);
}

View File

@@ -1,27 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.func;
/**
*
* @author huangyuhui
*/
public interface BiFunction<A, B, C> {
C apply(A a, B b);
}

View File

@@ -1,29 +0,0 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.func;
import java.io.IOException;
/**
*
* @author huangyuhui
*/
public interface CallbackIO<T> {
void call(T t) throws IOException;
}

View File

@@ -1,27 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.func;
/**
*
* @author huangyuhui
*/
public interface Consumer<T> {
void accept(T t);
}

View File

@@ -1,27 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.func;
/**
*
* @author huangyuhui
*/
public interface Function<T, R> {
R apply(T t);
}

View File

@@ -1,27 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.func;
/**
*
* @author huangyuhui
*/
public interface NonFunction<T> {
T apply();
}

View File

@@ -1,27 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.func;
/**
*
* @author huangyuhui
*/
public interface Predicate<T> {
boolean apply(T t);
}

View File

@@ -1,27 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.func;
/**
*
* @author huangyuhui
*/
public interface TriConsumer<V1, V2, V3> {
void onDone(V1 v1, V2 v2, V3 v3);
}

View File

@@ -1,75 +0,0 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.lang;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.system.IOUtils;
/**
*
* @author huangyuhui
*/
public class Localization {
private static final String ROOT_LOCATION = "/org/jackhuang/hellominecraft/lang/I18N%s.lang";
private static final Map<Locale, Localization> INSTANCE = new HashMap<>();
private final Map<String, String> lang;
private Localization(Locale locale) {
InputStream is = Localization.class.getResourceAsStream(String.format(ROOT_LOCATION, "_" + locale.getLanguage() + "_" + locale.getCountry()));
if (is == null)
is = Localization.class.getResourceAsStream(String.format(ROOT_LOCATION, "_" + locale.getLanguage()));
if (is == null)
is = Localization.class.getResourceAsStream(String.format(ROOT_LOCATION, ""));
if (is == null)
throw new RuntimeException("LANG FILE MISSING");
this.lang = new HashMap<>();
try {
String[] strings = IOUtils.readFully(is).toString("UTF-8").split("\n");
for (String s : strings)
if (!s.isEmpty() && s.charAt(0) != 35) {
int i = s.indexOf("=");
if (i == -1)
continue;
lang.put(s.substring(0, i), s.substring(i + 1));
}
} catch (IOException ex) {
HMCLog.err("LANG FILE MISSING", ex);
}
}
public synchronized String localize(String key) {
String s = lang.get(key);
return s == null ? key : s;
}
public static Localization get(Locale l) {
if (!INSTANCE.containsKey(l))
INSTANCE.put(l, new Localization(l));
return INSTANCE.get(l);
}
}

View File

@@ -1,62 +0,0 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.lang;
import java.util.Locale;
/**
*
* @author huangyuhui
*/
public enum SupportedLocales {
def(Locale.getDefault(), "lang.default"), en(Locale.ENGLISH, null), zh_TW(Locale.TRADITIONAL_CHINESE, null), zh_CN(Locale.SIMPLIFIED_CHINESE, null);
public Locale self;
private String showString, customized;
private Localization bundle;
private SupportedLocales(Locale self, String customized) {
this.self = self;
try {
bundle = Localization.get(self);
showString = bundle.localize("lang");
this.customized = customized;
} catch (Throwable t) {
showString = name();
t.printStackTrace();
}
}
public String showString() {
if (customized == null)
return showString;
else
return NOW_LOCALE.translate(customized);
}
public static SupportedLocales NOW_LOCALE = def;
public String translate(String key, Object... format) {
try {
return String.format(bundle.localize(key), format);
} catch (Exception ex) {
ex.printStackTrace();
return key;
}
}
}

View File

@@ -1,68 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging;
import org.jackhuang.hellominecraft.util.logging.appender.IAppender;
public class AppenderControl {
private final ThreadLocal<AppenderControl> recursive = new ThreadLocal();
private final IAppender appender;
private final Level level;
private final int intLevel;
public AppenderControl(IAppender appender, Level level) {
this.appender = appender;
this.level = level;
this.intLevel = (level == null ? Level.ALL.level : level.level);
}
public IAppender getAppender() {
return this.appender;
}
public void callAppender(LogEvent event) {
if ((this.level != null)
&& (this.intLevel < event.level.level))
return;
if (this.recursive.get() != null) {
System.err.println("Recursive call to appender " + this.appender.getName());
return;
}
try {
this.recursive.set(this);
try {
this.appender.append(event);
} catch (RuntimeException ex) {
System.err.println("An exception occurred processing Appender " + this.appender.getName());
ex.printStackTrace();
if (!this.appender.ignoreExceptions())
throw ex;
} catch (Exception ex) {
System.err.println("An exception occurred processing Appender " + this.appender.getName());
ex.printStackTrace();
if (!this.appender.ignoreExceptions())
throw new LoggingException(ex);
}
} finally {
this.recursive.set(null);
}
}
}

View File

@@ -1,40 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging;
import java.util.ArrayList;
import org.jackhuang.hellominecraft.util.logging.appender.ConsoleAppender;
import org.jackhuang.hellominecraft.util.logging.appender.IAppender;
import org.jackhuang.hellominecraft.util.logging.layout.DefaultLayout;
/**
*
* @author huangyuhui
*/
public class Configuration {
public ArrayList<IAppender> appenders = new ArrayList<>();
public static final Configuration DEFAULT;
static {
DEFAULT = new Configuration();
DEFAULT.appenders.add(new ConsoleAppender("Console", new DefaultLayout(), true, new ConsoleAppender.SystemOutStream(), true));
}
}

View File

@@ -1,58 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging;
import org.jackhuang.hellominecraft.util.logging.logger.Logger;
/**
*
* @author huangyuhui
*/
public class HMCLog {
private static final Logger LOGGER = new Logger("Hello Minecraft!");
public static void log(String message) {
LOGGER.info(message);
}
public static void warn(String message) {
LOGGER.warn(message);
}
public static void debug(String message) {
LOGGER.debug(message);
}
public static void warn(String msg, Throwable t) {
LOGGER.warn(msg, t);
}
public static void debug(String msg, Throwable t) {
LOGGER.debug(msg, t);
}
public static void err(String msg) {
LOGGER.error(msg);
}
public static void err(String msg, Throwable t) {
LOGGER.error(msg, t);
}
}

View File

@@ -1,109 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging;
import java.awt.Color;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* @author huangyuhui
*/
public enum Level {
OFF(0, Color.gray),
FATAL(1, Color.red),
ERROR(2, Color.red),
WARN(3, Color.orange),
INFO(4, Color.black),
DEBUG(5, Color.blue),
TRACE(6, Color.blue),
ALL(2147483647, Color.black);
public final int level;
public final Color COLOR;
private Level(int i, Color c) {
level = i;
COLOR = c;
}
public boolean lessOrEqual(Level level) {
return this.level <= level.level;
}
public boolean lessOrEqual(int level) {
return this.level <= level;
}
public static final Pattern MINECRAFT_LOGGER = Pattern.compile("\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]");
public static final String JAVA_SYMBOL = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*";
public static Level guessLevel(String line, Level level) {
Matcher m = MINECRAFT_LOGGER.matcher(line);
if (m.find()) {
// New style logs from log4j
String levelStr = m.group("level");
if (null != levelStr)
switch (levelStr) {
case "INFO":
level = INFO;
break;
case "WARN":
level = WARN;
break;
case "ERROR":
level = ERROR;
break;
case "FATAL":
level = FATAL;
break;
case "TRACE":
level = TRACE;
break;
case "DEBUG":
level = DEBUG;
break;
default:
break;
}
} else {
if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]")
|| line.contains("[FINER]") || line.contains("[FINEST]"))
level = INFO;
if (line.contains("[SEVERE]") || line.contains("[STDERR]"))
level = ERROR;
if (line.contains("[WARNING]"))
level = WARN;
if (line.contains("[DEBUG]"))
level = DEBUG;
}
if (line.contains("overwriting existing"))
return FATAL;
if (line.contains("Exception in thread")
|| line.matches("\\s+at " + JAVA_SYMBOL)
|| line.matches("Caused by: " + JAVA_SYMBOL)
|| line.matches("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)")
|| line.matches("... \\d+ more$"))
return ERROR;
return level;
}
}

View File

@@ -1,33 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging;
import org.jackhuang.hellominecraft.util.logging.message.IMessage;
/**
*
* @author huangyuhui
*/
public class LogEvent {
public Level level;
public String threadName;
public Throwable thrown;
public IMessage message;
}

View File

@@ -1,30 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging;
/**
*
* @author huangyuhui
*/
public class LoggingException extends RuntimeException {
public LoggingException(Exception e) {
super(e);
}
}

View File

@@ -1,57 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.appender;
import java.io.Serializable;
import org.jackhuang.hellominecraft.util.logging.layout.ILayout;
/**
*
* @author huangyuhui
*/
public abstract class AbstractAppender implements IAppender {
String name;
private final ILayout<? extends Serializable> layout;
private final boolean ignoreExceptions;
public AbstractAppender(String name, ILayout<? extends Serializable> layout) {
this(name, layout, true);
}
public AbstractAppender(String name, ILayout<? extends Serializable> layout, boolean ignoreExceptions) {
this.name = name;
this.layout = layout;
this.ignoreExceptions = ignoreExceptions;
}
@Override
public String getName() {
return name;
}
@Override
public boolean ignoreExceptions() {
return ignoreExceptions;
}
@Override
public ILayout<? extends Serializable> getLayout() {
return this.layout;
}
}

View File

@@ -1,90 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.appender;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import org.jackhuang.hellominecraft.util.logging.layout.ILayout;
/**
*
* @author huangyuhui
*/
public class ConsoleAppender extends OutputStreamAppender {
public ConsoleAppender(String name, ILayout<? extends Serializable> layout, boolean ignoreExceptions, OutputStream stream, boolean immediateFlush) {
super(name, layout, ignoreExceptions, stream, true);
}
public static class SystemOutStream extends OutputStream {
@Override
public void close() {
}
@Override
public void flush() {
System.out.flush();
}
@Override
public void write(byte[] b) throws IOException {
System.out.write(b);
}
@Override
public void write(byte[] b, int off, int len)
throws IOException {
System.out.write(b, off, len);
}
@Override
public void write(int b) throws IOException {
System.out.write(b);
}
}
public static class SystemErrStream extends OutputStream {
@Override
public void close() {
}
@Override
public void flush() {
System.err.flush();
}
@Override
public void write(byte[] b) throws IOException {
System.err.write(b);
}
@Override
public void write(byte[] b, int off, int len)
throws IOException {
System.err.write(b, off, len);
}
@Override
public void write(int b) {
System.err.write(b);
}
}
}

View File

@@ -1,38 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.appender;
import java.io.Serializable;
import org.jackhuang.hellominecraft.util.logging.LogEvent;
import org.jackhuang.hellominecraft.util.logging.layout.ILayout;
/**
*
* @author huangyuhui
*/
public interface IAppender {
void append(LogEvent event);
String getName();
boolean ignoreExceptions();
ILayout<? extends Serializable> getLayout();
}

View File

@@ -1,63 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.appender;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.jackhuang.hellominecraft.util.logging.LogEvent;
import org.jackhuang.hellominecraft.util.logging.LoggingException;
import org.jackhuang.hellominecraft.util.logging.layout.ILayout;
/**
*
* @author huangyuhui
*/
public abstract class OutputStreamAppender extends AbstractAppender {
protected final OutputStream stream;
protected final boolean immediateFlush;
private final Lock readLock = new ReentrantReadWriteLock().readLock();
public OutputStreamAppender(String name, ILayout<? extends Serializable> layout, boolean ignoreExceptions, OutputStream stream, boolean immediateFlush) {
super(name, layout, ignoreExceptions);
this.immediateFlush = immediateFlush;
this.stream = stream;
}
@Override
public void append(LogEvent event) {
this.readLock.lock();
try {
byte[] bytes = getLayout().toByteArray(event);
if (bytes.length > 0)
stream.write(bytes);
if (event.thrown != null)
event.thrown.printStackTrace(new PrintStream(stream));
} catch (IOException ex) {
System.err.println("Unable to write to stream for appender: " + getName());
throw new LoggingException(ex);
} finally {
this.readLock.unlock();
}
}
}

View File

@@ -1,33 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.layout;
import org.jackhuang.hellominecraft.util.logging.LogEvent;
/**
*
* @author huangyuhui
*/
public abstract class AbstractStringLayout implements ILayout<String> {
@Override
public byte[] toByteArray(LogEvent event) {
return toSerializable(event).getBytes();
}
}

View File

@@ -1,37 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.layout;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.jackhuang.hellominecraft.util.logging.LogEvent;
/**
*
* @author huangyuhui
*/
public class DefaultLayout extends AbstractStringLayout {
private static final SimpleDateFormat SDF = new SimpleDateFormat("HH:mm:ss");
@Override
public String toSerializable(LogEvent event) {
return "[" + SDF.format(new Date()) + "] [" + event.threadName + "/" + event.level.name() + "] " + event.message.getFormattedMessage() + "\n";
}
}

View File

@@ -1,34 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.layout;
import java.io.Serializable;
import org.jackhuang.hellominecraft.util.logging.LogEvent;
/**
*
* @author huangyuhui
* @param <T>
*/
public interface ILayout<T extends Serializable> {
byte[] toByteArray(LogEvent event);
T toSerializable(LogEvent event);
}

View File

@@ -1,485 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.logger;
import org.jackhuang.hellominecraft.util.logging.Level;
import org.jackhuang.hellominecraft.util.logging.message.IMessage;
import org.jackhuang.hellominecraft.util.logging.message.IMessageFactory;
import org.jackhuang.hellominecraft.util.logging.message.ParameterizedMessageFactory;
import org.jackhuang.hellominecraft.util.logging.message.StringFormattedMessage;
public abstract class AbstractLogger
implements ILogger {
public static final Class<? extends IMessageFactory> DEFAULT_MESSAGE_FACTORY_CLASS = ParameterizedMessageFactory.class;
private static final String FQCN = AbstractLogger.class.getName();
private static final String THROWING = "throwing";
private static final String CATCHING = "catching";
private final String name;
private final IMessageFactory messageFactory;
public AbstractLogger() {
this.name = getClass().getName();
this.messageFactory = createDefaultMessageFactory();
}
public AbstractLogger(String name) {
this.name = name;
this.messageFactory = createDefaultMessageFactory();
}
public AbstractLogger(String name, IMessageFactory messageFactory) {
this.name = name;
this.messageFactory = (messageFactory == null ? createDefaultMessageFactory() : messageFactory);
}
private IMessageFactory createDefaultMessageFactory() {
try {
return (IMessageFactory) DEFAULT_MESSAGE_FACTORY_CLASS.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
@Override
public void catching(Level level, Throwable t) {
if (isEnabled(level, (Object) null, null))
log(level, this.messageFactory.newMessage(CATCHING), t);
}
@Override
public void catching(Throwable t) {
catching(Level.ERROR, t);
}
@Override
public void debug(IMessage msg) {
if (isEnabled(Level.DEBUG, msg, null))
log(Level.DEBUG, msg, null);
}
@Override
public void debug(IMessage msg, Throwable t) {
if (isEnabled(Level.DEBUG, msg, t))
log(Level.DEBUG, msg, t);
}
@Override
public void debug(Object message) {
if (isEnabled(Level.DEBUG, message, null))
log(Level.DEBUG, this.messageFactory.newMessage(message), null);
}
@Override
public void debug(Object message, Throwable t) {
if (isEnabled(Level.DEBUG, message, t))
log(Level.DEBUG, this.messageFactory.newMessage(message), t);
}
@Override
public void debug(String message) {
if (isEnabled(Level.DEBUG, message))
log(Level.DEBUG, this.messageFactory.newMessage(message), null);
}
@Override
public void debug(String message, Object[] params) {
if (isEnabled(Level.DEBUG, message, params)) {
IMessage msg = this.messageFactory.newMessage(message, params);
log(Level.DEBUG, msg, msg.getThrowable());
}
}
@Override
public void debug(String message, Throwable t) {
if (isEnabled(Level.DEBUG, message, t))
log(Level.DEBUG, this.messageFactory.newMessage(message), t);
}
@Override
public void entry() {
entry(new Object[0]);
}
@Override
public void entry(Object[] params) {
if (isEnabled(Level.TRACE, (Object) null, null))
log(Level.TRACE, entryMsg(params.length, params), null);
}
private IMessage entryMsg(int count, Object[] params) {
if (count == 0)
return this.messageFactory.newMessage("entry");
StringBuilder sb = new StringBuilder("entry params(");
int i = 0;
for (Object parm : params) {
if (parm != null)
sb.append(parm.toString());
else
sb.append("null");
i++;
if (i < params.length)
sb.append(", ");
}
sb.append(")");
return this.messageFactory.newMessage(sb.toString());
}
@Override
public void error(IMessage msg) {
if (isEnabled(Level.ERROR, msg, null))
log(Level.ERROR, msg, null);
}
@Override
public void error(IMessage msg, Throwable t) {
if (isEnabled(Level.ERROR, msg, t))
log(Level.ERROR, msg, t);
}
@Override
public void error(Object message) {
if (isEnabled(Level.ERROR, message, null))
log(Level.ERROR, this.messageFactory.newMessage(message), null);
}
@Override
public void error(Object message, Throwable t) {
if (isEnabled(Level.ERROR, message, t))
log(Level.ERROR, this.messageFactory.newMessage(message), t);
}
@Override
public void error(String message) {
if (isEnabled(Level.ERROR, message))
log(Level.ERROR, this.messageFactory.newMessage(message), null);
}
@Override
public void error(String message, Object[] params) {
if (isEnabled(Level.ERROR, message, params)) {
IMessage msg = this.messageFactory.newMessage(message, params);
log(Level.ERROR, msg, msg.getThrowable());
}
}
@Override
public void error(String message, Throwable t) {
if (isEnabled(Level.ERROR, message, t))
log(Level.ERROR, this.messageFactory.newMessage(message), t);
}
@Override
public void fatal(IMessage msg) {
if (isEnabled(Level.FATAL, msg, null))
log(Level.FATAL, msg, null);
}
@Override
public void fatal(IMessage msg, Throwable t) {
if (isEnabled(Level.FATAL, msg, t))
log(Level.FATAL, msg, t);
}
@Override
public void fatal(Object message) {
if (isEnabled(Level.FATAL, message, null))
log(Level.FATAL, this.messageFactory.newMessage(message), null);
}
@Override
public void fatal(Object message, Throwable t) {
if (isEnabled(Level.FATAL, message, t))
log(Level.FATAL, this.messageFactory.newMessage(message), t);
}
@Override
public void fatal(String message) {
if (isEnabled(Level.FATAL, message))
log(Level.FATAL, this.messageFactory.newMessage(message), null);
}
@Override
public void fatal(String message, Object[] params) {
if (isEnabled(Level.FATAL, message, params)) {
IMessage msg = this.messageFactory.newMessage(message, params);
log(Level.FATAL, msg, msg.getThrowable());
}
}
@Override
public void fatal(String message, Throwable t) {
if (isEnabled(Level.FATAL, message, t))
log(Level.FATAL, this.messageFactory.newMessage(message), t);
}
@Override
public String getName() {
return this.name;
}
@Override
public void info(IMessage msg) {
if (isEnabled(Level.INFO, msg, null))
log(Level.INFO, msg, null);
}
@Override
public void info(IMessage msg, Throwable t) {
if (isEnabled(Level.INFO, msg, t))
log(Level.INFO, msg, t);
}
@Override
public void info(Object message) {
if (isEnabled(Level.INFO, message, null))
log(Level.INFO, this.messageFactory.newMessage(message), null);
}
@Override
public void info(Object message, Throwable t) {
if (isEnabled(Level.INFO, message, t))
log(Level.INFO, this.messageFactory.newMessage(message), t);
}
@Override
public void info(String message) {
if (isEnabled(Level.INFO, message))
log(Level.INFO, this.messageFactory.newMessage(message), null);
}
@Override
public void info(String message, Object[] params) {
if (isEnabled(Level.INFO, message, params)) {
IMessage msg = this.messageFactory.newMessage(message, params);
log(Level.INFO, msg, msg.getThrowable());
}
}
@Override
public void info(String message, Throwable t) {
if (isEnabled(Level.INFO, message, t))
log(Level.INFO, this.messageFactory.newMessage(message), t);
}
protected abstract boolean isEnabled(Level paramLevel, IMessage paramIMessage, Throwable paramThrowable);
protected abstract boolean isEnabled(Level paramLevel, Object paramObject, Throwable paramThrowable);
protected abstract boolean isEnabled(Level paramLevel, String paramString);
protected abstract boolean isEnabled(Level paramLevel, String paramString, Object[] paramArrayOfObject);
protected abstract boolean isEnabled(Level paramLevel, String paramString, Throwable paramThrowable);
protected abstract void abstractLog(Level level, IMessage msg, Throwable t);
@Override
public boolean isErrorEnabled() {
return isEnabled(Level.ERROR);
}
@Override
public boolean isFatalEnabled() {
return isEnabled(Level.FATAL);
}
@Override
public boolean isInfoEnabled() {
return isEnabled(Level.INFO);
}
@Override
public boolean isTraceEnabled() {
return isEnabled(Level.TRACE);
}
@Override
public boolean isWarnEnabled() {
return isEnabled(Level.WARN);
}
@Override
public boolean isDebugEnabled() {
return isEnabled(Level.DEBUG);
}
@Override
public boolean isEnabled(Level level) {
return isEnabled(level, (Object) null, null);
}
@Override
public void log(Level level, IMessage msg) {
if (isEnabled(level, msg, null))
log(level, msg, null);
}
@Override
public void log(Level level, IMessage msg, Throwable t) {
if (isEnabled(level, msg, t))
abstractLog(level, msg, t);
}
@Override
public void log(Level level, Object message) {
if (isEnabled(level, message, null))
log(level, this.messageFactory.newMessage(message), null);
}
@Override
public void log(Level level, Object message, Throwable t) {
if (isEnabled(level, message, t))
log(level, this.messageFactory.newMessage(message), t);
}
@Override
public void log(Level level, String message) {
if (isEnabled(level, message))
log(level, this.messageFactory.newMessage(message), null);
}
@Override
public void log(Level level, String message, Object[] params) {
if (isEnabled(level, message, params)) {
IMessage msg = this.messageFactory.newMessage(message, params);
log(level, msg, msg.getThrowable());
}
}
@Override
public void log(Level level, String message, Throwable t) {
if (isEnabled(level, message, t))
log(level, this.messageFactory.newMessage(message), t);
}
@Override
public void printf(Level level, String format, Object[] params) {
if (isEnabled(level, format, params)) {
IMessage msg = new StringFormattedMessage(format, params);
log(level, msg, msg.getThrowable());
}
}
@Override
public <T extends Throwable> T throwing(T t) {
return throwing(Level.ERROR, t);
}
@Override
public <T extends Throwable> T throwing(Level level, T t) {
if (isEnabled(level, (Object) null, null))
log(level, this.messageFactory.newMessage(THROWING), t);
return t;
}
@Override
public String toString() {
return this.name;
}
@Override
public void trace(IMessage msg) {
if (isEnabled(Level.TRACE, msg, null))
log(Level.TRACE, msg, null);
}
@Override
public void trace(IMessage msg, Throwable t) {
if (isEnabled(Level.TRACE, msg, t))
log(Level.TRACE, msg, t);
}
@Override
public void trace(Object message) {
if (isEnabled(Level.TRACE, message, null))
log(Level.TRACE, this.messageFactory.newMessage(message), null);
}
@Override
public void trace(Object message, Throwable t) {
if (isEnabled(Level.TRACE, message, t))
log(Level.TRACE, this.messageFactory.newMessage(message), t);
}
@Override
public void trace(String message) {
if (isEnabled(Level.TRACE, message))
log(Level.TRACE, this.messageFactory.newMessage(message), null);
}
@Override
public void trace(String message, Object[] params) {
if (isEnabled(Level.TRACE, message, params)) {
IMessage msg = this.messageFactory.newMessage(message, params);
log(Level.TRACE, msg, msg.getThrowable());
}
}
@Override
public void trace(String message, Throwable t) {
if (isEnabled(Level.TRACE, message, t))
log(Level.TRACE, this.messageFactory.newMessage(message), t);
}
@Override
public void warn(IMessage msg) {
if (isEnabled(Level.WARN, msg, null))
log(Level.WARN, msg, null);
}
@Override
public void warn(IMessage msg, Throwable t) {
if (isEnabled(Level.WARN, msg, t))
log(Level.WARN, msg, t);
}
@Override
public void warn(Object message) {
if (isEnabled(Level.WARN, message, null))
log(Level.WARN, this.messageFactory.newMessage(message), null);
}
@Override
public void warn(Object message, Throwable t) {
if (isEnabled(Level.WARN, message, t))
log(Level.WARN, this.messageFactory.newMessage(message), t);
}
@Override
public void warn(String message) {
if (isEnabled(Level.WARN, message))
log(Level.WARN, this.messageFactory.newMessage(message), null);
}
@Override
public void warn(String message, Object[] params) {
if (isEnabled(Level.WARN, message, params)) {
IMessage msg = this.messageFactory.newMessage(message, params);
log(Level.WARN, msg, msg.getThrowable());
}
}
@Override
public void warn(String message, Throwable t) {
if (isEnabled(Level.WARN, message, t))
log(Level.WARN, this.messageFactory.newMessage(message), t);
}
}

View File

@@ -1,157 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.logger;
import org.jackhuang.hellominecraft.util.logging.Level;
import org.jackhuang.hellominecraft.util.logging.message.IMessage;
/**
*
* @author huangyuhui
*/
public interface ILogger {
void catching(Level paramLevel, Throwable paramThrowable);
void catching(Throwable paramThrowable);
void debug(IMessage paramIMessage);
void debug(IMessage paramIMessage, Throwable paramThrowable);
void debug(Object paramObject);
void debug(Object paramObject, Throwable paramThrowable);
void debug(String paramString);
void debug(String paramString, Object[] paramArrayOfObject);
void debug(String paramString, Throwable paramThrowable);
void entry();
void entry(Object[] paramArrayOfObject);
void error(IMessage paramIMessage);
void error(IMessage paramIMessage, Throwable paramThrowable);
void error(Object paramObject);
void error(Object paramObject, Throwable paramThrowable);
void error(String paramString);
void error(String paramString, Object[] paramArrayOfObject);
void error(String paramString, Throwable paramThrowable);
void fatal(IMessage paramIMessage);
void fatal(IMessage paramIMessage, Throwable paramThrowable);
void fatal(Object paramObject);
void fatal(Object paramObject, Throwable paramThrowable);
void fatal(String paramString);
void fatal(String paramString, Object[] paramArrayOfObject);
void fatal(String paramString, Throwable paramThrowable);
String getName();
void info(IMessage paramIMessage);
void info(IMessage paramIMessage, Throwable paramThrowable);
void info(Object paramObject);
void info(Object paramObject, Throwable paramThrowable);
void info(String paramString);
void info(String paramString, Object[] paramArrayOfObject);
void info(String paramString, Throwable paramThrowable);
boolean isDebugEnabled();
boolean isEnabled(Level paramLevel);
boolean isErrorEnabled();
boolean isFatalEnabled();
boolean isInfoEnabled();
boolean isTraceEnabled();
boolean isWarnEnabled();
void log(Level paramLevel, IMessage paramIMessage);
void log(Level paramLevel, IMessage paramIMessage, Throwable paramThrowable);
void log(Level paramLevel, Object paramObject);
void log(Level paramLevel, Object paramObject, Throwable paramThrowable);
void log(Level paramLevel, String paramString);
void log(Level paramLevel, String paramString, Object[] paramArrayOfObject);
void log(Level paramLevel, String paramString, Throwable paramThrowable);
void printf(Level paramLevel, String paramString, Object[] paramArrayOfObject);
<T extends Throwable> T throwing(Level paramLevel, T paramT);
<T extends Throwable> T throwing(T paramT);
void trace(IMessage paramIMessage);
void trace(IMessage paramIMessage, Throwable paramThrowable);
void trace(Object paramObject);
void trace(Object paramObject, Throwable paramThrowable);
void trace(String paramString);
void trace(String paramString, Object[] paramArrayOfObject);
void trace(String paramString, Throwable paramThrowable);
void warn(IMessage paramIMessage);
void warn(IMessage paramIMessage, Throwable paramThrowable);
void warn(Object paramObject);
void warn(Object paramObject, Throwable paramThrowable);
void warn(String paramString);
void warn(String paramString, Object[] paramArrayOfObject);
void warn(String paramString, Throwable paramThrowable);
}

View File

@@ -1,170 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.logger;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.jackhuang.hellominecraft.util.logging.AppenderControl;
import org.jackhuang.hellominecraft.util.logging.Configuration;
import org.jackhuang.hellominecraft.util.logging.Level;
import org.jackhuang.hellominecraft.util.logging.LogEvent;
import org.jackhuang.hellominecraft.util.logging.appender.IAppender;
import org.jackhuang.hellominecraft.util.logging.message.IMessage;
import org.jackhuang.hellominecraft.util.logging.message.IMessageFactory;
public class Logger extends AbstractLogger {
protected volatile PrivateConfig config;
private final Map<String, AppenderControl> appenders = new ConcurrentHashMap();
public Logger(String name) {
this(name, null, Level.INFO);
}
public Logger(String name, IMessageFactory messageFactory, Level defaultLevel) {
this(name, Configuration.DEFAULT, messageFactory, defaultLevel);
}
public Logger(String name, Configuration config, IMessageFactory messageFactory, Level defaultLevel) {
super(name, messageFactory);
this.config = new PrivateConfig(config, this, defaultLevel);
}
public synchronized void setLevel(Level level) {
if (level != null)
this.config = new PrivateConfig(this.config, level);
}
public synchronized Level getLevel() {
return this.config.level;
}
@Override
public void abstractLog(Level level, IMessage data, Throwable t) {
LogEvent event = new LogEvent();
event.level = level;
event.message = data;
event.thrown = t;
event.threadName = Thread.currentThread().getName();
log(event);
}
public void log(LogEvent event) {
callAppenders(event);
}
protected void callAppenders(LogEvent event) {
for (AppenderControl control : this.appenders.values())
control.callAppender(event);
}
@Override
public boolean isEnabled(Level level, String msg) {
return this.config.filter(level, msg);
}
@Override
public boolean isEnabled(Level level, String msg, Throwable t) {
return this.config.filter(level, msg, t);
}
@Override
public boolean isEnabled(Level level, String msg, Object[] p1) {
return this.config.filter(level, msg, p1);
}
@Override
public boolean isEnabled(Level level, Object msg, Throwable t) {
return this.config.filter(level, msg, t);
}
@Override
public boolean isEnabled(Level level, IMessage msg, Throwable t) {
return this.config.filter(level, msg, t);
}
public void addAppender(IAppender appender) {
this.appenders.put(appender.getName(), new AppenderControl(appender, null));
}
public void removeAppender(IAppender appender) {
this.appenders.remove(appender.getName());
}
public Map<String, IAppender> getAppenders() {
Map map = new HashMap();
for (Map.Entry entry : this.appenders.entrySet())
map.put(entry.getKey(), ((AppenderControl) entry.getValue()).getAppender());
return map;
}
@Override
public String toString() {
String nameLevel = "" + getName() + ":" + getLevel();
return nameLevel;
}
protected class PrivateConfig {
public final Configuration config;
private final Level level;
private final int intLevel;
private final Logger logger;
public PrivateConfig(Configuration c, Logger logger, Level level) {
this.level = level;
this.intLevel = this.level.level;
this.logger = logger;
this.config = c;
for (IAppender appender : config.appenders)
addAppender(appender);
}
public PrivateConfig(PrivateConfig pc, Level level) {
this(pc.config, pc.logger, level);
}
boolean filter(Level level, String msg) {
return this.intLevel >= level.level;
}
boolean filter(Level level, String msg, Throwable t) {
return this.intLevel >= level.level;
}
boolean filter(Level level, String msg, Object[] p1) {
return this.intLevel >= level.level;
}
boolean filter(Level level, Object msg, Throwable t) {
return this.intLevel >= level.level;
}
boolean filter(Level level, IMessage msg, Throwable t) {
return this.intLevel >= level.level;
}
}
}

View File

@@ -1,137 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.logger;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.jackhuang.hellominecraft.util.logging.Level;
import org.jackhuang.hellominecraft.util.logging.message.IMessage;
import org.jackhuang.hellominecraft.util.logging.message.IMessageFactory;
public class SimpleLogger extends AbstractLogger {
private static final char SPACE = ' ';
private DateFormat dateFormatter;
private Level level;
private final boolean showDateTime;
private final boolean showContextMap;
private PrintStream stream;
private final String logName;
public SimpleLogger(String name, Level defaultLevel, boolean showLogName, boolean showShortLogName, boolean showDateTime, boolean showContextMap, String dateTimeFormat, IMessageFactory messageFactory, PrintStream stream) {
super(name, messageFactory);
this.level = defaultLevel;
if (showShortLogName) {
int index = name.lastIndexOf(".");
if ((index > 0) && (index < name.length()))
this.logName = name.substring(index + 1);
else
this.logName = name;
} else if (showLogName)
this.logName = name;
else
this.logName = null;
this.showDateTime = showDateTime;
this.showContextMap = showContextMap;
this.stream = stream;
if (showDateTime)
try {
this.dateFormatter = new SimpleDateFormat(dateTimeFormat);
} catch (IllegalArgumentException e) {
this.dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS zzz");
}
}
public void setStream(PrintStream stream) {
this.stream = stream;
}
public Level getLevel() {
return this.level;
}
public void setLevel(Level level) {
if (level != null)
this.level = level;
}
@Override
public void abstractLog(Level level, IMessage msg, Throwable throwable) {
StringBuilder sb = new StringBuilder();
if (this.showDateTime) {
Date now = new Date();
String dateText;
synchronized (this.dateFormatter) {
dateText = this.dateFormatter.format(now);
}
sb.append(dateText);
sb.append(SPACE);
}
sb.append(level.toString());
sb.append(SPACE);
if ((this.logName != null) && (this.logName.length() > 0)) {
sb.append(this.logName);
sb.append(SPACE);
}
sb.append(msg.getFormattedMessage());
Object[] params = msg.getParameters();
Throwable t;
if ((throwable == null) && (params != null) && ((params[(params.length - 1)] instanceof Throwable)))
t = (Throwable) params[(params.length - 1)];
else
t = throwable;
if (t != null) {
sb.append(SPACE);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
t.printStackTrace(new PrintStream(baos));
sb.append(baos.toString());
}
this.stream.println(sb.toString());
}
@Override
protected boolean isEnabled(Level level, String msg) {
return this.level.level >= level.level;
}
@Override
protected boolean isEnabled(Level level, String msg, Throwable t) {
return this.level.level >= level.level;
}
@Override
protected boolean isEnabled(Level level, String msg, Object[] p1) {
return this.level.level >= level.level;
}
@Override
protected boolean isEnabled(Level level, Object msg, Throwable t) {
return this.level.level >= level.level;
}
@Override
protected boolean isEnabled(Level level, IMessage msg, Throwable t) {
return this.level.level >= level.level;
}
}

View File

@@ -1,36 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.message;
/**
*
* @author huangyuhui
*/
public abstract class AbstractMessageFactory
implements IMessageFactory {
@Override
public IMessage newMessage(Object message) {
return new ObjectMessage(message);
}
@Override
public IMessage newMessage(String message) {
return new SimpleMessage(message);
}
}

View File

@@ -1,35 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.message;
import java.io.Serializable;
/**
*
* @author huangyuhui
*/
public interface IMessage extends Serializable {
String getFormattedMessage();
String getFormat();
Object[] getParameters();
Throwable getThrowable();
}

View File

@@ -1,31 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.message;
/**
*
* @author huangyuhui
*/
public abstract interface IMessageFactory {
public abstract IMessage newMessage(Object paramObject);
public abstract IMessage newMessage(String paramString);
public abstract IMessage newMessage(String paramString, Object[] paramArrayOfObject);
}

View File

@@ -1,73 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.message;
public class ObjectMessage
implements IMessage {
private static final long serialVersionUID = -5903272448334166185L;
private final transient Object obj;
public ObjectMessage(Object obj) {
if (obj == null)
obj = "null";
this.obj = obj;
}
@Override
public String getFormattedMessage() {
return this.obj.toString();
}
@Override
public String getFormat() {
return this.obj.toString();
}
@Override
public Object[] getParameters() {
return new Object[] { this.obj };
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if ((o == null) || (getClass() != o.getClass()))
return false;
ObjectMessage that = (ObjectMessage) o;
return this.obj != null ? this.obj.equals(that.obj) : that.obj == null;
}
@Override
public int hashCode() {
return this.obj != null ? this.obj.hashCode() : 0;
}
@Override
public String toString() {
return "ObjectMessage[obj=" + this.obj.toString() + "]";
}
@Override
public Throwable getThrowable() {
return (this.obj instanceof Throwable) ? (Throwable) this.obj : null;
}
}

View File

@@ -1,359 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.message;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
*
* @author huangyuhui
*/
public class ParameterizedMessage
implements IMessage {
public static final String RECURSION_PREFIX = "[...";
public static final String RECURSION_SUFFIX = "...]";
public static final String ERROR_PREFIX = "[!!!";
public static final String ERROR_SEPARATOR = "=>";
public static final String ERROR_MSG_SEPARATOR = ":";
public static final String ERROR_SUFFIX = "!!!]";
private static final long serialVersionUID = -665975803997290697L;
private static final int HASHVAL = 31;
private static final char DELIM_START = '{';
private static final char DELIM_STOP = '}';
private static final char ESCAPE_CHAR = '\\';
private final String messagePattern;
private final String[] stringArgs;
private transient Object[] argArray;
private transient String formattedMessage;
private transient Throwable throwable;
public ParameterizedMessage(String messagePattern, String[] stringArgs, Throwable throwable) {
this.messagePattern = messagePattern;
this.stringArgs = stringArgs;
this.throwable = throwable;
}
public ParameterizedMessage(String messagePattern, Object[] objectArgs, Throwable throwable) {
this.messagePattern = messagePattern;
this.throwable = throwable;
this.stringArgs = parseArguments(objectArgs);
}
public ParameterizedMessage(String messagePattern, Object[] arguments) {
this.messagePattern = messagePattern;
this.stringArgs = parseArguments(arguments);
}
public ParameterizedMessage(String messagePattern, Object arg) {
this(messagePattern, new Object[] { arg });
}
public ParameterizedMessage(String messagePattern, Object arg1, Object arg2) {
this(messagePattern, new Object[] { arg1, arg2 });
}
private String[] parseArguments(Object[] arguments) {
if (arguments == null)
return null;
int argsCount = countArgumentPlaceholders(this.messagePattern);
int resultArgCount = arguments.length;
if ((argsCount < arguments.length)
&& (this.throwable == null) && ((arguments[(arguments.length - 1)] instanceof Throwable))) {
this.throwable = ((Throwable) arguments[(arguments.length - 1)]);
resultArgCount--;
}
this.argArray = new Object[resultArgCount];
System.arraycopy(arguments, 0, this.argArray, 0, resultArgCount);
String[] strArgs;
if ((argsCount == 1) && (this.throwable == null) && (arguments.length > 1)) {
strArgs = new String[1];
strArgs[0] = deepToString(arguments);
} else {
strArgs = new String[resultArgCount];
for (int i = 0; i < strArgs.length; i++)
strArgs[i] = deepToString(arguments[i]);
}
return strArgs;
}
@Override
public String getFormattedMessage() {
if (this.formattedMessage == null)
this.formattedMessage = formatMessage(this.messagePattern, this.stringArgs);
return this.formattedMessage;
}
@Override
public String getFormat() {
return this.messagePattern;
}
@Override
public Object[] getParameters() {
if (this.argArray != null)
return this.argArray;
return this.stringArgs;
}
@Override
public Throwable getThrowable() {
return this.throwable;
}
protected String formatMessage(String msgPattern, String[] sArgs) {
return format(msgPattern, sArgs);
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ParameterizedMessage that = (ParameterizedMessage) o;
if (this.messagePattern != null ? !this.messagePattern.equals(that.messagePattern) : that.messagePattern != null)
return false;
return Arrays.equals(this.stringArgs, that.stringArgs);
}
@Override
public int hashCode() {
int result = this.messagePattern != null ? this.messagePattern.hashCode() : 0;
result = HASHVAL * result + (this.stringArgs != null ? Arrays.hashCode(this.stringArgs) : 0);
return result;
}
public static String format(String messagePattern, Object[] arguments) {
if ((messagePattern == null) || (arguments == null) || (arguments.length == 0))
return messagePattern;
StringBuilder result = new StringBuilder();
int escapeCounter = 0;
int currentArgument = 0;
for (int i = 0; i < messagePattern.length(); i++) {
char curChar = messagePattern.charAt(i);
if (curChar == ESCAPE_CHAR)
escapeCounter++;
else if ((curChar == DELIM_START)
&& (i < messagePattern.length() - 1)
&& (messagePattern.charAt(i + 1) == DELIM_STOP)) {
int escapedEscapes = escapeCounter / 2;
for (int j = 0; j < escapedEscapes; j++)
result.append(ESCAPE_CHAR);
if (escapeCounter % 2 == 1) {
result.append(DELIM_START);
result.append(DELIM_STOP);
} else {
if (currentArgument < arguments.length)
result.append(arguments[currentArgument]);
else
result.append(DELIM_START).append(DELIM_STOP);
currentArgument++;
}
i++;
escapeCounter = 0;
} else {
if (escapeCounter > 0) {
for (int j = 0; j < escapeCounter; j++)
result.append(ESCAPE_CHAR);
escapeCounter = 0;
}
result.append(curChar);
}
}
return result.toString();
}
public static int countArgumentPlaceholders(String messagePattern) {
if (messagePattern == null)
return 0;
int delim = messagePattern.indexOf(123);
if (delim == -1)
return 0;
int result = 0;
boolean isEscaped = false;
for (int i = 0; i < messagePattern.length(); i++) {
char curChar = messagePattern.charAt(i);
switch (curChar) {
case ESCAPE_CHAR:
isEscaped = !isEscaped;
break;
case DELIM_START:
if ((!isEscaped)
&& (i < messagePattern.length() - 1)
&& (messagePattern.charAt(i + 1) == DELIM_STOP)) {
result++;
i++;
}
isEscaped = false;
break;
default:
isEscaped = false;
break;
}
}
return result;
}
public static String deepToString(Object o) {
if (o == null)
return null;
if (o instanceof String)
return (String) o;
StringBuilder str = new StringBuilder();
Set dejaVu = new HashSet();
recursiveDeepToString(o, str, dejaVu);
return str.toString();
}
private static void recursiveDeepToString(Object o, StringBuilder str, Set<String> dejaVu) {
if (o == null) {
str.append("null");
return;
}
if ((o instanceof String)) {
str.append(o);
return;
}
Class oClass = o.getClass();
if (oClass.isArray())
if (oClass == byte[].class)
str.append(Arrays.toString((byte[]) (byte[]) o));
else if (oClass == short[].class)
str.append(Arrays.toString((short[]) (short[]) o));
else if (oClass == int[].class)
str.append(Arrays.toString((int[]) (int[]) o));
else if (oClass == long[].class)
str.append(Arrays.toString((long[]) (long[]) o));
else if (oClass == float[].class)
str.append(Arrays.toString((float[]) (float[]) o));
else if (oClass == double[].class)
str.append(Arrays.toString((double[]) (double[]) o));
else if (oClass == boolean[].class)
str.append(Arrays.toString((boolean[]) (boolean[]) o));
else if (oClass == char[].class)
str.append(Arrays.toString((char[]) (char[]) o));
else {
String id = identityToString(o);
if (dejaVu.contains(id))
str.append("[...").append(id).append("...]");
else {
dejaVu.add(id);
Object[] oArray = (Object[]) (Object[]) o;
str.append("[");
boolean first = true;
for (Object current : oArray) {
if (first)
first = false;
else
str.append(", ");
recursiveDeepToString(current, str, new HashSet(dejaVu));
}
str.append("]");
}
}
else if ((o instanceof Map)) {
String id = identityToString(o);
if (dejaVu.contains(id))
str.append("[...").append(id).append("...]");
else {
dejaVu.add(id);
Map oMap = (Map) o;
str.append("{");
boolean isFirst = true;
for (Object o1 : oMap.entrySet()) {
Map.Entry current = (Map.Entry) o1;
if (isFirst)
isFirst = false;
else
str.append(", ");
Object key = current.getKey();
Object value = current.getValue();
recursiveDeepToString(key, str, new HashSet(dejaVu));
str.append("=");
recursiveDeepToString(value, str, new HashSet(dejaVu));
}
str.append("}");
}
} else if ((o instanceof Collection)) {
String id = identityToString(o);
if (dejaVu.contains(id))
str.append("[...").append(id).append("...]");
else {
dejaVu.add(id);
Collection oCol = (Collection) o;
str.append("[");
boolean isFirst = true;
for (Iterator i$ = oCol.iterator(); i$.hasNext();) {
Object anOCol = i$.next();
if (isFirst)
isFirst = false;
else
str.append(", ");
recursiveDeepToString(anOCol, str, new HashSet(dejaVu));
}
str.append("]");
}
} else if ((o instanceof Date)) {
Date date = (Date) o;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
str.append(format.format(date));
} else
try {
str.append(o.toString());
} catch (Throwable t) {
str.append("[!!!");
str.append(identityToString(o));
str.append("=>");
String msg = t.getMessage();
String className = t.getClass().getName();
str.append(className);
if (!className.equals(msg)) {
str.append(":");
str.append(msg);
}
str.append("!!!]");
}
}
public static String identityToString(Object obj) {
if (obj == null)
return null;
return obj.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(obj));
}
@Override
public String toString() {
return "ParameterizedMessage[messagePattern=" + this.messagePattern + ", stringArgs=" + Arrays.toString(this.stringArgs) + ", throwable=" + this.throwable + "]";
}
}

View File

@@ -1,32 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.message;
/**
*
* @author huangyuhui
*/
public final class ParameterizedMessageFactory extends AbstractMessageFactory {
public static final ParameterizedMessageFactory INSTANCE = new ParameterizedMessageFactory();
@Override
public IMessage newMessage(String message, Object[] params) {
return new ParameterizedMessage(message, params);
}
}

View File

@@ -1,79 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.message;
/**
*
* @author huangyuhui
*/
public class SimpleMessage
implements IMessage {
private static final long serialVersionUID = -8398002534962715992L;
private final String message;
public SimpleMessage() {
this(null);
}
public SimpleMessage(String message) {
this.message = message;
}
@Override
public String getFormattedMessage() {
return this.message;
}
@Override
public String getFormat() {
return this.message;
}
@Override
public Object[] getParameters() {
return null;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if ((o == null) || (getClass() != o.getClass()))
return false;
SimpleMessage that = (SimpleMessage) o;
return this.message != null ? this.message.equals(that.message) : that.message == null;
}
@Override
public int hashCode() {
return this.message != null ? this.message.hashCode() : 0;
}
@Override
public String toString() {
return "SimpleMessage[message=" + this.message + "]";
}
@Override
public Throwable getThrowable() {
return null;
}
}

View File

@@ -1,100 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.logging.message;
import java.util.Arrays;
import java.util.IllegalFormatException;
public class StringFormattedMessage
implements IMessage {
private static final long serialVersionUID = -665975803997290697L;
private final String messagePattern;
private final transient Object[] argArray;
private String[] stringArgs;
private transient String formattedMessage;
private transient Throwable throwable;
public StringFormattedMessage(String messagePattern, Object[] arguments) {
this.messagePattern = messagePattern;
this.argArray = arguments;
if ((arguments != null) && (arguments.length > 0) && ((arguments[(arguments.length - 1)] instanceof Throwable)))
this.throwable = ((Throwable) arguments[(arguments.length - 1)]);
}
@Override
public String getFormattedMessage() {
if (this.formattedMessage == null)
this.formattedMessage = formatMessage(this.messagePattern, this.argArray);
return this.formattedMessage;
}
@Override
public String getFormat() {
return this.messagePattern;
}
@Override
public Object[] getParameters() {
if (this.argArray != null)
return this.argArray;
return this.stringArgs;
}
protected String formatMessage(String msgPattern, Object[] args) {
try {
return String.format(msgPattern, args);
} catch (IllegalFormatException ife) {
System.err.println("Unable to format msg: " + msgPattern);
ife.printStackTrace();
}
return msgPattern;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if ((o == null) || (getClass() != o.getClass()))
return false;
StringFormattedMessage that = (StringFormattedMessage) o;
if (this.messagePattern != null ? !this.messagePattern.equals(that.messagePattern) : that.messagePattern != null)
return false;
return Arrays.equals(this.stringArgs, that.stringArgs);
}
@Override
public int hashCode() {
int result = this.messagePattern != null ? this.messagePattern.hashCode() : 0;
result = 31 * result + (this.stringArgs != null ? Arrays.hashCode(this.stringArgs) : 0);
return result;
}
@Override
public String toString() {
return "StringFormatMessage[messagePattern=" + this.messagePattern + ", args=" + Arrays.toString(this.argArray) + "]";
}
@Override
public Throwable getThrowable() {
return this.throwable;
}
}

View File

@@ -1,197 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.jackhuang.hellominecraft.util.func.Predicate;
import java.util.zip.ZipInputStream;
import org.jackhuang.hellominecraft.util.func.BiFunction;
/**
* 文件压缩/解压类
*
* @author huangyuhui
*/
public class Compressor {
public static void zip(String sourceDir, String zipFile) throws IOException {
zip(new File(sourceDir), new File(zipFile), null);
}
/**
* 功能:把 sourceDir 目录下的所有文件进行 zip 格式的压缩,保存为指定 zip 文件
*
* @param sourceDir 源文件夹
* @param zipFile 压缩生成的zip文件路径。
* @param pathNameCallback callback(pathName, isDirectory) returns your
* modified pathName
*
* @throws java.io.IOException 压缩失败或无法读取
*/
public static void zip(File sourceDir, File zipFile, BiFunction<String, Boolean, String> pathNameCallback) throws IOException {
FileOutputStream os = new FileOutputStream(zipFile);
BufferedOutputStream bos = new BufferedOutputStream(os);
try (ZipOutputStream zos = new ZipOutputStream(bos)) {
String basePath;
if (sourceDir.isDirectory())
basePath = sourceDir.getPath();
else//直接压缩单个文件时,取父目录
basePath = sourceDir.getParent();
zipFile(sourceDir, basePath, zos, pathNameCallback);
zos.closeEntry();
}
}
/**
* 功能:把 sourceDir 目录下的所有文件进行 zip 格式的压缩,保存为指定 zip 文件
*
* @param sourceDir 源文件夹
* @param zipFile 压缩生成的zip文件路径。
* @param pathNameCallback callback(pathName, isDirectory) returns your
* modified pathName
*
* @throws java.io.IOException 压缩失败或无法读取
*/
public static ZipOutputStream zipContinuing(File sourceDir, File zipFile, BiFunction<String, Boolean, String> pathNameCallback) throws IOException {
FileOutputStream os = new FileOutputStream(zipFile);
BufferedOutputStream bos = new BufferedOutputStream(os);
try (ZipOutputStream zos = new ZipOutputStream(bos)) {
String basePath;
if (sourceDir.isDirectory())
basePath = sourceDir.getPath();
else//直接压缩单个文件时,取父目录
basePath = sourceDir.getParent();
zipFile(sourceDir, basePath, zos, pathNameCallback);
return zos;
}
}
/**
* 将文件压缩成zip文件
*
* @param source zip文件路径
* @param basePath 待压缩文件根目录
* @param zos zip文件的os
* @param pathNameCallback callback(pathName, isDirectory) returns your
* modified pathName, null if you dont want this file zipped
*/
private static void zipFile(File source, String basePath,
ZipOutputStream zos, BiFunction<String, Boolean, String> pathNameCallback) throws IOException {
File[] files;
if (source.isDirectory())
files = source.listFiles();
else {
files = new File[1];
files[0] = source;
}
String pathName;//存相对路径(相对于待压缩的根目录)
byte[] buf = new byte[1024];
int length;
for (File file : files)
if (file.isDirectory()) {
pathName = file.getPath().substring(basePath.length() + 1)
+ "/";
if (pathNameCallback != null)
pathName = pathNameCallback.apply(pathName, true);
if (pathName == null)
continue;
zos.putNextEntry(new ZipEntry(pathName));
zipFile(file, basePath, zos, pathNameCallback);
} else {
pathName = file.getPath().substring(basePath.length() + 1);
if (pathNameCallback != null)
pathName = pathNameCallback.apply(pathName, true);
if (pathName == null)
continue;
try (InputStream is = new FileInputStream(file)) {
BufferedInputStream bis = new BufferedInputStream(is);
zos.putNextEntry(new ZipEntry(pathName));
while ((length = bis.read(buf)) > 0)
zos.write(buf, 0, length);
}
}
}
public static void unzip(String zipFileName, String extPlace) throws IOException {
unzip(new File(zipFileName), new File(extPlace));
}
public static void unzip(File zipFileName, File extPlace) throws IOException {
unzip(zipFileName, extPlace, null, true);
}
/**
* 将文件压缩成zip文件
*
* @param zipFileName zip文件路径
* @param extPlace 待压缩文件根目录
* @param callback will be called for every entry in the zip file,
* returns false if you dont want this file unzipped.
*
* @throws java.io.IOException 解压失败或无法写入
*/
public static void unzip(File zipFileName, File extPlace, Predicate<String> callback, boolean ignoreExistsFile) throws IOException {
extPlace.mkdirs();
try (ZipInputStream zipFile = new ZipInputStream(new FileInputStream(zipFileName))) {
if (zipFileName.exists()) {
String strPath, gbkPath, strtemp;
strPath = extPlace.getAbsolutePath();
ZipEntry zipEnt;
while ((zipEnt = zipFile.getNextEntry()) != null) {
gbkPath = zipEnt.getName();
if (callback != null)
if (!callback.apply(gbkPath))
continue;
if (zipEnt.isDirectory()) {
strtemp = strPath + File.separator + gbkPath;
File dir = new File(strtemp);
dir.mkdirs();
} else {
//读写文件
gbkPath = zipEnt.getName();
strtemp = strPath + File.separator + gbkPath;
//建目录
String strsubdir = gbkPath;
for (int i = 0; i < strsubdir.length(); i++)
if (strsubdir.substring(i, i + 1).equalsIgnoreCase("/")) {
String temp = strPath + File.separator + strsubdir.substring(0, i);
File subdir = new File(temp);
if (!subdir.exists())
subdir.mkdir();
}
if (ignoreExistsFile && new File(strtemp).exists())
continue;
try (FileOutputStream fos = new FileOutputStream(strtemp); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
int c;
while ((c = zipFile.read()) != -1)
bos.write((byte) c);
}
}
}
}
}
}
}

View File

@@ -1,383 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.NetUtils;
/**
*
* @author huangyuhui
*/
public class FileUtils {
public static void deleteDirectory(File directory)
throws IOException {
if (!directory.exists())
return;
if (!isSymlink(directory))
cleanDirectory(directory);
if (!directory.delete()) {
String message = "Unable to delete directory " + directory + ".";
throw new IOException(message);
}
}
public static boolean deleteDirectoryQuietly(File directory) {
try {
deleteDirectory(directory);
return true;
} catch (Exception e) {
HMCLog.err("Failed to delete directory " + directory, e);
return false;
}
}
public static boolean cleanDirectoryQuietly(File directory) {
try {
cleanDirectory(directory);
return true;
} catch (Exception e) {
HMCLog.err("Failed to clean directory " + directory, e);
return false;
}
}
public static void cleanDirectory(File directory)
throws IOException {
if (!directory.exists()) {
directory.mkdirs();
return;
}
if (!directory.isDirectory()) {
String message = directory + " is not a directory";
throw new IllegalArgumentException(message);
}
File[] files = directory.listFiles();
if (files == null)
throw new IOException("Failed to list contents of " + directory);
IOException exception = null;
for (File file : files)
try {
forceDelete(file);
} catch (IOException ioe) {
exception = ioe;
}
if (null != exception)
throw exception;
}
public static void forceDelete(File file)
throws IOException {
if (file.isDirectory())
deleteDirectory(file);
else {
boolean filePresent = file.exists();
if (!file.delete()) {
if (!filePresent)
throw new FileNotFoundException("File does not exist: " + file);
String message = "Unable to delete file: " + file;
throw new IOException(message);
}
}
}
public static boolean isSymlink(File file)
throws IOException {
if (file == null)
throw new NullPointerException("File must not be null");
if (File.separatorChar == '\\')
return false;
File fileInCanonicalDir;
if (file.getParent() == null)
fileInCanonicalDir = file;
else {
File canonicalDir = file.getParentFile().getCanonicalFile();
fileInCanonicalDir = new File(canonicalDir, file.getName());
}
return !fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile());
}
public static void copyDirectory(File srcDir, File destDir)
throws IOException {
copyDirectory(srcDir, destDir, null);
}
public static void copyDirectory(File srcDir, File destDir, FileFilter filter)
throws IOException {
if (srcDir == null)
throw new NullPointerException("Source must not be null");
if (destDir == null)
throw new NullPointerException("Destination must not be null");
if (!srcDir.exists())
throw new FileNotFoundException("Source '" + srcDir + "' does not exist");
if (!srcDir.isDirectory())
throw new IOException("Source '" + srcDir + "' exists but is not a directory");
if (srcDir.getCanonicalPath().equals(destDir.getCanonicalPath()))
throw new IOException("Source '" + srcDir + "' and destination '" + destDir + "' are the same");
List exclusionList = null;
if (destDir.getCanonicalPath().startsWith(srcDir.getCanonicalPath())) {
File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
if ((srcFiles != null) && (srcFiles.length > 0)) {
exclusionList = new ArrayList(srcFiles.length);
for (File srcFile : srcFiles) {
File copiedFile = new File(destDir, srcFile.getName());
exclusionList.add(copiedFile.getCanonicalPath());
}
}
}
doCopyDirectory(srcDir, destDir, filter, exclusionList);
}
private static void doCopyDirectory(File srcDir, File destDir, FileFilter filter, List<String> exclusionList)
throws IOException {
File[] srcFiles = filter == null ? srcDir.listFiles() : srcDir.listFiles(filter);
if (srcFiles == null)
throw new IOException("Failed to list contents of " + srcDir);
if (destDir.exists()) {
if (!destDir.isDirectory())
throw new IOException("Destination '" + destDir + "' exists but is not a directory");
} else if ((!destDir.mkdirs()) && (!destDir.isDirectory()))
throw new IOException("Destination '" + destDir + "' directory cannot be created");
if (!destDir.canWrite())
throw new IOException("Destination '" + destDir + "' cannot be written to");
for (File srcFile : srcFiles) {
File dstFile = new File(destDir, srcFile.getName());
if ((exclusionList == null) || (!exclusionList.contains(srcFile.getCanonicalPath())))
if (srcFile.isDirectory())
doCopyDirectory(srcFile, dstFile, filter, exclusionList);
else
doCopyFile(srcFile, dstFile);
}
destDir.setLastModified(srcDir.lastModified());
}
public static String read(File file)
throws IOException {
return NetUtils.getStreamContent(IOUtils.openInputStream(file));
}
public static String readQuietly(File file) {
try {
return NetUtils.getStreamContent(IOUtils.openInputStream(file));
} catch (IOException ex) {
HMCLog.err("Failed to read file: " + file, ex);
return null;
}
}
public static String read(File file, String charset)
throws IOException {
return NetUtils.getStreamContent(IOUtils.openInputStream(file), charset);
}
public static String readIgnoreFileNotFound(File file) throws IOException {
try {
return NetUtils.getStreamContent(IOUtils.openInputStream(file));
} catch (FileNotFoundException ex) {
return "";
}
}
public static void copyFileQuietly(File srcFile, File destFile) {
try {
copyFile(srcFile, destFile);
} catch (IOException ex) {
HMCLog.warn("Failed to copy file", ex);
}
}
public static void copyFile(File srcFile, File destFile)
throws IOException {
if (srcFile == null)
throw new NullPointerException("Source must not be null");
if (destFile == null)
throw new NullPointerException("Destination must not be null");
if (!srcFile.exists())
throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
if (srcFile.isDirectory())
throw new IOException("Source '" + srcFile + "' exists but is a directory");
if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath()))
throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same");
File parentFile = destFile.getParentFile();
if ((parentFile != null)
&& (!parentFile.mkdirs()) && (!parentFile.isDirectory()))
throw new IOException("Destination '" + parentFile + "' directory cannot be created");
if ((destFile.exists()) && (!destFile.canWrite()))
throw new IOException("Destination '" + destFile + "' exists but is read-only");
doCopyFile(srcFile, destFile);
}
public static void doCopyFile(File srcFile, File destFile)
throws IOException {
Files.copy(srcFile.toPath(), destFile.toPath(), StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING);
}
public static int indexOfLastSeparator(String filename) {
if (filename == null)
return -1;
int lastUnixPos = filename.lastIndexOf(47);
int lastWindowsPos = filename.lastIndexOf(92);
return Math.max(lastUnixPos, lastWindowsPos);
}
public static int indexOfExtension(String filename) {
if (filename == null)
return -1;
int extensionPos = filename.lastIndexOf(46);
int lastSeparator = indexOfLastSeparator(filename);
return lastSeparator > extensionPos ? -1 : extensionPos;
}
public static String getName(String filename) {
if (filename == null)
return null;
int index = indexOfLastSeparator(filename);
return filename.substring(index + 1);
}
/**
* Get the file name without extensions.
*
* @param filename
*
* @return the file name without extensions
*/
public static String getBaseName(String filename) {
return removeExtension(getName(filename));
}
public static String getExtension(String filename) {
if (filename == null)
return null;
int index = indexOfExtension(filename);
if (index == -1)
return "";
return filename.substring(index + 1);
}
public static String removeExtension(String filename) {
if (filename == null)
return null;
int index = indexOfExtension(filename);
if (index == -1)
return filename;
return filename.substring(0, index);
}
public static boolean writeQuietly(File file, String data) {
try {
FileUtils.write(file, data);
return true;
} catch (IOException e) {
HMCLog.warn("Failed to write data to file: " + file, e);
return false;
}
}
public static void write(File file, String data)
throws IOException {
write(file, data, "UTF-8", false);
}
public static void write(File file, String data, String encoding)
throws IOException {
write(file, data, encoding, false);
}
public static void write(File file, String data, String encoding, boolean append)
throws IOException {
OutputStream out = null;
try {
out = openOutputStream(file, append);
IOUtils.write(data, out, encoding);
out.close();
} finally {
IOUtils.closeQuietly(out);
}
}
public static FileInputStream openInputStream(File file)
throws IOException {
if (file.exists()) {
if (file.isDirectory())
throw new IOException("File '" + file + "' exists but is a directory");
if (!file.canRead())
throw new IOException("File '" + file + "' cannot be read");
} else
throw new FileNotFoundException("File '" + file + "' does not exist");
return new FileInputStream(file);
}
public static FileOutputStream openOutputStream(File file)
throws IOException {
return openOutputStream(file, false);
}
public static FileOutputStream openOutputStream(File file, boolean append)
throws IOException {
if (file.exists()) {
if (file.isDirectory())
throw new IOException("File '" + file + "' exists but is a directory");
if (!file.canWrite())
throw new IOException("File '" + file + "' cannot be written to");
} else {
File parent = file.getParentFile();
if ((parent != null)
&& (!parent.mkdirs()) && (!parent.isDirectory()))
throw new IOException("Directory '" + parent + "' could not be created");
file.createNewFile();
}
return new FileOutputStream(file, append);
}
public static File[] searchSuffix(File dir, String suffix) {
ArrayList<File> al = new ArrayList();
File[] files = dir.listFiles();
if (files == null)
return new File[0];
for (File f : files)
if (f.getName().endsWith(suffix))
al.add(f);
return al.toArray(new File[0]);
}
}

View File

@@ -1,291 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
/**
*
* @author huang
*/
public class IOUtils {
public static String addSeparator(String path) {
if (path == null || path.trim().length() == 0)
return "";
if (isSeparator(path.charAt(path.length() - 1)))
return path;
else
return path + File.separatorChar;
}
public static String addURLSeparator(String path) {
if (path == null || path.trim().length() == 0)
return "";
if (path.charAt(path.length() - 1) == '/')
return path;
else
return path + '/';
}
public static boolean isSeparator(char ch) {
return ch == File.separatorChar || ch == '/' || ch == '\\';
}
public static String removeLastSeparator(String dir) {
String t = dir.trim();
char ch = t.charAt(t.length() - 1);
if (isSeparator(ch))
return t.substring(0, t.length() - 1);
return t;
}
public static String extractLastDirectory(String dir) {
String t = removeLastSeparator(dir);
int i = t.length() - 1;
while (i >= 0 && !isSeparator(dir.charAt(i)))
i--;
if (i < 0)
return t;
return t.substring(i + 1, (t.length() - i) + (i + 1) - 1);
}
public static void findAllFile(File f, Consumer<String> callback) {
if (f.isDirectory()) {
File[] f1 = f.listFiles();
int len = f1.length;
for (int i = 0; i < len; i++)
if (f1[i].isFile())
callback.accept(f1[i].getName());
}
}
public static void findAllDir(File f, Consumer<String> callback) {
if (f.isDirectory()) {
File[] f1 = f.listFiles();
int len = f1.length;
for (int i = 0; i < len; i++)
if (f1[i].isDirectory())
callback.accept(f1[i].getName());
}
}
public static String getRealPath() {
String realPath = IOUtils.class.getClassLoader().getResource("").getFile();
java.io.File file = new java.io.File(realPath);
realPath = file.getAbsolutePath();
try {
realPath = java.net.URLDecoder.decode(realPath, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return realPath;
}
public static boolean isAbsolutePath(String path) {
if (path == null)
return true;
return path.startsWith("/") || path.indexOf(":") > 0;
}
public static String getLocalMAC() {
InetAddress addr;
try {
addr = InetAddress.getLocalHost();
String ip = addr.getHostAddress();
return getMacAddress(ip);
} catch (UnknownHostException e) {
HMCLog.warn("Failed to get local mac address because of the unknown host.", e);
}
return "ERROR";
}
public static String getMacAddress(String host) {
String mac;
StringBuilder sb = new StringBuilder();
try {
NetworkInterface ni = NetworkInterface.getByInetAddress(InetAddress.getByName(host));
byte[] macs = ni.getHardwareAddress();
for (int i = 0; i < macs.length; i++) {
mac = Integer.toHexString(macs[i] & 0xFF);
if (mac.length() == 1)
mac = '0' + mac;
sb.append(mac).append("-");
}
} catch (SocketException e) {
HMCLog.warn("Failed to get mac address because the socket has thrown an exception.", e);
} catch (UnknownHostException e) {
HMCLog.warn("Failed to get mac address because of the unknown host.", e);
}
mac = sb.toString();
mac = mac.substring(0, mac.length() - 1);
return mac;
}
public static String extractFileName(String fileName) {
File file = new File(fileName);
return file.getName();
}
public static String getJavaDir() {
return getJavaDir(System.getProperty("java.home"));
}
public static String getJavaDir(String home) {
String path = home + File.separatorChar + "bin" + File.separatorChar;
path = addSeparator(path);
if (OS.os() == OS.WINDOWS && new File(path + "javaw.exe").isFile())
return path + "javaw.exe";
else
return path + "java";
}
public static ByteArrayOutputStream readFully(InputStream stream) throws IOException {
byte[] data = new byte[4096];
ByteArrayOutputStream entryBuffer = new ByteArrayOutputStream();
int len;
do {
len = stream.read(data);
if (len <= 0)
continue;
entryBuffer.write(data, 0, len);
} while (len != -1);
return entryBuffer;
}
public static void closeQuietly(Closeable closeable) {
try {
if (closeable != null)
closeable.close();
} catch (IOException ioe) {
}
}
public static void write(byte[] data, OutputStream output)
throws IOException {
if (data != null)
output.write(data);
}
public static void write(String data, OutputStream output, String encoding)
throws IOException {
if (data != null)
output.write(data.getBytes(encoding));
}
public static FileInputStream openInputStream(File file)
throws IOException {
if (file.exists()) {
if (file.isDirectory())
throw new IOException("File '" + file + "' exists but is a directory");
if (!file.canRead())
throw new IOException("File '" + file + "' cannot be read");
} else
throw new FileNotFoundException("File '" + file + "' does not exist");
return new FileInputStream(file);
}
public static String tryGetCanonicalFolderPath(File file) {
try {
return IOUtils.addSeparator(file.getCanonicalPath());
} catch (IOException ignored) {
return IOUtils.addSeparator(file.getAbsolutePath());
}
}
public static File tryGetCanonicalFile(File file) {
try {
return file.getCanonicalFile();
} catch (IOException ignored) {
return file.getAbsoluteFile();
}
}
public static File tryGetCanonicalFile(String file) {
return tryGetCanonicalFile(new File(file));
}
public static String tryGetCanonicalFilePath(File file) {
try {
return file.getCanonicalPath();
} catch (IOException ignored) {
return file.getAbsolutePath();
}
}
public static URL parseURL(String str) {
try {
return new URL(str);
} catch (MalformedURLException ex) {
HMCLog.warn("Failed to parse URL:" + str);
return null;
}
}
public static List<String> readProcessByInputStream(String[] cmd) throws IOException, InterruptedException {
JavaProcess jp = new JavaProcess(cmd, new ProcessBuilder(cmd).start(), null);
ArrayList<String> lines = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(jp.getRawProcess().getInputStream()))) {
jp.getRawProcess().waitFor();
String line;
while ((line = br.readLine()) != null)
lines.add(line);
}
return lines;
}
public static List<String> readProcessByErrorStream(String[] cmd) throws IOException, InterruptedException {
JavaProcess jp = new JavaProcess(cmd, new ProcessBuilder(cmd).start(), null);
ArrayList<String> lines = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(jp.getRawProcess().getErrorStream()))) {
jp.getRawProcess().waitFor();
String line;
while ((line = br.readLine()) != null)
lines.add(line);
}
return lines;
}
}

View File

@@ -1,176 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
/**
*
* @author huangyuhui
*/
public class Java {
public static final List<Java> JAVA;
static {
List<Java> temp = new ArrayList<>();
temp.add(new Java("Default", System.getProperty("java.home")));
temp.add(new Java("Custom", null));
if (OS.os() == OS.WINDOWS)
temp.addAll(Java.queryAllJavaHomeInWindowsByReg());
if (OS.os() == OS.OSX)
temp.addAll(Java.queryAllJDKInMac());
JAVA = Collections.unmodifiableList(temp);
}
public static Java suggestedJava() {
for (Java j : JAVA)
if (j.name.startsWith("1.8") || j.name.startsWith("9"))
return j;
return JAVA.get(0);
}
String name, home;
public Java(String name, String home) {
this.name = name;
this.home = home;
}
public String getName() {
return name;
}
public String getLocalizedName() {
if (name.equals("Default"))
return C.i18n("settings.default");
if (name.equals("Custom"))
return C.i18n("settings.custom");
return name;
}
public String getHome() {
return home;
}
public String getJava() {
return IOUtils.getJavaDir(getHome());
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Java) {
Java j = (Java) obj;
return (j.getName() == null && this.getName() == null) || ((Java) obj).getName().equals(this.getName());
} else
return false;
}
@Override
public int hashCode() {
return name.hashCode();
}
/*
* -----------------------------------
* MAC OS X
* -----------------------------------
*/
public static List<Java> queryAllJDKInMac() {
List<Java> ans = new ArrayList<>();
File jre = new File("/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home");
if (jre.exists())
ans.add(new Java("JRE", jre.getPath()));
File f = new File("/Library/Java/JavaVirtualMachines/");
if (f.exists())
for (File a : f.listFiles())
ans.add(new Java(a.getName(), new File(a, "Contents/Home").getAbsolutePath()));
return ans;
}
/*
* -----------------------------------
* WINDOWS
* -----------------------------------
*/
public static List<Java> queryAllJavaHomeInWindowsByReg() {
List<Java> ans = new ArrayList<>();
try {
queryJava(ans, "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment");
queryJava(ans, "HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit");
} catch (IOException | InterruptedException ex) {
HMCLog.err("Faield to query java", ex);
}
return ans;
}
private static void queryJava(List<Java> ans, String location) throws IOException, InterruptedException {
for (String java : queryRegSubFolders(location)) {
int s = 0;
for (char c : java.toCharArray())
if (c == '.')
++s;
if (s <= 1)
continue;
String javahome = queryRegValue(java, "JavaHome");
if (javahome != null)
ans.add(new Java(java.substring(location.length()), javahome));
}
}
private static List<String> queryRegSubFolders(String location) throws IOException, InterruptedException {
String[] cmd = new String[] { "cmd", "/c", "reg", "query", location };
List<String> l = IOUtils.readProcessByInputStream(cmd);
List<String> ans = new ArrayList<>();
for (String line : l)
if (line.startsWith(location) && !line.equals(location))
ans.add(line);
return ans;
}
private static String queryRegValue(String location, String name) throws IOException, InterruptedException {
String[] cmd = new String[] { "cmd", "/c", "reg", "query", location, "/v", name };
List<String> l = IOUtils.readProcessByInputStream(cmd);
boolean last = false;
for (String s : l) {
if (s.trim().isEmpty())
continue;
if (last == true && s.trim().startsWith(name)) {
int begins = s.indexOf(name);
if (begins > 0) {
s = s.substring(begins + name.length());
begins = s.indexOf("REG_SZ");
if (begins > 0) {
s = s.substring(begins + "REG_SZ".length());
return s.trim();
}
}
}
if (s.trim().equals(location))
last = true;
}
return null;
}
}

View File

@@ -1,88 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*
* @author huangyuhui
*/
public class JavaProcess {
private final List<String> commands;
private final Process process;
private final ArrayList<String> stdOutLines = new ArrayList<>();
public JavaProcess(List<String> commands, Process process, ProcessManager pm) {
this.commands = commands;
this.process = process;
if (pm != null)
pm.registerProcess(this);
}
public JavaProcess(String[] commands, Process process, ProcessManager pm) {
this(Arrays.asList(commands), process, pm);
}
public Process getRawProcess() {
return this.process;
}
public List<String> getStartupCommands() {
return this.commands;
}
public String getStartupCommand() {
return this.process.toString();
}
public ArrayList<String> getStdOutLines() {
return this.stdOutLines;
}
public boolean isRunning() {
try {
this.process.exitValue();
} catch (IllegalThreadStateException ex) {
return true;
}
return false;
}
public int getExitCode() {
try {
return this.process.exitValue();
} catch (IllegalThreadStateException ex) {
ex.fillInStackTrace();
throw ex;
}
}
@Override
public String toString() {
return "JavaProcess[commands=" + this.commands + ", isRunning=" + isRunning() + "]";
}
public void stop() {
this.process.destroy();
}
}

View File

@@ -1,91 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import java.util.Arrays;
import java.util.HashSet;
import org.jackhuang.hellominecraft.util.CollectionUtils;
import org.jackhuang.hellominecraft.util.EventHandler;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.logging.Level;
/**
*
* @author huangyuhui
*/
public class JavaProcessMonitor {
private final HashSet<Thread> al = new HashSet<>();
/**
* this event will be executed only if the application returned 0.
*/
public final EventHandler<JavaProcess> stoppedEvent = new EventHandler<>(this);
/**
* When the monitored application exited with exit code not zero, this event
* will be executed. Event args is the exit code.
*/
public final EventHandler<Integer> applicationExitedAbnormallyEvent = new EventHandler<>(this);
/**
* When jvm crashed, this event will be executed. Event args is the exit
* code.
*/
public final EventHandler<Integer> jvmLaunchFailedEvent = new EventHandler<>(this);
private final JavaProcess p;
public JavaProcessMonitor(JavaProcess p) {
this.p = p;
}
public JavaProcess getJavaProcess() {
return p;
}
public void start() {
ProcessThread a = new ProcessThread(p);
a.stopEvent.register((sender, t) -> {
HMCLog.log("Process exit code: " + t.getExitCode());
if (t.getExitCode() != 0 || StrUtils.containsOne(t.getStdOutLines(),
Arrays.asList("Unable to launch"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
applicationExitedAbnormallyEvent.execute(t.getExitCode());
if (t.getExitCode() != 0 && StrUtils.containsOne(t.getStdOutLines(),
Arrays.asList("Could not create the Java Virtual Machine.",
"Error occurred during initialization of VM",
"A fatal exception has occurred. Program will exit.",
"Unable to launch"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
jvmLaunchFailedEvent.execute(t.getExitCode());
processThreadStopped((ProcessThread) sender, false);
return true;
});
a.start();
al.add(a);
}
void processThreadStopped(ProcessThread t, boolean forceTermintate) {
al.remove(t);
al.removeAll(CollectionUtils.map(al, t1 -> !t1.isAlive()));
if (al.isEmpty() || forceTermintate) {
for (Thread a : al)
a.interrupt();
al.clear();
stoppedEvent.execute(p);
}
}
}

View File

@@ -1,205 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.StrUtils;
/**
*
* @author huangyuhui
*/
public final class JdkVersion implements Cloneable {
private String ver;
public String getVersion() {
return ver;
}
public Platform getPlatform() {
return Platform.values()[platform];
}
public String getLocation() {
return location;
}
public int getParsedVersion() {
return parseVersion(getVersion());
}
/**
* -1 - unkown 0 - 32Bit 1 - 64Bit
*/
private int platform;
private String location;
@Override
public boolean equals(Object obj) {
if (!(obj instanceof JdkVersion))
return false;
JdkVersion b = (JdkVersion) obj;
if (b.location == null || location == null)
return b.location == location;
return new File(b.location).equals(new File(location));
}
@Override
public int hashCode() {
return location == null ? 0 : new File(location).hashCode();
}
@Override
protected Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException ex) {
throw new Error(ex);
}
}
public JdkVersion(String location) {
File f = new File(location);
if (f.exists() && f.isFile())
f = f.getParentFile();
this.location = f.getAbsolutePath();
}
public JdkVersion(String location, String ver, Platform platform) {
this(location);
this.ver = ver;
this.platform = platform.ordinal();
}
/**
* Constant identifying the 1.5 JVM (Java 5).
*/
public static final int UNKOWN = 2;
/**
* Constant identifying the 1.6 JVM (Java 6).
*/
public static final int JAVA_16 = 3;
/**
* Constant identifying the 1.7 JVM (Java 7).
*/
public static final int JAVA_17 = 4;
/**
* Constant identifying the 1.8 JVM (Java 8).
*/
public static final int JAVA_18 = 5;
/**
* Constant identifying the 1.9 JVM (Java 9).
*/
public static final int JAVA_19 = 6;
private static final String JAVA_VER;
private static final int MAJOR_JAVA_VER;
static {
JAVA_VER = System.getProperty("java.version");
// version String should look like "1.4.2_10"
MAJOR_JAVA_VER = parseVersion(JAVA_VER);
}
private static int parseVersion(String javaVersion) {
if (StrUtils.isBlank(javaVersion))
return UNKOWN;
int a = UNKOWN;
if (javaVersion.contains("1.9.") || javaVersion.startsWith("9"))
a = JAVA_19;
else if (javaVersion.contains("1.8."))
a = JAVA_18;
else if (javaVersion.contains("1.7."))
a = JAVA_17;
else if (javaVersion.contains("1.6."))
a = JAVA_16;
return a;
}
/**
* Return the full Java version string, as returned by
* <code>System.getProperty("java.version")</code>.
*
* @return the full Java version string
*
* @see System#getProperty(String)
*/
public static String getJavaVersion() {
return JAVA_VER;
}
/**
* Get the major version code. This means we can do things like
* <code>if (getMajorJavaVersion() < JAVA_14)</code>. @retu
*
*
* rn a code comparable to the JAVA_XX codes in this class
*
* @return
*
* @see #JAVA_13
* @see #JAVA_14
* @see #JAVA_15
* @see #JAVA_16
* @see #JAVA_17
*/
public static int getMajorJavaVersion() {
return MAJOR_JAVA_VER;
}
public static boolean isJava64Bit() {
String jdkBit = System.getProperty("sun.arch.data.model");
return jdkBit.contains("64");
}
private static final Pattern p = Pattern.compile("java version \"[1-9]*\\.[1-9]*\\.[0-9]*(.*?)\"");
public static JdkVersion getJavaVersionFromExecutable(String file) throws IOException {
String[] str = new String[] { file, "-version" };
Platform platform = Platform.BIT_32;
String ver = null;
try {
for (String line : IOUtils.readProcessByErrorStream(str)) {
Matcher m = p.matcher(line);
if (m.find()) {
ver = m.group();
ver = ver.substring("java version \"".length(), ver.length() - 1);
}
if (line.contains("64-Bit"))
platform = Platform.BIT_64;
}
} catch (InterruptedException | IOException e) {
HMCLog.warn("Failed to get java version", e);
}
return new JdkVersion(file, ver, platform);
}
public void write(File f) throws IOException {
if (ver != null && getPlatform() != Platform.UNKNOWN)
FileUtils.write(f, ver + "\n" + platform);
}
public boolean isEarlyAccess() {
return getVersion() != null && getVersion().endsWith("-ea");
}
}

View File

@@ -1,125 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import com.sun.management.OperatingSystemMXBean;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.util.StringTokenizer;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
/**
* @author huangyuhui
*/
public enum OS {
LINUX('/', "linux"),
WINDOWS('\\', "windows"),
OSX('/', "osx"),
UNKOWN('/', "universal");
public final char fileSeparator;
public final String checked_name;
private OS(char fileSeparator, String n) {
this.fileSeparator = fileSeparator;
checked_name = n;
}
public static OS os() {
String str = System.getProperty("os.name").toLowerCase();
if (str.contains("win"))
return OS.WINDOWS;
if (str.contains("mac"))
return OS.OSX;
if (str.contains("solaris"))
return OS.LINUX;
if (str.contains("sunos"))
return OS.LINUX;
if (str.contains("linux"))
return OS.LINUX;
if (str.contains("unix"))
return OS.LINUX;
return OS.UNKOWN;
}
/**
* @return Free Physical Memory Size (Byte)
*/
public static long getTotalPhysicalMemory() {
try {
if (os() == LINUX)
return memoryInfoForLinux()[0] * 1024;
else {
OperatingSystemMXBean o = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
return o.getTotalPhysicalMemorySize();
}
} catch (Throwable t) {
HMCLog.warn("Failed to get total physical memory size", t);
return -1;
}
}
public static long[] memoryInfoForLinux() throws IOException {
File file = new File("/proc/meminfo");
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(file)));
long[] result = new long[4];
String str;
StringTokenizer token;
while ((str = br.readLine()) != null) {
token = new StringTokenizer(str);
if (!token.hasMoreTokens())
continue;
str = token.nextToken();
if (!token.hasMoreTokens())
continue;
if (str.equalsIgnoreCase("MemTotal:"))
result[0] = Long.parseLong(token.nextToken());
else if (str.equalsIgnoreCase("MemFree:"))
result[1] = Long.parseLong(token.nextToken());
else if (str.equalsIgnoreCase("SwapTotal:"))
result[2] = Long.parseLong(token.nextToken());
else if (str.equalsIgnoreCase("SwapFree:"))
result[3] = Long.parseLong(token.nextToken());
}
return result;
}
public static String getLinuxReleaseVersion() throws IOException {
return FileUtils.read(new File("/etc/issue"));
}
public static String getSystemVersion() {
if (os() == LINUX)
try {
return getLinuxReleaseVersion();
} catch (IOException e) {
HMCLog.warn("Failed to catch /etc/issue");
}
return System.getProperty("os.name") + " (" + System.getProperty("os.arch") + "), " + System.getProperty("os.version");
}
}

View File

@@ -1,56 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
/**
*
* @author huangyuhui
*/
public enum Platform {
UNKNOWN {
@Override
public String getBit() {
return "unknown";
}
},
BIT_32 {
@Override
public String getBit() {
return "32";
}
},
BIT_64 {
@Override
public String getBit() {
return "64";
}
};
public abstract String getBit();
public static Platform getPlatform() {
return System.getProperty("os.arch").contains("64") ? BIT_64 : BIT_32;
}
}

View File

@@ -1,43 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import java.util.HashSet;
/**
*
* @author huangyuhui
*/
public class ProcessManager {
private static final HashSet<JavaProcess> GAME_PROCESSES = new HashSet();
public void registerProcess(JavaProcess jp) {
GAME_PROCESSES.add(jp);
}
public void stopAllProcesses() {
for (JavaProcess jp : GAME_PROCESSES)
jp.stop();
GAME_PROCESSES.clear();
}
public void onProcessStopped(JavaProcess p) {
GAME_PROCESSES.remove(p);
}
}

View File

@@ -1,84 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.EventHandler;
/**
*
* @author huangyuhui
*/
public class ProcessThread extends Thread {
JavaProcess p;
public final EventHandler<String> printlnEvent = new EventHandler<>(this);
public final EventHandler<JavaProcess> stopEvent = new EventHandler<>(this);
public ProcessThread(JavaProcess process) {
p = process;
}
public JavaProcess getProcess() {
return p;
}
@Override
public void run() {
setName("ProcessMonitor");
InputStreamReader br = null;
try {
InputStream in = p.getRawProcess().getInputStream();
try {
br = new InputStreamReader(in, System.getProperty("sun.jnu.encoding", "UTF-8"));
} catch (UnsupportedEncodingException ex) {
HMCLog.warn("Unsupported encoding: " + System.getProperty("sun.jnu.encoding", "UTF-8"), ex);
br = new InputStreamReader(in);
}
int ch;
String line = "";
while (p.isRunning())
while ((ch = br.read()) != -1)
if (ch == '\n') {
printlnEvent.execute(line);
System.out.println("Minecraft: " + line);
p.getStdOutLines().add(line);
line = "";
} else
line += (char) ch;
while ((ch = br.read()) != -1)
if (ch == '\n') {
printlnEvent.execute(line);
System.out.println("Minecraft: " + line);
p.getStdOutLines().add(line);
line = "";
} else
line += (char) ch;
stopEvent.execute(p);
} catch (Exception e) {
HMCLog.err("An error occured when reading process stdout/stderr.", e);
} finally {
IOUtils.closeQuietly(br);
}
}
}

View File

@@ -1,47 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import org.jackhuang.hellominecraft.util.func.Consumer;
/**
*
* @author huangyuhui
*/
public class ThreadExecutor extends Thread {
public final Consumer<Throwable> c;
public final Runnable r;
public ThreadExecutor(Consumer<Throwable> c, Runnable r) {
super();
this.c = c;
this.r = r;
}
@Override
public void run() {
try {
r.run();
c.accept(null);
} catch (Throwable t) {
c.accept(t);
}
}
}

View File

@@ -1,147 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.system;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.jackhuang.hellominecraft.util.func.BiFunction;
/**
* Non thread-safe
*
* @author huangyuhui
*/
public class ZipEngine {
byte[] buf = new byte[1024];
ZipOutputStream zos;
public ZipEngine(File f) throws IOException {
FileOutputStream os = new FileOutputStream(f);
zos = new ZipOutputStream(new BufferedOutputStream(os));
}
public void closeFile() throws IOException {
zos.closeEntry();
zos.close();
}
public void putDirectory(String sourceDir) throws IOException {
putDirectory(new File(sourceDir), null);
}
public void putDirectory(File sourceDir) throws IOException {
putDirectory(sourceDir, null);
}
/**
* 功能:把 sourceDir 目录下的所有文件进行 zip 格式的压缩,保存为指定 zip 文件
*
* @param sourceDir 源文件夹
* @param zipFile 压缩生成的zip文件路径。
* @param pathNameCallback callback(pathName, isDirectory) returns your
* modified pathName
*
* @throws java.io.IOException 压缩失败或无法读取
*/
public void putDirectory(File sourceDir, BiFunction<String, Boolean, String> pathNameCallback) throws IOException {
putDirectoryImpl(sourceDir, sourceDir.isDirectory() ? sourceDir.getPath() : sourceDir.getParent(), pathNameCallback);
}
/**
* 将文件压缩成zip文件
*
* @param source zip文件路径
* @param basePath 待压缩文件根目录
* @param zos zip文件的os
* @param pathNameCallback callback(pathName, isDirectory) returns your
* modified pathName, null if you dont want this file zipped
*/
private void putDirectoryImpl(File source, String basePath, BiFunction<String, Boolean, String> pathNameCallback) throws IOException {
File[] files;
if (source.isDirectory())
files = source.listFiles();
else {
files = new File[1];
files[0] = source;
}
if (files == null)
return;
String pathName;//存相对路径(相对于待压缩的根目录)
for (File file : files)
if (file.isDirectory()) {
pathName = file.getPath().substring(basePath.length() + 1)
+ "/";
pathName = pathName.replace('\\', '/');
if (pathNameCallback != null)
pathName = pathNameCallback.apply(pathName, true);
if (pathName == null)
continue;
put(new ZipEntry(pathName));
putDirectoryImpl(file, basePath, pathNameCallback);
} else {
if (".DS_Store".equals(file.getName())) // For Mac computers.
continue;
pathName = file.getPath().substring(basePath.length() + 1);
pathName = pathName.replace('\\', '/');
if (pathNameCallback != null)
pathName = pathNameCallback.apply(pathName, false);
if (pathName == null)
continue;
putFile(file, pathName);
}
}
public void putFile(File file, String pathName) throws IOException {
putStream(new FileInputStream(file), pathName);
}
public void putStream(InputStream is, String pathName) throws IOException {
int length;
try (BufferedInputStream bis = new BufferedInputStream(is)) {
put(new ZipEntry(pathName));
while ((length = bis.read(buf)) > 0)
zos.write(buf, 0, length);
}
}
public void putTextFile(String text, String pathName) throws IOException {
putTextFile(text, "UTF-8", pathName);
}
public void putTextFile(String text, String encoding, String pathName) throws IOException {
putStream(new ByteArrayInputStream(text.getBytes(encoding)), pathName);
}
protected HashSet<String> names = new HashSet<>();
public void put(ZipEntry entry) throws IOException {
if (names.add(entry.getName()))
zos.putNextEntry(entry);
}
}

View File

@@ -1,46 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
import java.io.File;
import org.jackhuang.hellominecraft.util.system.Compressor;
/**
*
* @author huangyuhui
*/
public class DecompressTask extends Task {
File src, dest;
public DecompressTask(File src, File dest) {
this.src = src;
this.dest = dest;
}
@Override
public void executeTask() throws Throwable {
Compressor.unzip(src, dest);
}
@Override
public String getInfo() {
return "Decompress: " + src.getAbsolutePath() + " to " + dest.getAbsolutePath();
}
}

View File

@@ -1,44 +0,0 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
import java.io.File;
/**
*
* @author huangyuhui
*/
public class DeleteFileTask extends Task {
File f;
public DeleteFileTask(File f) {
this.f = f;
}
@Override
public void executeTask() throws Throwable {
f.delete();
}
@Override
public String getInfo() {
return "Delete: " + f.getAbsolutePath();
}
}

View File

@@ -1,48 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
import java.util.Collection;
/**
*
* @author huangyuhui
*/
public interface DoingDoneListener<K> {
/**
* Task done.
*
* @param k
*/
void onDone(K k, Collection<Task> tasks);
/**
* Before task executing.
*
* @param k
*/
void onDoing(K k, Collection<Task> tasks);
/**
* Task failed.
*
* @param k
*/
void onFailed(K k);
}

View File

@@ -1,55 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
import java.util.Arrays;
import java.util.Collection;
/**
*
* @author huangyuhui
*/
public class DoubleTask extends TaskInfo {
Task a, b;
public DoubleTask(Task a, Task b) {
this(a, b, "Double Task");
}
public DoubleTask(Task a, Task b, String info) {
super(info);
this.a = a;
this.b = b;
}
@Override
public Collection<Task> getDependTasks() {
return Arrays.asList(a);
}
@Override
public Collection<Task> getAfterTasks() {
return Arrays.asList(b);
}
@Override
public void executeTask() throws Throwable {
}
}

View File

@@ -1,29 +0,0 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
/**
*
* @author huangyuhui
*/
public class NoShownTaskException extends RuntimeException {
public NoShownTaskException(String msg) {
super(msg);
}
}

View File

@@ -1,49 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
import java.util.Collection;
import java.util.HashSet;
/**
*
* @author huangyuhui
*/
public class ParallelTask extends Task {
Collection<Task> dependsTask = new HashSet<>();
@Override
public void executeTask() {
}
@Override
public String getInfo() {
return "PARALLEL";
}
@Override
public Collection<Task> getDependTasks() {
return dependsTask;
}
public void addDependsTask(Task t) {
dependsTask.add(t);
}
}

View File

@@ -1,31 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
/**
*
* @author huangyuhui
*/
public interface ProgressProviderListener {
void setProgress(Task task, int prog, int max);
void setStatus(Task task, String sta);
void onProgressProviderDone(Task task);
}

View File

@@ -1,136 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
import java.util.ArrayList;
import java.util.Collection;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
/**
*
* @author huangyuhui
*/
public abstract class Task {
/**
* Run in a new thread(packed in TaskList).
*/
public abstract void executeTask() throws Throwable;
/**
* if this func returns false, TaskList will force abort the thread. run in
* main thread.
*
* @return is aborted.
*/
public boolean abort() {
aborted = true;
return false;
}
protected boolean aborted = false;
public boolean isAborted() {
return aborted;
}
public Throwable getFailReason() {
return failReason;
}
protected Throwable failReason = null;
protected void setFailReason(Throwable s) {
failReason = s;
}
protected String tag;
protected boolean parallelExecuting;
public Task setTag(String tag) {
this.tag = tag;
return this;
}
public boolean isParallelExecuting() {
return parallelExecuting;
}
public void setParallelExecuting(boolean parallelExecuting) {
this.parallelExecuting = parallelExecuting;
}
ArrayList<DoingDoneListener<Task>> taskListener = new ArrayList();
public Task addTaskListener(DoingDoneListener<Task> l) {
taskListener.add(l);
return this;
}
public ArrayList<DoingDoneListener<Task>> getTaskListeners() {
return taskListener;
}
public abstract String getInfo();
public Collection<Task> getDependTasks() {
return null;
}
public Collection<Task> getAfterTasks() {
return null;
}
public boolean areDependTasksSucceeded;
protected ProgressProviderListener ppl;
public Task setProgressProviderListener(ProgressProviderListener p) {
ppl = p;
return this;
}
public Task after(Task t) {
return new DoubleTask(this, t);
}
public Task before(Task t) {
return new DoubleTask(t, this);
}
public void runWithException() throws Throwable {
Collection<Task> c = getDependTasks();
if (c != null)
for (Task t : c)
t.runWithException();
executeTask();
c = getAfterTasks();
if (c != null)
for (Task t : c)
t.runWithException();
}
public boolean run() {
try {
runWithException();
return true;
} catch (Throwable t) {
HMCLog.err("Failed to execute task", t);
return false;
}
}
}

View File

@@ -1,37 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
/**
*
* @author huangyuhui
*/
public abstract class TaskInfo extends Task {
String info;
public TaskInfo(String info) {
this.info = info;
}
@Override
public String getInfo() {
return info;
}
}

View File

@@ -1,192 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
/**
*
* @author huangyuhui
*/
public class TaskList extends Thread {
List<Task> taskQueue = Collections.synchronizedList(new LinkedList<>());
ArrayList<Runnable> allDone = new ArrayList();
ArrayList<DoingDoneListener<Task>> taskListener = new ArrayList();
int totTask;
boolean shouldContinue = true;
public TaskList() {
setDaemon(true);
}
public void clean() {
shouldContinue = true;
taskQueue.clear();
}
public void addAllDoneListener(Runnable l) {
allDone.add(l);
}
public void addTaskListener(DoingDoneListener<Task> l) {
taskListener.add(l);
}
public void addTask(Task task) {
taskQueue.add(task);
}
public int taskCount() {
return totTask;
}
private class Invoker implements Runnable {
Task task;
CountDownLatch latch;
AtomicBoolean bool;
public Invoker(Task task, CountDownLatch latch, AtomicBoolean bool) {
this.task = task;
this.latch = latch;
this.bool = bool;
}
@Override
public void run() {
if (!executeTask(task))
bool.set(false);
latch.countDown();
}
}
ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(64);
HashMap<Invoker, Future<?>> futures = new HashMap<>();
HashSet<Invoker> invokers = new HashSet<>();
private boolean processTasks(Collection<? extends Task> c) {
if (c == null || c.isEmpty())
return true;
this.totTask += c.size();
AtomicBoolean bool = new AtomicBoolean(true);
CountDownLatch counter = new CountDownLatch(c.size());
for (Task t2 : c) {
if (t2 == null)
continue;
t2.setParallelExecuting(true);
Invoker thread = new Invoker(t2, counter, bool);
invokers.add(thread);
if (!EXECUTOR_SERVICE.isShutdown() && !EXECUTOR_SERVICE.isTerminated())
futures.put(thread, EXECUTOR_SERVICE.submit(thread));
}
try {
counter.await();
} catch (InterruptedException ignore) {
}
return bool.get();
}
private boolean executeTask(Task t) {
if (!shouldContinue)
return false;
if (t == null)
return true;
Collection<Task> c = t.getDependTasks();
if (c == null)
c = new HashSet<>();
HMCLog.log("Executing task: " + t.getInfo());
for (DoingDoneListener<Task> d : t.getTaskListeners())
d.onDoing(t, c);
for (DoingDoneListener<Task> d : taskListener)
d.onDoing(t, c);
t.areDependTasksSucceeded = processTasks(c);
boolean flag = true;
try {
t.executeTask();
} catch (Throwable e) {
t.setFailReason(e);
flag = false;
}
if (flag) {
HMCLog.log((t.isAborted() ? "Task aborted: " : "Task finished: ") + t.getInfo());
Collection<Task> at = t.getAfterTasks();
if (at == null)
at = new HashSet<>();
for (DoingDoneListener<Task> d : t.getTaskListeners())
d.onDone(t, at);
for (DoingDoneListener<Task> d : taskListener)
d.onDone(t, at);
processTasks(at);
} else {
HMCLog.err("Task failed: " + t.getInfo(), t.getFailReason());
for (DoingDoneListener<Task> d : taskListener)
d.onFailed(t);
for (DoingDoneListener<Task> d : t.getTaskListeners())
d.onFailed(t);
}
return flag;
}
@Override
public void run() {
Thread.currentThread().setName("TaskList");
totTask = taskQueue.size();
while (!taskQueue.isEmpty())
executeTask(taskQueue.remove(0));
if (shouldContinue)
for (Runnable d : allDone)
d.run();
}
public boolean isEmpty() {
return taskQueue.isEmpty();
}
public void abort() {
shouldContinue = false;
final HashSet<Invoker> in = this.invokers;
EXECUTOR_SERVICE.shutdown();
while (!in.isEmpty())
synchronized (in) {
Invoker it = in.iterator().next();
if (!it.task.abort() && futures.get(it) != null)
futures.get(it).cancel(true);
in.remove(it);
}
this.interrupt();
}
}

View File

@@ -1,42 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
/**
*
* @author huangyuhui
*/
public class TaskRunnable extends TaskInfo {
private final Runnable r;
public TaskRunnable(String info, Runnable r) {
super(info);
this.r = r;
}
public TaskRunnable(Runnable r) {
this("TaskRunnable", r);
}
@Override
public void executeTask() {
r.run();
}
}

View File

@@ -1,93 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.6" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="taskwindow.title" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<Events>
<EventHandler event="windowClosed" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosed"/>
</Events>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="pgsTotal" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnCancel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Component id="srlDownload" alignment="0" pref="517" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="srlDownload" pref="290" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="pgsTotal" alignment="3" min="-2" pref="22" max="-2" attributes="0"/>
<Component id="btnCancel" alignment="3" min="-2" pref="22" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="btnCancel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="taskwindow.cancel" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCancelActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JProgressBar" name="pgsTotal">
<Properties>
<Property name="stringPainted" type="boolean" value="true"/>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="srlDownload">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="lstDownload">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="SwingUtils.makeDefaultTableModel(new String[]{C.i18n(&quot;taskwindow.file_name&quot;), C.i18n(&quot;taskwindow.download_progress&quot;)}, new Class[]{String.class, String.class}, new boolean[]{false,false})&#xd;&#xa;" type="code"/>
</Property>
<Property name="rowSelectionAllowed" type="boolean" value="false"/>
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
<JTableSelectionModel selectionMode="0"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@@ -1,346 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.ui.SwingUtils;
/**
*
* @author huangyuhui
*/
public class TaskWindow extends javax.swing.JDialog
implements ProgressProviderListener, Runnable, DoingDoneListener<Task> {
private static volatile TaskWindow INSTANCE = null;
private static synchronized TaskWindow instance() {
if (INSTANCE == null)
INSTANCE = new TaskWindow();
INSTANCE.clean();
return INSTANCE;
}
public static TaskWindowFactory factory() {
return new TaskWindowFactory();
}
boolean suc = false;
private TaskList taskList;
private final ArrayList<String> failReasons = new ArrayList();
private String stackTrace = null, lastStackTrace = null;
/**
* Creates new form DownloadWindow
*/
private TaskWindow() {
initComponents();
setLocationRelativeTo(null);
if (lstDownload.getColumnModel().getColumnCount() > 1) {
int i = 35;
lstDownload.getColumnModel().getColumn(1).setMinWidth(i);
lstDownload.getColumnModel().getColumn(1).setMaxWidth(i);
lstDownload.getColumnModel().getColumn(1).setPreferredWidth(i);
}
setModal(true);
}
public TaskWindow addTask(Task task) {
taskList.addTask(task);
return this;
}
public synchronized void clean() {
if (isVisible())
return;
taskList = new TaskList();
taskList.addTaskListener(this);
taskList.addAllDoneListener(this);
}
public static String downloadSource = "";
public boolean start() {
if (isVisible() || taskList == null || taskList.isAlive())
return false;
pgsTotal.setValue(0);
suc = false;
SwingUtils.clearDefaultTable(lstDownload);
failReasons.clear();
tasks.clear();
try {
taskList.start();
} catch (Exception e) {
HMCLog.err("Failed to start thread, maybe there're already a taskwindow here.", e);
HMCLog.err("There's the stacktrace of the this invoking.");
HMCLog.err(stackTrace);
HMCLog.err("There's the stacktrace of the last invoking.");
HMCLog.err(lastStackTrace);
MessageBox.Show(C.i18n("taskwindow.no_more_instance"));
return false;
}
setTitle(C.i18n("taskwindow.title") + " - " + C.i18n("download.source") + ": " + downloadSource);
this.setVisible(true);
return this.areTasksFinished();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
btnCancel = new javax.swing.JButton();
pgsTotal = new javax.swing.JProgressBar();
srlDownload = new javax.swing.JScrollPane();
lstDownload = new javax.swing.JTable();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle(C.i18n("taskwindow.title")); // NOI18N
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosed(java.awt.event.WindowEvent evt) {
formWindowClosed(evt);
}
});
btnCancel.setText(C.i18n("taskwindow.cancel")); // NOI18N
btnCancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnCancelActionPerformed(evt);
}
});
pgsTotal.setStringPainted(true);
lstDownload.setModel(SwingUtils.makeDefaultTableModel(new String[]{C.i18n("taskwindow.file_name"), C.i18n("taskwindow.download_progress")}, new Class[]{String.class, String.class}, new boolean[]{false,false})
);
lstDownload.setRowSelectionAllowed(false);
lstDownload.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
srlDownload.setViewportView(lstDownload);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(pgsTotal, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCancel)
.addContainerGap())
.addComponent(srlDownload, javax.swing.GroupLayout.DEFAULT_SIZE, 517, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(srlDownload, javax.swing.GroupLayout.DEFAULT_SIZE, 290, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(pgsTotal, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
if (MessageBox.Show(C.i18n("operation.confirm_stop"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
this.dispose();
}//GEN-LAST:event_btnCancelActionPerformed
private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
if (taskList == null)
return;
tasks.clear();
if (!this.failReasons.isEmpty()) {
String str = StrUtils.parseParams("", failReasons.toArray(), "\n");
SwingUtilities.invokeLater(() -> MessageBox.Show(str, C.i18n("message.error"), MessageBox.ERROR_MESSAGE));
failReasons.clear();
}
if (!suc) {
if (taskList != null)
SwingUtilities.invokeLater(taskList::abort);
HMCLog.log("Tasks have been canceled by user.");
}
taskList = null;
}//GEN-LAST:event_formWindowClosed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnCancel;
private javax.swing.JTable lstDownload;
private javax.swing.JProgressBar pgsTotal;
private javax.swing.JScrollPane srlDownload;
// End of variables declaration//GEN-END:variables
final ArrayList<Task> tasks = new ArrayList<>();
final ArrayList<Integer> progresses = new ArrayList<>();
@Override
public void setProgress(Task task, int progress, int max) {
SwingUtilities.invokeLater(() -> {
if (task == null)
return;
int idx = tasks.indexOf(task);
if (idx == -1)
return;
int pgs = progress * 100 / max;
if (progresses.size() > idx && progresses.get(idx) != pgs && lstDownload.getRowCount() > idx) {
SwingUtils.setValueAt(lstDownload, pgs < 0 ? "???" : pgs + "%", idx, 1);
progresses.set(idx, pgs);
}
});
}
@Override
public void run() {
SwingUtilities.invokeLater(() -> {
dispose();
suc = true;
HMCLog.log("Tasks are finished.");
});
}
@Override
public void onDoing(Task task, Collection<Task> taskCollection) {
if (task == null)
return;
task.setProgressProviderListener(this);
SwingUtilities.invokeLater(() -> {
if (taskList == null)
return;
tasks.add(task);
progresses.add(-1);
SwingUtils.appendLast(lstDownload, task.getInfo(), "0%");
SwingUtils.moveEnd(srlDownload);
});
}
public boolean areTasksFinished() {
return suc;
}
@Override
public void onDone(Task task, Collection<Task> taskCollection) {
SwingUtilities.invokeLater(() -> {
if (taskList == null || task == null)
return;
pgsTotal.setMaximum(taskList.taskCount());
pgsTotal.setValue(pgsTotal.getValue() + 1);
int idx = tasks.indexOf(task);
if (idx == -1)
return;
tasks.remove(idx);
progresses.remove(idx);
SwingUtils.removeRow(lstDownload, idx);
});
}
@Override
public void onFailed(Task task) {
SwingUtilities.invokeLater(() -> {
if (taskList == null || task == null)
return;
String msg = null;
if (task.getFailReason() != null && !(task.getFailReason() instanceof NoShownTaskException))
if (StrUtils.isBlank(task.getFailReason().getLocalizedMessage()))
msg = task.getFailReason().getClass().getSimpleName();
else
msg = task.getFailReason().getLocalizedMessage();
if (msg != null)
failReasons.add(task.getInfo() + ": " + msg);
pgsTotal.setMaximum(taskList.taskCount());
pgsTotal.setValue(pgsTotal.getValue() + 1);
int idx = tasks.indexOf(task);
if (idx == -1)
return;
SwingUtils.setValueAt(lstDownload, task.getFailReason(), idx, 0);
SwingUtils.setValueAt(lstDownload, "0%", idx, 1);
SwingUtils.moveEnd(srlDownload);
});
}
@Override
public void onProgressProviderDone(Task task) {
}
@Override
public void setStatus(Task task, String sta) {
SwingUtilities.invokeLater(() -> {
if (taskList == null || task == null)
return;
int idx = tasks.indexOf(task);
if (idx == -1)
return;
SwingUtils.setValueAt(lstDownload, task.getInfo() + ": " + sta, idx, 0);
});
}
public static boolean execute(Task... ts) {
TaskWindowFactory f = factory();
for (Task t : ts)
f.append(t);
return f.create();
}
public static class TaskWindowFactory {
LinkedList<Task> ll = new LinkedList<>();
boolean flag;
public TaskWindowFactory append(Task t) {
if (t != null)
ll.add(t);
return this;
}
public boolean create() {
String stacktrace = StrUtils.getStackTrace(new Throwable());
return SwingUtils.invokeAndWait(() -> {
final TaskWindow tw = instance();
synchronized (tw) {
if (tw.isVisible())
return false;
for (Task t : ll)
tw.addTask(t);
tw.lastStackTrace = tw.stackTrace;
tw.stackTrace = stacktrace;
return tw.start();
}
});
}
}
}

View File

@@ -1,38 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.communication;
/**
*
* @author huangyuhui
* @param <T> the type of result.
*/
public class DefaultPreviousResult<T> implements PreviousResult<T> {
T a;
public DefaultPreviousResult(T a) {
this.a = a;
}
@Override
public T getResult() {
return a;
}
}

View File

@@ -1,29 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.communication;
/**
*
* @author huangyuhui
* @param <T> Task result type
*/
public interface PreviousResult<T> {
T getResult();
}

View File

@@ -1,36 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.communication;
import org.jackhuang.hellominecraft.util.tasks.Task;
/**
*
* @author huangyuhui
* @param <T> Previous task result type
*/
public interface PreviousResultRegistrar<T> {
/**
*
* @param pr previous task handler
*
* @return task self instance
*/
Task registerPreviousResult(PreviousResult<T> pr);
}

View File

@@ -1,54 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.download;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.util.ui.LogWindow;
/**
*
* @author huangyuhui
*/
public class ContentGetAndShowTask extends HTTPGetTask implements Event<String> {
public ContentGetAndShowTask(String info, String changeLogUrl) {
super(changeLogUrl);
this.info = info;
}
@Override
public void executeTask() throws Exception {
tdtsl.register(this);
super.executeTask();
}
String info;
@Override
public String getInfo() {
return info;
}
@Override
public boolean call(Object sender, String value) {
LogWindow.INSTANCE.clean();
LogWindow.INSTANCE.log(value);
LogWindow.INSTANCE.setVisible(true);
return true;
}
}

View File

@@ -1,31 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.download;
import org.jackhuang.hellominecraft.util.tasks.ProgressProviderListener;
/**
*
* @author huangyuhui
*/
public interface DownloadListener extends ProgressProviderListener {
boolean OnFailed();
void OnFailedMoreThan5Times(String url);
}

View File

@@ -1,263 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.download;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.ArrayList;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.code.DigestUtils;
import org.jackhuang.hellominecraft.util.func.Function;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.tasks.Task;
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult;
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResultRegistrar;
import org.jackhuang.hellominecraft.util.system.IOUtils;
/**
*
* @author huangyuhui
*/
// This class downloads a file from a URL.
public class FileDownloadTask extends Task implements PreviousResult<File>, PreviousResultRegistrar<String> {
// Max size of download buffer.
protected static final int MAX_BUFFER_SIZE = 2048;
protected URL url; // download URL
protected int downloaded = 0; // number of bytes downloaded
protected File filePath;
protected String expectedHash;
protected Function<Integer, String> failedCallbackReturnsNewURL;
public FileDownloadTask setFailedCallbackReturnsNewURL(Function<Integer, String> failedCallbackReturnsNewURL) {
this.failedCallbackReturnsNewURL = failedCallbackReturnsNewURL;
return this;
}
public FileDownloadTask() {
}
public FileDownloadTask(File filePath) {
this((URL) null, filePath);
}
public FileDownloadTask(String url, File filePath) {
this(IOUtils.parseURL(url), filePath);
}
public FileDownloadTask(URL url, File filePath) {
this(url, filePath, null);
}
public FileDownloadTask(String url, File filePath, String hash) {
this(IOUtils.parseURL(url), filePath, hash);
}
public FileDownloadTask(URL url, File file, String hash) {
this.url = url;
this.filePath = file;
this.expectedHash = hash;
}
// Get this download's URL.
public String getUrl() {
return url.toString();
}
RandomAccessFile file = null;
InputStream stream = null;
boolean shouldContinue = true;
private void closeFiles() {
// Close file.
if (file != null)
try {
file.close();
file = null;
} catch (IOException e) {
HMCLog.warn("Failed to close file", e);
}
// Close connection to server.
if (stream != null)
try {
stream.close();
stream = null;
} catch (IOException e) {
HMCLog.warn("Failed to close stream", e);
}
}
// Download file.
@Override
public void executeTask() throws Throwable {
for (PreviousResult<String> p : al)
this.url = IOUtils.parseURL(p.getResult());
for (int repeat = 0; repeat < 6; repeat++) {
if (repeat > 0)
if (failedCallbackReturnsNewURL != null) {
URL tmp = IOUtils.parseURL(failedCallbackReturnsNewURL.apply(repeat));
if (tmp != null) {
url = tmp;
HMCLog.warn("Switch to: " + url);
}
}
HMCLog.log("Downloading: " + url + ", to: " + filePath);
if (!shouldContinue)
break;
try {
if (ppl != null)
ppl.setProgress(this, -1, 1);
// Open connection to URL.
HttpURLConnection connection
= (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestProperty("User-Agent", "Hello Minecraft!");
// Connect to server.
connection.connect();
// Make sure response code is in the 200 range.
if (connection.getResponseCode() / 100 != 2)
throw new NetException(C.i18n("download.not_200") + " " + connection.getResponseCode());
// Check for valid content length.
int contentLength = connection.getContentLength();
if (contentLength < 1)
throw new NetException("The content length is invalid.");
filePath.getParentFile().mkdirs();
File tempFile = new File(filePath.getAbsolutePath() + ".hmd");
if (!tempFile.exists())
tempFile.createNewFile();
else if (!tempFile.renameTo(tempFile)) // check file lock
throw new RuntimeException("The temp file is locked, maybe there is an application using the file?");
// Open file and seek to the end of it.
file = new RandomAccessFile(tempFile, "rw");
MessageDigest digest = DigestUtils.getSha1Digest();
stream = connection.getInputStream();
int lastDownloaded = 0;
downloaded = 0;
long lastTime = System.currentTimeMillis();
while (true) {
// Size buffer according to how much of the file is left to download.
if (!shouldContinue) {
closeFiles();
filePath.delete();
break;
}
byte buffer[] = new byte[MAX_BUFFER_SIZE];
// Read from server into buffer.
int read = stream.read(buffer);
if (read == -1)
break;
digest.update(buffer, 0, read);
// Write buffer to file.
file.write(buffer, 0, read);
downloaded += read;
long now = System.currentTimeMillis();
if (ppl != null && (now - lastTime) >= 1000) {
ppl.setProgress(this, downloaded, contentLength);
ppl.setStatus(this, (downloaded - lastDownloaded) / 1024 + "KB/s");
lastDownloaded = downloaded;
lastTime = now;
}
}
closeFiles();
if (aborted)
tempFile.delete();
else {
if (filePath.exists())
filePath.delete();
tempFile.renameTo(filePath);
}
if (!shouldContinue)
break;
if (downloaded != contentLength)
throw new IllegalStateException("Unexptected file size: " + downloaded + ", expected: " + contentLength);
String hashCode = String.format("%1$040x", new Object[] { new BigInteger(1, digest.digest()) });
if (expectedHash != null && !expectedHash.equals(hashCode))
throw new IllegalStateException("Unexpected hash code: " + hashCode + ", expected: " + expectedHash);
if (ppl != null)
ppl.onProgressProviderDone(this);
return;
} catch (Exception e) {
setFailReason(new NetException(C.i18n("download.failed") + " " + url, e));
} finally {
closeFiles();
}
}
if (failReason != null)
throw failReason;
}
public static void download(String url, String file, DownloadListener dl) throws Throwable {
download(url, new File(file), dl);
}
public static void download(String url, File file, DownloadListener dl) throws Throwable {
((Task) new FileDownloadTask(url, file).setProgressProviderListener(dl)).executeTask();
}
@Override
public boolean abort() {
//for (Downloader d : downloaders) d.abort();
shouldContinue = false;
aborted = true;
return true;
}
@Override
public String getInfo() {
return C.i18n("download") + ": " + url;
}
@Override
public File getResult() {
return filePath;
}
ArrayList<PreviousResult<String>> al = new ArrayList();
@Override
public Task registerPreviousResult(PreviousResult<String> pr) {
al.add(pr);
return this;
}
}

View File

@@ -1,107 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.download;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.tasks.TaskInfo;
import org.jackhuang.hellominecraft.util.tasks.communication.PreviousResult;
import org.jackhuang.hellominecraft.util.EventHandler;
/**
*
* @author huangyuhui
*/
public class HTTPGetTask extends TaskInfo implements PreviousResult<String> {
String url, encoding, result;
EventHandler<String> tdtsl = new EventHandler<>(this);
boolean shouldContinue = true;
public HTTPGetTask(String url) {
this(null, url);
}
public HTTPGetTask(String info, String url) {
this(info, url, "UTF-8");
}
public HTTPGetTask(String info, String url, String encoding) {
super(info);
this.url = url;
this.encoding = encoding;
}
@Override
public void executeTask() throws Exception {
Exception t = null;
for (int repeat = 0; repeat < 6; repeat++) {
if (repeat > 0)
HMCLog.warn("Failed to download, repeat: " + repeat);
try {
if (ppl != null)
ppl.setProgress(this, -1, 1);
URLConnection conn = new URL(url).openConnection();
InputStream is = conn.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i;
int size = conn.getContentLength(), read = 0;
long lastTime = System.currentTimeMillis();
while ((i = is.read()) != -1) {
baos.write(i);
++read;
long now = System.currentTimeMillis();
if (ppl != null && (now - lastTime) >= 1000) {
ppl.setProgress(this, read, size);
lastTime = now;
}
if (!shouldContinue)
return;
}
result = baos.toString();
tdtsl.execute(result);
return;
} catch (Exception ex) {
t = new NetException("Failed to get " + url, ex);
}
}
if (t != null)
throw t;
}
@Override
public boolean abort() {
shouldContinue = false;
aborted = true;
return true;
}
@Override
public String getInfo() {
return super.getInfo() != null ? super.getInfo() : "Get: " + url;
}
@Override
public String getResult() {
return result;
}
}

View File

@@ -1,38 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.tasks.download;
/**
*
* @author huangyuhui
*/
public class NetException extends RuntimeException {
public NetException(Exception message) {
super(message);
}
public NetException(String message) {
super(message);
}
public NetException(String message, Exception e) {
super(message, e);
}
}

View File

@@ -1,90 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.ui;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
public abstract class AbstractFilter
implements BufferedImageOp {
@Override
public abstract BufferedImage filter(BufferedImage paramBufferedImage1, BufferedImage paramBufferedImage2);
@Override
public Rectangle2D getBounds2D(BufferedImage src) {
return new Rectangle(0, 0, src.getWidth(), src.getHeight());
}
@Override
public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel destCM) {
if (destCM == null)
destCM = src.getColorModel();
return new BufferedImage(destCM, destCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), destCM.isAlphaPremultiplied(), null);
}
@Override
public Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
return (Point2D) srcPt.clone();
}
@Override
public RenderingHints getRenderingHints() {
return null;
}
protected int[] getPixels(BufferedImage img, int x, int y, int w, int h, int[] pixels) {
if ((w == 0) || (h == 0))
return new int[0];
if (pixels == null)
pixels = new int[w * h];
else if (pixels.length < w * h)
throw new IllegalArgumentException("pixels array must have a length >= w*h");
int imageType = img.getType();
if ((imageType == 2) || (imageType == 1)) {
Raster raster = img.getRaster();
return (int[]) (int[]) raster.getDataElements(x, y, w, h, pixels);
}
return img.getRGB(x, y, w, h, pixels, 0, w);
}
protected void setPixels(BufferedImage img, int x, int y, int w, int h, int[] pixels) {
if ((pixels == null) || (w == 0) || (h == 0))
return;
if (pixels.length < w * h)
throw new IllegalArgumentException("pixels array must have a length >= w*h");
int imageType = img.getType();
if ((imageType == 2) || (imageType == 1)) {
WritableRaster raster = img.getRaster();
raster.setDataElements(x, y, w, h, pixels);
} else
img.setRGB(x, y, w, h, pixels, 0, w);
}
}

View File

@@ -1,60 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.ui;
import java.awt.Color;
/**
*
* @author huangyuhui
*/
public class BasicColors {
private static Color getWebColor(String c) {
return new Color(
Integer.parseInt(c.substring(0, 2), 16),
Integer.parseInt(c.substring(2, 4), 16),
Integer.parseInt(c.substring(4, 6), 16)
);
}
public static final Color COLOR_RED = new Color(229, 0, 0);
public static final Color COLOR_RED_DARKER = new Color(157, 41, 51);
public static final Color COLOR_GREEN = new Color(90, 184, 96);
public static final Color COLOR_BLUE = new Color(16, 108, 163);
public static final Color COLOR_BLUE_DARKER = new Color(12, 94, 145);
public static final Color COLOR_WHITE_TEXT = new Color(254, 254, 254);
public static final Color COLOR_CENTRAL_BACK = new Color(25, 30, 34, 160);
public static final Color bgcolors[] = new Color[] {
COLOR_BLUE,
getWebColor("1ABC9C"),
getWebColor("9B59B6"),
getWebColor("34495E"),
getWebColor("E67E22"),
getWebColor("E74C3C")
};
public static final Color bgcolors_darker[] = new Color[] {
COLOR_BLUE_DARKER,
getWebColor("16A085"),
getWebColor("8E44AD"),
getWebColor("2C3E50"),
getWebColor("D35400"),
getWebColor("C0392B")
};
}

View File

@@ -1,99 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.ui;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import javax.swing.border.AbstractBorder;
import org.jackhuang.hellominecraft.util.Pair;
public class DropShadowBorder extends AbstractBorder {
private Color color;
private int thickness = 1;
private Insets insets = null;
RenderingHints hints;
public DropShadowBorder(Color color) {
this(color, 3);
}
public DropShadowBorder(Color color, int thickness) {
this.thickness = thickness;
this.color = color;
this.hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
this.insets = new Insets(thickness * 4, thickness * 4, thickness * 4, thickness * 4);
}
public void setColor(Color c) {
color = c;
}
@Override
public Insets getBorderInsets(Component c) {
return this.insets;
}
@Override
public Insets getBorderInsets(Component c, Insets insets) {
return getBorderInsets(c);
}
private static final HashMap<Pair<Integer, Integer>, BufferedImage> CACHE = new HashMap<>();
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Pair<Integer, Integer> pair = new Pair<>(width, height);
if (CACHE.containsKey(pair))
g.drawImage(CACHE.get(pair), x, y, width, height, null);
else {
BufferedImage shadow = new BufferedImage(width, height, 2);
Graphics2D g2 = shadow.createGraphics();
g2.setRenderingHints(this.hints);
Composite oldComposite = g2.getComposite();
AlphaComposite composite = AlphaComposite.getInstance(1, 0.0F);
g2.setComposite(composite);
g2.setColor(new Color(0, 0, 0, 0));
g2.fillRect(0, 0, width, height);
g2.setComposite(oldComposite);
g2.setColor(this.color);
int border = (int) (this.thickness * 4);
g2.fillRect(border, border + border / 6, width - border * 2, height - border * 2);
g2.dispose();
FastBlurFilter blur = new FastBlurFilter(this.thickness);
shadow = blur.filter(shadow, null);
shadow = blur.filter(shadow, null);
shadow = blur.filter(shadow, null);
shadow = blur.filter(shadow, null);
CACHE.put(pair, shadow);
g.drawImage(shadow, x, y, width, height, null);
}
}
}

View File

@@ -1,137 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.ui;
import java.awt.image.BufferedImage;
public class FastBlurFilter extends AbstractFilter {
private final int radius;
public FastBlurFilter() {
this(3);
}
public FastBlurFilter(int radius) {
if (radius < 1)
radius = 1;
this.radius = radius;
}
public int getRadius() {
return this.radius;
}
@Override
public BufferedImage filter(BufferedImage src, BufferedImage dst) {
int width = src.getWidth();
int height = src.getHeight();
if (dst == null)
dst = createCompatibleDestImage(src, null);
int[] srcPixels = new int[width * height];
int[] dstPixels = new int[width * height];
getPixels(src, 0, 0, width, height, srcPixels);
blur(srcPixels, dstPixels, width, height, this.radius);
blur(dstPixels, srcPixels, height, width, this.radius);
setPixels(dst, 0, 0, width, height, srcPixels);
return dst;
}
static void blur(int[] srcPixels, int[] dstPixels, int width, int height, int radius) {
int windowSize = radius * 2 + 1;
int radiusPlusOne = radius + 1;
int srcIndex = 0;
int[] sumLookupTable = new int[256 * windowSize];
for (int i = 0; i < sumLookupTable.length; i++)
sumLookupTable[i] = (i / windowSize);
int[] indexLookupTable = new int[radiusPlusOne];
if (radius < width)
for (int i = 0; i < indexLookupTable.length; i++)
indexLookupTable[i] = i;
else {
for (int i = 0; i < width; i++)
indexLookupTable[i] = i;
for (int i = width; i < indexLookupTable.length; i++)
indexLookupTable[i] = (width - 1);
}
for (int y = 0; y < height; y++) {
int sumBlue;
int sumGreen;
int sumRed;
int sumAlpha = sumRed = sumGreen = sumBlue = 0;
int dstIndex = y;
int pixel = srcPixels[srcIndex];
sumAlpha += radiusPlusOne * (pixel >> 24 & 0xFF);
sumRed += radiusPlusOne * (pixel >> 16 & 0xFF);
sumGreen += radiusPlusOne * (pixel >> 8 & 0xFF);
sumBlue += radiusPlusOne * (pixel & 0xFF);
for (int i = 1; i <= radius; i++) {
pixel = srcPixels[(srcIndex + indexLookupTable[i])];
sumAlpha += (pixel >> 24 & 0xFF);
sumRed += (pixel >> 16 & 0xFF);
sumGreen += (pixel >> 8 & 0xFF);
sumBlue += (pixel & 0xFF);
}
for (int x = 0; x < width; x++) {
dstPixels[dstIndex] = (sumLookupTable[sumAlpha] << 24 | sumLookupTable[sumRed] << 16 | sumLookupTable[sumGreen] << 8 | sumLookupTable[sumBlue]);
dstIndex += height;
int nextPixelIndex = x + radiusPlusOne;
if (nextPixelIndex >= width)
nextPixelIndex = width - 1;
int previousPixelIndex = x - radius;
if (previousPixelIndex < 0)
previousPixelIndex = 0;
int nextPixel = srcPixels[(srcIndex + nextPixelIndex)];
int previousPixel = srcPixels[(srcIndex + previousPixelIndex)];
sumAlpha += (nextPixel >> 24 & 0xFF);
sumAlpha -= (previousPixel >> 24 & 0xFF);
sumRed += (nextPixel >> 16 & 0xFF);
sumRed -= (previousPixel >> 16 & 0xFF);
sumGreen += (nextPixel >> 8 & 0xFF);
sumGreen -= (previousPixel >> 8 & 0xFF);
sumBlue += (nextPixel & 0xFF);
sumBlue -= (previousPixel & 0xFF);
}
srcIndex += width;
}
}
}

View File

@@ -1,207 +0,0 @@
package org.jackhuang.hellominecraft.util.ui;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.plaf.synth.SynthContext;
import javax.swing.plaf.synth.SynthGraphicsUtils;
/**
* NimbusGraphicsUtils - extends SynthGraphicsUtils to force all Synth painted
* text to be antialiased and provides some static helper methods.
*
* @author Created by Jasper Potts (Jan 4, 2007)
* @version 1.0
*/
public class GraphicsUtils extends SynthGraphicsUtils {
private Map<?, ?> desktopHints;
/**
* Get rendering hints from a Graphics instance. "hintsToSave" is a Map of
* RenderingHint key-values. For each hint key present in that map, the
* value of that hint is obtained from the Graphics and stored as the value
* for the key in savedHints.
*
* @param g2d the graphics surface
* @param hintsToSave the list of rendering hints to set on the graphics
* @param savedHints a set where to save the previous rendering hints,
* might
* be null
*
* @return the previous set of rendering hints
*/
public static RenderingHints getRenderingHints(Graphics2D g2d,
Map<?, ?> hintsToSave,
RenderingHints savedHints) {
if (savedHints == null)
savedHints = new RenderingHints(null);
else
savedHints.clear();
if (hintsToSave.isEmpty())
return savedHints;
/* RenderingHints.keySet() returns Set */
for (Object o : hintsToSave.keySet()) {
RenderingHints.Key key = (RenderingHints.Key) o;
Object value = g2d.getRenderingHint(key);
savedHints.put(key, value);
}
return savedHints;
}
/**
* Overrides paintText in SynthGraphicsUtils to force all Synth painted text
* to be antialiased
*/
@Override
public void paintText(SynthContext ss, Graphics g, String text, int x, int y, int mnemonicIndex) {
Graphics2D g2 = (Graphics2D) g;
// XXX: In Java SE 6, Synth already uses the desktop hints, this code should just check whether java.version < 1.6
if (desktopHints == null) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
desktopHints = (Map<?, ?>) (toolkit.getDesktopProperty("awt.font.desktophints"));
}
Object oldAA = null;
RenderingHints oldHints = null;
if (desktopHints != null) {
oldHints = getRenderingHints(g2, desktopHints, null);
g2.addRenderingHints(desktopHints);
} else {
oldAA = g2.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
super.paintText(ss, g, text, x, y, mnemonicIndex);
if (oldHints != null)
g2.addRenderingHints(oldHints);
else if (oldAA != null)
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
oldAA);
}
/**
* Load an image using ImageIO from resource in
* org.jdesktop.swingx.plaf.nimbus.images. Catches and prints all Exceptions
* so that it can safely be used in a static context.
*
* @param imgName The name of the image to load, eg. "border.png"
*
* @return The loaded image
*/
public static BufferedImage loadImage(String imgName) {
try {
return ImageIO.read(GraphicsUtils.class.getClassLoader().getResource("org/jackhuang/hellominecraft/lookandfeel/images/" + imgName));
} catch (Exception e) {
System.err.println("Error loading image \"org/jackhuang/hellominecraft/lookandfeel/images/" + imgName + "\"");
e.printStackTrace();
}
return null;
}
public static String getColor(Color c) {
return Integer.toHexString(c.getRGB() & 0xFFFFFF);
}
/**
* Get a Color object from a web color string of the form "FF00AB" or
* "#FF00AB".
*
* @param c The color string
*
* @return The Color described
*/
public static Color getWebColor(String c) {
if (c.startsWith("#"))
c = c.substring(1);
return new Color(
Integer.parseInt(c.substring(0, 2), 16),
Integer.parseInt(c.substring(2, 4), 16),
Integer.parseInt(c.substring(4, 6), 16)
);
}
/**
* Get a Color object from a web color string of the form "FF00AB" or
* "#FF00AB".
*
* @param c The color string
*
* @return The Color described
*/
public static Color getWebColorWithAlpha(String c) {
if (c.startsWith("#"))
c = c.substring(1);
return new Color(
Integer.parseInt(c.substring(0, 2), 16),
Integer.parseInt(c.substring(2, 4), 16),
Integer.parseInt(c.substring(4, 6), 16),
Integer.parseInt(c.substring(6, 8), 16)
);
}
/**
* Get a Color that is 50% inbetween the two web colors given. The Web
* colors are of the form "FF00AB" or "#FF00AB".
*
* @param c1 The first color string
* @param c2 The second color string
*
* @return The Color middle color
*/
public static Color getMidWebColor(String c1, String c2) {
return getMidWebColor(c1, c2, 50);
}
/**
* Get a Color that is 50% inbetween the two web colors given. The Web
* colors are of the form "FF00AB" or "#FF00AB".
*
* @param c1 The first color string
* @param c2 The second color string
*
* @return The Color middle color
*/
public static Color getMidWebColor(String c1, String c2, int percent) {
if (c1.startsWith("#"))
c1 = c1.substring(1);
if (c2.startsWith("#"))
c2 = c2.substring(1);
int rTop = Integer.parseInt(c1.substring(0, 2), 16);
int gTop = Integer.parseInt(c1.substring(2, 4), 16);
int bTop = Integer.parseInt(c1.substring(4, 6), 16);
int rBot = Integer.parseInt(c2.substring(0, 2), 16);
int gBot = Integer.parseInt(c2.substring(2, 4), 16);
int bBot = Integer.parseInt(c2.substring(4, 6), 16);
int rMid = rTop + ((rBot - rTop) * percent / 100);
int gMid = gTop + ((gBot - gTop) * percent / 100);
int bMid = bTop + ((bBot - bTop) * percent / 100);
return new Color(rMid, gMid, bMid);
}
public static Color getMidWebColor(Color c1, Color c2, int percent) {
int rTop = c1.getRed();
int gTop = c1.getGreen();
int bTop = c1.getBlue();
int aTop = c1.getAlpha();
int rBot = c2.getRed();
int gBot = c2.getGreen();
int bBot = c2.getBlue();
int aBot = c2.getAlpha();
int rMid = rTop + ((rBot - rTop) * percent / 100);
int gMid = gTop + ((gBot - gTop) * percent / 100);
int bMid = bTop + ((bBot - bTop) * percent / 100);
int aMid = aTop + ((aBot - aTop) * percent / 100);
return new Color(rMid, gMid, bMid, aMid);
}
}

View File

@@ -1,176 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="logwindow.title" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<Events>
<EventHandler event="windowClosing" listener="java.awt.event.WindowListener" parameters="java.awt.event.WindowEvent" handler="formWindowClosing"/>
</Events>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="jScrollPane2" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="btnTieBa" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnMCBBS" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnMCF" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnGitHub" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="btnTerminateGame" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnCopy" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnClear" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnClose" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="lblCrash" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="lblCrash" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane2" pref="356" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="btnClear" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnClose" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnCopy" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnMCBBS" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnTieBa" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnMCF" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnTerminateGame" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnGitHub" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="btnClear">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="ui.button.clear" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnClearActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnClose">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="ui.button.close" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCloseActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnCopy">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="ui.button.copy" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnCopyActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lblCrash">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="ui.label.crashing" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnMCBBS">
<Properties>
<Property name="text" type="java.lang.String" value="MCBBS"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMCBBSActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnTieBa">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="logwindow.tieba" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnTieBaActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnMCF">
<Properties>
<Property name="text" type="java.lang.String" value="Minecraft Forum"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnMCFActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnTerminateGame">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="logwindow.terminate_game" replaceFormat="C.i18n(&quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnTerminateGameActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnGitHub">
<Properties>
<Property name="text" type="java.lang.String" value="GitHub"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnGitHubActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextPane" name="txtLog">
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@@ -1,324 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.ui;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.logging.Level;
import org.jackhuang.hellominecraft.util.func.NonFunction;
import org.jackhuang.hellominecraft.util.DoubleOutputStream;
import org.jackhuang.hellominecraft.util.LauncherPrintStream;
import org.jackhuang.hellominecraft.util.Utils;
/**
*
* @author huangyuhui
*/
public class LogWindow extends javax.swing.JFrame {
boolean movingEnd;
NonFunction<Boolean> listener;
Runnable terminateGameListener;
/**
* Creates new form LogWindow
*/
public LogWindow() {
initComponents();
movingEnd = true;
setLocationRelativeTo(null);
txtLog.setEditable(false);
DoubleOutputStream out = new DoubleOutputStream(new LogWindowOutputStream(this, Level.INFO), System.out);
System.setOut(new LauncherPrintStream(out));
DoubleOutputStream err = new DoubleOutputStream(new LogWindowOutputStream(this, Level.ERROR), System.err);
System.setErr(new LauncherPrintStream(err));
}
public static final LogWindow INSTANCE = new LogWindow();
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
btnClear = new javax.swing.JButton();
btnClose = new javax.swing.JButton();
btnCopy = new javax.swing.JButton();
lblCrash = new javax.swing.JLabel();
btnMCBBS = new javax.swing.JButton();
btnTieBa = new javax.swing.JButton();
btnMCF = new javax.swing.JButton();
btnTerminateGame = new javax.swing.JButton();
btnGitHub = new javax.swing.JButton();
jScrollPane2 = new javax.swing.JScrollPane();
txtLog = new javax.swing.JTextPane();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle(C.i18n("logwindow.title")); // NOI18N
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
formWindowClosing(evt);
}
});
btnClear.setText(C.i18n("ui.button.clear")); // NOI18N
btnClear.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnClearActionPerformed(evt);
}
});
btnClose.setText(C.i18n("ui.button.close")); // NOI18N
btnClose.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnCloseActionPerformed(evt);
}
});
btnCopy.setText(C.i18n("ui.button.copy")); // NOI18N
btnCopy.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnCopyActionPerformed(evt);
}
});
lblCrash.setText(C.i18n("ui.label.crashing")); // NOI18N
btnMCBBS.setText("MCBBS");
btnMCBBS.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnMCBBSActionPerformed(evt);
}
});
btnTieBa.setText(C.i18n("logwindow.tieba")); // NOI18N
btnTieBa.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnTieBaActionPerformed(evt);
}
});
btnMCF.setText("Minecraft Forum");
btnMCF.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnMCFActionPerformed(evt);
}
});
btnTerminateGame.setText(C.i18n("logwindow.terminate_game")); // NOI18N
btnTerminateGame.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnTerminateGameActionPerformed(evt);
}
});
btnGitHub.setText("GitHub");
btnGitHub.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnGitHubActionPerformed(evt);
}
});
jScrollPane2.setViewportView(txtLog);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jScrollPane2)
.addGroup(layout.createSequentialGroup()
.addComponent(btnTieBa)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnMCBBS)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnMCF)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnGitHub)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnTerminateGame)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCopy)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnClear)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnClose))
.addComponent(lblCrash, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(lblCrash)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 356, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnClear)
.addComponent(btnClose)
.addComponent(btnCopy)
.addComponent(btnMCBBS)
.addComponent(btnTieBa)
.addComponent(btnMCF)
.addComponent(btnTerminateGame)
.addComponent(btnGitHub))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void btnCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCloseActionPerformed
if (listener != null && listener.apply() && terminateGameListener != null)
terminateGameListener.run();
SwingUtils.exitIfNoWindow(this, true);
}//GEN-LAST:event_btnCloseActionPerformed
private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearActionPerformed
this.txtLog.setText("");
}//GEN-LAST:event_btnClearActionPerformed
private void btnCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCopyActionPerformed
Utils.setClipborad(this.txtLog.getText());
}//GEN-LAST:event_btnCopyActionPerformed
private void btnMCBBSActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCBBSActionPerformed
SwingUtils.openLink(C.URL_PUBLISH);
}//GEN-LAST:event_btnMCBBSActionPerformed
private void btnTieBaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTieBaActionPerformed
SwingUtils.openLink(C.URL_TIEBA);
}//GEN-LAST:event_btnTieBaActionPerformed
private void btnMCFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCFActionPerformed
SwingUtils.openLink(C.URL_MINECRAFTFORUM);
}//GEN-LAST:event_btnMCFActionPerformed
private void btnTerminateGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTerminateGameActionPerformed
if (terminateGameListener != null)
terminateGameListener.run();
}//GEN-LAST:event_btnTerminateGameActionPerformed
private void btnGitHubActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGitHubActionPerformed
SwingUtils.openLink(C.URL_GITHUB);
}//GEN-LAST:event_btnGitHubActionPerformed
private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
if (listener != null && listener.apply() && terminateGameListener != null)
terminateGameListener.run();
SwingUtils.exitIfNoWindow(this);
}//GEN-LAST:event_formWindowClosing
public void log(String status) {
log(status, Level.INFO);
}
public void warning(String status) {
log(status, Level.WARN);
}
public synchronized void log(String status, Level c) {
status = status.replace("\t", " ");
Document d = txtLog.getStyledDocument();
SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setForeground(sas, c.COLOR);
try {
d.insertString(d.getLength(), status, sas);
} catch (Exception ex) {
HMCLog.err("Failed to insert \"" + status + "\" to " + d.getLength(), ex);
}
if (movingEnd) {
int position = d.getLength();
txtLog.setCaretPosition(position);
}
}
public void setExit(NonFunction<Boolean> exit) {
this.listener = exit;
}
public void setTerminateGame(Runnable l) {
this.terminateGameListener = l;
}
public void clean() {
txtLog.setText("");
}
public boolean getMovingEnd() {
return movingEnd;
}
public void setMovingEnd(boolean b) {
movingEnd = b;
}
@Override
public void setVisible(boolean b) {
lblCrash.setVisible(false);
btnMCBBS.setVisible(false);
btnTieBa.setVisible(false);
btnMCF.setVisible(false);
super.setVisible(b);
}
public void showAsCrashWindow(boolean out_date) {
if (out_date) {
lblCrash.setVisible(false);
btnMCBBS.setVisible(false);
btnTieBa.setVisible(false);
btnMCF.setVisible(false);
lblCrash.setText(C.i18n("ui.label.crashing_out_dated"));
} else {
lblCrash.setVisible(true);
btnMCBBS.setVisible(true);
btnTieBa.setVisible(true);
btnMCF.setVisible(true);
lblCrash.setText(C.i18n("ui.label.crashing"));
}
super.setVisible(true);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnClear;
private javax.swing.JButton btnClose;
private javax.swing.JButton btnCopy;
private javax.swing.JButton btnGitHub;
private javax.swing.JButton btnMCBBS;
private javax.swing.JButton btnMCF;
private javax.swing.JButton btnTerminateGame;
private javax.swing.JButton btnTieBa;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JLabel lblCrash;
private javax.swing.JTextPane txtLog;
// End of variables declaration//GEN-END:variables
}

View File

@@ -1,69 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.ui;
import java.io.OutputStream;
import java.util.Timer;
import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.util.logging.Level;
/**
*
* @author huangyuhui
*/
public class LogWindowOutputStream extends OutputStream {
private static final Timer TIMER = new Timer();
private final LogWindow txt;
private final Level sas;
public LogWindowOutputStream(LogWindow logWindow, Level l) {
txt = logWindow;
this.sas = l;
}
@Override
public final void write(byte[] paramArrayOfByte) {
write(paramArrayOfByte, 0, paramArrayOfByte.length);
}
@Override
public final void write(byte[] paramArrayOfByte, int off, int len) {
append(new String(paramArrayOfByte, off, len));
}
private void append(final String newString) {
try {
SwingUtilities.invokeLater(() -> {
txt.log(newString, Level.guessLevel(newString, sas));
});
} catch (Throwable e) {
e.printStackTrace();
}
}
@Override
public final void write(int paramInt) {
append(new String(new byte[] { (byte) paramInt }));
}
public static void dispose() {
TIMER.cancel();
}
}

View File

@@ -1,367 +0,0 @@
/*
* Hello Minecraft!.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.util.ui;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Window;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.table.DefaultTableModel;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.logging.HMCLog;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.Utils;
import org.jackhuang.hellominecraft.util.func.NonFunction;
import org.jackhuang.hellominecraft.util.system.OS;
/**
*
* @author huang
*/
public class SwingUtils {
/**
* Make DefaultTableModel by overriding getColumnClass and isCellEditable of
* DefaultTableModel.
*
* @param titleA The title of each column.
* @param typesA The type of each column value.
* @param canEditA Is column editable?
*
* @return
*/
public static DefaultTableModel makeDefaultTableModel(String[] titleA, final Class[] typesA, final boolean[] canEditA) {
return new DefaultTableModel(
new Object[][] {},
titleA) {
Class[] types = typesA;
boolean[] canEdit = canEditA;
@Override
public Class getColumnClass(int columnIndex) {
return types[columnIndex];
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit[columnIndex];
}
};
}
public static void openFolder(File f) {
f.mkdirs();
String path = f.getAbsolutePath();
switch (OS.os()) {
case OSX:
try {
Runtime.getRuntime().exec(new String[] { "/usr/bin/open", path });
} catch (IOException ex) {
HMCLog.err("Failed to open " + path + " through /usr/bin/open", ex);
}
break;
default:
try {
java.awt.Desktop.getDesktop().open(f);
} catch (Throwable ex) {
MessageBox.Show(C.i18n("message.cannot_open_explorer") + ex.getMessage());
HMCLog.warn("Failed to open " + path + " through java.awt.Desktop.getDesktop().open()", ex);
}
break;
}
}
/**
* Open URL by java.awt.Desktop
*
* @param link null is allowed but will be ignored
*/
public static void openLink(String link) {
if (link == null)
return;
try {
java.awt.Desktop.getDesktop().browse(new URI(link));
} catch (Throwable e) {
if (OS.os() == OS.OSX)
try {
Runtime.getRuntime().exec(new String[] { "/usr/bin/open", link });
} catch (IOException ex) {
HMCLog.warn("Failed to open link: " + link, ex);
}
HMCLog.warn("Failed to open link: " + link, e);
}
}
/**
* Move the cursor to the end of TextArea.
*
* @param tf the TextArea
*/
public static void moveEnd(JTextArea tf) {
int position = tf.getText().length();
tf.setCaretPosition(position);
}
/**
* Move the cursor to the end of ScrollPane.
*
* @param pane the ScrollPane
*/
public static void moveEnd(JScrollPane pane) {
JScrollBar bar = pane.getVerticalScrollBar();
bar.setValue(bar.getMaximum());
}
/**
* Get the DefaultListModel from JList.
*
* @param list
*
* @return Forcely Type casted to DefaultListModel
*/
public static DefaultListModel getDefaultListModel(JList list) {
return (DefaultListModel) list.getModel();
}
/**
* Append new element to JList
*
* @param list the JList
* @param element the Element
*/
public static void appendLast(JList list, Object element) {
getDefaultListModel(list).addElement(element);
}
public static void replaceLast(JList list, Object element) {
DefaultListModel model = getDefaultListModel(list);
model.set(model.getSize() - 1, element);
}
public static void clear(JList list) {
list.setModel(new DefaultListModel());
}
/**
* Clear the JTable
*
* @param table JTable with DefaultTableModel.
*
* @return To make the code succinct
*/
public static DefaultTableModel clearDefaultTable(JTable table) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
while (model.getRowCount() > 0)
model.removeRow(0);
return model;
}
public static void appendLast(JTable table, Object... elements) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(elements);
}
public static void setValueAt(JTable table, Object element, int row, int col) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setValueAt(element, row, col);
}
public static Object[] getValueBySelectedRow(JTable table, int rows[], int col) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
Object[] ret = new Object[rows.length];
for (int i = 0; i < rows.length; i++)
ret[i] = model.getValueAt(rows[i], col);
return ret;
}
public static void removeRow(JTable table, int row) {
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.removeRow(row);
}
public static String getParsedJPanelText(JLabel jLabel1, String longString) {
if (StrUtils.isBlank(longString))
return longString;
StringBuilder builder = new StringBuilder();
char[] chars = longString.toCharArray();
FontMetrics fontMetrics = jLabel1.getFontMetrics(jLabel1.getFont());
for (int beginIndex = 0, limit = 1;; limit++) {
if (beginIndex + limit > chars.length)
break;
if (fontMetrics.charsWidth(chars, beginIndex, limit) < jLabel1.getWidth()) {
if (beginIndex + limit < chars.length)
continue;
builder.append(chars, beginIndex, limit);
break;
}
builder.append(chars, beginIndex, limit - 1).append("<br/>");
beginIndex += limit - 1;
limit = 1;
}
return builder.toString();
}
private static final Map<Integer, Object> INVOKE_AND_WAIT_MAP = Collections.synchronizedMap(new HashMap<>());
private static int INVOKE_AND_WAIT_ID = 0;
private static final Object INVOKE_AND_WAIT_LOCK = new Object();
public static <T> T invokeAndWait(NonFunction<T> x) {
int id;
synchronized (INVOKE_AND_WAIT_LOCK) {
id = ++INVOKE_AND_WAIT_ID;
}
int fuck = id;
Runnable r = () -> INVOKE_AND_WAIT_MAP.put(fuck, x.apply());
invokeAndWait(r);
return (T) INVOKE_AND_WAIT_MAP.remove(id);
}
public static void invokeAndWait(Runnable r) {
if (EventQueue.isDispatchThread())
r.run();
else
try {
EventQueue.invokeAndWait(r);
} catch (Exception e) {
HMCLog.err("Failed to invokeAndWait, the UI will work abnormally.", e);
r.run();
}
}
public static int select(String[] selList, String msg) {
Object msgs[] = new Object[2];
msgs[0] = msg;
msgs[1] = new JComboBox(selList);
int result = JOptionPane.showOptionDialog(null, msgs, msg, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
if (result == JOptionPane.CANCEL_OPTION)
return -1;
return ((JComboBox) msgs[1]).getSelectedIndex();
}
public static void setEnabled(JComponent component, boolean t) {
synchronized (component.getTreeLock()) {
for (Component c : component.getComponents())
if (c instanceof JComponent)
setEnabled((JComponent) c, t);
}
component.setEnabled(t);
}
public static void exitIfNoWindow(Window thisFrame) {
exitIfNoWindow(thisFrame, false);
}
public static void exitIfNoWindow(Window thisFrame, boolean neededDispose) {
boolean flag = false;
for (Window f : Window.getWindows()) {
if (f == thisFrame)
continue;
if (f.isVisible())
flag = true;
}
if (!flag)
try {
Utils.shutdownForcely(0);
} catch (Exception e) {
MessageBox.Show(C.i18n("launcher.exit_failed"));
HMCLog.err("Failed to shutdown forcely", e);
}
else
thisFrame.dispose();
}
public static ImageIcon scaleImage(ImageIcon i, int x, int y) {
return new ImageIcon(i.getImage().getScaledInstance(x, y, Image.SCALE_SMOOTH));
}
public static ImageIcon searchBackgroundImage(ImageIcon init, String bgpath, int width, int height) {
Random r = new Random();
boolean loaded = false;
ImageIcon background = init;
// bgpath
if (StrUtils.isNotBlank(bgpath) && !loaded) {
String[] backgroundPath = bgpath.split(";");
if (backgroundPath.length > 0) {
int index = r.nextInt(backgroundPath.length);
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage(backgroundPath[index]).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in bgpath.");
loaded = true;
}
}
// bgskin
if (!loaded) {
File backgroundImageFile = new File("bg");
if (backgroundImageFile.exists() && backgroundImageFile.isDirectory()) {
String[] backgroundPath = backgroundImageFile.list();
if (backgroundPath.length > 0) {
int index = r.nextInt(backgroundPath.length);
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage("bg" + File.separator + backgroundPath[index]).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in bgskin folder.");
loaded = true;
}
}
}
// background.png
if (!loaded) {
File backgroundImageFile = new File("background.png");
if (backgroundImageFile.exists()) {
loaded = true;
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage(backgroundImageFile.getAbsolutePath()).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in background.png.");
}
}
// background.jpg
if (!loaded) {
File backgroundImageFile = new File("background.jpg");
if (backgroundImageFile.exists()) {
//loaded = true;
background = new ImageIcon(Toolkit.getDefaultToolkit().getImage(backgroundImageFile.getAbsolutePath()).getScaledInstance(width, height, Image.SCALE_DEFAULT));
HMCLog.log("Prepared background image in background.jpg.");
}
}
if (background == null)
return init;
return background;
}
}

Some files were not shown because too many files have changed in this diff Show More