Load plugins from jar file

This commit is contained in:
huangyuhui 2017-02-17 20:00:45 +08:00
parent 413854d1f1
commit 5f65496500
19 changed files with 139 additions and 110 deletions

View File

@ -46,7 +46,7 @@ def buildnumber = System.getenv("TRAVIS_BUILD_NUMBER")
if (buildnumber == null) if (buildnumber == null)
buildnumber = System.getenv("BUILD_NUMBER") buildnumber = System.getenv("BUILD_NUMBER")
if (buildnumber == null) if (buildnumber == null)
buildnumber = "0" buildnumber = "1"
def versionroot = System.getenv("VERSION_ROOT") def versionroot = System.getenv("VERSION_ROOT")
if (versionroot == null) if (versionroot == null)

View File

@ -120,6 +120,7 @@ public final class Main implements Runnable {
System.out.println("--plugin=<your plugin class>: this arg will allow a new plugin to be loaded, please keep your jar in system class path and this class extends IPlugin."); System.out.println("--plugin=<your plugin class>: this arg will allow a new plugin to be loaded, please keep your jar in system class path and this class extends IPlugin.");
return; return;
} }
PluginManager.loadPlugins();
IUpgrader.NOW_UPGRADER.parseArguments(HMCLApi.HMCL_VERSION, args); IUpgrader.NOW_UPGRADER.parseArguments(HMCLApi.HMCL_VERSION, args);

View File

