MrLetsplay2003/ShittyAuthLauncher

[Suggestion] Plugin API?

Closed this issue · 19 comments

A plugin API would allow people to possibly rebrand the launcher and add new UI features without people actually having to fork this and change the aspects they want.

This could include

  • Changing Launcher's name, version( even the ones sent to the authentication servers ) and icons. Could be used by mod packs that use custom launchers, to match the branding of the mod packs
  • Changing the Default Mirror, add and delete authentication servers (methods). Good for some servers that use their own launcher and auth servers
  • (Complex) Add new UI features e.g. specialised tabs at the top which could open various JavaFX elements - like a custom side bar or a popup.
  • Adding, deleting and changing themes.
  • Load plugins from a folder or the class path. Loading from class path would allow people to package their plugin in the same jar as the launcher.

I know of a library called PF4J (Plugin Framework for Java). You may see how I use it in my game.

Also an auto updater which could be configured by plugins?

I've been experimenting with this for the last few days (as you can see in the latest commits to the launcher). I've implemented some of the features you've listed but am unsure about some things.

  • What exactly do you mean by adding adding authentication servers (methods)? Would that include supporting other authentication schemes?
  • I don't know whether deleting stuff from the launcher is useful, same with changing themes. Plugins can change the defaults for these anyway, so I don't see a reason for that.

The authentication servers (methods) would be selecting between custom and Shityauth in the new account window. This would be useful for cracked servers with their own launcher and want to restrict the use of it.

So it would basically change it, so the launcher will only use your server when adding an account?

Yes

Maybe also find all plugins on the class path and. This line in my game uses a special class which can be used to find all types of an object on the class path.

Also have a way to change the "Play Minecraft" button, Good for special modpacks with their own launcher.

Maybe also find all plugins on the class path

As I understand it, PF4J loads Extension classes from the class path by default, but doesn't run actual plugin code (e.g. in start()) or create an instance of Plugin, so e.g. adding themes would still work when the plugin is on the classpath.

Also have a way to change the "Play Minecraft" button, Good for special modpacks with their own launcher.

What exactly would you need to change about the "Play Minecraft" button?

Some modpacks or servers may want to change the "Play Minecraft" into "Play %name_here%" and only restrict the user to special versions of Minecraft (with download mirrors).

For theming / branding purposes a plugin might want to change some icons (e.g. the installation icon), so a plugin can make icons match more with their custom themes

So you mean having a different installation icon to the launcher icon?

Just defining different images for any icon in the program would be fine

