Hi, this is just a crappy tool I made to load a fully working HTML5 website in Java and have a "play" button on that website that will load the .jar client in another window.
I think the code is very poorly written however it should be fully functioning.
Just take into consideration I'm not the best coder and I know you experts will flame me for it! KThxbye
Please please note: You need JavaFX to compile. JavaFX is including with the default JRE (I was using JRE8) however it may not be included in JDK.
The code is in this spoiler tag.
[spoil]
Code:
package com.swagger;
import com.swagger.html.Browser;
public class Main {
public static void main(String[] args) {
Browser b = new Browser();
b.loadURL("http://mywebsite.com/game-launcher/");
}
}
Code:
package com.swagger.client;
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.net.URL;
import java.net.URLClassLoader;
import javax.swing.JFrame;
public final class ClientLoader {
public static void loadClient(String address) throws Exception {
URL url = new URL(address);
WebCrawler crawler = new WebCrawler(url);
ClientStub stub = new ClientStub(url, crawler);
crawler.start();
URLClassLoader loader = new URLClassLoader(new URL[] { new URL(address + crawler.getProperty("archive-name")) });
Class<?> appletClass = loader.loadClass(crawler.getProperty("main-class"));
Applet applet = Applet.class.cast(appletClass.getConstructor().newInstance());
applet.setStub(stub);
applet.setPreferredSize(new Dimension(765, 503));
JFrame frame = new JFrame("RuneScape");
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(applet, BorderLayout.NORTH);
frame.getContentPane().setBackground(Color.BLACK);
frame.setResizable(false);
frame.setVisible(true);
frame.pack();
frame.setLocationRelativeTo(null);
applet.init();
applet.start();
}
}
Code:
package com.swagger.client;
import java.applet.AppletContext;
import java.applet.AppletStub;
import java.net.URL;
public final class ClientStub implements AppletStub {
private final URL url;
private final WebCrawler crawler;
public ClientStub(URL url, WebCrawler crawler) {
this.url = url;
this.crawler = crawler;
}
@Override
public boolean isActive() {
return true;
}
@Override
public URL getDocumentBase() {
return url;
}
@Override
public URL getCodeBase() {
return url;
}
@Override
public String getParameter(String name) {
return crawler.getProperty(name);
}
@Override
public AppletContext getAppletContext() {
throw new RuntimeException("called getAppletContext()");
}
@Override
public void appletResize(int width, int height) {
}
}
Code:
package com.swagger.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class WebCrawler {
private static final Pattern ARCHIVE_PATTERN = Pattern.compile("archive=(.*)\\s+");
private static final Pattern PARAMETER_PATTERN = Pattern.compile("<param name=([^\\s]+)\\s+value=([^>]*)>");
private final Map<String, String> properties = new HashMap<>();
private final URL url;
public WebCrawler(URL url) {
this.url = url;
}
public String getProperty(String key) {
return properties.get(key);
}
public void start() throws IOException {
readWebContents(url);
}
private void readWebContents(URL url) throws IOException {
HttpURLConnection connection = HttpURLConnection.class.cast(url.openConnection());
StringBuilder contents = new StringBuilder();
try (BufferedReader stream = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String read;
while ((read = stream.readLine()) != null) {
contents.append(read);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
parseWebContents(contents.toString());
}
}
private void parseWebContents(String contents) {
Matcher matcher = PARAMETER_PATTERN.matcher(contents);
while (matcher.find()) {
String[] tokens = cleanHtml(matcher.group()).split(" ");
String key = tokens[0].split("=")[1];
String value = join(tokens[1].split("="), 1);
properties.put(key, value);
}
matcher = ARCHIVE_PATTERN.matcher(contents);
if (matcher.find()) {
String[] tokens = matcher.group().split(" ");
properties.put("archive-name", tokens[0].split("=")[1].replaceAll("\"", ""));
properties.put("main-class", tokens[1].split("=")[1].replaceAll("\"", "").replaceAll(".class", ""));
}
}
private static String cleanHtml(String string) {
string = string.replaceAll("\"", "");
string = string.replaceAll("<param ", "");
string = string.substring(0, string.length() - 1);
return string;
}
private static String join(String[] strings, int offset) {
StringBuffer sb = new StringBuffer();
for (int i = offset; i < strings.length; ++i) {
sb.append(strings[i]);
}
return sb.toString();
}
}
Code:
package com.swagger.html;
import java.net.MalformedURLException;
import java.net.URL;
import com.swagger.client.ClientLoader;
import javafx.application.Platform;
public final class Browser implements Runnable {
private final Display display;
private Thread t;
private boolean running;
public Browser() {
display = new Display();
start();
}
@Override
public void run() {
while (running) {
if (display != null && display.getWebEngine() != null) {
if (display.getWebEngine().getLocation().contains("client")) {
try {
ClientLoader.loadClient(display.getWebEngine().getLocation());
} catch (Exception e) {
e.printStackTrace();
//TODO: Give the user some sort of error message
//JDialogeBox thingy?
}
display.getFrame().setVisible(false);
display.getFrame().dispose();
stop();
}
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
/* Ignore */
}
}
private void start() {
if (t == null) {
running = true;
t = new Thread(this);
t.start();
}
}
private void stop() {
if (t != null) {
running = false;
try {
t.join();
} catch (InterruptedException e) {
/* Ignore */
}
t = null;
}
}
public void loadURL(String url) {
Platform.runLater(() -> {
String tmp = toURL(url);
if (tmp == null) {
tmp = toURL("http://" + url);
}
display.getWebEngine().load(tmp);
});
}
private static String toURL(String str) {
try {
return new URL(str).toExternalForm();
} catch (MalformedURLException exception) {
return null;
}
}
}
Code:
package com.swagger.html;
import java.awt.Dimension;
import javax.swing.JFrame;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
public class Display {
private final JFrame frame;
private final JFXPanel jfxPanel;
private WebEngine engine;
public Display() {
frame = new JFrame();
jfxPanel = new JFXPanel();
init();
}
private void init() {
createScene();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(1024, 600));
frame.setLocationRelativeTo(null);
frame.getContentPane().add(jfxPanel);
frame.pack();
frame.setVisible(true);
}
private void createScene() {
Platform.runLater(() -> {
WebView view = new WebView();
engine = view.getEngine();
jfxPanel.setScene(new Scene(view));
});
}
public JFrame getFrame() {
return frame;
}
public WebEngine getWebEngine() {
return engine;
}
}
[/spoil]
Okay once that's added, in Main.java make sure you add the link to the webpage that will act like a "game launcher".
Lastly you will now need to go old school and make a client folder on your website that has a index.html with the following code and the client.jar
URL should look like this: http://mydomain.com/client/client.jar
The index.html should look like this:
[spoil]
Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Webclient</title>
<style
applet { }
</style>
</head>
<body>
Client is loading please wait...<br>
<applet archive="loader.jar" code="loader.class" width="765" height="503">
<!-- These parms tags are not really required depending on client -->
<param name="worldid" value="1" />
<param name="members" value="1" />
<param name="modewhat" value="0" />
<param name="modewhere" value="0" />
<param name="safemode" value="0" />
<param name="game" value="0" />
<param name="js" value="1" />
<param name="lang" value="0" />
<param name="affid" value="0" />
<param name="lowmem" value="0" />
<param name="settings" value="kKmok3kJqOeN6D3mDdihco3oPeYN2KFy6W5--vZUbNA" />
</applet>
</body>
</html>
[/spoil]
Here's an image of the final product:
In my example I used the rune-server play button as my action to start the client lol (you can edit this action in Browser.java)
[spoil]
[/spoil]
Credits to Imthenull on Moparscape for releasing a OSRS loader ages ago on Moparscape. I ripped his code to run the client. No need to reinvent the wheel