Giter Club home page Giter Club logo

lila-ws's Introduction

Lila websocket

Handle incoming websocket traffic for lichess.org.

lila <-> redis <-> lila-ws <-> websocket <-> client

Start:

sbt
~reStart

Start with custom config file:

sbt -Dconfig.file=/path/to/my.conf

Custom config file example:

include "application"
http.port = 8080
mongo.uri = "mongodb://localhost:27017/lichess"
redis.uri = "redis://127.0.0.1"

Trusts X-Forwarded-For. Use only behind a reverse proxy!

Code formatting

Please sbt prepare before you submit a PR. This will reformats and do some auto refactoring the code.

lila-ws's People

Contributors

aimorris avatar bak1an avatar benediktwerner avatar brollin avatar cymruu avatar dylvaz avatar fitztrev avatar isaacl avatar kraktus avatar lakinwecker avatar lenguyenthanh avatar m-dinhhoangviet avatar niklasf avatar ornicar avatar scala-steward avatar schlawg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lila-ws's Issues

Add the ability to run the application as a Docker container

The only way to run the whole stack at the moment is by running everything on a host(s) or by isolating each piece using lichocker.

Unfortunately, lichocker is running all processes in one container where most are in the background. This does not make real usage of a container as its scope is not limited to one process. Moreover, we end up with a container that acts the same way as if we were running all on the host machine.

Proposal

Starting with this issue, my suggesting is clear: "Dockerize" each source application individually and build a real docker stack in lichocker using docker-compose.

Furthermore, this container approach can re reused later to ease off the deployment methods and costs in the cloud.

Usage examples

Building the application will be as follow:
docker build -t lila-ws .

Running the application could be as follow:
docker run -it lila-ws

Running the application by overriding the properties would be as follow:
docker run -it -v $PWD:/usr/app -w /usr/app -e JAVA_OPTS="-Dproperty.key=value -Dother.property.key=other.value" lila-ws

I can take care of it. It would be very useful for newcomers as myself!

Platform independent build configuration

So when I was trying to get the websockets working for the first time on macos I spent quite a lot of time with reactivemongo errors caused by this line in the build file.

I was wondering if it might be possible / a good idea to have an os-agnostic build file maybe doing something like this.

Compiler error on current master (fd8af31e9b9ff7442)

[error] /home/niklas/Projekte/lila-ws/src/main/scala/actor/LobbyClientActor.scala:38:75: value flag is not a member of lila.ws.ClientActor.Deps
[error]       case ctrl: ClientCtrl => ClientActor.socketControl(state.site, deps.flag, ctrl)
[error]                                                                           ^
[error] /home/niklas/Projekte/lila-ws/src/main/scala/actor/LobbyClientActor.scala:73:32: type mismatch;
[error]  found   : Any
[error]  required: akka.actor.typed.scaladsl.ActorContext[lila.ws.ipc.ClientMsg]
[error]       onStop(state.site, deps, ctx)
[error]                                ^
[error] /home/niklas/Projekte/lila-ws/src/main/scala/actor/SiteClientActor.scala:25:70: value flag is not a member of lila.ws.ClientActor.Deps
[error]       case ctrl: ClientCtrl => ClientActor.socketControl(state, deps.flag, ctrl)
[error]                                                                      ^
[error] /home/niklas/Projekte/lila-ws/src/main/scala/actor/SiteClientActor.scala:39:27: type mismatch;
[error]  found   : Any
[error]  required: akka.actor.typed.scaladsl.ActorContext[lila.ws.ipc.ClientMsg]
[error]       onStop(state, deps, ctx)
[error]                           ^
[error] four errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 27 s, completed 17.09.2019 10:48:12

properly reject unexpected http requests

HTTP 502 had me confused for a while:

*   Trying 2001:41d0:303:c475:::443...
* Connected to socket0.lichess.org (2001:41d0:303:c475::) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=socket.lichess.org
*  start date: Apr  7 18:34:07 2020 GMT
*  expire date: Jul  6 18:34:07 2020 GMT
*  subjectAltName: host "socket0.lichess.org" matched cert's "socket0.lichess.org"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
> GET / HTTP/1.1
> Host: socket0.lichess.org
> User-Agent: curl/7.69.1
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
< HTTP/1.1 502 Bad Gateway
< Server: nginx
< Date: Tue, 07 Apr 2020 20:06:11 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 150
< Connection: keep-alive
< 
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host socket0.lichess.org left intact

macOS M1: Compilation Error

