mirror of
https://github.com/ViaVersion/VIAaaS.git
synced 2025-01-23 21:52:35 +01:00
parent
e80c1384c2
commit
49a39eb592
@ -57,8 +57,8 @@ dependencies {
|
||||
implementation(kotlin("stdlib-jdk8"))
|
||||
implementation(kotlin("reflect"))
|
||||
|
||||
val vvVer = "4.2.2-SNAPSHOT"
|
||||
val vbVer = "4.2.1-SNAPSHOT"
|
||||
val vvVer = "4.3.0-22w11a-SNAPSHOT"
|
||||
val vbVer = "4.3.0-22w11a-SNAPSHOT"
|
||||
val vrVer = "ae62eba"
|
||||
implementation("com.viaversion:viaversion:$vvVer") { isTransitive = false }
|
||||
implementation("com.viaversion:viabackwards:$vbVer") { isTransitive = false }
|
||||
@ -68,7 +68,7 @@ dependencies {
|
||||
implementation("io.netty:netty-tcnative-boringssl-static:2.0.50.Final")
|
||||
implementation("io.netty.incubator:netty-incubator-transport-native-io_uring:0.0.12.Final:linux-x86_64")
|
||||
|
||||
implementation("com.google.guava:guava:31.0.1-jre")
|
||||
implementation("com.google.guava:guava:31.1-jre")
|
||||
implementation("com.velocitypowered:velocity-native:3.1.0")
|
||||
implementation("net.coobird:thumbnailator:0.4.17")
|
||||
implementation("org.powernukkit.fastutil:fastutil-lite:8.1.1")
|
||||
|
@ -41,4 +41,9 @@ public class StatusKicked implements ConnectionState {
|
||||
public void onInactivated(@NotNull MinecraftHandler handler) {
|
||||
ConnectionState.DefaultImpls.onInactivated(this, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(@NotNull MinecraftHandler handler) {
|
||||
ConnectionState.DefaultImpls.start(this, handler);
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,7 @@ import com.google.common.primitives.Ints;
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import kotlin.text.StringsKt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AddressParser {
|
||||
@ -19,11 +17,18 @@ public class AddressParser {
|
||||
public String username;
|
||||
public Boolean online;
|
||||
|
||||
public AddressParser parse(String address, String viaHostName) {
|
||||
address = StringsKt.removeSuffix(address, ".");
|
||||
String suffixRemoved = StringsKt.removeSuffix(address, "." + viaHostName);
|
||||
public AddressParser parse(String rawAddress, List<String> viaHostName) {
|
||||
String address = StringsKt.removeSuffix(rawAddress, ".");
|
||||
|
||||
if (suffixRemoved.equals(address)) {
|
||||
String suffix = viaHostName.stream()
|
||||
.filter(s -> StringsKt.endsWith("." + address, s, true))
|
||||
.findAny()
|
||||
.orElse(null);
|
||||
|
||||
String suffixRemoved;
|
||||
if (suffix != null) {
|
||||
suffixRemoved = StringsKt.removeSuffix(address, "." + suffix);
|
||||
} else {
|
||||
serverAddress = address;
|
||||
return this;
|
||||
}
|
||||
@ -43,7 +48,7 @@ public class AddressParser {
|
||||
|
||||
serverAddress = String.join(".", Lists.reverse(serverParts));
|
||||
viaOptions = String.join(".", Lists.reverse(optionsParts));
|
||||
viaSuffix = viaHostName;
|
||||
viaSuffix = suffix;
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -61,7 +66,7 @@ public class AddressParser {
|
||||
}
|
||||
|
||||
String arg = part.substring(2);
|
||||
switch (option) {
|
||||
switch (option.toLowerCase(Locale.ROOT)) {
|
||||
case "o": {
|
||||
parseOnlineMode(arg);
|
||||
break;
|
||||
|
@ -32,4 +32,7 @@ interface ConnectionState {
|
||||
logDisconnect(handler, "-")
|
||||
handler.other?.close()
|
||||
}
|
||||
|
||||
fun start(handler: MinecraftHandler) {
|
||||
}
|
||||
}
|
||||
|
@ -7,16 +7,12 @@ import com.google.common.util.concurrent.RateLimiter
|
||||
import com.viaversion.aas.codec.packet.Packet
|
||||
import com.viaversion.aas.codec.packet.handshake.Handshake
|
||||
import com.viaversion.aas.config.VIAaaSConfig
|
||||
import com.viaversion.aas.fireExceptionCaughtIfOpen
|
||||
import com.viaversion.aas.handler.MinecraftHandler
|
||||
import com.viaversion.aas.mcLogger
|
||||
import com.viaversion.aas.setAutoRead
|
||||
import com.viaversion.aas.util.AddressParser
|
||||
import com.viaversion.aas.util.StacklessException
|
||||
import com.viaversion.viaversion.api.protocol.packet.State
|
||||
import io.netty.channel.ChannelHandlerContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.net.InetAddress
|
||||
import java.net.InetSocketAddress
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -52,7 +48,7 @@ class HandshakeState : ConnectionState {
|
||||
private fun handleNextState(handler: MinecraftHandler, packet: Handshake) {
|
||||
handler.data.frontVer = packet.protocolId
|
||||
when (packet.nextState.ordinal) {
|
||||
1 -> handler.data.state = StatusState
|
||||
1 -> handler.data.state = StatusState()
|
||||
2 -> handler.data.state = LoginState()
|
||||
else -> throw StacklessException("Invalid next state")
|
||||
}
|
||||
@ -63,36 +59,42 @@ class HandshakeState : ConnectionState {
|
||||
val extraData = packet.address.substringAfter(0.toChar(), missingDelimiterValue = "").ifEmpty { null }
|
||||
val virtualHostNoExtra = packet.address.substringBefore(0.toChar())
|
||||
|
||||
val parsed = VIAaaSConfig.hostName.map {
|
||||
AddressParser().parse(virtualHostNoExtra, it)
|
||||
}.sortedBy {
|
||||
it.viaSuffix == null
|
||||
}.first()
|
||||
val parsed = AddressParser().parse(virtualHostNoExtra, VIAaaSConfig.hostName)
|
||||
|
||||
val backProto = parsed.protocol ?: -2
|
||||
val hadHostname = parsed.viaSuffix != null
|
||||
|
||||
packet.address = parsed.serverAddress!!
|
||||
packet.port = parsed.port ?: VIAaaSConfig.defaultBackendPort ?: virtualPort
|
||||
val backAddress = parsed.serverAddress!!
|
||||
val port = parsed.port ?: VIAaaSConfig.defaultBackendPort ?: virtualPort
|
||||
val host = HostAndPort.fromParts(backAddress, port)
|
||||
|
||||
var frontOnline = parsed.online
|
||||
if (VIAaaSConfig.forceOnlineMode) frontOnline = true
|
||||
|
||||
val addressFromWeb = VIAaaSConfig.hostName.any { parsed.serverAddress.equals(it, ignoreCase = true) }
|
||||
|
||||
handler.data.backServerVer = backProto
|
||||
(handler.data.state as? LoginState)?.also {
|
||||
it.frontOnline = frontOnline
|
||||
it.backName = parsed.username
|
||||
it.backAddress = HostAndPort.fromParts(packet.address, packet.port)
|
||||
if (!addressFromWeb) {
|
||||
it.backAddress = host
|
||||
}
|
||||
it.extraData = extraData
|
||||
}
|
||||
(handler.data.state as? StatusState)?.also {
|
||||
if (!addressFromWeb) {
|
||||
it.address = host
|
||||
}
|
||||
}
|
||||
|
||||
val playerAddr = handler.data.frontHandler.endRemoteAddress
|
||||
mcLogger.debug(
|
||||
"HS: $playerAddr ${handler.data.state.state.toString().substring(0, 1)} " +
|
||||
"HS: $playerAddr ${handler.data.state.state.name[0]} " +
|
||||
"$virtualHostNoExtra $virtualPort v${handler.data.frontVer}"
|
||||
)
|
||||
|
||||
if (!hadHostname && VIAaaSConfig.requireHostName) {
|
||||
if (!hadHostname && VIAaaSConfig.requireHostName && !addressFromWeb
|
||||
) {
|
||||
throw StacklessException("Missing parts in hostname")
|
||||
}
|
||||
}
|
||||
@ -104,20 +106,7 @@ class HandshakeState : ConnectionState {
|
||||
checkRateLimit(handler, packet.nextState)
|
||||
handleVirtualHost(handler, packet)
|
||||
|
||||
connectStatus(handler, ctx, packet)
|
||||
}
|
||||
|
||||
private fun connectStatus(handler: MinecraftHandler, ctx: ChannelHandlerContext, packet: Handshake) {
|
||||
if (packet.nextState == State.STATUS) { // see LoginState for LOGIN
|
||||
handler.data.frontChannel.setAutoRead(false)
|
||||
handler.coroutineScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
connectBack(handler, packet.address, packet.port, packet.nextState)
|
||||
} catch (e: Exception) {
|
||||
ctx.channel().fireExceptionCaughtIfOpen(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
handler.data.state.start(handler)
|
||||
}
|
||||
|
||||
override fun disconnect(handler: MinecraftHandler, msg: String) {
|
||||
|
@ -32,7 +32,7 @@ class LoginState : ConnectionState {
|
||||
lateinit var frontServerId: String
|
||||
var frontOnline: Boolean? = null
|
||||
lateinit var frontName: String
|
||||
lateinit var backAddress: HostAndPort
|
||||
var backAddress: HostAndPort? = null
|
||||
lateinit var cryptoKey: KeyPair
|
||||
var extraData: String? = null
|
||||
var backName: String? = null
|
||||
@ -226,15 +226,24 @@ class LoginState : ConnectionState {
|
||||
|
||||
handler.coroutineScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
if (backAddress == null) {
|
||||
mcLogger.info("Requesting address info from web for $frontName")
|
||||
val info = AspirinServer.viaWebServer.requestAddressInfo(frontName).await()
|
||||
backAddress = info.backHostAndPort
|
||||
handler.data.backServerVer = info.backVersion
|
||||
frontOnline = info.frontOnline
|
||||
}
|
||||
if (VIAaaSConfig.forceOnlineMode) frontOnline = true
|
||||
if (frontOnline != null) {
|
||||
when (frontOnline) {
|
||||
false -> callbackPlayerId.complete(generateOfflinePlayerUuid(frontName))
|
||||
true -> authenticateOnlineFront(handler.data.frontChannel) // forced
|
||||
else -> {}
|
||||
}
|
||||
val id = callbackPlayerId.await()
|
||||
mcLogger.info("Login: ${handler.endRemoteAddress} $frontName $id")
|
||||
}
|
||||
connectBack(handler, backAddress.host, backAddress.port, State.LOGIN, extraData)
|
||||
connectBack(handler, HostAndPort.fromParts(backAddress!!.host, backAddress!!.port), State.LOGIN, extraData)
|
||||
loginStart.username = backName!!
|
||||
send(handler.data.backChannel!!, loginStart, true)
|
||||
} catch (e: Exception) {
|
||||
|
@ -1,25 +1,27 @@
|
||||
package com.viaversion.aas.handler.state
|
||||
|
||||
import com.google.common.net.HostAndPort
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import com.viaversion.aas.AspirinServer
|
||||
import com.viaversion.aas.*
|
||||
import com.viaversion.aas.codec.packet.Packet
|
||||
import com.viaversion.aas.codec.packet.UnknownPacket
|
||||
import com.viaversion.aas.codec.packet.status.StatusResponse
|
||||
import com.viaversion.aas.config.VIAaaSConfig
|
||||
import com.viaversion.aas.handler.MinecraftHandler
|
||||
import com.viaversion.aas.handler.forward
|
||||
import com.viaversion.aas.parseProtocol
|
||||
import com.viaversion.aas.send
|
||||
import com.viaversion.aas.util.StacklessException
|
||||
import com.viaversion.viaversion.api.protocol.packet.State
|
||||
import io.netty.channel.ChannelHandlerContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
object StatusState : ConnectionState {
|
||||
class StatusState : ConnectionState {
|
||||
override val state: State
|
||||
get() = State.STATUS
|
||||
var address: HostAndPort? = null
|
||||
|
||||
override fun handlePacket(handler: MinecraftHandler, ctx: ChannelHandlerContext, packet: Packet) {
|
||||
if (packet is UnknownPacket) throw StacklessException("Invalid packet")
|
||||
@ -72,4 +74,19 @@ object StatusState : ConnectionState {
|
||||
send(handler.data.frontChannel, packet, flush = true)
|
||||
handler.data.state = StatusKicked()
|
||||
}
|
||||
|
||||
override fun start(handler: MinecraftHandler) {
|
||||
handler.data.frontChannel.setAutoRead(false)
|
||||
handler.coroutineScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
if (address != null) {
|
||||
connectBack(handler, address!!, state)
|
||||
} else {
|
||||
handler.disconnect("VIAaaS")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
handler.data.frontChannel.fireExceptionCaughtIfOpen(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ private suspend fun createBackChannel(
|
||||
.channel()
|
||||
(channel.pipeline()["proxy"] as? ProxyHandler)?.connectFuture()?.suspendAwait()
|
||||
|
||||
mcLogger.info("+ ${state.name.substring(0, 1)} ${handler.endRemoteAddress} -> $socketAddr")
|
||||
mcLogger.info("+ ${state.name[0]} ${handler.endRemoteAddress} -> $socketAddr")
|
||||
handler.data.backChannel = channel as SocketChannel
|
||||
|
||||
autoDetectVersion(handler, socketAddr)
|
||||
@ -143,12 +143,11 @@ private suspend fun resolveBackendAddresses(hostAndPort: HostAndPort): List<Inet
|
||||
|
||||
suspend fun connectBack(
|
||||
handler: MinecraftHandler,
|
||||
address: String,
|
||||
port: Int,
|
||||
address: HostAndPort,
|
||||
state: State,
|
||||
extraData: String? = null
|
||||
) {
|
||||
val addresses = resolveBackendAddresses(HostAndPort.fromParts(address, port))
|
||||
val addresses = resolveBackendAddresses(address)
|
||||
|
||||
if (addresses.isEmpty()) throw StacklessException("Hostname has no IP addresses")
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
package com.viaversion.aas.web
|
||||
|
||||
import com.google.common.net.HostAndPort
|
||||
import com.google.common.primitives.Ints
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import com.viaversion.aas.*
|
||||
import com.viaversion.aas.util.StacklessException
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.request.forms.*
|
||||
import io.ktor.http.*
|
||||
@ -27,10 +30,11 @@ class WebLogin : WebState {
|
||||
|
||||
when (obj.getAsJsonPrimitive("action").asString) {
|
||||
"offline_login" -> handleOfflineLogin(webClient, msg, obj)
|
||||
"minecraft_id_login" -> handleMcIdLogin(webClient, msg, obj)
|
||||
"listen_login_requests" -> handleListenLogins(webClient, msg, obj)
|
||||
"unlisten_login_requests" -> handleUnlisten(webClient, msg, obj)
|
||||
"session_hash_response" -> handleSessionResponse(webClient, msg, obj)
|
||||
"minecraft_id_login" -> handleMcIdLogin(webClient, obj)
|
||||
"listen_login_requests" -> handleListenLogins(webClient, obj)
|
||||
"unlisten_login_requests" -> handleUnlisten(webClient, obj)
|
||||
"session_hash_response" -> handleSessionResponse(webClient, obj)
|
||||
"parameters_response" -> handleParametersResponse(webClient, obj)
|
||||
else -> throw StacklessException("invalid action!")
|
||||
}
|
||||
|
||||
@ -77,7 +81,7 @@ class WebLogin : WebState {
|
||||
webLogger.info("Token gen: ${webClient.id}: offline $username $uuid")
|
||||
}
|
||||
|
||||
private suspend fun handleMcIdLogin(webClient: WebClient, msg: String, obj: JsonObject) {
|
||||
private suspend fun handleMcIdLogin(webClient: WebClient, obj: JsonObject) {
|
||||
val username = obj["username"].asString
|
||||
val code = obj["code"].asString
|
||||
|
||||
@ -102,7 +106,7 @@ class WebLogin : WebState {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun handleListenLogins(webClient: WebClient, msg: String, obj: JsonObject) {
|
||||
private suspend fun handleListenLogins(webClient: WebClient, obj: JsonObject) {
|
||||
val token = obj.getAsJsonPrimitive("token").asString
|
||||
val user = webClient.server.parseToken(token)
|
||||
val response = JsonObject().also {
|
||||
@ -121,7 +125,7 @@ class WebLogin : WebState {
|
||||
webClient.ws.send(response.toString())
|
||||
}
|
||||
|
||||
private suspend fun handleUnlisten(webClient: WebClient, msg: String, obj: JsonObject) {
|
||||
private suspend fun handleUnlisten(webClient: WebClient, obj: JsonObject) {
|
||||
val uuid = UUID.fromString(obj.getAsJsonPrimitive("uuid").asString)
|
||||
webLogger.info("Unlisten: ${webClient.id}: $uuid")
|
||||
val response = JsonObject().also {
|
||||
@ -132,8 +136,26 @@ class WebLogin : WebState {
|
||||
webClient.ws.send(response.toString())
|
||||
}
|
||||
|
||||
private suspend fun handleSessionResponse(webClient: WebClient, msg: String, obj: JsonObject) {
|
||||
private fun handleSessionResponse(webClient: WebClient, obj: JsonObject) {
|
||||
val hash = obj["session_hash"].asString
|
||||
webClient.server.sessionHashCallbacks.getIfPresent(hash)?.complete(Unit)
|
||||
}
|
||||
|
||||
private fun handleParametersResponse(webClient: WebClient, obj: JsonObject) {
|
||||
val callback = UUID.fromString(obj["callback"].asString)
|
||||
webClient.server.addressCallbacks[callback].complete(
|
||||
WebServer.AddressInfo(
|
||||
backVersion = obj["version"].asString.let {
|
||||
var protocol = Ints.tryParse(it)
|
||||
if (protocol == null) {
|
||||
val ver = ProtocolVersion.getClosest(it)
|
||||
if (ver != null) protocol = ver.version
|
||||
}
|
||||
protocol ?: -2
|
||||
},
|
||||
backHostAndPort = HostAndPort.fromParts(obj["host"].asString, obj["port"].asInt),
|
||||
frontOnline = obj["frontOnline"].asString.toBooleanStrictOrNull()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,11 @@ import com.google.common.cache.CacheBuilder
|
||||
import com.google.common.cache.CacheLoader
|
||||
import com.google.common.collect.MultimapBuilder
|
||||
import com.google.common.collect.Multimaps
|
||||
import com.google.common.net.HostAndPort
|
||||
import com.google.gson.JsonObject
|
||||
import com.viaversion.aas.AspirinServer
|
||||
import com.viaversion.aas.*
|
||||
import com.viaversion.aas.config.VIAaaSConfig
|
||||
import com.viaversion.aas.parseUndashedId
|
||||
import com.viaversion.aas.reverseLookup
|
||||
import com.viaversion.aas.util.StacklessException
|
||||
import com.viaversion.aas.webLogger
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.server.netty.*
|
||||
@ -25,6 +23,7 @@ import io.netty.handler.codec.dns.DnsRecordType
|
||||
import io.netty.util.ReferenceCountUtil
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.future.asCompletableFuture
|
||||
import kotlinx.coroutines.future.await
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.SocketAddress
|
||||
import java.time.Duration
|
||||
@ -78,14 +77,63 @@ class WebServer {
|
||||
.build<String, CompletableFuture<UUID?>>(CacheLoader.from { name ->
|
||||
CoroutineScope(Dispatchers.IO).async {
|
||||
AspirinServer.httpClient
|
||||
.get("https://api.mojang.com/users/profiles/minecraft/$name").body<JsonObject?>()
|
||||
?.get("id")?.asString?.let { parseUndashedId(it) }
|
||||
.get("https://api.mojang.com/users/profiles/minecraft/$name")
|
||||
.body<JsonObject?>()?.get("id")?.asString?.let { parseUndashedId(it) }
|
||||
}.asCompletableFuture()
|
||||
})
|
||||
|
||||
val sessionHashCallbacks = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(30, TimeUnit.SECONDS)
|
||||
.build<String, CompletableFuture<Unit>>(CacheLoader.from { _ -> CompletableFuture() })
|
||||
val addressCallbacks = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(30, TimeUnit.SECONDS)
|
||||
.build<UUID, CompletableFuture<AddressInfo>>(CacheLoader.from { _ -> CompletableFuture() })
|
||||
|
||||
data class AddressInfo(val backVersion: Int, val backHostAndPort: HostAndPort, var frontOnline: Boolean? = null)
|
||||
|
||||
suspend fun requestAddressInfo(frontName: String): CompletableFuture<AddressInfo> {
|
||||
var onlineId: UUID? = null
|
||||
try {
|
||||
onlineId = usernameIdCache[frontName].await()
|
||||
} catch (e: java.lang.Exception) {
|
||||
webLogger.debug("Couldn't get online uuid for $frontName", e)
|
||||
}
|
||||
val offlineId = generateOfflinePlayerUuid(frontName)
|
||||
|
||||
val callbackId = UUID.randomUUID()
|
||||
val future = addressCallbacks.get(callbackId)
|
||||
CoroutineScope(coroutineContext).apply {
|
||||
launch(Dispatchers.IO) {
|
||||
run sending@{
|
||||
onlineId?.let {
|
||||
if (sendRequestAddress(it, callbackId)) return@sending
|
||||
}
|
||||
if (sendRequestAddress(offlineId, callbackId)) return@sending
|
||||
future.completeExceptionally(StacklessException("Username $frontName not listened. Use web auth to select backend server address."))
|
||||
}
|
||||
}
|
||||
launch {
|
||||
delay(20_000)
|
||||
future.completeExceptionally(StacklessException("No response from browser"))
|
||||
}
|
||||
}
|
||||
return future
|
||||
}
|
||||
|
||||
private suspend fun sendRequestAddress(uuid: UUID, callbackId: UUID): Boolean {
|
||||
var sent = false
|
||||
listeners.get(uuid).forEach {
|
||||
it.ws.send(
|
||||
JsonObject().also {
|
||||
it.addProperty("action", "parameters_request")
|
||||
it.addProperty("callback", callbackId.toString())
|
||||
}.toString()
|
||||
)
|
||||
it.ws.flush()
|
||||
sent = true
|
||||
}
|
||||
return sent
|
||||
}
|
||||
|
||||
suspend fun requestSessionJoin(
|
||||
frontName: String,
|
||||
|
@ -91,12 +91,32 @@ script-src 'self' https://*.cloudflare.com/ https://alcdn.msauth.net/ https://*.
|
||||
<p>WebSocket connection status: <span class="text-white bg-dark" id="connection_status">?</span></p>
|
||||
<p>CORS Proxy status: <span class="text-white bg-dark" id="cors_status">?</span></p>
|
||||
<hr>
|
||||
<p>Listening to frontend logins from: <span id="listening"></span></p>
|
||||
<p>Listening to frontend logins from:</p>
|
||||
<div id="listening"></div>
|
||||
<div id="actions">
|
||||
<button id="listen_continue" type="button" class="btn btn-primary">Listen to</button>
|
||||
<button id="listen_continue" type="button" class="btn btn-primary">Listen to <span id="mcIdUsername"></span>
|
||||
</button>
|
||||
<button id="listen_premium" type="button" class="btn btn-primary">Listen to premium login</button>
|
||||
<button id="listen_offline" type="button" class="btn btn-primary">Listen to offline mode login</button>
|
||||
</div>
|
||||
<hr>
|
||||
<p>Connecting to backend server:</p>
|
||||
<div id="connect">
|
||||
<form class="input-group">
|
||||
<input id="connect_address" type="text" class="form-control" placeholder="Address">
|
||||
<input id="connect_port" type="number" min="1" max="65535" class="form-control"
|
||||
placeholder="Port">
|
||||
<input id="connect_version" type="text" class="form-control" placeholder="Version">
|
||||
<select class="form-select" id="connect_online">
|
||||
<option value="null" selected>Front Online Mode...</option>
|
||||
<option>AUTO</option>
|
||||
<option value="true">Force online</option>
|
||||
<option value="false">Force offline (recommended for Geyser)</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
<p>You can also use <a href="https://jo0001.github.io/ViaSetup/aspirin" id="viasetup_address">address
|
||||
generator</a></p>
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="settings-tab" class="tab-pane fade" id="settings">
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Minecraft.id
|
||||
let urlParams = new URLSearchParams();
|
||||
window.location.hash.substr(1).split("?")
|
||||
window.location.hash.substring(1).split("?")
|
||||
.map(it => new URLSearchParams(it)
|
||||
.forEach((a, b) => urlParams.append(b, a)));
|
||||
let mcIdUsername = urlParams.get("username");
|
||||
@ -138,7 +138,8 @@ $("#listen_offline").on("click", () => {
|
||||
workers.forEach(it => it.postMessage({action: "listen_pow", user: user, id: taskId, deltaTime: deltaTime}));
|
||||
addToast("Offline username", "Please wait a minute...");
|
||||
});
|
||||
$("#listen_continue").append(document.createTextNode(" " + mcIdUsername)).on("click", () => {
|
||||
$("#mcIdUsername").text(mcIdUsername);
|
||||
$("#listen_continue").on("click", () => {
|
||||
sendSocket(JSON.stringify({
|
||||
"action": "minecraft_id_login",
|
||||
"username": mcIdUsername,
|
||||
@ -449,7 +450,7 @@ class MojangAccount extends McAccount {
|
||||
headers: {"content-type": "application/json"},
|
||||
})
|
||||
.then(r => {
|
||||
if (r.status == 403) {
|
||||
if (r.status === 403) {
|
||||
this.logout();
|
||||
throw "403, token expired?";
|
||||
}
|
||||
@ -548,6 +549,13 @@ class MicrosoftAccount extends McAccount {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
checkActive() {
|
||||
return fetch(getCorsProxy() + "https://api.minecraftservices.com/entitlements/mcstore", {
|
||||
method: "get",
|
||||
headers: {"authorization": "Bearer " + this.accessToken}
|
||||
}).then(data => data.ok);
|
||||
}
|
||||
}
|
||||
|
||||
function findAccountByMcName(name) {
|
||||
@ -727,9 +735,22 @@ function onSocketMsg(event) {
|
||||
}
|
||||
} else if (parsed.action === "session_hash_request") {
|
||||
handleJoinRequest(parsed);
|
||||
} else if (parsed.action === "parameters_request") {
|
||||
handleParametersRequest(parsed);
|
||||
}
|
||||
}
|
||||
|
||||
function handleParametersRequest(parsed) {
|
||||
socket.send(JSON.stringify({
|
||||
action: "parameters_response",
|
||||
callback: parsed["callback"],
|
||||
version: $("#connect_version").val(),
|
||||
host: $("#connect_address").val(),
|
||||
port: parseInt($("#connect_port").val()) || 25565,
|
||||
frontOnline: $("#connect_online").val()
|
||||
}));
|
||||
}
|
||||
|
||||
function listenStoredTokens() {
|
||||
getTokens().forEach(listen);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ self.addEventListener("fetch", evt => {
|
||||
if (!shouldCache(evt.request.url)
|
||||
|| evt.request.method !== "GET") return;
|
||||
evt.respondWith(
|
||||
fromCache(evt.request).catch(() => fromNetwork(evt.request))
|
||||
fromNetwork(evt.request).catch(() => fromCache(evt.request))
|
||||
);
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user