-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmodel.scala
174 lines (134 loc) · 4.57 KB
/
model.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package lila.ws
import strategygames.{ Player => PlayerIndex }
import strategygames.format.{ FEN, Uci }
trait StringValue extends Any {
def value: String
override def toString = value
}
trait IntValue extends Any {
def value: Int
override def toString = value.toString
}
case class User(id: User.ID) extends AnyVal
object User {
type ID = String
}
object Game {
case class Id(value: String) extends AnyVal with StringValue {
def full(playerId: PlayerId) = FullId(s"$value$playerId")
}
case class FullId(value: String) extends AnyVal with StringValue {
def gameId = Id(value take 8)
def playerId = PlayerId(value drop 8)
}
case class PlayerId(value: String) extends AnyVal with StringValue
case class Player(id: PlayerId, userId: Option[User.ID])
// must only contain invariant data (no status, turns, or termination)
// because it's cached in Mongo.scala
case class Round(id: Id, players: PlayerIndex.Map[Player], ext: Option[RoundExt]) {
def player(id: PlayerId, userId: Option[User.ID]): Option[RoundPlayer] =
PlayerIndex.all.collectFirst {
case c if players(c).id == id && players(c).userId == userId => RoundPlayer(id, c, ext)
}
}
case class RoundPlayer(
id: PlayerId,
playerIndex: PlayerIndex,
ext: Option[RoundExt]
) {
def tourId = ext collect { case RoundExt.Tour(id) => id }
def swissId = ext collect { case RoundExt.Swiss(id) => id }
def simulId = ext collect { case RoundExt.Simul(id) => id }
}
sealed abstract trait RoundExt { val id: String }
object RoundExt {
case class Tour(id: String) extends RoundExt
case class Swiss(id: String) extends RoundExt
case class Simul(id: String) extends RoundExt
}
}
object Simul {
type ID = String
}
case class Simul(id: Simul.ID) extends AnyVal
object Tour {
type ID = String
}
case class Tour(id: Tour.ID) extends AnyVal
object Study {
type ID = String
}
case class Study(id: Study.ID) extends AnyVal
object Chat {
type ID = String
}
object Team {
type ID = String
}
object Swiss {
type ID = String
}
object Challenge {
case class Id(value: String) extends AnyVal with StringValue
sealed trait Challenger
case class Anon(secret: String) extends Challenger
case class User(userId: String) extends Challenger
case object Open extends Challenger
}
object Racer {
type RaceId = String
sealed trait PlayerId
object PlayerId {
case class User(uid: String) extends PlayerId { override def toString = uid }
case class Anon(sid: String) extends PlayerId { override def toString = s"@$sid" }
}
}
case class Chat(id: Chat.ID) extends AnyVal
case class Sri(value: String) extends AnyVal with StringValue
object Sri {
type Str = String
def random = Sri(util.Util.secureRandom string 12)
def from(str: String): Option[Sri] =
if (str contains ' ') None
else Some(Sri(str))
}
case class Flag private (value: String) extends AnyVal with StringValue
object Flag {
def make(value: String) =
value match {
case "simul" | "tournament" | "api" => Some(Flag(value))
case _ => None
}
val api = Flag("api")
}
case class IpAddress(value: String) extends AnyVal with StringValue
case class Path(value: String) extends AnyVal with StringValue
case class ChapterId(value: String) extends AnyVal with StringValue
case class JsonString(value: String) extends AnyVal with StringValue
case class SocketVersion(value: Int) extends AnyVal with IntValue with Ordered[SocketVersion] {
def compare(other: SocketVersion) = Integer.compare(value, other.value)
}
case class IsTroll(value: Boolean) extends AnyVal
case class RoomId(value: String) extends AnyVal with StringValue
object RoomId {
def apply(v: StringValue): RoomId = RoomId(v.value)
}
case class ReqId(value: Int) extends AnyVal with IntValue
case class UptimeMillis(millis: Long) extends AnyVal {
def toNow: Long = UptimeMillis.make.millis - millis
}
object UptimeMillis {
def make = UptimeMillis(System.currentTimeMillis() - util.Util.startedAtMillis)
}
case class ThroughStudyDoor(user: User, through: Either[RoomId, RoomId])
case class RoundEventFlags(
watcher: Boolean,
owner: Boolean,
player: Option[PlayerIndex],
moveBy: Option[PlayerIndex],
troll: Boolean
)
case class UserTv(value: User.ID) extends AnyVal with StringValue
// NOTE: byoyomi - Shogi removed this stuff, but we definitely need it.
case class Clock(p1: Int, p2: Int, p1Pending: Int, p2Pending: Int, p1Delay: Int, p2Delay: Int)
case class Position(lastUci: Uci, fen: FEN, clock: Option[Clock], turnPlayerIndex: PlayerIndex)