Schafkopf-Server/Sources/App/Model/Players/Player.swift
2021-12-21 14:53:47 +01:00

110 lines
2.2 KiB
Swift

import Foundation
import WebSocketKit
class Player {
let name: PlayerName
var socket: WebSocket?
var isNextActor: Bool
init(name: PlayerName, socket: WebSocket? = nil) {
self.name = name
self.socket = socket
self.isNextActor = false
}
init(player: Player) {
self.name = player.name
self.socket = player.socket
self.isNextActor = false
}
var actions: [PlayerAction] {
[]
}
var states: [PlayerState] {
isConnected ? [] : [.isDisconnected]
}
var info: PlayerInfo {
var result = PlayerInfo(name: name)
result.isConnected = isConnected
result.isNextActor = isNextActor
result.state = states.map { $0.rawValue }
return result
}
}
extension Player: Equatable {
static func == (lhs: Player, rhs: Player) -> Bool {
lhs.name == rhs.name
}
}
extension Player {
// MARK: Connection
/// Indicate that the player is connected when at a table
var isConnected: Bool {
guard let socket = socket else {
return false
}
guard !socket.isClosed else {
self.socket = nil
return false
}
return true
}
func connect(using socket: WebSocket) {
_ = self.socket?.close()
self.socket = socket
}
@discardableResult
func disconnect() -> Bool {
guard let socket = socket else {
return false
}
socket.close().whenFailure { [weak self] error in
print("Failed to close socket for player: \(self?.name ?? "<Released>"): \(error)")
}
self.socket = nil
return true
}
@discardableResult
func send(_ info: TableInfo) -> Bool {
guard let socket = socket else {
return false
}
do {
try socket.send(encodeJSON(info))
} catch {
print("Failed to send info: \(error)")
return false
}
return true
}
// MARK: Actions
func canPerform(_ action: PlayerAction) -> Bool {
actions.contains(action)
}
}
extension Player: CustomStringConvertible {
var description: String {
name
}
}