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()

Recommended Answers

All 4 Replies

You could simply change the password in the script and then run main() again.

You could simply change the password in the script and then run main() again.

Well that wouldn't really be any different than running each one, one at a time than I currently do......

So you want each program to run on it's own pipe? As long as you're in a *nix environment use fork()

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.