Ejemplo n.º 1
0
    async def pgmanage(self, ctx: commands.Context, *args):
        if len(args) == 0:
            raise gb.BotException('Specifica un pg!')

        charid = args[0].lower()
        isChar, character = self.bot.dbm.validators.getValidateCharacter(
            charid).validate()
        if not isChar:
            raise gb.BotException(f"Il personaggio {charid} non esiste!")

        # TODO move to security. The reason why we do this here is because "ce" is computed in security checks, but is needed in the command (to be passed to pc_interact)
        # we need a way for security checks to pass on some stuff to the command (maybe with the ctx object?)

        # permission checks
        issuer = str(ctx.message.author.id)
        playerid = character['player']

        st, _ = self.bot.dbm.isStorytellerForCharacter(issuer, charid)
        ba, _ = self.bot.dbm.validators.getValidateBotAdmin(issuer).validate()
        co = playerid == issuer
        ce = st or ba  # can edit
        if co and (not ce):
            #1: unlinked
            cl, _ = self.bot.dbm.isCharacterLinked(charid)
            #2 active session
            sa, _ = self.bot.dbm.isSessionActiveForCharacter(
                charid, ctx.channel.id)
            ce = (not cl) or sa
        if not (st or ba or co):
            return  # non vogliamo che .rossellini faccia cose
            #raise BotException("Per modificare un personaggio è necessario esserne proprietari e avere una sessione aperta, oppure essere Admin o Storyteller")

        response = await self.pc_interact(ctx, character, ce, *args[1:])
        await self.bot.atSend(ctx, response)
Ejemplo n.º 2
0
    async def newTrait(self, ctx: commands.Context, traitid: gc.GreedyShortIdConverter, traittype: gc.TraitTypeConverter, tracktype: gc.TrackerTypeConverter, std: gc.NoYesConverter, *args):
        if len(args) == 0:
            await self.bot.atSend(ctx, newTrait_description)
            return
                
        istrait, _ = self.bot.dbm.validators.getValidateTrait(traitid).validate()
        if istrait:
            raise gb.BotException(f"Il tratto {traitid} esiste già!")
        
        traittypeid = traittype['id']

        traitname = " ".join(args)

        response = ""
        t = self.bot.dbm.db.transaction()
        try:
            self.bot.dbm.db.insert("Trait", id = traitid, name = traitname, traittype = traittypeid, trackertype = tracktype, standard = std, ordering = 1.0)
            # we insert it in all available languages and we assume that it will be translated later:
            # better have it in the wrong language than not having it at all
            self.bot.dbm.db.query(query_addTraitLangs, vars = dict(traitid=traitid, traitname=traitname))
            response = f'Il tratto {traitname} è stato inserito'
            if std:
                self.bot.dbm.db.query(query_addTraitToPCs, vars = dict(traitid=traitid))
                response +=  f'\nIl nuovo tratto standard {traitname} è stato assegnato ai personaggi!'
        except:
            t.rollback()
            raise
        else:
            t.commit()

        await self.bot.atSend(ctx, response)
Ejemplo n.º 3
0
    async def name(self, ctx: commands.Context, user: gc.RegisteredUserConverter):
        
        target_st = user['userid'] 
        name = user['name']

        t_st, _ = self.bot.dbm.validators.getValidateBotStoryTeller(target_st).validate()
        if t_st:
            raise gb.BotException(f"L'utente selezionato è già uno storyteller")
        
        self.bot.dbm.db.insert("Storyteller",  userid=target_st)
        await self.bot.atSend(ctx, f"{name} ora è Storyteller")
