├── LICENSE ├── README.md ├── cache.py ├── cogs ├── anticrash.py ├── antispam.py ├── backup.py ├── cmdengine.py ├── logs.py ├── modercmd.py ├── nickcor.py ├── othercmds.py ├── premium.py ├── quarantine.py ├── rr.py └── settings.py ├── config.py ├── fonts └── Rubik-Light.ttf ├── helper.py ├── json └── commandinfo.json ├── log2.txt ├── logs.txt ├── main.py ├── messages.py ├── mongo.py ├── oauth.py ├── profilactic.py ├── punishments.py ├── requirements.txt ├── settings.py ├── snus.txt └── word.py /README.md: -------------------------------------------------------------------------------- 1 | # hiprotect 2 | тот самый бот, чей токен слил самсунг ассистент а потом он его удалил 3 | 4 | # Информация 5 | я не буду (а может быть и буду) рассказывать, как его запустить, да и вообще меня сьедят так что вообще меня больше не ждите в дискорде 6 | -------------------------------------------------------------------------------- /cache.py: -------------------------------------------------------------------------------- 1 | from mongo import db 2 | 3 | class Collection: 4 | def __init__(self, collection): 5 | self.collection = db[collection] 6 | print(collection, "loaded") 7 | self.cached = {} 8 | 9 | def add(self, id, data): 10 | idict = {"_id": id} 11 | self.collection.update_one(idict, {"$set": data}, upsert=True) 12 | if not id in self.cached: 13 | self.cached[id] = {} 14 | for i in data: 15 | self.cached[id][i] = data[i] 16 | 17 | def remove(self, id): 18 | idict = {"_id": id} 19 | self.collection.delete_one(idict) 20 | del self.cached[id] 21 | 22 | def delete(self, id, data): 23 | idict = {"_id": id} 24 | self.collection.update_one(idict, {"$unset": data}) 25 | for i in data: 26 | del self.cached[id][i] 27 | 28 | def load_data(self): 29 | results = self.collection.find({}) 30 | for res in results: 31 | self.cached[res["_id"]] = res 32 | return self.cached 33 | 34 | 35 | configs = Collection(collection = "config") 36 | configs_data = configs.load_data() 37 | 38 | antiflood = Collection(collection = "antiflood") 39 | antiflood_data = antiflood.load_data() 40 | 41 | antiinvite = Collection(collection = "antiinvite") 42 | antiinvite_data = antiinvite.load_data() 43 | 44 | antiraid = Collection(collection = "antiraid") 45 | antiraid_data = antiraid.load_data() 46 | 47 | bans = Collection(collection = "bans") 48 | bans_data = bans.load_data() 49 | 50 | locks = Collection(collection = "locks") 51 | locks_data = locks.load_data() 52 | 53 | mutes = Collection(collection = "mutes") 54 | mutes_data = mutes.load_data() 55 | 56 | warns = Collection(collection = "warns") 57 | warns_data = warns.load_data() 58 | 59 | invited = Collection(collection = "invited") 60 | invited_data = invited.load_data() 61 | 62 | perms = Collection(collection = "perms") 63 | perms_data = perms.load_data() 64 | 65 | rr = Collection(collection = "rr-new") 66 | rr_data = rr.load_data() 67 | 68 | whitelist = Collection(collection = "whitelist") 69 | whitelist_data = whitelist.load_data() 70 | 71 | quarantine = Collection(collection = "quarantine") 72 | quarantine_data = quarantine.load_data() 73 | 74 | bl = Collection(collection = "bot-bl") 75 | bl_data = bl.load_data() 76 | 77 | logs = Collection(collection = "logs") 78 | logs_data = logs.load_data() 79 | 80 | bonus = Collection(collection = "bonus") 81 | bonus_data = bonus.load_data() 82 | 83 | antinuke = Collection(collection = "antinuke") 84 | antinuke_data = antinuke.load_data() 85 | 86 | botstats = Collection(collection = "bot_stats") 87 | botstats_data = botstats.load_data() 88 | 89 | premium = Collection(collection = "premium") 90 | premium_data = premium.load_data() 91 | 92 | invoices = Collection(collection = "invoices") 93 | invoices_data = invoices.load_data() 94 | 95 | allowed = Collection(collection = "allowed") 96 | allowed_data = allowed.load_data() -------------------------------------------------------------------------------- /cogs/antispam.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.ext import commands 3 | from config import Color 4 | import messages 5 | import word 6 | import punishments 7 | import asyncio 8 | import mongo 9 | import time 10 | import datetime 11 | import typing 12 | import random 13 | import cache 14 | from word import ago 15 | from discord.utils import get 16 | from profilactic import measures 17 | 18 | 19 | def spamer(ctx, mode): 20 | ir, ic = [], [] 21 | enabled = False 22 | if mode == 'antiflood': c = cache.antiflood_data 23 | else: c = cache.antiinvite_data 24 | if ctx.guild.id in c: 25 | v = c[ctx.guild.id] 26 | try: 27 | ir = v['ir'] 28 | except: 29 | pass 30 | try: 31 | ic = v['ic'] 32 | except: 33 | pass 34 | try: 35 | enabled = v['enabled'] 36 | except: 37 | pass 38 | 39 | oneofrole = False 40 | for i in ir: 41 | if ctx.guild.get_role(int(i)) in ctx.author.roles: 42 | oneofrole = True 43 | return not ctx.channel.id in ic and not oneofrole and ctx.author != ctx.guild.owner and enabled 44 | 45 | msgs = {} 46 | async def clear_af(guild, user): 47 | await asyncio.sleep(60) 48 | global msgs 49 | try: 50 | del msgs[guild.id][user.id] 51 | if len(list(msgs[guild.id])) == 0: 52 | del msgs[guild.id] 53 | except: 54 | pass 55 | 56 | class AntiSpam(commands.Cog): 57 | def __init__(self, bot): 58 | self.bot = bot 59 | 60 | # Команды 61 | @commands.group(aliases=['ai']) 62 | @commands.check(messages.check_perms) 63 | @commands.cooldown(1, 5, commands.BucketType.guild) 64 | async def antiinvite(self, ctx): 65 | measures.add(what=7) 66 | if ctx.invoked_subcommand is None: 67 | embed = discord.Embed(title = "🔗 | Анти-ссылки-приглашения") 68 | embed.color = Color.primary 69 | p = ctx.prefix 70 | embed.description = f''' 71 | `<обязательный параметр>` `[необязательный параметр]` 72 | **Не используйте скобочки при указании параметров.** 73 | 74 | `{p}antiinvite ` – переключить защиту от ссылок 75 | `{p}antiinvite punishment [длительность]` – установить наказание 76 | `{p}antiinvite ir <роли>` – установить игнорируемые роли 77 | `{p}antiinvite ic <каналы>` – установить игнорируемые каналы 78 | ''' 79 | with ctx.channel.typing(): 80 | if ctx.guild.id in cache.antiinvite_data: 81 | v = cache.antiinvite_data[ctx.guild.id] 82 | ir, ic = "", "" 83 | cpunishments = {"none": "Отсутствует", "warn": "Предупреждение", "mute": "Мьют", "kick": "Кик", "ban": "Бан"} 84 | temp = "" 85 | try: 86 | for i in v['ir']: 87 | try: 88 | r = ctx.guild.get_role(int(i)) 89 | ir += f'{r.mention} ' 90 | except: 91 | pass 92 | if not len(ir.split()): ir = "Отсутствуют" 93 | except KeyError: 94 | ir = "Отсутствуют" 95 | try: 96 | for i in v['ic']: 97 | try: 98 | c = self.bot.get_channel(int(i)) 99 | ic += f'{c.mention} ' 100 | except: 101 | pass 102 | try: 103 | if not len(iс.split()): iс = "Отсутствуют" 104 | except: 105 | pass 106 | try: 107 | if ic == "": ic = "Отсутствуют" 108 | except: 109 | pass 110 | except KeyError: 111 | ic = "Отсутствуют" 112 | try: 113 | if v['punishment']['duration'] > 0: 114 | temp = f" на {word.hms2(v['punishment']['duration'])}" 115 | except: 116 | pass 117 | try: 118 | punishment = cpunishments[v['punishment']['type']] 119 | except KeyError: 120 | punishment = "Отсутствует" 121 | 122 | try: 123 | if v['enabled']: 124 | enabled = "Включено" 125 | else: 126 | enabled = "Выключено" 127 | except KeyError: 128 | enabled = "Выключено" 129 | else: 130 | ir, ic = "Отсутствуют", "Отсутствуют" 131 | enabled = "Выключено" 132 | punishment = "Отсутствует" 133 | temp = "" 134 | 135 | embed.add_field( 136 | name = "Настройки", 137 | value = f""" 138 | **Игнорируемые роли:** {ir} 139 | **Игнорируемые каналы:** {ic} 140 | **Наказание:** {punishment}{temp} 141 | **Состояние:** {enabled} 142 | """ 143 | ) 144 | await ctx.send(embed = embed) 145 | 146 | @antiinvite.command(aliases = ['ignorechannels', 'ignore_channels']) 147 | async def ic(self, ctx, channels: commands.Greedy[discord.TextChannel]): 148 | with ctx.channel.typing(): 149 | if not ctx.guild.id in cache.antiinvite_data: 150 | cache.antiinvite_data[ctx.guild.id] = {} 151 | try: 152 | data = cache.antiinvite_data[ctx.guild.id] 153 | except KeyError: 154 | data = {} 155 | data['ic'] = [ch.id for ch in channels] 156 | cache.antiinvite.add(ctx.guild.id, data) 157 | embed = discord.Embed(color = Color.success) 158 | embed.title = "✅ | Готово" 159 | if len(channels): 160 | embed.description = f'Игнорируемые каналы были установлены на {", ".join(c.mention for c in channels)}.' 161 | else: 162 | embed.description = f'Игнорируемые каналы были сброшены.' 163 | await ctx.send(embed = embed) 164 | 165 | @antiinvite.command(aliases = ['ignoreroles', 'ignore_roles']) 166 | async def ir(self, ctx, roles: commands.Greedy[discord.Role]): 167 | with ctx.channel.typing(): 168 | if not ctx.guild.id in cache.antiinvite_data: 169 | cache.antiinvite_data[ctx.guild.id] = {} 170 | try: 171 | data = cache.antiinvite_data[ctx.guild.id] 172 | except KeyError: 173 | data = {} 174 | data['ir'] = [ch.id for ch in roles] 175 | cache.antiinvite.add(ctx.guild.id, data) 176 | embed = discord.Embed(color = Color.success) 177 | embed.title = "✅ | Готово" 178 | if len(roles): 179 | embed.description = f'Игнорируемые роли были установлены на {", ".join(c.mention for c in roles)}.' 180 | else: embed.description = 'Игнорируемые роли были сброшены.' 181 | await ctx.send(embed = embed) 182 | 183 | @antiinvite.command(aliases = ['pm']) 184 | async def punishment(self, ctx, p, t = "0s"): 185 | with ctx.channel.typing(): 186 | p = p.lower() 187 | ct = word.string_to_seconds(t) 188 | cpunishments = {"none": "Ничего", "warn": "Предупреждение", "mute": "Мьют", "kick": "Кик", "ban": "Бан"} 189 | temp = "" 190 | if not ctx.guild.id in cache.antiinvite_data: 191 | cache.antiinvite_data[ctx.guild.id] = {} 192 | try: 193 | data = cache.antiinvite_data[ctx.guild.id] 194 | except KeyError: 195 | data = {} 196 | if ct > 0: 197 | temp = f" на {word.hms2(ct)}" 198 | 199 | if ct > 0 and p in ['none', 'warn', 'kick']: 200 | await messages.err(ctx, f"{cpunishments[p]} не имеет настройки по времени.", True) 201 | else: 202 | data['punishment'] = {} 203 | data['punishment']['type'] = p 204 | data['punishment']['duration'] = ct 205 | cache.antiinvite.add(ctx.guild.id, data) 206 | embed = discord.Embed(color = Color.success) 207 | embed.title = "✅ | Готово" 208 | embed.description = f'Теперь отправивший ссылку-приглашение получит {cpunishments[p].lower()}{temp}.' 209 | await ctx.send(embed = embed) 210 | 211 | @antiinvite.command(aliases = ['on']) 212 | async def _on(self, ctx): 213 | with ctx.channel.typing(): 214 | if not ctx.guild.id in cache.antiinvite_data: 215 | cache.antiinvite_data[ctx.guild.id] = {} 216 | try: 217 | data = cache.antiinvite_data[ctx.guild.id] 218 | except KeyError: 219 | data = {} 220 | 221 | try: 222 | en = data['enabled'] 223 | except: 224 | en = False 225 | 226 | if en: 227 | await messages.err(ctx, "Фильтр уже включён.", True) 228 | else: 229 | data['enabled'] = True 230 | cache.antiinvite.add(ctx.guild.id, data) 231 | embed = discord.Embed(color = Color.success) 232 | embed.title = "✅ | Готово" 233 | embed.description = 'Фильтр ссылок-приглашений включён. Наслаждайтесь ;)' 234 | await ctx.send(embed = embed) 235 | 236 | @antiinvite.command(aliases = ['off']) 237 | async def _off(self, ctx): 238 | with ctx.channel.typing(): 239 | if not ctx.guild.id in cache.antiinvite_data: 240 | cache.antiinvite_data[ctx.guild.id] = {} 241 | try: 242 | data = cache.antiinvite_data[ctx.guild.id] 243 | except KeyError: 244 | data = {} 245 | 246 | try: 247 | en = data['enabled'] 248 | except: 249 | en = False 250 | 251 | if not en: 252 | await messages.err(ctx, "Фильтр уже выключен.", True) 253 | else: 254 | data['enabled'] = False 255 | cache.antiinvite.add(ctx.guild.id, data) 256 | embed = discord.Embed(color = Color.success) 257 | embed.title = "✅ | Готово" 258 | embed.description = 'Фильтр ссылок-приглашений был выключен.' 259 | await ctx.send(embed = embed) 260 | 261 | 262 | @commands.group(aliases=['af']) 263 | @commands.check(messages.check_perms) 264 | @commands.cooldown(1, 5, commands.BucketType.guild) 265 | async def antiflood(self, ctx): 266 | measures.add(what=7) 267 | if ctx.invoked_subcommand is None: 268 | embed = discord.Embed(title = "💥 | Анти-флуд") 269 | embed.color = Color.primary 270 | p = ctx.prefix 271 | embed.description = f''' 272 | `<обязательный параметр>` `[необязательный параметр]` 273 | **Не используйте скобочки при указании параметров.** 274 | 275 | `{p}antiflood ` – переключить защиту от флуда 276 | `{p}antiflood punishment [длительность]` – установить наказание 277 | `{p}antiflood ir <роли>` – установить игнорируемые роли 278 | `{p}antiflood ic <каналы>` – установить игнорируемые каналы 279 | `{p}antiflood maxmsg <кол-во сообщений>` – установить максимальное количество повторяющихся сообщений 280 | ''' 281 | with ctx.channel.typing(): 282 | if ctx.guild.id in cache.antiflood_data: 283 | v = cache.antiflood_data[ctx.guild.id] 284 | ir, ic = "", "" 285 | cpunishments = {"none": "Отсутствует", "warn": "Предупреждение", "mute": "Мьют", "kick": "Кик", "ban": "Бан"} 286 | temp = "" 287 | try: 288 | for i in v['ir']: 289 | try: 290 | r = ctx.guild.get_role(int(i)) 291 | ir += f'{r.mention} ' 292 | except: 293 | pass 294 | if not len(ir.split()): ir = "Отсутствуют" 295 | except KeyError: 296 | ir = "Отсутствуют" 297 | try: 298 | for i in v['ic']: 299 | try: 300 | c = self.bot.get_channel(int(i)) 301 | ic += f'{c.mention} ' 302 | except: 303 | pass 304 | try: 305 | if not len(iс.split()): iс = "Отсутствуют" 306 | except: 307 | pass 308 | try: 309 | if ic == "": ic = "Отсутствуют" 310 | except: 311 | pass 312 | except KeyError: 313 | ic = "Отсутствуют" 314 | try: 315 | if v['punishment']['duration'] > 0: 316 | temp = f" на {word.hms2(v['punishment']['duration'])}" 317 | except: 318 | pass 319 | try: 320 | punishment = cpunishments[v['punishment']['type']] 321 | except KeyError: 322 | punishment = "Отсутствует" 323 | 324 | try: 325 | maxmsg = v['max'] 326 | except KeyError: 327 | maxmsg = 3 328 | 329 | try: 330 | if v['enabled']: 331 | enabled = "Включено" 332 | else: 333 | enabled = "Выключено" 334 | except KeyError: 335 | enabled = "Выключено" 336 | else: 337 | ir, ic = "Отсутствуют", "Отсутствуют" 338 | enabled = "Выключено" 339 | punishment = "Отсутствует" 340 | temp = "" 341 | maxmsg = 3 342 | 343 | embed.add_field( 344 | name = "Настройки", 345 | value = f""" 346 | **Игнорируемые роли:** {ir} 347 | **Игнорируемые каналы:** {ic} 348 | **Наказание:** {punishment}{temp} 349 | **Состояние:** {enabled} 350 | **Максимум сообщений:** {maxmsg} 351 | """ 352 | ) 353 | await ctx.send(embed = embed) 354 | 355 | @antiflood.command(aliases = ['ic', 'ignorechannels', 'ignore_channels']) 356 | async def _ic(self, ctx, channels: commands.Greedy[discord.TextChannel]): 357 | with ctx.channel.typing(): 358 | if not ctx.guild.id in cache.antiflood_data: 359 | cache.antiflood_data[ctx.guild.id] = {} 360 | try: 361 | data = cache.antiflood_data[ctx.guild.id] 362 | except KeyError: 363 | data = {} 364 | data['ic'] = [ch.id for ch in channels] 365 | cache.antiflood.add(ctx.guild.id, data) 366 | embed = discord.Embed(color = Color.success) 367 | embed.title = "✅ | Готово" 368 | if len(channels): 369 | embed.description = f'Игнорируемые каналы были установлены на {", ".join(c.mention for c in channels)}.' 370 | else: 371 | embed.description = 'Игнорируемые каналы были сброшены.' 372 | await ctx.send(embed = embed) 373 | 374 | @antiflood.command(aliases = ['ir', 'ignoreroles', 'ignore_roles']) 375 | async def _ir(self, ctx, roles: commands.Greedy[discord.Role]): 376 | with ctx.channel.typing(): 377 | if not ctx.guild.id in cache.antiflood_data: 378 | cache.antiflood_data[ctx.guild.id] = {} 379 | try: 380 | data = cache.antiflood_data[ctx.guild.id] 381 | except KeyError: 382 | data = {} 383 | data['ir'] = [ch.id for ch in roles] 384 | cache.antiflood.add(ctx.guild.id, data) 385 | embed = discord.Embed(color = Color.success) 386 | embed.title = "✅ | Готово" 387 | if len(roles): 388 | embed.description = f'Игнорируемые роли были установлены на {", ".join(c.mention for c in roles)}.' 389 | else: 390 | embed.description = 'Игнорируемые роли были сброшены.' 391 | await ctx.send(embed = embed) 392 | 393 | @antiflood.command(aliases = ['pm', 'punishment']) 394 | async def _punishment(self, ctx, p, t = "0s"): 395 | with ctx.channel.typing(): 396 | p = p.lower() 397 | ct = word.string_to_seconds(t) 398 | cpunishments = {"none": "Ничего", "warn": "Предупреждение", "mute": "Мьют", "kick": "Кик", "ban": "Бан"} 399 | temp = "" 400 | if not ctx.guild.id in cache.antiflood_data: 401 | cache.antiflood_data[ctx.guild.id] = {} 402 | try: 403 | data = cache.antiflood_data[ctx.guild.id] 404 | except KeyError: 405 | data = {} 406 | if ct > 0: 407 | temp = f" на {word.hms2(ct)}" 408 | 409 | if ct > 0 and p in ['none', 'warn', 'kick']: 410 | await messages.err(ctx, f"{cpunishments[p]} не имеет настройки по времени.", True) 411 | else: 412 | data['punishment'] = {} 413 | data['punishment']['type'] = p 414 | data['punishment']['duration'] = ct 415 | cache.antiflood.add(ctx.guild.id, data) 416 | embed = discord.Embed(color = Color.success) 417 | embed.title = "✅ | Готово" 418 | embed.description = f'Теперь флудер получит {cpunishments[p].lower()}{temp}.' 419 | await ctx.send(embed = embed) 420 | 421 | @antiflood.command(aliases = ['on']) 422 | async def __on(self, ctx): 423 | with ctx.channel.typing(): 424 | if not ctx.guild.id in cache.antiflood_data: 425 | cache.antiflood_data[ctx.guild.id] = {} 426 | try: 427 | data = cache.antiflood_data[ctx.guild.id] 428 | except KeyError: 429 | data = {} 430 | 431 | try: 432 | en = data['enabled'] 433 | except: 434 | en = False 435 | 436 | if en: 437 | await messages.err(ctx, "Фильтр уже включён.", True) 438 | else: 439 | data['enabled'] = True 440 | cache.antiflood.add(ctx.guild.id, data) 441 | embed = discord.Embed(color = Color.success) 442 | embed.title = "✅ | Готово" 443 | embed.description = 'Фильтр от флуда включён. Наслаждайтесь ;)' 444 | await ctx.send(embed = embed) 445 | 446 | @antiflood.command(aliases = ['off']) 447 | async def __off(self, ctx): 448 | with ctx.channel.typing(): 449 | if not ctx.guild.id in cache.antiflood_data: 450 | cache.antiflood_data[ctx.guild.id] = {} 451 | try: 452 | data = cache.antiflood_data[ctx.guild.id] 453 | except KeyError: 454 | data = {} 455 | 456 | try: 457 | en = data['enabled'] 458 | except: 459 | en = False 460 | 461 | if not en: 462 | await messages.err(ctx, "Фильтр уже выключен.", True) 463 | else: 464 | data['enabled'] = False 465 | cache.antiflood.add(ctx.guild.id, data) 466 | embed = discord.Embed(color = Color.success) 467 | embed.title = "✅ | Готово" 468 | embed.description = 'Фильтр от флуда был выключен.' 469 | await ctx.send(embed = embed) 470 | 471 | @antiflood.command(aliases = ['mm', 'max']) 472 | async def maxmsg(self, ctx, amount: int): 473 | with ctx.channel.typing(): 474 | if not ctx.guild.id in cache.antiflood_data: 475 | cache.antiflood_data[ctx.guild.id] = {} 476 | try: 477 | data = cache.antiflood_data[ctx.guild.id] 478 | except KeyError: 479 | data = {} 480 | if amount < 1: 481 | await messages.err(ctx, "Минимум - 1 сообщение.", True) 482 | else: 483 | data['max'] = amount 484 | cache.antiflood.add(ctx.guild.id, data) 485 | embed = discord.Embed(color = Color.success) 486 | embed.title = "✅ | Готово" 487 | embed.description = f'Максимальное количество повторяющихся сообщений: **{amount}**.' 488 | await ctx.send(embed = embed) 489 | 490 | @commands.Cog.listener() 491 | async def on_message(self, msg): 492 | global msgs 493 | if not msg.author.bot: 494 | if word.oneof(msg.content, ['discord.gg/', 'discord.com/invite/', 'discordapp.com/invite/', 'dsc.gg/'])[0]: 495 | if spamer(msg, 'antiinvite'): 496 | measures.add(what=8) 497 | await msg.delete() 498 | await msg.channel.send(f'{msg.author.mention}, здесь запрещено оставлять ссылки-приглашения.', delete_after = 10.0) 499 | try: v = cache.antiinvite_data[msg.guild.id] 500 | except: v = {} 501 | try: 502 | pdict = v['punishment'] 503 | except: 504 | pdict = {"type": "none", "duration": 0} 505 | if pdict['duration'] == 0: 506 | pdict['duration'] = 228133722 507 | if pdict['type'] == 'mute': 508 | await punishments.tempmute(msg, msg.author, pdict['duration']) 509 | elif pdict['type'] == 'warn': 510 | await punishments.warn(msg, msg.author) 511 | elif pdict['type'] == 'kick': 512 | await msg.author.kick(reason = "Анти-ссылки-приглашения") 513 | elif pdict['type'] == 'ban': 514 | if pdict['duration'] == 228133722: 515 | await msg.author.ban(reason = "Анти-ссылки-приглашения") 516 | else: 517 | await msg.author.ban(reason = f"Анти-ссылки-приглашения | {word.hms(pdict['duration'])}") 518 | await punishments.tempban(msg, msg.author, pdict['duration']) 519 | '''if not msg.guild.id in msgs: 520 | msgs[msg.guild.id] = {msg.author.id: {"count": 0, "content": msg.content}} 521 | if not msg.author.id in msgs[msg.guild.id]: 522 | msgs[msg.guild.id][msg.author.id] = {"count": 0, "content": msg.content} 523 | if spamer(msg, "antiflood"): 524 | try: v = cache.antiflood_data[msg.guild.id] 525 | except: v = {} 526 | try: 527 | max1 = v['max'] 528 | except: 529 | max1 = 3 530 | if msgs[msg.guild.id][msg.author.id]["count"] < max1: 531 | if msgs[msg.guild.id][msg.author.id]["content"] == msg.content: 532 | msgs[msg.guild.id][msg.author.id]["count"] += 1 533 | else: 534 | def check(m): 535 | return m.author == msg.author 536 | await msg.channel.purge(limit = max1 + 1, check = check) 537 | await msg.channel.send(f'{msg.author.mention}, здесь запрещено флудить.', delete_after = 10.0) 538 | try: 539 | pdict = v['punishment'] 540 | except: 541 | pdict = {"type": "none", "duration": 0} 542 | if pdict['duration'] == 0: 543 | pdict['duration'] = 228133722 544 | if pdict['type'] == 'mute': 545 | await punishments.tempmute(msg, msg.author, pdict['duration']) 546 | elif pdict['type'] == 'warn': 547 | await punishments.warn(msg, msg.author) 548 | elif pdict['type'] == 'kick': 549 | await msg.author.kick(reason = "Анти-флуд") 550 | elif pdict['type'] == 'ban': 551 | if pdict['duration'] == 228133722: 552 | await msg.author.ban(reason = "Анти-флуд") 553 | else: 554 | await msg.author.ban(reason = f"Анти-флуд | {word.hms(pdict['duration'])}") 555 | await punishments.tempban(msg, msg.author, pdict['duration']) 556 | self.bot.loop.create_task(clear_af(msg.guild, msg.author))''' 557 | 558 | 559 | def setup(bot): 560 | bot.add_cog(AntiSpam(bot)) 561 | -------------------------------------------------------------------------------- /cogs/cmdengine.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.ext import commands 3 | from discord.ext.commands.core import cooldown 4 | from dislash.interactions.message_components import ActionRow, Button, ButtonStyle, SelectMenu, SelectOption 5 | from pymongo import settings 6 | from config import Color, Other 7 | import messages 8 | import word 9 | import asyncio 10 | import time 11 | import pytz 12 | import json 13 | from word import ago 14 | import cache 15 | import datetime 16 | 17 | cooldowns = {} 18 | 19 | 20 | async def reset(id, delay): 21 | global cooldowns 22 | await asyncio.sleep(delay) 23 | try: del cooldowns[id] 24 | except: pass 25 | 26 | class Cmd(commands.Cog): 27 | def __init__(self, bot): 28 | self.bot = bot 29 | 30 | @commands.command(aliases=['h', 'helo', 'hwlp']) 31 | @commands.cooldown(1, 3, commands.BucketType.guild) 32 | @commands.check(messages.check_perms) 33 | async def help(self, ctx, category = None): 34 | if category is None: 35 | embed = discord.Embed( 36 | title="📖 | Список команд", 37 | description=f"`<обязательный параметр>` `[необязательный параметр]`\n**Не используйте скобочки при указании параметров**\n\nИспользуйте `{ctx.prefix}help [команда]` для получения подробной информации о команде", 38 | color=Color.primary 39 | ) 40 | embed.add_field( 41 | name=f"Информация", 42 | value="`info` `invite` `ping` `server` `user`", 43 | inline=False 44 | ) 45 | embed.add_field( 46 | name=f"Модерация", 47 | value="`addroles` `ban` `bans` `correct` `correct-all` `kick` `lock-bot` `mute` `mutes` `purge` `quarantine` `remroles` `unban` `unlock-bot` `unmute` `unwarn` `warn` `warns`", 48 | inline=False 49 | ) 50 | embed.add_field( 51 | name=f"Администрация", 52 | value="`delspamchannels` `delspamroles` `echo` `lock` `massban` `unlock`", 53 | inline=False 54 | ) 55 | embed.add_field( 56 | name=f"Весёлости", 57 | value="`8ball`", 58 | inline=False 59 | ) 60 | embed.add_field( 61 | name=f"Для владельца сервера", 62 | value="`alertcrash` `reset-all`", 63 | inline=False 64 | ) 65 | embed.add_field( 66 | name=f"Настройка", 67 | value="`antiraid` ~~`antiflood`~~ `antiinvite` `muterole` `nickcorrector` `notify-dm` `np` `nuker` `perms` `prefix` `role-protect` `score` `warn-actions` `whitelist`", 68 | inline=False 69 | ) 70 | embed.add_field( 71 | name=f"Роли за реакции", 72 | value="`addsingle` `delsingle`", 73 | inline=False 74 | ) 75 | embed.add_field( 76 | name=f"Прочее", 77 | value="`avatar` `backup` `discrim`", 78 | inline=False 79 | ) 80 | embed.add_field( 81 | name=f"Hi Plus", 82 | value="`invoices` `plus`", 83 | inline=False 84 | ) 85 | infoe = discord.Embed(color=Color.primary, title="ℹ | Список команд: Информация", description=f""" 86 | `{ctx.prefix}info` – информация о боте 87 | `{ctx.prefix}invite` – пригласить бота на свой сервер 88 | `{ctx.prefix}ping` – пинг бота 89 | `{ctx.prefix}server` – информация о сервере 90 | `{ctx.prefix}user` – информация о пользователе 91 | """) 92 | modere = discord.Embed(color=Color.primary, title="👮‍♂️ | Список команд: Модерация", description=f""" 93 | `{ctx.prefix}addroles` – выдать всем роль 94 | `{ctx.prefix}ban` – забанить пользователя 95 | `{ctx.prefix}bans` – список действующих банов 96 | `{ctx.prefix}correct` – исправить никнейм указанным участникам 97 | `{ctx.prefix}correct-all` – исправить никнейм всем участникам 98 | `{ctx.prefix}kick` – кикнуть участника 99 | `{ctx.prefix}lock-bot` – заблокировать бота 100 | `{ctx.prefix}mute` – замьютить участника 101 | `{ctx.prefix}mutes` – список действующих мьютов 102 | `{ctx.prefix}purge` – очистить чат 103 | `{ctx.prefix}quarantine` – управление карантином 104 | `{ctx.prefix}remroles` – забрать роль у всех участников 105 | `{ctx.prefix}unban` – разбанить пользователя 106 | `{ctx.prefix}unlock-bot` – разблокировать бота 107 | `{ctx.prefix}unmute` – размьютить участника 108 | `{ctx.prefix}unwarn` – снять предупреждение у участника 109 | `{ctx.prefix}warn` – выдать предупреждение участнику 110 | `{ctx.prefix}warns` – посмотреть свои или чужие предупреждения 111 | """) 112 | admine = discord.Embed(color=Color.primary, title="🛠 | Список команд: Администрация", description=f""" 113 | `{ctx.prefix}delspamchannels` – удалить каналы с одинаковым названием 114 | `{ctx.prefix}delspamroles` – удалить роли с одинаковым названием 115 | `{ctx.prefix}echo` – сказать что-нибудь от лица бота 116 | `{ctx.prefix}lock` – заблокировать канал 117 | `{ctx.prefix}massban` – забанить сразу несколько пользователей 118 | `{ctx.prefix}unlock` – разблокировать канал 119 | """) 120 | fune = discord.Embed(color=Color.primary, title="😃 | Список команд: Весёлости", description=f""" 121 | `{ctx.prefix}8ball` – задать вопрос магическому шару 122 | """) 123 | ownere = discord.Embed(color=Color.primary, title="👑 | Список команд: Для владельца сервера", description=f""" 124 | `{ctx.prefix}alertcrash` – снять всех администраторов и модераторов 125 | `{ctx.prefix}reset-all` – сбросить **все** настройки бота 126 | """) 127 | settingse = discord.Embed(color=Color.primary, title="⚙ | Список команд: Настройка", description=f""" 128 | `{ctx.prefix}antiraid` – настройка анти-рейда 129 | ~~`{ctx.prefix}antiflood` – настройка анти-флуда~~ 130 | `{ctx.prefix}antiinvite` – настройка анти-приглашений 131 | `{ctx.prefix}muterole` – указать роль мьюта 132 | `{ctx.prefix}nickcorrector` – корректор никнеймов 133 | `{ctx.prefix}notify-dm` – оповещения о наказаниях в личку 134 | `{ctx.prefix}np` – наказание за краш 135 | `{ctx.prefix}nuker` – наказание за приглашение краш-бота 136 | `{ctx.prefix}perms` – ограничить команду по каналам и ролям 137 | `{ctx.prefix}prefix` – изменить префикс бота 138 | `{ctx.prefix}role-protect` – защита роли участника от изменения прав 139 | `{ctx.prefix}score` – управление баллами за краш 140 | `{ctx.prefix}warn-actions` – наказания за предупреждения 141 | `{ctx.prefix}whitelist` – белый список 142 | """) 143 | rre = discord.Embed(color=Color.primary, title="🚩 | Список команд: Роли за реакции", description=f""" 144 | `{ctx.prefix}addsingle` – добавить роль за реакцию 145 | `{ctx.prefix}delsingle` – удалить роль за реакцию 146 | """) 147 | othere = discord.Embed(color=Color.primary, title="💾 | Список команд: Прочее", description=f""" 148 | `{ctx.prefix}avatar` – получить аватар пользователя 149 | `{ctx.prefix}backup` – управление резервными копиями сервера 150 | `{ctx.prefix}discrim` – поиск участников с определённым Discord тегом 151 | """) 152 | cpplus = discord.Embed(color=Color.primary, title="⭐ | Список команд: Управление подпиской HiProtect Plus", description=f""" 153 | `{ctx.prefix}invoices` – выставленные счета 154 | `{ctx.prefix}plus` – подробнее о подписке 155 | """) 156 | selectmenu = SelectMenu( 157 | custom_id="cmds", 158 | placeholder="Выберите категорию", 159 | options=[ 160 | SelectOption("Информация", "Информационные команды", emoji="ℹ"), 161 | SelectOption("Модерация", "Команды модерации", emoji="👮‍♂️"), 162 | SelectOption("Администрация", "Команды администраторов", emoji="🛠"), 163 | SelectOption("Весёлости", "Команды для веселья", emoji="😃"), 164 | SelectOption("Для владельца сервера", "Команды, доступные только владельцу сервера", emoji="👑"), 165 | SelectOption("Настройка", "Команды для настройки бота", emoji="⚙"), 166 | SelectOption("Роли за реакции", "Команды для ролей за реакции", emoji="🚩"), 167 | SelectOption("Прочее", "Прочие команды", emoji="💾"), 168 | SelectOption("Hi Plus", "Управление подпиской HiProtect Plus", emoji="⭐") 169 | ] 170 | ) 171 | button = ActionRow( 172 | Button( 173 | style=ButtonStyle.red, 174 | custom_id="back", 175 | label="Назад" 176 | ) 177 | ) 178 | msg = await ctx.send(embed=embed, components=[selectmenu]) 179 | def check(inter): 180 | return inter.message.id == msg.id and ctx.author == inter.author 181 | for i in range(20): 182 | inter = await msg.wait_for_dropdown(check=check, timeout=300) 183 | embeds = { 184 | "Информация": infoe, 185 | "Модерация": modere, 186 | "Весёлости": fune, 187 | "Для владельца сервера": ownere, 188 | "Настройка": settingse, 189 | "Прочее": othere, 190 | "Роли за реакции": rre, 191 | "Администрация": admine, 192 | "Hi Plus": cpplus 193 | } 194 | await inter.create_response(type=6) 195 | await msg.edit(embed=embeds[inter.select_menu.selected_options[0].label]) 196 | else: 197 | cmd = messages.get_command(self.bot, category) 198 | if not cmd: 199 | return await ctx.send("Мы обыскали всё вдоль и поперёк, но так и не смогли найти эту команду.") 200 | with open("json/commandinfo.json", "r", encoding="utf-8") as f: 201 | data = json.load(f) 202 | if not cmd in data: 203 | return await ctx.send("Об этой команде совсем ничего не известно, так как мой ленивый разработчик не добавил информацию о ней. Используйте на свой страх и риск.") 204 | embed = discord.Embed(title=f"❔ | О команде `{ctx.prefix}{cmd}`", color=Color.primary) 205 | embed.description = """ 206 | `<обязательный параметр>` `[необязательный параметр]` 207 | **Не используйте скобочки при указании параметров** 208 | """ 209 | embed.add_field(inline=False, name="Описание", value=">>> " + data[cmd]["description"] + ".") 210 | if len(data[cmd]["args"]): 211 | embed.add_field(inline=False, name="Параметры", value=">>> " + "\n".join([f"`{a}`" for a in data[cmd]["args"]])) 212 | if len(data[cmd]["examples"]): 213 | embed.add_field(inline=False, name="Примеры использования", value=">>> " + "\n".join([f"`{ctx.prefix}{a}`" for a in data[cmd]["examples"]])) 214 | if len(discord.utils.get(self.bot.commands, name=cmd).aliases): 215 | embed.add_field(inline=False, name="Алиасы (синонимы)", value=">>> " + ", ".join([f"`{a}`" for a in discord.utils.get(self.bot.commands, name=cmd).aliases])) 216 | await ctx.send(embed=embed) 217 | @commands.command() 218 | @commands.check(messages.check_perms) 219 | @commands.cooldown(1, 5, commands.BucketType.guild) 220 | async def invite(self, ctx): 221 | embed = discord.Embed(title="🔗 | Ссылки", color=Color.primary) 222 | embed.description = ''' 223 | [🤖 Пригласить бота](https://discord.com/oauth2/authorize?client_id=740540209896095864&scope=applications.commands%20bot&permissions=8) 224 | [❔ Поддержка](https://discord.gg/U4ge8Fup5u) 225 | [🌐 Сайт](https://hiprotect.tk) 226 | ''' 227 | await ctx.send(embed=embed) 228 | @commands.command(aliases=['serverinfo', 'server-info', 'server_info', 'si']) 229 | @commands.check(messages.check_perms) 230 | @commands.cooldown(1, 5, commands.BucketType.guild) 231 | async def server(self, ctx): 232 | months = { 233 | 1: "января", 234 | 2: "февраля", 235 | 3: "марта", 236 | 4: "апреля", 237 | 5: "мая", 238 | 6: "июня", 239 | 7: "июля", 240 | 8: "августа", 241 | 9: "сентября", 242 | 10: "октября", 243 | 11: "ноября", 244 | 12: "декабря" 245 | } 246 | embed = discord.Embed(title=f'🌍 | Информация о сервере **{ctx.guild.name}**', color=Color.primary) 247 | embed.set_thumbnail(url=ctx.guild.icon_url) 248 | rgs = { 249 | 'brazil':':flag_br: Бразилия', 250 | 'europe':':flag_eu: Европа', 251 | 'hongkong':':flag_hk: Гонконг', 252 | 'india':':flag_in: Индия', 253 | 'japan':':flag_jp: Япония', 254 | 'russia':':flag_ru: Россия', 255 | 'singapore':':flag_sg: Сингапур', 256 | 'southafrica':':flag_za: ЮАР', 257 | 'sydney':':flag_au: Сидней', 258 | 'us-central':':flag_us: Центральная Америка', 259 | 'us-east':':flag_us: Восточное побережье США', 260 | 'us-south':':flag_us: Америка (Юг)', 261 | 'us-west':':flag_us: Западное побережье США', 262 | 'deprecated':'Убран' 263 | } 264 | vlevels = { 265 | 'none':':white_circle: Отсутствует', 266 | 'low':':green_circle: Низкий', 267 | 'medium':':yellow_circle: Средний', 268 | 'high':':orange_circle: Высокий', 269 | 'extreme':':red_circle: Самый высокий' 270 | } 271 | embed.add_field(name='Роли', value=f''' 272 | > Всего: **{len(ctx.guild.roles)}** 273 | > С правами администратора: **{len([r for r in ctx.guild.roles if r.permissions.administrator])}** 274 | > С правами модератора: **{len([r for r in ctx.guild.roles if r.permissions.kick_members])}** 275 | > Интеграций: **{len([r for r in ctx.guild.roles if r.managed])}** 276 | ''') 277 | embed.add_field(name='Каналы', value=f''' 278 | > Всего: **{len([c for c in ctx.guild.channels if not isinstance(c, discord.CategoryChannel)])}** 279 | > Текстовых: **{len(ctx.guild.text_channels)}** 280 | > Голосовых: **{len(ctx.guild.voice_channels)}** 281 | > Категорий: **{len(ctx.guild.categories)}** 282 | ''') 283 | embed.add_field(name='Участники', inline=False, value=f''' 284 | > Всего: **{len(ctx.guild.members)}** 285 | > Людей: **{len([m for m in ctx.guild.members if not m.bot])}** 286 | > Ботов: **{len([m for m in ctx.guild.members if m.bot])}** 287 | > Админов: **{len([m for m in ctx.guild.members if m.guild_permissions.administrator])}** 288 | > Модераторов: **{len([m for m in ctx.guild.members if m.guild_permissions.kick_members])}** 289 | ''') 290 | dt = ctx.guild.created_at.replace(tzinfo=datetime.timezone.utc).astimezone(tz=None) 291 | if not ctx.guild.owner: 292 | oww = "**Не кэширован**" 293 | else: 294 | oww = f"**{ctx.guild.owner}** ({ctx.guild.owner.mention})" 295 | embed.add_field(name='Прочее', value=f''' 296 | > Владелец: {oww} 297 | > Уровень проверки: **{vlevels[str(ctx.guild.verification_level)]}** 298 | > Дата создания сервера: () 299 | ''') 300 | if messages.has_premium(ctx.guild.id): 301 | embed.add_field(name="HiProtect Plus активен!", value="Спасибо за поддержку HiProtect :heart:", inline=False) 302 | embed.set_footer(text=f'ID: {ctx.guild.id} | Шард {ctx.guild.shard_id}') 303 | await ctx.send(embed=embed) 304 | 305 | @commands.command(aliases=['userinfo', 'user-info', 'user_info', 'u']) 306 | @commands.cooldown(1, 5, commands.BucketType.guild) 307 | @commands.check(messages.check_perms) 308 | async def user(self, ctx, user: discord.User = None): 309 | months = { 310 | 1: "января", 311 | 2: "февраля", 312 | 3: "марта", 313 | 4: "апреля", 314 | 5: "мая", 315 | 6: "июня", 316 | 7: "июля", 317 | 8: "августа", 318 | 9: "сентября", 319 | 10: "октября", 320 | 11: "ноября", 321 | 12: "декабря" 322 | } 323 | if user is None: 324 | user = ctx.author 325 | embed = discord.Embed(color=Color.primary) 326 | if user.bot: 327 | embed.title = f"🤖 | Информация о боте **{user}**" 328 | else: 329 | embed.title = f"👤 | Информация о пользователе **{user}**" 330 | embed.set_thumbnail(url=user.avatar_url) 331 | embed.set_footer(text=f'ID: {user.id}') 332 | if ctx.guild.get_member(user.id): 333 | user = ctx.guild.get_member(user.id) 334 | if user.bot: 335 | try: 336 | dob_id = int(cache.invited_data[ctx.guild.id][str(user.id)]) 337 | dob_u = self.bot.get_user(dob_id) 338 | if dob_u: 339 | embed.add_field(name="Кто добавил", value=dob_u, inline=False) 340 | except: 341 | pass 342 | embed.add_field(inline=False, name="Роли", value=f'Всего: **{len(user.roles)}**, наивысшая: {user.top_role.mention}') 343 | if user == ctx.guild.owner: 344 | embed.add_field(inline=True, name="Владелец сервера?", value='✅ Да') 345 | else: 346 | embed.add_field(inline=True, name="Владелец сервера?", value='❌ Нет') 347 | if user.guild_permissions.administrator: 348 | embed.add_field(inline=True, name="Администратор?", value='✅ Да') 349 | else: 350 | embed.add_field(inline=True, name="Администратор?", value='❌ Нет') 351 | ja = user.joined_at.replace(tzinfo=datetime.timezone.utc).astimezone(tz=None) 352 | embed.add_field(inline=False, name="Дата присоединения к серверу", value=f' ()') 353 | ca = user.created_at 354 | embed.add_field(inline=False, name="Дата создания аккаунта", value=f' ()') 355 | await ctx.send(embed=embed) 356 | 357 | @commands.command() 358 | @commands.cooldown(1, 10, commands.BucketType.guild) 359 | @commands.check(messages.check_perms) 360 | async def prefix(self, ctx, prefix): 361 | if prefix.lower() in ["reset", "сброс", "hi."]: 362 | if ctx.guild.id in cache.configs_data: 363 | if "prefix" in cache.configs_data[ctx.guild.id]: 364 | cache.configs.delete(ctx.guild.id, {"prefix": True}) 365 | await ctx.send(embed = discord.Embed( 366 | title="✅ | Готово", 367 | description="Префикс успешно сброшен.", 368 | color=Color.success 369 | )) 370 | else: 371 | await messages.err(ctx, "Префикс и так стоит по умолчанию.", True) 372 | else: 373 | await messages.err(ctx, "Префикс и так стоит по умолчанию.", True) 374 | else: 375 | if len(prefix) > 6: 376 | await messages.err(ctx, "Максимальная длина префикса — **6**.", True) 377 | else: 378 | cache.configs.add(ctx.guild.id, {"prefix": prefix}) 379 | await ctx.send(embed = discord.Embed( 380 | title="✅ | Готово", 381 | description=f"Новый префикс — `{prefix}`.", 382 | color=Color.success 383 | )) 384 | 385 | @commands.Cog.listener() 386 | async def on_message(self, message): 387 | if not message.author.bot: 388 | if message.content.startswith(f'<@{self.bot.user.id}>') or message.content.startswith(f'<@!{self.bot.user.id}>'): 389 | try: 390 | prefix = cache.configs_data[message.guild.id]['prefix'] 391 | except: 392 | prefix = 'hi.' 393 | await message.channel.send(f'{message.author.mention}, мой префикс – `{prefix}`. Для просмотра списка команд введи `{prefix}help`.') 394 | 395 | @commands.command() 396 | @commands.cooldown(1, 5, commands.BucketType.guild) 397 | @commands.check(messages.check_perms) 398 | async def info(self, ctx): 399 | if Other.uptime == 0: 400 | uptime2 = 0 401 | else: 402 | uptime2 = int(time.time()) - Other.uptime 403 | embed = discord.Embed(title="ℹ | Информация", description="Привет! Я – анти-краш бот, который защищает сервера от краша.", color=Color.primary) 404 | if Other.shard_count <= 2: 405 | embed.add_field( 406 | name="Система", 407 | inline=False, 408 | value=f''' 409 | 🛰 Средняя задержка бота: **{int(self.bot.latency * 1000)} мс** 410 | ⏳ Аптайм: **{word.hms(uptime2)}** 411 | 💬 Команд выполнено: **{cache.botstats_data[self.bot.user.id]["commands_completed"]}** 412 | ''' 413 | ) 414 | else: 415 | embed.add_field( 416 | name="Система", 417 | inline=False, 418 | value=f''' 419 | 🛰 Средняя задержка бота: **{int(self.bot.latency * 1000)} мс** 420 | ⏳ Аптайм: **{word.hms(uptime2)}** 421 | 🖥 Шардов: **{len(self.bot.shards)}** 422 | 🆔 ID шарда этого сервера: **{ctx.guild.shard_id}** 423 | 💬 Команд выполнено: **{cache.botstats_data[self.bot.user.id]["commands_completed"]}** 424 | ''' 425 | ) 426 | embed.add_field( 427 | name="Серверы", 428 | inline=False, 429 | value=f''' 430 | 🌐 Количество: **{len(self.bot.guilds)}** 431 | 🏆 Крупных серверов (1000+): **{len([g for g in self.bot.guilds if g.member_count >= 1000])}** 432 | 👥 Пользователей: **{len(self.bot.users)}** 433 | ''' 434 | ) 435 | embed.add_field( 436 | name="Прочее", 437 | inline=False, 438 | value=f''' 439 | 📆 Дата создания: **10 мая 2022 года** 440 | 🐍 Версия Python: **3.10** 441 | 📄 Версия: **1.4 (13 мая 2022 года)** 442 | 👨‍💻 Разработчики: **Artem Bay#0547**, **самсунг ассистент#0205** 443 | ''' 444 | ) 445 | embed.add_field( 446 | name="Ссылки", 447 | inline=False, 448 | value=f''' 449 | [Пригласить бота](https://discord.com/oauth2/authorize?client_id=740540209896095864&scope=applications.commands%20bot&permissions=8) 450 | [Сервер поддержки](https://discord.gg/U4ge8Fup5u) 451 | [Сайт бота](https://www.hiprotect.tk/) 452 | ''' 453 | ) 454 | embed.add_field( 455 | name="Благодарность", 456 | inline=False, 457 | value=f''' 458 | **Cymon#4380** - за оригинальный код бота и аватарку боту. Жалко краш протекта 459 | ''' 460 | ) 461 | embed.set_footer(text="© 2022, Artem Bay | Все права защищены ботом HiProtect", icon_url=self.bot.get_user(356737308898099201).avatar_url) 462 | embed.set_thumbnail(url=self.bot.user.avatar_url) 463 | await ctx.send(embed=embed) 464 | 465 | @commands.command() 466 | @commands.check(messages.check_perms) 467 | @commands.cooldown(1, 3, commands.BucketType.guild) 468 | async def ping(self, ctx): 469 | embed = discord.Embed(title="🏓 | Понг!", description=f'Средняя задержка: **{int(self.bot.latency * 1000)} мс**', color=Color.primary) 470 | if Other.shard_count => 2: 471 | embed.add_field(inline=False, name="По шардам:", value=f''' 472 | Шард **0**: **{int(self.bot.get_shard(0).latency) * 1000}мс** 473 | Шард **1**: **None мс** 474 | Шард **2**: **None мс** 475 | Шард **3**: **None мс** 476 | Шард **4**: **None мс** 477 | Шард **5**: **None мс** 478 | Шард **6**: **None мс** 479 | Шард **7**: **None мс** 480 | ''') 481 | embed.set_footer(text=f'ID вашего шарда: {ctx.guild.shard_id}') 482 | await ctx.send(embed=embed) 483 | 484 | @commands.Cog.listener() 485 | async def on_command_error(self, ctx, error): 486 | if isinstance(error, commands.CommandOnCooldown): 487 | embed = discord.Embed( 488 | title="⏳ | Команда перезаряжается", 489 | description=f'Попробуйте снова через **{word.hms2(error.retry_after)}**.', 490 | color=Color.primary 491 | ) 492 | await ctx.send(embed=embed) 493 | elif isinstance(error, commands.MissingRequiredArgument): 494 | await messages.err(ctx, f"В команде указано слишком мало аргументов. Если вы хотите посмотреть подробную справку о команде, напишите `{ctx.prefix}help {ctx.command.name}`.", True) 495 | elif isinstance(error, commands.CommandInvokeError): 496 | pass 497 | elif isinstance(error, messages.HasNoRoles): 498 | embed = discord.Embed(title="✋ | Недостаточно прав") 499 | embed.color = Color.danger 500 | embed.add_field(name="Вам нужно иметь хотя бы одну из этих ролей:", value=f'>>> {str(error)}') 501 | await ctx.send(embed=embed) 502 | elif isinstance(error, messages.HasDeniedRoles): 503 | embed = discord.Embed(title="✋ | Недостаточно прав") 504 | embed.color = Color.danger 505 | embed.add_field(name="Данная роль препятствует выполнению команды:", value=f'>>> {str(error)}') 506 | await ctx.send(embed=embed) 507 | elif isinstance(error, messages.NotAllowedChannel): 508 | embed = discord.Embed(title="❌ | Не тот канал") 509 | embed.color = Color.danger 510 | embed.add_field(name="Команду можно выполнить только в этих каналах:", value=f'>>> {str(error)}') 511 | await ctx.send(embed=embed) 512 | elif isinstance(error, messages.DeniedChannel): 513 | embed = discord.Embed(title="❌ | Не тот канал") 514 | embed.color = Color.danger 515 | embed.description = "Команду нельзя выполнить в этом канале." 516 | await ctx.send(embed=embed) 517 | elif isinstance(error, messages.NoPerms): 518 | embed = discord.Embed(title="✋ | Недостаточно прав") 519 | embed.color = Color.danger 520 | embed.add_field(name="Вы должны иметь следующее право:", value=f'>>> {str(error)}') 521 | await ctx.send(embed=embed) 522 | elif isinstance(error, commands.MemberNotFound): 523 | await messages.err(ctx, "Такой участник не найден.", True) 524 | elif isinstance(error, commands.UserNotFound): 525 | await messages.err(ctx, "Такой пользователь не найден.", True) 526 | elif isinstance(error, commands.ChannelNotFound): 527 | await messages.err(ctx, "Такой канал не найден.", True) 528 | elif isinstance(error, commands.RoleNotFound): 529 | await messages.err(ctx, "Такая роль не найдена.", True) 530 | elif isinstance(error, commands.BadArgument) or isinstance(error, commands.BadUnionArgument): 531 | await messages.err(ctx, "Указан неправильный аргумент при написании команды.", True) 532 | elif isinstance(error, commands.CommandNotFound): 533 | pass 534 | else: 535 | raise error 536 | 537 | def setup(bot): 538 | bot.add_cog(Cmd(bot)) 539 | -------------------------------------------------------------------------------- /cogs/logs.py: -------------------------------------------------------------------------------- 1 | import re 2 | import discord 3 | from discord.ext import commands 4 | from config import Color 5 | import messages 6 | import word 7 | import punishments 8 | import asyncio 9 | import mongo 10 | import time 11 | import datetime 12 | import typing 13 | import random 14 | import cache 15 | from profilactic import measures 16 | from word import ago 17 | 18 | class Logs(commands.Cog): 19 | def __init__(self, bot): 20 | self.bot = bot 21 | 22 | '''@commands.group(aliases=['log', 'logchannel', 'log-channel', 'lc']) 23 | @commands.cooldown(1, 5, commands.BucketType.guild) 24 | @commands.check(messages.check_perms) 25 | async def log_channel(self, ctx): 26 | if ctx.invoked_subcommand is None: 27 | embed = discord.Embed(color=Color.primary) 28 | embed.title = "📝 | Канал логов" 29 | embed.add_field(name="Команды", inline=False, value=f""" 30 | `{ctx.prefix}log-channel set` – указать канал для логов 31 | `{ctx.prefix}log-channel remove` – удалить канал для логов 32 | """) 33 | try: 34 | channel = self.bot.get_channel(cache.logs_data[ctx.guild.id]["default-channel"]).mention 35 | except AttributeError: 36 | channel = None 37 | except KeyError: 38 | channel = None 39 | 40 | if channel: 41 | embed.add_field(name="Текущий канал логов", value=channel) 42 | 43 | await ctx.send(embed=embed) 44 | 45 | @log_channel.command(aliases=['set']) 46 | async def __set(self, ctx, channel1: discord.TextChannel): 47 | try: 48 | channel = cache.logs_data[ctx.guild.id]["default-channel"] 49 | except KeyError: 50 | channel = None 51 | 52 | if channel: 53 | if channel1.id == channel: 54 | return await messages.err(ctx, "Новый канал для логов не может совпадать со старым.") 55 | 56 | webhook = await channel1.create_webhook(name="Crash Protect Logs") 57 | await webhook.send("Этот канал указан в качестве канала для логов. Пожалуйста, не удаляйте этот вебхук. Спасибо!") 58 | cache.logs.add(ctx.guild.id, {"default-channel": channel1.id, "default-webhook": webhook.id}) 59 | embed = discord.Embed( 60 | title="✅ | Готово", 61 | description=f"Канал {channel1.mention} указан как канал для логов.", 62 | color=Color.success 63 | ) 64 | await ctx.send(embed=embed) 65 | 66 | @log_channel.command(aliases=['delete', 'remove']) 67 | async def __remove(self, ctx): 68 | try: 69 | channel = self.bot.get_channel(cache.logs_data[ctx.guild.id]["default-channel"]) 70 | except KeyError: 71 | channel = None 72 | 73 | if not channel: 74 | return await messages.err(ctx, "Канал логов не был указан ранее!") 75 | 76 | embed = discord.Embed( 77 | title="✅ | Готово", 78 | description=f"Канал {channel.mention} указан как канал для логов.", 79 | color=Color.success 80 | ) 81 | await ctx.send(embed=embed)''' 82 | 83 | def setup(bot): 84 | bot.add_cog(Logs(bot)) -------------------------------------------------------------------------------- /cogs/nickcor.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.ext import commands 3 | from config import Color 4 | import messages 5 | import word 6 | import punishments 7 | import asyncio 8 | import mongo 9 | import time 10 | import datetime 11 | import typing 12 | import random 13 | import cache 14 | from word import ago 15 | from discord.utils import get 16 | from profilactic import measures 17 | 18 | async def checknick(member): 19 | allowed = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ' 20 | norm = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' 21 | bold = '𝐀𝐁𝐂𝐃𝐄𝐅𝐆𝐇𝐈𝐉𝐊𝐋𝐌𝐍𝐎𝐏𝐐𝐑𝐒𝐓𝐔𝐕𝐖𝐗𝐘𝐙𝐚𝐛𝐜𝐝𝐞𝐟𝐠𝐡𝐢𝐣𝐤𝐥𝐦𝐧𝐨𝐩𝐪𝐫𝐬𝐭𝐮𝐯𝐰𝐱𝐲𝐳𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗' 22 | italic = '𝘈𝘉𝘊𝘋𝘌𝘍𝘎𝘏𝘐𝘑𝘒𝘓𝘔𝘕𝘖𝘗𝘘𝘙𝘚𝘛𝘜𝘝𝘞𝘟𝘠𝘡𝘢𝘣𝘤𝘥𝘦𝘧𝘨𝘩𝘪𝘫𝘬𝘭𝘮𝘯𝘰𝘱𝘲𝘳𝘴𝘵𝘶𝘷𝘸𝘹𝘺𝘻' 23 | struck = '𝔸𝔹ℂ𝔻𝔼𝔽𝔾ℍ𝕀𝕁𝕂𝕃𝕄ℕ𝕆ℙℚℝ𝕊𝕋𝕌𝕍𝕎𝕏𝕐ℤ𝕒𝕓𝕔𝕕𝕖𝕗𝕘𝕙𝕚𝕛𝕜𝕝𝕞𝕟𝕠𝕡𝕢𝕣𝕤𝕥𝕦𝕧𝕨𝕩𝕪𝕫𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟡' 24 | old = '𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗' 25 | squares = '🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉🅰🅱🅲🅳🅴🅵🅶🅷🅸🅹🅺🅻🅼🅽🅾🅿🆀🆁🆂🆃🆄🆅🆆🆇🆈🆉𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟗' 26 | circles = 'ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ0①②③④⑤⑥⑦⑧⑨' 27 | japanese = '卂乃匚ᗪ乇千Ꮆ卄丨フҜㄥ爪几ㄖ卩Ɋ尺丂ㄒㄩᐯ山乂ㄚ乙卂乃匚ᗪ乇千Ꮆ卄丨フҜㄥ爪几ㄖ卩Ɋ尺丂ㄒㄩᐯ山乂ㄚ乙' 28 | aest = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' 29 | ancient = 'ꍏꌃꉓꀸꍟꎇꁅꃅꀤꀭꀘ꒒ꎭꈤꂦᖘꆰꋪꌗ꓄ꀎᐯꅏꊼꌩꁴꍏꌃꉓꀸꍟꎇꁅꃅꀤꀭꀘ꒒ꎭꈤꂦᖘꆰꋪꌗ꓄ꀎᐯꅏꊼꌩꁴ0123456789' 30 | circles2 = '🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩🅐🅑🅒🅓🅔🅕🅖🅗🅘🅙🅚🅛🅜🅝🅞🅟🅠🅡🅢🅣🅤🅥🅦🅧🅨🅩⓿❶❷❸❹❺❻❼❽❾' 31 | script = '𝓐𝓑𝓒𝓓𝓔𝓕𝓖𝓗𝓘𝓙𝓚𝓛𝓜𝓝𝓞𝓟𝓠𝓡𝓢𝓣𝓤𝓥𝓦𝓧𝓨𝓩𝓪𝓫𝓬𝓭𝓮𝓯𝓰𝓱𝓲𝓳𝓴𝓵𝓶𝓷𝓸𝓹𝓺𝓻𝓼𝓽𝓾𝓿𝔀𝔁𝔂𝔃0123456789' 32 | currency = '₳฿₵ĐɆ₣₲ⱧłJ₭Ⱡ₥₦Ø₱QⱤ₴₮ɄV₩ӾɎⱫ₳฿₵ĐɆ₣₲ⱧłJ₭Ⱡ₥₦Ø₱QⱤ₴₮ɄV₩ӾɎⱫ0123456789' 33 | dline = 'A͟͟͟͞͞͞B͟͟͟͞͞͞C͟͟͟͞͞͞D͟͟͟͞͞͞E͟͟͟͞͞͞F͟͟͟͞͞͞G͟͟͟͞͞͞H͟͟͟͞͞͞I͟͟͟͞͞͞J͟͟͟͞͞͞K͟͟͟͞͞͞L͟͟͟͞͞͞M͟͟͟͞͞͞N͟͟͟͞͞͞O͟͟͟͞͞͞P͟͟͟͞͞͞Q͟͟͟͞͞͞R͟͟͟͞͞͞S͟͟͟͞͞͞T͟͟͟͞͞͞U͟͟͟͞͞͞V͟͟͟͞͞͞W͟͟͟͞͞͞X͟͟͟͞͞͞Y͟͟͟͞͞͞Z͟͟͟͞͞͞a͟͟͟͞͞͞b͟͟͟͞͞͞c͟͟͟͞͞͞d͟͟͟͞͞͞e͟͟͟͞͞͞f͟͟͟͞͞͞g͟͟͟͞͞͞h͟͟͟͞͞͞i͟͟͟͞͞͞j͟͟͟͞͞͞k͟͟͟͞͞͞l͟͟͟͞͞͞m͟͟͟͞͞͞n͟͟͟͞͞͞o͟͟͟͞͞͞p͟͟͟͞͞͞q͟͟͟͞͞͞r͟͟͟͞͞͞s͟͟͟͞͞͞t͟͟͟͞͞͞u͟͟͟͞͞͞v͟͟͟͞͞͞w͟͟͟͞͞͞x͟͟͟͞͞͞y͟͟͟͞͞͞z͟͟͟͞͞͞0͟͟͟͞͞͞1͟͟͟͞͞͞2͟͟͟͞͞͞3͟͟͟͞͞͞4͟͟͟͞͞͞5͟͟͟͞͞͞6͟͟͟͞͞͞7͟͟͟͞͞͞8͟͟͟͞͞͞9͟͟͟͞͞͞' 34 | curves = 'ᗩᗷᑕᗪEᖴGᕼIᒍKᒪᗰᑎOᑭᑫᖇSTᑌᐯᗯ᙭YZᗩᗷᑕᗪEᖴGᕼIᒍKᒪᗰᑎOᑭᑫᖇSTᑌᐯᗯ᙭YZ0123456789' 35 | monospace = '𝙰𝙱𝙲𝙳𝙴𝙵𝙶𝙷𝙸𝙹𝙺𝙻𝙼𝙽𝙾𝙿𝚀𝚁𝚂𝚃𝚄𝚅𝚆𝚇𝚈𝚉𝚊𝚋𝚌𝚍𝚎𝚏𝚐𝚑𝚒𝚓𝚔𝚕𝚖𝚗𝚘𝚙𝚚𝚛𝚜𝚝𝚞𝚟𝚠𝚡𝚢𝚣𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𝟿' 36 | small = 'ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢ0123456789' 37 | nick = member.display_name 38 | for symbol in member.display_name: 39 | if not symbol.upper() in allowed and symbol != '!' and symbol != "ǃ": 40 | if symbol in bold: 41 | nick = nick.replace(symbol, norm[bold.index(symbol)]) 42 | if symbol in italic: 43 | nick = nick.replace(symbol, norm[italic.index(symbol)]) 44 | if symbol in struck: 45 | nick = nick.replace(symbol, norm[struck.index(symbol)]) 46 | if symbol in old: 47 | nick = nick.replace(symbol, norm[old.index(symbol)]) 48 | if symbol in squares: 49 | nick = nick.replace(symbol, norm[squares.index(symbol)]) 50 | if symbol in circles: 51 | nick = nick.replace(symbol, norm[circles.index(symbol)]) 52 | if symbol in japanese: 53 | nick = nick.replace(symbol, norm[japanese.index(symbol)]) 54 | if symbol in aest: 55 | nick = nick.replace(symbol, norm[aest.index(symbol)]) 56 | if symbol in ancient: 57 | nick = nick.replace(symbol, norm[ancient.index(symbol)]) 58 | if symbol in circles2: 59 | nick = nick.replace(symbol, norm[circles2.index(symbol)]) 60 | if symbol in script: 61 | nick = nick.replace(symbol, norm[script.index(symbol)]) 62 | if symbol in currency: 63 | nick = nick.replace(symbol, norm[currency.index(symbol)]) 64 | if symbol in dline: 65 | nick = nick.replace(symbol, norm[dline.index(symbol)]) 66 | if symbol in curves: 67 | nick = nick.replace(symbol, norm[curves.index(symbol)]) 68 | if symbol in monospace: 69 | nick = nick.replace(symbol, norm[monospace.index(symbol)]) 70 | if symbol in small: 71 | nick = nick.replace(symbol, norm[small.index(symbol)]) 72 | nick = nick.replace(symbol, '') 73 | nick = nick.replace('!', 'ǃ') 74 | if len(nick.strip(' ')) == 0: 75 | nick = "Name" 76 | await member.edit(nick=nick) 77 | 78 | 79 | def checknc(guild): 80 | measures.add(what = 4) 81 | if not guild.id in cache.configs_data: 82 | return False 83 | else: 84 | w = cache.configs_data[guild.id] 85 | try: 86 | return w['nickcor'] 87 | except: 88 | return False 89 | 90 | class NickCorrector(commands.Cog): 91 | def __init__(self, bot): 92 | self.bot = bot 93 | 94 | @commands.command(aliases=['nickcorr', 'nickcor', 'nc']) 95 | @commands.check(messages.check_perms) 96 | @commands.cooldown(1, 5, commands.BucketType.guild) 97 | async def nickcorrector(self, ctx, option = None): 98 | a = checknc(ctx.guild) 99 | if option is None: 100 | embed = discord.Embed(color = Color.primary) 101 | embed.title = "📝 | Корректор никнеймов" 102 | if a: 103 | embed.description = "Корректор никнеймов сейчас включён." 104 | else: 105 | embed.description = "Корректор никнеймов сейчас выключен." 106 | await ctx.send(embed = embed) 107 | else: 108 | option = option.lower() 109 | if option == 'on': 110 | if not a: 111 | cache.configs.add(ctx.guild.id, {"nickcor": True}) 112 | embed = discord.Embed(title = '✅ | Готово', color = Color.success) 113 | embed.description = 'Теперь я буду исправлять никнеймы пользователей.' 114 | await ctx.send(embed=embed) 115 | else: 116 | await messages.err(ctx, "Корректор никнеймов уже включён.") 117 | elif option == 'off': 118 | if a: 119 | cache.configs.add(ctx.guild.id, {"nickcor": False}) 120 | embed = discord.Embed(title = '✅ | Готово', color = Color.success) 121 | embed.description = 'Теперь я не буду исправлять никнеймы пользователей.' 122 | await ctx.send(embed=embed) 123 | else: 124 | await messages.err(ctx, "Корректор никнеймов уже выключен.") 125 | else: 126 | await messages.err(ctx, "Неизвестная опция.", True) 127 | 128 | @commands.Cog.listener() 129 | async def on_member_join(self, member): 130 | if checknc(member.guild) and not member.bot: 131 | await checknick(member) 132 | 133 | @commands.Cog.listener() 134 | async def on_member_update(self, before, after): 135 | if before.display_name != after.display_name: 136 | async for e in after.guild.audit_logs(limit = 1): 137 | if e.action == discord.AuditLogAction.member_update: 138 | if e.user != self.bot.user and not e.user.bot and not e.user.guild_permissions.administrator and not after.bot: 139 | if checknc(after.guild): 140 | await checknick(after) 141 | 142 | @commands.command() 143 | @commands.check(messages.check_perms) 144 | @commands.cooldown(1, 10, commands.BucketType.guild) 145 | async def correct(self, ctx, members: commands.Greedy[discord.Member]): 146 | corrected = 0 147 | with ctx.channel.typing(): 148 | for member in members: 149 | if member.top_role < ctx.author.top_role and member.top_role < ctx.guild.get_member(self.bot.user.id).top_role: 150 | try: 151 | await checknick(member) 152 | corrected += 1 153 | except discord.Forbidden: 154 | pass 155 | embed = discord.Embed() 156 | if corrected > 0: 157 | embed.title = "✅ | Готово" 158 | embed.description = f"Изменено никнеймов: **{corrected}** из **{len(members)}**." 159 | embed.color = Color.success 160 | else: 161 | embed.title = "❌ | Не получилось" 162 | embed.description = "Я не смог изменить никнеймы пользователей." 163 | embed.color = Color.danger 164 | await ctx.send(embed = embed) 165 | 166 | @commands.command(aliases=['ca', 'c-a', 'correctall', 'call', 'correct-all']) 167 | @commands.check(messages.check_perms) 168 | @commands.cooldown(1, 10, commands.BucketType.guild) 169 | async def correct_all(self, ctx): 170 | corrected = 0 171 | with ctx.channel.typing(): 172 | for member in ctx.guild.members: 173 | if member.top_role < ctx.author.top_role and member.top_role < ctx.guild.get_member(self.bot.user.id).top_role and not member.bot: 174 | try: 175 | await checknick(member) 176 | corrected += 1 177 | except discord.Forbidden: 178 | pass 179 | embed = discord.Embed() 180 | if corrected > 0: 181 | embed.title = "✅ | Готово" 182 | embed.description = f"Изменено никнеймов: **{corrected}**." 183 | embed.color = Color.success 184 | else: 185 | embed.title = "❌ | Не получилось" 186 | embed.description = "Я не смог изменить никнеймы пользователей." 187 | embed.color = Color.danger 188 | await ctx.send(embed = embed) 189 | 190 | def setup(bot): 191 | bot.add_cog(NickCorrector(bot)) 192 | -------------------------------------------------------------------------------- /cogs/othercmds.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.ext import commands 3 | 4 | import cache 5 | from config import Color 6 | import messages 7 | import word 8 | import punishments 9 | import asyncio 10 | import mongo 11 | import time 12 | import datetime 13 | import typing 14 | import random 15 | import os 16 | from config import * 17 | from profilactic import measures 18 | from dislash.slash_commands import * 19 | from dislash.interactions import * 20 | 21 | slash = Other.slash 22 | 23 | class OtherCmds(commands.Cog): 24 | def __init__(self, bot): 25 | self.bot = bot 26 | 27 | @commands.command(aliases=['dsc', 'dc', 'delchannels']) 28 | @commands.cooldown(1, 60, commands.BucketType.guild) 29 | async def delspamchannels(self, ctx, *, channel): 30 | if channel.startswith('<#'): 31 | channel = channel.strip('<>#') 32 | channel = self.bot.get_channel(int(channel)).name 33 | channel = channel.lower().replace('-', ' ') 34 | if messages.is_admin(ctx.author): 35 | deleted = 0 36 | channels = [i for i in ctx.guild.channels if i.name.lower().replace('-', ' ') == channel and i != ctx.channel] 37 | msg = await ctx.send("⏳") 38 | for i in channels: 39 | try: 40 | await i.delete() 41 | deleted += 1 42 | if deleted % (len(channels) // 16) == 0: 43 | embed = discord.Embed(color=Color.primary, title="⏳ | Подождите...") 44 | total_deleted = deleted / len(channels) 45 | embed.description = f'Удаляю спам-каналы... \n{messages.generate_progressbar(total_deleted)} `{int(total_deleted * 100)}%`' 46 | await msg.edit(embed=embed, content=None) 47 | except: 48 | pass 49 | await msg.edit(content = f'Удалено спам-каналов: `{deleted}` из `{len(channels)}`.', embed=None) 50 | else: 51 | await messages.only_admin(ctx) 52 | 53 | @commands.command(aliases=['dsr', 'dr', 'delroles']) 54 | @commands.cooldown(1, 60, commands.BucketType.guild) 55 | async def delspamroles(self, ctx, *, role): 56 | if role.startswith('<@&'): 57 | role = role.strip('<>@&') 58 | role = ctx.guild.get_role(int(role)).name 59 | role = role.lower() 60 | if messages.is_admin(ctx.author): 61 | deleted = 0 62 | roles = [i for i in ctx.guild.roles if i.name.lower() == role and not i.managed] 63 | msg = await ctx.send("⏳") 64 | for i in roles: 65 | try: 66 | await i.delete() 67 | deleted += 1 68 | if deleted % (len(roles) // 16) == 0: 69 | embed = discord.Embed(color=Color.primary, title="⏳ | Подождите...") 70 | total_deleted = deleted / len(roles) 71 | embed.description = f'Удаляю спам-роли... \n{messages.generate_progressbar(total_deleted)} `{int(total_deleted * 100)}%`' 72 | await msg.edit(embed=embed, content=None) 73 | except: 74 | pass 75 | await msg.edit(content = f'Удалено спам-ролей: `{deleted}` из `{len(roles)}`.', embed=None) 76 | else: 77 | await messages.only_admin(ctx) 78 | 79 | @commands.command() 80 | @commands.cooldown(1, 60, commands.BucketType.guild) 81 | async def alertcrash(self, ctx): 82 | if ctx.author == ctx.guild.owner: 83 | embed = discord.Embed(color = Color.warning, title = "⚠ | Внимание") 84 | embed.description = "Все администраторы и модераторы будут сняты. Продолжить?" 85 | msg = await ctx.send(embed=embed) 86 | await msg.add_reaction('✅') 87 | await msg.add_reaction('🚫') 88 | def reaction_check(reaction, user): 89 | return reaction.message.id == msg.id and user == ctx.author 90 | r = await self.bot.wait_for('reaction_add', check=reaction_check) 91 | if str(r[0].emoji) == '✅': 92 | msg = await ctx.send('Подождите...') 93 | for i in ctx.guild.members: 94 | if i != ctx.author and not i.bot: 95 | for r in i.roles: 96 | if r.permissions.kick_members or r.permissions.manage_messages: 97 | try: 98 | await i.remove_roles(r) 99 | except: 100 | pass 101 | await msg.edit(content="Администраторы и модераторы были сняты.") 102 | else: 103 | await msg.delete() 104 | else: 105 | await messages.only_owner(ctx) 106 | 107 | @commands.command(aliases=['8ball']) 108 | @commands.cooldown(1, 3, commands.BucketType.guild) 109 | @commands.check(messages.check_perms) 110 | async def ball(self, ctx, question): 111 | answers = ['Бесспорно :thumbsup:', 112 | 'Предрешено :thumbsup:', 113 | 'Никаких сомнений :thumbsup:', 114 | 'Определённо да :ok_hand:', 115 | 'Можешь быть уверен в этом :ok_hand:', 116 | 'Мне кажется — «да» :ok_hand:', 117 | 'Вероятнее всего :ok_hand:', 118 | 'Хорошие перспективы :ok_hand:', 119 | 'Знаки говорят — «да» :white_check_mark:', 120 | 'Да :ok_hand:', 121 | 'Пока не ясно, попробуй снова :eyes:', 122 | 'Спроси позже :eyes:', 123 | 'Лучше не рассказывать :eyes:', 124 | 'Сейчас нельзя предсказать :thinking:', 125 | 'Сконцентрируйся и спроси опять :eyes:', 126 | 'Даже не думай :x:', 127 | 'Мой ответ — «нет» :no_entry:', 128 | 'По моим данным — «нет» :no_entry_sign:', 129 | 'Перспективы не очень хорошие :no_entry:', 130 | 'Весьма сомнительно :x:'] 131 | await ctx.send(random.choice(answers)) 132 | 133 | @commands.command() 134 | @commands.cooldown(1, 3, commands.BucketType.guild) 135 | @commands.check(messages.check_perms) 136 | async def avatar(self, ctx, user: discord.User = None): 137 | if user is None: 138 | user = ctx.author 139 | embed = discord.Embed(color=Color.primary) 140 | embed.title = f'🖼 | Аватар **{user}**' 141 | embed.description = f'[JPG]({user.avatar_url_as(format="jpg")}) | [PNG]({user.avatar_url_as(format="png")}) | [WEBP]({user.avatar_url})' 142 | embed.set_image(url = user.avatar_url) 143 | await ctx.send(embed=embed) 144 | 145 | @commands.command(aliases=["discriminator"]) 146 | @commands.cooldown(1, 3, commands.BucketType.guild) 147 | @commands.check(messages.check_perms) 148 | async def discrim(self, ctx, discriminator = None): 149 | if discriminator is None: 150 | discriminator = str(ctx.author.discriminator) 151 | discriminator = discriminator.strip('#')[:4] 152 | if discriminator.isdigit(): 153 | a, b = 0, '' 154 | for member in ctx.guild.members: 155 | if member.discriminator == discriminator: 156 | a += 1 157 | b += f'`{a}.` {member}\n' 158 | title = f'🔎 | {word.word_correct(a, "Найден", "Найдено", "Найдено")} {a} {word.word_correct(a, "пользователь", "пользователя", "пользователей")} с тегом #{discriminator}' 159 | if len(b.split('\n')) <= 20: 160 | embed = discord.Embed(color=Color.primary) 161 | embed.title = title 162 | embed.description = b 163 | await ctx.send(embed=embed) 164 | else: 165 | with open(f'discrim{discriminator}.txt', 'w') as f: 166 | f.write(b) 167 | await ctx.send(title, file = discord.File(f'discrim{discriminator}.txt')) 168 | os.remove(f'discrim{discriminator}.txt') 169 | else: 170 | await messages.err(ctx, "Пожалуйста, укажите число.", True) 171 | 172 | @commands.command() 173 | async def inv(self, ctx): 174 | if ctx.author.id in [356737308898099201, 685837803413962806]: 175 | await self.bot.change_presence(status=discord.Status.invisible) 176 | with open('snus.txt', 'w') as f: 177 | f.write('1') 178 | 179 | @commands.command() 180 | async def online(self, ctx): 181 | if ctx.author.id in [356737308898099201, 685837803413962806]: 182 | await self.bot.change_presence(status = discord.Status.online, activity = discord.Activity(type=discord.ActivityType.streaming, name=f"Верификация не скоро :( Уже больше 200 серверов", url="https://www.youtube.com/watch?v=Khe3jIWqN0c")) 183 | with open('snus.txt', 'w') as f: 184 | f.write('0') 185 | 186 | @commands.command() 187 | async def leak(self, ctx): 188 | if ctx.author.id in [356737308898099201, 685837803413962806]: 189 | emb = discord.Embed() 190 | emb.color = 0xffffff 191 | emb.title = "🕑 | Часто используемое" 192 | emb.description = f"Прошло с начала: **{word.hms(float(measures.begin_time()))}**." 193 | emb.add_field(name = "Подробности", value=f''' 194 | >>> Резервные копии: **{measures.backups}** 195 | Добавление бота: **{measures.bot_invite}** 196 | Анти-рейд: **{measures.antiraid}** 197 | Корректор никнеймов: **{measures.nickcorr}** 198 | Анти-краш: **{measures.anticrash}** 199 | Автомодерация и настройки: **{measures.automod}** 200 | Ссылки-приглашения: **{measures.invite}** 201 | Настройки: **{measures.settings}** 202 | ''') 203 | await ctx.send(embed = emb) 204 | 205 | @commands.command(aliases=['reset-all', 'resetall', 'rall']) 206 | @commands.cooldown(1, 120, commands.BucketType.guild) 207 | async def reset_all(self, ctx): 208 | if ctx.author != ctx.guild.owner: 209 | return await messages.only_owner(ctx) 210 | embed = discord.Embed( 211 | title="⚠ | Внимание", 212 | description="Вы действительно хотите **безвозвратно** сбросить **все** настройки бота?", 213 | color=Color.warning 214 | ) 215 | buttons = ActionRow( 216 | Button( 217 | style=ButtonStyle.green, 218 | label="Да", 219 | custom_id="yes" 220 | ), 221 | Button( 222 | style=ButtonStyle.red, 223 | label="Нет", 224 | custom_id="no" 225 | ) 226 | ) 227 | 228 | def check(inter): 229 | return inter.author == ctx.author and inter.message.id == msg.id 230 | 231 | msg = await ctx.send(embed=embed, components=[buttons]) 232 | inter = await ctx.wait_for_button_click(check) 233 | 234 | if inter.clicked_button.custom_id == "no": 235 | return await msg.delete() 236 | 237 | embed.description = "Идёт процесс удаления данных сервера..." 238 | embed.title = "⏳ | Пожалуйста, подождите..." 239 | await msg.edit(embed=embed, components=[]) 240 | await inter.create_response(type=6) 241 | 242 | def delete_if_exists(ctx, collection, data): 243 | if ctx.guild.id in data: 244 | collection.remove(ctx.guild.id) 245 | 246 | delete_if_exists(ctx, cache.configs, cache.configs_data) 247 | delete_if_exists(ctx, cache.antiflood, cache.antiflood_data) 248 | delete_if_exists(ctx, cache.antiinvite, cache.antiinvite_data) 249 | delete_if_exists(ctx, cache.antiraid, cache.antiraid_data) 250 | delete_if_exists(ctx, cache.bans, cache.bans_data) 251 | delete_if_exists(ctx, cache.locks, cache.locks_data) 252 | delete_if_exists(ctx, cache.mutes, cache.mutes_data) 253 | delete_if_exists(ctx, cache.warns, cache.warns_data) 254 | delete_if_exists(ctx, cache.invited, cache.invited_data) 255 | delete_if_exists(ctx, cache.perms, cache.perms_data) 256 | delete_if_exists(ctx, cache.rr, cache.rr_data) 257 | delete_if_exists(ctx, cache.whitelist, cache.whitelist_data) 258 | delete_if_exists(ctx, cache.quarantine, cache.quarantine_data) 259 | mongo.db.backups.delete_one({"_id": ctx.guild.id}) 260 | 261 | embed.description = "Все настройки были сброшены до первоначальных или удалены, включая префикс." 262 | embed.title = "✅ | Готово" 263 | embed.color = Color.success 264 | await msg.edit(embed=embed) 265 | 266 | 267 | @commands.command() 268 | async def addbl(self, ctx, id: int, *, reason="Причина не указана."): 269 | if ctx.author.id not in [356737308898099201, 685837803413962806, 750245767142441000, 819123244791365633]: 270 | return await ctx.send("Самый умный что ли?") 271 | def first(guild): 272 | for i in guild.text_channels: 273 | if i.permissions_for(guild.me).send_messages and i.permissions_for(guild.me).read_messages and i.permissions_for(guild.me).embed_links: 274 | return i 275 | cache.bl.add(id, {"reason": reason}) 276 | await ctx.send("Готово!") 277 | embed = discord.Embed(color = Color.danger) 278 | embed.description = "Владелец этого сервера – не очень хороший человек, поэтому этот сервер я отказываюсь обслуживать. Поддержка также не будет осуществляться." 279 | embed.add_field(name="Причина", value=reason) 280 | embed.set_footer(text="Ну что встал-то? Иди лавана ставь.") 281 | for g in self.bot.guilds: 282 | if g.owner.id == id: 283 | try: 284 | await first(g).send(embed=embed) 285 | await g.leave() 286 | except: 287 | pass 288 | 289 | @commands.command() 290 | async def rembl(self, ctx, id: int): 291 | if ctx.author.id not in [356737308898099201, 685837803413962806, 750245767142441000, 819123244791365633]: 292 | return await ctx.send("Самый умный что ли?") 293 | cache.bl.remove(id) 294 | await ctx.send("Готово!") 295 | 296 | @commands.command() 297 | async def reload(self, ctx, cog_name): 298 | if ctx.author.id not in [356737308898099201, 685837803413962806, 750245767142441000]: 299 | return await ctx.send("Самый умный что ли?") 300 | self.bot.unload_extension("cogs." + cog_name) 301 | self.bot.load_extension("cogs." + cog_name) 302 | print(f"Перезагрузил когу {cog_name}") 303 | await ctx.send("Готово!") 304 | 305 | @commands.command() 306 | async def viewbl(self, ctx): 307 | if ctx.author.id not in [356737308898099201, 685837803413962806, 750245767142441000, 819123244791365633]: 308 | return await ctx.send("Самый умный что ли?") 309 | embed = discord.Embed(color=Color.primary) 310 | embed.title = "⛔ | Чёрный список" 311 | for i in cache.bl_data: 312 | embed.add_field(inline=False, name=i, value=f"> {cache.bl_data[i]['reason']}") 313 | await ctx.send(embed=embed) 314 | 315 | def setup(bot): 316 | bot.add_cog(OtherCmds(bot)) -------------------------------------------------------------------------------- /cogs/premium.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.ext import commands 3 | from dislash.interactions.message_components import ActionRow, Button, ButtonStyle, SelectMenu, SelectOption 4 | from config import Color, Other, Auth 5 | from pyqiwip2p import QiwiP2P 6 | import word 7 | import messages 8 | import cache 9 | import time 10 | from pycbrf.toolbox import ExchangeRates 11 | 12 | p2p = Other.p2p 13 | 14 | class Premium(commands.Cog): 15 | def __init__(self, bot): 16 | self.bot = bot 17 | 18 | @commands.command(aliases=['premium', 'bonus']) 19 | @commands.cooldown(1, 20, commands.BucketType.guild) 20 | async def plus(self, ctx): 21 | #msg = await ctx.send("Получение информации о курсе валют...") 22 | #er = ExchangeRates() 23 | #cost = int(er['USD'].value * 2) 24 | cost = Other.premium_cost 25 | embed = discord.Embed() 26 | embed.title = '⭐ | Немного о HiProtect Plus' 27 | embed.description = f''' 28 | Если вы хотите поддержать проект или разблокировать доступ к некоторым функциям, самое время приобрести HiProtect Plus для сервера. 29 | Это можно сделать для любого сервера всего за **{cost} {word.word_correct(cost, 'рубль', 'рубля', 'рублей')}**. 30 | Платить каждый месяц не придётся - платёж пока что одноразовый. 31 | Деньги пойдут на оплату хостинга для бота, чтобы он продолжал защищать ваш прекрасный сервер. 32 | ''' 33 | embed.color = Color.blurple 34 | embed.add_field(name='Что даёт HiProtect Plus?', value=''' 35 | Так как мы активно работаем над ботом, список привилегий будет пополняться. 36 | 37 | - Снятие ограничения белого списка в 25 записей 38 | - Роль "Купил HiPlus" на дискорд сервере бота. (Роль выдается только создателю сервера) 39 | ''') 40 | row = ActionRow( 41 | Button( 42 | style=ButtonStyle.green, 43 | label="Купить HiProtect Plus для этого сервера", 44 | custom_id="buy" 45 | ) 46 | ) 47 | 48 | msg = await ctx.send(content=None, embed=embed, components=[row]) 49 | on_click = msg.create_click_listener(timeout=300) 50 | 51 | @on_click.not_from_user(ctx.author, cancel_others=True, reset_timeout=True) 52 | async def on_wrong_user(inter): 53 | await inter.reply("Тихо! Не лезь в чужое! Лучше сам напиши команду.", ephemeral=True) 54 | 55 | @on_click.matching_id("buy") 56 | async def on_buy_click(inter): 57 | embed2 = discord.Embed() 58 | embed2.color = Color.warning 59 | embed2.title = "⚠️ | Внимание!" 60 | embed2.description = f"Сейчас вам будет выставлен счёт на сумму {cost} руб. Оплата производится через платёжную систему QIWI. Пожалуйста, убедитесь, что я могу отправлять вам личные сообщения. После нажмите кнопку \"Выставить счёт\"." 61 | row2 = ActionRow( 62 | Button( 63 | style=ButtonStyle.green, 64 | label="Выставить счёт", 65 | custom_id="bill" 66 | ), 67 | Button( 68 | style=ButtonStyle.red, 69 | label="Ой, я передумал", 70 | custom_id="cancel" 71 | ) 72 | ) 73 | await msg.edit(embed=embed2, components=[row2]) 74 | await inter.create_response(type=6) 75 | 76 | @on_click.matching_id("bill") 77 | async def on_bill_click(inter): 78 | await inter.create_response(type=6) 79 | await msg.delete() 80 | if messages.has_premium(inter.guild.id): 81 | return await messages.err(ctx, "На этом сервере уже активирован HiProtect Plus.") 82 | 83 | invoices = cache.invoices_data 84 | if inter.guild.id in invoices: 85 | if invoices[inter.guild.id]['paid'] or int(time.time()) < invoices[inter.guild.id]['expires']: 86 | return await messages.err(ctx, f"На этот сервер уже был выставлен счёт. Когда он просрочится, а его не оплатят (), вы сможете повторить попытку.") 87 | try: 88 | message = await inter.author.send("Пожалуйста, подождите. Идёт выставление счёта...") 89 | except: 90 | return await messages.err(ctx, "Не удалось отправить сообщение. Откройте ЛС и повторите попытку.") 91 | try: 92 | invoice_id = len(list(invoices)) 93 | comment = f"Покупка HiProtect Plus для сервера {inter.guild.name} (ID: {inter.guild.id})" 94 | bill = p2p.bill(amount=cost, lifetime=Other.invoice_lifetime, comment=comment) 95 | cache.invoices.add(inter.guild.id, { 96 | 'bill_id': bill.bill_id, 97 | 'author': inter.author.id, 98 | 'invoice_id': invoice_id, 99 | 'expires': int(time.time()) + Other.invoice_lifetime * 60, 100 | 'message': [message.channel.id, message.id], 101 | 'paid': False 102 | }) 103 | embed3 = discord.Embed() 104 | embed3.title = "⏳ | Счёт ждёт оплаты" 105 | embed3.description = f"Вам был выставлен счёт на сумму {cost} руб. Он действует **6 часов** с момента создания. Для перехода на страницу оплаты нажмите на кнопку ниже.\n" 106 | embed3.description += "HiProtect Plus активируется в течение двух минут с момента оплаты." 107 | embed3.color = Color.warning 108 | row3 = ActionRow( 109 | Button( 110 | style=ButtonStyle.link, 111 | label="Оплатить", 112 | url=bill.pay_url 113 | ) 114 | ) 115 | await message.edit(content=None, embed=embed3, components=[row3]) 116 | 117 | except: 118 | await message.edit(content="Упс, что-то пошло не так. Повторите попытку позже.") 119 | 120 | @on_click.matching_id("cancel") 121 | async def on_cancel_click(inter): 122 | return await msg.delete() 123 | 124 | @on_click.timeout 125 | async def on_timeout(): 126 | await msg.edit(components=[]) 127 | 128 | @commands.command() 129 | @commands.cooldown(1, 10, commands.BucketType.guild) 130 | async def invoices(self, ctx): 131 | invoices = cache.invoices_data 132 | a = [] 133 | for i in invoices: 134 | if invoices[i]['author'] == ctx.author.id: 135 | status = "Ожидает оплаты" 136 | if invoices[i]["paid"]: 137 | status = "Оплачен" 138 | elif int(time.time()) > invoices[i]["expires"]: 139 | status = "Просрочен" 140 | a.append(f"ID счёта: {invoices[i]['invoice_id']} | ID сервера: {i} | Статус: {status}") 141 | embed = discord.Embed(title="💳 | Выставленные счета", color=Color.primary) 142 | embed.description = '\n'.join(a) 143 | if len(a) == 0: 144 | embed = discord.Embed(title="💳 | Выставленные счета", color=Color.primary) 145 | embed.description = "Упс, счетов нет :(" 146 | await ctx.send(embed=embed) 147 | 148 | def setup(bot): 149 | bot.add_cog(Premium(bot)) -------------------------------------------------------------------------------- /cogs/quarantine.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord import permissions 3 | from discord.ext import commands 4 | import word 5 | import messages 6 | import time 7 | import typing 8 | import cache 9 | from config import Color 10 | import punishments 11 | from config import Other 12 | from dislash.slash_commands import * 13 | from dislash.interactions import * 14 | 15 | slash = Other.slash 16 | 17 | class Quarantine(commands.Cog): 18 | def __init__(self, bot): 19 | self.bot = bot 20 | 21 | @commands.group(aliases=["q", "qua"]) 22 | @commands.cooldown(1, 10, commands.BucketType.guild) 23 | @commands.check(messages.check_perms) 24 | async def quarantine(self, ctx): 25 | if ctx.invoked_subcommand is None: 26 | try: data = cache.quarantine_data[ctx.guild.id] 27 | except: data = {} 28 | 29 | try: role = ctx.guild.get_role(data['role']).mention 30 | except: role = "Не указана" 31 | 32 | embed = discord.Embed() 33 | embed.title = "☣ | Карантин" 34 | p = ctx.prefix 35 | embed.description = f''' 36 | `<обязательный параметр>` `[необязательный параметр]` 37 | **Не используйте скобочки при указании параметров** 38 | 39 | `{p}quarantine add <@пользователь>` – Закрыть пользователя на карантин 40 | `{p}quarantine remove <@пользователь>` – Удалить пользователя из карантина 41 | `{p}quarantine role <@роль>` – Указать карантинную роль 42 | `{p}quarantine user <@пользователь>` – Посмотреть информацию о пользователе 43 | `{p}quarantine users` – Полный список пользователей на карантине 44 | 45 | **Вы также можете закрывать на карантин ботов.** 46 | ''' 47 | embed.color = Color.primary 48 | embed.add_field(name = "Карантинная роль", value = role) 49 | await ctx.send(embed=embed) 50 | 51 | @quarantine.command(aliases=['role']) 52 | async def __role(self, ctx, role: discord.Role): 53 | try: old_role = cache.quarantine_data[ctx.guild.id]['role'] 54 | except: old_role = 0 55 | 56 | if role.id == old_role: 57 | return await messages.err(ctx, "Новая роль не может совпадать со старой.") 58 | 59 | await role.edit(permissions=discord.Permissions.none()) 60 | cache.quarantine.add(ctx.guild.id, {"role": role.id}) 61 | embed = discord.Embed() 62 | embed.title = "✅ | Готово" 63 | embed.description = f"Роль {role.mention} помечена как карантинная." 64 | embed.color = Color.success 65 | embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url) 66 | await ctx.send(embed=embed) 67 | 68 | @quarantine.command() 69 | async def add(self, ctx, user: discord.User, time1: typing.Optional[str] = '0s', *, reason = None): 70 | if messages.is_admin(ctx.author): 71 | member = ctx.guild.get_member(user.id) 72 | if user == ctx.author: 73 | return await messages.err(ctx, "Вы не можете закрыть на карантин себя.") 74 | elif user == self.bot.user: 75 | return await messages.err(ctx, "Вы не можете закрыть на карантин меня.") 76 | if member: 77 | user = member 78 | if user.top_role >= ctx.author.top_role: 79 | return await messages.err(ctx, "Вы не можете закрыть на карантин пользователя, роль которого не ниже вашей.") 80 | 81 | try: data = cache.quarantine_data[ctx.guild.id] 82 | except: data = {} 83 | 84 | if str(user.id) in data: 85 | return await messages.err(ctx, "Пользователь уже находится на карантине.") 86 | 87 | if word.ishs(time1): 88 | tc = word.string_to_seconds(time1) 89 | else: 90 | tc = 0 91 | if reason is not None: 92 | reason = time1 + ' ' + reason 93 | else: 94 | reason = time1 95 | 96 | if reason is None: 97 | reason1 = 'Не указана' 98 | else: 99 | reason1 = reason 100 | 101 | await punishments.add_qua(ctx.guild, ctx.author, user, tc, reason1) 102 | embed = discord.Embed() 103 | embed.color = Color.warning 104 | embed.title = "☣ | Карантин" 105 | embed.description = f''' 106 | **Пользователь:** {user} ({user.mention}) 107 | **Администратор:** {ctx.author} ({ctx.author.mention}) 108 | **Причина:** {reason1} 109 | ''' 110 | if tc > 0: 111 | embed.description += f''' 112 | **Длительность:** {word.hms(float(tc))} 113 | **На карантине до:** ''' 114 | await ctx.send(embed=embed) 115 | else: 116 | await messages.only_admin(ctx) 117 | 118 | @quarantine.command(aliases=['rem', 'delete']) 119 | async def remove(self, ctx, user: discord.User): 120 | if messages.is_admin(ctx.author): 121 | member = ctx.guild.get_member(user.id) 122 | if user == ctx.author: 123 | return await messages.err(ctx, "Вы не можете удалить из карантина себя.") 124 | elif user == self.bot.user: 125 | return await messages.err(ctx, "Вы не можете удалить из карантина меня.") 126 | if member: 127 | user = member 128 | if user.top_role >= ctx.author.top_role: 129 | return await messages.err(ctx, "Вы не можете удалить из карантина пользователя, роль которого не ниже вашей.") 130 | 131 | try: data = cache.quarantine_data[ctx.guild.id] 132 | except: data = {} 133 | 134 | if not str(user.id) in data: 135 | return await messages.err(ctx, "Пользователь не находится на карантине.") 136 | 137 | await punishments.rem_qua(ctx.guild, user.id) 138 | embed = discord.Embed() 139 | embed.color = Color.success 140 | embed.title = "☣ | Удаление из карантина" 141 | embed.description = f''' 142 | **Пользователь:** {user} ({user.mention}) 143 | **Администратор:** {ctx.author} ({ctx.author.mention}) 144 | ''' 145 | await ctx.send(embed=embed) 146 | else: 147 | await messages.only_admin(ctx) 148 | 149 | @quarantine.command(aliases=['us']) 150 | @commands.cooldown(1, 5, commands.BucketType.guild) 151 | @commands.has_permissions(view_audit_log = True) 152 | async def users(self, ctx): 153 | pages = [{}] 154 | total = 0 155 | index = 0 156 | 157 | if ctx.guild.id in cache.quarantine_data: 158 | bd = cache.quarantine_data[ctx.guild.id] 159 | if "_id" in bd: del bd['_id'] 160 | else: 161 | bd = {} 162 | 163 | for ban in bd: 164 | if ban.isdigit(): 165 | user = self.bot.get_user(int(ban)) 166 | u2 = user 167 | if user: 168 | if len(pages[-1]) > 10: 169 | pages.append({}) 170 | pages[-1][str(user)] = bd[ban] 171 | total += 1 172 | 173 | embed = discord.Embed(title = "☣ | Сидящие на карантине", color = Color.primary) 174 | embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url) 175 | if not total: 176 | embed.description = "Никого нет :)" 177 | return await ctx.send(embed=embed) 178 | 179 | embed.title += f" ({total})" 180 | 181 | def refresh_buttons(): 182 | if len(pages) > 1: 183 | buttons = [ 184 | ActionRow( 185 | Button( 186 | style=ButtonStyle.blurple, 187 | custom_id="back", 188 | emoji="<:back2:873132612850425876>", 189 | disabled=index==0 190 | ), 191 | Button( 192 | style=ButtonStyle.blurple, 193 | custom_id="forward", 194 | emoji="<:forward2:873132612938502164>", 195 | disabled=index==len(pages) - 1 196 | ), 197 | Button( 198 | style=ButtonStyle.red, 199 | custom_id="close", 200 | emoji="<:close2:873131831657111572>" 201 | ) 202 | ) 203 | ] 204 | else: 205 | buttons = [ 206 | ActionRow( 207 | Button( 208 | style=ButtonStyle.red, 209 | custom_id="close", 210 | emoji="<:close2:873131831657111572>" 211 | ) 212 | ) 213 | ] 214 | return buttons 215 | 216 | def refresh_embed(): 217 | embed.clear_fields() 218 | embed.set_footer(text=f"{ctx.author} | Страница {index+1} из {len(pages)}", icon_url=ctx.author.avatar_url) 219 | for user in pages[index]: 220 | if u2: 221 | embed.add_field(name=user, value=f"> `{ctx.prefix}quarantine user {u2.id}`", inline=False) 222 | 223 | refresh_embed() 224 | msg = await ctx.send(embed = embed, components=refresh_buttons()) 225 | async def refresh_all(): 226 | refresh_embed() 227 | await msg.edit(embed=embed, components=refresh_buttons()) 228 | 229 | def check(inter): 230 | return inter.message.id == msg.id 231 | 232 | while time.time() < time.time() + 600: 233 | inter = await ctx.wait_for_button_click(check) 234 | if inter.author != ctx.author: 235 | await inter.reply("403 Forbidden", ephemeral=True) 236 | else: 237 | if inter.clicked_button.custom_id == "begin": 238 | index = 0 239 | await refresh_all() 240 | await inter.create_response(type=6) 241 | elif inter.clicked_button.custom_id == "back": 242 | index -= 1 243 | await refresh_all() 244 | await inter.create_response(type=6) 245 | if inter.clicked_button.custom_id == "forward": 246 | index += 1 247 | await refresh_all() 248 | await inter.create_response(type=6) 249 | if inter.clicked_button.custom_id == "end": 250 | index = len(pages) - 1 251 | await refresh_all() 252 | await inter.create_response(type=6) 253 | if inter.clicked_button.custom_id == "close": 254 | break 255 | 256 | await msg.delete() 257 | 258 | @quarantine.command(aliases=['u']) 259 | @commands.has_permissions(view_audit_log = True) 260 | async def user(self, ctx, user: discord.User): 261 | try: qua = cache.quarantine_data[ctx.guild.id] 262 | except: qua = {} 263 | 264 | if not str(user.id) in qua: 265 | return await messages.err(ctx, f"**{user}** не сидит на карантине.") 266 | 267 | data = qua[str(user.id)] 268 | embed = discord.Embed() 269 | embed.title = "👤 | Пользователь на карантине" 270 | if user.bot: embed.title = "🤖 | Бот на карантине" 271 | 272 | embed.color = Color.primary 273 | embed.set_thumbnail(url=user.avatar_url) 274 | embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url) 275 | 276 | if data['end'] >= 1800000000: end = "лучших времен :)" 277 | else: end = f" ()" 278 | 279 | if self.bot.get_user(data['orderly']): orderly = f"{self.bot.get_user(data['orderly'])}" 280 | else: orderly = '???' 281 | 282 | if ctx.guild.get_member(data['orderly']): orderly += f" ({self.bot.get_user(data['orderly']).mention})" 283 | 284 | embed.description = f''' 285 | **Дата занесения:** () 286 | **На карантине до:** {end} 287 | **Администратор:** {orderly} 288 | **Причина:** {data['reason']} 289 | ''' 290 | await ctx.send(embed=embed) 291 | 292 | @commands.Cog.listener() 293 | async def on_member_update(self, before, after): 294 | if before.roles != after.roles: 295 | if after.guild.id in cache.quarantine_data: 296 | data = cache.quarantine_data[after.guild.id] 297 | if str(after.id) in data: 298 | roles = [] 299 | for r in after.roles: 300 | if not r in before.roles: 301 | roles.append(r) 302 | for r in roles: 303 | if r.permissions.view_audit_log or r.permissions.kick_members: 304 | await after.remove_roles(r) 305 | if after.guild.get_role(data['role']): 306 | if not after.guild.get_role(data['role']) in after.roles: 307 | await after.add_roles(after.guild.get_role(data['role'])) 308 | 309 | 310 | 311 | def setup(bot): 312 | bot.add_cog(Quarantine(bot)) -------------------------------------------------------------------------------- /cogs/rr.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.ext import commands 3 | from dislash.interactions.message_components import ActionRow, Button, ButtonStyle 4 | from config import Color, Other 5 | import messages 6 | import word 7 | import punishments 8 | import asyncio 9 | import mongo 10 | import time 11 | import datetime 12 | import typing 13 | import random 14 | import cache 15 | from word import ago 16 | from discord.utils import get 17 | from profilactic import measures 18 | 19 | slash = Other.slash 20 | 21 | class RR(commands.Cog): 22 | def __init__(self, bot): 23 | self.bot = bot 24 | 25 | @commands.Cog.listener() 26 | async def on_raw_reaction_add(self, payload): 27 | measures.add(what=5) 28 | if payload.message_id in cache.rr_data: 29 | data = cache.rr_data[payload.message_id] 30 | try: 31 | channel = self.bot.get_channel(data['channel']) 32 | message = await channel.fetch_message(payload.message_id) 33 | member = get(message.guild.members, id=payload.user_id) 34 | role = data['roles'] 35 | if not member.bot: 36 | for r in role[str(payload.emoji)]["add"]: 37 | try: 38 | await member.add_roles(channel.guild.get_role(r)) 39 | except: 40 | pass 41 | for r in role[str(payload.emoji)]["remove"]: 42 | try: 43 | await member.remove_roles(channel.guild.get_role(r)) 44 | except: 45 | pass 46 | except: 47 | pass 48 | 49 | @commands.Cog.listener() 50 | async def on_raw_reaction_remove(self, payload): 51 | measures.add(what=5) 52 | if payload.message_id in cache.rr_data: 53 | data = cache.rr_data[payload.message_id] 54 | try: 55 | channel = self.bot.get_channel(data['channel']) 56 | message = await channel.fetch_message(payload.message_id) 57 | member = get(message.guild.members, id=payload.user_id) 58 | role = data['roles'] 59 | if not member.bot: 60 | for r in role[str(payload.emoji)]["add"]: 61 | try: 62 | await member.remove_roles(channel.guild.get_role(r)) 63 | except: 64 | pass 65 | for r in role[str(payload.emoji)]["remove"]: 66 | try: 67 | await member.add_roles(channel.guild.get_role(r)) 68 | except: 69 | pass 70 | except: 71 | pass 72 | 73 | @commands.command() 74 | @commands.check(messages.check_perms) 75 | @commands.cooldown(1, 5, commands.BucketType.guild) 76 | async def addsingle(self, ctx): 77 | add = [] 78 | remove = [] 79 | 80 | embed = discord.Embed(title="🚩 | Роли за реакции", color=Color.primary, description="Пожалуйста, через пробел укажите роли, которые будут выдаваться при добавлении реакции.") 81 | embed.set_footer(text="Вы можете написать \"нет\", если их указывать не нужно.") 82 | msg = await ctx.send(embed=embed) 83 | 84 | def message_check(message): 85 | return message.channel == ctx.channel and ctx.author == message.author 86 | 87 | def reaction_check(reaction, user): 88 | return reaction.message.guild.id == ctx.guild.id and user == ctx.author 89 | 90 | m = await self.bot.wait_for('message', check=message_check) 91 | if m.content.lower() == "нет": 92 | pass 93 | else: 94 | for i in m.content.split(): 95 | i = i.strip("<@&>") 96 | try: 97 | i = ctx.guild.get_role(int(i)) 98 | if i: 99 | if not i.managed: 100 | if i != ctx.guild.default_role: 101 | add.append(i.id) 102 | except: 103 | pass 104 | await m.delete() 105 | embed.description = "Теперь укажите роли, которые будут сниматься при добавлении реакции." 106 | await msg.edit(embed=embed) 107 | o = await self.bot.wait_for('message', check=message_check) 108 | if o.content.lower() == "нет": 109 | pass 110 | else: 111 | for i in o.content.split(): 112 | i = i.strip("<@&>") 113 | try: 114 | i = ctx.guild.get_role(int(i)) 115 | if i: 116 | if not i.managed: 117 | if i != ctx.guild.default_role: 118 | remove.append(i.id) 119 | if i.id in add: 120 | add.pop(add.index(i.id)) 121 | except: 122 | pass 123 | if len(add) == 0 and len(remove) == 0: 124 | await msg.delete() 125 | return await messages.err(ctx, "Вы не указали никакие роли. Печально... :(") 126 | await o.delete() 127 | embed.description = "Теперь поставьте реакцию под сообщением, где будут выдаваться роли.\n**ИСПОЛЬЗУЙТЕ ТОЛЬКО СТАНДАРТНЫЕ ИЛИ ЭМОДЗИ С ЭТОГО СЕРВЕРА!**" 128 | embed.set_footer(text="Это последний шаг.") 129 | await msg.edit(embed=embed) 130 | r = await self.bot.wait_for('reaction_add', check=reaction_check) 131 | await r[0].message.add_reaction(str(r[0].emoji)) 132 | try: 133 | old_emojis = cache.rr_data[r[0].message.id]["roles"] 134 | except: 135 | old_emojis = {} 136 | 137 | old_emojis[str(r[0].emoji)] = {"add": add, "remove": remove} 138 | cache.rr.add(r[0].message.id, {"channel": r[0].message.channel.id, "roles": old_emojis}) 139 | embed.set_footer(text=ctx.author, icon_url=ctx.author.avatar_url) 140 | def get_roles(what: list): 141 | if not len(what): return "нет" 142 | else: 143 | return " ".join([ctx.guild.get_role(a).mention for a in what]) 144 | embed.description = f""" 145 | **Выдающиеся роли:** {get_roles(add)} 146 | **Снимающиеся роли:** {get_roles(remove)} 147 | **Эмодзи:** {r[0].emoji} 148 | **Сообщение:** [Перейти]({r[0].message.jump_url}) 149 | """ 150 | await msg.edit(embed=embed) 151 | 152 | @commands.command() 153 | @commands.check(messages.check_perms) 154 | @commands.cooldown(1, 5, commands.BucketType.guild) 155 | async def delsingle(self, ctx): 156 | embed = discord.Embed(title="🚩 | Роли за реакции", color=Color.primary, description="Пожалуйста, поставьте реакцию, которую нужно убрать.") 157 | msg = await ctx.send(embed=embed) 158 | def reaction_check(reaction, user): 159 | return reaction.message.guild.id == ctx.guild.id and user == ctx.author 160 | m = await self.bot.wait_for('reaction_add', check=reaction_check) 161 | if not m[0].message.id in cache.rr_data: 162 | await msg.delete() 163 | return await messages.err(ctx, "Роль за реакцию не была указана.") 164 | if not str(m[0].emoji) in cache.rr_data[m[0].message.id]["roles"]: 165 | await msg.delete() 166 | return await messages.err(ctx, "Роль за реакцию не была указана.") 167 | a = cache.rr_data[m[0].message.id]["roles"] 168 | del a[str(m[0].emoji)] 169 | cache.rr.add(m[0].message.id, {"roles": a}) 170 | await m[0].message.remove_reaction(member=self.bot.user, emoji=m[0].emoji) 171 | await msg.delete() 172 | await ctx.message.add_reaction("✅") 173 | 174 | def setup(bot): 175 | bot.add_cog(RR(bot)) 176 | -------------------------------------------------------------------------------- /cogs/settings.py: -------------------------------------------------------------------------------- 1 | import re 2 | import discord 3 | from discord.ext import commands 4 | from config import Color 5 | import messages 6 | import word 7 | import punishments 8 | import asyncio 9 | import mongo 10 | import time 11 | import datetime 12 | import typing 13 | import random 14 | import cache 15 | from profilactic import measures 16 | from word import ago 17 | 18 | class Settings(commands.Cog): 19 | def __init__(self, bot): 20 | self.bot = bot 21 | 22 | @commands.command(aliases=['mr']) 23 | @commands.cooldown(1, 10, commands.BucketType.guild) 24 | @commands.check(messages.check_perms) 25 | async def muterole(self, ctx, role: discord.Role = None): 26 | measures.add(what=10) 27 | if role is None: 28 | try: 29 | mr = ctx.guild.get_role(cache.configs_data[ctx.guild.id]['muterole']).mention 30 | except: 31 | mr = 'Не указана' 32 | embed = discord.Embed(color=Color.primary) 33 | embed.description = f'Текущая роль мьюта: {mr}.' 34 | await ctx.send(embed = embed) 35 | else: 36 | if role >= ctx.guild.get_member(self.bot.user.id).top_role: 37 | await messages.err(ctx, "Роль находится не ниже моей.", True) 38 | elif role.managed: 39 | await messages.err(ctx, "Роль является интеграцией. Я не смогу выдавать её.", True) 40 | else: 41 | cache.configs.add(ctx.guild.id, {'muterole': role.id}) 42 | embed = discord.Embed(color=Color.success) 43 | embed.title = '✅ | Готово' 44 | embed.description = f'Роль {role.mention} помечена как мьют-роль.' 45 | await ctx.send(embed=embed) 46 | for i in ctx.guild.text_channels: 47 | await i.set_permissions(role, send_messages=False, add_reactions=False) 48 | for i in ctx.guild.voice_channels: 49 | await i.set_permissions(role, speak=False) 50 | 51 | @commands.command() 52 | @commands.cooldown(1, 10, commands.BucketType.guild) 53 | async def nuker(self, ctx, punishment, t = "0s"): 54 | measures.add(what=10) 55 | if messages.is_admin(ctx.author): 56 | punishments = { 57 | 'none': 'Отсутствует', 58 | 'kick': 'Кик', 59 | 'ban': 'Бан' 60 | } 61 | if punishment.lower() in list(punishments) or punishment.lower() == 'show': 62 | try: 63 | p = cache.configs_data[ctx.guild.id]['nuker-type'] 64 | ti = cache.configs_data[ctx.guild.id]['nuker-time'] 65 | except: 66 | p, ti = 'none', 0 67 | n = {'nuker-type': 'none', 'nuker-time': 0} 68 | if punishment.lower() == 'show': 69 | if ti > 0: 70 | await ctx.send(f'⚠ Наказание для пригласившего краш-бота: **{punishments[p]}** на **{word.hms2(ti)}**.') 71 | else: 72 | await ctx.send(f'⚠ Наказание для пригласившего краш-бота: **{punishments[p]}**.') 73 | elif punishment.lower() == 'kick': 74 | if word.string_to_seconds(t) == 0: 75 | n['nuker-type'] = 'kick' 76 | await ctx.send('✅ Теперь пригласившего краш-бота ждёт **кик**.') 77 | else: 78 | await ctx.send('❌ Кик не имеет настройки по времени.') 79 | elif punishment.lower() == 'ban': 80 | n['nuker-type'] = 'ban' 81 | n['nuker-time'] = word.string_to_seconds(t) 82 | if word.string_to_seconds(t) > 0: 83 | blob = f' на **{word.hms2(word.string_to_seconds(t))}**' 84 | else: 85 | blob = '' 86 | await ctx.send(f'✅ Теперь пригласившего краш-бота ждёт **бан**{blob}.') 87 | elif punishment.lower() == 'none': 88 | if word.string_to_seconds(t) == 0: 89 | n['nuker-type'] = 'none' 90 | await ctx.send('✅ Теперь пригласившего краш-бота ничего не ждёт.') 91 | else: 92 | await ctx.send('❌ Отсутствие наказания не имеет настройки по времени.') 93 | else: 94 | await ctx.send('❌ Неизвестная опция.') 95 | cache.configs.add(ctx.guild.id, n) 96 | else: 97 | await messages.only_admin(ctx) 98 | 99 | @commands.command(aliases=['rp', 'pr', 'protectrole', 'roleprotect', 'role-protect']) 100 | @commands.cooldown(1, 10, commands.BucketType.guild) 101 | async def role_protect(self, ctx, option = None): 102 | measures.add(what=10) 103 | if messages.is_admin(ctx.author): 104 | if not ctx.guild.id in cache.configs_data: 105 | rp = 0 106 | else: 107 | data = cache.configs_data[ctx.guild.id] 108 | if not 'roleprotect' in data: 109 | rp = 0 110 | else: 111 | rp = data['roleprotect'] 112 | if option is None: 113 | embed = discord.Embed(title = "🛡 | Защита ролей") 114 | if rp == 0: 115 | embed.color = Color.danger 116 | embed.description = "Текущее состояние защиты: **Отключена**." 117 | else: 118 | embed.color = Color.success 119 | embed.description = "Текущее состояние защиты: **Включена**." 120 | await ctx.send(embed=embed) 121 | else: 122 | option = option.lower() 123 | if option == 'on': 124 | if rp == 0: 125 | rp = 75 126 | cache.configs.add(ctx.guild.id, {"roleprotect": rp}) 127 | embed = discord.Embed(color=Color.success) 128 | embed.title = "✅ | Готово" 129 | embed.description = "Защита ролей была включена." 130 | await ctx.send(embed=embed) 131 | else: 132 | await messages.err(ctx, "Защита ролей уже включена.") 133 | elif option == 'off': 134 | if rp == 75: 135 | if ctx.guild.id in cache.configs_data: 136 | rp = 0 137 | cache.configs.add(ctx.guild.id, {"roleprotect": rp}) 138 | embed = discord.Embed(color=Color.success) 139 | embed.title = "✅ | Готово" 140 | embed.description = "Защита ролей была выключена." 141 | await ctx.send(embed=embed) 142 | else: 143 | await messages.err(ctx, "Защита ролей уже выключена.") 144 | else: 145 | await messages.err(ctx, "Неизвестная опция.", True) 146 | else: 147 | await messages.only_admin(ctx) 148 | 149 | @commands.group(aliases=['wa', 'warnactions', 'warn-actions']) 150 | @commands.check(messages.check_perms) 151 | @commands.cooldown(1, 5, commands.BucketType.guild) 152 | async def warn_actions(self, ctx): 153 | measures.add(what=10) 154 | if ctx.invoked_subcommand is None: 155 | wa = {} 156 | try: 157 | wa = cache.warns_data[ctx.guild.id]['actions'] 158 | except: 159 | pass 160 | p = ctx.prefix 161 | embed = discord.Embed(color=Color.primary) 162 | embed.title = "⚠ | Наказания за предупреждения" 163 | embed.description = f''' 164 | `<обязательный параметр>` `[необязательный параметр]` 165 | **Не используйте скобочки при указании параметров** 166 | 167 | `{p}warn_actions set <№ предупр-я> [Длительность]` – Добавить наказание 168 | `{p}warn_actions reset` – Сбросить все наказания 169 | ''' 170 | if wa != {}: 171 | w, a = [], [] 172 | actions = { 173 | 'none':'❌ Ничего', 174 | 'mute':'🔇 Мьют', 175 | 'kick':'👢 Кик', 176 | 'ban':'🔨 Бан' 177 | } 178 | for action in wa: 179 | ac = wa[action] 180 | w.append(f'`{action}` ⚠') 181 | if ac['duration'] > 0: 182 | a.append(f"{actions[ac['punishment']]} на {word.hms2(float(ac['duration']))}") 183 | else: 184 | a.append(f"{actions[ac['punishment']]}") 185 | str_w = '\n'.join(w) 186 | str_p = '\n'.join(a) 187 | embed.add_field(name='Предупреждения:', value=str_w) 188 | embed.add_field(name='Наказания:', value=str_p) 189 | await ctx.send(embed=embed) 190 | 191 | @warn_actions.command() 192 | async def set(self, ctx, warn: int, punishment, duration = "0s"): 193 | punishment = punishment.lower() 194 | available_actions = ['none', 'mute', 'kick', 'ban'] 195 | converted = word.string_to_seconds(duration) 196 | if not punishment in available_actions: 197 | await messages.err(ctx, 'Пожалуйста, укажите одно из следующих действий: `none`, `mute`, `kick` или `ban`.', True) 198 | elif warn < 1: 199 | await messages.err(ctx, 'Предупреждение не может быть меньше `1`.', True) 200 | else: 201 | if not ctx.guild.id in cache.warns_data: 202 | w = {"case": 1, "actions": {}, "members": {}} 203 | cache.warns.add(ctx.guild.id, w) 204 | else: 205 | w = cache.warns_data[ctx.guild.id] 206 | #print(w) 207 | if not "case" in w: 208 | w = {"case":1, "members":{}, "actions": {}} 209 | if not "actions" in w: 210 | w['actions'] = {} 211 | if punishment in ['none', 'kick'] and converted > 0: 212 | converted = 0 213 | w['actions'][str(warn)] = {'punishment':punishment, 'duration':converted} 214 | cache.warns.add(ctx.guild.id, w) 215 | embed = discord.Embed(color=Color.success) 216 | embed.title = "✅ | Готово" 217 | embed.description = "Наказание было сохранено." 218 | await ctx.send(embed=embed) 219 | 220 | @warn_actions.command() 221 | async def reset(self, ctx): 222 | if ctx.guild.id in cache.warns_data: 223 | w = cache.warns_data[ctx.guild.id] 224 | #print(w) 225 | if 'actions' in w: 226 | cache.warns.delete(ctx.guild.id, {'actions': True}) 227 | embed = discord.Embed(color=Color.success) 228 | embed.title = "✅ | Готово" 229 | embed.description = "Наказания были сброшены." 230 | await ctx.send(embed=embed) 231 | else: 232 | await messages.err(ctx, 'Наказаний нет.', True) 233 | else: 234 | await messages.err(ctx, 'Наказаний нет.', True) 235 | 236 | @commands.command(aliases=['ar']) 237 | @commands.check(messages.check_perms) 238 | @commands.cooldown(1, 3, commands.BucketType.guild) 239 | async def antiraid(self, ctx, joins: int = None, interval = None): 240 | measures.add(what=10) 241 | if joins is not None and interval is not None: 242 | t = word.string_to_seconds(interval) 243 | if joins < 0: 244 | await messages.err(ctx, "Минимальное значение заходов – **1**.") 245 | elif t < 0: 246 | await messages.err(ctx, "Минимальное Длительность для заходов – **1 секунда**.") 247 | else: 248 | if joins == 0 and t == 0: 249 | turn = 0 250 | else: 251 | turn = 1 252 | cache.antiraid.add(ctx.guild.id, {"joins": joins, "interval": t, "turn": turn}) 253 | embed = discord.Embed(color = Color.success, title = "✅ | Готово") 254 | if turn == 0: 255 | embed.description = 'Защита от рейдов была выключена.' 256 | else: 257 | embed.description = f'Теперь на сервер можно зайти максимум {joins} {word.word_correct(joins, "раз", "раза", "раз")} за {word.hms(float(t))}.\nЕсли вы хотите отключить защиту от рейдов, напишите `{ctx.prefix}antiraid 0 0`.' 258 | await ctx.send(embed = embed) 259 | else: 260 | try: 261 | ar = cache.antiraid_data[ctx.guild.id] 262 | turn = ar['turn'] 263 | j = ar['joins'] 264 | i = ar['interval'] 265 | except: 266 | turn, j, i = 0, 0, 0 267 | 268 | embed = discord.Embed(title = "✋ | Защита от рейдов", color = Color.primary) 269 | if turn == 0: 270 | embed.description = "Защита выключена." 271 | else: 272 | embed.description = f'На сервер можно зайти максимум {j} {word.word_correct(j, "раз", "раза", "раз")} за {word.hms(float(i))}.\nЕсли вы хотите отключить защиту от рейдов, напишите `{ctx.prefix}antiraid 0 0`.' 273 | await ctx.send(embed = embed) 274 | 275 | @commands.group() 276 | @commands.cooldown(1, 5, commands.BucketType.guild) 277 | async def perms(self, ctx): 278 | if not messages.is_admin(ctx.author): 279 | return await messages.only_admin(ctx) 280 | if ctx.invoked_subcommand is None: 281 | await ctx.send(f"Чтобы узнать больше о команде, напишите `{ctx.prefix}help perms`.") 282 | 283 | @perms.command() 284 | async def ar(self, ctx, cmd, *, r): 285 | if cmd != "*": 286 | cmd = messages.get_command(self.bot, cmd) 287 | if not cmd: 288 | return await messages.err(ctx, "Команда не найдена.") 289 | try: 290 | alr = cache.perms_data[ctx.guild.id][cmd]["roles"]["allowed"] 291 | except: alr = [] 292 | 293 | try: 294 | der = cache.perms_data[ctx.guild.id][cmd]["roles"]["denied"] 295 | except: der = [] 296 | 297 | try: 298 | cc = cache.perms_data[ctx.guild.id][cmd]["channels"] 299 | except: cc = {} 300 | 301 | r = r.strip("<@&>").replace(">", "").replace("<", "").replace("@", "").replace("&", "") 302 | if not r.lower() in ["нет", "no", "none"]: 303 | for i in r.split(): 304 | if ctx.guild.get_role(int(i)): 305 | if int(i) in der: 306 | der.pop(der.index(int(i))) 307 | if not int(i) in alr: 308 | alr.append(int(i)) 309 | result = '\n'.join([ctx.guild.get_role(int(a)).mention for a in r.strip("<@&>").replace(">", "").replace("<", "").replace("@", "").replace("&", "").split() if ctx.guild.get_role(int(a))]) 310 | else: 311 | alr = [] 312 | 313 | cache.perms.add(ctx.guild.id, {cmd: {"roles": {"allowed": alr, "denied": der}, "channels": cc}}) 314 | embed = discord.Embed(title="✅ | Готово", color=Color.success) 315 | if cmd == "*": 316 | if r.lower() in ["нет", "no", "none"]: 317 | embed.description = "Вы убрали все разрешённые роли для всех команд" 318 | else: 319 | embed.description = f"Вы указали следующие разрешённые роли для всех команд: \n>>> {result}" 320 | else: 321 | if r.lower() in ["нет", "no", "none"]: 322 | embed.description = f"Вы убрали все разрешённые роли для команды `{ctx.prefix}{cmd}`." 323 | else: 324 | embed.description = f"Вы указали следующие разрешённые роли для команды `{ctx.prefix}{cmd}`: \n>>> {result}" 325 | await ctx.send(embed=embed) 326 | 327 | @perms.command() 328 | async def dr(self, ctx, cmd, *, r): 329 | if cmd != "*": 330 | cmd = messages.get_command(self.bot, cmd) 331 | if not cmd: 332 | return await messages.err(ctx, "Команда не найдена.") 333 | try: 334 | alr = cache.perms_data[ctx.guild.id][cmd]["roles"]["allowed"] 335 | except: alr = [] 336 | 337 | try: 338 | der = cache.perms_data[ctx.guild.id][cmd]["roles"]["denied"] 339 | except: der = [] 340 | 341 | try: 342 | cc = cache.perms_data[ctx.guild.id][cmd]["channels"] 343 | except: cc = {} 344 | 345 | r = r.strip("<@&>").replace(">", "").replace("<", "").replace("@", "").replace("&", "") 346 | if not r.lower() in ["нет", "no", "none"]: 347 | for i in r.split(): 348 | if ctx.guild.get_role(int(i)): 349 | if int(i) in alr: 350 | alr.pop(alr.index(int(i))) 351 | if not int(i) in der: 352 | der.append(int(i)) 353 | result = '\n'.join([ctx.guild.get_role(int(a)).mention for a in r.strip("<@&>").replace(">", "").replace("<", "").replace("@", "").replace("&", "").split() if ctx.guild.get_role(int(a))]) 354 | else: 355 | der = [] 356 | 357 | cache.perms.add(ctx.guild.id, {cmd: {"roles": {"allowed": alr, "denied": der}, "channels": cc}}) 358 | embed = discord.Embed(title="✅ | Готово", color=Color.success) 359 | if cmd == "*": 360 | if r.lower() in ["нет", "no", "none"]: 361 | embed.description = "Вы убрали все запрещённые роли для всех команд" 362 | else: 363 | embed.description = f"Вы указали следующие запрещённые роли для всех команд: \n>>> {result}" 364 | else: 365 | if r.lower() in ["нет", "no", "none"]: 366 | embed.description = f"Вы убрали все запрещённые роли для команды `{ctx.prefix}{cmd}`." 367 | else: 368 | embed.description = f"Вы указали следующие запрещённые роли для команды `{ctx.prefix}{cmd}`: \n>>> {result}" 369 | await ctx.send(embed=embed) 370 | 371 | @perms.command() 372 | async def ac(self, ctx, cmd, *, r): 373 | if cmd != "*": 374 | cmd = messages.get_command(self.bot, cmd) 375 | if not cmd: 376 | return await messages.err(ctx, "Команда не найдена.") 377 | try: 378 | alr = cache.perms_data[ctx.guild.id][cmd]["channels"]["allowed"] 379 | except: alr = [] 380 | 381 | try: 382 | der = cache.perms_data[ctx.guild.id][cmd]["channels"]["denied"] 383 | except: der = [] 384 | 385 | try: 386 | cc = cache.perms_data[ctx.guild.id][cmd]["roles"] 387 | except: cc = {} 388 | 389 | r = r.strip("<@#>").replace(">", "").replace("<", "").replace("@", "").replace("#", "") 390 | if not r.lower() in ["нет", "no", "none"]: 391 | for i in r.split(): 392 | if ctx.guild.get_channel(int(i)): 393 | if int(i) in der: 394 | der.pop(der.index(int(i))) 395 | if not int(i) in alr: 396 | alr.append(int(i)) 397 | result = '\n'.join([ctx.guild.get_channel(int(a)).mention for a in r.strip("<@#>").replace(">", "").replace("<", "").replace("@", "").replace("#", "").split() if ctx.guild.get_channel(int(a))]) 398 | else: 399 | alr = [] 400 | 401 | cache.perms.add(ctx.guild.id, {cmd: {"channels": {"allowed": alr, "denied": der}, "roles": cc}}) 402 | embed = discord.Embed(title="✅ | Готово", color=Color.success) 403 | if cmd == "*": 404 | if r.lower() in ["нет", "no", "none"]: 405 | embed.description = "Вы убрали все разрешённые каналы для всех команд" 406 | else: 407 | embed.description = f"Вы указали следующие разрешённые каналы для всех команд: \n>>> {result}" 408 | else: 409 | if r.lower() in ["нет", "no", "none"]: 410 | embed.description = f"Вы убрали все разрешённые каналы для команды `{ctx.prefix}{cmd}`." 411 | else: 412 | embed.description = f"Вы указали следующие разрешённые каналы для команды `{ctx.prefix}{cmd}`: \n>>> {result}" 413 | await ctx.send(embed=embed) 414 | 415 | @perms.command() 416 | async def dc(self, ctx, cmd, *, r): 417 | if cmd != "*": 418 | cmd = messages.get_command(self.bot, cmd) 419 | if not cmd: 420 | return await messages.err(ctx, "Команда не найдена.") 421 | try: 422 | alr = cache.perms_data[ctx.guild.id][cmd]["channels"]["allowed"] 423 | except: alr = [] 424 | 425 | try: 426 | der = cache.perms_data[ctx.guild.id][cmd]["channels"]["denied"] 427 | except: der = [] 428 | 429 | try: 430 | cc = cache.perms_data[ctx.guild.id][cmd]["roles"] 431 | except: cc = {} 432 | 433 | r = r.strip("<@#>").replace(">", "").replace("<", "").replace("@", "").replace("#", "") 434 | if not r.lower() in ["нет", "no", "none"]: 435 | for i in r.split(): 436 | if ctx.guild.get_channel(int(i)): 437 | if int(i) in alr: 438 | alr.pop(alr.index(int(i))) 439 | if not int(i) in der: 440 | der.append(int(i)) 441 | result = '\n'.join([ctx.guild.get_channel(int(a)).mention for a in r.strip("<@#>").replace(">", "").replace("<", "").replace("@", "").replace("#", "").split() if ctx.guild.get_channel(int(a))]) 442 | else: 443 | der = [] 444 | 445 | cache.perms.add(ctx.guild.id, {cmd: {"channels": {"allowed": alr, "denied": der}, "roles": cc}}) 446 | embed = discord.Embed(title="✅ | Готово", color=Color.success) 447 | if cmd == "*": 448 | if r.lower() in ["нет", "no", "none"]: 449 | embed.description = "Вы убрали все запрещённые каналы для всех команд" 450 | else: 451 | embed.description = f"Вы указали следующие запрещённые каналы для всех команд: \n>>> {result}" 452 | else: 453 | if r.lower() in ["нет", "no", "none"]: 454 | embed.description = f"Вы убрали все запрещённые каналы для команды `{ctx.prefix}{cmd}`." 455 | else: 456 | embed.description = f"Вы указали следующие запрещённые каналы для команды `{ctx.prefix}{cmd}`: \n>>> {result}" 457 | await ctx.send(embed=embed) 458 | 459 | @perms.command() 460 | async def show(self, ctx, cmd): 461 | if cmd != "*": 462 | cmd = messages.get_command(self.bot, cmd) 463 | if not cmd: 464 | return await messages.err(ctx, "Команда не найдена.") 465 | try: 466 | alr = cache.perms_data[ctx.guild.id][cmd]["roles"]["allowed"] 467 | except: alr = [] 468 | 469 | try: 470 | der = cache.perms_data[ctx.guild.id][cmd]["roles"]["denied"] 471 | except: der = [] 472 | 473 | try: 474 | alc = cache.perms_data[ctx.guild.id][cmd]["channels"]["allowed"] 475 | except: alc = [] 476 | 477 | try: 478 | dlc = cache.perms_data[ctx.guild.id][cmd]["channels"]["denied"] 479 | except: dlc = [] 480 | 481 | alr = [a for a in alr if ctx.guild.get_role(a)] 482 | der = [a for a in der if ctx.guild.get_role(a)] 483 | 484 | alc = [a for a in alc if ctx.guild.get_channel(a)] 485 | dlc = [a for a in dlc if ctx.guild.get_channel(a)] 486 | 487 | embed = discord.Embed(color=Color.primary) 488 | if cmd != "*": embed.title = f"👮‍♂️ | Права для команды `{ctx.prefix}{cmd}`" 489 | else: embed.title = "👮‍♂️ | Права для всех команд" 490 | if alr == [] and der == [] and alc == [] and dlc == []: 491 | embed.description = "Всё по умолчанию, никто не ограничивал эту команду." 492 | else: 493 | if len(alr) == 0: alr = "Отсутствуют" 494 | else: alr = '\n'.join([ctx.guild.get_role(a).mention for a in alr]) 495 | 496 | if len(der) == 0: der = "Отсутствуют" 497 | else: der = '\n'.join([ctx.guild.get_role(a).mention for a in der]) 498 | 499 | if len(alc) == 0: alc = "Отсутствуют" 500 | else: alc = '\n'.join([ctx.guild.get_channel(a).mention for a in alc]) 501 | 502 | if len(dlc) == 0: dlc = "Отсутствуют" 503 | else: dlc = '\n'.join([ctx.guild.get_channel(a).mention for a in dlc]) 504 | 505 | embed.add_field(inline=False, name="Разрешённые роли", value=f">>> {alr}") 506 | embed.add_field(inline=False, name="Запрещённые роли", value=f">>> {der}") 507 | embed.add_field(inline=False, name="Разрешённые каналы", value=f">>> {alc}") 508 | embed.add_field(inline=False, name="Запрещённые каналы", value=f">>> {dlc}") 509 | 510 | await ctx.send(embed=embed) 511 | 512 | @commands.command(aliases=['ndm', 'notify-dm']) 513 | @commands.check(messages.check_perms) 514 | @commands.cooldown(1, 10, commands.BucketType.guild) 515 | async def notify_dm(self, ctx, option=None): 516 | if option: 517 | option = option.lower() 518 | 519 | try: 520 | curopt = cache.configs_data[ctx.guild.id]["notify-dm"] 521 | except KeyError: 522 | curopt = False 523 | 524 | embed = discord.Embed(title="📣 | Оповещения о наказаниях в личку", color=Color.primary) 525 | if not option: 526 | embed.description = f"Я {messages.rebool(curopt, 'оповещаю', 'не оповещаю')} о наказаниях." 527 | return await ctx.send(embed=embed) 528 | 529 | if option == "on": 530 | cache.configs.add(ctx.guild.id, {"notify-dm": True}) 531 | embed.title = "✅ | Готово" 532 | embed.color = Color.success 533 | embed.description = "Теперь я буду оповещать о наказаниях в личку." 534 | return await ctx.send(embed=embed) 535 | if option == "off": 536 | cache.configs.add(ctx.guild.id, {"notify-dm": False}) 537 | embed.title = "✅ | Готово" 538 | embed.color = Color.success 539 | embed.description = "Теперь я не буду оповещать о наказаниях в личку." 540 | return await ctx.send(embed=embed) 541 | return await messages.err(ctx, "Опция не найдена!") 542 | 543 | @commands.command() 544 | @commands.check(messages.check_perms) 545 | @commands.cooldown(1, 5, commands.BucketType.guild) 546 | async def score(self, ctx, option=None, amount: int=None): 547 | if not option: 548 | sc = messages.default_scores 549 | 550 | if ctx.guild.id in cache.antinuke_data: 551 | for i in list(messages.default_scores): 552 | if i in cache.antinuke_data[ctx.guild.id]: 553 | sc[i] = cache.antinuke_data[ctx.guild.id][i] 554 | 555 | try: max = cache.configs_data[ctx.guild.id]["maxscore"] 556 | except: max = 20 557 | 558 | embed = discord.Embed(title="🎚️ | Баллы за краш") 559 | embed.description = f"Используйте команду `{ctx.prefix}help score`, чтобы получить справку о команде." 560 | embed.color = Color.primary 561 | 562 | embed.add_field(inline=False, name="Текущие значения (баллы)", value=f""" 563 | **Удаление каналов:** {sc['channel_delete']} 564 | **Удаление ролей:** {sc['role_delete']} 565 | **Создание каналов:** {sc['channel_create']} 566 | **Создание ролей:** {sc['role_create']} 567 | **Бан участников:** {sc['ban']} 568 | **Кик участников:** {sc['kick']} 569 | **Изменение сервера:** {sc['guild_update']} 570 | 571 | **Максимум:** {max} 572 | """) 573 | return await ctx.send(embed=embed) 574 | elif option.lower() == "help": 575 | embed = discord.Embed(title="❔ | Справка по фильтрам") 576 | embed.description = """ 577 | `channel_create` – создание каналов 578 | `channel_delete` – удаление каналов 579 | `role_create` – создание ролей 580 | `role_delete` – удаление ролей 581 | `ban` – бан 582 | `kick` - кик 583 | `guild_update` - изменение сервера 584 | `max` – максимум (при превышении этого значения включается анти-краш) 585 | """ 586 | embed.color = Color.primary 587 | return await ctx.send(embed=embed) 588 | 589 | if not amount: 590 | return await messages.err(ctx, "Вам следует указать значение.") 591 | if option.lower() == "max": 592 | if amount < 10: 593 | return await messages.err(ctx, "Значение не должно быть меньше 10.") 594 | if amount > 200: 595 | return await messages.err(ctx, "Значение не должно быть больше 200.") 596 | cache.configs.add(ctx.guild.id, {"maxscore": amount}) 597 | embed = discord.Embed() 598 | embed.title = "✅ | Готово" 599 | embed.color = Color.success 600 | embed.description = f"Теперь анти-краш включается при превышении порога в **{amount} {word.word_correct(amount, 'балл', 'балла', 'баллов')}**." 601 | return await ctx.send(embed=embed) 602 | elif option.lower().replace("-", "_") in list(messages.default_scores): 603 | if amount < 0: 604 | return await messages.err(ctx, "Значение не должно быть меньше 0.") 605 | if amount > 50: 606 | return await messages.err(ctx, "Значение не должно быть больше 50.") 607 | cache.antinuke.add(ctx.guild.id, {option.lower().replace("-", "_"): amount}) 608 | embed = discord.Embed() 609 | embed.title = "✅ | Готово" 610 | embed.color = Color.success 611 | embed.description = f"Теперь за это действие даётся **{amount} {word.word_correct(amount, 'балл', 'балла', 'баллов')}**." 612 | return await ctx.send(embed=embed) 613 | else: 614 | return await messages.err(ctx, "Фильтр не найден. Стоит попробовать ещё раз?") 615 | 616 | def setup(bot): 617 | bot.add_cog(Settings(bot)) 618 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | class Color: 4 | primary = 0x3EE2B7 5 | transparent = 0x2F3136 6 | blurple_old = 0x7289DA 7 | blurple = 0x5865F2 8 | danger = 0xE92323 9 | warning = 0xE9B623 10 | success = 0x44E923 11 | 12 | class Auth: 13 | discord_auth = { 14 | "debug": os.getenv("discord_token"), #discord bot debug token 15 | "release": os.getenv("discord_token") #you can enter token from debug 16 | } 17 | mongo_auth = { 18 | "url": os.getenv("mongo_cluster_url"), #mongo db url like "cluster1.free.mongodb.com" 19 | "username": os.getenv("mongodb_username"), #mongo db username. exmaple "ArtemBay" 20 | "auth":{ 21 | "debug": os.getenv("mongodb_password"), #mongo db password. looks like random symbols 22 | "release": os.getenv("mongodb_password") #same password with debug 23 | } 24 | } 25 | qiwi_auth = os.getenv("qiwi_2p2_token") #https://qiwi.com/p2p-admin/transfers/api 26 | 27 | class Other: 28 | shard_count = 1 29 | slash = None #dont enable this PLS 30 | premium_cost = 99 #in rub 31 | invoice_lifetime = 360 # in minutes 32 | p2p = None #dont touch this 33 | uptime = 0 34 | -------------------------------------------------------------------------------- /fonts/Rubik-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TerminalPR0/hiprotect/73fbc7a1b21f41453ae44a56c8345913d5d15d83/fonts/Rubik-Light.ttf -------------------------------------------------------------------------------- /helper.py: -------------------------------------------------------------------------------- 1 | import cache 2 | 3 | async def is_owner(ctx): 4 | if not ctx.author.id in [356737308898099201, 685837803413962806]: 5 | await ctx.send("This command is only available to bot owners!") 6 | return False 7 | return True 8 | 9 | def get_bonus_data(user_id, nostr=False): 10 | d = { 11 | "balance": 0.0, 12 | "pay-period": 0, 13 | "guilds": [], 14 | } 15 | if not nostr: 16 | d["strbal"] = "0.00" 17 | if not user_id in cache.bonus_data: 18 | return d 19 | 20 | data = cache.bonus_data[user_id] 21 | print(cache.bonus_data) 22 | 23 | if "balance" in data: 24 | d["balance"] = data["balance"] 25 | if "pay-period" in data: 26 | d["pay-period"] = data["pay-period"] 27 | if "guilds" in data: 28 | d["guilds"] = data["guilds"] 29 | if not nostr: 30 | d["strbal"] = "{:.2f}".format(d["balance"]) 31 | 32 | return d -------------------------------------------------------------------------------- /json/commandinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "addroles":{ 3 | "description": "Выдать роль всем участникам сервера", 4 | "args": ["<Роль, которую нужно выдать>"], 5 | "examples": ["addroles @Участник"] 6 | }, 7 | "help":{ 8 | "description": "Выведет информацию о всех командна или о одной определённой", 9 | "args": ["[Команда]"], 10 | "examples": ["help", "help antiraid"] 11 | }, 12 | "exec":{ 13 | "description": "Вам это точно не понадобится. Мы вас уверяем.", 14 | "args": [], 15 | "examples": [] 16 | }, 17 | "info":{ 18 | "description": "Посмотреть информацию о боте", 19 | "args": [], 20 | "examples": ["info"] 21 | }, 22 | "ping":{ 23 | "description": "Посмотреть задержку бота", 24 | "args": [], 25 | "examples": ["ping"] 26 | }, 27 | "server":{ 28 | "description": "Посмотреть информацию о сервере", 29 | "args": [], 30 | "examples": ["server"] 31 | }, 32 | "invite":{ 33 | "description": "Посмотреть ссылки на приглашение бота и прочие ресурсы", 34 | "args": [], 35 | "examples": ["invite"] 36 | }, 37 | "user":{ 38 | "description": "Посмотреть информацию об указанном пользователе. Если он не указан, отобразится информация о вас", 39 | "args": ["[Пользователь]"], 40 | "examples": ["user", "user @Example#9999"] 41 | }, 42 | "ban":{ 43 | "description": "Изгнать участника с сервера и заблокировать его (забанить)", 44 | "args": ["<Пользователь>", "[Длительность]", "[Причина]"], 45 | "examples": ["ban @Example#9999", "ban @Example#9999 Рейдер", "ban @Example#9999 1h30m Оскорбинка", "ban @Example#9999 1d"] 46 | }, 47 | "bans":{ 48 | "description": "Посмотреть список забаненных пользователей", 49 | "args": [], 50 | "examples": ["bans"] 51 | }, 52 | "correct":{ 53 | "description": "Исправить никнеймы указанным пользователям", 54 | "args": ["<Участник1 Участник2 ...>"], 55 | "examples": ["correct @Example#9999", "correct @Example#9999 @Example#0001 @Example#1337"] 56 | }, 57 | "correct_all":{ 58 | "description": "Исправить никнеймы всем участникам сервера", 59 | "args": [], 60 | "examples": ["correct-all"] 61 | }, 62 | "kick":{ 63 | "description": "Выгнать участника с сервера с возможностью перезахода", 64 | "args": ["<Участник>", "[Причина]"], 65 | "examples": ["kick @Example#9999", "kick @Example#9999 Неадекват"] 66 | }, 67 | "lock_bot":{ 68 | "description": "Забрать все права у бота", 69 | "args": ["<Бот>", "[Длительность]", "[Причина]"], 70 | "examples": ["lock-bot @Bot#1234", "lock-bot @Bot#1234 2h", "lock-bot @Bot#1234 Тест", "lock-bot @Bot#1234 1h30m Мешает работе"] 71 | }, 72 | "mute":{ 73 | "description": "Запретить определённому участнику сервера что-либо писать в чат и разговаривать (замьютить)", 74 | "args": ["<Участник>", "[Длительность]", "[Причина]"], 75 | "examples": ["mute @Example#9999", "mute @Example#9999 Флуд", "mute @Example#9999 1h30m Флуд", "mute @Example#9999 1d"] 76 | }, 77 | "mutes":{ 78 | "description": "Посмотреть список замьюченных пользователей", 79 | "args": [], 80 | "examples": ["mutes"] 81 | }, 82 | "purge":{ 83 | "description": "Очистить определённое количество сообщений в текущем канале (100 по умолчанию). Максимум – 1000", 84 | "args": ["[Пользователь]", "[Количество сообщений]"], 85 | "examples": ["purge", "purge 50", "purge @Example#9999", "purge @Example#9999 500"] 86 | }, 87 | "quarantine":{ 88 | "description": "Управление карантином", 89 | "args": ["add <Участник> [Длительность] [Причина]", "remove <Участник>", "users", "user ", "role <Роль>"], 90 | "examples": ["quarantine add @Example#1234 6h Попытка краша сервера", "quarantine remove @Example#1234", "quarantine users", "quarantine user 752367350657056851", "quarantine role @Карантин"] 91 | }, 92 | "remroles":{ 93 | "description": "Забрать роль у всех участников сервера", 94 | "args": ["<Роль, которую нужно забрать>"], 95 | "examples": ["remroles @Админка"] 96 | }, 97 | "unban":{ 98 | "description": "Разбанить пользователя", 99 | "args": ["<Пользователь>"], 100 | "examples": ["unban @Example#9999"] 101 | }, 102 | "unlock_bot":{ 103 | "description": "Разблокировать бота", 104 | "args": ["<Бот>"], 105 | "examples": ["unlock_bot @Bot#1234"] 106 | }, 107 | "unmute":{ 108 | "description": "Размьютить участника (снова разрешить ему говорить)", 109 | "args": ["<Участник>"], 110 | "examples": ["unmute @Example#9999"] 111 | }, 112 | "unwarn":{ 113 | "description": "Снять предупреждения у участника", 114 | "args": ["<Участник>", "[Количество предупреждений для снятия]"], 115 | "examples": ["unwarn @Example#9999", "unwarn @Example#9999 2"] 116 | }, 117 | "warn":{ 118 | "description": "Выдать предупреждение участнику", 119 | "args": ["<Участник>", "[Причина]"], 120 | "examples": ["warn @Example#9999", "warn @Example#9999 Оскорбления"] 121 | }, 122 | "warns":{ 123 | "description": "Посмотреть свои или чужие предупреждения", 124 | "args": ["[Участник]"], 125 | "examples": ["warns", "warns @Example#9999"] 126 | }, 127 | "echo":{ 128 | "description": "Сказать что-нибудь от лица бота", 129 | "args": ["<Сообщение>"], 130 | "examples": ["echo Завтра будет раздача печенек!"] 131 | }, 132 | "lock":{ 133 | "description": "Запретить всем отправлять сообщения в указанном или текущем канале", 134 | "args": ["[Канал]"], 135 | "examples": ["lock", "lock #правила-сервера"] 136 | }, 137 | "mass_ban":{ 138 | "description": "Забанить сразу несколько пользователей (максимум 50 за раз)", 139 | "args": ["<Пользователь1> <Пользователь2> ...", "[Длительность]", "[Причина]"], 140 | "examples": ["massban @Example#8888 @Example#9999 @Example#0001", "massban @Example#8888 @Example#9999 @Example#0001 1h", "massban @Example#8888 @Example#9999 @Example#0001 Краш сервера", "massban @Example#8888 @Example#9999 @Example#0001 2h50m Дурачки"] 141 | }, 142 | "unlock":{ 143 | "description": "Разрешить всем отправлять сообщения в указанном или текущем канале", 144 | "args": ["[Канал]"], 145 | "examples": ["unlock", "unlock #чатик"] 146 | }, 147 | "8ball":{ 148 | "description": "Задать вопрос магическому шару", 149 | "args": ["<Вопрос>"], 150 | "examples": ["8ball Мы сможем добить 5000 серверов к концу года?"] 151 | }, 152 | "alertcrash":{ 153 | "description": "Снять всех администраторов и модераторов со своих должностей", 154 | "args": [], 155 | "examples": ["alertcrash"] 156 | }, 157 | "delspamchannels":{ 158 | "description": "Удалить каналы с одинаковым названием", 159 | "args": ["<Канал> ИЛИ <Название канала>"], 160 | "examples": ["delspamchannels #crash-by-bot", "delspamchannels Admin Loh"] 161 | }, 162 | "delspamroles":{ 163 | "description": "Удалить роли с одинаковым названием", 164 | "args": ["<Роль> ИЛИ <Название роли>"], 165 | "examples": ["delspamroles @Crash", "delspamroles Admin Loh"] 166 | }, 167 | "antiraid":{ 168 | "description": "Ограничить количество заходов на сервер за определённый промежуток времени", 169 | "args": ["<Максимальное количество заходов>", "<Промежуток времени>"], 170 | "examples": ["antiraid 5 15s"] 171 | }, 172 | "antiflood":{ 173 | "description": "Настройка анти-флуда (напишите команду без параметров для настройки)", 174 | "args": [], 175 | "examples": [] 176 | }, 177 | "antiinvite":{ 178 | "description": "Настройка анти-приглашений (напишите команду без параметров для настройки)", 179 | "args": [], 180 | "examples": [] 181 | }, 182 | "muterole":{ 183 | "description": "Указать роль, которая будет выдаваться при мьюте. Отсутствие параметра покажет текущую роль мьюта", 184 | "args": ["[Роль]"], 185 | "examples": ["muterole", "muterole @Замьючен"] 186 | }, 187 | "nickcorrector":{ 188 | "description": "Включить или выключить исправитель никнеймов. Отсутствие параметра покажет текущее состояние", 189 | "args": ["[on ИЛИ off]"], 190 | "examples": ["nickcorrector", "nickcorrector on", "nickcorrector off"] 191 | }, 192 | "addsingle":{ 193 | "description": "Интуитивно понятное добавление роли за реакции", 194 | "args": [], 195 | "examples": ["addsingle"] 196 | }, 197 | "delsingle":{ 198 | "description": "Интуитивно понятное удаление роли за реакции", 199 | "args": [], 200 | "examples": ["delsingle"] 201 | }, 202 | "perms":{ 203 | "description": "Ограничить бота по каналам и ролям. Для обозначения всех команд следует указать `*`", 204 | "args": ["ar <Название команды> <РазрешённаяРоль1 РазрешённаяРоль2 ...>", "dr <Название команды> <ЗапрещённаяРоль1 ЗапрещённаяРоль2 ...>", "ac <Название команды> <РазрешённыйКанал1 РазрешённыйКанал2 ...>", "dc <Название команды> <ЗапрещённыйКанал1 ЗапрещённыйКанал2 ...>", "show <Название команды>"], 205 | "examples": ["perms ar backup @Бэкапы @Админ", "perms dr 8ball @Не веселимся", "perms ac * #команды-ботов", "perms dc user #общение", "perms show kick"] 206 | }, 207 | "prefix":{ 208 | "description": "Установка нового префикса для бота", 209 | "args": ["<Новый префикс ИЛИ сброс>"], 210 | "examples": ["prefix !", "prefix reset", "prefix сброс"] 211 | }, 212 | "role_protect":{ 213 | "description": "Включить или выключить защиту общедоступных ролей от изменения прав. Отсутствие параметра покажет текущее состояние", 214 | "args": ["[on ИЛИ off]"], 215 | "examples": ["role-protect", "role-protect on", "role-protect off"] 216 | }, 217 | "np":{ 218 | "description": "Установить наказание за краш сервера для бота или пользователя", 219 | "args": ["", "<Наказание>", "[Длительность]"], 220 | "examples": ["np bot lock 5h", "np user ban 5d12h", "np user ban 1mo"] 221 | }, 222 | "nuker":{ 223 | "description": "Установить наказание за приглашение краш-бота", 224 | "args": ["", "[Длительность]"], 225 | "examples": ["nuker kick", "nuker ban", "nuker ban 1y"] 226 | }, 227 | "warn_actions":{ 228 | "description": "Установить наказания за предупреждения", 229 | "args": ["set <Количество предпр-й> <Наказание> [Длительность]", "reset"], 230 | "examples": ["warn-actions set 2 mute 10m", "warn-actions set 6 ban", "warn-actions reset"] 231 | }, 232 | "wl":{ 233 | "description": "Игнорировать пользователя или бота на указанные действия", 234 | "args": ["add <Пользователь>", "remove <Пользователь>", "list"], 235 | "examples": ["wl add @Example#9999", "wl remove @Bot#1234", "wl list"] 236 | }, 237 | "avatar":{ 238 | "description": "Посмотреть свой или чужой аватар", 239 | "args": ["[Пользователь]"], 240 | "examples": ["avatar", "avatar @Example#9999"] 241 | }, 242 | "backup":{ 243 | "description": "Управление резервными копиями сервера", 244 | "args": ["create", "load", "protect"], 245 | "examples": ["backup create", "backup load", "backup protect"] 246 | }, 247 | "discrim":{ 248 | "description": "Поиск участников на сервере с указанными четырьмя цифрами после никнейма (с вашим, если не указано)", 249 | "args": ["[Дискриминатор]"], 250 | "examples": ["discrim", "discrim #0001", "discrim 1234"] 251 | }, 252 | "reset_all":{ 253 | "description": "Безвозвратно сбросить ВСЕ настройки бота", 254 | "args": [], 255 | "examples": ["reset-all"] 256 | }, 257 | "notify_dm":{ 258 | "description": "Включить или выключить оповещения о наказаниях в личку", 259 | "args": ["[on ИЛИ off]"], 260 | "examples": ["notify-dm", "notify-dm on", "notify-dm off"] 261 | }, 262 | "score":{ 263 | "description": "Настроить баллы за действия, подразумевающие краш или засорение сервера.", 264 | "args": ["[название, см. score help]", "max (баллы для включения анти-краша)"], 265 | "examples": ["score", "score channel_delete 6", "score ban 4", "score max 20", "score help"] 266 | } 267 | } -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import time 2 | import datetime 3 | def time4logs(): 4 | return f'[{datetime.datetime.now().strftime("%d.%m.%Y %H:%M:%S")}]' 5 | print(time4logs(), 'Начало запуска бота') 6 | start = time.time() 7 | import discord 8 | from discord.ext import commands, tasks #del tasks after ver 9 | import os 10 | import pymongo 11 | from dislash import slash_commands 12 | from dislash.interactions import * 13 | import io 14 | import contextlib 15 | import textwrap 16 | from traceback import format_exception 17 | from dislash.slash_commands import * 18 | import asyncio 19 | import subprocess 20 | from discord.utils import get 21 | from config import * 22 | from pytz import timezone as tz #del after ver 23 | import word 24 | import cache 25 | from memory_profiler import memory_usage 26 | from profilactic import measures 27 | import requests 28 | import json 29 | from messages import send_graph 30 | import oauth 31 | from pyqiwip2p import QiwiP2P 32 | print(time4logs(), 'Библиотеки импортированы') 33 | 34 | mongo = pymongo.MongoClient("mongodb+srv://{}:{}@{}/tests?retryWrites=true&w=majority".format(Auth.mongo_auth['username'], Auth.mongo_auth['auth']['debug'], Auth.mongo_auth['url'])) 35 | print(time4logs(), 'MongoDB подключена') 36 | 37 | release = oauth.release 38 | if release: 39 | token = Auth.discord_auth["release"] 40 | else: 41 | token = Auth.discord_auth["debug"] 42 | db = mongo.cp 43 | default_prefixes = ['Hi.', 'hI.', 'hi.', 'HI.'] 44 | 45 | begin = time.time() 46 | 47 | async def determine_prefix(bot, message): 48 | guild = message.guild 49 | if guild: 50 | try: 51 | return cache.configs_data[guild.id]["prefix"] 52 | except: 53 | return default_prefixes 54 | 55 | class Botik(commands.Bot): 56 | def __init__(self, *args, **kwargs): 57 | super().__init__(*args, **kwargs) 58 | self.remove_command(help) 59 | 60 | intents = discord.Intents.default() 61 | intents.members = True 62 | intents.guilds = True 63 | intents.messages = True 64 | bot = Botik(command_prefix = determine_prefix, intents = intents) 65 | bot.remove_command('help') 66 | slash = SlashClient(bot) 67 | p2p = QiwiP2P(Auth.qiwi_auth) 68 | Other.slash = slash 69 | Other.p2p = p2p 70 | 71 | 72 | for file in os.listdir('./cogs'): 73 | if file.endswith('.py') and not file in ["config.py", "mongo.py", "messages.py"]: 74 | bot.load_extension(f'cogs.{file[:-3]}') 75 | print(time4logs(), 'Кога', file[:-3], 'загружена') 76 | 77 | print(time4logs(), 'Подключение шардов') 78 | 79 | @bot.event 80 | async def on_ready(): 81 | print(f'{time4logs()} Бот загружен за {word.hms2(time.time() - start)}') 82 | await bot.change_presence(status = discord.Status.idle, activity = discord.Game("на тех работах")) #https://private-cp.tk | Серверов: {word.unit(len(bot.guilds))} 83 | 84 | @bot.event 85 | async def on_shard_connect(shard_id): 86 | print(f'{time4logs()} Шард {shard_id} готов к работе ;)') 87 | if Other.shard_count <= 2: 88 | Other.uptime = int(time.time()) 89 | else: 90 | if int(shard_id) == len(bot.shards) - 1: 91 | Other.uptime = int(time.time()) 92 | ''' 93 | @bot.event 94 | async def on_socket_raw_receive(msg): 95 | print('<<', msg) 96 | 97 | @bot.event 98 | async def on_socket_raw_send(payload): 99 | print('>>', payload) 100 | ''' 101 | @bot.event 102 | async def on_guild_join(guild): 103 | def first(guild): 104 | for i in guild.text_channels: 105 | if i.permissions_for(guild.me).send_messages and i.permissions_for(guild.me).read_messages and i.permissions_for(guild.me).embed_links: 106 | return i 107 | if not guild.owner.id in cache.bl_data: 108 | async for entry in guild.audit_logs(limit = 1, action = discord.AuditLogAction.bot_add): 109 | embed = discord.Embed() 110 | embed.color = Color.primary 111 | embed.title = "👋 | Привет!" 112 | embed.description = "Спасибо, что добавил меня сюда, ведь теперь этот сервер под защитой.\n" 113 | try: prefix = cache.configs_data[guild.id]['prefix'] 114 | except: prefix = "hi." 115 | embed.description += f"Мой префикс – `{prefix}`. Для получения списка команд введи `{prefix}help`." 116 | embed.add_field(inline=False, name="Пожалуйста, сделай следующие действия:", value=""" 117 | `1.` Передвинь мою роль как можно выше, чтобы наказывать нарушителей; 118 | `2.` Убедись, что у меня есть права администратора для работы. 119 | """) 120 | row = ActionRow( 121 | Button( 122 | style=ButtonStyle.link, 123 | label="Поддержка", 124 | emoji="❔", 125 | url="https://discord.gg/9PwC49p8Cp" 126 | )#, 127 | #Button( 128 | #style=ButtonStyle.link, 129 | #label="Документация", 130 | #emoji="📚", 131 | #url="https://docs.crashprotect.ru" 132 | #) 133 | ) 134 | await first(guild).send(embed=embed, components=[row]) 135 | if bot.user.id == bot.user.id: 136 | lb = discord.Embed(title="🤖 | Бот был добавлен на сервер") 137 | lb.color = Color.success 138 | lb.description = f''' 139 | **Название сервера:** {guild.name} 140 | **Владелец:** {guild.owner} 141 | **Количество участников:** {guild.member_count} 142 | **Кто добавил:** {entry.user} 143 | **ID:** {guild.id} 144 | ''' 145 | lb.set_thumbnail(url=guild.icon_url) 146 | await bot.get_channel(973591928010588261).send(embed=lb) #change channel id 147 | else: 148 | embed = discord.Embed(color = Color.danger) 149 | embed.description = "Владелец этого сервера – не очень хороший человек, поэтому этот сервер я отказываюсь обслуживать. Поддержка также не будет осуществляться." 150 | embed.add_field(name="Причина", value=cache.bl_data[guild.owner.id]["reason"]) 151 | embed.set_footer(text="Ну что встал-то? Иди лавана ставь.") 152 | for g in bot.guilds: 153 | if g.owner.id == guild.owner.id: 154 | try: 155 | await first(g).send(embed=embed) 156 | await g.leave() 157 | if bot.user.id == bot.user.id: 158 | lb = discord.Embed(title="😡 | Сервер в черном списке!") 159 | lb.color = Color.danger 160 | lb.description = f''' 161 | **Название сервера:** {g.name} 162 | **Владелец:** {g.owner} 163 | **Количество участников:** {g.member_count} 164 | **ID:** {g.id} 165 | ''' 166 | lb.set_thumbnail(url=guild.icon_url) 167 | await bot.get_channel(973591928010588261).send(embed=lb)#change channel id 168 | except: pass 169 | 170 | @bot.event 171 | async def on_guild_remove(guild): 172 | if bot.user.id == bot.user.id: 173 | lb = discord.Embed(title="😢 | К сожалению, этому серверу бот не понравился") 174 | lb.color = Color.danger 175 | lb.description = f''' 176 | **Название сервера:** {guild.name} 177 | **Владелец:** {guild.owner} 178 | **Количество участников:** {guild.member_count} 179 | **ID:** {guild.id} 180 | ''' 181 | lb.set_thumbnail(url=guild.icon_url) 182 | await bot.get_channel(973591928010588261).send(embed=lb)#change channel id 183 | 184 | async def checkbans(): 185 | while True: 186 | for dictionary in cache.bans_data: 187 | try: 188 | guild = bot.get_guild(dictionary) 189 | for member in cache.bans_data[dictionary]: 190 | if cache.bans_data[dictionary][member] <= int(time.time()): 191 | user = bot.get_user(int(member)) 192 | await guild.unban(user) 193 | #del cache.bans_data[dictionary][member] 194 | cache.bans.delete(dictionary, {member: True}) 195 | except: 196 | pass 197 | await asyncio.sleep(60) 198 | 199 | async def checkmutes(): 200 | while True: 201 | for dictionary in cache.mutes_data: 202 | try: 203 | guild = bot.get_guild(dictionary) 204 | if 'muterole' in cache.configs_data[dictionary]: 205 | muterole = guild.get_role(cache.configs_data[dictionary]['muterole']) 206 | for member in cache.mutes_data[dictionary]: 207 | if cache.mutes_data[dictionary][member] <= int(time.time()): 208 | user = guild.get_member(int(member)) 209 | if user is not None: 210 | await user.remove_roles(muterole) 211 | cache.mutes.delete(dictionary, {member: True}) 212 | except: 213 | pass 214 | await asyncio.sleep(60) 215 | 216 | async def checklocks(): 217 | while True: 218 | for dictionary in cache.locks_data: 219 | try: 220 | guild = bot.get_guild(dictionary) 221 | for member in cache.locks_data[dictionary]: 222 | if cache.locks_data[dictionary][member]['locked'] <= int(time.time()): 223 | user = guild.get_member(int(member)) 224 | for role in cache.locks_data[dictionary][member]['roles']: 225 | try: 226 | await user.add_roles(guild.get_role(int(role))) 227 | except: 228 | pass 229 | mngd = [r for r in user.roles if r.managed] 230 | await mngd[0].edit(permissions=discord.Permissions(permissions=cache.locks_data[dictionary][member]['managed']['perms'])) 231 | cache.locks.delete(dictionary, {member: True}) 232 | except: 233 | pass 234 | await asyncio.sleep(60) 235 | 236 | async def unquarantine(): 237 | while True: 238 | for dictionary in cache.quarantine_data: 239 | try: 240 | guild = bot.get_guild(dictionary) 241 | for member in cache.quarantine_data[dictionary]: 242 | if member.isdigit(): 243 | if cache.quarantine_data[dictionary][member]['end'] <= int(time.time()): 244 | cache.quarantine.delete(guild.id, {member: True}) 245 | try: role = guild.get_role(cache.quarantine_data[guild.id]['role']) 246 | except: role = None 247 | if guild.get_member(int(member)) and role: 248 | await guild.get_member(int(member)).remove_roles(role) 249 | except: 250 | pass 251 | await asyncio.sleep(60) 252 | 253 | @bot.command() 254 | async def ram(ctx): 255 | if ctx.author.id in [356737308898099201, 685837803413962806]: 256 | emb = discord.Embed() 257 | emb.color = 0xffffff 258 | emb.title = "💿 | Оперативная память" 259 | emb.description = f"Использовано памяти: **{round(memory_usage()[0], 2)} Мб**." 260 | await ctx.send(embed = emb) 261 | 262 | async def print_ram(): 263 | while True: 264 | print(f"Использовано памяти: {round(memory_usage()[0], 2)} Мб.") 265 | await asyncio.sleep(30) 266 | 267 | 268 | guilds, ts = [], [] 269 | 270 | def clean_code(content): 271 | if content.startswith("```") and content.endswith("```"): 272 | return "\n".join(content.split("\n")[1:])[:-3] 273 | else: 274 | return content 275 | 276 | @bot.command(name="exec", aliases = ["eval", "e"]) 277 | async def _eval(ctx, *, code): 278 | await ctx.message.delete() 279 | if ctx.author.id in []: 280 | pending_embed = discord.Embed(title = 'Добрый день!', description = 'Код выполняется, подождите...', color = discord.Colour.from_rgb(255, 255, 0)) 281 | message = await ctx.send(embed = pending_embed) 282 | success_embed = discord.Embed(title = 'Выполнение кода - успех', color = discord.Colour.from_rgb(0, 255, 0)) 283 | code = clean_code(code) 284 | local_variables = { 285 | "discord": discord, 286 | "cache": cache, 287 | "db": db, 288 | "commands": commands, 289 | "client": bot, 290 | "bot": bot, 291 | "ctx": ctx, 292 | "channel": ctx.channel, 293 | "author": ctx.author, 294 | "guild": ctx.guild, 295 | "message": ctx.message 296 | } 297 | stdout = io.StringIO() 298 | try: 299 | with contextlib.redirect_stdout(stdout): 300 | exec( 301 | f"async def func():\n{textwrap.indent(code, ' ')}", local_variables, 302 | ) 303 | obj = await local_variables["func"]() 304 | result = stdout.getvalue() 305 | success_embed.add_field(name = 'Выполненный код:', value = f'```py\n{code}\n```', inline = False) 306 | what_returned = None 307 | if obj != None: 308 | if isinstance(obj, int) == True: 309 | if obj == True: 310 | what_returned = 'Логическое значение' 311 | elif obj == False: 312 | what_returned = 'Логическое значение' 313 | else: 314 | what_returned = 'Целое число' 315 | elif isinstance(obj, str) == True: 316 | what_returned = 'Строка' 317 | elif isinstance(obj, float) == True: 318 | what_returned = 'Дробное число' 319 | elif isinstance(obj, list) == True: 320 | what_returned = 'Список' 321 | elif isinstance(obj, tuple) == True: 322 | what_returned = 'Неизменяемый список' 323 | elif isinstance(obj, set) == True: 324 | what_returned = 'Уникальный список' 325 | else: 326 | what_returned = 'Неизвестный тип данных...' 327 | success_embed.add_field(name = 'Тип данных:', value = f'```\n{what_returned}\n```', inline = False) 328 | success_embed.add_field(name = 'Вернулось:', value = f'```\n{obj}\n```', inline = False) 329 | else: 330 | pass 331 | if result: 332 | success_embed.add_field(name = 'Результат выполнения:', value = f'```py\nКонсоль:\n\n{result}\n```', inline = False) 333 | else: 334 | pass 335 | await message.edit(embed = success_embed) 336 | except Exception as e: 337 | result = "".join(format_exception(e, e, e.__traceback__)) 338 | fail_embed = discord.Embed(title = 'Выполнение кода - провал', color = discord.Colour.from_rgb(255, 0, 0)) 339 | fail_embed.add_field(name = 'Выполненный код:', value = f'```py\n{code}\n```', inline = False) 340 | fail_embed.add_field(name = 'Ошибка:', value = f'```py\n{e}\n```', inline = False) 341 | await message.edit(embed = fail_embed, delete_after = 15) 342 | else: 343 | fail_embed = discord.Embed(title = 'Выполнение кода - провал', color = discord.Colour.from_rgb(255, 0, 0)) 344 | fail_embed.add_field(name = 'Выполненный код:', value = f'```py\nкод скрыт из-за соображений безопасности.\n```', inline = False) 345 | fail_embed.add_field(name = 'Ошибка:', value = f'```\nВы не имеете право запускать данную команду.\n```', inline = False) 346 | await ctx.send(embed = fail_embed, delete_after = 5) 347 | 348 | @bot.event 349 | async def on_command_completion(ctx): 350 | try: cc = cache.botstats_data[bot.user.id]["commands_completed"] 351 | except KeyError: cc = 0 352 | cache.botstats.add(bot.user.id, {"commands_completed": cc + 1}) 353 | 354 | @bot.command() 355 | async def servers(ctx): 356 | global ts, guilds 357 | if 0.06 in ts: ts.pop(ts.index(0.06)) 358 | if 0.06 in guilds: guilds.pop(guilds.index(0.06)) 359 | await send_graph(ctx, ts[8:], guilds[8:], "Рост серверов", ylabel="Количество", xfields=True, yfields=True) 360 | 361 | bot.loop.create_task(checkbans()) 362 | bot.loop.create_task(checklocks()) 363 | bot.loop.create_task(print_ram()) 364 | bot.loop.create_task(checkmutes()) 365 | bot.loop.create_task(unquarantine()) 366 | 367 | 368 | async def check_bills(): 369 | while True: 370 | invoices = cache.invoices_data 371 | for invoice in invoices: 372 | try: 373 | try: 374 | message = await bot.get_channel(invoices[invoice]['message'][0]).fetch_message(invoices[invoice]['message'][1]) 375 | except: 376 | message = None 377 | if not invoices[invoice]['paid']: 378 | if str(p2p.check(str(invoices[invoice]['bill_id'])).status) == "PAID": 379 | cache.premium.add(invoice, {'active': True}) 380 | cache.invoices.add(invoice, {'paid': True}) 381 | embed = discord.Embed() 382 | embed.title = "✅ | Счёт оплачен" 383 | embed.description = "Счёт был успешно оплачен. Приятного пользования :)" 384 | embed.color = Color.success 385 | if message: 386 | await message.edit(embed=embed, components=[]) 387 | elif int(time.time()) > invoices[invoice]['expires'] and not invoices[invoice]['paid']: 388 | embed = discord.Embed() 389 | embed.title = "⌛ | Счёт просрочен" 390 | embed.description = "Вы слишком долго не оплачивали счёт, поэтому он просрочился. Если вы хотите, то можете снова выставить счёт." 391 | embed.color = Color.danger 392 | if message: 393 | await message.edit(embed=embed, components=[]) 394 | except: 395 | pass 396 | await asyncio.sleep(.2) 397 | await asyncio.sleep(40) 398 | 399 | 400 | bot.loop.create_task(check_bills()) 401 | bot.run(token) 402 | -------------------------------------------------------------------------------- /messages.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.ext import commands 3 | from config import Color 4 | import datetime 5 | import pytz 6 | import matplotlib.pyplot as plt 7 | import os 8 | import matplotlib.font_manager as font_manager 9 | import random 10 | import cache 11 | import punishments 12 | 13 | async def send_graph( 14 | ctx, x, y, title="Простой график, ничего необычного", label_color="white", background_color="#181818", line_color="#7e57c2", xlabel="Время", ylabel="Величина", xfields=None, yfields=None 15 | ): 16 | fe = font_manager.FontEntry( 17 | fname='/home/container/fonts/Rubik-Light.ttf', 18 | name='Rubik') 19 | font_manager.fontManager.ttflist.insert(0, fe) 20 | plt.rcParams['text.color'] = label_color 21 | plt.rcParams['axes.labelcolor'] = label_color 22 | plt.rcParams['xtick.color'] = label_color 23 | plt.rcParams['ytick.color'] = label_color 24 | plt.rcParams['font.family'] = fe.name 25 | plt.rcParams['font.size'] = 12 26 | fig, ax1 = plt.subplots(1, 1) 27 | ax1.set_facecolor(background_color) 28 | fig.patch.set_facecolor(background_color) 29 | plt.xlabel(xlabel) 30 | plt.ylabel(ylabel) 31 | ax1.plot(x, y, color=line_color) 32 | fig.canvas.draw() 33 | labels = [item.get_text() for item in ax1.get_xticklabels()] 34 | ax1.set_title(title) 35 | if xfields: 36 | labels = [datetime.datetime.fromtimestamp(i, pytz.timezone("Europe/Moscow")).strftime('%H:%M') for i in x] 37 | ax1.set_xticklabels(labels) 38 | labels = [item.get_text() for item in ax1.get_yticklabels()] 39 | if yfields: 40 | labels = [int(float(i)) for i in labels] 41 | ax1.set_yticklabels(labels) 42 | code = ''.join(random.choices("abcdef0123456789", k = 6)) 43 | plt.savefig(f"/home/container/{code}.png") 44 | await ctx.send(file=discord.File(f"{code}.png")) 45 | os.remove(f"/home/container/{code}.png") 46 | 47 | async def err(ctx, message, reset_cooldown=False): 48 | embed = discord.Embed( 49 | title = "❌ | Упс, ошибка", 50 | description = message, 51 | color = Color.danger 52 | ) 53 | embed.set_footer(icon_url=ctx.author.avatar_url, text=ctx.author) 54 | await ctx.send(embed=embed) 55 | if reset_cooldown: 56 | ctx.command.reset_cooldown(ctx) 57 | 58 | async def only_owner(ctx): 59 | embed = discord.Embed( 60 | title = "✋ | Недостаточно прав", 61 | description = 'Данную команду может использовать только владелец сервера. Если вы являетесь таковым, просто подождите несколько минут и заново введите её.', 62 | color = Color.danger 63 | ) 64 | embed.set_footer(icon_url=ctx.author.avatar_url, text=ctx.author) 65 | await ctx.send(embed=embed) 66 | 67 | async def only_admin(ctx): 68 | embed = discord.Embed( 69 | title = "✋ | Недостаточно прав", 70 | description = 'Данную команду могут использовать только высшие администраторы (роль которых выше большинства других ролей).', 71 | color = Color.danger 72 | ) 73 | embed.set_footer(icon_url=ctx.author.avatar_url, text=ctx.author) 74 | await ctx.send(embed=embed) 75 | 76 | '''def reaction_check(reaction, user): 77 | return reaction.message.id == msg.id and user == ctx.author 78 | 79 | def message_check(author): 80 | def inner_check(message): 81 | if message.author != author: 82 | return False 83 | try: 84 | message.content 85 | return True 86 | except ValueError: 87 | return False 88 | return inner_check''' 89 | 90 | def is_admin(member): 91 | roles = [r for r in member.guild.roles if not r.managed] 92 | if member == member.guild.owner: return True 93 | if member.top_role.position > len(roles) - 5 and member.guild_permissions.administrator: return True 94 | return False 95 | 96 | async def send_logs(self, guild, embed): 97 | if not guild.id in cache.configs_data: return 98 | if not "log-channel" in cache.configs_data[guild.id]: return 99 | channel = self.bot.get_channel(cache.configs_data[guild.id]['log-channel']) 100 | if not channel: return 101 | await channel.send(embed=embed) 102 | 103 | async def nukep(self, member, reason): 104 | if member.bot: a = 'pu-bot' 105 | else: a = 'pu-user' 106 | 107 | try: 108 | data = cache.configs_data[member.guild.id][a] 109 | except: 110 | if member.bot: 111 | data = {"type": "kick", "duration": 0} 112 | else: 113 | data = {"type": "ban", "duration": 0} 114 | if data['duration'] == 0: data['duration'] = 228133722 115 | 116 | if data['type'] == 'ban': 117 | await member.ban(reason=reason) 118 | await punishments.tempban(member, member, data['duration'], ignore_ndm=True) 119 | elif data['type'] == 'kick': 120 | await member.kick(reason=reason) 121 | elif data['type'] == 'lock': 122 | await punishments.lockbot(member, member, data['duration']) 123 | elif data['type'] == 'quarantine': 124 | await punishments.add_qua(member.guild, self.bot.user, member, data['duration'], reason) 125 | 126 | def get_command(bot, name: str): 127 | name = name.lower() 128 | c = {} 129 | for i in bot.commands: 130 | c[i.name] = i.aliases 131 | for n, a in c.items(): 132 | if name == n or name in a: 133 | return n 134 | 135 | class HasNoRoles(commands.CheckFailure): 136 | pass 137 | 138 | class HasDeniedRoles(commands.CheckFailure): 139 | pass 140 | 141 | class NotAllowedChannel(commands.CheckFailure): 142 | pass 143 | 144 | class DeniedChannel(commands.CheckFailure): 145 | pass 146 | 147 | class NoPerms(commands.CheckFailure): 148 | pass 149 | 150 | async def check_perms(ctx): 151 | 152 | default_perms = { 153 | "addroles": [ctx.author.guild_permissions.administrator, "Администратор"], 154 | "ban": [ctx.author.guild_permissions.ban_members, "Банить участников"], 155 | "bans": [ctx.author.guild_permissions.ban_members, "Банить участников"], 156 | "correct": [ctx.author.guild_permissions.manage_nicknames, "Управлять никнеймами"], 157 | "correct_all": [ctx.author.guild_permissions.manage_nicknames, "Управлять никнеймами"], 158 | "kick": [ctx.author.guild_permissions.kick_members, "Выгонять участников"], 159 | "lock_bot": [ctx.author.guild_permissions.administrator, "Администратор"], 160 | "mute": [ctx.author.guild_permissions.manage_roles, "Управлять ролями"], 161 | "mutes": [ctx.author.guild_permissions.manage_roles, "Управлять ролями"], 162 | "purge": [ctx.author.guild_permissions.manage_messages, "Управлять сообщениями"], 163 | "quarantine": [ctx.author.guild_permissions.administrator, "Администратор"], 164 | "remroles": [ctx.author.guild_permissions.administrator, "Администратор"], 165 | "unban": [ctx.author.guild_permissions.ban_members, "Банить участников"], 166 | "unlock_bot": [ctx.author.guild_permissions.administrator, "Администратор"], 167 | "unmute": [ctx.author.guild_permissions.manage_roles, "Управлять ролями"], 168 | "unwarn": [ctx.author.guild_permissions.kick_members, "Выгонять участников"], 169 | "warn": [ctx.author.guild_permissions.kick_members, "Выгонять участников"], 170 | "echo": [ctx.author.guild_permissions.administrator, "Администратор"], 171 | "lock": [ctx.author.guild_permissions.administrator, "Администратор"], 172 | "mass_ban": [ctx.author.guild_permissions.administrator, "Администратор"], 173 | "unlock": [ctx.author.guild_permissions.administrator, "Администратор"], 174 | "antiraid": [ctx.author.guild_permissions.administrator, "Администратор"], 175 | "antiflood": [ctx.author.guild_permissions.administrator, "Администратор"], 176 | "antiinvite": [ctx.author.guild_permissions.administrator, "Администратор"], 177 | "muterole": [ctx.author.guild_permissions.manage_roles, "Управлять ролями"], 178 | "nickcorrector": [ctx.author.guild_permissions.manage_nicknames, "Управлять никнеймами"], 179 | "prefix": [ctx.author.guild_permissions.administrator, "Администратор"], 180 | "np": [ctx.author.guild_permissions.administrator, "Администратор"], 181 | "warn_actions": [ctx.author.guild_permissions.administrator, "Администратор"], 182 | "addsingle": [ctx.author.guild_permissions.manage_roles, "Управлять ролями"], 183 | "delsingle": [ctx.author.guild_permissions.manage_roles, "Управлять ролями"], 184 | "rr_list": [ctx.author.guild_permissions.manage_roles, "Управлять ролями"], 185 | "backup": [ctx.author.guild_permissions.administrator, "Администратор"], 186 | "notify_dm": [ctx.author.guild_permissions.administrator, "Администратор"], 187 | "log_channel": [ctx.author.guild_permissions.administrator, "Администратор"], 188 | "wl": [is_admin(ctx.author), "Высший администратор"], 189 | "score": [is_admin(ctx.author), "Высший администратор"], 190 | "perms": [is_admin(ctx.author), "Высший администратор"] 191 | } 192 | 193 | aa = ctx.command.name 194 | 195 | if ctx.guild.id in cache.perms_data: 196 | if "*" in cache.perms_data[ctx.guild.id]: 197 | aa = "*" 198 | 199 | aroles, droles = [], [] 200 | achannels, dchannels = [], [] 201 | try: aroles = cache.perms_data[ctx.guild.id][aa]["roles"]["allowed"] 202 | except: aroles = [] 203 | try: droles = cache.perms_data[ctx.guild.id][aa]["roles"]["denied"] 204 | except: droles = [] 205 | 206 | try: achannels = cache.perms_data[ctx.guild.id][aa]["channels"]["allowed"] 207 | except: achannels = [] 208 | try: dchannels = cache.perms_data[ctx.guild.id][aa]["channels"]["denied"] 209 | except: dchannels = [] 210 | 211 | 212 | aroles = [a for a in aroles if ctx.guild.get_role(a)] 213 | droles = [a for a in droles if ctx.guild.get_role(a)] 214 | 215 | achannels = [a for a in achannels if ctx.guild.get_channel(a)] 216 | dchannels = [a for a in dchannels if ctx.guild.get_channel(a)] 217 | 218 | if not len(achannels) and not len(dchannels) and not len(aroles) and not len(droles): 219 | if ctx.command.name in default_perms: 220 | if not default_perms[ctx.command.name][0]: 221 | raise NoPerms(default_perms[ctx.command.name][1]) 222 | 223 | if len(aroles) or len(droles): 224 | found = False 225 | for r in ctx.author.roles: 226 | if r.id in droles: 227 | raise HasDeniedRoles(r.mention) 228 | if r.id in aroles: found = True 229 | if not found: 230 | raise HasNoRoles('\n'.join([ctx.guild.get_role(a).mention for a in aroles])) 231 | 232 | if (len(dchannels) or len(achannels)) and not (len(aroles) and len(droles)): 233 | if ctx.command.name in default_perms: 234 | if not default_perms[ctx.command.name][0]: 235 | raise NoPerms(default_perms[ctx.command.name][1]) 236 | 237 | if len(achannels) or len(dchannels): 238 | if ctx.channel.id in dchannels: 239 | raise DeniedChannel(ctx.channel.mention) 240 | if not ctx.channel.id in achannels: 241 | if achannels != []: 242 | raise NotAllowedChannel('\n'.join([ctx.guild.get_channel(a).mention for a in achannels])) 243 | 244 | return True 245 | 246 | def rebool(bool: bool, true_return, false_return=None): 247 | if bool: return true_return 248 | return false_return 249 | 250 | default_scores = { 251 | "channel_delete": 6, 252 | "channel_create": 3, 253 | "role_delete": 5, 254 | "role_create": 2, 255 | "ban": 5, 256 | "kick": 4, 257 | "guild_update": 6, 258 | 259 | } 260 | 261 | def generate_progressbar(amount): 262 | amount = int(amount * 100) 263 | bar = "<:progress_begin_unfill:910102173780705310>" 264 | if amount >= 10: 265 | bar = "<:progress_begin_fill:910102173747138601>" 266 | bar += "<:progress_middle_fill:910102173625516083>" * (amount//10) 267 | bar += "<:progress_middle_unfill:910102173839409193>" * (9-(amount//10)) 268 | if amount >= 100: 269 | bar += "<:progress_end_fill:910102173805854751>" 270 | else: 271 | bar += "<:progress_end_unfill:910102173881335818>" 272 | return bar 273 | 274 | def has_premium(guild_id): 275 | return guild_id in cache.premium_data -------------------------------------------------------------------------------- /mongo.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | from config import Auth 3 | 4 | mongo = pymongo.MongoClient("mongodb+srv://{}:{}@{}/tests?retryWrites=true&w=majority".format(Auth.mongo_auth['username'], Auth.mongo_auth['auth']['debug'], Auth.mongo_auth['url'])) 5 | db = mongo.cp_new 6 | 7 | def set(collection, id, data): 8 | i = {"_id":id} 9 | if db[collection].count_documents({"_id":id}) == 0: 10 | db[collection].insert_one({**i, **data}) 11 | else: 12 | db[collection].update_one(i, {"$set":data}) -------------------------------------------------------------------------------- /oauth.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | release = True 4 | 5 | if not release: 6 | client_id = 755645853590356099 7 | client_secret = "igqAYbPcGlQqkiMG3RW3hS5ciR9nCTNR" 8 | redirect_uri = "http://127.0.0.1/auth" 9 | else: 10 | client_id = 752367350657056851 11 | client_secret = " " 12 | redirect_uri = " " 13 | 14 | 15 | def gat(code): 16 | global client_id, client_secret, redirect_uri 17 | 18 | data = { 19 | "client_id": str(client_id), 20 | "client_secret": client_secret, 21 | "grant_type": "authorization_code", 22 | "code": code, 23 | "redirect_uri": redirect_uri, 24 | "scope": "identify%20email%20guilds" 25 | } 26 | 27 | at = requests.post(url="https://discord.com/api/oauth2/token", data=data).json() 28 | return at.get("access_token") 29 | 30 | def get_user_json(access_token): 31 | url = "https://discord.com/api/users/@me" 32 | headers = {"Authorization": f"Bearer {access_token}"} 33 | 34 | user_obj = requests.get(url, headers=headers).json() 35 | return user_obj 36 | 37 | def get_guilds(access_token): 38 | url = "https://discord.com/api/guilds/@me" 39 | headers = {"Authorization": f"Bearer {access_token}"} 40 | 41 | user_obj = requests.get(url, headers=headers).json() 42 | return user_obj -------------------------------------------------------------------------------- /profilactic.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | class meass: 4 | def __init__(self): 5 | self.links = 0 6 | self.backups = 0 7 | self.add_bot = 0 8 | self.antiraid = 0 9 | self.nickcorr = 0 10 | self.rr = 0 11 | self.anticrash = 0 12 | self.automod = 0 13 | self.invite = 0 14 | self.bot_invite = 0 15 | self.settings = 0 16 | self.begin = time.time() 17 | 18 | def add(self, what): 19 | define = { 20 | 0: self.links, 21 | 1: self.backups, 22 | 2: self.add_bot, 23 | 3: self.antiraid, 24 | 4: self.nickcorr, 25 | 5: self.rr, 26 | 6: self.anticrash, 27 | 7: self.automod, 28 | 8: self.invite, 29 | 9: self.bot_invite, 30 | 10: self.settings 31 | } 32 | define[what] += 1 33 | #print(what, define[what]) 34 | 35 | def begin_time(self): 36 | return int(time.time() - self.begin) 37 | 38 | measures = meass() -------------------------------------------------------------------------------- /punishments.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.ext import commands 3 | from config import Color 4 | import messages 5 | import word 6 | import cache 7 | import mongo 8 | import time 9 | import datetime 10 | from word import ago 11 | from profilactic import measures 12 | 13 | def ndm(ctx): 14 | try: 15 | curopt = cache.configs_data[ctx.guild.id]["notify-dm"] 16 | except KeyError: 17 | curopt = False 18 | return curopt 19 | 20 | async def tempban(ctx, user, tc, reason="Не указана", ignore_ndm=False): 21 | if ndm(ctx): 22 | if not ignore_ndm: 23 | embed = discord.Embed(color=Color.danger) 24 | embed.title = f"🔨 | Вы были забанены на сервере **{ctx.guild.name}**" 25 | embed.description = f""" 26 | **Причина:** {reason}""" 27 | if tc != 228133722: 28 | embed.description += f""" 29 | **Длительность:** {word.hms(tc)} 30 | **Дата разбана:** """ 31 | embed.set_thumbnail(url=ctx.guild.icon_url) 32 | try: 33 | await user.send(embed=embed) 34 | except: 35 | pass 36 | cache.bans.add(ctx.guild.id, {str(user.id): int(time.time()) + tc}) 37 | 38 | async def tempmute(ctx, user, tc, reason="Не указана", ignore_ndm=False): 39 | try: 40 | role = ctx.guild.get_role(cache.configs_data[ctx.guild.id]['muterole']) 41 | except: 42 | role = await ctx.guild.create_role(name = "HI-MUTED", permissions = discord.Permissions.none(), colour = discord.Colour(0x675D7D)) 43 | cache.configs.add(ctx.guild.id, {"muterole": role.id}) 44 | cache.mutes.add(ctx.guild.id, {str(user.id): int(time.time()) + tc}) 45 | await user.add_roles(role) 46 | if ndm(ctx): 47 | if not ignore_ndm: 48 | embed = discord.Embed(color=Color.warning) 49 | embed.title = f"🔇 | Вы были замьючены на сервере **{ctx.guild.name}**" 50 | embed.description = f""" 51 | **Причина:** {reason}""" 52 | if tc != 228133722: 53 | embed.description += f""" 54 | **Длительность:** {word.hms(tc)} 55 | **Дата размьюта:** """ 56 | embed.set_thumbnail(url=ctx.guild.icon_url) 57 | try: 58 | await user.send(embed=embed) 59 | except: 60 | pass 61 | for channel in ctx.guild.text_channels: 62 | await channel.set_permissions(role, send_messages = False, add_reactions = False) 63 | for channel in ctx.guild.voice_channels: 64 | await channel.set_permissions(role, speak = False) 65 | 66 | async def unmute(ctx, user): 67 | measures.add(what=7) 68 | if ctx.guild.id in cache.configs_data: 69 | cache.mutes.delete(ctx.guild.id, {str(user.id): True}) 70 | if "muterole" in cache.configs_data[ctx.guild.id]: 71 | role = ctx.guild.get_role(cache.configs_data[ctx.guild.id]['muterole']) 72 | if role is not None: 73 | await user.remove_roles(role) 74 | 75 | async def lockbot(ctx, user, tc): 76 | measures.add(what=7) 77 | managed_role = [r for r in user.roles if r.managed][0] 78 | other_roles = [r.id for r in user.roles if not r.managed] 79 | cache.locks.add(ctx.guild.id, {str(user.id):{"locked": int(time.time()) + tc, "roles": other_roles, "managed": {"id": managed_role.id, "perms": managed_role.permissions.value}}}) 80 | for role in [r for r in user.roles if not r.managed]: 81 | try: 82 | await user.remove_roles(role) 83 | except: 84 | pass 85 | await managed_role.edit(permissions=discord.Permissions.none()) 86 | 87 | async def unlockbot(ctx, user): 88 | measures.add(what=7) 89 | managed_role = [r for r in user.roles if r.managed][0] 90 | if ctx.guild.id in cache.locks_data: 91 | managed_perms_value = cache.locks_data[ctx.guild.id][str(user.id)]['managed']['perms'] 92 | managed_perms = discord.Permissions(permissions=managed_perms_value) 93 | role_ids = cache.locks_data[ctx.guild.id][str(user.id)]['roles'] 94 | for role in role_ids: 95 | try: 96 | r = ctx.guild.get_role(role) 97 | await user.add_roles(r) 98 | except: 99 | pass 100 | await managed_role.edit(permissions=managed_perms) 101 | cache.locks.delete(ctx.guild.id, {str(user.id): True}) 102 | 103 | async def checkwarns(ctx, user): 104 | measures.add(what=7) 105 | ptype, duration = 'none', 0 106 | if ctx.guild.id in cache.warns_data: 107 | warns = cache.warns_data[ctx.guild.id] 108 | uwarns = warns['members'][str(user.id)] 109 | if 'actions' in warns: 110 | actions = warns['actions'] 111 | if str(uwarns) in actions: 112 | if actions[str(uwarns)]['duration'] == 0: 113 | duration = 228133722 114 | else: 115 | duration = actions[str(uwarns)]['duration'] 116 | ptype = duration = actions[str(uwarns)]['punishment'] 117 | embed = discord.Embed() 118 | if ptype == 'mute': 119 | await tempmute(ctx, user, duration) 120 | embed.color = Color.primary 121 | if duration == 228133722: 122 | embed.title = '🔇 | Мьют' 123 | embed.description = f''' 124 | **Пользователь:** {user} ({user.mention}) 125 | **Модератор:** HiProtect#2121 (<@356737308898099201>) 126 | **Причина:** Накоплено **{uwarns}** {word.word_correct(uwarns, 'предупреждение', "предупреждения", "предупреждений")} 127 | ''' 128 | else: 129 | embed.title = '🔇 | Временный мьют' 130 | embed.description = f''' 131 | **Пользователь:** {user} ({user.mention}) 132 | **Модератор:** HiProtect#2121 (<@356737308898099201>) 133 | **Время:** {word.hms(float(duration))} 134 | **Причина:** Накоплено **{uwarns}** {word.word_correct(uwarns, 'предупреждение', "предупреждения", "предупреждений")} 135 | ''' 136 | await ctx.send(embed=embed) 137 | elif ptype == 'ban': 138 | await tempban(ctx, user, duration) 139 | embed.color = Color.danger 140 | if duration == 228133722: 141 | embed.title = '🔨 | Бан' 142 | embed.description = f''' 143 | **Пользователь:** {user} ({user.mention}) 144 | **Модератор:** HiProtect#2121 (<@356737308898099201>) 145 | **Причина:** Накоплено **{uwarns}** {word.word_correct(uwarns, 'предупреждение', "предупреждения", "предупреждений")} 146 | ''' 147 | await user.ban(reason = f"Накоплено **{uwarns}** {word.word_correct(uwarns, 'предупреждение', 'предупреждения', 'предупреждений')}") 148 | else: 149 | embed.title = '🔨 | Временный бан' 150 | embed.description = f''' 151 | **Пользователь:** {user} ({user.mention}) 152 | **Модератор:** HiProtect#2121 (<@356737308898099201>) 153 | **Время:** {word.hms(float(duration))} 154 | **Причина:** Накоплено **{uwarns}** {word.word_correct(uwarns, 'предупреждение', "предупреждения", "предупреждений")} 155 | ''' 156 | await user.ban(reason = f"Накоплено **{uwarns}** {word.word_correct(uwarns, 'предупреждение', 'предупреждения', 'предупреждений')} | {word.hms(float(duration))}") 157 | await ctx.send(embed=embed) 158 | elif ptype == 'kick': 159 | await user.kick(reason = f"Накоплено **{uwarns}** {word.word_correct(uwarns, 'предупреждение', 'предупреждения', 'предупреждений')}") 160 | embed.title = '👢 | Кик' 161 | embed.color = Color.primary 162 | embed.description = f''' 163 | **Пользователь:** {user} ({user.mention}) 164 | **Модератор:** HiProtect#2121 (<@356737308898099201>) 165 | **Причина:** Накоплено **{uwarns}** {word.word_correct(uwarns, 'предупреждение', "предупреждения", "предупреждений")} 166 | ''' 167 | await ctx.send(embed=embed) 168 | 169 | async def warn(ctx, user, amount = 1, reason="Не указана", ignore_ndm=False): 170 | measures.add(what=7) 171 | if not ctx.guild.id in cache.warns_data: 172 | cache.warns.add(ctx.guild.id, {'case':1, 'members':{}, 'actions':{}}) 173 | try: 174 | warns = cache.warns_data[ctx.guild.id] 175 | except: 176 | warns = {'case':1, 'members':{}, 'actions':{}} 177 | if not str(user.id) in warns['members']: 178 | warns['members'][str(user.id)] = amount 179 | else: 180 | warns['members'][str(user.id)] += amount 181 | warns['case'] += 1 182 | cache.warns.add(ctx.guild.id, warns) 183 | if ndm(ctx): 184 | if not ignore_ndm: 185 | embed = discord.Embed(color=Color.warning) 186 | embed.title = f"⚠ | Вы получили предупреждение на сервере **{ctx.guild.name}**" 187 | embed.description = f""" 188 | **Причина:** {reason}""" 189 | embed.set_thumbnail(url=ctx.guild.icon_url) 190 | try: 191 | await user.send(embed=embed) 192 | except: 193 | pass 194 | await checkwarns(ctx, user) 195 | return warns['case'], warns['members'][str(user.id)] 196 | 197 | async def unwarn(ctx, user, amount = 1): 198 | measures.add(what=7) 199 | mongo_id = {"_id": ctx.guild.id} 200 | if ctx.guild.id in cache.warns_data: 201 | warns = cache.warns_data[ctx.guild.id] 202 | if str(user.id) in warns['members']: 203 | if warns['members'][str(user.id)] < amount: 204 | amount = warns['members'][str(user.id)] 205 | warns['members'][str(user.id)] -= amount 206 | cache.warns.add(ctx.guild.id, warns) 207 | return amount 208 | else: 209 | return False 210 | else: 211 | return False 212 | 213 | async def add_qua(guild, author, user, tc, reason): 214 | try: role = guild.get_role(cache.quarantine_data[guild.id]['role']) 215 | except: role = None 216 | 217 | if tc == 0: tc = 228133722 218 | 219 | if guild.get_member(user.id): 220 | user = guild.get_member(user.id) 221 | for r in user.roles: 222 | try: 223 | await user.remove_roles(r) 224 | except: 225 | pass 226 | if user.bot: 227 | await lockbot(user, user, tc) 228 | if role: await user.add_roles(role) 229 | 230 | dictionary = { 231 | "begin": int(time.time()), 232 | "orderly": author.id, 233 | "end": int(time.time()) + tc, 234 | "reason": reason 235 | } 236 | 237 | cache.quarantine.add(guild.id, {str(user.id): dictionary}) 238 | 239 | async def rem_qua(guild, id): 240 | cache.quarantine.delete(guild.id, {str(id): True}) 241 | try: role = guild.get_role(cache.quarantine_data[guild.id]['role']) 242 | except: role = None 243 | if guild.get_member(id) and role: 244 | await guild.get_member(id).remove_roles(role) 245 | if guild.get_member(id).bot: 246 | await unlockbot(guild.get_member(id), guild.get_member(id)) 247 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | discord.py 2 | requests 3 | dislash.py 4 | pymongo 5 | dnspython 6 | pillow 7 | typing 8 | memory_profiler 9 | matplotlib 10 | pytz 11 | pyqiwip2p 12 | pycbrf -------------------------------------------------------------------------------- /snus.txt: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /word.py: -------------------------------------------------------------------------------- 1 | import string, datetime 2 | 3 | import pytz 4 | 5 | def string_to_seconds(string): 6 | total_seconds, number_string = 0, '' 7 | string = string.lower().strip('-').replace('мес', 'е').replace('mo', 'o') 8 | multi = 1 9 | units = { 10 | "s": 1, 11 | "с": 1, 12 | "m": 60, 13 | "м": 60, 14 | "h": 3600, 15 | "ч": 3600, 16 | "d": 86400, 17 | "д": 86400, 18 | "w": 604800, 19 | "н": 604800, 20 | "o": 2592000, 21 | "е": 2592000, 22 | "y": 31536000, 23 | "г": 31536000, 24 | "л": 31536000 25 | } 26 | for char in string: 27 | if char.isdigit(): 28 | number_string += char 29 | else: 30 | try: 31 | multi = units[char] 32 | except KeyError: 33 | multi = 1 34 | try: 35 | total_seconds += int(number_string) * multi 36 | except: 37 | pass 38 | number_string = '' 39 | if total_seconds < 0: 40 | total_seconds = 0 41 | return total_seconds 42 | 43 | def word_correct(number: int, p1, p2, p3): 44 | number = str(number) 45 | ld = number[-2:] 46 | cases = { 47 | "0": "p3", 48 | "1": "p1", 49 | "2": "p2", 50 | "3": "p2", 51 | "4": "p2", 52 | "5": "p3", 53 | "6": "p3", 54 | "7": "p3", 55 | "8": "p3", 56 | "9": "p3" 57 | } 58 | if ld[0] == "1" and len(ld) > 1: 59 | case = "p3" 60 | else: 61 | if len(ld) == 1: 62 | case = cases[ld[0]] 63 | else: 64 | case = cases[ld[1]] 65 | 66 | words = { 67 | "p1": p1, 68 | "p2": p2, 69 | "p3": p3 70 | } 71 | return words[case] 72 | def hms(sec: float): 73 | w = int(sec // 604800) 74 | d = int((sec % 604800) // 86400) 75 | h = int((sec % 86400) // 3600) 76 | m = int((sec % 3600) // 60) 77 | s = int(sec % 60) 78 | ms = int(sec % 1 * 1000) 79 | 80 | if d > 0: 81 | display_d = f'{d} {word_correct( d, "день", "дня", "дней" )} ' 82 | else: 83 | display_d = '' 84 | 85 | if h > 0: 86 | display_h = f'{h} {word_correct( h, "час", "часа", "часов" )} ' 87 | else: 88 | display_h = '' 89 | 90 | if m > 0: 91 | display_m = f'{m} {word_correct( m, "минута", "минуты", "минут" )} ' 92 | else: 93 | display_m = '' 94 | 95 | if s > 0: 96 | display_s = f'{s} {word_correct(s, "секунда", "секунды", "секунд" )}' 97 | else: 98 | display_s = '' 99 | 100 | if sec < 1: 101 | return f'{ms} {word_correct( ms, "миллисекунда", "миллисекунды", "миллисекунд" )}'.strip() 102 | elif sec < 60: 103 | return f'{s} {word_correct( s, "секунда", "секунды", "секунд" )}'.strip() 104 | elif sec < 3600: 105 | return f'{m} {word_correct( m, "минута", "минуты", "минут" )} {display_s}'.strip() 106 | elif sec < 86400: 107 | return f'{h} {word_correct( h, "час", "часа", "часов" )} {display_m}{display_s}'.strip() 108 | elif sec < 604800: 109 | return f'{display_d}{display_h}{display_m}{display_s}'.strip() 110 | else: 111 | return f'{w} {word_correct( w, "неделя", "недели", "недель" )} {display_d}{display_h}{display_m}{display_s}'.strip() 112 | 113 | def hms2(sec: float): 114 | w = int(sec // 604800) 115 | d = int((sec % 604800) // 86400) 116 | h = int((sec % 86400) // 3600) 117 | m = int((sec % 3600) // 60) 118 | s = int(sec % 60) 119 | ms = int(sec % 1 * 1000) 120 | 121 | if d > 0: 122 | display_d = f'{d} {word_correct( d, "день", "дня", "дней" )} ' 123 | else: 124 | display_d = '' 125 | 126 | if h > 0: 127 | display_h = f'{h} {word_correct( h, "час", "часа", "часов" )} ' 128 | else: 129 | display_h = '' 130 | 131 | if m > 0: 132 | display_m = f'{m} {word_correct( m, "минуту", "минуты", "минут" )} ' 133 | else: 134 | display_m = '' 135 | 136 | if s > 0: 137 | display_s = f'{s} {word_correct(s, "секунду", "секунды", "секунд" )}' 138 | else: 139 | display_s = '' 140 | 141 | if sec < 1: 142 | return f'{ms} {word_correct( ms, "миллисекунду", "миллисекунды", "миллисекунд" )}' 143 | elif sec < 60: 144 | return f'{s} {word_correct( s, "секунду", "секунды", "секунд" )}' 145 | elif sec < 3600: 146 | return f'{m} {word_correct( m, "минуту", "минуты", "минут" )} {display_s}' 147 | elif sec < 86400: 148 | return f'{h} {word_correct( h, "час", "часа", "часов" )} {display_m}{display_s}' 149 | elif sec < 604800: 150 | return f'{display_d}{display_h}{display_m}{display_s}'.strip() 151 | else: 152 | return f'{w} {word_correct( w, "неделю", "недели", "недель" )} {display_d}{display_h}{display_m}{display_s}'.strip() 153 | 154 | def oneof(string, list): 155 | found = False 156 | for l in list: 157 | if l in string.lower(): 158 | found = True 159 | break 160 | return found, l 161 | 162 | def ishs(string1): 163 | string1 = string1.lower() 164 | return oneof(string1, list('smhdwyсмчднгл'))[0] and oneof(string1, [str(n) for n in string.digits])[0] 165 | 166 | def ago(dt): 167 | days = (datetime.datetime.now(pytz.timezone("Europe/Moscow")) - dt).days 168 | if days >= 365: 169 | d = f'{days//365} {word_correct(days//365, "год", "года", "лет")} назад' 170 | elif days >= 30: 171 | d = f'{days//30} {word_correct(days//30, "месяц", "месяца", "месяцев")} назад' 172 | elif days >= 7: 173 | d = f'{days//7} {word_correct(days//7, "неделю", "недели", "недель")} назад' 174 | elif days > 1: 175 | d = f'{days} {word_correct(days, "день", "дня", "дней")} назад' 176 | elif days == 1: 177 | d = 'вчера' 178 | elif days == 0: 179 | d = 'сегодня' 180 | return d 181 | 182 | def eround(number: float, decimal: int = 0): 183 | if str(round(number, decimal)).endswith(".0"): 184 | return int(number) 185 | return round(number, decimal) 186 | 187 | def unit(number: int): 188 | if number < 1000: 189 | return str(number) 190 | elif number < 1000000: 191 | return f"{eround(number / 1000, 1)} тыс" 192 | elif number < 1000000000: 193 | return f"{eround(number / 1000000, 1)} млн" 194 | elif number < 1000000000000: 195 | return f"{eround(number / 1000000000, 1)} млрд" 196 | else: 197 | return f"{eround(number / 1000000000000, 1)} трлн" --------------------------------------------------------------------------------