Merge branch 'master' into conquest_develop
This commit is contained in:
commit
8abeca3d1e
@ -8,6 +8,19 @@ from redbot.core.bot import Red
|
||||
from redbot.core.utils.chat_formatting import box, pagify
|
||||
|
||||
|
||||
async def _get_roles_from_content(ctx, content):
|
||||
content_list = content.split(",")
|
||||
try:
|
||||
role_list = [
|
||||
discord.utils.get(ctx.guild.roles, name=role.strip(" ")).id
|
||||
for role in content_list
|
||||
]
|
||||
except (discord.HTTPException, AttributeError): # None.id is attribute error
|
||||
return None
|
||||
else:
|
||||
return role_list
|
||||
|
||||
|
||||
class CCRole(commands.Cog):
|
||||
"""
|
||||
Custom commands
|
||||
@ -77,7 +90,7 @@ class CCRole(commands.Cog):
|
||||
|
||||
arole_list = []
|
||||
if answer.content.upper() != "NONE":
|
||||
arole_list = await self._get_roles_from_content(ctx, answer.content)
|
||||
arole_list = await _get_roles_from_content(ctx, answer.content)
|
||||
if arole_list is None:
|
||||
await ctx.send("Invalid answer, canceling")
|
||||
return
|
||||
@ -94,7 +107,7 @@ class CCRole(commands.Cog):
|
||||
|
||||
rrole_list = []
|
||||
if answer.content.upper() != "NONE":
|
||||
rrole_list = await self._get_roles_from_content(ctx, answer.content)
|
||||
rrole_list = await _get_roles_from_content(ctx, answer.content)
|
||||
if rrole_list is None:
|
||||
await ctx.send("Invalid answer, canceling")
|
||||
return
|
||||
@ -112,7 +125,7 @@ class CCRole(commands.Cog):
|
||||
|
||||
prole_list = []
|
||||
if answer.content.upper() != "NONE":
|
||||
prole_list = await self._get_roles_from_content(ctx, answer.content)
|
||||
prole_list = await _get_roles_from_content(ctx, answer.content)
|
||||
if prole_list is None:
|
||||
await ctx.send("Invalid answer, canceling")
|
||||
return
|
||||
@ -244,14 +257,17 @@ class CCRole(commands.Cog):
|
||||
https://github.com/Cog-Creators/Red-DiscordBot/blob/V3/develop/redbot/cogs/customcom/customcom.py#L508
|
||||
for the message filtering
|
||||
"""
|
||||
# This covers message.author.bot check
|
||||
if not await self.bot.message_eligible_as_command(message):
|
||||
return
|
||||
|
||||
###########
|
||||
is_private = isinstance(message.channel, discord.abc.PrivateChannel)
|
||||
|
||||
# user_allowed check, will be replaced with self.bot.user_allowed or
|
||||
# something similar once it's added
|
||||
user_allowed = True
|
||||
if is_private or len(message.content) < 2:
|
||||
return
|
||||
|
||||
if len(message.content) < 2 or is_private or not user_allowed or message.author.bot:
|
||||
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
||||
return
|
||||
|
||||
ctx = await self.bot.get_context(message)
|
||||
@ -273,40 +289,6 @@ class CCRole(commands.Cog):
|
||||
if cmd is not None:
|
||||
await self.eval_cc(cmd, message, ctx)
|
||||
|
||||
# @commands.Cog.listener()
|
||||
# async def on_message(self, message: discord.Message):
|
||||
# if len(message.content) < 2 or message.guild is None:
|
||||
# return
|
||||
#
|
||||
# ctx: commands.Context = await self.bot.get_context(message)
|
||||
# cmd = ctx.invoked_with
|
||||
# guild = message.guild
|
||||
# # try:
|
||||
# # prefix = await self.get_prefix(message)
|
||||
# # except ValueError:
|
||||
# # return
|
||||
#
|
||||
# # prefix = ctx.prefix
|
||||
#
|
||||
# cmdlist = self.config.guild(guild).cmdlist
|
||||
# # cmd = message.content[len(prefix) :].split()[0].lower()
|
||||
# cmd = await cmdlist.get_raw(cmd, default=None)
|
||||
#
|
||||
# if cmd is not None:
|
||||
# await self.eval_cc(cmd, message, ctx)
|
||||
|
||||
async def _get_roles_from_content(self, ctx, content):
|
||||
content_list = content.split(",")
|
||||
try:
|
||||
role_list = [
|
||||
discord.utils.get(ctx.guild.roles, name=role.strip(" ")).id
|
||||
for role in content_list
|
||||
]
|
||||
except (discord.HTTPException, AttributeError): # None.id is attribute error
|
||||
return None
|
||||
else:
|
||||
return role_list
|
||||
|
||||
async def get_prefix(self, message: discord.Message) -> str:
|
||||
"""
|
||||
Borrowed from alias cog
|
||||
@ -325,7 +307,7 @@ class CCRole(commands.Cog):
|
||||
return p
|
||||
raise ValueError
|
||||
|
||||
async def eval_cc(self, cmd, message, ctx):
|
||||
async def eval_cc(self, cmd, message: discord.Message, ctx: commands.Context):
|
||||
"""Does all the work"""
|
||||
if cmd["proles"] and not (
|
||||
set(role.id for role in message.author.roles) & set(cmd["proles"])
|
||||
@ -400,7 +382,7 @@ class CCRole(commands.Cog):
|
||||
await message.channel.send("Permission error: Unable to remove roles")
|
||||
|
||||
out_message = self.format_cc(cmd, message, target)
|
||||
await message.channel.send(out_message)
|
||||
await message.channel.send(out_message, allowed_mentions=discord.AllowedMentions())
|
||||
|
||||
def format_cc(self, cmd, message, target):
|
||||
out = cmd["text"]
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Creates custom commands to adjust roles and send custom messages",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing Custom Commands w/ Roles. Get started with `[p]load ccrole` and `[p]help CCRole`",
|
||||
|
@ -219,7 +219,7 @@ class Chatter(Cog):
|
||||
|
||||
@chatter.command(name="algorithm", aliases=["algo"])
|
||||
async def chatter_algorithm(
|
||||
self, ctx: commands.Context, algo_number: int, threshold: float = None
|
||||
self, ctx: commands.Context, algo_number: int, threshold: float = None
|
||||
):
|
||||
"""
|
||||
Switch the active logic algorithm to one of the three. Default after reload is Spacy
|
||||
@ -283,7 +283,9 @@ class Chatter(Cog):
|
||||
async with ctx.typing():
|
||||
self.chatbot = self._create_chatbot()
|
||||
|
||||
await ctx.maybe_send_embed(f"Model has been switched to {self.tagger_language.ISO_639_1}")
|
||||
await ctx.maybe_send_embed(
|
||||
f"Model has been switched to {self.tagger_language.ISO_639_1}"
|
||||
)
|
||||
|
||||
@chatter.command(name="minutes")
|
||||
async def minutes(self, ctx: commands.Context, minutes: int):
|
||||
@ -427,6 +429,9 @@ class Chatter(Cog):
|
||||
if len(message.content) < 2 or is_private or not user_allowed or message.author.bot:
|
||||
return
|
||||
|
||||
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
||||
return
|
||||
|
||||
ctx: commands.Context = await self.bot.get_context(message)
|
||||
|
||||
if ctx.prefix is not None:
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.10",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Create an offline chatbot that talks like your average member using Machine Learning",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing Chatter! Get started ith `[p]load chatter` and `[p]help Chatter`",
|
||||
|
@ -89,6 +89,9 @@ class Dad(Cog):
|
||||
if guild is None:
|
||||
return
|
||||
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
|
||||
guild_config = self.config.guild(guild)
|
||||
is_on = await guild_config.enabled()
|
||||
if not is_on:
|
||||
@ -113,7 +116,10 @@ class Dad(Cog):
|
||||
else:
|
||||
out = cleaned_content[4:]
|
||||
try:
|
||||
await message.channel.send(f"Hi {out}, I'm {guild.me.display_name}!")
|
||||
await message.channel.send(
|
||||
f"Hi {out}, I'm {guild.me.display_name}!",
|
||||
allowed_mentions=discord.AllowedMentions(),
|
||||
)
|
||||
except discord.HTTPException:
|
||||
return
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Tell dad jokes and give out bad nicknames",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing Dad. Get started with `[p]load dad`, then `[p]help Dad`",
|
||||
|
@ -97,6 +97,9 @@ class ExclusiveRole(Cog):
|
||||
if before.roles == after.roles:
|
||||
return
|
||||
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
|
||||
await asyncio.sleep(1)
|
||||
|
||||
role_set = set(await self.config.guild(after.guild).role_list())
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Assign roles to be exclusive, preventing other roles from being added",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing ExclusiveRole. Get started with `[p]load exclusiverole` and `[p]help ExclusiveRole`",
|
||||
|
@ -66,7 +66,9 @@ class Flag(Cog):
|
||||
Set the number of days for flags to expire after for server
|
||||
"""
|
||||
await self.config.guild(ctx.guild).days.set(days)
|
||||
await ctx.maybe_send_embed("Number of days for new flags to expire is now {} days".format(days))
|
||||
await ctx.maybe_send_embed(
|
||||
"Number of days for new flags to expire is now {} days".format(days)
|
||||
)
|
||||
|
||||
@flagset.command(name="dm")
|
||||
async def flagset_dm(self, ctx: commands.Context):
|
||||
@ -75,7 +77,9 @@ class Flag(Cog):
|
||||
dm = await self.config.guild(ctx.guild).dm()
|
||||
await self.config.guild(ctx.guild).dm.set(not dm)
|
||||
|
||||
await ctx.maybe_send_embed("DM-ing members when they get a flag is now set to **{}**".format(not dm))
|
||||
await ctx.maybe_send_embed(
|
||||
"DM-ing members when they get a flag is now set to **{}**".format(not dm)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _flag_template():
|
||||
|
@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
|
||||
import discord
|
||||
from discord.utils import get
|
||||
from redbot.core import Config, checks, commands
|
||||
from redbot.core.bot import Red
|
||||
@ -38,8 +39,18 @@ class ForceMention(Cog):
|
||||
|
||||
if not role_obj.mentionable:
|
||||
await role_obj.edit(mentionable=True)
|
||||
await ctx.send("{}\n{}".format(role_obj.mention, message))
|
||||
await ctx.send(
|
||||
"{}\n{}".format(role_obj.mention, message),
|
||||
allowed_mentions=discord.AllowedMentions(
|
||||
everyone=False, users=False, roles=[role_obj]
|
||||
),
|
||||
)
|
||||
await asyncio.sleep(5)
|
||||
await role_obj.edit(mentionable=False)
|
||||
else:
|
||||
await ctx.send("{}\n{}".format(role_obj.mention, message))
|
||||
await ctx.send(
|
||||
"{}\n{}".format(role_obj.mention, message),
|
||||
allowed_mentions=discord.AllowedMentions(
|
||||
everyone=False, users=False, roles=[role_obj]
|
||||
),
|
||||
)
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Mentions roles that are unmentionable",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing ForceMention! Get started with `[p]load forcemention`, then `[p]forcemention`",
|
||||
|
@ -1,5 +1,6 @@
|
||||
from collections import defaultdict
|
||||
from random import randint
|
||||
from typing import Union
|
||||
|
||||
import discord
|
||||
from redbot.core import Config, checks, commands
|
||||
@ -179,14 +180,18 @@ class Hangman(Cog):
|
||||
|
||||
current = await self.config.guild(ctx.guild).emojis()
|
||||
await self.config.guild(ctx.guild).emojis.set(not current)
|
||||
await ctx.maybe_send_embed("Emoji Letter reactions have been set to {}".format(not current))
|
||||
await ctx.maybe_send_embed(
|
||||
"Emoji Letter reactions have been set to {}".format(not current)
|
||||
)
|
||||
|
||||
@commands.command(aliases=["hang"])
|
||||
async def hangman(self, ctx, guess: str = None):
|
||||
"""Play a game of hangman against the bot!"""
|
||||
if guess is None:
|
||||
if self.the_data[ctx.guild]["running"]:
|
||||
await ctx.maybe_send_embed("Game of hangman is already running!\nEnter your guess!")
|
||||
await ctx.maybe_send_embed(
|
||||
"Game of hangman is already running!\nEnter your guess!"
|
||||
)
|
||||
await self._printgame(ctx.channel)
|
||||
"""await self.bot.send_cmd_help(ctx)"""
|
||||
else:
|
||||
@ -194,7 +199,9 @@ class Hangman(Cog):
|
||||
self._startgame(ctx.guild)
|
||||
await self._printgame(ctx.channel)
|
||||
elif not self.the_data[ctx.guild]["running"]:
|
||||
await ctx.maybe_send_embed("Game of hangman is not yet running!\nStarting a game of hangman!")
|
||||
await ctx.maybe_send_embed(
|
||||
"Game of hangman is not yet running!\nStarting a game of hangman!"
|
||||
)
|
||||
self._startgame(ctx.guild)
|
||||
await self._printgame(ctx.channel)
|
||||
else:
|
||||
@ -280,15 +287,22 @@ class Hangman(Cog):
|
||||
await self._reprintgame(message)
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_react(self, reaction, user):
|
||||
async def on_react(self, reaction, user: Union[discord.User, discord.Member]):
|
||||
""" Thanks to flapjack reactpoll for guidelines
|
||||
https://github.com/flapjax/FlapJack-Cogs/blob/master/reactpoll/reactpoll.py"""
|
||||
|
||||
if reaction.message.id != self.the_data[user.guild]["trackmessage"]:
|
||||
guild: discord.Guild = getattr(user, "guild", None)
|
||||
if guild is None:
|
||||
return
|
||||
|
||||
if reaction.message.id != self.the_data[guild]["trackmessage"]:
|
||||
return
|
||||
|
||||
if user.bot:
|
||||
return # Don't react to bot reactions
|
||||
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
|
||||
if user == self.bot.user:
|
||||
return # Don't react to bot's own reactions
|
||||
message = reaction.message
|
||||
emoji = reaction.emoji
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Play Hangman with your friends",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing Hangman! Get started with `[p]load hangman`, then `[p]help Hangman`",
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Create a channel with updating server info",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing InfoChannel. Get started with `[p]load infochannel`, then `[p]help InfoChannel`",
|
||||
|
@ -273,14 +273,20 @@ class InfoChannel(Cog):
|
||||
|
||||
@Cog.listener()
|
||||
async def on_member_join(self, member: discord.Member):
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
await self.update_infochannel_with_cooldown(member.guild)
|
||||
|
||||
@Cog.listener()
|
||||
async def on_member_remove(self, member: discord.Member):
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
await self.update_infochannel_with_cooldown(member.guild)
|
||||
|
||||
@Cog.listener()
|
||||
async def on_member_update(self, before: discord.Member, after: discord.Member):
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
onlinecount = await self.config.guild(after.guild).online_count()
|
||||
if onlinecount:
|
||||
if before.status != after.status:
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Keeps track of when people leave the server, and posts a message notifying",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing Leaver. Get started with `[p]load leaver`, then `[p]help Leaver`",
|
||||
|
@ -38,6 +38,10 @@ class Leaver(Cog):
|
||||
@commands.Cog.listener()
|
||||
async def on_member_remove(self, member: discord.Member):
|
||||
guild = member.guild
|
||||
|
||||
if await self.bot.cog_disabled_in_guild(self, guild):
|
||||
return
|
||||
|
||||
channel = await self.config.guild(guild).channel()
|
||||
|
||||
if channel != "":
|
||||
|
@ -18,7 +18,7 @@ class LoveCalculator(Cog):
|
||||
|
||||
@commands.command(aliases=["lovecalc"])
|
||||
async def lovecalculator(
|
||||
self, ctx: commands.Context, lover: discord.Member, loved: discord.Member
|
||||
self, ctx: commands.Context, lover: discord.Member, loved: discord.Member
|
||||
):
|
||||
"""Calculate the love percentage!"""
|
||||
|
||||
@ -34,8 +34,8 @@ class LoveCalculator(Cog):
|
||||
try:
|
||||
description = (
|
||||
soup_object.find("div", attrs={"class": "result__score"})
|
||||
.get_text()
|
||||
.strip()
|
||||
.get_text()
|
||||
.strip()
|
||||
)
|
||||
except:
|
||||
description = "Dr. Love is busy right now"
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Keep track of when users were last seen online",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing LastSeen. Get started with `[p]load lseen`, then `[p]help LastSeen`",
|
||||
|
@ -75,7 +75,9 @@ class LastSeen(Cog):
|
||||
else:
|
||||
last_seen = await self.config.member(member).seen()
|
||||
if last_seen is None:
|
||||
await ctx.maybe_send_embed(embed=discord.Embed(description="I've never seen this user"))
|
||||
await ctx.maybe_send_embed(
|
||||
embed=discord.Embed(description="I've never seen this user")
|
||||
)
|
||||
return
|
||||
last_seen = self.get_date_time(last_seen)
|
||||
|
||||
@ -89,6 +91,8 @@ class LastSeen(Cog):
|
||||
@commands.Cog.listener()
|
||||
async def on_member_update(self, before: discord.Member, after: discord.Member):
|
||||
if before.status != self.offline_status and after.status == self.offline_status:
|
||||
if not await self.config.guild(before.guild).enabled():
|
||||
if await self.bot.cog_disabled_in_guild(self, after.guild):
|
||||
return
|
||||
if not await self.config.guild(after.guild).enabled():
|
||||
return
|
||||
await self.config.member(before).seen.set(datetime.utcnow().isoformat())
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.11",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Monitor images for NSFW content and moves them to a nsfw channel if possible",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing Nudity. Get started with `[p]load nudity`, then `[p]help Nudity`",
|
||||
|
@ -96,6 +96,9 @@ class Nudity(commands.Cog):
|
||||
# print("did not qualify")
|
||||
return
|
||||
|
||||
if await self.bot.cog_disabled_in_guild(self, message.guild):
|
||||
return
|
||||
|
||||
try:
|
||||
is_on = await self.config.guild(message.guild).enabled()
|
||||
except AttributeError:
|
||||
|
@ -48,7 +48,9 @@ class QRInvite(Cog):
|
||||
invite = await ctx.channel.invites()
|
||||
invite = invite[0]
|
||||
except discord.Forbidden:
|
||||
await ctx.maybe_send_embed("No permission to get an invite, please provide one")
|
||||
await ctx.maybe_send_embed(
|
||||
"No permission to get an invite, please provide one"
|
||||
)
|
||||
return
|
||||
invite = invite.code
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Cog to prevent reactions on specific messages from certain users",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing ReactRestrict.",
|
||||
|
@ -281,6 +281,9 @@ class ReactRestrict(Cog):
|
||||
if member.bot:
|
||||
return
|
||||
|
||||
if await self.bot.cog_disabled_in_guild(self, member.guild):
|
||||
return
|
||||
|
||||
try:
|
||||
roles = [self._get_role(member.guild, c.role_id) for c in combos]
|
||||
except LookupError:
|
||||
|
@ -2,7 +2,7 @@
|
||||
"author": [
|
||||
"Bobloy"
|
||||
],
|
||||
"min_bot_version": "3.3.0",
|
||||
"min_bot_version": "3.4.0",
|
||||
"description": "Steals custom emojis the bot sees and moves them to an emoji server",
|
||||
"hidden": false,
|
||||
"install_msg": "Thank you for installing StealEmoji",
|
||||
|
@ -181,6 +181,10 @@ class StealEmoji(Cog):
|
||||
# print("Collecting is off")
|
||||
return
|
||||
|
||||
guild: discord.Guild = getattr(user, "guild", None)
|
||||
if await self.bot.cog_disabled_in_guild(self, guild): # Handles None guild just fine
|
||||
return
|
||||
|
||||
emoji: discord.Emoji = reaction.emoji
|
||||
if emoji in self.bot.emojis:
|
||||
# print("Emoji already in bot.emojis")
|
||||
|
@ -8,7 +8,7 @@
|
||||
"install_msg": "Thank you for installing Werewolf! Get started with `[p]load werewolf`\n Use `[p]wwset` to run inital setup",
|
||||
"requirements": [],
|
||||
"short": "Werewolf Game",
|
||||
"end_user_data_statement": "This store user IDs in memory while they're actively using the cog, and store no persistent End User Data.",
|
||||
"end_user_data_statement": "This stores user IDs in memory while they're actively using the cog, and stores no persistent End User Data.",
|
||||
"tags": [
|
||||
"mafia",
|
||||
"werewolf",
|
||||
|
Loading…
x
Reference in New Issue
Block a user