Scripts:IdleKick
Jump to navigation
Jump to search
# ------------------------------------------------------------------------ # Module: IdleKick.py # Authors: xlr8or, www.xlr8or.com # Version 2.02 # Description: # This script kicks players who are idle, based on the configuration settings below. # Requirements: # None. # Installation: # Save this script as 'IdleKick.py' in your <bf2>/admin/standard_admin directory, # and add the lines 'import IdleKick' and 'IdleKick.init()' to the file # '<bf2>/admin/standard_admin/__init__.py'. # Credit: # This script is based on the pingkick script from the guys at bf2.no # Format is mainly the same as what they did, and where I could use their # code I have shamelessly done so. # Credit therefor goes to Kybber and Panic, Battlefield.no # History: # Autobalancing is a nice feature, but not when a large part of your team # is doing something else, while staying ingame to not lose their slot. # BF2 does not have a spectator ability, so if you're not participating, # you're letting your team down! # Version 1.00 to 2.00: # Cleaned some code up, added the ability to exclude clanmembers. # Version 2.00 to 2.01: # Cleaned and corrected some global def's. # Version 2.01 to 2.02: # Fixed the clantag protection. # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # C O N F I G U R A T I O N # ------------------------------------------------------------------------ # Settings for auto-kicking: autokick = 1 # Enables/disables autokicking warnings = 10 # The number of checks/warns a player has to fail/get before being kicked interval = 30 # The interval between idle checks minplayers = 5 # The minimum ammount of players online before checking idle players. announceme = 0 # Announce the module at roundstart? warnme = 1 # Warn the idle player 3 intervals before the maximum nr of warnings is reached? clantags = ["[XLR]","[xlr]","xlr8or"] # Clantags to protect from being kicked # ------------------------------------------------------------------------ # I M P O R T # ------------------------------------------------------------------------ import host import bf2 from bf2 import g_debug # ------------------------------------------------------------------------ # V A R I A B L E S # ------------------------------------------------------------------------ # Let's set up our debug flag: xlr_debug = False # The timers: IkCheckTimer = None # Timer firing off the idle checker. Depends on the 'interval' variable. KickTimer = None # Timer that delays kicking after the final warning has been issued. AnnounceTimer = None # Timer that delays the "activated" message after entering bf2.GameStatus.Playing # List of people to kick for high idle. Will contain touples of p.index and p.getProfileId(): kicklist = [] # For keeping track of the game status: gamestatus = None # ------------------------------------------------------------------------ # F U N C T I O N S # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # The init function is run by the standard_admin/__init__ functions: # ------------------------------------------------------------------------ def init(): if g_debug or xlr_debug: print 'IDLEKICK: initializing IdleKick script' # Force at least 20 seconds between idle checks: if interval < 10: interval = 10 # Print debug message if autokick is disabled: if autokick != 1: if g_debug or xlr_debug: print 'IDLEKICK: Idle autokick not enabled' # Autokick is enabled, so hook it up: else: if g_debug or xlr_debug: print 'IDLEKICK: Enabling kick for being idle. Max. checkfails = %s.' % (warnings) # Register 'PlayerConnect' callback: host.registerHandler('PlayerConnect', onPlayerConnect, 1) host.registerHandler('PlayerSpawn', onPlayerSpawn, 1) host.registerGameStatusHandler(onGameStatusChanged) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Callback function for the "PlayerConnect" event: # ------------------------------------------------------------------------ def onPlayerConnect(p): #Resets the idle warning counter for the player resetPlayer(p) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Callback function for the "PlayerSpawn" event: # ------------------------------------------------------------------------ def onPlayerSpawn(p,s): # Sets the 'actuallyPlaying' flag for the player p.actuallyPlaying = True # We can reset the warnings, since the player has actually spawned. p.idleWarnings = 0 # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Callback function for the "PreGame" game status event: # ------------------------------------------------------------------------ def onGameStatusChanged(status): # Enables the idle check timer # Import variables, and update the game status: global gamestatus, kicklist, AnnounceTimer gamestatus = status if gamestatus == bf2.GameStatus.Playing: if announceme ==1: if g_debug or xlr_debug: print "IDLEKICK: Round Started. Setting AnnounceTimer" AnnounceTimer = bf2.Timer(onAnnounceTimer,10,1) if g_debug or xlr_debug: print "IDLEKICK: Round Started. (Re-)enabling check-timer" # Enable the idle check timer: enableCheckTimer() elif gamestatus == bf2.GameStatus.PreGame: if g_debug or xlr_debug: print "IDLEKICK: Game status changed to PreGame. Killing check-timer" # Kill the check-timer disableCheckTimer() elif gamestatus == bf2.GameStatus.Paused: if g_debug or xlr_debug: print "IDLEKICK: Game status changed to Paused. Killing check-timer" # Kill the check-timer disableCheckTimer() elif gamestatus == bf2.GameStatus.EndGame: if g_debug or xlr_debug: print "IDLEKICK: Game status changed to EndGame. Reset Players, Kicklist and killing check-timer" # Kill the check-timer disableCheckTimer() # Reset the kicklist kicklist = [] # Reset players: resetPlayers() # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Reset the idlescript variables placed in the player object: # ------------------------------------------------------------------------ def resetPlayers(): # Reset Warnings and stuff: if g_debug or xlr_debug: print "IDLEKICK: Resetting Players" for p in bf2.playerManager.getPlayers(): resetPlayer(p) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Reset the idlescript variables placed in the player object: # ------------------------------------------------------------------------ def resetPlayer(p): # Reset Warnings and stuff: p.idleWarnings = 0 p.actuallyPlaying = False # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Callback function for timer, that delays a message at round start: # ------------------------------------------------------------------------ def onAnnounceTimer(data): global AnnounceTimer if g_debug or xlr_debug: print "IDLEKICK: Entering onAnnounceTimer... Sending the Activated announcement" msg = "Activated! Kicking after " + str(warnings) + " checks." sendMsg(msg) AnnounceTimer.destroy() AnnounceTimer = None # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Send text messages to the server, using rcon game.sayAll: # ------------------------------------------------------------------------ def sendMsg(msg): # Sure you can edit this. But hey, why not give us the credit? ;-) host.rcon_invoke("game.sayAll \"[XLR]No-Idle: " + str(msg) + "\"") # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Enable the KickTimer: # ------------------------------------------------------------------------ def enableKickTimer(): # Enables the timer that runs the 'kickPlayers' functions global KickTimer if g_debug or xlr_debug: print "IDLEKICK: Enabling the kicktimer..." KickTimer = bf2.Timer(kickPlayers, 5, 1) # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Enable the IkCheckTimer: # ------------------------------------------------------------------------ def enableCheckTimer(): # Enables the timer that runs the 'checkidle' function global IkCheckTimer if IkCheckTimer: if g_debug or xlr_debug: print "IDLEKICK: IkCheckTimer (already) running: Next check @ %s" % (IkCheckTimer.getTime()) return True else: # Create the timer: if g_debug or xlr_debug: print "IDLEKICK: Timer not enabled. Enabling..." IkCheckTimer = bf2.Timer(checkidle, interval, 1) IkCheckTimer.setRecurring(interval) # Print debug message telling the status of the timer: if IkCheckTimer: if g_debug or xlr_debug: print "IDLEKICK: First check @ %s" % (IkCheckTimer.getTime()) return True else: if g_debug or xlr_debug: print "IDLEKICK: ERROR: IkCheckimer Not enabled in def enableCheckTimer()" return False # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Disable the IkCheckTimer: # ------------------------------------------------------------------------ def disableCheckTimer(): global IkCheckTimer IkCheckTimer.destroy() IkCheckTimer = None # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Loop all players, checking their idle, kick high-idleer: # ------------------------------------------------------------------------ def checkidle(data): # Checks idle of all players, and kicks idlers global kicklist, gamestatus # We only want to check idle during rounds: if gamestatus != bf2.GameStatus.Playing: return # Make sure our timer is enabled: if not enableCheckTimer(): return if bf2.playerManager.getNumberOfPlayers() < minplayers: if g_debug or xlr_debug: print "IDLEKICK: Not enough players to check for idlers..." return if g_debug or xlr_debug: print "IDLEKICK: Running checkidle" # Loop all players for p in bf2.playerManager.getPlayers(): # Do not check players that haven't completed their "connect" yet: if not p.isConnected(): if g_debug or xlr_debug: print "IDLEKICK: Player not yet connected, continuing..." continue if p.isAlive(): if g_debug or xlr_debug: print "IDLEKICK: Player is already playing, continuing..." continue if p.isManDown(): if g_debug or xlr_debug: print "IDLEKICK: Player in ManDown state, continuing..." continue # Get the player name. We'll use it often: name = str(p.getName()) # Prevent Clanmembers from being kicked skip = 0 for clantag in clantags: if name.find(clantag)>-1: skip = 1 break if skip == 1: continue # If we have a valid idle, check it, and issue a warning if the idle exceeds the limit: p.idleWarnings += 1 if g_debug or xlr_debug: print "IDLEKICK: Player " + name + " has been detected as idle " + str(p.idleWarnings) + " time(s)" if warnme == 1 and p.idleWarnings == (warnings - 3): #tmp = p.idleWarnings * interval / 60 sendMsg("WARNING: " + name + " has not returned to duty for quite some time now. Move in fast, you're about to be court marshalled!") # Issue a warning if a player has reached the maximum number of warnings. Will be kicked next time 'checkidle' is run: if warnings <= p.idleWarnings: #tmp = p.idleWarnings * intervals / 60 sendMsg("Desertion Violation: " + name + " is being removed for not returning to duty in time! (aka idling)") # Add the player to the kicklist: kicklist.append((p.index,p.getProfileId())) # Check of we shall enable the kicktimer: if len(kicklist): enableKickTimer() # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # Function run by the kicktimer: # ------------------------------------------------------------------------ def kickPlayers(data): # Loops through 'kicklist', and kicks players accordingly. #print "IDLEKICK: kickPlayers..." global kicklist, KickTimer for i in kicklist: p = bf2.playerManager.getPlayerByIndex(i[0]) # Make sure we're not kicking a player that has gotten an already disconnected "violater's" index: if not p.getProfileId() == i[1]: continue # Check if this player indeed has reached the limit for maximum warnings if warnings <= p.idleWarnings: # Kick if limit is reached: if g_debug or xlr_debug: print "IDLEKICK: Kicking player " + p.getName() + " for being idle." result = host.rcon_invoke("admin.kickPlayer " + str(p.index)) kicklist = [] KickTimer.destroy() KickTimer = None # ------------------------------------------------------------------------