diff --git a/modules/game/src/main/Event.scala b/modules/game/src/main/Event.scala index 33fea59e7f..f203c3d905 100644 --- a/modules/game/src/main/Event.scala +++ b/modules/game/src/main/Event.scala @@ -12,6 +12,7 @@ sealed trait Event { def only: Option[Color] = None def owner: Boolean = false def watcher: Boolean = false + def troll: Boolean = false } object Event { @@ -112,18 +113,20 @@ object Event { def data = JsString(pos.key) } - case class Message(author: String, text: String) extends Event { + case class Message(author: String, text: String, t: Boolean) extends Event { def typ = "message" def data = Json.obj("u" -> author, "t" -> escapeXml(text)) override def owner = true + override def troll = t } // it *IS* a username, and not a user ID // immediately used for rendering - case class WatcherMessage(username: Option[String], text: String) extends Event { + case class WatcherMessage(username: Option[String], text: String, t: Boolean) extends Event { def typ = "message" def data = Json.obj("u" -> username, "t" -> escapeXml(text)) override def watcher = true + override def troll = t } object End extends Empty { diff --git a/modules/round/src/main/History.scala b/modules/round/src/main/History.scala index 2fb5f8dc1d..d14c88e88a 100644 --- a/modules/round/src/main/History.scala +++ b/modules/round/src/main/History.scala @@ -37,7 +37,8 @@ private[round] final class History(ttl: Duration) extends Actor { data = e.data, only = e.only, owner = e.owner, - watcher = e.watcher) ~ { events.put(version, _) } + watcher = e.watcher, + troll = e.troll) ~ { events.put(version, _) } } } } diff --git a/modules/round/src/main/Messenger.scala b/modules/round/src/main/Messenger.scala index 049020f742..49e46d1969 100644 --- a/modules/round/src/main/Messenger.scala +++ b/modules/round/src/main/Messenger.scala @@ -44,28 +44,29 @@ final class Messenger( _ ← nextWR.nonEmpty ?? $insert(nextWR) } yield () - def playerMessage(ref: PovRef, text: String): Fu[List[Event.Message]] = + def playerMessage(ref: PovRef, text: String, troll: Boolean): Fu[List[Event.Message]] = cleanupText(text).future flatMap { t ⇒ - RoomRepo.addMessage(ref.gameId, ref.color.name, t) inject { - Event.Message(ref.color.name, t) :: Nil + (!troll ?? RoomRepo.addMessage(ref.gameId, ref.color.name, t)) inject { + Event.Message(ref.color.name, t, troll) :: Nil } } def watcherMessage( gameId: String, userId: Option[String], - text: String): Fu[List[Event.WatcherMessage]] = for { + text: String, + troll: Boolean): Fu[List[Event.WatcherMessage]] = for { userOption ← userId.??(UserRepo.byId) message ← userOrAnonMessage(userOption, text).future (u, t) = message - _ ← WatcherRoomRepo.addMessage(gameId, u, t) - } yield Event.WatcherMessage(u, t) :: Nil + _ ← !troll ?? WatcherRoomRepo.addMessage(gameId, u, t) + } yield Event.WatcherMessage(u, t, troll) :: Nil def systemMessages(game: Game, messages: List[SelectI18nKey]): Fu[List[Event]] = game.hasChat ?? { (messages map { m ⇒ trans(m) }) |> { messageKeys ⇒ RoomRepo.addSystemMessages(game.id, messageKeys) inject { - messageKeys map { Event.Message("system", _) } + messageKeys map { Event.Message("system", _, false) } } } } @@ -74,7 +75,7 @@ final class Messenger( game.hasChat ?? { trans(message) |> { messageKey ⇒ RoomRepo.addSystemMessage(game.id, messageKey) inject { - Event.Message("system", messageKey) :: Nil + Event.Message("system", messageKey, false) :: Nil } } } @@ -85,7 +86,7 @@ final class Messenger( status.fold("en", "dis") + "abled" ) |> { message ⇒ RoomRepo.addSystemMessage(ref.gameId, message) inject { - Event.Message("system", message) :: Nil + Event.Message("system", message, false) :: Nil } } diff --git a/modules/round/src/main/SocketHandler.scala b/modules/round/src/main/SocketHandler.scala index 68f0d41d05..8b81ad2d8a 100644 --- a/modules/round/src/main/SocketHandler.scala +++ b/modules/round/src/main/SocketHandler.scala @@ -42,14 +42,15 @@ private[round] final class SocketHandler( } messenger.watcherMessage( ref.gameId, member.userId, - txt) pipeTo socket + txt, + member.troll) pipeTo socket }) { playerId ⇒ { case ("p", o) ⇒ o int "v" foreach { v ⇒ socket ! PingVersion(uid, v) } case ("talk", o) ⇒ for { txt ← o str "d" if flood.allowMessage(uid, txt) - } messenger.playerMessage(ref, txt) pipeTo socket + } messenger.playerMessage(ref, txt, member.troll) pipeTo socket case ("rematch-yes", _) ⇒ round(RematchYes(playerId)) case ("rematch-no", _) ⇒ round(RematchNo(playerId)) case ("takeback-yes", _) ⇒ round(TakebackYes(playerId)) diff --git a/modules/round/src/main/VersionedEvent.scala b/modules/round/src/main/VersionedEvent.scala index fc844963b6..f3901be9c3 100644 --- a/modules/round/src/main/VersionedEvent.scala +++ b/modules/round/src/main/VersionedEvent.scala @@ -12,7 +12,8 @@ case class VersionedEvent( data: JsValue, only: Option[Color], owner: Boolean, - watcher: Boolean) { + watcher: Boolean, + troll: Boolean) { def jsFor(m: Member): JsObject = visibleBy(m).fold( Json.obj( @@ -26,5 +27,6 @@ case class VersionedEvent( private def visibleBy(m: Member): Boolean = if (watcher && m.owner) false else if (owner && m.watcher) false + else if (troll && !m.troll) false else only.fold(true)(_ == m.color) }