Esempio n. 1
0
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)
Esempio n. 2
0
    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
Esempio n. 3
0
 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])
Esempio n. 4
0
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()
Esempio n. 5
0
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"))
Esempio n. 6
0
    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
Esempio n. 7
0
 def robocop(self, message, notice):
     for chan in Config.items("Channels"):
         message.notice(notice, chan[1])
Esempio n. 8
0
 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
Esempio n. 9
0
    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,)
Esempio n. 10
0
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), )

Esempio n. 11
0
# 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 = {
Esempio n. 12
0
 
# 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",
Esempio n. 13
0
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], )

Esempio n. 14
0
# 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], )
Esempio n. 15
0
# 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), )
Esempio n. 16
0
File: maps.py Progetto: munin/merlin
            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)
Esempio n. 17
0
 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
Esempio n. 18
0
    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)" % (
Esempio n. 19
0
File: auth.py Progetto: JDD/DLR
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")
Esempio n. 20
0
    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.")
Esempio n. 21
0
File: auth.py Progetto: JDD/merlin
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"));
Esempio n. 22
0
    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)
Esempio n. 23
0
    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)