class scannerhelp(loadable): """Help for scanners""" alias = "scanhelp" usage = " [nick]" access = "member" helptext = """When a request comes in, it looks like this... [123] %s requested a Planet Scan of 1:1:1 Dists(i:17) https://game.planetarion.com/waves.pl?id=1&x=1&y=1&z=1 or... [123] %s requested a Planet Scan of 1:1:1 Dists(i:17/r:35) https://game.planetarion.com/waves.pl?id=1&x=1&y=1&z=1 The "Dists(i:17)" is the number of distorters I think the planet has, based on blocked scanners or from dev scans. The real number may be higher, or possibly lower if some distorters have been destroyed. The "r:35" in the second example means that the user requesting the scan thinks that the planet has at least 35 distorters. If you don't have as many amplifiers as the planet has distorters, it's probably not worth wasting your resources trying. The URL at the end will take you straight to the waves page in-game and will do the scan. You can then copy the URL of the scan (from the "Scan Link" on the page or from your address bar) and paste it in PM to me or in any channel where I can see it. To list open requests, use ".req l" (.request list) for a list in an abbreviated format: [123: (17/35) P 1:1:1] Alternatively, ".req links" will give a list of scan URLs to click on: [123 (17/35): http://game.planetarion.com/waves.pl?id=1&x=1&y=1&z=1] If you get blocked, you can use the "blocks" subcommand. "!req 123 b 20" would indicate that you were blocked doing the example above (the request ID, 123, is in the square brackets) and you have 20 amplifiers. If you have any problems, ask. Scanners are often idle, but usually helpful when they're around! Thanks for scanning for %s!""" % ("Anon" if Config.getboolean( "Misc", "anonscans") else Config.items("Admins")[0][0], "Anon" if Config.getboolean("Misc", "anonscans") else Config.items("Admins")[0][0], Config.get("Alliance", "name")) @route(r"(.*)") def execute(self, message, user, params): if params.group(1): if not user.is_admin(): message.alert("Insufficient access to send the help to %s." % params.group(1)) return from Hooks.scans.request import request tnick = params.group(1).strip() if not CUT.nick_in_chan(tnick, request().scanchan()): message.alert( "%s does not appear to be in the scanner channel. Aborting." % tnick) return if message.reply_type() == NOTICE_REPLY: message.notice(self.helptext, tnick, 2) else: message.privmsg(self.helptext, tnick, 2) elif message.reply_type() == PUBLIC_REPLY and not user.is_admin(): message.alert( "Insufficient access to spam the channel. Try another prefix." % params.group(1)) else: message.reply(self.helptext, 2)
def connect(self, nick): # Configure socket server = Config.get("Connection", "server") port = Config.getint("Connection", "port") print "%s Connecting... (%s %s)" % ( time.asctime(), server, port, ) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.settimeout(330) self.sock.connect(( server, port, )) passwd = Config.get("Connection", "servpass") if passwd: self.write("PASS %s" % (passwd, )) self.write("NICK %s" % (nick, )) self.write("USER %s 0 * :%s bot. Admin: %s" % ( nick, Config.get("Alliance", "name"), Config.items("Admins")[0][0], )) return self.sock
def execute(self, message, user, params): if params.group(1)[-6:].lower() == "hideme": notice = "%s" % (params.group(1)[:-6]) else: notice = "(%s) %s" % (user.name, params.group(1)) for chan in Config.items("Channels"): message.notice(notice, chan[1])
class parse(Thread): useragent = "Merlin (Python-urllib/%s); Alliance/%s; BotNick/%s; Admin/%s" % ( urllib2.__version__, Config.get("Alliance", "name"), Config.get("Connection", "nick"), Config.items("Admins")[0][0]) def __init__(self, uid, type, id, share=True): self.uid = uid self.type = type self.id = id self.share = share Thread.__init__(self) def run(self): scanlog(asctime()) t_start = time() uid = self.uid type = self.type id = self.id try: if type == "scan": self.scan(uid, id) elif type == "group": self.group(uid, id) except Exception, e: scanlog("Exception in scan: %s" % (str(e), ), traceback=True) t1 = time() - t_start scanlog("Total time taken: %.3f seconds" % (t1, ), spacing=True) session.remove()
def secure(message): """Secures the PNick of the bot.""" message.privmsg("SET MAXLOGINS 2\nSET INVISIBLE ON\nSET AUTOKILL ON", Config.get("Services", "nick")) message.reply("Secured the %s nick" % (Config.get("Services", "nick"), )) for chan, name in Config.items("Channels"): message.privmsg("SET %s AUTOINVITE ON" % (name, ), Config.get("Services", "nick"))
def connect(self, nick): # Configure socket server = Config.get("Connection", "server") port = Config.getint("Connection", "port") print "%s Connecting... (%s %s)" % ( time.strftime("%Y%m%d %H:%M:%S |"), server, port, ) try: self.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) self.sock.settimeout(330) self.sock.connect(( server, port, )) except: print "Error connecting with IPv6. Falling back to IPv4..." self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.settimeout(330) self.sock.connect(( server, port, )) passwd = Config.get("Connection", "servpass") if passwd: self.write("PASS %s" % (passwd, ), 0) self.write("NICK %s" % (nick, ), 0) self.write( "USER %s 0 * :%s bot. Admin: %s" % ( nick, Config.get("Alliance", "name"), Config.items("Admins")[0][0], ), 0) return self.sock
def robocop(self, message, notice): for chan in Config.items("Channels"): message.notice(notice, chan[1])
def connect(self, nick): # Configure socket server = Config.get("Connection", "server") port = Config.getint("Connection", "port") print "%s Connecting... (%s %s)" % (time.asctime(), server, port,) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.settimeout(330) self.sock.connect((server, port,)) passwd = Config.get("Connection", "servpass") if passwd: self.write("PASS %s" % (passwd,), 0) self.write("NICK %s" % (nick,), 0) self.write("USER %s 0 * :%s bot. Admin: %s" % (nick, Config.get("Alliance", "name"), Config.items("Admins")[0][0],), 0) return self.sock
session.execute(text("CREATE SCHEMA public;")) except ProgrammingError: print "A public schema already exists, but this is completely normal" session.rollback() else: session.commit() finally: session.close() Base.metadata.create_all() print "Setting up default channels" userlevel = Config.get("Access", "member") maxlevel = Config.get("Access", "admin") gallevel = Config.get("Access", "galmate") for chan, name in Config.items("Channels"): try: channel = Channel(name=name) if chan != "public": channel.userlevel = userlevel channel.maxlevel = maxlevel else: channel.userlevel = gallevel channel.maxlevel = gallevel session.add(channel) session.flush() except IntegrityError: print "Channel '%s' already exists" % (channel.name,) session.rollback() else: print "Created '%s' with access (%s|%s)" % (channel.name, channel.userlevel, channel.maxlevel,)
TIME_ZONE = 'Europe/London' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-GB' MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'Arthur.errors.exceptions', 'Arthur.errors.db', 'Arthur.views.graphs.graphs', ) APPEND_SLASH = True ROOT_URLCONF = 'Arthur' INSTALLED_APPS = ( 'Arthur', ) SECRET_KEY = Config.get("Arthur", "secretkey", raw=True) ALLOWED_HOSTS = ( hostre.match(Config.get("URL", "arthur")).group(1), ) # Get all alturls for url in Config.items("alturls"): ALLOWED_HOSTS += ( hostre.match(url[1]).group(1), )
# You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import re import sys import urllib2 from sqlalchemy.sql import text from Core.config import Config from Core.paconf import PA from Core.db import true, false, session from Core.maps import Ship useragent = "Merlin (Python-urllib/%s); Alliance/%s; BotNick/%s; Admin/%s" % ( urllib2.__version__, Config.get("Alliance", "name"), Config.get("Connection", "nick"), Config.items("Admins")[0][0]) regex = r'^<tr class="(' races = [] for race in PA.options("races"): races.append(PA.get(race, "name")) regex += "|".join(races) regex += ')">.+?>([^<]+)</td>' # race & name regex += r'<td>(\w+)</td>' # class regex += r'(?:<td>(\w\w|\-)</td>)?' * 3 # t1,t2,t3 regex += r'<td>(\w+)</td>' # type regex += r'.+?(\d+|\-)</td>' * 8 # some numbers regex += r'.+?</tr>$' # end of the line sre = re.compile(regex, re.I | re.M) mapping = {
# You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import re import sys import urllib2 from sqlalchemy.sql import text from Core.config import Config from Core.paconf import PA from Core.db import true, false, session from Core.maps import Ship useragent = "Merlin (Python-urllib/%s); Alliance/%s; BotNick/%s; Admin/%s" % (urllib2.__version__, Config.get("Alliance", "name"), Config.get("Connection", "nick"), Config.items("Admins")[0][0]) regex = r'^<tr class="(' races = [] for race in PA.options("races"): races.append(PA.get(race, "name")) regex += "|".join(races) regex += ')">.+?>([^<]+)</td>' # race & name regex += r'<td>(\w+)</td>' # class regex += r'(?:<td>(\w\w|\-)</td>)?'*3 # t1,t2,t3 regex += r'<td>(\w+)</td>' # type regex += r'.+?(\d+|\-)</td>'*8 # some numbers regex += r'.+?</tr>$' # end of the line sre = re.compile(regex,re.I|re.M) mapping = { "Fi": "Fighter",
TIME_ZONE = 'Europe/London' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-GB' MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'Arthur.errors.exceptions', 'Arthur.errors.db', 'Arthur.views.graphs.graphs', ) APPEND_SLASH = True ROOT_URLCONF = 'Arthur' INSTALLED_APPS = ( 'Arthur', ) SECRET_KEY = Config.get("Arthur", "secretkey", raw=True) ALLOWED_HOSTS = ( hostre.match(Config.get("URL", "arthur")).group(1), ) # Get all alturls for url in Config.items("arthururls"): ALLOWED_HOSTS += ( url[1], )
# Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = 'Europe/London' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-GB' MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'Arthur.errors.exceptions', 'Arthur.errors.db', 'Arthur.views.graphs.graphs', ) APPEND_SLASH = True ROOT_URLCONF = 'Arthur' INSTALLED_APPS = ('Arthur', ) SECRET_KEY = Config.get("Arthur", "secretkey", raw=True) ALLOWED_HOSTS = (hostre.match(Config.get("URL", "arthur")).group(1), ) # Get all alturls for url in Config.items("arthururls"): ALLOWED_HOSTS += (url[1], )
# Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = 'Europe/London' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'en-GB' MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'Arthur.errors.exceptions', 'Arthur.errors.db', 'Arthur.views.graphs.graphs', ) APPEND_SLASH = True ROOT_URLCONF = 'Arthur' INSTALLED_APPS = ('Arthur', ) SECRET_KEY = Config.get("Arthur", "secretkey", raw=True) ALLOWED_HOSTS = (hostre.match(Config.get("URL", "arthur")).group(1), ) # Get all alturls for url in Config.items("alturls"): ALLOWED_HOSTS += (hostre.match(url[1]).group(1), )
return None Planet.user = relation(User, uselist=False, backref="planet") def user_access_function(num): # Function generator for access check def func(self): if self.access >= num: return True return func for lvl, num in Config.items("Access"): # Bind user access functions setattr(User, "is_" + lvl, user_access_function(int(num))) class Session(Base): __tablename__ = "session" key = Column(String(40), primary_key=True) user_id = Column(Integer, ForeignKey(User.id, ondelete="set null")) expire = Column(DateTime) @staticmethod def load(key, now=None): Q = session.query(Session) if now is not None: Q = Q.filter(Session.expire > now)
def connect(self, nick): # Configure socket server = Config.get("Connection", "server") port = Config.getint("Connection", "port") print "%s Connecting... (%s %s)" % (time.strftime("%Y%m%d %H:%M:%S |"), server, port,) try: self.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) self.sock.settimeout(330) self.sock.connect((server, port,)) except: print "Error connecting with IPv6. Falling back to IPv4..." self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.settimeout(330) self.sock.connect((server, port,)) passwd = Config.get("Connection", "servpass") if passwd: self.write("PASS %s" % (passwd,), 0) self.write("NICK %s" % (nick,), 0) self.write("USER %s 0 * :%s bot. Admin: %s" % (nick, Config.get("Alliance", "name"), Config.items("Admins")[0][0],), 0) return self.sock
session.execute(text("CREATE SCHEMA public;")) except ProgrammingError: print "A public schema already exists, but this is completely normal" session.rollback() else: session.commit() finally: session.close() Base.metadata.create_all() print "Setting up default channels" userlevel = Config.get("Access", "member") maxlevel = Config.get("Access", "admin") gallevel = Config.get("Access", "galmate") for chan, name in Config.items("Channels"): try: channel = Channel(name=name) if chan != "public": channel.userlevel = userlevel channel.maxlevel = maxlevel else: channel.userlevel = gallevel channel.maxlevel = gallevel session.add(channel) session.flush() except IntegrityError: print "Channel '%s' already exists" % (channel.name, ) session.rollback() else: print "Created '%s' with access (%s|%s)" % (
def secure(message): """Secures the PNick of the bot.""" message.privmsg("SET MAXLOGINS 2\nSET INVISIBLE ON\nSET AUTOKILL ON", "P") message.reply("Secured the PNick") for chan, name in Config.items("Channels"): message.privmsg("set %s autoinvite on" % (name,), "P")
def set_prefs(self, message, user, params): params = self.split_opts(params.group(1)) reply = "" flux_update = -1 for opt, val in params.items(): if opt == "planet": m = self.planet_coordre.match(val) if m: planet = Planet.load(*m.group(1,3,5)) if planet is None: message.alert("No planet with coords %s:%s:%s" % m.group(1,3,5)) continue user.planet = planet reply += " planet=%s:%s:%s"%(planet.x,planet.y,planet.z) if user.is_member(): alliance = Alliance.load(Config.get("Alliance","name")) if planet.intel is None: planet.intel = Intel(nick=user.name, alliance=alliance) else: planet.intel.nick = user.name planet.intel.alliance = alliance elif val in self.nulls: user.planet = None reply += " planet=None" if opt == "password": if message.in_chan(): message.reply("Don't set your password in public you shit") continue user.passwd = val reply += " password=%s"%(val) if Config.has_section("FluxBB"): flux_update = self.flux_passwd(user) if opt == "url": if val == "game" or val in self.nulls: user.url = None val = Config.get("URL", "game") elif val not in Config.options("alturls"): ret = "Valid URLs are: game: %s, " %(Config.get("URL", "game"),) ret+= ", ".join(["%s: %s" %(k,v,) for k, v in Config.items("alturls")]) message.reply(ret) continue else: user.url = val val = Config.get("alturls", val) reply += " url: %s"%(val) if opt == "email": if val in self.nulls: user.email = None reply += " email=None" else: try: user.email = val except AssertionError: reply += " email=%s"%(user.email) else: reply += " email=%s"%(val) if opt == "phone": if val in self.nulls: user.phone = "" reply += " phone=None" else: user.phone = val reply += " phone=%s"%(val) if opt == "pubphone": if val.lower() in self.true: user.pubphone = True reply += " pubphone=%s"%(True) elif val.lower() in self.false: user.pubphone = False reply += " pubphone=%s"%(False) if opt == "smsmode": if (val[:1] in ['C', 'G']) and (Config.get("Misc", "sms") != "combined"): message.alert("Your alliance doesn't support SMS mode switching") continue if val[:1].upper() in User._sms_modes: if val[:1] == 'C' and not Config.get("clickatell", "user"): message.alert("Your alliance doesn't support Clickatell SMS") continue if val[:1] == 'G' and not Config.get("googlevoice", "user"): message.alert("Your alliance doesn't support Google Voice SMS") continue if val[:1] == 'T' and not Config.get("Twilio", "sid"): message.alert("Your alliance doesn't support Twilio SMS") continue if val[:1] == 'W' and not Config.get("WhatsApp", "login"): message.alert("Your alliance doesn't support WhatsApp") continue user.smsmode = val reply += " smsmode=%s" % (user.smsmode,) elif val[:1].lower() == "b" or val in self.nulls: user._smsmode = None reply += " smsmode=None" session.commit() if len(reply) > 0: message.reply("Updated your preferences:"+reply) if flux_update == 0: message.reply("Failed to update forum password.") elif flux_update == 1: message.reply("Updated forum password.")
def secure(message): """Secures the PNick of the bot.""" message.privmsg("SET MAXLOGINS 2\nSET INVISIBLE ON\nSET AUTOKILL ON", Config.get("Services", "nick")) message.reply("Secured the %s nick"%(Config.get("Services", "nick"),)) for chan, name in Config.items("Channels"): message.privmsg("SET %s AUTOINVITE ON" %(name,),Config.get("Services", "nick"));
def set_prefs(self, message, user, params): params = self.split_opts(params.group(1)) reply = "" for opt, val in params.items(): if opt == "planet": m = self.planet_coordre.match(val) if m: planet = Planet.load(*m.group(1, 3, 5)) if planet is None: message.alert("No planet with coords %s:%s:%s" % m.group(1, 3, 5)) continue user.planet = planet reply += " planet=%s:%s:%s" % (planet.x, planet.y, planet.z) if user.is_member(): alliance = Alliance.load(Config.get( "Alliance", "name")) if planet.intel is None: planet.intel = Intel(nick=user.name, alliance=alliance) else: planet.intel.nick = user.name planet.intel.alliance = alliance elif val in self.nulls: user.planet = None reply += " planet=None" if opt == "password": if message.in_chan(): message.reply("Don't set your password in public you shit") continue user.passwd = val reply += " password=%s" % (val) if opt == "url": if val == "game" or val in self.nulls: user.url = None val = Config.get("URL", "game") elif val not in Config.options("alturls"): ret = "Valid URLs are: game: %s, " % (Config.get( "URL", "game"), ) ret += ", ".join([ "%s: %s" % ( k, v, ) for k, v in Config.items("alturls") ]) message.reply(ret) continue else: user.url = val val = Config.get("alturls", val) reply += " url: %s" % (val) if opt == "email": if val in self.nulls: user.email = None reply += " email=None" else: try: user.email = val except AssertionError: reply += " email=%s" % (user.email) else: reply += " email=%s" % (val) if opt == "phone": if val in self.nulls: user.phone = "" reply += " phone=None" else: user.phone = val reply += " phone=%s" % (val) if opt == "pubphone": if val.lower() in self.true: user.pubphone = True reply += " pubphone=%s" % (True) elif val.lower() in self.false: user.pubphone = False reply += " pubphone=%s" % (False) if opt == "smsmode": if Config.get("Misc", "sms") != "combined": message.alert( "Your alliance doesn't support SMS mode switching") continue if val[:1].upper() in User._sms_modes: user.smsmode = val reply += " smsmode=%s" % (user.smsmode, ) elif val[:1].lower() == "b" or val in self.nulls: user._smsmode = None reply += " smsmode=None" session.commit() if len(reply) > 0: message.reply("Updated your preferences:" + reply)
def set_prefs(self, message, user, params): name=params.group(1) u = User.load(name=name, exact=False) if u is None: message.reply("No members matching %s found"%(name,)) return else: user=u params = self.split_opts(params.group(2)) reply = "" for opt, val in params.items(): if opt == "planet": m = self.planet_coordre.match(val) if m: planet = Planet.load(*m.group(1,3,5)) if planet is None: message.alert("No planet with coords %s:%s:%s" % m.group(1,3,5)) continue user.planet = planet reply += " planet=%s:%s:%s"%(planet.x,planet.y,planet.z) if user.is_member(): alliance = Alliance.load(Config.get("Alliance","name")) if planet.intel is None: planet.intel = Intel(nick=user.name, alliance=alliance) else: planet.intel.nick = user.name planet.intel.alliance = alliance elif val in self.nulls: user.planet = None reply += " planet=None" if opt == "password": if message.in_chan(): message.reply("Don't set passwords in public you shit") continue user.passwd = val reply += " password=%s"%(val) if opt == "tguser": user.tguser = val reply += " tguser=%s"%(val) if opt == "url": if val == "game" or val in self.nulls: user.url = None val = Config.get("URL", "game") elif val not in Config.options("alturls"): ret = "Valid URLs are: game: %s, " %(Config.get("URL", "game"),) ret+= ", ".join(["%s: %s" %(k,v,) for k, v in Config.items("alturls")]) message.reply(ret) continue else: user.url = val val = Config.get("alturls", val) reply += " url: %s"%(val) if opt == "email": if val in self.nulls: user.email = None reply += " email=None" else: try: user.email = val except AssertionError: reply += " email=%s"%(user.email) else: reply += " email=%s"%(val) if opt == "phone": if val in self.nulls: user.phone = "" reply += " phone=None" else: user.phone = val reply += " phone=%s"%(val) if opt == "pubphone": if val.lower() in self.true: user.pubphone = True reply += " pubphone=%s"%(True) elif val.lower() in self.false: user.pubphone = False reply += " pubphone=%s"%(False) if opt == "smsmode": if (val[:1] in ['C', 'G']) and (Config.get("Misc", "sms") != "combined"): message.alert("Your alliance doesn't support SMS mode switching") continue if val[:1].upper() in User._sms_modes: user.smsmode = val reply += " smsmode=%s" % (user.smsmode,) elif val[:1].lower() == "b" or val in self.nulls: user._smsmode = None reply += " smsmode=None" session.commit() if len(reply) > 0: message.reply("Updated preferences for %s:" % (user.name) + reply)