Apologies if this is something very basic, but I'm struggling with this as I'm not familar with scala.
I did make the change to exclude this line from build.sbt: -libraryDependencies += "org.reactivemongo" % "reactivemongo-shaded-native" % s"$reactivemongoVersion-$os-x86-64" but I still get this error on sbt run.

sbt:lila-ws> run
[info] compiling 62 Scala sources to /Users/dev/lila-ws/target/scala-3.1.2/classes ...
[error] -- Error: /Users/dev/lila-ws/src/main/scala/Fens.scala:71:9 --------------------
[error] 71 |        }.fold(watched) { position =>
[error]    |         ^
[error]    |         end of statement expected but '.' found
[error] -- [E007] Type Mismatch Error: /Users/dev/lila-ws/src/main/scala/Fens.scala:64:12 
[error] 64 |            for {
[error]    |            ^
[error]    |            Found:    Option[lila.ws.Position]
[error]    |            Required: lila.ws.Fens.Watched
[error] 65 |              uci <- Uci(uciS)
[error] 66 |              wc  <- wcS.toIntOption
[error] 67 |              bc  <- bcS.toIntOption
[error] 68 |            } yield Position(uci, FEN(fenS), Some(Clock(wc, bc)), turnColor)
[error] Explanation
[error] ===========
[error] 
[error] Tree: chess.format.Uci.apply(uciS).flatMap[lila.ws.Position](
[error]   {
[error]     def $anonfun(uci: chess.format.Uci): Option[lila.ws.Position] = 
[error]       augmentString(wcS).toIntOption.flatMap[lila.ws.Position](
[error]         {
[error]           def $anonfun(wc: Int): Option[lila.ws.Position] = 
[error]             augmentString(bcS).toIntOption.map[lila.ws.Position](
[error]               {
[error]                 def $anonfun(bc: Int): lila.ws.Position = 
[error]                   lila.ws.Position.apply(uci, chess.format.FEN.apply(fenS), 
[error]                     Some.apply[lila.ws.Clock](lila.ws.Clock.apply(wc, bc))
[error]                   , turnColor)
[error]                 closure($anonfun)
[error]               }
[error]             )
[error]           closure($anonfun)
[error]         }
[error]       )
[error]     closure($anonfun)
[error]   }
[error] )
[error] 
[error] I tried to show that
[error]   Option[lila.ws.Position]
[error] conforms to
[error]   lila.ws.Fens.Watched
[error] but the comparison trace ended with `false`:
[error]           
[error]   ==> Option[lila.ws.Position]  <:  lila.ws.Fens.Watched
[error]   <== Option[lila.ws.Position]  <:  lila.ws.Fens.Watched = false
[error] 
[error] The tests were made under a constraint with:
[error]  uninstantiated variables: B, B
[error]  constrained types: [B](f: chess.format.Uci => B): Option[B], 
[error]   [B](f: chess.format.Uci => B): Option[B]
[error]  bounds: 
[error]      B
[error]      B
[error]  ordering: 
[error] -- [E007] Type Mismatch Error: /Users/dev/lila-ws/src/main/scala/Fens.scala:69:40 
[error] 69 |          case MoveRegex(uciS, fenS) => Uci(uciS) map { Position(_, FEN(fenS), None, turnColor) }
[error]    |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error]    |                                      Found:    Option[lila.ws.Position]
[error]    |                                      Required: lila.ws.Fens.Watched
[error] Explanation
[error] ===========
[error] 
[error] Tree: chess.format.Uci.apply(uciS).map[lila.ws.Position](
[error]   {
[error]     {
[error]       def $anonfun(_$5: chess.format.Uci): lila.ws.Position = 
[error]         lila.ws.Position.apply(_$5, chess.format.FEN.apply(fenS), None, 
[error]           turnColor
[error]         )
[error]       closure($anonfun)
[error]     }
[error]   }
[error] )
[error] 
[error] I tried to show that
[error]   Option[lila.ws.Position]
[error] conforms to
[error]   lila.ws.Fens.Watched
[error] but the comparison trace ended with `false`:
[error]           
[error]   ==> Option[lila.ws.Position]  <:  lila.ws.Fens.Watched
[error]   <== Option[lila.ws.Position]  <:  lila.ws.Fens.Watched = false
[error] 
[error] The tests were made under a constraint with:
[error]  uninstantiated variables: B, B
[error]  constrained types: [B](f: chess.format.Uci => B): Option[B], 
[error]   [B](f: chess.format.Uci => B): Option[B]
[error]  bounds: 
[error]      B
[error]      B
[error]  ordering: 
[error] -- [E007] Type Mismatch Error: /Users/dev/lila-ws/src/main/scala/Fens.scala:70:40 
[error] 70 |          case _                     => None
[error]    |                                        ^^^^
[error]    |                                        Found:    None.type
[error]    |                                        Required: lila.ws.Fens.Watched
[error] Explanation
[error] ===========
[error] 
[error] Tree: None
[error] 
[error] I tried to show that
[error]   None.type
[error] conforms to
[error]   lila.ws.Fens.Watched
[error] but the comparison trace ended with `false`:
[error]           
[error]   ==> None.type  <:  lila.ws.Fens.Watched
[error]     ==> None  <:  lila.ws.Fens.Watched (left is approximated)
[error]     <== None  <:  lila.ws.Fens.Watched (left is approximated) = false
[error]   <== None.type  <:  lila.ws.Fens.Watched = false
[error] 
[error] The tests were made under a constraint with:
[error]  uninstantiated variables: B, B
[error]  constrained types: [B](f: chess.format.Uci => B): Option[B], 
[error]   [B](f: chess.format.Uci => B): Option[B]
[error]  bounds: 
[error]      B
[error]      B
[error]  ordering: 
[error] -- [E081] Type Error: /Users/dev/lila-ws/src/main/scala/SeenAtUpdate.scala:99:10 
[error] 99 |    ) map _.result[BSONDocument]
[error]    |          ^
[error]    |Missing parameter type
[error]    |
[error]    |I could not infer the type of the parameter _$6 of expanded function:
[error]    |_$6 => 
[error]    |  coll.findAndModify(selector = selector, 
[error]    |    modifier = coll.updateModifier(modifier)
[error]    |  , sort = None, fields = Some(fields), bypassDocumentValidation = false, 
[error]    |    writeConcern = WriteConcern.Default
[error]    |  , maxTime = None, collation = None, arrayFilters = Seq.empty) map 
[error]    |    _$6.result[BSONDocument].
[error] 5 errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 2 s, completed 22-May-2022, 3:13:29 am

