Example #1
0
    def render_GET(self, request, conn):
        from_number, to_number, message = self.get_from_to_numbers(request)
        if from_number == -1 or to_number == -1:
            return message

        # Viene creato un semilavorato in maniera tale che si possano eseguire
        # eventuali sostituzioni anche nel testo delle news
        semifinished = self.PAGE_TEMPLATE.safe_substitute({"news" : self.create_news(conn, from_number, to_number)})

        mapping = {"game_name"         : config.game_name,
                   "game_name_nocolor" : remove_colors(config.game_name),
                   "motto_nocolor"     : remove_colors(config.motto)}
        return string.Template(semifinished).safe_substitute(mapping)
Example #2
0
    def render_POST(self, request, conn):
        # Ricava gli argomenti del form dalla richiesta
        email = ""
        if "email":
            email = request.args["email"][0].lower()

        if not email:
            return self.create_page(request, conn, "", False)

        # Cerca la mail tra quella degli account
        for account in database["accounts"].itervalues():
            if account.email == email:
                break
        else:
            return self.create_page(request, conn, email, False)

        preposition = "a"
        game_name = remove_colors(config.game_name)
        if is_vowel(game_name[0]):
            preposition = "ad"

        subject = "[%s] Richiesta di recupero utente e password." % game_name.upper()
        message  = "Nome utente: %s\n" % account.name
        message += "Password: %s\n" % account.password
        message += "Potete eseguire l'accesso %s %s dalla pagina:\n" % (preposition, game_name)
        message += "%s/login.html\n" % config.site_address
        mail.send(account.email, subject, message)

        return self.create_page(request, conn, email, True)
Example #3
0
    def render_GET(self, request, conn):
        disabled = ""
        if engine.test_inputs_mode:
            disabled = ''' disabled="disabled"'''

        mapping = {"game_name"         : config.game_name,
                   "game_name_nocolor" : remove_colors(config.game_name),
                   "disabled"          : disabled}
        return self.PAGE_TEMPLATE.safe_substitute(mapping)
Example #4
0
def talk_channel(entity, channel, argument):
    """
    Gestisce i canali off rpg.
    """
    if not entity:
        log.bug("entity non è un parametro valido: %r" % entity)
        return False

    if not channel:
        log.bug("channel non è un parametro valido: %r" % channel)
        return False

    # argument può essere una stringa vuota

    # -------------------------------------------------------------------------

    if not argument or not remove_colors(argument):
        entity.send_output("Con che messaggio vorresti %s?" % channel)
        return False

    if len(argument) > config.max_google_translate:
        entity.send_output("Non puoi %s un messaggio più lungo di %d caratteri" % (channel, config.max_google_translate))
        return False

    argument = convert_urls(argument)
    for player in database["players"].itervalues():
        if not player.game_request:
            continue
        if player == entity:
            continue
        if player.trust < channel.trust:
            continue
        message = "<br>%s%s: '%s'" % (entity.name, channel.verb_it, argument)
        send_channel_message(player, message, False)
        player.send_prompt()

    message = "%s: '%s'" % (channel.verb_you, argument)
    send_channel_message(entity, message, True)

    if channel == CHANNEL.CHAT:
        check_for_badwords(entity, argument)
        log.chat("%s %s: %s\n" % (datetime.datetime.now(), remove_colors(entity.name), remove_colors(argument)))

    return True
Example #5
0
    def get_permissions(self):
        rows = []

        for player in sorted(database["players"].values(), key=lambda player: remove_colors(player.name)):
            if player.permissions:
                rows.append('''<tr><td>%s</td><td>%s</td><td>%s</td></tr>''' % (player.name, player.permissions, player.account.name))

        if rows:
            return "".join(rows)
        else:
            return '''<tr><td colspan="3">Nessuno</td></tr>'''
Example #6
0
    def render_GET(self, request, conn):
        race_options = ""
        for race in RACE.sort_playable_first():
            name = remove_colors(race.name.replace("$o", "o"))
            race_options += '''\t<option value="%s">%s</option>\n''' % (name, name)

        social_options = ""
        for social in sorted(database["socials"].values()):
            social_name = social.fun_name[len("social_") : ]
            social_options += '''\t<option value="%s">%s</option>\n''' % (social_name, social_name)

        mapping = {"race_options"   : race_options,
                   "social_options" : social_options}
        return self.PAGE_TEMPLATE.safe_substitute(mapping)
Example #7
0
def grammar_cleaner(argument):
    """
    Passato un argomento ne ritorna la prima parola in minuscolo e senza
    caratteri di colore che potrebbero interferire con le funzioni grammaticali
    qui sotto.
    """
    if not argument:
        log.bug("argument non è un parametro valido: %r" % argument)
        return ""

    # -------------------------------------------------------------------------

    first_word = argument.split()[0]
    return remove_colors(first_word).lower()
Example #8
0
    def render_POST(self, request, conn):
        aliases = {}

        # Ricava gli argomenti del form dalla richiesta
        for arg in request.args:
            if arg.startswith("name_"):
                alias = Alias()
                alias.name   = request.args["name_%s"   % arg[len("name_")  : ]][0].lower().strip()
                alias.action = request.args["action_%s" % arg[len("name_")  : ]][0].strip()

                if alias.name:
                    alias.name = remove_colors(alias.name)
                if " " in alias.action:
                    input, argument = alias.action.split(None, 1)
                    alias.action = "%s %s" % (remove_colors(input), argument)

                if alias.name and alias.action:
                    aliases[alias.name] = alias

            # (TD) unire questa parte alla parte sopra che è praticamente uguale
            if arg.startswith("new_name_"):
                alias = Alias()
                alias.name   = request.args["new_name_%s"   % arg[len("new_name_") : ]][0].lower().strip()
                alias.action = request.args["new_action_%s" % arg[len("new_name_")  : ]][0].strip()

                if alias.name:
                    alias.name = remove_colors(alias.name)
                if " " in alias.action:
                    input, argument = alias.action.split(None, 1)
                    alias.action = "%s %s" % (remove_colors(input), argument)

                if alias.name and alias.action:
                    aliases[alias.name] = alias

        # Sostituisce gli aliases vecchi con quelli ricavati dal post
        conn.account.aliases = aliases
        return self.create_page(request, conn)
Example #9
0
def clean_string(argument):
    if not argument:
        log.bug("argument non è un parametro valido: %r" % argument)
        return ""

    # -------------------------------------------------------------------------

    argument = remove_accents(argument)

    if "[" in argument:
        global remove_colors
        if not remove_colors:
            from src.color import remove_colors
        argument = remove_colors(argument)

    return argument.lower()
Example #10
0
def create_random_player(name="", level=0, race=RACE.NONE, sex=SEX.NONE, way=WAY.NONE):
    """
    Crea un personaggio con caratteristiche casuali, serve principalmente per
    testing, per esempio per creare due personaggi che combattano tra loro.
    """
    if not name and name != "":
        log.bug("name non è un parametro valido: %r" % name)
        return

    if level < 0 or level > config.max_level:
        log.bug("level non è un parametro valido: %d" % level)
        return

    if not race:
        log.bug("race non è un parametro valido: %r" % race)
        return

    if not sex:
        log.bug("sex non è un parametro valido: %r" % sex)
        return

    if not way:
        log.bug("way non è un parametro valido: %r" % way)
        return

    # -------------------------------------------------------------------------

    player = Player()
    player = create_random_mob(player, name, level, race, sex, way)

    # Ora che player possiede una razza ed un sesso può creare un nome
    # casuale se questo non è stato passato
    if not player.name:
        player.name = create_random_name(player.race, player.sex, is_player_name=True)
    player.code = remove_colors(player.name.lower())

    # Crea il giocatore con i dati di base
    # (TD) dovrei impostare casualmente tanti altri attributi
    player.flags.randomize()
    create_random_reputations(player)

    return player
Example #11
0
    def spelling(self, dictionary=None, typos_file=None):
        if dictionary is None or typos_file is None:
            from src.database import database
            if not dictionary:
                dictionary = database.spelling_dictionary
            if not typos_file:
                typos_file = database.load_typos_file()

        for attr_name in ("descr", "descr_night", "descr_hearing", "descr_hearing_night", "descr_smell", "descr_smell_night", "descr_touch", "descr_touch_night", "descr_taste", "descr_taste_night", "descr_sixth", "descr_sixth_night"):
            text = getattr(self, attr_name)
            if not text:
                continue
            text = remove_colors(text)
            if not text:
                log.bug("testo dell'attributo %s del dato %s con solo il colore" % (attr_name, self.code))
                continue
            if "$o" in text:
                text = text.replace("$o", "o")
            if "$O" in text:
                text = text.replace("$O", "o")

            words = text.split()
            for word in reversed(words):
                if "'" in word and word[0] != "'" and word[-1] != "'":
                    if word.lower() != "po'":
                        words.remove(word)
                        words += word.split("'")

            for word in words:
                word = word.rstrip(",;.!?")
                if not word:
                    log.bug("Punteggiatura isolata per l'attributo %s al dato %s" % (attr_name, self.code))
                    continue
                if not word.isalpha():
                    continue
                if word not in dictionary:
                    word = word.lower()
                    if word not in dictionary:
                        typos_file.write("%s (%s)\n" % (word, self.code))
Example #12
0
    def render_GET(self, request, conn):
        max_help_types = len(HELP.elements)
        for help_element in HELP.elements:
            if (conn.player and help_element.trust > conn.player.trust
            or  conn.account and help_element.trust > conn.account.trust
            or  not conn.account and not conn.player and help_element.trust > TRUST.PLAYER):
                max_help_types -= 1
        half_help_types = max_help_types / 2 + max_help_types % 2

        help_types = []
        help_types.append('''<table class="mud" align="center" width="100%"><tr>''')
        help_types.append('''<td valign="top"><ul>''')
        help_types += self._render_help_types_list(0, half_help_types)
        help_types.append('''</ul></td>''')
        help_types.append('''<td valign="top"><ul>''')
        help_types += self._render_help_types_list(half_help_types, max_help_types)
        help_types.append('''</ul></td>''')
        help_types.append('''</tr></table>''')

        mapping = {"game_name"          : config.game_name,
                   "game_name_nocolor"  : remove_colors(config.game_name),
                   "help_types"        : "".join(help_types)}
        return self.PAGE_TEMPLATE.safe_substitute(mapping)
