Example #1
0
 def execute(self, message, user, params):
     
     p = Planet.load(*params.group(1,3,5))
     if p is None:
         message.reply("No planet with coords %s:%s:%s found" % params.group(1,3,5))
         return
     ship = Ship.load(name=params.group(6))
     if ship is None:
         message.alert("No Ship called: %s" % (params.group(6),))
         return
     
     scan = p.scan("P")
     if scan is None:
         message.reply("No planet scans available on %s:%s:%s" % (p.x,p.y,p.z,))
         return
     
     planetscan = scan.planetscan
     tick=scan.tick
     res_m=planetscan.res_metal
     res_c=planetscan.res_crystal
     res_e=planetscan.res_eonium
     prod_res=planetscan.prod_res
     rand_id=scan.pa_id
     
     cost_m=ship.metal
     cost_c=ship.crystal
     cost_e=ship.eonium
     total_cost=ship.total_cost
     
     class_factory_table = {'Fighter': 'factory_usage_light', 'Corvette': 'factory_usage_light', 'Frigate': 'factory_usage_medium',
                            'Destroyer': 'factory_usage_medium', 'Cruiser': 'factory_usage_heavy', 'Battleship': 'factory_usage_heavy'}
     prod_modifier_table = {'None': 0.0, 'Low': 0.33, 'Medium': 0.66, 'High': 1.0}
     
     capped_number = min(res_m/cost_m, res_c/cost_c, res_e/cost_e)
     overflow = res_m+res_c+res_e-(capped_number*(cost_m+cost_c+cost_e))
     buildable = capped_number + ((overflow*.95)/total_cost)
     
     reply="Newest planet scan on %s:%s:%s (id: %s, pt: %s)" % (p.x,p.y,p.z,rand_id,tick)
     reply+=" can purchase %s: %s"%(ship.name,int(buildable))
     
     for gov in PA.options("govs"):
         bonus = PA.getfloat(gov, "prodcost")
         if bonus == 0:
             continue
         reply+=" | %s: %s"%(PA.get(gov, "name"),int(buildable/(1+bonus)))
     
     factory_usage=getattr(planetscan,class_factory_table[ship.class_])
     if prod_res > 0 and factory_usage != "None":
         max_prod_modifier=prod_modifier_table[factory_usage]
         buildable_from_prod = buildable + max_prod_modifier*prod_res/total_cost
         reply+=" Counting %s res in prod at %s usage:" % (self.num2short(prod_res),factory_usage)
         reply+=" %s"%(int(buildable_from_prod))
         
         for gov in PA.options("govs"):
             bonus = PA.getfloat(gov, "prodcost")
             if bonus == 0:
                 continue
             reply+=" | %s: %s"%(PA.get(gov, "name"),int(buildable_from_prod/(1+bonus)))
     
     message.reply(reply)
Example #2
0
    def execute(self, message, user, params):

        roids, cost, bonus = params.groups()
        roids, cost, bonus = int(roids), self.short2num(cost), int(bonus or 0)
        mining = PA.getint("roids", "mining")

        if roids == 0:
            message.reply("Another NewDawn landing, eh?")
            return

        mining = mining * ((float(bonus) + 100) / 100)

        ticks = (cost * PA.getint("numbers", "ship_value")) // (roids * mining)
        reply = "Capping %s roids at %s value with %s%% bonus will repay in %s ticks (%s days)" % (
            roids, self.num2short(cost), bonus, int(ticks), int(ticks / 24))

        for gov in PA.options("govs"):
            bonus = PA.getfloat(gov, "prodcost")
            if bonus == 0:
                continue
            ticks_b = ticks * (1 + bonus)
            reply += " %s: %s ticks (%s days)" % (PA.get(
                gov, "name"), int(ticks_b), int(ticks_b / 24))

        message.reply(reply)
Example #3
0
File: roidcost.py Project: JDD/DLR
    def execute(self, message, user, params):

        roids, cost, bonus = params.groups()
        roids, cost, bonus = int(roids), self.short2num(cost), int(bonus or 0)
        mining = PA.getint("roids", "mining")

        if roids == 0:
            message.reply("Another NewDawn landing, eh?")
            return

        mining = mining * ((float(bonus) + 100) / 100)

        ticks = (cost * PA.getint("numbers", "ship_value")) / (roids * mining)
        reply = "Capping %s roids at %s value with %s%% bonus will repay in %s ticks (%s days)" % (
            roids,
            self.num2short(cost),
            bonus,
            int(ticks),
            int(ticks / 24),
        )

        for gov in PA.options("govs"):
            bonus = PA.getfloat(gov, "prodcost")
            if bonus == 0:
                continue
            ticks_b = ticks * (1 + bonus)
            reply += " %s: %s ticks (%s days)" % (PA.get(gov, "name"), int(ticks_b), int(ticks_b / 24))

        message.reply(reply)
Example #4
0
File: cost.py Project: munin/merlin
 def execute(self, message, user, params):
     
     num, name = params.groups()
     
     ship = Ship.load(name=name)
     if ship is None:
         message.alert("No Ship called: %s" % (name,))
         return
     
     num = self.short2num(num)
     reply="Buying %s %s will cost %s metal, %s crystal and %s eonium."%(num,ship.name,
             self.num2short(ship.metal*num),
             self.num2short(ship.crystal*num),
             self.num2short(ship.eonium*num))
     
     for gov in PA.options("govs"):
         bonus = PA.getfloat(gov, "prodcost")
         if bonus == 0:
             continue
         
         reply += " %s: %s metal, %s crystal and %s eonium."%(
                     PA.get(gov, "name"),
                     self.num2short(ship.metal*(1+bonus)*num),
                     self.num2short(ship.crystal*(1+bonus)*num),
                     self.num2short(ship.eonium*(1+bonus)*num))
     
     reply+=" It will add %s value"%(self.num2short(ship.total_cost*num/100),)
     message.reply(reply)
