Esempio n. 1
0
def unblacklist_player(request):
    data = _get_data(request)
    res = {}
    try:
        remove_player_from_blacklist(data["steam_id_64"])
        audit("unblacklist", request, data)
        if get_config()["BANS"]["unblacklist_does_unban"]:
            ctl.do_unban(data["steam_id_64"])  # also remove bans
            if get_config()["MULTI_SERVERS"]["broadcast_unbans"]:
                forward_command(
                    "/api/do_unban",
                    json=data,
                    sessionid=request.COOKIES.get("sessionid"),
                )
        failed = False
    except:
        logger.exception("Unable to unblacklist player")
        failed = True

    return JsonResponse({
        "result": res,
        "command": "unblacklist_player",
        "arguments": data,
        "failed": failed,
    })
Esempio n. 2
0
def unban(request):
    data = _get_data(request)
    res = {}
    results = None

    try:
        ctl.do_unban(data["steam_id_64"])  # also remove bans
        audit("unban", request, data)
        if get_config()["MULTI_SERVERS"]["broadcast_unbans"]:
            results = forward_command(
                "/api/do_unban",
                json=data,
                sessionid=request.COOKIES.get("sessionid"))
        if get_config()["BANS"]["unban_does_unblacklist"]:
            try:
                remove_player_from_blacklist(data["steam_id_64"])
            except CommandFailedError:
                logger.warning("Player %s was not on blacklist",
                               data["steam_id_64"])
        failed = False
    except:
        logger.exception("Unable to unban player")
        failed = True

    return JsonResponse({
        "result": res,
        "command": "unban_player",
        "arguments": data,
        "failed": failed,
        "forward_results": results,
    })
Esempio n. 3
0
def live_scoreboard(request):
    stats = LiveStats()
    config = get_config()

    try:
        result = stats.get_cached_stats()
        result = {
            "snapshot_timestamp":
            result["snapshot_timestamp"],
            "refresh_interval_sec":
            config.get('LIVE_STATS', {}).get('refresh_stats_seconds', 30),
            "stats":
            list(result["stats"].values()),
        }
        error = (None, )
        failed = False
    except Exception as e:
        logger.exception("Unable to produce live stats")
        result = {}
        error = ""
        failed = True

    return api_response(result=result,
                        error=error,
                        failed=failed,
                        command="live_scoreboard")
Esempio n. 4
0
def auto_kick(_, log):
    try:
        config = get_config().get('NAME_KICKS')
    except KeyError:
        logger.error("Invalid configuration file, NAME_KICKS key is missing")
        return

    for r in config['regexps']:
        name = log["player"]
        info = recorded_rcon.get_player_info(name)
        try:
            profile = get_player_profile(info["steam_id_64"], 0)
            for f in config.get("whitelist_flags", []):
                if player_has_flag(profile, f):
                    logger.debug(
                        "Not checking nickname validity for whitelisted player %s (%s)",
                        name, info["steam_id_64"])
                    return
        except:
            logger.exception("Unable to check player profile")

        if re.match(r, name):
            logger.info("%s matched player %s", r, name)
            recorded_rcon.do_kick(player=name,
                                  reason=config["reason"],
                                  by="NAME_KICK")
            try:
                send_to_discord_audit(
                    f"`{name}` kicked from regexp `{r}`",
                    by="NAME_KICK",
                    webhookurl=config.get("discord_webhook_url"))
            except Exception:
                logger.error("Unable to send to audit_log")
            return
Esempio n. 5
0
 def from_config(cls, server_number=None):
     server_number = server_number or os.getenv("SERVER_NUMBER")
     config = get_config()
     config = config.get("GTX").get(f"server_{server_number}")
     return cls(
         ip=config["ip"],
         port=config["port"],
         username=config["username"],
         password=config["password"],
     )
Esempio n. 6
0
def live_stats_loop():
    live = LiveStats()
    config = get_config()
    sleep_seconds = config.get("LIVE_STATS", {}).get("refresh_stats_seconds", 30)

    while True:
        try:
            live.set_live_stats()
            logger.debug("Refreshed")
        except Exception:
            logger.exception("Error while producing stats")
        time.sleep(sleep_seconds)
