GithubHelp home page GithubHelp logo

th3-z / kf2-magicked-admin Goto Github PK

View Code? Open in Web Editor NEW
31.0 8.0 7.0 1.9 MB

:spider: Mutator-free management, statistics, and in-game bot for ranked Killing Floor 2 servers

Home Page: https://kf2-ma.th3-z.xyz

License: MIT License

Python 98.53% Makefile 0.75% Dockerfile 0.21% Shell 0.21% Lua 0.30%
bot killingfloor2 chatbot statistics player-stats kf2 player-commands

kf2-magicked-admin's Introduction

Killing Floor 2 Magicked Admin

Downloads Build Status Coverage Status CodeFactor GitHub license

About

Scripted management, statistics, and bot for ranked Killing Floor 2 servers. Provides in-game commands, player stat tracking and ranking, live MOTD scoreboard and stats, greeter, and admin functions. Running entirely through the web admin, it does not affect a server's ranked/custom status. It can be ran either directly on the server or remotely, and manage multiple servers at once.

Downloads

The most recent stable version is 0.1.6. A binary is provided on the releases page for Windows and Linux users.

Release 0.1.6

Old releases

Features

Commands

When inputting commands into the chat they need to be prefixed with !. When writting commands into a script, or chaining them this should be omitted.

Many commands will look for closest matches to their parameters. For example 'biotics' will match 'kf-biotics-lab' and 'userO' will match 'userOne™/@:®'.

All commands have in-game help text that can be accessed with the -h flag.

  • Example: !commands -h

All commands also have the following flags.

  • -q - Suppresses output
  • -p - Pads output to hide the username line

Escape sequences as follows are available to format messages.

  • \n - Newline
    • Example: !say line 0\nline 1
  • \t - Tab
    • Example: !say line 0\n\tline 1 is indented

Player commands

Commands that can be executed by any player.

Click to see the player commands!
  • !commands - Shows a list of all commands available to players
  • !stats <user> - Shows general statistics about a user
    • Example: !stats Shows stats about yourself
    • Example: !stats the_z Shows stats about the_z
  • !kills <user> - Shows kill statistics about a user
    • Example: !kills Shows kill stats about yourself
    • Example: !kills the_z Shows kill stats about the_z
  • !dosh <user> - Shows dosh statistics about a user
    • Example: !dosh Shows dosh stats about yourself
    • Example: !dosh the_z Shows dosh stats about the_z
  • !time <user> - Shows time statistics about a user
    • Example: !dosh Shows time stats about yourself
    • Example: !dosh the_z Shows time stats about the_z
  • !map - Shows statistics about the current map
  • !record_wave - Shows the highest wave achieved on the current map
  • !top_kills - Shows the global kills leaderboard
  • !top_dosh - Shows the global dosh leaderboard
  • !top_time - Shows the global play time leaderboard
  • !top_wave_kills - Shows information about who killed the most ZEDs in the current wave. Generally for use with start_trc
    • Example: !start_trc -- top_wave_kills
  • !top_wave_dosh - Shwows information about who earned the most dosh in the current wave. Generally for use with !start_trc
    • Example: !start_trc -- top_wave_dosh
  • !server_kills - Shows total kills on the server
  • !server_dosh - Shows total dosh earned on the server
  • !scoreboard - Shows the complete player scoreboard, useful on servers with >6 max players
    • Alias: !sb Does the same
  • !game - Shows information about the current game
  • !maps [--all] - Shows the current map cycle
    • Option -a: Show all available maps
  • !player_count - Shows the player count and max players

Admin commands

Commands that can be ran by server administrators or users authorized with the !op command.

