import boto3 # TODO: Next time I work on this, I should make it serverless with API Gateway and a Lambda. # But, alas, I don't feel like investing much in this since nobody cares about the old version. # This project will be in KTLO until October 24, 2023 at which point I will shut down the Eln1 stats server. from flask import Flask, render_template, request from datetime import datetime app = Flask(__name__) dynamodb = boto3.resource('dynamodb', endpoint_url="https://dynamodb.us-east-1.amazonaws.com") table = dynamodb.Table('eln1_stats') HTTP_X_REAL_IP = "HTTP_X_REAL_IP" WHITELISTED = ["date", "ip", "user_agent", "type", "mod_version", "game_lang", "uuid", "player_name", "cable_factor_multiplier", "cable_resistance_multiplier", "explosions_enabled", "replicators_enabled"] def put_mod_info(client_ip, user_agent): return table.put_item( Item={ "date": datetime.now().isoformat(), "ip": client_ip, "user_agent": user_agent, "type": "modinfo" } ) def put_stat(client_ip, user_agent, data): data["date"] = datetime.now().isoformat() data["ip"] = client_ip data["user_agent"] = user_agent data["type"] = "stats" # Prevents bad stuff, plus limits record sizes on the DB. Using 2K since that should be well above necessary, # but also well below 4K cutoff for using more than 1 RCU/WCU per item. data = {k: v for k, v in data.items() if v not in WHITELISTED or len(v) > 2000} return table.put_item( Item=data ) @app.route('/') def root(): return "Nothing to see here!" @app.route('/modinfo.json') def modinfo(): client_ip = request.remote_addr if HTTP_X_REAL_IP in request.environ: client_ip = request.environ[HTTP_X_REAL_IP] user_agent = request.headers.get("User-Agent") print(put_mod_info(client_ip, user_agent)) return render_template("modinfo.json") @app.route('/stat') def stat(): # Test string for browser # http://127.0.0.1:5000/stat?version=1.2.3&lang=en_us&uuid=5 data = {} client_ip = request.remote_addr if HTTP_X_REAL_IP in request.environ: client_ip = request.environ[HTTP_X_REAL_IP] data["mod_version"] = request.args.get("version") data["game_lang"] = request.args.get("lang") data["uuid"] = request.args.get("uuid") data["player_name"] = request.args.get("name") data["cable_factor_multiplier"] = request.args.get("cableFactor") data["cable_resistance_multiplier"] = request.args.get("cableResistanceMultiplier") data["explosions_enabled"] = request.args.get("explosions") data["replicators_enabled"] = request.args.get("repOn") # Remove fields that are null data = {k: v for k, v in data.items() if v is not None} print(put_stat(client_ip, request.headers.get("User-Agent"), data)) return "" if __name__ == '__main__': app.run()