Example #13
0
def put_final_dot(argument, char="."):
    """
    Aggiunge, se ce n'è bisogno, un punto a fine stringa.
    """
    if not argument:
        log.bug("argument non è un parametro valido: %r" % argument)
        return ""

    # -------------------------------------------------------------------------

    argument_without_css = argument
    if "[" in argument:
        global remove_colors
        if not remove_colors:
            from src.color import remove_colors
        argument_without_css = remove_colors(argument)
        if not argument_without_css:
            log.bug("argument_without_css non è valido: %r" % argument_without_css)
            return ""

    if argument_without_css[-1].isalnum():
        argument += char

    return argument
Example #14
0
    def start(self):
        from src.calendar import calendar
        from src.config   import config
        from src.database import database
        from src.log      import log

        starting_time = time.time()
        self.booting = True

        log.platform_infos()

        print "Cancella tutti i file compilati per forzarne la ricompilazione"
        remove_compiled_files()

        try:
            # Dona maggiori informazioni sotto gli OS Linux e simili
            log.booting("Avvio del gioco sul server %s per l'utente %s al gruppo %s" % (socket.gethostname(), os.geteuid(), os.getgid()))
        except:
            log.booting("Avvio del gioco sul server %s" % socket.gethostname())

        log.booting("===========================================================================")
        log.booting("Carica il file di configurazione %s" % self.options.config_filename)
        config.load(self.options.config_filename)
        self.check_the_mode()

        log.booting("Carica la data del calendario gdr")
        calendar.load()

        from src.entity import load_little_words
        log.booting("Carica da file le little words da utilizzare per filtrare le keywords")
        load_little_words()

        from src.account import load_forbidden_names
        log.booting("Carica da file la lista dei nomi proibiti per nuovi account e giocatori")
        load_forbidden_names()

        log.booting("Carica tutti gli input nelle differenti lingue")
        from src.database import fread_list
        from src.input import Input
        import src.interpret as interpret_module
        interpret_module.inputs_command_it = fread_list("data/inputs_command_it.list", Input, "inputs_command_it[%d]")
        interpret_module.inputs_command_en = fread_list("data/inputs_command_en.list", Input, "inputs_command_en[%d]")
        interpret_module.inputs_skill_it   = fread_list("data/inputs_skill_it.list",   Input, "inputs_skill_it[%d]")
        interpret_module.inputs_skill_en   = fread_list("data/inputs_skill_en.list",   Input, "inputs_skill_en[%d]")
        interpret_module.inputs_social_it  = fread_list("data/inputs_social_it.list",  Input, "inputs_social_it[%d]")
        interpret_module.inputs_social_en  = fread_list("data/inputs_social_en.list",  Input, "inputs_social_en[%d]")

        # (TD) per ora inutilizzato
        #from grammar import vocabulary, EntryWord
        #log.booting("Caricamento del vocabolario grammaticale")
        #vocabulary = fread_list("data/vocabulary.list", EntryWord, "vocabulary[%d]")

        from src.database import database
        log.booting("Carica il Database:")
        database.load(use_spelling=self.options.spelling)

        from src.gamescript import create_init_files
        log.booting("Si assicura dell'esistenza dei file __init__ per importare i gamescript")
        create_init_files("data", ("proto_rooms", "proto_mobs", "proto_items"))
        create_init_files("persistence", ("rooms", "mobs", "items", "players"))

        from src.gamescript import import_all_proto_gamescripts
        log.booting("Aggiunge i riferimenti ai gamescript dei dati prototipo")
        import_all_proto_gamescripts("data", ("proto_rooms", "proto_mobs", "proto_items"))

        from src.gamescript import import_all_instance_gamescripts
        log.booting("Aggiunge i riferimenti ai gamescript dei dati delle istanze")
        import_all_instance_gamescripts("persistence", ("rooms", "mobs", "items"))
        import_all_instance_gamescripts("data", ("players", ))

        from src.gamescript import import_all_area_gamescripts
        log.booting("Aggiunge i riferimenti ai gamescript delle aree")
        import_all_area_gamescripts()

        from src.games.wumpus import import_all_wumpus_gamescripts
        log.booting("Aggiunge i riferimenti ai gamescript delle aree wumpus")
        import_all_wumpus_gamescripts()

        from src.site import site
        log.booting("Prepara il web server del gioco")
        reactor.listenTCP(config.http_port, site)

        from src.forum_db import forum_db
        log.booting("Carica il Forum")
        forum_db.load()

        # (TD) molto in futuro saranno più di una
        from src.wild import load_wild
        log.booting("Carica le informazioni sulla Wild")
        #load_wild()

        from src.element import create_elements_list_page
        log.booting("Crea dinamicamente la pagina web della lista degli elementi")
        create_elements_list_page()

        from src.fight import create_damages_page
        log.booting("Crea dinamicamente la pagina web della lista dei danni")
        create_damages_page()

        from src.reset import finalize_room_resets
        log.booting("Inizializza eventuali valori impliciti nella date dei reset.")
        finalize_room_resets()

        from src.reset import start_repop_laters
        log.booting("Prepara le informazioni di repop per tutti i dati caricati dalla persistenza")
        start_repop_laters()

        from src.reset import defer_all_reset_events
        log.booting("Prepara le aree in gioco eseguendo i primi reset.")
        defer_all_reset_events()

        from src.entitypes.plant import restart_all_planting
        log.booting("Rinizia da capo eventuali stadi di crescita lasciati a metà dal precedente shutdown.")
        restart_all_planting()

        from src.loops.aggressiveness import aggressiveness_loop
        from src.loops.blob           import blob_loop
        from src.entitypes.corpse     import decomposer_loop
        from src.loops.digestion      import digestion_loop
        from src.fight                import fight_loop
        from src.game                 import game_loop
        from src.maintenance          import maintenance_loop
        from src.behaviour            import room_behaviour_loop
        log.booting("Avvia tutti i loop")
        aggressiveness_loop.start()
        blob_loop.start()
        decomposer_loop.start()
        digestion_loop.start()
        fight_loop.start()
        game_loop.start()
        maintenance_loop.start()
        room_behaviour_loop.start()

        from src.gamescript import triggering_on_booting
        log.booting("Attivazione dei trigger on_booting")
        triggering_on_booting()

        log.booting("Finalizza e controlla la configurazione caricata precedentemente.")
        config.finalize()
        config.get_error_message()

        log.booting("Esegue un controllo al nome dei metodi della singleton log.")
        log.check_log_methods()

        # Se sono stati trovati degli errori sui riferimenti, controllati dal
        # metodo _search_the_reference o altri tipo di errori pesanti o
        # bloccanti, allora blocca il boot del gioco, a meno che non sia stato
        # avviato ignorando esplicitamente tale cosa
        if self.critical_errors > 0:
            if self.critical_errors > 1:
                message = "Sono stati riscontrati %d errori critici" % self.critical_errors
            elif self.critical_errors == 1:
                message = "E' stato riscontrato 1 errore critico"
            log.booting("===>> %s al caricamento del Gioco (ignora l'eventuale blocco dell'avvio con l'opzione d'avvio -i) <<===" % message)
            if self.options.mode == "official" and not self.options.ignore:
                sys.exit(1)

        log.booting("allow_web_robots=%s: le pagine %sverranno indicizzate dai motori di ricerca" % (
            config.allow_web_robots, "NON " if not config.allow_web_robots else ""))

        self.boot_seconds = time.time() - starting_time
        log.booting("Esecuzione del boot in %d secondi" % self.boot_seconds)

        from src.color import remove_colors
        log.booting("Il gioco %s è pronto alla porta http %d" % (remove_colors(config.game_name), config.http_port))

        if self.options.boot_only:
            print "Esecuzione del solo boot terminata."
            sys.exit(0)

        log.booting("===========================================================================")
        self.booting = False

        try:
            if config.use_profiler:
                log.booting("%s è stato avviato in modalità di profiling" % remove_colors(config.game_name))
                now = datetime.datetime.now()
                cProfile.run("from twisted.internet import reactor; reactor.run()", "profile_%dy_%dm_%dd_%dh_%dm_%ds.results" % (
                    now.year, now.month, now.day, now.hour, now.minute, now.second))
            else:
                reactor.run()
        except (KeyboardInterrupt, SystemExit):
            # Sono eccezioni accettabili e non comportano il reboot automatico
            pass
        except:
            self.automatic_reboot = True
        finally:
            self.stop()
            # Nel qual caso vi sia stato un'eccezione sconosciuta e che il
            # gioco sia quello ufficiale (e quindi è sottinteso che debba
            # sempre rimanere up and running) allora tenta di riavviarlo
            # con le stesse opzioni utilizzate per questa istanza morente
            if self.automatic_reboot and self.options.mode == "official":
                os.system("%s %s" % (sys.executable, " ".join(sys.argv)))
