Fixed not showing prompt when no version here

This commit is contained in:
huangyuhui
2017-02-12 22:56:44 +08:00
parent f756f32bda
commit 80599013f2
80 changed files with 1637 additions and 436 deletions

View File

@@ -33,11 +33,11 @@ def buildnumber = System.getenv("TRAVIS_BUILD_NUMBER")
if (buildnumber == null) if (buildnumber == null)
buildnumber = System.getenv("BUILD_NUMBER") buildnumber = System.getenv("BUILD_NUMBER")
if (buildnumber == null) if (buildnumber == null)
buildnumber = "5" buildnumber = "0"
def versionroot = System.getenv("VERSION_ROOT") def versionroot = System.getenv("VERSION_ROOT")
if (versionroot == null) if (versionroot == null)
versionroot = "2.6.0" versionroot = "2.6.1"
String mavenGroupId = 'HMCL' String mavenGroupId = 'HMCL'
String mavenVersion = versionroot + '.' + buildnumber String mavenVersion = versionroot + '.' + buildnumber

View File

@@ -0,0 +1,28 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api;
import org.jackhuang.hellominecraft.util.ui.Page;
/**
*
* @author huang
*/
public interface AddTabCallback {
void addTab(Page tabPage, String id, String title);
}

View File

@@ -17,12 +17,8 @@
*/ */
package org.jackhuang.hellominecraft.launcher.api; package org.jackhuang.hellominecraft.launcher.api;
import org.jackhuang.hellominecraft.launcher.core.GameException; import javax.swing.JFrame;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions;
import org.jackhuang.hellominecraft.util.func.Consumer; import org.jackhuang.hellominecraft.util.func.Consumer;
/** /**
@@ -31,34 +27,12 @@ import org.jackhuang.hellominecraft.util.func.Consumer;
*/ */
public interface IPlugin { public interface IPlugin {
/**
* You can modify the application actions by this method.
*
* @param obj minecraft service wanted
*
* @return For example, you can implement IMinecraftProvider to support
* MultiMC
*/
IMinecraftService provideMinecraftService(Object obj);
/** /**
* Register authenticators by calling IAuthenticator.LOGINS.add. * Register authenticators by calling IAuthenticator.LOGINS.add.
* *
* @param apply call apply.accept(your authenticator) * @param apply call apply.accept(your authenticator)
*/ */
void onRegisterAuthenticators(Consumer<IAuthenticator> apply); void onRegisterAuthenticators(Consumer<IAuthenticator> apply);
/** void onAddTab(JFrame frame, AddTabCallback callback);
* Open your customized UI.
*/
void showUI();
/**
* Add your server ip or modify the access token.
*
* @param result What you want.
*/
void onProcessingLoginResult(UserProfileProvider result) throws AuthenticationException;
void onProcessingLaunchOptions(LaunchOptions p) throws GameException;
} }

View File

@@ -17,6 +17,10 @@
*/ */
package org.jackhuang.hellominecraft.launcher.api; package org.jackhuang.hellominecraft.launcher.api;
import java.util.ArrayList;
import javax.swing.JFrame;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
/** /**
@@ -25,19 +29,25 @@ import org.jackhuang.hellominecraft.util.log.HMCLog;
*/ */
public class PluginManager { public class PluginManager {
private static IPlugin NOW_PLUGIN; private static final ArrayList<IPlugin> PLUGINS = new ArrayList<>();
public static void getPlugin(Class<?> cls) { public static void getPlugin(Class<?> cls) {
try { try {
IPlugin p = (IPlugin) cls.newInstance(); IPlugin p = (IPlugin) cls.newInstance();
NOW_PLUGIN = p; PLUGINS.add(p);
} catch (IllegalAccessException | InstantiationException e) { } catch (IllegalAccessException | InstantiationException e) {
HMCLog.err("Failed to new instance"); HMCLog.err("Failed to new instance");
} }
} }
public static IPlugin plugin() { public static void fireRegisterAuthenticators(Consumer<IAuthenticator> callback) {
return NOW_PLUGIN; for (IPlugin p : PLUGINS)
p.onRegisterAuthenticators(callback);
}
public static void fireAddTab(JFrame frame, AddTabCallback callback) {
for (IPlugin p : PLUGINS)
p.onAddTab(frame, callback);
} }
} }

View File

