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)
buildnumber = System.getenv("BUILD_NUMBER")
if (buildnumber == null)
buildnumber = "5"
buildnumber = "0"
def versionroot = System.getenv("VERSION_ROOT")
if (versionroot == null)
versionroot = "2.6.0"
versionroot = "2.6.1"
String mavenGroupId = 'HMCL'
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;
import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
import javax.swing.JFrame;
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;
/**
@@ -31,34 +27,12 @@ import org.jackhuang.hellominecraft.util.func.Consumer;
*/
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.
*
* @param apply call apply.accept(your authenticator)
*/
void onRegisterAuthenticators(Consumer<IAuthenticator> apply);
/**
* 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;
void onAddTab(JFrame frame, AddTabCallback callback);
}

View File

@@ -17,6 +17,10 @@
*/
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;
/**
@@ -25,19 +29,25 @@ import org.jackhuang.hellominecraft.util.log.HMCLog;
*/
public class PluginManager {
private static IPlugin NOW_PLUGIN;
private static final ArrayList<IPlugin> PLUGINS = new ArrayList<>();
public static void getPlugin(Class<?> cls) {
try {
IPlugin p = (IPlugin) cls.newInstance();
NOW_PLUGIN = p;
PLUGINS.add(p);
} catch (IllegalAccessException | InstantiationException e) {
HMCLog.err("Failed to new instance");
}
}
public static IPlugin plugin() {
return NOW_PLUGIN;
public static void fireRegisterAuthenticators(Consumer<IAuthenticator> callback) {
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
* 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 org.jackhuang.hellominecraft.launcher.core.version.Extract;
/**
*
* @author huangyuhui
*/
public class DecompressLibraryJob {
@@ -29,6 +29,12 @@ public class DecompressLibraryJob {
public Extract[] extractRules;
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) {
this.decompressFiles = decompressFiles.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
* 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 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
* 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
*/
public enum LaunchingState {
Starting,
LoggingIn,
GeneratingLaunchingCodes,
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;
/**
*
* Thrown if we have some problem generating launch command.
* @author huangyuhui
*/
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;
/**
* Thrown if we are trying to log in but there's some problems like password wrong.
*
* @author huangyuhui
*/
public class AuthenticationException extends Exception {
public AuthenticationException() {

View File

@@ -33,7 +33,7 @@ public abstract class IAuthenticator {
public static final List<IAuthenticator> LOGINS = new ArrayList<>();
static {
PluginManager.plugin().onRegisterAuthenticators(LOGINS::add);
PluginManager.fireRegisterAuthenticators(LOGINS::add);
}
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;
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.task.TaskWindow;
@@ -59,4 +61,7 @@ public enum DownloadType {
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;
import org.jackhuang.hellominecraft.launcher.api.event.launch.DownloadLibraryJob;
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftDownloadService;
import com.google.gson.JsonSyntaxException;
import java.io.File;

View File

@@ -19,16 +19,22 @@ package org.jackhuang.hellominecraft.launcher.core.launch;
import java.io.IOException;
import java.util.HashSet;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.log.HMCLog;
import java.util.List;
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.LoginInfo;
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
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.TaskWindow;
import org.jackhuang.hellominecraft.util.sys.CompressingUtils;
import org.jackhuang.hellominecraft.util.MessageBox;
public class DefaultGameLauncher extends GameLauncher {
@@ -38,11 +44,12 @@ public class DefaultGameLauncher extends GameLauncher {
}
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();
ParallelTask parallelTask = new ParallelTask();
HashSet<String> names = new HashSet<>();
for (DownloadLibraryJob s : t) {
for (DownloadLibraryJob s : t.getValue()) {
if (names.contains(s.lib.name))
continue;
names.add(s.lib.name);
@@ -50,22 +57,23 @@ public class DefaultGameLauncher extends GameLauncher {
}
dw.append(parallelTask);
boolean flag = true;
if (t.size() > 0)
if (t.getValue().size() > 0)
flag = dw.execute();
if (!flag && MessageBox.show(C.i18n("launch.not_finished_downloading_libraries"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
flag = true;
return flag;
t.setResult(flag);
});
decompressNativesEvent.register((sender, value) -> {
if (value == null)
return false;
for (int i = 0; i < value.decompressFiles.length; i++)
HMCLAPI.EVENT_BUS.channel(DecompressLibrariesEvent.class).register(t -> {
if (t.getValue() == null) {
t.setResult(false);
return;
}
for (int i = 0; i < t.getValue().decompressFiles.length; i++)
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) {
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.OutputStreamWriter;
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.RuntimeGameException;
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.launcher.core.auth.LoginInfo;
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.IMinecraftService;
import org.jackhuang.hellominecraft.launcher.core.version.DecompressLibraryJob;
import org.jackhuang.hellominecraft.util.C;
import org.jackhuang.hellominecraft.util.EventHandler;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.util.code.Charsets;
import org.jackhuang.hellominecraft.util.log.HMCLog;
@@ -52,11 +58,6 @@ public class GameLauncher {
LoginInfo info;
UserProfileProvider result;
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) {
this.options = options;
@@ -75,10 +76,21 @@ public class GameLauncher {
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("Logging in...");
launchingStateChangedEvent.execute(LaunchingState.LoggingIn);
HMCLAPI.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(this, LaunchingState.LoggingIn));
IMinecraftLoader loader;
if (info != null)
result = login.login(info);
@@ -86,9 +98,9 @@ public class GameLauncher {
result = login.loginBySettings();
if (result == 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);
File file = service.version().getDecompressNativesToLocation(loader.getMinecraftVersion());
@@ -97,19 +109,18 @@ public class GameLauncher {
if (!options.isNotCheckGame()) {
HMCLog.log("Detecting libraries...");
launchingStateChangedEvent.execute(LaunchingState.DownloadingLibraries);
if (!downloadLibrariesEvent.execute(service.download().getDownloadLibraries(loader.getMinecraftVersion())))
HMCLAPI.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(this, LaunchingState.DownloadingLibraries));
if (!HMCLAPI.EVENT_BUS.fireChannelResulted(new DownloadLibrariesEvent(this, service.download().getDownloadLibraries(loader.getMinecraftVersion()))))
throw new GameException("Failed to download libraries");
}
HMCLog.log("Unpacking natives...");
launchingStateChangedEvent.execute(LaunchingState.DecompressingNatives);
HMCLAPI.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(this, LaunchingState.DecompressingNatives));
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");
successEvent.execute(loader.makeLaunchingCommand());
return loader;
HMCLAPI.EVENT_BUS.fireChannel(new LaunchSucceededEvent(this, loader.makeLaunchingCommand()));
}
/**
@@ -139,7 +150,7 @@ public class GameLauncher {
.environment().put("APPDATA", service.baseDirectory().getAbsolutePath());
JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER);
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;
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;
/**

View File

@@ -20,7 +20,7 @@ package org.jackhuang.hellominecraft.launcher.core.service;
import java.io.File;
import java.util.List;
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.util.task.Task;

View File

@@ -20,9 +20,9 @@ package org.jackhuang.hellominecraft.launcher.core.service;
import java.io.File;
import java.util.Collection;
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.util.EventHandler;
import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.func.Predicate;
@@ -143,10 +143,6 @@ public abstract class IMinecraftProvider {
*/
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.
*/

View File

@@ -17,6 +17,7 @@
*/
package org.jackhuang.hellominecraft.launcher.core.version;
import org.jackhuang.hellominecraft.launcher.api.event.launch.DecompressLibraryJob;
import com.google.gson.JsonSyntaxException;
import java.io.File;
import java.io.IOException;
@@ -24,6 +25,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
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.log.HMCLog;
import org.jackhuang.hellominecraft.launcher.core.GameException;
@@ -67,7 +72,7 @@ public class MinecraftVersionManager extends IMinecraftProvider {
@Override
public synchronized void refreshVersions() {
onRefreshingVersions.execute(service);
HMCLAPI.EVENT_BUS.fireChannel(new RefreshingVersionsEvent(this, service));
try {
MCUtils.tryWriteProfile(service.baseDirectory());
@@ -137,12 +142,12 @@ public class MinecraftVersionManager extends IMinecraftProvider {
}
versions.put(id, mcVersion);
onLoadedVersion.execute(id);
HMCLAPI.EVENT_BUS.fireChannel(new LoadedOneVersionEvent(this, id));
} catch (Exception 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

View File

@@ -143,10 +143,9 @@ public final class Main implements Runnable {
SupportedLocales.NOW_LOCALE = sl;
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");
}
try {
LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings);
@@ -155,11 +154,11 @@ public final class Main implements Runnable {
} catch (ParseException | UnsupportedLookAndFeelException ex) {
HMCLog.warn("Failed to set look and feel...", ex);
}
LogWindow.INSTANCE.clean();
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();
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 {
PluginManager.plugin().showUI();
} catch (Throwable t) {
new CrashReporter(false).uncaughtException(Thread.currentThread(), t);
System.exit(1);
}
MainFrame.showMainFrame();
}
}

View File

@@ -27,7 +27,10 @@ import java.util.TreeMap;
import java.util.UUID;
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
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.OS;
@@ -78,10 +81,6 @@ public final class Config implements Cloneable {
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() {
if (theme >= Theme.values().length)
theme = 0;
@@ -90,7 +89,7 @@ public final class Config implements Cloneable {
public void setTheme(int theme) {
this.theme = theme;
themeChangedEvent.execute(getTheme());
HMCLAPI.EVENT_BUS.fireChannel(new ThemeChangedEvent(this, getTheme()));
Settings.save();
}
@@ -171,7 +170,7 @@ public final class Config implements Cloneable {
if (logintype < 0 || logintype >= IAuthenticator.LOGINS.size())
return;
this.logintype = logintype;
authChangedEvent.execute(IAuthenticator.LOGINS.get(logintype));
HMCLAPI.EVENT_BUS.fireChannel(new AuthenticatorChangedEvent(this, IAuthenticator.LOGINS.get(logintype)));
Settings.save();
}
@@ -181,7 +180,7 @@ public final class Config implements Cloneable {
public void setDownloadType(int downloadtype) {
this.downloadtype = downloadtype;
downloadTypeChangedEvent.execute(getDownloadSource());
HMCLAPI.EVENT_BUS.fireChannel(new DownloadTypeChangedEvent(this, getDownloadSource()));
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.HMCLMinecraftService;
import java.io.File;
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
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.util.sys.IOUtils;
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;
/**
@@ -45,9 +44,9 @@ public final class Profile {
@SerializedName("global")
private VersionSetting global;
private transient IMinecraftService service;
private transient HMCLMinecraftService service;
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() {
this("Default");
@@ -71,9 +70,9 @@ public final class Profile {
gameDir = v.gameDir;
}
public IMinecraftService service() {
public HMCLMinecraftService service() {
if (service == null)
service = PluginManager.plugin().provideMinecraftService(this);
service = new HMCLMinecraftService(this);
return service;
}
@@ -86,7 +85,7 @@ public final class Profile {
}
public VersionSetting getVersionSetting(String id) {
VersionSetting vs = ((HMCLMinecraftService) service()).getVersionSetting(id);
VersionSetting vs = service().getVersionSetting(id);
if (vs == null || vs.isUsesGlobal()) {
global.isGlobal = true;
global.id = id;
@@ -96,23 +95,21 @@ public final class Profile {
}
public boolean isVersionSettingGlobe(String id) {
VersionSetting vs = ((HMCLMinecraftService) service()).getVersionSetting(id);
VersionSetting vs = service().getVersionSetting(id);
return vs == null || vs.isUsesGlobal();
}
public void makeVersionSettingSpecial(String id) {
HMCLMinecraftService s = (HMCLMinecraftService) service();
VersionSetting vs = s.getVersionSetting(id);
VersionSetting vs = service().getVersionSetting(id);
if (vs == null) {
s.createVersionSetting(id);
vs = s.getVersionSetting(id);
service().createVersionSetting(id);
vs = service().getVersionSetting(id);
if (vs == null)
return;
vs.setUsesGlobal(false);
} else
vs.setUsesGlobal(false);
propertyChanged.execute("selectedMinecraftVersion");
selectedVersionChangedEvent.execute(selectedMinecraftVersion);
propertyChanged.fire(new PropertyChangedEvent<>(this, "selectedMinecraftVersion", selectedMinecraftVersion, selectedMinecraftVersion));
}
public void makeVersionSettingGlobal(String id) {
@@ -121,8 +118,7 @@ public final class Profile {
if (vs == null)
return;
vs.setUsesGlobal(true);
propertyChanged.execute("selectedMinecraftVersion");
selectedVersionChangedEvent.execute(selectedMinecraftVersion);
propertyChanged.fire(new PropertyChangedEvent<>(this, "selectedMinecraftVersion", selectedMinecraftVersion, selectedMinecraftVersion));
}
public String getSettingsSelectedMinecraftVersion() {
@@ -141,12 +137,10 @@ public final class Profile {
return StrUtils.isBlank(v) ? null : v;
}
public transient final EventHandler<String> selectedVersionChangedEvent = new EventHandler<>(this);
public void setSelectedMinecraftVersion(String selectedMinecraftVersion) {
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "selectedMinecraftVersion", this.selectedMinecraftVersion, selectedMinecraftVersion);
this.selectedMinecraftVersion = selectedMinecraftVersion;
propertyChanged.execute("selectedMinecraftVersion");
selectedVersionChangedEvent.execute(selectedMinecraftVersion);
propertyChanged.fire(event);
}
public String getGameDir() {
@@ -168,9 +162,10 @@ public final class Profile {
}
public Profile setGameDir(String gameDir) {
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "gameDir", this.gameDir, gameDir);
this.gameDir = gameDir;
service().version().refreshVersions();
propertyChanged.execute("gameDir");
propertyChanged.fire(event);
return this;
}
@@ -179,8 +174,9 @@ public final class Profile {
}
void setName(String name) {
PropertyChangedEvent event = new PropertyChangedEvent<>(this, "name", this.name, name);
this.name = name;
propertyChanged.execute("name");
propertyChanged.fire(event);
}
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.download.DownloadType;
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.MessageBox;
import org.jackhuang.hellominecraft.util.UpdateChecker;
@@ -54,7 +56,6 @@ public final class Settings {
static {
SETTINGS = initSettings();
SETTINGS.downloadTypeChangedEvent.register(DownloadType::setSuggestedDownloadType);
DownloadType.setSuggestedDownloadType(SETTINGS.getDownloadSource());
if (!getProfiles().containsKey(DEFAULT_PROFILE))
getProfiles().put(DEFAULT_PROFILE, new Profile(DEFAULT_PROFILE));
@@ -156,19 +157,16 @@ public final class Settings {
return flag;
}
public static final EventHandler<Profile> profileChangedEvent = new EventHandler<>(null);
public static final EventHandler<Void> profileLoadingEvent = new EventHandler<>(null);
static void onProfileChanged() {
Profile p = getLastProfile();
if (p == null)
throw new Error("No profiles here, it should not happen");
profileChangedEvent.execute(p);
HMCLAPI.EVENT_BUS.fireChannel(new ProfileChangedEvent(SETTINGS, p.getName()));
p.onSelected();
}
public static void onProfileLoading() {
profileLoadingEvent.execute(null);
HMCLAPI.EVENT_BUS.fireChannel(new ProfileLoadingEvent(SETTINGS));
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.version.GameDirType;
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.log.HMCLog;
import org.jackhuang.hellominecraft.util.sys.Java;
@@ -87,7 +88,7 @@ public class VersionSetting {
@SerializedName("gameDirType")
private int gameDirType;
public transient final EventHandler<String> propertyChanged = new EventHandler<>(this);
public transient final EventHandler<PropertyChangedEvent> propertyChanged = new EventHandler<>();
public VersionSetting() {
fullscreen = usesGlobal = false;
@@ -113,8 +114,9 @@ public class VersionSetting {
}
public void setJavaDir(String javaDir) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "javaDir", this.javaDir, javaDir);
this.javaDir = javaDir;
propertyChanged.execute("javaDir");
propertyChanged.fire(event);
}
public Java getJava() {
@@ -133,6 +135,7 @@ public class VersionSetting {
}
public void setJava(Java java) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "java", this.java, java);
if (java == null)
this.java = Java.JAVA.get(0).getName();
else {
@@ -141,7 +144,7 @@ public class VersionSetting {
return;
this.java = java.getName();
}
propertyChanged.execute("java");
propertyChanged.fire(event);
}
public String getJavaArgs() {
@@ -151,8 +154,9 @@ public class VersionSetting {
}
public void setJavaArgs(String javaArgs) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "javaArgs", this.javaArgs, javaArgs);
this.javaArgs = javaArgs;
propertyChanged.execute("javaArgs");
propertyChanged.fire(event);
}
public String getMaxMemory() {
@@ -162,8 +166,9 @@ public class VersionSetting {
}
public void setMaxMemory(String maxMemory) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "maxMemory", this.maxMemory, maxMemory);
this.maxMemory = maxMemory;
propertyChanged.execute("maxMemory");
propertyChanged.fire(event);
}
public String getWidth() {
@@ -173,8 +178,9 @@ public class VersionSetting {
}
public void setWidth(String width) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "width", this.width, width);
this.width = width;
propertyChanged.execute("width");
propertyChanged.fire(event);
}
public String getHeight() {
@@ -184,8 +190,9 @@ public class VersionSetting {
}
public void setHeight(String height) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "height", this.height, height);
this.height = height;
propertyChanged.execute("height");
propertyChanged.fire(event);
}
public boolean isFullscreen() {
@@ -193,8 +200,9 @@ public class VersionSetting {
}
public void setFullscreen(boolean fullscreen) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "fullscreen", this.fullscreen, fullscreen);
this.fullscreen = fullscreen;
propertyChanged.execute("fullscreen");
propertyChanged.fire(event);
}
public LauncherVisibility getLauncherVisibility() {
@@ -202,8 +210,9 @@ public class VersionSetting {
}
public void setLauncherVisibility(LauncherVisibility launcherVisibility) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "launcherVisibility", this.launcherVisibility, launcherVisibility);
this.launcherVisibility = launcherVisibility.ordinal();
propertyChanged.execute("launcherVisibility");
propertyChanged.fire(event);
}
public GameDirType getGameDirType() {
@@ -213,8 +222,9 @@ public class VersionSetting {
}
public void setGameDirType(GameDirType gameDirType) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "gameDirType", this.gameDirType, gameDirType);
this.gameDirType = gameDirType.ordinal();
propertyChanged.execute("gameDirType");
propertyChanged.fire(event);
}
public String getPermSize() {
@@ -222,8 +232,9 @@ public class VersionSetting {
}
public void setPermSize(String permSize) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "permSize", this.permSize, permSize);
this.permSize = permSize;
propertyChanged.execute("permSize");
propertyChanged.fire(event);
}
public boolean isNoJVMArgs() {
@@ -231,8 +242,9 @@ public class VersionSetting {
}
public void setNoJVMArgs(boolean noJVMArgs) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "noJVMArgs", this.noJVMArgs, noJVMArgs);
this.noJVMArgs = noJVMArgs;
propertyChanged.execute("noJVMArgs");
propertyChanged.fire(event);
}
public String getMinecraftArgs() {
@@ -240,8 +252,9 @@ public class VersionSetting {
}
public void setMinecraftArgs(String minecraftArgs) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "minecraftArgs", this.minecraftArgs, minecraftArgs);
this.minecraftArgs = minecraftArgs;
propertyChanged.execute("minecraftArgs");
propertyChanged.fire(event);
}
public String getPrecalledCommand() {
@@ -249,8 +262,9 @@ public class VersionSetting {
}
public void setPrecalledCommand(String precalledCommand) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "precalledCommand", this.precalledCommand, precalledCommand);
this.precalledCommand = precalledCommand;
propertyChanged.execute("precalledCommand");
propertyChanged.fire(event);
}
public String getWrapper() {
@@ -258,8 +272,9 @@ public class VersionSetting {
}
public void setWrapper(String wrapper) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "wrapper", this.wrapper, wrapper);
this.wrapper = wrapper;
propertyChanged.execute("wrapper");
propertyChanged.fire(event);
}
public String getServerIp() {
@@ -267,8 +282,9 @@ public class VersionSetting {
}
public void setServerIp(String serverIp) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "serverIp", this.serverIp, serverIp);
this.serverIp = serverIp;
propertyChanged.execute("serverIp");
propertyChanged.fire(event);
}
public boolean isNotCheckGame() {
@@ -276,8 +292,9 @@ public class VersionSetting {
}
public void setNotCheckGame(boolean notCheckGame) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "notCheckGame", this.notCheckGame, notCheckGame);
this.notCheckGame = notCheckGame;
propertyChanged.execute("notCheckGame");
propertyChanged.fire(event);
}
public boolean isUsesGlobal() {
@@ -285,8 +302,9 @@ public class VersionSetting {
}
public void setUsesGlobal(boolean usesGlobal) {
PropertyChangedEvent event = new PropertyChangedEvent(this, "usesGlobal", this.usesGlobal, usesGlobal);
this.usesGlobal = usesGlobal;
propertyChanged.execute("usesGlobal");
propertyChanged.fire(event);
}
public LaunchOptions createLaunchOptions(File gameDir) {

View File

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

View File

@@ -52,7 +52,7 @@
<Group type="102" alignment="0" attributes="0">
<Component id="pnlTop" min="-2" 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"/>
<Group type="103" groupAlignment="3" 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;
import org.jackhuang.hellominecraft.util.ui.Page;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
@@ -37,10 +38,15 @@ import javax.swing.DefaultComboBoxModel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
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.util.C;
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.core.mod.ModInfo;
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.MinecraftVersion;
import org.jackhuang.hellominecraft.launcher.setting.VersionSetting;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.AbstractSwingWorker;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.util.MinecraftVersionRequest;
import org.jackhuang.hellominecraft.util.sys.OS;
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 {
boolean isLoading = false;
boolean showedNoVersion = false;
public MinecraftVersionRequest minecraftVersion;
String mcVersion;
final InstallerPanel installerPanels[] = new InstallerPanel[InstallerType.values().length];
public GameSettingsPanel(MainFrame mf) {
mf.actions.put("showGameDownloads", () -> {
MainFrame.INSTANCE.selectTab("game");
showGameDownloads();
public GameSettingsPanel() {
HMCLAPI.EVENT_BUS.channel(RefreshedVersionsEvent.class).register(t -> {
if (Settings.getLastProfile().service() == t.getValue())
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);
@@ -92,6 +105,8 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
void initGui() {
initComponents();
animationEnabled = Settings.getInstance().isEnableAnimation();
dropTarget = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
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());
isLoading = false;
Settings.profileLoadingEvent.register(onLoadingProfiles);
Settings.profileChangedEvent.register(onSelectedProfilesChanged);
HMCLAPI.EVENT_BUS.channel(ProfileLoadingEvent.class).register(onLoadingProfiles);
HMCLAPI.EVENT_BUS.channel(ProfileChangedEvent.class).register(onSelectedProfilesChanged);
HMCLAPI.EVENT_BUS.channel(RefreshedVersionsEvent.class).register(onRefreshedVersions);
}
void initExplorationMenu() {
@@ -1437,8 +1453,8 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
isLoading = false;
}
final Consumer<IMinecraftService> onRefreshedVersions = t -> {
if (Settings.getLastProfile().service() == t)
final Consumer<RefreshedVersionsEvent> onRefreshedVersions = t -> {
if (Settings.getLastProfile().service() == t.getValue())
loadVersions();
};
@@ -1451,11 +1467,9 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
}
cboVersions.setModel(model);
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) {
isLoading = true;
DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) cboVersions.getModel();
@@ -1477,9 +1491,12 @@ public final class GameSettingsPanel extends RepaintPage implements DropTargetLi
isLoading = false;
}
final Consumer<Profile> onSelectedProfilesChanged = t -> {
t.service().version().onRefreshedVersions.register(onRefreshedVersions);
t.selectedVersionChangedEvent.register(selectedVersionChangedEvent);
final Consumer<ProfileChangedEvent> onSelectedProfilesChanged = event -> {
Profile t = Settings.getProfile(event.getValue());
t.propertyChanged.register(e -> {
if ("selectedMinecraftVersion".equals(e.getPropertyName()))
versionChanged(e.getNewValue());
});
txtGameDir.setText(t.getGameDir());

View File

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

View File

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

View File

@@ -19,16 +19,21 @@ package org.jackhuang.hellominecraft.launcher.ui;
import java.io.File;
import java.io.IOException;
import java.util.List;
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.core.launch.GameLauncher;
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchingState;
import org.jackhuang.hellominecraft.launcher.setting.Profile;
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.util.C;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.log.HMCLog;
@@ -43,118 +48,127 @@ import org.jackhuang.hellominecraft.util.net.WebFrame;
*/
public class LaunchingUIDaemon {
Runnable customizedSuccessEvent = null;
void runGame(Profile profile) {
MainFrame.INSTANCE.showMessage(C.i18n("ui.message.launching"));
profile.launcher().genLaunchCode(value -> {
value.launchingStateChangedEvent.register(LAUNCHING_STATE_CHANGED);
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()) {
public LaunchingUIDaemon() {
HMCLAPI.EVENT_BUS.channel(LaunchingStateChangedEvent.class).register(LAUNCHING_STATE_CHANGED);
HMCLAPI.EVENT_BUS.channel(LaunchEvent.class).register(p -> {
GameLauncher obj = (GameLauncher) p.getSource();
HMCLGameLauncher.GameLauncherTag tag = (HMCLGameLauncher.GameLauncherTag) obj.getTag();
if (tag.launcherVisibility == 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\".");
System.exit(0);
} else if ((LauncherVisibility) obj.getTag() == LauncherVisibility.KEEP)
} else if (tag.launcherVisibility == LauncherVisibility.KEEP)
MainFrame.INSTANCE.closeMessage();
else {
if (LogWindow.INSTANCE.isVisible())
LogWindow.INSTANCE.setExit(() -> true);
MainFrame.INSTANCE.dispose();
}
JavaProcessMonitor jpm = new JavaProcessMonitor(p);
jpm.applicationExitedAbnormallyEvent.register(t -> {
HMCLog.err("The game exited abnormally, exit code: " + t);
String[] logs = jpm.getJavaProcess().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: " + 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();
// We promise that JavaProcessMonitor.tag is LauncherVisibility
// See events below.
JavaProcessMonitor monitor = new JavaProcessMonitor(p.getValue());
monitor.setTag(tag.launcherVisibility);
monitor.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 {
obj.launch(str);
((GameLauncher) event.getSource()).launch(event.getValue());
} catch (IOException e) {
MainFrame.INSTANCE.failed(C.i18n("launch.failed_creating_process") + "\n" + e.getMessage());
HMCLog.err("Failed to launch when creating a new process.", e);
}
return true;
};
private static void checkExit(LauncherVisibility v) {
if (v != LauncherVisibility.KEEP && !LogWindow.INSTANCE.isVisible()) {
HMCLog.log("Launcher will exit now.");
System.exit(0);
} else {
HMCLog.log("Launcher will not exit now.");
}
}
private static final Event<List<String>> LAUNCH_SCRIPT_FINISHER = (sender, str) -> {
boolean flag = false;
private static final Consumer<LaunchSucceededEvent> LAUNCH_SCRIPT_FINISHER = event -> {
try {
String s = JOptionPane.showInputDialog(C.i18n("mainwindow.enter_script_name"));
if (s != null)
MessageBox.show(C.i18n("mainwindow.make_launch_succeed") + " " + ((GameLauncher) sender).makeLauncher(s, str).getAbsolutePath());
flag = true;
MessageBox.show(C.i18n("mainwindow.make_launch_succeed") + " " + ((GameLauncher) event.getSource()).makeLauncher(s, event.getValue()).getAbsolutePath());
} catch (IOException ex) {
MessageBox.show(C.i18n("mainwindow.make_launch_script_failed"));
HMCLog.err("Failed to create script file.", ex);
}
MainFrame.INSTANCE.closeMessage();
return flag;
};
}

View File

@@ -17,6 +17,7 @@
*/
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.IRepaint;
import java.awt.BorderLayout;
@@ -50,7 +51,10 @@ import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.jackhuang.hellominecraft.api.HMCLAPI;
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.setting.Settings;
import org.jackhuang.hellominecraft.lookandfeel.Theme;
@@ -155,7 +159,7 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
}
((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"));
}
@@ -185,9 +189,7 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
header.add(Box.createRigidArea(new Dimension(8, 0)));
initializeTab(new MainPagePanel(), "main");
initializeTab(new GameSettingsPanel(this), "game");
initializeTab(new LauncherSettingsPanel(), "launcher");
PluginManager.fireAddTab(this, this::initializeTab);
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 void initializeTab(Page inst, String cmd) {
HeaderTab tab = new HeaderTab(C.i18n("launcher.title." + cmd));
private void initializeTab(Page inst, String cmd, String title) {
HeaderTab tab = new HeaderTab(title);
tab.setActionCommand(cmd);
tab.setForeground(BasicColors.COLOR_WHITE_TEXT);
tab.setBackground(borderColorDarker);
@@ -489,9 +491,4 @@ public final class MainFrame extends DraggableFrame implements IRepaint {
}
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;
import org.jackhuang.hellominecraft.util.ui.Page;
import org.jackhuang.hellominecraft.util.ui.WideComboBox;
import org.jackhuang.hellominecraft.util.ui.GaussionPanel;
import java.awt.CardLayout;
@@ -28,18 +29,22 @@ import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
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.launcher.core.auth.IAuthenticator;
import org.jackhuang.hellominecraft.launcher.setting.Profile;
import org.jackhuang.hellominecraft.util.MessageBox;
import org.jackhuang.hellominecraft.util.StrUtils;
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
import org.jackhuang.hellominecraft.launcher.setting.Settings;
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.util.HMCLMinecraftService;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.lookandfeel.ConstomButton;
import org.jackhuang.hellominecraft.util.func.Consumer;
import org.jackhuang.hellominecraft.util.sys.FileUtils;
@@ -60,7 +65,7 @@ public class MainPagePanel extends Page {
void initGui() {
initComponents();
animationEnabled = false;
pnlButtons = new javax.swing.JPanel();
@@ -86,19 +91,20 @@ public class MainPagePanel extends Page {
pnlMore.setBackground(GraphicsUtils.getWebColorWithAlpha("FFFFFF7F"));
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())
((GaussionPanel) pnlRoot).addAeroObject(pnlMore);
((GaussionPanel) pnlRoot).setBackgroundImage(MainFrame.INSTANCE.background.getImage());
((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
// <editor-fold defaultstate="collapsed" desc="Loads">
private void prepareAuths() {
preparingAuth = true;
cboLoginMode.removeAllItems();
@@ -460,8 +465,8 @@ public class MainPagePanel extends Page {
private javax.swing.JTextField txtPlayerName;
// End of variables declaration//GEN-END:variables
final Event<IAuthenticator> onAuthChanged = (sender, l) -> {
if (l.hasPassword()) {
final Consumer<AuthenticatorChangedEvent> onAuthChanged = (x) -> {
if (x.getValue().hasPassword()) {
pnlPassword.setVisible(true);
lblUserName.setText(C.i18n("login.account"));
} else {
@@ -470,16 +475,14 @@ public class MainPagePanel extends Page {
}
CardLayout cl = (CardLayout) pnlPassword.getLayout();
if (l.isLoggedIn())
if (x.getValue().isLoggedIn())
cl.last(pnlPassword);
else
cl.first(pnlPassword);
String username = l.getUserName();
String username = x.getValue().getUserName();
if (username == null)
username = "";
txtPlayerName.setText(username);
return true;
};
final Runnable onLoadingProfiles = () -> {
@@ -491,8 +494,8 @@ public class MainPagePanel extends Page {
isLoading = false;
};
final Consumer<IMinecraftService> onRefreshedVersions = t -> {
if (Settings.getLastProfile().service() == t)
final Consumer<RefreshedVersionsEvent> onRefreshedVersions = t -> {
if (Settings.getLastProfile().service() == t.getValue())
loadVersions();
};
@@ -502,28 +505,18 @@ public class MainPagePanel extends Page {
isLoading = true;
cboVersions.removeAllItems();
String selVersion = Settings.getLastProfile().getSelectedVersion();
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 {
if (!Settings.getLastProfile().service().version().getVersions().isEmpty()) {
for (MinecraftVersion mcVersion : Settings.getLastProfile().service().version().getVersions()) {
if (mcVersion.hidden)
continue;
cboVersions.addItem(mcVersion.id);
}
versionChanged.accept(selVersion);
versionChanged(selVersion);
}
isLoading = false;
}
final Consumer<Boolean> launchingStateChanged = t -> SwingUtils.setEnabled(MainFrame.INSTANCE.getRootPane(), !t);
final Consumer<String> versionChanged = this::versionChanged;
final Consumer<LaunchingStateChangedEvent> launchingStateChanged = t -> SwingUtils.setEnabled(MainFrame.INSTANCE.getRootPane(), t.getValue() == LaunchingState.Done);
void versionChanged(String selectedVersion) {
isLoading = true;
@@ -536,10 +529,12 @@ public class MainPagePanel extends Page {
isLoading = false;
}
final Consumer<Profile> onSelectedProfilesChanged = t -> {
t.service().version().onRefreshedVersions.register(onRefreshedVersions);
t.selectedVersionChangedEvent.register(versionChanged);
t.launcher().launchingStateChanged.register(launchingStateChanged);
final Consumer<ProfileChangedEvent> onSelectedProfilesChanged = event -> {
Profile t = Settings.getProfile(event.getValue());
t.propertyChanged.register(e -> {
if ("selectedMinecraftVersion".equals(e.getPropertyName()))
versionChanged(e.getNewValue());
});
isLoading = true;
DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) cboProfiles.getModel();

View File

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

View File

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

View File

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

View File

@@ -18,7 +18,6 @@
package org.jackhuang.hellominecraft.launcher.util;
import java.io.File;
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
import org.jackhuang.hellominecraft.launcher.core.GameException;
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
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.Settings;
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.log.HMCLog;
import org.jackhuang.hellominecraft.util.sys.JavaProcess;
/**
*
@@ -42,15 +47,15 @@ public class HMCLGameLauncher {
Profile profile;
boolean isLaunching = false;
public final EventHandler<Boolean> launchingStateChanged = new EventHandler<>(this);
public HMCLGameLauncher(Profile p) {
this.profile = p;
HMCLAPI.EVENT_BUS.channel(LaunchSucceededEvent.class).register(() -> setLaunching(false));
}
void setLaunching(boolean isLaunching) {
if (isLaunching != this.isLaunching)
launchingStateChanged.execute(isLaunching);
HMCLAPI.EVENT_BUS.fireChannel(new LaunchingStateChangedEvent(this, isLaunching ? LaunchingState.Starting : LaunchingState.Done));
this.isLaunching = isLaunching;
}
@@ -80,13 +85,14 @@ public class HMCLGameLauncher {
Thread.currentThread().setName("Game Launcher");
try {
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);
gl.setTag(profile.getSelectedVersionSetting().getLauncherVisibility());
gl.successEvent.register(() -> setLaunching(false));
GameLauncherTag tag = new GameLauncherTag();
tag.launcherVisibility = profile.getSelectedVersionSetting().getLauncherVisibility();
gl.setTag(tag);
listener.accept(gl);
gl.makeLaunchCommand();
} catch (GameException e) {
} catch (GameException | RuntimeGameException e) {
failed.accept(C.i18n("launch.failed") + ", " + e.getMessage());
setLaunching(false);
} catch (AuthenticationException e) {
@@ -99,4 +105,9 @@ public class HMCLGameLauncher {
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.Map;
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.install.MinecraftInstallerService;
import org.jackhuang.hellominecraft.launcher.core.asset.MinecraftAssetService;
@@ -53,8 +57,8 @@ public class HMCLMinecraftService extends IMinecraftService {
this.p = p;
this.provider = new HMCLGameProvider(this);
provider.initializeMiencraft();
provider.onRefreshingVersions.register(versionSettings::clear);
provider.onRefreshedVersions.register(() -> {
HMCLAPI.EVENT_BUS.channel(RefreshingVersionsEvent.class).register(versionSettings::clear);
HMCLAPI.EVENT_BUS.channel(RefreshedVersionsEvent.class).registerFirst(() -> {
if (!checkingModpack) {
checkingModpack = true;
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.mds = new MinecraftDownloadService(this);
this.mas = new MinecraftAssetService(this);
@@ -105,10 +109,7 @@ public class HMCLMinecraftService extends IMinecraftService {
private void initVersionSetting(String id, VersionSetting vs) {
vs.id = id;
vs.propertyChanged.register((sender, t) -> {
saveVersionSetting(((VersionSetting) sender).id);
return true;
});
vs.propertyChanged.register(event -> saveVersionSetting(((VersionSetting) event.getSource()).id));
versionSettings.put(id, vs);
}

View File

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

View File

@@ -17,14 +17,15 @@
*/
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.func.Consumer;
/**
*
* @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();
@@ -48,5 +49,5 @@ public abstract class IUpgrader implements Event<VersionNumber> {
* @return should return true
*/
@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.IOException;
import org.jackhuang.hellominecraft.api.SimpleEvent;
import org.jackhuang.hellominecraft.util.log.HMCLog;
import org.jackhuang.hellominecraft.util.task.TaskWindow;
import org.jackhuang.hellominecraft.util.net.FileDownloadTask;
@@ -45,7 +46,7 @@ public class NewFileUpgrader extends IUpgrader {
}
@Override
public boolean call(Object sender, VersionNumber number) {
public void accept(SimpleEvent<VersionNumber> event) {
String str = requestDownloadLink();
File newf = new File(FileUtils.getName(str));
if (TaskWindow.factory().append(new FileDownloadTask(str, newf)).execute()) {
@@ -56,7 +57,6 @@ public class NewFileUpgrader extends IUpgrader {
}
System.exit(0);
}
return true;
}
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.WaitForThread;
import org.jackhuang.hellominecraft.svrmgr.util.Utilities;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.util.EventHandler;
import org.jackhuang.hellominecraft.api.Event;
import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.util.code.Charsets;
import org.jackhuang.hellominecraft.util.func.Consumer;
@@ -133,7 +133,7 @@ public class Server implements Event<Integer>, MonitorThread.MonitorThreadListen
registerThreadC(server);
bw = new BufferedWriter(new OutputStreamWriter(server.getOutputStream(), Charsets.toCharset()));
isRunning = true;
startedEvent.execute(null);
startedEvent.fire(null);
sendStatus("*** 启动服务端中 ***");
} catch (IOException 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 \"\\?\"");
Matcher m = p.matcher(status);
if (m.find()) {
stoppedEvent.execute(null);
stoppedEvent.fire(null);
timer = new Timer();
timerTasks.clear();
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.svrmgr.util.version.MinecraftRemoteVersion;
import org.jackhuang.hellominecraft.lookandfeel.ConstomButton;
import org.jackhuang.hellominecraft.util.Event;
import org.jackhuang.hellominecraft.api.Event;
import org.jackhuang.hellominecraft.util.StrUtils;
/**

View File

@@ -17,7 +17,7 @@
*/
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;
/**
@@ -37,10 +37,10 @@ public class WaitForThread extends Thread {
public void run() {
try {
int exitCode = p.waitFor();
event.execute(exitCode);
event.fire(exitCode);
} catch (InterruptedException 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
* 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.EventObject;
import org.jackhuang.hellominecraft.util.func.Consumer;
/**
@@ -25,18 +26,11 @@ import org.jackhuang.hellominecraft.util.func.Consumer;
* @author huangyuhui
* @param <T> EventArgs
*/
public class EventHandler<T> {
public class EventHandler<T extends EventObject> {
ArrayList<Object> events = new ArrayList<>();
Object sender;
public EventHandler(Object sender) {
this.sender = sender;
}
public void register(Event<T> t) {
if (!events.contains(t))
events.add(t);
public EventHandler() {
}
public void register(Consumer<T> t) {
@@ -44,20 +38,40 @@ public class EventHandler<T> {
events.add(t);
}
public void registerFirst(Consumer<T> t) {
if (!events.contains(t))
events.add(0, t);
}
public void register(Runnable t) {
if (!events.contains(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;
for (Object t : events)
if (t instanceof Event) {
if (!((Event<T>) t).call(sender, x))
if (t instanceof Consumer) {
((Consumer) t).accept(x);
if (!event.result())
flag = false;
} else if (t instanceof Consumer)
((Consumer<T>) t).accept(x);
else if (t instanceof Runnable)
} else if (t instanceof Runnable)
((Runnable) t).run();
return flag;
}

View File

@@ -1,7 +1,7 @@
/*
* Hello Minecraft!.
* 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
@@ -15,14 +15,16 @@
* 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.util;
package org.jackhuang.hellominecraft.api;
/**
*
* @author huangyuhui
* @param <T> EventArgs
* @author huang
*/
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;
import org.jackhuang.hellominecraft.api.EventHandler;
import org.jackhuang.hellominecraft.util.net.NetUtils;
import com.google.gson.JsonSyntaxException;
import java.io.IOException;
import org.jackhuang.hellominecraft.util.log.HMCLog;
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
public void checkOutdate() {
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;
import java.util.EventListener;
/**
*
* @author huangyuhui
*/
public interface Consumer<T> {
public interface Consumer<T> extends EventListener {
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.log.HMCLog;
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.task.Task;
@@ -39,7 +40,7 @@ public class HTTPGetTask extends Task implements PreviousResult<String> {
String url, result;
Charset encoding;
EventHandler<String> doneEvent = new EventHandler<>(this);
EventHandler<SimpleEvent<String>> doneEvent = new EventHandler<>();
boolean shouldContinue = true;
public HTTPGetTask(String url) {
@@ -81,7 +82,7 @@ public class HTTPGetTask extends Task implements PreviousResult<String> {
return;
}
result = baos.toString(encoding.name());
doneEvent.execute(result);
doneEvent.fire(new SimpleEvent<>(this, result));
return;
} catch (IOException 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.HashSet;
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.log.HMCLog;
import org.jackhuang.hellominecraft.util.log.Level;
@@ -32,20 +37,6 @@ import org.jackhuang.hellominecraft.util.log.Level;
public class JavaProcessMonitor {
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;
public JavaProcessMonitor(JavaProcess p) {
@@ -55,24 +46,35 @@ public class JavaProcessMonitor {
public JavaProcess getJavaProcess() {
return p;
}
private Object tag;
public Object getTag() {
return tag;
}
public void setTag(Object tag) {
this.tag = tag;
}
public void start() {
HMCLAPI.EVENT_BUS.fireChannel(new JavaProcessStartingEvent(this, p));
ProcessThread a = new ProcessThread(p);
a.stopEvent.register((sender, t) -> {
HMCLog.log("Process exit code: " + t.getExitCode());
if (t.getExitCode() != 0 || StrUtils.containsOne(t.getStdOutLines(),
a.stopEvent.register(event -> {
HMCLog.log("Process exit code: " + p.getExitCode());
if (p.getExitCode() != 0 || StrUtils.containsOne(p.getStdOutLines(),
Arrays.asList("Unable to launch"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
applicationExitedAbnormallyEvent.execute(t.getExitCode());
if (t.getExitCode() != 0 && StrUtils.containsOne(t.getStdOutLines(),
HMCLAPI.EVENT_BUS.fireChannel(new JavaProcessExitedAbnormallyEvent(JavaProcessMonitor.this, p));
if (p.getExitCode() != 0 && StrUtils.containsOne(p.getStdOutLines(),
Arrays.asList("Could not create the Java Virtual Machine.",
"Error occurred during initialization of VM",
"A fatal exception has occurred. Program will exit.",
"Unable to launch"),
x -> Level.guessLevel(x, Level.INFO).lessOrEqual(Level.ERROR)))
jvmLaunchFailedEvent.execute(t.getExitCode());
processThreadStopped((ProcessThread) sender, false);
return true;
HMCLAPI.EVENT_BUS.fireChannel(new JVMLaunchFailedEvent(JavaProcessMonitor.this, p));
processThreadStopped((ProcessThread) event.getSource(), false);
});
a.start();
al.add(a);
@@ -84,7 +86,7 @@ public class JavaProcessMonitor {
for (Thread a : al)
a.interrupt();
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.InputStreamReader;
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;
/**
@@ -33,8 +34,8 @@ public class ProcessThread extends Thread {
JavaProcess p;
public final EventHandler<String> printlnEvent = new EventHandler<>(this);
public final EventHandler<JavaProcess> stopEvent = new EventHandler<>(this);
public final EventHandler<SimpleEvent<String>> printlnEvent = new EventHandler<>();
public final EventHandler<SimpleEvent<JavaProcess>> stopEvent = new EventHandler<>();
public ProcessThread(JavaProcess process) {
p = process;
@@ -55,18 +56,18 @@ public class ProcessThread extends Thread {
String line;
while (p.isRunning())
while ((line = br.readLine()) != null) {
printlnEvent.execute(line);
System.out.println("Minecraft: " + line);
printlnEvent.fire(new SimpleEvent<>(this, line));
System.out.println("MC: " + line);
p.getStdOutLines().add(line);
}
while ((line = br.readLine()) != null) {
printlnEvent.execute(line);
System.out.println("Minecraft: " + line);
printlnEvent.fire(new SimpleEvent<>(this, line));
System.out.println("MC: " + line);
p.getStdOutLines().add(line);
}
if (p.getProcessManager() != null)
p.getProcessManager().onProcessStopped(p);
stopEvent.execute(p);
stopEvent.fire(new SimpleEvent<>(this, p));
} catch (IOException e) {
HMCLog.err("An error occured when reading process stdout/stderr.", e);
} finally {

View File

@@ -20,6 +20,7 @@ package org.jackhuang.hellominecraft.util.task;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EventObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -29,7 +30,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
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;
/**
@@ -39,7 +40,7 @@ import org.jackhuang.hellominecraft.util.log.HMCLog;
public class TaskList extends Thread {
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<>();
int totTask;
@@ -159,7 +160,7 @@ public class TaskList extends Thread {
executeTask(taskQueue.remove(0));
if (shouldContinue) {
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
* 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.Graphics;
@@ -24,7 +24,6 @@ import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import org.jackhuang.hellominecraft.launcher.setting.Settings;
/**
*
@@ -118,10 +117,10 @@ public class Page extends JPanel implements Selectable {
Timer timer;
boolean animationEnabled = true;
protected boolean animationEnabled = true;
public void animate() {
if (Settings.getInstance().isEnableAnimation() && animationEnabled) {
if (animationEnabled) {
offsetX = 0;
timer.start();
}

View File

@@ -15,7 +15,7 @@
* 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.ui;
package org.jackhuang.hellominecraft.util.ui;
/**
*