Ejemplo n.º 4
0
    async def updt(self, ctx: gb.GreedyContext, old_traitid: gc.GreedyShortIdConverter, new_traitid: gc.GreedyShortIdConverter, traittype: gc.TraitTypeConverter, tracktype: gc.TrackerTypeConverter, std: gc.NoYesConverter, *args):    
        if len(args) == 0:
            await self.bot.atSend(ctx, newTrait_description)
            return
        
        istrait, old_trait = self.bot.dbm.validators.getValidateTrait( old_traitid).validate()
        if not istrait:
            raise gb.BotException(f"Il tratto {old_traitid} non esiste!")
        
        istrait, new_trait = self.bot.dbm.validators.getValidateTrait(new_traitid).validate()
        if istrait and (old_traitid!=new_traitid):
            raise gb.BotException(f"Il tratto {new_traitid} esiste già!")

        traittypeid = traittype['id']

        traitname = " ".join(list(args))
        
        response = f'Il tratto {traitname} è stato aggiornato'
        t = self.bot.dbm.db.transaction()
        try:
            self.bot.dbm.db.update("Trait", where= 'id = $oldid' , vars=dict(oldid = old_traitid), id = new_traitid, name = traitname, traittype = traittypeid, trackertype = tracktype, standard = std, ordering = 1.0)
            # now we update the language description, but only of the current language
            self.bot.dbm.db.update("LangTrait", where= 'traitId = $traitid and langId = $lid' , vars=dict(traitid=new_traitid, lid = ctx.getLID()), traitName = traitname)
            if std and not old_trait['standard']:
                self.bot.dbm.db.query(query_addTraitToPCs_safe, vars = dict(traitid=new_traitid))
                response +=  f'\nIl nuovo talento standard {traitname} è stato assegnato ai personaggi!'
            elif not std and old_trait['standard']:
                self.bot.dbm.db.query("""
    delete from CharacterTrait
    where trait = $traitid and max_value = 0 and cur_value = 0 and text_value = '';
    """, vars = dict(traitid=new_traitid))
                response += f'\nIl talento {traitname} è stato rimosso dai personaggi che non avevano pallini'
        except:
            t.rollback()
            raise
        else:
            t.commit()

        await self.bot.atSend(ctx, response)
Ejemplo n.º 5
0
    async def link(self, ctx: commands.Context, chronicle: gc.ChronicleConverter, storyteller: gc.StorytellerConverter = None):
        issuer = str(ctx.message.author.id)
        
        chronid = chronicle['id']

        target_st = None
        if storyteller == None:
            storyteller = await gc.StorytellerConverter().convert(ctx, issuer)
        target_st = storyteller['userid']
        
        t_stc, _ = self.bot.dbm.isChronicleStoryteller(target_st, chronid)
        if t_stc:
            raise gb.BotException(f"L'utente selezionato è già Storyteller per {chronid}")  

        # link
        self.bot.dbm.db.insert("StoryTellerChronicleRel", storyteller=target_st, chronicle=chronid)
        await self.bot.atSend(ctx, f"Cronaca associata")
Ejemplo n.º 6
0
    async def roll(self, ctx: commands.Context, *args):
        if len(args) == 0:
            raise gb.BotException(
                self.bot.getStringForUser(ctx, "string_error_x_what", "roll") +
                " diomadonna")  # xd
        args_list = list(args)

        # capisco che tipo di tiro ho di fronte
        what = args_list[0].lower()

        action = None
        if what in INIZIATIVA_CMD:
            action = RollCat.INITIATIVE
        elif what in RIFLESSI_CMD:
            action = RollCat.REFLEXES
        elif what in SOAK_CMD:
            action = RollCat.SOAK
        else:
            action = RollCat.DICE

        # leggo e imposto le varie opzioni
        parsed = None
        start_arg = 0 if action == RollCat.DICE else 1
        try:
            parsed = self.parseRollArgs(ctx, args_list[start_arg:])
        except ValueError as e:
            await self.bot.atSend(ctx, str(e))
            return

        # gestisco i tiri specifici
        response = ''
        if action == RollCat.INITIATIVE:
            response = await self.roll_initiative(ctx, parsed)
        elif action == RollCat.REFLEXES:
            response = await self.roll_reflexes(ctx, parsed)
        elif action == RollCat.SOAK:
            response = await self.roll_soak(ctx, parsed)
        else:
            response = await self.roll_dice(ctx, parsed)
        await self.bot.atSend(ctx, response)