Esempio n. 7
0
    def wrapper(request):
        logger = logging.getLogger("rconweb")
        arguments = {}
        data = {}
        failure = False
        others = None
        error = ""
        data = _get_data(request)

        for pname, param in parameters.items():
            if pname == "by":
                arguments[pname] = request.user.username
            elif param.default != inspect._empty:
                arguments[pname] = data.get(pname, param.default)
            else:
                try:
                    arguments[pname] = data[pname]
                except KeyError:
                    # TODO raise 400
                    raise

        try:
            logger.debug("%s %s", func.__name__, arguments)
            res = func(**arguments)
            audit(func.__name__, request, arguments)
        except CommandFailedError as e:
            failure = True
            error = e.args[0] if e.args else None
            res = None

        response = JsonResponse(
            dict(
                result=res,
                command=func.__name__,
                arguments=data,
                failed=failure,
                error=error,
                forward_results=others,
            ))
        if data.get("forward"):
            if command_name == "do_temp_ban" and not get_config().get(
                    "MULTI_SERVERS", {}).get("broadcast_temp_bans", True):
                logger.debug("Not broadcasting temp ban due to settings")
                return response
            try:
                others = forward_request(request)
            except:
                logger.exception("Unexpected error while forwarding request")
        # logger.debug("%s %s -> %s", func.__name__, arguments, res)
        return response
Esempio n. 8
0
def live_stats_loop():
    live = LiveStats()
    config = get_config()
    last_loop_session = datetime.datetime(year=2020, month=1, day=1)
    last_loop_game = datetime.datetime(year=2020, month=1, day=1)
    live_session_sleep_seconds = config.get("LIVE_STATS",
                                            {}).get("refresh_stats_seconds",
                                                    30)
    live_game_sleep_seconds = config.get("LIVE_STATS", {}).get(
        "refresh_current_game_stats_seconds", 5)
    logger.debug(
        "live_session_sleep_seconds: {}".format(live_session_sleep_seconds))
    logger.debug("live_game_sleep_seconds: {}".format(live_game_sleep_seconds))
    red = get_redis_client()

    while True:
        # Keep track of session and game timers seperately
        last_loop_session_seconds = (datetime.datetime.now() -
                                     last_loop_session).total_seconds()
        last_loop_game_seconds = (datetime.datetime.now() -
                                  last_loop_game).total_seconds()

        if last_loop_session_seconds >= live_session_sleep_seconds:
            last_loop_session = datetime.datetime.now()
            try:
                live.set_live_stats()
                logger.debug("Refreshed set_live_stats")
            except Exception:
                logger.exception("Error while producing stats")

        if last_loop_game_seconds >= live_game_sleep_seconds:
            last_loop_game = datetime.datetime.now()
            try:
                snapshot_ts = datetime.datetime.now().timestamp()
                stats = current_game_stats()
                logger.debug("Refreshed current_game_stats")
                red.set(
                    "LIVE_GAME_STATS",
                    pickle.dumps(
                        dict(snapshot_timestamp=snapshot_ts,
                             stats=list(stats.values()),
                             refresh_interval_sec=live_game_sleep_seconds)),
                )
            except Exception:
                logger.exception("Failed to compute live game stats")

        time.sleep(0.1)
