mirror of
https://github.com/ViaVersion/VIAaaS.git
synced 2024-11-25 12:35:36 +01:00
create config, some web things, wip
This commit is contained in:
parent
812370dc2e
commit
8237ec20ae
@ -4,7 +4,7 @@ plugins {
|
||||
}
|
||||
|
||||
application {
|
||||
mainClassName = "com.github.creeper123123321.viaaas.ViaaaSKt"
|
||||
mainClassName = "com.github.creeper123123321.viaaas.VIAaaSKt"
|
||||
}
|
||||
|
||||
java {
|
||||
@ -36,7 +36,7 @@ dependencies {
|
||||
implementation("io.ktor:ktor-server-netty:$ktorVersion")
|
||||
implementation("io.ktor:ktor-websockets:$ktorVersion")
|
||||
implementation("ch.qos.logback:logback-classic:1.2.3")
|
||||
testCompile("io.ktor:ktor-server-test-host:$ktorVersion")
|
||||
testImplementation("io.ktor:ktor-server-test-host:$ktorVersion")
|
||||
}
|
||||
|
||||
val run: JavaExec by tasks
|
||||
|
@ -46,10 +46,10 @@ object CloudHeadProtocol : SimpleProtocol() {
|
||||
handler { wrapper: PacketWrapper ->
|
||||
val playerVer = wrapper.passthrough(Type.VAR_INT)
|
||||
val addr = wrapper.passthrough(Type.STRING) // Server Address
|
||||
wrapper.passthrough(Type.UNSIGNED_SHORT)
|
||||
val receivedPort = wrapper.passthrough(Type.UNSIGNED_SHORT)
|
||||
val nextState = wrapper.passthrough(Type.VAR_INT)
|
||||
|
||||
val parsed = ViaaaSAddress().parse(addr)
|
||||
val parsed = VIAaaSAddress().parse(addr, VIAaaSConfig.hostName)
|
||||
|
||||
logger.info("connecting ${wrapper.user().channel!!.remoteAddress()} ($playerVer) to ${parsed.realAddress}:${parsed.port} (${parsed.protocol})")
|
||||
|
||||
@ -64,7 +64,7 @@ object CloudHeadProtocol : SimpleProtocol() {
|
||||
val frontForwarder = wrapper.user().channel!!.pipeline().get(CloudSideForwarder::class.java)
|
||||
try {
|
||||
var srvResolvedAddr = parsed.realAddress
|
||||
var srvResolvedPort = parsed.port
|
||||
var srvResolvedPort = if (parsed.port != 0) parsed.port else receivedPort
|
||||
if (srvResolvedPort == 25565) {
|
||||
try {
|
||||
// https://github.com/GeyserMC/Geyser/blob/99e72f35b308542cf0dbfb5b58816503c3d6a129/connector/src/main/java/org/geysermc/connector/GeyserConnector.java
|
||||
|
@ -10,6 +10,7 @@ import io.ktor.routing.*
|
||||
import io.ktor.server.netty.*
|
||||
import io.ktor.websocket.*
|
||||
import io.netty.bootstrap.ServerBootstrap
|
||||
import io.netty.channel.ChannelOption
|
||||
import io.netty.channel.nio.NioEventLoopGroup
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel
|
||||
import kotlinx.coroutines.channels.consumeEach
|
||||
@ -17,27 +18,27 @@ import us.myles.ViaVersion.ViaManager
|
||||
import us.myles.ViaVersion.api.Via
|
||||
import us.myles.ViaVersion.api.data.MappingDataLoader
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion
|
||||
import us.myles.ViaVersion.util.Config
|
||||
import java.io.File
|
||||
import java.net.InetAddress
|
||||
import java.time.Duration
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val args = args.mapIndexed { i, content -> i to content }.toMap()
|
||||
File("config/https.jks").apply {
|
||||
parentFile.mkdirs()
|
||||
if (!exists()) generateCertificate(this)
|
||||
}
|
||||
|
||||
Via.init(ViaManager.builder()
|
||||
.injector(CloudInjector)
|
||||
.loader(CloudLoader)
|
||||
.commandHandler(CloudCommands)
|
||||
.platform(CloudPlatform).build())
|
||||
|
||||
MappingDataLoader.enableMappingsCache()
|
||||
|
||||
Via.getManager().init()
|
||||
|
||||
CloudRewind.init(ViaRewindConfigImpl(File("config/viarewind.yml")))
|
||||
|
||||
CloudBackwards.init(File("config/viabackwards.yml"))
|
||||
|
||||
val boss = NioEventLoopGroup()
|
||||
@ -45,8 +46,9 @@ fun main(args: Array<String>) {
|
||||
val future = ServerBootstrap().group(boss, worker)
|
||||
.channel(NioServerSocketChannel::class.java)
|
||||
.childHandler(ChannelInit)
|
||||
.bind(InetAddress.getByName(args[0] ?: "::"), args[1]?.toIntOrNull() ?: 25565)
|
||||
|
||||
.childOption(ChannelOption.IP_TOS, 0x18)
|
||||
.childOption(ChannelOption.TCP_NODELAY, true)
|
||||
.bind(InetAddress.getByName(VIAaaSConfig.bindAddress), VIAaaSConfig.port)
|
||||
println("Binded minecraft into " + future.sync().channel().localAddress())
|
||||
|
||||
Thread { EngineMain.main(arrayOf()) }.start()
|
||||
@ -72,13 +74,32 @@ fun main(args: Array<String>) {
|
||||
exitProcess(0) // todo what's stucking?
|
||||
}
|
||||
|
||||
class ViaaaSAddress {
|
||||
fun Application.mainWeb() {
|
||||
ViaWebApp().apply { main() }
|
||||
}
|
||||
|
||||
object VIAaaSConfig : Config(File("config/viaaas.yml")) {
|
||||
init {
|
||||
reloadConfig()
|
||||
}
|
||||
|
||||
override fun getUnsupportedOptions() = emptyList<String>().toMutableList()
|
||||
override fun getDefaultConfigURL() = VIAaaSConfig::class.java.classLoader.getResource("viaaas.yml")!!
|
||||
override fun handleConfig(p0: MutableMap<String, Any>?) {
|
||||
}
|
||||
|
||||
val port: Int get() = this.getInt("port", 25565)
|
||||
val bindAddress: String get() = this.getString("bind-address", "localhost")!!
|
||||
val hostName: String get() = this.getString("host-name", "viaaas.localhost")!!
|
||||
}
|
||||
|
||||
class VIAaaSAddress {
|
||||
var protocol = 0
|
||||
var viaSuffix: String? = null
|
||||
var realAddress: String? = null
|
||||
var port: Int = 25565
|
||||
var online: Boolean = false
|
||||
fun parse(address: String): ViaaaSAddress {
|
||||
var port = 0
|
||||
var online = false
|
||||
fun parse(address: String, viaHostName: String): VIAaaSAddress {
|
||||
val parts = address.split('.')
|
||||
var foundDomain = false
|
||||
var foundOptions = false
|
||||
@ -112,7 +133,8 @@ class ViaaaSAddress {
|
||||
if (foundOptions) {
|
||||
realAddrPart = true
|
||||
}
|
||||
} else if (part.equals("viaaas", ignoreCase = true)) {
|
||||
} else if (parts.filterIndexed { a, _ -> a <= i }
|
||||
.joinToString(".").equals(viaHostName, ignoreCase = true)) {
|
||||
foundDomain = true
|
||||
}
|
||||
if (realAddrPart) {
|
||||
@ -131,96 +153,4 @@ class ViaaaSAddress {
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
fun Application.mainWeb() {
|
||||
ViaWebApp().apply { main() }
|
||||
}
|
||||
|
||||
class ViaWebApp {
|
||||
data class WebSession(val id: String)
|
||||
|
||||
val server = WebDashboardServer()
|
||||
|
||||
fun Application.main() {
|
||||
install(DefaultHeaders)
|
||||
install(CallLogging)
|
||||
install(WebSockets) {
|
||||
pingPeriod = Duration.ofMinutes(1)
|
||||
}
|
||||
|
||||
routing {
|
||||
webSocket("/ws") {
|
||||
server.connected(this)
|
||||
|
||||
try {
|
||||
incoming.consumeEach { frame ->
|
||||
if (frame is Frame.Text) {
|
||||
server.onMessage(this, frame.readText())
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
server.disconnected(this)
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
defaultResource("auth.html", "web")
|
||||
resources("web")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WebDashboardServer {
|
||||
val clients = ConcurrentHashMap<WebSocketSession, WebClient>()
|
||||
suspend fun connected(ws: WebSocketSession) {
|
||||
clients[ws] = WebClient(ws, WebLogin())
|
||||
}
|
||||
|
||||
suspend fun onMessage(ws: WebSocketSession, msg: String) {
|
||||
val client = clients[ws]!!
|
||||
client.state.onMessage(client, msg)
|
||||
}
|
||||
|
||||
suspend fun disconnected(ws: WebSocketSession) {
|
||||
val client = clients[ws]!!
|
||||
client.state.disconnected(client)
|
||||
clients.remove(ws)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
data class WebClient(val ws: WebSocketSession, val state: WebState) {
|
||||
}
|
||||
|
||||
|
||||
interface WebState {
|
||||
fun onMessage(webClient: WebClient, msg: String)
|
||||
fun disconnected(webClient: WebClient)
|
||||
}
|
||||
|
||||
class WebLogin : WebState {
|
||||
override fun onMessage(webClient: WebClient, msg: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun disconnected(webClient: WebClient) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object CertificateGenerator {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
val jksFile = File("build/temporary.jks").apply {
|
||||
parentFile.mkdirs()
|
||||
}
|
||||
|
||||
if (!jksFile.exists()) {
|
||||
generateCertificate(jksFile) // Generates the certificate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
93
src/main/kotlin/com/github/creeper123123321/viaaas/ViaWeb.kt
Normal file
93
src/main/kotlin/com/github/creeper123123321/viaaas/ViaWeb.kt
Normal file
@ -0,0 +1,93 @@
|
||||
package com.github.creeper123123321.viaaas
|
||||
|
||||
import io.ktor.application.*
|
||||
import io.ktor.features.*
|
||||
import io.ktor.http.cio.websocket.*
|
||||
import io.ktor.http.cio.websocket.WebSockets
|
||||
import io.ktor.http.content.*
|
||||
import io.ktor.routing.*
|
||||
import io.ktor.websocket.*
|
||||
import kotlinx.coroutines.channels.consumeEach
|
||||
import java.time.Duration
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
// todo https://minecraft.id/documentation
|
||||
|
||||
class ViaWebApp {
|
||||
val server = WebDashboardServer()
|
||||
|
||||
fun Application.main() {
|
||||
install(DefaultHeaders)
|
||||
install(CallLogging)
|
||||
install(WebSockets) {
|
||||
pingPeriod = Duration.ofMinutes(1)
|
||||
}
|
||||
|
||||
routing {
|
||||
webSocket("/ws") {
|
||||
server.connected(this)
|
||||
try {
|
||||
incoming.consumeEach { frame ->
|
||||
if (frame is Frame.Text) {
|
||||
server.onMessage(this, frame.readText())
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
server.disconnected(this)
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
defaultResource("index.html", "web")
|
||||
resources("web")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WebDashboardServer {
|
||||
val clients = ConcurrentHashMap<WebSocketSession, WebClient>()
|
||||
suspend fun connected(ws: WebSocketSession) {
|
||||
val loginState = WebLogin()
|
||||
val client = WebClient(ws, loginState)
|
||||
clients[ws] = client
|
||||
loginState.start(client)
|
||||
}
|
||||
|
||||
suspend fun onMessage(ws: WebSocketSession, msg: String) {
|
||||
val client = clients[ws]!!
|
||||
client.state.onMessage(client, msg)
|
||||
}
|
||||
|
||||
suspend fun disconnected(ws: WebSocketSession) {
|
||||
val client = clients[ws]!!
|
||||
client.state.disconnected(client)
|
||||
clients.remove(ws)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
data class WebClient(val ws: WebSocketSession, val state: WebState) {
|
||||
}
|
||||
|
||||
interface WebState {
|
||||
suspend fun start(webClient: WebClient)
|
||||
suspend fun onMessage(webClient: WebClient, msg: String)
|
||||
suspend fun disconnected(webClient: WebClient)
|
||||
}
|
||||
|
||||
class WebLogin : WebState {
|
||||
override suspend fun start(webClient: WebClient) {
|
||||
webClient.ws.send("test")
|
||||
webClient.ws.flush()
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun onMessage(webClient: WebClient, msg: String) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun disconnected(webClient: WebClient) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
@ -5,12 +5,12 @@ ktor {
|
||||
}
|
||||
|
||||
application {
|
||||
modules = [ com.github.creeper123123321.viaaas.ViaaaSKt.mainWeb ]
|
||||
modules = [ com.github.creeper123123321.viaaas.VIAaaSKt.mainWeb ]
|
||||
}
|
||||
|
||||
security {
|
||||
ssl {
|
||||
keyStore = build/temporary.jks
|
||||
keyStore = config/https.jks
|
||||
keyAlias = mykey
|
||||
keyStorePassword = changeit
|
||||
privateKeyPassword = changeit
|
||||
|
7
src/main/resources/viaaas.yml
Normal file
7
src/main/resources/viaaas.yml
Normal file
@ -0,0 +1,7 @@
|
||||
# See application.conf in resources for https interface options
|
||||
# Port used for binding Minecraft port
|
||||
port: 25565
|
||||
# Address to bind
|
||||
bind-address: localhost
|
||||
# Host name of this instance, that will be used in the virtual host
|
||||
host-name: viaaas.localhost
|
@ -1,43 +1,46 @@
|
||||
<!doctype html>
|
||||
<!-- insert here online mode auth code with wss -->
|
||||
<html>
|
||||
<!-- todo insert here online mode auth code with wss -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<script>
|
||||
// Global variable to hold the websocket.
|
||||
var socket = null;
|
||||
|
||||
function connect() {
|
||||
console.log("Begin connect");
|
||||
socket = new WebSocket("wss://" + window.location.host + "/ws");
|
||||
|
||||
socket.onerror = function() {
|
||||
console.log("socket error");
|
||||
};
|
||||
|
||||
socket.onopen = function() {
|
||||
console.log("Connected");
|
||||
};
|
||||
|
||||
socket.onclose = function(evt) {
|
||||
// Try to gather an explanation about why this was closed.
|
||||
var explanation = "";
|
||||
if (evt.reason && evt.reason.length > 0) {
|
||||
explanation = "reason: " + evt.reason;
|
||||
} else {
|
||||
explanation = "without a reason specified";
|
||||
}
|
||||
|
||||
console.log("Disconnected with close code " + evt.code + " and " + explanation);
|
||||
setTimeout(connect, 5000);
|
||||
};
|
||||
|
||||
socket.onmessage = function(event) {
|
||||
console.log(event.data.toString());
|
||||
};
|
||||
}
|
||||
connect();
|
||||
</script>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>VIAaaS</title>
|
||||
<style>
|
||||
body {font-family: sans-serif}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>WebSocket connection status: <span id="connection_status">?</span></p>
|
||||
<p>DO NOT TYPE YOUR CREDENTIALS IF YOU DON'T TRUST THE CONNECTION TO THIS VIAAAS INSTANCE!</p>
|
||||
<p>Minecraft Login:</p>
|
||||
<p>Minecraft Password:</p>
|
||||
<script>
|
||||
var socket = null;
|
||||
var connectionStatus = document.getElementById("connection_status");
|
||||
|
||||
function connect() {
|
||||
connectionStatus.innerText = "connecting...";
|
||||
socket = new WebSocket("wss://" + window.location.host + "/ws");
|
||||
|
||||
socket.onerror = () => {
|
||||
connectionStatus.innerText = "socket error";
|
||||
};
|
||||
|
||||
socket.onopen = () => {
|
||||
connectionStatus.innerText = "connected";
|
||||
};
|
||||
|
||||
socket.onclose = evt => {
|
||||
connectionStatus.innerText = "disconnected with close code " + evt.code + " and reason: " + evt.reason;
|
||||
setTimeout(connect, 5000);
|
||||
};
|
||||
|
||||
socket.onmessage = event => {
|
||||
console.log(event.data.toString());
|
||||
};
|
||||
}
|
||||
|
||||
connect();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
15
src/main/resources/web/index.html
Normal file
15
src/main/resources/web/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>VIAaaS</title>
|
||||
<style>
|
||||
body {font-family: sans-serif}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>VIAaaS</h1>
|
||||
<p><a href="auth.html">Authentication management</a></p>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user