Click to see the admin commands!
  • !op <user> - Gives a user administrative rights
    • Example: !op the_z
  • !deop <user> - Revokes a user's administrative rights
    • Example: !deop the_z
  • !say <message> - Echoes a message into chat
    • Example: !say The quick brown fox jumps over the lazy dog
    • Example: !start_trc -- say The trader is open
  • !players - Shows detailed information about players on the server
  • !kick <user> - Kicks <user> from the match
    • Example: !kick the_z
  • !ban <user> - Bans <user> from the server
    • Example: !ban the_z
    • Warnng: The web admin currently has a bug that causes bans to persist after they are deleted, thus there is no unban command
  • !length <length> - Change the length to <length> next game
    • Example: !length short
  • !difficulty <difficulty> - Change the difficulty to <difficulty> next game
    • Example: !difficulty hell
  • !game_mode <game_mode> - Immediately change the game mode to <game_mode>
    • Example: !game_mode endless Changes the game mode to Endless
  • !load_map <map> - Immediately change the map to <map>
    • Example: !load_map biotics Changes the map to Biotics Lab
  • !restart - Immediately restart the current game
  • !password [--set] <on|off>
    • Example: !password on Enables the game password defined in the config
    • Example: !password off Disables the game password
    • Example: !password --set somePass Sets a specific password
  • !start_jc [-r] -- <command> - Start a command that runs every time a player joins - -r Only run for returning players
    • Example: !start_jc -- say Welcome %PLR - Greets a player on join
    • Available tokens: %PLR - username, %KLL - total kills, %DSH - total dosh; %PLR - username, %BCK - "back" if sessions > 1, %DRK - dosh rank, %KRK - kill rank, %TME - play time, %TRK - play time rank, %SES - sessions
  • !stop_jc - Stops all join commands
  • !start_wc [-w <wave>] -- <command> - Start a command that runs on wave <wave>
    • -w Wave to run the command on, can be omitted to have the command run every wave
    • -w Can be negative to count backwards from the boss wave
    • Example: !start_wc -1 -- say Welcome to the boss wave
  • !stop_wc - Stops all wave commands
  • !start_tc [-r, -t <seconds>] -- <command> - Start a command that runs after <seconds> seconds
    • Option -r: Add to have the command run repeatedly
    • Option -t: Required, the number of seconds before the command runs
    • Example: !start_tc -rt 600 -- say Join our Steam group!\n http://steam.group/
  • !stop_tc - Stops all timed commands
  • !start_trc [-w <wave>] -- <command> - Start a commands that runs when the trader opens
    • -w Wave to run the command on, can be omitted to have the command run every wave
    • -w Can be negative to count backwards from the boss wave
    • Example: !start_trc -- top_wave_dosh - Shows who earned the most dosh every wave when the trader opens
  • !stop_trc - Stop all commands that run on trader open
  • !silent - Toggles suppression of all chat output, commands still have effect, but the response will not be visible to players
  • !run <script_name> - Executes a script from the conf/scripts folder, more information in the scripts section
    • Example: !run example
  • !marquee <marquee_name> - Runs a marquee in the chat from the conf/marquee folder, experimental
    • Example: !marquee example
  • !update_motd <type> - Refreshes the welcome screen leaderboard, type is one of: kills, dosh, or time
    • Example: !start_tc 300 -- update_motd kills
  • !reload_motd - Reloads the server's *.motd file from conf
  • !alias - Check the help text !alias -h
  • !enforce_dosh <amount> - Kicks all players that have more dosh than the specified amount
    • Example: !start_tc 600 -- enforce_dosh 60000

MOTD leaderboard

A sample .motd file is provided in conf/. The filename should match the server's name as specified in conf/magicked_admin.conf. The template format is Jinja2. An example follows, please refer to the Jinja2 designer documentation.

Welcome to our server.

{{ millify(server_kills) }} Zeds killed on this server.

Top Players (total dosh):
{% for player in top_dosh[0:9] -%}
    {{loop.index}}. {{player.username|truncate(11)}} [{{millify(player.score)}}]		{% if loop.index is divisibleby 3 %}
{% endif %}
{%- endfor %}

Have fun and good luck!

Scripts

Writing a server_name.init in the conf/scripts folder with a series of commands will run the commands in sequence when the bot starts on server_name.

Additional scripts can be written in the conf/scripts folder and ran with the !run command. There is an example already in there that can be ran with !run example.

  • Comments can be added to scripts by prefixing a line with ;.

Webadmin patches

