Esempio n. 1
0
def loadLegacy(id):
    """Load a user from the old file format"""
    with open(userdb.userdbpath / f"{id}.txt", "r") as f:
        # Make array of lines from file.
        lines = f.read().splitlines()
    lines = [line.strip() for line in lines]

    userdata = userdb.User()
    userdata.id = id
    userdata.nickname = lines[NICK]
    userdata.display = lines[DISP]
    if lines[CHEI] != "None":
        userdata.height = lines[CHEI]
        userdata.height /= Decimal("1e6")
    if lines[BHEI] != "None":
        userdata.baseheight = lines[BHEI]
        userdata.baseheight /= Decimal("1e6")
    if lines[BWEI] != "None":
        userdata.baseweight = lines[BWEI] * lines[DENS]     # Drop density, and instead update base weight to match
        userdata.baseweight /= Decimal("1e3")
    userdata.unitsystem = lines[UNIT]
    if lines[SPEC] != "None":
        userdata.species = lines[SPEC]

    return userdata
Esempio n. 2
0
def loadLegacy(path):
    """Load a user from the old file format"""
    with open(path, "r", encoding = "utf-8") as f:
        # Make array of lines from file.
        lines = f.read().splitlines()
    lines = [line.strip() for line in lines]
    if len(lines) < 8:
        raise BadLegacyUser(f"Bad legacy user file: {path}")
    uid = path.stem

    userdata = userdb.User()
    userdata.guildid = 350429009730994199
    userdata.id = uid
    userdata.nickname = lines[NICK]
    userdata.display = False if lines[DISP].lower() == "n" else True
    if lines[CHEI] != "None":
        userdata.height = Decimal(lines[CHEI])
        userdata.height /= Decimal("1e6")
    if lines[BHEI] != "None":
        userdata.baseheight = Decimal(lines[BHEI])
        userdata.baseheight /= Decimal("1e6")
    if lines[BWEI] != "None":
        userdata.baseweight = Decimal(lines[BWEI]) * Decimal(lines[DENS])  # Drop density, and instead update base weight to match
        userdata.baseweight /= Decimal("1e3")
    userdata.unitsystem = lines[UNIT]
    if lines[SPEC] != "None":
        userdata.species = lines[SPEC]

    return userdata
Esempio n. 3
0
    def __init__(self, userdata1, userdata2):
        smallUserdata, bigUserdata = utils.minmax(userdata1, userdata2)
        self.big = PersonStats(bigUserdata)
        self.small = PersonStats(smallUserdata)
        self.multiplier = self.big.height / self.small.height

        bigToSmallUserdata = userdb.User()
        bigToSmallUserdata.height = bigUserdata.height * self.small.viewscale
        self.bigToSmall = PersonStats(bigToSmallUserdata)

        smallToBigUserdata = userdb.User()
        smallToBigUserdata.height = smallUserdata.height * self.big.viewscale
        self.smallToBig = PersonStats(smallToBigUserdata)

        viewangle = calcViewAngle(self.small.height, self.big.height)
        self.lookangle = abs(viewangle)
        self.lookdirection = "up" if viewangle >= 0 else "down"
Esempio n. 4
0
def getUserdata(memberOrSV, nickname="Raw"):
    if nickname is None:
        nickname = "Raw"
    if isinstance(memberOrSV, discord.Member):
        userdata = userdb.load(memberOrSV.guild.id, memberOrSV.id)
    else:
        userdata = userdb.User()
        userdata.nickname = nickname
        userdata.height = memberOrSV
    return userdata
Esempio n. 5
0
def getUserdata(memberOrSV, nickname = None, *, allow_unreg=False):
    if isinstance(memberOrSV, discord.Member):
        userdata = userdb.load(memberOrSV.guild.id, memberOrSV.id, member=memberOrSV, allow_unreg=allow_unreg)
    else:
        userdata = userdb.User()
        userdata.height = memberOrSV
        if nickname is None:
            nickname = f"a {userdata.height:,.3mu} person"
        userdata.nickname = nickname
    return userdata
