def getLevelFromIndex(self, index): decho('dc_ass: entering getLevelFromIndex() method', 5) # make False the default return value returnValue = False # grab their keyhash keyhash = self.getKeyhashFromIndex(index) if keyhash: decho('dc_ass: Attempting to authenticate keyhash: %s' % keyhash, 5) # just in case there is no pbpower.dat file try: # loop through each line looking for their keyhash for line in open('admin/standard_admin/power.dat', 'r'): if keyhash == line.split(' ')[1].strip(): # assign their level userLevel = int(line.split(' ')[0].strip()) decho( 'dc_ass: %s is level %d in power.dat!' % (keyhash, userLevel), 5) break except IOError: decho('dc_ass: unable to open pb/pbpower.dat file', 5) userLevel = None returnValue = (userLevel, keyhash) decho('dc_ass: exiting getLevelFromIndex() method', 5) return returnValue
def getPlayerList(self): decho('dc_ass: entering getPlayerList() method', 5) rawData = host.rcon_invoke('admin.listplayers') # this pattern is for line 0 of the output for each player # pattern1 = re.compile(r'''^Id:\ +(\d+)\ -\ (\S+)\ is\ remote\ ip:\ (\d+\.\d+\.\d+\.\d+):(\d+)''', re.VERBOSE) pattern1 = re.compile( r'''^Id:\ +(\d+)\ -\ (.*?)\ is\ remote\ ip:\ (\d+\.\d+\.\d+\.\d+):(\d+)''', re.VERBOSE) # this pattern is for line 1 of the output for each player pattern2 = re.compile(r'''(?:.*hash:\ (\w{32}))?''', re.VERBOSE) players = {} i = 0 for line in rawData.split("\n"): # if we're looking at a "line 0" if i == 0: matches = pattern1.findall(line) if len(matches) != 0: p_id = int(matches[0][0]) players[p_id] = [] players[p_id].append(matches[0][1]) players[p_id].append(matches[0][2]) players[p_id].append(matches[0][3]) # if we're looking at a "line 1" elif i == 1: matches = pattern2.findall(line) players[p_id].append(matches[0]) # flop the value of the iter i ^= 1 decho('dc_ass: exiting getPlayerList() method', 5) return players
def tacticalSwitchTeam(admin): splitArgs = admin.splitArguments(admin.command.arguments) splitArgsLen = len(splitArgs) if splitArgsLen == 1: roundNum = int(splitArgs[0]) if roundNum == 1: host.rcon_invoke('admin.restartmap'); host.rcon_invoke('sv.startDelay 900'); elif roundNum == 2: host.rcon_invoke('admin.restartmap'); host.rcon_invoke('sv.startDelay 300'); admin.command.arguments = '@' switchTeam(admin) elif roundNum == 3: host.rcon_invoke('admin.restartmap'); host.rcon_invoke('sv.startDelay 600'); elif roundNum == 4: host.rcon_invoke('admin.restartmap'); host.rcon_invoke('sv.startDelay 300'); admin.command.arguments = '@' switchTeam(admin) else: decho('dc_ass: Argument must be a valid tactical round number', 1) else: decho('dc_ass: Number of arguments for !tst is 1', 1)
def tacticalSwitchTeam(admin): splitArgs = admin.splitArguments(admin.command.arguments) splitArgsLen = len(splitArgs) if splitArgsLen == 1: roundNum = int(splitArgs[0]) if roundNum == 1: host.rcon_invoke('admin.restartmap'); host.rcon_invoke('sv.startDelay 900'); elif roundNum == 2: host.rcon_invoke('admin.restartmap'); host.rcon_invoke('sv.startDelay 300'); admin.command.arguments = '@' switchTeam(admin) elif roundNum == 3: host.rcon_invoke('admin.restartmap'); host.rcon_invoke('sv.startDelay 600'); elif roundNum == 4: host.rcon_invoke('admin.restartmap'); host.rcon_invoke('sv.startDelay 300'); admin.command.arguments = '@' switchTeam(admin) else: decho('dc_ass: Argument must be a valid tactical round number', 1) else: decho('dc_ass: Number of arguments for !tst is 1', 1)
def execKick(self): decho('dc_ass: entering execKick() method', 5) if self.prepExec(): # make a victim list if self.getVictimIDs(self.command.arguments): self.processPoints() else: decho('dc_ass: Victim ID not findable given the arguments', 2)
def onPlayerDisconnect(self, p): decho('dc_ass: entering onPlayerDisconnect() method', 5) # if they disconnect, which might have happened if they were kicked, drop them from the tracker, if they're even in it if self.victimTracker.has_key(p.index): del (self.victimTracker[p.index]) decho( 'dc_ass: player %d disconnected and no longer tracked' % p.index, 2)
def clearPoints(admin): admin.getVictimIDs(admin.command.arguments) for vId in admin.victimID: if admin.victimTracker.has_key(vId): admin.victimTracker.pop(vId) # I figure I can say their all cleared even if we're not tracking them... yet decho( "dc_ass: Points for %s have been cleared" % bf2.PlayerManager.Player(vId).getName(), 1 )
def onPlayerDisconnect(p): decho("dc_pop_log: player disconnected", 5) id = p.getProfileId() name = p.getName() ip = p.getAddress() timestamp = time.time() state = "disconnected" writeLogFile(id, name, ip, timestamp, state)
def onPlayerDisconnect(p): decho("dc_pop_log: player disconnected", 5) id = p.getProfileId() name = p.getName() ip = p.getAddress() timestamp = time.time() state = "disconnected" writeLogFile(id, name, ip, timestamp, state)
def writeLogFile(id, name, ip, timestamp, state): decho( "dc_pop_log: writing that %s %s to population_log.in_progress" % (name, state), 3 ) try: fh = open('%s/population_log.in_progress' % dir, 'a') fh.write("%d,\"%s\",%s,%d,%s\n" % (id, name, ip, timestamp, state)) fh.close() except: decho( 'dc_pop_log: unable to write to %s/population_log.in_progress' % dir, 2 )
def writeLogFile(id, name, ip, timestamp, state): decho( "dc_pop_log: writing that %s %s to population_log.in_progress" % (name, state), 3 ) try: fh = open('%s/population_log.in_progress' % dir, 'a') fh.write("%d,\"%s\",%s,%d,%s\n" % (id, name, ip, timestamp, state)) fh.close() except: decho( 'dc_pop_log: unable to write to %s/population_log.in_progress' % dir, 2 )
def clearPoints(admin): admin.getVictimIDs(admin.command.arguments) for vId in admin.victimID: if admin.victimTracker.has_key(vId): admin.victimTracker.pop(vId) # I figure I can say their all cleared even if we're not tracking them... yet decho( "dc_ass: Points for %s have been cleared" % bf2.PlayerManager.Player(vId).getName(), 1 )
def customKick(admin): slicePoint = admin.command.arguments.find(' ') if slicePoint == -1: decho( 'dc_ass: 2 arguments are required for this command', 1 ) else: argVictim = admin.command.arguments[:slicePoint] admin.command.reason = admin.command.arguments[slicePoint + 1:] if admin.getVictimIDs(argVictim): admin.processPoints()
def customKick(admin): slicePoint = admin.command.arguments.find(' ') if slicePoint == -1: decho( 'dc_ass: 2 arguments are required for this command', 1 ) else: argVictim = admin.command.arguments[:slicePoint] admin.command.reason = admin.command.arguments[slicePoint + 1:] if admin.getVictimIDs(argVictim): admin.processPoints()
def stripPrefix(self, text): decho('dc_ass: entering stripPrefix() method', 5) text = text.replace('HUD_TEXT_CHAT_TEAM', '') text = text.replace('HUD_TEXT_CHAT_SQUAD', '') text = text.replace('HUD_CHAT_DEADPREFIX', '') text = text.replace("*\xA71DEAD\xA70*", '') decho('dc_ass: exiting stripPrefix() method', 5) # in later versions of BF2 we sometimes saw extra white space in the # chat text return text.strip()
def execRcon(self): decho('dc_ass: entering execRcon() method', 5) if self.prepExec(): decho('dc_ass: Running rcon command: %s' % self.command.rconString, 2) if self.command.arguments == None: unused = host.rcon_invoke(self.command.rconString) else: unused = host.rcon_invoke(self.command.rconString + ' ' + self.command.arguments)
def getKeyhashFromIndex(self, index): decho('dc_ass: entering getKeyhashFromIndex() method', 5) # make False the default return value returnValue = False # get a list of players connected right now players = self.getPlayerList() # is our index in this list of players? if players.has_key(index): # grab their keyhash returnValue = players[index][3] decho('dc_ass: exiting getKeyhashFromIndex() method', 5) return returnValue
def manageTracker(self, victimID, keyhash, delta, reason): decho('dc_ass: entering manageTracker() method', 5) returnValue = True # if they're not already being tracked... if not self.victimTracker.has_key(victimID): self.victimTracker[victimID] = {} decho('dc_ass: now tracking player: %d' % victimID, 5) # has this keyhash already applied their points? if self.victimTracker[victimID].has_key(keyhash): # apply the delta self.victimTracker[victimID][keyhash]['points'] += delta # if the resulting delta totally removes this keyhash points then delete the keyhash from their tracker if self.victimTracker[victimID][keyhash]['points'] <= 0: del (self.victimTracker[victimID][keyhash]) # if this keyhash HAS NOT already applied their points, only if the delta is > 0 should we even touch the tracker elif delta > 0: self.victimTracker[victimID][keyhash] = { 'points': delta, 'reason': reason } else: decho('dc_ass: no action taken where issuer points <= 0', 2) returnValue = False decho('dc_ass: exiting manageTracker() method', 5) return returnValue
def checkPoints(self): decho('dc_ass: entering checkPoints() method', 5) for index, tracking in self.victimTracker.iteritems(): # reset totalPoints for this victim (as we loop through them) # this variable hold the accumlative value of all points so far applied to a player totalPoints = self.getPointsFromIndex(index) # if we see any of our victims here lets print to the screen that they have new and shiny points if index in self.victimID: decho( 'dc_ass: %s now has %d of %d kick points' % (bf2.PlayerManager.Player(index).getName(), totalPoints, self.kickThreshold), 1) if totalPoints >= self.kickThreshold: # issue the kick command decho( "dc_ass: Kicking player '%s' (%d) %s" % (bf2.PlayerManager.Player(index).getName(), index, self.command.reason), 1) # need to change this to show them ALL the reasons they were kicked unused = host.rcon_invoke( 'pb_sv_kick %d %d %s' % (index + 1, self.command.length, self.command.reason)) decho('dc_ass: exiting checkPoints() method', 5)
def prepExec(self): decho('dc_ass: entering prepExec() method', 5) # set default returnValue returnValue = False # find the issuer's level and keyhash levelAndKeyhash = self.getLevelFromIndex(self.issuer.index) if levelAndKeyhash: # assign the level and keyhash as properties to the issuer object # see if we need to assign the default level for this user if levelAndKeyhash[0] == None: self.issuer.level = self.defaultLevel else: self.issuer.level = levelAndKeyhash[0] self.issuer.keyhash = levelAndKeyhash[1] # is the issuer allowed to run this command? if self.issuer.level >= self.command.level: returnValue = True else: decho( 'dc_ass: %s is not authorized for the requested action' % bf2.PlayerManager.Player(self.issuer.index).getName(), 1) else: decho( 'dc_ass: ERROR failed to get keyhash for player: %s' % bf2.PlayerManager.Player(self.issuer.index).getName(), 1) decho('dc_ass: exiting prepExec() method', 5) return returnValue
def forgiveTK(admin): #Have a victim? if admin.getVictimIDs(admin.command.arguments): #Is the victim in victimTracker? if admin.victimTracker.has_key(admin.victimID[0]): #If so, is the issuer's keyhash in the victim's tracker? if admin.victimTracker[admin.victimID[0]].has_key(admin.issuer.keyhash): #If the reason in the tracker is the same reason we're looking for, adjust points if admin.command.reason == admin.victimTracker[admin.victimID[0]][admin.issuer.keyhash]['reason']: #Adjust points, check them, and escape from the function. if admin.manageTracker(admin.victimID[0], admin.issuer.keyhash, -2, admin.command.reason): decho('ftk 6', 5) admin.checkPoints() return #If any preceding step failed, we have no TK to forgive. decho('dc_ass: No teamkills to forgive for '+bf2.PlayerManager.Player(admin.victimID[0]).getName(), 1)
def checkPoints(self): for index, tracking in self.victim_tracker.iteritems(): # reset total_points for this victim total_points = 0 # added up all the points being applied to this victim for unused_key, points in tracking.iteritems(): total_points += points if index in self.victim_id: decho( "dc_ass: %s now has %d of %d kick points" % (bf2.PlayerManager.Player(index).getName(), total_points, self.kick_threshold), 1 ) if total_points >= self.kick_threshold: self.reason += " - see dontcamp.com/forums for discussion" # issue the kick command decho( "dc_ass: Kicking player '%s' (%d) %s" % (bf2.PlayerManager.Player(index).getName(), index, self.reason), 1 ) unused = host.rcon_invoke('pb_sv_kick %d %d %s' % (index + 1, self.length, self.reason) )
def forgiveTK(admin): #Have a victim? if admin.getVictimIDs(admin.command.arguments): #Is the victim in victimTracker? if admin.victimTracker.has_key(admin.victimID[0]): #If so, is the issuer's keyhash in the victim's tracker? if admin.victimTracker[admin.victimID[0]].has_key(admin.issuer.keyhash): #If the reason in the tracker is the same reason we're looking for, adjust points if admin.command.reason == admin.victimTracker[admin.victimID[0]][admin.issuer.keyhash]['reason']: #Adjust points, check them, and escape from the function. if admin.manageTracker(admin.victimID[0], admin.issuer.keyhash, -2, admin.command.reason): decho('ftk 6', 5) admin.checkPoints() return #If any preceding step failed, we have no TK to forgive. decho('dc_ass: No teamkills to forgive for '+bf2.PlayerManager.Player(admin.victimID[0]).getName(), 1)
def getPointsFromIndex(self, index): decho('dc_ass: entering getPointsFromIndex() method', 5) # set default returnValue returnValue = 0 # is this player index being tracked? if self.victimTracker.has_key(index): # init value for totalPoints totalPoints = 0 for unusedKey, record in admin.victimTracker[index].iteritems(): totalPoints += record['points'] returnValue = totalPoints decho('dc_ass: exiting getPointsFromIndex() method', 5) return returnValue
def switchTeam(admin): admin.getVictimIDs(admin.command.arguments) for vID in admin.victimID: decho('debug 1', 5) p = bf2.PlayerManager.Player(vID) # if they were not in a vehicle if killPlayerAtIndex(vID): decho( '%s is on team %d' % ( p.getName(), p.getTeam() ), 5 ) if p.getTeam() == 1: p.setTeam(2) decho( 'dc_ass: switched %s to team 2' % p.getName(), 1) else: p.setTeam(1) decho( 'dc_ass: switched %s to team 1' % p.getName(), 1) else: decho( 'dc_ass: unable to switch teams for %s' % p.getName(), 1 )
def switchTeam(admin): admin.getVictimIDs(admin.command.arguments) for vID in admin.victimID: decho('debug 1', 5) p = bf2.PlayerManager.Player(vID) # if they were not in a vehicle if killPlayerAtIndex(vID): decho( '%s is on team %d' % ( p.getName(), p.getTeam() ), 5 ) if p.getTeam() == 1: p.setTeam(2) decho( 'dc_ass: switched %s to team 2' % p.getName(), 1) else: p.setTeam(1) decho( 'dc_ass: switched %s to team 1' % p.getName(), 1) else: decho( 'dc_ass: unable to switch teams for %s' % p.getName(), 1 )
def getCommandData(self, command): decho('dc_ass: entering getCommandData() method', 5) # set a default returnValue returnValue = False # read in the commands INI file try: self.config = ConfigParser.ConfigParser() self.config.read('admin/standard_admin/dc_ass_cmds.ini') # is this a defined command in the INI file if command in self.config.sections(): decho('dc_ass: command: %s found in INI file' % command, 5) # define/declare some vars for this admin event # (I really wouldn't need to do this if I know how to check if a var is defined or even exists type = None # the default length for a kick length = 2 rconString = None # default reason, is no reason at all reason = 'No reason given' # this makes all commands default to requiring full admin privs level = self.adminLevel function = None # get all possible options # I could add sanity checks in here for poorly formated lines in the INI file for option in self.config.options(command): if option == 'type': type = self.config.get(command, option).strip() elif option == 'reason': reason = self.config.get(command, option).strip() elif option == 'length': length = int(self.config.get(command, option)) elif option == 'command': rconString = self.config.get(command, option).strip() elif option == 'level': level = int(self.config.get(command, option)) elif option == 'function': function = self.config.get(command, option).strip() returnValue = (type, reason, length, rconString, level, function) else: # end of is command in INI file conditional decho('dc_ass: (ERROR) %s command not found!' % command, 1) except IOError: decho('dc_ass: (FATAL ERROR) could not open dc_ass_cmds.ini', 1) return returnValue
def kill(admin): argReason = None argSpawnTime = None argVictim = None splitArgs = admin.splitArguments(admin.command.arguments) splitArgsLen = len(splitArgs) if splitArgsLen > 2: argReason = splitArgs[2] if splitArgsLen > 1: argSpawnTime = int(splitArgs[1]) if splitArgsLen > 0: argVictim = splitArgs[0] admin.getVictimIDs(argVictim) for vID in admin.victimID: if not killPlayerAtIndex(vID): decho( 'dc_ass: unable to kill %s' % bf2.PlayerManager.Player(vID).getName(), 1 ) else: if argSpawnTime != None: bf2.PlayerManager.Player(vID).setTimeToSpawn(argSpawnTime) if argReason != None: decho( 'dc_ass: %s was killed \'%s\'' % ( bf2.PlayerManager.Player(vID).getName(), argReason ), 1 ) else: decho( 'dc_ass: %s was killed via admin system' % bf2.PlayerManager.Player(vID).getName(), 1 )
def kill(admin): argReason = None argSpawnTime = None argVictim = None splitArgs = admin.splitArguments(admin.command.arguments) splitArgsLen = len(splitArgs) if splitArgsLen > 2: argReason = splitArgs[2] if splitArgsLen > 1: argSpawnTime = int(splitArgs[1]) if splitArgsLen > 0: argVictim = splitArgs[0] admin.getVictimIDs(argVictim) for vID in admin.victimID: if not killPlayerAtIndex(vID): decho( 'dc_ass: unable to kill %s' % bf2.PlayerManager.Player(vID).getName(), 1 ) else: if argSpawnTime != None: bf2.PlayerManager.Player(vID).setTimeToSpawn(argSpawnTime) if argReason != None: decho( 'dc_ass: %s was killed \'%s\'' % ( bf2.PlayerManager.Player(vID).getName(), argReason ), 1 ) else: decho( 'dc_ass: %s was killed via admin system' % bf2.PlayerManager.Player(vID).getName(), 1 )
def addPoints(self): # add entries in the victim_tracker foreach victim for v_id in self.victim_id: # check to see if we're already tracking the joker if self.victim_tracker.has_key(v_id): decho( "dc_ass: already tracking %d" % v_id, 5 ) # check to see if this admin has already applied their weight to the victim if not self.victim_tracker[v_id].has_key(self.keyhash): self.victim_tracker[v_id][self.keyhash] = self.user_weight # added this conditional to make it a bit less noisy when someone is just kicked with one action if self.user_weight < self.kick_threshold: decho( "dc_ass: applied %d points from %s to player %d" % (self.user_weight, self.keyhash, v_id), 5 ) # this elif was really added to deal with an extension used at DontCamp.com but it makes sense to have anyway elif self.user_weight == self.kick_threshold: self.victim_tracker[v_id][self.keyhash] = self.user_weight else: decho( "dc_ass: %s has already applied their points to %s" % (bf2.PlayerManager.Player(self.issuer).getName(), bf2.PlayerManager.Player(v_id).getName()), 1 ) else: self.victim_tracker[v_id] = {} decho( "dc_ass: now tracking player: %d" % v_id, 5 ) self.victim_tracker[v_id][self.keyhash] = self.user_weight decho( "dc_ass: applied %d points from %s to player %d" % (self.user_weight, self.keyhash, v_id), 5 )
def execBan(self): decho('dc_ass: entering execBan() method', 5) if self.prepExec(): # make a victim list if self.getVictimIDs(self.command.arguments): for vID in self.victimID: decho( "dc_ass: Banning player '%s' (%d) %s" % (bf2.PlayerManager.Player(vID).getName(), vID, self.command.reason), 1) unused = host.rcon_invoke('pb_sv_ban %d %s' % (vID + 1, self.command.reason)) else: decho('dc_ass: Victim ID not findable given the arguments', 2)
def execExtension(self): decho('dc_ass: entering execExtension() method', 5) if self.prepExec(): # reload the extensions file reload(dc_ass_extensions) if self.command.function in dc_ass_extensions.__dict__: decho( 'dc_ass: executing %s() extension' % self.command.function, 2) # send the entire ass object to the extensions exec('dc_ass_extensions.%s(%s)' % (self.command.function, 'self')) else: decho( 'dc_ass: %s() extension not found.' % self.command.function, 2)
def onStatusChange(status): decho("dc_pop_log: status handler entered", 5) if status == bf2.GameStatus.EndGame: decho("dc_pop_log: status == EndGame", 5) timestamp = time.time() try: fh_old = open('%s/population_log.in_progress' % dir, 'r+') fh_new = open('%s/population_log.%d.csv' % (dir, timestamp), 'w') for line in fh_old: fh_new.write(line) fh_old.truncate(0) fh_old.close() fh_new.close() except: decho( 'dc_pop_log: there was an error trying to "move" the in progress log', 2 )
def onStatusChange(status): decho("dc_pop_log: status handler entered", 5) if status == bf2.GameStatus.EndGame: decho("dc_pop_log: status == EndGame", 5) timestamp = time.time() try: fh_old = open('%s/population_log.in_progress' % dir, 'r+') fh_new = open('%s/population_log.%d.csv' % (dir, timestamp), 'w') for line in fh_old: fh_new.write(line) fh_old.truncate(0) fh_old.close() fh_new.close() except: decho( 'dc_pop_log: there was an error trying to "move" the in progress log', 2 )
def _getWeight(self, index): return_value = False players = self._getPlayerList() self.user_weight = self.default_weight if players.has_key(index): return_value = True self.keyhash = players[index][3] # assigns the default weight in case this user is not found in the pbpower.dat file decho( "dc_ass: Attempting to authenticate keyhash: %s" % self.keyhash, 5 ) # just in case there is no pbpower.dat file try: for line in open('admin/standard_admin/power.dat', 'r'): if self.keyhash == line.split(' ')[1].strip(): self.user_weight = int(line.split(' ')[0].strip()) decho( "dc_ass: %s is level %d in power.dat!" % (self.keyhash, self.user_weight), 5 ) break except IOError: decho( "dc_ass: unable to open pb/pbpower.dat file", 5 ) return return_value
def setTickets(admin): slicePoint = admin.command.arguments.find(' ') if slicePoint == -1: arg = int(admin.command.arguments) if arg > 999 or arg < 0: decho( 'dc_ass: First argument must be a valid team number or a ticket value for both teams.', 1) return else: bf2.gameLogic.setTickets(1, arg) bf2.gameLogic.setTickets(2, arg) else: argTeam = int(admin.command.arguments[:slicePoint]) argTickets = int(admin.command.arguments[slicePoint + 1:]) if argTeam != 1 and argTeam != 2: decho( 'dc_ass: First argument must be a valid team number or a ticket value for both teams. ', 1) return if argTickets > 999 or argTickets < 0: decho( 'dc_ass: Second argument must be a valid ticket value.', 1) return bf2.gameLogic.setTickets(argTeam, argTickets)
def setTickets(admin): slicePoint = admin.command.arguments.find(' ') if slicePoint == -1: arg = int(admin.command.arguments) if arg > 999 or arg < 0: decho( 'dc_ass: First argument must be a valid team number or a ticket value for both teams.', 1) return else: bf2.gameLogic.setTickets(1, arg) bf2.gameLogic.setTickets(2, arg) else: argTeam = int(admin.command.arguments[:slicePoint]) argTickets = int(admin.command.arguments[slicePoint + 1:]) if argTeam != 1 and argTeam != 2: decho( 'dc_ass: First argument must be a valid team number or a ticket value for both teams. ', 1) return if argTickets > 999 or argTickets < 0: decho( 'dc_ass: Second argument must be a valid ticket value.', 1) return bf2.gameLogic.setTickets(argTeam, argTickets)
def getStatus(admin): # if the issuer is an admin decho('dc_ass: debug 1', 5) if admin.issuer.level == admin.adminLevel: decho('dc_ass: debug 2', 5) # if no argument was given just print the status of the issuer if admin.command.arguments == None: decho('dc_ass: debug 3', 5) decho( "dc_ass: %s has %d of %d kick points" % (bf2.PlayerManager.Player(admin.issuer.index).getName(), admin.getPointsFromIndex(admin.issuer.index), admin.kickThreshold), 1 ) # get victimIDs elif admin.getVictimIDs(admin.command.arguments): decho('dc_ass: debug 4', 5) for vID in admin.victimID: decho('dc_ass: debug 5', 5) decho( 'dc_ass: %s has %d of %d kick points' % (bf2.PlayerManager.Player(vID).getName(), admin.getPointsFromIndex(vID), admin.kickThreshold), 1 ) # if the issuer is NOT an admin else: decho('dc_ass: debug 7', 5) decho( 'dc_ass: %s has %d of %d kick points' % (bf2.PlayerManager.Player(admin.issuer.index).getName(), admin.getPointsFromIndex(admin.issuer.index), admin.kickThreshold), 1 )
def privGetMyKeyhash(admin): host.rcon_feedback( admin.issuer.index, '%s, your keyhash is %s' % (bf2.PlayerManager.Player(admin.issuer.index).getName(), admin.issuer.keyhash) ) decho( 'dc_ass: %s, check your console for your keyhash' % bf2.PlayerManager.Player(admin.issuer.index).getName(), 1 )
def showTime(admin): decho( 'The time is %s' % time.strftime('%H:%M:%S'), 1 )
def setNextMap(admin): # default restltValue result = False argSize = None argGPM = None argName = None # split our args splitArgs = admin.splitArguments(admin.command.arguments) splitArgsLen = len(splitArgs) # this is for future use, right now we just use the argName if splitArgsLen > 2: argSize = splitArgs[2] if splitArgsLen > 1: argGPM = splitArgs[1] if splitArgsLen > 0: argName = splitArgs[0] if argName == None: decho( 'dc_ass: (ERROR) at least one argument is required', 1 ) else: # set a centinal value for id so we know if we've found a map yet id = -1 mapList = admin.getMapList() # search our maplist for mapID, mapData in mapList.iteritems(): if mapData['name'].lower().find( argName.lower() ) != -1: decho( 'dc_ass: %s loosely matches %s' % ( argName, mapData['name'] ), 5 ) # if this is the first map we've found... if id == -1: decho( 'dc_ass: found %s in %s' % ( argName, mapData['name'] ), 5 ) id = mapID result = True # if we've gotten another possible match... else: result = False break if id != -1: if result: decho( 'dc_ass: mapID found @ %d' % id, 5 ) if host.rcon_invoke('admin.nextLevel %d' % id): decho( 'dc_ass: nextmap will be %s' % mapList[id]['name'], 1 ) else: decho( 'dc_ass: (ERROR) failed to set nextmap', 1 ) else: decho( 'dc_ass: %s is ambiguous.' % argName, 1 ) else: decho( 'dc_ass: no maps can be matched to %s' % argName, 1 )
def getMyKeyhash(admin): decho( 'dc_ass: %s, your keyhash is %s' % (bf2.PlayerManager.Player(admin.issuer.index).getName(), admin.issuer.keyhash), 1 )
def init(): decho('dc_pop_log: initializing DontCamp.com Population Logger', 2) host.registerHandler('PlayerConnect', onPlayerConnect, 1) host.registerHandler('PlayerDisconnect', onPlayerDisconnect, 1) host.registerGameStatusHandler(onStatusChange)
def setNextMap(admin): # default restltValue result = False argSize = None argGPM = None argName = None # split our args splitArgs = admin.splitArguments(admin.command.arguments) splitArgsLen = len(splitArgs) # this is for future use, right now we just use the argName if splitArgsLen > 2: argSize = splitArgs[2] if splitArgsLen > 1: argGPM = splitArgs[1] if splitArgsLen > 0: argName = splitArgs[0] if argName == None: decho( 'dc_ass: (ERROR) at least one argument is required', 1 ) else: # set a centinal value for id so we know if we've found a map yet id = -1 mapList = admin.getMapList() # search our maplist for mapID, mapData in mapList.iteritems(): if mapData['name'].lower().find( argName.lower() ) != -1: decho( 'dc_ass: %s loosely matches %s' % ( argName, mapData['name'] ), 5 ) # if this is the first map we've found... if id == -1: decho( 'dc_ass: found %s in %s' % ( argName, mapData['name'] ), 5 ) id = mapID result = True # if we've gotten another possible match... else: result = False break if id != -1: if result: decho( 'dc_ass: mapID found @ %d' % id, 5 ) if host.rcon_invoke('admin.nextLevel %d' % id): decho( 'dc_ass: nextmap will be %s' % mapList[id]['name'], 1 ) else: decho( 'dc_ass: (ERROR) failed to set nextmap', 1 ) else: decho( 'dc_ass: %s is ambiguous.' % argName, 1 ) else: decho( 'dc_ass: no maps can be matched to %s' % argName, 1 )
def onChatMessage(player_id, text, channel, flags): # pull the potential prefix off the text line text = text.replace("HUD_TEXT_CHAT_TEAM", "") text = text.replace("HUD_TEXT_CHAT_SQUAD", "") text = text.replace("*\xA71DEAD\xA70*", "") # unless the first character is ! don't do anything if text[0:1] == "!": decho("dc_irs: the first character of %s was !" % text, 5) # grab the parts of the chatline I need with a REGEX pattern = re.compile(r'!(\w*) ?(.*)') matches = pattern.findall(text) command = matches[0][0] decho("dc_irs: command = %s" % command, 5) # grab a parameter, if any if matches[0][1] != "": parameter = matches[0][1] decho("dc_irs: parameter = %s" % parameter, 5) else: parameter = None decho("dc_irs: no parameter given", 5) if command == "nextmap": decho('The next map is %s' % host.rcon_invoke('maplist.list').splitlines()[int(host.rcon_invoke('admin.nextLevel').strip())].split()[1].strip('"').replace('_', ' ').title(), 1) elif command == "time": decho('The time is: %s' % time.strftime('%H:%M %p %Z'), 1) else: decho('ERROR: invalid command', 1)
def _getVictimId(self, parameter): # returns true/false on success/failure and assigns self.victim_id if possible # self.victim_id is a list of all victims found # sorry for the silly parameter name, but it does make sense in this case. self.victim_id = [] result = False # default value for result decho("dc_ass: Attempting to find victim ID...", 5) # if the parameter is the player number if parameter[0:1] == ".": id = int(parameter[1:]) for p in bf2.playerManager.getPlayers(): if p.index == id: self.victim_id = [id] decho( "dc_ass: parameter was an int, and id = %d" % self.victim_id[0], 5 ) result = True break if not result: decho( "dc_ass: (ERROR) no player found with ID: %d" % id, 1 ) # if the parameter is a wildcard / clantag elif parameter[0:1] == "@": decho( "dc_ass: finding ALL matching players with parameter...", 5 ) decho( "dc_ass: parameter was NOT an int", 5 ) # for all players connected... for p in bf2.playerManager.getPlayers(): decho( "dc_ass: checking player: %s" % p.getName(), 5 ) # if we find a name that loosely matches... if p.getName().lower().find( parameter[1:].lower() ) != -1: decho( "dc_ass: %s loosely matches %s" % ( parameter[1:], p.getName() ), 5 ) self.victim_id.append(p.index) result = True if result: decho( "dc_ass: Victim ID(s) found @ %r" % self.victim_id, 5 ) else: decho( "dc_ass: (ERROR) no players found with %s in their name" % parameter[1:], 1 ) # if the parameter is a team number elif parameter[0:1] == "%": decho( "dc_ass: finding ALL matching players on team matching paramenter...", 5 ) # for all players connected... for p in bf2.playerManager.getPlayers(): decho( "dc_ass: checking player: %s" % p.getName(), 5 ) # if we find a player on the team supplied if p.getTeam() == int(parameter[1:]): decho( "dc_ass: %s is on team %s" % ( p.getName(), p.getTeam() ), 5 ) self.victim_id.append(p.index) result = True if result: decho( "dc_ass: Victim ID(s) found @ %r" % self.victim_id, 5 ) else: decho( "dc_ass: (ERROR) there seems to be no one on team %s" % parameter[1:], 1 ) # if the parameter is a playername or partial playername else: id = -1 decho("dc_ass: parameter was NOT an int", 5) # for all players connected... for p in bf2.playerManager.getPlayers(): decho( "dc_ass: checking player: %s" % p.getName(), 5 ) # if we find a name that loosely matches... if p.getName().lower().find( parameter.lower() ) != -1: decho( "dc_ass: %s loosely matches %s" % ( parameter, p.getName() ), 5 ) # if this is the first victim we've found... if id == -1: decho("dc_ass: found %s in %s" % ( parameter, p.getName() ), 5) id = [int(p.index)] result = True # if we've gotten another possible match... else: result = False break if result: self.victim_id = id decho( "dc_ass: Victim ID found @ %d" % self.victim_id[0], 5 ) else: decho( "dc_ass: %s is ambiguous." % parameter, 1 ) return result
def onChatMessage(self, player_id, text, channel, flags): self.issuer = player_id # pull the potential prefix off the text line text = self._stripPrefix(text) # unless the first character is ! don't do anything if text[0:1] == "!": decho( "dc_ass: the first character of %s was !" % text, 5 ) # As BF2 playernames cannot contain spaces except what is printed # between the prefix and the name, it is probably safe to assume # that we don't need to accept spaces in playernames for this # parameter. Therefore, I could use the space as a separator # between the victim name and another command parameter, like # a custom reason. # grab the parts of the chatline I need with a REGEX pattern = re.compile(r'!(\w*) ?(\S*) ?(.*)') matches = pattern.findall(text) command = matches[0][0] # set an arguments property for future use or for extensions self.arguments = matches[0][2] decho( "dc_ass: command = %s" % command, 5 ) # in case the command doesn't require a victim parameter... if matches[0][1] != "": parameter = matches[0][1] decho( "dc_ass: parameter = %s" % parameter, 5 ) else: parameter = None decho( "dc_ass: no parameter given", 5 ) try: # read in the commands INI file self.config = ConfigParser.ConfigParser() self.config.read('admin/standard_admin/dc_ass_cmds.ini') # is this a defined command in the INI file if command in self.config.sections(): decho( "dc_ass: Command found in INI file!", 5 ) # define/declare some vars for this admin event (I really wouldn't need to do this if I know how to check if a var is defined or even exists type = "" # these values will be members of the object because they may be needed in an extension self.length = 2 # the default length for a kick self.reason = "" admin = 1 # this makes all commands default to requiring admin privs # get all possible options # I could add sanity checks in here for poorly formated lines in the INI file for option in self.config.options(command): if option == "type": type = self.config.get(command, option).strip() elif option == "reason": self.reason = self.config.get(command, option).strip() elif option == "length": self.length = int(self.config.get(command, option)) elif option == "command": rcon_string = self.config.get(command, option).strip() elif option == "admin": admin = int(self.config.get(command, option)) elif option == "function": function = self.config.get(command, option).strip() # make sure we have a type if type == "": decho( "dc_ass: (ERROR) No type value for %s in dc_ass_cmds.ini file!" % command, 1 ) # good, we're all set else: decho( "dc_ass: type: %s" % type, 5 ) # to get their keyhash and admin level if self._getWeight(player_id): # see if we can/need to get a victim ID to move forward if ( parameter != None and self._getVictimId(parameter) ) or parameter == None: # for non-perma bans, change type to kick_ban - this will be useful when we start to log this stuff if type == "ban" and self.length != "": decho( "dc_ass: Length value given for ban. Converting type to kick_ban.", 5 ) type = "kick_ban" # if no parameter was given, make the command reflect on the issuer if parameter == None: decho( "dc_ass: No parameter given... assigning victim_id to issuer.", 5 ) self.victim_id = [player_id] if ( admin and self.user_weight == self.admin_level ) or not admin: # the main switch like section that gets the shit done (if only I had switches) # Are reasons optional in these PB kicks/bans? If so, I guess I don't need to worry about sanity checking them if type == "kick" or type == "kick_ban": self.addPoints() self.checkPoints() elif type == "ban": for v_id in self.victim_id: decho( "dc_ass: Banning player '%s' (%d) %s" % (bf2.PlayerManager.Player(v_id).getName(), v_id, self.reason), 1 ) unused = host.rcon_invoke( 'pb_sv_ban %d %s' % (v_id + 1, self.reason) ) elif type == "rcon": decho( "dc_ass: Running rcon command: %s" % rcon_string, 2 ) unused = host.rcon_invoke( rcon_string ) elif type == "extension": reload( dc_ass_extensions ) if function in dc_ass_extensions.__dict__: decho( "dc_ass: executing %s() extension" % function, 2 ) # send the entire object to the extensions exec( "dc_ass_extensions.%s(%s)" % (function, "self") ) else: decho( "dc_ass: %s() extension not found." % function, 2 ) else: decho( "dc_ass: No such type: %s" % type, 1 ) else: decho ( "dc_ass: User in slot %d is not authorized for the requested action" % player_id, 1 ) else: decho( "dc_ass: Victim ID not findable given the parameter", 2 ) else: decho( "dc_ass: ERROR failed to get keyhash for player: %d" % player_id, 1 ) else: # end of is command in INI file conditional decho( "dc_ass: (ERROR) %s command not found!" % command, 1 ) except IOError: print "dc_ass: (FATAL ERROR) could not open one or more required files: (admin_profile_ids.csv | dc_ass_cmds.ini)" else: # a debug line just so I can see all the chat if I need to decho( "dc_ass: player %d: %s" % (player_id, text), 5 )
def init(): decho('dc_ass: initializing DontCamp.com Admin Support System', 2) host.registerHandler('ChatMessage', admin.onChatMessage, 1) host.registerHandler('PlayerDisconnect', admin.onPlayerDisconnect, 1) showLevel()
def init(): decho('dc_irs: initializing DontCamp.com In-game Report System', 2) host.registerHandler('ChatMessage', onChatMessage, 1)
def onPlayerDisconnect(self, p): # if they disconnect, which might have happened if they were kicked, drop them from the tracker, if they're even in it if self.victim_tracker.has_key(p.index): del(self.victim_tracker[p.index]) decho( "dc_ass: player %d disconnected and no longer tracked" % p.index, 2 )
def showTime(admin): decho( 'The time is %s' % time.strftime('%H:%M:%S'), 1 )
def privGetMyKeyhash(admin): host.rcon_feedback( admin.issuer.index, '%s, your keyhash is %s' % (bf2.PlayerManager.Player(admin.issuer.index).getName(), admin.issuer.keyhash) ) decho( 'dc_ass: %s, check your console for your keyhash' % bf2.PlayerManager.Player(admin.issuer.index).getName(), 1 )
def getStatus(admin): # if the issuer is an admin decho('dc_ass: debug 1', 5) if admin.issuer.level == admin.adminLevel: decho('dc_ass: debug 2', 5) # if no argument was given just print the status of the issuer if admin.command.arguments == None: decho('dc_ass: debug 3', 5) decho( "dc_ass: %s has %d of %d kick points" % (bf2.PlayerManager.Player(admin.issuer.index).getName(), admin.getPointsFromIndex(admin.issuer.index), admin.kickThreshold), 1 ) # get victimIDs elif admin.getVictimIDs(admin.command.arguments): decho('dc_ass: debug 4', 5) for vID in admin.victimID: decho('dc_ass: debug 5', 5) decho( 'dc_ass: %s has %d of %d kick points' % (bf2.PlayerManager.Player(vID).getName(), admin.getPointsFromIndex(vID), admin.kickThreshold), 1 ) # if the issuer is NOT an admin else: decho('dc_ass: debug 7', 5) decho( 'dc_ass: %s has %d of %d kick points' % (bf2.PlayerManager.Player(admin.issuer.index).getName(), admin.getPointsFromIndex(admin.issuer.index), admin.kickThreshold), 1 )
def getMyKeyhash(admin): decho( 'dc_ass: %s, your keyhash is %s' % (bf2.PlayerManager.Player(admin.issuer.index).getName(), admin.issuer.keyhash), 1 )
def sayNextMap(unused=None): #It works. We'll just leave it at that. decho( 'The next map is %s' % (host.rcon_invoke('maplist.list').splitlines()[int(host.rcon_invoke('admin.nextLevel').strip())].split()[1].strip('"').replace('_', ' ').title()), 1 )
def sayNextMap(unused=None): #It works. We'll just leave it at that. decho( 'The next map is %s' % (host.rcon_invoke('maplist.list').splitlines()[int(host.rcon_invoke('admin.nextLevel').strip())].split()[1].strip('"').replace('_', ' ').title()), 1 )