Example #15
0
def command_tell(entity, argument=""):
    """
    Permette di parlare con tutti nel Mud, in maniera off-gdr.
    """
    if not entity:
        log.bug("entity non è un parametro valido: %r" % entity)
        return False

    # -------------------------------------------------------------------------

    if not argument:
        entity.send_output("Vuoi %s a qualcuno che cosa?" % CHANNEL.TELL)
        if entity.IS_PLAYER and OPTION.NEWBIE in entity.account.options:
            syntax = get_command_syntax(entity, "command_tell")
            entity.send_output(syntax, break_line=False)
        return False

    # Qui per la ricerca di target non viene utilizzata la find_entity perché
    # deve cercare solo i giocatori online
    # (TD) oltre alla ricerca di admin che possiedono mob o oggetti
    arg, argument = one_argument(argument)
    target = search_for_player(entity, arg)
    if not target:
        # (TD) se non è stato tovato allora cerca tra gli identificativi
        # personali relativi ai personaggi invisibili (implementazione
        # alternativa del reply)
        entity.send_output("Non è stato trovato nessun giocatore con argomento [white]%s[close]" % arg)
        return False

    # (TD) possibile implementazione di NOTELL, anche se è preferibile punizione
    # classica di NO_ENTER_IN_GAME per tot giorni

    if entity == target:
        entity.send_output("Non puoi comunicare con [white]te stess$o[close]!")
        return False

    if not target.game_request:
        entity.send_output("Il giocatore [white]%s[close] è attualmente [darkslategray]offline[close]." % target.name)
        return False

    if not argument:
        entity.send_output("Che messaggio privato vorresti inviare a [white]%s[close]?" % target.name)
        return False

    channel_color = get_first_color(str(CHANNEL.TELL))

    afk_status = ""
    if FLAG.AFK in target.flags:
        if entity.account and OPTION.ITALIAN in entity.account.options:
            afk_status = " (LDT)"
        else:
            afk_status = " (AFK)"

    if is_vowel(remove_colors(target.name)[0]):
        preposition = "ad"
    else:
        preposition = "a"

    entity.send_output("%s %s%s[close] %s: %s'%s'" % (
        CHANNEL.TELL.verb_you, channel_color, preposition, target.name, afk_status, argument), avoid_snoop=True)
    # (TD) inviare anche il soft beep per avvertire che ha ricevuto un messaggio
    # ed aggiungere l'opzione apposita
    if target.get_conn().get_browser():
        numbered_keyword = entity.get_numbered_keyword(looker=target)
        javascript = '''javascript:putInput('%s %s ');''' % (translate_input(target, "tell", "en"), numbered_keyword)
        target.send_output("""\n<a href="%s">%s%s ti[close]%s</a>: '%s'""" % (javascript, entity.name, channel_color, CHANNEL.TELL.verb_it, argument), avoid_snoop=True)
    else:
        target.send_output("""\n%s %sti[close]%s: '%s'""" % (entity.name, channel_color, CHANNEL.TELL.verb_it, argument), avoid_snoop=True)
    target.send_prompt()

    return True
Example #16
0
 def __init__(self, code="", who="", where="", when="", text=""):
     self.code    = code
     self.who     = remove_colors(who) if who else ""   # Chi ha inviato la nota
     self.where   = where                               # Da dove l'ha inviata
     self.when    = remove_colors(when) if when else "" # Quando l'ha inviata
     self.text    = text                                # Testo della nota
Example #17
0
def clean_and_add_article(argument, type, genre=GRAMMAR.MASCULINE, number=GRAMMAR.SINGULAR):
    if not argument:
        log.bug("argument non è un parametro valido: %r" % argument)
        return ""

    if not type:
        log.bug("type non è un parametro valido: %r" % type)
        return ""

    if not genre:
        log.bug("genre non è un parametro valido: %r" % genre)
        return ""

    if not number:
        log.bug("number non è un parametro valido: %r" % number)
        return ""

    # -------------------------------------------------------------------------

    colorless = remove_colors(argument)
    if not colorless:
        log.bug("la stringa %s è formata solo da colori" % argument)
        return ""

    # Ci sono casi particolari in cui non serve convertire aggiungendo un articolo
    # altrimenti vengono furoi cose come:
    # Posi un piccone nell'all'interno delle miniere.
    if type == GRAMMAR.PREPOSITION_IN and colorless[ : 4] in ("all'", "alla", "agli", "alle"):
        return argument

    if colorless[ : 6] in ("degli "):
        old_article = colorless[ : 6]
        genre = GRAMMAR.MASCULINE
        number = GRAMMAR.PLURAL
    elif colorless[ : 6] in ("delle "):
        old_article = colorless[ : 6]
        genre = GRAMMAR.FEMININE
        number = GRAMMAR.PLURAL
    elif colorless[ : 4] in ("dei "):
        old_article = colorless[ : 4]
        genre = GRAMMAR.MASCULINE
        number = GRAMMAR.PLURAL
    elif colorless[ : 4] in ("una "):
        old_article = colorless[ : 4]
        genre = GRAMMAR.FEMININE
        number = GRAMMAR.SINGULAR
    elif colorless[ : 4] in ("gli "):
        old_article = colorless[ : 4]
        genre = GRAMMAR.MASCULINE
        number = GRAMMAR.PLURAL
    elif colorless[ : 3] in ("il ", "un "):
        old_article = colorless[ : 3]
        genre = GRAMMAR.MASCULINE
        number = GRAMMAR.SINGULAR
    elif colorless[ : 3] in ("la ", "un'"):
        old_article = colorless[ : 3]
        genre = GRAMMAR.FEMININE
        number = GRAMMAR.SINGULAR
    elif colorless[ : 3] in ("le "):
        old_article = colorless[ : 3]
        genre = GRAMMAR.FEMININE
        number = GRAMMAR.PLURAL
    elif colorless[ : 2] in ("i "):
        old_article = colorless[ : 2]
        genre = GRAMMAR.MASCULINE
        number = GRAMMAR.PLURAL
    elif colorless[ : 2] in ("l'"):
        old_article = colorless[ : 2]
        genre = get_grammar_genre(colorless)  # (bb) essendo is_masculine non terminato qui potrebbe ritornare baco al momento
        number = GRAMMAR.SINGULAR
    else:
        old_article = ""

    article = get_article(colorless[len(old_article) : ], genre, number, type)

    # Eseguendo la replace tenta di mantenere la colorazione originale,
    # altrimenti ne invia una versione semplicificata senza colori
    # (bb) sì lo so, non è perfetta perché se l'articolo è formato da più
    # colori il sistema non regge, ma per ora va bene così
    if argument.find(old_article) != -1:
        return argument.replace(old_article, article, 1)
    else:
        return colorless.replace(old_article, article, 1)
Example #18
0
def interpret(entity, argument, use_check_alias=True, force_position=True, show_input=True, show_prompt=True, behavioured=False):
    """
    Funzione che interpreta gli inputi inviati dalle entità.
    L'argomento use_check_alias a False viene passato dalla find_alias per
    evitare chiamate di alias da altri alias e quindi ricorsioni.
    """
    if not entity:
        log.bug("entity non è un parametro valido: %r" % entity)
        return

    if not argument:
        log.bug("argument non è un parametro valido: %r" % argument)
        return

    # -------------------------------------------------------------------------

    # Si assicura che colui che esegue l'azione sia un'entità unica e
    # non un mucchio fisico
    entity = entity.split_entity(1)

    if FLAG.CONVERSING in entity.flags and len(argument) == 1 and is_number(argument):
        # (TD)
        return

    arg, argument = one_argument(argument, search_separator=False)
    arg = arg.lower()

    input, huh_input, lang = multiple_search_on_inputs(entity, arg, use_check_alias=use_check_alias, argument=argument)
    # Utilizzo bislacco di lang per indicare che è stato trovato un alias
    # e che questo verrà processato tramite un'altra chiamata all'interpret
    if use_check_alias and lang == "alias":
        return

    # Resetta l'inattività di un player se ha inviato un comando
    if entity.IS_PLAYER:
        entity.inactivity = 0

    # Se non ha trovato nulla invia un messaggio apposito
    if not input:
        if show_input:
            entity.send_output(''' <span class="system">%s %s</span>''' % (remove_colors(arg), argument))
        entity.send_output("Huh?")
        # Se l'input non è stato trovato neanche nell'altra lingua allora
        # esegue il log dell'input, potrebbero esservene alcuni di sensati
        # da utilizzare in futuro come sinonimi
        # Scrive anche gli huh input dei mob così da ricavare gamescript o
        # random_do_inputs errati
        if not huh_input:
            log.huh_inputs(entity, arg)
        # Se serve visualizza il prompt
        if show_input:
            entity.send_prompt()
        return False

    # Poiché alcune words nello stesso input a volte hanno prefisso differente
    # tra loro allora cerca quello più simile possibile per farlo visualizzare
    # all'utente
    founded_input = input.findable_words[0]
    for word in input.findable_words:
        if is_prefix(arg, word):
            founded_input = word
            break

    # Se il giocatore è in stato di wait e l'input è un comando interattivo
    # allora evita di inviarlo subito ma lo mette in coda
    if entity.deferred_wait and CMDFLAG.INTERACT in input.command.flags:
        entity.waiting_inputs.append("%s %s" % (founded_input, argument))
        return False
    else:
        # Altrimenti scrive anche l'input a fianco del prompt
        if show_input:
            entity.send_output(''' <span class="system">%s %s</span>''' % (founded_input, argument))

    # Se il pg si è scollegato dalla pagina di gioco non esegue il comando
    if not entity.location:
        return False

    # Vengono salvate le informazioni sull'ultimo input inviato
    if argument:
        last_input = "%s %s" % (arg, argument)
    else:
        last_input = arg
    engine.last_input_sender = entity
    engine.last_input_sended = last_input
    # Si salva l'ultimo input inviato con successo
    if show_input and entity.IS_PLAYER and CMDFLAG.NO_LAST_INPUT not in input.command.flags:
        entity.last_input = last_input

    if CMDFLAG.GDR in input.command.flags:
        entity.sended_inputs.append("%s %s" % (founded_input, argument))

    if argument:
        argument = html_escape(argument)

    # Gestisce i comandi che devono essere digitati per intero
    command = input.command
    if CMDFLAG.TYPE_ALL in command.flags and not is_same(arg, input.findable_words):
        first_words, other_words = one_argument(input.words, search_separator=False)
        entity.send_output("Se vuoi veramente farlo devi scrivere per intero [limegreen]%s[close]." % first_words)
        execution_result = False
    elif not check_position(entity, command.position, force_position):
        # Se la posizione non è corretta invia il relativo messaggio d'errore
        vowel_of_genre = grammar_gender(entity)
        if entity.position == POSITION.DEAD:
            entity.send_output("Un po' difficile fino a che rimani MORT%s.." % vowel_of_genre.upper())
        elif (entity.position == POSITION.MORTAL
        or    entity.position == POSITION.INCAP):
            entity.send_output("Sei troppo ferit%s per farlo." % vowel_of_genre)
        elif entity.position == POSITION.STUN:
            entity.send_output("Sei troppo intontit%s per farlo." % vowel_of_genre)
        elif entity.position == POSITION.SLEEP:
            entity.send_output("Nei tuoi sogni, o cosa?")
        elif entity.position == POSITION.REST:
            entity.send_output("Nah.. Sei troppo rilassat%s ora.." % vowel_of_genre)
        elif entity.position == POSITION.KNEE:
            entity.send_output("Non puoi farlo da inginocchiat%s" % vowel_of_genre)
        elif entity.position == POSITION.SIT:
            entity.send_output("Non puoi farlo da sedut%s." % vowel_of_genre)
        else:
            log.bug("Manca la posizione %r" % entity.position)
        execution_result = False
    else:
        if command.type == CMDTYPE.SOCIAL:
            check_social(entity, command, argument=argument, behavioured=behavioured)

        if CMDFLAG.PRIVATE not in command.flags and (entity.IS_PLAYER or config.print_entity_inputs) and show_input and show_prompt:
            if entity.IS_PLAYER:
                write_on_file = True
            else:
                write_on_file = False
            log.input("'%s%s%s' digitato da %s in %s" % (
                founded_input,
                " " if argument else "",
                argument,
                entity.code,
                entity.location.get_name()), write_on_file=write_on_file)

        # Per comodità di sviluppo ricarica il modulo relativo al comando ogni
        # volta che lo si digita, così da poter testare le modifiche al codice
        # dei comandi senza aver bisogno di riavviare il gioco tutte le volte
        if config.reload_commands:
            reload(command.module)
            command.import_module_and_function()

        # Se si sta eseguendo un'azione che richiede tempo la interrompe
        if entity.action_in_progress and CMDFLAG.INTERACT in command.flags:
            if entity.action_in_progress.defer_later:
                entity.action_in_progress.stop()
            entity.action_in_progress = None

        # Esegue la funzione del comando cronometrandola
        input.counter_use += 1
        starting_time = time.time()
        execution_result = (command.function)(entity, argument)
        if command.fun_name[ : 8] == "command_" and execution_result != True and execution_result != False:
            log.bug("execution_result non è valido per il comando %s: %r" % (command.fun_name, execution_result))
        if command.fun_name[ : 6] == "skill_" and execution_result != "clumsy" and execution_result != "failure" and execution_result != "success" and execution_result != "magistral":
            log.bug("execution_result non è valido per la skill %s: %r" % (command.fun_name, execution_result))
        execution_time = time.time() - starting_time
        # Comandi che superano il tempo definito nella max_execution_time
        # possono portare a bachi creati dalla deferred impostata nel metodo
        # split_entity (nello stesso metodo c'è un commento con più informazioni)
        # Quindi devono essere il più possibile da evitare, allo stesso tempo
        # sarebbe meglio che il max_execution_time sia relativamente basso.
        if execution_time > config.max_execution_time:
            log.time("Il comando %s è stato eseguito in troppo tempo: %f secondi" % (command.fun_name, execution_time))
        command.timer += execution_time

    # Gestisce i comandi da loggare
    if CMDFLAG.LOG in command.flags:
        log.command("%s %s" % (command.fun_name, argument))

    if FLAG.AFK in entity.flags and command.fun_name != "command_afk":
        command_afk(entity)

    # Infine visualizza il prompt
    if show_prompt:
        entity.send_prompt()

    # Se la lista di input ancora da inviare non è vuota allora crea un
    # "falso wait" per forzarne l'invio. In teoria potrei inviarlo da qui, ma
    # il codice di ritorno execution_result andrebbe perduto, ecco perché
    # si fa uso della wait().
    if not entity.deferred_wait and entity.waiting_inputs:
        entity.wait(0.001)

    # Questa parte è da attivare con l'opzione check_references solo nei
    # server di test perché consuma molta cpu essendo eseguita su migliaia
    # di dati ad ogni invio di input, è una modalità di diagnostica
    # che non bada a spese in termini prestazionali
    if config.check_references and not database.reference_error_found:
        database.check_all_references()

    return execution_result