Ejemplo n.º 7
0
 async def addt(self, ctx: gb.GreedyContext, character: gc.CharacterConverter, trait: gc.TraitConverter, value, *args):
     issuer = str(ctx.message.author.id)
     
     try:
         lid = ctx.getLID()
         ptrait = self.bot.dbm.getTrait_LangSafe(character['id'], trait['id'], lid)
         raise gb.BotException(f"{character['fullname']} ha già il tratto {ptrait['name']} ")
     except ghostDB.DBException:
         pass
     
     ttype = self.bot.dbm.db.select('TraitType', where='id=$id', vars=dict(id=trait['traittype']))[0]
     val = None
     if ttype['textbased']:
         val = " ".join([value]+list(args))
         self.bot.dbm.db.insert("CharacterTrait", trait=trait['id'], playerchar=character['id'], cur_value = 0, max_value = 0, text_value = val, pimp_max = 0)
         self.bot.dbm.log(issuer, character['id'], trait['id'], ghostDB.LogType.TEXT_VALUE, val, '', ctx.message.content)
     else:
         val = int(value)
         pimp = 6 if trait['traittype'] in ['fisico', 'sociale', 'mentale'] else 0
         self.bot.dbm.db.insert("CharacterTrait", trait=trait['id'], playerchar=character['id'], cur_value = val, max_value = val, text_value = "", pimp_max = pimp)
         self.bot.dbm.log(issuer, character['id'], trait['id'], ghostDB.LogType.MAX_VALUE, val, '', ctx.message.content)
     
     await self.bot.atSend(ctx, f"{character['fullname']} ora ha {trait['name']} {val}")