Esempio n. 6
0
def getPlayerData(guild: int, player: str) -> userdb.User:
    if guild not in current_games:
        raise NoGameFoundError
    if player not in current_games[guild].royale.players or player is None:
        raise NoPlayerFoundError(player)

    userdata = userdb.User()
    p = current_games[guild].royale.players[player]

    userdata.baseheight = p.baseheight
    userdata.baseweight = defaultweight * ((p.baseheight / defaultheight)**3)
    userdata.height = p.height
    userdata.nickname = p.name
    userdata.gender = p.gender
    if "paw" in p.attributes or "paws" in p.attributes:
        userdata.pawtoggle = True
    if "fur" in p.attributes:
        userdata.furtoggle = True
    if "tail" in p.attributes:
        userdata.taillength = p.height * Decimal("94169/150000")

    return userdata
Esempio n. 7
0
    async def register(self, ctx):
        # nick: str
        # currentheight: SV = proportions.defaultheight
        # baseheight: SV = proportions.defaultheight
        # baseweight: WV = userdb.defaultweight
        # unitsystem: str = "m"
        # species: str = None
        """Registers a user for SizeBot."""

        userdata = None
        try:
            userdata = userdb.load(ctx.guild.id,
                                   ctx.author.id,
                                   allow_unreg=True)
        except errors.UserNotFoundException:
            userdata = None

        # User data already exists
        if userdata:
            if userdata.registered:
                await ctx.send(
                    "Sorry! You already registered with SizeBot.\n"
                    f"To unregister, use the `{conf.prefix}unregister` command."
                )
            else:
                await showNextStep(ctx, userdata)
            return

        # User is already in different guilds, offer to copy profile to this guild?
        guilds = [
            self.bot.get_guild(g)
            for g, _ in userdb.listUsers(userid=ctx.author.id)
        ]
        guilds = [g for g in guilds if g is not None]
        guilds_names = [g.name for g in guilds]
        if guilds_names:
            guildsstring = "\n".join(guilds_names)
            sentMsg = await ctx.send(
                f"You are already registered with SizeBot in these servers:\n{guildsstring}\n"
                f"You can copy a profile from one of these guilds to this one using `{ctx.prefix}copy.`\n"
                "Proceed with registration anyway?")
            await sentMsg.add_reaction(emojis.check)
            await sentMsg.add_reaction(emojis.cancel)

            # Wait for requesting user to react to sent message with emojis.check or emojis.cancel
            def check(reaction, reacter):
                return reaction.message.id == sentMsg.id \
                    and reacter.id == ctx.author.id \
                    and (
                        str(reaction.emoji) == emojis.check
                        or str(reaction.emoji) == emojis.cancel
                    )

            try:
                reaction, ctx.author = await self.bot.wait_for("reaction_add",
                                                               timeout=60.0,
                                                               check=check)
            except asyncio.TimeoutError:
                # User took too long to respond
                await sentMsg.delete()
                return

            # if the reaction isn't the right one, stop.
            if reaction.emoji != emojis.check:
                return

        telemetry.RegisterStarted(ctx.guild.id, ctx.author.id).save()
        userdata = userdb.User()
        userdata.guildid = ctx.guild.id
        userdata.id = ctx.author.id
        userdata.nickname = ctx.author.display_name
        userdata.display = False
        if ctx.me.guild_permissions.manage_nicknames:
            userdata.display = True
            if any(c in ctx.author.display_name for c in "()[]"):
                await ctx.send(
                    f"If you have already have a size tag in your name, you can fix your nick with `{conf.prefix}setnick`."
                )
        userdata.registration_steps_remaining = [
            "setheight", "setweight", "setsystem"
        ]

        # TODO: If the bot has MANAGE_NICKNAMES permission but can't change this user's permission, let the user know
        # TODO: If the bot has MANAGE_NICKNAMES permission but can't change this user's permission, and the user is an admin, let them know they may need to fix permissions

        userdb.save(userdata)

        await addUserRole(ctx.author)

        logger.warn(f"Started registration for a new user: {ctx.author}!")
        logger.info(userdata)

        # user has display == "y" and is server owner
        if userdata.display and userdata.id == ctx.author.guild.owner.id:
            await ctx.send(
                "I can't update a server owner's nick. You'll have to manage it manually."
            )

        await ctx.send("Initial registration completed!")
        await showNextStep(ctx, userdata)