For gamemodes other than survival to function in full patches have to be applied to the KFGame/Web/ServerAdmin folder on the server. For this reason a script is provided in the admin-patches folder that will automatically patch your server.

There is currently no CLI or Windows build for this component. You can run it with python3 admin-patches/admin-patches.py. A dialogue box will appear asking you to locate your server.

Configuration options

Basic setup is done on the first run. However this does not cover all of the options KF2-MA can offer. Please see the config file, conf/magicked_admin.conf, for more configuration options as some features are disabled by default.

Each server managed by KF2-MA has a section that looks something like [server_one], followed by several options (x = y). Copy and edit the default server section if you want to manage multiple servers. [server_one] is the name of the server, this can be changed to whatever you want.

Options

Options can be configured in the config file conf/magicked_admin.conf.

  • address
    • Web address of the server's webadmin panel. Requires scheme and protocol, e.g. https://0.0.0.0:8080
  • username
    • Webadmin username to login with, this will appear in the chat when the bot has something to output. It's recommended to create a separate account for the bot.
  • password
    • Webadmin password that matches the username above.
  • game_password
    • Default game password to set when the password is toggled using !password <on|off>.
  • refresh_rate
    • Integer value, webadmin polling rate

Running with Docker

Running with docker is easy. Just issue this command:

    docker run -it -p 1880:1880 --name kf2-magicked-admin -v '<host config folder location>':'/magicked_admin/conf' th3z/kf2-magicked-admin

You will need to change <host config folder location> to wherever you want to store your config folder. /mnt/user/appdata/kf2-magicked-admin is a popular choice for systems running Unraid.

After this command runs the container will exit out and the logs will tell you to setup the config file. Go to your conf folder and set things up then run the container again and you are good to go!

If you want to use the admin_patches so that kf-magicked-admin gets installed into your server directory when the container starts (some gamemodes wont track stats without it) just mount your game directory into the container and set the PATCHES_TARGET_DIR env variable to the directory. You can mount multiple directories and just separate them with a comma "," in the env variable if you have many servers. Here is an example:

    docker run -it -p 1880:1880 --name kf2-magicked-admin -v '<host config folder location>':'/magicked_admin/conf' -v '<host kf folder>':/kf2-server -v '<host kf folder>':/kf2-server-two -e 'PATCHES_TARGET_DIR'='/kf2-server,/kf2-server-two' th3z/kf2-magicked-admin

Running from Python sources

Before contributing code you will need to install the Python requirements.

Requirements

Examples work on Debian 10 and Ubuntu Xenial, may differ for other operating systems. Install the following packages.

  • Python 3.7 - apt install python3
  • Pip - apt install python3-pip
  • Pybabel - apt install python3-babel
  • Python 3 dependencies - pip3 install -r requirements.txt
    • This might complain about cx_freeze not installing if you haven't got zlib-dev, but cx_freeze is only needed for building.

Running

git clone https://github.com/th3-z/kf2-magicked-admin.git

cd kf2-magicked-admin

pip3 install -r requirements.txt

make i18n-compile

python3 -O magicked_admin/magicked_admin.py

The -O flag runs the program in release mode, remove it to run KF2-MA in debug mode. Debug mode will enable more detailed output.

Building

You can build a binary release for distribution with make after installing both the run and build requirements.

Requirements

Examples work on Debian 10 and Ubuntu Xenial, may differ for other operating systems.

  • Python 3.7 - apt install python3
  • Pybabel - apt install python3-babel
  • Pip - apt install python3-pip
  • Pip dependencies - pip3 install -r requirements.txt
  • Make - apt install make

On Windows it's recommend to build with Cygwin. However you can also build it by running python3 setup.py build. Check the makefile for help building the locale files.

kf2-magicked-admin's People

Contributors

d1ceward avatar shompi avatar skylord123 avatar stephen720 avatar th3-z avatar williambrown42 avatar yakonche avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kf2-magicked-admin's Issues

Lobby players considered dead.

Players that join mid-game and click receive a death.
One solution is to only allow players to die after killing ZEDs, but ZED kill persist when rejoining.

Multi-admin related errors