Ejemplo n.º 8
0
    async def pc_interact(self, ctx: gb.GreedyContext, pc: object,
                          can_edit: bool, *args_tuple) -> str:
        lid = ctx.getLID()

        args = list(args_tuple)

        response = ''
        if len(args) == 0:
            parsed = list(
                urllib.parse.urlparse(self.bot.config['Website']
                                      ['website_url']))  # load website url
            parsed[4] = urllib.parse.urlencode({'character':
                                                pc['id']})  # fill query
            unparsed = urllib.parse.urlunparse(tuple(parsed))  # recreate url
            return f"Personaggio: {pc['fullname']}\nScheda: {unparsed}"

        # detach stuff like ["exp+1"] to ["exp", "+1"]" or ["exp-", "1"] to ["exp", "-", "1"] in args
        for op in ["+", "-", "="]:
            idx = args[0].find(op)
            if idx > 0:
                args = [args[0][:idx]] + [args[0][idx:]] + args[1:]
                break

        trait_id = args[0].lower()
        if len(args) == 1:
            trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
            return self.getFormattedTrait(ctx, trait)

        # qui siamo sicuri che c'è un'operazione (o spazzatura)
        if not can_edit:
            return f'A sessione spenta puoi solo consultare le tue statistiche'

        param = "".join(args[1:])  # squish
        operazione = None
        if param in reset_aliases:
            operazione = "r"
        else:
            operazione = param[0]
            if not operazione in ["+", "-", "="]:
                return f'Operazione "{operazione}" non supportata'

        trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
        #trait = dbm.getTrait(pc['id'], trait_id)
        if trait['pimp_max'] == 0 and trait['trackertype'] == 0:
            raise gb.BotException(
                f"Non puoi modificare il valore corrente di {trait['traitName']}"
            )
        if trait['trackertype'] != 2:
            n = None
            if operazione != "r":
                n = param[1:]
                if not (n.isdigit()):
                    return f'"{n}" non è un intero >= 0'

            if operazione == "r":
                if trait['trackertype'] == 1 or trait['trackertype'] == 0:
                    n = trait['max_value'] - trait['cur_value']
                elif trait['trackertype'] == 3:
                    n = -trait['cur_value']
                else:
                    raise gb.BotException(
                        f"Tracker {trait['trackertype']} non supportato")
            elif operazione == "=":
                n = int(param[1:]) - trait['cur_value']  # tricks
            else:
                n = int(param)
            new_val = trait['cur_value'] + n
            max_val = max(trait['max_value'], trait['pimp_max'])
            if new_val < 0:
                raise gb.BotException(
                    f'Non hai abbastanza {trait["traitName"].lower()}!')
            elif new_val > max_val and trait['trackertype'] != 3:
                raise gb.BotException(
                    f"Non puoi avere {new_val} {trait['traitName'].lower()}. Valore massimo: {max_val}"
                )
            #
            u = self.bot.dbm.db.update(
                'CharacterTrait',
                where='trait = $trait and playerchar = $pc',
                vars=dict(trait=trait['id'], pc=pc['id']),
                cur_value=new_val)
            self.bot.dbm.log(ctx.message.author.id, pc['id'], trait['trait'],
                             ghostDB.LogType.CUR_VALUE, new_val,
                             trait['cur_value'], ctx.message.content)
            if u == 1:
                trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
                return self.getFormattedTrait(ctx, trait)
            elif u == 0:
                trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
                return self.getFormattedTrait(ctx, trait)
            else:
                return f'Qualcosa è andato storto, righe aggiornate:  {u}'

        # salute
        response = ''
        n = param[
            1:-1]  # 1st char is the operation, last char is the damaage type
        if n == '':
            n = 1
        elif n.isdigit():
            n = int(n)
        elif operazione == "=" or operazione == "r":
            pass
        else:
            raise gb.BotException(f'"{n}" non è un parametro valido!')
        dmgtype = param[-1].lower()
        new_health = trait['text_value']
        if (not dmgtype in damage_types) and operazione != "r":
            raise gb.BotException(f'"{dmgtype}" non è un tipo di danno valido')
        if operazione == "r":
            new_health = ""

            u = self.bot.dbm.db.update(
                'CharacterTrait',
                where='trait = $trait and playerchar = $pc',
                vars=dict(trait=trait['id'], pc=pc['id']),
                text_value=new_health,
                cur_value=trait['max_value'])
            self.bot.dbm.log(ctx.message.author.id, pc['id'], trait['trait'],
                             ghostDB.LogType.CUR_VALUE, new_health,
                             trait['text_value'], ctx.message.content)
            if u != 1:
                raise gb.BotException(
                    f'Qualcosa è andato storto, righe aggiornate: {u}')
            trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
            response = self.getFormattedTrait(ctx, trait)
        elif operazione == "+":
            rip = False
            for i in range(
                    n):  # applico i danni uno alla volta perchè sono un nabbo
                if dmgtype == "c" and new_health.endswith(
                        "c"):  # non rischio di cambiare la lunghezza
                    new_health = new_health[:-1] + "l"
                else:
                    if len(new_health) < trait[
                            'max_value']:  # non ho già raggiunto il massimo
                        if dmgtype == "c":
                            new_health += "c"
                        elif dmgtype == "a":
                            new_health = "a" + new_health
                        else:
                            la = new_health.rfind("a") + 1
                            new_health = new_health[:la] + "l" + new_health[la:]
                    else:  # oh no
                        convert = False
                        if dmgtype == "c":
                            if trait['cur_value'] > 0:  # trick per salvarsi mezzo aggravato
                                trait['cur_value'] = 0
                            else:
                                convert = True
                                trait['cur_value'] = trait['max_value']
                        elif dmgtype == 'l':
                            convert = True
                        else:
                            rip = True

                        if convert:
                            fl = new_health.find('l')
                            if fl >= 0:
                                new_health = new_health[:fl] + 'a' + new_health[
                                    fl + 1:]
                            else:
                                rip = True
                        if rip:
                            break
            if new_health.count("a") == trait['max_value']:
                rip = True

            u = self.bot.dbm.db.update(
                'CharacterTrait',
                where='trait = $trait and playerchar = $pc',
                vars=dict(trait=trait['id'], pc=pc['id']),
                text_value=new_health,
                cur_value=trait['cur_value'])
            self.bot.dbm.log(ctx.message.author.id, pc['id'], trait['trait'],
                             ghostDB.LogType.CUR_VALUE, new_health,
                             trait['text_value'], ctx.message.content)
            if u != 1 and not rip:
                raise gb.BotException(
                    f'Qualcosa è andato storto, righe aggiornate: {u}')
            trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
            response = self.getFormattedTrait(ctx, trait)
            if rip:
                response += "\n\n RIP"
        elif operazione == "-":
            if dmgtype == "a":
                if new_health.count(dmgtype) < n:
                    raise gb.BotException("Non hai tutti quei danni aggravati")
                else:
                    new_health = new_health[n:]
            elif dmgtype == "l":
                if new_health.count(dmgtype) < n:
                    raise gb.BotException("Non hai tutti quei danni letali")
                else:
                    fl = new_health.find(dmgtype)
                    new_health = new_health[:fl] + new_health[fl + n:]
            else:  # dio can
                if ((int(trait['cur_value']) == 0) + new_health.count(dmgtype)
                        + new_health.count("l") * 2) < n:
                    raise gb.BotException(
                        "Non hai tutti quei danni contundenti")
                for i in range(n):
                    if trait['cur_value'] == 0:
                        trait['cur_value'] = trait[
                            'max_value']  # togli il mezzo aggravato
                    else:
                        if new_health[-1] == 'c':
                            new_health = new_health[:-1]
                        elif new_health[-1] == 'l':
                            new_health = new_health[:-1] + 'c'
                        else:
                            raise gb.BotException(
                                "Non hai tutti quei danni contundenti"
                            )  # non dovrebbe mai succedere
            u = self.bot.dbm.db.update(
                'CharacterTrait',
                where='trait = $trait and playerchar = $pc',
                vars=dict(trait=trait['id'], pc=pc['id']),
                text_value=new_health,
                cur_value=trait['cur_value'])
            self.bot.dbm.log(ctx.message.author.id, pc['id'], trait['trait'],
                             ghostDB.LogType.CUR_VALUE, new_health,
                             trait['text_value'], ctx.message.content)
            if u != 1:
                raise gb.BotException(
                    f'Qualcosa è andato storto, righe aggiornate: {u}')
            trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
            response = self.getFormattedTrait(ctx, trait)
        else:  # =
            full = param[1:]
            counts = list(map(lambda x: full.count(x), damage_types))
            if sum(counts) != len(full):
                raise gb.BotException(f'"{full}" non è un parametro valido!')
            new_health = "".join(
                list(map(lambda x: x[0] * x[1],
                         zip(damage_types,
                             counts))))  # siamo generosi e riordiniamo l'input

            u = self.bot.dbm.db.update(
                'CharacterTrait',
                where='trait = $trait and playerchar = $pc',
                vars=dict(trait=trait['id'], pc=pc['id']),
                text_value=new_health,
                cur_value=1)
            self.bot.dbm.log(ctx.message.author.id, pc['id'], trait['trait'],
                             ghostDB.LogType.CUR_VALUE, new_health,
                             trait['text_value'], ctx.message.content)
            if u != 1:
                raise gb.BotException(
                    f'Qualcosa è andato storto, righe aggiornate: {u}')
            trait = self.bot.dbm.getTrait_LangSafe(pc['id'], trait_id, lid)
            response = self.getFormattedTrait(ctx, trait)

        return response