示例#1
0
    def post(self):
        """HTTP post method."""
        # todo: xsrf protection
        user = userinfo.get_user(self.request)
        if not user:
            self.response.out.write("Not logged in.")
            return

        try:
            # This regex is a bit sloppy but good enough.
            email = utils.get_verified_arg(re.compile("[a-z0-9_+.-]+@[a-z0-9.-]+$"), self.request, "email")
            desc = self.request.get("desc")
        except utils.InvalidValue:
            self.error(400)
            self.response.out.write('<div style="color:red">' + "Valid email address required.</div>")
            return

        user_info = user.get_user_info()
        user_info.moderator_request_email = self.request.get("email")
        user_info.moderator_request_desc = self.request.get("desc")
        if not user_info.moderator_request_admin_notes:
            user_info.moderator_request_admin_notes = ""
        user_info.moderator_request_admin_notes += "%s: Requested.\n" % datetime.datetime.isoformat(
            datetime.datetime.now()
        )
        user_info.put()

        return self.get()
示例#2
0
    def get(self):
        """HTTP get method."""
        user = userinfo.get_user(self.request)
        self.response.out.write("Login info<ul>")
        if user:
            self.response.out.write(
                "<li>Account type: %s"
                "<li>User_id: %s"
                "<li>User_info:  %s"
                "<li>Name: %s"
                "<li>Moderator: %s"
                '<li>Image: %s <img src="%s" />'
                % (
                    user.account_type,
                    user.user_id,
                    user.get_user_info(),
                    user.display_name,
                    user.get_user_info().moderator,
                    user.thumbnail_url,
                    user.thumbnail_url,
                )
            )
        else:
            self.response.out.write("<li>Not logged in.")

        self.response.out.write("<li>Total # of users: %s" % models.UserStats.get_count())

        self.response.out.write("</ul>")
        self.response.out.write(
            '<form method="POST">'
            'Userid: <input name="userid" />'
            '<input name="Test Login" type="submit" />'
            "(Blank form = logout)"
            "</form>"
        )
    def get(self):
        """HTTP get method."""
        user = userinfo.get_user(self.request)
        if not user:
            self.response.out.write('Not logged in.')
            return

        self.response.out.write('Moderator Request<ul>')

        if user.get_user_info().moderator:
            self.response.out.write('<li>You are already a moderator.')

        if user.get_user_info().moderator_request_email:
            # TODO: This is very vulnerable to html injection.
            self.response.out.write(
                '<li>We have received your request'
                '<li>Your email: %s'
                '<li>Your comments: %s' %
                (cgi.escape(user.get_user_info().moderator_request_email),
                 cgi.escape(user.get_user_info().moderator_request_desc)))

        self.response.out.write('</ul>')
        self.response.out.write(
            '<form method="POST">'
            'Your email address: <input name="email" /><br>'
            'Why you want to be a moderator: <br><textarea name="desc"></textarea>'
            '<br><input type="submit" name="submit"/>'
            '</form>')
示例#4
0
    def get(self):
        """HTTP get method."""
        user = userinfo.get_user(self.request)
        if not user:
            self.response.out.write("Not logged in.")
            return

        self.response.out.write("Moderator Request<ul>")

        if user.get_user_info().moderator:
            self.response.out.write("<li>You are already a moderator.")

        if user.get_user_info().moderator_request_email:
            # TODO: This is very vulnerable to html injection.
            self.response.out.write(
                "<li>We have received your request"
                "<li>Your email: %s"
                "<li>Your comments: %s"
                % (
                    cgi.escape(user.get_user_info().moderator_request_email),
                    cgi.escape(user.get_user_info().moderator_request_desc),
                )
            )

        self.response.out.write("</ul>")
        self.response.out.write(
            '<form method="POST">'
            'Your email address: <input name="email" /><br>'
            'Why you want to be a moderator: <br><textarea name="desc"></textarea>'
            '<br><input type="submit" name="submit"/>'
            "</form>"
        )
