diff options
author | Joel Kronqvist <joel.kronqvist@iki.fi> | 2024-11-07 01:17:58 +0200 |
---|---|---|
committer | Joel Kronqvist <joel.kronqvist@iki.fi> | 2024-11-07 01:17:58 +0200 |
commit | fdaec6534eb7ee902c75be3e4b732b6970abd859 (patch) | |
tree | f323d11dc1a33a93ee44417a58df62ef5f9ad98a /src/main/scala/Server/Clients.scala | |
parent | 12cbf4d451d1002b8872b0028acbe6bd886ca9bd (diff) | |
download | scalevalapokalypsi-fdaec6534eb7ee902c75be3e4b732b6970abd859.tar.gz scalevalapokalypsi-fdaec6534eb7ee902c75be3e4b732b6970abd859.zip |
Made the server work with the adventure model
* The model was imported from the wrong version, so that needs to be fixed.
* The client side doesn't work at all right now. Use netcat for testing.
* There are inconveniences and bugs in the model (eg. it lists the player among entities)
* Players can just see each other, not interact in any way
But it's a good base.
Diffstat (limited to 'src/main/scala/Server/Clients.scala')
-rw-r--r-- | src/main/scala/Server/Clients.scala | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/main/scala/Server/Clients.scala b/src/main/scala/Server/Clients.scala new file mode 100644 index 0000000..24a245c --- /dev/null +++ b/src/main/scala/Server/Clients.scala @@ -0,0 +1,70 @@ +package o1game.Server + +import scala.util.Try + +class Clients(maxClients: Int): + private val clients: Array[Option[Client]] = Array.fill(maxClients)(None) + + /** Adds `client` to this collection of clients. + * + * @param client the Client to add + * @return true if there was room for the client + * i.e. fewer clients than `maxClients`, false otherwise + */ + def addClient(client: Client): Boolean = + val i = this.clients.indexOf(None) + if i == -1 then + false + else + this.clients(i) = Some(client) + true + + /** Returns all the clients. + * + * @return an iterable of all the clients + */ + def allClients: Iterable[Client] = clients.toVector.flatten + + /** Applies the function `f` to all the clients for its side effects. */ + def foreach(f: Client => Any): Unit = this.clients.flatten.foreach(f) + + /** Returns true if the predicate `f` stands for all clients, + * false otherwise + * + * @param f the predicate to check for all clients + * @return whether `f` stands for all clients + */ + def forall(f: Client => Boolean): Boolean = this.clients.flatten.forall(f) + + def names: Vector[String] = this.clients.flatten.flatMap(_.getName).toVector + + def isEmpty: Boolean = this.clients.flatten.isEmpty + + /** Applies the function `f` to all the clients for its side effects + * and removes all the clients for which `f([client])` returns false. + * This is useful for doing IO with the client and removing clients + * with stale sockets. + * + * @param f the function to apply to all the clients and filter them with + */ + def removeNonSatisfying(f: Client => Boolean): Unit = + for i <- this.clients.indices do + this.clients(i) match + case Some(c) => + if !f(c) then + this.clients(i) = None + case None => + + /** Removes clients that have not behaved according to protocol */ + def removeNonCompliant(): Unit = + this.removeNonSatisfying(_.isIntactProtocolWise) + + /** Applies the function f to all clients for its side effects. + * If the function throws an exception, the client is removed. + * Probably a more concise alternative to `removeNonSatisfying`, + * but might catch exceptions unintentionally. + * + * @param f the function to apply for its side effects to each client + */ + def mapAndRemove(f: Client => Unit): Unit = + this.removeNonSatisfying(c => Try(f(c)).isSuccess) |