Example #19
0
    def render_GET(self, request, conn):
        page = ""

        page += '''<h3>Elenco dei tuoi Personaggi:</h3>'''
        page += '''<table rules="rows" width="100%">'''
        page += '''  <tr align="center"><th>Gioca con</th><th>Razza</th><th>Livello</th><th>Creato il</th><th>Connesso il</th><th>Disconnesso il</th><th>Giocato</th></tr>'''
        for player in sorted(conn.account.players.values(), key=lambda player: remove_colors(player.name)):
            if player.login_time:
                login_time = pretty_date(past=player.login_time)
            else:
                login_time = "Mai"

            if player.logout_time:
                logout_time = pretty_date(past=player.logout_time)
            else:
                logout_time = "Mai"

            # (TD) pensare se separare il codice e fare una funzione come la pretty_date
            seconds = (player.seconds_played) % 60
            minutes = (player.seconds_played / 60) % 60
            hours   = (player.seconds_played / 3600) % 24
            days    = (player.seconds_played / 86400)
            if days == 0:
                if hours == 0:
                    if minutes == 0:
                        time_played = "%d second%s" % (seconds, "o" if seconds == 1 else "i")
                    else:
                        time_played = "%d minut%s" % (minutes, "o" if minutes == 1 else "i")
                else:
                    time_played = "%d or%s e %d minut%s" % (hours, "a" if hours == 1 else "e", minutes, "o" if minutes == 1 else "i")
            else:
                time_played = "%d giorn%s e %d or%s" % (days, "o" if days == 1 else "i", hours, "a" if hours == 1 else "e",)

            # Sotto alcuni browser non funziona la pagina di gioco se non si
            # inserisce l'url per intero
            browser = conn.get_browser()
            server_address = ""
            if browser.startswith("IE"):
                server_address = "%s:%s/" % (config.site_address, config.http_port)

            href = '''href="game_interface.html?pg_code=%s" target="game_page"''' % player.code
            page += '''  <tr align="center"><td align="left">%s<a %s>%s</a></td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>''' % (
                create_icon(player.get_icon()),
                href,
                player.name,
                player.sex_replacer(player.race.name),
                player.level,
                pretty_date(past=player.created_time),
                login_time,
                logout_time,
                time_played)
        if config.max_account_players == 0:
            page += '''  <tr><td colspan="7">La creazione di nuovi personaggi è disattiva.</td></tr>'''
        elif len(conn.account.players) < config.max_account_players:
            page += '''  <tr><td colspan="7"><a href="create_player1.html">Un Nuovo Personaggio</a></td></tr>'''
        else:
            page += '''  <tr><td colspan="7">Numero massimo di personaggi creabili raggiunto.</td></tr>'''
        page += '''</table>'''
        page += '''%s personaggi creati su %s.<br>''' % (len(conn.account.players), config.max_account_players)
        page += '''<br>'''

        page += '''<br>È inevitabile per i personaggi creati durante questa apertura finiscano lentamente con l'acquisire vantaggi, oggetti ed abilità troppo potenti per poter essere conservati quando si passerà dalla beta alla versione definitiva; è altrettanto inevitabile che sia una sofferenza indicibile rinunciarvi... pertanto concerteremo assieme una via che consenta ai partecipanti di mantenere almeno una parte dello status e dei privilegi acquisiti anche come segno virtuale-tangibile della nostra riconoscenza per aver contribuito alla crescita di Aarit.'''

        page += '''<script>$.post("players.html", {width:screen.width, height:screen.height});</script>'''

        return page
