Python script I made for our clans Knife and pistol server we ran for BF3.
Since we are no longer running the server right now, I decided I would put it up here.
create an admins.txt file with a single in game admin on each line. They will have ingame admin.
Again, this is a Knife and Pistol rule set, you can modified it to your liking to with other weapons sets.
This is no longer in development, and as such, I probably wont update it for a while.
Also, this is kinda advanced
#!/usr/bin/python
#
### BF3 Admin Rcon script
### version 0.1.6 (BETA)
### Author: Imrac
###
### Heavily Modified EA CommandConsole.py script
###
### Weapon Restriction Kicker
### In Game Admin
from struct import *
import md5
import socket
import sys
import shlex
import string
import threading
import os
import time
import Queue
import re
import random
import ast
###############################################################################
# Packet encoding/decoding helper functions
def EncodeHeader(isFromServer, isResponse, sequence):
header = sequence & 0x3fffffff
if isFromServer:
header += 0x80000000
if isResponse:
header += 0x40000000
return pack('<I', header)
def DecodeHeader(data):
[header] = unpack('<I', data[0 : 4])
return [header & 0x80000000, header & 0x40000000, header & 0x3fffffff]
def EncodeInt32(size):
return pack('<I', size)
def DecodeInt32(data):
return unpack('<I', data[0 : 4])[0]
def EncodeWords(words):
size = 0
encodedWords = ''
for word in words:
strWord = str(word)
encodedWords += EncodeInt32(len(strWord))
encodedWords += strWord
encodedWords += '\x00'
size += len(strWord) + 5
return size, encodedWords
def DecodeWords(size, data):
numWords = DecodeInt32(data[0:])
words = []
offset = 0
while offset < size:
wordLen = DecodeInt32(data[offset : offset + 4])
word = data[offset + 4 : offset + 4 + wordLen]
words.append(word)
offset += wordLen + 5
return words
def EncodePacket(isFromServer, isResponse, sequence, words):
encodedHeader = EncodeHeader(isFromServer, isResponse, sequence)
encodedNumWords = EncodeInt32(len(words))
[wordsSize, encodedWords] = EncodeWords(words)
encodedSize = EncodeInt32(wordsSize + 12)
return encodedHeader + encodedSize + encodedNumWords + encodedWords
# Decode a request or response packet
# Return format is:
# [isFromServer, isResponse, sequence, words]
# where
# isFromServer = the command in this command/response packet pair originated on the server
# isResponse = True if this is a response, False otherwise
# sequence = sequence number
# words = list of words
def DecodePacket(data):
[isFromServer, isResponse, sequence] = DecodeHeader(data)
wordsSize = DecodeInt32(data[4:8]) - 12
words = DecodeWords(wordsSize, data[12:])
return [isFromServer, isResponse, sequence, words]
###############################################################################
# Encode a request packet
def EncodeClientRequest(words,clientSequenceNr):
packet = EncodePacket(False, False, clientSequenceNr, words)
clientSequenceNr = (clientSequenceNr + 1) & 0x3fffffff
return [packet, clientSequenceNr]
# Encode a response packet
def EncodeClientResponse(sequence, words):
return EncodePacket(True, True, sequence, words)
###################################################################################
# Display contents of packet in user-friendly format, useful for debugging purposes
def printPacket(packet):
if (packet[0]):
print "IsFromServer, ",
else:
print "IsFromClient, ",
if (packet[1]):
print "Response, ",
else:
print "Request, ",
print "Sequence: " + str(packet[2]),
if packet[3]:
print " Words:",
for word in packet[3]:
print "\"" + word + "\"",
print ""
def printRawPacket(rawpacket):
printPacket(DecodePacket(rawpacket))
###################################################################################
def generatePasswordHash(salt, password):
m = md5.new()
m.update(salt)
m.update(password)
return string.upper(m.hexdigest())
###################################################################################
def containsCompletePacket(data):
if len(data) < 8:
return False
if len(data) < DecodeInt32(data[4:8]):
return False
return True
# Wait until the local receive buffer contains a full packet (appending data from the network socket),
# then split receive buffer into first packet and remaining buffer data
def responseOK(response):
try:
if response[0] == "OK":
return True
else:
return False
except (IndexError, TypeError):
return False
###################################################################################
#
class rconError(Exception):
def __init__(self,args):
self.args = args
def __str__(self):
return repr(self.args)
class rconBF3(object):
def __init__(self,name,ip,port,password,disconnectEvent):
import logging
# setup our logger
self.logger = logging.getLogger('rconBF3-%s:%d' % (ip, port))
self.hdlr = logging.FileHandler('%s-%s-%d.log' % (name,ip,port))
self.formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
self.hdlr.setFormatter(self.formatter)
self.logger.addHandler(self.hdlr)
self.logger.setLevel(logging.INFO)
self.logger.info('************* Initializing *************')
# Set Name/ip/portpassword
self.name = name
self.ip = ip
self.port = port
self.password = password
# Set our event to wait for a response from our request
self.responseWait = threading.Event()
self.disconnectEvent = disconnectEvent
self.returnedResponse = None
# Set our Run flag to true
self.running = True
""" ------------- MAIN method ----------------"""
# Clean Up the Object and Connections
def disconnect(self,exceptions=[]):
try:
self.running = False
self.eventHandler.join()
self.receiver.join()
self.sendHandler.join()
self.serverSock.close()
'[%s] %s Socket Closed' % (self.name,time.asctime())
except RuntimeError, detail:
if str(detail) == 'cannot join current thread':
pass
else:
raise
except AttributeError:
pass
if len(exceptions) > 0:
raise rconError(exceptions)
self.logger.info('Disconnected')
self.logger.removeHandler(self.hdlr)
def connect(self):
try:
# Connect to
print '[%s] %s Connecting to Server. (%s:%d)' % (self.name,time.asctime(),self.ip,self.port)
self.logger.info('Connecting to Server %s:%d' % (self.ip,self.port))
self.serverSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.serverSock.connect( (self.ip, self.port) )
self.serverSock.setblocking(1)
#Set Our Sequence Number
self.clientSequenceNr = 0
#setup request queue
print '[%s] %s Loading Queue.' % (self.name,time.asctime())
self.inside_queue = Queue.Queue()
#start event thread
print '[%s] %s Starting Event Handler.' % (self.name,time.asctime())
self.eventHandler = eventHandler(self)
self.eventHandler.start()
#start socket reader
print '[%s] %s Starting Socket Reciver' % (self.name,time.asctime())
self.receiver = receivePacket(self)
self.receiver.start()
#start our send handler
print '[%s] %s Starting recieve Reciver' % (self.name,time.asctime())
self.sendHandler = sendHandler(self)
self.sendHandler.start()
# Try and Login
#send Login Request
print '[%s] %s Sending Login Request.' % (self.name,time.asctime())
response = self.sendRequest(['login.hashed'])
if not responseOK(response):
self.logger.error('Server Doesn\'t know login command, aborting.')
print '[%s] %s Server Doesn\'t know login command, aborting.' % (self.name,time.asctime())
raise rconError(['Connect Failed','Bad Login Response'])
# Has our password
print '[%s] %s Sending Password' % (self.name,time.asctime())
salt = response[1].decode('hex')
passwordHash = generatePasswordHash(salt, self.password)
#send login request
checkpassword = self.sendRequest(['login.hashed',passwordHash])
if not responseOK(checkpassword):
self.logger.error('Bad Password, aborting connect')
print '[%s] %s Bad Password Returning!' % (self.name,time.asctime())
raise rconError(['Connect Failed','Bad Password'])
eventsEnabled = self.sendRequest(['admin.eventsEnabled','true'])
if not responseOK(eventsEnabled):
self.logger.error('Couldn\'t start events, aborting connect')
print '[%s] %s Coulnd\'t Start Events!' % (self.name,time.asctime())
raise rconError(['Connect Failed','Events Failed'])
print '[%s] %s Events Sucessfully Enabled' % (self.name,time.asctime())
# Throw Exceptions
except socket.error:
self.logger.error('sock.error when connecting')
raise rconError(['sock.error','When Connecting'])
else:
return True
def sendRequest(self,words):
waiting = threading.Event()
self.sendHandler.sendQueue.put([waiting,words])
while self.running:
didWait = waiting.wait(.5)
if (didWait):
response = self.returnedResponse[1]
waiting.clear()
self.responseWait.set()
return response
else:
continue
def sendCommand(self,command,*args):
response = self.sendRequest([command] + args)
return responseOK(response), response
def sendResponse(self,sequence,words):
# Send our reponse to server after getting request
# usually used to send 'OK'
try:
packet = EncodeClientResponse(sequence,words)
self.serverSock.send(packet)
except (socket.error):
raise rconError(['sock.error','sendRepsonse'])
def registerEvent(self,event,callBack):
# set event name and function and give it too the reciver block
print '[%s] %s Regsitering Event %s' % (self.name,time.asctime(),event)
self.logger.info('Registering Event %s to call %s' % (event,str(callBack)) )
self.receiver.registeredEvent[event] = callBack
""" ------------- END MAIN Methods ----------------"""
""" ------------- Admin Methods --------------------"""
def getPlayerList(self,subplayers):
response = self.sendRequest(['admin.listPlayers'] + subplayers.split())
if responseOK(response):
n = int(response[1])
attributes = response[2: 2 + n]
unSplitPlayer = response[3 + n:]
players = [ ]
offset = 0
for i in range(0,len(unSplitPlayer),n):
player = unSplitPlayer[i:i+n]
playerAtr = {}
for x in range(len(attributes)):
playerAtr[attributes[x]] = player[x]
players += [playerAtr]
return True, players
else:
return False, response
def getBanList(self):
response = self.sendRequest(['banList.list'])
banList = []
if responseOK(response):
numOfBans = len(response)
if numOfBans == '0':
pass
else:
for i in range(1,numOfBans,6):
banList += [response[i:i+6]]
return True, banList
else:
return False, response
def adminMove(self,offender,teamId,squadId='0',forcekill='false'):
self.logger.info('adminMove: %s' % (offender))
response = self.sendRequest(['admin.movePlayer',offender,teamId,squadId,forcekill])
return responseOK(response), response
# kick a player
def adminKick(self,offender,reason=''):
self.logger.info('adminKick: %s - %s' % (offender,reason))
response = self.sendRequest(['admin.kickPlayer',offender,reason])
return responseOK(response), response
#kill player
def adminKill(self,offender):
self.logger.info('adminKill: %s' % (offender))
response = self.sendRequest(['admin.killPlayer',offender])
return responseOK(response), response
# temp ban a player by seconds
def adminTBan(self,offender,banTime,reason=''):
self.logger.info('adminTban: %s Until: %s GMT - %s' % (offender,time.asctime(time.gmtime(time.time() + banTime)),reason))
response = self.sendRequest(['banList.add','name',offender,'seconds', banTime,reason])
if responseOK(response):
response = self.sendRequest(['banList.save'])
return responseOK(response), response
else:
return False, response
# perm ban a player
def adminBan(self,offender,reason=''):
self.logger.info('adminBan: %s Perm - %s' % (offender,reason))
response = self.sendRequest(['banList.add','name',offender,'perm',reason])
if responseOK(response):
response = self.sendRequest(['banList.save'])
return responseOK(response), response
else:
return False, response
# chat to the server
def adminSay(self,target,string):
response = self.sendRequest(['admin.Say',string,target])
return responseOK(response), response
class receivePacket(threading.Thread):
def __init__(self,mainClass):
threading.Thread.__init__(self)
# Set our Variables
self.mainClass = mainClass
self.serverSock = mainClass.serverSock
# queue
self.outside_queue = mainClass.inside_queue
# event
self.responseWait = mainClass.responseWait
# Change our timeout
self.serverSock.settimeout(0.5)
# sync running
# setup our dict for events
self.registeredEvent = {}
def run(self):
receiveBuffer = ''
# Make sure we are still allowed to run
while self.mainClass.running:
# make sure we have total packet
while not containsCompletePacket(receiveBuffer) and self.mainClass.running:
try:
receiveBuffer += self.serverSock.recv(4096)
except socket.timeout:
continue
except IOError:
self.mainClass.disconnect()
except:
raise
if self.mainClass.running is False:
break
packetSize = DecodeInt32(receiveBuffer[4:8])
packet = receiveBuffer[0:packetSize]
receiveBuffer = receiveBuffer[packetSize:len(receiveBuffer)]
#printRawPacket(packet)
# decode the packet
[isFromServer, isResponse, sequence, words] = DecodePacket(packet)
# now we have total packet and decoded it reset the receiveBuffer
if isFromServer:
if (isResponse):
#unexpected response from server... Ignoring
pass
else:
self.mainClass.sendResponse(sequence,['OK'])
#fire events
if words[0] == 'player.onChat':
if words[1] != 'Server':
self.logger.info('Chat: %s Said - %s' % (words[1],words[2]))
if words[0] in self.registeredEvent:
self.outside_queue.put([ self.registeredEvent[words[0]], words[1:]])
else:
if (isResponse):
#pass response to our request thread
self.mainClass.returnedResponse = [sequence, words]
self.responseWait.set()
else:
# unexpected request from client??... Ignoring
pass
print '[%s] %s recivePacket Thread Stopped' % (self.mainClass.name,time.asctime())
return
# Stop ourselfs from going out of control!
def stop(self):
self.mainClass.running = False
self.join()
class eventHandler(threading.Thread):
def __init__(self,mainClass):
threading.Thread.__init__(self)
self.mainClass = mainClass
self.out_queue = mainClass.inside_queue
def run(self):
# Make sure we can still run!
while self.mainClass.running:
# Try to get stuff from queue
try:
q = self.out_queue.get(True,0.5)
# Queue timed out, continue gracefully
except Queue.Empty:
continue
try:
# run the function in queue
func = q[0]
args = q[1]
func(*args)
# Take task out of queue
self.out_queue.task_done()
except rconError, details:
self.mainClass.disconnect()
#except:
#self.mainClass.disconnect()
print '[%s] %s eventHandler Thread Stopped' % (self.mainClass.name,time.asctime())
return
def stop(self):
self.mainClass.running = False
self.join()
class sendHandler(threading.Thread):
def __init__(self,mainClass):
threading.Thread.__init__(self)
self.mainClass = mainClass
self.sendQueue = Queue.Queue()
self.clientSequenceNr = 0
def run(self):
# While our main thread is running
while self.mainClass.running:
#Try to get queue, time out after .5 seconds to fail gracefully
try:
q = self.sendQueue.get(True,0.5)
except Queue.Empty:
continue
# Set our respondBack event and words
respondBack = q[0]
words = q[1]
try:
#Encode and send our packet!
packet, self.clientSequenceNr = EncodeClientRequest(words,self.clientSequenceNr)
self.mainClass.returnedResponse = None
#printRawPacket(packet)
sent = self.mainClass.serverSock.send(packet)
# Loop while we haven't received the packet and that we are still running
while self.mainClass.running and self.mainClass.returnedResponse is None:
# Set Timeout period on wait to gracefully stop
eventFired = self.mainClass.responseWait.wait(0.5)
if (eventFired):
# We got our repsonse, lets do something about it
self.mainClass.responseWait.clear()
responseNum = self.mainClass.returnedResponse[0] + 1
# Make sure the sequence number is the same as what we sent
if responseNum == self.clientSequenceNr:
respondBack.set()
while not self.mainClass.responseWait.wait(0.5) and self.mainClass.running:
pass
self.mainClass.responseWait.clear()
break
# if its less, our squence is out of wack.. but continue to wait for next response
elif responseNum < self.clientSequenceNr:
continue
else:
# We received a response larger then our current client sequence number
self.mainClass.logger.error('sock.error Sequence Recoved > Sequence Sent')
raise rconError(['socket.error','Sequence recived > sequence sent'])
self.sendQueue.task_done()
else:
continue
# Throw Exceptions
except socket.error:
raise rconError(['sock.error','sendRequest'])
print '[%s] %s sendHandler Thread Stopped' % (self.mainClass.name,time.asctime())
return
def stop(self):
self.mainClass.running = False
self.join()
""" --------------------------------------------------------------------------------------------------------- """
""" Example Program """
class knifeAndPistol(object):
def __init__(self,name,ip,port,password):
self.name = name
self.ip = ip
self.port = port
self.password = password
self.adminList = { }
self.weaponTypes = { }
self.tBanTime = 604800
try:
self.adminFile = open('admins.txt', 'r')
for admin in self.adminFile:
self.adminList[admin.rstrip()] = { }
except IOError:
print '[MainThread] %s Unabled To Load admin.txt File!' % time.asctime()
pass
#setup our Main Running Thread
self.running = True
self.offenderList = { }
self.weaponTypes = {
'knife':[ 'Damagearea', 'Suicide', 'Death', 'Melee', 'Weapons/Knife/Knife', 'Repair Tool', 'Medkit', 'RoadKill', 'Defib', 'SoldierCollision' ],
'pistol':[ 'Weapons/MP443/MP443', 'M93R', 'Glock18', 'Taurus .44', 'M1911', 'M9','Weapons/MP412Rex/MP412REX' ],
'shotgun':[ '870MCS', 'Siaga20k', 'USAS-12', 'DAO-12', 'M1014' ],
'sniper':[ 'Mk11', 'SVD', 'M40A5', 'SV98', 'Model98B', 'M39', 'SKS' ],
'rocket':[ 'RPG-7', 'SMAW', 'FGM-148', 'FIM92', 'Weapons/Sa18IGLA/Sa18IGLA' ],
#explosive':[ 'M67', 'Weapons/Gadgets/C4/C4', 'M320']
}
# Main loop
while self.running:
try:
self.disconnectEvent = threading.Event()
self.myBF3Server = None
self.myBF3Server = rconBF3(self.name,self.ip,self.port,self.password,self.disconnectEvent)
self.myBF3Server.connect()
self.ruleStatus = True
self.weaponRestriction = 'knife pistol'
self.myBF3Server.registerEvent('player.onKill',self.eventPlayerKill)
self.myBF3Server.registerEvent('player.onChat',self.eventPlayerChat)
self.myBF3Server.registerEvent('server.onLevelLoaded',self.eventLevelLoaded)
self.roundCount = 0
self.startTime = time.time()
#creat our timers
self.timers = [
#[ offset, interval, [function,args], optional:count],
[10,300,[self.updBanList]],
[0,60,[self.spamMessage,'roundtype']],
[5,60,[self.spamMessage,'rule 1']],
[10,60,[self.spamMessage,'rule 2']],
[15,60,[self.spamMessage,'rule 3']],
[20,60,[self.spamMessage,'rule 4']],
[25,60,[self.spamMessage,'recruit']],
]
# set our offsets
for i in self.timers:
i[0] = i[0] + self.startTime
# Waiting Loop
while self.myBF3Server.running:
finished = self.disconnectEvent.wait(1.0)
if (finished):
self.disconnectEvent.clear()
continue
else:
for i in self.timers:
offset = i[0]
interval = i[1]
curtime = time.time()
if round(curtime - offset,0) % interval == 0:
func = i[2][0]
args = i[2][1:]
func(*args)
if 4 in i:
i[4] -= 1
if i[4] < 1:
del i
# Shut down gracefully on keyboard interupt
except KeyboardInterrupt:
self.myBF3Server.disconnect()
self.running = False
break
# if we got a rconError that has to do with the socket closing, start new iteration of main loop, else raise
except rconError, detail:
print '[MainThread] %s Socket Error, attempting to reconnect in 10 seconds.' % time.asctime()
self.myBF3Server.disconnect()
del self.myBF3Server
time.sleep(10)
continue
except:
self.myBF3Server.disconnect()
raise
print '[MainThread] %s connection closed, attempting to reconnect in 10 seconds.' % time.asctime()
time.sleep(10)
# update our local ban text file
def updBanList(self):
[isTrue, banList] = self.myBF3Server.getBanList()
if isTrue:
f = open('banlist_%s-%s.txt' % (self.ip,self.port),'w')
f.write('%-20s %-34s %s\n' % ('PlayerName','Banned Until','Reason'))
for ban in banList:
if ban[2] == 'seconds':
banType = '%s GMT' % time.asctime(time.gmtime(time.time() + int(ban[3])))
else:
banType = ban[2]
f.write('%-20s %-34s %s\n' % (ban[1],banType,ban[5]))
f.close()
return
# Our Spam Function that has dynamic changes
def spamMessage(self,message):
if message == 'roundtype':
if self.ruleStatus:
if self.weaponRestriction == 'knife pistol' or self.weaponRestriction == 'pistol knife':
say = '***Current Round Type: %s***' % self.weaponRestriction
else:
say = '!!!!!BONUS ROUND: %s!!!!!' % self.weaponRestriction
else:
say = '***No Weapon Restrictions!***'
elif message == 'time':
say = 'Current Time: %s' % time.asctime()
elif message == 'rule 1':
say = 'Rule 1: No Tactlights OR Lasers (Press T to Turn OFF)'
elif message == 'rule 2':
say = 'Rule 2: RU Gets Flag A, US Gets Flag C, Fight For B'
elif message == 'rule 3':
say = 'Rule 3: US Do NOT Pass the Turnstiles (Gates) at B'
elif message == 'rule 4':
say = 'Rule 4: RU Do NOT Go Down Escaltors OR Second Set of Stairs'
elif message == 'recruit':
say = '***We are Recruiting Mature Players. www.TexasGaming.org***'
else:
return
self.myBF3Server.adminSay('all',say)
# weapon list helper function, parses weapon type to concatinate a weapnonlist
def getWeaponList(self,weaponType):
x = weaponType.split()
if 'knife' not in x:
x += ['knife']
result = []
for i in x:
if i in self.weaponTypes:
result += self.weaponTypes[i]
return result
# Kicking tracker that kicks 3 times and temp bans the fourth
def myKicker(self,playerSubSet,reason,admin='AutoKicker',tban=False,ban=False):
# If the offender is not in our list yet, add some default values
offender = playerSubSet['name']
if offender not in self.offenderList:
self.offenderList[offender] = { 'count':0, 'time':0 }
# local vars
count = self.offenderList[offender]['count']
expiretime = time.time() - 86400
# reset count after 24 hours of non-abuse
if self.offenderList[offender]['time'] < expiretime:
count = 0
reason = '%s (count #%d)[%s]' % (reason, count + 1,admin)
if count < 2 and not tban and not ban:
self.myBF3Server.adminSay('all','Kicking %s for %s' % (offender,reason))
print '[%s] %s Kicking %s for %s' % (self.myBF3Server.name,time.asctime(),offender,reason)
result = self.myBF3Server.adminKick(offender,reason)
elif not ban:
self.myBF3Server.adminSay('all','TBan (1 Week) %s for %s' % (offender,reason))
print '[%s] %s TBaning (1 Week) %s for %s' % (self.myBF3Server.name,time.asctime(),offender,reason)
result = self.myBF3Server.adminTBan(offender,self.tBanTime,reason)
else:
self.myBF3Server.adminSay('all','Permanently Banning %s for %s' % (offender,reason))
print '[%s] %s Permanently Banning %s for %s' % (self.myBF3Server.name,time.asctime(),offender,reason)
result = self.myBF3Server.adminBan(offender,reason)
self.offenderList[offender]['count'] += 1
self.offenderList[offender]['time'] = time.time()
#return result
def verifyPlayer(self,searchStr,who,outCommand):
isTrue, players = self.playerSearch('all',searchStr)
if len(players) > 0:
replacedOutCommand = [ ]
for i in outCommand:
if i is None:
i = players[0]
replacedOutCommand += [i]
name = players[0]['name']
if len(players) > 1:
self.myBF3Server.adminSay('all','Did you mean %s?' % players[0]['name'])
self.adminList[who]['yes/no'] = replacedOutCommand
elif len(players) == 1:
percentOfName = len(searchStr) / len(players[0]['name'])
if (percentOfName > 0.33) and (len(searchStr) > 3):
func = replacedOutCommand[0]
args = replacedOutCommand[1:]
func(*args)
if 'yes/no' in self.adminList[who]:
del self.adminList[who]['yes/no']
else:
self.myBF3Server.adminSay('all','Did you mean %s?' % players[0]['name'])
self.adminList[who]['yes/no'] = replacedOutCommand
else:
self.myBF3Server.adminSay('all','No Matches Found for: %s' % searchStr)
def playerSearch(self,playerSubSet,searchStr):
isTrue, players = self.myBF3Server.getPlayerList(playerSubSet)
if players is False:
return False, []
prog = re.compile(re.escape(searchStr),re.I)
result = []
for i in players:
if prog.search(i['name']):
result += [i]
return True, result
def teamSwitch(self,playerSubSet,forcekill='false'):
player = playerSubSet['name']
if playerSubSet['teamId'] == '1':
newTeam = 2
else:
newTeam = 1
self.myBF3Server.adminMove(player,newTeam,'0',forcekill)
def nukePlayers(self,playerSubSet='all'):
isTrue, players = self.myBF3Server.getPlayerList(playerSubSet)
if players is False:
return False, []
for i in players:
self.myBF3Server.adminKill(i['name'])
def setBonusRound(self,newRoundType):
self.weaponRestriction = newRoundType
self.myBF3Server.adminSay('all','Setting Current Round To: %s' % newRoundType)
return
def killPlayer(self,playerFull,reason='[No Reason Given]'):
self.myBF3Server.adminSay('all','Killing %s for %s' % (playerFull['name'],reason))
self.myBF3Server.adminKill(playerFull['name'])
# --------------------------------- EVENTS -----------------------------------------------------------------------------------------
# our Kill Event,
def eventPlayerKill(self,killingPlayer,kiledPlayer,weapon,headshot):
#check to make sure we have a killing player and our weapon restriction is on
if killingPlayer != '' and self.ruleStatus:
okWeapons = self.getWeaponList(self.weaponRestriction)
# check if the weapon they used is not in our Accept list
if weapon not in okWeapons:
self.myKicker({'name':killingPlayer},'Using %s During %s Round' % (weapon.split('/')[-1],self.weaponRestriction))
return
def eventLevelLoaded(self, *args):
self.roundCount += 1
if self.roundCount % 3 == 0:
roundType = random.choice(self.weaponTypes.keys())
if roundType == 'knife':
roundType = 'knife'
else:
roundType = 'knife pistol %s' % roundType
else:
roundType = 'knife pistol'
self.setBonusRound(roundType)
self.ruleStatus = True
def eventPlayerChat(self,who,message):
match = re.match('/?([$])([^ ]+) ?(.*)$',message,re.I)
if who in self.adminList and match:
prefix = match.group(1)
inCommand = match.group(2).lower()
parameters = match.group(3)
if inCommand == 'bounds':
if len(parameters) > 0:
outCommand = [self.myKicker, None, 'Being Out of Bounds!',who]
self.verifyPlayer(parameters,who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %sbounds <playername>' % prefix)
elif inCommand == 'tact':
if len(parameters) > 0:
outCommand = [self.myKicker, None, 'Using a Tact Light!',who]
self.verifyPlayer(parameters,who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %stact <playername>' % prefix)
elif inCommand == 'laser':
if len(parameters) > 0:
outCommand = [self.myKicker, None, 'Using a Laser!',who]
self.verifyPlayer(parameters,who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %stact <playername>' % prefix)
elif inCommand == 'weapon':
if len(parameters) > 0:
outCommand = [self.myKicker, None, 'Using an Illegal Weapon!',who]
self.verifyPlayer(parameters,who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %sweapon <playername>' % prefix)
elif inCommand == 'disrupt':
if len(parameters) > 0:
outCommand = [self.myKicker, None, 'Disruptive GamePlay!',who]
self.verifyPlayer(parameters,who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %sdisrupt <playername>' % prefix)
elif inCommand == 'move':
if len(parameters) > 0:
outCommand = [self.teamSwitch,None]
self.verifyPlayer(parameters,who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %smove <playername>' % prefix)
elif inCommand == 'fmove':
if len(parameters) > 0:
outCommand = [self.teamSwitch,None,'true']
self.verifyPlayer(parameters,who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %sfmove <playername>' % prefix)
elif inCommand == 'kick':
if len(parameters) > 0:
player = parameters.split()
if len(player) == 1:
reason = '[No Reason Given]'
else:
reason = ' '.join(player[1:])
outCommand = [self.myKicker, None, reason,who]
self.verifyPlayer(player[0],who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %skick <playername> [reason]' % prefix)
elif inCommand == 'tban':
if len(parameters) > 0:
player = parameters.split()
if len(player) == 1:
reason = '[No Reason Given]'
else:
reason = ' '.join(player[1:])
outCommand = [self.myKicker, None, reason,who,True]
self.verifyPlayer(player[0],who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %stban <playername> [reason]' % prefix)
elif inCommand == 'ban':
if len(parameters) > 0:
player = parameters.split()
if len(player) == 1:
reason = '[No Reason Given]'
else:
reason = ' '.join(player[1:])
outCommand = [self.myKicker, None, reason,who,False,True]
self.verifyPlayer(player[0],who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %sban <playername> [reason]' % prefix)
elif inCommand == 'nuke':
if len(parameters) == 0:
self.myBF3Server.adminSay('all','Are you Sure you want to nuke the entire Server?')
self.adminList[who]['yes/no'] = [self.nukePlayers]
else:
if parameters.lower() == 'us':
self.myBF3Server.adminSay('all','Are you Sure you want to nuke the US Team?')
self.adminList[who]['yes/no'] = [self.nukePlayers, 'team 1']
elif parameters.lower() == 'ru':
self.myBF3Server.adminSay('all','Are you Sure you want to nuke the RU Team?')
self.adminList[who]['yes/no'] = [self.nukePlayers, 'team 2']
else:
self.myBF3Server.adminSay('all','Invalid Team. Valid Teams: US or RU')
elif inCommand == 'kill':
if len(parameters) > 0:
player = parameters.split()
if len(player) == 1:
reason = '[No Reason Given]'
else:
reason = ' '.join(player[1:])
outCommand = [self.killPlayer, None,reason]
self.verifyPlayer(player[0],who,outCommand)
else:
self.myBF3Server.adminSay('all','Usage %skill <playername> [reason]' % prefix)
elif inCommand == 'bonus':
if parameters == '':
self.myBF3Server.adminSay('all','Bonus Types: %s' % ', '.join(self.weaponTypes))
else:
x = parameters.lower()
x = x.split()
if 'knife' not in x:
x += ['knife']
result = []
for i in x:
if i in self.weaponTypes:
result += [i]
result = ' '.join(result)
self.myBF3Server.adminSay('all','Set Bonus Round to %s?' % result)
self.adminList[who]['yes/no'] = [self.setBonusRound,result]
elif inCommand == 'restrict':
if parameters == 'on':
if self.ruleStatus:
self.myBF3Server.adminSay('all','Weapon Restriction is Already On!')
else:
self.ruleStatus = True
self.myBF3Server.adminSay('all','Turning Weapon Retriction On!')
self.spamMessage('roundtype')
else:
if self.ruleStatus:
self.ruleStatus = False
self.myBF3Server.adminSay('all','Turning Weapon Retriction Off!')
else:
self.myBF3Server.adminSay('all','Weapon Restriction is Already Off!')
elif inCommand == 'say':
if len(parameters) > 0:
self.myBF3Server.adminSay('all',parameters)
else:
self.myBF3Server.adminSay('all','Usage %ssay <something>' % prefix)
elif inCommand == 'yes':
if 'yes/no' in self.adminList[who]:
func = self.adminList[who]['yes/no'][0]
args = self.adminList[who]['yes/no'][1:]
func(*args)
del self.adminList[who]['yes/no']
elif inCommand == 'no':
if 'yes/no' in self.adminList[who]:
del self.adminList[who]['yes/no']
elif inCommand == 'updbanlist':
self.updBanList()
self.myBF3Server.adminSay('all','BanList Updated!')
else:
return
else:
return
if __name__ == '__main__':
knpServer = knifeAndPistol('knp-64','xxxxxxxxx', 25200,'xxxxxxx')