mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-10 04:16:02 -04:00
Load plugins from jar file
This commit is contained in:
parent
413854d1f1
commit
5f65496500
@ -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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.");
|
||||||
|
@ -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));
|
||||||
|
@ -45,13 +45,12 @@ 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;
|
||||||
|
|
||||||
public class GameLauncher {
|
public class GameLauncher {
|
||||||
|
|
||||||
LaunchOptions options;
|
LaunchOptions options;
|
||||||
IMinecraftService service;
|
IMinecraftService service;
|
||||||
LoginInfo info;
|
LoginInfo info;
|
||||||
@ -80,7 +79,7 @@ public class GameLauncher {
|
|||||||
public UserProfileProvider getLoginResult() {
|
public UserProfileProvider getLoginResult() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object tag;
|
private Object tag;
|
||||||
|
|
||||||
public Object getTag() {
|
public Object getTag() {
|
||||||
@ -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());
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
}
|
@ -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));
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user