Renamed login server to auth and data to account.

This commit is contained in:
Daan Vanden Bosch 2021-08-01 16:03:20 +02:00
parent a2285a5a03
commit 73e53177a8
9 changed files with 103 additions and 86 deletions

View File

@ -8,8 +8,8 @@ the `--config=/path/to/config.json` parameter to specify a configuration file.
## Proxy
Phantasmal PSO server can proxy any other PSO server. Below is a sample configuration for proxying a
locally running Tethealla server using a Tethealla client. Be sure to modify tethealla.ini and set
server port to 22000.
locally running Tethealla patch and login server using the standard Tethealla client. Be sure to
modify tethealla.ini and set server port to 22000.
```json
{
@ -36,7 +36,7 @@ server port to 22000.
"remotePort": 22000
},
{
"name": "login_2_proxy",
"name": "character_proxy",
"version": "BB",
"bindPort": 12001,
"remotePort": 22001

View File

@ -6,8 +6,8 @@ import kotlinx.serialization.Serializable
class Config(
val address: String? = null,
val patch: PatchServerConfig? = null,
val login: ServerConfig? = null,
val data: ServerConfig? = null,
val auth: ServerConfig? = null,
val account: ServerConfig? = null,
val proxy: ProxyConfig? = null,
)

View File

@ -11,8 +11,8 @@ import world.phantasmal.psoserv.messages.Message
import world.phantasmal.psoserv.messages.MessageDescriptor
import world.phantasmal.psoserv.messages.PcMessageDescriptor
import world.phantasmal.psoserv.servers.*
import world.phantasmal.psoserv.servers.character.DataServer
import world.phantasmal.psoserv.servers.login.LoginServer
import world.phantasmal.psoserv.servers.account.AccountServer
import world.phantasmal.psoserv.servers.auth.AuthServer
import world.phantasmal.psoserv.servers.patch.PatchServer
import java.io.File
import java.net.Inet4Address
@ -87,8 +87,8 @@ private class PhantasmalServer(
private fun initialize(config: Config): PhantasmalServer {
val defaultAddress = config.address?.let(::inet4Address) ?: DEFAULT_ADDRESS
val dataAddress = config.data?.address?.let(::inet4Address) ?: defaultAddress
val dataPort = config.data?.port ?: DEFAULT_DATA_PORT
val dataAddress = config.account?.address?.let(::inet4Address) ?: defaultAddress
val dataPort = config.account?.port ?: DEFAULT_DATA_PORT
val servers = mutableListOf<Server>()
@ -112,17 +112,17 @@ private fun initialize(config: Config): PhantasmalServer {
)
}
if (config.login == null && run || config.login?.run == true) {
if (config.auth == null && run || config.auth?.run == true) {
val bindPair = Inet4Pair(
config.login?.address?.let(::inet4Address) ?: defaultAddress,
config.login?.port ?: DEFAULT_LOGIN_PORT,
config.auth?.address?.let(::inet4Address) ?: defaultAddress,
config.auth?.port ?: DEFAULT_LOGIN_PORT,
)
LOGGER.info { "Configuring login server to bind to $bindPair." }
LOGGER.info { "Configuring auth server to bind to $bindPair." }
servers.add(
LoginServer(
name = "login",
AuthServer(
name = "auth",
bindPair,
dataServerAddress = dataAddress,
dataServerPort = dataPort,
@ -130,17 +130,17 @@ private fun initialize(config: Config): PhantasmalServer {
)
}
if (config.data == null && run || config.data?.run == true) {
if (config.account == null && run || config.account?.run == true) {
val bindPair = Inet4Pair(
config.data?.address?.let(::inet4Address) ?: defaultAddress,
config.data?.port ?: DEFAULT_DATA_PORT,
config.account?.address?.let(::inet4Address) ?: defaultAddress,
config.account?.port ?: DEFAULT_DATA_PORT,
)
LOGGER.info { "Configuring data server to bind to $bindPair." }
LOGGER.info { "Configuring account server to bind to $bindPair." }
servers.add(
DataServer(
name = "data",
AccountServer(
name = "account",
bindPair,
)
)

View File

@ -223,8 +223,8 @@ sealed class BbMessage(override val buffer: Buffer) : AbstractMessage(BB_HEADER_
// 2092 Bytes of team data.
repeat(523) { writeInt(0) }
// Enable all team rewards.
writeUInt(UInt.MAX_VALUE)
writeUInt(UInt.MAX_VALUE)
writeUInt(0xFFFFFFFFu)
writeUInt(0xFFFFFFFFu)
}
)
}

View File

@ -6,7 +6,6 @@ import java.net.InetSocketAddress
class Inet4Pair(addr: Inet4Address, port: Int) : InetSocketAddress(addr, port) {
constructor(addr: ByteArray, port: Int) : this(inet4Address(addr), port)
constructor(addr: String, port: Int) : this(inet4Address(addr), port)
val address: Inet4Address get() = super.getAddress() as Inet4Address
}

View File

@ -1,4 +1,4 @@
package world.phantasmal.psoserv.servers.character
package world.phantasmal.psoserv.servers.account
import world.phantasmal.psoserv.encryption.Cipher
import world.phantasmal.psoserv.messages.BbMessage
@ -6,17 +6,17 @@ import world.phantasmal.psoserv.servers.BbServer
import world.phantasmal.psoserv.servers.Inet4Pair
import world.phantasmal.psoserv.servers.SocketSender
class DataServer(
class AccountServer(
name: String,
bindPair: Inet4Pair,
) : BbServer<DataState>(name, bindPair) {
) : BbServer<AccountState>(name, bindPair) {
override fun initializeState(
sender: SocketSender<BbMessage>,
serverCipher: Cipher,
clientCipher: Cipher,
): DataState {
val ctx = DataContext(logger, sender)
): AccountState {
val ctx = AccountContext(logger, sender)
ctx.send(
BbMessage.InitEncryption(
@ -27,6 +27,6 @@ class DataServer(
encrypt = false,
)
return DataState.Authentication(ctx)
return AccountState.Authentication(ctx)
}
}

View File

@ -1,4 +1,4 @@
package world.phantasmal.psoserv.servers.character
package world.phantasmal.psoserv.servers.account
import mu.KLogger
import world.phantasmal.core.math.clamp
@ -13,14 +13,16 @@ import world.phantasmal.psoserv.servers.ServerStateContext
import world.phantasmal.psoserv.servers.SocketSender
import kotlin.math.min
class DataContext(
class AccountContext(
logger: KLogger,
socketSender: SocketSender<BbMessage>,
) : ServerStateContext<BbMessage>(logger, socketSender)
sealed class DataState(ctx: DataContext) : ServerState<BbMessage, DataContext, DataState>(ctx) {
class Authentication(ctx: DataContext) : DataState(ctx) {
override fun process(message: BbMessage): DataState =
sealed class AccountState(ctx: AccountContext) :
ServerState<BbMessage, AccountContext, AccountState>(ctx) {
class Authentication(ctx: AccountContext) : AccountState(ctx) {
override fun process(message: BbMessage): AccountState =
if (message is BbMessage.Authenticate) {
// TODO: Actual authentication.
ctx.send(
@ -31,26 +33,26 @@ sealed class DataState(ctx: DataContext) : ServerState<BbMessage, DataContext, D
)
)
Account(ctx)
GetAccount(ctx)
} else {
unexpectedMessage(message)
}
}
class Account(ctx: DataContext) : DataState(ctx) {
override fun process(message: BbMessage): DataState =
class GetAccount(ctx: AccountContext) : AccountState(ctx) {
override fun process(message: BbMessage): AccountState =
if (message is BbMessage.GetAccount) {
// TODO: Send correct guild card number and team ID.
ctx.send(BbMessage.Account(0, 0))
CharacterSelect(ctx)
GetCharacters(ctx)
} else {
unexpectedMessage(message)
}
}
class CharacterSelect(ctx: DataContext) : DataState(ctx) {
override fun process(message: BbMessage): DataState =
class GetCharacters(ctx: AccountContext) : AccountState(ctx) {
override fun process(message: BbMessage): AccountState =
when (message) {
is BbMessage.CharacterSelect -> {
// TODO: Look up character data.
@ -89,19 +91,17 @@ sealed class DataState(ctx: DataContext) : ServerState<BbMessage, DataContext, D
// TODO: Checksum checking.
ctx.send(BbMessage.ChecksumResponse(true))
DataDownload(ctx)
GetGuildCardData(ctx)
}
else -> unexpectedMessage(message)
}
}
class DataDownload(ctx: DataContext) : DataState(ctx) {
class GetGuildCardData(ctx: AccountContext) : AccountState(ctx) {
private val guildCardBuffer = Buffer.withSize(54672)
private val fileBuffer = Buffer.withSize(0)
private var fileChunkNo = 0
override fun process(message: BbMessage): DataState =
override fun process(message: BbMessage): AccountState =
when (message) {
is BbMessage.GetGuildCardHeader -> {
ctx.send(
@ -126,28 +126,11 @@ sealed class DataState(ctx: DataContext) : ServerState<BbMessage, DataContext, D
guildCardBuffer.cursor(offset, size),
)
)
}
this
} else {
GetFiles(ctx)
}
is BbMessage.GetFileList -> {
ctx.send(BbMessage.FileList())
this
}
is BbMessage.GetFileChunk -> {
val offset = min(fileChunkNo * MAX_CHUNK_SIZE, fileBuffer.size)
val size = min(fileBuffer.size - offset, MAX_CHUNK_SIZE)
ctx.send(BbMessage.FileChunk(fileChunkNo, fileBuffer.cursor(offset, size)))
if (offset + size < fileBuffer.size) {
fileChunkNo++
}
this
}
else -> unexpectedMessage(message)
@ -177,8 +160,41 @@ sealed class DataState(ctx: DataContext) : ServerState<BbMessage, DataContext, D
}
}
class Final(ctx: DataContext) : DataState(ctx), FinalServerState {
override fun process(message: BbMessage): DataState =
class GetFiles(ctx: AccountContext) : AccountState(ctx) {
private val fileBuffer = Buffer.withSize(0)
private var fileChunkNo = 0
override fun process(message: BbMessage): AccountState =
when (message) {
is BbMessage.GetFileList -> {
ctx.send(BbMessage.FileList())
this
}
is BbMessage.GetFileChunk -> {
val offset = min(fileChunkNo * MAX_CHUNK_SIZE, fileBuffer.size)
val size = min(fileBuffer.size - offset, MAX_CHUNK_SIZE)
ctx.send(BbMessage.FileChunk(fileChunkNo, fileBuffer.cursor(offset, size)))
if (offset + size < fileBuffer.size) {
fileChunkNo++
}
this
}
else -> unexpectedMessage(message)
}
companion object {
private const val MAX_CHUNK_SIZE: Int = 0x6800
}
}
class Final(ctx: AccountContext) : AccountState(ctx), FinalServerState {
override fun process(message: BbMessage): AccountState =
unexpectedMessage(message)
}
}

View File

@ -1,4 +1,4 @@
package world.phantasmal.psoserv.servers.login
package world.phantasmal.psoserv.servers.auth
import world.phantasmal.psoserv.encryption.Cipher
import world.phantasmal.psoserv.messages.BbMessage
@ -7,19 +7,19 @@ import world.phantasmal.psoserv.servers.Inet4Pair
import world.phantasmal.psoserv.servers.SocketSender
import java.net.Inet4Address
class LoginServer(
class AuthServer(
name: String,
bindPair: Inet4Pair,
private val dataServerAddress: Inet4Address,
private val dataServerPort: Int,
) : BbServer<LoginState>(name, bindPair) {
) : BbServer<AuthState>(name, bindPair) {
override fun initializeState(
sender: SocketSender<BbMessage>,
serverCipher: Cipher,
clientCipher: Cipher,
): LoginState {
val ctx = LoginContext(logger, sender, dataServerAddress.address, dataServerPort)
): AuthState {
val ctx = AuthContext(logger, sender, dataServerAddress.address, dataServerPort)
ctx.send(
BbMessage.InitEncryption(
@ -30,6 +30,6 @@ class LoginServer(
encrypt = false,
)
return LoginState.Authentication(ctx)
return AuthState.Authentication(ctx)
}
}

View File

@ -1,4 +1,4 @@
package world.phantasmal.psoserv.servers.login
package world.phantasmal.psoserv.servers.auth
import mu.KLogger
import world.phantasmal.psoserv.messages.BbAuthenticationStatus
@ -8,16 +8,18 @@ import world.phantasmal.psoserv.servers.ServerState
import world.phantasmal.psoserv.servers.ServerStateContext
import world.phantasmal.psoserv.servers.SocketSender
class LoginContext(
class AuthContext(
logger: KLogger,
socketSender: SocketSender<BbMessage>,
val characterServerAddress: ByteArray,
val characterServerPort: Int,
val accountServerAddress: ByteArray,
val accountServerPort: Int,
) : ServerStateContext<BbMessage>(logger, socketSender)
sealed class LoginState(ctx: LoginContext) : ServerState<BbMessage, LoginContext, LoginState>(ctx) {
class Authentication(ctx: LoginContext) : LoginState(ctx) {
override fun process(message: BbMessage): LoginState =
sealed class AuthState(ctx: AuthContext) :
ServerState<BbMessage, AuthContext, AuthState>(ctx) {
class Authentication(ctx: AuthContext) : AuthState(ctx) {
override fun process(message: BbMessage): AuthState =
if (message is BbMessage.Authenticate) {
// TODO: Actual authentication.
ctx.send(
@ -29,8 +31,8 @@ sealed class LoginState(ctx: LoginContext) : ServerState<BbMessage, LoginContext
)
ctx.send(
BbMessage.Redirect(
ctx.characterServerAddress,
ctx.characterServerPort,
ctx.accountServerAddress,
ctx.accountServerPort,
)
)
@ -40,8 +42,8 @@ sealed class LoginState(ctx: LoginContext) : ServerState<BbMessage, LoginContext
}
}
class Final(ctx: LoginContext) : LoginState(ctx), FinalServerState {
override fun process(message: BbMessage): LoginState =
class Final(ctx: AuthContext) : AuthState(ctx), FinalServerState {
override fun process(message: BbMessage): AuthState =
unexpectedMessage(message)
}
}