Maybe also a way for the plugin to change the data / installations directories so different data can be kept separately when using different plugins, also allows branding for special servers or modpacks. For example %appdata%/.shittyauthlauncher becomes ```%appdata%/name_here% and the same idea for thee installation directory. This can also allow plugins to keep different launcher versions' data in separate places, a menu could be provided (by the plugin) by using modifiable JavaFX pages to specify where the directory should be.

Maybe the Minecraft Version string should become %name_here% Version because its inconsistent with the play button

Maybe the Edit Servers button for accounts should be disabled if DefaultsProvider#allowCustomServerConfigurations() is false. Or maybe have a DefaultsProvider#allowEditServerConfigurations() which will return true or false

Also the BrandingProvider#loadIcon() seems to override the account's skin icon

Actually it seems like I get a certificate error. Don't know why because it is liked everywhere else.

Session/skin server for account 'samuelh2005@https://minersonline.tk/api' is unreachable
Exception in thread "JavaFX Application Thread" me.mrletsplay.mrcore.http.HttpException: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at me.mrletsplay.mrcore.http.HttpGeneric.execute(HttpGeneric.java:158)
	at me.mrletsplay.mrcore.http.HttpGet.execute(HttpGet.java:79)
	at me.mrletsplay.shittyauthlauncher.util.SkinHelper.loadSkinHead(SkinHelper.java:30)
	at me.mrletsplay.shittyauthlauncher.util.SkinHelper.getSkinHead(SkinHelper.java:51)
	at me.mrletsplay.shittyauthlauncher.ShittyAuthController.createAccountItem(ShittyAuthController.java:485)
	at me.mrletsplay.shittyauthlauncher.ShittyAuthController.lambda$init$4(ShittyAuthController.java:138)
	at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
	at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
	at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:239)
	at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
	at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
	at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:211)
	at javafx.collections.ModifiableObservableListBase.addAll(ModifiableObservableListBase.java:109)
	at me.mrletsplay.shittyauthlauncher.ShittyAuthController.init(ShittyAuthController.java:141)
	at me.mrletsplay.shittyauthlauncher.ShittyAuthLauncher.start(ShittyAuthLauncher.java:40)
	at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
	at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
	at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
	at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
	at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:576)
	at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:123)
	at me.mrletsplay.mrcore.http.HttpGeneric.execute(HttpGeneric.java:156)
	... 23 more
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:371)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:314)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:309)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1351)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1226)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1169)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480)
	at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1277)
	at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1264)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
	at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1209)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.lambda$executeTasks$3(SSLFlowDelegate.java:1118)
	at java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:155)
	at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.executeTasks(SSLFlowDelegate.java:1113)
	at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.doHandshake(SSLFlowDelegate.java:1079)
	at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:484)
	at java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:268)
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:205)
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$TryEndDeferredCompleter.complete(SequentialScheduler.java:347)
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:151)
	at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:230)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	... 1 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:388)
	at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:271)
	at java.base/sun.security.validator.Validator.validate(Validator.java:256)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:285)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:144)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1329)
	... 23 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
	at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:383)
	... 28 more

I modified the SkinHelper to throw the HttpException

Maybe these

agent.put("name", "Minecraft");
agent.put("version", 1);
should be the game name and launcher version?

Maybe these

agent.put("name", "Minecraft");
agent.put("version", 1);

should be the game name and launcher version?

Those are actually always constant values, as per wiki.vg

Maybe these

agent.put("name", "Minecraft");
agent.put("version", 1);

should be the game name and launcher version?

Those are actually always constant values, as per wiki.vg

But some custom authentication servers may want different values. This then can allow custom authentication servers to enforce the use of their plugin

Maybe also a way for the plugin to change the data / installations directories so different data can be kept separately when using different plugins, also allows branding for special servers or modpacks. For example %appdata%/.shittyauthlauncher becomes ```%appdata%/name_here% and the same idea for thee installation directory. This can also allow plugins to keep different launcher versions' data in separate places, a menu could be provided (by the plugin) by using modifiable JavaFX pages to specify where the directory should be.

I could add the default game data to the DefaultsProvider API, but the launcher data path would be kind of weird to change using a plugin, since plugin (jars) are themselves loaded from the plugins folder inside the data path, so it would be an API only available to plugins on the classpath.

Maybe the Minecraft Version string should become %name_here% Version because its inconsistent with the play button

I've been thinking about just making all of the strings part of some kind of localization file, so everything could be easily changed (and also allowing for different languages). The strings would then just have placeholders for the game name etc.

Also the BrandingProvider#loadIcon() seems to override the account's skin icon

Actually it seems like I get a certificate error. Don't know why because it is liked everywhere else.

Session/skin server for account 'samuelh2005@https://minersonline.tk/api' is unreachable
Exception in thread "JavaFX Application Thread" me.mrletsplay.mrcore.http.HttpException: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
...

I modified the SkinHelper to throw the HttpException

Are you using a self-signed certificate which your OS doesn't trust? Maybe you've added an exception in other places

Maybe these

agent.put("name", "Minecraft");
agent.put("version", 1);

should be the game name and launcher version?

Those are actually always constant values, as per wiki.vg

But some custom authentication servers may want different values. This then can allow custom authentication servers to enforce the use of their plugin

Seems like a niche use-case, considering most authentication servers implementing Yggdrasil will most likely just ignore it, but it could be added to the API as well.