Skip to content

FAForever/faf-java-server

Repository files navigation

Spring Boot based FAF-Server

Codacy Badge Build Status Coveralls Status

This is a reimplementation of the Forged Alliance Forever's server application.

It abstracts the communication protocol as far as possible in order to stay compatible with current server's legacy protocol while at the same time allowing new protocols to be added and supported simultaneously.

It's compatible with the legacy database as well, so it can be used as a drop-in replacement of the existing server.

How to run

Prerequisites

In order to run this software, you need to set up a FAF database.

From source within IntelliJ

  1. Clone the repository
  2. Import the project into IntelliJ as Gradle project. Doing so will delete the .idea folder which also deletes launch configurations and code style settings. Please revert such deleted files first (Version Control (Alt+F9) -> Local Changes)
  3. Configure your JDK 10 if you haven't already
  4. Make sure you have the IntelliJ Lombok plugin installed
  5. Launch FafServerApplication

From source using the command line

  1. Clone the repository
  2. Run .\gradlew bootRun

From binary

Given the number of required configuration values, it's easiest to run the server using faf-stack:

docker-compose up -d faf-server

Note on first time startup

The server will need to download the GeoLite2 database which is around 60mb so it may take a wile to start up the first time. You know the server is ready when you see something like:

c.faforever.server.FafServerApplication  : Started FafServerApplication in 258.971 seconds

Technology Stack

This project uses:

Architecture

Architecture overview

Learn

Learn about Spring Integration: https://www.youtube.com/watch?v=icIosLjHu3I&list=PLr2Nvl0YJxI5-QasO8XY5m8Fy34kG-YF2

Why I made this

I have high expectations on software quality. There are many reasons why the current Python server, even though it has been refactored over months, still is of bad quality. So let's compare this Java based server to the current Python based server.

Java Server Python Server
Has thoroughly been performance-tested, proofing that it can withstand more load than FAF will ever experience. Has never been performance-tested during its development, later performance tests revealed that it handles load very badly and even crashes.
Uses a very popular framework in order to:

  • Reuse mature and stable technology instead of building "our own thing"
  • Reduce the amount of code to be written
  • Reduce possible of bugs and vulnerabilities
  • Be easily adjustable for future requirements

Doesn't use any framework, so that it:

  • Reinvents the wheel
  • Requires much more code to be written
  • Is more error-prone
  • Doesn't adjust well for future requirements

Uses a statically typed programming language which:

  • Drastically reduces the amount of possible bugs
  • Allows to find many bugs before the software is even started
  • Makes it a lot easier for developers to find their way around

Uses a dynamically typed programming language which:

  • Allows the developer to do things that make no sense at all
  • Makes it very difficult to impossible to automatically detect bugs, so you often only find them when the software is running (even very trivial ones like typos). Which caused production problems more than once.
  • Makes it much harder for (especially new) developers to find their way around

Makes use of a very strong and mature ecosystem when it comes to libraries, documentation, build tools, developer tools and everything you need. Lives in an ecosystem where you often encounter immature libraries and frameworks and/or lack of good documentation.
Is highly decoupled from the underlying communication protocol, so that additional protocols can be added easily and supported simultaneously. Is strongly coupled to the underlying communication protocol so that it's difficult to add new protocols or support multiple protocols at once. Also the server's internal implementation can't be changed easily without breaking client compatibility.
Makes heavy use of design patterns of modern Software development, making it easily understandable (for educated developers) and provides high flexibility while avoiding common mistakes. Makes little use of design patterns, making it more difficult to understand, less flexible and more error-prone.
Runs on Windows, Linux and Mac with very little setup time so that every developer can get started within couple of minutes. Only runs on Linux based systems. In order to run it on Windows, developers have to spend a significant amount of time setting up a Linux virtual machine and installing many dependencies manually. By using Docker some problems are solved but replaced by new ones.
Was built from scratch so it's free from any legacy bugs that are unknown or difficult to figure out. Is a refactoring of a terrible code base so that there are many "left overs", and has given us ridiculous bugs nobody has yet figured out why they happen (see list of problems below).
Can be managed while it is running (e.g. configuration values can be changed, or commands can be executed) using a web interface. Can not be managed once it's running, instead it needs to be restarted for every configuration change.
Produces very clear, well readable and helpful log messages making it easy for administrators to analyse and locate problems. Produces a lot of unreadable, messy and useless log messages, making it difficult for administrators to analyse and locate problems.
Was built in accordance with a set of design and implementation principles, like Clean Code, and strong quality control to assure high quality and maintainability. Was built by "Hackers" with little principles or bigger picture in mind, focusing on "getting the job done".
Is actively maintained by me, and various other people are (interested in) contributing. Hasn't had a committed maintainer for over a year, and nobody is willing take over. Many unfinished PRs are lying around as the original authors lost interest, and nobody is taking care.
Uses a database abstraction technology so that the application is decoupled from the underlying database, which allows easy switching to a different database. Is tightly coupled to the rather infamous MySQL database, making it expensive to ever switch to different (better) database.
Verifies incoming messages thoroughly. If a messages is invalid in the current context (e. g. a player reports a result for a game he isn't part of, or for an army that doesn't exist) he receives a very clear error message. This protects the server from malicious messages and helps client developers know when their application is misbehaving. Does little message verification, allowing players to manipulate the system. Silently drops invalid messages or disconnects the client without specifying a reason, making it difficult for client developers to identify mistakes.

Solved problems of the current server

The following issues that exist in the original server are not present in this implementation. Even though some of them have only "recently" been reported, they have all been around for at least 1.5 years.

Additional features

This implementation provides the following additional features over the original server:

  • Management and monitoring using a web interface, allowing for better live-administration
  • Automatic update of the GeoIP file (used to display the country flags in the client), eliminating manual updates and out-of-date/missing flags
  • Support for min/max rating for games
  • Verification that it's compatible with the underlying database schema version, preventing runtime-errors
  • Updating scores for the league & divisions system after each ladder game
  • ICE support, improving player connectivity
  • Error codes for error messages, allowing easy problem identification, error message translation and specific error handling client-side
  • Connection via WebSocket, allowing websites (and any other tool) to easily connect
  • Extended (v2) protocol, fixing shortcomings of the legacy protocol
  • Auto-generated v2 protocol documentation to ensure it's always up-to-date, complete and error-free
  • OAuth2 support, so that basically everyone can write services that connect to the server
  • Helpful, detailed, and runtime-configurable logging for easier investigation in case of problems
  • Authentication toggle, allowing to disable authentication when being run as a test-server
  • Transactional database access, ensuring database integrity
  • Invalidation of "unfinished" games in case of server crash/restart
  • Better protection against cheaters
  • Providing player time zones to the client

About

Spring Boot based server for Forged Alliance Forever

Resources

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages