Restructure repository

* Move /common/src to /src
* Move services to net.psforever package
* Move /pslogin to /server
This commit is contained in:
Jakob Gillich 2020-08-23 03:26:06 +02:00
parent 89a30ae6f6
commit f4fd78fc5d
958 changed files with 527 additions and 725 deletions

View file

@ -51,18 +51,11 @@ ignore:
- "common/src/main/scala/net/psforever/types/MeritCommendation.scala"
- "common/src/main/scala/net/psforever/types/PlanetSideEmpire.scala"
- "common/src/main/scala/net/psforever/types/TransactionType.scala"
- "common/src/main/scala/services/avatar/AvatarAction.scala"
- "common/src/main/scala/services/avatar/AvatarResponse.scala"
- "common/src/main/scala/services/galaxy/GalaxyAction.scala"
- "common/src/main/scala/services/galaxy/GalaxyResponse.scala"
- "common/src/main/scala/services/local/LocalAction.scala"
- "common/src/main/scala/services/local/LocalResponse.scala"
- "common/src/main/scala/services/vehicle/VehicleAction.scala"
- "common/src/main/scala/services/vehicle/VehicleResponse.scala"
- "pslogin/src/main/scala/CryptoSessionActor.scala"
- "pslogin/src/main/scala/DatabaseConnector.scala"
- "pslogin/src/main/scala/LoginConfig.scala"
- "pslogin/src/main/scala/Maps.scala"
- "pslogin/src/main/scala/MDCContextAware.scala"
- "pslogin/src/main/scala/MDCPropagatingExecutionContext.scala"
- "pslogin/src/main/scala/Zones.scala"
- "common/src/main/scala/net.psforever.services/avatar/AvatarAction.scala"
- "common/src/main/scala/net.psforever.services/avatar/AvatarResponse.scala"
- "common/src/main/scala/net.psforever.services/galaxy/GalaxyAction.scala"
- "common/src/main/scala/net.psforever.services/galaxy/GalaxyResponse.scala"
- "common/src/main/scala/net.psforever.services/local/LocalAction.scala"
- "common/src/main/scala/net.psforever.services/local/LocalResponse.scala"
- "common/src/main/scala/net.psforever.services/vehicle/VehicleAction.scala"
- "common/src/main/scala/net.psforever.services/vehicle/VehicleResponse.scala"

View file

@ -32,9 +32,9 @@ jobs:
- name: Install pscrypto
run: curl -L https://github.com/psforever/PSCrypto/releases/download/v1.1/pscrypto-lib-1.1.zip | jar vx
- name: Run migrations
run: sbt "pslogin/run migrate"
run: sbt "server/run migrate"
- name: Run build
run: sbt packArchiveZip
run: sbt server/packArchiveZip
- name: Run tests
run: sbt coverage test:compile quiet:test coverageReport
- name: Upload coverage
@ -42,8 +42,8 @@ jobs:
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: pslogin.zip
path: target/pslogin*.zip
name: server.zip
path: server/target/server*.zip
docker:
runs-on: ubuntu-latest
steps:

View file

@ -1,4 +1,4 @@
FROM mozilla/sbt:8u232_1.3.8 as builder
FROM mozilla/sbt as builder
COPY . /PSF-LoginServer
@ -6,14 +6,14 @@ WORKDIR /PSF-LoginServer
RUN wget https://github.com/psforever/PSCrypto/releases/download/v1.1/pscrypto-lib-1.1.zip && \
unzip pscrypto-lib-1.1.zip && rm pscrypto-lib-1.1.zip && \
sbt pack
sbt server/pack
FROM openjdk:8u252-slim
FROM openjdk:8-slim
COPY --from=builder /PSF-LoginServer/target/pack/ /usr/local
COPY --from=builder /PSF-LoginServer/server/target/pack/ /usr/local
EXPOSE 51000
EXPOSE 51001
EXPOSE 51002
CMD ["ps-login"]
CMD ["psf-server"]

151
README.md
View file

