Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.0.5 #1

Open
wants to merge 66 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
f0029fb
Refactored client update functions
Teifion Mar 30, 2024
13b25ec
Added ability to disconnect client processes
Teifion Apr 1, 2024
3e49aba
Added caches
Teifion Apr 1, 2024
e80033c
Added cluster cache invalidation function
Teifion Apr 2, 2024
71cc719
Added cache clearing when users are updated
Teifion Apr 2, 2024
0a8ed43
Added user and server settings
Teifion Apr 3, 2024
f64cf82
Doc fixes for settings
Teifion Apr 3, 2024
3e9508b
Added audit logs
Teifion Apr 3, 2024
5d1f5da
Added create_anonymous_audit_log to Api
Teifion Apr 4, 2024
bc508b5
Added logging tables
Teifion Apr 7, 2024
86b71b5
Formatting and documentation fixes
Teifion Apr 7, 2024
ca04ba5
Removed telemetry and event database stuff, moved to Angen instead
Teifion Apr 7, 2024
5b7c9df
Started putting in :telemetry events, mostly copied from Oban right now
Teifion Apr 8, 2024
0a5b0f2
Added github action
Teifion Apr 14, 2024
e957f94
Add github action badge to readme.md
L-e-x-o-n Apr 14, 2024
b57f04a
Merge pull request #2 from L-e-x-o-n/patch-1
Teifion Apr 14, 2024
bffa0cf
Login improvements
Teifion Apr 17, 2024
6d39ca6
Emit metric on failed login
Teifion Apr 17, 2024
93a7730
Expanded login options
Teifion May 20, 2024
8cb0ee1
Tweaked some emitters
Teifion May 20, 2024
a339fb9
Query guard fixes
Teifion May 20, 2024
a768137
Cluster member server fixes
Teifion May 26, 2024
e541561
Tweaked some client events
Teifion May 27, 2024
e3242be
Expanded telemetry events slightly
Teifion May 27, 2024
a605155
Telemetry tweaks, test.ci now used for PR tests
Teifion Jun 12, 2024
168cac5
Updated elixir version
Teifion Jun 24, 2024
d176e4a
Updated deps
Teifion Jun 24, 2024
a321e9f
mix format
Teifion Jun 24, 2024
904c464
Moved test fixtures outside the main Teiserver namespace
Teifion Jun 24, 2024
5523677
Minor bugfix
Teifion Jun 26, 2024
80cd661
Moved caches into their own supervisor trees
Teifion Jun 26, 2024
ff833f4
Swapped to use utc_datetimes for all timestamps
Teifion Jun 26, 2024
94fe5b6
Removed mix.lock
Teifion Jun 26, 2024
fb3e946
Tweaked Elixir version for github
Teifion Jun 26, 2024
bf0d48f
Fixed failing tests from fixture change
Teifion Jun 26, 2024
81e2a20
Added some match query options
Teifion Jun 29, 2024
5b51d39
Added messaging around match start/end
Teifion Jun 29, 2024
ddb7c94
Fixed test
Teifion Jun 29, 2024
f3ab0fd
Caching improvements
Teifion Jul 9, 2024
a1567ab
Server settings use text and added player_count to matches
Teifion Jul 10, 2024
8768b78
Added some query options
Teifion Jul 11, 2024
6c7665f
Added indexes
Teifion Jul 12, 2024
3135113
Added user choices to matches
Teifion Jul 15, 2024
5c38559
Expanded readme
Teifion Jul 15, 2024
9a4da2b
Removed clustering code
Teifion Jul 15, 2024
3e24bf0
Improved some tests
Teifion Jul 15, 2024
e5a49e6
mix format
Teifion Jul 15, 2024
72af724
Fixed a bug with a test
Teifion Jul 24, 2024
c9ca19b
Added defdelegate for some settings to Teiserver directly
Teifion Aug 6, 2024
8acd3a9
Deprecated Teiserver.Api
Teifion Aug 6, 2024
aea4284
Fixed tests
Teifion Aug 6, 2024
9850412
Added missing client pubsub doc entry
Teifion Aug 6, 2024
dc2a960
Minor fixes
Teifion Aug 8, 2024
6fc5cb5
Extended some query options
Teifion Aug 10, 2024
429a7cb
Undid allowing match_id to be cast in the changeset
Teifion Aug 11, 2024
fdad625
Added helper functions related to user restrictions
Teifion Aug 25, 2024
a5c4f7b
Bugfixes and test coverage
Teifion Aug 26, 2024
5e2a7db
Fixed some test config
Teifion Aug 27, 2024
e7446bd
Removed timex
Teifion Sep 22, 2024
f4d3e9a
Merge branch '0.0.5' of github.com:Teifion/teiserver into 0.0.5
Teifion Sep 22, 2024
6622c18
format
Teifion Sep 22, 2024
db1c3fc
Test DB fix
Teifion Sep 23, 2024
cecd684
Listing clients no longer contains nil values
Teifion Sep 24, 2024
35e88b7
Added ability for creating matches to fail
Teifion Sep 24, 2024
85639d2
Swapped string error messages to atom error messages
Teifion Sep 24, 2024
b07d3c6
Minor cleanup
Teifion Sep 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Build and test