Example #20
0
def rpg_channel(entity, argument, channel, ask=False, exclaim=False, behavioured=False):
    """
    Gestisce i canali rpg, ha le seguenti caratteristiche:
    - supporto per gli smile
    - supporto per i modi di esprimersi con esclamativo e punto di domanda
    - supporto per gli emote
    - gestione del bersaglio che può essere un'entità, il gruppo o sé stessi
    - (TD) parlata da ubriaco
    - (TD) espansione della potenza della voce in altre stanze
    - (TD) espressioni per le stanze attorno, anche per coloro che riconoscono la voce,
           pensare anche alla suddivisione tra social gestuali e 'rumorosi' per gli smile-espressioni around
    - (TD) modulazione della voce a seconda delle dimensioni di chi parla e della sua voice_potence
    """
    if not entity:
        log.bug("entity non è un parametro valido: %r" % entity)
        return False

    if not channel:
        log.bug("channel non è un parametro valido: %r" % channel)
        return False

    # -------------------------------------------------------------------------

    if entity.IS_ROOM:
        return False

    objective = OBJECTIVE_ROOM  # obiettivo del messaggio
    # Linguaggio utilizzato per dire il messaggio
    if entity.IS_ITEM:
        language = LANGUAGE.COMMON
    else:
        language = entity.speaking
    smile = ""            # conterrà l'eventuale espressione di uno smile-social
    emote = ""            # conterrà l'eventuale emote inviato con il messaggio tra due asterischi
    expres_entity = ""    # espressione per chi parla
    expres_room   = ""    # espressione per chi sta ascoltando nella stanza
    expres_objective = "" # espressione per chi riceverà il messaggio

    # Ricava i verbi e il colore relativi al canale
    # Se si sta parlando normalmente la propria lingua vengono utilizzati
    # i verbi razziali per descriverne timbro, flessione o pronuncia
    if channel == CHANNEL.SAY:
        verb_you, verb_it = entity.race.say_verb_you, entity.race.say_verb_it
    else:
        verb_you, verb_it = channel.verb_you, channel.verb_it
    color = get_first_color(channel.name)

    # Se non è stato passato nessun messaggio esce
    if not argument or not remove_colors(argument):
        entity.send_output("Cosa vorresti %s?" % channel)
        return False

    if len(argument) > config.max_google_translate:
        entity.send_output("Non puoi %s un messaggio così logorroico." % channel)
        return False

    # Copia l'argomento originale, in alcuni casi serve recuperarlo poi
    original_argument = argument

    # Controlla se si sta parlando a qualcuno, il controllo sulla particella
    # la esegue in minuscolo, dando per sottinteso che quando uno scrive
    # maiuscolo voglia iniziare un discorso
    target = None
    if argument[0 : 2] == "a ":
        arg, argument = one_argument(argument)
        # Se sta parlando a qualcuno cerca di acquisirlo dal nome successivo
        objective_name, argument = one_argument(argument)
        target = entity.find_entity_extensively(objective_name)
        # con me e self esegue un check senza la is_same volutamente, per evitare
        # ricerche con nome di player che iniziano con Me o Self
        if target == entity or objective_name in ("me", "self"):
            objective = OBJECTIVE_SELF
            # Se si parla da soli lo si fa utilizzando la lingua madre
            language = entity.race.natural_language
        elif target:
            objective = OBJECTIVE_TARGET
            # Se si parla con qualcuno della stessa razza lo si fa utilizzando
            # la lingua preferita dalla razza, è un fattore culturale
            if entity.race == target.race:
                language = entity.race.natural_language
        else:
            # Se non ha trovato nessun 'a <nome bersaglio>' riprende
            # l'argument originale
            argument = original_argument
    # Stessa cosa di sopra ma qui controlla se si stia parlando al gruppo
    elif argument[0 : 3] == "al ":
        arg, argument = one_argument(argument)
        objective_name, argument = one_argument(argument)
        if is_prefix(objective_name, "gruppo"):
            if not entity.group:
                entity.send_output("Non fai parte di nessun gruppo.")
                return False
            # Questa variabile verrà utilizza poi nell'invio del messaggio
            group_members = entity.get_members_here(entity.location)
            if not group_members:
                entity.send_output("Non trovi nessun membro del gruppo vicino a te con cui poter parlare.")
                return False
            objective = OBJECTIVE_GROUP
            # Se si parla in un gruppo in cui tutti sono formati dalla stessa
            # razza si preferirà parlare con la lingua della propria razza
            for group_member in group_members:
                if group_member.race != entity.race:
                    break
            else:
                language = entity.race.natural_language
        else:
            # Se il personaggio non vuole parlare al gruppo recupera
            # il valore originale inviato
            argument = original_argument

    # (TD) Gestisce il caso in cui l'entità si trovi immersa in un liquido
    #if entity.is_immersed():
    #    entity.send_output("Tenti di %s qualcosa ma subito l'acqua ti riempie la gola soffocandoti!" % channel)
    #    entity.points.life -= random.randint(entity.level / 6, entity.level / 4) + 1
    #    return False

    if not entity.location:
        log.bug("entity %s non si trova in una locazione valida: %r (original_argument: %s)" % (
            entity.code, entity.location, original_argument))
        return False

    # Gestisce le stanze che obbligano al silenzio
    if entity.location.IS_ROOM:
        if ROOM.SILENCE in entity.location.flags:
            entity.send_output("Il silenzio del luogo ti blocca la gola impedendoti di %s." % channel)
            return False

        # (TT) Se nella stanza c'è molto casino, tante persone etc etc è difficile
        # parlare piano
        if entity.location.mod_noise > 75 and channel <= CHANNEL.SAY:
            entity.send_output("Non puoi %s con tutta questa confusione!" % channel)
            return False

    # Invia l'appropriato messaggio nel caso in cui trovi argument vuoto
    if not argument:
        send_not_argument_message(entity, objective, channel)
        return False

    # Cerca eventuali smiles nella stringa controllando gli ultimi caratteri
    for social in database["socials"].itervalues():
        if not social.smiles:
            continue
        for single_smile in social.smiles.split():
            if single_smile in argument[-config.chars_for_smile : ]:
                break
        else:
            # Se non trova nessun smile esce dal ciclo dei social e continua
            # col prossimo set di smiles trovato
            continue

        cut_smile = argument.rfind(single_smile)
        # Se argument è formato solo dallo smile invia il corrispondente social
        if cut_smile == 0:
            social_name = social.fun_name[len("social_") : ]
            if objective == OBJECTIVE_TARGET:
                input_to_send = "%s %s" % (social_name, target.name)
            elif objective == OBJECTIVE_SELF:
                input_to_send = "%s %s" % (social_name, entity.name)
            else:
                input_to_send = social_name

            send_input(entity, input_to_send, "en", show_input=False, show_prompt=False)
            return True

        # Altrimenti ne ricava l'espressione dello smile-social e toglie lo
        # smile da argument, se il carattere dopo lo smile era un simbolo di
        # punteggiatura lo attacca alla frase togliendo gli spazi
        first_part  = argument[ : cut_smile]
        second_part = argument[cut_smile + len(single_smile) : ]
        if second_part.strip() and second_part.strip()[0] in "!?.,:;":
            first_part = first_part.rstrip()
            second_part = second_part.lstrip()
        argument = first_part.rstrip() + second_part.rstrip()
        smile = " %s" % social.expression
        break

    # Elabora i punti esclamativi e interrogativi per il canale say.
    # Qui viene utilizzata l'opzione chars_for_smile visto che si sta facendo
    # una cosa simile a sopra, ovvero considerare solo l'ultima parte
    # dell'argomento passato.
    exclamations = argument[-config.chars_for_smile : ].count("!")
    questions    = argument[-config.chars_for_smile : ].count("?")
    if exclamations > questions:
        if channel == CHANNEL.SAY:
            verb_you = "Esclami"
            verb_it  = " esclama"
        exclaim = True
    elif exclamations < questions:
        if channel == CHANNEL.SAY:
            verb_you = "Domandi"
            verb_it  = " domanda"
        ask = True
    # Questo elif sottintende che exclamations e questions siano uguali
    elif exclamations != 0 and questions != 0:
        # Con una stessa quantità di ! e di ? l'ultimo che viene trovato
        # ha maggiore peso rispetto all'altro
        exclamation_pos = argument.rfind("!")
        question_pos = argument.rfind("?")
        if exclamation_pos > question_pos:
            if channel == CHANNEL.SAY:
                verb_you = "Esclami"
                verb_it  = " esclama"
            exclaim = True
        else:
            if channel == CHANNEL.SAY:
                verb_you = "Domandi"
                verb_it  = " domanda"
            ask = True

    # Supporto per piccoli emote separati da * ad inizio argument
    if argument[0] == "*":
        cut_emote = argument[1 : ].find("*")
        if cut_emote != -1:
            emote = " %s" % argument[1 : cut_emote+1].strip()
            if smile:
                emote = " e%s" % emote
            argument = argument[cut_emote+2 : ].strip()

    # Unisce i vari pezzi per formare l'output
    expres_entity = verb_you
    expres_room = verb_it
    expres_target = ""
    if objective == OBJECTIVE_TARGET:
        name = target.get_name(entity)
        expres_entity += " a %s" % name
        expres_room   += " a %s" % name
        expres_target += " ti%s" % verb_it
    elif objective == OBJECTIVE_SELF:
        expres_entity += " a te stess%s" % grammar_gender(entity)
        expres_room   += " a sé stess%s" % grammar_gender(entity)
    elif objective == OBJECTIVE_GROUP:
        members = entity.get_members_here(entity.location)
        if len(members) == 1:
            expres_entity += " a %s" % members[0].name
            expres_room   += " a %s" % members[0].name
            expres_target += " ti%s" % verb_it
        else:
            if len(members) > 5:
                many = "folto "
            else:
                many = ""
            expres_entity += " al gruppo"
            expres_room   += " ad un %sgruppo" % many
            expres_target += "%s al gruppo" % verb_it
    # Aggiunge le eventuali espressioni dello smile e dell'emote
    expres_entity += smile + emote
    expres_room   += smile + emote
    expres_target += smile + emote

    if not argument:
        send_not_argument_message(entity, objective, channel)
        return False

    # Prepara il pezzo riguardante la lingua utilizzata
    language = ""
    if not entity.IS_ITEM and entity.speaking != LANGUAGE.COMMON:
        language = " in lingua %s" % entity.speaking

    # Mischia il testo se si è ubriachi
    original_argument = argument = color_first_upper(argument)
    argument = drunk_speech(argument, entity)

    # Parlando si impara la lingua
    if not entity.IS_ITEM:
        learn_language(entity, channel, entity.speaking)

    # Controlla se vi sono parolacce o parole offrpg e logga i relativi argument
    if entity.IS_PLAYER:
        check_for_badwords(entity, argument)

    # Invia il messaggio a tutti coloro che lo possono sentire
    for location in expand_voice_around(entity, channel):
        if not location:
            log.bug("location per il canale %s e per l'entità %s non è valida: %r" % (channel, entity.code, location))
            continue
        for listener in location.iter_contains(use_reversed=True):
            if listener.position <= POSITION.SLEEP:
                continue

            if listener == entity:
                force_return = check_trigger(entity, "before_rpg_channel", listener, entity, target, argument, ask, exclaim, behavioured)
                if force_return:
                    continue
                force_return = check_trigger(entity, "before_" + channel.trigger_suffix, listener, entity, target, argument, ask, exclaim, behavioured)
                if force_return:
                    continue

                # Invia all'entità il suo stesso messaggio
                first_part = (close_color(color) + expres_entity).rstrip()
                message = "%s: '%s'" % (first_part, close_color(argument))
                send_channel_message(entity, message, True)

                force_return = check_trigger(entity, "after_rpg_channel", listener, entity, target, argument, ask, exclaim, behavioured)
                if force_return:
                    continue
                force_return = check_trigger(entity, "after_" + channel.trigger_suffix, listener, entity, target, argument, ask, exclaim, behavioured)
                if force_return:
                    continue
            else:
                # Fa ascoltare solo ad un'entità di un eventuale gruppo fisico
                listener = listener.split_entity(1)

                force_return = check_trigger(listener, "before_listen_rpg_channel", listener, entity, target, argument, ask, exclaim, behavioured)
                if force_return:
                    continue
                force_return = check_trigger(listener, "before_listen_" + channel.trigger_suffix, listener, entity, target, argument, ask, exclaim, behavioured)
                if force_return:
                    continue

                # Prepara alcune cose a seconda della stanza di provenienza del messaggio
                if entity.location == listener.location:
                    entity_name = entity.get_name(listener)
                    entity_name = color_first_upper(entity_name)
                    from_direction = ""
                elif entity.location.IS_ROOM:
                    # (TD) invia qualcuno a meno che non lo si abbia conosciuto
                    # precedentemente con il sistema di presentazione
                    entity_name = "Qualcuno"
                    from_direction = get_from_direction(listener.location.x, listener.location.y, listener.location.z,
                                                        entity.location.x, entity.location.y, entity.location.z)
                elif entity.location.IS_ACTOR:
                    if entity.location != listener:
                        entity_name = "Qualcuno"  # (TD) come sopra
                    from_direction = " dall'inventario di %s" % entity.location.get_name(listener)
                else:
                    entity_name = "Qualcuno"  # (TD) come sopra
                    from_direction = " da dentro %s" % entity.location.get_name(listener)

                # Prepara la prima parte, quella senza il messaggio
                if objective == OBJECTIVE_ROOM:
                    output = "%s%s%s%s" % (entity_name, close_color(color) + expres_room, language, from_direction)
                elif objective == OBJECTIVE_TARGET or OBJECTIVE_SELF:
                    if listener == target:
                        output = "%s%s%s%s" % (entity_name, close_color(color) + expres_target, language, from_direction)
                    else:
                        output = "%s%s%s%s" % (entity_name, close_color(color) + expres_room, language, from_direction)
                elif objective == OBJECTIVE_GROUP:
                    if listener in group_members:
                        output = "%s%s%s%s" % (entity_name, close_color(color) + expres_target, language, from_direction)
                    else:
                        output = "%s%s%s%s" % (entity_name, close_color(color) + expres_room, language, from_direction)

                output = "<br>%s: '%s'" % (close_color(output).rstrip(), close_color(argument))
                send_channel_message(listener, output, False)
                listener.send_prompt()

                force_return = check_trigger(listener, "after_listen_rpg_channel", listener, entity, target, argument, ask, exclaim, behavioured)
                if force_return:
                    continue
                force_return = check_trigger(listener, "after_listen_" + channel.trigger_suffix, listener, entity, target, argument, ask, exclaim, behavioured)
                if force_return:
                    continue

    return True
