diff options
author | Joel Kronqvist <joel.kronqvist@iki.fi> | 2024-11-15 16:45:09 +0200 |
---|---|---|
committer | Joel Kronqvist <joel.kronqvist@iki.fi> | 2024-11-15 16:45:09 +0200 |
commit | eeb83ca379e7f4ab1a86596b80e206df48371454 (patch) | |
tree | 0f595308b7ba9077650e8a368b94ba75c5683c71 /src/main/scala/Server | |
parent | ea18a265a22ffc4c3f6ec3ca9d2f542552da9705 (diff) | |
download | scalevalapokalypsi-eeb83ca379e7f4ab1a86596b80e206df48371454.tar.gz scalevalapokalypsi-eeb83ca379e7f4ab1a86596b80e206df48371454.zip |
Added observations for Players in model & implemented sending them to other clients
Diffstat (limited to 'src/main/scala/Server')
-rw-r--r-- | src/main/scala/Server/Client.scala | 46 | ||||
-rw-r--r-- | src/main/scala/Server/Server.scala | 21 |
2 files changed, 38 insertions, 29 deletions
diff --git a/src/main/scala/Server/Client.scala b/src/main/scala/Server/Client.scala index 323b78c..d4f1864 100644 --- a/src/main/scala/Server/Client.scala +++ b/src/main/scala/Server/Client.scala @@ -4,8 +4,7 @@ import java.net.Socket import scala.math.min import o1game.constants.* import ServerProtocolState.* -import o1game.Model.Entity -import o1game.Model.Action +import o1game.Model.{Action,Player,Entity} class Client(val socket: Socket): private var incompleteMessage: Array[Byte] = @@ -13,7 +12,7 @@ class Client(val socket: Socket): private var incompleteMessageIndex = 0 private var protocolState = WaitingForVersion private var outData: String = "" - private var character: Option[Entity] = None + private var character: Option[Player] = None private var protocolIsIntact = true private var name: Option[String] = None private var nextAction: Option[Action] = None @@ -42,22 +41,22 @@ class Client(val socket: Socket): */ def gameStart(): Unit = this.protocolState = InGame - /** Returns the entity this client controls in the model. + /** Returns the player this client controls in the model. * - * @return an option containing the entity + * @return an option containing the player */ - def entity: Option[Entity] = this.character + def player: Option[Player] = this.character - /** Tells this client object that it controls the specified entity. + /** Tells this client object that it controls the specified player. * - * @param entity the entity this client is to control + * @param player the player this client is to control */ - def giveEntity(entity: Entity): Unit = - this.character = Some(entity) + def givePlayer(player: Player): Unit = + this.character = Some(player) - /** Gets the name of this client, which should match the name of the entity + /** Gets the name of this client, which should match the name of the player * that is given to this client. Not very useful if the client hasn't yet - * received the name or if it already has an entity. + * received the name or if it already has an player. * * @return the name of this client */ @@ -89,7 +88,7 @@ class Client(val socket: Socket): * @param data data to buffer for sending */ private def addDataToSend(data: String): Unit = - this.outData += s"$data" + this.outData += s"$data\r\n" /** Returns one line of data if there are any line breaks. @@ -110,7 +109,9 @@ class Client(val socket: Socket): /** Makes the client play its turn */ def act(): Unit = this.addDataToSend(ACTION_BLOCKING_INDICATOR.toString) - this.nextAction.foreach(this.executeAction(_)) + this.nextAction.foreach(a => this.addDataToSend( + s"$ACTION_BLOCKING_INDICATOR${this.executeAction(a)}" + )) this.nextAction = None /** Checks whether the client has chosen its next action @@ -135,11 +136,11 @@ class Client(val socket: Socket): this.protocolIsIntact = this.protocolState match case WaitingForVersion => if line == GAME_VERSION then - addDataToSend(s"$PROTOCOL_VERSION_GOOD\r\n") + addDataToSend(s"$PROTOCOL_VERSION_GOOD") this.protocolState = WaitingForClientName true else - addDataToSend(s"$PROTOCOL_VERSION_BAD\r\n") + addDataToSend(s"$PROTOCOL_VERSION_BAD") false case WaitingForClientName => this.name = Some(line) @@ -155,18 +156,17 @@ class Client(val socket: Socket): private def bufferAction(action: Action) = if ( this.nextAction.isEmpty && - this.entity.exists(action.takesATurnFor(_)) + this.player.exists(action.takesATurnFor(_)) ) then this.nextAction = Some(action) else if this.nextAction.isEmpty then - this.addDataToSend(ACTION_NONBLOCKING_INDICATOR.toString) - this.executeAction(action) + this.addDataToSend(s"$ACTION_NONBLOCKING_INDICATOR${this.executeAction(action)}") - /** Executes the specified action and buffers its description for sending */ - private def executeAction(action: Action) = + /** Executes the specified action and returns its description */ + private def executeAction(action: Action): String = this.character.flatMap(action.execute(_)) match - case Some(s) => this.addDataToSend(s"$s\r\n") - case None => this.addDataToSend("You can't do that\r\n") + case Some(s) => s + case None => "You can't do that" end Client diff --git a/src/main/scala/Server/Server.scala b/src/main/scala/Server/Server.scala index 5eb15cb..ac0e010 100644 --- a/src/main/scala/Server/Server.scala +++ b/src/main/scala/Server/Server.scala @@ -7,8 +7,7 @@ import java.lang.Thread.{currentThread, sleep} import java.io.IOException import java.net.{ServerSocket, Socket} import o1game.constants.* -import o1game.Model.Adventure -import o1game.Model.Entity +import o1game.Model.{Adventure,Entity,Player} import o1game.utils.stringToByteArray import java.lang.System.currentTimeMillis @@ -53,9 +52,11 @@ class Server( this.readFromAll() this.clients.foreach(_.interpretData()) this.writeClientDataToClients() + this.writeObservations() if this.canExecuteTurns then this.clients.inRandomOrder(_.act()) this.writeClientDataToClients() + this.writeObservations() this.clients.foreach(c => this.writeToClient(this.turnStartInfo(c), c) ) @@ -83,17 +84,25 @@ class Server( c.gameStart() val name = c.getName - val entity: Option[Entity] = name match + val playerEntity: Option[Player] = name match case Some(n) => this.adventure match case Some(a) => a.getPlayer(n) case None => None case None => None - entity.foreach(c.giveEntity(_)) + playerEntity.foreach(c.givePlayer(_)) this.writeToClient( s"$timeLimit\r\n${this.turnStartInfo(c)}", c ) + + private def writeObservations(): Unit = + this.clients.foreach(c => + val observations = c.player.map(_.readAndClearObservations()) +// if observations.filter(_.length > 0).isDefined then +// println(s"Observations of $c: ```$observations```") + observations.foreach(_.foreach((s: String) => this.writeToClient(s"$s\r\n", c))) + ) /** Helper function to determine if the next turn can be taken */ private def canExecuteTurns: Boolean = @@ -121,7 +130,7 @@ class Server( false private def turnStartInfo(client: Client): String = - val clientArea = client.entity.map(_.location) + val clientArea = client.player.map(_.location) val areaDesc = clientArea .map(_.description) .getOrElse("You are floating in the middle of a soothing void.") @@ -131,7 +140,7 @@ class Server( val items = clientArea .map(_.getItemNames.mkString(LIST_SEPARATOR)) .getOrElse("") - val entities = client.entity.map(c => + val entities = client.player.map(c => c.location .getEntityNames .filter(c.name != _) |