@ -224,7 +224,7 @@ public final class Config implements Cloneable {
theme = LAFTheme.BLUE.id; theme = LAFTheme.BLUE.id;
decorated = OS.os() == OS.LINUX; decorated = OS.os() == OS.LINUX;
auth = new HashMap<>(); auth = new HashMap<>();
commonpath = MCUtils.getLocation().getAbsolutePath(); commonpath = MCUtils.getLocation().getPath();
} }
public DownloadType getDownloadSource() { public DownloadType getDownloadSource() {

View File

@ -17,28 +17,25 @@
*/ */
package org.jackhuang.hmcl.setting; package org.jackhuang.hmcl.setting;
import org.jackhuang.hmcl.core.service.IProfile;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import org.jackhuang.hmcl.util.HMCLGameLauncher; import org.jackhuang.hmcl.util.HMCLGameLauncher;
import org.jackhuang.hmcl.util.HMCLMinecraftService; import org.jackhuang.hmcl.util.HMCLMinecraftService;
import java.io.File; import java.io.File;
import org.jackhuang.hmcl.core.MCUtils; import org.jackhuang.hmcl.core.MCUtils;
import org.jackhuang.hmcl.core.version.MinecraftVersion; import org.jackhuang.hmcl.core.version.MinecraftVersion;
import org.jackhuang.hmcl.util.sys.IOUtils;
import org.jackhuang.hmcl.util.StrUtils; import org.jackhuang.hmcl.util.StrUtils;
import org.jackhuang.hmcl.api.event.EventHandler; import org.jackhuang.hmcl.api.event.EventHandler;
import org.jackhuang.hmcl.api.event.PropertyChangedEvent; import org.jackhuang.hmcl.api.event.PropertyChangedEvent;
import org.jackhuang.hmcl.util.sys.OS;
/** /**
* *
* @author huangyuhui * @author huangyuhui
*/ */
public final class Profile { public final class Profile implements IProfile {
@SerializedName("name")
private String name;
@SerializedName("selectedMinecraftVersion") @SerializedName("selectedMinecraftVersion")
private String selectedMinecraftVersion = ""; private String selectedVersion = "";
@SerializedName("gameDir") @SerializedName("gameDir")
private String gameDir; private String gameDir;
@SerializedName("noCommon") @SerializedName("noCommon")
@ -46,7 +43,8 @@ public final class Profile {
@SerializedName("global") @SerializedName("global")
private VersionSetting global; private VersionSetting global;
private transient HMCLMinecraftService service; private transient String name;
private transient HMCLMinecraftService service = new HMCLMinecraftService(this);
private transient HMCLGameLauncher launcher = new HMCLGameLauncher(this); private transient HMCLGameLauncher launcher = new HMCLGameLauncher(this);
public transient final EventHandler<PropertyChangedEvent<String>> propertyChanged = new EventHandler<>(); public transient final EventHandler<PropertyChangedEvent<String>> propertyChanged = new EventHandler<>();
@ -55,7 +53,7 @@ public final class Profile {
} }
public Profile(String name) { public Profile(String name) {
this(name, new File(".minecraft").getPath()); this(name, ".minecraft");
} }
public Profile(String name, String gameDir) { public Profile(String name, String gameDir) {
@ -72,9 +70,8 @@ public final class Profile {
gameDir = v.gameDir; gameDir = v.gameDir;
} }
@Override
public HMCLMinecraftService service() { public HMCLMinecraftService service() {
if (service == null)
service = new HMCLMinecraftService(this);
return service; return service;
} }
@ -111,7 +108,7 @@ public final class Profile {
vs.setUsesGlobal(false); vs.setUsesGlobal(false);
} else } else
vs.setUsesGlobal(false); vs.setUsesGlobal(false);
propertyChanged.fire(new PropertyChangedEvent<>(this, "selectedMinecraftVersion", selectedMinecraftVersion, selectedMinecraftVersion)); propertyChanged.fire(new PropertyChangedEvent<>(this, "selectedVersion", selectedVersion, selectedVersion));
} }
public void makeVersionSettingGlobal(String id) { public void makeVersionSettingGlobal(String id) {
@ -120,55 +117,42 @@ public final class Profile {
if (vs == null) if (vs == null)
return; return;
vs.setUsesGlobal(true); vs.setUsesGlobal(true);
propertyChanged.fire(new PropertyChangedEvent<>(this, "selectedMinecraftVersion", selectedMinecraftVersion, selectedMinecraftVersion)); propertyChanged.fire(new PropertyChangedEvent<>(this, "selectedVersion", selectedVersion, selectedVersion));
}
public String getSettingsSelectedMinecraftVersion() {
return selectedMinecraftVersion;
} }
@Override
public String getSelectedVersion() { public String getSelectedVersion() {
String v = selectedMinecraftVersion; String v = selectedVersion;
if (StrUtils.isBlank(v) || service().version().getVersionById(v) == null || service().version().getVersionById(v).hidden) { if (StrUtils.isBlank(v) || service().version().getVersionById(v) == null || service().version().getVersionById(v).hidden) {
MinecraftVersion mv = service().version().getOneVersion(t -> !t.hidden); MinecraftVersion mv = service().version().getOneVersion(t -> !t.hidden);
if (mv != null) if (mv != null)
v = mv.id; v = mv.id;
if (StrUtils.isNotBlank(v)) if (StrUtils.isNotBlank(v))
setSelectedMinecraftVersion(v); setSelectedVersion(v);
} }
return StrUtils.isBlank(v) ? null : v; return StrUtils.isBlank(v) ? null : v;
} }
public void setSelectedMinecraftVersion(String selectedMinecraftVersion) { @Override
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "selectedMinecraftVersion", this.selectedMinecraftVersion, selectedMinecraftVersion); public void setSelectedVersion(String newVersion) {
this.selectedMinecraftVersion = selectedMinecraftVersion; PropertyChangedEvent event = new PropertyChangedEvent<>(this, "selectedVersion", this.selectedVersion, newVersion);
this.selectedVersion = newVersion;
propertyChanged.fire(event); propertyChanged.fire(event);
} }
public String getGameDir() { @Override
public File getGameDir() {
if (StrUtils.isBlank(gameDir)) if (StrUtils.isBlank(gameDir))
gameDir = MCUtils.getInitGameDir().getPath(); gameDir = MCUtils.getInitGameDir().getPath();
return IOUtils.addSeparator(gameDir); return new File(gameDir.replace('\\', '/'));
} }
public String getCanonicalGameDir() { @Override
return IOUtils.tryGetCanonicalFolderPath(getGameDirFile()); public void setGameDir(File gameDir) {
}
public File getCanonicalGameDirFile() {
return IOUtils.tryGetCanonicalFile(getGameDirFile());
}
public File getGameDirFile() {
return new File(getGameDir());
}
public Profile setGameDir(String gameDir) {
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "gameDir", this.gameDir, gameDir); PropertyChangedEvent event = new PropertyChangedEvent<>(this, "gameDir", this.gameDir, gameDir);
this.gameDir = gameDir; this.gameDir = gameDir.getPath();
service().version().refreshVersions(); service().version().refreshVersions();
propertyChanged.fire(event); propertyChanged.fire(event);
return this;
} }
public boolean isNoCommon() { public boolean isNoCommon() {
@ -181,6 +165,7 @@ public final class Profile {
propertyChanged.fire(event); propertyChanged.fire(event);
} }
@Override
public String getName() { public String getName() {
return name; return name;
} }
@ -191,10 +176,7 @@ public final class Profile {
propertyChanged.fire(event); propertyChanged.fire(event);
} }
public void checkFormat() { @Override
gameDir = gameDir.replace('/', OS.os().fileSeparator).replace('\\', OS.os().fileSeparator);
}
public void onSelected() { public void onSelected() {
service().version().refreshVersions(); service().version().refreshVersions();
} }

View File

@ -62,7 +62,6 @@ public final class Settings {
for (Map.Entry<String, Profile> entry : getProfiles().entrySet()) { for (Map.Entry<String, Profile> entry : getProfiles().entrySet()) {
Profile e = entry.getValue(); Profile e = entry.getValue();
e.setName(entry.getKey()); e.setName(entry.getKey());
e.checkFormat();
e.propertyChanged.register(Settings::save); e.propertyChanged.register(Settings::save);
} }
} }