set cross-origin-resource-policy

for local development without nginx, we will have to add the following header to all responses:

Cross-Origin-Resource-Policy: cross-origin

meanwhile using nginx on prod (note always, to include it despite non-2xx status code):

add_header Cross-Origin-Resource-Policy "cross-origin" always;

error when running with a config file

I'm trying to run the server with a config file, but even if use the same config file as in the readme, when I do sbt run -Dconfig.file=my.conf I get this error:

[error] (run-main-0) com.typesafe.config.ConfigException$Missing: merge of system properties,my.conf: 1,reference.conf @ jar:file:/mnt/d/github/lila-ws/target/bg-jobs/sbt_d0fd6c7b/target/454908f7/caebe80d/akka-actor-typed_2.13-2.6.15.jar!/reference.conf: 1,reference.conf @ jar:file:/mnt/d/github/lila-ws/target/bg-jobs/sbt_d0fd6c7b/target/0cf4da2e/ae2d481e/kamon-core_2.13-2.2.1.jar!/reference.conf: 1,reference.conf @ jar:file:/mnt/d/github/lila-ws/target/bg-jobs/sbt_d0fd6c7b/target/d2c2698a/f43337f6/kamon-influxdb_2.13-2.2.1.jar!/reference.conf: 1,reference.conf @ jar:file:/mnt/d/github/lila-ws/target/bg-jobs/sbt_d0fd6c7b/target/d1d9b9b5/ebf92e9a/kamon-system-metrics_2.13-2.2.1.jar!/reference.conf: 1,reference.conf @ jar:file:/mnt/d/github/lila-ws/target/bg-jobs/sbt_d0fd6c7b/target/5fdf4126/5ff27aca/akka-actor_2.13-2.6.15.jar!/reference.conf: 1: No configuration setting found for key 'reactivemongo'
[error] com.typesafe.config.ConfigException$Missing: merge of system properties,my.conf: 1,reference.conf @ jar:file:/mnt/d/github/lila-ws/target/bg-jobs/sbt_d0fd6c7b/target/454908f7/caebe80d/akka-actor-typed_2.13-2.6.15.jar!/reference.conf: 1,reference.conf @ jar:file:/mnt/d/github/lila-ws/target/bg-jobs/sbt_d0fd6c7b/target/0cf4da2e/ae2d481e/kamon-core_2.13-2.2.1.jar!/reference.conf: 1,reference.conf @ jar:file:/mnt/d/github/lila-ws/target/bg-jobs/sbt_d0fd6c7b/target/d2c2698a/f43337f6/kamon-influxdb_2.13-2.2.1.jar!/reference.conf: 1,reference.conf @ jar:file:/mnt/d/github/lila-ws/target/bg-jobs/sbt_d0fd6c7b/target/d1d9b9b5/ebf92e9a/kamon-system-metrics_2.13-2.2.1.jar!/reference.conf: 1,reference.conf @ jar:file:/mnt/d/github/lila-ws/target/bg-jobs/sbt_d0fd6c7b/target/5fdf4126/5ff27aca/akka-actor_2.13-2.6.15.jar!/reference.conf: 1: No configuration setting found for key 'reactivemongo'
[error]         at com.typesafe.config.impl.SimpleConfig.findKeyOrNull(SimpleConfig.java:156)
[error]         at com.typesafe.config.impl.SimpleConfig.findOrNull(SimpleConfig.java:174)
[error]         at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:188)
[error]         at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:193)
[error]         at com.typesafe.config.impl.SimpleConfig.getObject(SimpleConfig.java:268)
[error]         at com.typesafe.config.impl.SimpleConfig.getConfig(SimpleConfig.java:274)
[error]         at com.typesafe.config.impl.SimpleConfig.getConfig(SimpleConfig.java:41)
[error]         at lila.ws.Mongo.<init>(Mongo.scala:17)
[error]         at lila.ws.Boot$.mongo$lzycompute(LilaWsServer.scala:19)
[error]         at lila.ws.Boot$.mongo(LilaWsServer.scala:19)
[error]         at lila.ws.Boot$.controller$lzycompute(LilaWsServer.scala:34)
[error]         at lila.ws.Boot$.controller(LilaWsServer.scala:34)
[error]         at lila.ws.Boot$.router$lzycompute(LilaWsServer.scala:35)
[error]         at lila.ws.Boot$.router(LilaWsServer.scala:35)
[error]         at lila.ws.Boot$.nettyServer$lzycompute(LilaWsServer.scala:38)
[error]         at lila.ws.Boot$.router(LilaWsServer.scala:35)
[error]         at lila.ws.Boot$.nettyServer$lzycompute(LilaWsServer.scala:38)
[error]         at lila.ws.Boot$.nettyServer(LilaWsServer.scala:38)
[error]         at lila.ws.Boot$.delayedEndpoint$lila$ws$Boot$1(LilaWsServer.scala:41)
[error]         at lila.ws.Boot$delayedInit$body.apply(LilaWsServer.scala:12)
[error]         at scala.Function0.apply$mcV$sp(Function0.scala:39)
[error]         at scala.Function0.apply$mcV$sp$(Function0.scala:39)
[error]         at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
[error]         at scala.App.$anonfun$main$1(App.scala:76)
[error]         at scala.App.$anonfun$main$1$adapted(App.scala:76)
[error]         at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:563)
[error]         at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:561)
[error]         at scala.collection.AbstractIterable.foreach(Iterable.scala:919)
[error]         at scala.App.main(App.scala:76)
[error]         at scala.App.main$(App.scala:74)
[error]         at lila.ws.Boot$.main(LilaWsServer.scala:12)
[error]         at lila.ws.Boot.main(LilaWsServer.scala)
[error]         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error]         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error]         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error]         at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[error] stack trace is suppressed; run last Compile / bgRun for the full output