Example #21
0
    def __init__(self, name=""):
        super(Player, self).__init__(code="")

        # Il codice non bisogna passarlo come parametro nell'inizializzazione
        # degli attributi perché viene ricavato dal nome
        if name:
            self.code = remove_colors(name)
            self.name = name

        # Rimuove o deinizializza gli attributi inutili per i giocatori
        del(self.behaviour)
        del(self.keywords_name)
        del(self.keywords_short)
        del(self.keywords_short_night)
        del(self.prototype)

        self.life           = config.starting_points
        self.mana           = config.starting_points
        self.vigour         = config.starting_points
        self.max_life       = self.life
        self.max_mana       = self.mana
        self.max_vigour     = self.vigour

        self.strength       = config.starting_attrs
        self.endurance      = config.starting_attrs
        self.agility        = config.starting_attrs
        self.speed          = config.starting_attrs
        self.intelligence   = config.starting_attrs
        self.willpower      = config.starting_attrs
        self.personality    = config.starting_attrs
        self.luck           = config.starting_attrs

        # Variabile proprie di un'istanza di Player
        self.created_time        = datetime.datetime.now()  # Data di creazione del personaggio
        self.account             = None  # Account del giocatore che contiene questo personaggio
        self.permissions         = ""  # Permessi aggiunti alla normale trust
        self.surname             = ""  # Cognome o simile
        self.old_names           = ""  # Tiene traccia dei vecchi nomi in caso di restring del nome
        self.title               = ""  # Titolo con cui è conosciuto il personaggio
        self.target_descr        = ""  # Descrizione dell'obiettivo che il personaggio vuole perseguire
        self.login_time          = None
        self.logout_time         = None
        self.inactivity          = 0
        self.seconds_played      = 0
        self.login_times         = 0
        self.last_input          = "guarda"  # Ultimo input inviato al Mud
        self.reputations         = {}  # Reputazione nei confronti delle varie razze
        self.talents             = 0
        self.practices           = 0
        self.gifts               = []
        self.idle_seconds        = 0
        self.ban                 = None
        self.visited_areas       = {}  # Indica quali aree sono state visitate e quante volte
        self.visited_rooms       = {}  # Indica quali aree e quali room sono state visitate almeno una volta
        self.readed_books        = {}  # Indica quali libri sono stati letti almeno una volta
        self.digged_rooms        = {}  # Indica quali stanze sono state stavate almeno una volta
        self.eated_entities      = {}  # Indica quali entità sono state mangiate almeno una volta
        self.drinked_entities    = {}  # Indica quali entità sono state bevute almeno una volta
        self.possessed_entities  = {}  # Indica quali entità sono state possedute in inventario almeno una volta
        self.sensed_entities     = {}  # Indica quali entità sono state esaminate con un comando sensoriale che non sia il look
        self.sensed_rooms        = {}  # Indica quali stanze sono state esaminate con un comando sensoriale che non sia il look
        self.interred_entities   = {}  # Indica quali entità sono state interrate tramite il comando plant o il comando seed
        self.opened_entities     = {}  # Indica quali entità sono state aperte tramite il comando open
        self.unlocked_entities   = {}  # Indica quali entità sono state sbloccate tramite il comando unlock
        self.unbolted_entities   = {}  # Indica quali entità sono state svincolate tramite il comando unbolt
        self.entered_entities    = {}  # Indica quali entità sono state utilizzate come portali tramite il comando enter
        self.selled_entities     = {}  # Indica quali entità sono state vendute tramite il comando sell
        self.bought_entities     = {}  # Indica quali entità sono state vendute tramite il comando buy

        # Variabili volatili
        self.sended_inputs  = collections.deque([], 100)  # Lista degl input inviati dal giocatore
        self.backsteps      = collections.deque([], 100)  # Lista delle locazioni cui l'entità si è trovata precedentemente
Example #22
0
    def enter_in_game(self):
        force_return = check_trigger(self, "before_enter_in_game", self)
        if force_return:
            return

        # Resetta il contatore di idle, è normale che conn non sia valido
        # durante il test degli inputs
        conn = self.get_conn()
        if conn:
            conn.reinit()
        elif not engine.test_inputs_mode:
            log.bug("conn non è valido: %r" % conn)
            return

        # Se il pg ha impostato l'incognito ma non è un admin allora gli
        # viene rimosso
        if self.incognito and self.trust == TRUST.PLAYER:
            log.admin("Rimozione automatica dell'incognito al giocatore %s" % self.code)
            self.incognito = False

        # Se la stanza in cui il personaggio si trova è ancora impostata
        # significa che il giocatore si sta riconnettendo (per colpa di un
        # crash oppure utilizzando un altro browser)
        if self.location:
            # Ripulisce qualsiasi precedente istanza di connessione alla pagina
            # del gioco che non sia quella attuale
            actual_session = self.game_request.getSession()
            for session, connection in connections.iteritems():
                if session == actual_session:
                    continue
                if connection.account and OPTION.COMET not in connection.account.options:
                    continue
                if ("/game_input.html" in repr(connection.request)
                or  "/game_output.html" in repr(connection.request)):
                    # (TT) in realtà qui dovrei ucciderla o unpausarla,
                    # altrimenti mi occupa spazio di memoria, magari aggiungerla
                    # come lista alle precedenti deferrenti di questa connessione
                    connection.defer_exit_from_game.pause()
                    connection.defer_exit_from_game = None
                    del(connection)
            # Se un pg si riconnette non avvisa via mail
            send_a_mail = False
            log_message = "%s si riconnette al gioco" % self.code
        # Qui dovrebbe passare per tutti i personaggi che sono entrati almeno
        # una volta in gioco e che non hanno avuto problemi di sorta
        elif self.previous_location and self.previous_location() and not self.previous_location().IS_PLAYER:
            location = self.previous_location()
            self.previous_location = None
            self.to_location(location, use_iterative_put=False)
            send_a_mail = True
            self.login_times += 1
            log_message = "%s entra nel gioco per la %d° volta" % (self.code, self.login_times)
        # Se la stanza in cui se ne era andato il personaggio non è stata
        # impostata durante il quit allora significa che il giocatore è nuovo
        # oppure c'è stato un baco che ne ha corrotto il riferimento
        else:
            destination_room = config.initial_destination.get_room()
            if not destination_room:
                log.bug("destination_room non valida: %r" % destination_room)
                return
            self.to_location(destination_room, use_iterative_put=True)
            send_a_mail = True
            self.login_times += 1
            log_message = "%s entra nel gioco per la %d° volta" % (self.code, self.login_times)

        if not engine.test_inputs_mode:
            log.always(log_message)

        # Controlla se deve donare un'entità all'evento a cui il giocatore
        # sta partecipando; il regalo può essere sia un oggetto che un mob
        if config.gift_on_enter and config.gift_on_enter not in self.gifts:
            gift = config.gift_on_enter.CONSTRUCTOR(config.gift_on_enter.code)
            if gift:
                # Si presuppone che i gift non abbiano il max_global_quantity
                gift.inject(self)
                self.gifts.append(config.gift_on_enter)
            else:
                log.bug("Impossibile creare il dono %s per %s: %r" % (
                    config.gift_on_enter.code, self.code, gift))

        # Avvisa gli admin via mail se un pg è appena entrato nel Mud
        if self.account and self.account.trust > TRUST.PLAYER:
            send_a_mail = False
        for player in self.account.players.itervalues():
            if player.trust > TRUST.PLAYER:
                send_a_mail = False
        if send_a_mail and config.mail_on_enter_in_game:
            mail.send_to_admins(log_message, "%s è un %s di livello %s dell'account %s." % (
                self.code,
                self.sex_replacer(remove_colors(self.race.name)),
                self.level,
                self.account.name if self.account else "<Errore>"))

        eyes = self.eye_colorize("occhi")
        self.act("Ti materializzi poco a poco dal nulla e poi apri gli %s.\n" % eyes, TO.ENTITY)
        self.act("$n si materializza poco a poco dal nulla e apre gli %s come se si stesse svegliando." % eyes, TO.OTHERS)
        command_look(self)

        self.inactivity = 0

        log.connections()

        force_return = check_trigger(self, "after_enter_in_game", self)
        if force_return:
            return
Example #23
0
    def create_quantities_list(self):
        quantities = []

        for table_name in ("proto_mobs", "proto_items"):
            quantities.append('''<table class="mud">''')
            for proto_code, prototype in database[table_name].iteritems():
                if prototype.max_global_quantity <= 0:
                    continue
                quantities.append('''<tr><td>''')
                quantities.append('''<a href="global_quantity.html?proto_code=%s" title="%s">%s</a>''' % (proto_code, remove_colors(prototype.name), proto_code))
                quantities.append('''</td><td>''')
                quantities.append('''<span style="color:%s">%d su %d</span>''' % (
                    "red" if prototype.current_global_quantity >= prototype.max_global_quantity else "", prototype.current_global_quantity, prototype.max_global_quantity))
                quantities.append('''</tr></td>''')
            quantities.append('''</table><br>''')

        return quantities
