def on_rcon_client_ready(self, **kwargs): #rcon_client.command('logaddress_del %s %s' % (config['rcon']['remote']['host'], config['rcon']['remote']['port'])) rcon_client.command('logaddress_add %s %s' % (cget('rcon', 'remote', 'host'), cget('rcon', 'remote', 'port'))) if not self.rcon_tracker: self.rcon_tracker = RconTracker() self.rcon_tracker.setup()
def __init__(self, *args, **kwargs): global irc_client Plugin.__init__(self, *args, **kwargs) command_handler.event.connect(get_dispatcher(self)) network = { 'host': cget('plugins', 'ircbot', 'host'), 'port': int(cget('plugins', 'ircbot', 'port')), 'alias': cget('plugins', 'ircbot', 'alias'), 'nickname': cget('plugins', 'ircbot', 'nickname'), 'username': cget('plugins', 'ircbot', 'username'), 'realname': cget('plugins', 'ircbot', 'realname', default=''), 'authname': cget('plugins', 'ircbot', 'authname'), 'password': cget('plugins', 'ircbot', 'password'), 'channels': cget('plugins', 'ircbot', 'channels'), 'modes': cget('plugins', 'ircbot', 'modes', default='') } irc_client = IrcClient(network) irc_client.events['post_joined'].connect(self.on_joined) irc_client.events['post_left'].connect(self.on_left) irc_client.events['post_privmsg'].connect(self.on_privmsg) reactor.connectTCP(network['host'], network['port'], irc_client.factory) self.finding = False self.ad = '' self.ad_delayed_call = None self.comment = '' self.channels = [] self.nicks = {} # Usually means spammers. self.bad_message_re = re.compile(r'(#[a-zA-Z])|click|paste|idle')
def on_control(self, command, params, silent, **kwargs): extra = kwargs.get('extra', {}) uniqueid = extra.get('uniqueid', '') if not has_access(uniqueid, 'admin'): return True parsed_params = shell_parse(params) # Test if there is a --force parameter. If so then ignore any exceptions. # Otherwise, build a list of exceptions based on the admin users. uniqueid_exceptions = [] if parsed_params and parsed_params[0] == '--force': parsed_params = parsed_params[1:] else: # If there was no force param, then add all people who are admins or higher # onto the list of exceptions. for user in cget('users', default=[]): entry = cget('users', user, default={'uniqueid': None}) if has_access(entry['uniqueid'], 'user'): uniqueid_exceptions.append(entry['uniqueid']) action = '' # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Kick if command == 'k' or command == 'kick': action = 'kick' rcon_client.kick_ex(names=parsed_params, uniqueid_exceptions=uniqueid_exceptions) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Reverse kick elif command == 'rkick' or command == 'rk': action = 'rkick' rcon_client.rkick_ex(names=parsed_params, uniqueid_exceptions=uniqueid_exceptions) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Ban elif command == 'b' or command == 'ban' or command == 'kb': action = 'ban' rcon_client.ban_ex(names=parsed_params, uniqueid_exceptions=uniqueid_exceptions) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Reverse ban elif command == 'rban' or command == 'rb' or command == 'rkb': action = 'rban' rcon_client.rban_ex(names=parsed_params, uniqueid_exceptions=uniqueid_exceptions) #if action: # if not silent: # rcon_client.hsay('', '[%s]: %s' % (action, params)) # This will print out a warning as to why the action was not performed on # the list of players. #if 'exceptions' in ret and ret['exceptions']: #names = [rcon_client.cache['players'][uniqueid]['name'] for uniqueid in ret['exceptions']] #rcon_client.say('[%s]: Use --force to %s exceptions.' % (action, action)) return True
def get_cookie(self, browser): browser.open('http://www.ip2location.com/login.aspx') browser.select_form('Form1') browser['txtEmailAddress'] = cget('plugins', 'ip2location', 'login') browser['txtPassword'] = cget('plugins', 'ip2location', 'password') browser['chkRememberMe'] = ['on'] browser.submit() # Kind of an ugly hack but it allows me to not have to pass in the # cookiejar as well. browser._ua_handlers['_cookies'].cookiejar.save()
def lookup_ip(self, ip): if not ip: return # Grab the location of our cookies path = cget('plugins', 'ip2location', 'cookies_path', default=os.path.join(os.path.dirname(__file__), 'cookies')) cookie_path = os.path.join(path, 'cookies.txt') # Use the mozilla cookie jar. Just because. cj = mechanize.MozillaCookieJar() cj.filename = cookie_path # Attempt to load the cookie file at this point if os.path.exists(cookie_path): cj.load() # Create our browser and set the cookiejar br = mechanize.Browser() br.set_cookiejar(cj) # If the cookie jar contains no cookies, get them. if not cj._cookies: self.get_cookie(br) response = br.open('http://www.ip2location.com/%s' % ip) data = response.read() return self.parse_html(data)
def load_all(): """Loads all the plugins from the directories specified by the config.""" plugins = cget('global', 'plugins', default=[]) paths = cget('global', 'directories', 'plugins', default=[os.path.join(INSTALLDIR, 'plugins')]) for plugin in plugins: try: moduleInfo = imp.find_module(plugin, paths) log.debug('Found plugin "%s", attempting to load...' % plugin) module = imp.load_module(plugin, *moduleInfo) except ImportError: sys.modules.pop(plugin, None) log.debug('Could not import plugin: %s. Is the configuration correct?' % plugin) raise except: sys.modules.pop(plugin, None) raise log.debug('Plugin loaded: %s' % module) if module.__name__ in sys.modules: sys.modules[module.__name__] = module
def do_advertising(self): """A function responsible for advertising. If we are still finding, it will continually call itself at a specific interval.""" if not self.finding: return # Send an ad to each of the channels that we're in. for channel in self.channels: irc_client.msg(channel, self.ad) self.ad_delayed_call = reactor.callLater(int(cget('plugins', 'ircbot', 'ad_interval', default=45)), self.do_advertising)
def on_lo3(self, command, params, silent, **kwargs): extra = kwargs.get('extra', {}) uniqueid = extra.get('uniqueid', '') if not has_access(uniqueid, 'admin'): return True if command == 'lo3': # Don't do lo3 if we're already doing lo3. if self.performing_lo3: return True self.performing_lo3 = True self.pre_lo3.send(sender=self.__class__) self.exec_(cget('plugins', 'exec', 'exec_on_lo3')) # Get the configuration options for going lo3. default_lo3_messages = ['[ Going live on 3 restarts ]', '[ Two more restarts ]', '[ Last restart ]'] default_lo3_delays = ['2', '2', '5'] lo3_messages = cget('plugins', 'exec', 'lo3_messages', default=default_lo3_messages) lo3_delays = cget('plugins', 'exec', 'lo3_delays', default=default_lo3_delays) lo3_live_message = cget('plugins', 'exec', 'lo3_live_message', default='[* LIVE LIVE LIVE *]') #============================== def do_restarts(index): if index < len(lo3_messages): message = lo3_messages[index] delay = lo3_delays[index] rcon_client.hsay('', message) rcon_client.command('sv_restart', delay) index += 1 reactor.callLater(int(delay)+0.9, do_restarts, index) else: self.performing_lo3 = False rcon_client.hsay('', lo3_live_message) self.post_lo3.send(sender=self.__class__) do_restarts(0)
def setup(self): rcon_receiver.event.connect(self.on_rcon_event) reactor.listenUDP(interface=cget('rcon', 'local', 'host'), port=int(cget('rcon', 'local', 'port')), protocol=rcon_receiver) network = HL1Network(cget('rcon', 'host'), int(cget('rcon', 'port')), cget('rcon', 'password')) network.ready.connect(self.on_rcon_client_ready) rcon_client.set_network(network) rcon_client.set_default_hostname(cget('game', 'hostname')) reactor.listenUDP(0, network)
def exec_(self, name): if not name: return # Grab the location of our scripts path = cget('plugins', 'exec', 'scripts_path', default=os.path.join(os.path.dirname(__file__), 'scripts')) # Iterate through the scripts dir and try to find any file matching name. list = os.listdir(path) for file in list: file_name = os.path.splitext(file)[0] if name == file_name: fp = open(os.path.join(path, file), 'r') for line in fp: rcon_client.command(line, deferred=False) fp.close() break
def on_privmsg(self, user, channel, message, **kwargs): """Called when the bot receives a privmsg.""" user = user.split('!', 1)[0] if self.channels and channel == irc_client.network['nickname']: if self.finding: self.nicks[user] = user # Probably should fill with info or something. if not self.bad_message_re.match(message): rcon_client.hsay('irc:%s' % user, message) else: # If the user is in the ignore list, then just return. This could be # "Global" telling you something that we shouldn't respond to or we'll # enter into an infinite loop. user = user.lower() for ignore in cget('plugins', 'ircbot', 'ignore_nicks', default=[]): if ignore.lower() == user: return irc_client.msg(user, 'Sorry, I\'m no longer looking for a scrim.')
def on_command(self, command, params, silent, **kwargs): extra = kwargs.get('extra', {}) uniqueid = extra.get('uniqueid', '') # We don't have access. Return. if not has_access(uniqueid, 'admin'): # Keep processing other plugins. return True # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Find if command == 'find': # We must decode the string to interpret the escapes (e.g. '\x37' into '7'). ad = cget('plugins', 'ircbot', 'ad').decode('string-escape') self.comment = params if params else cget('plugins', 'ircbot', 'default_comment', default='de_any') self.ad = ad.replace('{comment}', self.comment) # We're not finding, so let's start it. if not self.finding: if not silent: rcon_client.hsay('', 'Finding a scrim.') self.finding = True # Only call do_advertising if the delayed call isn't active. # Otherwise we would message the channel immediately and potientially # get kicked/banned from it for spamming. if not self.ad_delayed_call or not self.ad_delayed_call.active(): self.do_advertising() # If we are finding, just notify the user that we changed the parameters. else: if not silent: rcon_client.hsay('', 'Changed parameters. Still finding.') # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Stop finding elif command == 'stopfind' or command == 'stopfinding' or command == 'findstop': if not silent: if self.finding: rcon_client.hsay('', 'No longer finding a scrim.') else: rcon_client.hsay('', 'Not finding. Nothing to stop.') self.finding = False self.nicks = {} # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Accept elif command == 'accept': if params: nick = self.find_nick(params, silent) if nick: default_password = cget('game', 'default_password', default='scrim') new_password = '******' % (default_password, random.randint(1, 99)) rcon_client.cvar('sv_password', new_password) rcon_client.hsay('', 'Giving "%s" the info. New password: %s' % (nick, new_password)) rcon_client.hsay('', 'Don\'t forget to .stopfind when they connect.') # Too bad python 2.6's string formatting isn't in 2.5 accept_message = cget('plugins', 'ircbot', 'accept_message', default='connect {host}:{port};password {password}') accept_message = accept_message.replace('{host}', cget('rcon', 'host')) accept_message = accept_message.replace('{port}', cget('rcon', 'port')) accept_message = accept_message.replace('{password}', new_password) irc_client.msg(nick, accept_message) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Ad elif command == 'ad': rcon_client.hsay('', 'Find ad: %s' % self.comment) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Message elif command == 'msg': if params: params = params.split(' ', 1) if len(params) >= 2: nick = self.find_nick(params[0], silent) if nick: irc_client.msg(nick, params[1]) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Private message or literal message. We send the message via irc no # matter if we have a record of the nick or not. elif command == 'privmsg' or command == 'lmsg': if params: params = params.split(' ', 1) if len(params) >= 2: irc_client.msg(params[0], params[1]) # Keep processing other plugins. return True