mirror of
https://github.com/redstrate/Kawari.git
synced 2025-04-29 09:57:46 +00:00
Serve a launcher page under launcher.ffxiv.localhost
This can eventually be put into a retail launcher, but it doesn't do much yet.
This commit is contained in:
parent
ef58358756
commit
28b27866db
7 changed files with 152 additions and 1 deletions
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
|
@ -74,6 +74,7 @@ jobs:
|
|||
target/release/kawari-patch*
|
||||
target/release/kawari-web*
|
||||
target/release/kawari-world*
|
||||
target/release/kawari-launcher*
|
||||
!target/release/*.d
|
||||
resources/
|
||||
!resources/tests
|
||||
|
|
|
@ -31,6 +31,9 @@ name = "kawari-lobby"
|
|||
name = "kawari-world"
|
||||
required-features = ["oodle"]
|
||||
|
||||
[[bin]]
|
||||
name = "kawari-launcher"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
strip = true
|
||||
|
|
|
@ -10,6 +10,10 @@ ffxiv.localhost:80 {
|
|||
reverse_proxy :5801
|
||||
}
|
||||
|
||||
launcher.ffxiv.localhost:80 {
|
||||
reverse_proxy :5802
|
||||
}
|
||||
|
||||
frontier.ffxiv.localhost:80 {
|
||||
reverse_proxy :5857
|
||||
}
|
||||
|
|
|
@ -9,4 +9,5 @@ cargo run -q --package kawari --features oodle --bin kawari-patch &
|
|||
cargo run -q --package kawari --features oodle --bin kawari-web &
|
||||
cargo run -q --package kawari --features oodle --bin kawari-lobby &
|
||||
cargo run -q --package kawari --features oodle --bin kawari-world &
|
||||
cargo run -q --package kawari --features oodle --bin kawari-launcher &
|
||||
wait
|
||||
|
|
42
src/bin/kawari-launcher.rs
Normal file
42
src/bin/kawari-launcher.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
use axum::response::Html;
|
||||
use axum::{Router, routing::get};
|
||||
use kawari::config::get_config;
|
||||
use minijinja::Environment;
|
||||
use minijinja::context;
|
||||
|
||||
fn setup_default_environment() -> Environment<'static> {
|
||||
let mut env = Environment::new();
|
||||
env.add_template(
|
||||
"launcher.html",
|
||||
include_str!("../../templates/launcher.html"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
env
|
||||
}
|
||||
|
||||
async fn root() -> Html<String> {
|
||||
let config = get_config();
|
||||
|
||||
let environment = setup_default_environment();
|
||||
let template = environment.get_template("launcher.html").unwrap();
|
||||
Html(
|
||||
template
|
||||
.render(context! { login_server => config.login.server_name })
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let app = Router::new().route("/v700", get(root));
|
||||
|
||||
let config = get_config();
|
||||
|
||||
let addr = config.launcher.get_socketaddr();
|
||||
tracing::info!("Server started on {addr}");
|
||||
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
}
|
|
@ -263,6 +263,32 @@ impl WorldConfig {
|
|||
}
|
||||
}
|
||||
|
||||
/// Configuration for the launcher server.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct LauncherConfig {
|
||||
pub port: u16,
|
||||
pub listen_address: String,
|
||||
}
|
||||
|
||||
impl Default for LauncherConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
port: 5802,
|
||||
listen_address: "127.0.0.1".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LauncherConfig {
|
||||
/// Returns the configured IP address & port as a `SocketAddr`.
|
||||
pub fn get_socketaddr(&self) -> SocketAddr {
|
||||
SocketAddr::from((
|
||||
IpAddr::from_str(&self.listen_address).expect("Invalid IP address format in config!"),
|
||||
self.port,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Global and all-encompassing config.
|
||||
/// Settings that affect all servers belong here.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
@ -294,6 +320,9 @@ pub struct Config {
|
|||
#[serde(default)]
|
||||
pub world: WorldConfig,
|
||||
|
||||
#[serde(default)]
|
||||
pub launcher: LauncherConfig,
|
||||
|
||||
/// Enable various packet debug functions. This will clutter your working directory!
|
||||
#[serde(default)]
|
||||
pub packet_debugging: bool,
|
||||
|
@ -311,6 +340,7 @@ impl Default for Config {
|
|||
patch: PatchConfig::default(),
|
||||
web: WebConfig::default(),
|
||||
world: WorldConfig::default(),
|
||||
launcher: LauncherConfig::default(),
|
||||
packet_debugging: false,
|
||||
}
|
||||
}
|
||||
|
|
70
templates/launcher.html
Normal file
70
templates/launcher.html
Normal file
|
@ -0,0 +1,70 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang=en>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge;">
|
||||
<title>Kawari Launcher</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Welcome to Kawari!</p>
|
||||
|
||||
<input type="button" value="System Info" onclick="window.external.user('systemInfo');" />
|
||||
<input type="button" value="Play" onclick="window.external.user('startPlay');" />
|
||||
<input type="button" value="Exit" onclick="window.external.user('requestExit');" />
|
||||
<input type="button" value="Reboot" onclick="window.external.user('requestReboot');" />
|
||||
<input type="button" value="Open Google" onclick="window.external.user('link=https://google.com/');" />
|
||||
<input type="button" value="Accept EULA" onclick="window.external.user('eulaOk');" />
|
||||
<input type="button" value="Disable DX11" onclick="window.external.user('config=dx11enabled=0');" />
|
||||
<input type="button" value="Enable DX11" onclick="window.external.user('config=dx11enabled=1');" />
|
||||
<input type="button" value="Request Config" onclick="window.external.user('requestConfig');" />
|
||||
<input type="button" value="Request Login Url" onclick="window.external.user('requestLoginUrl');" />
|
||||
<input type="button" value="Request Platform" onclick="window.external.user('requestDP');" />
|
||||
|
||||
<p id="replace-me">meh</p>
|
||||
|
||||
<script type="text/javascript">
|
||||
function checkHandlerType(e) {
|
||||
if ('function' != typeof e) throw new Error('Protocol Callback is not function.');
|
||||
return e
|
||||
}
|
||||
|
||||
function fromAppConfig(thing) {
|
||||
document.getElementById('replace-me').innerText += "config: " + JSON.stringify(thing);
|
||||
}
|
||||
window.fromAppConfig = this.checkHandlerType(fromAppConfig);
|
||||
|
||||
function fromAppWarn(thing) {
|
||||
document.getElementById('replace-me').innerText += "warn: " + JSON.stringify(thing);
|
||||
}
|
||||
window.fromAppWarn = this.checkHandlerType(fromAppWarn);
|
||||
|
||||
function fromAppStartVersionCheck(thing) {
|
||||
document.getElementById('replace-me').innerText += "version: " + JSON.stringify(thing);
|
||||
}
|
||||
window.fromAppStartVersionCheck = this.checkHandlerType(fromAppStartVersionCheck);
|
||||
|
||||
function fromAppDP(thing) {
|
||||
document.getElementById('replace-me').innerText += "dp: " + JSON.stringify(thing);
|
||||
}
|
||||
window.fromAppDP = this.checkHandlerType(fromAppDP);
|
||||
|
||||
function fromAppDisplaySettings(thing) {
|
||||
document.getElementById('replace-me').innerText += "display settings: " + JSON.stringify(thing);
|
||||
}
|
||||
window.fromAppDisplaySettings = this.checkHandlerType(fromAppDisplaySettings);
|
||||
|
||||
function fromAppResumeInfo(thing) {
|
||||
document.getElementById('replace-me').innerText += "resume info: " + JSON.stringify(thing);
|
||||
}
|
||||
window.fromAppResumeInfo = this.checkHandlerType(fromAppResumeInfo);
|
||||
|
||||
// this is what the retail launcher does
|
||||
window.external.user('permissionFromApp=1');
|
||||
window.external.user('requestDP');
|
||||
window.external.user('requestConfig');
|
||||
window.external.user('requestDisplaySettings');
|
||||
window.external.user('requestResumeInfo');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Reference in a new issue