Example #24
0
def get_error_message_name(name, already_in_database, table_name="accounts"):
    """
    Controlla che il nome passato sia valido.
    Questa funzione viene utilizzata sia per i nomi degli account sia per
    quelli dei personaggi.
    Ritorna un messaggio vuoto se tutto è a posto, altrimenti il primo
    messaggio d'errore incontrato.
    Bisogna passare l'argomento already_in_database uguale a False quando si
    controlla l'integrità di un nome di Account o di Player appena creati e
    non ancora aggiunti al relativo database, viceversa bisogna passarlo a True.
    """
    if table_name not in ("players", "accounts"):
        return "L'argomento table_name non è valido: %s" % table_name

    # -------------------------------------------------------------------------

    name = name or ""

    # Se è un nome di un personaggio rimuove gli eventuali codici css
    if table_name == "players":
        name = remove_colors(name)

    # Controlla la lunghezza del nome
    length = len(name)
    if length < config.min_len_name:
        return "Nome troppo corto, deve essere almeno di %d caratteri." % config.min_len_name
    if length > config.max_len_name:
        return "Nome troppo lungo, può essere al massimo lungo %d caratteri." % config.max_len_name

    # Controlla che i caratteri del nome siano solo alfabetici o accentati
    # (BB) c'è ancora il problema degli accenti che non vengono letti da scritte
    # inviate tramite web, commentate alcune righe in favore di un rimpiazzo
    # in attesa del python 3.0 per risolvere la faccenda
    if table_name == "accounts" and not isalnum_accent(name):
        #return "Il nome può essere formato solo da lettere (accentate o meno) e da numeri."
        return "Il nome può essere formato solo da lettere e da numeri."
    if table_name == "players" and not isalpha_accent(name):
        #return "Il nome può essere formato solo da lettere (accentate o meno)."
        return "Il nome può essere formato solo da lettere."

    # Il nome può avere in più un accento per ogni tre caratteri
    if count_accents(name) > len(name) / 3:
        return "Il nome, per essere maggiormente leggibile, può avere solo un accento ogni tre caratteri."

    # Controlla che il nome abbia una determinata varietà di caratteri inseriti
    # per evitare nomi come Aaa
    if len(set(name.lower())) < math.floor(math.log(len(name)) * 2):
        return "Nome troppo poco vario, utilizzare un maggior numero di vocali o consonanti differenti"

    # Controlla se esiste già il nome nel database passato, bisogna utilizzare
    # is_same() altrimenti nomi simili, ma uno con vocale semplice e l'altro
    # con vocale accentanta, vengono visti come differenti
    for data in database[table_name].itervalues():
        if is_same(data.name, name) or (hasattr(data, "code") and is_same(data.code, name)):
            # Se si sta controllando un nome già esistente nel database
            # quando lo trova per una volta lo salta
            if already_in_database:
                already_in_database = False
                continue
            return "Il nome è già utilizzato in un altro account."

    # Controlla che il nome non sia una parolaccia, una parola off-rpg, un
    # nome non utilizzabile o una little word, che degenererebbe la creazione
    # dinamica delle kewywords per i personaggi
    for swear_word in swearwords:
        if is_same(swear_word, name):
            return "Il nome non è valido perché è una parolaccia."
    if table_name == "players":
        for offrpg_word in offrpg_words:
            if is_same(offrpg_word, name):
                return "Il nome non è valido perché è una parola non GDR."
        for forbidden_name in forbidden_names:
            if is_same(forbidden_name, name):
                return "Il nome non è valido."
        for little_word in little_words:
            if is_same(little_word, name):
                return "Il nome non è valido."

    # Controlla che la prima lettera sia maiuscola e il resto minuscolo
    if name != name.capitalize():
        return "Il nome non inizia con la maiuscola e il resto minuscolo"

    # Se tutto è ok ritorna un messaggio vuoto
    return ""
Example #25
0
def command_list(entity, argument="", behavioured=False):
    """
    Permette di comprare entità da un commerciante.
    """
    # Può essere normale se il comando è stato deferrato
    if not entity:
        return False

    entity = entity.split_entity(1)

    if argument:
        dealer = entity.find_entity_extensively(argument)
        if not dealer:
            entity.act("Non trovi nessun negoziante chiamato [white]%s[close]." % argument, TO.ENTITY)
            entity.act("$n sembra cercare qualcuno un negoziante.", TO.OTHERS)
            return False
        if not dealer.shop:
            entity.act("$N non sembra essere un negoziante.", TO.ENTITY, dealer)
            entity.act("$n crede erroneamente che $N sia un negoziante.", TO.OTHERS, dealer)
            entity.act("$n crede erroneamente che tu sia un negoziante.", TO.TARGET, dealer)
            return False
    # Altrimenti cerca il primo negoziante che si trova nella locazione del giocatore
    else:
        for dealer in entity.location.iter_contains():
            if dealer.shop:
                break
        else:
            entity.act("Qui non trovi nessun [white]negoziante[close].", TO.ENTITY)
            entity.act("$n non sembra trovare nessun negoziante qui intorno.", TO.OTHERS)
            return False

    in_location = dealer.shop.in_location(dealer)
    if not in_location and SHOP.DISPENSER not in dealer.shop.types:
        entity.act("$N non ti mostra la merce perché non si trova nel suo negozio.", TO.ENTITY, dealer)
        entity.act("$N non mostra la merce a $n perché non si trova nel suo negozio.", TO.OTHERS, dealer)
        entity.act("Non mostri la tua merce a $n perché non ti trovi nel tuo negozio.", TO.TARGET, dealer)
        return False

    # Indica che un'entità vuole interagire con il dealer
    if entity not in dealer.interactions:
        dealer.interactions.append(entity)

    storage = dealer.shop.get_storage(dealer)
    if not storage:
        if dealer.shop.proto_storages and dealer.shop.proto_storages[0].IS_MOB:
            from_where = "da chi"
        else:
            from_where = "da dove"
        entity.act("Non puoi avere la lista da $N perché non ha %s prendere la mercanzia!" % from_where, TO.ENTITY, dealer)
        entity.act("$n non può avere la lista da $N perché non ha %s prendere la mercanzia!" % from_where, TO.OTHERS, dealer)
        entity.act("$n non può avere la lista perché non hai %s prendere la mercanzia!" % from_where, TO.TARGET, dealer)
        return False

    if not dealer.shop.buyables:
        entity.send_output("%s non possiede nessuna mercanzia" % dealer.get_name(looker=entity))
        log.bug("Non è stato trovato nessun buyable impostato per %s" % dealer.code)
        return False

    # Controlla se il magazzino contiene almeno un oggetto comprabile dall'utente
    if dealer.shop.storage_is_empty(storage):
        entity.act("Ti accorgi che il negozio non possiede mercanzia, meglio tornare più tardi, dopo il rifornimento.", TO.ENTITY, dealer)
        entity.act("$n si accorge che il negozio non possiede mercanzia.", TO.OTHERS, dealer)
        entity.act("$n si accorge che il tuo negozio non possiede mercanzia.", TO.TARGET, dealer)
        return False

    force_return = check_trigger(entity, "before_list", entity, dealer, behavioured)
    if force_return:
        return True
    force_return = check_trigger(dealer, "before_listed", entity, dealer, behavioured)
    if force_return:
        return True

    if SHOP.DISPENSER in dealer.shop.types:
        if not in_location:
            entity.act("Leggi su di una targetta la lista delle mercanzie di $N anche se non si trova nel suo negozio.", TO.OTHERS, dealer)
            entity.act("$n legge su di una targetta la lista delle mercanzie di $N anche se non si trova nel suo negozio.", TO.OTHERS, dealer)
            entity.act("$n legge la tua targetta con la lista delle mercanzie anche se non si trova nel suo negozio.", TO.TARGET, dealer)
        else:
            entity.act("Leggi su di una targetta la lista delle mercanzie di $N.", TO.OTHERS, dealer)
            entity.act("$n legge su di una targetta la lista delle mercanzie di $N.", TO.OTHERS, dealer)
            entity.act("$n legge la tua targetta con la lista delle mercanzie.", TO.TARGET, dealer)
    else:
        entity.act("Chiedi la lista delle mercanzie di $N.", TO.OTHERS, dealer)
        entity.act("$n chiede la lista delle mercanzie di $N.", TO.OTHERS, dealer)
        entity.act("$n ti chiede la lista delle mercanzie.", TO.TARGET, dealer)

    discount_exist = False
    for buyable in dealer.shop.buyables:
        if buyable.has_discount():
            discount_exist = True

    buy_translation = translate_input(entity, "buy", "en")
    rows = []
    rows.append('''<table class="mud">''')
    discount_cell = ""
    if SHOP.DISPENSER in dealer.shop.types:
        name_cell = "Prodotti"
    else:
        name_cell = "Mercanzia"
    if discount_exist:
        discount_cell = '''<th>Sconto</th>'''
    rows.append('''<tr><th></th><th>%s</th><th colspan="4">Prezzo</th><th>Livello</th><th></th><th></th>%s</tr>''' % (
        name_cell, discount_cell))
    for en in storage.get_list_of_entities(entity):
        en = en[INSTANCE]
        for buyable in dealer.shop.buyables:
            if en.prototype != buyable.proto_entity:
                continue

            # Purtroppo però il sistema di mucchio visivo non permetterà di
            # visualizzare quantità superiori ad 1 per oggetti di long uguali
            # tra loro, la quantità si deve per forza basare sul mucchio fisico
            quantity = 10
            if buyable.has_discount():
                quantity = buyable.discount_quantity
            if en.quantity < quantity:
                quantity = en.quantity

            name = en.get_name(looker=entity)
            single_price, dummy_discount = buyable.get_price(en, quantity=1)
            block_price, dummy_discount = buyable.get_price(en, quantity=quantity)
            mithril, gold, silver, copper = pretty_money_icons(single_price)
            rows.append('''<tr><td>%s</td>''' % create_icon(en.get_icon(), add_span=False))
            rows.append('''<td>%s </td>''' % create_tooltip(entity.get_conn(), en.get_descr(looker=entity), name))
            rows.append('''<td align="right">%s</td>''' % mithril)
            rows.append('''<td align="right">%s</td>''' % gold)
            rows.append('''<td align="right">%s</td>''' % silver)
            rows.append('''<td align="right">%s</td>''' % copper)
            rows.append('''<td align="center">%d</td>''' % en.level)
            rows.append('''<td><input type="submit" value="%s" onclick="sendInput('%s 1 %s')" title="Comprerai %s per un prezzo di %s"/></td>''' % (
                buy_translation.capitalize(),
                buy_translation,
                en.get_numbered_keyword(looker=entity),
                remove_colors(name),
                remove_colors(pretty_money_value(single_price))))
            rows.append('''<td><input type="submit" value="%s x %d" onclick="sendInput('%s %d %s')" title="Comprerai %d unità di %s per un prezzo di %s"/></td>''' % (
                buy_translation.capitalize(),
                quantity,
                buy_translation,
                quantity,
                en.get_numbered_keyword(looker=entity),
                quantity,
                remove_colors(name),
                remove_colors(pretty_money_value(block_price))))
            if discount_exist:
                if buyable.has_discount():
                    rows.append('''<td align="center">%d%% per quantità maggiori di %d</td>''' % (buyable.discount_percent, buyable.discount_quantity))
                else:
                    rows.append('''<td align="center">Nessuno</td>''')
            rows.append('''</tr>''')
    rows.append('''</table>''')
    entity.send_output("".join(rows), break_line=False)

    force_return = check_trigger(entity, "after_list", entity, dealer, behavioured)
    if force_return:
        return True
    force_return = check_trigger(dealer, "after_listed", entity, dealer, behavioured)
    if force_return:
        return True

    return True
