mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-20 02:24:45 +00:00
The game uses a UDP-based protocol. Unlike TCP, UDP does not guarantee that packets arrive, or that they arrive in the correct order. For this reason, the game protocol implements those features using the following: * All packets have a sequence number that is utilized for reordering * Important packets are wrapped in a SlottedMetaPacket with a subslot number * RelatedA packets ae used to request lost packets using the subslot number * RelatedB packets are used to confirm received SlottedMetaPackets All of these go both ways, server <-> client. We used to only partially implement these features: Outgoing packet bundles used SMPs and could be resent, but not all packets were bundled and there was no logic for requesting lost packets from the client and there was no packet reordering, which resulted in dire consequences in the case of packet loss (zoning failures, crashes and many other odd bugs). This patch addresses all of these issues. * Packet bundling: Packets are now automatically bundled and sent as SlottedMetaPackets using a recurring timer. All manual bundling functionality was removed. * Packet reordering: Incoming packets, if received out of order, are stashed and reordered. The maximum wait time for reordering is 20ms. * Packet requesting: Missing SlottedMetaPackets are requested from the client. * PacketCoding refactor: Dropped confusing packet container types. Fixes #5. * Crypto rewrite: PSCrypto is based on a ancient buggy version of cryptopp. Updating to a current version was not possible because it removed the MD5-MAC algorithm. For more details, see Md5Mac.scala. This patch replaces PSCrypto with native Scala code. * Added two new actors: * SocketActor: A simple typed UDP socket actor * MiddlewareActor: The old session pipeline greatly simplified into a typed actor that does most of the things mentioned above. * Begun work on a headless client * Fixed anniversary gun breaking stamina regen * Resolved a few sentry errors
137 lines
6.7 KiB
Scala
137 lines
6.7 KiB
Scala
import xerial.sbt.pack.PackPlugin._
|
|
|
|
lazy val psforeverSettings = Seq(
|
|
organization := "net.psforever",
|
|
version := "1.0.2-SNAPSHOT",
|
|
scalaVersion := "2.13.3",
|
|
Global / cancelable := false,
|
|
semanticdbEnabled := true,
|
|
semanticdbVersion := scalafixSemanticdb.revision,
|
|
scalacOptions := Seq(
|
|
"-unchecked",
|
|
"-feature",
|
|
"-deprecation",
|
|
"-encoding",
|
|
"utf8",
|
|
"-language:postfixOps",
|
|
"-Wunused:imports",
|
|
"-Xmacro-settings:materialize-derivations"
|
|
),
|
|
// Quiet test options
|
|
// https://github.com/etorreborre/specs2/blob/8305db76c5084e4b3ce5827ce23117f6fb6beee4/common/shared/src/main/scala/org/specs2/main/Report.scala#L94
|
|
// https://etorreborre.github.io/specs2/guide/SPECS2-2.4.17/org.specs2.guide.Runners.html
|
|
testOptions in QuietTest += Tests.Argument(TestFrameworks.Specs2, "showOnly", "x!"),
|
|
// http://www.scalatest.org/user_guide/using_the_runner
|
|
testOptions in QuietTest += Tests.Argument(TestFrameworks.ScalaTest, "-oCEHILMNOPQRX"),
|
|
// Trick taken from https://groups.google.com/d/msg/scala-user/mxV9ok7J_Eg/kt-LnsrD0bkJ
|
|
// scaladoc flags: https://github.com/scala/scala/blob/2.11.x/src/scaladoc/scala/tools/nsc/doc/Settings.scala
|
|
scalacOptions in (Compile, doc) ++= Seq(
|
|
"-groups",
|
|
"-doc-title",
|
|
"PSF-LoginServer - ",
|
|
"-doc-version",
|
|
"master",
|
|
// For non unidoc builds, you may need bd.getName before the template parameter
|
|
"-doc-source-url",
|
|
"https://github.com/psforever/PSF-LoginServer/blob/master/€{FILE_PATH}.scala",
|
|
"-sourcepath",
|
|
baseDirectory.value.getAbsolutePath // needed for scaladoc relative source paths
|
|
),
|
|
classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat,
|
|
resolvers += "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots",
|
|
libraryDependencies ++= Seq(
|
|
"com.typesafe.akka" %% "akka-actor" % "2.6.9",
|
|
"com.typesafe.akka" %% "akka-slf4j" % "2.6.9",
|
|
"com.typesafe.akka" %% "akka-protobuf-v3" % "2.6.9",
|
|
"com.typesafe.akka" %% "akka-stream" % "2.6.9",
|
|
"com.typesafe.akka" %% "akka-testkit" % "2.6.9" % "test",
|
|
"com.typesafe.akka" %% "akka-actor-typed" % "2.6.9",
|
|
"com.typesafe.akka" %% "akka-cluster-typed" % "2.6.9",
|
|
"com.typesafe.akka" %% "akka-coordination" % "2.6.9",
|
|
"com.typesafe.akka" %% "akka-cluster-tools" % "2.6.9",
|
|
"com.typesafe.akka" %% "akka-slf4j" % "2.6.9",
|
|
"com.typesafe.scala-logging" %% "scala-logging" % "3.9.2",
|
|
"org.specs2" %% "specs2-core" % "4.10.3" % "test",
|
|
"org.scalatest" %% "scalatest" % "3.2.2" % "test",
|
|
"org.scodec" %% "scodec-core" % "1.11.7",
|
|
"ch.qos.logback" % "logback-classic" % "1.2.3",
|
|
"org.log4s" %% "log4s" % "1.8.2",
|
|
"org.fusesource.jansi" % "jansi" % "1.18",
|
|
"org.scoverage" %% "scalac-scoverage-plugin" % "1.4.1",
|
|
"com.github.nscala-time" %% "nscala-time" % "2.24.0",
|
|
"com.github.t3hnar" %% "scala-bcrypt" % "4.3.0",
|
|
"org.scala-graph" %% "graph-core" % "1.13.2",
|
|
"io.kamon" %% "kamon-bundle" % "2.1.6",
|
|
"io.kamon" %% "kamon-apm-reporter" % "2.1.6",
|
|
"org.json4s" %% "json4s-native" % "3.6.9",
|
|
"io.getquill" %% "quill-jasync-postgres" % "3.5.3",
|
|
"org.flywaydb" % "flyway-core" % "6.5.7",
|
|
"org.postgresql" % "postgresql" % "42.2.16",
|
|
"com.typesafe" % "config" % "1.4.0",
|
|
"com.github.pureconfig" %% "pureconfig" % "0.14.0",
|
|
"com.beachape" %% "enumeratum" % "1.6.1",
|
|
"joda-time" % "joda-time" % "2.10.6",
|
|
"commons-io" % "commons-io" % "2.8.0",
|
|
"com.github.scopt" %% "scopt" % "4.0.0-RC2",
|
|
"io.sentry" % "sentry-logback" % "1.7.30",
|
|
"io.circe" %% "circe-core" % "0.13.0",
|
|
"io.circe" %% "circe-generic" % "0.13.0",
|
|
"io.circe" %% "circe-parser" % "0.13.0",
|
|
"org.scala-lang.modules" %% "scala-parallel-collections" % "0.2.0",
|
|
"org.bouncycastle" % "bcprov-jdk15on" % "1.66"
|
|
),
|
|
// TODO(chord): remove exclusion when SessionActor is refactored: https://github.com/psforever/PSF-LoginServer/issues/279
|
|
coverageExcludedPackages := "net\\.psforever\\.actors\\.session\\.SessionActor.*"
|
|
)
|
|
|
|
lazy val psforever = (project in file("."))
|
|
.configs(QuietTest)
|
|
.settings(psforeverSettings: _*)
|
|
.settings(
|
|
name := "psforever",
|
|
// Copy all tests from Test -> QuietTest (we're only changing the run options)
|
|
inConfig(QuietTest)(Defaults.testTasks)
|
|
)
|
|
|
|
lazy val server = (project in file("server"))
|
|
.configs(QuietTest)
|
|
.enablePlugins(PackPlugin)
|
|
.settings(psforeverSettings: _*)
|
|
.settings(
|
|
name := "server",
|
|
// ActorTests have specific timing requirements and will be flaky if run in parallel
|
|
parallelExecution in Test := false,
|
|
// Copy all tests from Test -> QuietTest (we're only changing the run options)
|
|
inConfig(QuietTest)(Defaults.testTasks),
|
|
packMain := Map("psforever-server" -> "net.psforever.server.Server"),
|
|
packArchivePrefix := "psforever-server",
|
|
packJvmOpts := Map("psforever-server" -> Seq("-Dstacktrace.app.packages=net.psforever")),
|
|
packExtraClasspath := Map("psforever-server" -> Seq("${PROG_HOME}/config")),
|
|
packResourceDir += (baseDirectory.in(psforever).value / "config" -> "config")
|
|
)
|
|
.dependsOn(psforever)
|
|
|
|
lazy val decodePackets = (project in file("tools/decode-packets"))
|
|
.enablePlugins(PackPlugin)
|
|
.settings(psforeverSettings: _*)
|
|
.settings(
|
|
packMain := Map("psforever-decode-packets" -> "net.psforever.tools.decodePackets.DecodePackets")
|
|
)
|
|
.dependsOn(psforever)
|
|
|
|
lazy val client = (project in file("tools/client"))
|
|
.enablePlugins(PackPlugin)
|
|
.settings(psforeverSettings: _*)
|
|
.dependsOn(psforever)
|
|
|
|
// Special test configuration for really quiet tests (used in CI)
|
|
lazy val QuietTest = config("quiet") extend Test
|
|
|
|
lazy val docs = (project in file("docs"))
|
|
.settings(psforeverSettings: _*)
|
|
.enablePlugins(ScalaUnidocPlugin)
|
|
.settings(
|
|
name := "psforever"
|
|
)
|
|
.aggregate(psforever, server, decodePackets)
|