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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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",
# 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)), ]
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",
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)
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)))
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)
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)
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)))
# 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")
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)
# 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,))
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")
# 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"), )
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()
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")