on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:

# Sets the ENV `MIX_ENV` to `test` for running tests
env:
MIX_ENV: test
ELIXIR_VER: '1.17.1'
OTP_VER: '27.0'

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
name: Build and test

# Set up a Postgres DB service. By default, Phoenix applications
# use Postgres. This creates a database for running tests.
# Additional services can be defined here if required.
services:
db:
image: postgres:15
ports: ['5432:5432']
env:
POSTGRES_DB: teiserver_test
POSTGRES_USER: teiserver_test
POSTGRES_PASSWORD: 123456789
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
# Step: Setup Elixir + Erlang image as the base.
- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
otp-version: ${{ env.OTP_VER }}
elixir-version: ${{ env.ELIXIR_VER }}

# Step: Check out the code.
- name: Checkout code
uses: actions/checkout@v4

# Step: Define how to cache deps. Restores existing cache if present.
- name: Cache deps
id: cache-deps
uses: actions/cache@v4
env:
cache-name: cache-elixir-deps
with:
path: deps
key: ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix-${{ env.cache-name }}-

# Step: Define how to cache the `_build` directory. After the first run,
# this speeds up tests runs a lot. This includes not re-compiling our
# project's downloaded deps every run.
- name: Cache compiled build
id: cache-build
uses: actions/cache@v4
env:
cache-name: cache-compiled-build
with:
path: _build
key: ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('**/mix.lock') }}
restore-keys: |
${{ runner.os }}-mix-${{ env.cache-name }}-

# Step: Download project dependencies. If unchanged, uses
# the cached version.
- name: Install dependencies
run: mix deps.get