Esempio n. 8
0
    async def advancedregister(self,
                               ctx,
                               nick: str,
                               currentheight: SV = proportions.defaultheight,
                               baseheight: SV = proportions.defaultheight,
                               baseweight: WV = userdb.defaultweight,
                               unitsystem: str = "m",
                               species: str = None):
        """Registers a user for SizeBot, legacy style.

        Parameters:
        • `nick`: Your nickname. This will be the first thing displayed in your nickname. For a nickname with spaces, this must be wrapped in quotes.
        • `currentheight`: Self-explnatory.
        • `baseheight`: The default height of your character. It is recommended that this is a vaugely reasonable, human-like value, for instance your IRL height, except in rare circumnstances (for instance, if your character is a cat, or an orc, etc.)
        • `baseweight`: The default weight of your character. All the recommendations for baseheight apply here.
        • `unitsystem`: The unit system your size tag, and basic versions of your stats, will be displayed in by default. Accepts `M` for Metric, and `U` or `I` for U.S./Imperial.
        • `species`: Optional, a string to be appened after your size in your sizetag. Appears in the format `<nick> [<size>, <species>]`. If `species` is to contain a space, wrap it in quotes.

        Measurement parameters can accept a wide variety of units, as listed in `&units`.

        Examples:
        `&register DigiDuncan 0.5in 5'7.5 120lb U`
        `&register Surge 11ft 5'8 140lb U Raichu`
        `&register "Speck Boi" 0.1mm 190cm 120kg M`
        """
        readable = f"CH {currentheight}, BH {baseheight}, BW {baseweight}"
        logger.warn(f"New user attempt! Nickname: {nick}")
        logger.info(readable)

        # Already registered
        if userdb.exists(ctx.guild.id, ctx.author.id):
            await ctx.send("Sorry! You already registered with SizeBot.\n"
                           "To unregister, use the `&unregister` command.")
            logger.warn(
                f"User already registered on user registration: {ctx.author}.")
            return

        guilds = [
            self.bot.get_guild(g)
            for g, _ in userdb.listUsers(userid=ctx.author.id)
        ]
        guilds = [g for g in guilds if g is not None]
        guilds_names = [g.name for g in guilds]
        if guilds_names != []:
            guildsstring = "\n".join(guilds_names)
            sentMsg = await ctx.send(
                f"You are already registered with SizeBot in these servers:\n{guildsstring}\n"
                f"You can copy a profile from one of these guilds to this one using `{ctx.prefix}copy.`\n"
                "Proceed with registration anyway?")
            await sentMsg.add_reaction(emojis.check)
            await sentMsg.add_reaction(emojis.cancel)

            # Wait for requesting user to react to sent message with emojis.check or emojis.cancel
            def check(reaction, reacter):
                return reaction.message.id == sentMsg.id \
                    and reacter.id == ctx.author.id \
                    and (
                        str(reaction.emoji) == emojis.check
                        or str(reaction.emoji) == emojis.cancel
                    )

            reaction = None
            try:
                reaction, ctx.author = await self.bot.wait_for("reaction_add",
                                                               timeout=60.0,
                                                               check=check)
            except asyncio.TimeoutError:
                # User took too long to respond
                await sentMsg.delete()

            # if the reaction isn't the right one, stop.
            if reaction.emoji != emojis.check:
                return

        # Invalid size value
        if (currentheight <= 0 or baseheight <= 0 or baseweight <= 0):
            logger.warn("Invalid size value.")
            await ctx.send("All values must be an integer greater than zero.")
            return

        # Invalid unit value
        if unitsystem.lower() not in ["m", "u", "i"]:
            logger.warn(f"unitsystem was {unitsystem}, must be M or U/I.")
            await ctx.send("Unitsystem must be `M` or `U`/`I`.")
            raise errors.InvalidUnitSystemException

        # I system is really U.
        if unitsystem.lower() == "i":
            unitsystem = "u"

        telemetry.AdvancedRegisterUsed(ctx.guild.id, ctx.author.id).save()
        userdata = userdb.User()
        userdata.guildid = ctx.guild.id
        userdata.id = ctx.author.id
        userdata.nickname = nick
        userdata.display = True
        userdata.height = currentheight
        userdata.baseheight = baseheight
        userdata.baseweight = baseweight
        userdata.unitsystem = unitsystem
        userdata.species = species

        userdb.save(userdata)

        await addUserRole(ctx.author)

        logger.warn(f"Made a new user: {ctx.author}!")
        logger.info(userdata)
        await ctx.send(f"Registered <@{ctx.author.id}>. {userdata}.")

        # user has display == "y" and is server owner
        if userdata.display and userdata.id == ctx.author.guild.owner.id:
            await ctx.send(
                "I can't update a server owner's nick. You'll have to manage it manually."
            )
            return