117 lines
3.5 KiB
Swift
117 lines
3.5 KiB
Swift
import Foundation
|
|
import Vapor
|
|
|
|
let playerPerTable = 4
|
|
|
|
typealias TableId = String
|
|
typealias TableName = String
|
|
|
|
final class Database {
|
|
|
|
private let players: PlayerManagement
|
|
|
|
private let tables: TableManagement
|
|
|
|
private var sessions: [SessionToken : WebSocket]
|
|
|
|
init() {
|
|
self.players = PlayerManagement()
|
|
self.tables = TableManagement()
|
|
self.sessions = [:]
|
|
// TODO: Load server data from disk
|
|
// TODO: Save data to disk
|
|
}
|
|
|
|
// MARK: Players & Sessions
|
|
|
|
func registerPlayer(named name: PlayerName, hash: PasswordHash) -> SessionToken? {
|
|
players.registerPlayer(named: name, hash: hash)
|
|
}
|
|
|
|
func passwordHashForExistingPlayer(named name: PlayerName) -> PasswordHash? {
|
|
players.passwordHash(ofRegisteredPlayer: name)
|
|
}
|
|
|
|
func deletePlayer(named name: PlayerName) {
|
|
if let sessionToken = players.deletePlayer(named: name) {
|
|
closeAndRemoveSession(for: sessionToken)
|
|
}
|
|
// TODO: Delete player from tables
|
|
}
|
|
|
|
func isValid(sessionToken token: SessionToken) -> Bool {
|
|
players.isValid(sessionToken: token)
|
|
}
|
|
|
|
func startSession(socket: WebSocket, sessionToken: SessionToken) {
|
|
closeAndRemoveSession(for: sessionToken)
|
|
sessions[sessionToken] = socket
|
|
socket.onText { [weak self] socket, text in
|
|
self?.didReceive(message: text, forSessionToken: sessionToken)
|
|
}
|
|
}
|
|
|
|
private func didReceive(message: String, forSessionToken token: SessionToken) {
|
|
// TODO: Handle client requests
|
|
print("Session \(token.prefix(6)): \(message)")
|
|
}
|
|
|
|
func endSession(forSessionToken token: SessionToken) {
|
|
players.endSession(forSessionToken: token)
|
|
closeAndRemoveSession(for: token)
|
|
}
|
|
|
|
private func closeAndRemoveSession(for token: SessionToken) {
|
|
_ = sessions.removeValue(forKey: token)?.close()
|
|
}
|
|
|
|
/**
|
|
Start a new session for an existing user.
|
|
- Parameter name: The user name
|
|
- Returns: The generated access token for the session
|
|
*/
|
|
func startNewSessionForRegisteredPlayer(named name: PlayerName) -> SessionToken {
|
|
players.startNewSessionForRegisteredPlayer(named: name)
|
|
}
|
|
|
|
func registeredPlayerExists(withSessionToken token: SessionToken) -> PlayerName? {
|
|
players.registeredPlayerExists(withSessionToken: token)
|
|
}
|
|
|
|
// MARK: Tables
|
|
|
|
func tableExists(withId id: TableId) -> Bool {
|
|
tables.tableExists(withId: id)
|
|
}
|
|
|
|
func tableIsFull(withId id: TableId) -> Bool {
|
|
tables.tableIsFull(withId: id)
|
|
}
|
|
|
|
/**
|
|
Create a new table with optional players.
|
|
- Parameter name: The name of the table
|
|
- Parameter players: The player creating the table
|
|
- Parameter visible: Indicates that this is a game joinable by everyone
|
|
- Returns: The table id
|
|
*/
|
|
func createTable(named name: TableName, player: PlayerName, visible: Bool) -> TableId {
|
|
tables.createTable(named: name, player: player, visible: visible)
|
|
}
|
|
|
|
func getPublicTableInfos() -> [TableInfo] {
|
|
tables.getPublicTableInfos()
|
|
}
|
|
|
|
func join(tableId: TableId, player: PlayerName) {
|
|
let playersAtTable = tables.join(tableId: tableId, player: player)
|
|
playersAtTable
|
|
.compactMap { players.sessionToken(forPlayer: $0) } // Session Tokens
|
|
.compactMap { sessions[$0] } // Sockets
|
|
.forEach { socket in
|
|
// TODO: Notify sessions about changed players
|
|
// socket.send("")
|
|
}
|
|
}
|
|
}
|