Compare commits

...

49 Commits
latest ... main

Author SHA1 Message Date
Rim
6048d9f1c2 Merge branch 'master' of https://github.com/alterware/master-server 2024-05-30 19:39:04 -04:00
Rim
ad937f7202 maint: add support for h1 2024-05-30 19:36:43 -04:00
Future
27c2b2b75b
maint: improve overall logic in elimination_handler 2024-05-30 19:19:13 +02:00
Future
89f29244ac
fix: break out of loop when condition is met 2024-05-04 19:06:26 +02:00
Diamante
479f6fcbf3
maint: remove links from server names (#87) 2024-05-04 19:05:02 +02:00
Future
d48736c12a
fix: actually allow MAX_SERVERS_PER_GAME 2024-05-04 10:34:02 +02:00
Diamante
f2dd8d5c38
fix(elimination_handler): re-write patch (#86) 2024-05-04 10:15:40 +02:00
Future
f9e6352940
chore: update deps 2024-04-14 23:20:57 +02:00
Future
d43455a1d9
build: add Docker support 2024-03-22 16:13:30 +01:00
Edo
bb66931250
Merge pull request #77 from alterware/dependabot/submodules/deps/zlib-99b2294
build(deps): bump deps/zlib from `4a5e3e7` to `99b2294`
2024-03-13 16:19:55 +01:00
dependabot[bot]
bb8d5bbe9e
build(deps): bump deps/zlib from 4a5e3e7 to 99b2294
Bumps [deps/zlib](https://github.com/madler/zlib) from `4a5e3e7` to `99b2294`.
- [Release notes](https://github.com/madler/zlib/releases)
- [Commits](4a5e3e7d25...99b229487c)

---
updated-dependencies:
- dependency-name: deps/zlib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-13 15:03:54 +00:00
Edo
97343093b1
build: update workflow deps 2024-03-11 18:15:08 +01:00
Edo
6558dc6045
Merge pull request #75 from alterware/dependabot/submodules/deps/libtommath-7f39a72
build(deps): bump deps/libtommath from `7f96509` to `7f39a72`
2024-03-11 16:14:27 +01:00
Edo
38d532a49c
Merge pull request #74 from alterware/dependabot/submodules/deps/zlib-4a5e3e7
build(deps): bump deps/zlib from `5c42a23` to `4a5e3e7`
2024-03-11 16:14:19 +01:00
dependabot[bot]
b86c443616
build(deps): bump deps/libtommath from 7f96509 to 7f39a72
Bumps [deps/libtommath](https://github.com/libtom/libtommath) from `7f96509` to `7f39a72`.
- [Release notes](https://github.com/libtom/libtommath/releases)
- [Commits](7f96509df1...7f39a72cc2)

---
updated-dependencies:
- dependency-name: deps/libtommath
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 14:38:18 +00:00
dependabot[bot]
c32a1cfca7
build(deps): bump deps/zlib from 5c42a23 to 4a5e3e7
Bumps [deps/zlib](https://github.com/madler/zlib) from `5c42a23` to `4a5e3e7`.
- [Release notes](https://github.com/madler/zlib/releases)
- [Commits](5c42a230b7...4a5e3e7d25)

---
updated-dependencies:
- dependency-name: deps/zlib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 14:38:16 +00:00
Edo
7e5d2f4de9
Merge pull request #73 from alterware/dependabot/submodules/deps/rapidjson-5ec44fb
build(deps): bump deps/rapidjson from `68afb49` to `5ec44fb`
2024-03-08 15:35:27 +01:00
dependabot[bot]
4b0bc8156d
build(deps): bump deps/rapidjson from 68afb49 to 5ec44fb
Bumps [deps/rapidjson](https://github.com/Tencent/rapidjson) from `68afb49` to `5ec44fb`.
- [Release notes](https://github.com/Tencent/rapidjson/releases)
- [Commits](68afb49287...5ec44fb920)

---
updated-dependencies:
- dependency-name: deps/rapidjson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-08 14:32:24 +00:00
Edo
b7fc19c6fc
Merge pull request #72 from alterware/dependabot/submodules/deps/rapidjson-68afb49
build(deps): bump deps/rapidjson from `3f73eda` to `68afb49`
2024-03-07 15:55:49 +01:00
dependabot[bot]
a46e30f9b3
build(deps): bump deps/rapidjson from 3f73eda to 68afb49
Bumps [deps/rapidjson](https://github.com/Tencent/rapidjson) from `3f73eda` to `68afb49`.
- [Release notes](https://github.com/Tencent/rapidjson/releases)
- [Commits](3f73edae00...68afb49287)

---
updated-dependencies:
- dependency-name: deps/rapidjson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-07 14:33:04 +00:00
Diavolo
6a3a2a366f
build: add arm64 for the Windows platform 2024-03-04 11:56:52 +01:00
Edo
604e605f94
Merge pull request #71 from alterware/dependabot/submodules/deps/libtomcrypt-f7e6519
build(deps): bump deps/libtomcrypt from `1777e6d` to `f7e6519`
2024-02-27 15:41:15 +01:00
dependabot[bot]
ab576a7e36
build(deps): bump deps/libtomcrypt from 1777e6d to f7e6519
Bumps [deps/libtomcrypt](https://github.com/libtom/libtomcrypt) from `1777e6d` to `f7e6519`.
- [Release notes](https://github.com/libtom/libtomcrypt/releases)
- [Commits](1777e6d5c3...f7e6519fae)

---
updated-dependencies:
- dependency-name: deps/libtomcrypt
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-27 14:28:32 +00:00
Edo
658c6d5a3b
Merge pull request #69 from alterware/dependabot/submodules/deps/libtomcrypt-1777e6d
build(deps): bump deps/libtomcrypt from `7e863d2` to `1777e6d`
2024-02-26 18:05:17 +01:00
dependabot[bot]
80e65028bb
build(deps): bump deps/libtomcrypt from 7e863d2 to 1777e6d
Bumps [deps/libtomcrypt](https://github.com/libtom/libtomcrypt) from `7e863d2` to `1777e6d`.
- [Release notes](https://github.com/libtom/libtomcrypt/releases)
- [Commits](7e863d2142...1777e6d5c3)

---
updated-dependencies:
- dependency-name: deps/libtomcrypt
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-26 14:47:41 +00:00
Edo
d3b964c845
build: fix typo in premake5.lua 2024-02-19 22:47:52 +01:00
Diavolo
9ac42b065f
maint(bots): new wave of names 2024-02-13 10:51:29 +01:00
Edo
a08c7c5305
Merge pull request #67 from alterware/dependabot/submodules/deps/zlib-5c42a23
build(deps): bump deps/zlib from `985a62d` to `5c42a23`
2024-02-12 15:51:46 +01:00
Edo
1f87fb1e41
build: update version of ssh-key-action 2024-02-12 15:51:36 +01:00
dependabot[bot]
01bcd300d7
build(deps): bump deps/zlib from 985a62d to 5c42a23
Bumps [deps/zlib](https://github.com/madler/zlib) from `985a62d` to `5c42a23`.
- [Release notes](https://github.com/madler/zlib/releases)
- [Commits](985a62d118...5c42a230b7)

---
updated-dependencies:
- dependency-name: deps/zlib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 14:49:29 +00:00
Edo
2232fbf305
Merge pull request #66 from alterware/dependabot/submodules/deps/zlib-985a62d
build(deps): bump deps/zlib from `504403f` to `985a62d`
2024-02-09 09:53:55 -06:00
Edo
d1f5e413c5
Merge pull request #65 from alterware/dependabot/submodules/deps/rapidjson-3f73eda
build(deps): bump deps/rapidjson from `6089180` to `3f73eda`
2024-02-09 09:50:39 -06:00
dependabot[bot]
f4874ee104
build(deps): bump deps/zlib from 504403f to 985a62d
Bumps [deps/zlib](https://github.com/madler/zlib) from `504403f` to `985a62d`.
- [Release notes](https://github.com/madler/zlib/releases)
- [Commits](504403f3e4...985a62d118)

---
updated-dependencies:
- dependency-name: deps/zlib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 14:53:20 +00:00
dependabot[bot]
600be596ee
build(deps): bump deps/rapidjson from 6089180 to 3f73eda
Bumps [deps/rapidjson](https://github.com/Tencent/rapidjson) from `6089180` to `3f73eda`.
- [Release notes](https://github.com/Tencent/rapidjson/releases)
- [Commits](6089180ecb...3f73edae00)

---
updated-dependencies:
- dependency-name: deps/rapidjson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 14:53:18 +00:00
Edo
d481c5456e
Merge pull request #64 from alterware/dependabot/submodules/deps/zlib-504403f
build(deps): bump deps/zlib from `e342bb3` to `504403f`
2024-02-08 09:02:56 -06:00
dependabot[bot]
e56c2e31fb
build(deps): bump deps/zlib from e342bb3 to 504403f
Bumps [deps/zlib](https://github.com/madler/zlib) from `e342bb3` to `504403f`.
- [Release notes](https://github.com/madler/zlib/releases)
- [Commits](e342bb3dae...504403f3e4)

---
updated-dependencies:
- dependency-name: deps/zlib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-08 14:32:44 +00:00
Edo
8dd01ecb4d
Merge pull request #63 from alterware/dependabot/submodules/deps/zlib-e342bb3
build(deps): bump deps/zlib from `f1f503d` to `e342bb3`
2024-02-07 13:32:47 -06:00
dependabot[bot]
4cf4ecf591
build(deps): bump deps/zlib from f1f503d to e342bb3
Bumps [deps/zlib](https://github.com/madler/zlib) from `f1f503d` to `e342bb3`.
- [Release notes](https://github.com/madler/zlib/releases)
- [Commits](f1f503da85...e342bb3dae)

---
updated-dependencies:
- dependency-name: deps/zlib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-07 14:13:18 +00:00
Edo
251612a2b8
Merge pull request #61 from alterware/dependabot/submodules/deps/zlib-f1f503d
build(deps): bump deps/zlib from `2e3d86c` to `f1f503d`
2024-01-29 17:31:07 +01:00
dependabot[bot]
cdc53004fd
build(deps): bump deps/zlib from 2e3d86c to f1f503d
Bumps [deps/zlib](https://github.com/madler/zlib) from `2e3d86c` to `f1f503d`.
- [Release notes](https://github.com/madler/zlib/releases)
- [Commits](2e3d86c4e1...f1f503da85)

---
updated-dependencies:
- dependency-name: deps/zlib
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-29 14:23:23 +00:00
Edo
c9a77058b4
maint(bots): add more names (#59) 2024-01-22 17:20:20 +01:00
dependabot[bot]
66a5138056
build(deps): bump deps/zlib from ade6825 to 2e3d86c (#58) 2024-01-22 15:26:45 +01:00
dependabot[bot]
d31f17c8c1
build(deps): bump deps/GSL from 52212c2 to f1a494c (#55)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-18 16:07:15 +01:00
dependabot[bot]
16f2e165ac
build(deps): bump deps/zlib from 643e17b to ade6825 (#56) 2024-01-18 15:24:07 +01:00
Diavolo
794f3799ca
fix(readme): fix a broken link [skip ci] 2024-01-15 12:16:25 +01:00
Diavolo
1361cd502b
build: deploy release binary 2024-01-14 13:34:54 +01:00
Diavolo
b038ebf661
build: clean workflow 2024-01-13 10:40:06 +01:00
Diavolo
9f68a0ed4b
build: cleanup CI workflow 2024-01-12 11:55:14 +01:00
Diavolo
d4fad5d966
maint: some more bot names 2023-12-19 17:38:59 +01:00
10 changed files with 395 additions and 254 deletions

View File

@ -3,10 +3,12 @@ name: Build
on:
push:
branches:
- "*"
- "**"
tags:
- '[0-9]+.[0-9]+.[0-9]+'
pull_request:
branches:
- "*"
- "**"
types: [opened, synchronize, reopened]
concurrency:
@ -58,7 +60,11 @@ jobs:
uses: ammaraskar/msvc-problem-matcher@master
- name: Build ${{matrix.arch}} ${{matrix.configuration}} binaries
<<<<<<< HEAD
run: msbuild /m /v:minimal /p:Configuration=${{matrix.configuration}} /p:Platform=${{matrix.platform}} build/master-server.sln
=======
run: msbuild /m /v:minimal /p:Configuration=${{matrix.configuration}} /p:Platform=${{matrix.platform}} build/alterware-master.sln
>>>>>>> 27c2b2b75b56e54dcfbec690dd086946a45587d7
- name: Upload ${{matrix.arch}} ${{matrix.configuration}} binaries
uses: actions/upload-artifact@main
@ -162,17 +168,28 @@ jobs:
with:
name: macos-${{matrix.arch}}-${{matrix.configuration}}
path: |
<<<<<<< HEAD
build/bin/${{matrix.arch}}/${{matrix.configuration}}/master-server
=======
build/bin/${{matrix.arch}}/${{matrix.configuration}}/alterware-master
>>>>>>> 27c2b2b75b56e54dcfbec690dd086946a45587d7
deploy:
name: Deploy artifacts
needs: [build-win, build-linux, build-macos]
runs-on: ubuntu-latest
<<<<<<< HEAD
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
steps:
- name: Setup main environment
if: github.ref == 'refs/heads/master'
run: echo "MASTER_SERVER_PATH=${{ secrets.MASTER_SERVER_SSH_PATH }}" >> $GITHUB_ENV
=======
if: github.ref_type == 'tag'
steps:
- name: Setup main environment
run: echo "ALTERWARE_MASTER_SERVER_PATH=${{ secrets.ALTERWARE_MASTER_SERVER_SSH_PATH }}" >> $GITHUB_ENV
>>>>>>> 27c2b2b75b56e54dcfbec690dd086946a45587d7
- name: Download Release binaries
uses: actions/download-artifact@main
@ -182,6 +199,7 @@ jobs:
- name: Install SSH key
uses: shimataro/ssh-key-action@v2.7.0
with:
<<<<<<< HEAD
key: ${{ secrets.MASTER_SERVER_SSH_PRIVATE_KEY }}
known_hosts: 'just-a-placeholder-so-we-dont-get-errors'
@ -193,3 +211,74 @@ jobs:
- name: Publish changes
run: ssh ${{ secrets.MASTER_SERVER_SSH_USER }}@${{ secrets.MASTER_SERVER_SSH_ADDRESS }} ${{ secrets.SSH_SERVER_PUBLISH_COMMAND }}
=======
key: ${{ secrets.ALTERWARE_MASTER_SERVER_SSH_PRIVATE_KEY }}
known_hosts: 'just-a-placeholder-so-we-dont-get-errors'
- name: Add known hosts
run: ssh-keyscan -H ${{ secrets.ALTERWARE_MASTER_SERVER_SSH_ADDRESS }} >> ~/.ssh/known_hosts
- name: Upload release binary
run: rsync -avz alterware-master ${{ secrets.ALTERWARE_MASTER_SERVER_SSH_USER }}@${{ secrets.ALTERWARE_MASTER_SERVER_SSH_ADDRESS }}:${{ env.ALTERWARE_MASTER_SERVER_PATH }}/
- name: Publish changes
run: ssh ${{ secrets.ALTERWARE_MASTER_SERVER_SSH_USER }}@${{ secrets.ALTERWARE_MASTER_SERVER_SSH_ADDRESS }} ${{ secrets.ALTERWARE_SSH_SERVER_PUBLISH_COMMAND }}
docker:
name: Create Docker Image
needs: [build-win, build-linux, build-macos]
runs-on: ubuntu-latest
if: github.ref_type == 'tag'
steps:
- name: Check out files
uses: actions/checkout@main
with:
sparse-checkout: |
Dockerfile
README.md
sparse-checkout-cone-mode: false
- name: Download Release binaries
uses: actions/download-artifact@main
- name: Compress Binaries
run: |
for dir in */; do
if [[ $dir == *"windows"* ]]; then
cd "$dir" && zip -r "../${dir%/}.zip" . && cd ..
else
tar -czvf "${dir%/}.tar.gz" -C "$dir" .
fi
done
shell: bash
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3.2.0
- name: Login to DockerHub
uses: docker/login-action@v3.1.0
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- id: meta
uses: docker/metadata-action@v5.5.1
with:
images: |
alterware/master-server
tags: |
${{ github.ref_name }}
latest
- name: Build and Push Docker Image
id: build-and-push
uses: docker/build-push-action@v5.1.0
with:
context: .
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
>>>>>>> 27c2b2b75b56e54dcfbec690dd086946a45587d7

6
.gitmodules vendored
View File

@ -19,4 +19,8 @@
[submodule "deps/curl"]
path = deps/curl
url = https://github.com/curl/curl.git
branch = curl-8_7_1
<<<<<<< HEAD
branch = curl-8_7_1
=======
branch = curl-8_7_1
>>>>>>> 27c2b2b75b56e54dcfbec690dd086946a45587d7

13
Dockerfile Normal file
View File

@ -0,0 +1,13 @@
FROM ubuntu:latest
RUN apt-get update
RUN apt-get install -y libc++-dev libcurl4-gnutls-dev
COPY --chmod=755 ./linux-x64-release/alterware-master /usr/local/bin/
RUN groupadd alterware-master && useradd -r -g alterware-master alterware-master
USER alterware-master
EXPOSE 20810/udp
ENTRYPOINT ["/usr/local/bin/alterware-master"]

View File

@ -4,6 +4,13 @@
# Master Server
This is the master server our clients use. It is based on the DP Master Server (ID Tech) protocol
## Usage
Run using [Docker][docker-link]
```bash
docker run -p 20810:20810/udp alterware/master-server:latest
```
## Build
- Install [Premake5][premake5-link] and add it to your system PATH
- Clone this repository using [Git][git-link]
@ -18,6 +25,7 @@ Requirements for Unix systems:
- Customization: Modifications to the Premake5.lua script may be required
- Platform support: Details regarding supported platforms are available in [build.yml][build-link]
[docker-link]: https://www.docker.com
[premake5-link]: https://premake.github.io
[git-link]: https://git-scm.com
[mold-link]: https://github.com/rui314/mold

View File

@ -36,7 +36,7 @@ namespace crypto_key
if (!utils::io::write_file("./private.key", key.serialize()))
{
throw std::runtime_error("Failed to write server key!");
console::error("Failed to write server key!");
}
console::info("Generated cryptographic key: %llX", key.get_hash());

View File

@ -9,6 +9,7 @@ enum class game_type
iw5,
iw6,
iw7,
h1,
s1,
t7,
};
@ -22,6 +23,7 @@ inline const std::string& resolve_game_type_name(const game_type game)
{game_type::iw5, "IW5"},
{game_type::iw6, "IW6"},
{game_type::iw7, "IW7"},
{game_type::h1, "H1"},
{game_type::s1, "S1"},
{game_type::t7, "T7"},
};
@ -51,6 +53,11 @@ inline game_type resolve_game_type(const std::string& game_name)
return game_type::iw7;
}
if (game_name == "H1")
{
return game_type::h1;
}
if (game_name == "S1")
{
return game_type::s1;

View File

@ -30,6 +30,7 @@ void elimination_handler::run_frame()
(server.state == game_server::state::can_ping && diff > 15min))
{
context.remove();
return;
}
if (server.game == game_type::unknown)
@ -43,6 +44,7 @@ void elimination_handler::run_frame()
console::log("Removing T7 server '%s' because they are using an outdated protocol (%i)", context.get_address().to_string().data(), server.protocol);
#endif
context.remove();
return;
}
++server_count[server.game][context.get_address().to_string(false)];
@ -50,6 +52,18 @@ void elimination_handler::run_frame()
{
console::log("Removing server '%s' because it exceeds MAX_SERVERS_PER_GAME", context.get_address().to_string().data());
context.remove();
return;
}
const auto name = utils::string::to_lower(server.name);
for (const auto& entry : bad_names)
{
if (const auto pos = name.find(entry); pos != std::string::npos)
{
console::log("Removing server '%s' (%s) because it contains a bad name", server.name.data(), context.get_address().to_string().data());
context.remove();
return;
}
}
const auto name = utils::string::to_lower(server.name);

View File

@ -1,153 +1,159 @@
#include "std_include.hpp"
#include "kill_list.hpp"
#include <utils/io.hpp>
constexpr auto* kill_file = "./kill.txt";
kill_list::kill_list_entry::kill_list_entry(std::string ip_address, std::string reason)
: ip_address_(std::move(ip_address)), reason_(std::move(reason))
{
}
bool kill_list::contains(const network::address& address, std::string& reason)
{
auto str_address = address.to_string(false);
return this->entries_container_.access<bool>([&str_address, &reason](const kill_list_entries& entries)
{
if (const auto itr = entries.find(str_address); itr != entries.end())
{
reason = itr->second.reason_;
return true;
}
return false;
});
}
void kill_list::add_to_kill_list(const kill_list_entry& add)
{
const auto any_change = this->entries_container_.access<bool>([&add](kill_list_entries& entries)
{
const auto existing_entry = entries.find(add.ip_address_);
if (existing_entry == entries.end() || existing_entry->second.reason_ != add.reason_)
{
console::info("Added %s to kill list (reason: %s)", add.ip_address_.data(), add.reason_.data());
entries[add.ip_address_] = add;
return true;
}
return false;
});
if (!any_change)
{
console::info("%s already in kill list, doing nothing", add.ip_address_.data());
return;
}
this->write_to_disk();
}
void kill_list::remove_from_kill_list(const network::address& remove)
{
this->remove_from_kill_list(remove.to_string());
}
void kill_list::remove_from_kill_list(const std::string& remove)
{
const auto any_change = this->entries_container_.access<bool>([&remove](kill_list_entries& entries)
{
if (entries.erase(remove))
{
console::info("Removed %s from kill list", remove.data());
return true;
}
return false;
});
if (!any_change)
{
console::info("%s not in kill list, doing nothing", remove.data());
return;
}
this->write_to_disk();
}
void kill_list::reload_from_disk()
{
std::string contents;
if (!utils::io::read_file(kill_file, &contents))
{
console::info("Could not find %s, kill list will not be loaded.", kill_file);
return;
}
std::istringstream string_stream(contents);
std::string line;
this->entries_container_.access([&string_stream, &line](kill_list_entries& entries)
{
entries.clear();
while (std::getline(string_stream, line))
{
if (line[0] == '#')
{
// comments or ignored line
continue;
}
std::string ip;
std::string comment;
const auto index = line.find(' ');
if (index != std::string::npos)
{
ip = line.substr(0, index);
comment = line.substr(index + 1);
}
else
{
ip = line;
}
if (ip.empty())
{
continue;
}
// Double line breaks from windows' \r\n
if (ip[ip.size() - 1] == '\r')
{
ip.pop_back();
}
entries.emplace(ip, kill_list_entry(ip, comment));
}
console::info("Loaded %zu kill list entries from %s", entries.size(), kill_file);
});
}
void kill_list::write_to_disk()
{
std::ostringstream stream;
this->entries_container_.access([&stream](const kill_list_entries& entries)
{
for (const auto& [ip, entry] : entries)
{
stream << entry.ip_address_ << " " << entry.reason_ << "\n";
}
utils::io::write_file(kill_file, stream.str(), false);
console::info("Wrote %s to disk (%zu entries)", kill_file, entries.size());
});
}
kill_list::kill_list(server& server) : service(server)
{
this->reload_from_disk();
}
#include "std_include.hpp"
#include "kill_list.hpp"
#include <utils/io.hpp>
constexpr auto* kill_file = "./kill.txt";
kill_list::kill_list_entry::kill_list_entry(std::string ip_address, std::string reason)
: ip_address_(std::move(ip_address)), reason_(std::move(reason))
{
}
bool kill_list::contains(const network::address& address, std::string& reason)
{
auto str_address = address.to_string(false);
return this->entries_container_.access<bool>([&str_address, &reason](const kill_list_entries& entries)
{
if (const auto itr = entries.find(str_address); itr != entries.end())
{
reason = itr->second.reason_;
return true;
}
return false;
});
}
void kill_list::add_to_kill_list(const kill_list_entry& add)
{
const auto any_change = this->entries_container_.access<bool>([&add](kill_list_entries& entries)
{
const auto existing_entry = entries.find(add.ip_address_);
if (existing_entry == entries.end() || existing_entry->second.reason_ != add.reason_)
{
console::info("Added %s to kill list (reason: %s)", add.ip_address_.data(), add.reason_.data());
entries[add.ip_address_] = add;
return true;
}
return false;
});
if (!any_change)
{
console::info("%s already in kill list, doing nothing", add.ip_address_.data());
return;
}
this->write_to_disk();
}
void kill_list::remove_from_kill_list(const network::address& remove)
{
this->remove_from_kill_list(remove.to_string());
}
void kill_list::remove_from_kill_list(const std::string& remove)
{
const auto any_change = this->entries_container_.access<bool>([&remove](kill_list_entries& entries)
{
if (entries.erase(remove))
{
console::info("Removed %s from kill list", remove.data());
return true;
}
return false;
});
if (!any_change)
{
console::info("%s not in kill list, doing nothing", remove.data());
return;
}
this->write_to_disk();
}
void kill_list::reload_from_disk()
{
std::string contents;
if (!utils::io::read_file(kill_file, &contents))
{
console::info("Could not find %s, kill list will not be loaded.", kill_file);
return;
}
std::istringstream string_stream(contents);
std::string line;
this->entries_container_.access([&string_stream, &line](kill_list_entries& entries)
{
entries.clear();
while (std::getline(string_stream, line))
{
if (line[0] == '#')
{
// comments or ignored line
continue;
}
std::string ip;
std::string comment;
const auto index = line.find(' ');
if (index != std::string::npos)
{
ip = line.substr(0, index);
comment = line.substr(index + 1);
}
else
{
ip = line;
}
if (ip.empty())
{
continue;
}
// Double line breaks from windows' \r\n
if (ip[ip.size() - 1] == '\r')
{
ip.pop_back();
}
entries.emplace(ip, kill_list_entry(ip, comment));
}
console::info("Loaded %zu kill list entries from %s", entries.size(), kill_file);
});
}
void kill_list::write_to_disk()
{
std::ostringstream stream;
this->entries_container_.access([&stream](const kill_list_entries& entries)
{
for (const auto& [ip, entry] : entries)
{
stream << entry.ip_address_ << " " << entry.reason_ << "\n";
}
if (utils::io::write_file(kill_file, stream.str(), false))
{
console::info("Wrote %s to disk (%zu entries)", kill_file, entries.size());
}
else
{
console::error("Failed to write %s!", kill_file);
}
});
}
kill_list::kill_list(server& server) : service(server)
{
this->reload_from_disk();
}

View File

@ -1,32 +1,32 @@
#pragma once
#include <network/address.hpp>
#include "../service.hpp"
class kill_list : public service
{
public:
class kill_list_entry
{
public:
kill_list_entry() = default;
kill_list_entry(std::string ip_address, std::string reason);
std::string ip_address_;
std::string reason_;
};
kill_list(server& server);
bool contains(const network::address& address, std::string& reason);
void add_to_kill_list(const kill_list_entry& add);
void remove_from_kill_list(const network::address& remove);
void remove_from_kill_list(const std::string& remove);
private:
using kill_list_entries = std::unordered_map<std::string, kill_list_entry>;
utils::concurrency::container<kill_list_entries> entries_container_;
void reload_from_disk();
void write_to_disk();
};
#pragma once
#include <network/address.hpp>
#include "../service.hpp"
class kill_list : public service
{
public:
class kill_list_entry
{
public:
kill_list_entry() = default;
kill_list_entry(std::string ip_address, std::string reason);
std::string ip_address_;
std::string reason_;
};
kill_list(server& server);
bool contains(const network::address& address, std::string& reason);
void add_to_kill_list(const kill_list_entry& add);
void remove_from_kill_list(const network::address& remove);
void remove_from_kill_list(const std::string& remove);
private:
using kill_list_entries = std::unordered_map<std::string, kill_list_entry>;
utils::concurrency::container<kill_list_entries> entries_container_;
void reload_from_disk();
void write_to_disk();
};

View File

@ -1,65 +1,65 @@
#include <std_include.hpp>
#include "patch_kill_list_command.hpp"
#include "crypto_key.hpp"
#include "services/kill_list.hpp"
#include <utils/parameters.hpp>
#include <utils/io.hpp>
#include <utils/string.hpp>
const char* patch_kill_list_command::get_command() const
{
return "patchkill";
}
// patchkill timestamp signature add/remove target_ip (ban_reason)
void patch_kill_list_command::handle_command([[maybe_unused]] const network::address& target, const std::string_view& data)
{
const utils::parameters params(data);
if (params.size() < 3)
{
throw execution_exception("Invalid parameter count");
}
const auto supplied_timestamp = std::chrono::seconds(std::stoul(params[0]));
const auto current_timestamp = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());
// Abs the duration so that the client can be ahead or behind
const auto time_stretch = std::chrono::abs(current_timestamp - supplied_timestamp);
// not offset by more than 5 minutes in either direction
if (time_stretch > 5min)
{
throw execution_exception(utils::string::va("Invalid timestamp supplied - expected %llu, got %llu, which is more than 5 minutes apart", current_timestamp.count(), supplied_timestamp.count()));
}
const auto& signature = utils::cryptography::base64::decode(params[1]);
const auto should_remove = params[2] == "remove"s;
if (!should_remove && params[2] != "add"s)
{
throw execution_exception("Invalid parameter #2: should be 'add' or 'remove'");
}
const auto supplied_reason = params.join(4);
const auto& crypto_key = crypto_key::get();
const auto signature_candidate = std::to_string(supplied_timestamp.count());
if (!utils::cryptography::ecc::verify_message(crypto_key, signature_candidate, signature))
{
throw execution_exception("Signature verification of the kill list patch key failed");
}
const auto kill_list_service = this->get_server().get_service<kill_list>();
const auto& supplied_address = params[3];
if (should_remove)
{
kill_list_service->remove_from_kill_list(supplied_address);
}
else
{
kill_list_service->add_to_kill_list(kill_list::kill_list_entry(supplied_address, supplied_reason));
}
}
#include <std_include.hpp>
#include "patch_kill_list_command.hpp"
#include "crypto_key.hpp"
#include "services/kill_list.hpp"
#include <utils/parameters.hpp>
#include <utils/io.hpp>
#include <utils/string.hpp>
const char* patch_kill_list_command::get_command() const
{
return "patchkill";
}
// patchkill timestamp signature add/remove target_ip (ban_reason)
void patch_kill_list_command::handle_command([[maybe_unused]] const network::address& target, const std::string_view& data)
{
const utils::parameters params(data);
if (params.size() < 3)
{
throw execution_exception("Invalid parameter count");
}
const auto supplied_timestamp = std::chrono::seconds(std::stoul(params[0]));
const auto current_timestamp = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch());
// Abs the duration so that the client can be ahead or behind
const auto time_stretch = std::chrono::abs(current_timestamp - supplied_timestamp);
// not offset by more than 5 minutes in either direction
if (time_stretch > 5min)
{
throw execution_exception(utils::string::va("Invalid timestamp supplied - expected %llu, got %llu, which is more than 5 minutes apart", current_timestamp.count(), supplied_timestamp.count()));
}
const auto& signature = utils::cryptography::base64::decode(params[1]);
const auto should_remove = params[2] == "remove"s;
if (!should_remove && params[2] != "add"s)
{
throw execution_exception("Invalid parameter #2: should be 'add' or 'remove'");
}
const auto supplied_reason = params.join(4);
const auto& crypto_key = crypto_key::get();
const auto signature_candidate = std::to_string(supplied_timestamp.count());
if (!utils::cryptography::ecc::verify_message(crypto_key, signature_candidate, signature))
{
throw execution_exception("Signature verification of the kill list patch key failed");
}
const auto kill_list_service = this->get_server().get_service<kill_list>();
const auto& supplied_address = params[3];
if (should_remove)
{
kill_list_service->remove_from_kill_list(supplied_address);
}
else
{
kill_list_service->add_to_kill_list(kill_list::kill_list_entry(supplied_address, supplied_reason));
}
}