"""gennick module for hikka userbot Copyright (C) 2025 Ruslan Isaev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.""" # meta developer: @RUIS_VlP # при поддержке @hikka_mods __version__ = (1, 0, 0) from .. import loader, utils import random import string from typing import List, Optional, Literal import re class NicknameGenerator: """Генератор произносимых и стильных никнеймов.""" DEFAULT_SYLLABLES = [ 'ka', 'shi', 'mi', 'zo', 'ren', 'ti', 'ne', 'su', 'vo', 'dai', 'xan', 'ri', 'fu', 'pu', 'ko', 'me', 'el', 'tra', 'qua', 'gen', 'lor', 'vik', 'nyx', 'zel', 'thor', 'syn', 'try', 'pho', 'lux', 'ry', 'kor', 'vex', 'ji', 'al', 'bis', 'war', 'tex', 'yon', 'ga', 'dra', 'fi', 'na', 'to', 'va', 'qu', 'ex', 'ja', 'ki', 'lu', 'ma' ] SPECIAL_CHARS = ['_', '-', '.', '!', '~'] def __init__(self): self.syllables = self.DEFAULT_SYLLABLES.copy() def generate( self, length: int = 8, *, phonemic_alternation: bool = True, add_number: bool = False, add_special_char: bool = False, syllables: Optional[List[str]] = None, capital_style: Literal['first', 'all', 'random', 'camel'] = 'first', min_syllable_length: int = 1, max_syllable_length: int = 3 ) -> str: """ Генерирует произносимый никнейм с заданными параметрами. Параметры: length: Длина никнейма phonemic_alternation: Чередовать гласные/согласные для лучшей произносимости add_number: Добавить случайное число в конец add_special_char: Добавить специальный символ syllables: Кастомный список слогов capital_style: Стиль капитализации min_syllable_length: Минимальная длина слога max_syllable_length: Максимальная длина слога """ # Инициализация слогов syllables = syllables or self.syllables syllables = [s for s in syllables if min_syllable_length <= len(s) <= max_syllable_length] # Проверка параметров if not syllables: raise ValueError("Нет подходящих слогов для генерации") # Выделение места для дополнительных символов extra_length = 0 if add_number: extra_length += random.randint(1, 2) if add_special_char: extra_length += 1 if extra_length >= length: raise ValueError("Запрошенная длина слишком мала для добавления дополнительных символов") nickname = [] remaining = length - extra_length last_type = None # Генерация основной части while remaining > 0: # Фильтрация слогов по длине possible = [s for s in syllables if len(s) <= remaining] # Фильтрация по фонетическому чередованию if phonemic_alternation and last_type is not None and len(possible) > 1: possible = self._filter_by_phonetics(possible, last_type) if not possible: # Если нет подходящих слогов, добавляем случайную букву char = random.choice(string.ascii_lowercase) nickname.append(char) remaining -= 1 last_type = self._get_char_type(char) continue syllable = random.choice(possible) nickname.append(syllable) remaining -= len(syllable) last_type = self._get_char_type(syllable[0]) # Добавление дополнительных символов if add_number: num_length = min(2, length - len(''.join(nickname))) if num_length > 0: min_num = 10 ** (num_length - 1) max_num = (10 ** num_length) - 1 nickname.append(str(random.randint(min_num, max_num))) if add_special_char: special_char = random.choice(self.SPECIAL_CHARS) insert_pos = random.choice([len(nickname) - 1, # Перед числом random.randint(1, len(nickname) - 1), # В середине 0 # В начале ]) nickname.insert(insert_pos, special_char) # Сборка финальной строки nickname_str = ''.join(nickname)[:length] # Применение стиля капитализации nickname_str = self._apply_capital_style(nickname_str, capital_style) return nickname_str def _filter_by_phonetics(self, syllables: List[str], last_type: str) -> List[str]: """Фильтрует слоги по фонетическому чередованию.""" filtered = [] for s in syllables: first_char = s[0].lower() current_type = self._get_char_type(first_char) if last_type != current_type: filtered.append(s) return filtered or syllables @staticmethod def _get_char_type(char: str) -> str: """Определяет тип символа (гласный/согласный).""" vowels = {'a', 'e', 'i', 'o', 'u', 'y'} return 'vowel' if char.lower() in vowels else 'consonant' @staticmethod def _apply_capital_style(nickname: str, style: str) -> str: """Применяет выбранный стиль капитализации.""" if style == 'first': return nickname.capitalize() elif style == 'all': return nickname.upper() elif style == 'random': return ''.join(random.choice([c.upper(), c.lower()]) for c in nickname) elif style == 'camel': parts = [] for i, part in enumerate(re.split('([^a-zA-Z0-9]+)', nickname)): if i % 2 == 0 and part: parts.append(part.capitalize()) else: parts.append(part) return ''.join(parts) return nickname @loader.tds class GenNickMod(loader.Module): """Простой генератор ников""" strings = { "name": "GenNick", } @loader.command() async def GenNick(self, message): """Генерирует стандартный ник""" generator = NicknameGenerator() await utils.answer(message, f"Ваш новый ник: {generator.generate()}") @loader.command() async def GenIntNick(self, message): """Генерирует ник с цифрами""" generator = NicknameGenerator() await utils.answer(message, f"Ваш новый ник: {generator.generate(add_number=True)}")