I don't know exactly what to put for the key reactivemongo. It seems it needs to be an object but I don't know more.

Investigate a repeated warning logs

We have 1Gb of log each day, which mostly contains a warning message:

2024-02-17 00:00:34,612 WARN  io.netty.channel.DefaultChannelPipeline An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.lang.BootstrapMethodError: bootstrap method initialization exception
        at lila.ws.netty.FrameHandler.shutdown(FrameHandler.scala:63)
        at lila.ws.netty.FrameHandler.channelRead0(FrameHandler.scala:28)
        at lila.ws.netty.FrameHandler.channelRead0(FrameHandler.scala:18)
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
        at io.netty.handler.codec.http.websocketx.Utf8FrameValidator.channelRead(Utf8FrameValidator.java:89)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:102)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
        at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800)
        at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:509)
        at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:407)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:1583)

Version conflicts in library dependencies

When running sbt run I am getting version conflicts in library dependencies.

OS: Ubuntu 18.04
sbt: 1.4.9

Error:

java.lang.RuntimeException: found version conflict(s) in library dependencies; some are suspected to be binary incompatible:
[error] 
[error] 	* org.scala-lang.modules:scala-java8-compat_2.13:1.0.0 (early-semver) is selected over 0.9.0
[error] 	    +- com.github.blemale:scaffeine_2.13:4.1.0            (depends on 1.0.0)
[error] 	    +- com.typesafe.akka:akka-actor_2.13:2.6.15           (depends on 0.9.0)

