HMCL 2.3.2
This commit is contained in:
19
HMCLAPI/build.gradle
Normal file
19
HMCLAPI/build.gradle
Normal file
@@ -0,0 +1,19 @@
|
||||
apply plugin: 'me.tatarka.retrolambda'
|
||||
|
||||
if (!hasProperty('mainClass')) {
|
||||
ext.mainClass = ''
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral();
|
||||
|
||||
dependencies {
|
||||
classpath 'me.tatarka:gradle-retrolambda:3.1.0'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retrolambda {
|
||||
javaVersion = JavaVersion.VERSION_1_7
|
||||
}
|
||||
45
HMCLAPI/src/main/java/org/jackhuang/hellominecraft/C.java
Normal file
45
HMCLAPI/src/main/java/org/jackhuang/hellominecraft/C.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class C {
|
||||
public static final Gson gsonPrettyPrinting = new GsonBuilder().setPrettyPrinting().create();
|
||||
public static final Gson gson = new Gson();
|
||||
|
||||
public static final ResourceBundle I18N = ResourceBundle.getBundle("org/jackhuang/hellominecraft/launcher/I18N");
|
||||
|
||||
//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_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) {
|
||||
try {
|
||||
return String.format(C.I18N.getString(a), format);
|
||||
} catch(Exception e) {
|
||||
HMCLog.warn("Failed to read localization lang: " + a, e);
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft;
|
||||
|
||||
import org.jackhuang.hellominecraft.logging.logger.Logger;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class HMCLog {
|
||||
|
||||
public static Logger logger = new Logger("HMC");
|
||||
|
||||
public static void log(String message) {
|
||||
logger.info(message);
|
||||
}
|
||||
|
||||
public static void warn(String message) {
|
||||
logger.warn(message);
|
||||
}
|
||||
|
||||
public static void warn(String msg, Throwable t) {
|
||||
logger.warn(msg, t);
|
||||
}
|
||||
|
||||
public static void err(String msg) {
|
||||
logger.error(msg);
|
||||
}
|
||||
|
||||
public static void err(String msg, Throwable t) {
|
||||
logger.error(msg, t);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging;
|
||||
|
||||
import org.jackhuang.hellominecraft.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.logging;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.logging.appender.ConsoleAppender;
|
||||
import org.jackhuang.hellominecraft.logging.appender.IAppender;
|
||||
import org.jackhuang.hellominecraft.logging.layout.DefaultLayout;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
|
||||
public class Configuration {
|
||||
|
||||
public ArrayList<IAppender> appenders = new ArrayList<IAppender>();
|
||||
|
||||
public static Configuration DEFAULT;
|
||||
|
||||
static {
|
||||
DEFAULT = new Configuration();
|
||||
DEFAULT.appenders.add(new ConsoleAppender("Console", new DefaultLayout(), true, new ConsoleAppender.SystemOutStream(), true));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public enum Level {
|
||||
|
||||
OFF(0),
|
||||
FATAL(1),
|
||||
ERROR(2),
|
||||
WARN(3),
|
||||
INFO(4),
|
||||
DEBUG(5),
|
||||
TRACE(6),
|
||||
ALL(2147483647);
|
||||
|
||||
public final int level;
|
||||
|
||||
private Level(int i) {
|
||||
level = i;
|
||||
}
|
||||
|
||||
public boolean lessOrEqual(Level level) {
|
||||
return this.level <= level.level;
|
||||
}
|
||||
|
||||
public boolean lessOrEqual(int level) {
|
||||
return this.level <= level;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.logging;
|
||||
|
||||
import org.jackhuang.hellominecraft.logging.message.IMessage;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class LogEvent {
|
||||
|
||||
public Level level;
|
||||
public String threadName;
|
||||
public Throwable thrown;
|
||||
public IMessage message;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.logging;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class LoggingException extends RuntimeException {
|
||||
|
||||
public LoggingException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging.appender;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.jackhuang.hellominecraft.logging.layout.ILayout;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging.appender;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import org.jackhuang.hellominecraft.logging.layout.ILayout;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.logging.appender;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.jackhuang.hellominecraft.logging.LogEvent;
|
||||
import org.jackhuang.hellominecraft.logging.layout.ILayout;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public interface IAppender {
|
||||
|
||||
void append(LogEvent event);
|
||||
String getName();
|
||||
boolean ignoreExceptions();
|
||||
ILayout<? extends Serializable> getLayout();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.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.logging.LogEvent;
|
||||
import org.jackhuang.hellominecraft.logging.LoggingException;
|
||||
import org.jackhuang.hellominecraft.logging.layout.ILayout;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.logging.layout;
|
||||
|
||||
import org.jackhuang.hellominecraft.logging.LogEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract class AbstractStringLayout implements ILayout<String> {
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray(LogEvent event) {
|
||||
return toSerializable(event).getBytes();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.logging.layout;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import org.jackhuang.hellominecraft.logging.LogEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.logging.layout;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.jackhuang.hellominecraft.logging.LogEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
* @param <T>
|
||||
*/
|
||||
public interface ILayout<T extends Serializable> {
|
||||
|
||||
byte[] toByteArray(LogEvent event);
|
||||
T toSerializable(LogEvent event);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,523 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging.logger;
|
||||
|
||||
import org.jackhuang.hellominecraft.logging.Level;
|
||||
import org.jackhuang.hellominecraft.logging.message.IMessage;
|
||||
import org.jackhuang.hellominecraft.logging.message.IMessageFactory;
|
||||
import org.jackhuang.hellominecraft.logging.message.ParameterizedMessageFactory;
|
||||
import org.jackhuang.hellominecraft.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 e) {
|
||||
throw new IllegalStateException(e);
|
||||
} catch (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.logging.logger;
|
||||
|
||||
import org.jackhuang.hellominecraft.logging.Level;
|
||||
import org.jackhuang.hellominecraft.logging.message.IMessage;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging.logger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import org.jackhuang.hellominecraft.logging.AppenderControl;
|
||||
import org.jackhuang.hellominecraft.logging.Configuration;
|
||||
import org.jackhuang.hellominecraft.logging.Level;
|
||||
import org.jackhuang.hellominecraft.logging.LogEvent;
|
||||
import org.jackhuang.hellominecraft.logging.appender.IAppender;
|
||||
import org.jackhuang.hellominecraft.logging.message.IMessage;
|
||||
import org.jackhuang.hellominecraft.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) {
|
||||
super(name, messageFactory);
|
||||
this.config = new PrivateConfig(Configuration.DEFAULT, this, defaultLevel);
|
||||
}
|
||||
|
||||
public synchronized void setLevel(Level level) {
|
||||
if (level != null) {
|
||||
this.config = new PrivateConfig(this.config, level);
|
||||
}
|
||||
}
|
||||
|
||||
public 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.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.logging.Level;
|
||||
import org.jackhuang.hellominecraft.logging.message.IMessage;
|
||||
import org.jackhuang.hellominecraft.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(' ');
|
||||
}
|
||||
|
||||
sb.append(level.toString());
|
||||
sb.append(' ');
|
||||
if ((this.logName != null) && (this.logName.length() > 0)) {
|
||||
sb.append(this.logName);
|
||||
sb.append(' ');
|
||||
}
|
||||
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(' ');
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging.message;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.logging.message;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public interface IMessage extends Serializable {
|
||||
String getFormattedMessage();
|
||||
String getFormat();
|
||||
Object[] getParameters();
|
||||
Throwable getThrowable();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging.message;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract interface IMessageFactory {
|
||||
|
||||
public abstract IMessage newMessage(Object paramObject);
|
||||
|
||||
public abstract IMessage newMessage(String paramString);
|
||||
|
||||
public abstract IMessage newMessage(String paramString, Object[] paramArrayOfObject);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging.message;
|
||||
|
||||
public class ObjectMessage
|
||||
implements IMessage {
|
||||
|
||||
private static final long serialVersionUID = -5903272448334166185L;
|
||||
private 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.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 hyh
|
||||
*/
|
||||
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);
|
||||
if (curChar == ESCAPE_CHAR) {
|
||||
isEscaped = !isEscaped;
|
||||
} else if (curChar == DELIM_START) {
|
||||
if ((!isEscaped)
|
||||
&& (i < messagePattern.length() - 1)
|
||||
&& (messagePattern.charAt(i + 1) == DELIM_STOP)) {
|
||||
result++;
|
||||
i++;
|
||||
}
|
||||
|
||||
isEscaped = false;
|
||||
} else {
|
||||
isEscaped = false;
|
||||
}
|
||||
}
|
||||
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+"]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging.message;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.logging.message;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public interface DoingDoneListener<K> {
|
||||
/**
|
||||
* Task done.
|
||||
* @param k
|
||||
*/
|
||||
void onDone(K k);
|
||||
/**
|
||||
* Before task executing.
|
||||
* @param k
|
||||
*/
|
||||
void onDoing(K k);
|
||||
/**
|
||||
* Task failed.
|
||||
* @param k
|
||||
*/
|
||||
void onFailed(K k);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import org.jackhuang.hellominecraft.tasks.Task;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ParallelTask extends Task {
|
||||
Collection<Task> dependsTask = new HashSet<Task>();
|
||||
|
||||
@Override
|
||||
public boolean executeTask() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "PARALLEL";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task> getDependTasks() {
|
||||
return dependsTask;
|
||||
}
|
||||
|
||||
public void addDependsTask(Task t) {
|
||||
dependsTask.add(t);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract class ProgressProvider {
|
||||
protected ProgressProviderListener ppl;
|
||||
|
||||
public ProgressProvider setProgressProviderListener(ProgressProviderListener p) {
|
||||
ppl = p;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public interface ProgressProviderListener {
|
||||
void setProgress(int prog, int max);
|
||||
void setStatus(String sta);
|
||||
void onProgressProviderDone();
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract class Task extends ProgressProvider {
|
||||
|
||||
/**
|
||||
* Run in a new thread(packed in TaskList).
|
||||
* @return is task finished sucessfully.
|
||||
*/
|
||||
public abstract boolean executeTask();
|
||||
|
||||
/**
|
||||
* if this func returns false, TaskList will force abort the thread.
|
||||
* run in main thread.
|
||||
* @return is aborted.
|
||||
*/
|
||||
public boolean abort() { return false; }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public abstract String getInfo();
|
||||
|
||||
public Collection<Task> getDependTasks() { return null; }
|
||||
public Collection<Task> getAfterTasks() { return null; }
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract class TaskInfo extends Task {
|
||||
|
||||
String info;
|
||||
|
||||
public TaskInfo(String info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.jackhuang.hellominecraft.utils.functions.DoneListener0;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class TaskList extends Thread {
|
||||
|
||||
List<Task> taskQueue = Collections.synchronizedList(new ArrayList());
|
||||
ArrayList<DoneListener0> allDone = new ArrayList();
|
||||
ArrayList<DoingDoneListener<Task>> taskListener = new ArrayList();
|
||||
|
||||
int totTask = 0;
|
||||
boolean shouldContinue = true;
|
||||
|
||||
public TaskList() {
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
shouldContinue = true;
|
||||
totTask = 0;
|
||||
taskQueue.clear();
|
||||
}
|
||||
|
||||
public void addAllDoneListener(DoneListener0 l) {
|
||||
allDone.add(l);
|
||||
}
|
||||
|
||||
public void addTaskListener(DoingDoneListener<Task> l) {
|
||||
taskListener.add(l);
|
||||
}
|
||||
|
||||
public void addTask(Task task) {
|
||||
taskQueue.add(task);
|
||||
totTask++;
|
||||
}
|
||||
|
||||
public int taskCount() {
|
||||
return totTask;
|
||||
}
|
||||
|
||||
private class InvokeThread extends Thread {
|
||||
|
||||
Task task;
|
||||
Set<InvokeThread> s;
|
||||
|
||||
public InvokeThread(Task task, Set<InvokeThread> ss) {
|
||||
this.task = task;
|
||||
s = ss;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
executeTask(task);
|
||||
s.remove(this);
|
||||
threadPool.remove(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final Set<InvokeThread> threadPool = Collections.synchronizedSet(new HashSet<InvokeThread>());
|
||||
static final Set<Task> taskPool = Collections.synchronizedSet(new HashSet<Task>());
|
||||
|
||||
private void processTasks(Collection<Task> c) {
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
this.totTask += c.size();
|
||||
Set<InvokeThread> runningThread = Collections.synchronizedSet(new HashSet<InvokeThread>());
|
||||
for (Task t2 : c) {
|
||||
t2.setParallelExecuting(true);
|
||||
InvokeThread thread = new InvokeThread(t2, runningThread);
|
||||
threadPool.add(thread);
|
||||
runningThread.add(thread);
|
||||
thread.start();
|
||||
}
|
||||
while (!runningThread.isEmpty()) {
|
||||
try {
|
||||
if(this.isInterrupted()) return;
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException ex) {
|
||||
HMCLog.warn("Failed to sleep task thread", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void executeTask(Task t) {
|
||||
if (!shouldContinue || t == null) {
|
||||
return;
|
||||
}
|
||||
processTasks(t.getDependTasks());
|
||||
|
||||
HMCLog.log("Executing task: " + t.getInfo());
|
||||
for (DoingDoneListener<Task> d : taskListener) {
|
||||
d.onDoing(t);
|
||||
}
|
||||
|
||||
if (t.executeTask()) {
|
||||
HMCLog.log("Task finished: " + t.getInfo());
|
||||
for (DoingDoneListener<Task> d : taskListener) {
|
||||
d.onDone(t);
|
||||
}
|
||||
processTasks(t.getAfterTasks());
|
||||
} else {
|
||||
HMCLog.err("Task failed: " + t.getInfo(), t.getFailReason());
|
||||
for (DoingDoneListener<Task> d : taskListener) {
|
||||
d.onFailed(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Thread.currentThread().setName("TaskList");
|
||||
|
||||
threadPool.clear();
|
||||
for (Task taskQueue1 : taskQueue)
|
||||
executeTask(taskQueue1);
|
||||
if (shouldContinue)
|
||||
for (DoneListener0 d : allDone)
|
||||
d.onDone();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return taskQueue.isEmpty();
|
||||
}
|
||||
|
||||
public void abort() {
|
||||
shouldContinue = false;
|
||||
while(!threadPool.isEmpty())
|
||||
synchronized(threadPool) {
|
||||
InvokeThread it = threadPool.iterator().next();
|
||||
if(!it.task.abort()) it.interrupt();
|
||||
threadPool.remove(it);
|
||||
}
|
||||
this.interrupt();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class TaskRunnable extends TaskInfo {
|
||||
private final Runnable r;
|
||||
public TaskRunnable(String info, Runnable r) {
|
||||
super(info);
|
||||
this.r = r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeTask() {
|
||||
try {
|
||||
r.run();
|
||||
return true;
|
||||
} catch(Throwable t) {
|
||||
setFailReason(t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.tasks.communication.PreviousResultRegistrator;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
* @param <T> Runnable<T>
|
||||
*/
|
||||
public class TaskRunnableArg1<T> extends TaskInfo implements PreviousResultRegistrator<T> {
|
||||
private final Consumer<T> r;
|
||||
public TaskRunnableArg1(String info, Consumer<T> r) {
|
||||
super(info);
|
||||
this.r = r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeTask() {
|
||||
if(al.size() != 1) throw new IllegalStateException("the count of args is not one.");
|
||||
try {
|
||||
r.accept(al.get(0).getResult());
|
||||
return true;
|
||||
} catch(Throwable t) {
|
||||
setFailReason(t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<PreviousResult<T>> al = new ArrayList();
|
||||
|
||||
@Override
|
||||
public Task registerPreviousResult(PreviousResult<T> pr) {
|
||||
al.add(pr);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" 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="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{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"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lblSingleProgress" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="349" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="pgsSingle" alignment="0" pref="434" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="lblTotalProgress" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="pgsTotal" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<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" 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="241" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="btnCancel" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="lblSingleProgress" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pgsSingle" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="lblTotalProgress" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pgsTotal" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</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="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{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="pgsSingle">
|
||||
<Properties>
|
||||
<Property name="stringPainted" type="boolean" value="true"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblSingleProgress">
|
||||
<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.single_progress" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblTotalProgress">
|
||||
<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.total_progress" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</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.JList" name="lstDownload">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.utils.functions.DoneListener0;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.SwingUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class TaskWindow extends javax.swing.JDialog
|
||||
implements ProgressProviderListener, DoneListener0, DoingDoneListener<Task> {
|
||||
|
||||
private static final TaskWindow instance = new TaskWindow();
|
||||
|
||||
public static TaskWindow getInstance() {
|
||||
instance.clean();
|
||||
return instance;
|
||||
}
|
||||
|
||||
boolean suc = false;
|
||||
|
||||
private TaskList taskList;
|
||||
private final ArrayList<String> failReasons = new ArrayList();
|
||||
|
||||
/**
|
||||
* Creates new form DownloadWindow
|
||||
*/
|
||||
private TaskWindow() {
|
||||
initComponents();
|
||||
|
||||
setLocationRelativeTo(null);
|
||||
|
||||
setModal(true);
|
||||
}
|
||||
|
||||
public TaskWindow addTask(Task task) {
|
||||
taskList.addTask(task);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void clean() {
|
||||
taskList = null;
|
||||
taskList = new TaskList();
|
||||
taskList.addTaskListener(this);
|
||||
taskList.addAllDoneListener(this);
|
||||
}
|
||||
|
||||
public boolean start() {
|
||||
if (taskList.isAlive()) return false;
|
||||
pgsSingle.setValue(0);
|
||||
pgsTotal.setValue(0);
|
||||
suc = false;
|
||||
SwingUtils.clear(lstDownload);
|
||||
failReasons.clear();
|
||||
try {
|
||||
taskList.start();
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to start thread, maybe there're already a taskwindow here.", e);
|
||||
MessageBox.Show(C.i18n("taskwindow.no_more_instance"));
|
||||
return false;
|
||||
}
|
||||
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();
|
||||
pgsSingle = new javax.swing.JProgressBar();
|
||||
lblSingleProgress = new javax.swing.JLabel();
|
||||
lblTotalProgress = new javax.swing.JLabel();
|
||||
pgsTotal = new javax.swing.JProgressBar();
|
||||
srlDownload = new javax.swing.JScrollPane();
|
||||
lstDownload = new javax.swing.JList();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/jackhuang/hellominecraft/launcher/I18N"); // NOI18N
|
||||
setTitle(bundle.getString("taskwindow.title")); // NOI18N
|
||||
addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
public void windowClosed(java.awt.event.WindowEvent evt) {
|
||||
formWindowClosed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnCancel.setText(bundle.getString("taskwindow.cancel")); // NOI18N
|
||||
btnCancel.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnCancelActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
pgsSingle.setStringPainted(true);
|
||||
|
||||
lblSingleProgress.setText(bundle.getString("taskwindow.single_progress")); // NOI18N
|
||||
|
||||
lblTotalProgress.setText(bundle.getString("taskwindow.total_progress")); // NOI18N
|
||||
|
||||
pgsTotal.setStringPainted(true);
|
||||
|
||||
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()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblSingleProgress)
|
||||
.addGap(349, 349, 349))
|
||||
.addComponent(pgsSingle, javax.swing.GroupLayout.DEFAULT_SIZE, 434, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(lblTotalProgress)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.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)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(srlDownload, javax.swing.GroupLayout.DEFAULT_SIZE, 241, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(btnCancel, javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(lblSingleProgress)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pgsSingle, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(lblTotalProgress)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pgsTotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, 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_OPTION) == MessageBox.YES_OPTION)
|
||||
this.dispose();
|
||||
}//GEN-LAST:event_btnCancelActionPerformed
|
||||
|
||||
private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
|
||||
if (!this.failReasons.isEmpty()) {
|
||||
MessageBox.Show(StrUtils.parseParams("", failReasons.toArray(), "\n"), C.i18n("message.error"), MessageBox.ERROR_MESSAGE);
|
||||
failReasons.clear();
|
||||
}
|
||||
|
||||
if (!suc) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
taskList.abort();
|
||||
}
|
||||
});
|
||||
HMCLog.log("Tasks have been canceled by user.");
|
||||
}
|
||||
}//GEN-LAST:event_formWindowClosed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnCancel;
|
||||
private javax.swing.JLabel lblSingleProgress;
|
||||
private javax.swing.JLabel lblTotalProgress;
|
||||
private javax.swing.JList lstDownload;
|
||||
private javax.swing.JProgressBar pgsSingle;
|
||||
private javax.swing.JProgressBar pgsTotal;
|
||||
private javax.swing.JScrollPane srlDownload;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
@Override
|
||||
public void setProgress(int progress, int max) {
|
||||
pgsSingle.setMaximum(max);
|
||||
pgsSingle.setValue(progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDone() {
|
||||
suc = true;
|
||||
this.dispose();
|
||||
HMCLog.log("Tasks are finished.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDoing(Task task) {
|
||||
if (!task.isParallelExecuting())
|
||||
task.setProgressProviderListener(this);
|
||||
|
||||
SwingUtils.appendLast(lstDownload, task.getInfo());
|
||||
SwingUtils.moveEnd(srlDownload);
|
||||
}
|
||||
|
||||
public boolean areTasksFinished() {
|
||||
return suc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDone(Task task) {
|
||||
pgsTotal.setMaximum(taskList.taskCount());
|
||||
pgsTotal.setValue(pgsTotal.getValue() + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailed(Task task) {
|
||||
failReasons.add(task.getInfo() + ": " + (task.getFailReason() == null ? "No exception" : task.getFailReason().getLocalizedMessage()));
|
||||
pgsTotal.setMaximum(taskList.taskCount());
|
||||
pgsTotal.setValue(pgsTotal.getValue() + 1);
|
||||
SwingUtils.replaceLast(lstDownload, task.getFailReason());
|
||||
SwingUtils.moveEnd(srlDownload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressProviderDone() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(String sta) {
|
||||
SwingUtils.replaceLast(lstDownload, sta);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks.communication;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class DefaultPreviousResult<T> implements PreviousResult<T>{
|
||||
T a;
|
||||
|
||||
public DefaultPreviousResult(T a) {
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getResult() {
|
||||
return a;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks.communication;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
* @param <T> Task result type
|
||||
*/
|
||||
public interface PreviousResult<T> {
|
||||
|
||||
T getResult();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks.communication;
|
||||
|
||||
import org.jackhuang.hellominecraft.tasks.Task;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
* @param <T> Previous task result type
|
||||
*/
|
||||
public interface PreviousResultRegistrator<T> {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param pr previous task handler
|
||||
* @return task self instance
|
||||
*/
|
||||
Task registerPreviousResult(PreviousResult<T> pr);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import org.jackhuang.hellominecraft.utils.Event;
|
||||
import org.jackhuang.hellominecraft.views.LogWindow;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ContentGetAndShowTask extends HTTPGetTask implements Event<String> {
|
||||
|
||||
public ContentGetAndShowTask(String info, String changeLogUrl) {
|
||||
super(changeLogUrl);
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeTask() {
|
||||
tdtsl.register(this);
|
||||
return 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.tasks.ProgressProviderListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public interface DownloadListener extends ProgressProviderListener {
|
||||
|
||||
boolean OnFailed();
|
||||
void OnFailedMoreThan5Times(String url);
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks.download;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.tasks.communication.PreviousResultRegistrator;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
// This class downloads a file from a URL.
|
||||
public class FileDownloadTask extends Task implements PreviousResult<File>, PreviousResultRegistrator<String> {
|
||||
|
||||
private static final X509TrustManager xtm = new X509TrustManager() {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
private static final HostnameVerifier hnv = new HostnameVerifier() {
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static {
|
||||
SSLContext sslContext = null;
|
||||
|
||||
try {
|
||||
sslContext = SSLContext.getInstance("TLS");
|
||||
X509TrustManager[] xtmArray = new X509TrustManager[]{xtm};
|
||||
sslContext.init(null, xtmArray, new java.security.SecureRandom());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
}
|
||||
if (sslContext != null) {
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
||||
}
|
||||
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(hnv);
|
||||
}
|
||||
|
||||
// Max size of download buffer.
|
||||
private static final int MAX_BUFFER_SIZE = 2048;
|
||||
|
||||
private URL url; // download URL
|
||||
private int size; // size of download in bytes
|
||||
private int downloaded; // number of bytes downloaded
|
||||
private final File filePath;
|
||||
|
||||
public FileDownloadTask(File filePath) {
|
||||
this((URL) null, filePath);
|
||||
}
|
||||
|
||||
public FileDownloadTask(String url, File filePath) {
|
||||
this(IOUtils.parseURL(url), filePath);
|
||||
}
|
||||
|
||||
// Constructor for Download.
|
||||
public FileDownloadTask(URL url, File filePath) {
|
||||
this.url = url;
|
||||
size = -1;
|
||||
downloaded = 0;
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
// Get this download's URL.
|
||||
public String getUrl() {
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
RandomAccessFile file = null;
|
||||
InputStream stream = null;
|
||||
boolean shouldContinue = true, aborted = false;
|
||||
|
||||
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 boolean executeTask() {
|
||||
for (PreviousResult<String> p : al) {
|
||||
this.url = IOUtils.parseURL(p.getResult());
|
||||
}
|
||||
|
||||
for (int repeat = 0; repeat < 6; repeat++) {
|
||||
if (repeat > 0) {
|
||||
HMCLog.warn("Failed to download, repeat: " + repeat);
|
||||
}
|
||||
try {
|
||||
|
||||
// Open connection to URL.
|
||||
HttpURLConnection connection
|
||||
= (HttpURLConnection) url.openConnection();
|
||||
|
||||
connection.setConnectTimeout(5000);
|
||||
connection.setRequestProperty("User-Agent", "Hello Minecraft! Launcher");
|
||||
|
||||
// Connect to server.
|
||||
connection.connect();
|
||||
|
||||
// Make sure response code is in the 200 range.
|
||||
if (connection.getResponseCode() / 100 != 2) {
|
||||
setFailReason(new NetException(C.i18n("download.not_200") + " " + connection.getResponseCode()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for valid content length.
|
||||
int contentLength = connection.getContentLength();
|
||||
if (contentLength < 1) {
|
||||
setFailReason(new NetException("The content length is invalid."));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the size for this download if it hasn't been already set.
|
||||
if (size == -1) {
|
||||
size = contentLength;
|
||||
}
|
||||
|
||||
filePath.getParentFile().mkdirs();
|
||||
|
||||
File tempFile = new File(filePath.getAbsolutePath() + ".hmd");
|
||||
if (!tempFile.exists()) {
|
||||
tempFile.createNewFile();
|
||||
}
|
||||
|
||||
// Open file and seek to the end of it.
|
||||
file = new RandomAccessFile(tempFile, "rw");
|
||||
file.seek(downloaded);
|
||||
|
||||
stream = connection.getInputStream();
|
||||
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;
|
||||
}
|
||||
|
||||
// Write buffer to file.
|
||||
file.write(buffer, 0, read);
|
||||
downloaded += read;
|
||||
|
||||
if (ppl != null) {
|
||||
ppl.setProgress(downloaded, size);
|
||||
}
|
||||
}
|
||||
closeFiles();
|
||||
tempFile.renameTo(filePath);
|
||||
if (ppl != null) {
|
||||
ppl.onProgressProviderDone();
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
setFailReason(new NetException(C.i18n("download.failed") + " " + url, e));
|
||||
} finally {
|
||||
closeFiles();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void download(String url, String file, DownloadListener dl) {
|
||||
((Task) new FileDownloadTask(url, new File(file)).setProgressProviderListener(dl)).executeTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean abort() {
|
||||
shouldContinue = false;
|
||||
aborted = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("download") + ": " + url + " " + filePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getResult() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
ArrayList<PreviousResult<String>> al = new ArrayList();
|
||||
|
||||
@Override
|
||||
public Task registerPreviousResult(PreviousResult<String> pr) {
|
||||
al.add(pr);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks.download;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.tasks.TaskInfo;
|
||||
import org.jackhuang.hellominecraft.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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 boolean executeTask() {
|
||||
for (int repeat = 0; repeat < 6; repeat++) {
|
||||
if (repeat > 0) HMCLog.warn("Failed to download, repeat: " + repeat);
|
||||
try {
|
||||
URLConnection conn = new URL(url).openConnection();
|
||||
InputStream is = conn.getInputStream();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
int i;
|
||||
int size = conn.getContentLength(), read = 0;
|
||||
while ((i = is.read()) != -1) {
|
||||
baos.write(i);
|
||||
if (ppl != null) {
|
||||
ppl.setProgress(++read, size);
|
||||
}
|
||||
if (!shouldContinue) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
result = baos.toString();
|
||||
tdtsl.execute(result);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
setFailReason(new NetException("Failed to get " + url, ex));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean abort() {
|
||||
shouldContinue = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return super.getInfo() != null ? super.getInfo() : "Get: " + url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.tasks.download;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class NetException extends RuntimeException {
|
||||
|
||||
public NetException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NetException(String message, Exception e) {
|
||||
super(message, e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class BaseLauncherProfile {
|
||||
public static String profile = "{\"selectedProfile\": \"(Default)\",\"profiles\": {\"(Default)\": {\"name\": \"(Default)\"}},\"clientToken\": \"88888888-8888-8888-8888-888888888888\"}";
|
||||
public static void tryWriteProfile(File gameDir) throws IOException {
|
||||
File file = new File(gameDir, "launcher_profiles.json");
|
||||
if(!file.exists())
|
||||
FileUtils.writeStringToFile(file, profile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Bytes {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
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.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* 文件压缩/解压类
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Compressor {
|
||||
|
||||
public static void zip(String sourceDir, String zipFile) throws IOException {
|
||||
zip(new File(sourceDir), new File(zipFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能:把 sourceDir 目录下的所有文件进行 zip 格式的压缩,保存为指定 zip 文件
|
||||
*
|
||||
* @param sourceDir
|
||||
* @param zipFile
|
||||
*/
|
||||
public static void zip(File sourceDir, File zipFile) throws IOException {
|
||||
FileOutputStream os;
|
||||
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);
|
||||
zos.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文件压缩成zip文件
|
||||
*
|
||||
* @param source zip文件路径
|
||||
* @param basePath 待压缩文件根目录
|
||||
* @param zos
|
||||
*/
|
||||
private static void zipFile(File source, String basePath,
|
||||
ZipOutputStream zos) 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 (file.getName().toLowerCase().contains("meta-inf")) {
|
||||
continue;
|
||||
}
|
||||
zos.putNextEntry(new ZipEntry(pathName));
|
||||
zipFile(file, basePath, zos);
|
||||
} else {
|
||||
pathName = file.getPath().substring(basePath.length() + 1);
|
||||
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, new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将文件压缩成zip文件
|
||||
*
|
||||
* @param zipFileName zip文件路径
|
||||
* @param extPlace 待压缩文件根目录
|
||||
* @param without 带前缀的不解压
|
||||
*/
|
||||
public static void unzip(File zipFileName, File extPlace, String[] without) throws IOException {
|
||||
extPlace.mkdirs();
|
||||
try (ZipFile zipFile = new ZipFile(zipFileName)) {
|
||||
if (zipFileName.exists()) {
|
||||
String strPath, gbkPath, strtemp;
|
||||
strPath = extPlace.getAbsolutePath();
|
||||
java.util.Enumeration e = zipFile.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry zipEnt = (ZipEntry) e.nextElement();
|
||||
gbkPath = zipEnt.getName();
|
||||
if(StrUtils.startsWithOne(without, gbkPath)) continue;
|
||||
if (zipEnt.isDirectory()) {
|
||||
strtemp = strPath + File.separator + gbkPath;
|
||||
File dir = new File(strtemp);
|
||||
dir.mkdirs();
|
||||
} else {
|
||||
//读写文件
|
||||
InputStream is = zipFile.getInputStream(zipEnt);
|
||||
BufferedInputStream bis = new BufferedInputStream(is);
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
try (FileOutputStream fos = new FileOutputStream(strtemp); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
|
||||
int c;
|
||||
while ((c = bis.read()) != -1)
|
||||
bos.write((byte) c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将zip1合并到zip2里面,即保留zip2
|
||||
*
|
||||
* @param destFile zip1
|
||||
* @param srcFile zip2
|
||||
*/
|
||||
public static void merge(File destFile, File srcFile) throws IOException {
|
||||
try (ZipOutputStream os = new ZipOutputStream(new FileOutputStream(destFile))) {
|
||||
if (destFile.exists()) {
|
||||
File extPlace = new File(IOUtils.currentDir(), "HMCL-MERGE-TEMP");
|
||||
unzip(srcFile, extPlace);
|
||||
ZipFile zipFile = new ZipFile(srcFile);
|
||||
if (srcFile.exists()) {
|
||||
String gbkPath;//, strtemp, strPath;
|
||||
//strPath = extPlace.getAbsolutePath();
|
||||
java.util.Enumeration e = zipFile.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry zipEnt = (ZipEntry) e.nextElement();
|
||||
//gbkPath = zipEnt.getName();
|
||||
if (zipEnt.isDirectory()) {
|
||||
//strtemp = strPath + File.separator + gbkPath;
|
||||
} else {
|
||||
gbkPath = zipEnt.getName();
|
||||
//strtemp = strPath + File.separator + gbkPath;
|
||||
os.putNextEntry(zipEnt);
|
||||
os.write(gbkPath.getBytes("UTF-8"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
os.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
* @param <T> EventArgs
|
||||
*/
|
||||
public interface Event<T> {
|
||||
boolean call(Object sender, T t);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
* @param <T> EventArgs
|
||||
*/
|
||||
public class EventHandler<T> {
|
||||
HashSet<Event<T>> handlers;
|
||||
Object sender;
|
||||
|
||||
public EventHandler(Object sender) {
|
||||
handlers = new HashSet<>();
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public void register(Event<T> t) {
|
||||
handlers.add(t);
|
||||
}
|
||||
|
||||
public void unregister(Event<T> t) {
|
||||
handlers.remove(t);
|
||||
}
|
||||
|
||||
public boolean execute(T x) {
|
||||
boolean flag = true;
|
||||
for(Event<T> t : handlers)
|
||||
if(!t.call(sender, x)) flag = false;
|
||||
return flag;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
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.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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()) {
|
||||
//String message = directory + " does not exist";
|
||||
//throw new IllegalArgumentException(message);
|
||||
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, true);
|
||||
}
|
||||
|
||||
public static void copyDirectory(File srcDir, File destDir, boolean preserveFileDate)
|
||||
throws IOException {
|
||||
copyDirectory(srcDir, destDir, null, preserveFileDate);
|
||||
}
|
||||
|
||||
public static void copyDirectory(File srcDir, File destDir, FileFilter filter)
|
||||
throws IOException {
|
||||
copyDirectory(srcDir, destDir, filter, true);
|
||||
}
|
||||
|
||||
public static void copyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate)
|
||||
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, preserveFileDate, exclusionList);
|
||||
}
|
||||
|
||||
private static void doCopyDirectory(File srcDir, File destDir, FileFilter filter, boolean preserveFileDate, 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, preserveFileDate, exclusionList);
|
||||
} else {
|
||||
doCopyFile(srcFile, dstFile, preserveFileDate);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (preserveFileDate) {
|
||||
destDir.setLastModified(srcDir.lastModified());
|
||||
}
|
||||
}
|
||||
|
||||
public static String readFileToString(File file)
|
||||
throws IOException {
|
||||
return NetUtils.getStreamContent(IOUtils.openInputStream(file));
|
||||
}
|
||||
|
||||
public static String readFileToStringQuietly(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 readFileToString(File file, String charset)
|
||||
throws IOException {
|
||||
return NetUtils.getStreamContent(IOUtils.openInputStream(file), charset);
|
||||
}
|
||||
|
||||
public static String readFileToStringIgnoreFileNotFound(File file) throws IOException {
|
||||
try {
|
||||
return NetUtils.getStreamContent(IOUtils.openInputStream(file));
|
||||
} catch (FileNotFoundException ex) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyFile(File srcFile, File destFile)
|
||||
throws IOException {
|
||||
copyFile(srcFile, destFile, true);
|
||||
}
|
||||
|
||||
public static void copyFile(File srcFile, File destFile, boolean preserveFileDate)
|
||||
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, preserveFileDate);
|
||||
}
|
||||
|
||||
private static void doCopyFile(File srcFile, File destFile, boolean preserveFileDate)
|
||||
throws IOException {
|
||||
if ((destFile.exists()) && (destFile.isDirectory())) {
|
||||
throw new IOException("Destination '" + destFile + "' exists but is a directory");
|
||||
}
|
||||
|
||||
FileInputStream fis = null;
|
||||
FileOutputStream fos = null;
|
||||
FileChannel input = null;
|
||||
FileChannel output = null;
|
||||
try {
|
||||
fis = new FileInputStream(srcFile);
|
||||
fos = new FileOutputStream(destFile);
|
||||
input = fis.getChannel();
|
||||
output = fos.getChannel();
|
||||
long size = input.size();
|
||||
long pos = 0L;
|
||||
long count;
|
||||
while (pos < size) {
|
||||
count = size - pos > 31457280L ? 31457280L : size - pos;
|
||||
pos += output.transferFrom(input, pos, count);
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(output);
|
||||
IOUtils.closeQuietly(fos);
|
||||
IOUtils.closeQuietly(input);
|
||||
IOUtils.closeQuietly(fis);
|
||||
}
|
||||
|
||||
if (srcFile.length() != destFile.length()) {
|
||||
throw new IOException("Failed to copy full contents from '" + srcFile + "' to '" + destFile + "'");
|
||||
}
|
||||
|
||||
if (preserveFileDate) {
|
||||
destFile.setLastModified(srcFile.lastModified());
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 void writeQuietly(File file, CharSequence data) {
|
||||
try {
|
||||
write(file, data);
|
||||
} catch(IOException e) {
|
||||
HMCLog.warn("Failed to write data to file: " + file, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void write(File file, CharSequence data)
|
||||
throws IOException {
|
||||
write(file, data, "UTF-8", false);
|
||||
}
|
||||
|
||||
public static void write(File file, CharSequence data, boolean append)
|
||||
throws IOException {
|
||||
write(file, data, "UTF-8", append);
|
||||
}
|
||||
|
||||
public static void write(File file, CharSequence data, String encoding)
|
||||
throws IOException {
|
||||
write(file, data, encoding, false);
|
||||
}
|
||||
|
||||
public static void write(File file, CharSequence data, String encoding, boolean append)
|
||||
throws IOException {
|
||||
String str = data == null ? null : data.toString();
|
||||
writeStringToFile(file, str, encoding, append);
|
||||
}
|
||||
|
||||
public static void writeStringToFile(File file, String data)
|
||||
throws IOException {
|
||||
writeStringToFile(file, data, "UTF-8", false);
|
||||
}
|
||||
|
||||
public static void writeStringToFile(File file, String data, String encoding)
|
||||
throws IOException {
|
||||
writeStringToFile(file, data, encoding, false);
|
||||
}
|
||||
|
||||
public static void writeStringToFile(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();
|
||||
for(File f : files)
|
||||
if(f.getName().endsWith(suffix)) al.add(f);
|
||||
return al.toArray(new File[0]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
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) throws Exception {
|
||||
int digit = Character.digit(ch, 16);
|
||||
if (digit == -1) {
|
||||
throw new Exception("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 + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
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.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
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 org.jackhuang.hellominecraft.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 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 ArrayList<String> findAllFile(File f) {
|
||||
ArrayList<String> arr = new ArrayList<>();
|
||||
if (f.isDirectory()) {
|
||||
File[] f1 = f.listFiles();
|
||||
int len = f1.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (f1[i].isFile()) {
|
||||
arr.add(f1[i].getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static ArrayList<String> findAllFileWithFullName(File f) {
|
||||
ArrayList<String> arr = new ArrayList<>();
|
||||
if (f.isDirectory()) {
|
||||
File[] f1 = f.listFiles();
|
||||
int len = f1.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (f1[i].isFile()) {
|
||||
arr.add(addSeparator(f.getAbsolutePath()) + f1[i].getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static ArrayList<String> findAllDir(File f) {
|
||||
ArrayList<String> arr = new ArrayList<>();
|
||||
if (f.isDirectory()) {
|
||||
File[] f1 = f.listFiles();
|
||||
int len = f1.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (f1[i].isDirectory()) {
|
||||
arr.add(f1[i].getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
public static File currentDir() {
|
||||
return new File(".");
|
||||
}
|
||||
|
||||
public static String currentDirWithSeparator() {
|
||||
return addSeparator(currentDir().getAbsolutePath());
|
||||
}
|
||||
|
||||
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() {
|
||||
String path = System.getProperty("java.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 byte[] 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.toByteArray();
|
||||
}
|
||||
|
||||
public static void closeQuietly(Reader input) {
|
||||
closeQuietly((Closeable) input);
|
||||
}
|
||||
|
||||
public static void closeQuietly(Writer output) {
|
||||
closeQuietly((Closeable) output);
|
||||
}
|
||||
|
||||
public static void closeQuietly(InputStream input) {
|
||||
closeQuietly((Closeable) input);
|
||||
}
|
||||
|
||||
public static void closeQuietly(OutputStream output) {
|
||||
closeQuietly((Closeable) output);
|
||||
}
|
||||
|
||||
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 ex) {
|
||||
return IOUtils.addSeparator(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
public static File tryGetCanonicalFile(File file) {
|
||||
try {
|
||||
return file.getCanonicalFile();
|
||||
} catch (IOException ex) {
|
||||
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 ex) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class JavaProcess {
|
||||
|
||||
private final List<String> commands;
|
||||
private final Process process;
|
||||
private final ArrayList<String> stdOutLines = new ArrayList<>();
|
||||
private final ArrayList<String> stdErrLines = 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 ArrayList<String> getStdErrLines() {
|
||||
return this.stdErrLines;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class JdkVersion {
|
||||
|
||||
public String ver;
|
||||
/**
|
||||
* -1 - unkown 0 - 32Bit 1 - 64Bit
|
||||
*/
|
||||
public int is64Bit;
|
||||
|
||||
public JdkVersion(String ver, int is64Bit) {
|
||||
this.ver = ver;
|
||||
this.is64Bit = is64Bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant identifying the 1.5 JVM (Java 5).
|
||||
*/
|
||||
public static final int UNKOWN = 2;
|
||||
/**
|
||||
* Constant identifying the 1.5 JVM (Java 5).
|
||||
*/
|
||||
public static final int JAVA_15 = 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 javaVersion;
|
||||
private static final int majorJavaVersion;
|
||||
|
||||
static {
|
||||
javaVersion = System.getProperty("java.version");
|
||||
// version String should look like "1.4.2_10"
|
||||
if (javaVersion.contains("1.9.")) {
|
||||
majorJavaVersion = JAVA_18;
|
||||
} else if (javaVersion.contains("1.8.")) {
|
||||
majorJavaVersion = JAVA_18;
|
||||
} else if (javaVersion.contains("1.7.")) {
|
||||
majorJavaVersion = JAVA_17;
|
||||
} else if (javaVersion.contains("1.6.")) {
|
||||
majorJavaVersion = JAVA_16;
|
||||
} else {
|
||||
// else leave 1.5 as default (it's either 1.5 or unknown)
|
||||
majorJavaVersion = JAVA_15;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 javaVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 majorJavaVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to determine if the current JVM is at least Java 1.6
|
||||
* (Java 6).
|
||||
*
|
||||
* @return <code>true</code> if the current JVM is at least Java 1.6
|
||||
* @deprecated as of Spring 3.0, in favor of reflective checks for the
|
||||
* specific Java 1.6 classes of interest
|
||||
* @see #getMajorJavaVersion()
|
||||
* @see #JAVA_16
|
||||
* @see #JAVA_17
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isAtLeastJava16() {
|
||||
return (majorJavaVersion >= JAVA_16);
|
||||
}
|
||||
|
||||
public static boolean isJava64Bit() {
|
||||
String jdkBit = System.getProperty("sun.arch.data.model");
|
||||
return jdkBit.contains("64");
|
||||
}
|
||||
|
||||
static 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"};
|
||||
ProcessBuilder pb = new ProcessBuilder(str);
|
||||
JavaProcess jp = new JavaProcess(str, pb.start(), null);
|
||||
InputStream is = jp.getRawProcess().getErrorStream();
|
||||
BufferedReader br = null;
|
||||
int lineNumber = 0;
|
||||
String ver = null;
|
||||
int is64Bit = -1;
|
||||
try {
|
||||
br = new BufferedReader(new InputStreamReader(is));
|
||||
String line;
|
||||
jp.getRawProcess().waitFor();
|
||||
while ((line = br.readLine()) != null) {
|
||||
lineNumber++;
|
||||
switch (lineNumber) {
|
||||
case 1:
|
||||
Matcher m = p.matcher(line);
|
||||
if (m.find()) {
|
||||
ver = m.group();
|
||||
ver = ver.substring("java version \"".length(), ver.length() - 1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (line.contains("64-Bit")) {
|
||||
is64Bit = 1;
|
||||
} else {
|
||||
is64Bit = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException | IOException e) {
|
||||
HMCLog.warn("Failed to get java version", e);
|
||||
} finally {
|
||||
if (br != null) {
|
||||
br.close();
|
||||
}
|
||||
}
|
||||
return new JdkVersion(ver, is64Bit);
|
||||
}
|
||||
|
||||
public void write(File f) throws IOException {
|
||||
if (ver != null && is64Bit != -1) {
|
||||
FileUtils.write(f, ver + "\n" + is64Bit);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEarlyAccess() {
|
||||
return ver != null && ver.endsWith("-ea");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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 void addPrintListener(Consumer<String> paraml) {
|
||||
this.printListeners.add(paraml);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class MD5Utils {
|
||||
|
||||
private static final char e[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'a', 'b', 'c', 'd', 'e', 'f'
|
||||
};
|
||||
|
||||
public static String hash(String type, String source) {
|
||||
try {
|
||||
StringBuilder stringbuilder;
|
||||
MessageDigest md = MessageDigest.getInstance(type);
|
||||
md.update(source.getBytes());
|
||||
byte[] bytes = md.digest();
|
||||
int s2 = bytes.length;
|
||||
stringbuilder = new StringBuilder(s2 << 1);
|
||||
for (int i1 = 0; i1 < s2; i1++) {
|
||||
stringbuilder.append(e[bytes[i1] >> 4 & 0xf]);
|
||||
stringbuilder.append(e[bytes[i1] & 0xf]);
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
HMCLog.err("Failed to get md5", e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
|
||||
/**
|
||||
* @author hyh
|
||||
*/
|
||||
public class MessageBox
|
||||
{
|
||||
private static 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 JOptionPane.showConfirmDialog(null, Msg, Title, Option - 10);
|
||||
default:
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
|
||||
/**
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftVersionRequest {
|
||||
public static final int Unkown = 0, Invaild = 1, InvaildJar = 2,
|
||||
Modified = 3, OK = 4, NotFound = 5, NotReadable = 6, NotAFile = 7;
|
||||
public int type;
|
||||
public String version;
|
||||
|
||||
public static String getResponse(MinecraftVersionRequest minecraftVersion) {
|
||||
String text = "";
|
||||
switch (minecraftVersion.type) {
|
||||
case MinecraftVersionRequest.Invaild:
|
||||
text = C.i18n("minecraft.invalid");
|
||||
break;
|
||||
case MinecraftVersionRequest.InvaildJar:
|
||||
text = C.i18n("minecraft.invalid_jar");
|
||||
break;
|
||||
case MinecraftVersionRequest.NotAFile:
|
||||
text = C.i18n("minecraft.not_a_file");
|
||||
break;
|
||||
case MinecraftVersionRequest.NotFound:
|
||||
text = C.i18n("minecraft.not_found");
|
||||
break;
|
||||
case MinecraftVersionRequest.NotReadable:
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @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 {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is, encoding));
|
||||
String result = "";
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
result += line + "\n";
|
||||
}
|
||||
br.close();
|
||||
if(result.length() < 1) return "";
|
||||
else return result.substring(0, result.length() - 1);
|
||||
}
|
||||
|
||||
public static String doGet(String url, String encoding) throws IOException {
|
||||
return getStreamContent(new URL(url).openConnection().getInputStream());
|
||||
}
|
||||
|
||||
public static String doGet(String url) throws IOException {
|
||||
return doGet(url, DEFAULT_CHARSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an HTTP GET request to a url
|
||||
*
|
||||
* @param endpoint - The URL of the server. (Example: "
|
||||
* http://www.yahoo.com/search")
|
||||
* @param requestParameters - all the request parameters (Example:
|
||||
* "param1=val1¶m2=val2"). Note: This method will add the question mark
|
||||
* (?) to the request - DO NOT add it yourself
|
||||
* @return - The response from the end point
|
||||
*/
|
||||
public static String sendGetRequest(String endpoint,
|
||||
String requestParameters) {
|
||||
String result = null;
|
||||
if (endpoint.startsWith("http://")) {
|
||||
// Send a GET request to the servlet
|
||||
try {
|
||||
// Construct data
|
||||
StringBuilder data = new StringBuilder();
|
||||
// Send data
|
||||
String urlStr = endpoint;
|
||||
if (requestParameters != null && requestParameters.length() > 0) {
|
||||
urlStr += "?" + requestParameters;
|
||||
}
|
||||
URL url = new URL(urlStr);
|
||||
URLConnection conn = url.openConnection();
|
||||
|
||||
// Get the response
|
||||
InputStreamReader r = new InputStreamReader(conn.getInputStream());
|
||||
StringBuffer sb;
|
||||
BufferedReader rd = new BufferedReader(r);
|
||||
sb = new StringBuffer();
|
||||
String line;
|
||||
while ((line = rd.readLine()) != null)
|
||||
sb.append(line);
|
||||
result = sb.toString();
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to send get request.", e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String post(String url, Map<String, String> params) {
|
||||
URL u = null;
|
||||
HttpURLConnection con = null;
|
||||
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 = new StringBuilder(sb.substring(0, sb.length() - 1));
|
||||
}
|
||||
System.out.println("send_url:" + url);
|
||||
System.out.println("send_data:" + sb.toString());
|
||||
try {
|
||||
u = new URL(url);
|
||||
con = (HttpURLConnection) u.openConnection();
|
||||
con.setRequestMethod(METHOD_POST);
|
||||
con.setDoOutput(true);
|
||||
con.setDoInput(true);
|
||||
con.setUseCaches(false);
|
||||
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||
OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream(), DEFAULT_CHARSET);
|
||||
osw.write(sb.toString());
|
||||
osw.flush();
|
||||
osw.close();
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to post.", e);
|
||||
}
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(con
|
||||
.getInputStream(), DEFAULT_CHARSET));
|
||||
String temp;
|
||||
while ((temp = br.readLine()) != null) {
|
||||
buffer.append(temp);
|
||||
buffer.append("\n");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
con.disconnect();
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
private static final String METHOD_POST = "POST";
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import com.sun.management.OperatingSystemMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
* @author hyh
|
||||
*/
|
||||
public enum OS {
|
||||
|
||||
LINUX,
|
||||
WINDOWS,
|
||||
OSX,
|
||||
UNKOWN;
|
||||
|
||||
public static OS os() {
|
||||
String str;
|
||||
if ((str = System.getProperty("os.name").toLowerCase())
|
||||
.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;
|
||||
}
|
||||
|
||||
public static boolean is64Bit() {
|
||||
String arch = System.getProperty("os.arch");
|
||||
return arch.contains("64");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Free Physical Memory Size (Byte)
|
||||
*/
|
||||
public static long getTotalPhysicalMemory() {
|
||||
try {
|
||||
OperatingSystemMXBean o = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
|
||||
return o.getTotalPhysicalMemorySize();
|
||||
} catch(Throwable t) {
|
||||
HMCLog.warn("Failed to get total physical memory size", t);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Pair<K, V> {
|
||||
public K key;
|
||||
public V value;
|
||||
|
||||
public Pair(K k, V v) {
|
||||
key = k;
|
||||
value = v;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ProcessManager {
|
||||
|
||||
private static final HashSet<JavaProcess> gameProcesses = new HashSet();
|
||||
|
||||
public void registerProcess(JavaProcess jp) {
|
||||
gameProcesses.add(jp);
|
||||
}
|
||||
|
||||
public void stopAllProcesses() {
|
||||
for(JavaProcess jp : gameProcesses) {
|
||||
jp.stop();
|
||||
}
|
||||
gameProcesses.clear();
|
||||
}
|
||||
|
||||
public void onProcessStopped(JavaProcess p) {
|
||||
gameProcesses.remove(p);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ProcessThread extends Thread {
|
||||
|
||||
JavaProcess p;
|
||||
boolean readError = false, enableReading = true;
|
||||
|
||||
public final EventHandler<String> printlnEvent = new EventHandler<String>(this);
|
||||
public final EventHandler<JavaProcess> stopEvent = new EventHandler<JavaProcess>(this);
|
||||
|
||||
public ProcessThread(JavaProcess process, boolean readError, boolean enableReading) {
|
||||
p = process;
|
||||
this.readError = readError;
|
||||
this.enableReading = enableReading;
|
||||
}
|
||||
|
||||
public JavaProcess getProcess() {
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
InputStream in = null;
|
||||
BufferedReader br = null;
|
||||
if (enableReading) {
|
||||
in = readError ? p.getRawProcess().getErrorStream() : p.getRawProcess().getInputStream();
|
||||
}
|
||||
try {
|
||||
if (enableReading) {
|
||||
try {
|
||||
br = new BufferedReader(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 BufferedReader(new InputStreamReader(in));
|
||||
}
|
||||
}
|
||||
|
||||
String line;
|
||||
while (p.isRunning()) {
|
||||
if (enableReading) {
|
||||
while ((line = br.readLine()) != null) {
|
||||
printlnEvent.execute(line);
|
||||
if (readError) {
|
||||
System.err.println(line);
|
||||
p.getStdErrLines().add(line);
|
||||
} else {
|
||||
System.out.println(line);
|
||||
p.getStdOutLines().add(line);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (enableReading) {
|
||||
while ((line = br.readLine()) != null) {
|
||||
printlnEvent.execute(line);
|
||||
if (readError) {
|
||||
System.err.println(line);
|
||||
p.getStdErrLines().add(line);
|
||||
} else {
|
||||
System.out.println(line);
|
||||
p.getStdOutLines().add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
stopEvent.execute(p);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void stopped() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ReflectUtils {
|
||||
|
||||
public static Set<? extends Class<?>> getClasses(Class c) {
|
||||
HashSet set = new HashSet();
|
||||
set.addAll(Arrays.asList(c.getInterfaces()));
|
||||
while(c != Object.class) {
|
||||
set.add(c);
|
||||
c = c.getSuperclass();
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public final class StrUtils {
|
||||
|
||||
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 equalsOne(String base, String... a) {
|
||||
for (String s : a) {
|
||||
if (base.equals(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 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[] paramArrayOfObject, String paramString) {
|
||||
if (paramArrayOfObject == null) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder localStringBuffer = new StringBuilder();
|
||||
for (int i = 0; i < paramArrayOfObject.length; i++) {
|
||||
Object localObject = paramArrayOfObject[i];
|
||||
if (i > 0) {
|
||||
localStringBuffer.append(addBefore).append(paramString);
|
||||
}
|
||||
if (localObject == null) {
|
||||
localStringBuffer.append("null");
|
||||
} else if (localObject.getClass().isArray()) {
|
||||
localStringBuffer.append("[");
|
||||
|
||||
if ((localObject instanceof Object[])) {
|
||||
Object[] arrayOfObject = (Object[]) localObject;
|
||||
localStringBuffer.append(parseParams(addBefore, arrayOfObject, paramString));
|
||||
} else {
|
||||
for (int j = 0; j < Array.getLength(localObject); j++) {
|
||||
if (j > 0) {
|
||||
localStringBuffer.append(paramString);
|
||||
}
|
||||
localStringBuffer.append(addBefore).append(Array.get(localObject, j));
|
||||
}
|
||||
}
|
||||
localStringBuffer.append("]");
|
||||
} else {
|
||||
localStringBuffer.append(addBefore).append(paramArrayOfObject[i]);
|
||||
}
|
||||
}
|
||||
return localStringBuffer.toString();
|
||||
}
|
||||
|
||||
public static boolean isEquals(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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.net.URI;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JList;
|
||||
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.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public class SwingUtils {
|
||||
|
||||
public static DefaultTableModel makeDefaultTableModel(String[] titleA, final Class[] typesA, final boolean[] canEditA) {
|
||||
return new javax.swing.table.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 openLink(URI link) {
|
||||
try {
|
||||
java.awt.Desktop.getDesktop().browse(link);
|
||||
} catch (Throwable e) {
|
||||
HMCLog.warn("Failed to open link: " + link, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void moveEnd(JTextArea tf) {
|
||||
int position = tf.getText().length();
|
||||
tf.setCaretPosition(position);
|
||||
}
|
||||
|
||||
public static void moveEnd(JScrollPane pane) {
|
||||
JScrollBar bar = pane.getVerticalScrollBar();
|
||||
bar.setValue(bar.getMaximum());
|
||||
}
|
||||
|
||||
public static DefaultListModel getDefaultListModel(JList list) {
|
||||
return (DefaultListModel)list.getModel();
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
public static void clearDefaultTable(JTable table) {
|
||||
DefaultTableModel model = (DefaultTableModel)table.getModel();
|
||||
while(model.getRowCount() > 0) {
|
||||
model.removeRow(0);
|
||||
}
|
||||
table.updateUI();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class TextComponentOutputStream extends OutputStream {
|
||||
|
||||
private JTextComponent txt;
|
||||
|
||||
public TextComponentOutputStream(JTextComponent paramJTextComponent) {
|
||||
txt = paramJTextComponent;
|
||||
}
|
||||
|
||||
@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(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String t = txt.getText() + newString.replace("\t", " ");
|
||||
txt.setText(t);
|
||||
txt.setCaretPosition(t.length());
|
||||
}
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void write(int paramInt) {
|
||||
append(new String(new byte[]{(byte) paramInt}));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.utils.functions.DoneListener0;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class UpdateChecker extends Thread {
|
||||
public static boolean OUT_DATED = false;
|
||||
public VersionNumber base;
|
||||
public String type;
|
||||
public boolean continueUpdate;
|
||||
public DoneListener0 dl;
|
||||
|
||||
public UpdateChecker(VersionNumber base, String type, boolean continueUpdate, DoneListener0 dl) {
|
||||
super("UpdateChecker");
|
||||
this.base = base;
|
||||
this.type = type;
|
||||
this.continueUpdate = continueUpdate;
|
||||
this.dl = dl;
|
||||
}
|
||||
|
||||
VersionNumber value;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
String url = "http://huangyuhui.duapp.com/info.php?type=" + type, version;
|
||||
try {
|
||||
version = NetUtils.doGet(url);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to get update url.", e);
|
||||
return;
|
||||
}
|
||||
value = VersionNumber.check(version);
|
||||
if (!continueUpdate) {
|
||||
return;
|
||||
}
|
||||
process(false);
|
||||
}
|
||||
|
||||
public void process(boolean showMessage) {
|
||||
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;
|
||||
dl.onDone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public VersionNumber getNewVersion() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.sun.management.OperatingSystemMXBean;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Random;
|
||||
import javax.swing.ImageIcon;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
* @author hyh
|
||||
*/
|
||||
public final class Utils {
|
||||
|
||||
private static final GsonBuilder gsonBuilder = new GsonBuilder().setPrettyPrinting();
|
||||
public static GsonBuilder getDefaultGsonBuilder() {
|
||||
return gsonBuilder;
|
||||
}
|
||||
|
||||
public static String[] getURL() {
|
||||
URL[] urls = ((URLClassLoader) Utils.class.getClassLoader()).getURLs();
|
||||
String[] urlStrings = new String[urls.length];
|
||||
for (int i = 0; i < urlStrings.length; i++) {
|
||||
try {
|
||||
urlStrings[i] = URLDecoder.decode(urls[i].getPath(), "UTF-8");
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
HMCLog.warn("Unsupported UTF-8 encoding", ex);
|
||||
}
|
||||
}
|
||||
return urlStrings;
|
||||
}
|
||||
|
||||
public static void addDir(String s) throws IOException {
|
||||
try {
|
||||
Field field = ClassLoader.class.getDeclaredField("usr_paths");
|
||||
field.setAccessible(true);
|
||||
String[] paths = (String[]) field.get(null);
|
||||
for (int i = 0; i < paths.length; i++) {
|
||||
if (s.equals(paths[i])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
String[] tmp = new String[paths.length + 1];
|
||||
System.arraycopy(paths, 0, tmp, 0, paths.length);
|
||||
tmp[paths.length] = s;
|
||||
field.set(null, tmp);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IOException("Failed to get permissions to set library path");
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new IOException("Failed to get field handle to set library path");
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static boolean openLink(String url) {
|
||||
try {
|
||||
Desktop.getDesktop().browse(new URI(url));
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
HMCLog.warn("Failed to open link:" + url, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void openFolder(File f) {
|
||||
try {
|
||||
f.mkdirs();
|
||||
java.awt.Desktop.getDesktop().open(f);
|
||||
} catch (Exception ex) {
|
||||
MessageBox.Show(C.i18n("message.cannot_open_explorer") + ex.getMessage());
|
||||
HMCLog.warn("Failed to open folder:" + f, ex);
|
||||
}
|
||||
}
|
||||
|
||||
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 background, String bgpath, int width, int height) {
|
||||
Random r = new Random();
|
||||
boolean loaded = false;
|
||||
|
||||
// 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.");
|
||||
}
|
||||
}
|
||||
|
||||
return background;
|
||||
}
|
||||
|
||||
/**
|
||||
* In order to fight against the permission manager.
|
||||
*/
|
||||
public static void shutdownForcely() {
|
||||
try {
|
||||
Class z = Class.forName("java.lang.Shutdown");
|
||||
Method exit = z.getDeclaredMethod("exit", int.class);
|
||||
exit.setAccessible(true);
|
||||
exit.invoke(z, 0);
|
||||
} catch(Exception e) {
|
||||
MessageBox.Show(C.i18n("launcher.exit_failed"));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class Validate {
|
||||
|
||||
public static <T> T notNull(T o) {
|
||||
if(o == null) {
|
||||
throw new IllegalArgumentException("The validated object is null");
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils;
|
||||
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class VersionNumber implements Comparable<VersionNumber> {
|
||||
|
||||
public byte firstVer, secondVer, thirdVer;
|
||||
|
||||
public VersionNumber(byte a, byte b, byte c) {
|
||||
firstVer = a; secondVer = b; thirdVer = c;
|
||||
}
|
||||
|
||||
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 = null;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils.functions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface BiFunction<A, B, C> {
|
||||
C apply(A a, B b);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils.functions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface Consumer<T> {
|
||||
void accept(T t);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.utils.functions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public interface DoneListener0 {
|
||||
void onDone();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils.functions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public interface DoneListener0Return<T> {
|
||||
T onDone();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils.functions;
|
||||
|
||||
/**
|
||||
* @author hyh
|
||||
*/
|
||||
public interface DoneListener2<V, V2> {
|
||||
void onDone(V value, V2 value2);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hellominecraft.utils.functions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public interface DoneListener3<V1, V2, V3> {
|
||||
void onDone(V1 v1, V2 v2, V3 v3);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils.functions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class FalseDoneListener implements DoneListener0Return<Boolean> {
|
||||
|
||||
@Override
|
||||
public Boolean onDone() {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils.functions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface Function<T, R> {
|
||||
R apply(T t);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils.functions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public interface Predicate<T> {
|
||||
boolean apply(T t);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils.functions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class TrueDoneListener implements DoneListener0Return<Boolean> {
|
||||
|
||||
public static final TrueDoneListener instance = new TrueDoneListener();
|
||||
|
||||
private TrueDoneListener(){}
|
||||
|
||||
@Override
|
||||
public Boolean onDone() {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils.tinystream;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Predicate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class CollectionUtils {
|
||||
public static <T> void forEach(Collection<T> coll, Consumer<T> p) {
|
||||
for(T t : coll) p.accept(t);
|
||||
}
|
||||
|
||||
public static <T> Collection<T> sortOut(Collection<T> coll, Predicate<T> p) {
|
||||
ArrayList<T> newColl = new ArrayList<>();
|
||||
forEach(coll, t -> { 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.utils.tinystream;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.functions.BiFunction;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Function;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Predicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Stream<T> {
|
||||
|
||||
List<T> internal;
|
||||
|
||||
public Stream(Collection<T> internal) {
|
||||
this.internal = new ArrayList<>(internal);
|
||||
}
|
||||
|
||||
protected Stream() {
|
||||
}
|
||||
|
||||
protected static <T> Stream<T> of(List<T> a) {
|
||||
Stream<T> b = new Stream<>();
|
||||
b.internal = a;
|
||||
return b;
|
||||
}
|
||||
|
||||
public Stream<T> forEach(Consumer<? super T> p) {
|
||||
for (T t : internal) p.accept(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Stream<T> filter(Predicate<? super T> p) {
|
||||
ArrayList<T> newList = new ArrayList<>();
|
||||
forEach(a -> {
|
||||
if (p.apply(a)) newList.add(a);
|
||||
});
|
||||
internal = newList;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return internal.size();
|
||||
}
|
||||
|
||||
public Stream<T> distinct() {
|
||||
internal = new ArrayList<>(new HashSet<>(internal));
|
||||
return this;
|
||||
}
|
||||
|
||||
public <R> Stream<R> map(Function<? super T, ? extends R> func) {
|
||||
List<R> newList = new ArrayList<>(internal.size());
|
||||
forEach(a -> newList.add(func.apply(a)));
|
||||
return of(newList);
|
||||
}
|
||||
|
||||
public Stream<T> sorted(Comparator<? super T> c) {
|
||||
Collections.sort(internal, c);
|
||||
return this;
|
||||
}
|
||||
|
||||
public <U> U reduce(U identity, BiFunction<U, T, U> accumulator) {
|
||||
for (T t : internal) identity = accumulator.apply(identity, t);
|
||||
return identity;
|
||||
}
|
||||
|
||||
public boolean anyMatch(Predicate<? super T> p) {
|
||||
return map(t -> p.apply(t)).reduce(false, (accumulator, _item) -> accumulator | _item);
|
||||
}
|
||||
|
||||
public boolean allMatch(Predicate<? super T> p) {
|
||||
return map(t -> p.apply(t)).reduce(true, (accumulator, _item) -> accumulator & _item);
|
||||
}
|
||||
|
||||
public T findFirst() {
|
||||
return internal.isEmpty() ? null : internal.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.version;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftRemoteLatestVersion {
|
||||
|
||||
public String snapshot, release;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.version;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftRemoteVersion {
|
||||
|
||||
public String id, time, releaseTime, type;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.version;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftRemoteVersions {
|
||||
|
||||
public ArrayList<MinecraftRemoteVersion> versions;
|
||||
public MinecraftRemoteLatestVersion latest;
|
||||
|
||||
public static MinecraftRemoteVersions fromJson(String s) {
|
||||
return C.gson.fromJson(s, MinecraftRemoteVersions.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.views;
|
||||
|
||||
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
|
||||
{
|
||||
public abstract BufferedImage filter(BufferedImage paramBufferedImage1, BufferedImage paramBufferedImage2);
|
||||
|
||||
public Rectangle2D getBounds2D(BufferedImage src)
|
||||
{
|
||||
return new Rectangle(0, 0, src.getWidth(), src.getHeight());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public Point2D getPoint2D(Point2D srcPt, Point2D dstPt)
|
||||
{
|
||||
return (Point2D)srcPt.clone();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.views;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
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")
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.views;
|
||||
|
||||
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 javax.swing.border.AbstractBorder;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return this.insets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
return getBorderInsets(c);
|
||||
}
|
||||
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
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);
|
||||
|
||||
g.drawImage(shadow, x, y, width, height, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.views;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?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" value="Log"/>
|
||||
</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" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" 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="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" pref="639" 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="jScrollPane1" pref="375" 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"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<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.JTextArea" name="txtLog">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
<Property name="columns" type="int" value="20"/>
|
||||
<Property name="rows" type="int" value="5"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<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="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{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="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{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="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{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.getString("{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="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{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="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnTerminateGameActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.views;
|
||||
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.utils.functions.DoneListener0;
|
||||
import org.jackhuang.hellominecraft.utils.functions.DoneListener0Return;
|
||||
import org.jackhuang.hellominecraft.utils.DoubleOutputStream;
|
||||
import org.jackhuang.hellominecraft.utils.LauncherPrintStream;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.SwingUtils;
|
||||
import org.jackhuang.hellominecraft.utils.TextComponentOutputStream;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class LogWindow extends javax.swing.JFrame {
|
||||
|
||||
boolean movingEnd;
|
||||
DoneListener0Return<Boolean> listener;
|
||||
DoneListener0 terminateGameListener;
|
||||
|
||||
/**
|
||||
* Creates new form LogWindow
|
||||
*/
|
||||
public LogWindow() {
|
||||
initComponents();
|
||||
|
||||
movingEnd = true;
|
||||
|
||||
setLocationRelativeTo(null);
|
||||
|
||||
TextComponentOutputStream tc = new TextComponentOutputStream(txtLog);
|
||||
DoubleOutputStream out = new DoubleOutputStream(tc, System.out);
|
||||
System.setOut(new LauncherPrintStream(out));
|
||||
DoubleOutputStream err = new DoubleOutputStream(tc, System.err);
|
||||
System.setErr(new LauncherPrintStream(err));
|
||||
}
|
||||
|
||||
public static 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() {
|
||||
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
txtLog = new javax.swing.JTextArea();
|
||||
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();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setTitle("Log");
|
||||
addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
public void windowClosed(java.awt.event.WindowEvent evt) {
|
||||
formWindowClosed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
txtLog.setEditable(false);
|
||||
txtLog.setColumns(20);
|
||||
txtLog.setRows(5);
|
||||
jScrollPane1.setViewportView(txtLog);
|
||||
|
||||
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/jackhuang/hellominecraft/launcher/I18N"); // NOI18N
|
||||
btnClear.setText(bundle.getString("ui.button.clear")); // NOI18N
|
||||
btnClear.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnClearActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnClose.setText(bundle.getString("ui.button.close")); // NOI18N
|
||||
btnClose.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnCloseActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnCopy.setText(bundle.getString("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.getString("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(bundle.getString("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(bundle.getString("logwindow.terminate_game")); // NOI18N
|
||||
btnTerminateGame.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnTerminateGameActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
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()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, 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, 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.DEFAULT_SIZE, 639, Short.MAX_VALUE))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(lblCrash, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 375, 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))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void btnCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCloseActionPerformed
|
||||
this.dispose();
|
||||
}//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 formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
|
||||
if(listener != null && listener.onDone()) Utils.shutdownForcely();
|
||||
}//GEN-LAST:event_formWindowClosed
|
||||
|
||||
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
|
||||
Utils.openLink(C.URL_PUBLISH);
|
||||
}//GEN-LAST:event_btnMCBBSActionPerformed
|
||||
|
||||
private void btnTieBaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTieBaActionPerformed
|
||||
Utils.openLink(C.URL_TIEBA);
|
||||
}//GEN-LAST:event_btnTieBaActionPerformed
|
||||
|
||||
private void btnMCFActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMCFActionPerformed
|
||||
Utils.openLink(C.URL_MINECRAFTFORUM);
|
||||
}//GEN-LAST:event_btnMCFActionPerformed
|
||||
|
||||
private void btnTerminateGameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTerminateGameActionPerformed
|
||||
if(terminateGameListener != null)
|
||||
terminateGameListener.onDone();
|
||||
}//GEN-LAST:event_btnTerminateGameActionPerformed
|
||||
|
||||
public void log(String status) {
|
||||
String text = txtLog.getText();
|
||||
text += status + System.getProperty("line.separator");
|
||||
txtLog.setText(text);
|
||||
|
||||
if(movingEnd) {
|
||||
int position = text.length();
|
||||
txtLog.setCaretPosition(position);
|
||||
}
|
||||
}
|
||||
|
||||
public void log(String status, Throwable t) {
|
||||
log(status);
|
||||
log(StrUtils.getStackTrace(t));
|
||||
}
|
||||
|
||||
public void setExit(DoneListener0Return<Boolean> exit) {
|
||||
this.listener = exit;
|
||||
}
|
||||
|
||||
public void setTerminateGame(DoneListener0 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 btnMCBBS;
|
||||
private javax.swing.JButton btnMCF;
|
||||
private javax.swing.JButton btnTerminateGame;
|
||||
private javax.swing.JButton btnTieBa;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JLabel lblCrash;
|
||||
private javax.swing.JTextArea txtLog;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user