View File

@ -997,7 +997,9 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
MessageBox.show(C.i18n("setupwindow.no_empty_name")); MessageBox.show(C.i18n("setupwindow.no_empty_name"));
return; return;
} }
Settings.putProfile(new Profile(name).setGameDir(newGameDir.getAbsolutePath())); Profile newProfile = new Profile(name);
newProfile.setGameDir(newGameDir);
Settings.putProfile(newProfile);
MessageBox.show(C.i18n("setupwindow.find_in_configurations")); MessageBox.show(C.i18n("setupwindow.find_in_configurations"));
loadProfiles(); loadProfiles();
} }
@ -1042,7 +1044,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
private void cboVersionsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboVersionsItemStateChanged private void cboVersionsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboVersionsItemStateChanged
if (isLoading || evt.getStateChange() != ItemEvent.SELECTED || cboVersions.getSelectedIndex() < 0 || StrUtils.isBlank((String) cboVersions.getSelectedItem())) if (isLoading || evt.getStateChange() != ItemEvent.SELECTED || cboVersions.getSelectedIndex() < 0 || StrUtils.isBlank((String) cboVersions.getSelectedItem()))
return; return;
Settings.getLastProfile().setSelectedMinecraftVersion((String) cboVersions.getSelectedItem()); Settings.getLastProfile().setSelectedVersion((String) cboVersions.getSelectedItem());
}//GEN-LAST:event_cboVersionsItemStateChanged }//GEN-LAST:event_cboVersionsItemStateChanged
// <editor-fold defaultstate="collapsed" desc="UI Events"> // <editor-fold defaultstate="collapsed" desc="UI Events">
@ -1131,7 +1133,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
try { try {
String path = fc.getSelectedFile().getCanonicalPath(); String path = fc.getSelectedFile().getCanonicalPath();
txtGameDir.setText(path); txtGameDir.setText(path);
Settings.getLastProfile().setGameDir(path); Settings.getLastProfile().setGameDir(fc.getSelectedFile());
} catch (IOException e) { } catch (IOException e) {
HMCLog.warn("Failed to set game dir.", e); HMCLog.warn("Failed to set game dir.", e);
MessageBox.show(C.i18n("ui.label.failed_set") + e.getMessage()); MessageBox.show(C.i18n("ui.label.failed_set") + e.getMessage());
@ -1216,7 +1218,7 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
}//GEN-LAST:event_txtWidthFocusLost }//GEN-LAST:event_txtWidthFocusLost
private void txtGameDirFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtGameDirFocusLost private void txtGameDirFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtGameDirFocusLost
Settings.getLastProfile().setGameDir(txtGameDir.getText()); Settings.getLastProfile().setGameDir(new File(txtGameDir.getText()));
loadVersions(); loadVersions();
}//GEN-LAST:event_txtGameDirFocusLost }//GEN-LAST:event_txtGameDirFocusLost
@ -1512,11 +1514,11 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
final Consumer<ProfileChangedEvent> onSelectedProfilesChanged = event -> { final Consumer<ProfileChangedEvent> onSelectedProfilesChanged = event -> {
Profile t = event.getValue(); Profile t = event.getValue();
t.propertyChanged.register(e -> { t.propertyChanged.register(e -> {
if ("selectedMinecraftVersion".equals(e.getPropertyName())) if ("selectedVersion".equals(e.getPropertyName()))
versionChanged(e.getNewValue()); versionChanged(e.getNewValue());
}); });
txtGameDir.setText(t.getGameDir()); txtGameDir.setText(t.getGameDir().getPath());
isLoading = true; isLoading = true;
DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) cboProfiles.getModel(); DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) cboProfiles.getModel();

