import Foundation import Vapor final class Database { private let players: PlayerManagement private let tables: TableManagement init(storageFolder: URL) throws { self.players = try PlayerManagement(storageFolder: storageFolder) self.tables = TableManagement() // TODO: Load table 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) { _ = players.deletePlayer(named: name) tables.remove(player: name) } func isValid(sessionToken token: SessionToken) -> Bool { players.isValid(sessionToken: token) } func startSession(socket: WebSocket, sessionToken: SessionToken) -> Bool { guard let player = players.registeredPlayerExists(withSessionToken: sessionToken) else { return false } return tables.connect(player: player, using: socket) } private func didReceive(message: String, forSessionToken token: SessionToken) { // TODO: Handle client requests print("Session \(token.prefix(6)): \(message)") } func endSession(forSessionToken sessionToken: SessionToken) { guard let player = players.endSession(forSessionToken: sessionToken) else { return } closeSession(for: player) } private func closeSession(for player: PlayerName) { tables.disconnect(player: player) } /** 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) } func currentTableOfPlayer(named player: PlayerName) -> TableId { tables.currentTableOfPlayer(named: player) ?? "" } // MARK: Tables /** 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, playerToken: SessionToken) -> JoinTableResult { guard let player = players.registeredPlayerExists(withSessionToken: playerToken) else { return .invalidToken } return tables.join(tableId: tableId, player: player) } func leaveTable(playerToken: SessionToken) -> Bool { guard let player = players.registeredPlayerExists(withSessionToken: playerToken) else { return false } tables.remove(player: player) return true } }