# Step: Execute the tests.
- name: Run tests
env:
DATABASE_URL: postgres://teiserver_test:123456789@localhost/teiserver_test
run: mix test.ci
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ teiserver-*.tar
.elixir_ls/*
.idea

mix.lock

# Notes I put in for myself I don't want on github
/zignore
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
erlang 26.2
elixir 1.15.7-otp-26
erlang 27.0
elixir 1.17.1-otp-27
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
## v0.0.5
- Swapped to Elixir 1.17
- Swapped `team_colour` for `player_colour`
- Refactored the client update process
- Added messaging around match start/end
- Added User and Server runtime settings
- Added Telemetry events
- Added rate limiting of login attempts
- Added more options for connecting clients (currently just `bot?`)
- Added support for guest accounts
- Added caching for some db calls
- Added `player_count` as a property to matches
- Added concept of user choices to represent pre-game choices made by users (e.g. in-game faction)
- Removed clustering code so it can be handled by the application using Teiserver as a library
- Moved everything from `Teiserver.Api` to `Teiserver`
- Dropped Timex
- Swapped string error messages to atom error messages

## v0.0.4
- Added `Lobby`, `LobbySummary`, `MatchType`, `Match`, `MatchMembership`, `MatchSettingType`, `MatchSetting` schemas, libs and queries
- Added pubsub events for clients connecting, disconnecting and process destruction
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
<a href="https://hexdocs.pm/teiserver"><img alt="Hex Docs" src="http://img.shields.io/badge/hex.pm-docs-green.svg?style=flat"></a>
&nbsp;
<a href="https://opensource.org/licenses/Apache-2.0"><img alt="Apache 2 License" src="https://img.shields.io/hexpm/l/teiserver"></a>
&nbsp;
<a href="https://github.com/Teifion/teiserver/actions/workflows/elixir.yml/badge.svg?branch=0.0.5"><img alt="Tests" src="https://github.com/Teifion/teiserver/actions/workflows/elixir.yml/badge.svg?branch=0.0.5"></a>
</p>

_Note: This README is for the unreleased master branch, please reference the
_Note: This README is for the unreleased main branch, please reference the
[official documentation on hexdocs][hexdoc] for the latest stable release._

[hexdoc]: https://hexdocs.pm/teiserver/Teiserver.html
Expand All @@ -20,7 +22,6 @@ _Note: This README is for the unreleased master branch, please reference the
- User connectivity
- User to User communications
- Lobby system (planned)
- Telemetry/Event logging (planned)
- Community management tools (planned)
- Steam integration (planned)

Expand All @@ -29,7 +30,7 @@ First add to your dependencies in `mix.exs`.
```elixir
def deps do
[
{:teiserver, "~> 0.0.3"}
{:teiserver, "~> 0.0.5"}
]
end
```
Expand All @@ -56,9 +57,8 @@ defmodule MyApp.Repo.Migrations.AddTeiserverTables do
end
```

Add this to your Application supervision tree:
```elixir
children = [
{Teiserver, Application.get_env(:my_app, Teiserver)}
]
Finally, update your config to link the repo:
```
config :teiserver,
repo: MyApp.Repo
```
4 changes: 1 addition & 3 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ config :teiserver, Teiserver.Test.Repo,
priv: "test/support/postgres",
url:
System.get_env("DATABASE_URL") ||
"postgres://teiserver_test:123456789@localhost/teiserver_test"
"postgres://teiserver_test:postgres@localhost/teiserver_test"

config :teiserver,
# Overridden by application
client_destroy_timeout_seconds: 300,
lobby_join_method: :simple,
teiserver_clustering: true,
teiserver_clustering_post_join_functions: [],

# User defaults
default_behaviour_score: 10_000,
Expand Down
9 changes: 1 addition & 8 deletions config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,5 @@ import Config
# This makes anything in our tests involving user passwords (creating or logging in) much faster
config :argon2_elixir, t_cost: 1, m_cost: 8

config :teiserver, Teiserver.Test.Repo,
database: "teiserver_test",
username: "postgres",
password: "postgres",
hostname: "localhost"

config :teiserver,
repo: Teiserver.Test.Repo,
teiserver_clustering: false
repo: Teiserver.Test.Repo
3 changes: 3 additions & 0 deletions coveralls.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"skip_files": [
"^test/.*",
"lib/teiserver.ex",
"lib/teiserver/contexts/telemetry.ex",
"lib/teiserver/migrations/*",
"lib/teiserver/helpers/file_macros.ex",
"lib/teiserver/game/servers/lobby_id_server.ex"
],
Expand Down
1 change: 1 addition & 0 deletions documentation/development/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
## Connections
### Clients
- Tracking
- Login attempt rate limiting

## Communication
- Room messages
Expand Down
10 changes: 2 additions & 8 deletions documentation/development/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ This is not a rigid document, it is (especially at this stage) liable to change.
* `v0.0.2` - Client features (Connections)
* `v0.0.3` - Chat and Messaging (Communication)
* `v0.0.4` - Lobbies (Lobby and Game)
* `v0.0.5` - Logging and Event telemetry (Telemetry and Logging)
* `v0.0.5` - Site and User Settings, plus internal Telemetry (Settings, Telemetry)
* `v0.0.6` - Player relationships (Account and Community)
* `v0.0.7` - Moderation (Moderation and Account)
* `v0.0.8` - Parties (Community)
* `v0.0.9` - Site and User Settings (Settings)
* `v0.0.9` - tbd
* `v0.1` - Stability, tests and better examples on how to use it

At v0.1 I want the server to be in a state where developers can start to make use of it.
Expand Down Expand Up @@ -41,12 +41,6 @@ At v0.1 I want the server to be in a state where developers can start to make us
- Site settings
- User settings

- Telemetry
- In game events
- Server events
- Lobby events
- User events

## Planned/intended features
- Administration
- Moderation
Expand Down
2 changes: 2 additions & 0 deletions documentation/development/telemetry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Events
Teiserver emits the following events:
14 changes: 4 additions & 10 deletions documentation/guides/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ The `social_score` given to users registered using `Teiserver.Account.UserLib.re
## default_min_user_password_length - Default: 6
The minimum length for a user password.

# Clustering
## `teiserver_clustering` - Default: true
When enabled Teiserver will attempt to handle the clustering of nodes using a database table. Turning it off will mean this behaves like any other application and you can either not cluster it or use things like `libcluster` as you desire. See `Teiserver.System.ClusterManager` for more details.

## `teiserver_clustering_post_join_functions` - Default: []
When teiserver_clustering is enabled, this will be a list of functions called by the genserver handling the join once it has joined the cluster. See `Teiserver.System.ClusterManager` for more details.

# Function overrides
Teiserver implements some defaults you may want to overwrite.

Expand All @@ -50,22 +43,23 @@ Allows you to overwrite `Teiserver.Game.MatchTypeLib.default_calculate_match_typ
Allows you to overwrite `Teiserver.Account.User.default_calculate_user_permissions/1`. This is used to generate the list of permissions held by a user. By default it mirrors their groups.

## `fn_lobby_name_acceptor`
A function used to determine if a lobby name is acceptable. Defaults to `Teiserver.Game.LobbyLib.default_lobby_name_acceptable/1` which always returns true.
A function used to determine if a lobby name is acceptable. Defaults to `Teiserver.Game.LobbyLib.default_lobby_name_acceptable?/1` which always returns true.

## `fn_user_name_acceptor`
A function used to determine if a lobby name is acceptable. Defaults to `Teiserver.Account.UserLib.default_user_name_acceptable/1` which always returns true.
A function used to determine if a lobby name is acceptable. Defaults to `Teiserver.Account.UserLib.default_user_name_acceptable?/1` which always returns true.

## `fn_uuid_generator`
The function used to generate UUIDs. Defaults to `&Ecto.UUID.generate/0`.

# Function extensions
Teiserver has a number of functions which you will likely want to extend.

# Complete example config
```elixir
config :teiserver,
repo: HelloWorldServer.Repo,
client_destroy_timeout_seconds: 300,
lobby_join_method: :simple,
teiserver_clustering: true,

# Users
default_behaviour_score: 10_000,
Expand Down
12 changes: 5 additions & 7 deletions documentation/guides/hello_world.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,20 +116,18 @@ end
```

## Data in
Place in `lib/hellow_world_server/tcp_in.ex`, this will handle all the commands coming in.
Place in `lib/hello_world_server/tcp_in.ex`, this will handle all the commands coming in.
```elixir
defmodule HelloWorldServer.TcpIn do
alias Teiserver.Api

def data_in("ping" <> _data, state) do
{state, "pong"}
end

def data_in("login " <> data, state) do
[name, password] = String.split(data, " ")
case Api.maybe_authenticate_user(name, password) do
case Teiserver.maybe_authenticate_user_by_name(name, password) do
{:ok, user} ->
Api.connect_user(user)
Teiserver.connect_user(user)
{%{state | user_id: user.id}, "You are now logged in as '#{user.name}'"}
{:error, :no_user} ->
{state, "Login failed (no user)"}
Expand All @@ -145,7 +143,7 @@ defmodule HelloWorldServer.TcpIn do
# this will do for the purposes of this example
email = to_string(:rand.uniform())

case Api.register_user(name, email, password) do
case Teiserver.register_user(name, email, password) do
{:ok, _user} ->
{state, "User created, you can now login with 'login name password'"}
{:error, _} ->
Expand Down Expand Up @@ -192,7 +190,7 @@ end
```

## Data out
Place in `lib/hellow_world_server/tcp_out.ex`, this will handle sending data back to our users.
Place in `lib/hello_world_server/tcp_out.ex`, this will handle sending data back to our users.
```elixir
defmodule HelloWorldServer.TcpOut do
def data_out(msg, state) do
Expand Down
2 changes: 1 addition & 1 deletion documentation/guides/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ First add to your dependencies in `mix.exs`.
```elixir
def deps do
[
{:teiserver, "~> 0.0.4"}
{:teiserver, "~> 0.0.5"}
]
end
```
Expand Down
12 changes: 5 additions & 7 deletions documentation/guides/match_lifecycle.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Match lifecycle
The main purpose of Teiserver is to facilitate running a game; as a result the Lobby and Match systems are one of the core features and have a lot of customisation and flexibility.

In every case where the `Game` context is used there is a similar or identical function in `Api`.

### Overview
There are multiple stages to a match taking place, they will typically follow the below diagram.
```mermaid
Expand Down Expand Up @@ -36,7 +34,7 @@ To remove a client from a lobby you will need to call `Teiserver.Game.remove_cli
- The lobby state will be updated to remove this user from the member, spectator and player lists as appropriate

### Client updates
Typically a client will update via `Teiserver.Connections.update_client/2` but if you want to update the lobby details of a client you should use `Teiserver.Connections.update_client_in_lobby/2`.
Typically a client will update via `Teiserver.Connections.update_client/3` but if you want to update the lobby details of a client you should use `Teiserver.Connections.update_client_in_lobby/3`.

The standard `update_client` only contacts the ClientServer to update values but with the `update_client_in_lobby` function the ClientServer will check with the LobbyServer before updating any details to ensure it is allowed to.

Expand All @@ -48,21 +46,21 @@ The standard `update_client` only contacts the ClientServer to update values but
Lobbies have a key `:game_settings` which holds key-value map of the settings chosen for the upcoming match. These can be changed at any time prior to the match starting.

## Match start
When the match is started and the users move into playing the game itself (which does not take place on the middleware server) a call needs to be made to `Api` or `Game` `start_match/1` (delegated to `Teiserver.Game.MatchLib.start_match/1`).
When the match is started and the users move into playing the game itself (which does not take place on the middleware server) a call needs to be made to `Teiserver` or `Game` `start_match/1` (delegated to `Teiserver.Game.MatchLib.start_match/1`).

This will update the previously added Match object with the relevant information from the Lobby. It will create `Teiserver.Game.MatchMembership` objects for each player, create the relevant `Teiserver.Game.MatchSetting` objects (along with types) and update the Lobby to show the match as ongoing.

## Playing the game
While the game is ongoing the server is not directly involved except for anything the host wishes to relay to the server such as public chat or game telemetry events.

## Match end
At the conclusion of the match players should be returned to the lobby interface and the `Api` or `Game` `end_match/2` (delegated to `Teiserver.Game.MatchLib.end_match/2`) should be called.
At the conclusion of the match players should be returned to the lobby interface, you end it with and the `Teiserver` or `Game` `end_match/2` (delegated to `Teiserver.Game.MatchLib.end_match/2`) should be called.

This will update both the Match object and MatchMembership objects with the relevant data.

## Post game
### Close
In some cases you will want the lobby to close in which case `Api` or `Game` `close_lobby/1` (delegated to `Teiserver.Game.LobbyLib.close_lobby/1`) should be called. This will remove everybody from the lobby and stop the lobby process.
In some cases you will want the lobby to close in which case `Teiserver` or `Game` `close_lobby/1` (delegated to `Teiserver.Game.LobbyLib.close_lobby/1`) should be called. This will remove everybody from the lobby and stop the lobby process.

### Cycle
If you wish to keep the lobby in existence you should call `Api` or `Game` `cycle_lobby/1` (delegated to `Teiserver.Game.LobbyLib.cycle_lobby/1`) which will create a new empty Match object for the new upcoming match.
If you wish to keep the lobby in existence you should call `Teiserver` or `Game` `cycle_lobby/1` (delegated to `Teiserver.Game.LobbyLib.cycle_lobby/1`) which will create a new empty Match object for the new upcoming match.
Loading