mirror of
https://github.com/ViaVersion/VIAaaS.git
synced 2024-11-15 10:55:27 +01:00
native transport, refresh account only when used, console command completing
closes #8 closes #9
This commit is contained in:
parent
7d4ee38392
commit
bb7778d9a9
@ -1,6 +1,7 @@
|
|||||||
VIAaaS
|
VIAaaS
|
||||||
---
|
---
|
||||||
Idea: server.example.com._p25565._v1_12_2._otrue.viaaas.example.com (default backend 25565 port and version default as auto, online-mode can be optional/required) (similar to tor to web proxies)
|
Idea: server.example.com._p25565._v1_12_2._otrue._uBACKUSERNAME.viaaas.example.com (default backend 25565 port and version
|
||||||
|
default as auto, online-mode can be optional/required) (similar to tor to web proxies)
|
||||||
|
|
||||||
- TODO: _o option for disabling online mode only in front end, protocol auto detection
|
- TODO: _o option for disabling online mode only in front end, protocol auto detection
|
||||||
|
|
||||||
@ -18,8 +19,10 @@ Usage for offline mode:
|
|||||||
|
|
||||||
Usage for online mode (may block your Mojang account):
|
Usage for online mode (may block your Mojang account):
|
||||||
- Run the shadow jar or ./gradlew clean run
|
- Run the shadow jar or ./gradlew clean run
|
||||||
- You'll need 2 premium accounts for online mode
|
- You'll need 2 premium accounts for online mode (using only one account is possible but, as only one access tokens
|
||||||
- Set up a CORS Proxy (something like https://github.com/Rob--W/cors-anywhere (less likely to look suspicious to Mojang if you run on your local machine) or https://github.com/Zibri/cloudflare-cors-anywhere (more suspicious)).
|
can be active, your Minecraft client will give Bad Login after you approve the login)
|
||||||
|
- Set up a CORS Proxy (something like https://github.com/Rob--W/cors-anywhere (less likely to look suspicious to
|
||||||
|
Mojang if you run on your local machine) or https://github.com/Zibri/cloudflare-cors-anywhere (more suspicious)).
|
||||||
- Go to https://localhost:25543/auth.html, configure the CORS Proxy URL and listen to the username you're using to connect.
|
- Go to https://localhost:25543/auth.html, configure the CORS Proxy URL and listen to the username you're using to connect.
|
||||||
- Log in into Minecraft account with the username you'll use in _u option via browser.
|
- Log in into Minecraft account with the username you'll use in _u option via browser.
|
||||||
- Connect to mc.example.com._v1_8.viaaas._u(BACKUSERNAME).localhost
|
- Connect to mc.example.com._v1_8.viaaas._u(BACKUSERNAME).localhost
|
||||||
|
@ -12,7 +12,6 @@ import io.netty.channel.ChannelHandlerContext
|
|||||||
import io.netty.channel.ChannelOption
|
import io.netty.channel.ChannelOption
|
||||||
import io.netty.channel.SimpleChannelInboundHandler
|
import io.netty.channel.SimpleChannelInboundHandler
|
||||||
import io.netty.channel.socket.SocketChannel
|
import io.netty.channel.socket.SocketChannel
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -145,7 +144,7 @@ class HandshakeState : MinecraftConnectionState {
|
|||||||
|| addrInfo.isAnyLocalAddress) throw SecurityException("Local addresses aren't allowed")
|
|| addrInfo.isAnyLocalAddress) throw SecurityException("Local addresses aren't allowed")
|
||||||
|
|
||||||
val bootstrap = Bootstrap().handler(BackendInit(handler.user))
|
val bootstrap = Bootstrap().handler(BackendInit(handler.user))
|
||||||
.channel(NioSocketChannel::class.java)
|
.channelFactory(channelSocketFactory())
|
||||||
.group(handler.user.channel!!.eventLoop())
|
.group(handler.user.channel!!.eventLoop())
|
||||||
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 15_000) // Half of mc timeout
|
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 15_000) // Half of mc timeout
|
||||||
.connect(socketAddr)
|
.connect(socketAddr)
|
||||||
@ -403,7 +402,7 @@ fun encryptRsa(publicKey: PublicKey, data: ByteArray) = Cipher.getInstance("RSA"
|
|||||||
it.doFinal(data)
|
it.doFinal(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mcCfb8(key: ByteArray, mode: Int) : Cipher {
|
fun mcCfb8(key: ByteArray, mode: Int): Cipher {
|
||||||
val spec = SecretKeySpec(key, "AES")
|
val spec = SecretKeySpec(key, "AES")
|
||||||
val iv = IvParameterSpec(key)
|
val iv = IvParameterSpec(key)
|
||||||
return Cipher.getInstance("AES/CFB8/NoPadding").let {
|
return Cipher.getInstance("AES/CFB8/NoPadding").let {
|
||||||
|
@ -10,11 +10,27 @@ import io.ktor.network.tls.certificates.*
|
|||||||
import io.ktor.server.engine.*
|
import io.ktor.server.engine.*
|
||||||
import io.ktor.server.netty.*
|
import io.ktor.server.netty.*
|
||||||
import io.netty.bootstrap.ServerBootstrap
|
import io.netty.bootstrap.ServerBootstrap
|
||||||
|
import io.netty.channel.ChannelFactory
|
||||||
import io.netty.channel.ChannelOption
|
import io.netty.channel.ChannelOption
|
||||||
|
import io.netty.channel.EventLoopGroup
|
||||||
|
import io.netty.channel.epoll.Epoll
|
||||||
|
import io.netty.channel.epoll.EpollEventLoopGroup
|
||||||
|
import io.netty.channel.epoll.EpollServerSocketChannel
|
||||||
|
import io.netty.channel.epoll.EpollSocketChannel
|
||||||
|
import io.netty.channel.kqueue.KQueue
|
||||||
|
import io.netty.channel.kqueue.KQueueEventLoopGroup
|
||||||
|
import io.netty.channel.kqueue.KQueueServerSocketChannel
|
||||||
|
import io.netty.channel.kqueue.KQueueSocketChannel
|
||||||
import io.netty.channel.nio.NioEventLoopGroup
|
import io.netty.channel.nio.NioEventLoopGroup
|
||||||
|
import io.netty.channel.socket.ServerSocketChannel
|
||||||
|
import io.netty.channel.socket.SocketChannel
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel
|
import io.netty.channel.socket.nio.NioServerSocketChannel
|
||||||
|
import io.netty.channel.socket.nio.NioSocketChannel
|
||||||
import io.netty.util.concurrent.Future
|
import io.netty.util.concurrent.Future
|
||||||
import net.minecrell.terminalconsole.SimpleTerminalConsole
|
import net.minecrell.terminalconsole.SimpleTerminalConsole
|
||||||
|
import org.jline.reader.Candidate
|
||||||
|
import org.jline.reader.LineReader
|
||||||
|
import org.jline.reader.LineReaderBuilder
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import us.myles.ViaVersion.ViaManager
|
import us.myles.ViaVersion.ViaManager
|
||||||
import us.myles.ViaVersion.api.Via
|
import us.myles.ViaVersion.api.Via
|
||||||
@ -23,7 +39,6 @@ import us.myles.ViaVersion.api.data.MappingDataLoader
|
|||||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion
|
import us.myles.ViaVersion.api.protocol.ProtocolVersion
|
||||||
import us.myles.ViaVersion.util.Config
|
import us.myles.ViaVersion.util.Config
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.lang.IllegalArgumentException
|
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.security.KeyPairGenerator
|
import java.security.KeyPairGenerator
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -49,6 +64,30 @@ val mcCryptoKey = KeyPairGenerator.getInstance("RSA").let {
|
|||||||
it.genKeyPair()
|
it.genKeyPair()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun eventLoopGroup(): EventLoopGroup {
|
||||||
|
if (VIAaaSConfig.isNativeTransportMc) {
|
||||||
|
if (Epoll.isAvailable()) return EpollEventLoopGroup()
|
||||||
|
if (KQueue.isAvailable()) return KQueueEventLoopGroup()
|
||||||
|
}
|
||||||
|
return NioEventLoopGroup()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun channelServerSocketFactory(): ChannelFactory<ServerSocketChannel> {
|
||||||
|
if (VIAaaSConfig.isNativeTransportMc) {
|
||||||
|
if (Epoll.isAvailable()) return ChannelFactory { EpollServerSocketChannel() }
|
||||||
|
if (KQueue.isAvailable()) return ChannelFactory { KQueueServerSocketChannel() }
|
||||||
|
}
|
||||||
|
return ChannelFactory { NioServerSocketChannel() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun channelSocketFactory(): ChannelFactory<SocketChannel> {
|
||||||
|
if (VIAaaSConfig.isNativeTransportMc) {
|
||||||
|
if (Epoll.isAvailable()) return ChannelFactory { EpollSocketChannel() }
|
||||||
|
if (KQueue.isAvailable()) return ChannelFactory { KQueueSocketChannel() }
|
||||||
|
}
|
||||||
|
return ChannelFactory { NioSocketChannel() }
|
||||||
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
File("config/https.jks").apply {
|
File("config/https.jks").apply {
|
||||||
parentFile.mkdirs()
|
parentFile.mkdirs()
|
||||||
@ -65,10 +104,12 @@ fun main(args: Array<String>) {
|
|||||||
CloudRewind.init(ViaRewindConfigImpl(File("config/viarewind.yml")))
|
CloudRewind.init(ViaRewindConfigImpl(File("config/viarewind.yml")))
|
||||||
CloudBackwards.init(File("config/viabackwards.yml"))
|
CloudBackwards.init(File("config/viabackwards.yml"))
|
||||||
|
|
||||||
val boss = NioEventLoopGroup()
|
val parent = eventLoopGroup()
|
||||||
val worker = NioEventLoopGroup()
|
val child = eventLoopGroup()
|
||||||
val future = ServerBootstrap().group(boss, worker)
|
|
||||||
.channel(NioServerSocketChannel::class.java)
|
val future = ServerBootstrap()
|
||||||
|
.group(parent, child)
|
||||||
|
.channelFactory(channelServerSocketFactory())
|
||||||
.childHandler(ChannelInit)
|
.childHandler(ChannelInit)
|
||||||
.childOption(ChannelOption.IP_TOS, 0x18)
|
.childOption(ChannelOption.IP_TOS, 0x18)
|
||||||
.childOption(ChannelOption.TCP_NODELAY, true)
|
.childOption(ChannelOption.TCP_NODELAY, true)
|
||||||
@ -91,28 +132,65 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
ktorServer?.stop(1000, 1000)
|
ktorServer?.stop(1000, 1000)
|
||||||
httpClient.close()
|
httpClient.close()
|
||||||
listOf<Future<*>>(future.channel().close(), boss.shutdownGracefully(), worker.shutdownGracefully())
|
listOf<Future<*>>(future.channel().close(), parent.shutdownGracefully(), child.shutdownGracefully())
|
||||||
.forEach { it.sync() }
|
.forEach { it.sync() }
|
||||||
|
|
||||||
Via.getManager().destroy()
|
Via.getManager().destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
class VIAaaSConsole : SimpleTerminalConsole(), ViaCommandSender {
|
class VIAaaSConsole : SimpleTerminalConsole(), ViaCommandSender {
|
||||||
val commands = hashMapOf<String, (String, Array<String>) -> Unit>()
|
val commands = hashMapOf<String, (MutableList<String>?, String, Array<String>) -> Unit>()
|
||||||
override fun isRunning(): Boolean = runningServer
|
override fun isRunning(): Boolean = runningServer
|
||||||
|
|
||||||
init {
|
init {
|
||||||
commands["stop"] = { _, _ -> this.shutdown() }
|
commands["stop"] = { suggestion, _, _ -> if (suggestion == null) this.shutdown() }
|
||||||
commands["end"] = commands["stop"]!!
|
commands["end"] = commands["stop"]!!
|
||||||
commands["viaversion"] = { _, args ->
|
commands["viaversion"] = { suggestion, _, args ->
|
||||||
Via.getManager().commandHandler.onCommand(this, args)
|
if (suggestion == null) {
|
||||||
|
Via.getManager().commandHandler.onCommand(this, args)
|
||||||
|
} else {
|
||||||
|
suggestion.addAll(Via.getManager().commandHandler.onTabComplete(this, args))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
commands["viaver"] = commands["viaversion"]!!
|
commands["viaver"] = commands["viaversion"]!!
|
||||||
commands["vvcloud"] = commands["viaversion"]!!
|
commands["vvcloud"] = commands["viaversion"]!!
|
||||||
commands["help"] = { _, _ ->
|
commands["help"] = { suggestion , _, _ ->
|
||||||
sendMessage(commands.keys.toString())
|
if (suggestion == null) sendMessage(commands.keys.toString())
|
||||||
}
|
}
|
||||||
commands["?"] = commands["help"]!!
|
commands["?"] = commands["help"]!!
|
||||||
|
commands["list"] = { suggestion, _, _ ->
|
||||||
|
if (suggestion == null) {
|
||||||
|
Via.getPlatform().connectionManager.connections.forEach {
|
||||||
|
sendMessage("${it.channel?.remoteAddress()} (${it.protocolInfo?.protocolVersion}) -> " +
|
||||||
|
"(${it.protocolInfo?.serverProtocolVersion}) " +
|
||||||
|
"${it.channel?.pipeline()?.get(CloudMinecraftHandler::class.java)?.other?.remoteAddress()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun buildReader(builder: LineReaderBuilder): LineReader {
|
||||||
|
// Stolen from Velocity
|
||||||
|
return super.buildReader(builder.appName("VIAaaS").completer { _, line, candidates ->
|
||||||
|
try {
|
||||||
|
val cmdArgs = line.line().substring(0, line.cursor()).split(" ")
|
||||||
|
val alias = cmdArgs[0]
|
||||||
|
val args = cmdArgs.filterIndexed { i, _ -> i > 0 }
|
||||||
|
if (cmdArgs.size == 1) {
|
||||||
|
candidates.addAll(commands.keys.filter { it.startsWith(alias, ignoreCase = true) }
|
||||||
|
.map { Candidate(it) })
|
||||||
|
} else {
|
||||||
|
val cmd = commands[alias.toLowerCase()]
|
||||||
|
if (cmd != null) {
|
||||||
|
val suggestions = mutableListOf<String>()
|
||||||
|
cmd(suggestions, alias, args.toTypedArray())
|
||||||
|
candidates.addAll(suggestions.map(::Candidate))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
sendMessage("Error completing command: $e")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun runCommand(command: String) {
|
override fun runCommand(command: String) {
|
||||||
@ -124,7 +202,7 @@ class VIAaaSConsole : SimpleTerminalConsole(), ViaCommandSender {
|
|||||||
if (runnable == null) {
|
if (runnable == null) {
|
||||||
sendMessage("unknown command, try 'help'")
|
sendMessage("unknown command, try 'help'")
|
||||||
} else {
|
} else {
|
||||||
runnable(alias, args)
|
runnable(null, alias, args)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
sendMessage("Error running command: $e")
|
sendMessage("Error running command: $e")
|
||||||
@ -160,6 +238,7 @@ object VIAaaSConfig : Config(File("config/viaaas.yml")) {
|
|||||||
override fun handleConfig(p0: MutableMap<String, Any>?) {
|
override fun handleConfig(p0: MutableMap<String, Any>?) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val isNativeTransportMc: Boolean get() = this.getBoolean("native-transport-mc", true)
|
||||||
val port: Int get() = this.getInt("port", 25565)
|
val port: Int get() = this.getInt("port", 25565)
|
||||||
val bindAddress: String get() = this.getString("bind-address", "localhost")!!
|
val bindAddress: String get() = this.getString("bind-address", "localhost")!!
|
||||||
val hostName: String get() = this.getString("host-name", "viaaas.localhost")!!
|
val hostName: String get() = this.getString("host-name", "viaaas.localhost")!!
|
||||||
@ -171,7 +250,7 @@ class VIAaaSAddress {
|
|||||||
var realAddress: String? = null
|
var realAddress: String? = null
|
||||||
var port: Int? = null
|
var port: Int? = null
|
||||||
var online = true
|
var online = true
|
||||||
var altUsername : String? = null
|
var altUsername: String? = null
|
||||||
fun parse(address: String, viaHostName: String): VIAaaSAddress {
|
fun parse(address: String, viaHostName: String): VIAaaSAddress {
|
||||||
val parts = address.split('.')
|
val parts = address.split('.')
|
||||||
var foundDomain = false
|
var foundDomain = false
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
# See application.conf in resources for https interface options
|
## CHANGING THIS CONFIG AT RUNTIME ISN'T SUPPORTED
|
||||||
|
## See application.conf in resources for https interface options
|
||||||
# Port used for binding Minecraft port
|
# Port used for binding Minecraft port
|
||||||
port: 25565
|
port: 25565
|
||||||
# Address to bind
|
# Address to bind
|
||||||
bind-address: localhost
|
bind-address: localhost
|
||||||
# Host name of this instance, that will be used in the virtual host
|
# Host name of this instance, that will be used in the virtual host
|
||||||
host-name: viaaas.localhost
|
host-name: viaaas.localhost
|
||||||
|
# Use netty native transport for Minecraft when available.
|
||||||
|
native-transport-mc: true
|
@ -93,9 +93,11 @@
|
|||||||
|
|
||||||
function storeMcAccount(accessToken, clientToken, name, id) {
|
function storeMcAccount(accessToken, clientToken, name, id) {
|
||||||
let accounts = JSON.parse(localStorage.getItem("mc_accounts")) || [];
|
let accounts = JSON.parse(localStorage.getItem("mc_accounts")) || [];
|
||||||
accounts.push({accessToken: accessToken, clientToken: clientToken, name: name, id: id});
|
let account = {accessToken: accessToken, clientToken: clientToken, name: name, id: id};
|
||||||
|
accounts.push(account);
|
||||||
localStorage.setItem("mc_accounts", JSON.stringify(accounts));
|
localStorage.setItem("mc_accounts", JSON.stringify(accounts));
|
||||||
refreshAccountList();
|
refreshAccountList();
|
||||||
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeMcAccount(id) {
|
function removeMcAccount(id) {
|
||||||
@ -149,42 +151,43 @@
|
|||||||
getMcAccounts().forEach(it => addMcAccountToList(it.id, it.name));
|
getMcAccounts().forEach(it => addMcAccountToList(it.id, it.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshAccountsIfNeeded() {
|
function refreshAccountIfNeeded(it, doneCallback, failCallback) {
|
||||||
getMcAccounts().forEach(it => {
|
$.ajax({type: "post",
|
||||||
|
url: localStorage.getItem("cors-proxy") + "https://authserver.mojang.com/validate",
|
||||||
|
data: JSON.stringify({
|
||||||
|
accessToken: it.accessToken,
|
||||||
|
clientToken: it.clientToken
|
||||||
|
}),
|
||||||
|
contentType: "application/json",
|
||||||
|
dataType: "json"
|
||||||
|
})
|
||||||
|
.done(() => doneCallback(it))
|
||||||
|
.fail(() => {
|
||||||
|
// Needs refresh
|
||||||
|
console.log("refreshing " + it.id);
|
||||||
$.ajax({type: "post",
|
$.ajax({type: "post",
|
||||||
url: localStorage.getItem("cors-proxy") + "https://authserver.mojang.com/validate",
|
url: localStorage.getItem("cors-proxy") + "https://authserver.mojang.com/refresh",
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
accessToken: it.accessToken,
|
accessToken: it.accessToken,
|
||||||
clientToken: it.clientToken
|
clientToken: it.clientToken
|
||||||
}),
|
}),
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
dataType: "json"
|
dataType: "json"
|
||||||
|
}).done((data) => {
|
||||||
|
console.log("refreshed " + data.selectedProfile.id);
|
||||||
|
removeMcAccount(data.selectedProfile.id);
|
||||||
|
doneCallback(storeMcAccount(data.accessToken, data.clientToken, data.selectedProfile.name, data.selectedProfile.id));
|
||||||
}).fail(() => {
|
}).fail(() => {
|
||||||
// Needs refresh
|
if (confirm("failed to refresh token! remove account?")) {
|
||||||
$.ajax({type: "post",
|
removeMcAccount(it.id);
|
||||||
url: localStorage.getItem("cors-proxy") + "https://authserver.mojang.com/refresh",
|
}
|
||||||
data: JSON.stringify({
|
failCallback();
|
||||||
accessToken: it.accessToken,
|
|
||||||
clientToken: it.clientToken
|
|
||||||
}),
|
|
||||||
contentType: "application/json",
|
|
||||||
dataType: "json"
|
|
||||||
}).done((data) => {
|
|
||||||
removeMcAccount(data.selectedProfile.id);
|
|
||||||
storeMcAccount(data.accessToken, data.clientToken, data.selectedProfile.name, data.selectedProfile.id);
|
|
||||||
}).fail(() => {
|
|
||||||
if (confirm("failed to refresh token! remove account?")) {
|
|
||||||
removeMcAccount(it.id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshAccountList();
|
refreshAccountList();
|
||||||
|
|
||||||
refreshAccountsIfNeeded();
|
|
||||||
|
|
||||||
function listen(token) {
|
function listen(token) {
|
||||||
socket.send(JSON.stringify({"action": "listen_login_requests", "token": token}));
|
socket.send(JSON.stringify({"action": "listen_login_requests", "token": token}));
|
||||||
}
|
}
|
||||||
@ -282,22 +285,28 @@
|
|||||||
}
|
}
|
||||||
} else if (parsed.action == "session_hash_request") {
|
} else if (parsed.action == "session_hash_request") {
|
||||||
if (confirm("Confirm auth request sent from VIAaaS instance? info: " + event.data)) {
|
if (confirm("Confirm auth request sent from VIAaaS instance? info: " + event.data)) {
|
||||||
let accounts = getMcAccounts().filter(it => it.user.toLowerCase() == parsed.user.toLowerCase());
|
let accounts = getMcAccounts().filter(it => it.name.toLowerCase() == parsed.user.toLowerCase());
|
||||||
accounts.forEach(it => {
|
accounts.forEach(it => {
|
||||||
$.ajax({type: "post",
|
refreshAccountIfNeeded(it, (data) => {
|
||||||
url: localStorage.getItem("cors-proxy") + "https://sessionserver.mojang.com/session/minecraft/join",
|
$.ajax({type: "post",
|
||||||
data: JSON.stringify({
|
url: localStorage.getItem("cors-proxy") + "https://sessionserver.mojang.com/session/minecraft/join",
|
||||||
accessToken: it.accessToken,
|
data: JSON.stringify({
|
||||||
selectedProfile: it.id,
|
accessToken: data.accessToken,
|
||||||
serverId: parsed.session_hash
|
selectedProfile: data.id,
|
||||||
}),
|
serverId: parsed.session_hash
|
||||||
contentType: "application/json",
|
}),
|
||||||
dataType: "json"
|
contentType: "application/json",
|
||||||
}).done((data) => {
|
dataType: "json"
|
||||||
confirmJoin(parsed.session_hash);
|
}).done((data) => {
|
||||||
}).fail((e) => {
|
confirmJoin(parsed.session_hash);
|
||||||
console.log(e);
|
}).fail((e) => {
|
||||||
alert("Failed to authenticate to Minecraft backend server!");
|
console.log(e);
|
||||||
|
alert("Failed to authenticate to Minecraft backend server!");
|
||||||
|
});
|
||||||
|
}, () => {
|
||||||
|
if (confirm("Couldn't refresh " + parsed.user + " account in browser. Continue without authentication (works on LAN worlds)?")) {
|
||||||
|
confirmJoin(parsed.session_hash);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (accounts.length == 0 && confirm("Couldn't find " + parsed.user + " account in browser. Continue without authentication (works on LAN worlds)?")) {
|
if (accounts.length == 0 && confirm("Couldn't find " + parsed.user + " account in browser. Continue without authentication (works on LAN worlds)?")) {
|
||||||
|
Loading…
Reference in New Issue
Block a user