mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-04-24 18:50:52 +08:00
HMCL 2.3.2
This commit is contained in:
parent
0693d12f6b
commit
0656227183
.gitignore.nb-gradle-properties
HMCL
build.gradleicon.ico
image
3J33V83MSXJ6FSO4%WBZR7A.pngA.jpgK0B_H3C~2_PSK_[SB)([))E.pngN9_Q[X2BQ{9$@S14RX%3}0M.pngWO(NA%0}M$9BCRR62ZN{%87.pngbackground.jpg
launch4j.xmlproguard.prosrc/main
icon.icns
java/org/jackhuang
hellominecraft/launcher
Launcher.javaMain.java
launch
DefaultGameLauncher.javaGameLauncher.javaGameLauncherRequest.javaIMinecraftLoader.javaIMinecraftProvider.javaLaunchFinisher.javaLaunchScriptFinisher.javaMinecraftCrashAdvicer.javaMinecraftLoader.java
utils
CrashReport.javaMCUtils.java
assets
AssetsIndex.javaAssetsLoader.javaAssetsLoaderListener.javaAssetsMojangLoader.javaAssetsMojangOldLoader.javaAssetsObject.javaContents.javaIAssetsHandler.java
auth
BestLogin.javaIAuthenticator.javaLoginInfo.javaOfflineAuthenticator.javaSkinmeAuthenticator.javaUserProfileProvider.javaYggdrasilAuthenticator.java
download
installers
InstallProfile.javaInstallerVersionList.javaInstallerVersionNewerComparator.javaPackMinecraftInstaller.java
forge
liteloader
LiteLoaderInstaller.javaLiteLoaderMCVersions.javaLiteLoaderVersion.javaLiteLoaderVersionList.javaLiteLoaderVersionsMeta.javaLiteLoaderVersionsRoot.java
optifine
settings
version
views
mojang/authlib
13
.gitignore
vendored
13
.gitignore
vendored
@ -10,3 +10,16 @@
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
.gradle
|
||||
.nb-gradle
|
||||
|
||||
*.map
|
||||
*.bat
|
||||
*.log
|
||||
.mine*
|
||||
|
||||
HMCLAPI/build/
|
||||
HMCL/build/
|
||||
HMCSM/build/
|
||||
MetroLookAndFeel/build/
|
46
.nb-gradle-properties
Normal file
46
.nb-gradle-properties
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<gradle-project-properties>
|
||||
<!--DO NOT EDIT THIS FILE! - Used by the Gradle plugin of NetBeans.-->
|
||||
<target-platform-name>j2se</target-platform-name>
|
||||
<target-platform>1.8</target-platform>
|
||||
<source-level>1.8</source-level>
|
||||
<common-tasks>
|
||||
<task>
|
||||
<display-name>launch4j</display-name>
|
||||
<non-blocking>no</non-blocking>
|
||||
<task-names>
|
||||
<name must-exist="no">launch4j</name>
|
||||
</task-names>
|
||||
<task-args/>
|
||||
<task-jvm-args/>
|
||||
</task>
|
||||
<task>
|
||||
<display-name>launch4jpack</display-name>
|
||||
<non-blocking>no</non-blocking>
|
||||
<task-names>
|
||||
<name must-exist="no">launch4jpack</name>
|
||||
</task-names>
|
||||
<task-args/>
|
||||
<task-jvm-args/>
|
||||
</task>
|
||||
<task>
|
||||
<display-name>publish</display-name>
|
||||
<non-blocking>no</non-blocking>
|
||||
<task-names>
|
||||
<name must-exist="no">clean</name>
|
||||
<name must-exist="no">build</name>
|
||||
<name must-exist="no">launch4j</name>
|
||||
</task-names>
|
||||
<task-args/>
|
||||
<task-jvm-args/>
|
||||
</task>
|
||||
</common-tasks>
|
||||
<script-platform>
|
||||
<spec-name>j2se</spec-name>
|
||||
<spec-version>1.8</spec-version>
|
||||
</script-platform>
|
||||
<license-header>
|
||||
<name>GNU General Public License</name>
|
||||
<property name="organization">huangyuhui</property>
|
||||
</license-header>
|
||||
</gradle-project-properties>
|
95
HMCL/build.gradle
Normal file
95
HMCL/build.gradle
Normal file
@ -0,0 +1,95 @@
|
||||
apply plugin: 'launch4j'
|
||||
apply plugin: 'me.tatarka.retrolambda'
|
||||
|
||||
if (!hasProperty('mainClass')) {
|
||||
ext.mainClass = 'org.jackhuang.hellominecraft.launcher.Main'
|
||||
}
|
||||
|
||||
String mavenGroupId = 'HMCL'
|
||||
String mavenVersion = '2.3.2'
|
||||
String bundleName = "Hello Minecraft! Launcher"
|
||||
|
||||
group = mavenGroupId
|
||||
version = mavenVersion
|
||||
|
||||
String mavenArtifactId = name
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral();
|
||||
|
||||
dependencies {
|
||||
classpath 'net.sf.proguard:proguard-gradle:4.10'
|
||||
classpath 'edu.sc.seis.gradle:launch4j:1.0.6'
|
||||
classpath 'me.tatarka:gradle-retrolambda:3.1.0'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configure(install.repositories.mavenInstaller) {
|
||||
pom.project {
|
||||
groupId = mavenGroupId
|
||||
artifactId = mavenArtifactId
|
||||
version = mavenVersion
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(":MetroLookAndFeel")
|
||||
compile project(":HMCLAPI")
|
||||
}
|
||||
|
||||
retrolambda {
|
||||
javaVersion = JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
jar {
|
||||
jar.classifier = 'base'
|
||||
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
|
||||
manifest {
|
||||
attributes 'Created-By' : 'Copyright(c) 2013-2014 huangyuhui.',
|
||||
'Main-Class' : mainClass
|
||||
}
|
||||
}
|
||||
|
||||
task proguard(type: proguard.gradle.ProGuardTask, dependsOn: jar) {
|
||||
ext {
|
||||
def re = jar.classifier
|
||||
injar = jar.archivePath
|
||||
jar.classifier = ''
|
||||
outjar = jar.archivePath
|
||||
jar.classifier = re
|
||||
}
|
||||
|
||||
injars injar
|
||||
outjars outjar
|
||||
printusage "shrinking_" + version + ".map"
|
||||
printmapping "obfuscate_" + version + ".map"
|
||||
|
||||
configuration 'proguard.pro'
|
||||
}
|
||||
|
||||
launch4j {
|
||||
launch4jCmd = 'D:\\Develop\\Java\\Launch4j\\launch4j.exe'
|
||||
supportUrl = 'http://www.mcbbs.net/thread-142335-1-1.html'
|
||||
jreMinVersion = '1.6.0'
|
||||
|
||||
mainClassName = mainClass
|
||||
icon = new File(project.buildDir, '../icon.ico').absolutePath
|
||||
version = mavenVersion + '.0'
|
||||
downloadUrl = 'http://java.com/download'
|
||||
copyright = "Copyright(c) 2013-2014 huangyuhui."
|
||||
|
||||
jar = new File(project.buildDir, 'libs/' + mavenGroupId + '-' + mavenVersion + '.jar').absolutePath
|
||||
outfile = mavenGroupId + '-' + mavenVersion + '.exe'
|
||||
messagesJreVersionError = 'This application requires a Java Runtime Environment installation, or the runtime is corrupted.\n\u6ca1\u6709\u627e\u5230\u004a\u0061\u0076\u0061\u8fd0\u884c\u65f6\uff0c\u8bf7\u4e0d\u8981\u4f7f\u7528\u7eff\u8272\u004a\u0061\u0076\u0061\uff0c\u8bf7\u4f7f\u7528\u5b89\u88c5\u7248\u7684\u004a\u0061\u0076\u0061\uff0c\u70b9\u51fb\u786e\u5b9a\u8fdb\u5165\u004a\u0061\u0076\u0061\u5b89\u88c5\u9875\u9762\u3002'
|
||||
}
|
||||
|
||||
processResources {
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'icon.icns'
|
||||
}
|
||||
}
|
||||
|
||||
build.dependsOn proguard
|
BIN
HMCL/icon.ico
Normal file
BIN
HMCL/icon.ico
Normal file
Binary file not shown.
After (image error) Size: 4.2 KiB |
BIN
HMCL/image/3J33V83MSXJ6FSO4%WBZR7A.png
Normal file
BIN
HMCL/image/3J33V83MSXJ6FSO4%WBZR7A.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 573 KiB |
BIN
HMCL/image/A.jpg
Normal file
BIN
HMCL/image/A.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 63 KiB |
BIN
HMCL/image/K0B_H3C~2_PSK_[SB)([))E.png
Normal file
BIN
HMCL/image/K0B_H3C~2_PSK_[SB)([))E.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 309 KiB |
BIN
HMCL/image/N9_Q[X2BQ{9$@S14RX%3}0M.png
Normal file
BIN
HMCL/image/N9_Q[X2BQ{9$@S14RX%3}0M.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 248 KiB |
BIN
HMCL/image/WO(NA%0}M$9BCRR62ZN{%87.png
Normal file
BIN
HMCL/image/WO(NA%0}M$9BCRR62ZN{%87.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 657 KiB |
BIN
HMCL/image/background.jpg
Normal file
BIN
HMCL/image/background.jpg
Normal file
Binary file not shown.
After ![]() (image error) Size: 78 KiB |
41
HMCL/launch4j.xml
Normal file
41
HMCL/launch4j.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<launch4jConfig>
|
||||
<dontWrapJar>false</dontWrapJar>
|
||||
<headerType>gui</headerType>
|
||||
<jar>F:\Documents\NetBeansProjects\HMCL\HMCL\build\libs\HMCL-2.1.3.jar</jar>
|
||||
<outfile>F:\Documents\NetBeansProjects\HMCL\HMCL\build\libs\HMCL-2.1.3-Launch4j.exe</outfile>
|
||||
<errTitle></errTitle>
|
||||
<cmdLine></cmdLine>
|
||||
<chdir></chdir>
|
||||
<priority>normal</priority>
|
||||
<downloadUrl>http://java.com/download</downloadUrl>
|
||||
<supportUrl></supportUrl>
|
||||
<stayAlive>false</stayAlive>
|
||||
<manifest></manifest>
|
||||
<icon>F:\Documents\NetBeansProjects\HMCL\HMCL\icon.ico</icon>
|
||||
<jre>
|
||||
<path></path>
|
||||
<bundledJre64Bit>false</bundledJre64Bit>
|
||||
<minVersion>1.6.0</minVersion>
|
||||
<maxVersion></maxVersion>
|
||||
<jdkPreference>preferJre</jdkPreference>
|
||||
</jre>
|
||||
<versionInfo>
|
||||
<fileVersion>2.1.3.0</fileVersion>
|
||||
<txtFileVersion>2.1.3.0</txtFileVersion>
|
||||
<fileDescription>Hello Minecraft! Launcher</fileDescription>
|
||||
<copyright>Copyright(c) 2013~2014 huangyuhui</copyright>
|
||||
<productVersion>2.1.3.0</productVersion>
|
||||
<txtProductVersion>2.1.3.0</txtProductVersion>
|
||||
<productName>Hello Minecraft! Launcher</productName>
|
||||
<companyName></companyName>
|
||||
<internalName>Hello Minecraft! Launcher</internalName>
|
||||
<originalFilename>HMCL-2.1.3.exe</originalFilename>
|
||||
</versionInfo>
|
||||
<messages>
|
||||
<startupErr>启动程序时出现错误</startupErr>
|
||||
<bundledJreErr>未找到内置Java</bundledJreErr>
|
||||
<jreVersionErr>此程序需要Java</jreVersionErr>
|
||||
<launcherErr>未找到Java</launcherErr>
|
||||
<instanceAlreadyExistsMsg>已存在一个程序实例</instanceAlreadyExistsMsg>
|
||||
</messages>
|
||||
</launch4jConfig>
|
77
HMCL/proguard.pro
vendored
Normal file
77
HMCL/proguard.pro
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
-libraryjars D:\Develop\Java\jdk1.6.0_45\jre\lib\rt.jar
|
||||
-libraryjars D:\Develop\Java\jdk1.6.0_45\jre\lib\jce.jar
|
||||
-libraryjars D:\Develop\Java\jdk1.6.0_45\jre\lib\jsse.jar
|
||||
|
||||
-dontoptimize
|
||||
-dontshrink
|
||||
-dontwarn java.lang.invoke.*
|
||||
|
||||
-overloadaggressively
|
||||
-repackageclasses 'org.jackhuang.hellominecraft.launcher'
|
||||
-allowaccessmodification
|
||||
|
||||
-renamesourcefileattribute SourceFile
|
||||
|
||||
-keepattributes *Annotation*,SourceFile,LineNumberTable,Signature
|
||||
|
||||
-keep class com.** { *; }
|
||||
-keep class org.jackhuang.hellominecraft.lookandfeel.* { *; }
|
||||
-keep class org.jackhuang.hellominecraft.lookandfeel.painters.* { *; }
|
||||
-keep class org.jackhuang.hellominecraft.lookandfeel.ui.* { *; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.Agent { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.UserType { *; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.properties.Property { *; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.minecraft.MinecraftProfileTexture$Type { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.minecraft.MinecraftProfileTexture { *; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.request.AuthenticationRequest { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.request.InvalidateRequest { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.request.JoinMinecraftServerRequest { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.request.RefreshRequest { *; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.AuthenticationResponse { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.HasJoinedMinecraftServerResponse { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.ProfileSearchResultsResponse { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.RefreshResponse { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.Response { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.User { *; }
|
||||
|
||||
-keep class org.jackhuang.hellominecraft.launcher.Main { public static void main(java.lang.String[]); }
|
||||
-keep class org.jackhuang.hellominecraft.launcher.Launcher { public static void main(java.lang.String[]); }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.settings.Profile { private <fields>; public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.settings.Config { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.assets.AssetsObject { <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.assets.AssetsIndex { <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.version.MinecraftLibrary { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.version.IMinecraftLibrary { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.version.Natives { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.version.OS { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.version.Rules { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersion { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.InstallProfile { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.Install { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.vanilla.MinecraftForgeVersionRoot { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.vanilla.MinecraftForgeVersion { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.bmcl.ForgeVersion { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.bmcl.Downloads { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.optifine.OptiFineVersion { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderVersionsRoot { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderMCVersions { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderVersion { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderVersionsMeta { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.version.MinecraftRemoteLatestVersion { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.version.MinecraftRemoteVersion { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.version.MinecraftRemoteVersions { public <fields>; }
|
BIN
HMCL/src/main/icon.icns
Normal file
BIN
HMCL/src/main/icon.icns
Normal file
Binary file not shown.
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.functions.TrueDoneListener;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.views.LogWindow;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.MinecraftCrashAdvicer;
|
||||
import org.jackhuang.hellominecraft.utils.DoubleOutputStream;
|
||||
import org.jackhuang.hellominecraft.utils.JdkVersion;
|
||||
import org.jackhuang.hellominecraft.utils.LauncherPrintStream;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.OS;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class Launcher {
|
||||
|
||||
private static final Launcher instance = new Launcher();
|
||||
|
||||
public static void println(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
println("*** " + Main.makeTitle() + " ***");
|
||||
|
||||
Thread.currentThread().setName("launcher");
|
||||
try {
|
||||
File logFile = new File("hmclmc.log");
|
||||
if (!logFile.exists()) logFile.createNewFile();
|
||||
FileOutputStream tc = new FileOutputStream(logFile);
|
||||
DoubleOutputStream out = new DoubleOutputStream(tc, System.out);
|
||||
System.setOut(new LauncherPrintStream(out));
|
||||
DoubleOutputStream err = new DoubleOutputStream(tc, System.err);
|
||||
System.setErr(new LauncherPrintStream(err));
|
||||
} catch (Exception e) {
|
||||
println("Failed to add log file appender.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
LogWindow.instance.setTerminateGame(Utils::shutdownForcely);
|
||||
|
||||
boolean showInfo = false;
|
||||
String classPath = "";
|
||||
String mainClass = "net.minecraft.client.Minecraft";
|
||||
|
||||
ArrayList<String> cmdList = new ArrayList<>();
|
||||
|
||||
for (String s : args)
|
||||
if (s.startsWith("-cp=")) classPath = classPath.concat(s.substring("-cp=".length()));
|
||||
else if (s.startsWith("-mainClass=")) mainClass = s.substring("-mainClass=".length());
|
||||
else if (s.equals("-debug")) showInfo = true;
|
||||
else cmdList.add(s);
|
||||
|
||||
String[] cmds = (String[]) cmdList.toArray(new String[cmdList.size()]);
|
||||
|
||||
String[] tokenized = StrUtils.tokenize(classPath, File.pathSeparator);
|
||||
int len = tokenized.length;
|
||||
|
||||
if (showInfo) {
|
||||
println("Arguments: {\n" + StrUtils.parseParams(" ", args, "\n") + "\n}");
|
||||
println("Main Class: " + mainClass);
|
||||
println("Class Path: {\n" + StrUtils.parseParams(" ", tokenized, "\n") + "\n}");
|
||||
SwingUtilities.invokeLater(() -> LogWindow.instance.setVisible(true));
|
||||
}
|
||||
|
||||
URL[] urls = new URL[len];
|
||||
|
||||
try {
|
||||
for (int j = 0; j < len; j++)
|
||||
urls[j] = new File(tokenized[j]).toURI().toURL();
|
||||
} catch (Throwable e) {
|
||||
MessageBox.Show(C.i18n("crash.main_class_not_found"));
|
||||
println("Failed to get classpath.");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!JdkVersion.isJava64Bit() && OS.is64Bit())
|
||||
MessageBox.Show(C.i18n("advice.os64butjdk32"));
|
||||
|
||||
Method minecraftMain;
|
||||
try {
|
||||
minecraftMain = new URLClassLoader(urls).loadClass(mainClass).getMethod("main", String[].class);
|
||||
} catch (Throwable t) {
|
||||
MessageBox.Show(C.i18n("crash.main_class_not_found"));
|
||||
println("Minecraft main class not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
println("*** Launching Game ***");
|
||||
|
||||
try {
|
||||
minecraftMain.invoke(null, new Object[]{cmds});
|
||||
} catch (Throwable throwable) {
|
||||
HMCLog.err("Cought exception!");
|
||||
final StringWriter trace = new StringWriter();
|
||||
PrintWriter writer = new PrintWriter(trace);
|
||||
throwable.printStackTrace(writer);
|
||||
final String advice = MinecraftCrashAdvicer.getAdvice(throwable);
|
||||
MessageBox.Show(C.i18n("crash.minecraft") + ": " + advice);
|
||||
|
||||
LogWindow.instance.log(C.i18n("crash.minecraft"));
|
||||
LogWindow.instance.log(advice);
|
||||
LogWindow.instance.log(trace.toString());
|
||||
LogWindow.instance.setExit(TrueDoneListener.instance);
|
||||
LogWindow.instance.setVisible(true);
|
||||
}
|
||||
|
||||
println("*** Game Exited ***");
|
||||
}
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.UIManager;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.utils.functions.DoneListener0;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.GameLauncher;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.CrashReport;
|
||||
import org.jackhuang.hellominecraft.logging.Configuration;
|
||||
import org.jackhuang.hellominecraft.logging.appender.ConsoleAppender;
|
||||
import org.jackhuang.hellominecraft.logging.layout.DefaultLayout;
|
||||
import org.jackhuang.hellominecraft.views.LogWindow;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.launcher.views.MainFrame;
|
||||
import org.jackhuang.hellominecraft.lookandfeel.HelloMinecraftLookAndFeel;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class Main implements DoneListener0 {
|
||||
|
||||
public static String launcherName = "Hello Minecraft! Launcher";
|
||||
public static byte firstVer = 2, secondVer = 3, thirdVer = 2;
|
||||
public static int minimumLauncherVersion = 16;
|
||||
|
||||
/**
|
||||
* Make the version of HMCL.
|
||||
*
|
||||
* @return the version: firstVer.secondVer.thirdVer
|
||||
*/
|
||||
public static String makeVersion() {
|
||||
return "" + firstVer + '.' + secondVer + '.' + thirdVer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the main window title.
|
||||
*
|
||||
* @return the MainWindow title.
|
||||
*/
|
||||
public static String makeTitle() {
|
||||
return launcherName + ' ' + makeVersion();
|
||||
}
|
||||
|
||||
public static final Main instance = new Main();
|
||||
|
||||
public static void main(String[] args) {
|
||||
{
|
||||
Thread.setDefaultUncaughtExceptionHandler(new CrashReport(true));
|
||||
|
||||
try {
|
||||
File file = new File("hmcl.log");
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
Configuration.DEFAULT.appenders.add(new ConsoleAppender("File", new DefaultLayout(), true, new FileOutputStream(file), true));
|
||||
} catch (IOException ex) {
|
||||
System.err.println("Failed to add log appender File because an error occurred while creating or opening hmcl.log");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
HMCLog.log("*** " + Main.makeTitle() + " ***");
|
||||
|
||||
LogWindow.instance.clean();
|
||||
LogWindow.instance.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses);
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel(new HelloMinecraftLookAndFeel());
|
||||
} catch (Throwable ex) {
|
||||
HMCLog.warn("Failed to set look and feel...", ex);
|
||||
}
|
||||
|
||||
Settings.UPDATE_CHECKER.start();
|
||||
|
||||
MainFrame.showMainFrame(Settings.isFirstLoad());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDone() {
|
||||
GameLauncher.PROCESS_MANAGER.stopAllProcesses();
|
||||
}
|
||||
|
||||
public static void update() {
|
||||
if (MessageBox.Show(C.i18n("update.newest_version") + Settings.UPDATE_CHECKER.getNewVersion().firstVer + "." + Settings.UPDATE_CHECKER.getNewVersion().secondVer + "." + Settings.UPDATE_CHECKER.getNewVersion().thirdVer + "\n"
|
||||
+ C.i18n("update.should_open_link"),
|
||||
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
try {
|
||||
java.awt.Desktop.getDesktop().browse(new URI(C.URL_PUBLISH));
|
||||
} catch (Throwable e) {
|
||||
HMCLog.warn("Failed to browse uri: " + C.URL_PUBLISH, e);
|
||||
|
||||
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
cb.setContents(new StringSelection(C.URL_PUBLISH), null);
|
||||
MessageBox.Show(C.i18n("update.no_browser"));
|
||||
}
|
||||
else
|
||||
Settings.s().setCheckUpdate(false);
|
||||
}
|
||||
|
||||
public static void invokeUpdate() {
|
||||
if (Settings.s().isCheckUpdate()) update();
|
||||
MainFrame.instance.invokeUpdate();
|
||||
}
|
||||
|
||||
public static ImageIcon getIcon(String path) {
|
||||
try {
|
||||
return new ImageIcon(Main.class.getResource("/org/jackhuang/hellominecraft/launcher/" + path));
|
||||
} catch (Exception e) {
|
||||
HMCLog.err("Failed to load icon", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
69
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/DefaultGameLauncher.java
Normal file
69
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/DefaultGameLauncher.java
Normal file
@ -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.launcher.launch;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.GameLauncher.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.LoginInfo;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.tasks.ParallelTask;
|
||||
import org.jackhuang.hellominecraft.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.Compressor;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class DefaultGameLauncher extends GameLauncher {
|
||||
|
||||
public DefaultGameLauncher(Profile version, LoginInfo info, IAuthenticator lg) {
|
||||
super(version, info, lg);
|
||||
register();
|
||||
}
|
||||
|
||||
public DefaultGameLauncher(Profile version, LoginInfo info, IAuthenticator lg, DownloadType downloadType) {
|
||||
super(version, info, lg, downloadType);
|
||||
register();
|
||||
}
|
||||
|
||||
private void register() {
|
||||
downloadLibrariesEvent.register((sender, t) -> {
|
||||
final TaskWindow dw = TaskWindow.getInstance();
|
||||
ParallelTask parallelTask = new ParallelTask();
|
||||
for (DownloadLibraryJob o : t) {
|
||||
final DownloadLibraryJob s = (DownloadLibraryJob) o;
|
||||
parallelTask.addDependsTask(new FileDownloadTask(s.url, s.path).setTag(s.name));
|
||||
}
|
||||
dw.addTask(parallelTask);
|
||||
boolean flag = true;
|
||||
if (t.size() > 0) flag = dw.start();
|
||||
if (!flag && MessageBox.Show(C.i18n("launch.not_finished_downloading_libraries"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
flag = true;
|
||||
return flag;
|
||||
});
|
||||
decompressNativesEvent.register((sender, value) -> {
|
||||
//boolean flag = true;
|
||||
for (int i = 0; i < value.decompressFiles.length; i++)
|
||||
try {
|
||||
Compressor.unzip(value.decompressFiles[i], value.decompressTo, value.extractRules[i]);
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Unable to decompress library file: " + value.decompressFiles[i] + " to " + value.decompressTo, ex);
|
||||
//flag = false;
|
||||
}
|
||||
/*if(!flag)
|
||||
if(MessageBox.Show(C.i18n("launch.not_finished_decompressing_natives"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
flag = true;*/
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.launch;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.LoginInfo;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.utils.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.JavaProcess;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.OS;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
import org.jackhuang.hellominecraft.utils.ProcessManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class GameLauncher {
|
||||
|
||||
public static final ProcessManager PROCESS_MANAGER = new ProcessManager();
|
||||
Profile get;
|
||||
IMinecraftProvider provider;
|
||||
LoginInfo info;
|
||||
UserProfileProvider result;
|
||||
IAuthenticator login;
|
||||
public final EventHandler<String> failEvent = new EventHandler(this);
|
||||
public final EventHandler<List<DownloadLibraryJob>> downloadLibrariesEvent = new EventHandler(this);
|
||||
public final EventHandler<List<String>> successEvent = new EventHandler(this);
|
||||
public final EventHandler<JavaProcess> launchEvent = new EventHandler(this);
|
||||
public final EventHandler<DecompressLibraryJob> decompressNativesEvent = new EventHandler(this);
|
||||
DownloadType downloadType;
|
||||
|
||||
public GameLauncher(Profile version, LoginInfo info, IAuthenticator lg) {
|
||||
this(version, info, lg, DownloadType.Mojang);
|
||||
}
|
||||
|
||||
public GameLauncher(Profile version, LoginInfo info, IAuthenticator lg, DownloadType downloadType) {
|
||||
this.get = version;
|
||||
this.provider = get.getMinecraftProvider();
|
||||
this.info = info;
|
||||
this.login = lg;
|
||||
this.downloadType = downloadType;
|
||||
}
|
||||
|
||||
public Profile getProfile() {
|
||||
return get;
|
||||
}
|
||||
|
||||
public IMinecraftLoader makeLaunchCommand() {
|
||||
IMinecraftLoader loader;
|
||||
try {
|
||||
if (info != null) result = login.login(info);
|
||||
else result = login.loginBySettings();
|
||||
} catch (Exception e) {
|
||||
HMCLog.err("An exception has thrown when logging in.", e);
|
||||
result = new UserProfileProvider();
|
||||
result.setSuccess(false);
|
||||
result.setErrorReason(e.getLocalizedMessage());
|
||||
}
|
||||
if (result == null || result.isSuccessful() == false) {
|
||||
String error;
|
||||
if (result == null || result.getErrorReason() == null)
|
||||
error = C.i18n("login.failed");
|
||||
else {
|
||||
error = C.i18n("login.failed") + result.getErrorReason();
|
||||
HMCLog.warn("Login failed by method: " + login.getName() + ", state: " + result.isSuccessful() + ", error reason: " + result.getErrorReason());
|
||||
}
|
||||
failEvent.execute(error);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
loader = provider.provideMinecraftLoader(result, downloadType);
|
||||
} catch (IllegalStateException e) {
|
||||
HMCLog.err("Failed to get minecraft loader", e);
|
||||
failEvent.execute(C.i18n("launch.circular_dependency_versions"));
|
||||
return null;
|
||||
}
|
||||
|
||||
File file = provider.getDecompressNativesToLocation();
|
||||
if (file != null) FileUtils.cleanDirectoryQuietly(file);
|
||||
|
||||
if(!downloadLibrariesEvent.execute(provider.getDownloadLibraries(downloadType))) { failEvent.execute(C.i18n("launch.failed")); return null; }
|
||||
if(!decompressNativesEvent.execute(provider.getDecompressLibraries())) { failEvent.execute(C.i18n("launch.failed")); return null; }
|
||||
successEvent.execute(loader.makeLaunchingCommand());
|
||||
return loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the game "as soon as possible".
|
||||
*
|
||||
* @param str launch command
|
||||
*/
|
||||
public void launch(List str) {
|
||||
try {
|
||||
provider.onLaunch();
|
||||
ProcessBuilder builder = new ProcessBuilder(str);
|
||||
builder.directory(provider.getRunDirectory(get.getSelectedMinecraftVersion().id))
|
||||
.environment().put("APPDATA", get.getCanonicalGameDirFile().getParent());
|
||||
JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER);
|
||||
launchEvent.execute(jp);
|
||||
} catch (IOException e) {
|
||||
failEvent.execute(C.i18n("launch.failed_creating_process") + "\n" + e.getMessage());
|
||||
HMCLog.err("Failed to launch when creating a new process.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* According to the name...
|
||||
*
|
||||
* @param launcherName the name of launch bat/sh
|
||||
* @param str launch command
|
||||
* @return launcher location
|
||||
* @throws java.io.IOException write contents failed.
|
||||
*/
|
||||
public File makeLauncher(String launcherName, List str) throws IOException {
|
||||
provider.onLaunch();
|
||||
boolean isWin = OS.os() == OS.WINDOWS;
|
||||
File f = new File(launcherName + (isWin ? ".bat" : ".sh"));
|
||||
if (!f.exists()) f.createNewFile();
|
||||
BufferedWriter writer;
|
||||
try {
|
||||
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), System.getProperty("sun.jnu.encoding", "UTF-8")));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
HMCLog.warn("Failed to create writer, will try again.", ex);
|
||||
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f)));
|
||||
}
|
||||
if (isWin) {
|
||||
writer.write("@echo off");
|
||||
writer.newLine();
|
||||
String appdata = IOUtils.tryGetCanonicalFilePath(get.getCanonicalGameDirFile().getParentFile());
|
||||
if (appdata != null) {
|
||||
writer.write("set appdata=" + appdata);
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
writer.write(StrUtils.makeCommand(str));
|
||||
writer.close();
|
||||
if (!isWin)
|
||||
try {
|
||||
Runtime.getRuntime().exec("chmod +x " + IOUtils.tryGetCanonicalFilePath(f));
|
||||
} catch (IOException e) {
|
||||
HMCLog.warn("Failed to give sh file permission.", e);
|
||||
MessageBox.Show(C.i18n("launch.failed_sh_permission"));
|
||||
}
|
||||
|
||||
HMCLog.log("Command: " + StrUtils.parseParams("", str, " "));
|
||||
return f;
|
||||
}
|
||||
|
||||
public static class DownloadLibraryJob {
|
||||
|
||||
String url, name;
|
||||
File path;
|
||||
|
||||
public DownloadLibraryJob(String n, String u, File p) {
|
||||
url = u;
|
||||
name = n;
|
||||
path = IOUtils.tryGetCanonicalFile(p);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DecompressLibraryJob {
|
||||
File[] decompressFiles;
|
||||
String[][] extractRules;
|
||||
File decompressTo;
|
||||
|
||||
public DecompressLibraryJob(File[] decompressFiles, String[][] extractRules, File decompressTo) {
|
||||
this.decompressFiles = decompressFiles;
|
||||
this.extractRules = extractRules;
|
||||
this.decompressTo = decompressTo;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
19
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/GameLauncherRequest.java
Normal file
19
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/GameLauncherRequest.java
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.launch;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public enum GameLauncherRequest {
|
||||
|
||||
ERROR,
|
||||
DOWNLOAD_ASSETS,
|
||||
DOWNLOAD_LIBRARIES,
|
||||
UNZIP_LIBRARIES,
|
||||
PROCESS_STARTED,
|
||||
SUCCEED
|
||||
}
|
179
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/IMinecraftLoader.java
Normal file
179
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/IMinecraftLoader.java
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.launch;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Launcher;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.utils.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.JdkVersion;
|
||||
import org.jackhuang.hellominecraft.utils.MathUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.OS;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract class IMinecraftLoader {
|
||||
|
||||
protected File minecraftJar;
|
||||
protected Profile v;
|
||||
protected UserProfileProvider lr;
|
||||
protected File gameDir;
|
||||
protected IMinecraftProvider provider;
|
||||
|
||||
public IMinecraftLoader(Profile ver, IMinecraftProvider provider, UserProfileProvider lr, File minecraftJar) {
|
||||
this.lr = lr;
|
||||
|
||||
this.minecraftJar = minecraftJar;
|
||||
v = ver;
|
||||
this.provider = provider;
|
||||
gameDir = v.getCanonicalGameDirFile();
|
||||
}
|
||||
|
||||
public void makeHeadCommand(List<String> res) {
|
||||
HMCLog.log("On making head command.");
|
||||
|
||||
if (StrUtils.isNotBlank(v.getWrapperLauncher()))
|
||||
res.addAll(Arrays.asList(v.getWrapperLauncher().split(" ")));
|
||||
|
||||
String str = v.getJavaDir();
|
||||
JdkVersion jv = null;
|
||||
File f = new File(str + ".hmc");
|
||||
try {
|
||||
String s = FileUtils.readFileToString(f);
|
||||
String[] strs = s.split("\n");
|
||||
if (str.length() >= 2)
|
||||
jv = new JdkVersion(strs[0], MathUtils.parseInt(strs[1], -1));
|
||||
else
|
||||
throw new IllegalStateException("The format of file: " + f + " is wrong: " + s);
|
||||
} catch (IOException | IllegalStateException e) {
|
||||
try {
|
||||
jv = JdkVersion.getJavaVersionFromExecutable(str);
|
||||
jv.write(f);
|
||||
if (!f.exists())
|
||||
HMCLog.warn("Failed to load version from file " + f, e);
|
||||
} catch (Exception ex) {
|
||||
HMCLog.warn("Failed to read JDKVersion.", ex);
|
||||
}
|
||||
}
|
||||
res.add(str);
|
||||
|
||||
if (v.hasJavaArgs())
|
||||
res.addAll(Arrays.asList(StrUtils.tokenize(v.getJavaArgs())));
|
||||
|
||||
if (!v.isNoJVMArgs() && !(jv != null && jv.isEarlyAccess())) {
|
||||
res.add("-Xincgc");
|
||||
res.add("-XX:+UseConcMarkSweepGC");
|
||||
res.add("-XX:+CMSIncrementalMode");
|
||||
res.add("-XX:-UseAdaptiveSizePolicy");
|
||||
|
||||
res.add("-Xmn128m");
|
||||
}
|
||||
|
||||
if (jv != null && jv.is64Bit == 0 && OS.is64Bit())
|
||||
MessageBox.Show(C.i18n("advice.os64butjdk32"));
|
||||
|
||||
if (!StrUtils.isBlank(v.getMaxMemory())) {
|
||||
int mem = MathUtils.parseMemory(v.getMaxMemory(), 2147483647);
|
||||
if (jv != null && jv.is64Bit == 0 && mem > 1024)
|
||||
MessageBox.Show(C.i18n("launch.too_big_memory_alloc_64bit"));
|
||||
else {
|
||||
long a = OS.getTotalPhysicalMemory() / 1024 / 1024;
|
||||
HMCLog.log("System Physical Memory: " + a);
|
||||
if (a > 0 && a < mem)
|
||||
MessageBox.Show(C.i18n("launch.too_big_memory_alloc_free_space_too_low", a));
|
||||
}
|
||||
String a = "-Xmx" + v.getMaxMemory();
|
||||
if (MathUtils.canParseInt(v.getMaxMemory())) a += "m";
|
||||
res.add(a);
|
||||
}
|
||||
|
||||
if (!StrUtils.isBlank(v.getPermSize()) && !v.isNoJVMArgs())
|
||||
if (jv != null && jv.ver != null && (jv.ver.startsWith("1.8") || jv.ver.startsWith("1.9"))); else res.add("-XX:MaxPermSize=" + v.getPermSize() + "m");
|
||||
|
||||
if (!v.isNoJVMArgs())
|
||||
appendJVMArgs(res);
|
||||
|
||||
HMCLog.log("On making java.library.path.");
|
||||
|
||||
res.add("-Djava.library.path=" + provider.getDecompressNativesToLocation().getPath());//v.getSelectedMinecraftVersion().getNatives(v.getCanonicalGameDirFile()));
|
||||
res.add("-Dfml.ignoreInvalidMinecraftCertificates=true");
|
||||
res.add("-Dfml.ignorePatchDiscrepancies=true");
|
||||
|
||||
if (OS.os() != OS.WINDOWS)
|
||||
res.add("-Duser.home=" + gameDir.getParent());
|
||||
|
||||
if (!v.isCanceledWrapper()) {
|
||||
res.add("-cp");
|
||||
res.add(StrUtils.parseParams("", Utils.getURL(), File.pathSeparator));
|
||||
res.add(Launcher.class.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> makeLaunchingCommand() {
|
||||
HMCLog.log("*** Make shell command ***");
|
||||
|
||||
ArrayList<String> res = new ArrayList<>();
|
||||
|
||||
makeHeadCommand(res);
|
||||
makeSelf(res);
|
||||
|
||||
HMCLog.log("On making launcher args.");
|
||||
|
||||
if (StrUtils.isNotBlank(v.getHeight()) && StrUtils.isNotBlank(v.getWidth())) {
|
||||
res.add("--height");
|
||||
res.add(v.getHeight());
|
||||
res.add("--width");
|
||||
res.add(v.getWidth());
|
||||
}
|
||||
|
||||
if (StrUtils.isNotBlank(v.getServerIp())) {
|
||||
String[] args = v.getServerIp().split(":");
|
||||
res.add("--server");
|
||||
res.add(args[0]);
|
||||
res.add("--port");
|
||||
res.add(args.length > 1 ? args[1] : "25565");
|
||||
}
|
||||
|
||||
if (v.isFullscreen())
|
||||
res.add("--fullscreen");
|
||||
|
||||
if (v.isDebug() && !v.isCanceledWrapper())
|
||||
res.add("-debug");
|
||||
|
||||
if (StrUtils.isNotBlank(v.getMinecraftArgs()))
|
||||
res.addAll(Arrays.asList(v.getMinecraftArgs().split(" ")));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* You must do these things:<br />
|
||||
* 1 minecraft class path<br />
|
||||
* 2 main class<br />
|
||||
* 3 minecraft arguments<br />
|
||||
*
|
||||
* @param list the command list you shoud edit.
|
||||
*/
|
||||
protected abstract void makeSelf(List<String> list);
|
||||
|
||||
protected void appendJVMArgs(List<String> list) {
|
||||
}
|
||||
|
||||
public Profile getUserVersion() {
|
||||
return v;
|
||||
}
|
||||
}
|
63
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/IMinecraftProvider.java
Normal file
63
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/IMinecraftProvider.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.launcher.launch;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IMinecraftProvider {
|
||||
Profile profile;
|
||||
|
||||
public IMinecraftProvider(Profile profile) {
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
public abstract File getRunDirectory(String id);
|
||||
public abstract List<GameLauncher.DownloadLibraryJob> getDownloadLibraries(DownloadType type);
|
||||
public abstract void openSelf(String version);
|
||||
public abstract void open(String version, String folder);
|
||||
public abstract File getAssets();
|
||||
public abstract File getResourcePacks();
|
||||
public abstract GameLauncher.DecompressLibraryJob getDecompressLibraries();
|
||||
public abstract File getDecompressNativesToLocation();
|
||||
public abstract File getMinecraftJar();
|
||||
public abstract File getBaseFolder();
|
||||
|
||||
/**
|
||||
* Launch
|
||||
* @param p player informations, including username & auth_token
|
||||
* @param type according to the class name 233
|
||||
* @return what you want
|
||||
* @throws IllegalStateException circular denpendency versions
|
||||
*/
|
||||
public abstract IMinecraftLoader provideMinecraftLoader(UserProfileProvider p, DownloadType type) throws IllegalStateException;
|
||||
|
||||
// Versions
|
||||
public abstract boolean renameVersion(String from, String to);
|
||||
public abstract boolean removeVersionFromDisk(String a);
|
||||
public abstract boolean refreshJson(String a);
|
||||
public abstract boolean refreshAssetsIndex(String a);
|
||||
|
||||
public abstract MinecraftVersion getOneVersion();
|
||||
public abstract Collection<MinecraftVersion> getVersions();
|
||||
public abstract MinecraftVersion getVersionById(String id);
|
||||
public abstract int getVersionCount();
|
||||
public abstract void refreshVersions();
|
||||
|
||||
public abstract boolean install(String version, DownloadType type);
|
||||
|
||||
public abstract void onLaunch();
|
||||
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.launcher.launch;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.utils.functions.TrueDoneListener;
|
||||
import org.jackhuang.hellominecraft.launcher.views.MainFrame;
|
||||
import org.jackhuang.hellominecraft.utils.tinystream.CollectionUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Event;
|
||||
import org.jackhuang.hellominecraft.utils.JavaProcess;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Predicate;
|
||||
import org.jackhuang.hellominecraft.utils.ProcessThread;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.views.LogWindow;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LaunchFinisher implements Event<List<String>> {
|
||||
|
||||
private final HashSet<Thread> al = new HashSet<Thread>();
|
||||
|
||||
@Override
|
||||
public boolean call(Object sender, List<String> str) {
|
||||
final GameLauncher obj = (GameLauncher) sender;
|
||||
obj.launchEvent.register(new Event<JavaProcess>() {
|
||||
@Override
|
||||
public boolean call(Object sender, JavaProcess p) {
|
||||
if (obj.getProfile().getLauncherVisibility() == 0 && !LogWindow.instance.isVisible())
|
||||
System.exit(0);
|
||||
else if (obj.getProfile().getLauncherVisibility() == 2)
|
||||
MainFrame.instance.closeMessage();
|
||||
else {
|
||||
if (LogWindow.instance.isVisible())
|
||||
LogWindow.instance.setExit(TrueDoneListener.instance);
|
||||
MainFrame.instance.dispose();
|
||||
}
|
||||
Event<JavaProcess> event = new Event<JavaProcess>() {
|
||||
@Override
|
||||
public boolean call(Object sender, JavaProcess t) {
|
||||
processThreadStopped((ProcessThread) sender, obj, t, false);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
ProcessThread a = new ProcessThread(p, true, true);
|
||||
a.stopEvent.register(new Event<JavaProcess>() {
|
||||
@Override
|
||||
public boolean call(Object sender, JavaProcess p) {
|
||||
if (p.getExitCode() != 0 && p.getStdErrLines().size() > 0 && StrUtils.containsOne(p.getStdErrLines(),
|
||||
Arrays.asList("Could not create the Java Virtual Machine.",
|
||||
"Error occurred during initialization of VM",
|
||||
"A fatal exception has occurred. Program will exit.")))
|
||||
MessageBox.Show(C.i18n("launch.cannot_create_jvm"));
|
||||
processThreadStopped((ProcessThread) sender, obj, p, false);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
a.start();
|
||||
al.add(a);
|
||||
|
||||
a = new ProcessThread(p, false, true);
|
||||
a.stopEvent.register(event);
|
||||
a.start();
|
||||
al.add(a);
|
||||
|
||||
a = new ProcessThread(p, false, false);
|
||||
a.stopEvent.register(event);
|
||||
a.start();
|
||||
al.add(a);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
obj.launch(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
void processThreadStopped(ProcessThread t, GameLauncher obj, JavaProcess p, boolean forceTermintate) {
|
||||
al.remove(t);
|
||||
al.removeAll(CollectionUtils.sortOut(al, new Predicate<Thread>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Thread t) {
|
||||
return !t.isAlive();
|
||||
}
|
||||
|
||||
}));
|
||||
if (al.isEmpty() || forceTermintate) {
|
||||
for (Thread a : al) a.interrupt();
|
||||
al.clear();
|
||||
GameLauncher.PROCESS_MANAGER.onProcessStopped(p);
|
||||
if (obj.getProfile().getLauncherVisibility() != 2 && !LogWindow.instance.isVisible())
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
38
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/LaunchScriptFinisher.java
Normal file
38
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/LaunchScriptFinisher.java
Normal file
@ -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.launcher.launch;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.views.MainFrame;
|
||||
import org.jackhuang.hellominecraft.utils.Event;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LaunchScriptFinisher implements Event<List<String>> {
|
||||
|
||||
@Override
|
||||
public boolean call(Object sender, List str) {
|
||||
boolean flag = false;
|
||||
try {
|
||||
String s = JOptionPane.showInputDialog(C.i18n("mainwindow.enter_script_name"));
|
||||
if(s != null) MessageBox.Show(C.i18n("mainwindow.make_launch_succeed") + " " + ((GameLauncher)sender).makeLauncher(s, str).getAbsolutePath());
|
||||
flag = true;
|
||||
} catch (IOException ex) {
|
||||
MessageBox.Show(C.i18n("mainwindow.make_launch_script_failed"));
|
||||
HMCLog.err("Failed to create script file.", ex);
|
||||
}
|
||||
MainFrame.instance.closeMessage();
|
||||
return flag;
|
||||
}
|
||||
|
||||
}
|
48
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/MinecraftCrashAdvicer.java
Normal file
48
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/MinecraftCrashAdvicer.java
Normal file
@ -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.launcher.launch;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
|
||||
/**
|
||||
* Give the advice to solve the Minecraft crashing.
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class MinecraftCrashAdvicer {
|
||||
|
||||
public static String getAdvice(Throwable t) {
|
||||
return getAdvice(t, false);
|
||||
}
|
||||
|
||||
public static String getAdvice(Throwable t, boolean selfCrash) {
|
||||
if (t.getCause() instanceof UnsupportedClassVersionError) {
|
||||
return C.i18n("crash.advice.UnsupportedClassVersionError");
|
||||
} else if (t instanceof ConcurrentModificationException) {
|
||||
return C.i18n("crash.advice.ConcurrentModificationException");
|
||||
} else if (t instanceof SecurityException) {
|
||||
return C.i18n("crash.advice.SecurityException");
|
||||
} else if (t instanceof NoSuchFieldError || (t.getCause() != null && t.getCause() instanceof NoSuchFieldException)) {
|
||||
return C.i18n("crash.advice.NoSuchFieldError");
|
||||
} else if (t instanceof NoClassDefFoundError || (t.getCause() != null && t.getCause() instanceof ClassNotFoundException)) {
|
||||
return C.i18n("crash.advice.ClassNotFondException");
|
||||
}
|
||||
|
||||
if (t.getMessage() != null) {
|
||||
if (t.getMessage().contains("OpenGL") || t.getMessage().contains("OpenAL")) {
|
||||
return C.i18n("crash.advice.OpenGL");
|
||||
}
|
||||
}
|
||||
if (t.getCause() != null && t.getCause().getMessage() != null) {
|
||||
if (t.getCause().getMessage().contains("no lwjgl in java.library.path")) {
|
||||
return C.i18n("crash.advice.no_lwjgl");
|
||||
}
|
||||
}
|
||||
return selfCrash ? C.i18n("crash.advice.no") : C.i18n("crash.advice.otherwise");
|
||||
}
|
||||
|
||||
}
|
136
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/MinecraftLoader.java
Normal file
136
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/launch/MinecraftLoader.java
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.launch;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.MCUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.assets.AssetsIndex;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.assets.AssetsObject;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.OS;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftLoader extends IMinecraftLoader {
|
||||
|
||||
private MinecraftVersion version;
|
||||
String text;
|
||||
|
||||
public MinecraftLoader(Profile ver, IMinecraftProvider provider, UserProfileProvider lr, File minecraftJar) throws IllegalStateException {
|
||||
this(ver, provider, lr, minecraftJar, DownloadType.Mojang);
|
||||
}
|
||||
|
||||
public MinecraftLoader(Profile ver, IMinecraftProvider provider, UserProfileProvider lr, File minecraftJar, DownloadType downloadtype) throws IllegalStateException {
|
||||
super(ver, provider, lr, minecraftJar);
|
||||
version = ver.getSelectedMinecraftVersion().resolve(provider, downloadtype);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeSelf(List<String> res) {
|
||||
String library = v.isCanceledWrapper() ? "" : "-cp=";
|
||||
for (MinecraftLibrary l : version.libraries) {
|
||||
l.init();
|
||||
if (l.allow())
|
||||
library += l.getFilePath(gameDir).getAbsolutePath() + File.pathSeparator;
|
||||
}
|
||||
library += IOUtils.tryGetCanonicalFilePath(minecraftJar) + File.pathSeparator;
|
||||
library = library.substring(0, library.length() - File.pathSeparator.length());
|
||||
if (v.isCanceledWrapper()) res.add("-cp");
|
||||
res.add(library);
|
||||
String mainClass = version.mainClass;
|
||||
res.add((v.isCanceledWrapper() ? "" : "-mainClass=") + mainClass);
|
||||
|
||||
String arg = v.getSelectedMinecraftVersion().minecraftArguments;
|
||||
String[] splitted = org.jackhuang.hellominecraft.utils.StrUtils.tokenize(arg);
|
||||
|
||||
if (!new File(v.getGameDirFile(), "assets").exists())
|
||||
MessageBox.Show(C.i18n("assets.no_assets"));
|
||||
|
||||
String game_assets = reconstructAssets().getAbsolutePath();
|
||||
|
||||
for (String t : splitted) {
|
||||
t = t.replace("${auth_player_name}", lr.getUserName());
|
||||
t = t.replace("${auth_session}", lr.getSession());
|
||||
t = t.replace("${auth_uuid}", lr.getUserId());
|
||||
t = t.replace("${version_name}", version.id);
|
||||
t = t.replace("${profile_name}", provider.profile.getName());
|
||||
t = t.replace("${game_directory}", provider.getRunDirectory(version.id).getAbsolutePath());
|
||||
t = t.replace("${game_assets}", game_assets);
|
||||
t = t.replace("${assets_root}", provider.getAssets().getAbsolutePath());
|
||||
t = t.replace("${auth_access_token}", lr.getAccessToken());
|
||||
t = t.replace("${user_type}", lr.getUserType());
|
||||
t = t.replace("${assets_index_name}", version.assets == null ? "legacy" : version.assets);
|
||||
t = t.replace("${user_properties}", lr.getUserProperties());
|
||||
t = t.replace("${user_property_map}", lr.getUserPropertyMap());
|
||||
res.add(t);
|
||||
}
|
||||
|
||||
if (res.indexOf("--gameDir") != -1 && res.indexOf("--workDir") != -1) {
|
||||
res.add("--workDir");
|
||||
res.add(gameDir.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendJVMArgs(List<String> list) {
|
||||
super.appendJVMArgs(list);
|
||||
|
||||
try {
|
||||
if (OS.os() == OS.OSX) {
|
||||
list.add("-Xdock:icon=" + MCUtils.getAssetObject(C.gson, v.getCanonicalGameDir(), version.assets, "icons/minecraft.icns").getAbsolutePath());
|
||||
list.add("-Xdock:name=Minecraft");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
HMCLog.err("Failed to append jvm arguments when searching for asset objects.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private File reconstructAssets() {
|
||||
File assetsDir = new File(provider.getBaseFolder(), "assets");
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectDir = new File(assetsDir, "objects");
|
||||
String assetVersion = version.assets == null ? "legacy" : version.assets;
|
||||
File indexFile = new File(indexDir, assetVersion + ".json");
|
||||
File virtualRoot = new File(new File(assetsDir, "virtual"), assetVersion);
|
||||
|
||||
if (!indexFile.isFile()) {
|
||||
HMCLog.warn("No assets index file " + virtualRoot + "; can't reconstruct assets");
|
||||
return virtualRoot;
|
||||
}
|
||||
|
||||
try {
|
||||
AssetsIndex index = (AssetsIndex) C.gson.fromJson(FileUtils.readFileToString(indexFile, "UTF-8"), AssetsIndex.class);
|
||||
|
||||
if (index.isVirtual()) {
|
||||
HMCLog.log("Reconstructing virtual assets folder at " + virtualRoot);
|
||||
for (Map.Entry entry : index.getFileMap().entrySet()) {
|
||||
File target = new File(virtualRoot, (String) entry.getKey());
|
||||
File original = new File(new File(objectDir, ((AssetsObject) entry.getValue()).getHash().substring(0, 2)), ((AssetsObject) entry.getValue()).getHash());
|
||||
|
||||
if (!target.isFile())
|
||||
FileUtils.copyFile(original, target, false);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
HMCLog.warn("Failed to create virutal assets.", e);
|
||||
}
|
||||
|
||||
return virtualRoot;
|
||||
}
|
||||
}
|
@ -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.launcher.utils;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.MinecraftCrashAdvicer;
|
||||
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.views.LogWindow;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class CrashReport implements Thread.UncaughtExceptionHandler {
|
||||
|
||||
boolean enableLogger = false;
|
||||
|
||||
public CrashReport(boolean enableLogger) {
|
||||
this.enableLogger = enableLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
try {
|
||||
String text = "\n---- Hello Minecraft! Crash Report ----\n";
|
||||
text += " Version: " + Main.makeVersion() + "\n";
|
||||
text += " Time: " + DateFormat.getDateInstance().format(new Date()) + "\n";
|
||||
text += " Thread: " + t.toString() + "\n";
|
||||
text += "\n Advice: \n ";
|
||||
text += MinecraftCrashAdvicer.getAdvice(e, true);
|
||||
text += "\n Content: \n ";
|
||||
text += StrUtils.getStackTrace(e) + "\n\n";
|
||||
text += "-- System Details --\n";
|
||||
text += " Operating System: " + System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ") version " + System.getProperty("os.version") + "\n";
|
||||
text += " Java Version: " + System.getProperty("java.version") + ", " + System.getProperty("java.vendor") + "\n";
|
||||
text += " Java VM Version: " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor") + "\n";
|
||||
if (enableLogger) HMCLog.err(text);
|
||||
else System.out.println(text);
|
||||
SwingUtilities.invokeLater(() -> LogWindow.instance.showAsCrashWindow(UpdateChecker.OUT_DATED));
|
||||
} catch (Throwable ex) {
|
||||
try {
|
||||
MessageBox.Show(e.getMessage() + "\n" + ex.getMessage(), "ERROR", MessageBox.ERROR_MESSAGE);
|
||||
} catch (Throwable exx) {
|
||||
System.out.println("Failed to catch exception thrown by " + t + " on " + Main.makeVersion() + ".");
|
||||
exx.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,306 @@
|
||||
/*
|
||||
* 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.launcher.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.assets.AssetsIndex;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.assets.AssetsObject;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.version.MinecraftRemoteVersions;
|
||||
import org.jackhuang.hellominecraft.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.utils.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MinecraftVersionRequest;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public final class MCUtils {
|
||||
|
||||
public static File getAssetObject(Gson gson, String dir, String assetVersion, String name) throws IOException {
|
||||
File assetsDir = new File(dir, "assets");
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectsDir = new File(assetsDir, "objects");
|
||||
File indexFile = new File(indexDir, assetVersion + ".json");
|
||||
try {
|
||||
AssetsIndex index = (AssetsIndex) gson.fromJson(FileUtils.readFileToString(indexFile, "UTF-8"), AssetsIndex.class);
|
||||
|
||||
String hash = ((AssetsObject) index.getFileMap().get(name)).getHash();
|
||||
return new File(objectsDir, hash.substring(0, 2) + "/" + hash);
|
||||
} catch(JsonSyntaxException e) {
|
||||
throw new IOException("Assets file format malformed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static int lessThan32(byte[] b, int x) {
|
||||
for (; x < b.length; x++) {
|
||||
if (b[x] < 32) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static MinecraftVersionRequest getVersionOfOldMinecraft(ZipFile paramZipFile, ZipEntry paramZipEntry) throws IOException {
|
||||
MinecraftVersionRequest r = new MinecraftVersionRequest();
|
||||
byte[] tmp = NetUtils.getBytesFromStream(paramZipFile.getInputStream(paramZipEntry));
|
||||
|
||||
byte[] arrayOfByte = "Minecraft Minecraft ".getBytes("ASCII");
|
||||
int j;
|
||||
if ((j = ArrayUtils.matchArray(tmp, arrayOfByte)) < 0) {
|
||||
r.type = MinecraftVersionRequest.Unkown;
|
||||
return r;
|
||||
}
|
||||
int i = j + arrayOfByte.length;
|
||||
|
||||
if ((j = lessThan32(tmp, i)) < 0) {
|
||||
r.type = MinecraftVersionRequest.Unkown;
|
||||
return r;
|
||||
}
|
||||
String ver = new String(tmp, i, j - i, "ASCII");
|
||||
r.version = ver;
|
||||
|
||||
if (paramZipFile.getEntry("META-INF/MANIFEST.MF") == null) {
|
||||
r.type = MinecraftVersionRequest.Modified;
|
||||
} else {
|
||||
r.type = MinecraftVersionRequest.OK;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private static MinecraftVersionRequest getVersionOfNewMinecraft(ZipFile file, ZipEntry entry) throws IOException {
|
||||
MinecraftVersionRequest r = new MinecraftVersionRequest();
|
||||
byte[] tmp = NetUtils.getBytesFromStream(file.getInputStream(entry));
|
||||
|
||||
byte[] str = "-server.txt".getBytes("ASCII");
|
||||
int j = ArrayUtils.matchArray(tmp, str);
|
||||
if (j < 0) {
|
||||
r.type = MinecraftVersionRequest.Unkown;
|
||||
return r;
|
||||
}
|
||||
int i = j + str.length;
|
||||
i += 11;
|
||||
j = lessThan32(tmp, i);
|
||||
if (j < 0) {
|
||||
r.type = MinecraftVersionRequest.Unkown;
|
||||
return r;
|
||||
}
|
||||
r.version = new String(tmp, i, j - i, "ASCII");
|
||||
|
||||
char ch = r.version.charAt(0);
|
||||
// 1.8.1+
|
||||
if(ch < '0' || ch > '9') {
|
||||
str = "Can't keep up! Did the system time change, or is the server overloaded?".getBytes("ASCII");
|
||||
j = ArrayUtils.matchArray(tmp, str);
|
||||
if (j < 0) {
|
||||
r.type = MinecraftVersionRequest.Unkown;
|
||||
return r;
|
||||
}
|
||||
i = -1;
|
||||
while (j > 0) {
|
||||
if(tmp[j] >= 48 && tmp[j] <= 57) {
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
j--;
|
||||
}
|
||||
if (i == -1) {
|
||||
r.type = MinecraftVersionRequest.Unkown;
|
||||
return r;
|
||||
}
|
||||
int k = i;
|
||||
while (tmp[k] >= 48 && tmp[k] <= 57 || tmp[k] == 46) k--;
|
||||
k++;
|
||||
r.version = new String(tmp, k, i - k + 1);
|
||||
}
|
||||
|
||||
if (file.getEntry("META-INF/MANIFEST.MF") == null) {
|
||||
r.type = MinecraftVersionRequest.Modified;
|
||||
} else {
|
||||
r.type = MinecraftVersionRequest.OK;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public static MinecraftVersionRequest minecraftVersion(File file) {
|
||||
MinecraftVersionRequest r = new MinecraftVersionRequest();
|
||||
if (!file.exists()) {
|
||||
r.type = MinecraftVersionRequest.NotFound;
|
||||
return r;
|
||||
}
|
||||
if (!file.isFile()) {
|
||||
r.type = MinecraftVersionRequest.NotAFile;
|
||||
return r;
|
||||
}
|
||||
if (!file.canRead()) {
|
||||
r.type = MinecraftVersionRequest.NotReadable;
|
||||
return r;
|
||||
}
|
||||
ZipFile localZipFile = null;
|
||||
try {
|
||||
localZipFile = new ZipFile(file);
|
||||
ZipEntry minecraft = localZipFile
|
||||
.getEntry("net/minecraft/client/Minecraft.class");
|
||||
if (minecraft != null) {
|
||||
return getVersionOfOldMinecraft(localZipFile, minecraft);
|
||||
}
|
||||
ZipEntry main = localZipFile.getEntry("net/minecraft/client/main/Main.class");
|
||||
ZipEntry minecraftserver = localZipFile.getEntry("net/minecraft/server/MinecraftServer.class");
|
||||
if ((main != null) && (minecraftserver != null)) {
|
||||
return getVersionOfNewMinecraft(localZipFile, minecraftserver);
|
||||
}
|
||||
r.type = MinecraftVersionRequest.Invaild;
|
||||
return r;
|
||||
} catch (IOException localException) {
|
||||
HMCLog.warn("Zip file is invalid", localException);
|
||||
r.type = MinecraftVersionRequest.InvaildJar;
|
||||
return r;
|
||||
} finally {
|
||||
if (localZipFile != null) {
|
||||
try {
|
||||
localZipFile.close();
|
||||
} catch (IOException ex) {
|
||||
HMCLog.warn("Failed to close zip file", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static File getLocation() {
|
||||
String localObject = "minecraft";
|
||||
String str1 = System.getProperty("user.home", ".");
|
||||
File file;
|
||||
OS os = OS.os();
|
||||
if (os == OS.LINUX) {
|
||||
file = new File(str1, '.' + (String) localObject + '/');
|
||||
} else if (os == OS.WINDOWS) {
|
||||
String str2;
|
||||
if ((str2 = System.getenv("APPDATA")) != null) {
|
||||
file = new File(str2, "." + (String) localObject + '/');
|
||||
} else {
|
||||
file = new File(str1, '.' + (String) localObject + '/');
|
||||
}
|
||||
} else if (os == OS.OSX) {
|
||||
file = new File(str1, "Library/Application Support/" + localObject);
|
||||
} else {
|
||||
file = new File(str1, localObject + '/');
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public static boolean is16Folder(String path) {
|
||||
path = IOUtils.addSeparator(path);
|
||||
return new File(path, "versions").exists();
|
||||
}
|
||||
|
||||
public static String minecraft() {
|
||||
String os = System.getProperty("os.name").trim().toLowerCase();
|
||||
if (os.contains("mac")) {
|
||||
return "minecraft";
|
||||
}
|
||||
return ".minecraft";
|
||||
}
|
||||
|
||||
public static File getInitGameDir() {
|
||||
File gameDir = IOUtils.currentDir();
|
||||
if (gameDir.exists()) {
|
||||
gameDir = new File(gameDir, MCUtils.minecraft());
|
||||
if (!gameDir.exists()) {
|
||||
File newFile = MCUtils.getLocation();
|
||||
if(newFile.exists()) gameDir = newFile;
|
||||
}
|
||||
}
|
||||
return gameDir;
|
||||
}
|
||||
|
||||
public static MinecraftVersion downloadMinecraft(File gameDir, String id, DownloadType sourceType) {
|
||||
String vurl = sourceType.getProvider().getVersionsDownloadURL() + id + "/";
|
||||
File vpath = new File(gameDir, "versions/" + id);
|
||||
File mvt = new File(vpath, id + ".json");
|
||||
File mvj = new File(vpath, id + ".jar");
|
||||
vpath.mkdirs();
|
||||
mvt.delete();
|
||||
mvj.delete();
|
||||
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(vurl + id + ".json", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".json"))
|
||||
.addTask(new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvj)).setTag(id + ".jar"))
|
||||
.start()) {
|
||||
MinecraftVersion mv = new Gson().fromJson(FileUtils.readFileToStringQuietly(mvt), MinecraftVersion.class);
|
||||
//File apath = new File(gameDir, "assets/indexes");
|
||||
//downloadMinecraftAssetsIndex(apath, mv.assets, sourceType);
|
||||
return mv;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean downloadMinecraftVersionJson(File gameDir, String id, DownloadType sourceType) {
|
||||
String vurl = sourceType.getProvider().getVersionsDownloadURL() + id + "/";
|
||||
File vpath = new File(gameDir, "versions/" + id);
|
||||
File mvv = new File(vpath, id + ".json"), moved = null;
|
||||
if (mvv.exists()) {
|
||||
moved = new File(vpath, id + "-renamed.json");
|
||||
mvv.renameTo(moved);
|
||||
}
|
||||
File mvt = new File(vpath, id + ".json");
|
||||
vpath.mkdirs();
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(vurl + id + ".json", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".json"))
|
||||
.start()) {
|
||||
if (moved != null) {
|
||||
moved.delete();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
mvt.delete();
|
||||
if (moved != null) {
|
||||
moved.renameTo(mvt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean downloadMinecraftAssetsIndex(File assetsLocation, String assetsId, DownloadType sourceType) {
|
||||
String aurl = sourceType.getProvider().getIndexesDownloadURL();
|
||||
|
||||
assetsLocation.mkdirs();
|
||||
File assetsIndex = new File(assetsLocation, "indexes/" + assetsId + ".json");
|
||||
File renamed = null;
|
||||
if (assetsIndex.exists()) {
|
||||
renamed = new File(assetsLocation, "indexes/" + assetsId + "-renamed.json");
|
||||
assetsIndex.renameTo(renamed);
|
||||
}
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(aurl + assetsId + ".json", IOUtils.tryGetCanonicalFile(assetsIndex)).setTag(assetsId + ".json"))
|
||||
.start()) {
|
||||
if (renamed != null) {
|
||||
renamed.delete();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (renamed != null) {
|
||||
renamed.renameTo(assetsIndex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static MinecraftRemoteVersions getRemoteMinecraftVersions(DownloadType sourceType) throws IOException {
|
||||
String result = NetUtils.doGet(sourceType.getProvider().getVersionsListDownloadURL());
|
||||
return MinecraftRemoteVersions.fromJson(result);
|
||||
}
|
||||
}
|
38
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsIndex.java
Normal file
38
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsIndex.java
Normal file
@ -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.launcher.utils.assets;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class AssetsIndex {
|
||||
|
||||
public static final String DEFAULT_ASSET_NAME = "legacy";
|
||||
private Map<String, AssetsObject> objects;
|
||||
private boolean virtual;
|
||||
|
||||
public AssetsIndex() {
|
||||
this.objects = new LinkedHashMap();
|
||||
}
|
||||
|
||||
public Map<String, AssetsObject> getFileMap() {
|
||||
return this.objects;
|
||||
}
|
||||
|
||||
public Set<AssetsObject> getUniqueObjects() {
|
||||
return new HashSet(this.objects.values());
|
||||
}
|
||||
|
||||
public boolean isVirtual() {
|
||||
return this.virtual;
|
||||
}
|
||||
}
|
91
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsLoader.java
Normal file
91
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsLoader.java
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.assets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
import org.jackhuang.hellominecraft.utils.MathUtils;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class AssetsLoader extends Thread {
|
||||
|
||||
Document doc;
|
||||
Element root;
|
||||
NodeList nodes;
|
||||
public String uri;
|
||||
ArrayList<Contents> al;
|
||||
public final EventHandler<Throwable> failedEvent = new EventHandler<Throwable>(this);
|
||||
public final EventHandler<List<Contents>> successEvent = new EventHandler<List<Contents>>(this);
|
||||
|
||||
AssetsLoader(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
private Contents modifyContents(NodeList contents) {
|
||||
Contents ret = new Contents();
|
||||
for (int i = 0; i < contents.getLength(); i++) {
|
||||
Node result = contents.item(i);
|
||||
if (result.getNodeType() == Node.ELEMENT_NODE) {
|
||||
if (result.getNodeName().equalsIgnoreCase("Key")) {
|
||||
ret.key = result.getTextContent();
|
||||
}
|
||||
if (result.getNodeName().equalsIgnoreCase("ETag")) {
|
||||
ret.eTag = result.getTextContent();
|
||||
}
|
||||
if (result.getNodeName().equalsIgnoreCase("LastModified")) {
|
||||
ret.lastModified = result.getTextContent();
|
||||
}
|
||||
if (result.getNodeName().equalsIgnoreCase("Size")) {
|
||||
ret.size = MathUtils.parseInt(result.getTextContent(), 0);
|
||||
}
|
||||
if (result.getNodeName().equalsIgnoreCase("StorageClass")) {
|
||||
ret.storageClass = result.getTextContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Thread.currentThread().setName("AssetsLoader");
|
||||
al = new ArrayList<Contents>();
|
||||
try {
|
||||
HMCLog.log("AssetsLoader - Download begin.");
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = factory.newDocumentBuilder();
|
||||
doc = db.parse(uri);
|
||||
HMCLog.log("AssetsLoader - Download end and format begin.");
|
||||
root = doc.getDocumentElement();
|
||||
nodes = root.getChildNodes();
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Node result = nodes.item(i);
|
||||
if (result.getNodeType() == Node.ELEMENT_NODE && result.getNodeName().equals("Contents")) {
|
||||
Contents c = modifyContents(result.getChildNodes());
|
||||
if(c.key != null)
|
||||
al.add(c);
|
||||
}
|
||||
}
|
||||
HMCLog.log("AssetsLoader - Format end.");
|
||||
|
||||
successEvent.execute(al);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("AssetsLoader - Failed", e);
|
||||
failedEvent.execute(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
18
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsLoaderListener.java
Normal file
18
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsLoaderListener.java
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.assets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public interface AssetsLoaderListener {
|
||||
|
||||
void OnDone(ArrayList<Contents> loader);
|
||||
|
||||
void OnFailed(Exception e);
|
||||
}
|
99
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsMojangLoader.java
Normal file
99
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsMojangLoader.java
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.assets;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.MCUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.IDownloadProvider;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class AssetsMojangLoader extends IAssetsHandler {
|
||||
|
||||
public AssetsMojangLoader(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getList(final Consumer<String[]> dl) {
|
||||
if (mv == null) {
|
||||
dl.accept(null);
|
||||
return;
|
||||
}
|
||||
String assetsId = mv.assets == null ? "legacy" : mv.assets;
|
||||
File assets = mp.getAssets();
|
||||
HMCLog.log("Get index: " + assetsId);
|
||||
File f = IOUtils.tryGetCanonicalFile(new File(assets, "indexes/" + assetsId + ".json"));
|
||||
if (!f.exists() && !MCUtils.downloadMinecraftAssetsIndex(assets, assetsId, Settings.s().getDownloadSource())) {
|
||||
dl.accept(null);
|
||||
return;
|
||||
}
|
||||
|
||||
String result;
|
||||
try {
|
||||
result = FileUtils.readFileToString(f);
|
||||
} catch (IOException ex) {
|
||||
HMCLog.warn("Failed to read index json: " + f, ex);
|
||||
dl.accept(null);
|
||||
return;
|
||||
}
|
||||
if (StrUtils.isBlank(result)) {
|
||||
HMCLog.err("Index json is empty, please redownload it!");
|
||||
dl.accept(null);
|
||||
return;
|
||||
}
|
||||
AssetsIndex o;
|
||||
try {
|
||||
o = C.gson.fromJson(result, AssetsIndex.class);
|
||||
} catch (Exception e) {
|
||||
HMCLog.err("Failed to parse index json, please redownload it!", e);
|
||||
dl.accept(null);
|
||||
return;
|
||||
}
|
||||
assetsDownloadURLs = new ArrayList<>();
|
||||
assetsLocalNames = new ArrayList<>();
|
||||
ArrayList<String> al = new ArrayList<>();
|
||||
contents = new ArrayList<>();
|
||||
if (o != null && o.getFileMap() != null)
|
||||
for (Map.Entry<String, AssetsObject> e : o.getFileMap().entrySet()) {
|
||||
Contents c = new Contents();
|
||||
c.key = e.getValue().getHash().substring(0, 2) + "/" + e.getValue().getHash();
|
||||
c.eTag = e.getValue().getHash();
|
||||
c.size = e.getValue().getSize();
|
||||
contents.add(c);
|
||||
assetsDownloadURLs.add(c.key);
|
||||
assetsLocalNames.add(new File(assets, "objects" + File.separator + c.key.replace("/", File.separator)));
|
||||
al.add(e.getKey());
|
||||
}
|
||||
|
||||
dl.accept(al.toArray(new String[1]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task getDownloadTask(IDownloadProvider sourceType) {
|
||||
return new AssetsTask(sourceType.getAssetsDownloadURL());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVersionAllowed(String formattedVersion) {
|
||||
VersionNumber ur = VersionNumber.check(formattedVersion);
|
||||
if (ur == null) return false;
|
||||
return VersionNumber.check("1.6.0").compareTo(ur) <= 0;
|
||||
}
|
||||
}
|
61
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsMojangOldLoader.java
Normal file
61
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsMojangOldLoader.java
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.assets;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.IDownloadProvider;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
import org.jackhuang.hellominecraft.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class AssetsMojangOldLoader extends IAssetsHandler {
|
||||
|
||||
private static final String URL = "http://bmclapi.bangbang93.com/resources/";
|
||||
|
||||
public AssetsMojangOldLoader(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getList(final Consumer<String[]> dl) {
|
||||
AssetsLoader al = new AssetsLoader(URL);
|
||||
al.failedEvent.register((sender, e) -> {
|
||||
HMCLog.warn("Failed to get assets list.", e);
|
||||
dl.accept(null);
|
||||
return true;
|
||||
});
|
||||
al.successEvent.register((sender, t) -> {
|
||||
assetsDownloadURLs = new ArrayList<>();
|
||||
assetsLocalNames = new ArrayList<>();
|
||||
contents = t;
|
||||
for (Contents c : t) {
|
||||
assetsDownloadURLs.add(c.key);
|
||||
assetsLocalNames.add(new File(mp.getAssets(), c.key.replace("/", File.separator)));
|
||||
}
|
||||
dl.accept(assetsDownloadURLs.toArray(new String[1]));
|
||||
return true;
|
||||
});
|
||||
new Thread(al).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVersionAllowed(String formattedVersion) {
|
||||
VersionNumber r = VersionNumber.check(formattedVersion);
|
||||
if(r == null) return false;
|
||||
return VersionNumber.check("1.7.2").compareTo(r) >= 0 &&
|
||||
VersionNumber.check("1.6.0").compareTo(r) <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task getDownloadTask(IDownloadProvider sourceType) {
|
||||
return new AssetsTask(URL);
|
||||
}
|
||||
}
|
42
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsObject.java
Normal file
42
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/AssetsObject.java
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.launcher.utils.assets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class AssetsObject {
|
||||
private String hash;
|
||||
private long size;
|
||||
|
||||
public AssetsObject() {
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AssetsObject that = (AssetsObject) o;
|
||||
if (this.size != that.size) return false;
|
||||
return this.hash.equals(that.hash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = this.hash.hashCode();
|
||||
result = 31 * result + (int) (this.size ^ this.size >>> 32);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.assets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Contents {
|
||||
|
||||
public String key, eTag, lastModified, storageClass;
|
||||
public long size;
|
||||
|
||||
}
|
152
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/IAssetsHandler.java
Normal file
152
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/assets/IAssetsHandler.java
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.assets;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.IDownloadProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import org.jackhuang.hellominecraft.utils.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
|
||||
/**
|
||||
* Assets
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract class IAssetsHandler {
|
||||
|
||||
protected ArrayList<String> assetsDownloadURLs;
|
||||
protected ArrayList<File> assetsLocalNames;
|
||||
protected final String name;
|
||||
protected List<Contents> contents;
|
||||
|
||||
public IAssetsHandler(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private static final List<IAssetsHandler> assetsHandlers = new ArrayList<>();
|
||||
|
||||
public static IAssetsHandler getAssetsHandler(int i) {
|
||||
return assetsHandlers.get(i);
|
||||
}
|
||||
|
||||
public static List<IAssetsHandler> getAssetsHandlers() {
|
||||
return assetsHandlers;
|
||||
}
|
||||
|
||||
static {
|
||||
assetsHandlers.add(new AssetsMojangLoader(C.i18n("assets.list.1_7_3_after")));
|
||||
//assetsHandlers.add(new AssetsMojangOldLoader(C.i18n("assets.list.1_6")));
|
||||
}
|
||||
|
||||
/**
|
||||
* interface name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* All the files assets needed
|
||||
*
|
||||
* @param x finished event
|
||||
*/
|
||||
public abstract void getList(Consumer<String[]> x);
|
||||
|
||||
/**
|
||||
* Will be invoked when the user invoked "Download all assets".
|
||||
*
|
||||
* @param sourceType Download Source
|
||||
* @return Download File Task
|
||||
*/
|
||||
public abstract Task getDownloadTask(IDownloadProvider sourceType);
|
||||
|
||||
/**
|
||||
* assets path
|
||||
*/
|
||||
protected MinecraftVersion mv;
|
||||
protected IMinecraftProvider mp;
|
||||
|
||||
/**
|
||||
* @param mp
|
||||
* @param mv
|
||||
*/
|
||||
public void setAssets(IMinecraftProvider mp, MinecraftVersion mv) {
|
||||
this.mp = mp;
|
||||
this.mv = mv;
|
||||
}
|
||||
|
||||
public abstract boolean isVersionAllowed(String formattedVersion);
|
||||
|
||||
protected class AssetsTask extends Task {
|
||||
|
||||
ArrayList<Task> al;
|
||||
String u;
|
||||
int progress, max;
|
||||
|
||||
public AssetsTask(String url) {
|
||||
this.u = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeTask() {
|
||||
if (mv == null || assetsDownloadURLs == null) {
|
||||
setFailReason(new RuntimeException(C.i18n("assets.not_refreshed")));
|
||||
return false;
|
||||
}
|
||||
progress = 0;
|
||||
max = assetsDownloadURLs.size();
|
||||
al = new ArrayList<>();
|
||||
for (int i = 0; i < max; i++) {
|
||||
String mark = assetsDownloadURLs.get(i);
|
||||
String url = u + mark;
|
||||
File location = assetsLocalNames.get(i);
|
||||
if (!location.getParentFile().exists()) location.getParentFile().mkdirs();
|
||||
if (location.isDirectory()) continue;
|
||||
boolean need = true;
|
||||
try {
|
||||
if (location.exists()) {
|
||||
FileInputStream fis = new FileInputStream(location);
|
||||
String sha = DigestUtils.sha1Hex(NetUtils.getBytesFromStream(fis));
|
||||
IOUtils.closeQuietly(fis);
|
||||
if (contents.get(i).eTag.equals(sha)) {
|
||||
HMCLog.log("File " + assetsLocalNames.get(i) + " has downloaded successfully, skipped downloading.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
HMCLog.warn("Failed to get hash: " + location, e);
|
||||
need = !location.exists();
|
||||
}
|
||||
if (need) al.add(new FileDownloadTask(url, location).setTag(mark));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task> getAfterTasks() {
|
||||
return al;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("assets.download");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.launcher.utils.auth;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import org.jackhuang.hellominecraft.utils.DigestUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class BestLogin extends IAuthenticator {
|
||||
|
||||
public BestLogin(String clientToken) {
|
||||
super(clientToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider login(LoginInfo info) {
|
||||
try {
|
||||
String request = "bl:l:" + info.username + ":" + DigestUtils.sha1Hex(info.password);
|
||||
|
||||
Socket socket = new Socket("auth.zhh0000zhh.com", 8);
|
||||
OutputStream os = socket.getOutputStream();
|
||||
os.write(request.length());
|
||||
os.write(request.getBytes());
|
||||
|
||||
UserProfileProvider lr = new UserProfileProvider();
|
||||
lr.setSuccess(false);
|
||||
|
||||
InputStream is = socket.getInputStream();
|
||||
int code = is.read();
|
||||
switch (code) {
|
||||
case -1:
|
||||
lr.setErrorReason("internet error.");
|
||||
break;
|
||||
case 200:
|
||||
lr.setErrorReason("server restarting.");
|
||||
break;
|
||||
case 255:
|
||||
lr.setErrorReason("unknown error");
|
||||
break;
|
||||
case 3:
|
||||
lr.setErrorReason("unregistered.");
|
||||
break;
|
||||
case 50:
|
||||
lr.setErrorReason("please update your launcher and act your account.");
|
||||
break;
|
||||
case 2:
|
||||
lr.setErrorReason("wrong password.");
|
||||
break;
|
||||
case 100:
|
||||
lr.setErrorReason("server reloading.");
|
||||
break;
|
||||
case 0:
|
||||
lr.setSuccess(true);
|
||||
byte[] b = new byte[64];
|
||||
is.read(b, 0, b.length);
|
||||
String[] ss = new String(b).split(":");
|
||||
lr.setUserName(info.username);
|
||||
lr.setUserId(ss[1]);
|
||||
lr.setSession(ss[0]);
|
||||
lr.setAccessToken(ss[0]);
|
||||
break;
|
||||
}
|
||||
lr.setUserType("Legacy");
|
||||
return lr;
|
||||
} catch (Throwable t) {
|
||||
UserProfileProvider lr = new UserProfileProvider();
|
||||
lr.setSuccess(false);
|
||||
lr.setErrorReason(t.getMessage());
|
||||
return lr;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "BestLogin";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider loginBySettings() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
}
|
||||
|
||||
}
|
83
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/auth/IAuthenticator.java
Normal file
83
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/auth/IAuthenticator.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.auth;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Settings;
|
||||
|
||||
/**
|
||||
* Login interface
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract class IAuthenticator {
|
||||
|
||||
public static final YggdrasilAuthenticator yggdrasilLogin;
|
||||
public static final OfflineAuthenticator offlineLogin;
|
||||
public static final SkinmeAuthenticator skinmeLogin;
|
||||
//public static final BestLogin bestLogin;
|
||||
|
||||
public static final List<IAuthenticator> logins;
|
||||
|
||||
static {
|
||||
String clientToken = Settings.s().getClientToken();
|
||||
logins = new ArrayList<>();
|
||||
logins.add(offlineLogin = new OfflineAuthenticator(clientToken));
|
||||
logins.add(yggdrasilLogin = new YggdrasilAuthenticator(clientToken));
|
||||
logins.add(skinmeLogin = new SkinmeAuthenticator(clientToken));
|
||||
//logins.add(bestLogin = new BestLogin(clientToken));
|
||||
yggdrasilLogin.onLoadSettings(Settings.s().getYggdrasilConfig());
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Settings.s().setYggdrasilConfig(yggdrasilLogin.onSaveSettings());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected String clientToken;
|
||||
|
||||
public IAuthenticator(String clientToken) {
|
||||
this.clientToken = clientToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login Method
|
||||
*
|
||||
* @param info username & password
|
||||
* @return login result
|
||||
*/
|
||||
public abstract UserProfileProvider login(LoginInfo info);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the name of login method.
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* Has password?
|
||||
*
|
||||
* @return Will I hide password box?
|
||||
*/
|
||||
public boolean isHidePasswordBox() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isLoggedIn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setRememberMe(boolean is) {
|
||||
|
||||
}
|
||||
|
||||
public abstract UserProfileProvider loginBySettings();
|
||||
|
||||
public abstract void logout();
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.auth;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class LoginInfo {
|
||||
public String username, password;
|
||||
|
||||
public LoginInfo(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
}
|
55
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/auth/OfflineAuthenticator.java
Normal file
55
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/auth/OfflineAuthenticator.java
Normal file
@ -0,0 +1,55 @@
|
||||
package org.jackhuang.hellominecraft.launcher.utils.auth;
|
||||
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.DigestUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class OfflineAuthenticator extends IAuthenticator {
|
||||
|
||||
public OfflineAuthenticator(String clientToken) {
|
||||
super(clientToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider login(LoginInfo info) {
|
||||
UserProfileProvider result = new UserProfileProvider();
|
||||
result.setSuccess(StrUtils.isNotBlank(info.username));
|
||||
result.setUserName(info.username);
|
||||
String md5 = DigestUtils.md5Hex(info.username);
|
||||
String uuid = md5.substring(0, 8) + '-' + md5.substring(8, 12) + '-' + md5.substring(12, 16) + '-' + md5.substring(16, 21) + md5.substring(21);
|
||||
result.setSession(uuid);
|
||||
result.setUserId(uuid);
|
||||
result.setAccessToken("${auth_access_token}");
|
||||
result.setUserType("Legacy");
|
||||
result.setErrorReason(C.i18n("login.no_Player007"));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return C.i18n("login.methods.offline");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidePasswordBox() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider loginBySettings() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
}
|
||||
|
||||
}
|
125
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/auth/SkinmeAuthenticator.java
Normal file
125
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/auth/SkinmeAuthenticator.java
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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.launcher.utils.auth;
|
||||
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.views.Selector;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class SkinmeAuthenticator extends IAuthenticator {
|
||||
|
||||
public SkinmeAuthenticator(String clientToken) {
|
||||
super(clientToken);
|
||||
}
|
||||
|
||||
public String[] parseType1(String s) {
|
||||
return s.split(",");
|
||||
}
|
||||
|
||||
public String getCharacter(String user, String hash, String $char) throws Exception {
|
||||
if ($char == null)
|
||||
return NetUtils.doGet(
|
||||
"http://www.skinme.cc/api/login.php?user=" + user + "&hash=" + hash);
|
||||
else
|
||||
return NetUtils.doGet(
|
||||
"http://www.skinme.cc/api/login.php?user=" + user + "&hash=" + hash + "&char=" + $char);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider login(LoginInfo info) {
|
||||
UserProfileProvider req = new UserProfileProvider();
|
||||
if (info.username == null || !info.username.contains("@")) {
|
||||
req.setSuccess(false);
|
||||
req.setErrorReason(C.i18n("login.not_email"));
|
||||
return req;
|
||||
}
|
||||
try {
|
||||
String usr = info.username.toLowerCase();
|
||||
String pwd = info.password;
|
||||
|
||||
String str = DigestUtils.sha1Hex(usr);
|
||||
String hashCode = DigestUtils.sha1Hex(DigestUtils.md5Hex(DigestUtils.sha1Hex(pwd) + pwd) + str);
|
||||
String data = getCharacter(usr, hashCode, null);
|
||||
String[] sl = data.split(":");
|
||||
if (null != sl[0]) switch (sl[0]) {
|
||||
case "0":
|
||||
req.setSuccess(false);
|
||||
req.setErrorReason(sl[1]);
|
||||
break;
|
||||
case "1": {
|
||||
req.setSuccess(true);
|
||||
String[] s = parseType1(sl[1]);
|
||||
req.setUserName(s[0]);
|
||||
req.setSession(s[1]);
|
||||
req.setUserId(s[1]);
|
||||
req.setAccessToken(s[1]);
|
||||
break;
|
||||
}
|
||||
case "2": {
|
||||
req.setSuccess(true);
|
||||
String[] charators = sl[1].split(";");
|
||||
int len = charators.length;
|
||||
String[] $char = new String[len];
|
||||
String[] user = new String[len];
|
||||
System.out.println(sl[1]);
|
||||
for (int i = 0; i < len; i++) {
|
||||
String[] charator = charators[i].split(",");
|
||||
$char[i] = charator[0];
|
||||
user[i] = charator[1];
|
||||
}
|
||||
Selector s = new Selector(null, user, C.i18n("login.choose_charactor"));
|
||||
s.setVisible(true);
|
||||
if (s.sel == Selector.failedToSel) {
|
||||
req.setSuccess(false);
|
||||
req.setErrorReason(C.i18n("message.cancelled"));
|
||||
} else {
|
||||
int index = s.sel;
|
||||
String character = $char[index];
|
||||
sl = getCharacter(usr, hashCode, character).split(":");
|
||||
String[] s2 = parseType1(sl[1]);
|
||||
req.setUserName(s2[0]);
|
||||
req.setSession(s2[1]);
|
||||
req.setUserId(s2[1]);
|
||||
req.setAccessToken(s2[1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
req.setUserType("Legacy");
|
||||
return req;
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Failed to login skinme.", e);
|
||||
|
||||
req.setUserName(info.username);
|
||||
req.setSuccess(false);
|
||||
req.setUserType("Legacy");
|
||||
req.setErrorReason(e.getMessage());
|
||||
return req;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Skinme";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider loginBySettings() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
|
||||
}
|
||||
}
|
112
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/auth/UserProfileProvider.java
Normal file
112
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/auth/UserProfileProvider.java
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.auth;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class UserProfileProvider {
|
||||
|
||||
public String getUserName() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUserName(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public void setSession(String session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public boolean isSuccessful() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getErrorReason() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setErrorReason(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public String getUserProperties() {
|
||||
return userProperties;
|
||||
}
|
||||
|
||||
public void setUserProperties(String userProperties) {
|
||||
this.userProperties = userProperties;
|
||||
}
|
||||
|
||||
public String getUserPropertyMap() {
|
||||
return userPropertyMap;
|
||||
}
|
||||
|
||||
public void setUserPropertyMap(String userPropertyMap) {
|
||||
this.userPropertyMap = userPropertyMap;
|
||||
}
|
||||
|
||||
public String getOtherInfo() {
|
||||
return otherInfo;
|
||||
}
|
||||
|
||||
public void setOtherInfo(String otherInfo) {
|
||||
this.otherInfo = otherInfo;
|
||||
}
|
||||
|
||||
public String getClientIdentifier() {
|
||||
return clientIdentifier;
|
||||
}
|
||||
|
||||
public void setClientIdentifier(String clientIdentifier) {
|
||||
this.clientIdentifier = clientIdentifier;
|
||||
}
|
||||
|
||||
public String getUserType() {
|
||||
return userType;
|
||||
}
|
||||
|
||||
public void setUserType(String userType) {
|
||||
this.userType = userType;
|
||||
}
|
||||
|
||||
private String username = "";
|
||||
private String userId = "";
|
||||
private String session = "";
|
||||
private String accessToken = "";
|
||||
private boolean success = false;
|
||||
private String error = "";
|
||||
private String userProperties = "{}";
|
||||
private String userPropertyMap = "{}";
|
||||
private String otherInfo = "";
|
||||
private String clientIdentifier = "";
|
||||
private String userType = "Offline";
|
||||
}
|
145
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/auth/YggdrasilAuthenticator.java
Normal file
145
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/auth/YggdrasilAuthenticator.java
Normal file
@ -0,0 +1,145 @@
|
||||
package org.jackhuang.hellominecraft.launcher.utils.auth;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.net.Proxy;
|
||||
import java.util.Map;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.views.Selector;
|
||||
import org.jackhuang.mojang.authlib.Agent;
|
||||
import org.jackhuang.mojang.authlib.GameProfile;
|
||||
import org.jackhuang.mojang.authlib.UserType;
|
||||
import org.jackhuang.mojang.authlib.properties.PropertyMap;
|
||||
import org.jackhuang.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
import org.jackhuang.mojang.authlib.yggdrasil.YggdrasilUserAuthentication;
|
||||
import org.jackhuang.mojang.util.LegacyPropertyMapSerializer;
|
||||
import org.jackhuang.mojang.util.UUIDTypeAdapter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class YggdrasilAuthenticator extends IAuthenticator {
|
||||
|
||||
YggdrasilAuthenticationService service;
|
||||
YggdrasilUserAuthentication ua;
|
||||
|
||||
public YggdrasilAuthenticator(String clientToken) {
|
||||
super(clientToken);
|
||||
service = new YggdrasilAuthenticationService(Proxy.NO_PROXY, clientToken);
|
||||
ua = (YggdrasilUserAuthentication)service.createUserAuthentication(Agent.MINECRAFT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider login(LoginInfo info) {
|
||||
if(ua.canPlayOnline()) {
|
||||
UserProfileProvider result = new UserProfileProvider();
|
||||
result.setUserName(info.username);
|
||||
result.setSuccess(true);
|
||||
result.setUserId(UUIDTypeAdapter.fromUUID(ua.getSelectedProfile().getId()));
|
||||
result.setUserProperties(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new LegacyPropertyMapSerializer()).create().toJson(ua.getUserProperties()));
|
||||
result.setUserPropertyMap(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create().toJson(ua.getUserProperties()));
|
||||
result.setAccessToken(ua.getAuthenticatedToken());
|
||||
result.setSession(ua.getAuthenticatedToken());
|
||||
result.setUserType(ua.getUserType().getName());
|
||||
return result;
|
||||
}
|
||||
UserProfileProvider result = new UserProfileProvider();
|
||||
String usr = info.username;
|
||||
if(info.username == null || !info.username.contains("@")) {
|
||||
result.setSuccess(false);
|
||||
result.setErrorReason(C.i18n("login.not_email"));
|
||||
return result;
|
||||
}
|
||||
String pwd = info.password;
|
||||
|
||||
if(!ua.isLoggedIn())
|
||||
ua.setPassword(pwd);
|
||||
ua.setUsername(usr);
|
||||
try {
|
||||
ua.logIn();
|
||||
if(!ua.isLoggedIn()) throw new Exception(C.i18n("login.wrong_password"));
|
||||
GameProfile selectedProfile = ua.getSelectedProfile();
|
||||
GameProfile[] profiles = ua.getAvailableProfiles();
|
||||
String[] names;
|
||||
String username;
|
||||
if(selectedProfile == null) {
|
||||
if(ArrayUtils.isNotEmpty(profiles)) {
|
||||
names = new String[profiles.length];
|
||||
for(int i = 0; i < profiles.length; i++) {
|
||||
names[i] = profiles[i].getName();
|
||||
}
|
||||
Selector s = new Selector(null, names, C.i18n("login.choose_charactor"));
|
||||
s.setVisible(true);
|
||||
selectedProfile = profiles[s.sel];
|
||||
username = names[s.sel];
|
||||
} else {
|
||||
username = JOptionPane.showInputDialog(C.i18n("login.no_charactor"));
|
||||
}
|
||||
} else {
|
||||
username = selectedProfile.getName();
|
||||
}
|
||||
result.setUserName(username);
|
||||
result.setSuccess(true);
|
||||
result.setUserId(UUIDTypeAdapter.fromUUID(selectedProfile.getId()));
|
||||
result.setUserProperties(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new LegacyPropertyMapSerializer()).create().toJson(ua.getUserProperties()));
|
||||
result.setUserPropertyMap(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create().toJson(ua.getUserProperties()));
|
||||
result.setAccessToken(ua.getAuthenticatedToken());
|
||||
result.setSession(ua.getAuthenticatedToken());
|
||||
result.setUserType(ua.getUserType().getName());
|
||||
} catch (Exception ex) {
|
||||
result.setErrorReason(ex.getMessage());
|
||||
result.setSuccess(false);
|
||||
result.setUserName(ua.getUserID());
|
||||
result.setUserType(UserType.MOJANG.getName());
|
||||
|
||||
HMCLog.err("Failed to login by yggdrasil authentication.", ex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggedIn() {
|
||||
return ua.isLoggedIn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return C.i18n("login.methods.yggdrasil");
|
||||
}
|
||||
|
||||
public Map onSaveSettings() {
|
||||
return ua.saveForStorage();
|
||||
}
|
||||
|
||||
public void onLoadSettings(Map settings) {
|
||||
if(settings == null) return;
|
||||
ua.loadFromStorage(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider loginBySettings() {
|
||||
UserProfileProvider info = new UserProfileProvider();
|
||||
try {
|
||||
ua.logIn();
|
||||
if(!ua.isLoggedIn()) throw new Exception(C.i18n("WrongPassword"));
|
||||
GameProfile profile = ua.getSelectedProfile();
|
||||
info.setUserName(profile.getName());
|
||||
info.setSuccess(true);
|
||||
info.setUserId(profile.getId().toString());
|
||||
info.setAccessToken(ua.getAuthenticatedToken());
|
||||
} catch (Exception ex) {
|
||||
info.setErrorReason(ex.getMessage());
|
||||
info.setSuccess(false);
|
||||
info.setUserName(ua.getUserID());
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
ua.logOut();
|
||||
}
|
||||
}
|
70
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/download/BMCLAPIDownloadProvider.java
Normal file
70
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/download/BMCLAPIDownloadProvider.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.launcher.utils.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class BMCLAPIDownloadProvider implements IDownloadProvider {
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getForgeInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.utils.installers.forge.bmcl.ForgeBMCLVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getLiteLoaderInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getOptiFineInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.utils.installers.optifine.bmcl.OptiFineBMCLVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getInstallerByType(String type) {
|
||||
if(type.equalsIgnoreCase("forge")) return getForgeInstaller();
|
||||
if(type.equalsIgnoreCase("liteloader")) return getLiteLoaderInstaller();
|
||||
if(type.equalsIgnoreCase("optifine")) return getOptiFineInstaller();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLibraryDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/libraries";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/versions/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIndexesDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/indexes/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsListDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/versions/versions.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssetsDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/assets/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToUseSelfURL() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
33
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/download/DownloadType.java
Normal file
33
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/download/DownloadType.java
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.launcher.utils.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public enum DownloadType {
|
||||
Mojang(C.i18n("download.mojang"), new MojangDownloadProvider()),
|
||||
BMCL(C.i18n("download.BMCL"), new BMCLAPIDownloadProvider());
|
||||
|
||||
private final String name;
|
||||
private final IDownloadProvider provider;
|
||||
|
||||
DownloadType(String a, IDownloadProvider provider) {
|
||||
name = a;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public IDownloadProvider getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
25
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/download/IDownloadProvider.java
Normal file
25
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/download/IDownloadProvider.java
Normal file
@ -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.launcher.utils.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface IDownloadProvider {
|
||||
InstallerVersionList getInstallerByType(String type);
|
||||
InstallerVersionList getForgeInstaller();
|
||||
InstallerVersionList getLiteLoaderInstaller();
|
||||
InstallerVersionList getOptiFineInstaller();
|
||||
String getLibraryDownloadURL();
|
||||
String getVersionsDownloadURL();
|
||||
String getIndexesDownloadURL();
|
||||
String getVersionsListDownloadURL();
|
||||
String getAssetsDownloadURL();
|
||||
boolean isAllowedToUseSelfURL();
|
||||
}
|
70
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/download/MojangDownloadProvider.java
Normal file
70
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/download/MojangDownloadProvider.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.launcher.utils.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MojangDownloadProvider implements IDownloadProvider {
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getForgeInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.utils.installers.forge.vanilla.MinecraftForgeVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getLiteLoaderInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getOptiFineInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.utils.installers.optifine.vanilla.OptiFineVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getInstallerByType(String type) {
|
||||
if(type.equalsIgnoreCase("forge")) return getForgeInstaller();
|
||||
if(type.equalsIgnoreCase("liteloader")) return getLiteLoaderInstaller();
|
||||
if(type.equalsIgnoreCase("optifine")) return getOptiFineInstaller();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLibraryDownloadURL() {
|
||||
return "https://libraries.minecraft.net";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsDownloadURL() {
|
||||
return "https://s3.amazonaws.com/Minecraft.Download/versions/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIndexesDownloadURL() {
|
||||
return "https://s3.amazonaws.com/Minecraft.Download/indexes/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsListDownloadURL() {
|
||||
return "https://s3.amazonaws.com/Minecraft.Download/versions/versions.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssetsDownloadURL() {
|
||||
return "http://resources.download.minecraft.net/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToUseSelfURL() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
22
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/InstallProfile.java
Normal file
22
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/InstallProfile.java
Normal file
@ -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.launcher.utils.installers;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.forge.Install;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class InstallProfile {
|
||||
@SerializedName("install")
|
||||
public Install install;
|
||||
@SerializedName("versionInfo")
|
||||
public MinecraftVersion versionInfo;
|
||||
}
|
56
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/InstallerVersionList.java
Normal file
56
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/InstallerVersionList.java
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.launcher.utils.installers;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract class InstallerVersionList implements Consumer<String[]> {
|
||||
/**
|
||||
* Refresh installer versions list from the downloaded content.
|
||||
*/
|
||||
public abstract void refreshList(String[] versions) throws Exception;
|
||||
public abstract String getName();
|
||||
public abstract List<InstallerVersion> getVersions(String mcVersion);
|
||||
|
||||
public static class InstallerVersion implements Comparable<InstallerVersion> {
|
||||
public String selfVersion, mcVersion;
|
||||
public String installer, universal;
|
||||
public String changelog;
|
||||
|
||||
public InstallerVersion(String selfVersion, String mcVersion) {
|
||||
this.selfVersion = selfVersion;
|
||||
this.mcVersion = mcVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(InstallerVersion o) {
|
||||
return selfVersion.compareTo(o.selfVersion);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InstallerVersionComparator implements Comparator<InstallerVersion> {
|
||||
public static final InstallerVersionComparator INSTANCE = new InstallerVersionComparator();
|
||||
@Override
|
||||
public int compare(InstallerVersion o1, InstallerVersion o2) {
|
||||
return o2.compareTo(o1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(String[] v) {
|
||||
try {
|
||||
refreshList(v);
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
21
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/InstallerVersionNewerComparator.java
Normal file
21
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/InstallerVersionNewerComparator.java
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.launcher.utils.installers;
|
||||
|
||||
import java.util.Comparator;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList.InstallerVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class InstallerVersionNewerComparator implements Comparator<InstallerVersion> {
|
||||
|
||||
@Override
|
||||
public int compare(InstallerVersion o1, InstallerVersion o2) {
|
||||
return -o1.compareTo(o2);
|
||||
}
|
||||
}
|
35
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/PackMinecraftInstaller.java
Normal file
35
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/PackMinecraftInstaller.java
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.installers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.utils.Compressor;
|
||||
import org.jackhuang.hellominecraft.utils.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class PackMinecraftInstaller {
|
||||
|
||||
File dest;
|
||||
ArrayList<String> src;
|
||||
|
||||
public PackMinecraftInstaller(ArrayList<String> src, File dest) {
|
||||
this.dest = dest;
|
||||
this.src = src;
|
||||
}
|
||||
|
||||
public void install() throws IOException {
|
||||
File file = new File(IOUtils.currentDir(), "HMCL-MERGE-TEMP");
|
||||
file.mkdirs();
|
||||
for (String src1 : src) Compressor.unzip(new File(src1), file);
|
||||
Compressor.zip(file, dest);
|
||||
FileUtils.deleteDirectory(file);
|
||||
}
|
||||
}
|
103
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/ForgeInstaller.java
Normal file
103
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/ForgeInstaller.java
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.launcher.utils.installers.forge;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallProfile;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ForgeInstaller extends Task {
|
||||
|
||||
private final Gson gson = new Gson();
|
||||
public File gameDir;
|
||||
public File forgeInstaller;
|
||||
public IMinecraftProvider mp;
|
||||
|
||||
public ForgeInstaller(IMinecraftProvider mp, File forgeInstaller) {
|
||||
this.gameDir = mp.getBaseFolder();
|
||||
this.forgeInstaller = forgeInstaller;
|
||||
this.mp = mp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeTask() {
|
||||
try {
|
||||
HMCLog.log("Extracting install profiles...");
|
||||
|
||||
ZipFile zipFile = new ZipFile(forgeInstaller);
|
||||
ZipEntry entry = zipFile.getEntry("install_profile.json");
|
||||
String content = NetUtils.getStreamContent(zipFile.getInputStream(entry));
|
||||
InstallProfile profile = gson.fromJson(content, InstallProfile.class);
|
||||
|
||||
File from = new File(gameDir, "versions" + File.separator + profile.install.minecraft);
|
||||
if(!from.exists()) {
|
||||
if(MessageBox.Show(C.i18n("install.no_version_if_intall")) == MessageBox.YES_OPTION) {
|
||||
if(!mp.install(profile.install.minecraft, Settings.s().getDownloadSource())) {
|
||||
setFailReason(new RuntimeException(C.i18n("install.no_version")));
|
||||
}
|
||||
} else {
|
||||
setFailReason(new RuntimeException(C.i18n("install.no_version")));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
File to = new File(gameDir, "versions" + File.separator + profile.install.target);
|
||||
to.mkdirs();
|
||||
|
||||
HMCLog.log("Copying jar..." + profile.install.minecraft + ".jar to " + profile.install.target + ".jar");
|
||||
FileUtils.copyFile(new File(from, profile.install.minecraft + ".jar"),
|
||||
new File(to, profile.install.target + ".jar"));
|
||||
HMCLog.log("Creating new version profile..." + profile.install.target + ".json");
|
||||
FileUtils.write(new File(to, profile.install.target + ".json"), gson.toJson(profile.versionInfo));
|
||||
|
||||
HMCLog.log("Extracting universal forge pack..." + profile.install.filePath);
|
||||
|
||||
entry = zipFile.getEntry(profile.install.filePath);
|
||||
InputStream is = zipFile.getInputStream(entry);
|
||||
|
||||
MinecraftLibrary forge = new MinecraftLibrary(profile.install.path);
|
||||
forge.init();
|
||||
File file = new File(gameDir, "libraries/" + forge.formatted);
|
||||
file.getParentFile().mkdirs();
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
BufferedOutputStream bos = new BufferedOutputStream(fos);
|
||||
int c;
|
||||
while ((c = is.read()) != -1) bos.write((byte) c);
|
||||
bos.close();
|
||||
}
|
||||
return true;
|
||||
} catch(IOException | JsonSyntaxException e) {
|
||||
setFailReason(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("install.forge.install");
|
||||
}
|
||||
|
||||
}
|
25
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/ForgeOldInstaller.java
Normal file
25
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/ForgeOldInstaller.java
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.installers.forge;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.PackMinecraftInstaller;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ForgeOldInstaller {
|
||||
|
||||
public static void install(String destMinecraftJar, String srcMinecraftJar, String forgeUniversal) throws IOException {
|
||||
ArrayList<String> al = new ArrayList<String>();
|
||||
al.add(srcMinecraftJar);
|
||||
al.add(forgeUniversal);
|
||||
new PackMinecraftInstaller(al, new File(destMinecraftJar)).install();
|
||||
}
|
||||
|
||||
}
|
23
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/Install.java
Normal file
23
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/Install.java
Normal file
@ -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.launcher.utils.installers.forge;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Install {
|
||||
public String profileName;
|
||||
public String target;
|
||||
public String path;
|
||||
public String version;
|
||||
public String filePath;
|
||||
public String welcome;
|
||||
public String minecraft;
|
||||
public String mirrorList;
|
||||
public String logo;
|
||||
}
|
16
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/bmcl/Downloads.java
Normal file
16
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/bmcl/Downloads.java
Normal file
@ -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.launcher.utils.installers.forge.bmcl;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Downloads {
|
||||
|
||||
public String changelog;
|
||||
public String[] universal, src, javadoc, installer;
|
||||
}
|
87
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/bmcl/ForgeBMCLVersionList.java
Normal file
87
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/bmcl/ForgeBMCLVersionList.java
Normal file
@ -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.launcher.utils.installers.forge.bmcl;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ForgeBMCLVersionList extends InstallerVersionList {
|
||||
|
||||
private static ForgeBMCLVersionList instance;
|
||||
|
||||
public static ForgeBMCLVersionList getInstance() {
|
||||
if (instance == null) instance = new ForgeBMCLVersionList();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public ArrayList<ForgeVersion> root;
|
||||
public Map<String, List<InstallerVersion>> versionMap;
|
||||
public List<InstallerVersion> versions;
|
||||
|
||||
@Override
|
||||
public void refreshList(String[] neededVersions) throws Exception {
|
||||
if(versionMap == null) {
|
||||
versionMap = new HashMap<String, List<InstallerVersion>>();
|
||||
versions = new ArrayList<InstallerVersion>();
|
||||
}
|
||||
|
||||
for (String x : neededVersions) {
|
||||
if(versionMap.containsKey(x)) continue;
|
||||
String s = NetUtils.doGet("http://bmclapi2.bangbang93.com/forge/minecraft/" + x);
|
||||
|
||||
if (s == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
root = C.gson.fromJson(s, new TypeToken<ArrayList<ForgeVersion>>(){}.getType());
|
||||
for (ForgeVersion v : root) {
|
||||
InstallerVersion iv = new InstallerVersion(v.version, StrUtils.formatVersion(v.minecraft));
|
||||
|
||||
List<InstallerVersion> al = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.minecraft));
|
||||
iv.changelog = v.downloads.changelog;
|
||||
iv.installer = "http://bmclapi.bangbang93.com/forge/getforge/" + iv.mcVersion + "/" + iv.selfVersion;
|
||||
iv.universal = ArrayUtils.getEnd(v.downloads.universal);
|
||||
al.add(iv);
|
||||
versions.add(iv);
|
||||
}
|
||||
} catch(JsonSyntaxException e) {
|
||||
HMCLog.warn("Failed to parse BMCLAPI response.", e);
|
||||
}
|
||||
}
|
||||
Collections.sort(versions, new InstallerVersionComparator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstallerVersion> getVersions(String mcVersion) {
|
||||
if (versions == null || versionMap == null) return null;
|
||||
if (StrUtils.isBlank(mcVersion)) return versions;
|
||||
List c = versionMap.get(mcVersion);
|
||||
if (c == null) return versions;
|
||||
Collections.sort(c, InstallerVersionComparator.INSTANCE);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Forge - BMCLAPI (By: bangbang93)";
|
||||
}
|
||||
}
|
14
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/bmcl/ForgeVersion.java
Normal file
14
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/bmcl/ForgeVersion.java
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.installers.forge.bmcl;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class ForgeVersion {
|
||||
public String time, minecraft, version, _id, __v;
|
||||
public Downloads downloads;
|
||||
}
|
17
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/vanilla/MinecraftForgeVersion.java
Normal file
17
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/vanilla/MinecraftForgeVersion.java
Normal file
@ -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.launcher.utils.installers.forge.vanilla;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftForgeVersion {
|
||||
public String branch, mcversion, jobver, version;
|
||||
public int build;
|
||||
public double modified;
|
||||
public String[][] files;
|
||||
}
|
95
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/vanilla/MinecraftForgeVersionList.java
Normal file
95
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/vanilla/MinecraftForgeVersionList.java
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.launcher.utils.installers.forge.vanilla;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionNewerComparator;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftForgeVersionList extends InstallerVersionList {
|
||||
private static MinecraftForgeVersionList instance;
|
||||
public static MinecraftForgeVersionList getInstance() {
|
||||
if(instance == null)
|
||||
instance = new MinecraftForgeVersionList();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public MinecraftForgeVersionRoot root;
|
||||
public Map<String, List<InstallerVersion>> versionMap;
|
||||
public List<InstallerVersion> versions;
|
||||
|
||||
@Override
|
||||
public void refreshList(String[] needed) throws Exception {
|
||||
String s = NetUtils.doGet(C.URL_FORGE_LIST);
|
||||
if(root!=null) return;
|
||||
|
||||
root = C.gson.fromJson(s, MinecraftForgeVersionRoot.class);
|
||||
|
||||
versionMap = new HashMap<String, List<InstallerVersion>>();
|
||||
versions = new ArrayList<InstallerVersion>();
|
||||
|
||||
for(Map.Entry<String, int[]> arr : root.mcversion.entrySet()) {
|
||||
String mcver = StrUtils.formatVersion(arr.getKey());
|
||||
ArrayList<InstallerVersion> al = new ArrayList<InstallerVersion>();
|
||||
for(int num : arr.getValue()) {
|
||||
MinecraftForgeVersion v = root.number.get(num);
|
||||
InstallerVersion iv = new InstallerVersion(v.version, StrUtils.formatVersion(v.mcversion));
|
||||
for(String[] f : v.files) {
|
||||
|
||||
String ver = v.mcversion + "-" + v.version;
|
||||
if(!StrUtils.isBlank(v.branch)) {
|
||||
ver = ver + "-" + v.branch;
|
||||
}
|
||||
String filename = root.artifact + "-" + ver + "-" + f[1] + "." + f[0];
|
||||
String url = root.webpath + "/" + ver + "/" + filename;
|
||||
if(f[1].equals("installer")) {
|
||||
iv.installer = url;
|
||||
} else if(f[1].equals("universal")) {
|
||||
iv.universal = url;
|
||||
} else if(f[1].equals("changelog")) {
|
||||
iv.changelog = url;
|
||||
}
|
||||
}
|
||||
if(StrUtils.isBlank(iv.installer) || StrUtils.isBlank(iv.universal)) {
|
||||
continue;
|
||||
}
|
||||
Collections.sort(al, new InstallerVersionNewerComparator());
|
||||
al.add(iv);
|
||||
versions.add(iv);
|
||||
}
|
||||
|
||||
versionMap.put(StrUtils.formatVersion(mcver), al);
|
||||
}
|
||||
|
||||
Collections.sort(versions, new InstallerVersionComparator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstallerVersion> getVersions(String mcVersion) {
|
||||
if (versions == null || versionMap == null) return null;
|
||||
if(StrUtils.isBlank(mcVersion)) return versions;
|
||||
List c = versionMap.get(mcVersion);
|
||||
if(c == null) return versions;
|
||||
Collections.sort(c, InstallerVersionComparator.INSTANCE);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Forge - MinecraftForge Offical Site";
|
||||
}
|
||||
}
|
19
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/vanilla/MinecraftForgeVersionRoot.java
Normal file
19
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/forge/vanilla/MinecraftForgeVersionRoot.java
Normal file
@ -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.launcher.utils.installers.forge.vanilla;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftForgeVersionRoot {
|
||||
public String artifact, webpath, adfly, homepage, name;
|
||||
public Map<String, int[]> branches, mcversion;
|
||||
public Map<String, Integer> promos;
|
||||
public Map<Integer, MinecraftForgeVersion> number;
|
||||
}
|
90
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderInstaller.java
Normal file
90
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderInstaller.java
Normal file
@ -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.launcher.utils.installers.liteloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
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.launcher.utils.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.utils.FileUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class LiteLoaderInstaller extends Task implements PreviousResultRegistrator<File> {
|
||||
|
||||
public LiteLoaderVersionList.LiteLoaderInstallerVersion version;
|
||||
public File installer;
|
||||
public Profile profile;
|
||||
|
||||
public LiteLoaderInstaller(Profile profile, LiteLoaderVersionList.LiteLoaderInstallerVersion v) {
|
||||
this(profile, v, null);
|
||||
}
|
||||
|
||||
public LiteLoaderInstaller(Profile profile, LiteLoaderVersionList.LiteLoaderInstallerVersion v, File installer) {
|
||||
this.profile = profile;
|
||||
this.version = v;
|
||||
this.installer = installer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeTask() {
|
||||
if(profile == null || profile.getSelectedMinecraftVersion() == null) {
|
||||
setFailReason(new RuntimeException(C.i18n("install.no_version")));
|
||||
return false;
|
||||
}
|
||||
if(pre.size() != 1 && installer == null) throw new IllegalStateException("No registered previous task.");
|
||||
if(installer == null)
|
||||
installer = pre.get(pre.size() - 1).getResult();
|
||||
try {
|
||||
MinecraftVersion mv = (MinecraftVersion) profile.getSelectedMinecraftVersion().clone();
|
||||
mv.inheritsFrom = mv.id;
|
||||
mv.jar = mv.jar == null ? mv.id : mv.jar;
|
||||
mv.libraries = new ArrayList(Arrays.asList(version.libraries));
|
||||
|
||||
mv.libraries.add(0, new MinecraftLibrary("com.mumfrey:liteloader:" + version.selfVersion));
|
||||
FileUtils.copyFile(installer, new File(profile.getCanonicalGameDir(), "libraries/com/mumfrey/liteloader/" + version.selfVersion + "/liteloader-" + version.selfVersion + ".jar"));
|
||||
|
||||
mv.id += "-LiteLoader" + version.selfVersion;
|
||||
|
||||
if(!mv.mainClass.startsWith("net.minecraft.launchwrapper.")) {
|
||||
mv.mainClass = "net.minecraft.launchwrapper.Launch";
|
||||
mv.minecraftArguments += " --tweakClass " + version.tweakClass;
|
||||
}
|
||||
File folder = new File(profile.getCanonicalGameDir(), "versions/" + mv.id);
|
||||
folder.mkdirs();
|
||||
File json = new File(folder, mv.id + ".json");
|
||||
HMCLog.log("Creating new version profile..." + mv.id + ".json");
|
||||
FileUtils.write(json, C.gsonPrettyPrinting.toJson(mv));
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
setFailReason(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("install.liteloader.install");
|
||||
}
|
||||
|
||||
ArrayList<PreviousResult<File>> pre = new ArrayList();
|
||||
@Override
|
||||
public Task registerPreviousResult(PreviousResult pr) {
|
||||
pre.add(pr);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
16
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderMCVersions.java
Normal file
16
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderMCVersions.java
Normal file
@ -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.launcher.utils.installers.liteloader;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LiteLoaderMCVersions {
|
||||
public Map<String, Map<String, LiteLoaderVersion>> artefacts;
|
||||
}
|
17
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderVersion.java
Normal file
17
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderVersion.java
Normal file
@ -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.launcher.utils.installers.liteloader;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftLibrary;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LiteLoaderVersion {
|
||||
public String tweakClass, file, version, md5, timestamp;
|
||||
public MinecraftLibrary[] libraries;
|
||||
}
|
94
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderVersionList.java
Normal file
94
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderVersionList.java
Normal file
@ -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.launcher.utils.installers.liteloader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList.InstallerVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionNewerComparator;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class LiteLoaderVersionList extends InstallerVersionList {
|
||||
private static LiteLoaderVersionList instance;
|
||||
public static LiteLoaderVersionList getInstance() {
|
||||
if(instance == null) {
|
||||
instance = new LiteLoaderVersionList();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public LiteLoaderVersionsRoot root;
|
||||
public Map<String, List<InstallerVersion>> versionMap;
|
||||
public List<InstallerVersion> versions;
|
||||
|
||||
@Override
|
||||
public void refreshList(String[] needed) throws Exception {
|
||||
String s = NetUtils.doGet(C.URL_LITELOADER_LIST);
|
||||
if(root != null) return;
|
||||
|
||||
root = C.gson.fromJson(s, LiteLoaderVersionsRoot.class);
|
||||
|
||||
versionMap = new HashMap<String, List<InstallerVersion>>();
|
||||
versions = new ArrayList<InstallerVersion>();
|
||||
|
||||
for(Map.Entry<String, LiteLoaderMCVersions> arr : root.versions.entrySet()) {
|
||||
ArrayList<InstallerVersion> al = new ArrayList<InstallerVersion>();
|
||||
LiteLoaderMCVersions mcv = arr.getValue();
|
||||
for(Map.Entry<String, LiteLoaderVersion> entry : mcv.artefacts.get("com.mumfrey:liteloader").entrySet()) {
|
||||
if("latest".equals(entry.getKey())) continue;
|
||||
LiteLoaderVersion v = entry.getValue();
|
||||
LiteLoaderInstallerVersion iv = new LiteLoaderInstallerVersion(v.version, StrUtils.formatVersion(arr.getKey()));
|
||||
iv.universal = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + arr.getKey() + "/" + v.file;
|
||||
iv.tweakClass = v.tweakClass;
|
||||
iv.libraries = Arrays.copyOf(v.libraries, v.libraries.length);
|
||||
iv.installer = "http://dl.liteloader.com/redist/" + iv.mcVersion + "/liteloader-installer-" + iv.selfVersion.replace("_", "-") + ".jar";
|
||||
al.add(iv);
|
||||
versions.add(iv);
|
||||
}
|
||||
Collections.sort(al, new InstallerVersionNewerComparator());
|
||||
versionMap.put(StrUtils.formatVersion(arr.getKey()), al);
|
||||
}
|
||||
|
||||
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstallerVersion> getVersions(String mcVersion) {
|
||||
if (versions == null || versionMap == null) return null;
|
||||
if(StrUtils.isBlank(mcVersion)) return versions;
|
||||
List c = versionMap.get(mcVersion);
|
||||
if(c == null) return versions;
|
||||
Collections.sort(c, InstallerVersionComparator.INSTANCE);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "LiteLoader - LiteLoader Official Site(By: Mumfrey)";
|
||||
}
|
||||
|
||||
public static class LiteLoaderInstallerVersion extends InstallerVersion {
|
||||
public MinecraftLibrary[] libraries;
|
||||
public String tweakClass;
|
||||
|
||||
public LiteLoaderInstallerVersion(String selfVersion, String mcVersion) {
|
||||
super(selfVersion, mcVersion);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
14
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderVersionsMeta.java
Normal file
14
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderVersionsMeta.java
Normal file
@ -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.launcher.utils.installers.liteloader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LiteLoaderVersionsMeta {
|
||||
public String description, authors, url;
|
||||
}
|
17
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderVersionsRoot.java
Normal file
17
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/liteloader/LiteLoaderVersionsRoot.java
Normal file
@ -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.launcher.utils.installers.liteloader;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class LiteLoaderVersionsRoot {
|
||||
public Map<String, LiteLoaderMCVersions> versions;
|
||||
public LiteLoaderVersionsMeta meta;
|
||||
}
|
87
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/optifine/OptiFineInstaller.java
Normal file
87
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/optifine/OptiFineInstaller.java
Normal file
@ -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.launcher.utils.installers.optifine;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Profile;
|
||||
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.FileUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class OptiFineInstaller extends Task implements PreviousResultRegistrator<File> {
|
||||
|
||||
public File installer;
|
||||
public Profile profile;
|
||||
public String version;
|
||||
|
||||
public OptiFineInstaller(Profile profile, String version) {
|
||||
this(profile, version, null);
|
||||
}
|
||||
|
||||
public OptiFineInstaller(Profile profile, String version, File installer) {
|
||||
this.profile = profile;
|
||||
this.installer = installer;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeTask() {
|
||||
if(profile == null || profile.getSelectedMinecraftVersion() == null) {
|
||||
setFailReason(new RuntimeException(C.i18n("install.no_version")));
|
||||
return false;
|
||||
}
|
||||
MinecraftVersion mv = (MinecraftVersion)profile.getSelectedMinecraftVersion().clone();
|
||||
|
||||
try {
|
||||
mv.inheritsFrom = mv.id;
|
||||
mv.jar = mv.jar == null ? mv.id : mv.jar;
|
||||
mv.libraries.clear();
|
||||
mv.libraries.add(0, new MinecraftLibrary("optifine:OptiFine:" + version));
|
||||
FileUtils.copyFile(installer, new File(profile.getCanonicalGameDir(), "libraries/optifine/OptiFine/" + version + "/OptiFine-" + version + ".jar"));
|
||||
|
||||
mv.id += "-" + version;
|
||||
if(new ZipFile(installer).getEntry("optifine/OptiFineTweaker.class") != null) {
|
||||
if(!mv.mainClass.startsWith("net.minecraft.launchwrapper.")) {
|
||||
mv.mainClass = "net.minecraft.launchwrapper.Launch";
|
||||
mv.minecraftArguments += " --tweakClass optifine.OptiFineTweaker";
|
||||
mv.libraries.add(1, new MinecraftLibrary("net.minecraft:launchwrapper:1.7"));
|
||||
}
|
||||
}
|
||||
File loc = new File(profile.getCanonicalGameDir(), "versions/" + mv.id);
|
||||
loc.mkdirs();
|
||||
File json = new File(loc, mv.id + ".json");
|
||||
FileUtils.writeStringToFile(json, C.gsonPrettyPrinting.toJson(mv, MinecraftVersion.class));
|
||||
} catch (IOException ex) {
|
||||
setFailReason(ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "Optifine Installer";
|
||||
}
|
||||
|
||||
ArrayList<PreviousResult<File>> pre = new ArrayList();
|
||||
@Override
|
||||
public Task registerPreviousResult(PreviousResult pr) {
|
||||
pre.add(pr);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
13
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/optifine/OptiFineVersion.java
Normal file
13
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/optifine/OptiFineVersion.java
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.installers.optifine;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class OptiFineVersion {
|
||||
public String dl, ver, date, mirror, mcver;
|
||||
}
|
87
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/optifine/bmcl/OptiFineBMCLVersionList.java
Normal file
87
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/optifine/bmcl/OptiFineBMCLVersionList.java
Normal file
@ -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.launcher.utils.installers.optifine.bmcl;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.optifine.OptiFineVersion;
|
||||
import org.jackhuang.hellominecraft.utils.tinystream.CollectionUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class OptiFineBMCLVersionList extends InstallerVersionList {
|
||||
|
||||
private static OptiFineBMCLVersionList instance;
|
||||
|
||||
public static OptiFineBMCLVersionList getInstance() {
|
||||
if (null == instance)
|
||||
instance = new OptiFineBMCLVersionList();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public ArrayList<OptiFineVersion> root;
|
||||
public Map<String, List<InstallerVersion>> versionMap;
|
||||
public List<InstallerVersion> versions;
|
||||
|
||||
@Override
|
||||
public void refreshList(String[] needed) throws Exception {
|
||||
String s = NetUtils.doGet("http://bmclapi.bangbang93.com/optifine/versionlist");
|
||||
|
||||
versionMap = new HashMap<>();
|
||||
versions = new ArrayList<>();
|
||||
|
||||
if (s == null) return;
|
||||
root = C.gson.fromJson(s, new TypeToken<ArrayList<OptiFineVersion>>() {
|
||||
}.getType());
|
||||
for(OptiFineVersion v : root) {
|
||||
v.mirror = v.mirror.replace("http://optifine.net/http://optifine.net/", "http://optifine.net/");
|
||||
|
||||
if (StrUtils.isBlank(v.mcver)) {
|
||||
Pattern p = Pattern.compile("OptiFine (.*) HD");
|
||||
Matcher m = p.matcher(v.ver);
|
||||
while (m.find()) v.mcver = m.group(1);
|
||||
}
|
||||
InstallerVersion iv = new InstallerVersion(v.ver, StrUtils.formatVersion(v.mcver));
|
||||
|
||||
List<InstallerVersion> al = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.mcver));
|
||||
String url = "http://bmclapi.bangbang93.com/optifine/" + iv.selfVersion.replace(" ", "%20");
|
||||
iv.installer = iv.universal = v.mirror;
|
||||
al.add(iv);
|
||||
versions.add(iv);
|
||||
}
|
||||
|
||||
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstallerVersion> getVersions(String mcVersion) {
|
||||
if (versions == null || versionMap == null) return null;
|
||||
if (StrUtils.isBlank(mcVersion)) return versions;
|
||||
List c = versionMap.get(mcVersion);
|
||||
if (c == null) return versions;
|
||||
Collections.sort(c, InstallerVersionComparator.INSTANCE);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "OptiFine - BMCLAPI(By: bangbang93)";
|
||||
}
|
||||
|
||||
}
|
49
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/optifine/vanilla/OptiFineDownloadFormatter.java
Normal file
49
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/optifine/vanilla/OptiFineDownloadFormatter.java
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.launcher.utils.installers.optifine.vanilla;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jackhuang.hellominecraft.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class OptiFineDownloadFormatter extends Task implements PreviousResult<String> {
|
||||
String url, result;
|
||||
|
||||
public OptiFineDownloadFormatter(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeTask() {
|
||||
try {
|
||||
String content = NetUtils.doGet(url);
|
||||
Pattern p = Pattern.compile("\"downloadx\\?f=OptiFine(.*)\"");
|
||||
Matcher m = p.matcher(content);
|
||||
while(m.find()) result = m.group(1);
|
||||
result = "http://optifine.net/downloadx?f=OptiFine" + result;
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
setFailReason(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "Get OptiFine Download Link.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
}
|
119
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/optifine/vanilla/OptiFineVersionList.java
Normal file
119
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/installers/optifine/vanilla/OptiFineVersionList.java
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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.launcher.utils.installers.optifine.vanilla;
|
||||
|
||||
import java.io.StringBufferInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.installers.optifine.OptiFineVersion;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class OptiFineVersionList extends InstallerVersionList {
|
||||
private static OptiFineVersionList instance;
|
||||
public static OptiFineVersionList getInstance() {
|
||||
if(null == instance)
|
||||
instance = new OptiFineVersionList();
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<OptiFineVersion> root = new ArrayList();
|
||||
public Map<String, List<InstallerVersion>> versionMap;
|
||||
public List<InstallerVersion> versions;
|
||||
|
||||
@Override
|
||||
public void refreshList(String[] sss) throws Exception {
|
||||
String content = NetUtils.doGet("http://optifine.net/downloads");
|
||||
if(versions != null) return;
|
||||
versionMap = new HashMap<String, List<InstallerVersion>>();
|
||||
versions = new ArrayList<InstallerVersion>();
|
||||
|
||||
content = content.replace(" ", " ").replace(">", ">").replace("<", "<");
|
||||
|
||||
try {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = factory.newDocumentBuilder();
|
||||
Document doc = db.parse(new StringBufferInputStream(content));
|
||||
Element r = doc.getDocumentElement();
|
||||
NodeList tables = r.getElementsByTagName("table");
|
||||
for(int i = 0; i < tables.getLength(); i++) {
|
||||
Element e = (Element)tables.item(i);
|
||||
if("downloadTable".equals(e.getAttribute("class"))) {
|
||||
NodeList tr = e.getElementsByTagName("tr");
|
||||
for(int k = 0; k < tr.getLength(); k++) {
|
||||
NodeList downloadLine = ((Element)tr.item(k)).getElementsByTagName("td");
|
||||
OptiFineVersion v = new OptiFineVersion();
|
||||
for(int j = 0; j < downloadLine.getLength(); j++) {
|
||||
Element td = (Element)downloadLine.item(j);
|
||||
if(StrUtils.startsWith(td.getAttribute("class"), "downloadLineMirror")) {
|
||||
v.mirror = ((Element)td.getElementsByTagName("a").item(0)).getAttribute("href");
|
||||
}
|
||||
if(StrUtils.startsWith(td.getAttribute("class"), "downloadLineDownload")) {
|
||||
v.dl = ((Element)td.getElementsByTagName("a").item(0)).getAttribute("href");
|
||||
}
|
||||
if(StrUtils.startsWith(td.getAttribute("class"), "downloadLineDate")) {
|
||||
v.date = td.getTextContent();
|
||||
}
|
||||
if(StrUtils.startsWith(td.getAttribute("class"), "downloadLineFile")) {
|
||||
v.ver = td.getTextContent();
|
||||
}
|
||||
}
|
||||
if(StrUtils.isBlank(v.mcver)) {
|
||||
Pattern p = Pattern.compile("OptiFine (.*?) ");
|
||||
Matcher m = p.matcher(v.ver);
|
||||
while(m.find()) v.mcver = StrUtils.formatVersion(m.group(1));
|
||||
}
|
||||
InstallerVersion iv = new InstallerVersion(v.ver, StrUtils.formatVersion(v.mcver));
|
||||
iv.installer = iv.universal = v.mirror;
|
||||
root.add(v);
|
||||
versions.add(iv);
|
||||
|
||||
|
||||
List<InstallerVersion> ivl = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.mcver));
|
||||
ivl.add(iv);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "OptiFine - OptiFine Official Site";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstallerVersion> getVersions(String mcVersion) {
|
||||
if (versions == null || versionMap == null) return null;
|
||||
if(StrUtils.isBlank(mcVersion)) return versions;
|
||||
List c = versionMap.get(mcVersion);
|
||||
if(c == null) return versions;
|
||||
Collections.sort(c, InstallerVersionComparator.INSTANCE);
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.settings;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import org.jackhuang.hellominecraft.utils.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class Config {
|
||||
@SerializedName("last")
|
||||
private String last;
|
||||
@SerializedName("bgpath")
|
||||
private String bgpath;
|
||||
@SerializedName("username")
|
||||
private String username;
|
||||
@SerializedName("clientToken")
|
||||
private String clientToken;
|
||||
@SerializedName("enableShadow")
|
||||
private boolean enableShadow;
|
||||
@SerializedName("theme")
|
||||
private int theme;
|
||||
|
||||
public int getTheme() {
|
||||
return theme;
|
||||
}
|
||||
|
||||
public void setTheme(int theme) {
|
||||
this.theme = theme;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public boolean isEnableShadow() {
|
||||
return enableShadow;
|
||||
}
|
||||
|
||||
public void setEnableShadow(boolean enableShadow) {
|
||||
this.enableShadow = enableShadow;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getLast() {
|
||||
return last;
|
||||
}
|
||||
|
||||
public void setLast(String last) {
|
||||
this.last = last;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getBgpath() {
|
||||
return bgpath;
|
||||
}
|
||||
|
||||
public void setBgpath(String bgpath) {
|
||||
this.bgpath = bgpath;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getClientToken() {
|
||||
return clientToken;
|
||||
}
|
||||
|
||||
public int getLoginType() {
|
||||
return logintype;
|
||||
}
|
||||
|
||||
public void setLoginType(int logintype) {
|
||||
this.logintype = logintype;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public int getDownloadType() {
|
||||
return downloadtype;
|
||||
}
|
||||
|
||||
public void setDownloadType(int downloadtype) {
|
||||
this.downloadtype = downloadtype;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public TreeMap<String, Profile> getConfigurations() {
|
||||
if(configurations == null)
|
||||
configurations = new TreeMap<String, Profile>();
|
||||
return configurations;
|
||||
}
|
||||
|
||||
public boolean isCheckUpdate() {
|
||||
return checkUpdate;
|
||||
}
|
||||
|
||||
public void setCheckUpdate(boolean checkUpdate) {
|
||||
this.checkUpdate = checkUpdate;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public Map getYggdrasilConfig() {
|
||||
return yggdrasil;
|
||||
}
|
||||
|
||||
public void setYggdrasilConfig(Map yggdrasil) {
|
||||
this.yggdrasil = yggdrasil;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
@SerializedName("logintype")
|
||||
private int logintype;
|
||||
@SerializedName("downloadtype")
|
||||
private int downloadtype;
|
||||
@SerializedName("configurations")
|
||||
private TreeMap<String, Profile> configurations;
|
||||
@SerializedName("checkUpdate")
|
||||
private boolean checkUpdate;
|
||||
@SerializedName("yggdrasil")
|
||||
private Map yggdrasil;
|
||||
|
||||
public Config()
|
||||
{
|
||||
clientToken = UUID.randomUUID().toString();
|
||||
username = "";
|
||||
logintype = downloadtype = 0;
|
||||
checkUpdate = true;
|
||||
configurations = new TreeMap<String, Profile>();
|
||||
Profile profile = new Profile();
|
||||
configurations.put(profile.getName(), profile);
|
||||
enableShadow = OS.os() == OS.WINDOWS;
|
||||
theme = 0;
|
||||
}
|
||||
|
||||
public DownloadType getDownloadSource() {
|
||||
if(downloadtype >= DownloadType.values().length || downloadtype < 0) return null;
|
||||
return DownloadType.values()[downloadtype];
|
||||
}
|
||||
}
|
297
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/settings/Profile.java
Normal file
297
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/settings/Profile.java
Normal file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.settings;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.MCUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.GameDirType;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersionManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class Profile {
|
||||
|
||||
private String name, selectedMinecraftVersion = "", javaArgs, minecraftArgs, maxMemory, permSize, width, height, userProperties;
|
||||
private String gameDir, javaDir, wrapperLauncher, serverIp;
|
||||
private boolean fullscreen, debug, noJVMArgs, canceledWrapper;
|
||||
|
||||
/**
|
||||
* 0 - Close the launcher when the game starts.<br/>
|
||||
* 1 - Hide the launcher when the game starts.<br/>
|
||||
* 2 - Keep the launcher open.<br/>
|
||||
*/
|
||||
private int launcherVisibility;
|
||||
|
||||
/**
|
||||
* 0 - .minecraft<br/>
|
||||
* 1 - .minecraft/versions/<version>/<br/>
|
||||
*/
|
||||
private int gameDirType;
|
||||
|
||||
protected transient IMinecraftProvider minecraftProvider;
|
||||
|
||||
public Profile() {
|
||||
this("Default");
|
||||
}
|
||||
|
||||
public Profile(String name) {
|
||||
this.name = name;
|
||||
gameDir = MCUtils.getInitGameDir().getPath();
|
||||
debug = fullscreen = canceledWrapper = false;
|
||||
javaDir = IOUtils.getJavaDir();
|
||||
launcherVisibility = gameDirType = 0;
|
||||
minecraftArgs = serverIp = "";
|
||||
}
|
||||
|
||||
public Profile(Profile v) {
|
||||
this();
|
||||
if (v == null) {
|
||||
return;
|
||||
}
|
||||
name = v.name;
|
||||
gameDir = v.gameDir;
|
||||
maxMemory = v.maxMemory;
|
||||
width = v.width;
|
||||
height = v.height;
|
||||
fullscreen = v.fullscreen;
|
||||
javaArgs = v.javaArgs;
|
||||
javaDir = v.javaDir;
|
||||
debug = v.debug;
|
||||
minecraftArgs = v.minecraftArgs;
|
||||
permSize = v.permSize;
|
||||
gameDirType = v.gameDirType;
|
||||
canceledWrapper = v.canceledWrapper;
|
||||
noJVMArgs = v.noJVMArgs;
|
||||
launcherVisibility = v.launcherVisibility;
|
||||
wrapperLauncher = v.wrapperLauncher;
|
||||
serverIp = v.serverIp;
|
||||
}
|
||||
|
||||
public IMinecraftProvider getMinecraftProvider() {
|
||||
if(minecraftProvider == null) minecraftProvider = new MinecraftVersionManager(this);
|
||||
return minecraftProvider;
|
||||
}
|
||||
|
||||
public MinecraftVersion getSelectedMinecraftVersion() {
|
||||
if (StrUtils.isBlank(selectedMinecraftVersion)) {
|
||||
MinecraftVersion v = getMinecraftProvider().getOneVersion();
|
||||
if (v == null) {
|
||||
return null;
|
||||
}
|
||||
selectedMinecraftVersion = v.id;
|
||||
return v;
|
||||
}
|
||||
MinecraftVersion v = getMinecraftProvider().getVersionById(selectedMinecraftVersion);
|
||||
if(v == null) v = getMinecraftProvider().getOneVersion();
|
||||
if(v != null) setSelectedMinecraftVersion(v.id);
|
||||
return v;
|
||||
}
|
||||
|
||||
public String getGameDir() {
|
||||
if (StrUtils.isBlank(gameDir)) {
|
||||
gameDir = MCUtils.getInitGameDir().getPath();
|
||||
}
|
||||
return IOUtils.addSeparator(gameDir);
|
||||
}
|
||||
|
||||
public String getCanonicalGameDir() {
|
||||
return IOUtils.tryGetCanonicalFolderPath(getGameDirFile());
|
||||
}
|
||||
|
||||
public File getCanonicalGameDirFile() {
|
||||
return IOUtils.tryGetCanonicalFile(getGameDirFile());
|
||||
}
|
||||
|
||||
public File getGameDirFile() {
|
||||
return new File(getGameDir());
|
||||
}
|
||||
|
||||
public Profile setGameDir(String gameDir) {
|
||||
this.gameDir = gameDir;
|
||||
Settings.save();
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getJavaDir() {
|
||||
if (StrUtils.isBlank(javaDir)) {
|
||||
javaDir = IOUtils.getJavaDir();
|
||||
}
|
||||
return javaDir;
|
||||
}
|
||||
|
||||
public File getJavaDirFile() {
|
||||
return new File(getJavaDir());
|
||||
}
|
||||
|
||||
public void setJavaDir(String javaDir) {
|
||||
this.javaDir = javaDir;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public File getFolder(String folder) {
|
||||
return new File(getGameDir(), folder);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setSelectedMinecraftVersion(String selectedMinecraftVersion) {
|
||||
this.selectedMinecraftVersion = selectedMinecraftVersion;
|
||||
}
|
||||
|
||||
public String getJavaArgs() {
|
||||
if(StrUtils.isBlank(javaArgs)) return "";
|
||||
return javaArgs;
|
||||
}
|
||||
|
||||
public void setJavaArgs(String javaArgs) {
|
||||
this.javaArgs = javaArgs;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public boolean hasJavaArgs() {
|
||||
return StrUtils.isNotBlank(getJavaArgs().trim());
|
||||
}
|
||||
|
||||
public String getMaxMemory() {
|
||||
if(StrUtils.isBlank(maxMemory)) return String.valueOf(Utils.getSuggestedMemorySize());
|
||||
return maxMemory;
|
||||
}
|
||||
|
||||
public void setMaxMemory(String maxMemory) {
|
||||
this.maxMemory = maxMemory;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getWidth() {
|
||||
if(StrUtils.isBlank(width)) return "854";
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(String width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public String getHeight() {
|
||||
if(StrUtils.isBlank(height)) return "480";
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(String height) {
|
||||
this.height = height;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getUserProperties() {
|
||||
if(userProperties == null) return "";
|
||||
return userProperties;
|
||||
}
|
||||
|
||||
public void setUserProperties(String userProperties) {
|
||||
this.userProperties = userProperties;
|
||||
}
|
||||
|
||||
public boolean isFullscreen() {
|
||||
return fullscreen;
|
||||
}
|
||||
|
||||
public void setFullscreen(boolean fullscreen) {
|
||||
this.fullscreen = fullscreen;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public int getLauncherVisibility() {
|
||||
return launcherVisibility;
|
||||
}
|
||||
|
||||
public void setLauncherVisibility(int launcherVisibility) {
|
||||
this.launcherVisibility = launcherVisibility;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public GameDirType getGameDirType() {
|
||||
return GameDirType.values()[gameDirType];
|
||||
}
|
||||
|
||||
public void setGameDirType(GameDirType gameDirType) {
|
||||
this.gameDirType = gameDirType.ordinal();
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getPermSize() {
|
||||
return permSize;
|
||||
}
|
||||
|
||||
public void setPermSize(String permSize) {
|
||||
this.permSize = permSize;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public boolean isNoJVMArgs() {
|
||||
return noJVMArgs;
|
||||
}
|
||||
|
||||
public void setNoJVMArgs(boolean noJVMArgs) {
|
||||
this.noJVMArgs = noJVMArgs;
|
||||
}
|
||||
|
||||
public String getMinecraftArgs() {
|
||||
return minecraftArgs;
|
||||
}
|
||||
|
||||
public void setMinecraftArgs(String minecraftArgs) {
|
||||
this.minecraftArgs = minecraftArgs;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public boolean isCanceledWrapper() {
|
||||
return canceledWrapper;
|
||||
}
|
||||
|
||||
public void setCanceledWrapper(boolean canceledWrapper) {
|
||||
this.canceledWrapper = canceledWrapper;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getWrapperLauncher() {
|
||||
return wrapperLauncher;
|
||||
}
|
||||
|
||||
public void setWrapperLauncher(String wrapperLauncher) {
|
||||
this.wrapperLauncher = wrapperLauncher;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getServerIp() {
|
||||
return serverIp;
|
||||
}
|
||||
|
||||
public void setServerIp(String serverIp) {
|
||||
this.serverIp = serverIp;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
}
|
148
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/settings/Settings.java
Normal file
148
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/settings/Settings.java
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.utils.functions.DoneListener0;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.utils.tinystream.CollectionUtils;
|
||||
import org.jackhuang.hellominecraft.utils.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class Settings {
|
||||
public static final File settingsFile = new File(IOUtils.currentDir(), "hmcl.json");
|
||||
|
||||
private static boolean isFirstLoad;
|
||||
private static Config settings;
|
||||
public static final UpdateChecker UPDATE_CHECKER;
|
||||
|
||||
public static Config s() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public static boolean isFirstLoad() {
|
||||
return isFirstLoad;
|
||||
}
|
||||
|
||||
static {
|
||||
if (settingsFile.exists()) {
|
||||
try {
|
||||
String str = FileUtils.readFileToString(settingsFile);
|
||||
if (str == null || str.trim().equals("")) {
|
||||
init();
|
||||
|
||||
HMCLog.log("Settings file is empty, use the default settings.");
|
||||
} else {
|
||||
settings = C.gsonPrettyPrinting.fromJson(str, Config.class);
|
||||
}
|
||||
HMCLog.log("Initialized settings.");
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Something happened wrongly when load settings.", e);
|
||||
if (MessageBox.Show(C.i18n("settings.failed_load"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
||||
init();
|
||||
} else {
|
||||
HMCLog.err("Cancelled loading settings.");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
HMCLog.log("No settings file here, may be first loading.");
|
||||
|
||||
isFirstLoad = true;
|
||||
init();
|
||||
}
|
||||
if(settings == null) init();
|
||||
isFirstLoad = StrUtils.isBlank(settings.getUsername());
|
||||
if(!settings.getConfigurations().containsKey("Default")) {
|
||||
settings.getConfigurations().put("Default", new Profile());
|
||||
}
|
||||
|
||||
UPDATE_CHECKER = new UpdateChecker(new VersionNumber(Main.firstVer, Main.secondVer, Main.thirdVer), "hmcl", settings.isCheckUpdate(), new DoneListener0() {
|
||||
|
||||
@Override
|
||||
public void onDone() {
|
||||
Main.invokeUpdate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
settings = new Config();
|
||||
save();
|
||||
}
|
||||
|
||||
public static void save() {
|
||||
try {
|
||||
FileUtils.write(settingsFile, C.gsonPrettyPrinting.toJson(settings));
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Failed to save config", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static Profile getVersion(String name) {
|
||||
if (settings == null) {
|
||||
return null;
|
||||
}
|
||||
if (settings.getConfigurations() == null) {
|
||||
return null;
|
||||
}
|
||||
return settings.getConfigurations().get(name);
|
||||
}
|
||||
|
||||
public static Map<String, Profile> getVersions() {
|
||||
return settings.getConfigurations();
|
||||
}
|
||||
|
||||
public static void setVersion(Profile ver) {
|
||||
if (ver == null) {
|
||||
return;
|
||||
}
|
||||
settings.getConfigurations().put(ver.getName(), ver);
|
||||
}
|
||||
|
||||
public static Collection<Profile> getProfiles() {
|
||||
return CollectionUtils.sortOut(settings.getConfigurations().values(), (t) -> t != null && t.getName() != null);
|
||||
}
|
||||
|
||||
public static Profile getOneProfile() {
|
||||
if(settings.getConfigurations().size() == 0) {
|
||||
settings.getConfigurations().put("Default", new Profile());
|
||||
}
|
||||
return settings.getConfigurations().firstEntry().getValue();
|
||||
}
|
||||
|
||||
public static boolean trySetVersion(Profile ver) {
|
||||
if (ver == null || ver.getName() == null) {
|
||||
return false;
|
||||
}
|
||||
if (settings.getConfigurations().containsKey(ver.getName())) {
|
||||
return false;
|
||||
}
|
||||
settings.getConfigurations().put(ver.getName(), ver);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void delVersion(Profile ver) {
|
||||
delVersion(ver.getName());
|
||||
}
|
||||
|
||||
public static void delVersion(String ver) {
|
||||
if (settings == null) return;
|
||||
settings.getConfigurations().remove(ver);
|
||||
}
|
||||
}
|
@ -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.launcher.utils.version;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Extract extends Object implements Cloneable {
|
||||
String[] exclude;
|
||||
|
||||
@Override
|
||||
protected Object clone() {
|
||||
Extract e = new Extract();
|
||||
e.exclude = exclude == null ? null : Arrays.copyOf(exclude, exclude.length);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
}
|
15
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/GameDirType.java
Normal file
15
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/GameDirType.java
Normal file
@ -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.launcher.utils.version;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public enum GameDirType {
|
||||
ROOT_FOLDER,
|
||||
VERSION_FOLDER;
|
||||
}
|
46
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/IMinecraftLibrary.java
Normal file
46
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/IMinecraftLibrary.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.launcher.utils.version;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public abstract class IMinecraftLibrary {
|
||||
|
||||
public String name;
|
||||
public IMinecraftLibrary(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public abstract boolean isRequiredToUnzip();
|
||||
public abstract String[] getDecompressExtractRules();
|
||||
public abstract void init();
|
||||
public abstract boolean allow();
|
||||
public abstract File getFilePath(File gameDir);
|
||||
public abstract String getDownloadURL(String urlBase, DownloadType downloadType);
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof MinecraftLibrary)
|
||||
return ((MinecraftLibrary) obj).name.equals(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected abstract Object clone();
|
||||
}
|
63
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/MinecraftClassicVersion.java
Normal file
63
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/MinecraftClassicVersion.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.launcher.utils.version;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftClassicVersion extends MinecraftVersion {
|
||||
|
||||
public MinecraftClassicVersion() {
|
||||
super();
|
||||
|
||||
mainClass = "net.minecraft.client.Minecraft";
|
||||
id = "Classic";
|
||||
type = "release";
|
||||
processArguments = assets = releaseTime = time = null;
|
||||
minecraftArguments = "${auth_player_name} ${auth_session} --workDir ${game_directory}";
|
||||
libraries = new ArrayList<>();
|
||||
libraries.add(new MinecraftOldLibrary("lwjgl"));
|
||||
libraries.add(new MinecraftOldLibrary("jinput"));
|
||||
libraries.add(new MinecraftOldLibrary("lwjgl_util"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion resolve(IMinecraftProvider manager, Set<String> resolvedSoFar, DownloadType sourceType) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getJar(File gameDir) {
|
||||
return new File(gameDir, "bin/minecraft.jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getJar(File gameDir, String suffix) {
|
||||
return new File(gameDir, "bin/minecraft" + suffix + ".jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getNatives(File gameDir) {
|
||||
return new File(gameDir, "bin/natives");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToUnpackNatives() {
|
||||
return false;
|
||||
}
|
||||
}
|
137
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/MinecraftLibrary.java
Normal file
137
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/MinecraftLibrary.java
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.version;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.OS;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftLibrary extends IMinecraftLibrary implements Cloneable {
|
||||
|
||||
public ArrayList<Rules> rules;
|
||||
public String url, formatted=null;
|
||||
//public boolean serverreq=true, clientreq=true;
|
||||
public String[] checksums;
|
||||
public Natives natives;
|
||||
public Extract extract;
|
||||
|
||||
public MinecraftLibrary(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public MinecraftLibrary(ArrayList<Rules> rules, String url, String[] checksums, Natives natives, String name, Extract extract) {
|
||||
super(name);
|
||||
this.rules = rules == null ? null : (ArrayList<Rules>) rules.clone();
|
||||
this.url = url;
|
||||
this.checksums = checksums == null ? null : Arrays.copyOf(checksums, checksums.length);
|
||||
this.natives = natives == null ? null : (Natives)natives.clone();
|
||||
this.extract = extract == null ? null :(Extract)extract.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new MinecraftLibrary(rules, url, checksums, natives, name, extract);
|
||||
}
|
||||
|
||||
/**
|
||||
* is the library allowed to load.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean allow() {
|
||||
boolean flag = false;
|
||||
if (rules == null || rules.isEmpty()) {
|
||||
flag = true;
|
||||
} else {
|
||||
for (Rules r : rules) {
|
||||
if (r.action.equals("disallow")) {
|
||||
if (r.os != null && (StrUtils.isBlank(r.os.name) || r.os.name.equalsIgnoreCase(OS.os().toString()))) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (r.os != null && (StrUtils.isBlank(r.os.name) || r.os.name.equalsIgnoreCase(OS.os().toString()))) {
|
||||
flag = true;
|
||||
}
|
||||
if (r.os == null) {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
private String formatArch(String nati) {
|
||||
String arch = System.getProperty("os.arch");
|
||||
if (arch.contains("64")) {
|
||||
arch = "64";
|
||||
} else {
|
||||
arch = "32";
|
||||
}
|
||||
if (nati == null) {
|
||||
return "";
|
||||
}
|
||||
return nati.replace("${arch}", arch);
|
||||
}
|
||||
|
||||
private String getNative() {
|
||||
OS os = OS.os();
|
||||
if (os == OS.WINDOWS) {
|
||||
return formatArch(natives.windows);
|
||||
} else if (os == OS.OSX) {
|
||||
return formatArch(natives.osx);
|
||||
} else {
|
||||
return formatArch(natives.linux);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequiredToUnzip() {
|
||||
return natives != null && allow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
String str = name;
|
||||
String[] s = str.split(":");
|
||||
str = s[0];
|
||||
str = str.replace('.', File.separatorChar);
|
||||
if (natives == null) {
|
||||
str += File.separator + s[1] + File.separator + s[2]
|
||||
+ File.separator + s[1] + '-' + s[2] + ".jar";
|
||||
} else {
|
||||
str += File.separator + s[1] + File.separator + s[2]
|
||||
+ File.separator + s[1] + '-' + s[2] + '-';
|
||||
str += getNative();
|
||||
str += ".jar";
|
||||
}
|
||||
formatted = str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getFilePath(File gameDir) {
|
||||
return new File(gameDir, "libraries" + File.separatorChar + formatted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadURL(String urlBase, DownloadType downloadType) {
|
||||
if(StrUtils.isNotBlank(url)&&downloadType.getProvider().isAllowedToUseSelfURL()) urlBase = this.url;
|
||||
return urlBase + formatted.replace('\\', '/');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDecompressExtractRules() {
|
||||
return extract == null || extract.exclude == null ? new String[0] : extract.exclude;
|
||||
}
|
||||
}
|
51
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/MinecraftOldLibrary.java
Normal file
51
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/MinecraftOldLibrary.java
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.launcher.utils.version;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftOldLibrary extends MinecraftLibrary {
|
||||
|
||||
public MinecraftOldLibrary(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequiredToUnzip() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allow() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getFilePath(File gameDir) {
|
||||
return new File(gameDir, "bin/" + name + ".jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new MinecraftOldLibrary(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadURL(String urlBase, DownloadType downloadType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
113
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/MinecraftVersion.java
Normal file
113
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/MinecraftVersion.java
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.version;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MinecraftVersion implements Cloneable, Comparable<MinecraftVersion> {
|
||||
|
||||
public String minecraftArguments, mainClass, time, id, type, processArguments,
|
||||
releaseTime, assets, jar, inheritsFrom;
|
||||
public int minimumLauncherVersion;
|
||||
public boolean hidden;
|
||||
|
||||
public List<MinecraftLibrary> libraries;
|
||||
|
||||
public MinecraftVersion() {
|
||||
}
|
||||
|
||||
public MinecraftVersion(String minecraftArguments, String mainClass, String time, String id, String type, String processArguments, String releaseTime, String assets, String jar, String inheritsFrom, int minimumLauncherVersion, List<MinecraftLibrary> libraries, boolean hidden) {
|
||||
this();
|
||||
this.minecraftArguments = minecraftArguments;
|
||||
this.mainClass = mainClass;
|
||||
this.time = time;
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.processArguments = processArguments;
|
||||
this.releaseTime = releaseTime;
|
||||
this.assets = assets;
|
||||
this.jar = jar;
|
||||
this.inheritsFrom = inheritsFrom;
|
||||
this.minimumLauncherVersion = minimumLauncherVersion;
|
||||
this.hidden = hidden;
|
||||
if(libraries == null) this.libraries = new ArrayList<>();
|
||||
else {
|
||||
this.libraries = new ArrayList<>(libraries.size());
|
||||
for (IMinecraftLibrary library : libraries) {
|
||||
this.libraries.add((MinecraftLibrary) library.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new MinecraftVersion(minecraftArguments, mainClass, time, id, type, processArguments, releaseTime, assets, jar, inheritsFrom, minimumLauncherVersion, libraries, hidden);
|
||||
}
|
||||
|
||||
public MinecraftVersion resolve(IMinecraftProvider manager, DownloadType sourceType) {
|
||||
return resolve(manager, new HashSet<>(), sourceType);
|
||||
}
|
||||
|
||||
protected MinecraftVersion resolve(IMinecraftProvider manager, Set<String> resolvedSoFar, DownloadType sourceType) {
|
||||
if (inheritsFrom == null) {
|
||||
return this;
|
||||
}
|
||||
if (!resolvedSoFar.add(id)) {
|
||||
throw new IllegalStateException("Circular dependency detected.");
|
||||
}
|
||||
|
||||
MinecraftVersion parent = manager.getVersionById(inheritsFrom);
|
||||
if(parent == null) {
|
||||
if(!manager.install(inheritsFrom, sourceType)) return this;
|
||||
parent = manager.getVersionById(inheritsFrom);
|
||||
}
|
||||
parent = parent.resolve(manager, resolvedSoFar, sourceType);
|
||||
MinecraftVersion result = new MinecraftVersion(
|
||||
this.minecraftArguments != null ? this.minecraftArguments : parent.minecraftArguments,
|
||||
this.mainClass != null ? this.mainClass : parent.mainClass,
|
||||
this.time, this.id, this.type, parent.processArguments, this.releaseTime,
|
||||
this.assets != null ? this.assets : parent.assets,
|
||||
this.jar != null ? this.jar : parent.jar,
|
||||
null, parent.minimumLauncherVersion,
|
||||
this.libraries != null ? ArrayUtils.merge(this.libraries, parent.libraries) : parent.libraries, this.hidden);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public File getJar(File gameDir) {
|
||||
String jarId = this.jar == null ? this.id : this.jar;
|
||||
return new File(gameDir, "versions/" + jarId + "/" + jarId + ".jar");
|
||||
}
|
||||
|
||||
public File getJar(File gameDir, String suffix) {
|
||||
String jarId = this.jar == null ? this.id : this.jar;
|
||||
return new File(gameDir, "versions/" + jarId + "/" + jarId + suffix + ".jar");
|
||||
}
|
||||
|
||||
public File getNatives(File gameDir) {
|
||||
return new File(gameDir, "versions/" + id + "/" + id
|
||||
+ "-natives");
|
||||
}
|
||||
|
||||
public boolean isAllowedToUnpackNatives() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MinecraftVersion o) {
|
||||
return id.compareTo(((MinecraftVersion) o).id);
|
||||
}
|
||||
}
|
306
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/MinecraftVersionManager.java
Normal file
306
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/utils/version/MinecraftVersionManager.java
Normal file
@ -0,0 +1,306 @@
|
||||
/*
|
||||
* 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.launcher.utils.version;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.GameLauncher;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.GameLauncher.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.IMinecraftLoader;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.MinecraftLoader;
|
||||
import org.jackhuang.hellominecraft.utils.BaseLauncherProfile;
|
||||
import org.jackhuang.hellominecraft.utils.FileUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.MCUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class MinecraftVersionManager extends IMinecraftProvider {
|
||||
|
||||
private File baseFolder;
|
||||
private final Profile profile;
|
||||
private final Map<String, MinecraftVersion> versions = new TreeMap();
|
||||
private final Gson gson = Utils.getDefaultGsonBuilder().create();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param p
|
||||
*/
|
||||
public MinecraftVersionManager(Profile p) {
|
||||
super(p);
|
||||
this.profile = p;
|
||||
refreshVersions();
|
||||
}
|
||||
|
||||
public File getFolder() {
|
||||
return baseFolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MinecraftVersion> getVersions() {
|
||||
return versions.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersionCount() {
|
||||
return versions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshVersions() {
|
||||
baseFolder = profile.getCanonicalGameDirFile();
|
||||
try {
|
||||
BaseLauncherProfile.tryWriteProfile(baseFolder);
|
||||
} catch (IOException ex) {
|
||||
HMCLog.warn("Failed to create launcher_profiles.json, Forge/LiteLoader installer will not work.", ex);
|
||||
}
|
||||
|
||||
versions.clear();
|
||||
File oldDir = new File(baseFolder, "bin");
|
||||
if (oldDir.exists()) {
|
||||
MinecraftClassicVersion v = new MinecraftClassicVersion();
|
||||
versions.put(v.id, v);
|
||||
}
|
||||
|
||||
File version = new File(baseFolder, "versions");
|
||||
File[] files = version.listFiles();
|
||||
if (files == null || files.length == 0) return;
|
||||
|
||||
for (File dir : files) {
|
||||
String id = dir.getName();
|
||||
File jsonFile = new File(dir, id + ".json");
|
||||
|
||||
if (!dir.isDirectory()) continue;
|
||||
boolean ask = false;
|
||||
File[] jsons = null;
|
||||
if (!jsonFile.exists()) {
|
||||
jsons = FileUtils.searchSuffix(dir, "json");
|
||||
if (jsons.length == 1) ask = true;
|
||||
}
|
||||
if (ask) {
|
||||
HMCLog.warn("Found not matched filenames version: " + id + ", json: " + jsons[0].getName());
|
||||
if (MessageBox.Show(String.format(C.i18n("launcher.versions_json_not_matched"), id, jsons[0].getName()), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
jsons[0].renameTo(new File(jsons[0].getParent(), id + ".json"));
|
||||
}
|
||||
if (!jsonFile.exists()) {
|
||||
if (StrUtils.formatVersion(id) == null) {
|
||||
if (MessageBox.Show(C.i18n("launcher.versions_json_not_matched_cannot_auto_completion", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
FileUtils.deleteDirectoryQuietly(dir);
|
||||
} else if (MessageBox.Show(C.i18n("launcher.versions_json_not_matched_needs_auto_completion", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
||||
if (!refreshJson(id)) {
|
||||
if (MessageBox.Show(C.i18n("launcher.versions_json_not_matched_cannot_auto_completion", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
FileUtils.deleteDirectoryQuietly(dir);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
MinecraftVersion mcVersion = null;
|
||||
try {
|
||||
mcVersion = gson.fromJson(FileUtils.readFileToString(jsonFile), MinecraftVersion.class);
|
||||
if (mcVersion == null) throw new RuntimeException("Wrong json format, got null.");
|
||||
} catch (IOException | RuntimeException e) {
|
||||
HMCLog.warn("Found wrong format json, try to fix it.", e);
|
||||
if (MessageBox.Show(C.i18n("launcher.versions_json_not_formattedn", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
||||
refreshJson(id);
|
||||
try {
|
||||
mcVersion = gson.fromJson(FileUtils.readFileToString(jsonFile), MinecraftVersion.class);
|
||||
if (mcVersion == null) throw new RuntimeException("Wrong json format, got null.");
|
||||
} catch (IOException | RuntimeException ex) {
|
||||
HMCLog.err("Retried but still failed.");
|
||||
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", ex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (!id.equals(mcVersion.id)) {
|
||||
HMCLog.warn("Found: " + dir + ", it contains id: " + mcVersion.id + ", expected: " + id + ", the launcher will fix this problem.");
|
||||
mcVersion.id = id;
|
||||
FileUtils.writeQuietly(jsonFile, gson.toJson(mcVersion));
|
||||
}
|
||||
|
||||
if (mcVersion.libraries != null)
|
||||
for (MinecraftLibrary ml : mcVersion.libraries)
|
||||
ml.init();
|
||||
versions.put(id, mcVersion);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVersionFromDisk(String name) {
|
||||
File version = new File(baseFolder, "versions/" + name);
|
||||
if (!version.exists()) return true;
|
||||
|
||||
versions.remove(name);
|
||||
return FileUtils.deleteDirectoryQuietly(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renameVersion(String from, String to) {
|
||||
try {
|
||||
File fromJson = new File(baseFolder, "versions/" + from + "/" + from + ".json");
|
||||
MinecraftVersion mcVersion = gson.fromJson(FileUtils.readFileToString(fromJson), MinecraftVersion.class);
|
||||
mcVersion.id = to;
|
||||
FileUtils.writeQuietly(fromJson, gson.toJson(mcVersion));
|
||||
File toDir = new File(baseFolder, "versions/" + to);
|
||||
new File(baseFolder, "versions/" + from).renameTo(toDir);
|
||||
File toJson = new File(toDir, to + ".json");
|
||||
File toJar = new File(toDir, to + ".jar");
|
||||
new File(toDir, from + ".json").renameTo(toJson);
|
||||
new File(toDir, from + ".jar").renameTo(toJar);
|
||||
return true;
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
HMCLog.warn("Failed to rename " + from + " to " + to + ", the json of this Minecraft is malformed.", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean refreshJson(String id) {
|
||||
return MCUtils.downloadMinecraftVersionJson(baseFolder, id, Settings.s().getDownloadSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean refreshAssetsIndex(String id) {
|
||||
MinecraftVersion mv = getVersionById(id);
|
||||
if (mv == null) return false;
|
||||
return MCUtils.downloadMinecraftAssetsIndex(new File(baseFolder, "assets"), mv.assets, Settings.s().getDownloadSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean install(String id, DownloadType sourceType) {
|
||||
MinecraftVersion v = MCUtils.downloadMinecraft(baseFolder, id, sourceType);
|
||||
if (v != null) {
|
||||
versions.put(v.id, v);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getRunDirectory(String id) {
|
||||
switch (profile.getGameDirType()) {
|
||||
case VERSION_FOLDER:
|
||||
return new File(baseFolder, "versions/" + id + "/");
|
||||
default:
|
||||
return baseFolder;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GameLauncher.DownloadLibraryJob> getDownloadLibraries(DownloadType downloadType) {
|
||||
ArrayList<DownloadLibraryJob> downloadLibraries = new ArrayList<>();
|
||||
MinecraftVersion v = profile.getSelectedMinecraftVersion().resolve(this, Settings.s().getDownloadSource());
|
||||
for (IMinecraftLibrary l : v.libraries) {
|
||||
l.init();
|
||||
if (l.allow()) {
|
||||
File ff = l.getFilePath(baseFolder);
|
||||
if (!ff.exists()) {
|
||||
String libURL = downloadType.getProvider().getLibraryDownloadURL() + "/";
|
||||
libURL = l.getDownloadURL(libURL, downloadType);
|
||||
if (libURL != null)
|
||||
downloadLibraries.add(new DownloadLibraryJob(l.name, libURL, ff));
|
||||
}
|
||||
}
|
||||
}
|
||||
return downloadLibraries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openSelf(String mv) {
|
||||
Utils.openFolder(getRunDirectory(mv));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(String mv, String name) {
|
||||
Utils.openFolder(new File(getRunDirectory(mv), name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getAssets() {
|
||||
return new File(profile.getCanonicalGameDirFile(), "assets");
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameLauncher.DecompressLibraryJob getDecompressLibraries() {
|
||||
MinecraftVersion v = profile.getSelectedMinecraftVersion().resolve(this, Settings.s().getDownloadSource());
|
||||
ArrayList<File> unzippings = new ArrayList<>();
|
||||
ArrayList<String[]> extractRules = new ArrayList<>();
|
||||
for (IMinecraftLibrary l : v.libraries) {
|
||||
l.init();
|
||||
if (l.isRequiredToUnzip() && v.isAllowedToUnpackNatives()) {
|
||||
unzippings.add(IOUtils.tryGetCanonicalFile(l.getFilePath(baseFolder)));
|
||||
extractRules.add(l.getDecompressExtractRules());
|
||||
}
|
||||
}
|
||||
return new GameLauncher.DecompressLibraryJob(unzippings.toArray(new File[0]), extractRules.toArray(new String[0][]), getDecompressNativesToLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDecompressNativesToLocation() {
|
||||
MinecraftVersion v = profile.getSelectedMinecraftVersion();
|
||||
return v.getNatives(profile.getCanonicalGameDirFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getMinecraftJar() {
|
||||
return profile.getSelectedMinecraftVersion().getJar(baseFolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMinecraftLoader provideMinecraftLoader(UserProfileProvider p, DownloadType type)
|
||||
throws IllegalStateException {
|
||||
return new MinecraftLoader(profile, this, p, getMinecraftJar(), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion getOneVersion() {
|
||||
return versions.isEmpty() ? null : versions.values().iterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion getVersionById(String id) {
|
||||
return id == null ? null : versions.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getResourcePacks() {
|
||||
return new File(profile.getCanonicalGameDirFile(), "resourcepacks");
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getBaseFolder() {
|
||||
return baseFolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLaunch() {
|
||||
File resourcePacks = getResourcePacks();
|
||||
if (!resourcePacks.exists()) resourcePacks.mkdirs();
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.version;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Natives implements Cloneable {
|
||||
public String windows, osx, linux;
|
||||
|
||||
@Override
|
||||
protected Object clone() {
|
||||
Natives n = new Natives();
|
||||
n.windows = windows;
|
||||
n.osx = osx;
|
||||
n.linux = linux;
|
||||
return n;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.version;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class OS {
|
||||
public String version, name;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.version;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class Rules {
|
||||
public String action;
|
||||
public OS os;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.launcher.views;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class DraggableFrame extends JFrame
|
||||
implements MouseListener, MouseMotionListener {
|
||||
|
||||
private int dragGripX;
|
||||
private int dragGripY;
|
||||
|
||||
public DraggableFrame() {
|
||||
setUndecorated(true);
|
||||
addMouseListener(this);
|
||||
addMouseMotionListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.getButton() == 1) {
|
||||
this.dragGripX = e.getX();
|
||||
this.dragGripY = e.getY();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if ((e.getModifiersEx() & 0x400) != 0) {
|
||||
setLocation(e.getXOnScreen() - this.dragGripX, e.getYOnScreen() - this.dragGripY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
}
|
||||
}
|
1073
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/GameSettingsPanel.form
Normal file
1073
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/GameSettingsPanel.form
Normal file
File diff suppressed because it is too large
Load Diff
1468
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/GameSettingsPanel.java
Normal file
1468
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/GameSettingsPanel.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.launcher.views;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.DefaultButtonModel;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class HeaderTab extends JLabel
|
||||
implements MouseListener {
|
||||
|
||||
private boolean isActive;
|
||||
private final DefaultButtonModel model;
|
||||
|
||||
public HeaderTab(String text) {
|
||||
super(text);
|
||||
|
||||
this.model = new DefaultButtonModel();
|
||||
setIsActive(false);
|
||||
|
||||
setBorder(BorderFactory.createEmptyBorder(6, 18, 7, 18));
|
||||
addMouseListener(this);
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.isActive;
|
||||
}
|
||||
|
||||
public void setIsActive(boolean isActive) {
|
||||
this.isActive = isActive;
|
||||
setOpaque(isActive);
|
||||
|
||||
EventQueue.invokeLater(HeaderTab.this::repaint);
|
||||
}
|
||||
|
||||
public void addActionListener(ActionListener listener) {
|
||||
this.model.addActionListener(listener);
|
||||
}
|
||||
|
||||
public String getActionCommand() {
|
||||
return this.model.getActionCommand();
|
||||
}
|
||||
|
||||
public ActionListener[] getActionListeners() {
|
||||
return this.model.getActionListeners();
|
||||
}
|
||||
|
||||
public void removeActionListener(ActionListener listener) {
|
||||
this.model.removeActionListener(listener);
|
||||
}
|
||||
|
||||
public void setActionCommand(String command) {
|
||||
this.model.setActionCommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
this.model.setPressed(true);
|
||||
this.model.setArmed(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
this.model.setPressed(false);
|
||||
this.model.setArmed(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
this.model.setRollover(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
this.model.setRollover(false);
|
||||
}
|
||||
}
|
178
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/LauncherSettingsPanel.form
Normal file
178
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/LauncherSettingsPanel.form
Normal file
@ -0,0 +1,178 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<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">
|
||||
<Group type="102" attributes="0">
|
||||
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="chkEnableShadow" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="btnCheckUpdate" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jLabel7" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel14" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<Component id="txtBackgroundPath" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnSelBackgroundPath" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="cboDownloadSource" alignment="1" max="32767" attributes="0"/>
|
||||
<Component id="cboTheme" alignment="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</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"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel14" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnSelBackgroundPath" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="txtBackgroundPath" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboDownloadSource" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboTheme" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="chkEnableShadow" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnCheckUpdate" alignment="0" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace pref="119" max="32767" attributes="0"/>
|
||||
<Component id="jLabel4" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JComboBox" name="cboDownloadSource">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="2">
|
||||
<StringItem index="0" value="Mojang"/>
|
||||
<StringItem index="1" value="BMCLAPI(By bangbang93)"/>
|
||||
</StringArray>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboDownloadSourceItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel4">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="launcher.about" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnSelBackgroundPath">
|
||||
<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.explore" 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="btnSelBackgroundPathActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel14">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="launcher.background_location" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" value=""/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtBackgroundPath">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="launcher.background_tooltip" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtBackgroundPathFocusLost"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel7">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="launcher.download_source" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnCheckUpdate">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="launcher.update_launcher" 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="btnCheckUpdateActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JCheckBox" name="chkEnableShadow">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="launcher.enable_shadow" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="chkEnableShadowFocusLost"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="launcher.theme" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboTheme">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new DefaultComboBoxModel(new String[]{C.i18n("color.blue"),C.i18n("color.green"),C.i18n("color.purple"),C.i18n("color.dark_blue"),C.i18n("color.orange"),C.i18n("color.red")})" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboThemeItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
223
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/LauncherSettingsPanel.java
Normal file
223
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/LauncherSettingsPanel.java
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* 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.launcher.views;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JFileChooser;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.utils.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class LauncherSettingsPanel extends javax.swing.JPanel {
|
||||
|
||||
/**
|
||||
* Creates new form LancherSettingsPanel
|
||||
*/
|
||||
public LauncherSettingsPanel() {
|
||||
initComponents();
|
||||
|
||||
txtBackgroundPath.setText(Settings.s().getBgpath());
|
||||
cboDownloadSource.setSelectedIndex(Settings.s().getDownloadType());
|
||||
cboTheme.setSelectedIndex(Settings.s().getTheme());
|
||||
chkEnableShadow.setSelected(Settings.s().isEnableShadow());
|
||||
|
||||
setBackground(Color.white);
|
||||
setOpaque(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
cboDownloadSource = new javax.swing.JComboBox();
|
||||
jLabel4 = new javax.swing.JLabel();
|
||||
btnSelBackgroundPath = new javax.swing.JButton();
|
||||
jLabel14 = new javax.swing.JLabel();
|
||||
txtBackgroundPath = new javax.swing.JTextField();
|
||||
jLabel7 = new javax.swing.JLabel();
|
||||
btnCheckUpdate = new javax.swing.JButton();
|
||||
chkEnableShadow = new javax.swing.JCheckBox();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
cboTheme = new javax.swing.JComboBox();
|
||||
|
||||
cboDownloadSource.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Mojang", "BMCLAPI(By bangbang93)" }));
|
||||
cboDownloadSource.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboDownloadSourceItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/jackhuang/hellominecraft/launcher/I18N"); // NOI18N
|
||||
jLabel4.setText(bundle.getString("launcher.about")); // NOI18N
|
||||
|
||||
btnSelBackgroundPath.setText(bundle.getString("ui.button.explore")); // NOI18N
|
||||
btnSelBackgroundPath.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnSelBackgroundPathActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel14.setText(bundle.getString("launcher.background_location")); // NOI18N
|
||||
jLabel14.setToolTipText("");
|
||||
|
||||
txtBackgroundPath.setToolTipText(bundle.getString("launcher.background_tooltip")); // NOI18N
|
||||
txtBackgroundPath.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
txtBackgroundPathFocusLost(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel7.setText(bundle.getString("launcher.download_source")); // NOI18N
|
||||
|
||||
btnCheckUpdate.setText(bundle.getString("launcher.update_launcher")); // NOI18N
|
||||
btnCheckUpdate.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnCheckUpdateActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
chkEnableShadow.setText(bundle.getString("launcher.enable_shadow")); // NOI18N
|
||||
chkEnableShadow.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
chkEnableShadowFocusLost(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel1.setText(bundle.getString("launcher.theme")); // NOI18N
|
||||
|
||||
cboTheme.setModel(new DefaultComboBoxModel(new String[]{C.i18n("color.blue"),C.i18n("color.green"),C.i18n("color.purple"),C.i18n("color.dark_blue"),C.i18n("color.orange"),C.i18n("color.red")}));
|
||||
cboTheme.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboThemeItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.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(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 0, Short.MAX_VALUE))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(chkEnableShadow)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btnCheckUpdate))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jLabel7)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(jLabel14))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addComponent(txtBackgroundPath)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnSelBackgroundPath))
|
||||
.addComponent(cboDownloadSource, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(cboTheme, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel14)
|
||||
.addComponent(btnSelBackgroundPath, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(txtBackgroundPath, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel7)
|
||||
.addComponent(cboDownloadSource, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(cboTheme, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(chkEnableShadow)
|
||||
.addComponent(btnCheckUpdate, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 119, Short.MAX_VALUE)
|
||||
.addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void cboDownloadSourceItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboDownloadSourceItemStateChanged
|
||||
Settings.s().setDownloadType(cboDownloadSource.getSelectedIndex());
|
||||
}//GEN-LAST:event_cboDownloadSourceItemStateChanged
|
||||
|
||||
private void btnSelBackgroundPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSelBackgroundPathActionPerformed
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
fc.setDialogTitle(C.i18n("launcher.choose_bgpath"));
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
fc.showOpenDialog(this);
|
||||
if (fc.getSelectedFile() == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String path = fc.getSelectedFile().getCanonicalPath();
|
||||
path = IOUtils.removeLastSeparator(path);
|
||||
txtBackgroundPath.setText(path);
|
||||
Settings.s().setBgpath(path);
|
||||
MainFrame.instance.loadBackground();
|
||||
} catch (IOException e) {
|
||||
HMCLog.warn("Failed to set background path.", e);
|
||||
MessageBox.Show(C.i18n("ui.label.failed_set") + e.getMessage());
|
||||
}
|
||||
}//GEN-LAST:event_btnSelBackgroundPathActionPerformed
|
||||
|
||||
private void txtBackgroundPathFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtBackgroundPathFocusLost
|
||||
String path = txtBackgroundPath.getText();
|
||||
Settings.s().setBgpath(path);
|
||||
MainFrame.instance.loadBackground();
|
||||
}//GEN-LAST:event_txtBackgroundPathFocusLost
|
||||
|
||||
private void btnCheckUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckUpdateActionPerformed
|
||||
Settings.UPDATE_CHECKER.process(true);
|
||||
}//GEN-LAST:event_btnCheckUpdateActionPerformed
|
||||
|
||||
private void chkEnableShadowFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_chkEnableShadowFocusLost
|
||||
Settings.s().setEnableShadow(chkEnableShadow.isSelected());
|
||||
}//GEN-LAST:event_chkEnableShadowFocusLost
|
||||
|
||||
private void cboThemeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboThemeItemStateChanged
|
||||
Settings.s().setTheme(cboTheme.getSelectedIndex());
|
||||
if(MainFrame.instance != null)
|
||||
MainFrame.instance.reloadColor();
|
||||
}//GEN-LAST:event_cboThemeItemStateChanged
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnCheckUpdate;
|
||||
private javax.swing.JButton btnSelBackgroundPath;
|
||||
private javax.swing.JComboBox cboDownloadSource;
|
||||
private javax.swing.JComboBox cboTheme;
|
||||
private javax.swing.JCheckBox chkEnableShadow;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel14;
|
||||
private javax.swing.JLabel jLabel4;
|
||||
private javax.swing.JLabel jLabel7;
|
||||
private javax.swing.JTextField txtBackgroundPath;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
@ -0,0 +1,360 @@
|
||||
/*
|
||||
* 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.launcher.views;
|
||||
|
||||
import com.sun.awt.AWTUtilities;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
import org.jackhuang.hellominecraft.views.DropShadowBorder;
|
||||
import org.jackhuang.hellominecraft.views.TintablePanel;
|
||||
import org.jackhuang.hellominecraft.views.BasicColors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class MainFrame extends DraggableFrame {
|
||||
|
||||
public static final MainFrame instance = new MainFrame();
|
||||
|
||||
HeaderTab mainTab, gameTab, launcherTab;
|
||||
TintablePanel centralPanel;
|
||||
JPanel header;
|
||||
MainPagePanel mainPanel;
|
||||
GameSettingsPanel gamePanel;
|
||||
LauncherSettingsPanel launcherPanel;
|
||||
CardLayout infoLayout;
|
||||
JPanel infoSwap;
|
||||
JLabel backgroundLabel, windowTitle;
|
||||
JPanel realPanel;
|
||||
DropShadowBorder border;
|
||||
boolean enableShadow;
|
||||
String defaultTitle;
|
||||
|
||||
MainFrame() {
|
||||
defaultTitle = Main.makeTitle();
|
||||
enableShadow = Settings.s().isEnableShadow();
|
||||
if (enableShadow)
|
||||
setSize(834, 542);
|
||||
else
|
||||
setSize(802, 511);
|
||||
setDefaultCloseOperation(3);
|
||||
setTitle(Main.makeTitle());
|
||||
initComponents();
|
||||
selectTab("main");
|
||||
loadBackground();
|
||||
|
||||
setLocationRelativeTo(null);
|
||||
|
||||
if (enableShadow)
|
||||
try {
|
||||
AWTUtilities.setWindowOpaque(this, false);
|
||||
getRootPane().setBorder(border = new DropShadowBorder(borderColor, 4));
|
||||
} catch (Throwable ex) {
|
||||
HMCLog.err("Failed to set window transparent.", ex);
|
||||
Settings.s().setEnableShadow(false);
|
||||
setSize(802, 511);
|
||||
}
|
||||
|
||||
((JPanel) getContentPane()).setOpaque(true);
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
borderColor = BasicColors.bgcolors[Settings.s().getTheme()];
|
||||
borderColorDarker = BasicColors.bgcolors_darker[Settings.s().getTheme()];
|
||||
|
||||
realPanel = new JPanel();
|
||||
realPanel.setLayout(null);
|
||||
|
||||
header = new JPanel();
|
||||
header.setBounds(0, 0, 800, 30);
|
||||
realPanel.add(header);
|
||||
header.setOpaque(true);
|
||||
header.setLayout(new BoxLayout(header, BoxLayout.LINE_AXIS));
|
||||
header.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 5));
|
||||
header.setBackground(borderColor);
|
||||
header.setForeground(BasicColors.COLOR_WHITE_TEXT);
|
||||
|
||||
ImageIcon headerIcon = Main.getIcon("icon.png");
|
||||
this.setIconImage(headerIcon.getImage());
|
||||
headerIcon = Utils.scaleImage(headerIcon, 16, 16);
|
||||
JLabel headerLabel = new JLabel(headerIcon);
|
||||
headerLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0));
|
||||
header.add(headerLabel);
|
||||
|
||||
header.add(Box.createRigidArea(new Dimension(8, 0)));
|
||||
|
||||
ActionListener tabListener = (e) -> MainFrame.this.selectTab(e.getActionCommand());
|
||||
|
||||
this.mainTab = new HeaderTab(C.i18n("launcher.title.main"));
|
||||
this.mainTab.setForeground(BasicColors.COLOR_WHITE_TEXT);
|
||||
this.mainTab.setBackground(borderColorDarker);
|
||||
this.mainTab.setActionCommand("main");
|
||||
this.mainTab.addActionListener(tabListener);
|
||||
header.add(this.mainTab);
|
||||
|
||||
this.gameTab = new HeaderTab(C.i18n("launcher.title.game"));
|
||||
this.gameTab.setForeground(BasicColors.COLOR_WHITE_TEXT);
|
||||
this.gameTab.setBackground(borderColorDarker);
|
||||
this.gameTab.setIsActive(true);
|
||||
this.gameTab.setHorizontalTextPosition(10);
|
||||
this.gameTab.addActionListener(tabListener);
|
||||
this.gameTab.setActionCommand("game");
|
||||
header.add(this.gameTab);
|
||||
|
||||
this.launcherTab = new HeaderTab(C.i18n("launcher.title.launcher"));
|
||||
this.launcherTab.setForeground(BasicColors.COLOR_WHITE_TEXT);
|
||||
this.launcherTab.setBackground(borderColorDarker);
|
||||
this.launcherTab.setLayout(null);
|
||||
this.launcherTab.addActionListener(tabListener);
|
||||
this.launcherTab.setActionCommand("launcher");
|
||||
header.add(this.launcherTab);
|
||||
|
||||
header.add(Box.createHorizontalGlue());
|
||||
|
||||
JPanel rightHeaderPanel = new JPanel();
|
||||
rightHeaderPanel.setOpaque(false);
|
||||
rightHeaderPanel.setLayout(new BoxLayout(rightHeaderPanel, BoxLayout.PAGE_AXIS));
|
||||
rightHeaderPanel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
|
||||
|
||||
JPanel windowGadgetPanel = new JPanel();
|
||||
windowGadgetPanel.setOpaque(false);
|
||||
windowGadgetPanel.setLayout(new BoxLayout(windowGadgetPanel, BoxLayout.LINE_AXIS));
|
||||
windowGadgetPanel.setAlignmentX(1.0F);
|
||||
|
||||
ImageIcon minimizeIcon = Main.getIcon("minimize.png");
|
||||
JButton minimizeButton = new JButton(minimizeIcon);
|
||||
minimizeButton.setBorder(BorderFactory.createEmptyBorder());
|
||||
minimizeButton.setContentAreaFilled(false);
|
||||
minimizeButton.setCursor(new Cursor(12));
|
||||
minimizeButton.setFocusable(false);
|
||||
minimizeButton.addActionListener((e) -> MainFrame.this.minimizeWindow());
|
||||
windowGadgetPanel.add(minimizeButton);
|
||||
|
||||
ImageIcon closeIcon = Main.getIcon("close.png");
|
||||
JButton closeButton = new JButton(closeIcon);
|
||||
closeButton.setBorder(BorderFactory.createEmptyBorder());
|
||||
closeButton.setContentAreaFilled(false);
|
||||
closeButton.addActionListener((e) -> MainFrame.this.closeWindow());
|
||||
closeButton.setCursor(new Cursor(12));
|
||||
closeButton.setFocusable(false);
|
||||
windowGadgetPanel.add(closeButton);
|
||||
|
||||
rightHeaderPanel.add(windowGadgetPanel);
|
||||
|
||||
windowTitle = new JLabel(defaultTitle);
|
||||
windowTitle.setForeground(BasicColors.COLOR_WHITE_TEXT);
|
||||
windowTitle.addMouseListener(new MouseListener() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (UpdateChecker.OUT_DATED) Main.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
}
|
||||
});
|
||||
header.add(windowTitle);
|
||||
header.add(Box.createHorizontalGlue());
|
||||
header.add(rightHeaderPanel);
|
||||
|
||||
this.centralPanel = new TintablePanel();
|
||||
this.centralPanel.setTintColor(BasicColors.COLOR_CENTRAL_BACK);
|
||||
realPanel.add(this.centralPanel);
|
||||
JPanel truePanel = new JPanel();
|
||||
truePanel.setLayout(new BorderLayout());
|
||||
|
||||
this.infoSwap = new JPanel();
|
||||
this.infoLayout = new CardLayout();
|
||||
this.infoSwap.setLayout(infoLayout);
|
||||
this.infoSwap.setOpaque(false);
|
||||
|
||||
this.mainPanel = new MainPagePanel();
|
||||
this.infoSwap.add(mainPanel, "main");
|
||||
this.gamePanel = new GameSettingsPanel();
|
||||
this.infoSwap.add(gamePanel, "game");
|
||||
this.launcherPanel = new LauncherSettingsPanel();
|
||||
this.infoSwap.add(launcherPanel, "launcher");
|
||||
|
||||
truePanel.add(this.infoSwap, "Center");
|
||||
centralPanel.setLayout(null);
|
||||
centralPanel.add(truePanel);
|
||||
truePanel.setBounds(0, 0, 800, 480);
|
||||
centralPanel.setBounds(0, 30, 800, 480);
|
||||
|
||||
setLayout(null);
|
||||
realPanel.setBounds(1, 0, 800, 511);
|
||||
add(realPanel);
|
||||
}
|
||||
|
||||
public void selectTab(String tabName) {
|
||||
this.mainTab.setIsActive(false);
|
||||
this.gameTab.setIsActive(false);
|
||||
this.launcherTab.setIsActive(false);
|
||||
|
||||
if (tabName.equalsIgnoreCase("main")) {
|
||||
this.mainTab.setIsActive(true);
|
||||
this.mainPanel.onSelected();
|
||||
} else if (tabName.equalsIgnoreCase("game")) {
|
||||
this.gameTab.setIsActive(true);
|
||||
this.gamePanel.onSelected();
|
||||
} else if (tabName.equalsIgnoreCase("launcher"))
|
||||
this.launcherTab.setIsActive(true);
|
||||
|
||||
this.infoLayout.show(this.infoSwap, tabName);
|
||||
}
|
||||
|
||||
protected void closeWindow() {
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
protected void minimizeWindow() {
|
||||
setState(1);
|
||||
}
|
||||
|
||||
ImageIcon background;
|
||||
|
||||
public void loadBackground() {
|
||||
background = Utils.searchBackgroundImage(Main.getIcon("background.jpg"), Settings.s().getBgpath(), 800, 480);
|
||||
if (background != null) {
|
||||
if (backgroundLabel == null) {
|
||||
backgroundLabel = new JLabel(background);
|
||||
backgroundLabel.setBounds(0, 0, 800, 480);
|
||||
} else
|
||||
backgroundLabel.setIcon(background);
|
||||
centralPanel.add(backgroundLabel, -1);
|
||||
} else
|
||||
HMCLog.warn("No Background Image, the background will be white!");
|
||||
}
|
||||
|
||||
public JPanel getTitleBar() {
|
||||
return header;
|
||||
}
|
||||
|
||||
boolean isShowedMessage = false;
|
||||
|
||||
public void closeMessage() {
|
||||
if (isShowedMessage) {
|
||||
isShowedMessage = false;
|
||||
reloadColor();
|
||||
windowTitle.setText(defaultTitle);
|
||||
windowTitle.setForeground(UpdateChecker.OUT_DATED ? Color.red : Color.white);
|
||||
}
|
||||
}
|
||||
|
||||
public void showMessage(String message) {
|
||||
isShowedMessage = true;
|
||||
borderColor = BasicColors.COLOR_RED;
|
||||
borderColorDarker = BasicColors.COLOR_RED_DARKER;
|
||||
header.setBackground(borderColor);
|
||||
mainTab.setBackground(borderColorDarker);
|
||||
gameTab.setBackground(borderColorDarker);
|
||||
launcherTab.setBackground(borderColorDarker);
|
||||
if (border != null)
|
||||
border.setColor(borderColor);
|
||||
repaint();
|
||||
windowTitle.setText(message);
|
||||
windowTitle.setForeground(Color.white);
|
||||
}
|
||||
|
||||
public static void showMainFrame(boolean firstLoad) {
|
||||
instance.mainPanel.onShow(firstLoad);
|
||||
instance.show();
|
||||
}
|
||||
|
||||
Color borderColor = BasicColors.COLOR_BLUE;
|
||||
Color borderColorDarker = BasicColors.COLOR_BLUE_DARKER;
|
||||
|
||||
public void reloadColor() {
|
||||
borderColor = BasicColors.bgcolors[Settings.s().getTheme()];
|
||||
borderColorDarker = BasicColors.bgcolors_darker[Settings.s().getTheme()];
|
||||
if (border != null)
|
||||
border.setColor(borderColor);
|
||||
header.setBackground(borderColor);
|
||||
mainTab.setBackground(borderColorDarker);
|
||||
gameTab.setBackground(borderColorDarker);
|
||||
launcherTab.setBackground(borderColorDarker);
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void paintImpl(Graphics g) {
|
||||
super.paint(g);
|
||||
g.setColor(borderColor);
|
||||
int off = enableShadow ? 16 : 0;
|
||||
int width = 800;
|
||||
int height = header.getHeight() + 480 - 1;
|
||||
g.drawLine(off, off, off, height + off + 1);
|
||||
g.drawLine(off + width + 1, off, off + width + 1, height + off + 1);
|
||||
g.drawLine(off, height + off + 1, off + width + 1, height + off + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
if (!enableShadow)
|
||||
paintImpl(g);
|
||||
else {
|
||||
int off = enableShadow ? 16 : 0;
|
||||
int width = this.getWidth();
|
||||
int height = this.getHeight();
|
||||
int contentWidth = width - off - off;
|
||||
int contentHeight = height - off - off;
|
||||
BufferedImage contentImage = new BufferedImage(contentWidth,
|
||||
contentHeight, Transparency.OPAQUE);
|
||||
Graphics2D contentG2d = contentImage.createGraphics();
|
||||
contentG2d.translate(-off, -off);
|
||||
paintImpl(g);
|
||||
paintImpl(contentG2d);
|
||||
contentG2d.dispose();
|
||||
g.drawImage(contentImage, off, off, this);
|
||||
}
|
||||
}
|
||||
|
||||
public void invokeUpdate() {
|
||||
if (!isVisible()) return;
|
||||
defaultTitle = defaultTitle + C.i18n("update.found");
|
||||
if (!isShowedMessage) {
|
||||
windowTitle.setText(defaultTitle);
|
||||
windowTitle.setForeground(Color.red);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,280 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<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"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-32,0,0,3,32"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
|
||||
<Property name="useNullLayout" type="boolean" value="true"/>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="pnlMore">
|
||||
<Properties>
|
||||
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||
<Color blue="cc" green="cc" red="cc" type="rgb"/>
|
||||
</Property>
|
||||
<Property name="opaque" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
|
||||
<AbsoluteConstraints x="0" y="0" width="190" height="480"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<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">
|
||||
<Component id="pnlPassword" alignment="1" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="1" attributes="0">
|
||||
<Component id="jLabel10" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" alignment="1" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="cboProfiles" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="cboVersions" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<Component id="btnMakeLaunchScript" alignment="0" max="32767" attributes="0"/>
|
||||
<Component id="btnShowLog" alignment="0" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="lblUserName" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="jLabel7" alignment="0" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="cboLoginMode" max="32767" attributes="0"/>
|
||||
<Component id="txtPlayerName" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel10" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboProfiles" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="cboVersions" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel7" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboLoginMode" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="lblUserName" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtPlayerName" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="pnlPassword" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
<EmptySpace pref="254" max="32767" attributes="0"/>
|
||||
<Component id="btnShowLog" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnMakeLaunchScript" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextField" name="txtPlayerName">
|
||||
<Events>
|
||||
<EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtPlayerNameFocusGained"/>
|
||||
<EventHandler event="focusLost" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtPlayerNameFocusLost"/>
|
||||
<EventHandler event="keyPressed" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="txtPlayerNameKeyPressed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel7">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="login.type" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboLoginMode">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboLoginModeItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="lblUserName">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="login.username" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel10">
|
||||
<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.profile" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboProfiles">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboProfilesItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<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.version" replaceFormat="C.I18N.getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="ui.label.version" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboVersions">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cboVersionsItemStateChanged"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="pnlPassword">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel1">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||
<CardConstraints cardName="card2"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel9" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtPassword" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel9" alignment="3" min="-2" pref="22" max="-2" attributes="0"/>
|
||||
<Component id="txtPassword" alignment="3" min="-2" pref="26" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel9">
|
||||
<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.password" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JPasswordField" name="txtPassword">
|
||||
<Events>
|
||||
<EventHandler event="focusGained" listener="java.awt.event.FocusListener" parameters="java.awt.event.FocusEvent" handler="txtPasswordFocusGained"/>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="txtPasswordActionPerformed"/>
|
||||
<EventHandler event="keyPressed" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="txtPasswordKeyPressed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Container class="javax.swing.JPanel" name="jPanel3">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
|
||||
<CardConstraints cardName="card3"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="btnLogout" alignment="0" pref="170" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="btnLogout" alignment="0" pref="26" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JButton" name="btnLogout">
|
||||
<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.logout" replaceFormat="C.I18N.getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnLogoutActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="btnShowLog">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="mainwindow.show_log" 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="btnShowLogActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="btnMakeLaunchScript">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/jackhuang/hellominecraft/launcher/I18N.properties" key="mainwindow.make_launch_script" 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="btnMakeLaunchScriptActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
@ -0,0 +1,540 @@
|
||||
/*
|
||||
* 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.launcher.views;
|
||||
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hellominecraft.C;
|
||||
import org.jackhuang.hellominecraft.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.DefaultGameLauncher;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.auth.LoginInfo;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.GameLauncher;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.LaunchFinisher;
|
||||
import org.jackhuang.hellominecraft.launcher.launch.LaunchScriptFinisher;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.lookandfeel.GraphicsUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Event;
|
||||
import org.jackhuang.hellominecraft.views.LogWindow;
|
||||
import org.jackhuang.hellominecraft.lookandfeel.components.ConstomButton;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public class MainPagePanel extends javax.swing.JPanel {
|
||||
|
||||
/**
|
||||
* Creates new form MainPagePanel
|
||||
*/
|
||||
public MainPagePanel() {
|
||||
initComponents();
|
||||
|
||||
pnlButtons = new javax.swing.JPanel();
|
||||
pnlButtons.setLayout(null);
|
||||
|
||||
btnRun = new ConstomButton();
|
||||
btnRun.setBounds(0, 0, 150, 50);
|
||||
Font font = btnRun.getFont();
|
||||
Font newFont = new Font(font.getName(), font.getStyle(), 15);
|
||||
pnlButtons.add(btnRun);
|
||||
|
||||
btnRun.setText(C.i18n("ui.button.run"));
|
||||
btnRun.setFont(newFont);
|
||||
btnRun.addActionListener(e -> btnRunActionPerformed());
|
||||
|
||||
this.add(pnlButtons);
|
||||
pnlButtons.setBounds(0, 0, 150, 50);
|
||||
|
||||
this.setSize(new Dimension(deWidth, deHeight));
|
||||
this.pnlButtons.setLocation(deWidth - pnlButtons.getWidth() - 25, deHeight - pnlButtons.getHeight() - 25);
|
||||
pnlMore.setBounds(0, 0, pnlMore.getWidth(), deHeight);
|
||||
pnlMore.setBackground(GraphicsUtils.getWebColorWithAlpha("FFFFFF7F"));
|
||||
pnlMore.setOpaque(true);
|
||||
|
||||
prepareAuths();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
pnlMore = new javax.swing.JPanel();
|
||||
txtPlayerName = new javax.swing.JTextField();
|
||||
jLabel7 = new javax.swing.JLabel();
|
||||
cboLoginMode = new javax.swing.JComboBox();
|
||||
lblUserName = new javax.swing.JLabel();
|
||||
jLabel10 = new javax.swing.JLabel();
|
||||
cboProfiles = new javax.swing.JComboBox();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
cboVersions = new javax.swing.JComboBox();
|
||||
pnlPassword = new javax.swing.JPanel();
|
||||
jPanel1 = new javax.swing.JPanel();
|
||||
jLabel9 = new javax.swing.JLabel();
|
||||
txtPassword = new javax.swing.JPasswordField();
|
||||
jPanel3 = new javax.swing.JPanel();
|
||||
btnLogout = new javax.swing.JButton();
|
||||
btnShowLog = new javax.swing.JButton();
|
||||
btnMakeLaunchScript = new javax.swing.JButton();
|
||||
|
||||
setLayout(null);
|
||||
|
||||
pnlMore.setBackground(new java.awt.Color(204, 204, 204));
|
||||
pnlMore.setOpaque(false);
|
||||
|
||||
txtPlayerName.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusGained(java.awt.event.FocusEvent evt) {
|
||||
txtPlayerNameFocusGained(evt);
|
||||
}
|
||||
public void focusLost(java.awt.event.FocusEvent evt) {
|
||||
txtPlayerNameFocusLost(evt);
|
||||
}
|
||||
});
|
||||
txtPlayerName.addKeyListener(new java.awt.event.KeyAdapter() {
|
||||
public void keyPressed(java.awt.event.KeyEvent evt) {
|
||||
txtPlayerNameKeyPressed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/jackhuang/hellominecraft/launcher/I18N"); // NOI18N
|
||||
jLabel7.setText(bundle.getString("login.type")); // NOI18N
|
||||
|
||||
cboLoginMode.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboLoginModeItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
lblUserName.setText(bundle.getString("login.username")); // NOI18N
|
||||
|
||||
jLabel10.setText(bundle.getString("ui.label.profile")); // NOI18N
|
||||
|
||||
cboProfiles.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboProfilesItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel1.setText(C.I18N.getString("ui.label.version")); // NOI18N
|
||||
jLabel1.setToolTipText(bundle.getString("ui.label.version")); // NOI18N
|
||||
|
||||
cboVersions.addItemListener(new java.awt.event.ItemListener() {
|
||||
public void itemStateChanged(java.awt.event.ItemEvent evt) {
|
||||
cboVersionsItemStateChanged(evt);
|
||||
}
|
||||
});
|
||||
|
||||
pnlPassword.setLayout(new java.awt.CardLayout());
|
||||
|
||||
jLabel9.setText(bundle.getString("ui.label.password")); // NOI18N
|
||||
|
||||
txtPassword.addFocusListener(new java.awt.event.FocusAdapter() {
|
||||
public void focusGained(java.awt.event.FocusEvent evt) {
|
||||
txtPasswordFocusGained(evt);
|
||||
}
|
||||
});
|
||||
txtPassword.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
txtPasswordActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
txtPassword.addKeyListener(new java.awt.event.KeyAdapter() {
|
||||
public void keyPressed(java.awt.event.KeyEvent evt) {
|
||||
txtPasswordKeyPressed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
|
||||
jPanel1.setLayout(jPanel1Layout);
|
||||
jPanel1Layout.setHorizontalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(jPanel1Layout.createSequentialGroup()
|
||||
.addComponent(jLabel9)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtPassword))
|
||||
);
|
||||
jPanel1Layout.setVerticalGroup(
|
||||
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)))
|
||||
);
|
||||
|
||||
pnlPassword.add(jPanel1, "card2");
|
||||
|
||||
btnLogout.setText(C.I18N.getString("ui.button.logout")); // NOI18N
|
||||
btnLogout.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnLogoutActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
|
||||
jPanel3.setLayout(jPanel3Layout);
|
||||
jPanel3Layout.setHorizontalGroup(
|
||||
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(btnLogout, javax.swing.GroupLayout.DEFAULT_SIZE, 170, Short.MAX_VALUE)
|
||||
);
|
||||
jPanel3Layout.setVerticalGroup(
|
||||
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(btnLogout, javax.swing.GroupLayout.DEFAULT_SIZE, 26, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
pnlPassword.add(jPanel3, "card3");
|
||||
|
||||
btnShowLog.setText(bundle.getString("mainwindow.show_log")); // NOI18N
|
||||
btnShowLog.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnShowLogActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnMakeLaunchScript.setText(bundle.getString("mainwindow.make_launch_script")); // NOI18N
|
||||
btnMakeLaunchScript.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnMakeLaunchScriptActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout pnlMoreLayout = new javax.swing.GroupLayout(pnlMore);
|
||||
pnlMore.setLayout(pnlMoreLayout);
|
||||
pnlMoreLayout.setHorizontalGroup(
|
||||
pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(pnlMoreLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(pnlPassword, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(pnlMoreLayout.createSequentialGroup()
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
||||
.addComponent(jLabel10)
|
||||
.addComponent(jLabel1))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(cboProfiles, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(cboVersions, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
|
||||
.addComponent(btnMakeLaunchScript, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(btnShowLog, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(pnlMoreLayout.createSequentialGroup()
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(lblUserName)
|
||||
.addComponent(jLabel7))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(cboLoginMode, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(txtPlayerName))))
|
||||
.addContainerGap())
|
||||
);
|
||||
pnlMoreLayout.setVerticalGroup(
|
||||
pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlMoreLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel10)
|
||||
.addComponent(cboProfiles, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(cboVersions, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(jLabel1))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel7)
|
||||
.addComponent(cboLoginMode, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(pnlMoreLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(lblUserName)
|
||||
.addComponent(txtPlayerName, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(pnlPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 254, Short.MAX_VALUE)
|
||||
.addComponent(btnShowLog)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnMakeLaunchScript)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
add(pnlMore);
|
||||
pnlMore.setBounds(0, 0, 190, 480);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void txtPlayerNameFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPlayerNameFocusGained
|
||||
MainFrame.instance.closeMessage();
|
||||
}//GEN-LAST:event_txtPlayerNameFocusGained
|
||||
|
||||
private void txtPlayerNameFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPlayerNameFocusLost
|
||||
Settings.s().setUsername(txtPlayerName.getText());
|
||||
}//GEN-LAST:event_txtPlayerNameFocusLost
|
||||
|
||||
private void cboLoginModeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboLoginModeItemStateChanged
|
||||
if (preaparingAuth) return;
|
||||
int index = cboLoginMode.getSelectedIndex();
|
||||
if (index < 0) return;
|
||||
|
||||
IAuthenticator l = IAuthenticator.logins.get(index);
|
||||
if (l.isHidePasswordBox()) {
|
||||
pnlPassword.setVisible(false);
|
||||
lblUserName.setText(C.i18n("login.username"));
|
||||
} else {
|
||||
pnlPassword.setVisible(true);
|
||||
lblUserName.setText(C.i18n("login.account"));
|
||||
}
|
||||
|
||||
CardLayout cl = (CardLayout) pnlPassword.getLayout();
|
||||
if (l.isLoggedIn()) cl.last(pnlPassword);
|
||||
else cl.first(pnlPassword);
|
||||
String username = Settings.s().getUsername();
|
||||
if (StrUtils.isNotBlank(username)) txtPlayerName.setText(username);
|
||||
|
||||
Settings.s().setLoginType(index);
|
||||
}//GEN-LAST:event_cboLoginModeItemStateChanged
|
||||
|
||||
private void cboProfilesItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cboProfilesItemStateChanged
|
||||
if (!isLoading && cboProfiles.getSelectedIndex() != -1 && !StrUtils.isBlank((String) cboProfiles.getSelectedItem())) {
|
||||
Settings.s().setLast((String) cboProfiles.getSelectedItem());
|
||||
loadMinecraftVersions();
|
||||
}
|
||||
}//GEN-LAST:event_cboProfilesItemStateChanged
|
||||
|
||||
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()) || getCurrentProfile() == null)
|
||||
return;
|
||||
getCurrentProfile().setSelectedMinecraftVersion(cboVersions.getSelectedItem().toString());
|
||||
cboVersions.setToolTipText(cboVersions.getSelectedItem().toString());
|
||||
Settings.save();
|
||||
}//GEN-LAST:event_cboVersionsItemStateChanged
|
||||
|
||||
private void txtPasswordFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtPasswordFocusGained
|
||||
MainFrame.instance.closeMessage();
|
||||
}//GEN-LAST:event_txtPasswordFocusGained
|
||||
|
||||
private void txtPasswordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtPasswordActionPerformed
|
||||
btnRunActionPerformed();
|
||||
}//GEN-LAST:event_txtPasswordActionPerformed
|
||||
|
||||
private void btnLogoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLogoutActionPerformed
|
||||
if (preaparingAuth) return;
|
||||
int index = cboLoginMode.getSelectedIndex();
|
||||
|
||||
IAuthenticator l = IAuthenticator.logins.get(index);
|
||||
CardLayout cl = (CardLayout) pnlPassword.getLayout();
|
||||
if (l.isLoggedIn()) l.logout();
|
||||
cl.first(pnlPassword);
|
||||
}//GEN-LAST:event_btnLogoutActionPerformed
|
||||
|
||||
private void btnShowLogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnShowLogActionPerformed
|
||||
LogWindow.instance.setVisible(true);
|
||||
}//GEN-LAST:event_btnShowLogActionPerformed
|
||||
|
||||
private void btnMakeLaunchScriptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMakeLaunchScriptActionPerformed
|
||||
MainFrame.instance.showMessage(C.i18n("ui.message.launching"));
|
||||
genLaunchCode(value -> {
|
||||
value.successEvent.register(new LaunchScriptFinisher());
|
||||
value.successEvent.register(new PrepareAuthDoneListener());
|
||||
});
|
||||
}//GEN-LAST:event_btnMakeLaunchScriptActionPerformed
|
||||
|
||||
private void txtPlayerNameKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtPlayerNameKeyPressed
|
||||
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
int index = cboLoginMode.getSelectedIndex();
|
||||
if (index < 0) return;
|
||||
IAuthenticator l = IAuthenticator.logins.get(index);
|
||||
if (l.isHidePasswordBox()) btnRunActionPerformed();
|
||||
else if (!l.isLoggedIn()) txtPassword.requestFocus();
|
||||
}
|
||||
}//GEN-LAST:event_txtPlayerNameKeyPressed
|
||||
|
||||
private void txtPasswordKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtPasswordKeyPressed
|
||||
if (evt.getKeyCode() == KeyEvent.VK_ENTER) btnRunActionPerformed();
|
||||
}//GEN-LAST:event_txtPasswordKeyPressed
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Game Launch">
|
||||
void genLaunchCode(final Consumer<GameLauncher> listener) {
|
||||
HMCLog.log("Start generating launching command...");
|
||||
File file = getCurrentProfile().getCanonicalGameDirFile();
|
||||
if (!file.exists()) {
|
||||
HMCLog.warn("The minecraft path is wrong, please check it yourself.");
|
||||
MessageBox.Show(C.i18n("minecraft.wrong_path"));
|
||||
return;
|
||||
}
|
||||
final String name = (String) cboProfiles.getSelectedItem();
|
||||
if (StrUtils.isBlank(name) || getCurrentProfile().getSelectedMinecraftVersion() == null) {
|
||||
HMCLog.warn("There's no selected version, rechoose a version.");
|
||||
MessageBox.Show(C.i18n("minecraft.no_selected_version"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (cboLoginMode.getItemCount() == 0) {
|
||||
HMCLog.warn("There's no login method.");
|
||||
MessageBox.Show(C.i18n("login.methods.no_method"));
|
||||
return;
|
||||
}
|
||||
final int index = cboLoginMode.getSelectedIndex();
|
||||
final IAuthenticator l = IAuthenticator.logins.get(index);
|
||||
final LoginInfo li = new LoginInfo(Settings.s().getUsername(), l.isLoggedIn() || l.isHidePasswordBox() ? null : new String(txtPassword.getPassword()));
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Thread.currentThread().setName("Game Launcher");
|
||||
DefaultGameLauncher gl = new DefaultGameLauncher(getCurrentProfile(), li, l, Settings.s().getDownloadSource());
|
||||
gl.failEvent.register((sender, s) -> {
|
||||
if (s != null) MessageBox.Show(s);
|
||||
MainFrame.instance.closeMessage();
|
||||
return true;
|
||||
});
|
||||
listener.accept(gl);
|
||||
gl.makeLaunchCommand();
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Loads">
|
||||
private void prepareAuths() {
|
||||
preaparingAuth = true;
|
||||
List<IAuthenticator> list = IAuthenticator.logins;
|
||||
cboLoginMode.removeAllItems();
|
||||
for (IAuthenticator str : list)
|
||||
try {
|
||||
cboLoginMode.addItem(str.getName());
|
||||
} catch (Exception ex) {
|
||||
HMCLog.warn("Failed to get login name", ex);
|
||||
}
|
||||
if (Settings.s().getLoginType() < list.size()) {
|
||||
preaparingAuth = false;
|
||||
cboLoginMode.setSelectedIndex(Settings.s().getLoginType());
|
||||
|
||||
cboLoginModeItemStateChanged(null);
|
||||
}
|
||||
}
|
||||
|
||||
void loadFromSettings() {
|
||||
for (Profile s : Settings.getProfiles()) cboProfiles.addItem(s.getName());
|
||||
}
|
||||
|
||||
boolean showedNoVersion = false;
|
||||
|
||||
void loadMinecraftVersions() {
|
||||
isLoading = true;
|
||||
cboVersions.removeAllItems();
|
||||
int index = 0, i = 0;
|
||||
getCurrentProfile().getMinecraftProvider().refreshVersions();
|
||||
MinecraftVersion selVersion = getCurrentProfile().getSelectedMinecraftVersion();
|
||||
String selectedMC = selVersion == null ? null : selVersion.id;
|
||||
if (getCurrentProfile().getMinecraftProvider().getVersions().isEmpty()) {
|
||||
if (!showedNoVersion)
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
MessageBox.Show(C.i18n("mainwindow.no_version"));
|
||||
showedNoVersion = true;
|
||||
});
|
||||
} else {
|
||||
for (MinecraftVersion mcVersion : getCurrentProfile().getMinecraftProvider().getVersions()) {
|
||||
if (mcVersion.hidden) continue;
|
||||
cboVersions.addItem(mcVersion.id);
|
||||
if (mcVersion.id.equals(selectedMC)) index = i;
|
||||
i++;
|
||||
}
|
||||
if (index < cboVersions.getItemCount()) cboVersions.setSelectedIndex(index);
|
||||
}
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private void refreshMinecrafts(String last) {
|
||||
isLoading = true;
|
||||
cboProfiles.removeAllItems();
|
||||
loadFromSettings();
|
||||
for (int i = 0; i < cboProfiles.getItemCount(); i++) {
|
||||
String s = (String) cboProfiles.getItemAt(i);
|
||||
if (s != null && s.equals(last)) {
|
||||
cboProfiles.setSelectedIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
isLoading = false;
|
||||
loadMinecraftVersions();
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Private Variables">
|
||||
boolean preaparingAuth = true;
|
||||
private boolean isLoading = false;
|
||||
private final javax.swing.JPanel pnlButtons;
|
||||
private final ConstomButton btnRun;
|
||||
private static final int deWidth = 800, deHeight = 480;
|
||||
//</editor-fold>
|
||||
|
||||
class PrepareAuthDoneListener implements Event<List<String>> {
|
||||
|
||||
@Override
|
||||
public boolean call(Object sender, List<String> value) {
|
||||
prepareAuths();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void btnRunActionPerformed() {
|
||||
MainFrame.instance.showMessage(C.i18n("ui.message.launching"));
|
||||
genLaunchCode(value -> {
|
||||
value.successEvent.register(new LaunchFinisher());
|
||||
value.successEvent.register(new PrepareAuthDoneListener());
|
||||
});
|
||||
}
|
||||
|
||||
public void onShow(boolean showLeft) {
|
||||
if (showLeft)
|
||||
SwingUtilities.invokeLater(() -> MainFrame.instance.showMessage(C.i18n("ui.message.first_load")));
|
||||
if (cboLoginMode.getSelectedIndex() >= 0 && cboLoginMode.getSelectedIndex() < cboLoginMode.getItemCount()) {
|
||||
IAuthenticator l = IAuthenticator.logins.get(cboLoginMode.getSelectedIndex());
|
||||
if (!l.isHidePasswordBox() && !l.isLoggedIn())
|
||||
SwingUtilities.invokeLater(() -> MainFrame.instance.showMessage(C.i18n("ui.message.enter_password")));
|
||||
}
|
||||
}
|
||||
|
||||
public Profile getCurrentProfile() {
|
||||
return Settings.getVersion((String) cboProfiles.getSelectedItem());
|
||||
}
|
||||
|
||||
public void onSelected() {
|
||||
refreshMinecrafts(Settings.s().getLast());
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnLogout;
|
||||
private javax.swing.JButton btnMakeLaunchScript;
|
||||
private javax.swing.JButton btnShowLog;
|
||||
private javax.swing.JComboBox cboLoginMode;
|
||||
private javax.swing.JComboBox cboProfiles;
|
||||
private javax.swing.JComboBox cboVersions;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel10;
|
||||
private javax.swing.JLabel jLabel7;
|
||||
private javax.swing.JLabel jLabel9;
|
||||
private javax.swing.JPanel jPanel1;
|
||||
private javax.swing.JPanel jPanel3;
|
||||
private javax.swing.JLabel lblUserName;
|
||||
private javax.swing.JPanel pnlMore;
|
||||
private javax.swing.JPanel pnlPassword;
|
||||
private javax.swing.JPasswordField txtPassword;
|
||||
private javax.swing.JTextField txtPlayerName;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
124
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/NewProfileWindow.form
Normal file
124
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/NewProfileWindow.form
Normal file
@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" 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="ui.newProfileWindow.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>
|
||||
<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">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="txtNewProfileName" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jLabel2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cboProfiles" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="262" max="32767" attributes="0"/>
|
||||
<Component id="btnOK" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="btnCancel" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</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"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="txtNewProfileName" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cboProfiles" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="btnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="btnOK" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<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.newProfileWindow.new_profile_name" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="txtNewProfileName">
|
||||
<Events>
|
||||
<EventHandler event="keyTyped" listener="java.awt.event.KeyListener" parameters="java.awt.event.KeyEvent" handler="txtNewProfileNameKeyTyped"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="jLabel2">
|
||||
<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.newProfileWindow.copy_from" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="cboProfiles">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
|
||||
<StringArray count="0"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<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="button.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.JButton" name="btnOK">
|
||||
<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.ok" 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="btnOKActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
150
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/NewProfileWindow.java
Normal file
150
HMCL/src/main/java/org/jackhuang/hellominecraft/launcher/views/NewProfileWindow.java
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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.launcher.views;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.settings.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hyh
|
||||
*/
|
||||
public final class NewProfileWindow extends javax.swing.JDialog {
|
||||
|
||||
/**
|
||||
* Creates new form NewProfileWindow
|
||||
*/
|
||||
public NewProfileWindow(java.awt.Frame parent) {
|
||||
super(parent, true);
|
||||
initComponents();
|
||||
|
||||
setLocationRelativeTo(null);
|
||||
|
||||
for (Profile s : Settings.getProfiles()) {
|
||||
cboProfiles.addItem(s.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
txtNewProfileName = new javax.swing.JTextField();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
cboProfiles = new javax.swing.JComboBox();
|
||||
btnCancel = new javax.swing.JButton();
|
||||
btnOK = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/jackhuang/hellominecraft/launcher/I18N"); // NOI18N
|
||||
setTitle(bundle.getString("ui.newProfileWindow.title")); // NOI18N
|
||||
|
||||
jLabel1.setText(bundle.getString("ui.label.newProfileWindow.new_profile_name")); // NOI18N
|
||||
|
||||
txtNewProfileName.addKeyListener(new java.awt.event.KeyAdapter() {
|
||||
public void keyTyped(java.awt.event.KeyEvent evt) {
|
||||
txtNewProfileNameKeyTyped(evt);
|
||||
}
|
||||
});
|
||||
|
||||
jLabel2.setText(bundle.getString("ui.label.newProfileWindow.copy_from")); // NOI18N
|
||||
|
||||
btnCancel.setText(bundle.getString("button.cancel")); // NOI18N
|
||||
btnCancel.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnCancelActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
btnOK.setText(bundle.getString("ui.button.ok")); // NOI18N
|
||||
btnOK.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
btnOKActionPerformed(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)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(txtNewProfileName))
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jLabel2)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cboProfiles, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 262, Short.MAX_VALUE)
|
||||
.addComponent(btnOK)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(btnCancel)))
|
||||
.addContainerGap())
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(txtNewProfileName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel2)
|
||||
.addComponent(cboProfiles, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(btnCancel)
|
||||
.addComponent(btnOK))
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void txtNewProfileNameKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtNewProfileNameKeyTyped
|
||||
switch(evt.getKeyCode()) {
|
||||
case 13:
|
||||
Profile newProfile = new Profile(Settings.getVersion(cboProfiles.getSelectedItem().toString()));
|
||||
newProfile.setName(txtNewProfileName.getText());
|
||||
Settings.trySetVersion(newProfile);
|
||||
case 27:
|
||||
this.dispose();
|
||||
}
|
||||
}//GEN-LAST:event_txtNewProfileNameKeyTyped
|
||||
|
||||
private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed
|
||||
Profile newProfile = new Profile(Settings.getVersion(cboProfiles.getSelectedItem().toString()));
|
||||
newProfile.setName(txtNewProfileName.getText());
|
||||
Settings.trySetVersion(newProfile);
|
||||
this.dispose();
|
||||
}//GEN-LAST:event_btnOKActionPerformed
|
||||
|
||||
private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
|
||||
this.dispose();
|
||||
}//GEN-LAST:event_btnCancelActionPerformed
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton btnCancel;
|
||||
private javax.swing.JButton btnOK;
|
||||
private javax.swing.JComboBox cboProfiles;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JTextField txtNewProfileName;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
28
HMCL/src/main/java/org/jackhuang/mojang/authlib/Agent.java
Normal file
28
HMCL/src/main/java/org/jackhuang/mojang/authlib/Agent.java
Normal file
@ -0,0 +1,28 @@
|
||||
package org.jackhuang.mojang.authlib;
|
||||
|
||||
public class Agent {
|
||||
|
||||
public static final Agent MINECRAFT = new Agent("Minecraft", 1);
|
||||
public static final Agent SCROLLS = new Agent("Scrolls", 1);
|
||||
private final String name;
|
||||
private final int version;
|
||||
|
||||
public Agent(String name, int version) {
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Agent{name='" + this.name + '\'' + ", version=" + this.version + '}';
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package org.jackhuang.mojang.authlib;
|
||||
|
||||
import org.jackhuang.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
|
||||
public abstract interface AuthenticationService {
|
||||
|
||||
public abstract UserAuthentication createUserAuthentication(Agent paramAgent);
|
||||
|
||||
public abstract MinecraftSessionService createMinecraftSessionService();
|
||||
|
||||
public abstract GameProfileRepository createProfileRepository();
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package org.jackhuang.mojang.authlib;
|
||||
|
||||
public abstract class BaseAuthenticationService
|
||||
implements AuthenticationService {
|
||||
}
|
@ -0,0 +1,263 @@
|
||||
package org.jackhuang.mojang.authlib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.logging.logger.Logger;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Validate;
|
||||
import org.jackhuang.mojang.authlib.properties.Property;
|
||||
import org.jackhuang.mojang.authlib.properties.PropertyMap;
|
||||
import org.jackhuang.mojang.util.UUIDTypeAdapter;
|
||||
|
||||
public abstract class BaseUserAuthentication
|
||||
implements UserAuthentication {
|
||||
|
||||
private static final Logger LOGGER = new Logger("BaseUserAuthentication");
|
||||
protected static final String STORAGE_KEY_PROFILE_NAME = "displayName";
|
||||
protected static final String STORAGE_KEY_PROFILE_ID = "uuid";
|
||||
protected static final String STORAGE_KEY_PROFILE_PROPERTIES = "profileProperties";
|
||||
protected static final String STORAGE_KEY_USER_NAME = "username";
|
||||
protected static final String STORAGE_KEY_USER_ID = "userid";
|
||||
protected static final String STORAGE_KEY_USER_PROPERTIES = "userProperties";
|
||||
private final AuthenticationService authenticationService;
|
||||
private final PropertyMap userProperties = new PropertyMap();
|
||||
private String userid;
|
||||
private String username;
|
||||
private String password;
|
||||
private GameProfile selectedProfile;
|
||||
private UserType userType;
|
||||
|
||||
protected BaseUserAuthentication(AuthenticationService authenticationService) {
|
||||
Validate.notNull(authenticationService);
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canLogIn() {
|
||||
return (!canPlayOnline()) && (StrUtils.isNotBlank(getUsername())) && (StrUtils.isNotBlank(getPassword()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logOut() {
|
||||
this.password = null;
|
||||
this.userid = null;
|
||||
setSelectedProfile(null);
|
||||
getModifiableUserProperties().clear();
|
||||
setUserType(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggedIn() {
|
||||
return getSelectedProfile() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsername(String username) {
|
||||
if ((isLoggedIn()) && (canPlayOnline())) {
|
||||
throw new IllegalStateException("Cannot change username whilst logged in & online");
|
||||
}
|
||||
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPassword(String password) {
|
||||
if ((isLoggedIn()) && (canPlayOnline()) && (StrUtils.isNotBlank(password))) {
|
||||
throw new IllegalStateException("Cannot set password whilst logged in & online");
|
||||
}
|
||||
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
protected String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
protected String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFromStorage(Map<String, Object> credentials) {
|
||||
logOut();
|
||||
|
||||
setUsername((String)credentials.get("username"));
|
||||
|
||||
if (credentials.containsKey("userid")) {
|
||||
this.userid = (String)credentials.get("userid");
|
||||
} else {
|
||||
this.userid = this.username;
|
||||
}
|
||||
|
||||
if (credentials.containsKey("userProperties")) {
|
||||
try {
|
||||
List<Map> list = (List<Map>) credentials.get("userProperties");
|
||||
|
||||
for (Map propertyMap : list) {
|
||||
String name = (String) propertyMap.get("name");
|
||||
String value = (String) propertyMap.get("value");
|
||||
String signature = (String) propertyMap.get("signature");
|
||||
|
||||
if (signature == null) {
|
||||
getModifiableUserProperties().put(name, new Property(name, value));
|
||||
} else {
|
||||
getModifiableUserProperties().put(name, new Property(name, value, signature));
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LOGGER.warn("Couldn't deserialize user properties", t);
|
||||
}
|
||||
}
|
||||
|
||||
if ((credentials.containsKey("displayName")) && (credentials.containsKey("uuid"))) {
|
||||
GameProfile profile = new GameProfile(UUIDTypeAdapter.fromString((String)credentials.get("uuid")), (String)credentials.get("displayName"));
|
||||
if (credentials.containsKey("profileProperties")) {
|
||||
try {
|
||||
List<Map> list = (List<Map>) credentials.get("profileProperties");
|
||||
for (Map propertyMap : list) {
|
||||
String name = (String) propertyMap.get("name");
|
||||
String value = (String) propertyMap.get("value");
|
||||
String signature = (String) propertyMap.get("signature");
|
||||
|
||||
if (signature == null) {
|
||||
profile.getProperties().put(name, new Property(name, value));
|
||||
} else {
|
||||
profile.getProperties().put(name, new Property(name, value, signature));
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LOGGER.warn("Couldn't deserialize profile properties", t);
|
||||
}
|
||||
}
|
||||
setSelectedProfile(profile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> saveForStorage() {
|
||||
Map result = new HashMap();
|
||||
|
||||
if (getUsername() != null) {
|
||||
result.put("username", getUsername());
|
||||
}
|
||||
if (getUserID() != null) {
|
||||
result.put("userid", getUserID());
|
||||
} else if (getUsername() != null) {
|
||||
result.put("username", getUsername());
|
||||
}
|
||||
|
||||
if (!getUserProperties().isEmpty()) {
|
||||
List properties = new ArrayList();
|
||||
for (Property userProperty : getUserProperties().values()) {
|
||||
Map property = new HashMap();
|
||||
property.put("name", userProperty.getName());
|
||||
property.put("value", userProperty.getValue());
|
||||
property.put("signature", userProperty.getSignature());
|
||||
properties.add(property);
|
||||
}
|
||||
result.put("userProperties", properties);
|
||||
}
|
||||
|
||||
GameProfile sel = getSelectedProfile();
|
||||
if (sel != null) {
|
||||
result.put("displayName", sel.getName());
|
||||
result.put("uuid", sel.getId());
|
||||
|
||||
List properties = new ArrayList();
|
||||
for (Property profileProperty : sel.getProperties().values()) {
|
||||
Map property = new HashMap();
|
||||
property.put("name", profileProperty.getName());
|
||||
property.put("value", profileProperty.getValue());
|
||||
property.put("signature", profileProperty.getSignature());
|
||||
properties.add(property);
|
||||
}
|
||||
|
||||
if (!properties.isEmpty()) {
|
||||
result.put("profileProperties", properties);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void setSelectedProfile(GameProfile selectedProfile) {
|
||||
this.selectedProfile = selectedProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameProfile getSelectedProfile() {
|
||||
return this.selectedProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
|
||||
result.append(getClass().getSimpleName());
|
||||
result.append("{");
|
||||
|
||||
if (isLoggedIn()) {
|
||||
result.append("Logged in as ");
|
||||
result.append(getUsername());
|
||||
|
||||
if (getSelectedProfile() != null) {
|
||||
result.append(" / ");
|
||||
result.append(getSelectedProfile());
|
||||
result.append(" - ");
|
||||
|
||||
if (canPlayOnline()) {
|
||||
result.append("Online");
|
||||
} else {
|
||||
result.append("Offline");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result.append("Not logged in");
|
||||
}
|
||||
|
||||
result.append("}");
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public AuthenticationService getAuthenticationService() {
|
||||
return this.authenticationService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUserID() {
|
||||
return this.userid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyMap getUserProperties() {
|
||||
if (isLoggedIn()) {
|
||||
PropertyMap result = new PropertyMap();
|
||||
result.putAll(getModifiableUserProperties());
|
||||
return result;
|
||||
}
|
||||
return new PropertyMap();
|
||||
}
|
||||
|
||||
protected PropertyMap getModifiableUserProperties() {
|
||||
return this.userProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserType getUserType() {
|
||||
if (isLoggedIn()) {
|
||||
return this.userType == null ? UserType.LEGACY : this.userType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void setUserType(UserType userType) {
|
||||
this.userType = userType;
|
||||
}
|
||||
|
||||
protected void setUserid(String userid) {
|
||||
this.userid = userid;
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package org.jackhuang.mojang.authlib;
|
||||
|
||||
import org.jackhuang.mojang.authlib.properties.PropertyMap;
|
||||
import java.util.UUID;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
public class GameProfile {
|
||||
|
||||
private final UUID id;
|
||||
private final String name;
|
||||
private final PropertyMap properties = new PropertyMap();
|
||||
private boolean legacy;
|
||||
|
||||
public GameProfile(UUID id, String name) {
|
||||
if ((id == null) && (StrUtils.isBlank(name))) {
|
||||
throw new IllegalArgumentException("Name and ID cannot both be blank");
|
||||
}
|
||||
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public UUID getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public PropertyMap getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return (this.id != null) && (StrUtils.isNotBlank(getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if ((o == null) || (getClass() != o.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GameProfile that = (GameProfile) o;
|
||||
|
||||
if (this.id != null ? !this.id.equals(that.id) : that.id != null) {
|
||||
return false;
|
||||
}
|
||||
return this.name != null ? this.name.equals(that.name) : that.name == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = this.id != null ? this.id.hashCode() : 0;
|
||||
result = 31 * result + (this.name != null ? this.name.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GameProfile{" + "id=" + id + ", name=" + name + ", properties=" + properties + ", legacy=" + legacy + '}';
|
||||
}
|
||||
|
||||
|
||||
public boolean isLegacy() {
|
||||
return this.legacy;
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package org.jackhuang.mojang.authlib;
|
||||
|
||||
public abstract interface GameProfileRepository {
|
||||
|
||||
public abstract void findProfilesByNames(String[] paramArrayOfString, Agent paramAgent, ProfileLookupCallback paramProfileLookupCallback);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user