Not sure if frameLag calc is ideal

frameLag is currently a weighted running avg from trusted pongs.

This is very reasonable but what happens if a user hits a massive spike? The weighted avg skyrockets and won't return for a while. This translates into the old quota gain behavior for multiple moves in a row.

Consider:

  • capping millis so it can't skyrocket the frameLag weighted avg
  • changing the formula to drop faster if recording values that are lower than the current weighted avg.

For example:

private val trustedSpikeRefreshFactor = 0.05f
private val trustedNormalRefreshFactor = 0.1f
private val maxMillis = 5000
...

.fold(millis) { prev => {
    val weight = if (millis < prev) trustedNormalRefreshFactor else trustedSpikeRefreshFactor
    val cappedMillis = millis atMost maxMillis
    (prev * (1 - weight) + cappedMillis * weight).toInt
}
}

@ornicar @niklasf

frameLag should store per (UserId, IP, Fingerprint)

Potential exploit:

User can inflate frame lag by connecting a second time using a slower internet connection (i.e. a phone or another browser w/ VPN). They can they use an websocket exploit to inflate lag comp beyond their main tab's ping.

To combat this, frame lag should be stored based on (UserID, IP, Fingerprint) (or some lightweight hash of the three)

websocket is closing or close state error on https://play.thechesslabs.com/bn8yBK6r

ebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
RoundController.actualSendMove @ round.js:5703
RoundController.sendMove @ round.js:5724
RoundController.onUserMove @ round.js:5584
(anonymous) @ round.js:2185
setTimeout (async)
callUserFunction @ round.js:2185
userMove @ round.js:2336
selectSquare @ round.js:2380
(anonymous) @ round.js:2870
animate @ round.js:2725
anim @ round.js:2641
start @ round.js:2870
(anonymous) @ round.js:3600
site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:530
setTimeout (async)
StrongSocket.send @ site.js:530
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
10site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
2site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:530
setTimeout (async)
StrongSocket.send @ site.js:530
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
4site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
round.js:140 POST https://play.thechesslabs.com/statlog?e=roundTransientExpire 404 (Not Found)
exports.text @ round.js:140
TransientMove.expire @ round.js:5193
setTimeout (async)
TransientMove.register @ round.js:5186
RoundController.actualSendMove @ round.js:5707
RoundController.sendMove @ round.js:5724
RoundController.onUserMove @ round.js:5584
(anonymous) @ round.js:2185
setTimeout (async)
callUserFunction @ round.js:2185
userMove @ round.js:2336
selectSquare @ round.js:2380
(anonymous) @ round.js:2870
animate @ round.js:2725
anim @ round.js:2641
start @ round.js:2870
(anonymous) @ round.js:3600
bn8yBK6r:1 Uncaught (in promise) Not Found
Promise.then (async)
exports.text @ round.js:140
TransientMove.expire @ round.js:5193
setTimeout (async)
TransientMove.register @ round.js:5186
RoundController.actualSendMove @ round.js:5707
RoundController.sendMove @ round.js:5724
RoundController.onUserMove @ round.js:5584
(anonymous) @ round.js:2185
setTimeout (async)
callUserFunction @ round.js:2185
userMove @ round.js:2336
selectSquare @ round.js:2380
(anonymous) @ round.js:2870
animate @ round.js:2725
anim @ round.js:2641
start @ round.js:2870
(anonymous) @ round.js:3600
22site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
2site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:530
setTimeout (async)
StrongSocket.send @ site.js:530
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
28site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
2site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:530
setTimeout (async)
StrongSocket.send @ site.js:530
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
4site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
2site.js:524 WebSocket is already in CLOSING or CLOSED state.
StrongSocket.send @ site.js:524
(anonymous) @ site.js:530
setTimeout (async)
StrongSocket.send @ site.js:530
(anonymous) @ site.js:446
(anonymous) @ site.js:695
Ackable.resend @ site.js:693
4site.js:524 WebSocket is already in CLOSING or CLOSED state.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.