View File

@ -352,7 +352,7 @@ public class MainPagePanel extends Page {
if (isLoading || evt.getStateChange() != ItemEvent.SELECTED || cboVersions.getSelectedIndex() < 0 || StrUtils.isBlank((String) cboVersions.getSelectedItem())) if (isLoading || evt.getStateChange() != ItemEvent.SELECTED || cboVersions.getSelectedIndex() < 0 || StrUtils.isBlank((String) cboVersions.getSelectedItem()))
return; return;
String mcv = (String) cboVersions.getSelectedItem(); String mcv = (String) cboVersions.getSelectedItem();
Settings.getLastProfile().setSelectedMinecraftVersion(mcv); Settings.getLastProfile().setSelectedVersion(mcv);
}//GEN-LAST:event_cboVersionsItemStateChanged }//GEN-LAST:event_cboVersionsItemStateChanged
private void txtPasswordFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPasswordFocusGained private void txtPasswordFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPasswordFocusGained
@ -533,7 +533,7 @@ public class MainPagePanel extends Page {
final Consumer<ProfileChangedEvent> onSelectedProfilesChanged = event -> { final Consumer<ProfileChangedEvent> onSelectedProfilesChanged = event -> {
Profile t = event.getValue(); Profile t = event.getValue();
t.propertyChanged.register(e -> { t.propertyChanged.register(e -> {
if ("selectedMinecraftVersion".equals(e.getPropertyName())) if ("selectedVersion".equals(e.getPropertyName()))
versionChanged(e.getNewValue()); versionChanged(e.getNewValue());
}); });

View File

@ -64,8 +64,7 @@ public class HMCLGameLauncher {
return; return;
setLaunching(true); setLaunching(true);
HMCLog.log("Start generating launching command..."); HMCLog.log("Start generating launching command...");
File file = profile.getCanonicalGameDirFile(); if (!profile.getGameDir().exists()) {
if (!file.exists()) {
failed.accept(C.i18n("minecraft.wrong_path")); failed.accept(C.i18n("minecraft.wrong_path"));
setLaunching(false); setLaunching(false);
return; return;
@ -84,7 +83,7 @@ public class HMCLGameLauncher {
public void run() { public void run() {
Thread.currentThread().setName("Game Launcher"); Thread.currentThread().setName("Game Launcher");
try { try {
LaunchOptions options = profile.getSelectedVersionSetting().createLaunchOptions(profile.getCanonicalGameDirFile()); LaunchOptions options = profile.getSelectedVersionSetting().createLaunchOptions(profile.getGameDir());
HMCLApi.EVENT_BUS.fireChannel(new ProcessingLaunchOptionsEvent(this, options)); HMCLApi.EVENT_BUS.fireChannel(new ProcessingLaunchOptionsEvent(this, options));
DefaultGameLauncher gl = new DefaultGameLauncher(options, profile.service(), li, l); DefaultGameLauncher gl = new DefaultGameLauncher(options, profile.service(), li, l);
GameLauncherTag tag = new GameLauncherTag(); GameLauncherTag tag = new GameLauncherTag();

View File

@ -22,7 +22,6 @@ import org.jackhuang.hmcl.core.service.IMinecraftAssetService;
import org.jackhuang.hmcl.core.service.IMinecraftLoader; import org.jackhuang.hmcl.core.service.IMinecraftLoader;
import org.jackhuang.hmcl.core.service.IMinecraftDownloadService; import org.jackhuang.hmcl.core.service.IMinecraftDownloadService;
import org.jackhuang.hmcl.core.service.IMinecraftProvider; import org.jackhuang.hmcl.core.service.IMinecraftProvider;
import org.jackhuang.hmcl.util.C;
import org.jackhuang.hmcl.core.service.IMinecraftModService; import org.jackhuang.hmcl.core.service.IMinecraftModService;
import org.jackhuang.hmcl.core.service.IMinecraftInstallerService; import org.jackhuang.hmcl.core.service.IMinecraftInstallerService;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
@ -141,7 +140,7 @@ public class HMCLMinecraftService extends IMinecraftService {
@Override @Override
public File baseDirectory() { public File baseDirectory() {
return p.getCanonicalGameDirFile(); return p.getGameDir();
} }
protected IMinecraftProvider provider; protected IMinecraftProvider provider;

View File

@ -50,7 +50,7 @@ public class NewFileUpgrader extends IUpgrader {
File newf = new File(FileUtils.getName(str)); File newf = new File(FileUtils.getName(str));
if (TaskWindow.factory().append(new FileDownloadTask(str, newf)).execute()) { if (TaskWindow.factory().append(new FileDownloadTask(str, newf)).execute()) {
try { try {
new ProcessBuilder(new String[] { IOUtils.tryGetCanonicalFilePath(newf), "--removeOldLauncher", IOUtils.getRealPath() }).directory(new File(".")).start(); new ProcessBuilder(new String[] { newf.getCanonicalPath(), "--removeOldLauncher", IOUtils.getRealPath() }).directory(new File(".")).start();
} catch (IOException ex) { } catch (IOException ex) {
HMCLog.err("Failed to start new app", ex); HMCLog.err("Failed to start new app", ex);
} }

View File

@ -17,8 +17,15 @@
*/ */
package org.jackhuang.hmcl.api; package org.jackhuang.hmcl.api;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import org.jackhuang.hmcl.api.ui.AddTabCallback; import org.jackhuang.hmcl.api.ui.AddTabCallback;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.swing.JFrame; import javax.swing.JFrame;
import org.jackhuang.hmcl.api.auth.IAuthenticator; import org.jackhuang.hmcl.api.auth.IAuthenticator;
import org.jackhuang.hmcl.api.func.Consumer; import org.jackhuang.hmcl.api.func.Consumer;
@ -30,6 +37,7 @@ import org.jackhuang.hmcl.api.func.Consumer;
*/ */
public class PluginManager { public class PluginManager {
private static final File PLUGINS_FILE = new File("plugins/");
private static final ArrayList<IPlugin> PLUGINS = new ArrayList<>(); private static final ArrayList<IPlugin> PLUGINS = new ArrayList<>();
public static void getPlugin(Class<?> cls) { public static void getPlugin(Class<?> cls) {
@ -52,4 +60,35 @@ public class PluginManager {
p.onAddTab(frame, callback); p.onAddTab(frame, callback);
} }
public static void loadPlugins() {
ArrayList<URL> urls = new ArrayList<>();
ArrayList<JarFile> jars = new ArrayList<>();
if (PLUGINS_FILE.isDirectory()) {
for (File f : PLUGINS_FILE.listFiles(f -> f.isFile() && f.getName().endsWith(".jar")))
try {
jars.add(new JarFile(f));
urls.add(f.toURI().toURL());
} catch (IOException e) {
System.err.println("A malformed jar file: " + f);
e.printStackTrace();
}
URLClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]));
for (JarFile f : jars)
for (Enumeration<JarEntry> entries = f.entries(); entries.hasMoreElements();)
try {
JarEntry entry = entries.nextElement();
String clsName = entry.getName();
if (clsName.endsWith(".class") && !clsName.contains("$")) {
clsName = clsName.replace('/', '.').replace(".class", "");
Class clazz = classLoader.loadClass(clsName);
if (IPlugin.class.isAssignableFrom(clazz))
getPlugin(clazz);
}
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
}
} }

View File

@ -36,7 +36,6 @@ import org.jackhuang.hmcl.util.task.Task;
import org.jackhuang.hmcl.util.task.TaskWindow; import org.jackhuang.hmcl.util.task.TaskWindow;
import org.jackhuang.hmcl.util.net.FileDownloadTask; import org.jackhuang.hmcl.util.net.FileDownloadTask;
import org.jackhuang.hmcl.util.sys.FileUtils; import org.jackhuang.hmcl.util.sys.FileUtils;
import org.jackhuang.hmcl.util.sys.IOUtils;
import org.jackhuang.hmcl.util.task.TaskInfo; import org.jackhuang.hmcl.util.task.TaskInfo;
/** /**
@ -84,7 +83,7 @@ public class MinecraftAssetService extends IMinecraftAssetService {
return new TaskInfo("Download Asset Index") { return new TaskInfo("Download Asset Index") {
@Override @Override
public Collection<Task> getDependTasks() { public Collection<Task> getDependTasks() {
return Arrays.asList(new FileDownloadTask(assetIndex.getUrl(service.getDownloadType()), IOUtils.tryGetCanonicalFile(assetsIndex), assetIndex.sha1).setTag(assetIndex.getId() + ".json")); return Arrays.asList(new FileDownloadTask(assetIndex.getUrl(service.getDownloadType()), assetsIndex, assetIndex.sha1).setTag(assetIndex.getId() + ".json"));
} }
@Override @Override
@ -111,7 +110,7 @@ public class MinecraftAssetService extends IMinecraftAssetService {
HMCLog.warn("Failed to rename " + assetsIndex + " to " + renamed); HMCLog.warn("Failed to rename " + assetsIndex + " to " + renamed);
} }
if (TaskWindow.factory() if (TaskWindow.factory()
.append(new FileDownloadTask(assetIndex.getUrl(service.getDownloadType()), IOUtils.tryGetCanonicalFile(assetsIndex), assetIndex.sha1).setTag(assetIndex.getId() + ".json")) .append(new FileDownloadTask(assetIndex.getUrl(service.getDownloadType()), assetsIndex, assetIndex.sha1).setTag(assetIndex.getId() + ".json"))
.execute()) { .execute()) {
if (renamed != null && !renamed.delete()) if (renamed != null && !renamed.delete())
HMCLog.warn("Failed to delete " + renamed + ", maybe you should do it."); HMCLog.warn("Failed to delete " + renamed + ", maybe you should do it.");

View File

@ -28,7 +28,6 @@ import org.jackhuang.hmcl.core.install.optifine.OptiFineInstaller;
import org.jackhuang.hmcl.core.install.optifine.vanilla.OptiFineDownloadFormatter; import org.jackhuang.hmcl.core.install.optifine.vanilla.OptiFineDownloadFormatter;
import org.jackhuang.hmcl.util.task.Task; import org.jackhuang.hmcl.util.task.Task;
import org.jackhuang.hmcl.util.net.FileDownloadTask; import org.jackhuang.hmcl.util.net.FileDownloadTask;
import org.jackhuang.hmcl.util.sys.IOUtils;
import org.jackhuang.hmcl.util.task.DeleteFileTask; import org.jackhuang.hmcl.util.task.DeleteFileTask;
/** /**
@ -57,7 +56,7 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
@Override @Override
public Task downloadForge(String installId, InstallerVersion v) { public Task downloadForge(String installId, InstallerVersion v) {
File filepath = IOUtils.tryGetCanonicalFile("forge-installer.jar"); File filepath = new File("forge-installer.jar");
if (v.installer == null) if (v.installer == null)
return null; return null;
else else
@ -68,7 +67,7 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
@Override @Override
public Task downloadOptiFine(String installId, InstallerVersion v) { public Task downloadOptiFine(String installId, InstallerVersion v) {
File filepath = IOUtils.tryGetCanonicalFile("optifine-installer.jar"); File filepath = new File("optifine-installer.jar");
if (v.installer == null) if (v.installer == null)
return null; return null;
OptiFineDownloadFormatter task = new OptiFineDownloadFormatter(v.installer); OptiFineDownloadFormatter task = new OptiFineDownloadFormatter(v.installer);
@ -81,7 +80,7 @@ public final class MinecraftInstallerService extends IMinecraftInstallerService
public Task downloadLiteLoader(String installId, InstallerVersion v) { public Task downloadLiteLoader(String installId, InstallerVersion v) {
if (!(v instanceof LiteLoaderInstallerVersion)) if (!(v instanceof LiteLoaderInstallerVersion))
throw new Error("Download lite loader but the version is not ll's."); throw new Error("Download lite loader but the version is not ll's.");
File filepath = IOUtils.tryGetCanonicalFile("liteloader-universal.jar"); File filepath = new File("liteloader-universal.jar");
FileDownloadTask task = (FileDownloadTask) new FileDownloadTask(v.universal, filepath).setTag("LiteLoader"); FileDownloadTask task = (FileDownloadTask) new FileDownloadTask(v.universal, filepath).setTag("LiteLoader");
return task.with(new LiteLoaderInstaller(service, installId, (LiteLoaderInstallerVersion) v).registerPreviousResult(task)) return task.with(new LiteLoaderInstaller(service, installId, (LiteLoaderInstallerVersion) v).registerPreviousResult(task))
.with(new DeleteFileTask(filepath)); .with(new DeleteFileTask(filepath));

View File

@ -45,7 +45,6 @@ import org.jackhuang.hmcl.util.StrUtils;
import org.jackhuang.hmcl.util.code.Charsets; import org.jackhuang.hmcl.util.code.Charsets;
import org.jackhuang.hmcl.api.HMCLog; import org.jackhuang.hmcl.api.HMCLog;
import org.jackhuang.hmcl.util.sys.FileUtils; import org.jackhuang.hmcl.util.sys.FileUtils;
import org.jackhuang.hmcl.util.sys.IOUtils;
import org.jackhuang.hmcl.util.sys.JavaProcess; import org.jackhuang.hmcl.util.sys.JavaProcess;
import org.jackhuang.hmcl.util.sys.OS; import org.jackhuang.hmcl.util.sys.OS;
import org.jackhuang.hmcl.api.auth.IAuthenticator; import org.jackhuang.hmcl.api.auth.IAuthenticator;
@ -93,6 +92,7 @@ public class GameLauncher {
/** /**
* Generates the launch command. * Generates the launch command.
*
* @throws AuthenticationException having trouble logging in. * @throws AuthenticationException having trouble logging in.
* @throws GameException having trouble completing the game or making lanch command. * @throws GameException having trouble completing the game or making lanch command.
* @throws RuntimeGameException will be thrown when someone processing login result. * @throws RuntimeGameException will be thrown when someone processing login result.
@ -191,13 +191,10 @@ public class GameLauncher {
if (isWin) { if (isWin) {
writer.write("@echo off"); writer.write("@echo off");
writer.newLine(); writer.newLine();
String appdata = IOUtils.tryGetCanonicalFilePath(service.baseDirectory()); writer.write("set appdata=" + service.baseDirectory().getAbsolutePath());
if (appdata != null) { writer.newLine();
writer.write("set appdata=" + appdata); writer.write("cd /D %appdata%");
writer.newLine(); writer.newLine();
writer.write("cd /D %appdata%");
writer.newLine();
}
} }
if (StrUtils.isNotBlank(options.getPrecalledCommand())) { if (StrUtils.isNotBlank(options.getPrecalledCommand())) {
writer.write(options.getPrecalledCommand()); writer.write(options.getPrecalledCommand());

View File

@ -25,7 +25,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import org.jackhuang.hmcl.util.StrUtils; import org.jackhuang.hmcl.util.StrUtils;
import org.jackhuang.hmcl.api.HMCLog; import org.jackhuang.hmcl.api.HMCLog;
import org.jackhuang.hmcl.util.sys.IOUtils;
import org.jackhuang.hmcl.util.sys.OS; import org.jackhuang.hmcl.util.sys.OS;
import org.jackhuang.hmcl.core.GameException; import org.jackhuang.hmcl.core.GameException;
import org.jackhuang.hmcl.api.auth.UserProfileProvider; import org.jackhuang.hmcl.api.auth.UserProfileProvider;
@ -66,7 +65,7 @@ public class MinecraftLoader extends AbstractMinecraftLoader {
File f = version.getJar(service.baseDirectory()); File f = version.getJar(service.baseDirectory());
if (!f.exists()) if (!f.exists())
throw new GameException("Minecraft jar does not exists"); throw new GameException("Minecraft jar does not exists");
library.append(IOUtils.tryGetCanonicalFilePath(f)).append(File.pathSeparator); library.append(f.getAbsolutePath()).append(File.pathSeparator);
res.add("-cp"); res.add("-cp");
res.add(library.toString().substring(0, library.length() - File.pathSeparator.length())); res.add(library.toString().substring(0, library.length() - File.pathSeparator.length()));
res.add(version.mainClass); res.add(version.mainClass);

View File

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

View File

@ -39,7 +39,6 @@ import org.jackhuang.hmcl.core.service.IMinecraftService;
import org.jackhuang.hmcl.util.sys.FileUtils; import org.jackhuang.hmcl.util.sys.FileUtils;
import org.jackhuang.hmcl.core.MCUtils; import org.jackhuang.hmcl.core.MCUtils;
import org.jackhuang.hmcl.util.task.TaskWindow; import org.jackhuang.hmcl.util.task.TaskWindow;
import org.jackhuang.hmcl.util.sys.IOUtils;
import org.jackhuang.hmcl.util.MessageBox; import org.jackhuang.hmcl.util.MessageBox;
import org.jackhuang.hmcl.util.StrUtils; import org.jackhuang.hmcl.util.StrUtils;
import org.jackhuang.hmcl.api.func.Consumer; import org.jackhuang.hmcl.api.func.Consumer;
@ -233,7 +232,7 @@ public class MinecraftVersionManager extends IMinecraftProvider {
ArrayList<Extract> extractRules = new ArrayList<>(); ArrayList<Extract> extractRules = new ArrayList<>();
for (IMinecraftLibrary l : v.libraries) for (IMinecraftLibrary l : v.libraries)
if (l.isRequiredToUnzip() && v.isAllowedToUnpackNatives()) { if (l.isRequiredToUnzip() && v.isAllowedToUnpackNatives()) {
unzippings.add(IOUtils.tryGetCanonicalFile(getLibraryFile(v, l))); unzippings.add(getLibraryFile(v, l));
extractRules.add(l.getDecompressExtractRules()); extractRules.add(l.getDecompressExtractRules());
} }
return new DecompressLibraryJob(unzippings.toArray(new File[unzippings.size()]), extractRules.toArray(new Extract[extractRules.size()]), getDecompressNativesToLocation(v)); return new DecompressLibraryJob(unzippings.toArray(new File[unzippings.size()]), extractRules.toArray(new Extract[extractRules.size()]), getDecompressNativesToLocation(v));

View File

@ -101,7 +101,7 @@ public final class IOUtils {
public static String getRealPath() { public static String getRealPath() {
String realPath = IOUtils.class.getClassLoader().getResource("").getFile(); String realPath = IOUtils.class.getClassLoader().getResource("").getFile();
java.io.File file = new java.io.File(realPath); File file = new File(realPath);
realPath = file.getAbsolutePath(); realPath = file.getAbsolutePath();
try { try {
realPath = java.net.URLDecoder.decode(realPath, DEFAULT_CHARSET); realPath = java.net.URLDecoder.decode(realPath, DEFAULT_CHARSET);
@ -229,34 +229,6 @@ public final class IOUtils {
output.write(data.getBytes(encoding)); output.write(data.getBytes(encoding));
} }
public static String tryGetCanonicalFolderPath(File file) {
try {
return IOUtils.addSeparator(file.getCanonicalPath());
} catch (IOException ignored) {
return IOUtils.addSeparator(file.getAbsolutePath());
}
}
public static File tryGetCanonicalFile(File file) {
try {
return file.getCanonicalFile();
} catch (IOException ignored) {
return file.getAbsoluteFile();
}
}
public static File tryGetCanonicalFile(String file) {
return tryGetCanonicalFile(new File(file));
}
public static String tryGetCanonicalFilePath(File file) {
try {
return file.getCanonicalPath();
} catch (IOException ignored) {
return file.getAbsolutePath();
}
}
public static URL parseURL(String str) { public static URL parseURL(String str) {
try { try {
return new URL(str); return new URL(str);

View File

@ -124,7 +124,7 @@ public class InstructionsPanelImpl extends JComponent implements WizardObserver,
if (img == null) if (img == null)
try { try {
img = ImageIO.read(InstructionsPanelImpl.class.getResourceAsStream( img = ImageIO.read(InstructionsPanelImpl.class.getResourceAsStream(
"/org/jackhuang/hellominecraft/wizard.jpg")); "/org/jackhuang/hmcl/wizard.jpg"));
} catch (IOException ioe) { } catch (IOException ioe) {
HMCLog.err("Failed to load wizard.jpg, maybe you fucking modified the launcher", ioe); HMCLog.err("Failed to load wizard.jpg, maybe you fucking modified the launcher", ioe);
} }