When multi-admin is disabled the program will print errors, keeping running, but be completely non-functional.
Solution, check state of multi-admin from the login page and respond accordingly.

Unicode support

Players with pure Unicode names (e.g. Chinese players) of the same length will collide because the characters are replaced with ?s.

datatype error in info page

Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Users\Stephen\AppData\Local\Programs\Python\Python36-32\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "C:\Users\Stephen\Desktop\kf-magicked-admin\magicked_admin\server\managers\server_mapper.py", line 83, in run
int(new_health), int(new_kills), int(new_dosh), int(new_ping)
ValueError: invalid literal for int() with base 10: 'No'

Magicked Ignoring Chat

While having for instance "!start_tc 1 say test" active, Magicked refuses to listen to 90% of messages.
Encountered using self.time_interval of 2

!restart and !load_map change gamemode to survival

The Commands !restart and !load_map are not respecting the current game mode and always start the map on a survival game.

This is because the game mode is hard-coded within the payload of the function change_map in class server

Perk thresholds

Get player level from info page when it is enabled. option to boot perks below a certain level.

!sid

display player steam ids

Broken when running mutators.

https://github.com/th3-z/kf-magicked-admin/blob/57d0b39c32b13513bf5f28ab4f52695141d8cb0a/magicked_admin/server/managers/server_mapper.py#L48
https://github.com/th3-z/kf-magicked-admin/blob/57d0b39c32b13513bf5f28ab4f52695141d8cb0a/magicked_admin/server/managers/server_mapper.py#L49

Throws a ValueError: not enough to unpack (expected 2, got 1)

Changed the index from 7 to 8 on line 48 and from 8 to 9 on line 49 and it appears to be working. Looks like the mutator line being empty doesn't show up in the array throwing off the index when it is there.

Documentation

The code is horribly under documented. All functions and classes need detailed comments.

Recursive use of cursors

database.save_players() Line 122, called by server.write_all_players(), motd_updater.run()
Two players quit between updating motd and writing players messages. Crashed thread.

Username collisions

Should be using steam ID as primary key to avoid collisions. Can be read from the players page.

MOTD type option

%SRC in the motd is replaced by top kills. This should be configurable to show time or dosh too. Configuration option would work okay.

[Linux] Programm not terminating when run in terminal

Hello There!

First of all thank you guys for this awesome bot! I really like it and once you set it up it works like a charm.

But i have one Problem... I can't quit the program.
I'm running it within a Screen Session on my Debian-vServer.
When I terminate the program by pressing Crtl+C

Here is a copy of the terminal-output.

kf2server@vServer:~/magicked_admin$ python3 main.py
INFO: Database for server_one initialised
INFO: Connecting to: 127.0.0.1:22123 (server_one)
INFO: Mapper for server_one initialised
INFO: Server server_one initialised
INFO: Executing script: server_one.init
                start_wc 1 say Hello! I'm ChatBot and here to help you. Type !help so get started :)
                start_tc 180 say Hi! Want to know how you are doing? Typ !me or !help in the chat :)
INFO: Bot on server server_one initialised
INFO: Initialisation complete

ChatBot@server_one: Wave command started.
ChatBot@server_one: Timed command started.
DEBUG: No players
DEBUG: No players
DEBUG: No players
_N0x@server_one: !me
INFO: Writing players
ChatBot@server_one: Stats for _N0x:
Sessions:                       0
Play time:              00:00:00
Deaths:                 0
Kills:                          0
Dosh earned:            0
Dosh spent:             0
Health lost:            0
Dosh this game: 0
Kills this wave:                0
Dosh this wave: 0
_N0x@server_one: !help
ChatBot@server_one: Player commands:
 !me, !dosh, !kills, !server_dosh, !server_kills, !top_dosh, !top_kills, !stats, !info
DEBUG: No players
_N0x@server_one: !info
DEBUG: No players
ChatBot@server_one: I'm a bot for ranked Killing Floor 2 servers. Visit:
github.com/th3-z/kf-magicked-admin/
for information, source code, and credits.
DEBUG: No players
^C
INFO: Terminating...
INFO: Writing players