Esempio n. 9
0
def auto_ban_if_tks_right_after_connection(rcon: RecordedRcon, log):
    config = get_config()
    config = config.get("BAN_TK_ON_CONNECT")
    if not config or not config.get("enabled"):
        return

    player_name = log["player"]
    player_steam_id = log["steam_id_64_1"]
    player_profile = None
    vips = {}
    try:
        player_profile = get_player_profile(player_steam_id, 0)
    except:
        logger.exception("Unable to get player profile")
    try:
        vips = set(v['steam_id_64'] for v in rcon.get_vip_ids())
    except:
        logger.exception("Unable to get VIPS")

    last_logs = get_recent_logs(end=500,
                                player_search=player_name,
                                exact_player_match=True)
    logger.debug("Checking TK from %s", player_name)
    author = config.get("author_name", "Automation")
    reason = config.get("message", "No reasons provided")
    discord_msg = config.get("discord_webhook_message", "No message provided")
    webhook = config.get("discord_webhook_url")
    max_time_minute = config.get("max_time_after_connect_minutes", 5)
    excluded_weapons = [w.lower() for w in config.get("exclude_weapons", [])]
    ignore_after_kill = config.get("ignore_tk_after_n_kills", 1)
    ignore_after_death = config.get("ignore_tk_after_n_death", 1)
    whitelist_players = config.get("whitelist_players", {})
    tk_tolerance_count = config.get("teamkill_tolerance_count", 1)

    if player_profile:
        if whitelist_players.get('is_vip') and player_steam_id in vips:
            logger.debug("Not checking player because he's VIP")
            return

        if whitelist_players.get('has_at_least_n_sessions') and player_profile[
                'sessions_count'] >= whitelist_players.get(
                    'has_at_least_n_sessions'):
            logger.debug("Not checking player because he has %s sessions",
                         player_profile['sessions_count'])
            return

        flags = whitelist_players.get('has_flag', [])
        if not isinstance(flags, list):
            flags = [flags]

        for f in flags:
            if player_has_flag(player_profile, f):
                logger.debug("Not checking player because he has flag %s", f)
                return

    last_action_is_connect = False
    last_connect_time = None
    kill_counter = 0
    death_counter = 0
    tk_counter = 0
    for log in reversed(last_logs["logs"]):
        logger.debug(log)

        if log["action"] == "CONNECTED":
            last_action_is_connect = log
            last_connect_time = log["timestamp_ms"]
            kill_counter = 0
            death_counter = 0
            continue
        if log["action"] == "TEAM KILL" and log[
                'player'] == player_name and last_action_is_connect:
            if excluded_weapons and log["weapon"].lower() in excluded_weapons:
                logger.debug(
                    "Not counting TK as offense due to weapon exclusion")
                continue
            if log['timestamp_ms'] - last_connect_time > max_time_minute * 60 * 1000:
                logger.debug(
                    "Not counting TK as offense due to elapsed time exclusion, last connection time %s, tk time %s",
                    datetime.datetime.fromtimestamp(last_connect_time / 1000),
                    datetime.datetime.fromtimestamp(log["timestamp_ms"]))
                continue
            logger.info("Banning player %s for TEAMKILL after connect %s",
                        player_name, log)
            tk_counter += 1
            if tk_counter > tk_tolerance_count:
                rcon.do_perma_ban(
                    player=player_name,
                    reason=reason,
                    by=author,
                )
                send_to_discord_audit(discord_msg.format(player=player_name),
                                      by=author,
                                      webhookurl=webhook)
        elif is_player_death(player_name, log):
            death_counter += 1
            if death_counter >= ignore_after_death:
                last_action_is_connect = False
        elif is_player_kill(player_name, log):
            kill_counter += 1
            if kill_counter >= ignore_after_kill:
                last_action_is_connect = False
Esempio n. 10
0
import time
from logging.config import dictConfig
from sqlite3.dbapi2 import connect
from urllib.parse import urljoin

import discord
import requests
from discord.embeds import Embed
from discord.errors import HTTPException
from requests.exceptions import ConnectionError, RequestException

from rcon.config import get_config

logger = logging.getLogger(__name__)

SERVER_CONFIG = get_config()['SCOREBOT'][f'SERVER_{os.getenv("SERVER_NUMBER")}']
CONFIG = get_config()['SCOREBOT']['COMMON']


STATS_URL = SERVER_CONFIG["STATS_URL"]
INFO_URL = SERVER_CONFIG["INFO_URL"]
SCOREBOARD_PUBLIC_URL = SERVER_CONFIG["SCOREBOARD_PUBLIC_URL"]
SCORBOARD_BASE_PATH = SERVER_CONFIG["SCORBOARD_BASE_PATH"]
PAST_GAMES_URL = SERVER_CONFIG["PAST_GAMES_URL"]
WEBHOOK_URL = SERVER_CONFIG["WEBHOOK_URL"]

ALL_STATS_TEXT = CONFIG["ALL_STATS_TEXT"]
AUTHOR_NAME = CONFIG["AUTHOR_NAME"]
AUTHOR_ICON_URL = CONFIG["AUTHOR_ICON_URL"]
ELAPSED_TIME = CONFIG["ELAPSED_TIME"]
TOP_LIMIT = CONFIG["TOP_LIMIT"]