From 214d15384daf32e382ef2395696f79ad791d2df3 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Wed, 15 Jul 2020 10:09:58 -0500 Subject: [PATCH] remove discord deprecated discord webhook file, remove game log file as it's being moved to new repo --- DiscordWebhook/DiscordWebhook.py | 214 ------------------ DiscordWebhook/DiscordWebhook.pyproj | 99 -------- DiscordWebhook/config.json | 6 - DiscordWebhook/requirements.txt | 7 - GameLogServer/GameLogServer.pyproj | 118 ---------- GameLogServer/GameLogServer/__init__.py | 9 - GameLogServer/GameLogServer/log_reader.py | 118 ---------- GameLogServer/GameLogServer/log_resource.py | 16 -- .../GameLogServer/restart_resource.py | 29 --- GameLogServer/GameLogServer/server.py | 14 -- GameLogServer/requirements.txt | 11 - GameLogServer/runserver.py | 15 -- 12 files changed, 656 deletions(-) delete mode 100644 DiscordWebhook/DiscordWebhook.py delete mode 100644 DiscordWebhook/DiscordWebhook.pyproj delete mode 100644 DiscordWebhook/config.json delete mode 100644 DiscordWebhook/requirements.txt delete mode 100644 GameLogServer/GameLogServer.pyproj delete mode 100644 GameLogServer/GameLogServer/__init__.py delete mode 100644 GameLogServer/GameLogServer/log_reader.py delete mode 100644 GameLogServer/GameLogServer/log_resource.py delete mode 100644 GameLogServer/GameLogServer/restart_resource.py delete mode 100644 GameLogServer/GameLogServer/server.py delete mode 100644 GameLogServer/requirements.txt delete mode 100644 GameLogServer/runserver.py diff --git a/DiscordWebhook/DiscordWebhook.py b/DiscordWebhook/DiscordWebhook.py deleted file mode 100644 index e058b844..00000000 --- a/DiscordWebhook/DiscordWebhook.py +++ /dev/null @@ -1,214 +0,0 @@ -import requests -import time -import json -import collections -import os - -# the following classes model the discord webhook api parameters -class WebhookAuthor(): - def __init__(self, name=None, url=None, icon_url=None): - if name: - self.name = name - if url: - self.url = url - if icon_url: - self.icon_url = icon_url - -class WebhookField(): - def __init__(self, name=None, value=None, inline=False): - if name: - self.name = name - if value: - self.value = value - if inline: - self.inline = inline - -class WebhookEmbed(): - def __init__(self): - self.author = '' - self.title = '' - self.url = '' - self.description = '' - self.color = 0 - self.fields = [] - self.thumbnail = {} - -class WebhookParams(): - def __init__(self, username=None, avatar_url=None, content=None): - self.username = '' - self.avatar_url = '' - self.content = '' - self.embeds = [] - - # quick way to convert all the objects to a nice json object - def to_json(self): - return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True) - -# gets the relative link to a user's profile -def get_client_profile(profile_id): - return u'{}/Client/ProfileAsync/{}'.format(base_url, profile_id) - -def get_client_profile_markdown(client_name, profile_id): - return u'[{}]({})'.format(client_name, get_client_profile(profile_id)) - -#todo: exception handling for opening the file -if os.getenv("DEBUG"): - config_file_name = 'config.dev.json' -else: - config_file_name = 'config.json' - -with open(config_file_name) as json_config_file: - json_config = json.load(json_config_file) - -# this should be an URL to an IP or FQN to an IW4MAdmin instance -# ie http://127.0.0.1 or http://IW4MAdmin.com -base_url = json_config['IW4MAdminUrl'] -end_point = '/api/event' -request_url = base_url + end_point -# this should be the full discord webhook url -# ie https://discordapp.com/api/webhooks// -discord_webhook_notification_url = json_config['DiscordWebhookNotificationUrl'] -discord_webhook_information_url = json_config['DiscordWebhookInformationUrl'] -# this should be the numerical id of the discord group -# 12345678912345678 -notify_role_ids = json_config['NotifyRoleIds'] - -def get_new_events(): - events = [] - response = requests.get(request_url) - data = response.json() - should_notify = False - - for event in data: - # commonly used event info items - event_type = event['eventType']['name'] - server_name = event['ownerEntity']['name'] - - if event['originEntity']: - origin_client_name = event['originEntity']['name'] - origin_client_id = int(event['originEntity']['id']) - - if event['targetEntity']: - target_client_name = event['targetEntity']['name'] or '' - target_client_id = int(event['targetEntity']['id']) or 0 - - webhook_item = WebhookParams() - webhook_item_embed = WebhookEmbed() - - #todo: the following don't need to be generated every time, as it says the same - webhook_item.username = 'IW4MAdmin' - webhook_item.avatar_url = 'https://raidmax.org/IW4MAdmin/img/iw4adminicon-3.png' - webhook_item_embed.color = 31436 - webhook_item_embed.url = base_url - webhook_item_embed.thumbnail = { 'url' : 'https://raidmax.org/IW4MAdmin/img/iw4adminicon-3.png' } - webhook_item.embeds.append(webhook_item_embed) - - # the server should be visible on all event types - server_field = WebhookField('Server', server_name) - webhook_item_embed.fields.append(server_field) - - role_ids_string = '' - for id in notify_role_ids: - role_ids_string += '\r\n<@&{}>\r\n'.format(id) - - if event_type == 'Report': - report_reason = event['extraInfo'] - - report_reason_field = WebhookField('Reason', report_reason) - reported_by_field = WebhookField('By', get_client_profile_markdown(origin_client_name, origin_client_id)) - reported_field = WebhookField('Reported Player',get_client_profile_markdown(target_client_name, target_client_id)) - - # add each fields to the embed - webhook_item_embed.title = 'Player Reported' - webhook_item_embed.fields.append(reported_field) - webhook_item_embed.fields.append(reported_by_field) - webhook_item_embed.fields.append(report_reason_field) - - should_notify = True - - elif event_type == 'Ban': - ban_reason = event['extraInfo'] - ban_reason_field = WebhookField('Reason', ban_reason) - banned_by_field = WebhookField('By', get_client_profile_markdown(origin_client_name, origin_client_id)) - banned_field = WebhookField('Banned Player', get_client_profile_markdown(target_client_name, target_client_id)) - - # add each fields to the embed - webhook_item_embed.title = 'Player Banned' - webhook_item_embed.fields.append(banned_field) - webhook_item_embed.fields.append(banned_by_field) - webhook_item_embed.fields.append(ban_reason_field) - - should_notify = True - - elif event_type == 'Connect': - connected_field = WebhookField('Connected Player', get_client_profile_markdown(origin_client_name, origin_client_id)) - webhook_item_embed.title = 'Player Connected' - webhook_item_embed.fields.append(connected_field) - - elif event_type == 'Disconnect': - disconnected_field = WebhookField('Disconnected Player', get_client_profile_markdown(origin_client_name, origin_client_id)) - webhook_item_embed.title = 'Player Disconnected' - webhook_item_embed.fields.append(disconnected_field) - - elif event_type == 'Say': - say_client_field = WebhookField('Player', get_client_profile_markdown(origin_client_name, origin_client_id)) - message_field = WebhookField('Message', event['extraInfo']) - - webhook_item_embed.title = 'Message From Player' - webhook_item_embed.fields.append(say_client_field) - webhook_item_embed.fields.append(message_field) - - #if event_type == 'ScriptKill' or event_type == 'Kill': - # kill_str = '{} killed {}'.format(get_client_profile_markdown(origin_client_name, origin_client_id), - # get_client_profile_markdown(target_client_name, target_client_id)) - # killed_field = WebhookField('Kill Information', kill_str) - # webhook_item_embed.title = 'Player Killed' - # webhook_item_embed.fields.append(killed_field) - - #todo: handle other events - else: - continue - - #make sure there's at least one group to notify - if len(notify_role_ids) > 0: - # unfortunately only the content can be used to to notify members in groups - #embed content shows the role but doesn't notify - webhook_item.content = role_ids_string - - events.append({'item' : webhook_item, 'notify' : should_notify}) - - return events - -# sends the data to the webhook location -def execute_webhook(data): - for event in data: - event_json = event['item'].to_json() - url = None - - if event['notify']: - url = discord_webhook_notification_url - else: - if len(discord_webhook_information_url) > 0: - url = discord_webhook_information_url - - if url : - response = requests.post(url, - data=event_json, - headers={'Content-type' : 'application/json'}) - -# grabs new events and executes the webhook fo each valid event -def run(): - failed_count = 1 - print('starting polling for events') - while True: - try: - new_events = get_new_events() - execute_webhook(new_events) - except Exception as e: - print('failed to get new events ({})'.format(failed_count)) - print(e) - failed_count += 1 - time.sleep(5) - -if __name__ == "__main__": - run() \ No newline at end of file diff --git a/DiscordWebhook/DiscordWebhook.pyproj b/DiscordWebhook/DiscordWebhook.pyproj deleted file mode 100644 index 1a4c2b85..00000000 --- a/DiscordWebhook/DiscordWebhook.pyproj +++ /dev/null @@ -1,99 +0,0 @@ - - - Debug - 2.0 - 15a81d6e-7502-46ce-8530-0647a380b5f4 - . - DiscordWebhook.py - - - . - . - DiscordWebhook - true - DiscordWebhook - MSBuild|env|$(MSBuildProjectFullPath) - False - Standard Python launcher - False - DEBUG=True - C:\Projects\IW4M-Admin\Publish\WindowsPrerelease\DiscordWebhook - - - true - false - - - true - false - - - true - false - bin\Prerelease\ - - - - - - - env - 3.6 - env (Python 3.6 (64-bit)) - Scripts\python.exe - Scripts\pythonw.exe - PYTHONPATH - X64 - - - - - True - - - True - - - - - - - - - - - - - - True - True - http://localhost - False - - - - - - - CurrentPage - True - False - False - False - - - - - - - - - False - False - - - - - \ No newline at end of file diff --git a/DiscordWebhook/config.json b/DiscordWebhook/config.json deleted file mode 100644 index 4df6c614..00000000 --- a/DiscordWebhook/config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "IW4MAdminUrl": "", - "DiscordWebhookNotificationUrl": "", - "DiscordWebhookInformationUrl": "", - "NotifyRoleIds": [] -} \ No newline at end of file diff --git a/DiscordWebhook/requirements.txt b/DiscordWebhook/requirements.txt deleted file mode 100644 index 938de391..00000000 --- a/DiscordWebhook/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -certifi>=2018.4.16 -chardet>=3.0.4 -idna>=2.7 -pip>=18.0 -requests>=2.19.1 -setuptools>=39.0.1 -urllib3>=1.23 diff --git a/GameLogServer/GameLogServer.pyproj b/GameLogServer/GameLogServer.pyproj deleted file mode 100644 index 3fb824c9..00000000 --- a/GameLogServer/GameLogServer.pyproj +++ /dev/null @@ -1,118 +0,0 @@ - - - - 10.0 - Debug - 2.0 - 42efda12-10d3-4c40-a210-9483520116bc - . - {789894c7-04a9-4a11-a6b5-3f4435165112};{1b580a1a-fdb3-4b32-83e1-6407eb2722e6};{349c5851-65df-11da-9384-00065b846f21};{888888a0-9f3d-457c-b088-3a5042f75d52} - runserver.py - - - . - Standard Python launcher - http://localhost - . - true - GameLogServer - GameLogServer - MSBuild|game_log_server_env|$(MSBuildProjectFullPath) - False - DEBUG=True - - - true - false - - - true - false - - - true - false - bin\Prerelease\ - - - - Code - - - - Code - - - - - - - - - - - - - - env - 3.6 - env (Python 3.6 (64-bit)) - Scripts\python.exe - Scripts\pythonw.exe - PYTHONPATH - X64 - - - game_log_server_env - 3.8 - game_log_server_env (Python 3.8 (64-bit)) - Scripts\python.exe - Scripts\pythonw.exe - PYTHONPATH - X64 - - - - - - - - - - - - - - - - True - True - http://localhost - False - - - - - - - CurrentPage - True - False - False - False - - - - - - - - - False - False - - - - - \ No newline at end of file diff --git a/GameLogServer/GameLogServer/__init__.py b/GameLogServer/GameLogServer/__init__.py deleted file mode 100644 index ff2c60f1..00000000 --- a/GameLogServer/GameLogServer/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -""" -The flask application package. -""" - -from flask import Flask -from flask_restful import Api - -app = Flask(__name__) -api = Api(app) \ No newline at end of file diff --git a/GameLogServer/GameLogServer/log_reader.py b/GameLogServer/GameLogServer/log_reader.py deleted file mode 100644 index 0026b8b5..00000000 --- a/GameLogServer/GameLogServer/log_reader.py +++ /dev/null @@ -1,118 +0,0 @@ -import re -import os -import time -import random -import string - -class LogReader(object): - def __init__(self): - self.log_file_sizes = {} - # (if the time between checks is greater, ignore ) - in seconds - self.max_file_time_change = 30 - - def read_file(self, path, retrieval_key): - # this removes old entries that are no longer valid - try: - self._clear_old_logs() - except Exception as e: - print('could not clear old logs') - print(e) - - if os.name != 'nt': - path = re.sub(r'^[A-Z]\:', '', path) - path = re.sub(r'\\+', '/', path) - - # prevent traversing directories - if re.search('r^.+\.\.\\.+$', path): - return self._generate_bad_response() - - # must be a valid log path and log file - if not re.search(r'^.+[\\|\/](.+)[\\|\/].+.log$', path): - return self._generate_bad_response() - - # get the new file size - new_file_size = self.file_length(path) - - # the log size was unable to be read (probably the wrong path) - if new_file_size < 0: - return self._generate_bad_response() - - next_retrieval_key = self._generate_key() - - # this is the first time the key has been requested, so we need to the next one - if retrieval_key not in self.log_file_sizes or int(time.time() - self.log_file_sizes[retrieval_key]['read']) > self.max_file_time_change: - print('retrieval key "%s" does not exist or is outdated' % retrieval_key) - last_log_info = { - 'size' : new_file_size, - 'previous_key' : None - } - else: - last_log_info = self.log_file_sizes[retrieval_key] - - print('next key is %s' % next_retrieval_key) - expired_key = last_log_info['previous_key'] - print('expired key is %s' % expired_key) - - # grab the previous value - last_size = last_log_info['size'] - file_size_difference = new_file_size - last_size - - #print('generating info for next key %s' % next_retrieval_key) - - # update the new size - self.log_file_sizes[next_retrieval_key] = { - 'size' : new_file_size, - 'read': time.time(), - 'next_key': next_retrieval_key, - 'previous_key': retrieval_key - } - - if expired_key in self.log_file_sizes: - print('deleting expired key %s' % expired_key) - del self.log_file_sizes[expired_key] - - #print('reading %i bytes starting at %i' % (file_size_difference, last_size)) - - new_log_content = self.get_file_lines(path, last_size, file_size_difference) - return { - 'content': new_log_content, - 'next_key': next_retrieval_key - } - - def get_file_lines(self, path, start_position, length_to_read): - try: - file_handle = open(path, 'rb') - file_handle.seek(start_position) - file_data = file_handle.read(length_to_read) - file_handle.close() - # using ignore errors omits the pesky 0xb2 bytes we're reading in for some reason - return file_data.decode('utf-8', errors='ignore') - except Exception as e: - print('could not read the log file at {0}, wanted to read {1} bytes'.format(path, length_to_read)) - print(e) - return False - - def _clear_old_logs(self): - expired_logs = [path for path in self.log_file_sizes if int(time.time() - self.log_file_sizes[path]['read']) > self.max_file_time_change] - for key in expired_logs: - print('removing expired log with key {0}'.format(key)) - del self.log_file_sizes[key] - - def _generate_bad_response(self): - return { - 'content': None, - 'next_key': None - } - - def _generate_key(self): - return ''.join(random.choices(string.ascii_uppercase + string.digits, k=8)) - - def file_length(self, path): - try: - return os.stat(path).st_size - except Exception as e: - print('could not get the size of the log file at {0}'.format(path)) - print(e) - return -1 - -reader = LogReader() diff --git a/GameLogServer/GameLogServer/log_resource.py b/GameLogServer/GameLogServer/log_resource.py deleted file mode 100644 index b7d5d620..00000000 --- a/GameLogServer/GameLogServer/log_resource.py +++ /dev/null @@ -1,16 +0,0 @@ -from flask_restful import Resource -from GameLogServer.log_reader import reader -from base64 import urlsafe_b64decode - -class LogResource(Resource): - def get(self, path, retrieval_key): - path = urlsafe_b64decode(path).decode('utf-8') - log_info = reader.read_file(path, retrieval_key) - content = log_info['content'] - - return { - 'success' : content is not None, - 'length': 0 if content is None else len(content), - 'data': content, - 'next_key': log_info['next_key'] - } diff --git a/GameLogServer/GameLogServer/restart_resource.py b/GameLogServer/GameLogServer/restart_resource.py deleted file mode 100644 index 3b955c87..00000000 --- a/GameLogServer/GameLogServer/restart_resource.py +++ /dev/null @@ -1,29 +0,0 @@ -#from flask_restful import Resource -#from flask import request -#import requests -#import os -#import subprocess -#import re - -#def get_pid_of_server_windows(port): -# process = subprocess.Popen('netstat -aon', shell=True, stdout=subprocess.PIPE) -# output = process.communicate()[0] -# matches = re.search(' *(UDP) +([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}):'+ str(port) + ' +[^\w]*([0-9]+)', output.decode('utf-8')) -# if matches is not None: -# return matches.group(3) -# else: -# return 0 - -#class RestartResource(Resource): -# def get(self): -# try: -# response = requests.get('http://' + request.remote_addr + ':1624/api/restartapproved') -# if response.status_code == 200: -# pid = get_pid_of_server_windows(response.json()['port']) -# subprocess.check_output("Taskkill /PID %s /F" % pid) -# else: -# return {}, 400 -# except Exception as e: -# print(e) -# return {}, 500 -# return {}, 200 diff --git a/GameLogServer/GameLogServer/server.py b/GameLogServer/GameLogServer/server.py deleted file mode 100644 index 9fde829c..00000000 --- a/GameLogServer/GameLogServer/server.py +++ /dev/null @@ -1,14 +0,0 @@ -from flask import Flask -from flask_restful import Api -from .log_resource import LogResource -#from .restart_resource import RestartResource -import logging - -app = Flask(__name__) - -def init(): - log = logging.getLogger('werkzeug') - log.setLevel(logging.ERROR) - api = Api(app) - api.add_resource(LogResource, '/log//') - #api.add_resource(RestartResource, '/restart') diff --git a/GameLogServer/requirements.txt b/GameLogServer/requirements.txt deleted file mode 100644 index 8aadf7bc..00000000 --- a/GameLogServer/requirements.txt +++ /dev/null @@ -1,11 +0,0 @@ -aniso8601==8.0.0 -click==7.1.2 -Flask==1.1.2 -itsdangerous==1.1.0 -Jinja2==2.11.2 -MarkupSafe==1.1.1 -pip==20.1 -pytz==2020.1 -setuptools==46.4.0 -six==1.14.0 -Werkzeug==1.0.1 diff --git a/GameLogServer/runserver.py b/GameLogServer/runserver.py deleted file mode 100644 index f5e31453..00000000 --- a/GameLogServer/runserver.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -This script runs the GameLogServer application using a development server. -""" - -from os import environ -from GameLogServer.server import app, init - -if __name__ == '__main__': - HOST = environ.get('SERVER_HOST', '0.0.0.0') - try: - PORT = int(environ.get('SERVER_PORT', '1625')) - except ValueError: - PORT = 5555 - init() - app.run('0.0.0.0', PORT, debug=False)