@ -1,13 +1,16 @@
# PSForever Server [![Build Status](https://travis-ci.org/psforever/PSF-LoginServer.svg?branch=master)](https://travis-ci.com/psforever/PSF-LoginServer) [![Code coverage](https://codecov.io/gh/psforever/PSF-LoginServer/coverage.svg?branch=master)](https://codecov.io/gh/psforever/PSF-LoginServer/) [![Documentation](https://img.shields.io/badge/documentation-master-lightgrey)](https://psforever.github.io/docs/master/index.html)
<img src="https://psforever.net/index_files/logo_crop.png" align="left"
title="PSForever" width="120">
Welcome to the recreated login and world servers for PlanetSide 1. We are a community of players and developers who took it upon ourselves to preserve PlanetSide 1's unique gameplay and history _forever_.
<img src="https://psforever.net/index_files/logo_crop.png" align="left" title="PSForever" width="120">
The login and world servers (this repo runs both by default) are built to work with PlanetSide version 3.15.84.0. Anything older is not guaranteed to work.
Currently there are no binary releases of the server as the state is pre-alpha. You will need to have a development environment set up in order to get it running.
If you just want to play, you don't need to set up a development environment. Join the public test server
by following the _[PSForever Server Connection Guide](https://docs.google.com/document/d/1ZMx1NUylVZCXJNRyhkuVWT0eUKSVYu0JXsU-y3f93BY/edit)_, which has the instructions on downloading the game and using the PSForever launcher to start the game.
Welcome to the recreated login and world servers for PlanetSide 1. We are a community of players and developers who took
it upon ourselves to preserve PlanetSide 1's unique gameplay and history _forever_.
The login and world servers (this repo runs both by default) are built to work with PlanetSide version 3.15.84.0.
Anything older is not guaranteed to work. Currently, there are no binary releases of the server as the state is
pre-alpha. You will need to have a development environment set up in order to get it running. If you just want to play,
you don't need to set up a development environment. Join the public test server by following the _[PSForever Server
Connection Guide](https://docs.google.com/document/d/1ZMx1NUylVZCXJNRyhkuVWT0eUKSVYu0JXsU-y3f93BY/edit)_, which has the
instructions on downloading the game and using the PSForever launcher to start the game.
<p align="center">
<kbd>
@ -18,57 +21,77 @@ by following the _[PSForever Server Connection Guide](https://docs.google.com/do
## Server Requirements
- SBT (Scala build tool)
- sbt (Scala build tool)
- Java Development Kit (JDK) 8.0
- PSCrypto v1.1 - binary DLL (Windows) or Shared Library (Linux) placed in the root directory of the project. See [Downloading PSCrypto](#downloading-pscrypto) to get it set up.
- PostgreSQL
## Setting up a Build Environment
PSF-LoginServer is writen in [Scala](https://www.scala-lang.org/) and built using sbt, which allows it to be built on
any platform. sbt is the Scala version of Make, but is more powerful as build definitions are written in Scala. sbt is
distributed as a Java JAR and the only dependency it has is a JDK. [Follow the quick instructions on Scala's home
page](https://www.scala-lang.org/download/) to get a working development environment and come back when you are done.
PSF-LoginServer is writen in [Scala](https://www.scala-lang.org/) and built using SBT, which allows it to be built on any platform. SBT is the Scala version of Make, but is more powerful as build definitions are written in Scala. SBT is distributed as a Java JAR and the only dependency it has is a JDK. [Follow the quick instructions on Scala's home page](https://www.scala-lang.org/download/) to get a working development environment and come back when you are done.
In order to compile scala, `scalac` is used behind the scenes. This is equivalent to Java's `javac`, but for the Scala
language. Scala runs on top of the Java Virtual Machine, meaning it generates `.class` and `.jar` files and uses the
`java` executable. Essentially, Scala is just a compiler that targets the JVM, which is its runtime. All of this runs in
the background and is packaged automatically by your IDE or sbt, which automatically downloads the right version of the
Scala compiler for you.
In order to compile scala, `scalac` is used behind the scenes. This is equivalent to Java's `javac`, but for the Scala language.
Scala runs on top of the Java Virtual Machine, meaning it generates `.class` and `.jar` files and
uses the `java` executable. Essentially, Scala is just a compiler that targets the JVM, which is its
runtime. All of this runs in the background and is packaged automatically by your IDE or SBT, which
automatically downloads the right version of the Scala compiler for you.
If you have Docker and docker-compose installed on your system, you can get a complete development
environment up by running `docker-compose up` in the source code directory. Otherwise, keep reading.
If you have Docker and docker-compose installed on your system, you can get a complete development environment up by
running `docker-compose up` in the source code directory. Otherwise, keep reading.
### Using an IDE
Scala code can be fairly complex and a good IDE helps you understand the code and what methods are available for certain types, especially as you are learning the language.
IntelliJ IDEA has some of the most mature support for Scala of any IDE today. It has advanced type introspection and excellent code completion. It's recommended for those who are new to Scala in order to get familiar with the syntax.
Scala code can be fairly complex, and a good IDE helps you understand the code and what methods are available for certain
types, especially as you are learning the language. IntelliJ IDEA has some of the most mature support for Scala of any
IDE today. It has advanced type introspection and excellent code completion. It's recommended for those who are new to
Scala in order to get familiar with the syntax.
[Download the community edition of IDEA](https://www.jetbrains.com/idea/download/) directly from IntelliJ's website.
[Then get the required Scala plugin for IDEA](https://www.jetbrains.com/help/idea/managing-plugins.html).
Next, you need to get a copy of the LoginServer code. It's recommended that you perform a `git clone https://github.com/psforever/PSF-LoginServer.git` using your favorite git tool. You can also work from a downloaded ZIP of the source, but you cannot track/commit your changes.
Next, you need to get a copy of the LoginServer code. It's recommended that you perform a `git clone
https://github.com/psforever/PSF-LoginServer.git` using your favorite git tool. You can also work from a downloaded ZIP
of the source, but you cannot track/commit your changes.
Once you have the code downloaded, you will need to import the project into the IDE. Follow these instructions from [IntelliJ to import an SBT project](https://docs.scala-lang.org/getting-started/intellij-track/building-a-scala-project-with-intellij-and-sbt.html).
Once you have successfully imported the project ([and setup the DB](#setting-up-the-database)), navigate to the `pslogin/src/main/scala/PsLogin.scala` file, right click on the `object PsLogin` and hit 'Run PsLogin' from the context menu. This will boot up the login+world server.
Once you have the code downloaded, you will need to import the project into the IDE. Follow these instructions from
[IntelliJ to import an sbt
project](https://docs.scala-lang.org/getting-started/intellij-track/building-a-scala-project-with-intellij-and-sbt.html).
Once you have successfully imported the project ([and setup the DB](#setting-up-the-database)), create a new run
configuration with the `server/run` sbt task and click run to launch the server.
### Using SBT and a Text Editor
### Using sbt and a Text Editor
If you are not a fan of big clunky IDEs (IDEA is definitely one of them), you can opt to use your favorite text editor (VSCode, Sublime, ViM, Notepad++, Atom, etc.) and use SBT to build the project. The only dependency you will need is SBT itself. [Download SBT](http://www.scala-sbt.org/download.html) for your platform, install or extract, and open up a command line (cmd.exe, bash, CYGWIN, Git Bash) that has the Java Development Kit in its path.
If you are not a fan of big clunky IDEs (IDEA is definitely one of them), you can opt to use your favorite text editor
(VSCode, Sublime, ViM, Notepad++, Atom, etc.) and use sbt to build the project. The only dependency you will need is sbt
itself. [Download sbt](http://www.scala-sbt.org/download.html) for your platform, install or extract, and open up a
command line (cmd.exe, bash, CYGWIN, Git Bash) that has the Java Development Kit in its path.
At the command line run the following commands:
```
git clone https://github.com/psforever/PSF-LoginServer.git
cd PSF-LoginServer
sbt pslogin/run
sbt server/run
```
This will clone the repository and SBT will compile and run the login server ([make sure you have set up the DB](#setting-up-the-database)). Note: SBT is quite slow at starting up (JVM/JIT warmup). It's recommended you have an open SBT console (just run `sbt` without any arguments) in order to avoid this startup time.
With a SBT console you can run tests (and you should) using `sbt test`.
This will clone the repository and sbt will compile and run the login server ([make sure you have set up the
DB](#setting-up-the-database)). Note: sbt is quite slow at starting up (JVM/JIT warmup). It's recommended you have an
open sbt console (just run `sbt` without any arguments) in order to avoid this startup time. With a sbt console you can
run tests (and you should) using `sbt test`.
### Downloading PSCrypto
**The server requires binary builds of PSCrypto in order to run.** [Download the latest
*release](https://github.com/psforever/PSCrypto/releases/download/v1.1/pscrypto-lib-1.1.zip) and extract the the
*approprate dll for your operating system. If you are not comfortable with compiled binaries, you can [build the
*libraries yourself](https://github.com/psforever/PSCrypto).
**The server requires binary builds of PSCrypto in order to run.** [Download the latest release](https://github.com/psforever/PSCrypto/releases/download/v1.1/pscrypto-lib-1.1.zip) and extract the the approprate dll for your operating system. If you are not comfortable with compiled binaries, you can [build the libraries yourself](https://github.com/psforever/PSCrypto).
SBT, IDEA, and Java will automatically find the required libraries when running the server. The build expects to find the library in a subdirectory of the root directory called /pscrypto-lib/. Historically, we have recommended placing it directly into the root directory and that has worked as well. If you still have issues with PSCrypto being detected, try adding `-Djava.library.path=` (no path necessary) to your preferred IDE's build configuration with the library in the root directory. For example, with IDEA: Run -> Edit Configuration -> (select the configuration) -> Uncheck "Use SBT shell" -> VM Parameters
sbt, IDEA, and Java will automatically find the required libraries when running the server. The build expects to find
the library in a subdirectory of the root directory called /pscrypto-lib/. Historically, we have recommended placing it
directly into the root directory and that has worked as well. If you still have issues with PSCrypto being detected, try
adding `-Djava.library.path=` (no path necessary) to your preferred IDE's build configuration with the library in the
root directory. For example, with IDEA: Run -> Edit Configuration -> (select the configuration) -> Uncheck "Use sbt
shell" -> VM Parameters
## Setting up the Database
@ -76,18 +99,20 @@ The Login and World servers require PostgreSQL for persistence.
- Windows - [Official Downloads](https://www.postgresql.org/download/windows/)
- Linux - [Debian](https://www.postgresql.org/download/linux/debian/) or [Ubuntu](https://www.postgresql.org/download/linux/ubuntu/)
- macOS - Application https://www.postgresql.org/download/ (or `brew install postgresql && brew services start postgresql`)
- macOS - Application https://www.postgresql.org/download/ (or `brew install postgresql && brew net.psforever.services start postgresql`)
The default database is named `psforever` and the credentials are
`psforever:psforever`. To change these, create a configuration file at
`config/psforever.conf`. For configuration options and their defaults, see
[`application.conf`](/common/src/main/resources/application.conf). The database user will need
ALL access to tables, sequences, and functions.
The permissions required can be summarized by the SQL below.
Loading this in requires access to a graphical tool such as [pgAdmin](https://www.pgadmin.org/download/) (highly recommended) or a PostgreSQL terminal (`psql`) for advanced users.
The default database is named `psforever` and the credentials are `psforever:psforever`. To change these, create a
configuration file at `config/psforever.conf`. For configuration options and their defaults, see
[`application.conf`](/src/main/resources/application.conf). The database user will need ALL access to tables, sequences,
and functions. The permissions required can be summarized by the SQL below. Loading this in requires access to a
graphical tool such as [pgAdmin](https://www.pgadmin.org/download/) (highly recommended) or a PostgreSQL terminal
(`psql`) for advanced users.
To get started using pgAdmin, run the binary. This will start the pgAdmin server and pop-up a tab in your web browser with the interface. Upon first run, enter your connection details that you created during the PostgreSQL installation. When connected, right click the "Databases" menu -> Create... -> Database: psforever -> Save.
Next, right click on the newly created database (psforever) -> Query Tool... -> Copy and paste the commands below -> Hit the "Play/Run" button. The user should be created and granted the right permissions on all future objects.
To get started using pgAdmin, run the binary. This will start the pgAdmin server and pop-up a tab in your web browser
with the interface. Upon first run, enter your connection details that you created during the PostgreSQL installation.
When connected, right click the "Databases" menu -> Create... -> Database: psforever -> Save. Next, right click on the
newly created database (psforever) -> Query Tool... -> Copy and paste the commands below -> Hit the "Play/Run" button.
The user should be created and granted the right permissions on all future objects.
```sql
CREATE USER psforever;
@ -96,12 +121,12 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA PUBLIC GRANT ALL ON TABLES TO psforever;
ALTER DEFAULT PRIVILEGES IN SCHEMA PUBLIC GRANT ALL ON SEQUENCES TO psforever;
ALTER DEFAULT PRIVILEGES IN SCHEMA PUBLIC GRANT ALL ON FUNCTIONS TO psforever;
```
**NOTE:** applying default privileges _after_ importing the schema will not apply them to existing objects. To fix this,
*you must drop all objects and try again or apply permissions manually using the Query Tool / `psql`.
**NOTE:** applying default privileges _after_ importing the schema will not apply them to existing objects. To fix this, you must drop all objects and try again or apply permissions manually using the Query Tool / `psql`.
The server will automatically apply the latest schema. Migrations can also be applied manually using
the [Flyway CLI](https://flywaydb.org/documentation/commandline/). Existing databases before the
introduction of migrations must be baselined using the `flyway baseline` command.
The server will automatically apply the latest schema. Migrations can also be applied manually using the [Flyway
CLI](https://flywaydb.org/documentation/commandline/). Existing databases before the introduction of migrations must be
baselined using the `flyway baseline` command.
### Becoming a GM
@ -118,7 +143,7 @@ You can find your account id by viewing the accounts table.
To run a headless, non-interactive server, run
```
sbt pslogin/run
sbt server/run
```
PlanetSide can now connect to your server.
@ -126,7 +151,7 @@ PlanetSide can now connect to your server.
To run your custom server with an interactive `scala>` REPL, run
```
sbt pslogin/console
sbt server/console
```
![image](https://cloud.githubusercontent.com/assets/16912082/18024110/7b48dba8-6bc8-11e6-81d8-4692bc9d48a8.png)
@ -134,34 +159,42 @@ sbt pslogin/console
To start the server and begin listening for connections, enter the following expression into the REPL:
```
PsLogin.run
Server.run
```
![image](https://cloud.githubusercontent.com/assets/16912082/18024137/1167452a-6bc9-11e6-8765-a86fb465de61.png)
This process is identical to running the headless, non-interactive server: PlanetSide clients can connect, logging output will be printed to the screen, etc. The advantage is that you now have an interactive REPL that will evaluate any Scala expression you type into it.
This process is identical to running the headless, non-interactive server: PlanetSide clients can connect, logging
output will be printed to the screen, etc. The advantage is that you now have an interactive REPL that will evaluate any
Scala expression you type into it.
![image](https://cloud.githubusercontent.com/assets/16912082/18024339/62197f66-6bcd-11e6-90f7-5569d33472a7.png)
The REPL supports various useful commands. For example, to see the type of an arbitrary expression `foo`, run `:type foo`. To print all members of a type, run `:javap -p some-type`. You can run `:help` to see a full list of commands.
The REPL supports various useful commands. For example, to see the type of an arbitrary expression `foo`, run `:type
foo`. To print all members of a type, run `:javap -p some-type`. You can run `:help` to see a full list of commands.
![image](https://cloud.githubusercontent.com/assets/16912082/18024371/e0b72f9e-6bcd-11e6-9de5-421ec3eff994.png)
## Creating a Release
If you want to test the project without an IDE or deploy it to a server for run, you can use sbt-pack to create a release (included with the repository).
First make sure you have the [SBT tool](http://www.scala-sbt.org/download.html) on your command line (or create a new task in IntelliJ IDEA). Then get a copy of the source directory (either in ZIP or cloned form). Then do the below
If you want to test the project without an IDE or deploy it to a server for run, you can use sbt-pack to create a
release (included with the repository). First make sure you have the [sbt tool](http://www.scala-sbt.org/download.html)
on your command line (or create a new task in IntelliJ IDEA). Then get a copy of the source directory (either in ZIP or
cloned form). Then do the below
```
cd PSF-LoginServer
sbt packArchiveZip # creates a single zip with resources
```
This will use the sbt-pack plugin to create a JAR file and some helper scripts to run the server. The output for this will be in the `PSF-LoginServer\target` directory. Now you can copy the ZIP file to a server you want to run it on. You will need the Java 8 runtime (JRE only) on the target to run this. In the ZIP file, there is a `bin/` directory with some helper scripts. Run the correct file for your platform (.BAT for Windows and shell script for Unix).
This will use the sbt-pack plugin to create a JAR file and some helper scripts to run the server. The output for this
will be in the `PSF-LoginServer/target` directory. Now you can copy the ZIP file to a server you want to run it on. You
will need the Java 8 runtime (JRE only) on the target to run this. In the ZIP file, there is a `bin/` directory with
some helper scripts. Run the correct file for your platform (.BAT for Windows and shell script for Unix).
### Generating Documentation
Using SBT, you can generate documentation for both the common and pslogin projects using `sbt unidoc`.
Using sbt, you can generate documentation for both the common and pslogin projects using `sbt unidoc`.
Current documentation is available at [https://psforever.github.io/docs/master/index.html](https://psforever.github.io/docs/master/index.html)
@ -205,13 +238,15 @@ If you get an error like below
java.lang.UnsatisfiedLinkError: Unable to load library 'pscrypto': Native library (win32-x86-64/pscrypto.dll) not found in resource path
```
Then you are missing the native library required to provide cryptographic functions to the login server. To fix this, you need a binary build of [PSCrypto](#downloading-pscrypto).
Then you are missing the native library required to provide cryptographic functions to the login server. To fix this,
you need a binary build of [PSCrypto](#downloading-pscrypto).
If you are still having trouble on Linux, try putting the library in `root directory/pscrypto-lib/libpscrypto.so`.
## Contributing
Please fork the project and provide a pull request to contribute code. Coding guidelines and contribution checklists coming soon.
Please fork the project and provide a pull request to contribute code. Coding guidelines and contribution checklists
coming soon.
## Get in touch
@ -219,8 +254,6 @@ Please fork the project and provide a pull request to contribute code. Coding gu
- Discord (chat with us): https://discord.gg/0nRe5TNbTYoUruA4
- Join the #code channel and ask any questions you have there
Chord is the lead developer and you can contact him on Discord as Chord or by email [chord@tuta.io](mailto:chord@tuta.io). Discord is preferred.
## License
GNU GPLv3. See LICENSE.md for the full copy.

View file

@ -1,6 +1,6 @@
import xerial.sbt.pack.PackPlugin._
lazy val commonSettings = Seq(
lazy val psforeverSettings = Seq(
organization := "net.psforever",
version := "1.0.2-SNAPSHOT",
scalaVersion := "2.13.3",
@ -82,7 +82,7 @@ lazy val commonSettings = Seq(
"org.scala-lang.modules" %% "scala-parallel-collections" % "0.2.0"
),
// TODO(chord): remove exclusion when SessionActor is refactored: https://github.com/psforever/PSF-LoginServer/issues/279
coverageExcludedPackages := "net\\.psforever\\.actors\\.session\\.SessionActor.*;net\\.psforever\\.zones\\.zonemaps.*"
coverageExcludedPackages := "net\\.psforever\\.actors\\.session\\.SessionActor.*"
)
lazy val pscryptoSettings = Seq(
@ -91,59 +91,46 @@ lazy val pscryptoSettings = Seq(
unmanagedClasspath in Compile += (baseDirectory in ThisBuild).value / "pscrypto-lib"
)
lazy val psloginPackSettings = Seq(
packMain := Map("ps-login" -> "net.psforever.pslogin.PsLogin"),
packArchivePrefix := "pslogin",
packJvmOpts := Map("ps-login" -> Seq("-Dstacktrace.app.packages=net.psforever")),
packExtraClasspath := Map("ps-login" -> Seq("${PROG_HOME}/pscrypto-lib", "${PROG_HOME}/config")),
packResourceDir += (baseDirectory.value / "pscrypto-lib" -> "pscrypto-lib"),
packResourceDir += (baseDirectory.value / "config" -> "config")
)
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)
)
.settings(pscryptoSettings: _*)
lazy val root = (project in file("."))
lazy val server = (project in file("server"))
.configs(QuietTest)
.enablePlugins(PackPlugin)
.settings(commonSettings: _*)
.settings(psloginPackSettings: _*)
.enablePlugins(ScalaUnidocPlugin)
.aggregate(pslogin, common)
.dependsOn(pslogin, common)
lazy val pslogin = (project in file("pslogin"))
.configs(QuietTest)
.settings(commonSettings: _*)
.settings(psforeverSettings: _*)
.settings(
name := "pslogin",
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)
)
.settings(pscryptoSettings: _*)
.dependsOn(common)
lazy val common = (project in file("common"))
.configs(QuietTest)
.settings(commonSettings: _*)
.settings(
name := "common",
// Copy all tests from Test -> QuietTest (we're only changing the run options)
inConfig(QuietTest)(Defaults.testTasks)
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}/pscrypto-lib", "${PROG_HOME}/config")),
packResourceDir += (baseDirectory.in(psforever).value / "pscrypto-lib" -> "pscrypto-lib"),
packResourceDir += (baseDirectory.in(psforever).value / "config" -> "config")
)
.settings(pscryptoSettings: _*)
.dependsOn(psforever)
lazy val decodePackets = (project in file("tools/decode-packets"))
.enablePlugins(PackPlugin)
.settings(commonSettings: _*)
.settings(decodePacketsPackSettings: _*)
.settings(psforeverSettings: _*)
.settings(
libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-parallel-collections" % "0.2.0"
),
packMain := Map("psforever-decode-packets" -> "net.psforever.tools.decodePackets.DecodePackets")
)
)
.dependsOn(common)
lazy val decodePacketsPackSettings = Seq(packMain := Map("psf-decode-packets" -> "DecodePackets"))
.dependsOn(psforever)
// Special test configuration for really quiet tests (used in CI)
lazy val QuietTest = config("quiet") extend Test

View file

@ -1,11 +0,0 @@
// Copyright (c) 2017 PSForever
package services.account
import java.net.InetSocketAddress
class IPAddress(private val address: InetSocketAddress) {
def Address: String = address.getAddress.getHostAddress
def CanonicalHostName: String = address.getAddress.getCanonicalHostName
def HostName: String = address.getAddress.getHostName
def Port: Int = address.getPort
}

View file

@ -1,49 +1,39 @@
package net.psforever.pslogin
package net.psforever.server
import java.net.InetAddress
import java.nio.file.Paths
import java.util.Locale
import akka.{actor => classic}
import akka.actor.typed.scaladsl.adapter._
import akka.routing.RandomPool
import akka.{actor => classic}
import ch.qos.logback.classic.LoggerContext
import ch.qos.logback.classic.joran.JoranConfigurator
import net.psforever.crypto.CryptoInterface
import net.psforever.objects.Default
import net.psforever.objects.zones._
import net.psforever.objects.guid.TaskResolver
import org.slf4j
import org.fusesource.jansi.Ansi._
import org.fusesource.jansi.Ansi.Color._
import services.{InterstellarClusterService, ServiceManager}
import services.account.{AccountIntermediaryService, AccountPersistenceService}
import services.chat.ChatService
import services.galaxy.GalaxyService
import services.teamwork.SquadService
import kamon.Kamon
import org.apache.commons.io.FileUtils
import services.properties.PropertyOverrideManager
import org.flywaydb.core.Flyway
import java.nio.file.Paths
import scopt.OParser
import io.sentry.Sentry
import kamon.Kamon
import net.psforever.actors.session.SessionActor
import net.psforever.crypto.CryptoInterface
import net.psforever.login.psadmin.PsAdminActor
import net.psforever.login.{
CryptoSessionActor,
LoginSessionActor,
NetworkSimulatorParameters,
PacketCodingActor,
SessionPipeline,
SessionRouter,
TcpListener,
UdpListener
}
import net.psforever.login._
import net.psforever.objects.Default
import net.psforever.objects.guid.TaskResolver
import net.psforever.objects.zones._
import net.psforever.services.account.{AccountIntermediaryService, AccountPersistenceService}
import net.psforever.services.chat.ChatService
import net.psforever.services.galaxy.GalaxyService
import net.psforever.services.properties.PropertyOverrideManager
import net.psforever.services.teamwork.SquadService
import net.psforever.services.{InterstellarClusterService, ServiceManager}
import net.psforever.util.Config
import net.psforever.zones.Zones
import org.apache.commons.io.FileUtils
import org.flywaydb.core.Flyway
import org.fusesource.jansi.Ansi.Color._
import org.fusesource.jansi.Ansi._
import org.slf4j
import scopt.OParser
object PsLogin {
object Server {
private val logger = org.log4s.getLogger
case class CliConfig(
@ -58,7 +48,7 @@ object PsLogin {
println(ansi().fgBright(BLUE).a(""" / _ \/ __/ __/__ _______ _ _____ ____"""))
println(ansi().fgBright(MAGENTA).a(""" / ___/\ \/ _// _ \/ __/ -_) |/ / -_) __/"""))
println(ansi().fgBright(RED).a("""/_/ /___/_/ \___/_/ \__/|___/\__/_/""").reset())
println(""" Login Server - PSForever Project""")
println(""" PSForever Server - PSForever Project""")
println(""" http://psforever.net""")
println()
}
@ -245,7 +235,7 @@ object PsLogin {
val parser = {
import builder._
OParser.sequence(
programName("ps-login"),
programName("psforever-server"),
opt[Unit]("no-auto-migrate")
.action((_, c) => c.copy(noAutoMigrate = true))
.text("Do not auto migrate database."),

View file

@ -9,8 +9,8 @@ import net.psforever.objects.serverobject.structures.StructureType
import net.psforever.objects.{GlobalDefinitions, Player, Vehicle}
import net.psforever.objects.zones.Zone
import net.psforever.types.{PlanetSideGUID, _}
import services.RemoverActor
import services.vehicle.{VehicleAction, VehicleServiceMessage}
import net.psforever.services.RemoverActor
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
import akka.actor.typed.scaladsl.adapter._
import net.psforever.actors.zone.ZoneActor
import net.psforever.objects.avatar.Avatar

View file

@ -10,8 +10,8 @@ import net.psforever.objects.zones.{Zone, ZoneMap}
import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectClass, ObjectCreateMessageParent, PlacementData}
import net.psforever.packet.game.{ObjectCreateMessage, PlayerStateMessageUpstream}
import net.psforever.types._
import services.{RemoverActor, Service, ServiceManager}
import services.avatar._
import net.psforever.services.{RemoverActor, Service, ServiceManager}
import net.psforever.services.avatar._
import scala.concurrent.duration._
import akka.actor.typed.scaladsl.adapter._

View file

@ -1,4 +1,4 @@
# The socket bind address for all services except admin. 127.0.0.1 is the
# The socket bind address for all net.psforever.services except admin. 127.0.0.1 is the
# default for local testing, for public servers use 0.0.0.0 instead.
bind = 127.0.0.1

View file

@ -60,14 +60,14 @@ import net.psforever.util.Database._
import net.psforever.persistence
import net.psforever.util.DefinitionUtil
import org.joda.time.{LocalDateTime, Period}
import services.ServiceManager
import services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.services.ServiceManager
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.objects.Deployables
import scala.collection.mutable
import scala.concurrent.{ExecutionContextExecutor, Future, Promise}
import scala.util.{Failure, Success}
import scala.concurrent.duration._
import services.Service
import net.psforever.services.Service
object AvatarActor {
def apply(sessionActor: ActorRef[SessionActor.Command]): Behavior[Command] =

View file

@ -16,8 +16,8 @@ import net.psforever.packet.game.{ChatMsg, DeadState, RequestDestroyMessage, Zon
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID, Vector3}
import net.psforever.util.PointOfInterest
import net.psforever.zones.Zones
import services.chat.ChatService
import services.chat.ChatService.ChatChannel
import net.psforever.services.chat.ChatService
import net.psforever.services.chat.ChatService.ChatChannel
import scala.concurrent.ExecutionContextExecutor
import scala.concurrent.duration._

View file

@ -56,22 +56,27 @@ import net.psforever.packet.game.{HotSpotInfo => PacketHotSpotInfo, _}
import net.psforever.types._
import org.log4s.MDC
import scodec.bits.ByteVector
import services.ServiceManager.LookupResult
import services.account.{AccountPersistenceService, PlayerToken, ReceiveAccountData, RetrieveAccountData}
import services.avatar.{AvatarAction, AvatarResponse, AvatarServiceMessage, AvatarServiceResponse}
import services.galaxy.{GalaxyAction, GalaxyResponse, GalaxyServiceMessage, GalaxyServiceResponse}
import services.local.support.RouterTelepadActivation
import services.local.{LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse}
import services.properties.PropertyOverrideManager
import services.support.SupportActor
import services.teamwork.{SquadResponse, SquadServiceMessage, SquadServiceResponse, SquadAction => SquadServiceAction}
import services.vehicle.{VehicleAction, VehicleResponse, VehicleServiceMessage, VehicleServiceResponse}
import services.{InterstellarClusterService, RemoverActor, Service, ServiceManager}
import net.psforever.services.ServiceManager.LookupResult
import net.psforever.services.account.{AccountPersistenceService, PlayerToken, ReceiveAccountData, RetrieveAccountData}
import net.psforever.services.avatar.{AvatarAction, AvatarResponse, AvatarServiceMessage, AvatarServiceResponse}
import net.psforever.services.galaxy.{GalaxyAction, GalaxyResponse, GalaxyServiceMessage, GalaxyServiceResponse}
import net.psforever.services.local.support.RouterTelepadActivation
import net.psforever.services.local.{LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse}
import net.psforever.services.properties.PropertyOverrideManager
import net.psforever.services.support.SupportActor
import net.psforever.services.teamwork.{
SquadResponse,
SquadServiceMessage,
SquadServiceResponse,
SquadAction => SquadServiceAction
}
import net.psforever.services.vehicle.{VehicleAction, VehicleResponse, VehicleServiceMessage, VehicleServiceResponse}
import net.psforever.services.{InterstellarClusterService, RemoverActor, Service, ServiceManager}
import net.psforever.login.{DropCryptoSession, DropSession, HelloFriend, RawPacket}
import net.psforever.util.{Config, DefinitionUtil}
import net.psforever.login.WorldSession._
import net.psforever.zones.Zones
import services.chat.ChatService
import net.psforever.services.chat.ChatService
import net.psforever.objects.avatar.Cosmetic
import scala.concurrent.ExecutionContext.Implicits.global
@ -345,7 +350,7 @@ class SessionActor extends Actor with MDCContextAware {
rightRef = sender()
}
context.become(Started)
import services.ServiceManager.Lookup
import net.psforever.services.ServiceManager.Lookup
val serviceManager = ServiceManager.serviceManager
serviceManager ! Lookup("accountIntermediary")
serviceManager ! Lookup("accountPersistence")

View file

@ -10,9 +10,9 @@ import net.psforever.objects.zones.Zone
import net.psforever.persistence
import net.psforever.types.PlanetSideEmpire
import net.psforever.util.Database._
import services.galaxy.{GalaxyAction, GalaxyServiceMessage}
import services.local.{LocalAction, LocalServiceMessage}
import services.{InterstellarClusterService, ServiceManager}
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
import net.psforever.services.{InterstellarClusterService, ServiceManager}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}

View file

@ -16,9 +16,9 @@ import net.psforever.util.Config
import net.psforever.util.Database._
import org.log4s.MDC
import scodec.bits._
import services.ServiceManager
import services.ServiceManager.Lookup
import services.account.{ReceiveIPAddress, RetrieveIPAddress, StoreAccountData}
import net.psforever.services.ServiceManager
import net.psforever.services.ServiceManager.Lookup
import net.psforever.services.account.{ReceiveIPAddress, RetrieveIPAddress, StoreAccountData}
import scala.concurrent.Future
import scala.concurrent.duration._
@ -28,6 +28,7 @@ class LoginSessionActor extends Actor with MDCContextAware {
private[this] val log = org.log4s.getLogger
import scala.concurrent.ExecutionContext.Implicits.global
private case class UpdateServerList()
val usernameRegex = """[A-Za-z0-9]{3,}""".r

View file

@ -9,16 +9,20 @@ import net.psforever.packet.control.ConnectionClose
import net.psforever.util.Config
import org.log4s.MDC
import scodec.bits._
import services.ServiceManager
import services.ServiceManager.Lookup
import services.account.{IPAddress, StoreIPAddress}
import net.psforever.services.ServiceManager
import net.psforever.services.ServiceManager.Lookup
import net.psforever.services.account.{IPAddress, StoreIPAddress}
import scala.collection.mutable
import scala.concurrent.duration._
sealed trait SessionRouterAPI
final case class RawPacket(data: ByteVector) extends SessionRouterAPI
final case class ResponsePacket(data: ByteVector) extends SessionRouterAPI
final case class DropSession(id: Long, reason: String) extends SessionRouterAPI
final case class SessionReaper() extends SessionRouterAPI
case class SessionPipeline(nameTemplate: String, props: Props)

View file

@ -12,8 +12,8 @@ import net.psforever.objects.zones.Zone
import net.psforever.objects.{AmmoBox, GlobalDefinitions, Player, Tool}
import net.psforever.packet.game.ObjectHeldMessage
import net.psforever.types.{PlanetSideGUID, TransactionType, Vector3}
import services.Service
import services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.services.Service
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
@ -26,6 +26,7 @@ object WorldSession {
/**
* Convert a boolean value into an integer value.
* Use: `true:Int` or `false:Int`
*
* @param b `true` or `false` (or `null`)
* @return 1 for `true`; 0 for `false`
*/

View file

@ -2,7 +2,7 @@ package net.psforever.login.psadmin
import akka.actor.typed.receptionist.Receptionist
import akka.actor.{Actor, ActorRef}
import services.{InterstellarClusterService, ServiceManager}
import net.psforever.services.{InterstellarClusterService, ServiceManager}
import scala.collection.mutable.Map
import akka.actor.typed.scaladsl.adapter._

View file

@ -9,8 +9,8 @@ import org.json4s._
import org.json4s.native.Serialization.write
import scodec.bits._
import scodec.interop.akka._
import services.ServiceManager.Lookup
import services._
import net.psforever.services.ServiceManager.Lookup
import net.psforever.services._
import scala.collection.mutable.Map

View file

@ -23,10 +23,10 @@ object PsAdminCommands {
def usage: String
}
/// A command with full access to the ActorSystem and WorldServer services.
/// A command with full access to the ActorSystem and WorldServer net.psforever.services.
/// Spawns an Actor to handle the request and the service queries
case class Command[T](usage: String, handler: Class[T]) extends CommandInfo
/// A command without access to the ActorSystem or any services
/// A command without access to the ActorSystem or any net.psforever.services
case class CommandInternal(usage: String, handler: ((Array[String]) => CommandResponse)) extends CommandInfo
}

View file

@ -9,8 +9,8 @@ import net.psforever.objects.ce.{Deployable, DeployedItem}
import net.psforever.objects.zones.Zone
import net.psforever.packet.game.{DeployableInfo, DeploymentAction}
import net.psforever.types.PlanetSideGUID
import services.RemoverActor
import services.local.{LocalAction, LocalServiceMessage}
import net.psforever.services.RemoverActor
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
object Deployables {
private val log = org.log4s.getLogger("Deployables")

View file

@ -12,9 +12,9 @@ import net.psforever.objects.serverobject.damage.Damageable
import net.psforever.objects.vital.{StandardResolutions, Vitality}
import net.psforever.objects.zones.Zone
import net.psforever.types.{PlanetSideGUID, Vector3}
import services.Service
import services.avatar.{AvatarAction, AvatarServiceMessage}
import services.local.{LocalAction, LocalServiceMessage}
import net.psforever.services.Service
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
import scala.concurrent.duration._

View file

@ -10,8 +10,8 @@ import net.psforever.objects.serverobject.containable.{Containable, ContainableB
import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage}
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
import services.Service
import services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.services.Service
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
/**
* The companion of a `Locker` that is carried with a player

View file

@ -7,8 +7,8 @@ import net.psforever.objects.inventory.InventoryItem
import net.psforever.objects.loadouts.InfantryLoadout
import net.psforever.packet.game.{InventoryStateMessage, RepairMessage}
import net.psforever.types.{ExoSuitType, Vector3}
import services.Service
import services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.services.Service
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import scala.annotation.tailrec
@ -18,6 +18,7 @@ object Players {
/**
* Evaluate the progress of the user applying a tool to modify some other server object.
* This action is using the medical applicator to revive a fallen (dead but not released) ally.
*
* @param target the player being affected by the revive action
* @param user the player performing the revive action
* @param item the tool being used to revive the target player

View file

@ -13,9 +13,9 @@ import net.psforever.objects.serverobject.hackable.Hackable
import net.psforever.objects.serverobject.repair.RepairableEntity
import net.psforever.objects.vital.StandardResolutions
import net.psforever.types.{PlanetSideGUID, Vector3}
import services.Service
import services.local.{LocalAction, LocalServiceMessage}
import services.vehicle.{VehicleAction, VehicleServiceMessage}
import net.psforever.services.Service
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
import scala.concurrent.duration._

Some files were not shown because too many files have changed in this diff Show more