2015-01-03 02:58:09 +00:00
|
|
|
import socket
|
|
|
|
import time
|
|
|
|
import traceback
|
|
|
|
|
2015-03-16 02:55:13 +00:00
|
|
|
class LogEvent:
|
|
|
|
def __init__(self):
|
|
|
|
self.type = None
|
|
|
|
self.killerinfo = None
|
|
|
|
self.victiminfo = None
|
|
|
|
self.weaponinfo = None
|
|
|
|
|
|
|
|
class Player:
|
|
|
|
def __init__(self, name=""):
|
|
|
|
self.name = name
|
|
|
|
self.kills = 0
|
|
|
|
self.deaths = 0
|
|
|
|
self.objectives = 0
|
|
|
|
self.events = []
|
|
|
|
self.status = None
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return "%s :|: %d kills, %d deaths, %d objectives :|: Status=%s" % (self.name, self.kills, self.deaths, self.objectives, self.status)
|
2015-01-03 02:58:09 +00:00
|
|
|
|
|
|
|
class RCONRelay:
|
|
|
|
def __init__(self):
|
2015-03-16 02:55:13 +00:00
|
|
|
self.whitelist = ["joined team", "disconnected", "say", "killed", "suicide", "changed name", "flagevent", "flag."]
|
2015-01-03 02:58:09 +00:00
|
|
|
self.blacklist = ["say_team"]
|
|
|
|
self.weaponmap = {
|
|
|
|
"tf_projectile_rocket": "Rocket Launcher",
|
|
|
|
"tf_projectile_pipe_remote": "Sticky Bomb",
|
2015-03-16 02:55:13 +00:00
|
|
|
"tf_projectile_pipe": "Grenade Launcher",
|
2015-01-03 02:58:09 +00:00
|
|
|
"obj_sentrygun": "Sentry lvl 1",
|
|
|
|
"obj_sentrygun2": "Sentry lvl 2",
|
|
|
|
"obj_sentrygun3": "Sentry lvl 3",
|
|
|
|
"shotgun_pyro": "Shotgun",
|
|
|
|
"shotgun_soldier": "Shotgun",
|
2015-01-14 04:43:49 +00:00
|
|
|
"shotgun_primary": "Shotgun",
|
2015-03-16 02:55:13 +00:00
|
|
|
"club": "Kukri",
|
|
|
|
"pistol_scout": "Pistol",
|
|
|
|
"world": "World Hazard"
|
2015-01-03 02:58:09 +00:00
|
|
|
}
|
|
|
|
|
2015-01-14 04:43:49 +00:00
|
|
|
self.ip = "0.0.0.0"
|
2015-01-03 02:58:09 +00:00
|
|
|
self.port = 32768
|
2015-03-16 02:55:13 +00:00
|
|
|
self.players = []
|
2015-01-03 02:58:09 +00:00
|
|
|
|
|
|
|
def start(self):
|
|
|
|
self.rcon = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
|
|
#self.rcon.settimeout(60)
|
|
|
|
self.rcon.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
|
|
|
self.rcon.bind((self.ip, self.port))
|
|
|
|
print("Listening...")
|
|
|
|
while True:
|
|
|
|
chatdata = self.rcon.recvfrom(1024)
|
|
|
|
#print(chatdata)
|
2015-03-16 02:55:13 +00:00
|
|
|
chatdata = chatdata[0]
|
|
|
|
chatdata = chatdata.decode('utf-8', 'ignore')
|
|
|
|
chatdata = chatdata[3:-2]
|
|
|
|
self.parsechat(chatdata)
|
2015-01-03 02:58:09 +00:00
|
|
|
|
2015-03-16 02:55:13 +00:00
|
|
|
def parsechat(self, chat):
|
|
|
|
timestamp = chat.split(': ')[0]
|
|
|
|
quotesplit = chat.split('"')
|
2015-01-03 02:58:09 +00:00
|
|
|
if "killed" in chat:
|
|
|
|
killerinfo = quotesplit[1]
|
|
|
|
victiminfo = quotesplit[3]
|
|
|
|
weaponinfo = quotesplit[5]
|
|
|
|
weaponinfo = self.weaponmap.get(weaponinfo, weaponinfo)
|
|
|
|
misc = '"'.join(quotesplit[6:])
|
|
|
|
headshot = True if "(customkill \"headshot\")" in misc else False
|
|
|
|
chat = "%s] %s killed %s with %s" % (timestamp, killerinfo, victiminfo, weaponinfo)
|
|
|
|
if headshot:
|
|
|
|
chat += " (Headshot)"
|
|
|
|
|
2015-03-16 02:55:13 +00:00
|
|
|
elif "flagevent" in chat:
|
|
|
|
killerinfo = quotesplit[1]
|
|
|
|
flagevent = quotesplit[5]
|
|
|
|
if flagevent == 'captured':
|
|
|
|
capscurrent = quotesplit[7]
|
|
|
|
capstotal = quotesplit[9]
|
|
|
|
chat = "%s] %s %s flag. %s / %s" % (timestamp, killerinfo, flagevent, capscurrent, capstotal)
|
|
|
|
else:
|
|
|
|
chat = "%s] %s %s flag." % (timestamp, killerinfo, flagevent)
|
|
|
|
|
2015-01-03 02:58:09 +00:00
|
|
|
elif "committed suicide with \"world\" (attacker_position" in chat:
|
|
|
|
victiminfo = quotesplit[1]
|
|
|
|
chat = "%s] %s committed suicide" % (timestamp, victiminfo)
|
|
|
|
|
|
|
|
if any(white.lower() in chat.lower() for white in self.whitelist):
|
2015-03-16 02:55:13 +00:00
|
|
|
if not any(black.lower() in chat.lower() for black in self.blacklist):
|
2015-01-03 02:58:09 +00:00
|
|
|
print(chat)
|
|
|
|
|
2015-03-16 02:55:13 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
rcon = RCONRelay()
|
|
|
|
rcon.start()
|