Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a86881926 | ||
|
|
b255fd4601 | ||
|
|
562dd8d916 | ||
|
|
97d820446a | ||
|
|
826d382ad5 | ||
|
|
59d7ac3c82 | ||
|
|
566aed4ed6 | ||
|
|
1b90e94615 | ||
|
|
22ede84c3d | ||
|
|
0c4da069b7 |
No files matched your search
@@ -52,8 +52,9 @@ import org.xml.sax.XMLReader;
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LaunchingUIDaemon {
|
||||
|
||||
|
||||
XMLReader reader;
|
||||
Log4jHandler logHandler;
|
||||
|
||||
public LaunchingUIDaemon() {
|
||||
HMCLApi.EVENT_BUS.channel(LaunchingStateChangedEvent.class).register(LAUNCHING_STATE_CHANGED);
|
||||
@@ -76,12 +77,12 @@ public class LaunchingUIDaemon {
|
||||
PipedOutputStream os = new PipedOutputStream();
|
||||
monitor.setTag(obj);
|
||||
try {
|
||||
Log4jHandler handler = new Log4jHandler(monitor, os);
|
||||
handler.addForbiddenToken(obj.getLoginResult().getAccessToken(), "<access token>");
|
||||
handler.addForbiddenToken(obj.getLoginResult().getSession(), "<session>");
|
||||
handler.addForbiddenToken(obj.getLoginResult().getUserId(), "<uuid>");
|
||||
handler.addForbiddenToken("Setting user: " + obj.getLoginResult().getUserName(), "<player>");
|
||||
handler.start();
|
||||
logHandler = new Log4jHandler(monitor, os);
|
||||
logHandler.addForbiddenToken(obj.getLoginResult().getAccessToken(), "<access token>");
|
||||
logHandler.addForbiddenToken(obj.getLoginResult().getSession(), "<session>");
|
||||
logHandler.addForbiddenToken(obj.getLoginResult().getUserId(), "<uuid>");
|
||||
logHandler.addForbiddenToken("Setting user: " + obj.getLoginResult().getUserName(), "<player>");
|
||||
logHandler.start();
|
||||
} catch(Exception e) {
|
||||
HMCLog.err("", e);
|
||||
}
|
||||
@@ -128,7 +129,7 @@ public class LaunchingUIDaemon {
|
||||
noExitThisTime = true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
static LauncherVisibility unpackProcessMonitor(Object obj) {
|
||||
GameLauncher launcher = ((GameLauncher) ((ProcessMonitor) obj).getTag());
|
||||
HMCLGameLauncher.GameLauncherTag tag = (HMCLGameLauncher.GameLauncherTag) launcher.getTag();
|
||||
@@ -161,9 +162,9 @@ public class LaunchingUIDaemon {
|
||||
((HMCLGameLauncher.GameLauncherTag) value.getTag()).state = 2;
|
||||
}, MainFrame.INSTANCE::failed, Settings.getInstance().getAuthenticator().getPassword());
|
||||
}
|
||||
|
||||
|
||||
class PrintlnProcessor implements Consumer<PrintlnEvent> {
|
||||
|
||||
|
||||
GameLauncher launcher;
|
||||
PipedOutputStream os;
|
||||
|
||||
@@ -174,25 +175,27 @@ public class LaunchingUIDaemon {
|
||||
|
||||
@Override
|
||||
public void accept(PrintlnEvent t) {
|
||||
if (!t.isError())
|
||||
try {
|
||||
os.write((t.getLine() + C.LINE_SEPARATOR).replace("log4j:Event", "log4j_Event").replace("log4j:Message", "log4j_Message").getBytes());
|
||||
os.flush();
|
||||
} catch(IOException e) {
|
||||
HMCLog.err("", e);
|
||||
String log = t.getLine();
|
||||
if (!t.isError() && logHandler != null) {
|
||||
if (!log.trim().startsWith("<")) { // without logging configuration.
|
||||
log = "<![CDATA[" + log.replace("]]>", "") + "]]>";
|
||||
}
|
||||
logHandler.newLogLine(log + C.LINE_SEPARATOR);
|
||||
}
|
||||
else System.err.println(t.getLine());
|
||||
HMCLGameLauncher.GameLauncherTag tag = (HMCLGameLauncher.GameLauncherTag) launcher.getTag();
|
||||
LauncherVisibility l = tag.launcherVisibility;
|
||||
if (t.getLine().contains("LWJGL Version: ") && l != LauncherVisibility.KEEP)
|
||||
if (l != LauncherVisibility.HIDE_AND_REOPEN)
|
||||
MainFrame.INSTANCE.dispose();
|
||||
else { // If current state is 'hide and reopen', closes the main window and reset the state to normal.
|
||||
MainFrame.INSTANCE.setVisible(false);
|
||||
HMCLApi.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(launcher, LaunchingState.Done));
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (l != LauncherVisibility.HIDE_AND_REOPEN)
|
||||
MainFrame.INSTANCE.dispose();
|
||||
else { // If current state is 'hide and reopen', closes the main window and reset the state to normal.
|
||||
MainFrame.INSTANCE.setVisible(false);
|
||||
HMCLApi.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(launcher, LaunchingState.Done));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static final Consumer<LaunchingStateChangedEvent> LAUNCHING_STATE_CHANGED = t -> {
|
||||
@@ -231,13 +234,10 @@ public class LaunchingUIDaemon {
|
||||
|
||||
private void checkExit(LauncherVisibility v) {
|
||||
if (v == LauncherVisibility.HIDE_AND_REOPEN) {
|
||||
HMCLog.log("Launcher will not exit now.");
|
||||
MainFrame.INSTANCE.setVisible(true);
|
||||
} else if (v != LauncherVisibility.KEEP && !LogWindow.INSTANCE.isVisible() && !noExitThisTime) {
|
||||
HMCLog.log("Launcher will exit now.");
|
||||
System.exit(0);
|
||||
} else {
|
||||
HMCLog.log("Launcher will not exit now.");
|
||||
noExitThisTime = false;
|
||||
}
|
||||
}
|
||||
@@ -253,5 +253,5 @@ public class LaunchingUIDaemon {
|
||||
}
|
||||
MainFrame.INSTANCE.closeMessage();
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -39,7 +39,7 @@ public class HMCLGameProvider extends MinecraftVersionManager<HMCLMinecraftServi
|
||||
public File getLibraryFile(MinecraftVersion version, IMinecraftLibrary lib) {
|
||||
VersionSetting vs = service.getProfile().getVersionSetting(version.id);
|
||||
File self = super.getLibraryFile(version, lib);
|
||||
if (self.exists() || (vs != null && service.getProfile().isNoCommon()))
|
||||
if (self == null || self.exists() || (vs != null && service.getProfile().isNoCommon()))
|
||||
return self;
|
||||
else
|
||||
return lib.getFilePath(new File(Settings.getInstance().getCommonpath()));
|
||||
|
||||
@@ -18,12 +18,15 @@
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.jackhuang.hmcl.api.HMCLApi;
|
||||
import org.jackhuang.hmcl.api.event.process.JavaProcessStoppedEvent;
|
||||
@@ -49,6 +52,8 @@ public class Log4jHandler extends Thread implements Consumer<JavaProcessStoppedE
|
||||
PipedInputStream inputStream;
|
||||
PipedOutputStream outputStream;
|
||||
List<Pair<String, String>> forbiddenTokens = new LinkedList<>();
|
||||
AtomicBoolean interrupted = new AtomicBoolean(false);
|
||||
ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||
|
||||
public Log4jHandler(ProcessMonitor monitor, PipedOutputStream outputStream) throws ParserConfigurationException, IOException, SAXException {
|
||||
reader = XMLReaderFactory.createXMLReader();
|
||||
@@ -66,25 +71,59 @@ public class Log4jHandler extends Thread implements Consumer<JavaProcessStoppedE
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
outputStream.write("<output>".getBytes());
|
||||
outputStream.flush();
|
||||
setName("log4j-handler");
|
||||
newLogLine("<output>");
|
||||
reader.setContentHandler(new Log4jHandlerImpl());
|
||||
reader.parse(new InputSource(inputStream));
|
||||
} catch (InterruptedIOException e) {
|
||||
interrupted.set(true);
|
||||
} catch (SAXException | IOException e) {
|
||||
|
||||
throw new Error(e);
|
||||
} finally {
|
||||
executorService.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(JavaProcessStoppedEvent t) {
|
||||
if (!interrupted.get())
|
||||
return;
|
||||
if (t.getSource() == monitor) {
|
||||
executorService.submit(() -> {
|
||||
if (!interrupted.get()) {
|
||||
newLogLine("</output>").get();
|
||||
outputStream.close();
|
||||
join();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Always use this instance method to write to the log,
|
||||
* to make sure only this Thread writes to the PipedOutputStream.
|
||||
*
|
||||
* It will also flush the buffer, directly after write.
|
||||
*
|
||||
* This prevents java.io.IOException: Read end dead
|
||||
* See also https://techtavern.wordpress.com/2008/07/16/whats-this-ioexception-write-end-dead/
|
||||
*
|
||||
* @param content The content to be written to the log
|
||||
*/
|
||||
public Future newLogLine(String content) {
|
||||
return executorService.submit(() -> {
|
||||
try {
|
||||
outputStream.write("</output>".getBytes());
|
||||
outputStream.close();
|
||||
outputStream.write(content
|
||||
.replace("log4j:Event", "log4j_Event")
|
||||
.replace("log4j:Message", "log4j_Message")
|
||||
.replace("log4j:Throwable", "log4j_Throwable")
|
||||
.getBytes());
|
||||
outputStream.flush();
|
||||
} catch (IOException ignore) { // won't happen
|
||||
throw new Error(ignore);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class Log4jHandlerImpl extends DefaultHandler {
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class MinecraftDownloadService extends IMinecraftDownloadService {
|
||||
for (IMinecraftLibrary l : v.getLibraries())
|
||||
if (l != null && l.allow()) {
|
||||
File ff = service.version().getLibraryFile(mv, l);
|
||||
if (!ff.exists() && l.getDownloadURL(service.getDownloadType().name()) != null) {
|
||||
if (ff != null && !ff.exists() && l.getDownloadURL(service.getDownloadType().name()) != null) {
|
||||
String libURL = l.getDownloadURL(service.getDownloadType().name());
|
||||
if (libURL != null)
|
||||
downloadLibraries.add(new DownloadLibraryJob(l, libURL, ff));
|
||||
|
||||
+5
-1
@@ -41,7 +41,11 @@ public abstract class AbstractMinecraftLibrary implements IMinecraftLibrary {
|
||||
|
||||
@Override
|
||||
public String getDownloadURL(String downloadSource) {
|
||||
return getDownloadInfo().getUrl(DownloadType.valueOf(downloadSource));
|
||||
LibraryDownloadInfo info = getDownloadInfo();
|
||||
if (info == null)
|
||||
return null;
|
||||
else
|
||||
return info.getUrl(DownloadType.valueOf(downloadSource));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -123,6 +123,8 @@ public class MinecraftLibrary extends AbstractMinecraftLibrary {
|
||||
if (natives != null) {
|
||||
if (downloads.classifiers == null)
|
||||
downloads.classifiers = new HashMap<>();
|
||||
if (StrUtils.isBlank(getNative()))
|
||||
return null;
|
||||
if (!downloads.classifiers.containsKey(getNative()))
|
||||
downloads.classifiers.put(getNative(), info = new LibraryDownloadInfo());
|
||||
else info = downloads.classifiers.get(getNative());
|
||||
|
||||
@@ -247,11 +247,13 @@ public class MinecraftVersionManager<T extends IMinecraftService> extends IMinec
|
||||
throw new GameException("Wrong format: minecraft.json");
|
||||
ArrayList<File> unzippings = new ArrayList<>();
|
||||
ArrayList<Extract> extractRules = new ArrayList<>();
|
||||
for (IMinecraftLibrary l : v.libraries)
|
||||
if (l.isNative() && v.isAllowedToUnpackNatives()) {
|
||||
unzippings.add(getLibraryFile(v, l));
|
||||
for (IMinecraftLibrary l : v.libraries) {
|
||||
final File f = getLibraryFile(v, l);
|
||||
if (l.isNative() && v.isAllowedToUnpackNatives() && f != null) {
|
||||
unzippings.add(f);
|
||||
extractRules.add(l.getDecompressExtractRules());
|
||||
}
|
||||
}
|
||||
return new DecompressLibraryJob(unzippings.toArray(new File[unzippings.size()]), extractRules.toArray(new Extract[extractRules.size()]), getDecompressNativesToLocation(v));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.jackhuang.hmcl.util.log;
|
||||
import java.awt.Color;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jackhuang.hmcl.util.ui.GraphicsUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -27,12 +28,12 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public enum Level {
|
||||
|
||||
FATAL(1, Color.red),
|
||||
ERROR(2, Color.red),
|
||||
WARN(3, Color.orange),
|
||||
FATAL(1, GraphicsUtils.getWebColor("#C0392B")),
|
||||
ERROR(2, GraphicsUtils.getWebColor("#D35400")),
|
||||
WARN(3, GraphicsUtils.getWebColor("#F39C12")),
|
||||
INFO(4, Color.black),
|
||||
DEBUG(5, Color.blue),
|
||||
TRACE(6, Color.blue),
|
||||
DEBUG(5, GraphicsUtils.getWebColor("#2980B9")),
|
||||
TRACE(6, GraphicsUtils.getWebColor("#16A085")),
|
||||
ALL(2147483647, Color.black);
|
||||
|
||||
public final int level;
|
||||
|
||||
@@ -40,6 +40,7 @@ public final class NetUtils {
|
||||
|
||||
public static HttpURLConnection createConnection(URL url, Proxy proxy) throws IOException {
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection(proxy);
|
||||
con.setRequestProperty("User-Agent", "Hello Minecraft!");
|
||||
con.setDoInput(true);
|
||||
con.setUseCaches(false);
|
||||
con.setConnectTimeout(15000);
|
||||
@@ -48,7 +49,9 @@ public final class NetUtils {
|
||||
}
|
||||
|
||||
public static String get(String url, String encoding) throws IOException {
|
||||
return IOUtils.toString(new URL(url).openConnection().getInputStream());
|
||||
HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
|
||||
con.setRequestProperty("User-Agent", "Hello Minecraft!");
|
||||
return IOUtils.toString(con.getInputStream());
|
||||
}
|
||||
|
||||
public static String get(String url) throws IOException {
|
||||
|
||||
@@ -89,7 +89,7 @@ public class ProcessMonitor {
|
||||
try {
|
||||
exitCode = p.getExitCode();
|
||||
} catch(IllegalThreadStateException e) {
|
||||
HMCLog.err("Failed to ");
|
||||
HMCLog.err("Failed to get exit code ", e);
|
||||
}
|
||||
if (p.getExitCode() != 0 || StrUtils.containsOne(t.getLines(),
|
||||
Arrays.asList("Unable to launch"), // LaunchWrapper will terminate the application returning exit code 0, but this is an error state.
|
||||
|
||||
@@ -71,11 +71,20 @@ public class ProcessThread extends Thread {
|
||||
br = new BufferedReader(new InputStreamReader(in, Charsets.toCharset()));
|
||||
|
||||
String line;
|
||||
while (p.isRunning())
|
||||
while ((line = br.readLine()) != null)
|
||||
while (p.isRunning()) {
|
||||
if (isInterrupted())
|
||||
return;
|
||||
while ((line = br.readLine()) != null) {
|
||||
if (isInterrupted())
|
||||
return;
|
||||
println(line);
|
||||
while ((line = br.readLine()) != null)
|
||||
}
|
||||
}
|
||||
while ((line = br.readLine()) != null) {
|
||||
if (isInterrupted())
|
||||
return;
|
||||
println(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
HMCLog.err("An error occured when reading process stdout/stderr.", e);
|
||||
} finally {
|
||||
|
||||
@@ -79,10 +79,9 @@ public class ZipEngine implements Closeable {
|
||||
File[] files;
|
||||
if (source.isDirectory())
|
||||
files = source.listFiles();
|
||||
else {
|
||||
files = new File[1];
|
||||
files[0] = source;
|
||||
}
|
||||
else
|
||||
files = new File[] { source };
|
||||
|
||||
if (files == null)
|
||||
return;
|
||||
String pathName;//存相对路径(相对于待压缩的根目录)
|
||||
|
||||
Reference in new issue
Block a user