Example #5
0
    def execute(self, message, user, params):

        num, name = params.groups()

        ship = Ship.load(name=name)
        if ship is None:
            message.alert("No Ship called: %s" % (name, ))
            return

        num = self.short2num(num)
        reply = "Buying %s %s (%s) will cost %s metal, %s crystal and %s eonium." % (
            num, ship.name,
            self.num2short(
                ship.total_cost * num // PA.getint("numbers", "ship_value")),
            self.num2short(ship.metal * num), self.num2short(
                ship.crystal * num), self.num2short(ship.eonium * num))

        for gov in PA.options("govs"):
            bonus = PA.getfloat(gov, "prodcost")
            if bonus == 0:
                continue

            reply += " %s: %s metal, %s crystal and %s eonium." % (
                PA.get(gov, "name"),
                self.num2short(floor(ship.metal * (1 + bonus)) * num),
                self.num2short(floor(ship.crystal * (1 + bonus)) * num),
                self.num2short(floor(ship.eonium * (1 + bonus)) * num))

        reply += " It will add %s value" % (self.num2short(
            ship.total_cost * num *
            (1.0 / PA.getint("numbers", "ship_value") -
             1.0 / PA.getint("numbers", "res_value"))), )
        message.reply(reply)
Example #6
0
 def execute(self, request, user, page="1", sort="score", race="all"):
     page = int(page)
     offset = (page - 1)*50
     order =  {"score" : (asc(Planet.score_rank),),
               "value" : (asc(Planet.value_rank),),
               "size"  : (asc(Planet.size_rank),),
               "xp"    : (asc(Planet.xp_rank),),
               "race"  : (asc(Planet.race), asc(Planet.size_rank),),
               }
     if sort not in order.keys():
         sort = "score"
     order = order.get(sort)
     
     tick = Updates.midnight_tick()
     
     Q = session.query(Planet, PlanetHistory, Intel.nick, Alliance.name)
     Q = Q.outerjoin(Planet.intel)
     Q = Q.outerjoin(Intel.alliance)
     Q = Q.outerjoin((PlanetHistory, and_(Planet.id == PlanetHistory.id, PlanetHistory.tick == tick)))
     Q = Q.filter(Planet.active == True)
     
     if race.lower() in PA.options("races"):
         Q = Q.filter(Planet.race.ilike(race))
     else:
         race = "all"
     
     count = Q.count()
     pages = count/50 + int(count%50 > 0)
     pages = range(1, 1+pages)
     
     for o in order:
         Q = Q.order_by(o)
     Q = Q.limit(50).offset(offset)
     return render("planets.tpl", request, planets=Q.all(), offset=offset, pages=pages, page=page, sort=sort, race=race)
Example #7
0
 def execute(self, request, user, name, page="1", sort="score", race="all"):
     page = int(page)
     offset = (page - 1)*50
     order =  {"score" : (asc(Planet.score_rank),),
               "value" : (asc(Planet.value_rank),),
               "size"  : (asc(Planet.size_rank),),
               "xp"    : (asc(Planet.xp_rank),),
               "ratio" : (desc(Planet.ratio),),
               "race"  : (asc(Planet.race), asc(Planet.size_rank),),
               "xyz"   : (asc(Planet.x), asc(Planet.y), asc(Planet.z),),
               "score_growth" : (desc(Planet.score_growth),),
               "value_growth" : (desc(Planet.value_growth),),
               "size_growth"  : (desc(Planet.size_growth),),
               "xp_growth"    : (desc(Planet.xp_growth),),
               "score_growth_pc" : (desc(Planet.score_growth_pc),),
               "value_growth_pc" : (desc(Planet.value_growth_pc),),
               "size_growth_pc"  : (desc(Planet.size_growth_pc),),
               "xp_growth_pc"    : (desc(Planet.xp_growth_pc),),
               }
     if sort not in order.keys():
         sort = "score"
     order = order.get(sort)
     
     alliance = Alliance.load(name)
     if alliance is None:
         return HttpResponseRedirect(reverse("alliance_ranks"))
     
     Q = session.query(Planet, Intel.nick, Alliance.name)
     Q = Q.join(Planet.intel)
     Q = Q.join(Intel.alliance)
     Q = Q.filter(Planet.active == True)
     Q = Q.filter(Intel.alliance == alliance)
     
     if race.lower() in PA.options("races"):
         Q = Q.filter(Planet.race.ilike(race))
     else:
         race = "all"
     
     count = Q.count()
     pages = count//50 + int(count%50 > 0)
     pages = range(1, 1+pages)
     
     for o in order:
         Q = Q.order_by(o)
     Q = Q.limit(50).offset(offset)
     return render("palliance.tpl", request, alliance=alliance, members=alliance.intel_members, planets=Q.all(), offset=offset, pages=pages, page=page, sort=sort, race=race)
Example #8
0
File: palliance.py Project: JDD/DLR
 def execute(self, request, user, name, page="1", sort="score", race="all"):
     page = int(page)
     offset = (page - 1)*50
     order =  {"score" : (asc(Planet.score_rank),),
               "value" : (asc(Planet.value_rank),),
               "size"  : (asc(Planet.size_rank),),
               "xp"    : (asc(Planet.xp_rank),),
               "ratio" : (desc(Planet.ratio),),
               "race"  : (asc(Planet.race), asc(Planet.size_rank),),
               "xyz"   : (asc(Planet.x), asc(Planet.y), asc(Planet.z),),
               "score_growth" : (desc(Planet.score_growth),),
               "value_growth" : (desc(Planet.value_growth),),
               "size_growth"  : (desc(Planet.size_growth),),
               "xp_growth"    : (desc(Planet.xp_growth),),
               "score_growth_pc" : (desc(Planet.score_growth_pc),),
               "value_growth_pc" : (desc(Planet.value_growth_pc),),
               "size_growth_pc"  : (desc(Planet.size_growth_pc),),
               "xp_growth_pc"    : (desc(Planet.xp_growth_pc),),
               }
     if sort not in order.keys():
         sort = "score"
     order = order.get(sort)
     
     alliance = Alliance.load(name)
     if alliance is None:
         return HttpResponseRedirect(reverse("alliance_ranks"))
     
     Q = session.query(Planet, Intel.nick, Alliance.name)
     Q = Q.join(Planet.intel)
     Q = Q.join(Intel.alliance)
     Q = Q.filter(Planet.active == True)
     Q = Q.filter(Intel.alliance == alliance)
     
     if race.lower() in PA.options("races"):
         Q = Q.filter(Planet.race.ilike(race))
     else:
         race = "all"
     
     count = Q.count()
     pages = count/50 + int(count%50 > 0)
     pages = range(1, 1+pages)
     
     for o in order:
         Q = Q.order_by(o)
     Q = Q.limit(50).offset(offset)
     return render("palliance.tpl", request, alliance=alliance, planets=Q.all(), offset=offset, pages=pages, page=page, sort=sort, race=race)
Example #9
0
    def execute(self, message, user, params):
        
        roids=int(params.group(1))
        ticks=int(params.group(2))
        bonus=int(params.group(3) or 0)
        mining = PA.getint("roids","mining")

        mining = mining *(float(bonus+100)/100)

        value = ticks*roids*mining/100
        reply = "In %s ticks (%s days) %s roids with %s%% bonus will mine %s value" % (ticks,ticks/24,roids,bonus,self.num2short(value))
        
        for gov in PA.options("govs"):
            bonus = PA.getfloat(gov, "prodcost")
            if bonus == 0:
                continue
            value_b = value/(1+bonus)
            reply += " %s: %s value" % (PA.get(gov, "name"), self.num2short(value_b))
        
        message.reply(reply)
Example #10
0
    def execute(self, message, user, params):

        roids = int(params.group(1))
        ticks = int(params.group(2))
        bonus = int(params.group(3) or 0)
        mining = PA.getint("roids", "mining")

        mining = mining * (float(bonus + 100) / 100)

        value = ticks * roids * mining / PA.getint("numbers", "ship_value")
        reply = "In %s ticks (%s days) %s roids with %s%% bonus will mine %s value" % (
            ticks, ticks // 24, roids, bonus, self.num2short(value))

        for gov in PA.options("govs"):
            bonus = PA.getfloat(gov, "prodcost")
            if bonus == 0:
                continue
            value_b = value / (1 + bonus)
            reply += " %s: %s value" % (PA.get(
                gov, "name"), self.num2short(value_b))

        message.reply(reply)
Example #11
0
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",
    "Co": "Corvette",
    "Fr": "Frigate",
    "De": "Destroyer",
Example #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
 
from django.conf.urls import include, url
from Core.paconf import PA
from Arthur.views.scans import list as slist, request, planet, galaxy

urlpatterns = [
  url(r'^scans?/', include( [
    url(r'^$', slist.scans, name="scans"),
    url(r'^(?P<x>\d+)[. :\-](?P<y>\d+)[. :\-](?P<z>\d+)/',
        include(
            [url(r'^$', planet.planet, name="planet_scans"),
            url(r'^(?P<types>['+"".join([type.lower() for type in PA.options("scans")])+']+)/$', planet.types),
            ] + [url(r'^'+type.lower()+'\w*/$', planet.scan, {"type":type}, name="planet_scan_"+type.lower()) for type in PA.options("scans")]
        )),
    url(r'^(?P<x>\d+)[. :\-](?P<y>\d+)/',
        include( [
            url(r'^$', galaxy.galaxy, name="galaxy_scans"),
            url(r'^(?P<types>['+"".join([type.lower() for type in PA.options("scans")])+']+)/$', galaxy.types)
        ])),
    url('^(?P<tick>\d+)/$', slist.tick, name="scan_tick"),
    url('^(?P<tick>\d+)/(?P<id>\w+)/$', planet.id, name="scan_id"),
    url('^group/(?P<id>\w+)/$', slist.group, name="scan_group_id"),
  ])),
  url('^(?:scans?/)?requests?/$', request.requests, name="requests"),
  url(r'^(?:scans?/)?requests?/', include(request)),
]
Example #13
0
 
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",
            "Co": "Corvette",
            "Fr": "Frigate",
            "De": "Destroyer",
            "Cr": "Cruiser",
Example #14
0
    def execute(self, request, user, params=""):

        Q = session.query(Planet, Intel.nick, Alliance.name)
        Q = Q.outerjoin(Planet.intel)
        Q = Q.outerjoin(Intel.alliance)
        Q = Q.join(Planet.galaxy)
        Q = Q.filter(Planet.active == True)

        query = False

        page = 1

        search = {
            "ruler": "",
            "planet": "",
            "galaxy": "",
            "nick": "",
            "alliance": "",
            "ter": 'checked="checked"',
            "cat": 'checked="checked"',
            "xan": 'checked="checked"',
            "zik": 'checked="checked"',
            "etd": 'checked="checked"',
            "sizemin": "",
            "sizemax": "",
            "valuemin": "",
            "valuemax": "",
            "scoremin": "",
            "scoremax": "",
            "x": "",
            "galsizemin": "",
            "galsizemax": "",
            "galvaluemin": "",
            "galvaluemax": "",
            "galscoremin": "",
            "galscoremax": "",
            "planets": "",
            "bash": "" if params else 'checked="checked"',
            "rankmin": "",
            "rankmax": "",
            "galrankmin": "",
            "galrankmax": "",
            "ratiomin": "",
            "ratiomax": "",
            "galratiomin": "",
            "galratiomax": "",
            "order1": "",
            "order1o": "",
            "order2": "",
            "order2o": "",
        }

        intfilts = {
            "score": Planet.score,
            "value": Planet.value,
            "size": Planet.size,
            "xp": Planet.xp,
            "galscore": Galaxy.score,
            "galreal_score": Galaxy.real_score,
            "galvalue": Galaxy.value,
            "galsize": Galaxy.size,
            "galxp": Galaxy.xp,
            "idle": Planet.idle,
            "x": Planet.x,
            "y": Planet.y,
            "planets": Galaxy.members,
            "totalroundroids": Planet.totalroundroids,
            "totallostroids": Planet.totallostroids,
            "ticksroiding": Planet.ticksroiding,
            "ticksroided": Planet.ticksroided,
            "tickroids": Planet.tickroids,
        }

        floatfilts = {
            "ratio": Planet.ratio,
            "galratio": Galaxy.ratio,
            "avroids": Planet.avroids,
        }

        rankfilts = {
            "rank": Planet.score_rank,
            "valuerank": Planet.value_rank,
            "sizerank": Planet.size_rank,
            "xprank": Planet.xp_rank,
            "galrank": Galaxy.score_rank,
            "galrealrank": Galaxy.real_score_rank,
            "galvaluerank": Galaxy.value_rank,
            "galsizerank": Galaxy.size_rank,
            "galxprank": Galaxy.xp_rank,
        }

        filters = {}
        filters.update(intfilts)
        filters.update(floatfilts)
        filters.update(rankfilts)

        order = {
            "xyz": (
                Planet.x,
                Planet.y,
                Planet.z,
            ),
            "score_growth": Planet.score_growth,
            "value_growth": Planet.value_growth,
            "size_growth": Planet.size_growth,
            "xp_growth": Planet.xp_growth,
            "score_growth_pc": Planet.score_growth_pc,
            "value_growth_pc": Planet.value_growth_pc,
            "size_growth_pc": Planet.size_growth_pc,
            "xp_growth_pc": Planet.xp_growth_pc,
            "galscore_growth": Galaxy.score_growth,
            "galreal_score_growth": Galaxy.real_score_growth,
            "galvalue_growth": Galaxy.value_growth,
            "galsize_growth": Galaxy.size_growth,
            "galxp_growth": Galaxy.xp_growth,
            "galscore_growth_pc": Galaxy.score_growth_pc,
            "galreal_score_growth_pc": Galaxy.real_score_growth_pc,
            "galvalue_growth_pc": Galaxy.value_growth_pc,
            "galsize_growth_pc": Galaxy.size_growth_pc,
            "galxp_growth_pc": Galaxy.xp_growth_pc,
        }

        order.update(filters)
        orders = []

        wordfilts = {
            "ruler": Planet.rulername,
            "planet": Planet.planetname,
            "galaxy": Galaxy.name,
        }

        if request.REQUEST.get("search"):
            r = request.REQUEST
            search = "/search/"

            for word in wordfilts.keys() + ["nick", "alliance"]:
                filt = (r.get(word) or "").strip()
                if not filt:
                    continue
                search += "%s:%s/" % (
                    word,
                    filt,
                )

            for filt in filters.keys():
                one = (r.get("min" + filt) or "").strip()
                two = (r.get("max" + filt) or "").strip()
                if not one and not two:
                    continue

                if one and one == two:
                    search += "%s:%s/" % (
                        filt,
                        one,
                    )
                elif one and not two:
                    search += "%s:%s|/" % (
                        filt,
                        one,
                    )
                elif two and not one:
                    search += "%s:|%s/" % (
                        filt,
                        two,
                    )
                elif one and two:
                    search += "%s:%s|%s/" % (
                        filt,
                        one,
                        two,
                    )

            races = []
            for race in PA.options("races"):
                if (r.get(race) or "").strip():
                    races.append(race)
            if len(races) != len(PA.options("races")):
                search += "race:%s/" % ("|".join(races), )

            if (r.get("bash") or "").strip():
                search += "bash/"

            o1 = (r.get("order1") or "").strip()
            o1o = (r.get("order1o") or "").strip()
            o2 = (r.get("order2") or "").strip()
            o2o = (r.get("order2o") or "").strip()
            if o1 not in order:
                o1, o1o = o2, o2o
            if o1 in order and (o1 == o2 or o2 not in order):
                if o1 == "score" and o1o == "desc":
                    pass
                else:
                    o1o = "^" if o1o == "asc" else "_"
                    search += "order:%s%s/" % (
                        o1o,
                        o1,
                    )
            elif o1 in order and o2 in order:
                o1o = "^" if o1o == "asc" else "_"
                o2o = "^" if o2o == "asc" else "_"
                search += "order:%s%s|%s%s/" % (
                    o1o,
                    o1,
                    o2o,
                    o2,
                )

            return HttpResponseRedirect(search)

        for param in params.lower().split("/"):
            if param == "bash" and user.planet is not None:
                Q = Q.filter(
                    or_(
                        Planet.value.op(">")(user.planet.value *
                                             PA.getfloat("bash", "value")),
                        Planet.score.op(">")(user.planet.score *
                                             PA.getfloat("bash", "score"))))
                Q = Q.filter(Planet.x < 200)
                search[param] = 'checked="checked"'
                continue

            arg, sep, val = param.partition(":")
            if not (arg and val):
                continue

            if arg in filters:
                one, two = "", ""
                if "|" not in val:
                    one, two = val, val
                elif val[-1] == "|":
                    one, two = val[:-1], ""
                elif val[0] == "|":
                    one, two = "", val[1:]
                elif "|" in val:
                    one, two = val.split("|", 1)
                else:
                    continue

                try:
                    if one:
                        one = float(one) if arg in floatfilts else int(one)
                    if two:
                        two = float(two) if arg in floatfilts else int(two)
                except ValueError:
                    continue

                if one and one == two:
                    Q = Q.filter(filters[arg] == one)
                elif one and not two:
                    Q = Q.filter(
                        filters[arg] <= one) if arg in rankfilts else Q.filter(
                            filters[arg] >= one)
                elif two and not one:
                    Q = Q.filter(
                        filters[arg] >= two) if arg in rankfilts else Q.filter(
                            filters[arg] <= two)
                elif one and two:
                    Q = Q.filter(filters[arg].between(min(one, two),
                                                      max(one, two)))
                else:
                    continue

                search[arg + "min"], search[arg + "max"] = one, two
                query = True

            elif arg in wordfilts:
                Q = Q.filter(wordfilts[arg].ilike("%" + val + "%"))
                search[arg] = val
                query = True

            elif arg == "nick" and getattr(
                    user, "is_" + Config.get("Arthur", "intel"))():
                Q = Q.filter(Intel.nick.ilike("%" + val + "%"))
                search["nick"] = val
                query = True

            elif arg == "alliance" and getattr(
                    user, "is_" + Config.get("Arthur", "intel"))():
                if val[0] == "!":
                    val = val[1:]
                    inv = True
                else:
                    inv = False
                alliance = Alliance.load(val)
                if alliance:
                    Q = Q.filter(
                        Intel.alliance == alliance) if not inv else Q.filter(
                            Intel.alliance != alliance)
                    search["alliance"] = ["", "!"][inv] + alliance.name
                    query = True

            elif arg == "race":
                races = []
                for race in val.split("|"):
                    if race in PA.options("races") and race not in races:
                        races.append(Planet.race.ilike(race))
                        search[race] = True
                if len(races):
                    Q = Q.filter(or_(*races))
                    for race in PA.options("races"):
                        search[race] = 'checked="checked"' if search[
                            race] is True else ""
                    query = True

            elif arg == "order":
                for sort in val.split("|"):
                    if sort[0] == "^":
                        f = asc
                    elif sort[0] == "_":
                        f = desc
                    else:
                        continue
                    if sort[1:] in order:
                        orders.append((
                            f,
                            sort[1:],
                        ))
                        query = True

            elif arg == "page" and val.isdigit():
                page = int(val)

        if len(orders) < 1:
            orders.append((
                desc,
                "score",
            ))
        if len(orders) < 2:
            orders.append((
                desc,
                "score",
            ))
        search["order1"] = orders[0][1]
        search["order1o"] = orders[0][0].__name__
        search["order2"] = orders[1][1]
        search["order2o"] = orders[1][0].__name__
        for d, os in orders:
            if type(order[os]) is tuple:
                for o in order[os]:
                    Q = Q.order_by(d(o))
            else:
                Q = Q.order_by(d(order[os]))

        showsort = True if search["order1"] not in (
            "xyz",
            "size",
            "value",
            "score",
            "ratio",
            "xp",
            "size_growth",
            "value_growth",
            "score_growth",
            "size_growth_pc",
            "value_growth_pc",
            "score_growth_pc",
        ) else False

        count = Q.count()
        pages = count / 50 + int(count % 50 > 0)
        pages = range(1, 1 + pages)

        offset = (page - 1) * 50
        Q = Q.limit(50).offset(offset)

        results = Q.all() if query else None

        return render("search.tpl",
                      request,
                      planets=results,
                      sort=search["order1"],
                      showsort=showsort,
                      s=search,
                      params=params,
                      offset=offset,
                      pages=pages,
                      page=page)
Example #15
0
    def execute(self, message, user, params):

        planet = Planet.load(*params.group(1, 3, 5))
        if planet is None:
            message.alert("No planet with coords %s:%s:%s" %
                          params.group(1, 3, 5))
            return

        tick = Updates.load().current_tick()

        pscan = planet.scan("P")
        if pscan is None:
            message.reply("No Planet Scans of %s:%s:%s found" %
                          (planet.x, planet.y, planet.z))
            return
        else:
            p_age = tick - pscan.tick
            pscan = pscan.planetscan

        dscan = planet.scan("D")
        if dscan is None:
            message.reply("No Development Scans of %s:%s:%s found" %
                          (planet.x, planet.y, planet.z))
            return
        else:
            d_age = tick - dscan.tick
            dscan = dscan.devscan

        # Get government info from pa.cfg and intel
        gov_bonus = 0
        gov = "Unknown"
        gov_alert_max = 0.00
        gov_alert_min = 0.00
        int_gov = planet.intel.gov
        if int_gov is not None:
            int_gov = int_gov[0].lower()
        for gcode in PA.options("govs"):
            gov_alert = PA.getfloat(gcode, "alert")
            if int_gov and int_gov == gcode[0]:
                gov = PA.get(gcode, "name")
                gov_bonus = gov_alert
            if gov_alert > gov_alert_max:
                gov_alert_max = gov_alert
            if gov_alert < gov_alert_min:
                gov_alert_min = gov_alert

        alert_min = int(
            (50 + 5 * min(pscan.guards / (planet.size + 1), 15)) *
            (1 + dscan.security_centre * 2 / dscan.total +
             (gov_bonus if gov != "Unknown" else gov_alert_min) + 0.0))
        alert_max = int(
            (50 + 5 * min(pscan.guards / (planet.size + 1), 15)) *
            (1 + dscan.security_centre * 2 / dscan.total +
             (gov_bonus if gov != "Unknown" else gov_alert_max) + 0.5))

        message.reply(
            "Planet: %s:%s:%s  Government: %s  Alert: %s-%s  (Scan Age P:%s D:%s)"
            % (planet.x, planet.y, planet.z, gov, alert_min, alert_max, p_age,
               d_age))
        if params.group(6):
            agents = int(params.group(6))
            max_res = user.planet.resources_per_agent(planet)
            message.reply(
                "Results:   EF: %d roids (%dXP) AD: %d agents (%dXP) SGD: %d guards (%dXP) H:SD: %1.2f%% RP (%dXP) WDM: %d ship value (%dXP)"
                % (agents / 3, self.xpcalc(agents, 1), agents,
                   self.xpcalc(agents, 2), agents * 10, self.xpcalc(agents, 3),
                   agents * 0.25, self.xpcalc(agents, 4), agents *
                   (min(50 + 10 * planet.value / user.planet.value, 100)),
                   self.xpcalc(agents, 5)))
            message.reply(
                "           IB: %d amps+dists (%dXP) H: %d buildings (%dXP) H:RT: %dM %dC %dE (%dXP) GS: %d ticks (%dXP)"
                % (agents / 15, self.xpcalc(agents, 6), agents / 20,
                   self.xpcalc(agents, 7), min(max_res, pscan.res_metal / 10),
                   min(max_res, pscan.res_crystal / 10),
                   min(max_res, pscan.res_eonium / 10), self.xpcalc(
                       agents, 8), agents / 5, self.xpcalc(agents, 9)))

            # If stealth is supplied, calculate the probability of success.
            if params.group(7):
                stealth = int(params.group(7))
                stealth = stealth - 5 - int(agents / 2)
                t = 8 - alert_min
                prob = 100 * (t + stealth) / (t + alert_max)
                if prob < 0:
                    prob = 0
                elif prob > 100:
                    prob = 100

                growth = PA.getint(user.planet.race.lower(), "sgrowth")
                from math import ceil
                message.reply(
                    "New stealth: %s  Success rate: %s%%  Recovery time: %d ticks"
                    % (stealth, prob, ceil((5.0 + int(agents / 2)) / growth)))
Example #16
0
 def execute(self, request, user, params=""):
     
     Q = session.query(Planet, Intel.nick, Alliance.name)
     Q = Q.outerjoin(Planet.intel)
     Q = Q.outerjoin(Intel.alliance)
     Q = Q.join(Planet.galaxy)
     Q = Q.filter(Planet.active == True)
     
     query = False
     
     page = 1
     
     search = {
                 "ruler" : "", "planet" : "", "galaxy" : "", "nick" : "", "alliance" : "",
                 "ter" : 'checked="checked"', "cat" : 'checked="checked"', "xan" : 'checked="checked"', "zik" : 'checked="checked"', "etd" : 'checked="checked"',
                 "sizemin" : "", "sizemax" : "", "valuemin" : "", "valuemax" : "", "scoremin" : "", "scoremax" : "", "x" : "",
                 "galsizemin" : "", "galsizemax" : "", "galvaluemin" : "", "galvaluemax" : "", "galscoremin" : "", "galscoremax" : "", "planets" : "",
                 "bash" : "" if params else 'checked="checked"',
                 "rankmin" : "", "rankmax" : "", "galrankmin" : "", "galrankmax" : "",
                 "ratiomin" : "", "ratiomax" : "", "galratiomin" : "", "galratiomax" : "",
                 "order1" : "", "order1o" : "", "order2" : "", "order2o" : "",
              }
     
     intfilts = {
                 "score" : Planet.score,
                 "value" : Planet.value,
                 "size" : Planet.size,
                 "xp" : Planet.xp,
                 "galscore" : Galaxy.score,
                 "galreal_score" : Galaxy.real_score,
                 "galvalue" : Galaxy.value,
                 "galsize" : Galaxy.size,
                 "galxp" : Galaxy.xp,
                 "idle" : Planet.idle,
                 "x" : Planet.x,
                 "y" : Planet.y,
                 "planets" : Galaxy.members,
                 "totalroundroids" : Planet.totalroundroids,
                 "totallostroids" : Planet.totallostroids,
                 "ticksroiding" : Planet.ticksroiding,
                 "ticksroided" : Planet.ticksroided,
                 "tickroids" : Planet.tickroids,
                 }
     
     floatfilts = {
                 "ratio" : Planet.ratio,
                 "galratio" : Galaxy.ratio,
                 "avroids" : Planet.avroids,
                 }
     
     rankfilts = {
                 "rank" : Planet.score_rank,
                 "valuerank" : Planet.value_rank,
                 "sizerank" : Planet.size_rank,
                 "xprank" : Planet.xp_rank,
                 "galrank" : Galaxy.score_rank,
                 "galrealrank" : Galaxy.real_score_rank,
                 "galvaluerank" : Galaxy.value_rank,
                 "galsizerank" : Galaxy.size_rank,
                 "galxprank" : Galaxy.xp_rank,
                 }
     
     filters = {}
     filters.update(intfilts)
     filters.update(floatfilts)
     filters.update(rankfilts)
     
     order = {
                 "xyz"   : (Planet.x, Planet.y, Planet.z,),
                 "score_growth" : Planet.score_growth,
                 "value_growth" : Planet.value_growth,
                 "size_growth"  : Planet.size_growth,
                 "xp_growth"    : Planet.xp_growth,
                 "score_growth_pc" : Planet.score_growth_pc,
                 "value_growth_pc" : Planet.value_growth_pc,
                 "size_growth_pc"  : Planet.size_growth_pc,
                 "xp_growth_pc"    : Planet.xp_growth_pc,
                 "galscore_growth" : Galaxy.score_growth,
                 "galreal_score_growth" : Galaxy.real_score_growth,
                 "galvalue_growth" : Galaxy.value_growth,
                 "galsize_growth"  : Galaxy.size_growth,
                 "galxp_growth"    : Galaxy.xp_growth,
                 "galscore_growth_pc" : Galaxy.score_growth_pc,
                 "galreal_score_growth_pc" : Galaxy.real_score_growth_pc,
                 "galvalue_growth_pc" : Galaxy.value_growth_pc,
                 "galsize_growth_pc"  : Galaxy.size_growth_pc,
                 "galxp_growth_pc"    : Galaxy.xp_growth_pc,
                 }
     
     order.update(filters)
     orders = []
     
     wordfilts = {
                 "ruler" : Planet.rulername,
                 "planet" : Planet.planetname,
                 "galaxy" : Galaxy.name,
                 }
     
     if request.POST.get("search"):
         r = request.POST
         search = "/search/"
         
         for word in wordfilts.keys() + ["nick", "alliance"]:
             filt = (r.get(word) or "").strip()
             if not filt:
                 continue
             search += "%s:%s/" %(word,filt,)
         
         for filt in filters.keys():
             one = (r.get("min"+filt) or "").strip()
             two = (r.get("max"+filt) or "").strip()
             if not one and not two:
                 continue
             
             if one and one == two:
                 search += "%s:%s/" %(filt,one,)
             elif one and not two:
                 search += "%s:%s|/" %(filt,one,)
             elif two and not one:
                 search += "%s:|%s/" %(filt,two,)
             elif one and two:
                 search += "%s:%s|%s/" %(filt,one,two,)
         
         races = []
         for race in PA.options("races"):
             if (r.get(race) or "").strip():
                 races.append(race)
         if len(races) != len(PA.options("races")):
             search += "race:%s/" %("|".join(races),)
         
         if (r.get("bash") or "").strip():
             search += "bash/"
         
         o1 = (r.get("order1") or "").strip()
         o1o = (r.get("order1o") or "").strip()
         o2 = (r.get("order2") or "").strip()
         o2o = (r.get("order2o") or "").strip()
         if o1 not in order:
             o1, o1o = o2, o2o
         if o1 in order and (o1 == o2 or o2 not in order):
             if o1 == "score" and o1o == "desc":
                 pass
             else:
                 o1o = "^" if o1o == "asc" else "_"
                 search += "order:%s%s/" %(o1o,o1,)
         elif o1 in order and o2 in order:
             o1o = "^" if o1o == "asc" else "_"
             o2o = "^" if o2o == "asc" else "_"
             search += "order:%s%s|%s%s/" %(o1o,o1,o2o,o2,)
         
         return HttpResponseRedirect(search)
     
     for param in params.lower().split("/"):
         if param == "bash" and user.planet is not None:
             Q = Q.filter(or_(Planet.value.op(">")(user.planet.value*PA.getfloat("bash","value")),
                              Planet.score.op(">")(user.planet.score*PA.getfloat("bash","score"))))
             Q = Q.filter(Planet.x < 200)
             search[param] = 'checked="checked"'
             continue
         
         arg, sep, val = param.partition(":")
         if not (arg and val):
             continue
         
         if arg in filters:
             one, two = "", ""
             if "|" not in val:
                 one, two = val, val
             elif val[-1] == "|":
                 one, two = val[:-1], ""
             elif val[0] == "|":
                 one, two = "", val[1:]
             elif "|" in val:
                 one, two = val.split("|",1)
             else:
                 continue
             
             try:
                 if one:
                     one = float(one) if arg in floatfilts else int(one)
                 if two:
                     two = float(two) if arg in floatfilts else int(two)
             except ValueError:
                 continue
             
             if one and one == two:
                 Q = Q.filter(filters[arg] == one)
             elif one and not two:
                 Q = Q.filter(filters[arg] <= one) if arg in rankfilts else Q.filter(filters[arg] >= one)
             elif two and not one:
                 Q = Q.filter(filters[arg] >= two) if arg in rankfilts else Q.filter(filters[arg] <= two)
             elif one and two:
                 Q = Q.filter(filters[arg].between(min(one,two), max(one,two)))
             else:
                 continue
             
             search[arg+"min"], search[arg+"max"] = one, two
             query = True
         
         elif arg in wordfilts:
             Q = Q.filter(wordfilts[arg].ilike("%"+val+"%"))
             search[arg] = val
             query = True
         
         elif arg == "nick" and getattr(user, "is_" + Config.get("Arthur", "intel"))():
             Q = Q.filter(Intel.nick.ilike("%"+val+"%"))
             search["nick"] = val
             query = True
         
         elif arg == "alliance" and getattr(user, "is_" + Config.get("Arthur", "intel"))():
             if val[0] == "!":
                 val = val[1:]
                 inv = True
             else:
                 inv = False
             alliance = Alliance.load(val)
             if alliance:
                 Q = Q.filter(Intel.alliance == alliance) if not inv else Q.filter(Intel.alliance != alliance)
                 search["alliance"] = ["","!"][inv] + alliance.name
                 query = True
         
         elif arg == "race":
             races = []
             for race in val.split("|"):
                 if race in PA.options("races") and race not in races:
                     races.append(Planet.race.ilike(race))
                     search[race] = True
             if len(races):
                 Q = Q.filter(or_(*races))
                 for race in PA.options("races"):
                     search[race] = 'checked="checked"' if search[race] is True else ""
                 query = True
         
         elif arg == "order":
             for sort in val.split("|"):
                 if sort[0] == "^":
                     f = asc
                 elif sort[0] == "_":
                     f = desc
                 else:
                     continue
                 if sort[1:] in order:
                     orders.append((f, sort[1:],))
                     query = True
         
         elif arg == "page" and val.isdigit():
             page = int(val)
     
     if len(orders) < 1:
         orders.append((desc, "score",))
     if len(orders) < 2:
         orders.append((desc, "score",))
     search["order1"] = orders[0][1]
     search["order1o"] = orders[0][0].__name__
     search["order2"] = orders[1][1]
     search["order2o"] = orders[1][0].__name__
     for d, os in orders:
         if type(order[os]) is tuple:
             for o in order[os]:
                 Q = Q.order_by(d(o))
         else:
             Q = Q.order_by(d(order[os]))
     
     showsort = True if search["order1"] not in ("xyz","size","value","score","ratio","xp",
                                                 "size_growth","value_growth","score_growth",
                                                 "size_growth_pc","value_growth_pc","score_growth_pc",) else False
     
     count = Q.count()
     pages = count//50 + int(count%50 > 0)
     pages = range(1, 1+pages)
     
     offset = (page - 1)*50
     Q = Q.limit(50).offset(offset)
     
     results = Q.all() if query else None
     
     return render("search.tpl", request, planets=results, sort=search["order1"],
                             showsort=showsort, s=search, params=params,
                             offset=offset, pages=pages, page=page)
Example #17
0
    def execute(self, message, user, params):

        p = Planet.load(*params.group(1, 3, 5))
        if p is None:
            message.reply("No planet with coords %s:%s:%s found" %
                          params.group(1, 3, 5))
            return
        ship = Ship.load(name=params.group(6))
        if ship is None:
            message.alert("No Ship called: %s" % (params.group(6), ))
            return

        scan = p.scan("P")
        if scan is None:
            message.reply("No planet scans available on %s:%s:%s" % (
                p.x,
                p.y,
                p.z,
            ))
            return

        planetscan = scan.planetscan
        tick = scan.tick
        res_m = planetscan.res_metal
        res_c = planetscan.res_crystal
        res_e = planetscan.res_eonium
        prod_res = planetscan.prod_res
        rand_id = scan.pa_id

        cost_m = ship.metal
        cost_c = ship.crystal
        cost_e = ship.eonium
        total_cost = ship.total_cost

        class_factory_table = {
            'Fighter': 'factory_usage_light',
            'Corvette': 'factory_usage_light',
            'Frigate': 'factory_usage_medium',
            'Destroyer': 'factory_usage_medium',
            'Cruiser': 'factory_usage_heavy',
            'Battleship': 'factory_usage_heavy'
        }
        prod_modifier_table = {
            'None': 0.0,
            'Low': 0.33,
            'Medium': 0.66,
            'High': 1.0
        }

        capped_number = min(res_m / cost_m, res_c / cost_c, res_e / cost_e)
        overflow = res_m + res_c + res_e - (capped_number *
                                            (cost_m + cost_c + cost_e))
        buildable = capped_number + ((overflow * .95) / total_cost)

        reply = "Newest planet scan on %s:%s:%s (id: %s, pt: %s)" % (
            p.x, p.y, p.z, rand_id, tick)
        reply += " can purchase %s: %s" % (ship.name, int(buildable))

        for gov in PA.options("govs"):
            bonus = PA.getfloat(gov, "prodcost")
            if bonus == 0:
                continue
            reply += " | %s: %s" % (PA.get(
                gov, "name"), int(buildable / (1 + bonus)))

        factory_usage = getattr(planetscan, class_factory_table[ship.class_])
        if prod_res > 0 and factory_usage != "None":
            max_prod_modifier = prod_modifier_table[factory_usage]
            buildable_from_prod = buildable + max_prod_modifier * prod_res / total_cost
            reply += " Counting %s res in prod at %s usage:" % (
                self.num2short(prod_res), factory_usage)
            reply += " %s" % (int(buildable_from_prod))

            for gov in PA.options("govs"):
                bonus = PA.getfloat(gov, "prodcost")
                if bonus == 0:
                    continue
                reply += " | %s: %s" % (PA.get(
                    gov, "name"), int(buildable_from_prod / (1 + bonus)))

        message.reply(reply)
Example #18
0
    def execute(self, message, user, params):
        
        planet = Planet.load(*params.group(1,3,5))
        if planet is None:
            message.alert("No planet with coords %s:%s:%s" % params.group(1,3,5))
            return

        tick=Updates.load().current_tick()

        pscan = planet.scan("P")
        if pscan is None:
            message.reply("No Planet Scans of %s:%s:%s found"%(planet.x,planet.y,planet.z))
            return
        else:
            p_age = tick - pscan.tick
            pscan = pscan.planetscan

        dscan = planet.scan("D")
        if dscan is None:
            message.reply("No Development Scans of %s:%s:%s found"%(planet.x,planet.y,planet.z))
            return
        else:
            d_age = tick - dscan.tick
            dscan = dscan.devscan

        # Get government info from pa.cfg and intel
        gov_bonus = 0
        gov = "Unknown"
        gov_alert_max = 0.00
        gov_alert_min = 0.00
        int_gov = planet.intel.gov
        if int_gov is not None:
            int_gov = int_gov[0].lower()
        for gcode in PA.options("govs"):
            gov_alert = PA.getfloat(gcode, "alert")
            if int_gov and int_gov == gcode[0]:
                gov = PA.get(gcode, "name")
                gov_bonus = gov_alert
            if gov_alert > gov_alert_max:
                gov_alert_max = gov_alert
            if gov_alert < gov_alert_min:
                gov_alert_min = gov_alert


        alert_min = int((50+5*min(pscan.guards/(planet.size+1),15))*(1+dscan.security_centre*0.0275 + (gov_bonus if gov != "Unknown" else gov_alert_min) + 0.0))
        alert_max = int((50+5*min(pscan.guards/(planet.size+1),15))*(1+dscan.security_centre*0.0275 + (gov_bonus if gov != "Unknown" else gov_alert_max) + 0.5))

        message.reply("Planet: %s:%s:%s  Government: %s  Alert: %s-%s  (Scan Age P:%s D:%s)" % (planet.x, planet.y, planet.z, gov, alert_min, alert_max, p_age, d_age))
        if params.group(6):
            agents = int(params.group(6))
            max_res = user.planet.resources_per_agent(planet)
            message.reply("Results:   EF: %d roids (%dXP) AD: %d agents (%dXP) SGD: %d guards (%dXP) H:SD: %1.2f%% RP (%dXP) WDM: %d ship value (%dXP)" % (agents //3, 
                     self.xpcalc(agents,1), agents, self.xpcalc(agents,2), agents*10, self.xpcalc(agents,3), agents*0.25, self.xpcalc(agents,4), 
                     agents*(min(50+10*planet.value//user.planet.value, 100)), self.xpcalc(agents,5)))
            message.reply("           IB: %d amps+dists (%dXP) H: %d buildings (%dXP) H:RT: %dM %dC %dE (%dXP) GS: %d ticks (%dXP)" % (agents//15, self.xpcalc(agents,6),
                     agents//20, self.xpcalc(agents,7), min(max_res, pscan.res_metal//10), min(max_res, pscan.res_crystal//10), min(max_res, pscan.res_eonium//10),
                     self.xpcalc(agents,8), agents//5, self.xpcalc(agents,9)))

            # If stealth is supplied, calculate the probability of success.
            if params.group(7):
                stealth = int(params.group(7))
                stealth = stealth - 5 - int(agents/2)
                t=8-alert_min
                prob = 100*(t+stealth)//(t+alert_max)
                if prob < 0:
                    prob = 0
                elif prob > 100:
                    prob = 100

                growth = PA.getint(user.planet.race.lower(), "sgrowth")
                from math import ceil
                message.reply("New stealth: %s  Success rate: %s%%  Recovery time: %d ticks" % (stealth, prob, ceil((5.0+int(agents/2))/growth)))
Example #19
0
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

from django.conf.urls import include, patterns, url
from sqlalchemy.sql import asc
from Core.config import Config
from Core.paconf import PA
from Core.db import session
from Core.maps import Updates, Planet, Request
from Core.robocop import push
from Arthur.context import menu, render
from Arthur.loadable import loadable, load, require_user

urlpatterns = patterns(
    'Arthur.views.scans.request',
    url(r'^(?P<x>\d+)[. :\-](?P<y>\d+)[. :\-](?P<z>\d+)/(?P<type>[' +
        "".join([type.lower() for type in PA.options("scans")]) +
        '])/(?:(?P<dists>\d+)/)?$',
        'request',
        name="request_planet"),
    url(r'^cancel/(?P<id>\d+)/$', 'cancel', name="request_cancel"),
    url(r'^(?P<id>\d+)/blocks/(?P<dists>\d+)/$',
        'blocks',
        name="request_blocks"),
)


@load
@require_user
class request(loadable):
    access = Config.get("Arthur", "scans")
Example #20
0
class loadable(_base):
    # Base loadable class for callbacks
    ""
    usage = None
    alias = None
    param = ""
    trigger = "PRIVMSG"
    routes = None  # List of (name, regex, access,)
    robocop = None
    PParseError = "You need to login and set mode +x to use this command"
    AccessError = "You don't have access to this command"
    PrefError = "You must set your planet with !pref to use this command"
    ChanError = "This command may only be used in %s"
    coord = r"(\d+)([. :\-])(\d+)(\2(\d+))?"
    planet_coord = r"(\d+)([. :\-])(\d+)(\2(\d+))"
    govre = re.compile(r"(" + "|".join(PA.options("govs")) + ")", re.I)
    racere = re.compile(r"(" + "|".join(PA.options("races")) + ")", re.I)
    scanre = re.compile(r"(" + "|".join(PA.options("scans")) + ")", re.I)
    true = ["1", "yes", "y", "true", "t"]
    false = ["0", "no", "n", "false", "f"]
    nulls = ["<>", ".", "-", "?"]

    def __new__(cls):
        self = super(loadable, cls).__new__(cls)
        self.name = cls.__name__
        self.doc = cls.__doc__

        self.routes = self.routes or []
        self.routes.extend([
            (
                name,
                route._ROUTE,
                route._ACCESS,
            ) for name, route in sorted(cls.__dict__.items())
            if hasattr(route, "_ROUTE") and hasattr(route, "_ACCESS")
        ])

        if cls.access in Config.options("Access"):
            self.access = Config.getint("Access", cls.access)
        elif type(cls.access) is int:
            self.access = cls.access
        else:
            self.access = min([
                route._ACCESS for route in cls.__dict__.values()
                if hasattr(route, "_ROUTE") and hasattr(route, "_ACCESS")
            ])

        return self

    def __init__(self):
        cmd = self.name if self.alias is None else "%s|%s" % (
            self.name,
            self.alias,
        )
        self.commandre = re.compile(r"(%s)(\s+.*|$)" % (cmd, ), re.I)
        self.helpre = re.compile(r"help %s\s*$" % (cmd, ), re.I)
        self.usage = (self.name + self.usage) if self.usage else None

    def __call__(self, message):
        self.run(message)

    def match(self, message, regex):
        if message.get_msg() and message.get_prefix():
            return regex.match(message.get_msg()[1:])

    def router(self, message, command):
        for name, regex, access in self.routes:
            params = regex.match(command)
            if params is None:
                continue
            else:
                break
        else:
            raise ParseError

        route = getattr(self, name)

        user = self.check_access(message, access)
        if user is None:
            raise UserError

        if getattr(route, "_USER", False) is True:
            if self.is_user(user) is False:
                message.get_pnick()
                raise UserError

        if getattr(route, "_PLANET", False) is True:
            if self.user_has_planet(user) is False:
                raise PrefError

        if getattr(route, "_CHANNEL", None) is not None:
            if self.is_chan(message, route._CHANNEL) is False:
                raise ChanParseError(route._CHANNEL)

        if getattr(route, "_USER_IN", None) is not None:
            if CUT.nick_in_chan(message.get_nick(),
                                route._USER_IN) is not True:
                raise ChanParseError(route._USER_IN)

        return route, name, user, params

    def run(self, message):
        m = self.match(message, self.commandre)
        if m is None:
            if self.match(message, self.helpre) is not None:
                self.help(message)
            return
        command = m.group(2)

        try:
            route, subcommand, user, params = self.router(message, command)

            route(message, user, params)

            session = Session()
            session.add(
                Command(
                    command_prefix=message.get_prefix(),
                    command=self.name,
                    subcommand=subcommand,
                    command_parameters=self.hide_passwords(
                        self.name,
                        message.get_msg()[len(m.group(1)) + 1:].strip()),
                    nick=message.get_nick(),
                    username="" if user is True else user.name,
                    hostname=message.get_hostmask(),
                    target=message.get_chan()
                    if message.in_chan() else message.get_nick(),
                ))
            session.commit()
            session.close()

        except PNickParseError:
            message.alert(self.PParseError)
        except UserError:
            message.alert(self.AccessError)
        except PrefError:
            message.alert(self.PrefError)
        except ChanParseError, e:
            message.alert(self.ChanError % e)
        except ParseError:
            message.alert(self.usage)
Example #21
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
 
from django.conf.urls.defaults import include, patterns, url
from sqlalchemy.sql import asc
from Core.paconf import PA
from Core.db import session
from Core.maps import Updates, Planet, Request
from Core.robocop import push
from Arthur.context import menu, render
from Arthur.loadable import loadable, load

urlpatterns = patterns('Arthur.scans.request',
    url(r'^(?P<x>\d+)[. :\-](?P<y>\d+)[. :\-](?P<z>\d+)/(?P<type>['+"".join([type.lower() for type in PA.options("scans")])+'])/(?:(?P<dists>\d+)/)?$', 'request', name="request_planet"),
    url(r'^cancel/(?P<id>\d+)/$', 'cancel', name="request_cancel"),
    url(r'^(?P<id>\d+)/blocks/(?P<dists>\d+)/$', 'blocks', name="request_blocks"),
)

@load
class request(loadable):
    access = "half"
    def execute(self, request, user, x, y, z, type, dists):
        from Arthur.scans.list import scans
        tick = Updates.current_tick()
        type = type.upper()
        
        planet = Planet.load(x,y,z)
        if planet is None:
            return scans.execute(request, user, message="No planet with coords %s:%s:%s" %(x,y,z,))
Example #22
0
class request(loadable):
    """Request a scan"""
    alias = "req"
    usage = " <x.y.z> <scantype> [dists] | <id> blocks <amps> | cancel <id> | list | links"

    @route(loadable.planet_coord + "\s+(" + "|".join(PA.options("scans")) +
           r")\w*(?:\s+(\d+))?",
           access="member")
    @require_user
    def execute(self, message, user, params):
        planet = Planet.load(*params.group(1, 3, 5))
        if planet is None:
            message.alert("No planet with coords %s:%s:%s" %
                          params.group(1, 3, 5))
            return

        scan = params.group(6).upper()
        dists = int(params.group(7) or 0)

        request = self.request(message, user, planet, scan, dists)
        if message.get_chan() != self.scanchan():
            message.reply(
                "Requested a %s Scan of %s:%s:%s. !request cancel %s to cancel the request."
                % (
                    request.type,
                    planet.x,
                    planet.y,
                    planet.z,
                    request.id,
                ))

        scan = planet.scan(scan)
        if scan and request.tick - scan.tick < PA.getint(
                scan.scantype, "expire"):
            message.reply(
                "%s Scan of %s:%s:%s is already available from %s ticks ago: %s. !request cancel %s if this is suitable."
                % (
                    scan.scantype,
                    planet.x,
                    planet.y,
                    planet.z,
                    request.tick - scan.tick,
                    scan.link,
                    request.id,
                ))

    @robohci
    def robocop(self, message, request_id, mode):
        request = Request.load(request_id, active=False)
        if request is None:
            return

        if mode == "cancel":
            reply = "Cancelled scan request %s" % (request.id, )
            message.privmsg(reply, self.scanchan())
            nicks = CUT.get_user_nicks(request.user.name)
            for nick in nicks:
                message.privmsg(reply, nick)
            return

        if mode == "block":
            reply = "Updated request %s dists to %s" % (
                request.id,
                request.dists,
            )
            message.privmsg(reply, self.scanchan())
            nicks = CUT.get_user_nicks(request.user.name)
            for nick in nicks:
                message.privmsg(reply, nick)
            return

        user = request.user
        planet = request.target

        requester = user.name if not Config.getboolean("Misc",
                                                       "anonscans") else "Anon"
        dists_intel = planet.intel.dists if planet.intel else 0
        message.privmsg(
            "[%s] %s requested a %s Scan of %s:%s:%s Dists(i:%s/r:%s) " % (
                request.id,
                requester,
                request.type,
                planet.x,
                planet.y,
                planet.z,
                dists_intel,
                request.dists,
            ) + request.link, self.scanchan())

    def request(self, message, user, planet, scan, dists):
        request = Request(target=planet, scantype=scan, dists=dists)
        user.requests.append(request)
        session.commit()

        requester = user.name if not Config.getboolean("Misc",
                                                       "anonscans") else "Anon"
        dists_intel = planet.intel.dists if planet.intel else 0
        message.privmsg(
            "[%s] %s requested a %s Scan of %s:%s:%s Dists(i:%s/r:%s) " % (
                request.id,
                requester,
                request.type,
                planet.x,
                planet.y,
                planet.z,
                dists_intel,
                request.dists,
            ) + request.link, self.scanchan())

        return request

    @route(r"c(?:ancel)?\s+(\d+)", access="member")
    @require_user
    def cancel(self, message, user, params):
        id = params.group(1)
        request = Request.load(id)
        if request is None:
            message.reply("No open request number %s exists (idiot)." % (id, ))
            return
        if request.user is not user and not user.is_member(
        ) and not self.is_chan(message, self.scanchan()):
            message.reply(
                "Scan request %s isn't yours and you're not a scanner!" %
                (id, ))
            return

        request.active = False
        session.commit()

        reply = "Cancelled scan request %s" % (id, )
        message.reply(reply)
        if message.get_chan() != self.scanchan():
            message.privmsg(reply, self.scanchan())

        nicks = CUT.get_user_nicks(request.user.name)
        if message.get_nick() not in nicks:
            for nick in nicks:
                message.privmsg(reply, nick)

    @route(r"(\d+)\s+b(?:lock(?:s|ed)?)?\s+(\d+)", access="member")
    def blocks(self, message, user, params):
        id = params.group(1)
        dists = int(params.group(2)) + 1
        request = Request.load(id)
        if request is None:
            message.reply("No open request number %s exists (idiot)." % (id, ))
            return
        if request.user is not user and not user.is_member(
        ) and not self.is_chan(message, self.scanchan()):
            message.reply(
                "Scan request %s isn't yours and you're not a scanner!" %
                (id, ))
            return

        request.dists = max(request.dists, dists)
        session.commit()

        reply = "Updated request %s dists to %s" % (
            id,
            request.dists,
        )
        message.reply(reply)
        if message.get_chan() != self.scanchan():
            message.privmsg(reply, self.scanchan())

        nicks = CUT.get_user_nicks(request.user.name)
        if message.get_nick() not in nicks:
            for nick in nicks:
                message.privmsg(reply, nick)

    @route(r"l(?:ist)?", access="member")
    def list(self, message, user, params):
        Q = session.query(Request)
        Q = Q.filter(Request.tick > Updates.current_tick() - 5)
        Q = Q.filter(Request.active == True)
        Q = Q.order_by(asc(Request.id))

        if Q.count() < 1:
            message.reply("There are no open scan requests")
            return

        message.reply(" ".join(
            map(
                lambda request: "[%s: %s %s:%s:%s]" % (
                    request.id,
                    request.scantype,
                    request.target.x,
                    request.target.y,
                    request.target.z,
                ), Q.all())))

    @route(r"links?", access="member")
    def links(self, message, user, params):
        Q = session.query(Request)
        Q = Q.filter(Request.tick > Updates.current_tick() - 5)
        Q = Q.filter(Request.active == True)
        Q = Q.order_by(asc(Request.id))

        if Q.count() < 1:
            message.reply("There are no open scan requests")
            return

        message.reply(
            self.url(
                " ".join(
                    map(
                        lambda request: "[%s: %s]" % (
                            request.id,
                            request.link,
                        ), Q[:5])), user))

    def scanchan(self):
        return Config.get("Channels", "scans") if "scans" in Config.options(
            "Channels") else Config.get("Channels", "home")
Example #23
0
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
 
# 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
 
from django.conf.urls.defaults import include, patterns, url
from Core.paconf import PA
from Arthur.scans import list
from Arthur.scans import request

urlpatterns = patterns('Arthur.scans',
    url(r'^$', 'list.scans', name="scans"),
    url(r'^(?P<x>\d+)[. :\-](?P<y>\d+)[. :\-](?P<z>\d+)/',
        include(patterns('Arthur.scans.planet',
            url(r'^$', 'planet', name="planet_scans"),
            url(r'^(?P<types>['+"".join([type.lower() for type in PA.options("scans")])+']+)/$', "types"),
            *[url(r'^'+type.lower()+'\w*/$', "scan", {"type":type}, name="planet_scan_"+type.lower()) for type in PA.options("scans")]
        ))),
    url(r'^(?P<x>\d+)[. :\-](?P<y>\d+)/',
        include(patterns('Arthur.scans.galaxy',
            url(r'^$', 'galaxy', name="galaxy_scans"),
            url(r'^(?P<types>['+"".join([type.lower() for type in PA.options("scans")])+']+)/$', "types")
        ))),
    url('^(?P<tick>\d+)/$', 'list.tick', name="scan_tick"),
    url('^(?P<tick>\d+)/(?P<id>\w+)/$', 'planet.id', name="scan_id"),
    url('^group/(?P<id>\w+)/$', 'list.group', name="scan_group_id"),
    url('^requests/$', 'request.requests', name="requests"),
)
Example #24
0
 url(
     r'^scans?/',
     include(
         patterns(
             'Arthur.views.scans',
             url(r'^$', 'list.scans', name="scans"),
             url(
                 r'^(?P<x>\d+)[. :\-](?P<y>\d+)[. :\-](?P<z>\d+)/',
                 include(
                     patterns(
                         'Arthur.views.scans.planet',
                         url(r'^$', 'planet', name="planet_scans"),
                         url(
                             r'^(?P<types>[' + "".join([
                                 type.lower()
                                 for type in PA.options("scans")
                             ]) + ']+)/$', "types"), *[
                                 url(r'^' + type.lower() + '\w*/$',
                                     "scan", {"type": type},
                                     name="planet_scan_" + type.lower())
                                 for type in PA.options("scans")
                             ]))),
             url(
                 r'^(?P<x>\d+)[. :\-](?P<y>\d+)/',
                 include(
                     patterns(
                         'Arthur.views.scans.galaxy',
                         url(r'^$', 'galaxy', name="galaxy_scans"),
                         url(
                             r'^(?P<types>[' + "".join([
                                 type.lower()
Example #25
0
class request(loadable):
    """Request a scan"""
    alias = "req"
    usage = " <x.y.z> <scantype(s)> [dists] | <id> blocks <amps> | cancel <id> | list | links"
    
    @route(loadable.coord+"\s+(["+"".join(PA.options("scans"))+r"]+)\w*(?:\s+(\d+))?", access = "member")
    @require_user
    def execute(self, message, user, params):
        tick = Updates.current_tick()
        # Galaxy Scan
        if params.group(5) is None:

#            Access Control:
#            Uncomment this and change "group" to the lowest group that can request galscans.
#            if not user.is_group():
#                message.alert("Insufficient access for galaxy scans.")
#                return

            galaxy = Galaxy.load(*params.group(1,3))
            if galaxy is None:
                message.alert("No galaxy with coords %s:%s" % params.group(1,3))
                return
            planets = galaxy.planets
            galscan = Config.has_option("Misc", "galscans") and Config.getboolean("Misc", "galscans")
        else:
            planet = Planet.load(*params.group(1,3,5))
            if planet is None:
                message.alert("No planet with coords %s:%s:%s" % params.group(1,3,5))
                return
            planets = [planet]
            galscan = False

        # Scan Quota
        if Config.has_section("ScanQuota"):
            opts = Config.options("ScanQuota") 
            q = []
            for o in opts:
                if int(o) >= user.access:
                    q.append(int(o))
            if q:
                ScanQuota = Config.getint("ScanQuota", str(min(q)))
                reqs = session.query(Request.id).filter(Request.requester_id == user.id).filter(Request.tick == tick).count()
                if (reqs + len(planets) * len(params.group(6).upper())) > ScanQuota:
                    message.reply("This request will exceed your scan quota for this tick (%d scans remaining). " % (ScanQuota - reqs) +\
                                  "Try searching with !planet, !dev, !unit, !news, !jgp, !au.")
                    return

        dists = int(params.group(7) or 0)
        galdists = []

        mergescans = (not galscan) and (Config.has_option("Misc", "maxscans") and len(planets)*len(params.group(6)) > Config.getint("Misc", "maxscans"))

        for planet in planets:
            if galscan or mergescans:
                galdists.append(planet.intel.dists if planet.intel else 0)
                if len(galdists) < len(planets):
                    continue
            types = 0
            for scantype in params.group(6).upper():
                # Reject requests for incoming scans
                if not PA.getboolean(scantype, "request"):
                    message.alert("%s scans cannot be requested." % (PA.get(scantype, "name")))
                    continue
                types += 1
                if galscan or mergescans:
                    # Request the scans
                    for i in range(len(planets)):
                        request = self.request(message, user, planets[i], scantype, galdists[i], galscan or mergescans)
                    # Inform the requester    
                    if galscan and (message.get_chan() != self.scanchan()):
                        message.reply("Requested a Galaxy %s Scan of %s:%s. !request cancel %s:%s to cancel the request." % (request.type, planet.x, planet.y, 
                                                                                                                             request.id-len(planets)+1, request.id))
                    # Check for existing scans
                    scan = planet.scan(scantype)
                    if scan and request.tick - scan.tick < PA.getint(scantype,"expire"):
                        message.reply("%s Scan of %s:%s:%s is already available from %s ticks ago: %s. !request cancel %s if this is suitable." % (
                                                                        scantype, planet.x, planet.y, planet.z, request.tick - scan.tick, scan.link, request.id,))
                        # Cancel requests with a 0-tick old scan, if required
                        if (request.tick == scan.tick):
                            req0age = Config.getint("Misc", "req0agej") if request.scantype == "J" else Config.getint("Misc", "req0age")
                            if req0age == 1:
                               Q = session.query(Request).filter(Request.tick == request.tick).filter(Request.planet_id == request.planet_id)
                               Q = Q.filter(Request.scantype == request.scantype).filter(Request.requester_id == request.requester_id)
                               if Q.count() == 1:
                                   request.active = False
                                   message.reply("Request %s cancelled due to an existing scan. If you really need a newer one, repeat your scan request." % (request.id))
                                   message.privmsg("Cancelled scan request %s due to existing scan" % (request.id), self.scanchan())
                            elif req0age == 0:
                                request.active = False
                                message.reply("Request %s cancelled due to an existing scan." % (request.id))
                                message.privmsg("Cancelled scan request %s due to existing scan" % (request.id), self.scanchan())

                    # Tell the scanners
                    requester = user.name if not Config.getboolean("Misc", "anonscans") else "Anon"
                    if galscan:
                        message.privmsg("[%s:%s] %s requested a Galaxy %s Scan of %s:%s Max Dists(i:%s%s) " % (request.id-len(planets)+1, request.id, requester, 
                                        request.type, planet.x, planet.y, max(galdists), 
                                        "/r:%s" % dists if dists > 0 else "") + Config.get("URL", "reqgscan") % (planet.x, planet.y) , self.scanchan())
                else:
                    request = self.request(message, user, planet, scantype, dists)
                    if message.get_chan() != self.scanchan():
                        message.reply("Requested a %s Scan of %s:%s:%s. !request cancel %s to cancel the request." % (request.type, planet.x, planet.y, planet.z, request.id,))

                    # Check for existing scans
                    scan = planet.scan(scantype)
                    if scan and request.tick - scan.tick < PA.getint(scan.scantype,"expire"):
                        message.reply("%s Scan of %s:%s:%s is already available from %s ticks ago: %s. !request cancel %s if this is suitable." % (
                                                                        scantype, planet.x, planet.y, planet.z, request.tick - scan.tick, scan.link, request.id,))
                        # Cancel requests with a 0-tick old scan, if required
                        if (request.tick == scan.tick):
                            req0age = Config.getint("Misc", "req0agej") if request.scantype == "J" else Config.getint("Misc", "req0age")
                            if req0age == 1:
                               Q = session.query(Request).filter(Request.tick == request.tick).filter(Request.planet_id == request.planet_id)
                               Q = Q.filter(Request.scantype == request.scantype).filter(Request.requester_id == request.requester_id)
                               if Q.count() == 1:
                                   request.active = False
                                   message.reply("Request %s cancelled due to an existing scan. If you really need a newer one, repeat your scan request." % (request.id))
                                   message.privmsg("Cancelled scan request %s due to existing scan" % (request.id), self.scanchan())
                            elif req0age == 0:
                                request.active = False
                                message.reply("Request %s cancelled due to an existing scan." % (request.id))
                                message.privmsg("Cancelled scan request %s due to existing scan" % (request.id), self.scanchan())

            if mergescans:
                message.reply("Requested %d scans. !request cancel %s:%s to cancel the request." % (len(planets) * types, request.id-len(planets)*types+1, request.id))
                message.privmsg("[%s:%s] %s requested %d scans (%s) Max Dists(i:%s%s). !request links for details " % (request.id-len(planets)*types+1, request.id, 
                                requester, len(planets)*types, params.group(6).upper(), max(galdists), "/r:%s" % dists if dists > 0 else ""), self.scanchan())
        session.commit()
    
    @robohci
    def robocop(self, message, request_id, mode):
        request = Request.load(request_id, active=False)
        if request is None:
            return
        
        if mode == "cancel":
            reply = "Cancelled scan request %s" % (request.id,)
            message.privmsg(reply, self.scanchan())
            nicks = CUT.get_user_nicks(request.user.name)
            for nick in nicks:
                message.privmsg(reply, nick)
            return
        
        if mode == "block":
            reply = "Updated request %s dists to %s" % (request.id, request.dists,)
            message.privmsg(reply, self.scanchan())
            nicks = CUT.get_user_nicks(request.user.name)
            for nick in nicks:
                message.privmsg(reply, nick)
            return
        
        user = request.user
        planet = request.target
        
        requester = user.name if not Config.getboolean("Misc", "anonscans") else "Anon"
        dists_intel = planet.intel.dists if planet.intel else 0
        message.privmsg("[%s] %s requested a %s Scan of %s:%s:%s Dists(i:%s%s) " % (request.id, requester, request.type, planet.x,planet.y,planet.z, 
                                                        dists_intel, "/r:%s" % request.dists if request.dists > 0 else "") + request.link, self.scanchan())
    
    def request(self, message, user, planet, scan, dists, gal=False):
        request = Request(target=planet, scantype=scan, dists=dists)
        user.requests.append(request)
        session.commit()
        
        if not gal:
            requester = user.name if not Config.getboolean("Misc", "anonscans") else "Anon"
            dists_intel = planet.intel.dists if planet.intel else 0
            message.privmsg("[%s] %s requested a %s Scan of %s:%s:%s Dists(i:%s%s) " % (request.id, requester, request.type, planet.x,planet.y,planet.z, 
                                                            dists_intel, "/r:%s" % request.dists if request.dists > 0 else "") + request.link, self.scanchan())
        
        return request
    
    @route(r"c(?:ancel)?\s+(\d+(?:[: -]\d+)*)", access = "member")
    @require_user
    def cancel(self, message, user, params):
        cancel_ids = []
        reply_ids = []
        noexist = []
        noaccess = []

        for id in params.group(1).split():
            if ':' in id:
                [start,end] = id.split(':')
                cancel_ids += range(int(start), int(end)+1)
            elif '-' in id:
                [start,end] = id.split('-')
                cancel_ids += range(int(start), int(end)+1)
            else:
                cancel_ids.append(int(id))

        for id in cancel_ids:
            id = str(id)
            request = Request.load(id)
            if request is None:
                noexist.append(id)
                continue
            if request.user is not user and not user.is_member() and not self.is_chan(message, self.scanchan()):
                noaccess.append(id)
                continue
            
            request.active = False
            session.commit()

            reply = "Cancelled scan request %s" % (id)
            nicks = CUT.get_user_nicks(request.user.name)
            if message.get_nick() not in nicks:
                for nick in nicks:
                    message.privmsg(reply, nick)
            
            reply_ids.append(id)

        if len(noexist) > 0:
            message.reply("No open request number %s exists (idiot)."%(", ".join(noexist),))
        if len(noaccess) > 0:
            message.reply("Scan requests: %s aren't yours and you're not a scanner!"%(", ".join(noaccess),))
        if len(reply_ids) > 0:
            reply = "Cancelled scan request %s" % (", ".join(reply_ids))
            message.reply(reply)
            if message.get_chan() != self.scanchan():
                message.privmsg(reply, self.scanchan())
        
    
    @route(r"(\d+)\s+b(?:lock(?:s|ed)?)?\s+(\d+)", access = "member")
    def blocks(self, message, user, params):
        id = params.group(1)
        dists = int(params.group(2))+1
        request = Request.load(id)
        if request is None:
            message.reply("No open request number %s exists (idiot)."%(id,))
            return
        if request.user is not user and not user.is_member() and not self.is_chan(message, self.scanchan()):
            message.reply("Scan request %s isn't yours and you're not a scanner!"%(id,))
            return
        
        # Update Intel
        planet = request.target
        if planet.intel is None:
            planet.intel = Intel()
        planet.intel.dists = max(planet.intel.dists, dists)

        request.dists = max(request.dists, dists)
        session.commit()
        
        reply = "Updated request %s dists to %s" % (id, request.dists,)
        message.reply(reply)
        if message.get_chan() != self.scanchan():
            message.privmsg(reply, self.scanchan())
        
        nicks = CUT.get_user_nicks(request.user.name)
        if message.get_nick() not in nicks:
            for nick in nicks:
                message.privmsg(reply, nick)
    
    @route(r"l(?:ist)?", access = "member")
    def list(self, message, user, params):
        Q = session.query(func.count().label('count'), func.max(Request.id).label('max_id'))
        Q = Q.filter(Request.tick > Updates.current_tick() - 5)
        Q = Q.filter(Request.active == True)
        Q = Q.group_by(Request.planet_id, Request.scantype)
        Q = Q.order_by(asc('max_id'))
        SQ = Q.subquery()
        Q = session.query(Request, SQ.c.count).join((SQ, and_(Request.id == SQ.c.max_id)))
        
        if Q.count() < 1:
            message.reply("There are no open scan requests")
            return
        
        message.reply(" ".join(map(lambda (request, count): Config.get("Misc", "reqlist").decode("string_escape") % (request.id, request.target.intel.dists if request.target.intel else "0",
                      "/%s" % request.dists if request.dists > 0 else "", request.scantype, request.target.x, request.target.y, request.target.z,), Q.all())))
    
    @route(r"links? ?(.*)", access = "member")
    def links(self, message, user, params):
        try:
            if params.group(1) == "all":
                i=0
            else:
                i=int(params.group(1))
        except:
            i=5
            
        Q = session.query(func.count().label('count'), func.max(Request.id).label('max_id'))
        Q = Q.filter(Request.tick > Updates.current_tick() - 5)
        Q = Q.filter(Request.active == True)
        Q = Q.group_by(Request.planet_id, Request.scantype)
        Q = Q.order_by(asc('max_id'))
        SQ = Q.subquery()
        Q = session.query(Request, SQ.c.count).join((SQ, and_(Request.id == SQ.c.max_id)))
        
        if Q.count() < 1:
            message.reply("There are no open scan requests")
            return

        message.reply(self.url(" ".join(map(lambda (request, count): Config.get("Misc", "reqlinks").decode("string_escape") % (request.id, 
                      request.target.intel.dists if request.target.intel else "0", "/%s" % request.dists if request.dists > 0 else "", request.link), Q[:i] if i>0 else Q.all())), user))
    
    def scanchan(self):
        return Config.get("Channels", "scans") if "scans" in Config.options("Channels") else Config.get("Channels", "home")