示例#5
0
async def on_message(message):
    """Run when a user sends a message that the bot can see."""
    if (not message.author.bot):
        did = message.author.id

        if (isinstance(message.channel, discord.DMChannel)):
            targ_server = 245830822580453376
            targ_channel = 446559630315749376
            chnl = bot.get_guild(targ_server).get_channel(targ_channel)
            msg = "%s#%s: %s" % (message.author.name,
                                 message.author.discriminator, message.content)
            await chnl.send(msg)
            logging.info("[PM] %s" % msg)
        elif (userinfo.check_cooldown(did, 'Last_Bonus', BONUS_COOLDOWN) == 0):
            user = userinfo.get_user(did)
            user.mod_fuel(setting_random('resources.passive_gain.fuel'))
            user.mod_ammo(setting_random('resources.passive_gain.ammo'))
            user.mod_steel(setting_random('resources.passive_gain.steel'))
            user.mod_bauxite(setting_random('resources.passive_gain.bauxite'))

            fleet = userinfo.UserFleet.instance(1, did)
            if (setting('features.levels_enabled') and len(fleet.ships) > 0):
                si_flag = fleet.get_ship_instances()[0]
                flag_exp = setting_random('levels.passive_flag_bonus')
                lvl = si_flag.add_exp(flag_exp)
                if (lvl):
                    await message.channel.send("**%s** - *%s* has leveled up! "
                                               "(Level %s!)"
                                               % (message.author.display_name,
                                                   si_flag.base().name,
                                                   si_flag.level))

    await bot.process_commands(message)
    def post(self):
        """HTTP post method."""
        # todo: xsrf protection
        user = userinfo.get_user(self.request)
        if not user:
            self.response.out.write('Not logged in.')
            return

        try:
            # This regex is a bit sloppy but good enough.
            email = utils.get_verified_arg(
                re.compile('[a-z0-9_+.-]+@[a-z0-9.-]+$'), self.request,
                'email')
            desc = self.request.get('desc')
        except utils.InvalidValue:
            self.error(400)
            self.response.out.write('<div style="color:red">' +
                                    'Valid email address required.</div>')
            return

        user_info = user.get_user_info()
        user_info.moderator_request_email = self.request.get('email')
        user_info.moderator_request_desc = self.request.get('desc')
        if not user_info.moderator_request_admin_notes:
            user_info.moderator_request_admin_notes = ''
        user_info.moderator_request_admin_notes += (
            '%s: Requested.\n' %
            datetime.datetime.isoformat(datetime.datetime.now()))
        user_info.put()

        return self.get()
    def get(self):
        """HTTP get method."""
        user = userinfo.get_user(self.request)
        self.response.out.write('Login info<ul>')
        if user:
            self.response.out.write(
                '<li>Account type: %s'
                '<li>User_id: %s'
                '<li>User_info:  %s'
                '<li>Name: %s'
                '<li>Moderator: %s'
                '<li>Image: %s <img src="%s" />' %
                (user.account_type, user.user_id, user.get_user_info(),
                 user.display_name, user.get_user_info().moderator,
                 user.thumbnail_url, user.thumbnail_url))
        else:
            self.response.out.write('<li>Not logged in.')

        self.response.out.write('<li>Total # of users: %s' %
                                models.UserStats.get_count())

        self.response.out.write('</ul>')
        self.response.out.write('<form method="POST">'
                                'Userid: <input name="userid" />'
                                '<input name="Test Login" type="submit" />'
                                '(Blank form = logout)'
                                '</form>')
示例#8
0
  def get(self):
    """HTTP get method."""
    user_info = userinfo.get_user(self.request)

    # synthesize GET method url from either GET or POST submission
    geturl = self.request.path + "?"
    for arg, argv in get_unique_args_from_request(self.request).items():
      geturl += urllib.quote_plus(arg) + "=" + urllib.quote_plus(argv) + "&"
    template_values = {
      'current_page' : 'POST',
      'geturl' : geturl,
      'version' : os.getenv('CURRENT_VERSION_ID'),
      'private_keys': private_keys,
      }
    load_userinfo_into_dict(user_info, template_values)

    resp = None
    recaptcha_challenge_field = self.request.get('recaptcha_challenge_field')
    if not recaptcha_challenge_field:
      self.response.out.write(render_template(POST_TEMPLATE, template_values))
      return

    recaptcha_response_field = self.request.get('recaptcha_response_field')
    resp = captcha.submit(recaptcha_challenge_field, recaptcha_response_field,
                          PK, self.request.remote_addr)
    vals = {}
    computed_vals = {}
    recaptcha_response = self.request.get('recaptcha_response_field')
    if (resp and resp.is_valid) or recaptcha_response == "test":
      vals["user_ipaddr"] = self.request.remote_addr
      load_userinfo_into_dict(user_info, vals)
      for arg, argv in get_unique_args_from_request(self.request).items():
        vals[arg] = argv
      respcode, item_id, content = posting.create_from_args(vals, computed_vals)
      # TODO: is there a way to reference a dict-value in appengine+django ?
      for key in computed_vals:
        template_values["val_"+str(key)] = str(computed_vals[key])
      template_values["respcode"] = str(respcode)
      template_values["id"] = str(item_id)
      template_values["content"] = str(content)
    else:
      template_values["respcode"] = "401"
      template_values["id"] = ""
      template_values["content"] = "captcha error, e.g. response didn't match"

    template_values["vals"] = vals
    for key in vals:
      keystr = "val_"+str(key)
      if keystr in template_values:
        # should never happen-- throwing a 500 avoids silent failures
        self.response.set_status(500)
        self.response.out.write("internal viewserror: duplicate template key")
        logging.error('views.post_view duplicate template key: %s' % keystr)
        return
      template_values[keystr] = str(vals[key])
    self.response.out.write(render_template(POST_RESULT_TEMPLATE,
                                            template_values))
