2020-01-12 18:13:46 +00:00
# PSForever Server [](https://travis-ci.com/psforever/PSF-LoginServer) [](https://codecov.io/gh/psforever/PSF-LoginServer/) [](https://psforever.github.io/docs/master/index.html)
2016-03-04 19:47:14 +00:00
2020-08-23 01:26:06 +00:00
< img src = "https://psforever.net/index_files/logo_crop.png" align = "left" title = "PSForever" width = "120" >
2016-05-01 08:43:20 +00:00
2020-08-27 02:09:44 +00:00
Welcome to the recreated login and world servers for PlanetSide 1. We are a community of players and developers who took
2020-08-23 01:26:06 +00:00
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.
2016-07-20 02:36:04 +00:00
2020-01-12 18:13:46 +00:00
< p align = "center" >
< kbd >
< img src = "https://i.imgur.com/EkbIv5x.png"
title="PSForever Server Banner">
< / kbd >
< / p >
2016-07-16 17:45:35 +00:00
2020-01-12 18:13:46 +00:00
## Server Requirements
2020-08-23 01:26:06 +00:00
- sbt (Scala build tool)
2020-06-09 22:32:02 +00:00
- Java Development Kit (JDK) 8.0
- PostgreSQL
2016-07-16 17:45:35 +00:00
## Setting up a Build Environment
2020-08-23 01:26:06 +00:00
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.
2020-06-09 22:32:02 +00:00
2020-08-23 01:26:06 +00:00
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.
2020-05-26 20:19:44 +00:00
2020-08-23 01:26:06 +00:00
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.
2018-05-20 17:37:58 +00:00
2016-07-16 17:45:35 +00:00
### Using an IDE
2020-06-09 22:32:02 +00:00
2020-08-23 01:26:06 +00:00
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.
2016-07-16 17:45:35 +00:00
2020-01-12 18:13:46 +00:00
[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 ).
2016-07-16 17:45:35 +00:00
2020-08-23 01:26:06 +00:00
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.
2016-07-16 17:45:35 +00:00
2020-08-23 01:26:06 +00:00
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.
2016-07-16 17:45:35 +00:00
2020-08-23 01:26:06 +00:00
### Using sbt and a Text Editor
2020-06-09 22:32:02 +00:00
2020-08-23 01:26:06 +00:00
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.
2016-07-16 17:45:35 +00:00
2020-01-12 18:13:46 +00:00
At the command line run the following commands:
2020-06-09 22:32:02 +00:00
2016-07-16 17:45:35 +00:00
```
git clone https://github.com/psforever/PSF-LoginServer.git
cd PSF-LoginServer
2020-08-23 01:26:06 +00:00
sbt server/run
2016-07-16 17:45:35 +00:00
```
2020-08-23 01:26:06 +00:00
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` .
2016-07-16 17:45:35 +00:00
2020-01-10 16:13:37 +00:00
## Setting up the Database
2020-06-09 22:32:02 +00:00
2020-01-10 16:13:37 +00:00
The Login and World servers require PostgreSQL for persistence.
2020-06-09 22:32:02 +00:00
- 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/ )
2020-08-23 01:26:06 +00:00
- macOS - Application https://www.postgresql.org/download/ (or `brew install postgresql && brew net.psforever.services start postgresql` )
2020-01-10 16:13:37 +00:00
2020-08-23 01:26:06 +00:00
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.
2020-01-12 18:13:46 +00:00
2020-08-23 01:26:06 +00:00
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.
2020-08-23 19:27:02 +00:00
The user should be created and made owner of the database.
2020-01-12 17:22:41 +00:00
```sql
CREATE USER psforever;
ALTER USER psforever WITH PASSWORD 'psforever';
2020-08-23 19:27:02 +00:00
ALTER TABLE psforever OWNER TO psforever;
2020-01-12 17:22:41 +00:00
```
2020-08-23 01:26:06 +00:00
**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` .
2020-01-12 17:22:41 +00:00
2020-08-23 01:26:06 +00:00
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.
2020-01-10 16:13:37 +00:00
2020-01-12 17:22:41 +00:00
### Becoming a GM
2020-06-09 22:32:02 +00:00
2020-01-12 17:22:41 +00:00
By default users are not granted GM access. To grant a created user GM access execute the following query:
```sql
UPDATE accounts SET gm=true WHERE id=your_id;
```
You can find your account id by viewing the accounts table.
2016-08-27 03:46:57 +00:00
## Running the Server
To run a headless, non-interactive server, run
```
2020-08-23 01:26:06 +00:00
sbt server/run
2016-08-27 03:46:57 +00:00
```
PlanetSide can now connect to your server.
To run your custom server with an interactive `scala>` REPL, run
```
2020-08-23 01:26:06 +00:00
sbt server/console
2016-08-27 03:46:57 +00:00
```

To start the server and begin listening for connections, enter the following expression into the REPL:
```
2020-08-23 01:26:06 +00:00
Server.run
2016-08-27 03:46:57 +00:00
```

2020-08-23 01:26:06 +00:00
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.
2016-08-27 03:46:57 +00:00

2020-08-23 01:26:06 +00:00
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.
2016-08-27 03:46:57 +00:00

2016-07-17 22:03:23 +00:00
## Creating a Release
2020-06-09 22:32:02 +00:00
2020-08-23 01:26:06 +00:00
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
2016-07-17 22:03:23 +00:00
```
cd PSF-LoginServer
2016-07-27 02:05:57 +00:00
sbt packArchiveZip # creates a single zip with resources
2016-07-17 22:03:23 +00:00
```
2020-08-23 01:26:06 +00:00
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).
2016-07-17 22:03:23 +00:00
2020-01-12 18:13:46 +00:00
### Generating Documentation
2020-06-09 22:32:02 +00:00
2020-08-23 19:27:02 +00:00
Using sbt, you can generate documentation all projects using `sbt docs/unidoc` .
2020-01-12 18:13:46 +00:00
Networking
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
2020-09-17 15:04:06 +00:00
Current documentation is available at [https://psforever.github.io/PSF-LoginServer/net/psforever/index.html ](https://psforever.github.io/PSF-LoginServer/net/psforever/index.html )
2020-01-12 18:13:46 +00:00
2020-06-09 22:32:02 +00:00
## Tools
### decodePackets
The decodePackets program can be used to decode GameLogger `.gcap` packet captures. Requires
[gcapy ](https://github.com/psforever/gcapy ) to run, unless the `-p` flag is used.
To build, run:
```
sbt decodePackets/pack
```
The output will be in `tools/decode-packets/target/pack` . The `bin` folder contains scripts to
launch the program. On Linux, you can use the Makefile to install the files to any path:
```
make install PREFIX=$HOME/.local
```
Now you can run the program like that:
```
psf-decode-packets -o ./output-directory foo.gcap bar.gcap
```
By default, decodePackets takes in `.gcap` files, but it can also take gcapy ascii files with the
`-p` option. Run `psf-decode-packets --help` to get usage info.
2020-07-14 03:54:05 +00:00
## Contributing
2020-08-23 01:26:06 +00:00
Please fork the project and provide a pull request to contribute code. Coding guidelines and contribution checklists
coming soon.
2020-07-14 03:54:05 +00:00
## Get in touch
- Website: http://psforever.net
- Discord (chat with us): https://discord.gg/0nRe5TNbTYoUruA4
- Join the #code channel and ask any questions you have there
2016-05-02 04:08:33 +00:00
## License
2020-06-09 22:32:02 +00:00
2016-05-02 04:08:33 +00:00
GNU GPLv3. See LICENSE.md for the full copy.