117 lines
2.4 KiB
Swift
117 lines
2.4 KiB
Swift
import Foundation
|
|
import WebSocketKit
|
|
|
|
typealias PlayerName = String
|
|
|
|
class Player {
|
|
|
|
let name: PlayerName
|
|
|
|
var totalPoints: Int
|
|
|
|
var socket: WebSocket?
|
|
|
|
var isNextActor: Bool
|
|
|
|
init(name: PlayerName, points: Int, socket: WebSocket? = nil) {
|
|
self.name = name
|
|
self.socket = socket
|
|
self.isNextActor = false
|
|
self.totalPoints = points
|
|
}
|
|
|
|
init(player: Player) {
|
|
self.name = player.name
|
|
self.socket = player.socket
|
|
self.isNextActor = false
|
|
self.totalPoints = player.totalPoints
|
|
}
|
|
|
|
var actions: [PlayerAction] {
|
|
[]
|
|
}
|
|
|
|
var states: [PlayerState] {
|
|
isConnected ? [] : [.isDisconnected]
|
|
}
|
|
|
|
var info: PlayerInfo {
|
|
var result = PlayerInfo(name: name)
|
|
result.points = totalPoints
|
|
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
|
|
log("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 {
|
|
log("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
|
|
}
|
|
}
|