I took a look at the Python skripts and the last thing that is outputting "INFO: Writing players" is
the method write_all_players in server/server.py

def write_all_players(self, final=False):
   print("INFO: Writing players")
   for player in self.players:
       self.database.save_player(player, final)

because saving player stats works while the program is running i suspect that the error lies within the "final" part in the method save_player in the file database/database.py

        if final:
            now = datetime.datetime.now()
            elapsed_time = now - player.session_start
            seconds = elapsed_time.total_seconds()
            new_time = player.total_time + seconds

            self.cur.execute("UPDATE players SET time_online = ? WHERE username = ?",
                             (new_time, player.username))

But i could not find any thing wrong here. (Still learning pyhton...)

Please let me know if you need any other information!

Thank you

Tim

EDIT:
Just to make sure here are the permissions for the files. It should be no problem to write data to the .sqlite file.

kf2server@vServer:~/magicked_admin$ ls -lsh
insgesamt 92K
4,0K drwxr-xr-x 4 kf2server kf2server 4,0K Apr 10 12:05 chatbot
4,0K drwxr-xr-x 2 kf2server kf2server 4,0K Apr 10 12:03 config
4,0K drwxr-xr-x 3 kf2server kf2server 4,0K Apr 11 11:37 database
 32K -rw-r--r-- 1 kf2server kf2server  32K Apr 10 12:03 icon.ico
4,0K -rw-r--r-- 1 kf2server kf2server  205 Apr 10 12:40 magicked_admin.conf
4,0K -rw-r--r-- 1 kf2server kf2server 2,1K Apr 10 12:46 main.py
4,0K drwxr-xr-x 5 kf2server kf2server 4,0K Apr 10 12:04 server
 20K -rw-r--r-- 1 kf2server kf2server  20K Apr 11 09:26 server_one_db.sqlite
4,0K -rw-r--r-- 1 kf2server kf2server  170 Apr 10 13:32 server_one.init
4,0K -rw-r--r-- 1 kf2server kf2server  224 Apr 10 12:41 server_one.motd
4,0K -rw-r--r-- 1 kf2server kf2server  999 Apr 10 12:03 setup.py
4,0K drwxr-xr-x 3 kf2server kf2server 4,0K Apr 10 12:05 utils

Greeter doesnt work on first player

There is no in-game chat with only 1 player present, so the greeting goes unnoticed. This could be delayed until another player joins or until the game starts.

Greeter command

A greeter command with the joining player's total logins, time, and rank by dosh. An internal command !p_join {name} is already sent to chatbot on player join, it just needs a handler.

time command

command that displays the user's time logged in, session count, and rank by time spent.

Wave number for start_trc

Optional wave number argument for start_trc to run commands when the trader opens on a specific wave.

E.g. !start_trc 2 say wave two trader is open

Dependencies missing in list.

It looks like colorama and termcolor aren't part of the standard library, ran into troubles building until installing those two.

Web-admin Unavailable During Map Changes

Web-admin becomes unavailable to connect to when a new map is loaded, causing Magicked to lose connection to THAT server. Any other active servers in your config will stay connected until they also load a new map.

Player rank up triggers

Easiest way to implement this is probably retrieving the top 100 or so dosh/kill scores on initialisation and comparing them to the online player's scores. Only respond to milestones such as: 100,50,25,15,10,5,4,3,2,1.

Threads printing concurrently

In certain cases multiple threads are trying to print at the same time, e.g. chat logger and server_mapper death message.

No controll over Debug-Level when running from source

Hello!

I got a little problem when running the Bot under linux. This is really not that important but I wanted to just report this. Maybe there is already a way. If so please just let me know.

The problem I'm having is, that I have no control over the logging level when running the program directly on a linux client. It's always in DEBUG mode and outputs all Information. I know i could just change the main.py and be done with it but I guess there has to be a way to pass an argument at the start or add an config file.

If i have the time I'll try to add an argument to the config and change main.py so you can control the debug level with the config file. Maybe this will do the job.

Thanks for the help!

!ticket

Allow players to leave a message e.g. !ticket kf-manor is broken

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.