Example #26
0
    def msg(self, message, log_type=None, log_stack=True, write_on_file=True, send_output=True, use_blink=False):
        """
        Invia un messaggio di log contenente errori o avvisi.
        """
        if not message:
            print("[log.bug] message non è un parametro valido: %r" % message)
            return

        # -------------------------------------------------------------------------

        from src.enums import LOG

        # Questa extract_stack è un collo di bottiglia prestazionale del Mud,
        # tuttavia la sua utilità è indubbia e quindi fino a che Aarit non sarà
        # maturissimo è inutile anche evitarla con qualche opzione di config.
        # Ho deciso tuttavia di saltare il print della last_function relativa
        # a tutti i messaggi di log reset, che sono quelli maggiormente inviati
        stack = None
        last_function = ""
        last_function = ""
        if not log_type or log_type.show_last_function:
            stack = traceback.extract_stack()
            last_function = str(stack[-3][2])

        # Stampa il messaggio alla console e lo scrive sul file
        if stack:
            source_name = stack[-3][0].replace(os.getcwd(), "")
            if "src" in source_name:
                position = source_name.find("src")
                source_name = source_name[position : ]
            elif "data" in source_name:
                position = source_name.find("data")
                source_name = source_name[position : ]
            source_line = stack[-3][1]
            last_function = " (%s %s %s)" % (last_function, source_name, source_line)

        # Rimuove i colori dal messaggio per una stampa a video maggiormente amica
        from src.color import remove_colors
        message = remove_colors(message)

        # Invia il messaggio di log agli Admin del Mud
        if send_output:
            from src.database import database
            if "players" in database and log_type.show_on_mud:
                from src.utility import html_escape
                for player in database["players"].itervalues():
                    if not player.game_request:
                        continue
                    if player.trust < log_type.trust and str(log_type.code) not in player.permissions:
                        continue
                    if log_type != LOG.ALWAYS and log_type not in player.account.show_logs and str(log_type.code) not in player.permissions:
                        continue
                    open_span = ""
                    close_span = ""
                    if use_blink:
                        open_span = "<span style='text-decoration: blink;'>"
                        close_span = "</span>"
                    player.send_output("<br>[magenta]%s%s %s%s[close]" % (
                        open_span, last_function.lstrip(), html_escape(message), close_span), avoid_log=True)
                    player.send_prompt()

        # Visto che anche gli altri loop sono legati a questo, non c'è bisogno
        # di controllarle tutti
        from src.loops.aggressiveness import aggressiveness_loop
        from src.loops.blob           import blob_loop
        from src.entitypes.corpse     import decomposer_loop
        from src.loops.digestion      import digestion_loop
        from src.fight                import fight_loop
        from src.game                 import game_loop
        from src.maintenance          import maintenance_loop
        from src.behaviour            import room_behaviour_loop
        if (game_loop and game_loop.running
        and maintenance_loop and maintenance_loop.running
        and room_behaviour_loop and room_behaviour_loop.running
        and fight_loop and fight_loop.running
        and decomposer_loop and decomposer_loop.running
        and aggressiveness_loop and aggressiveness_loop.running
        and blob_loop and blob_loop.running
        and digestion_loop and digestion_loop.running):
            loop_status = "L"
        else:
            loop_status = "l"

        now = datetime.datetime.now()
        message = "%02d:%02d:%02d [%s] {%s}%s: %s" % (
            now.hour,
            now.minute,
            now.second,
            log_type,
            loop_status,
            last_function,
            message)

        log_file = None
        if write_on_file and log_type.write_on_file:
            log_path = "log/%d-%02d-%02d.log" % (now.year, now.month, now.day)
            try:
                log_file = open(log_path, "a")
            except IOError:
                print "Impossibile aprire il file %s in append" % log_path
                log_file = None
            else:
                log_file.write("%s\n" % message)

        # Questo viene fatto perché alcune console purtroppo non supportano
        # i caratteri accentati e simili, viene così convertito l'accento
        # nel famoso e muddoso accento apostrofato, quindi attenzione che
        # in tal caso il messaggio nello stdout è falsato da quello originale
        # nel qual caso si voglia cercarlo nel codice
        if log_type.print_on_console:
            from src.config import config
            if config.ready and config.log_accents:
                if "à" in message:
                    message = message.replace("à", "a'")
                if "è" in message:
                    message = message.replace("è", "e'")
                if "é" in message:
                    message = message.replace("é", "e'")
                if "ì" in message:
                    message = message.replace("ì", "i'")
                if "ò" in message:
                    message = message.replace("ò", "o'")
                if "ù" in message:
                    message = message.replace("ù", "u'")
            print(message)

        # Se la tipologia di log non è un bug allora evita le informazioni di stack
        if log_type != LOG.BUG:
            log_stack = False

        if stack and write_on_file and log_type.write_on_file and log_stack:
            try:
                traceback.print_stack(file=log_file)
                traceback.print_stack(file=sys.stdout)
            except IOError:
                # (TT) non ho capito bene come mai mi fa così, ma semplicemente
                # saltandolo mi evita di fare il traceback, cmq il log avviene
                pass

        if log_file:
            log_file.close()
Example #27
0
def get_error_message_name(name, already_in_database, table_name="accounts"):
    """
    Controlla che il nome passato sia valido.
    Questa funzione viene utilizzata sia per i nomi degli account sia per
    quelli dei personaggi.
    Ritorna un messaggio vuoto se tutto è a posto, altrimenti il primo
    messaggio d'errore incontrato.
    Bisogna passare l'argomento already_in_database uguale a False quando si
    controlla l'integrità di un nome di Account o di Player appena creati e
    non ancora aggiunti al relativo database, viceversa bisogna passarlo a True.
    """
    if table_name not in ("players", "accounts"):
        return "L'argomento table_name non è valido: %s" % table_name

    # -------------------------------------------------------------------------

    name = name or ""

    # Se è un nome di un personaggio rimuove gli eventuali codici css
    if table_name == "players":
        name = remove_colors(name)

    # Controlla la lunghezza del nome
    length = len(name)
    if length < config.min_len_name:
        return "Nome troppo corto, deve essere almeno di %d caratteri." % config.min_len_name
    if length > config.max_len_name:
        return "Nome troppo lungo, può essere al massimo lungo %d caratteri." % config.max_len_name

    # Controlla che i caratteri del nome siano solo alfabetici o accentati
    # (BB) c'è ancora il problema degli accenti che non vengono letti da scritte
    # inviate tramite web, commentate alcune righe in favore di un rimpiazzo
    # in attesa del python 3.0 per risolvere la faccenda
    if table_name == "accounts" and not isalnum_accent(name):
        #return "Il nome può essere formato solo da lettere (accentate o meno) e da numeri."
        return "Il nome può essere formato solo da lettere e da numeri."
    if table_name == "players" and not isalpha_accent(name):
        #return "Il nome può essere formato solo da lettere (accentate o meno)."
        return "Il nome può essere formato solo da lettere."

    # Il nome può avere in più un accento per ogni tre caratteri
    if count_accents(name) > len(name) / 3:
        return "Il nome, per essere maggiormente leggibile, può avere solo un accento ogni tre caratteri."

    # Controlla che il nome abbia una determinata varietà di caratteri inseriti
    # per evitare nomi come Aaa
    if len(set(name.lower())) < math.floor(math.log(len(name)) * 2):
        return "Nome troppo poco vario, utilizzare un maggior numero di vocali o consonanti differenti"

    # Controlla se esiste già il nome nel database passato, bisogna utilizzare
    # is_same() altrimenti nomi simili, ma uno con vocale semplice e l'altro
    # con vocale accentanta, vengono visti come differenti
    for data in database[table_name].itervalues():
        if is_same(data.name, name) or (hasattr(data, "code")
                                        and is_same(data.code, name)):
            # Se si sta controllando un nome già esistente nel database
            # quando lo trova per una volta lo salta
            if already_in_database:
                already_in_database = False
                continue
            return "Il nome è già utilizzato in un altro account."

    # Controlla che il nome non sia una parolaccia, una parola off-rpg, un
    # nome non utilizzabile o una little word, che degenererebbe la creazione
    # dinamica delle kewywords per i personaggi
    for swear_word in swearwords:
        if is_same(swear_word, name):
            return "Il nome non è valido perché è una parolaccia."
    if table_name == "players":
        for offrpg_word in offrpg_words:
            if is_same(offrpg_word, name):
                return "Il nome non è valido perché è una parola non GDR."
        for forbidden_name in forbidden_names:
            if is_same(forbidden_name, name):
                return "Il nome non è valido."
        for little_word in little_words:
            if is_same(little_word, name):
                return "Il nome non è valido."

    # Controlla che la prima lettera sia maiuscola e il resto minuscolo
    if name != name.capitalize():
        return "Il nome non inizia con la maiuscola e il resto minuscolo"

    # Se tutto è ok ritorna un messaggio vuoto
    return ""