示例#9
0
 def decorate(self):
   if not getattr(self, 'user', None):
     self.user = userinfo.get_user(self.request)
   self.usig = userinfo.get_usig(self.user)
   if self.usig != self.request.get('usig'):
     self.error(403)
     logging.warning('views.require_usig XSRF attempt %s!=%s',
                     self.usig, self.request.get('usig'))
     return
   return handler_method(self)
示例#10
0
 def decorate(self):
   if not getattr(self, 'user', None):
     self.user = userinfo.get_user(self.request)
   if not self.user:
     self.error(401)
     self.response.out.write('<html><body>Please log in.</body></html>')
     return
   if (not self.user.get_user_info() or
       not self.user.get_user_info().moderator):
     self.error(403)
     self.response.out.write('<html><body>Permission denied.</body></html>')
     logging.warning('views.require_moderator non-moderator blacklist attempt')
     return
   return handler_method(self)
示例#11
0
async def craft(ctx, fuel: int, ammo: int, steel: int, bauxite: int):
    """Craft a random ship based on the user's inputted resources."""
    did = ctx.author.id
    user = userinfo.get_user(did)
    if (not setting('features.crafting_enabled') or not setting('features.resources_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    if (userinfo.has_space_in_inventory(did)):
        cd = userinfo.check_cooldown(
            did, 'Last_Craft', CRAFTING_COOLDOWN, set_if_off=False)
        if (cd == 0):
            min_craft = setting('resources.min_crafting')
            if (fuel >= min_craft[0] and ammo >= min_craft[1] and
                    steel >= min_craft[2] and bauxite >= min_craft[3]):
                if (user.has_enough(fuel, ammo, steel, bauxite)):
                    craft = craftinghandler.get_craft_from_resources(
                        did, fuel, ammo, steel, bauxite)
                    user.mod_fuel(-fuel)
                    user.mod_ammo(-ammo)
                    user.mod_steel(-steel)
                    user.mod_bauxite(-bauxite)
                    inv = userinfo.get_user_inventory(did)
                    inv.add_to_inventory(craft)
                    # set cooldown
                    userinfo.check_cooldown(
                        did, 'Last_Craft', CRAFTING_COOLDOWN, set_if_off=True)
                    image_file = imggen.generate_ship_card(ctx.bot, craft)
                    ship_base = craft.base()
                    await ctx.send(
                        file=discord.File(io.BytesIO(image_file.getvalue()),
                                          filename="image.png"),
                        content="%s just crafted %s!\n\n%s: *%s*" % (
                            ctx.author.display_name, ship_base.name,
                            ship_base.name, ship_base.get_quote('intro')))
                    logging.info("[Craft] %s (%s) crafted %s using recipe "
                                 "%s/%s/%s/%s" %
                                 (str(ctx.author), did, ship_base.name,
                                  fuel, ammo, steel, bauxite))
                else:
                    await ctx.send("Not enough resources!")
            else:
                await ctx.send("Use at least 30 of each resource")
        else:
            min = cd // 60
            sec = cd % 60
            await ctx.send("You have %dm%02ds remaining until you can craft "
                           "another ship" % (min, sec))
    else:
        await ctx.send(namesub("Your inventory is full! You can scrap a <ship.title> with "
                       "`%sscrap [<ship.title> ID]`") % COMMAND_PREFIX)
示例#12
0
async def scrap(ctx, shipid: int):
    """Scrap the given ship from the user's inventory."""
    did = ctx.author.id
    user = userinfo.get_user(did)
    inv = userinfo.get_user_inventory(did)
    ins = [x for x in inv.inventory if x.invid == shipid]
    if (len(ins) > 0):
        ship_instance = ins.pop()
        base = ship_instance.base()
        user.mod_fuel(setting_random('resources.scrap_gain.fuel'))
        user.mod_ammo(setting_random('resources.scrap_gain.ammo'))
        user.mod_steel(setting_random('resources.scrap_gain.steel'))
        user.mod_bauxite(setting_random('resources.scrap_gain.bauxite'))
        inv.remove_from_inventory(shipid)
        await ctx.send("Scrapped %s... <:roosad:434916104268152853>" % (
            base.name))
        logging.info("[Scrap] %s (%s) scrapped ship %s with inv id %s" %
                     (str(ctx.author), did, base.name, shipid))
    else:
        await ctx.send(namesub("<ship.title> with ID %s not found in your inventory") % (
            shipid))
示例#13
0
def get_default_template_values(request, current_page):
  """for debugging login issues"""
  no_login = (request.get('no_login') == "1")

  version = request.get('dbgversion')
  # don't allow junk
  if not version or not re.search(r'^[0-9a-z._-]+$', version):
    version = os.getenv('CURRENT_VERSION_ID')

  template_values = {
    'user' : userinfo.get_user(request),
    'current_page' : current_page,
    'host' : urllib.quote(request.host_url),
    'path' : request.path,
    'version' : version,
    'no_login' : no_login,
    'optimize_page' : optimize_page_speed(request),
    'view_url': request.url,
    }
  load_userinfo_into_dict(template_values['user'], template_values)
  campaign_id = request.get('campaign_id')
  if campaign_id:
    template_values['campaign_id'] = campaign_id
  return template_values
示例#14
0
async def marry(ctx, shipid: int):
    """Allow the user to marry a level 99 ship, increasing its level cap."""
    if (not setting('features.marriage_enabled') or not setting('features.levels_enabled')):
        await ctx.send("This feature is not enabled.")
    did = ctx.author.id
    user = userinfo.get_user(did)
    inv = userinfo.get_user_inventory(did)
    ins = [x for x in inv.inventory if x.invid == shipid]
    if (len(ins) > 0):
        ship_instance = ins.pop()
        base = ship_instance.base()
        if (ship_instance.level == setting('levels.level_cap')):
            ring_req = setting('levels.marriage_ring_required')
            rings = user.rings
            if (rings > 0 or not ring_req):
                ship_instance.level = setting('levels.level_cap') + 1
                ship_instance.exp = 0
                ship_instance.add_exp(0)
                if (ring_req):
                    user.use_ring()
                ship_name = base.name
                image_file = imggen.generate_ship_card(ctx.bot, ship_instance)
                await ctx.send(file=discord.File(
                    io.BytesIO(image_file.getvalue()), filename="image.png"),
                               content="%s: *%s*" % (ship_name,
                                                     base.get_quote('married')
                                                     ))
                logging.info("[Marriage] %s (%s) married their %s" %
                             (str(ctx.author), did, ship_name))
            else:
                await ctx.send("You don't have any more rings.")
        else:
            await ctx.send("%s isn't ready for marriage yet." % (base.name))
    else:
        await ctx.send(namesub("<ship.title> with ID %s not found in your inventory") % (
            shipid))
示例#15
0
def get_default_template_values(request, current_page):
    """for debugging login issues"""
    no_login = (request.get('no_login') == "1")

    version = request.get('dbgversion')
    # don't allow junk
    if not version or not re.search(r'^[0-9a-z._-]+$', version):
        version = os.getenv('CURRENT_VERSION_ID')

    template_values = {
        'user': userinfo.get_user(request),
        'current_page': current_page,
        'host': urllib.quote(request.host_url),
        'path': request.path,
        'version': version,
        'no_login': no_login,
        'optimize_page': optimize_page_speed(request),
        'view_url': request.url,
    }
    load_userinfo_into_dict(template_values['user'], template_values)
    campaign_id = request.get('campaign_id')
    if campaign_id:
        template_values['campaign_id'] = campaign_id
    return template_values
示例#16
0
def generate_inventory_screen(member, page, only_dupes=False):
    """Return a BytesIO object of the user's inventory image.

    Parameters
    ----------
    member : discord.Member
        The user to generate the inventory of.
    page : int
        The page to show.
    only_dupes : bool
        If True, only display ships which the user has two or more of.
    """
    discord_id = member.id
    user = userinfo.get_user(discord_id)
    inv = userinfo.get_user_inventory(discord_id)
    layout = CONFIG_DATA['inventory']
    w, h = layout['image_size']
    antialias_value = 2
    w *= antialias_value
    h *= antialias_value
    sx, sy = layout['per_row'], layout['per_column']
    cw = int(w / sx)
    ch = int(h / sy)
    h += layout['lower_padding'] * antialias_value

    ship_pool = inv.inventory
    if (only_dupes):
        new_pool = []
        first_bases = {}
        for s in ship_pool:
            first_bases[s.sid] = s.base().get_first_base()
        for i in range(len(ship_pool)):
            s = ship_pool.pop(0)
            if (first_bases[s.sid].sid in map(lambda x:
                                              first_bases[x.sid].sid, new_pool)
                or first_bases[s.sid].sid in map(lambda x:
                                                 first_bases[x.sid].sid,
                                                 ship_pool)):
                new_pool.append(s)
        ship_pool = new_pool

    ships_per_page = sx * sy
    pages_needed = (len(ship_pool) // ships_per_page) + \
        (0 if len(ship_pool) % ships_per_page == 0 and len(ship_pool) > 0
         else 1)
    if (page < 1):
        page = 1
    elif (page > pages_needed):
        page = pages_needed

    img = Image.new(size=(w, h), mode="RGB", color=(255, 255, 255))

    draw = ImageDraw.Draw(img)
    shade = False
    indx = 0
    indx += (ships_per_page * (page - 1))
    for xi in range(sx):
        for yi in range(sy):
            ship = ship_pool[indx] if indx < len(ship_pool) else None

            shade_color = (("filled_color1" if shade else "filled_color2")
                           if ship else ("empty_color1" if shade else "empty_color2"))
            rbg = None

            if (ship):
                rbg = ship_stats.get_rarity_backdrop(ship.base().rarity)
                rbg = rbg.resize((cw, ch))
                fleet = userinfo.UserFleet.instance(1, discord_id)
                if (ship.invid in fleet.ships):
                    flag = fleet.ships.index(ship.invid) == 0
                    if flag:
                        shade_color = 'flag_border_color'
                    else:
                        shade_color = "fleet_color1" if shade else "fleet_color2"
                elif (ship.base().has_seasonal_cg()):
                    shade_color = "seasonal_color1" if shade else "seasonal_color2"

            shade_color = tuple(layout[shade_color])

            x, y = (xi * cw, yi * ch)
            draw.rectangle((x, y, x + cw, y + ch), fill=shade_color)
            if (rbg):
                img.paste(rbg, (x, y))
            if (ship):
                base = ship.base()
                font = ImageFont.truetype("fonts/trebucbd.ttf", ch * 1 // 2)
                num_str = "%s-%04d" % (base.stype, ship.invid)
                draw_squish_text(img, (x + cw * 3 // 4, y + ch * 1 // 4), num_str,
                                 font, cw * 7 // 16 - 2, color=(0, 0, 0))

                if (setting('features.levels_enabled')):
                    if (setting('features.marriage_enabled') and ship.level > setting('levels.level_cap')):
                        ring = Image.open(small_ico_ring_img)
                        ring = ring.resize((ch // 3 - 4, ch // 3 - 4))
                        ring_loc = (x + cw * 8 // 9 - 2, y + ch * 5 // 8 + 2)
                        draw.ellipse(
                            (ring_loc, tuple(map(sum, zip(ring_loc, ring.size)))), fill=(0, 0, 0))
                        img.paste(ring, ring_loc, mask=ring)
                    font = ImageFont.truetype(
                        "fonts/trebucbd.ttf", ch * 3 // 8)
                    lvl_str = "Lv. %02d" % (ship.level)
                    draw_squish_text(img, (x + 2 + cw * 11 // 16, y + ch * 3 // 4 - 2),
                                     lvl_str, font, cw // 3 - 4, color=(0, 0, 0))
                    if (ship.is_remodel_ready()):
                        draw.rectangle((x + cw // 2 + 2, y + ch * 9 // 16, x + cw * 31 // 32, y + ch * 15 // 16),
                                       outline=(50, 0, 250), width=2)

                cir_start_x = x + 3
                cir_start_y = y + 3
                use_damaged = False  # TODO check if use damaged image
                ico = base.get_cg(ico=True, dmg=use_damaged)
                ico = ico.resize((int(ch * 1.5) - 6, ch - 6), Image.BILINEAR)
                pxls = ico.load()
                grad_start = int(ico.size[0] * 0.75)
                grad_end = ico.size[0]
                for ix in range(grad_start, grad_end):
                    for iy in range(ico.size[1]):
                        fade_amt = (ix - grad_start) / (grad_end - grad_start)
                        fade_amt *= fade_amt
                        new_alpha = int(pxls[ix, iy][3] * (1 - fade_amt))
                        pxls[ix, iy] = pxls[ix, iy][:3] + (new_alpha,)
                img.paste(ico, (cir_start_x, cir_start_y), ico)

                draw.rectangle((x, y, x + cw - 1,
                                y + ch - 1), outline=shade_color, width=3)
            shade = not shade
            indx += 1
        if(sy % 2 == 0):
            shade = not shade

    draw = ImageDraw.Draw(img)
    # start position of footer
    x, y = (0, layout['image_size'][1] * antialias_value)
    fw, fh = (w, layout['lower_padding'] * antialias_value)  # size of footer

    display_name = "%s#%s" % (member.name, member.discriminator)
    font = ImageFont.truetype("fonts/framd.ttf", fh * 3 // 4)
    o_txt = namesub("<ship_plural.title>") if not only_dupes else "Dupes"
    draw.text((x + 10, y + fh // 8), "%s's %s" % (display_name, o_txt),
              font=font, fill=(0, 0, 0))

    font = ImageFont.truetype("fonts/framdit.ttf", fh // 2)
    pg_txt = "Page %s of %s" % (page, pages_needed)
    pgw, pgh = draw.textsize(pg_txt, font=font)
    pgx, pgy = (fw - pgw - 2, y + fh - pgh - 2)
    draw.text((pgx, pgy), pg_txt, font=font, fill=(50, 50, 50))

    font = ImageFont.truetype("fonts/trebucbd.ttf", fh * 3 // 8)
    rsc_x, rsc_y = (fw * 21 // 32, y + 1)

    txt_fuel = "%05d" % (user.fuel)
    txt_ammo = "%05d" % (user.ammo)
    txt_steel = "%05d" % (user.steel)
    txt_bauxite = "%05d" % (user.bauxite)
    txt_ships = "%03d / %03d" % (len(ship_pool), user.shipslots)
    txt_rings = "%01d" % (user.rings)

    txt_w, txt_h = draw.textsize(txt_fuel, font)

    ico_size = (fh * 3 // 8 + 2, fh * 3 // 8 + 2)
    if (setting('features.resources_enabled')):
        ico_fuel = Image.open(DIR_PATH + '/icons/fuel.png').resize(ico_size,
                                                                   Image.LINEAR)
        ico_ammo = Image.open(DIR_PATH + '/icons/ammo.png').resize(ico_size,
                                                                   Image.LINEAR)
        ico_steel = Image.open(DIR_PATH + '/icons/steel.png').resize(ico_size,
                                                                     Image.LINEAR)
        ico_bauxite = Image.open(DIR_PATH + '/icons/bauxite.png') \
            .resize(ico_size, Image.LINEAR)
    ico_ships = Image.open(DIR_PATH + '/icons/ship.png').resize(ico_size,
                                                                Image.LINEAR)
    if (setting('features.marriage_enabled') and setting('levels.marriage_ring_required')):
        ico_rings = Image.open(DIR_PATH + '/icons/marriagepapers.png') \
            .resize(ico_size, Image.LINEAR)

    x_off = ico_size[0] + txt_w + 6
    y_off = ico_size[1] + 2
    toff_x, toff_y = (ico_size[0] + 2, (ico_size[1] - txt_h) // 2)

    if (setting('features.resources_enabled')):
        draw.text((rsc_x + toff_x, rsc_y + toff_y), txt_fuel, font=font,
                  fill=(0, 0, 0))
        draw.text((rsc_x + toff_x, rsc_y + toff_y + y_off), txt_ammo, font=font,
                  fill=(0, 0, 0))
        draw.text((rsc_x + toff_x + x_off, rsc_y + toff_y), txt_steel, font=font,
                  fill=(0, 0, 0))
        draw.text((rsc_x + toff_x + x_off, rsc_y + toff_y + y_off), txt_bauxite,
                  font=font, fill=(0, 0, 0))
    draw.text((rsc_x + toff_x + x_off * 2, rsc_y + toff_y), txt_ships,
              font=font, fill=(0, 0, 0))
    if (setting('features.marriage_enabled') and setting('levels.marriage_ring_required')):
        draw.text((rsc_x + toff_x + int(x_off * 3.5), rsc_y + toff_y), txt_rings,
                  font=font, fill=(0, 0, 0))

    if (setting('features.resources_enabled')):
        img.paste(ico_fuel, (rsc_x, rsc_y), mask=ico_fuel)
        img.paste(ico_ammo, (rsc_x, rsc_y + y_off), mask=ico_fuel)
        img.paste(ico_steel, (rsc_x + x_off, rsc_y), mask=ico_fuel)
        img.paste(ico_bauxite, (rsc_x + x_off, rsc_y + y_off), mask=ico_fuel)
    img.paste(ico_ships, (rsc_x + x_off * 2, rsc_y), mask=ico_ships)
    if (setting('features.marriage_enabled') and setting('levels.marriage_ring_required')):
        img.paste(ico_rings, (rsc_x + int(x_off * 3.5), rsc_y), mask=ico_rings)

    img = img.resize((w // antialias_value, h //
                      antialias_value), Image.ANTIALIAS)

    r = io.BytesIO()
    img.save(r, format="PNG")
    return r
示例#17
0
async def train(ctx, dif: int=-1):
    """Train a user's fleet given the difficulty, or show training options."""
    did = ctx.author.id
    difs = fleet_training.ALL_DIFFICULTIES
    if (not setting('features.training_enabled') or not setting('features.levels_enabled')
            or not setting('features.fleets_enabled')):
        await ctx.send("That feature is not enabled.")
        return
    if (dif == -1):
        description = "Difficulties:\n"
        description += "\n".join([namesub("#%s. %s: Min <flagship> level %s, Recommended"
                                  " <fleet> level %s.") % (x + 1,
                                                           difs[x].name,
                                                           difs[x].min_flag,
                                                           difs[x].avg_lvl)
                                  for x in range(len(difs))])
        footer = "Type %strain (#) to train a fleet with a difficulty" % (
            COMMAND_PREFIX)
        embed = discord.Embed(title=namesub("<fleet.title> Training"), description=description)
        embed.set_footer(text=footer)

        await ctx.send(embed=embed)
    else:
        if (dif > 0 and dif <= len(difs)):
            dif_targ = difs[dif - 1]
            fleet = userinfo.UserFleet.instance(1, did)
            if (len(fleet.ships) > 0):
                ins = fleet.get_ship_instances()
                flag = ins[0]
                if (flag.level >= dif_targ.min_flag):
                    rsc = dif_targ.resource_costs(fleet)
                    rsc = tuple(map(int, rsc))
                    user = userinfo.get_user(did)
                    if (user.has_enough(*rsc)):
                        cd = userinfo.check_cooldown(
                            did, "Last_Training", TRAINING_COOLDOWN)
                        if (cd == 0):
                            # conditions passed
                            rank = dif_targ.rank_training(fleet)

                            exp_rew_base = rank.exp_mult \
                                * dif_targ.exp_reward_base
                            exp_rew_split = rank.exp_mult \
                                * dif_targ.exp_reward_split

                            exp = [exp_rew_base] * len(ins)
                            exp_per = exp_rew_split // len(ins) + 1
                            exp[0] += exp_per
                            exp = list(map(lambda x: x + exp_per, exp))

                            lvl_dif = [x.level for x in ins]
                            for i in range(len(ins)):
                                ins[i].add_exp(exp[i])
                                lvl_dif[i] = ins[i].level - lvl_dif[i]

                            user.mod_fuel(-rsc[0])
                            user.mod_ammo(-rsc[1])
                            user.mod_steel(-rsc[2])
                            user.mod_bauxite(-rsc[3])

                            embed = discord.Embed(title="Training %s" % (
                                "Success" if rank.is_success else "Failed"))
                            embed.color = 65280 if rank.is_success \
                                else 16711680
                            embed.description = "Rank %s | %s Difficulty" % (
                                rank.symbol, dif_targ.name)
                            flag = ins.pop(0)
                            embed.add_field(name="EXP Gain", value=flag.base(
                            ).name + " (*)\n" + "\n".join([x.base().name
                                                           for x in ins]),
                                                           inline=True)
                            embed.add_field(
                                name="--------", value="\n".join(["+%g EXP" % x
                                                                  for x in exp]
                                                                 ))
                            ins.insert(0, flag)
                            embed.add_field(name="--------", value="\n".join(
                                ["Level %s (+%s)" % (ins[i].level, lvl_dif[i])
                                 for i in range(len(ins))]))
                            if (setting('features.resources_enabled')):
                                embed.set_footer(
                                    text=namesub("Used %g <fuel>, %g <ammo>, %g <steel>, %g "
                                                 "<bauxite>") % rsc)

                            await ctx.send(embed=embed)
                            logging.info("[Training] %s (%s) completed "
                                         "training level %s with rank %s" % (
                                            str(ctx.author), did,
                                            dif_targ.name,
                                            rank.symbol))
                        else:
                            hrs = cd // 3600
                            min = cd // 60 % 60
                            sec = cd % 60
                            await ctx.send(namesub("You have %dh%02dm%02ds remaining "
                                                   "until you can train your <fleet> "
                                                   "again") % (hrs, min, sec))
                    else:
                        await ctx.send(namesub("Not enough resources! (Required: %g "
                                       "<fuel>, %g <ammo>, %g <steel>, %g <bauxite>)")
                                       % rsc)
                else:
                    await ctx.send(namesub("<flagship.title> isn't a high enough level! "
                                   "(Needs to be at least %s)") % (
                                       dif_targ.min_flag))
            else:
                await ctx.send(namesub("<fleet.title> %s is empty!") % (1))
        else:
            await ctx.send("No such difficulty #%s" % dif)
示例#18
0
  def post(self):
    """HTTP POST method."""
    if self.request.get('type') != 'star':
      self.error(400)  # Bad request
      return

    user = userinfo.get_user(self.request)
    opp_id = self.request.get('oid')
    base_url = self.request.get('base_url')
    new_value = self.request.get('i')

    if not user:
      logging.warning('views.action_view No user.')
      self.error(401)  # Unauthorized
      return

    if not opp_id or not base_url or not new_value:
      logging.warning('views.action_view bad param')
      self.error(400)  # Bad request
      return

    new_value = int(new_value)
    if new_value != 0 and new_value != 1:
      self.error(400)  # Bad request
      return

    xsrf_header_found = False
    for h, v in self.request.headers.iteritems():
      if h.lower() == 'x-requested-with' and v == 'XMLHttpRequest':
        xsrf_header_found = True
        break

    if not xsrf_header_found:
      self.error(400)
      logging.warning('views.action_view Attempted XSRF.')
      return

    user_entity = user.get_user_info()
    user_interest = models.UserInterest.get_or_insert(
      models.UserInterest.make_key_name(user_entity, opp_id),
      user=user_entity, opp_id=opp_id, liked_last_modified=datetime.now())

    if not user_interest:
      self.error(500)  # Server error.
      return

    # Populate VolunteerOpportunity table with (opp_id,base_url)
    # TODO(paul): Populate this more cleanly and securely, not from URL params.
    key = models.VolunteerOpportunity.DATASTORE_PREFIX + opp_id
    info = models.VolunteerOpportunity.get_or_insert(key)
    if info.base_url != base_url:
      info.base_url = base_url
      info.last_base_url_update = datetime.now()
      info.base_url_failure_count = 0
      info.put()

    # pylint: disable-msg=W0612
    (unused_new_entity, deltas) = \
      modelutils.set_entity_attributes(user_interest,
                                 { models.USER_INTEREST_LIKED: new_value },
                                 None)

    if deltas is not None:  # Explicit check against None.
      success = models.VolunteerOpportunityStats.increment(opp_id, deltas)
      if success:
        self.response.out.write('ok')
        return

    self.error(500)  # Server error.