@@ -0,0 +1,35 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.config;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
/**
* This event gets fired when the authenticator changed.
*
* @param IAuthenticator the new authenticator.
* @author huangyuhui
*/
public class AuthenticatorChangedEvent extends SimpleEvent<IAuthenticator> {
public AuthenticatorChangedEvent(Object source, IAuthenticator value) {
super(source, value);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.config;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
/**
* This event gets fired when the download type changed.
*
* @param DownloadType the new downlaod type;
* @author huangyuhui
*/
public class DownloadTypeChangedEvent extends SimpleEvent<DownloadType> {
public DownloadTypeChangedEvent(Object source, DownloadType value) {
super(source, value);
}
}

View File

@@ -0,0 +1,33 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.config;
import org.jackhuang.hellominecraft.api.SimpleEvent;
/**
* This event gets fired when the selected profile changed.
* @param String the new profile id.
* @author huangyuhui
*/
public class ProfileChangedEvent extends SimpleEvent<String> {
public ProfileChangedEvent(Object source, String value) {
super(source, value);
}
}

View File

@@ -0,0 +1,32 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.config;
import java.util.EventObject;
/**
* This event gets fired when loading profiles.
* @author huang
*/
public class ProfileLoadingEvent extends EventObject {
public ProfileLoadingEvent(Object source) {
super(source);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.config;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.lookandfeel.Theme;
/**
* This event gets fired when the application theme changed.
*
* @param Theme the changed theme
* @author huangyuhui
*/
public class ThemeChangedEvent extends SimpleEvent<Theme> {
public ThemeChangedEvent(Object source, Theme value) {
super(source, value);
}
}

View File

@@ -0,0 +1,39 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.launch;
import org.jackhuang.hellominecraft.api.ResultedSimpleEvent;
/**
* This event gets fired when we are launching a game and going to decompress natives.
* <br>
* This event is {@link org.jackhuang.hellominecraft.api.ResultedEvent}
* If this event is failed, the launching process will be terminated.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher}
* @param DecompressLibraryJob libraries to be decompressed
* @author huangyuhui
*/
public class DecompressLibrariesEvent extends ResultedSimpleEvent<DecompressLibraryJob> {
public DecompressLibrariesEvent(Object source, DecompressLibraryJob value) {
super(source, value);
}
}

View File

@@ -15,12 +15,12 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}. * along with this program. If not, see {http://www.gnu.org/licenses/}.
*/ */
package org.jackhuang.hellominecraft.launcher.core.version; package org.jackhuang.hellominecraft.launcher.api.event.launch;
import java.io.File; import java.io.File;
import org.jackhuang.hellominecraft.launcher.core.version.Extract;
/** /**
*
* @author huangyuhui * @author huangyuhui
*/ */
public class DecompressLibraryJob { public class DecompressLibraryJob {
@@ -29,6 +29,12 @@ public class DecompressLibraryJob {
public Extract[] extractRules; public Extract[] extractRules;
private File decompressTo; private File decompressTo;
/**
* The length of these 2 arrays must be the same.
* @param decompressFiles
* @param extractRules
* @param decompressTo folder
*/
public DecompressLibraryJob(File[] decompressFiles, Extract[] extractRules, File decompressTo) { public DecompressLibraryJob(File[] decompressFiles, Extract[] extractRules, File decompressTo) {
this.decompressFiles = decompressFiles.clone(); this.decompressFiles = decompressFiles.clone();
this.extractRules = extractRules.clone(); this.extractRules = extractRules.clone();

View File

@@ -0,0 +1,39 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.launch;
import java.util.List;
import org.jackhuang.hellominecraft.api.ResultedSimpleEvent;
/**
* This event gets fired when we are launching a game and there are some libraries to be downloaded.
* <br>
* This event is {@link org.jackhuang.hellominecraft.api.ResultedEvent}
* If this event is failed, the launching process will be terminated.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher}
* Passed value List&lt;DownloadLibraryJob&gt;: libraries to be downloaded.
* @author huangyuhui
*/
public class DownloadLibrariesEvent extends ResultedSimpleEvent<List<DownloadLibraryJob>> {
public DownloadLibrariesEvent(Object sender, List<DownloadLibraryJob> lists) {
super(sender, lists);
}
}

View File

@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}. * along with this program. If not, see {http://www.gnu.org/licenses/}.
*/ */
package org.jackhuang.hellominecraft.launcher.core.download; package org.jackhuang.hellominecraft.launcher.api.event.launch;
import java.io.File; import java.io.File;
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary; import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;

View File

@@ -0,0 +1,37 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.launch;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.sys.JavaProcess;
/**
* This event gets fired when we launched the game.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher}
* @param JavaProcess the game process
* @author huangyuhui
*/
public class LaunchEvent extends SimpleEvent<JavaProcess> {
public LaunchEvent(Object source, JavaProcess value) {
super(source, value);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.launch;
import java.util.List;
import org.jackhuang.hellominecraft.api.SimpleEvent;
/**
* This event gets fired when we make the launching command successfully(not launched the game process).
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher}
* @param List&lt;String&gt; Our launching command.
* @author huangyuhui
*/
public class LaunchSucceededEvent extends SimpleEvent<List<String>>{
public LaunchSucceededEvent(Object source, List<String> value) {
super(source, value);
}
}

View File

@@ -15,15 +15,17 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}. * along with this program. If not, see {http://www.gnu.org/licenses/}.
*/ */
package org.jackhuang.hellominecraft.launcher.core.launch; package org.jackhuang.hellominecraft.launcher.api.event.launch;
/** /**
* *
* @author huangyuhui * @author huangyuhui
*/ */
public enum LaunchingState { public enum LaunchingState {
Starting,
LoggingIn, LoggingIn,
GeneratingLaunchingCodes, GeneratingLaunchingCodes,
DownloadingLibraries, DownloadingLibraries,
DecompressingNatives DecompressingNatives,
Done
} }

View File

@@ -0,0 +1,36 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.launch;
import org.jackhuang.hellominecraft.api.SimpleEvent;
/**
* This event gets fired when we are launching a game and mark what things we are doing.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher}
* @param LaunchingState the launching state.
* @author huangyuhui
*/
public class LaunchingStateChangedEvent extends SimpleEvent<LaunchingState> {
public LaunchingStateChangedEvent(Object source, LaunchingState value) {
super(source, value);
}
}

View File

@@ -0,0 +1,40 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.launch;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions;
/**
* This event gets fired before generating launch command.
* <br>
* Pay attension: If you need to terminate the launching process, you must throw
* {@link org.jackhuang.hellominecraft.launcher.core.RuntimeGameException anyway.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher}
* @param LaunchOptions you can modify the value of this event to control the launching process.
* @author huang
*/
public class ProcessingLaunchOptionsEvent extends SimpleEvent<LaunchOptions> {
public ProcessingLaunchOptionsEvent(Object source, LaunchOptions value) {
super(source, value);
}
}

View File

@@ -0,0 +1,40 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.launch;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
/**
* This event gets fired when we successfully logged in.
* <br>
* Pay attension: If you need to terminate the launching process, you must throw
* {@link org.jackhuang.hellominecraft.launcher.core.RuntimeGameException anyway.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher}
* @param UserProfileProvider you can modify the value of this event to control the user profile.
* @author huangyuhui
*/
public class ProcessingLoginResultEvent extends SimpleEvent<UserProfileProvider> {
public ProcessingLoginResultEvent(Object source, UserProfileProvider value) {
super(source, value);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.version;
import org.jackhuang.hellominecraft.api.SimpleEvent;
/**
* This event gets fired when a minecraft version has been loaded.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersionManager}
* @param String the version id.
* @author huang
*/
public class LoadedOneVersionEvent extends SimpleEvent<String> {
public LoadedOneVersionEvent(Object source, String value) {
super(source, value);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.version;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
/**
* This event gets fired when all the versions in .minecraft folder are loaded.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersionManager}
* @param IMinecraftService the .minecraft folder.
* @author huangyuhui
*/
public class RefreshedVersionsEvent extends SimpleEvent<IMinecraftService> {
public RefreshedVersionsEvent(Object source, IMinecraftService value) {
super(source, value);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.api.event.version;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
/**
* This event gets fired when loading versions in a .minecraft folder.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersionManager}
* @param IMinecraftService .minecraft folder.
* @author huang
*/
public class RefreshingVersionsEvent extends SimpleEvent<IMinecraftService> {
public RefreshingVersionsEvent(Object source, IMinecraftService value) {
super(source, value);
}
}

View File

@@ -18,7 +18,7 @@
package org.jackhuang.hellominecraft.launcher.core; package org.jackhuang.hellominecraft.launcher.core;
/** /**
* * Thrown if we have some problem generating launch command.
* @author huangyuhui * @author huangyuhui
*/ */
public class GameException extends Exception { public class GameException extends Exception {

View File

@@ -0,0 +1,40 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.core;
/**
*
* @author huang
*/
public class RuntimeGameException extends RuntimeException {
public RuntimeGameException() {
}
public RuntimeGameException(String message) {
super(message);
}
public RuntimeGameException(String message, Throwable cause) {
super(message, cause);
}
public RuntimeGameException(Throwable cause) {
super(cause);
}
}

View File

@@ -17,6 +17,11 @@
*/ */
package org.jackhuang.hellominecraft.launcher.core.auth; package org.jackhuang.hellominecraft.launcher.core.auth;
/**
* Thrown if we are trying to log in but there's some problems like password wrong.
*
* @author huangyuhui
*/
public class AuthenticationException extends Exception { public class AuthenticationException extends Exception {
public AuthenticationException() { public AuthenticationException() {

View File

@@ -33,7 +33,7 @@ public abstract class IAuthenticator {
public static final List<IAuthenticator> LOGINS = new ArrayList<>(); public static final List<IAuthenticator> LOGINS = new ArrayList<>();
static { static {
PluginManager.plugin().onRegisterAuthenticators(LOGINS::add); PluginManager.fireRegisterAuthenticators(LOGINS::add);
} }
protected String clientToken, username, password; protected String clientToken, username, password;

View File

@@ -0,0 +1,55 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author huang
*/
public enum UserType {
LEGACY("legacy"), MOJANG("mojang");
private static final Map<String, UserType> BY_NAME;
private final String name;
private UserType(String name) {
this.name = name;
}
public static UserType byName(String name) {
return (UserType) BY_NAME.get(name.toLowerCase());
}
public static UserType byLegacy(boolean isLegacy) {
return isLegacy ? LEGACY : MOJANG;
}
public String getName() {
return this.name;
}
static {
BY_NAME = new HashMap();
for (UserType type : values())
BY_NAME.put(type.name, type);
}
}

View File

@@ -0,0 +1,33 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil;
/**
*
* @author huang
*/
public class ValidateRequest {
private String clientToken;
private String accessToken;
public ValidateRequest(YggdrasilAuthentication authentication) {
clientToken = authentication.getClientToken();
accessToken = authentication.getAuthenticatedToken();
}
}

View File

@@ -17,6 +17,8 @@
*/ */
package org.jackhuang.hellominecraft.launcher.core.download; package org.jackhuang.hellominecraft.launcher.core.download;
import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.launcher.api.event.config.DownloadTypeChangedEvent;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.task.TaskWindow; import org.jackhuang.hellominecraft.util.task.TaskWindow;
@@ -59,4 +61,7 @@ public enum DownloadType {
DownloadType.suggestedDownloadType = suggestedDownloadType; DownloadType.suggestedDownloadType = suggestedDownloadType;
} }
static {
HMCLAPI.EVENT_BUS.channel(DownloadTypeChangedEvent.class).register(t -> setSuggestedDownloadType(t.getValue()));
}
} }

View File

@@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hellominecraft.launcher.core.download; package org.jackhuang.hellominecraft.launcher.core.download;
import org.jackhuang.hellominecraft.launcher.api.event.launch.DownloadLibraryJob;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftDownloadService; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftDownloadService;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import java.io.File; import java.io.File;

View File

@@ -19,16 +19,22 @@ package org.jackhuang.hellominecraft.launcher.core.launch;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet; import java.util.HashSet;
import org.jackhuang.hellominecraft.util.C; import java.util.List;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.api.ResultedSimpleEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.DecompressLibrariesEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.DownloadLibrariesEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.DownloadLibraryJob;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.launcher.core.auth.LoginInfo; import org.jackhuang.hellominecraft.launcher.core.auth.LoginInfo;
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.log.HMCLog;
import org.jackhuang.hellominecraft.util.sys.CompressingUtils;
import org.jackhuang.hellominecraft.util.task.ParallelTask; import org.jackhuang.hellominecraft.util.task.ParallelTask;
import org.jackhuang.hellominecraft.util.task.TaskWindow; import org.jackhuang.hellominecraft.util.task.TaskWindow;
import org.jackhuang.hellominecraft.util.sys.CompressingUtils;
import org.jackhuang.hellominecraft.util.MessageBox;
public class DefaultGameLauncher extends GameLauncher { public class DefaultGameLauncher extends GameLauncher {
@@ -38,11 +44,12 @@ public class DefaultGameLauncher extends GameLauncher {
} }
private void register() { private void register() {
downloadLibrariesEvent.register((sender, t) -> { HMCLAPI.EVENT_BUS.channel(DownloadLibrariesEvent.class).register(t -> {
ResultedSimpleEvent<List<DownloadLibraryJob>> event = (ResultedSimpleEvent) t;
final TaskWindow.TaskWindowFactory dw = TaskWindow.factory(); final TaskWindow.TaskWindowFactory dw = TaskWindow.factory();
ParallelTask parallelTask = new ParallelTask(); ParallelTask parallelTask = new ParallelTask();
HashSet<String> names = new HashSet<>(); HashSet<String> names = new HashSet<>();
for (DownloadLibraryJob s : t) { for (DownloadLibraryJob s : t.getValue()) {
if (names.contains(s.lib.name)) if (names.contains(s.lib.name))
continue; continue;
names.add(s.lib.name); names.add(s.lib.name);
@@ -50,22 +57,23 @@ public class DefaultGameLauncher extends GameLauncher {
} }
dw.append(parallelTask); dw.append(parallelTask);
boolean flag = true; boolean flag = true;
if (t.size() > 0) if (t.getValue().size() > 0)
flag = dw.execute(); flag = dw.execute();
if (!flag && MessageBox.show(C.i18n("launch.not_finished_downloading_libraries"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) if (!flag && MessageBox.show(C.i18n("launch.not_finished_downloading_libraries"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
flag = true; flag = true;
return flag; t.setResult(flag);
}); });
decompressNativesEvent.register((sender, value) -> { HMCLAPI.EVENT_BUS.channel(DecompressLibrariesEvent.class).register(t -> {
if (value == null) if (t.getValue() == null) {
return false; t.setResult(false);
for (int i = 0; i < value.decompressFiles.length; i++) return;
}
for (int i = 0; i < t.getValue().decompressFiles.length; i++)
try { try {
CompressingUtils.unzip(value.decompressFiles[i], value.getDecompressTo(), value.extractRules[i]::allow, false); CompressingUtils.unzip(t.getValue().decompressFiles[i], t.getValue().getDecompressTo(), t.getValue().extractRules[i]::allow, false);
} catch (IOException ex) { } catch (IOException ex) {
HMCLog.err("Unable to decompress library: " + value.decompressFiles[i] + " to " + value.getDecompressTo(), ex); HMCLog.err("Unable to decompress library: " + t.getValue().decompressFiles[i] + " to " + t.getValue().getDecompressTo(), ex);
} }
return true;
}); });
} }

View File

@@ -23,18 +23,24 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.util.List; import java.util.List;
import org.jackhuang.hellominecraft.launcher.api.PluginManager; import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.launcher.api.event.launch.DecompressLibrariesEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.DecompressLibraryJob;
import org.jackhuang.hellominecraft.launcher.api.event.launch.DownloadLibrariesEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchSucceededEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchingState;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchingStateChangedEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.ProcessingLoginResultEvent;
import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.RuntimeGameException;
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException; import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.launcher.core.auth.LoginInfo; import org.jackhuang.hellominecraft.launcher.core.auth.LoginInfo;
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider; import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.core.version.DecompressLibraryJob;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.EventHandler;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.code.Charsets; import org.jackhuang.hellominecraft.util.code.Charsets;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
@@ -52,11 +58,6 @@ public class GameLauncher {
LoginInfo info; LoginInfo info;
UserProfileProvider result; UserProfileProvider result;
IAuthenticator login; IAuthenticator login;
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<LaunchingState> launchingStateChangedEvent = new EventHandler<>(this);
public final EventHandler<DecompressLibraryJob> decompressNativesEvent = new EventHandler<>(this);
public GameLauncher(LaunchOptions options, IMinecraftService version, LoginInfo info, IAuthenticator lg) { public GameLauncher(LaunchOptions options, IMinecraftService version, LoginInfo info, IAuthenticator lg) {
this.options = options; this.options = options;
@@ -75,10 +76,21 @@ public class GameLauncher {
this.tag = tag; this.tag = tag;
} }
public IMinecraftLoader makeLaunchCommand() throws AuthenticationException, GameException { /**
* Generates the launch command.
* @throws AuthenticationException having trouble logging in.
* @throws GameException having trouble completing the game or making lanch command.
* @throws RuntimeGameException will be thrown when someone processing login result.
* @see LaunchingStateChangedEvent
* @see DecompressLibrariesEvent
* @see LaunchSucceededEvent
* @see DownloadLibrariesEvent
* @see ProcessingLoginResultEvent
*/
public void makeLaunchCommand() throws AuthenticationException, GameException, RuntimeGameException {
HMCLog.log("Building process"); HMCLog.log("Building process");
HMCLog.log("Logging in..."); HMCLog.log("Logging in...");
launchingStateChangedEvent.execute(LaunchingState.LoggingIn); HMCLAPI.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(this, LaunchingState.LoggingIn));
IMinecraftLoader loader; IMinecraftLoader loader;
if (info != null) if (info != null)
result = login.login(info); result = login.login(info);
@@ -86,9 +98,9 @@ public class GameLauncher {
result = login.loginBySettings(); result = login.loginBySettings();
if (result == null) if (result == null)
throw new AuthenticationException("Result can not be null."); throw new AuthenticationException("Result can not be null.");
PluginManager.plugin().onProcessingLoginResult(result); HMCLAPI.EVENT_BUS.fireChannel(new ProcessingLoginResultEvent(this, result));
launchingStateChangedEvent.execute(LaunchingState.GeneratingLaunchingCodes); HMCLAPI.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(this, LaunchingState.GeneratingLaunchingCodes));
loader = service.launch(options, result); loader = service.launch(options, result);
File file = service.version().getDecompressNativesToLocation(loader.getMinecraftVersion()); File file = service.version().getDecompressNativesToLocation(loader.getMinecraftVersion());
@@ -97,19 +109,18 @@ public class GameLauncher {
if (!options.isNotCheckGame()) { if (!options.isNotCheckGame()) {
HMCLog.log("Detecting libraries..."); HMCLog.log("Detecting libraries...");
launchingStateChangedEvent.execute(LaunchingState.DownloadingLibraries); HMCLAPI.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(this, LaunchingState.DownloadingLibraries));
if (!downloadLibrariesEvent.execute(service.download().getDownloadLibraries(loader.getMinecraftVersion()))) if (!HMCLAPI.EVENT_BUS.fireChannelResulted(new DownloadLibrariesEvent(this, service.download().getDownloadLibraries(loader.getMinecraftVersion()))))
throw new GameException("Failed to download libraries"); throw new GameException("Failed to download libraries");
} }
HMCLog.log("Unpacking natives..."); HMCLog.log("Unpacking natives...");
launchingStateChangedEvent.execute(LaunchingState.DecompressingNatives); HMCLAPI.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(this, LaunchingState.DecompressingNatives));
DecompressLibraryJob job = service.version().getDecompressLibraries(loader.getMinecraftVersion()); DecompressLibraryJob job = service.version().getDecompressLibraries(loader.getMinecraftVersion());
if (!decompressNativesEvent.execute(job)) if (!HMCLAPI.EVENT_BUS.fireChannelResulted(new DecompressLibrariesEvent(this, job)))
throw new GameException("Failed to decompress natives"); throw new GameException("Failed to decompress natives");
successEvent.execute(loader.makeLaunchingCommand()); HMCLAPI.EVENT_BUS.fireChannel(new LaunchSucceededEvent(this, loader.makeLaunchingCommand()));
return loader;
} }
/** /**
@@ -139,7 +150,7 @@ public class GameLauncher {
.environment().put("APPDATA", service.baseDirectory().getAbsolutePath()); .environment().put("APPDATA", service.baseDirectory().getAbsolutePath());
JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER); JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER);
HMCLog.log("Have started the process"); HMCLog.log("Have started the process");
launchEvent.execute(jp); HMCLAPI.EVENT_BUS.fireChannel(new LaunchEvent(this, jp));
} }
/** /**

View File

@@ -18,7 +18,7 @@
package org.jackhuang.hellominecraft.launcher.core.launch; package org.jackhuang.hellominecraft.launcher.core.launch;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob; import org.jackhuang.hellominecraft.launcher.api.event.launch.DownloadLibraryJob;
import org.jackhuang.hellominecraft.util.net.FileDownloadTask; import org.jackhuang.hellominecraft.util.net.FileDownloadTask;
/** /**

View File

@@ -20,7 +20,7 @@ package org.jackhuang.hellominecraft.launcher.core.service;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob; import org.jackhuang.hellominecraft.launcher.api.event.launch.DownloadLibraryJob;
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
import org.jackhuang.hellominecraft.util.task.Task; import org.jackhuang.hellominecraft.util.task.Task;

View File

@@ -20,9 +20,9 @@ package org.jackhuang.hellominecraft.launcher.core.service;
import java.io.File; import java.io.File;
import java.util.Collection; import java.util.Collection;
import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.version.DecompressLibraryJob; import org.jackhuang.hellominecraft.launcher.api.event.launch.DecompressLibraryJob;
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.util.func.Consumer; import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.func.Predicate; import org.jackhuang.hellominecraft.util.func.Predicate;
@@ -143,10 +143,6 @@ public abstract class IMinecraftProvider {
*/ */
public abstract void refreshVersions(); public abstract void refreshVersions();
public final EventHandler<IMinecraftService> onRefreshingVersions = new EventHandler<>(this),
onRefreshedVersions = new EventHandler<>(this);
public final EventHandler<String> onLoadedVersion = new EventHandler<>(this);
/** /**
* Clean redundant files. * Clean redundant files.
*/ */

View File

@@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hellominecraft.launcher.core.version; package org.jackhuang.hellominecraft.launcher.core.version;
import org.jackhuang.hellominecraft.launcher.api.event.launch.DecompressLibraryJob;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -24,6 +25,10 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.launcher.api.event.version.LoadedOneVersionEvent;
import org.jackhuang.hellominecraft.launcher.api.event.version.RefreshedVersionsEvent;
import org.jackhuang.hellominecraft.launcher.api.event.version.RefreshingVersionsEvent;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.GameException;
@@ -67,7 +72,7 @@ public class MinecraftVersionManager extends IMinecraftProvider {
@Override @Override
public synchronized void refreshVersions() { public synchronized void refreshVersions() {
onRefreshingVersions.execute(service); HMCLAPI.EVENT_BUS.fireChannel(new RefreshingVersionsEvent(this, service));
try { try {
MCUtils.tryWriteProfile(service.baseDirectory()); MCUtils.tryWriteProfile(service.baseDirectory());
@@ -137,12 +142,12 @@ public class MinecraftVersionManager extends IMinecraftProvider {
} }
versions.put(id, mcVersion); versions.put(id, mcVersion);
onLoadedVersion.execute(id); HMCLAPI.EVENT_BUS.fireChannel(new LoadedOneVersionEvent(this, id));
} catch (Exception e) { } catch (Exception e) {
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", e); HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", e);
} }
} }
onRefreshedVersions.execute(service); HMCLAPI.EVENT_BUS.fireChannel(new RefreshedVersionsEvent(this, service));
} }
@Override @Override

View File

@@ -143,10 +143,9 @@ public final class Main implements Runnable {
SupportedLocales.NOW_LOCALE = sl; SupportedLocales.NOW_LOCALE = sl;
Locale.setDefault(sl.self); Locale.setDefault(sl.self);
} }
if (System.getProperty("java.vm.name").contains("Open")) { // OpenJDK if (System.getProperty("java.vm.name").contains("Open")) // OpenJDK
MessageBox.showLocalized("ui.message.open_jdk"); MessageBox.showLocalized("ui.message.open_jdk");
}
try { try {
LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings); LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings);
@@ -155,11 +154,11 @@ public final class Main implements Runnable {
} catch (ParseException | UnsupportedLookAndFeelException ex) { } catch (ParseException | UnsupportedLookAndFeelException ex) {
HMCLog.warn("Failed to set look and feel...", ex); HMCLog.warn("Failed to set look and feel...", ex);
} }
LogWindow.INSTANCE.clean(); LogWindow.INSTANCE.clean();
LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses); LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses);
Settings.UPDATE_CHECKER.outOfDateEvent.register(IUpgrader.NOW_UPGRADER); Settings.UPDATE_CHECKER.upgrade.register(IUpgrader.NOW_UPGRADER);
Settings.UPDATE_CHECKER.process(false).reg(t -> Main.invokeUpdate()).execute(); Settings.UPDATE_CHECKER.process(false).reg(t -> Main.invokeUpdate()).execute();
if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) { if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) {
@@ -175,12 +174,7 @@ public final class Main implements Runnable {
}); });
} }
try { MainFrame.showMainFrame();
PluginManager.plugin().showUI();
} catch (Throwable t) {
new CrashReporter(false).uncaughtException(Thread.currentThread(), t);
System.exit(1);
}
} }
} }

View File

@@ -27,7 +27,10 @@ import java.util.TreeMap;
import java.util.UUID; import java.util.UUID;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.lookandfeel.Theme; import org.jackhuang.hellominecraft.lookandfeel.Theme;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.launcher.api.event.config.AuthenticatorChangedEvent;
import org.jackhuang.hellominecraft.launcher.api.event.config.DownloadTypeChangedEvent;
import org.jackhuang.hellominecraft.launcher.api.event.config.ThemeChangedEvent;
import org.jackhuang.hellominecraft.util.sys.JdkVersion; import org.jackhuang.hellominecraft.util.sys.JdkVersion;
import org.jackhuang.hellominecraft.util.sys.OS; import org.jackhuang.hellominecraft.util.sys.OS;
@@ -78,10 +81,6 @@ public final class Config implements Cloneable {
return java == null ? java = new ArrayList<>() : java; return java == null ? java = new ArrayList<>() : java;
} }
public transient final EventHandler<Theme> themeChangedEvent = new EventHandler<>(this);
public transient final EventHandler<DownloadType> downloadTypeChangedEvent = new EventHandler<>(this);
public transient final EventHandler<IAuthenticator> authChangedEvent = new EventHandler<>(this);
public Theme getTheme() { public Theme getTheme() {
if (theme >= Theme.values().length) if (theme >= Theme.values().length)
theme = 0; theme = 0;
@@ -90,7 +89,7 @@ public final class Config implements Cloneable {
public void setTheme(int theme) { public void setTheme(int theme) {
this.theme = theme; this.theme = theme;
themeChangedEvent.execute(getTheme()); HMCLAPI.EVENT_BUS.fireChannel(new ThemeChangedEvent(this, getTheme()));
Settings.save(); Settings.save();
} }
@@ -171,7 +170,7 @@ public final class Config implements Cloneable {
if (logintype < 0 || logintype >= IAuthenticator.LOGINS.size()) if (logintype < 0 || logintype >= IAuthenticator.LOGINS.size())
return; return;
this.logintype = logintype; this.logintype = logintype;
authChangedEvent.execute(IAuthenticator.LOGINS.get(logintype)); HMCLAPI.EVENT_BUS.fireChannel(new AuthenticatorChangedEvent(this, IAuthenticator.LOGINS.get(logintype)));
Settings.save(); Settings.save();
} }
@@ -181,7 +180,7 @@ public final class Config implements Cloneable {
public void setDownloadType(int downloadtype) { public void setDownloadType(int downloadtype) {
this.downloadtype = downloadtype; this.downloadtype = downloadtype;
downloadTypeChangedEvent.execute(getDownloadSource()); HMCLAPI.EVENT_BUS.fireChannel(new DownloadTypeChangedEvent(this, getDownloadSource()));
Settings.save(); Settings.save();
} }

View File

@@ -21,13 +21,12 @@ import com.google.gson.annotations.SerializedName;
import org.jackhuang.hellominecraft.launcher.util.HMCLGameLauncher; import org.jackhuang.hellominecraft.launcher.util.HMCLGameLauncher;
import org.jackhuang.hellominecraft.launcher.util.HMCLMinecraftService; import org.jackhuang.hellominecraft.launcher.util.HMCLMinecraftService;
import java.io.File; import java.io.File;
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
import org.jackhuang.hellominecraft.launcher.core.MCUtils; import org.jackhuang.hellominecraft.launcher.core.MCUtils;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
import org.jackhuang.hellominecraft.util.sys.IOUtils; import org.jackhuang.hellominecraft.util.sys.IOUtils;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.api.PropertyChangedEvent;
import org.jackhuang.hellominecraft.util.sys.OS; import org.jackhuang.hellominecraft.util.sys.OS;
/** /**
@@ -45,9 +44,9 @@ public final class Profile {
@SerializedName("global") @SerializedName("global")
private VersionSetting global; private VersionSetting global;
private transient IMinecraftService service; private transient HMCLMinecraftService service;
private transient HMCLGameLauncher launcher = new HMCLGameLauncher(this); private transient HMCLGameLauncher launcher = new HMCLGameLauncher(this);
public transient final EventHandler<String> propertyChanged = new EventHandler<>(this); public transient final EventHandler<PropertyChangedEvent<String>> propertyChanged = new EventHandler<>();
public Profile() { public Profile() {
this("Default"); this("Default");
@@ -71,9 +70,9 @@ public final class Profile {
gameDir = v.gameDir; gameDir = v.gameDir;
} }
public IMinecraftService service() { public HMCLMinecraftService service() {
if (service == null) if (service == null)
service = PluginManager.plugin().provideMinecraftService(this); service = new HMCLMinecraftService(this);
return service; return service;
} }
@@ -86,7 +85,7 @@ public final class Profile {
} }
public VersionSetting getVersionSetting(String id) { public VersionSetting getVersionSetting(String id) {
VersionSetting vs = ((HMCLMinecraftService) service()).getVersionSetting(id); VersionSetting vs = service().getVersionSetting(id);
if (vs == null || vs.isUsesGlobal()) { if (vs == null || vs.isUsesGlobal()) {
global.isGlobal = true; global.isGlobal = true;
global.id = id; global.id = id;
@@ -96,23 +95,21 @@ public final class Profile {
} }
public boolean isVersionSettingGlobe(String id) { public boolean isVersionSettingGlobe(String id) {
VersionSetting vs = ((HMCLMinecraftService) service()).getVersionSetting(id); VersionSetting vs = service().getVersionSetting(id);
return vs == null || vs.isUsesGlobal(); return vs == null || vs.isUsesGlobal();
} }
public void makeVersionSettingSpecial(String id) { public void makeVersionSettingSpecial(String id) {
HMCLMinecraftService s = (HMCLMinecraftService) service(); VersionSetting vs = service().getVersionSetting(id);
VersionSetting vs = s.getVersionSetting(id);
if (vs == null) { if (vs == null) {
s.createVersionSetting(id); service().createVersionSetting(id);
vs = s.getVersionSetting(id); vs = service().getVersionSetting(id);
if (vs == null) if (vs == null)
return; return;
vs.setUsesGlobal(false); vs.setUsesGlobal(false);
} else } else
vs.setUsesGlobal(false); vs.setUsesGlobal(false);
propertyChanged.execute("selectedMinecraftVersion"); propertyChanged.fire(new PropertyChangedEvent<>(this, "selectedMinecraftVersion", selectedMinecraftVersion, selectedMinecraftVersion));
selectedVersionChangedEvent.execute(selectedMinecraftVersion);
} }
public void makeVersionSettingGlobal(String id) { public void makeVersionSettingGlobal(String id) {
@@ -121,8 +118,7 @@ public final class Profile {
if (vs == null) if (vs == null)
return; return;
vs.setUsesGlobal(true); vs.setUsesGlobal(true);
propertyChanged.execute("selectedMinecraftVersion"); propertyChanged.fire(new PropertyChangedEvent<>(this, "selectedMinecraftVersion", selectedMinecraftVersion, selectedMinecraftVersion));
selectedVersionChangedEvent.execute(selectedMinecraftVersion);
} }
public String getSettingsSelectedMinecraftVersion() { public String getSettingsSelectedMinecraftVersion() {
@@ -141,12 +137,10 @@ public final class Profile {
return StrUtils.isBlank(v) ? null : v; return StrUtils.isBlank(v) ? null : v;
} }
public transient final EventHandler<String> selectedVersionChangedEvent = new EventHandler<>(this);
public void setSelectedMinecraftVersion(String selectedMinecraftVersion) { public void setSelectedMinecraftVersion(String selectedMinecraftVersion) {
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "selectedMinecraftVersion", this.selectedMinecraftVersion, selectedMinecraftVersion);
this.selectedMinecraftVersion = selectedMinecraftVersion; this.selectedMinecraftVersion = selectedMinecraftVersion;
propertyChanged.execute("selectedMinecraftVersion"); propertyChanged.fire(event);
selectedVersionChangedEvent.execute(selectedMinecraftVersion);
} }
public String getGameDir() { public String getGameDir() {
@@ -168,9 +162,10 @@ public final class Profile {
} }
public Profile setGameDir(String gameDir) { public Profile setGameDir(String gameDir) {
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "gameDir", this.gameDir, gameDir);
this.gameDir = gameDir; this.gameDir = gameDir;
service().version().refreshVersions(); service().version().refreshVersions();
propertyChanged.execute("gameDir"); propertyChanged.fire(event);
return this; return this;
} }
@@ -179,8 +174,9 @@ public final class Profile {
} }
void setName(String name) { void setName(String name) {
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "name", this.name, name);
this.name = name; this.name = name;
propertyChanged.execute("name"); propertyChanged.fire(event);
} }
public void checkFormat() { public void checkFormat() {

View File

@@ -28,7 +28,9 @@ import org.jackhuang.hellominecraft.launcher.Main;
import org.jackhuang.hellominecraft.launcher.core.MCUtils; import org.jackhuang.hellominecraft.launcher.core.MCUtils;
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType; import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
import org.jackhuang.hellominecraft.util.CollectionUtils; import org.jackhuang.hellominecraft.util.CollectionUtils;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.launcher.api.event.config.ProfileChangedEvent;
import org.jackhuang.hellominecraft.launcher.api.event.config.ProfileLoadingEvent;
import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.util.sys.FileUtils;
import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.UpdateChecker; import org.jackhuang.hellominecraft.util.UpdateChecker;
@@ -54,7 +56,6 @@ public final class Settings {
static { static {
SETTINGS = initSettings(); SETTINGS = initSettings();
SETTINGS.downloadTypeChangedEvent.register(DownloadType::setSuggestedDownloadType);
DownloadType.setSuggestedDownloadType(SETTINGS.getDownloadSource()); DownloadType.setSuggestedDownloadType(SETTINGS.getDownloadSource());
if (!getProfiles().containsKey(DEFAULT_PROFILE)) if (!getProfiles().containsKey(DEFAULT_PROFILE))
getProfiles().put(DEFAULT_PROFILE, new Profile(DEFAULT_PROFILE)); getProfiles().put(DEFAULT_PROFILE, new Profile(DEFAULT_PROFILE));
@@ -156,19 +157,16 @@ public final class Settings {
return flag; return flag;
} }
public static final EventHandler<Profile> profileChangedEvent = new EventHandler<>(null);
public static final EventHandler<Void> profileLoadingEvent = new EventHandler<>(null);
static void onProfileChanged() { static void onProfileChanged() {
Profile p = getLastProfile(); Profile p = getLastProfile();
if (p == null) if (p == null)
throw new Error("No profiles here, it should not happen"); throw new Error("No profiles here, it should not happen");
profileChangedEvent.execute(p); HMCLAPI.EVENT_BUS.fireChannel(new ProfileChangedEvent(SETTINGS, p.getName()));
p.onSelected(); p.onSelected();
} }
public static void onProfileLoading() { public static void onProfileLoading() {
profileLoadingEvent.execute(null); HMCLAPI.EVENT_BUS.fireChannel(new ProfileLoadingEvent(SETTINGS));
onProfileChanged(); onProfileChanged();
} }
} }

View File

@@ -25,7 +25,8 @@ import org.jackhuang.hellominecraft.launcher.util.LauncherVisibility;
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions; import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions;
import org.jackhuang.hellominecraft.launcher.core.version.GameDirType; import org.jackhuang.hellominecraft.launcher.core.version.GameDirType;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.api.PropertyChangedEvent;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
import org.jackhuang.hellominecraft.util.sys.Java; import org.jackhuang.hellominecraft.util.sys.Java;
@@ -87,7 +88,7 @@ public class VersionSetting {
@SerializedName("gameDirType") @SerializedName("gameDirType")
private int gameDirType; private int gameDirType;
public transient final EventHandler<String> propertyChanged = new EventHandler<>(this); public transient final EventHandler<PropertyChangedEvent> propertyChanged = new EventHandler<>();
public VersionSetting() { public VersionSetting() {
fullscreen = usesGlobal = false; fullscreen = usesGlobal = false;
@@ -113,8 +114,9 @@ public class VersionSetting {
} }
public void setJavaDir(String javaDir) { public void setJavaDir(String javaDir) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "javaDir", this.javaDir, javaDir);
this.javaDir = javaDir; this.javaDir = javaDir;
propertyChanged.execute("javaDir"); propertyChanged.fire(event);
} }
public Java getJava() { public Java getJava() {
@@ -133,6 +135,7 @@ public class VersionSetting {
} }
public void setJava(Java java) { public void setJava(Java java) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "java", this.java, java);
if (java == null) if (java == null)
this.java = Java.JAVA.get(0).getName(); this.java = Java.JAVA.get(0).getName();
else { else {
@@ -141,7 +144,7 @@ public class VersionSetting {
return; return;
this.java = java.getName(); this.java = java.getName();
} }
propertyChanged.execute("java"); propertyChanged.fire(event);
} }
public String getJavaArgs() { public String getJavaArgs() {
@@ -151,8 +154,9 @@ public class VersionSetting {
} }
public void setJavaArgs(String javaArgs) { public void setJavaArgs(String javaArgs) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "javaArgs", this.javaArgs, javaArgs);
this.javaArgs = javaArgs; this.javaArgs = javaArgs;
propertyChanged.execute("javaArgs"); propertyChanged.fire(event);
} }
public String getMaxMemory() { public String getMaxMemory() {
@@ -162,8 +166,9 @@ public class VersionSetting {
} }
public void setMaxMemory(String maxMemory) { public void setMaxMemory(String maxMemory) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "maxMemory", this.maxMemory, maxMemory);
this.maxMemory = maxMemory; this.maxMemory = maxMemory;
propertyChanged.execute("maxMemory"); propertyChanged.fire(event);
} }
public String getWidth() { public String getWidth() {
@@ -173,8 +178,9 @@ public class VersionSetting {
} }
public void setWidth(String width) { public void setWidth(String width) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "width", this.width, width);
this.width = width; this.width = width;
propertyChanged.execute("width"); propertyChanged.fire(event);
} }
public String getHeight() { public String getHeight() {
@@ -184,8 +190,9 @@ public class VersionSetting {
} }
public void setHeight(String height) { public void setHeight(String height) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "height", this.height, height);
this.height = height; this.height = height;
propertyChanged.execute("height"); propertyChanged.fire(event);
} }
public boolean isFullscreen() { public boolean isFullscreen() {
@@ -193,8 +200,9 @@ public class VersionSetting {
} }
public void setFullscreen(boolean fullscreen) { public void setFullscreen(boolean fullscreen) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "fullscreen", this.fullscreen, fullscreen);
this.fullscreen = fullscreen; this.fullscreen = fullscreen;
propertyChanged.execute("fullscreen"); propertyChanged.fire(event);
} }
public LauncherVisibility getLauncherVisibility() { public LauncherVisibility getLauncherVisibility() {
@@ -202,8 +210,9 @@ public class VersionSetting {
} }
public void setLauncherVisibility(LauncherVisibility launcherVisibility) { public void setLauncherVisibility(LauncherVisibility launcherVisibility) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "launcherVisibility", this.launcherVisibility, launcherVisibility);
this.launcherVisibility = launcherVisibility.ordinal(); this.launcherVisibility = launcherVisibility.ordinal();
propertyChanged.execute("launcherVisibility"); propertyChanged.fire(event);
} }
public GameDirType getGameDirType() { public GameDirType getGameDirType() {
@@ -213,8 +222,9 @@ public class VersionSetting {
} }
public void setGameDirType(GameDirType gameDirType) { public void setGameDirType(GameDirType gameDirType) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "gameDirType", this.gameDirType, gameDirType);
this.gameDirType = gameDirType.ordinal(); this.gameDirType = gameDirType.ordinal();
propertyChanged.execute("gameDirType"); propertyChanged.fire(event);
} }
public String getPermSize() { public String getPermSize() {
@@ -222,8 +232,9 @@ public class VersionSetting {
} }
public void setPermSize(String permSize) { public void setPermSize(String permSize) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "permSize", this.permSize, permSize);
this.permSize = permSize; this.permSize = permSize;
propertyChanged.execute("permSize"); propertyChanged.fire(event);
} }
public boolean isNoJVMArgs() { public boolean isNoJVMArgs() {
@@ -231,8 +242,9 @@ public class VersionSetting {
} }
public void setNoJVMArgs(boolean noJVMArgs) { public void setNoJVMArgs(boolean noJVMArgs) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "noJVMArgs", this.noJVMArgs, noJVMArgs);
this.noJVMArgs = noJVMArgs; this.noJVMArgs = noJVMArgs;
propertyChanged.execute("noJVMArgs"); propertyChanged.fire(event);
} }
public String getMinecraftArgs() { public String getMinecraftArgs() {
@@ -240,8 +252,9 @@ public class VersionSetting {
} }
public void setMinecraftArgs(String minecraftArgs) { public void setMinecraftArgs(String minecraftArgs) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "minecraftArgs", this.minecraftArgs, minecraftArgs);
this.minecraftArgs = minecraftArgs; this.minecraftArgs = minecraftArgs;
propertyChanged.execute("minecraftArgs"); propertyChanged.fire(event);
} }
public String getPrecalledCommand() { public String getPrecalledCommand() {
@@ -249,8 +262,9 @@ public class VersionSetting {
} }
public void setPrecalledCommand(String precalledCommand) { public void setPrecalledCommand(String precalledCommand) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "precalledCommand", this.precalledCommand, precalledCommand);
this.precalledCommand = precalledCommand; this.precalledCommand = precalledCommand;
propertyChanged.execute("precalledCommand"); propertyChanged.fire(event);
} }
public String getWrapper() { public String getWrapper() {
@@ -258,8 +272,9 @@ public class VersionSetting {
} }
public void setWrapper(String wrapper) { public void setWrapper(String wrapper) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "wrapper", this.wrapper, wrapper);
this.wrapper = wrapper; this.wrapper = wrapper;
propertyChanged.execute("wrapper"); propertyChanged.fire(event);
} }
public String getServerIp() { public String getServerIp() {
@@ -267,8 +282,9 @@ public class VersionSetting {
} }
public void setServerIp(String serverIp) { public void setServerIp(String serverIp) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "serverIp", this.serverIp, serverIp);
this.serverIp = serverIp; this.serverIp = serverIp;
propertyChanged.execute("serverIp"); propertyChanged.fire(event);
} }
public boolean isNotCheckGame() { public boolean isNotCheckGame() {
@@ -276,8 +292,9 @@ public class VersionSetting {
} }
public void setNotCheckGame(boolean notCheckGame) { public void setNotCheckGame(boolean notCheckGame) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "notCheckGame", this.notCheckGame, notCheckGame);
this.notCheckGame = notCheckGame; this.notCheckGame = notCheckGame;
propertyChanged.execute("notCheckGame"); propertyChanged.fire(event);
} }
public boolean isUsesGlobal() { public boolean isUsesGlobal() {
@@ -285,8 +302,9 @@ public class VersionSetting {
} }
public void setUsesGlobal(boolean usesGlobal) { public void setUsesGlobal(boolean usesGlobal) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "usesGlobal", this.usesGlobal, usesGlobal);
this.usesGlobal = usesGlobal; this.usesGlobal = usesGlobal;
propertyChanged.execute("usesGlobal"); propertyChanged.fire(event);
} }
public LaunchOptions createLaunchOptions(File gameDir) { public LaunchOptions createLaunchOptions(File gameDir) {

View File

@@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hellominecraft.launcher.ui; package org.jackhuang.hellominecraft.launcher.ui;
import org.jackhuang.hellominecraft.util.ui.Page;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;
import org.jackhuang.hellominecraft.launcher.core.download.MinecraftRemoteVersions; import org.jackhuang.hellominecraft.launcher.core.download.MinecraftRemoteVersions;
import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.launcher.setting.Settings;

View File

@@ -52,7 +52,7 @@
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<Component id="pnlTop" min="-2" max="-2" attributes="0"/> <Component id="pnlTop" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="tabVersionEdit" pref="309" max="32767" attributes="0"/> <Component id="tabVersionEdit" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0"> <Group type="103" groupAlignment="3" attributes="0">
<Component id="btnTestGame" alignment="3" min="-2" max="-2" attributes="0"/> <Component id="btnTestGame" alignment="3" min="-2" max="-2" attributes="0"/>

View File

@@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hellominecraft.launcher.ui; package org.jackhuang.hellominecraft.launcher.ui;
import org.jackhuang.hellominecraft.util.ui.Page;
import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable; import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.datatransfer.UnsupportedFlavorException;
@@ -37,10 +38,15 @@ import javax.swing.DefaultComboBoxModel;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelEvent;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;
import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.launcher.api.event.config.ProfileChangedEvent;
import org.jackhuang.hellominecraft.launcher.api.event.config.ProfileLoadingEvent;
import org.jackhuang.hellominecraft.launcher.api.event.version.RefreshedVersionsEvent;
import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
@@ -50,13 +56,11 @@ import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.launcher.util.FileNameFilter; import org.jackhuang.hellominecraft.launcher.util.FileNameFilter;
import org.jackhuang.hellominecraft.launcher.core.mod.ModInfo; import org.jackhuang.hellominecraft.launcher.core.mod.ModInfo;
import org.jackhuang.hellominecraft.launcher.core.install.InstallerType; import org.jackhuang.hellominecraft.launcher.core.install.InstallerType;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.core.version.GameDirType; import org.jackhuang.hellominecraft.launcher.core.version.GameDirType;
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
import org.jackhuang.hellominecraft.launcher.setting.VersionSetting; import org.jackhuang.hellominecraft.launcher.setting.VersionSetting;
import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.AbstractSwingWorker; import org.jackhuang.hellominecraft.util.AbstractSwingWorker;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.util.MinecraftVersionRequest; import org.jackhuang.hellominecraft.util.MinecraftVersionRequest;
import org.jackhuang.hellominecraft.util.sys.OS; import org.jackhuang.hellominecraft.util.sys.OS;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;
@@ -75,15 +79,24 @@ import org.jackhuang.hellominecraft.util.ui.LogWindow;
public final class GameSettingsPanel extends RepaintPage implements DropTargetListener { public final class GameSettingsPanel extends RepaintPage implements DropTargetListener {
boolean isLoading = false; boolean isLoading = false;
boolean showedNoVersion = false;
public MinecraftVersionRequest minecraftVersion; public MinecraftVersionRequest minecraftVersion;
String mcVersion; String mcVersion;
final InstallerPanel installerPanels[] = new InstallerPanel[InstallerType.values().length]; final InstallerPanel installerPanels[] = new InstallerPanel[InstallerType.values().length];
public GameSettingsPanel(MainFrame mf) { public GameSettingsPanel() {
mf.actions.put("showGameDownloads", () -> { HMCLAPI.EVENT_BUS.channel(RefreshedVersionsEvent.class).register(t -> {
MainFrame.INSTANCE.selectTab("game"); if (Settings.getLastProfile().service() == t.getValue())
showGameDownloads(); if (!showedNoVersion && Settings.getLastProfile().service().checkingModpack) {
showedNoVersion = true;
SwingUtilities.invokeLater(() -> {
if (MessageBox.show(C.i18n("mainwindow.no_version"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
MainFrame.INSTANCE.selectTab("game");
showGameDownloads();
}
});
}
}); });
setRepainter(this); setRepainter(this);
@@ -92,6 +105,8 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
void initGui() { void initGui() {
initComponents(); initComponents();
animationEnabled = Settings.getInstance().isEnableAnimation();
dropTarget = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this); dropTarget = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
for (int i = 0; i < InstallerType.values().length; i++) for (int i = 0; i < InstallerType.values().length; i++)
@@ -108,8 +123,9 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
cboJava.addItem(j.getLocalizedName()); cboJava.addItem(j.getLocalizedName());
isLoading = false; isLoading = false;
Settings.profileLoadingEvent.register(onLoadingProfiles); HMCLAPI.EVENT_BUS.channel(ProfileLoadingEvent.class).register(onLoadingProfiles);
Settings.profileChangedEvent.register(onSelectedProfilesChanged); HMCLAPI.EVENT_BUS.channel(ProfileChangedEvent.class).register(onSelectedProfilesChanged);
HMCLAPI.EVENT_BUS.channel(RefreshedVersionsEvent.class).register(onRefreshedVersions);
} }
void initExplorationMenu() { void initExplorationMenu() {
@@ -1437,8 +1453,8 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
isLoading = false; isLoading = false;
} }
final Consumer<IMinecraftService> onRefreshedVersions = t -> { final Consumer<RefreshedVersionsEvent> onRefreshedVersions = t -> {
if (Settings.getLastProfile().service() == t) if (Settings.getLastProfile().service() == t.getValue())
loadVersions(); loadVersions();
}; };
@@ -1451,11 +1467,9 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
} }
cboVersions.setModel(model); cboVersions.setModel(model);
if (Settings.getLastProfile().getSelectedVersion() != null) if (Settings.getLastProfile().getSelectedVersion() != null)
selectedVersionChangedEvent.accept(Settings.getLastProfile().getSelectedVersion()); versionChanged(Settings.getLastProfile().getSelectedVersion());
} }
final Consumer<String> selectedVersionChangedEvent = this::versionChanged;
public void versionChanged(String version) { public void versionChanged(String version) {
isLoading = true; isLoading = true;
DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) cboVersions.getModel(); DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) cboVersions.getModel();
@@ -1477,9 +1491,12 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
isLoading = false; isLoading = false;
} }
final Consumer<Profile> onSelectedProfilesChanged = t -> { final Consumer<ProfileChangedEvent> onSelectedProfilesChanged = event -> {
t.service().version().onRefreshedVersions.register(onRefreshedVersions); Profile t = Settings.getProfile(event.getValue());
t.selectedVersionChangedEvent.register(selectedVersionChangedEvent); t.propertyChanged.register(e -> {
if ("selectedMinecraftVersion".equals(e.getPropertyName()))
versionChanged(e.getNewValue());
});
txtGameDir.setText(t.getGameDir()); txtGameDir.setText(t.getGameDir());

View File

@@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hellominecraft.launcher.ui; package org.jackhuang.hellominecraft.launcher.ui;
import org.jackhuang.hellominecraft.util.ui.Page;
import java.util.List; import java.util.List;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;

View File

@@ -45,6 +45,8 @@ public class LauncherSettingsPanel extends RepaintPage {
void initGui() { void initGui() {
initComponents(); initComponents();
animationEnabled = Settings.getInstance().isEnableAnimation();
DefaultComboBoxModel<String> d = new DefaultComboBoxModel<>(); DefaultComboBoxModel<String> d = new DefaultComboBoxModel<>();
for (DownloadType type : DownloadType.values()) for (DownloadType type : DownloadType.values())

View File

@@ -19,16 +19,21 @@ package org.jackhuang.hellominecraft.launcher.ui;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.api.event.process.JVMLaunchFailedEvent;
import org.jackhuang.hellominecraft.api.event.process.JavaProcessExitedAbnormallyEvent;
import org.jackhuang.hellominecraft.api.event.process.JavaProcessStoppedEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchSucceededEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchingStateChangedEvent;
import org.jackhuang.hellominecraft.launcher.util.LauncherVisibility; import org.jackhuang.hellominecraft.launcher.util.LauncherVisibility;
import org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher; import org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher;
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchingState;
import org.jackhuang.hellominecraft.launcher.setting.Profile; import org.jackhuang.hellominecraft.launcher.setting.Profile;
import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.launcher.util.HMCLGameLauncher;
import org.jackhuang.hellominecraft.launcher.util.MinecraftCrashAdvicer; import org.jackhuang.hellominecraft.launcher.util.MinecraftCrashAdvicer;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.util.MessageBox; import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.func.Consumer; import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
@@ -43,118 +48,127 @@ import org.jackhuang.hellominecraft.util.net.WebFrame;
*/ */
public class LaunchingUIDaemon { public class LaunchingUIDaemon {
Runnable customizedSuccessEvent = null; public LaunchingUIDaemon() {
HMCLAPI.EVENT_BUS.channel(LaunchingStateChangedEvent.class).register(LAUNCHING_STATE_CHANGED);
void runGame(Profile profile) { HMCLAPI.EVENT_BUS.channel(LaunchEvent.class).register(p -> {
MainFrame.INSTANCE.showMessage(C.i18n("ui.message.launching")); GameLauncher obj = (GameLauncher) p.getSource();
profile.launcher().genLaunchCode(value -> { HMCLGameLauncher.GameLauncherTag tag = (HMCLGameLauncher.GameLauncherTag) obj.getTag();
value.launchingStateChangedEvent.register(LAUNCHING_STATE_CHANGED); if (tag.launcherVisibility == LauncherVisibility.CLOSE && !LogWindow.INSTANCE.isVisible()) {
value.successEvent.register(LAUNCH_FINISHER);
value.successEvent.register(customizedSuccessEvent);
}, MainFrame.INSTANCE::failed, Settings.getInstance().getAuthenticator().getPassword());
}
void makeLaunchScript(Profile profile) {
MainFrame.INSTANCE.showMessage(C.i18n("ui.message.launching"));
profile.launcher().genLaunchCode(value -> {
value.launchingStateChangedEvent.register(LAUNCHING_STATE_CHANGED);
value.successEvent.register(LAUNCH_SCRIPT_FINISHER);
value.successEvent.register(customizedSuccessEvent);
}, MainFrame.INSTANCE::failed, Settings.getInstance().getAuthenticator().getPassword());
}
private static final Consumer<LaunchingState> LAUNCHING_STATE_CHANGED = t -> {
String message = null;
switch (t) {
case LoggingIn:
message = "launch.state.logging_in";
break;
case GeneratingLaunchingCodes:
message = "launch.state.generating_launching_codes";
break;
case DownloadingLibraries:
message = "launch.state.downloading_libraries";
break;
case DecompressingNatives:
message = "launch.state.decompressing_natives";
break;
}
MainFrame.INSTANCE.showMessage(C.i18n(message));
};
private static final Event<List<String>> LAUNCH_FINISHER = (sender, str) -> {
final GameLauncher obj = (GameLauncher) sender;
obj.launchEvent.register(p -> {
if ((LauncherVisibility) obj.getTag() == LauncherVisibility.CLOSE && !LogWindow.INSTANCE.isVisible()) {
HMCLog.log("Without the option of keeping the launcher visible, this application will exit and will NOT catch game logs, but you can turn on \"Debug Mode\"."); HMCLog.log("Without the option of keeping the launcher visible, this application will exit and will NOT catch game logs, but you can turn on \"Debug Mode\".");
System.exit(0); System.exit(0);
} else if ((LauncherVisibility) obj.getTag() == LauncherVisibility.KEEP) } else if (tag.launcherVisibility == LauncherVisibility.KEEP)
MainFrame.INSTANCE.closeMessage(); MainFrame.INSTANCE.closeMessage();
else { else {
if (LogWindow.INSTANCE.isVisible()) if (LogWindow.INSTANCE.isVisible())
LogWindow.INSTANCE.setExit(() -> true); LogWindow.INSTANCE.setExit(() -> true);
MainFrame.INSTANCE.dispose(); MainFrame.INSTANCE.dispose();
} }
JavaProcessMonitor jpm = new JavaProcessMonitor(p); // We promise that JavaProcessMonitor.tag is LauncherVisibility
jpm.applicationExitedAbnormallyEvent.register(t -> { // See events below.
HMCLog.err("The game exited abnormally, exit code: " + t); JavaProcessMonitor monitor = new JavaProcessMonitor(p.getValue());
String[] logs = jpm.getJavaProcess().getStdOutLines().toArray(new String[0]); monitor.setTag(tag.launcherVisibility);
String errorText = null; monitor.start();
for (String s : logs) {
int pos = s.lastIndexOf("#@!@#");
if (pos >= 0 && pos < s.length() - "#@!@#".length() - 1) {
errorText = s.substring(pos + "#@!@#".length()).trim();
break;
}
}
String msg = C.i18n("launch.exited_abnormally") + " exit code: " + t;
if (errorText != null)
msg += ", advice: " + MinecraftCrashAdvicer.getAdvice(FileUtils.readQuietly(new File(errorText)));
WebFrame f = new WebFrame(logs);
f.setModal(true);
f.setTitle(msg);
f.setVisible(true);
checkExit((LauncherVisibility) obj.getTag());
});
jpm.jvmLaunchFailedEvent.register(t -> {
HMCLog.err("Cannot create jvm, exit code: " + t);
WebFrame f = new WebFrame(jpm.getJavaProcess().getStdOutLines().toArray(new String[0]));
f.setModal(true);
f.setTitle(C.i18n("launch.cannot_create_jvm") + " exit code: " + t);
f.setVisible(true);
checkExit((LauncherVisibility) obj.getTag());
});
jpm.stoppedEvent.register(() -> checkExit((LauncherVisibility) obj.getTag()));
jpm.start();
}); });
HMCLAPI.EVENT_BUS.channel(LaunchSucceededEvent.class).register(p -> {
int state = ((HMCLGameLauncher.GameLauncherTag) ((GameLauncher) p.getSource()).getTag()).state;
if (state == 1)
LAUNCH_FINISHER.accept(p);
else if (state == 2)
LAUNCH_SCRIPT_FINISHER.accept(p);
});
HMCLAPI.EVENT_BUS.channel(JavaProcessStoppedEvent.class).register(event -> checkExit((LauncherVisibility) ((JavaProcessMonitor) event.getSource()).getTag()));
HMCLAPI.EVENT_BUS.channel(JavaProcessExitedAbnormallyEvent.class).register(event -> {
int exitCode = event.getValue().getExitCode();
HMCLog.err("The game exited abnormally, exit code: " + exitCode);
String[] logs = event.getValue().getStdOutLines().toArray(new String[0]);
String errorText = null;
for (String s : logs) {
int pos = s.lastIndexOf("#@!@#");
if (pos >= 0 && pos < s.length() - "#@!@#".length() - 1) {
errorText = s.substring(pos + "#@!@#".length()).trim();
break;
}
}
String msg = C.i18n("launch.exited_abnormally") + " exit code: " + exitCode;
if (errorText != null)
msg += ", advice: " + MinecraftCrashAdvicer.getAdvice(FileUtils.readQuietly(new File(errorText)));
WebFrame f = new WebFrame(logs);
f.setModal(true);
f.setTitle(msg);
f.setVisible(true);
checkExit((LauncherVisibility) ((JavaProcessMonitor) event.getSource()).getTag());
});
HMCLAPI.EVENT_BUS.channel(JVMLaunchFailedEvent.class).register(event -> {
int exitCode = event.getValue().getExitCode();
HMCLog.err("Cannot create jvm, exit code: " + exitCode);
WebFrame f = new WebFrame(event.getValue().getStdOutLines().toArray(new String[0]));
f.setModal(true);
f.setTitle(C.i18n("launch.cannot_create_jvm") + " exit code: " + exitCode);
f.setVisible(true);
checkExit((LauncherVisibility) ((JavaProcessMonitor) event.getSource()).getTag());
});
}
void runGame(Profile profile) {
MainFrame.INSTANCE.showMessage(C.i18n("ui.message.launching"));
profile.launcher().genLaunchCode(value -> {
((HMCLGameLauncher.GameLauncherTag) value.getTag()).state = 1;
}, MainFrame.INSTANCE::failed, Settings.getInstance().getAuthenticator().getPassword());
}
void makeLaunchScript(Profile profile) {
MainFrame.INSTANCE.showMessage(C.i18n("ui.message.launching"));
profile.launcher().genLaunchCode(value -> {
((HMCLGameLauncher.GameLauncherTag) value.getTag()).state = 2;
}, MainFrame.INSTANCE::failed, Settings.getInstance().getAuthenticator().getPassword());
}
private static final Consumer<LaunchingStateChangedEvent> LAUNCHING_STATE_CHANGED = t -> {
String message = null;
switch (t.getValue()) {
case LoggingIn:
message = "launch.state.logging_in";
break;
case GeneratingLaunchingCodes:
message = "launch.state.generating_launching_codes";
break;
case DownloadingLibraries:
message = "launch.state.downloading_libraries";
break;
case DecompressingNatives:
message = "launch.state.decompressing_natives";
break;
}
MainFrame.INSTANCE.showMessage(C.i18n(message));
};
private static final Consumer<LaunchSucceededEvent> LAUNCH_FINISHER = event -> {
try { try {
obj.launch(str); ((GameLauncher) event.getSource()).launch(event.getValue());
} catch (IOException e) { } catch (IOException e) {
MainFrame.INSTANCE.failed(C.i18n("launch.failed_creating_process") + "\n" + e.getMessage()); MainFrame.INSTANCE.failed(C.i18n("launch.failed_creating_process") + "\n" + e.getMessage());
HMCLog.err("Failed to launch when creating a new process.", e); HMCLog.err("Failed to launch when creating a new process.", e);
} }
return true;
}; };
private static void checkExit(LauncherVisibility v) { private static void checkExit(LauncherVisibility v) {
if (v != LauncherVisibility.KEEP && !LogWindow.INSTANCE.isVisible()) { if (v != LauncherVisibility.KEEP && !LogWindow.INSTANCE.isVisible()) {
HMCLog.log("Launcher will exit now."); HMCLog.log("Launcher will exit now.");
System.exit(0); System.exit(0);
} else {
HMCLog.log("Launcher will not exit now.");
} }
} }
private static final Event<List<String>> LAUNCH_SCRIPT_FINISHER = (sender, str) -> { private static final Consumer<LaunchSucceededEvent> LAUNCH_SCRIPT_FINISHER = event -> {
boolean flag = false;
try { try {
String s = JOptionPane.showInputDialog(C.i18n("mainwindow.enter_script_name")); String s = JOptionPane.showInputDialog(C.i18n("mainwindow.enter_script_name"));
if (s != null) if (s != null)
MessageBox.show(C.i18n("mainwindow.make_launch_succeed") + " " + ((GameLauncher) sender).makeLauncher(s, str).getAbsolutePath()); MessageBox.show(C.i18n("mainwindow.make_launch_succeed") + " " + ((GameLauncher) event.getSource()).makeLauncher(s, event.getValue()).getAbsolutePath());
flag = true;
} catch (IOException ex) { } catch (IOException ex) {
MessageBox.show(C.i18n("mainwindow.make_launch_script_failed")); MessageBox.show(C.i18n("mainwindow.make_launch_script_failed"));
HMCLog.err("Failed to create script file.", ex); HMCLog.err("Failed to create script file.", ex);
} }
MainFrame.INSTANCE.closeMessage(); MainFrame.INSTANCE.closeMessage();
return flag;
}; };
} }

View File

@@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hellominecraft.launcher.ui; package org.jackhuang.hellominecraft.launcher.ui;
import org.jackhuang.hellominecraft.util.ui.Page;
import org.jackhuang.hellominecraft.util.ui.GaussionPanel; import org.jackhuang.hellominecraft.util.ui.GaussionPanel;
import org.jackhuang.hellominecraft.util.ui.IRepaint; import org.jackhuang.hellominecraft.util.ui.IRepaint;
import java.awt.BorderLayout; import java.awt.BorderLayout;
@@ -50,7 +51,10 @@ import javax.swing.JComponent;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.launcher.Main; import org.jackhuang.hellominecraft.launcher.Main;
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
import org.jackhuang.hellominecraft.launcher.api.event.config.ThemeChangedEvent;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.lookandfeel.Theme; import org.jackhuang.hellominecraft.lookandfeel.Theme;
@@ -155,7 +159,7 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
} }
((JPanel) getContentPane()).setOpaque(true); ((JPanel) getContentPane()).setOpaque(true);
Settings.getInstance().themeChangedEvent.register(this::reloadColor); HMCLAPI.EVENT_BUS.channel(ThemeChangedEvent.class).register(x -> reloadColor(x.getValue()));
SwingUtilities.invokeLater(() -> selectTab("main")); SwingUtilities.invokeLater(() -> selectTab("main"));
} }
@@ -185,9 +189,7 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
header.add(Box.createRigidArea(new Dimension(8, 0))); header.add(Box.createRigidArea(new Dimension(8, 0)));
initializeTab(new MainPagePanel(), "main"); PluginManager.fireAddTab(this, this::initializeTab);
initializeTab(new GameSettingsPanel(this), "game");
initializeTab(new LauncherSettingsPanel(), "launcher");
header.add(Box.createHorizontalGlue()); header.add(Box.createHorizontalGlue());
@@ -258,8 +260,8 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
private transient final ActionListener tabListener = e -> MainFrame.this.selectTab(e.getActionCommand()); private transient final ActionListener tabListener = e -> MainFrame.this.selectTab(e.getActionCommand());
private void initializeTab(Page inst, String cmd) { private void initializeTab(Page inst, String cmd, String title) {
HeaderTab tab = new HeaderTab(C.i18n("launcher.title." + cmd)); HeaderTab tab = new HeaderTab(title);
tab.setActionCommand(cmd); tab.setActionCommand(cmd);
tab.setForeground(BasicColors.COLOR_WHITE_TEXT); tab.setForeground(BasicColors.COLOR_WHITE_TEXT);
tab.setBackground(borderColorDarker); tab.setBackground(borderColorDarker);
@@ -489,9 +491,4 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
} }
transient LaunchingUIDaemon daemon = new LaunchingUIDaemon(); transient LaunchingUIDaemon daemon = new LaunchingUIDaemon();
transient final HashMap<String, Runnable> actions = new HashMap<>();
void invokeAction(String name) {
if (actions.containsKey(name))
actions.get(name).run();
}
} }

View File

@@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hellominecraft.launcher.ui; package org.jackhuang.hellominecraft.launcher.ui;
import org.jackhuang.hellominecraft.util.ui.Page;
import org.jackhuang.hellominecraft.util.ui.WideComboBox; import org.jackhuang.hellominecraft.util.ui.WideComboBox;
import org.jackhuang.hellominecraft.util.ui.GaussionPanel; import org.jackhuang.hellominecraft.util.ui.GaussionPanel;
import java.awt.CardLayout; import java.awt.CardLayout;
@@ -28,18 +29,22 @@ import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;
import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.launcher.api.event.config.AuthenticatorChangedEvent;
import org.jackhuang.hellominecraft.launcher.api.event.config.ProfileChangedEvent;
import org.jackhuang.hellominecraft.launcher.api.event.config.ProfileLoadingEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchSucceededEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchingState;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchingStateChangedEvent;
import org.jackhuang.hellominecraft.launcher.api.event.version.RefreshedVersionsEvent;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.launcher.setting.Profile; import org.jackhuang.hellominecraft.launcher.setting.Profile;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion; import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.launcher.core.mod.ModpackManager; import org.jackhuang.hellominecraft.launcher.core.mod.ModpackManager;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.ui.modpack.ModpackWizard; import org.jackhuang.hellominecraft.launcher.ui.modpack.ModpackWizard;
import org.jackhuang.hellominecraft.launcher.util.HMCLMinecraftService;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.lookandfeel.ConstomButton; import org.jackhuang.hellominecraft.lookandfeel.ConstomButton;
import org.jackhuang.hellominecraft.util.func.Consumer; import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.sys.FileUtils; import org.jackhuang.hellominecraft.util.sys.FileUtils;
@@ -60,7 +65,7 @@ public class MainPagePanel extends Page {
void initGui() { void initGui() {
initComponents(); initComponents();
animationEnabled = false; animationEnabled = false;
pnlButtons = new javax.swing.JPanel(); pnlButtons = new javax.swing.JPanel();
@@ -86,19 +91,20 @@ public class MainPagePanel extends Page {
pnlMore.setBackground(GraphicsUtils.getWebColorWithAlpha("FFFFFF7F")); pnlMore.setBackground(GraphicsUtils.getWebColorWithAlpha("FFFFFF7F"));
pnlMore.setOpaque(true); pnlMore.setOpaque(true);
Settings.getInstance().authChangedEvent.register(onAuthChanged);
Settings.profileLoadingEvent.register(onLoadingProfiles);
Settings.profileChangedEvent.register(onSelectedProfilesChanged);
MainFrame.INSTANCE.daemon.customizedSuccessEvent = this::prepareAuths;
prepareAuths();
if (Settings.getInstance().isEnableBlur()) if (Settings.getInstance().isEnableBlur())
((GaussionPanel) pnlRoot).addAeroObject(pnlMore); ((GaussionPanel) pnlRoot).addAeroObject(pnlMore);
((GaussionPanel) pnlRoot).setBackgroundImage(MainFrame.INSTANCE.background.getImage()); ((GaussionPanel) pnlRoot).setBackgroundImage(MainFrame.INSTANCE.background.getImage());
((RepaintPage) pnlMore).setRepainter(pnlRoot); ((RepaintPage) pnlMore).setRepainter(pnlRoot);
HMCLAPI.EVENT_BUS.channel(AuthenticatorChangedEvent.class).register(onAuthChanged);
HMCLAPI.EVENT_BUS.channel(ProfileLoadingEvent.class).register(onLoadingProfiles);
HMCLAPI.EVENT_BUS.channel(ProfileChangedEvent.class).register(onSelectedProfilesChanged);
HMCLAPI.EVENT_BUS.channel(RefreshedVersionsEvent.class).register(onRefreshedVersions);
HMCLAPI.EVENT_BUS.channel(LaunchingStateChangedEvent.class).register(launchingStateChanged);
HMCLAPI.EVENT_BUS.channel(LaunchSucceededEvent.class).register(this::prepareAuths);
prepareAuths();
} }
/** /**
@@ -409,7 +415,6 @@ public class MainPagePanel extends Page {
}//GEN-LAST:event_txtPasswordCaretUpdate }//GEN-LAST:event_txtPasswordCaretUpdate
// <editor-fold defaultstate="collapsed" desc="Loads"> // <editor-fold defaultstate="collapsed" desc="Loads">
private void prepareAuths() { private void prepareAuths() {
preparingAuth = true; preparingAuth = true;
cboLoginMode.removeAllItems(); cboLoginMode.removeAllItems();
@@ -460,8 +465,8 @@ public class MainPagePanel extends Page {
private javax.swing.JTextField txtPlayerName; private javax.swing.JTextField txtPlayerName;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
final Event<IAuthenticator> onAuthChanged = (sender, l) -> { final Consumer<AuthenticatorChangedEvent> onAuthChanged = (x) -> {
if (l.hasPassword()) { if (x.getValue().hasPassword()) {
pnlPassword.setVisible(true); pnlPassword.setVisible(true);
lblUserName.setText(C.i18n("login.account")); lblUserName.setText(C.i18n("login.account"));
} else { } else {
@@ -470,16 +475,14 @@ public class MainPagePanel extends Page {
} }
CardLayout cl = (CardLayout) pnlPassword.getLayout(); CardLayout cl = (CardLayout) pnlPassword.getLayout();
if (l.isLoggedIn()) if (x.getValue().isLoggedIn())
cl.last(pnlPassword); cl.last(pnlPassword);
else else
cl.first(pnlPassword); cl.first(pnlPassword);
String username = l.getUserName(); String username = x.getValue().getUserName();
if (username == null) if (username == null)
username = ""; username = "";
txtPlayerName.setText(username); txtPlayerName.setText(username);
return true;
}; };
final Runnable onLoadingProfiles = () -> { final Runnable onLoadingProfiles = () -> {
@@ -491,8 +494,8 @@ public class MainPagePanel extends Page {
isLoading = false; isLoading = false;
}; };
final Consumer<IMinecraftService> onRefreshedVersions = t -> { final Consumer<RefreshedVersionsEvent> onRefreshedVersions = t -> {
if (Settings.getLastProfile().service() == t) if (Settings.getLastProfile().service() == t.getValue())
loadVersions(); loadVersions();
}; };
@@ -502,28 +505,18 @@ public class MainPagePanel extends Page {
isLoading = true; isLoading = true;
cboVersions.removeAllItems(); cboVersions.removeAllItems();
String selVersion = Settings.getLastProfile().getSelectedVersion(); String selVersion = Settings.getLastProfile().getSelectedVersion();
if (Settings.getLastProfile().service().version().getVersions().isEmpty()) { if (!Settings.getLastProfile().service().version().getVersions().isEmpty()) {
if (!showedNoVersion && ((HMCLMinecraftService) Settings.getLastProfile().service()).checkedModpack) {
showedNoVersion = true;
SwingUtilities.invokeLater(() -> {
if (MessageBox.show(C.i18n("mainwindow.no_version"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
MainFrame.INSTANCE.invokeAction("showGameDownloads");
});
}
} else {
for (MinecraftVersion mcVersion : Settings.getLastProfile().service().version().getVersions()) { for (MinecraftVersion mcVersion : Settings.getLastProfile().service().version().getVersions()) {
if (mcVersion.hidden) if (mcVersion.hidden)
continue; continue;
cboVersions.addItem(mcVersion.id); cboVersions.addItem(mcVersion.id);
} }
versionChanged.accept(selVersion); versionChanged(selVersion);
} }
isLoading = false; isLoading = false;
} }
final Consumer<Boolean> launchingStateChanged = t -> SwingUtils.setEnabled(MainFrame.INSTANCE.getRootPane(), !t); final Consumer<LaunchingStateChangedEvent> launchingStateChanged = t -> SwingUtils.setEnabled(MainFrame.INSTANCE.getRootPane(), t.getValue() == LaunchingState.Done);
final Consumer<String> versionChanged = this::versionChanged;
void versionChanged(String selectedVersion) { void versionChanged(String selectedVersion) {
isLoading = true; isLoading = true;
@@ -536,10 +529,12 @@ public class MainPagePanel extends Page {
isLoading = false; isLoading = false;
} }
final Consumer<Profile> onSelectedProfilesChanged = t -> { final Consumer<ProfileChangedEvent> onSelectedProfilesChanged = event -> {
t.service().version().onRefreshedVersions.register(onRefreshedVersions); Profile t = Settings.getProfile(event.getValue());
t.selectedVersionChangedEvent.register(versionChanged); t.propertyChanged.register(e -> {
t.launcher().launchingStateChanged.register(launchingStateChanged); if ("selectedMinecraftVersion".equals(e.getPropertyName()))
versionChanged(e.getNewValue());
});
isLoading = true; isLoading = true;
DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) cboProfiles.getModel(); DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) cboProfiles.getModel();

View File

@@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hellominecraft.launcher.ui; package org.jackhuang.hellominecraft.launcher.ui;
import org.jackhuang.hellominecraft.util.ui.Selectable;
import javax.swing.JTabbedPane; import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;

View File

@@ -17,6 +17,7 @@
*/ */
package org.jackhuang.hellominecraft.launcher.ui; package org.jackhuang.hellominecraft.launcher.ui;
import org.jackhuang.hellominecraft.util.ui.Page;
import org.jackhuang.hellominecraft.util.ui.IRepaint; import org.jackhuang.hellominecraft.util.ui.IRepaint;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Window; import java.awt.Window;

View File

@@ -18,17 +18,19 @@
package org.jackhuang.hellominecraft.launcher.util; package org.jackhuang.hellominecraft.launcher.util;
import java.util.ArrayList; import java.util.ArrayList;
import javax.swing.JFrame;
import org.jackhuang.hellominecraft.launcher.api.AddTabCallback;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService; import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.api.IPlugin; import org.jackhuang.hellominecraft.launcher.api.IPlugin;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.launcher.core.auth.OfflineAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.OfflineAuthenticator;
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
import org.jackhuang.hellominecraft.launcher.core.auth.YggdrasilAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.YggdrasilAuthenticator;
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions;
import org.jackhuang.hellominecraft.launcher.setting.Profile; import org.jackhuang.hellominecraft.launcher.setting.Profile;
import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.launcher.ui.MainFrame; import org.jackhuang.hellominecraft.launcher.ui.GameSettingsPanel;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.launcher.ui.LauncherSettingsPanel;
import org.jackhuang.hellominecraft.launcher.ui.MainPagePanel;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.func.Consumer; import org.jackhuang.hellominecraft.util.func.Consumer;
/** /**
@@ -39,11 +41,6 @@ public class DefaultPlugin implements IPlugin {
ArrayList<IAuthenticator> auths = new ArrayList<>(); ArrayList<IAuthenticator> auths = new ArrayList<>();
@Override
public IMinecraftService provideMinecraftService(Object profile) {
return new HMCLMinecraftService((Profile) profile);
}
@Override @Override
public void onRegisterAuthenticators(Consumer<IAuthenticator> apply) { public void onRegisterAuthenticators(Consumer<IAuthenticator> apply) {
String clientToken = Settings.getInstance().getClientToken(); String clientToken = Settings.getInstance().getClientToken();
@@ -64,19 +61,10 @@ public class DefaultPlugin implements IPlugin {
} }
@Override @Override
public void showUI() { public void onAddTab(JFrame frame, AddTabCallback callback) {
MainFrame.showMainFrame(); callback.addTab(new MainPagePanel(), "main", C.i18n("launcher.title.main"));
} callback.addTab(new GameSettingsPanel(), "game", C.i18n("launcher.title.game"));
callback.addTab(new LauncherSettingsPanel(), "launcher", C.i18n("launcher.title.launcher"));
@Override
public void onProcessingLoginResult(UserProfileProvider result) {
}
public transient final EventHandler<LaunchOptions> onProcessingLaunchOptionsEvent = new EventHandler<>(this);
@Override
public void onProcessingLaunchOptions(LaunchOptions p) {
onProcessingLaunchOptionsEvent.execute(p);
} }
} }

View File

@@ -18,7 +18,6 @@
package org.jackhuang.hellominecraft.launcher.util; package org.jackhuang.hellominecraft.launcher.util;
import java.io.File; import java.io.File;
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException; import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator; import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
@@ -29,9 +28,15 @@ import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions;
import org.jackhuang.hellominecraft.launcher.setting.Profile; import org.jackhuang.hellominecraft.launcher.setting.Profile;
import org.jackhuang.hellominecraft.launcher.setting.Settings; import org.jackhuang.hellominecraft.launcher.setting.Settings;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchSucceededEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchingState;
import org.jackhuang.hellominecraft.launcher.api.event.launch.LaunchingStateChangedEvent;
import org.jackhuang.hellominecraft.launcher.api.event.launch.ProcessingLaunchOptionsEvent;
import org.jackhuang.hellominecraft.launcher.core.RuntimeGameException;
import org.jackhuang.hellominecraft.util.func.Consumer; import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
import org.jackhuang.hellominecraft.util.sys.JavaProcess;
/** /**
* *
@@ -42,15 +47,15 @@ public class HMCLGameLauncher {
Profile profile; Profile profile;
boolean isLaunching = false; boolean isLaunching = false;
public final EventHandler<Boolean> launchingStateChanged = new EventHandler<>(this);
public HMCLGameLauncher(Profile p) { public HMCLGameLauncher(Profile p) {
this.profile = p; this.profile = p;
HMCLAPI.EVENT_BUS.channel(LaunchSucceededEvent.class).register(() -> setLaunching(false));
} }
void setLaunching(boolean isLaunching) { void setLaunching(boolean isLaunching) {
if (isLaunching != this.isLaunching) if (isLaunching != this.isLaunching)
launchingStateChanged.execute(isLaunching); HMCLAPI.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(this, isLaunching ? LaunchingState.Starting : LaunchingState.Done));
this.isLaunching = isLaunching; this.isLaunching = isLaunching;
} }
@@ -80,13 +85,14 @@ public class HMCLGameLauncher {
Thread.currentThread().setName("Game Launcher"); Thread.currentThread().setName("Game Launcher");
try { try {
LaunchOptions options = profile.getSelectedVersionSetting().createLaunchOptions(profile.getCanonicalGameDirFile()); LaunchOptions options = profile.getSelectedVersionSetting().createLaunchOptions(profile.getCanonicalGameDirFile());
PluginManager.plugin().onProcessingLaunchOptions(options); HMCLAPI.EVENT_BUS.fireChannel(new ProcessingLaunchOptionsEvent(this, options));
DefaultGameLauncher gl = new DefaultGameLauncher(options, profile.service(), li, l); DefaultGameLauncher gl = new DefaultGameLauncher(options, profile.service(), li, l);
gl.setTag(profile.getSelectedVersionSetting().getLauncherVisibility()); GameLauncherTag tag = new GameLauncherTag();
gl.successEvent.register(() -> setLaunching(false)); tag.launcherVisibility = profile.getSelectedVersionSetting().getLauncherVisibility();
gl.setTag(tag);
listener.accept(gl); listener.accept(gl);
gl.makeLaunchCommand(); gl.makeLaunchCommand();
} catch (GameException e) { } catch (GameException | RuntimeGameException e) {
failed.accept(C.i18n("launch.failed") + ", " + e.getMessage()); failed.accept(C.i18n("launch.failed") + ", " + e.getMessage());
setLaunching(false); setLaunching(false);
} catch (AuthenticationException e) { } catch (AuthenticationException e) {
@@ -99,4 +105,9 @@ public class HMCLGameLauncher {
t.start(); t.start();
} }
public static class GameLauncherTag {
public LauncherVisibility launcherVisibility;
public JavaProcess process;
public int state; // 0 - unknown; 1 - launch; 2 - make launch script.
}
} }

View File

@@ -22,6 +22,10 @@ import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.launcher.api.event.version.LoadedOneVersionEvent;
import org.jackhuang.hellominecraft.launcher.api.event.version.RefreshedVersionsEvent;
import org.jackhuang.hellominecraft.launcher.api.event.version.RefreshingVersionsEvent;
import org.jackhuang.hellominecraft.launcher.core.GameException; import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.install.MinecraftInstallerService; import org.jackhuang.hellominecraft.launcher.core.install.MinecraftInstallerService;
import org.jackhuang.hellominecraft.launcher.core.asset.MinecraftAssetService; import org.jackhuang.hellominecraft.launcher.core.asset.MinecraftAssetService;
@@ -53,8 +57,8 @@ public class HMCLMinecraftService extends IMinecraftService {
this.p = p; this.p = p;
this.provider = new HMCLGameProvider(this); this.provider = new HMCLGameProvider(this);
provider.initializeMiencraft(); provider.initializeMiencraft();
provider.onRefreshingVersions.register(versionSettings::clear); HMCLAPI.EVENT_BUS.channel(RefreshingVersionsEvent.class).register(versionSettings::clear);
provider.onRefreshedVersions.register(() -> { HMCLAPI.EVENT_BUS.channel(RefreshedVersionsEvent.class).registerFirst(() -> {
if (!checkingModpack) { if (!checkingModpack) {
checkingModpack = true; checkingModpack = true;
if (version().getVersionCount() == 0) { if (version().getVersionCount() == 0) {
@@ -68,7 +72,7 @@ public class HMCLMinecraftService extends IMinecraftService {
} }
} }
}); });
provider.onLoadedVersion.register(this::loadVersionSetting); HMCLAPI.EVENT_BUS.channel(LoadedOneVersionEvent.class).register(e -> loadVersionSetting(e.getValue()));
this.mms = new MinecraftModService(this); this.mms = new MinecraftModService(this);
this.mds = new MinecraftDownloadService(this); this.mds = new MinecraftDownloadService(this);
this.mas = new MinecraftAssetService(this); this.mas = new MinecraftAssetService(this);
@@ -105,10 +109,7 @@ public class HMCLMinecraftService extends IMinecraftService {
private void initVersionSetting(String id, VersionSetting vs) { private void initVersionSetting(String id, VersionSetting vs) {
vs.id = id; vs.id = id;
vs.propertyChanged.register((sender, t) -> { vs.propertyChanged.register(event -> saveVersionSetting(((VersionSetting) event.getSource()).id));
saveVersionSetting(((VersionSetting) sender).id);
return true;
});
versionSettings.put(id, vs); versionSettings.put(id, vs);
} }

View File

@@ -34,6 +34,7 @@ import java.util.jar.JarFile;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import java.util.jar.Pack200; import java.util.jar.Pack200;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
import org.jackhuang.hellominecraft.launcher.core.MCUtils; import org.jackhuang.hellominecraft.launcher.core.MCUtils;
@@ -97,9 +98,10 @@ public class AppDataUpgrader extends IUpgrader {
} }
@Override @Override
public boolean call(Object sender, final VersionNumber number) { public void accept(SimpleEvent<VersionNumber> event) {
((UpdateChecker) sender).requestDownloadLink().reg(map -> { final VersionNumber version = event.getValue();
if (MessageBox.show(C.i18n("update.newest_version") + number.firstVer + "." + number.secondVer + "." + number.thirdVer + "\n" ((UpdateChecker) event.getSource()).requestDownloadLink().reg(map -> {
if (MessageBox.show(C.i18n("update.newest_version") + version.firstVer + "." + version.secondVer + "." + version.thirdVer + "\n"
+ C.i18n("update.should_open_link"), + C.i18n("update.should_open_link"),
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
if (map != null && map.containsKey("pack")) if (map != null && map.containsKey("pack"))
@@ -107,8 +109,8 @@ public class AppDataUpgrader extends IUpgrader {
String hash = null; String hash = null;
if (map.containsKey("packsha1")) if (map.containsKey("packsha1"))
hash = map.get("packsha1"); hash = map.get("packsha1");
if (TaskWindow.factory().append(new AppDataUpgraderTask(map.get("pack"), number.version, hash)).execute()) { if (TaskWindow.factory().append(new AppDataUpgraderTask(map.get("pack"), version.version, hash)).execute()) {
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(number.version).getAbsolutePath() }).directory(new File(".")).start(); new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(version.version).getAbsolutePath() }).directory(new File(".")).start();
System.exit(0); System.exit(0);
} }
} catch (IOException ex) { } catch (IOException ex) {
@@ -132,7 +134,6 @@ public class AppDataUpgrader extends IUpgrader {
} }
} }
}).execute(); }).execute();
return true;
} }
public static class AppDataUpgraderTask extends Task { public static class AppDataUpgraderTask extends Task {

View File

@@ -17,14 +17,15 @@
*/ */
package org.jackhuang.hellominecraft.launcher.util.upgrade; package org.jackhuang.hellominecraft.launcher.util.upgrade;
import org.jackhuang.hellominecraft.util.Event; import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.VersionNumber; import org.jackhuang.hellominecraft.util.VersionNumber;
import org.jackhuang.hellominecraft.util.func.Consumer;
/** /**
* *
* @author huangyuhui * @author huangyuhui
*/ */
public abstract class IUpgrader implements Event<VersionNumber> { public abstract class IUpgrader implements Consumer<SimpleEvent<VersionNumber>> {
public static final IUpgrader NOW_UPGRADER = new AppDataUpgrader(); public static final IUpgrader NOW_UPGRADER = new AppDataUpgrader();
@@ -48,5 +49,5 @@ public abstract class IUpgrader implements Event<VersionNumber> {
* @return should return true * @return should return true
*/ */
@Override @Override
public abstract boolean call(Object sender, VersionNumber number); public abstract void accept(SimpleEvent<VersionNumber> event);
} }

View File

@@ -19,6 +19,7 @@ package org.jackhuang.hellominecraft.launcher.util.upgrade;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
import org.jackhuang.hellominecraft.util.task.TaskWindow; import org.jackhuang.hellominecraft.util.task.TaskWindow;
import org.jackhuang.hellominecraft.util.net.FileDownloadTask; import org.jackhuang.hellominecraft.util.net.FileDownloadTask;
@@ -45,7 +46,7 @@ public class NewFileUpgrader extends IUpgrader {
} }
@Override @Override
public boolean call(Object sender, VersionNumber number) { public void accept(SimpleEvent<VersionNumber> event) {
String str = requestDownloadLink(); String str = requestDownloadLink();
File newf = new File(FileUtils.getName(str)); File newf = new File(FileUtils.getName(str));
if (TaskWindow.factory().append(new FileDownloadTask(str, newf)).execute()) { if (TaskWindow.factory().append(new FileDownloadTask(str, newf)).execute()) {
@@ -56,7 +57,6 @@ public class NewFileUpgrader extends IUpgrader {
} }
System.exit(0); System.exit(0);
} }
return true;
} }
private String requestDownloadLink() { private String requestDownloadLink() {

View File

@@ -44,8 +44,8 @@ import org.jackhuang.hellominecraft.svrmgr.setting.SettingsManager;
import org.jackhuang.hellominecraft.svrmgr.util.MonitorThread; import org.jackhuang.hellominecraft.svrmgr.util.MonitorThread;
import org.jackhuang.hellominecraft.svrmgr.util.WaitForThread; import org.jackhuang.hellominecraft.svrmgr.util.WaitForThread;
import org.jackhuang.hellominecraft.svrmgr.util.Utilities; import org.jackhuang.hellominecraft.svrmgr.util.Utilities;
import org.jackhuang.hellominecraft.util.Event; import org.jackhuang.hellominecraft.api.Event;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.util.code.Charsets; import org.jackhuang.hellominecraft.util.code.Charsets;
import org.jackhuang.hellominecraft.util.func.Consumer; import org.jackhuang.hellominecraft.util.func.Consumer;
@@ -133,7 +133,7 @@ public class Server implements Event<Integer>, MonitorThread.MonitorThreadListen
registerThreadC(server); registerThreadC(server);
bw = new BufferedWriter(new OutputStreamWriter(server.getOutputStream(), Charsets.toCharset())); bw = new BufferedWriter(new OutputStreamWriter(server.getOutputStream(), Charsets.toCharset()));
isRunning = true; isRunning = true;
startedEvent.execute(null); startedEvent.fire(null);
sendStatus("*** 启动服务端中 ***"); sendStatus("*** 启动服务端中 ***");
} catch (IOException ex) { } catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex); Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
@@ -342,7 +342,7 @@ public class Server implements Event<Integer>, MonitorThread.MonitorThreadListen
Pattern p = Pattern.compile("\\[INFO\\] Done \\([0-9]*\\.[0-9]*s\\)! For help, type \"help\" or \"\\?\""); Pattern p = Pattern.compile("\\[INFO\\] Done \\([0-9]*\\.[0-9]*s\\)! For help, type \"help\" or \"\\?\"");
Matcher m = p.matcher(status); Matcher m = p.matcher(status);
if (m.find()) { if (m.find()) {
stoppedEvent.execute(null); stoppedEvent.fire(null);
timer = new Timer(); timer = new Timer();
timerTasks.clear(); timerTasks.clear();
for (int i = 0; i < schedules.size(); i++) { for (int i = 0; i < schedules.size(); i++) {

View File

@@ -87,7 +87,7 @@ import org.jackhuang.hellominecraft.svrmgr.util.Utilities;
import org.jackhuang.hellominecraft.util.ui.SwingUtils; import org.jackhuang.hellominecraft.util.ui.SwingUtils;
import org.jackhuang.hellominecraft.svrmgr.util.version.MinecraftRemoteVersion; import org.jackhuang.hellominecraft.svrmgr.util.version.MinecraftRemoteVersion;
import org.jackhuang.hellominecraft.lookandfeel.ConstomButton; import org.jackhuang.hellominecraft.lookandfeel.ConstomButton;
import org.jackhuang.hellominecraft.util.Event; import org.jackhuang.hellominecraft.api.Event;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;
/** /**

View File

@@ -17,7 +17,7 @@
*/ */
package org.jackhuang.hellominecraft.svrmgr.util; package org.jackhuang.hellominecraft.svrmgr.util;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
/** /**
@@ -37,10 +37,10 @@ public class WaitForThread extends Thread {
public void run() { public void run() {
try { try {
int exitCode = p.waitFor(); int exitCode = p.waitFor();
event.execute(exitCode); event.fire(exitCode);
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
HMCLog.err("Game has been interrupted.", ex); HMCLog.err("Game has been interrupted.", ex);
event.execute(-1); event.fire(-1);
} }
} }

View File

@@ -0,0 +1,48 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.api;
import java.util.EventObject;
import java.util.HashMap;
/**
*
* @author huang
*/
public class EventBus {
HashMap<Class, EventHandler> events = new HashMap<>();
public EventBus() {
}
public <T extends EventObject> EventHandler<T> channel(Class<T> classOfT) {
if (!events.containsKey(classOfT))
events.put(classOfT, new EventHandler<>());
return events.get(classOfT);
}
public void fireChannel(EventObject obj) {
channel((Class<EventObject>) obj.getClass()).fire(obj);
}
public boolean fireChannelResulted(ResultedEvent obj) {
return channel((Class<ResultedEvent>) obj.getClass()).fireResulted(obj);
}
}

View File

@@ -15,9 +15,10 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}. * along with this program. If not, see {http://www.gnu.org/licenses/}.
*/ */
package org.jackhuang.hellominecraft.util; package org.jackhuang.hellominecraft.api;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EventObject;
import org.jackhuang.hellominecraft.util.func.Consumer; import org.jackhuang.hellominecraft.util.func.Consumer;
/** /**
@@ -25,18 +26,11 @@ import org.jackhuang.hellominecraft.util.func.Consumer;
* @author huangyuhui * @author huangyuhui
* @param <T> EventArgs * @param <T> EventArgs
*/ */
public class EventHandler<T> { public class EventHandler<T extends EventObject> {
ArrayList<Object> events = new ArrayList<>(); ArrayList<Object> events = new ArrayList<>();
Object sender;
public EventHandler(Object sender) { public EventHandler() {
this.sender = sender;
}
public void register(Event<T> t) {
if (!events.contains(t))
events.add(t);
} }
public void register(Consumer<T> t) { public void register(Consumer<T> t) {
@@ -44,20 +38,40 @@ public class EventHandler<T> {
events.add(t); events.add(t);
} }
public void registerFirst(Consumer<T> t) {
if (!events.contains(t))
events.add(0, t);
}
public void register(Runnable t) { public void register(Runnable t) {
if (!events.contains(t)) if (!events.contains(t))
events.add(t); events.add(t);
} }
public void registerFirst(Runnable t) {
if (!events.contains(t))
events.add(0, t);
}
public boolean execute(T x) { public void fire(T x) {
for (Object t : events)
if (t instanceof Consumer) {
((Consumer) t).accept(x);
} else if (t instanceof Runnable)
((Runnable) t).run();
}
public boolean fireResulted(T x) {
if (!(x instanceof ResultedEvent))
throw new IllegalArgumentException("x should be ResultedEvent");
ResultedEvent event = (ResultedEvent) x;
boolean flag = true; boolean flag = true;
for (Object t : events) for (Object t : events)
if (t instanceof Event) { if (t instanceof Consumer) {
if (!((Event<T>) t).call(sender, x)) ((Consumer) t).accept(x);
if (!event.result())
flag = false; flag = false;
} else if (t instanceof Consumer) } else if (t instanceof Runnable)
((Consumer<T>) t).accept(x);
else if (t instanceof Runnable)
((Runnable) t).run(); ((Runnable) t).run();
return flag; return flag;
} }

View File

@@ -1,7 +1,7 @@
/* /*
* Hello Minecraft!. * Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com> * Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
@@ -15,14 +15,16 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}. * along with this program. If not, see {http://www.gnu.org/licenses/}.
*/ */
package org.jackhuang.hellominecraft.util; package org.jackhuang.hellominecraft.api;
/** /**
* *
* @author huangyuhui * @author huang
* @param <T> EventArgs
*/ */
public interface Event<T> { public class HMCLAPI {
boolean call(Object sender, T t); /**
* Events.
*/
public static final EventBus EVENT_BUS = new EventBus();
} }

View File

@@ -0,0 +1,49 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.api;
import java.util.EventObject;
/**
*
* @author huang
*/
public class PropertyChangedEvent<T> extends EventObject {
String propertyName;
T oldValue, newValue;
public PropertyChangedEvent(Object source, String propertyName, T oldValue, T newValue) {
super(source);
this.propertyName = propertyName;
this.oldValue = oldValue;
this.newValue = newValue;
}
public String getPropertyName() {
return propertyName;
}
public T getNewValue() {
return newValue;
}
public T getOldValue() {
return oldValue;
}
}

View File

@@ -0,0 +1,44 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.api;
import java.util.EventObject;
/**
*
* @author huang
*/
public class ResultedEvent extends EventObject {
protected boolean result = true;
public ResultedEvent(Object sender) {
super(sender);
}
public boolean result() {
return result;
}
public void failed() {
setResult(false);
}
public void setResult(boolean canceled) {
this.result = canceled;
}
}

View File

@@ -0,0 +1,41 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.api;
/**
*
* @author huang
*/
public class ResultedSimpleEvent<T> extends ResultedEvent {
T value;
public ResultedSimpleEvent(Object sender, T t) {
super(sender);
value = t;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}

View File

@@ -0,0 +1,41 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.api;
import java.util.EventObject;
/**
*
* @author huang
*/
public class SimpleEvent<T> extends EventObject {
private T value;
public SimpleEvent(Object source, T value) {
super(source);
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}

View File

@@ -0,0 +1,40 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.api.event;
import org.jackhuang.hellominecraft.api.ResultedSimpleEvent;
import org.jackhuang.hellominecraft.util.VersionNumber;
/**
* This event gets fired when we found that user's HMCL is out of date.
* <br>
* This event is {@link org.jackhuang.hellominecraft.api.ResultedEvent}
* If this event is failed, HMCL will not ask user to upgrade the application.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.util.UpdateChecker}
* @param VersionNumber newest version
* @author huang
*/
public class OutOfDateEvent extends ResultedSimpleEvent<VersionNumber> {
public OutOfDateEvent(Object source, VersionNumber value) {
super(source, value);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.api.event.process;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.sys.JavaProcess;
/**
* This event gets fired when we launch the JVM and it got crashed.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.util.sys.JavaProcessMonitor}
* @param JavaProcess the crashed process.
* @author huangyuhui
*/
public class JVMLaunchFailedEvent extends SimpleEvent<JavaProcess> {
public JVMLaunchFailedEvent(Object source, JavaProcess value) {
super(source, value);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.api.event.process;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.sys.JavaProcess;
/**
* This event gets fired when a JavaProcess exited abnormally and the exit code is not zero.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.util.sys.JavaProcessMonitor}
* @param JavaProcess The process that exited abnormally.
* @author huangyuhui
*/
public class JavaProcessExitedAbnormallyEvent extends SimpleEvent<JavaProcess> {
public JavaProcessExitedAbnormallyEvent(Object source, JavaProcess value) {
super(source, value);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.api.event.process;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.sys.JavaProcess;
/**
* This event gets fired when a JavaProcess is starting.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.util.sys.JavaProcessMonitor}
* @param JavaProcess the starting JavaProcess.
* @author huang
*/
public class JavaProcessStartingEvent extends SimpleEvent<JavaProcess> {
public JavaProcessStartingEvent(Object source, JavaProcess value) {
super(source, value);
}
}

View File

@@ -0,0 +1,37 @@
/*
* Hello Minecraft! Launcher.
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}.
*/
package org.jackhuang.hellominecraft.api.event.process;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.sys.JavaProcess;
/**
* This event gets fired when minecraft process exited successfully and the exit code is 0.
* <br>
* This event is fired on the {@link org.jackhuang.hellominecraft.api.HMCLAPI#EVENT_BUS}
* @param source {@link org.jackhuang.hellominecraft.util.sys.JavaProcessMonitor}
* @param JavaProcess minecraft process
* @author huangyuhui
*/
public class JavaProcessStoppedEvent extends SimpleEvent<JavaProcess> {
public JavaProcessStoppedEvent(Object source, JavaProcess value) {
super(source, value);
}
}

View File

@@ -17,11 +17,15 @@
*/ */
package org.jackhuang.hellominecraft.util; package org.jackhuang.hellominecraft.util;
import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.util.net.NetUtils; import org.jackhuang.hellominecraft.util.net.NetUtils;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import java.io.IOException; import java.io.IOException;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
import java.util.Map; import java.util.Map;
import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.api.event.OutOfDateEvent;
/** /**
* *
@@ -89,11 +93,12 @@ public final class UpdateChecker implements IUpdateChecker {
}; };
} }
public final EventHandler<VersionNumber> outOfDateEvent = new EventHandler<>(this); public final EventHandler<SimpleEvent<VersionNumber>> upgrade = new EventHandler<>();
@Override @Override
public void checkOutdate() { public void checkOutdate() {
if (outOfDate) if (outOfDate)
outOfDateEvent.execute(getNewVersion()); if (HMCLAPI.EVENT_BUS.fireChannelResulted(new OutOfDateEvent(this, getNewVersion())))
upgrade.fire(new SimpleEvent<>(this, getNewVersion()));
} }
} }

View File

@@ -17,11 +17,13 @@
*/ */
package org.jackhuang.hellominecraft.util.func; package org.jackhuang.hellominecraft.util.func;
import java.util.EventListener;
/** /**
* *
* @author huangyuhui * @author huangyuhui
*/ */
public interface Consumer<T> { public interface Consumer<T> extends EventListener {
void accept(T t); void accept(T t);
} }

View File

@@ -27,7 +27,8 @@ import java.nio.charset.Charset;
import org.jackhuang.hellominecraft.util.C; import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
import org.jackhuang.hellominecraft.util.task.comm.PreviousResult; import org.jackhuang.hellominecraft.util.task.comm.PreviousResult;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.code.Charsets; import org.jackhuang.hellominecraft.util.code.Charsets;
import org.jackhuang.hellominecraft.util.task.Task; import org.jackhuang.hellominecraft.util.task.Task;
@@ -39,7 +40,7 @@ public class HTTPGetTask extends Task implements PreviousResult<String> {
String url, result; String url, result;
Charset encoding; Charset encoding;
EventHandler<String> doneEvent = new EventHandler<>(this); EventHandler<SimpleEvent<String>> doneEvent = new EventHandler<>();
boolean shouldContinue = true; boolean shouldContinue = true;
public HTTPGetTask(String url) { public HTTPGetTask(String url) {
@@ -81,7 +82,7 @@ public class HTTPGetTask extends Task implements PreviousResult<String> {
return; return;
} }
result = baos.toString(encoding.name()); result = baos.toString(encoding.name());
doneEvent.execute(result); doneEvent.fire(new SimpleEvent<>(this, result));
return; return;
} catch (IOException ex) { } catch (IOException ex) {
t = new IOException("Failed to get " + url, ex); t = new IOException("Failed to get " + url, ex);

View File

@@ -20,7 +20,12 @@ package org.jackhuang.hellominecraft.util.sys;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import org.jackhuang.hellominecraft.util.CollectionUtils; import org.jackhuang.hellominecraft.util.CollectionUtils;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.api.HMCLAPI;
import org.jackhuang.hellominecraft.api.event.process.JVMLaunchFailedEvent;
import org.jackhuang.hellominecraft.api.event.process.JavaProcessExitedAbnormallyEvent;
import org.jackhuang.hellominecraft.api.event.process.JavaProcessStartingEvent;
import org.jackhuang.hellominecraft.api.event.process.JavaProcessStoppedEvent;
import org.jackhuang.hellominecraft.util.StrUtils; import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
import org.jackhuang.hellominecraft.util.log.Level; import org.jackhuang.hellominecraft.util.log.Level;
@@ -32,20 +37,6 @@ import org.jackhuang.hellominecraft.util.log.Level;
public class JavaProcessMonitor { public class JavaProcessMonitor {
private final HashSet<Thread> al = new HashSet<>(); private final HashSet<Thread> al = new HashSet<>();
/**
* this event will be executed only if the application returned 0.
*/
public final EventHandler<JavaProcess> stoppedEvent = new EventHandler<>(this);
/**
* When the monitored application exited with exit code not zero, this event
* will be executed. Event args is the exit code.
*/
public final EventHandler<Integer> applicationExitedAbnormallyEvent = new EventHandler<>(this);
/**
* When jvm crashed, this event will be executed. Event args is the exit
* code.
*/
public final EventHandler<Integer> jvmLaunchFailedEvent = new EventHandler<>(this);
private final JavaProcess p; private final JavaProcess p;
public JavaProcessMonitor(JavaProcess p) { public JavaProcessMonitor(JavaProcess p) {
@@ -55,24 +46,35 @@ public class JavaProcessMonitor {
public JavaProcess getJavaProcess() { public JavaProcess getJavaProcess() {
return p; return p;
} }
private Object tag;
public Object getTag() {
return tag;
}
public void setTag(Object tag) {
this.tag = tag;
}
public void start() { public void start() {
HMCLAPI.EVENT_BUS.fireChannel(new JavaProcessStartingEvent(this, p));
ProcessThread a = new ProcessThread(p); ProcessThread a = new ProcessThread(p);
a.stopEvent.register((sender, t) -> { a.stopEvent.register(event -> {
HMCLog.log("Process exit code: " + t.getExitCode()); HMCLog.log("Process exit code: " + p.getExitCode());
if (t.getExitCode() != 0 || StrUtils.containsOne(t.getStdOutLines(), if (p.getExitCode() != 0 || StrUtils.containsOne(p.getStdOutLines(),
Arrays.asList("Unable to launch"), Arrays.asList("Unable to launch"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR))) x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
applicationExitedAbnormallyEvent.execute(t.getExitCode()); HMCLAPI.EVENT_BUS.fireChannel(new JavaProcessExitedAbnormallyEvent(JavaProcessMonitor.this, p));
if (t.getExitCode() != 0 && StrUtils.containsOne(t.getStdOutLines(), if (p.getExitCode() != 0 && StrUtils.containsOne(p.getStdOutLines(),
Arrays.asList("Could not create the Java Virtual Machine.", Arrays.asList("Could not create the Java Virtual Machine.",
"Error occurred during initialization of VM", "Error occurred during initialization of VM",
"A fatal exception has occurred. Program will exit.", "A fatal exception has occurred. Program will exit.",
"Unable to launch"), "Unable to launch"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR))) x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
jvmLaunchFailedEvent.execute(t.getExitCode()); HMCLAPI.EVENT_BUS.fireChannel(new JVMLaunchFailedEvent(JavaProcessMonitor.this, p));
processThreadStopped((ProcessThread) sender, false); processThreadStopped((ProcessThread) event.getSource(), false);
return true;
}); });
a.start(); a.start();
al.add(a); al.add(a);
@@ -84,7 +86,7 @@ public class JavaProcessMonitor {
for (Thread a : al) for (Thread a : al)
a.interrupt(); a.interrupt();
al.clear(); al.clear();
stoppedEvent.execute(p); HMCLAPI.EVENT_BUS.fireChannel(new JavaProcessStoppedEvent(this, p));
} }
} }
} }

View File

@@ -22,7 +22,8 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.code.Charsets; import org.jackhuang.hellominecraft.util.code.Charsets;
/** /**
@@ -33,8 +34,8 @@ public class ProcessThread extends Thread {
JavaProcess p; JavaProcess p;
public final EventHandler<String> printlnEvent = new EventHandler<>(this); public final EventHandler<SimpleEvent<String>> printlnEvent = new EventHandler<>();
public final EventHandler<JavaProcess> stopEvent = new EventHandler<>(this); public final EventHandler<SimpleEvent<JavaProcess>> stopEvent = new EventHandler<>();
public ProcessThread(JavaProcess process) { public ProcessThread(JavaProcess process) {
p = process; p = process;
@@ -55,18 +56,18 @@ public class ProcessThread extends Thread {
String line; String line;
while (p.isRunning()) while (p.isRunning())
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
printlnEvent.execute(line); printlnEvent.fire(new SimpleEvent<>(this, line));
System.out.println("Minecraft: " + line); System.out.println("MC: " + line);
p.getStdOutLines().add(line); p.getStdOutLines().add(line);
} }
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
printlnEvent.execute(line); printlnEvent.fire(new SimpleEvent<>(this, line));
System.out.println("Minecraft: " + line); System.out.println("MC: " + line);
p.getStdOutLines().add(line); p.getStdOutLines().add(line);
} }
if (p.getProcessManager() != null) if (p.getProcessManager() != null)
p.getProcessManager().onProcessStopped(p); p.getProcessManager().onProcessStopped(p);
stopEvent.execute(p); stopEvent.fire(new SimpleEvent<>(this, p));
} catch (IOException e) { } catch (IOException e) {
HMCLog.err("An error occured when reading process stdout/stderr.", e); HMCLog.err("An error occured when reading process stdout/stderr.", e);
} finally { } finally {

View File

@@ -20,6 +20,7 @@ package org.jackhuang.hellominecraft.util.task;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EventObject;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
@@ -29,7 +30,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.jackhuang.hellominecraft.util.EventHandler; import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.util.log.HMCLog; import org.jackhuang.hellominecraft.util.log.HMCLog;
/** /**
@@ -39,7 +40,7 @@ import org.jackhuang.hellominecraft.util.log.HMCLog;
public class TaskList extends Thread { public class TaskList extends Thread {
List<Task> taskQueue = Collections.synchronizedList(new LinkedList<>()); List<Task> taskQueue = Collections.synchronizedList(new LinkedList<>());
public final EventHandler<Object> doneEvent = new EventHandler<>(this); public final EventHandler<EventObject> doneEvent = new EventHandler<>();
ArrayList<DoingDoneListener<Task>> taskListener = new ArrayList<>(); ArrayList<DoingDoneListener<Task>> taskListener = new ArrayList<>();
int totTask; int totTask;
@@ -159,7 +160,7 @@ public class TaskList extends Thread {
executeTask(taskQueue.remove(0)); executeTask(taskQueue.remove(0));
if (shouldContinue) { if (shouldContinue) {
HMCLog.log("Tasks are successfully finished."); HMCLog.log("Tasks are successfully finished.");
doneEvent.execute(null); doneEvent.fire(new EventObject(this));
} }
} }

View File

@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}. * along with this program. If not, see {http://www.gnu.org/licenses/}.
*/ */
package org.jackhuang.hellominecraft.launcher.ui; package org.jackhuang.hellominecraft.util.ui;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
import java.awt.Graphics; import java.awt.Graphics;
@@ -24,7 +24,6 @@ import java.awt.image.BufferedImage;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.Timer; import javax.swing.Timer;
import org.jackhuang.hellominecraft.launcher.setting.Settings;
/** /**
* *
@@ -118,10 +117,10 @@ public class Page extends JPanel implements Selectable {
Timer timer; Timer timer;
boolean animationEnabled = true; protected boolean animationEnabled = true;
public void animate() { public void animate() {
if (Settings.getInstance().isEnableAnimation() && animationEnabled) { if (animationEnabled) {
offsetX = 0; offsetX = 0;
timer.start(); timer.start();
} }

View File

@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see {http://www.gnu.org/licenses/}. * along with this program. If not, see {http://www.gnu.org/licenses/}.
*/ */
package org.jackhuang.hellominecraft.launcher.ui; package org.jackhuang.hellominecraft.util.ui;
/** /**
* *