Reconstruct codes
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 + "]";
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 + "]";
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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("{key}")"/>
|
||||
</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("{key}")"/>
|
||||
</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("taskwindow.file_name"), C.i18n("taskwindow.download_progress")}, new Class[]{String.class, String.class}, new boolean[]{false,false})
" 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>
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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("{key}")"/>
|
||||
</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("{key}")"/>
|
||||
</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("{key}")"/>
|
||||
</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("{key}")"/>
|
||||
</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("{key}")"/>
|
||||
</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("{key}")"/>
|
||||
</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("{key}")"/>
|
||||
</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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user