One of my clan members put together the following script in python. It works great but I have a small problem. I have to have a 2nd copy under another name to take care of our game servers with a different password. Now I know nothing whatsoever about python so I don't know how to do what I want to do with this. Is there a script I can use to run both .py files without having to run each seperately?
For example ./ban.py -n -b 225.225.225.225
which sends the "-n -b 225.225.225.225" to both of the scripts to execute them simultaneously? Or can the following script be rewritten to handle the servers with different passwords? Any help will be truly appreciated and you can reach me at alpha_wolf (at) urtalphaclan (dot) com
#!/usr/bin/python
"""
Python Quake 3 Library
http://misc.slowchop.com/misc/wiki/pyquake3
Copyright (C) 2006-2007 Gerald Kaszuba
pyBan mass rcon banner
http://intertrusion.com/files
Copyright (C) 2008 |ALPHA|SodaPhish
"""
import socket
import re
import sys
import md5
import urllib
from optparse import OptionParser
VERSION = "0.4.0"
rconPass = 'password'
servers = [ '8.9.3.30:27960', '66.55.134.20:27960', '8.12.16.213:27960', '8.6.75.43:27960', '8.6.76.200:27960', '66.55.131.15:27960', '63.209.35.207:27960', '66.55.154.184:27960', '8.9.8.183:27960', '64.154.38.72:27960', '63.209.35.66:27960' ]
class Server:
def __init__( self, ip, rconPass ):
self.ip = ip
self.rconPass = rconPass
self.rcon = PyQuake3( ip, rconPass )
def ban_host( self, banip ):
cmd = "addip %s" % ( banip )
result = self.rcon.rcon( cmd )
return result[-1].rstrip('\n')
def unban_host( self, banip ):
cmd = "removeip %s" % ( banip )
result = self.rcon.rcon( cmd )
return result[-1].rstrip('\n')
def get_ip(self):
return self.ip
def get_rcon( self ):
return self.rconPass
class Player:
def __init__(self, name, frags, ping, address=None, bot=-1):
self.name = name
self.frags = frags
self.ping = ping
self.address = address
self.bot = bot
def __str__(self):
return self.name
def __repr__(self):
return str(self)
class PyQuake3:
packet_prefix = '\xff' * 4
player_reo = re.compile(r'^(\d+) (\d+) "(.*)"')
def __init__(self, server, rcon_password=''):
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.set_server(server)
self.set_rcon_password(rcon_password)
def set_server(self, server):
try:
self.address, self.port = server.split(':')
except:
raise Exception('Server address must be in the format of \
"address:port"')
self.port = int(self.port)
self.s.connect((self.address, self.port))
def get_address(self):
return '%s:%s' % (self.address, self.port)
def set_rcon_password(self, rcon_password):
self.rcon_password = rcon_password
def send_packet(self, data):
self.s.send('%s%s\n' % (self.packet_prefix, data))
def recv(self, timeout=1):
self.s.settimeout(timeout)
try:
return self.s.recv(4096)
except socket.error, e:
raise Exception('Error receiving the packet: %s' % \
e[1])
def command(self, cmd, timeout=1, retries=3):
while retries:
self.send_packet(cmd)
try:
data = self.recv(timeout)
except:
data = None
if data:
return self.parse_packet(data)
retries -= 1
raise Exception('Server response timed out')
def rcon(self, cmd):
r = self.command('rcon "%s" %s' % (self.rcon_password, cmd))
if r[1] == 'No rconpassword set on the server.\n' or r[1] == \
'Bad rconpassword.\n':
raise Exception(r[1][:-1])
return r
def parse_packet(self, data):
if data.find(self.packet_prefix) != 0:
raise Exception('Malformed packet')
first_line_length = data.find('\n')
if first_line_length == -1:
raise Exception('Malformed packet')
response_type = data[len(self.packet_prefix):first_line_length]
response_data = data[first_line_length+1:]
return response_type, response_data
def parse_status(self, data):
split = data[1:].split('\\')
values = dict(zip(split[::2], split[1::2]))
# if there are \n's in one of the values, it's the list of players
for var, val in values.items():
pos = val.find('\n')
if pos == -1:
continue
split = val.split('\n', 1)
values[var] = split[0]
self.parse_players(split[1])
return values
def parse_players(self, data):
self.players = []
for player in data.split('\n'):
if not player:
continue
match = self.player_reo.match(player)
if not match:
print 'couldnt match', player
continue
frags, ping, name = match.groups()
self.players.append(Player(name, frags, ping))
def update(self):
cmd, data = self.command('getstatus')
self.vars = self.parse_status(data)
def rcon_update(self):
cmd, data = self.rcon('status')
lines = data.split('\n')
players = lines[3:]
self.players = []
for p in players:
while p.find(' ') != -1:
p = p.replace(' ', ' ')
while p.find(' ') == 0:
p = p[1:]
if p == '':
continue
p = p.split(' ')
try:
self.players.append(Player(p[3][:-2], p[0], p[1], p[5], p[6]))
except:
# for whatever reason, some shit hit the fan here.
self.players.append( Player( "", "", 'None', "") )
def ban( ip ):
for server in servers:
q = PyQuake3( server, rconPass )
try:
cmd = "addip %s" % ( ip )
print '%s on %s' % ( q.rcon( cmd )[-1].rstrip('\n'), server )
except:
print "couldn\'t addip on %s" % ( server )
def unban( ip ):
for server in servers:
q = PyQuake3( server, rconPass )
try:
cmd = "removeip %s" % ( ip )
print '%s on %s' % ( q.rcon( cmd )[-1].rstrip('\n'), server )
except:
print "couldn\'t removeip on %s" % ( server )
def selfupdate():
# this should be identitical to previous version except now it supports
thisfile = sys.argv[0]
f = open( thisfile, 'r' )
banContents = f.read()
hash = md5.new( banContents )
checksum = hash.hexdigest()
f.close()
mcs = urllib.urlopen( "http://website" )
masterCheckSum = mcs.read()
if checksum.rstrip() != masterCheckSum.rstrip():
retryCount = 5
pyBanHandler = urllib.urlopen( "http://website" )
pyBanContents = pyBanHandler.read()
pyBanHandler.close()
newHash = md5.new( pyBanContents )
while( ( newHash.hexdigest() != masterCheckSum.rstrip() ) and ( retryCount > 0 ) ):
pyBanHandler = urllib.urlopen( "http://website" )
pyBanContents = pyBanHandler.read()
pyBanHandler.close()
newHash = md5.new( pyBanContents )
retryCount = retryCount - 1
if newHash.hexdigest() == masterCheckSum.rstrip():
f = open( thisfile, 'w' )
f.write( pyBanContents )
f.close()
print "I: pyBan has been updated!!! you need to re-run the command for it to work."
else:
print "E: update failed. e-mail email@where.com for help"
sys.exit()
def main():
check = 1
parser = OptionParser()
parser = OptionParser(usage="%prog [OPTIONS] <IP>", version="%prog 0.4.0")
parser.add_option( "-b", "--ban", dest="banip", help="ban <ip>" )
parser.add_option( "-u", "--unban", dest="unbanip", help="unban <ip>" )
parser.add_option( "-c", "--check", action="store_const", const=1, dest="check" )
parser.add_option( "-n", "--nocheck", action="store_const", const=0, dest="check" )
parser.add_option( "-r", "--reason", dest="reason", help="the reason you're banning this IP" )
(options, args) = parser.parse_args()
print "pyBan %s" % ( VERSION )
print "...by |ALPHA|SodaPhish\n"
#if len( args ) == 1:
# this maintains our backward compatibility
#selfupdate()
#ban( args[0] )
if options.check:
# user didn't want to skip software update, so update!!!
selfupdate()
if options.banip:
ban( options.banip )
sys.exit()
if options.unbanip:
unban( options.unbanip )
sys.exit()
if __name__ == '__main__':
main()