mirror of
https://github.com/RGBCube/minearchy-bot
synced 2025-07-27 08:57:46 +00:00
add suggestions and do cleanup
This commit is contained in:
parent
2322dec868
commit
a3a3d7b966
9 changed files with 113 additions and 92 deletions
3
.replit
3
.replit
|
@ -1,3 +0,0 @@
|
|||
run="python3 bot.py"
|
||||
language="python3"
|
||||
onBoot="pip3 install -r requirements.txt"
|
64
bot.py
64
bot.py
|
@ -1,46 +1,47 @@
|
|||
import discord
|
||||
import time
|
||||
import aiohttp
|
||||
from discord.ext import commands
|
||||
import os
|
||||
import json
|
||||
import asyncio
|
||||
from mcstatus import MinecraftServer
|
||||
import traceback
|
||||
import itertools
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
import time
|
||||
import traceback
|
||||
|
||||
import aiohttp
|
||||
import discord
|
||||
import mcstatus
|
||||
from discord.ext import commands
|
||||
|
||||
|
||||
class MinearchyBot(commands.Bot):
|
||||
session: aiohttp.ClientSession
|
||||
suggestions_channel: discord.TextChannel
|
||||
log_webhook: discord.Webhook
|
||||
up_ts: float
|
||||
|
||||
embed_color = 0x3500FF
|
||||
|
||||
def __init__(self, token: str, webhook_url: str, /) -> None:
|
||||
def __init__(
|
||||
self, *, token: str, webhook_url: str, suggestions_channel_id: int
|
||||
) -> None:
|
||||
ip = "play.landsofminearchy.com"
|
||||
self.mc_server = MinecraftServer.lookup(ip)
|
||||
self.mc_server = mcstatus.JavaServer.lookup(ip)
|
||||
self.mc_server.ip = ip
|
||||
self.mc_server.bedrock_ip = "bedrock.landsofminearchy.com"
|
||||
|
||||
self.token = token
|
||||
self.webhook_url = webhook_url
|
||||
|
||||
intents = discord.Intents(
|
||||
guilds=True,
|
||||
members=True,
|
||||
messages=True,
|
||||
message_content=True,
|
||||
)
|
||||
stuff_to_cache = discord.MemberCacheFlags.from_intents(intents)
|
||||
|
||||
self.suggestions_channel_id = suggestions_channel_id
|
||||
super().__init__(
|
||||
command_prefix="=",
|
||||
owner_ids=set([512640455834337290]),
|
||||
intents=intents,
|
||||
intents=discord.Intents(
|
||||
guilds=True,
|
||||
members=True,
|
||||
messages=True,
|
||||
message_content=True,
|
||||
),
|
||||
case_insensitive=True,
|
||||
allowed_mentions=discord.AllowedMentions.none(),
|
||||
member_cache_flags=stuff_to_cache,
|
||||
max_messages=1000,
|
||||
strip_after_prefix=True,
|
||||
help_attrs=dict(
|
||||
|
@ -51,13 +52,17 @@ class MinearchyBot(commands.Bot):
|
|||
|
||||
async def on_ready(self) -> None:
|
||||
self.up_ts = time.time()
|
||||
self.suggestions_channel = self.get_channel(self.suggestions_channel_id)
|
||||
print(f"\nConnected to Discord!\nUser: {self.user}\nID: {self.user.id}")
|
||||
await self.log_webhook.send("Bot is now online!")
|
||||
|
||||
async def load_extensions(self) -> None:
|
||||
for fn in map(
|
||||
lambda file_path: str(file_path).replace("/", ".")[:-3],
|
||||
pathlib.Path("./cogs").rglob("*.py"),
|
||||
for fn in itertools.chain(
|
||||
map(
|
||||
lambda file_path: str(file_path).replace("/", ".")[:-3],
|
||||
pathlib.Path("./cogs").rglob("*.py"),
|
||||
),
|
||||
["jishaku"],
|
||||
):
|
||||
try:
|
||||
await self.load_extension(fn)
|
||||
|
@ -87,11 +92,10 @@ with open("./config.json") as f:
|
|||
for key in ["BOT_TOKEN", "WEBHOOK_URL"]:
|
||||
config.setdefault(key, os.getenv(key))
|
||||
|
||||
bot = MinearchyBot(config["BOT_TOKEN"], config["WEBHOOK_URL"])
|
||||
|
||||
if os.getenv("USING_REPLIT"):
|
||||
import webserver
|
||||
|
||||
webserver.keep_alive()
|
||||
bot = MinearchyBot(
|
||||
token=config["BOT_TOKEN"],
|
||||
webhook_url=config["WEBHOOK_URL"],
|
||||
suggestions_channel_id=config["SUGGESTIONS_CHANNEL_ID"],
|
||||
)
|
||||
|
||||
bot.run()
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from discord.ext import commands
|
||||
import discord
|
||||
import sys
|
||||
import traceback
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bot import MinearchyBot
|
||||
|
||||
|
||||
class ErrorHandler(commands.Cog):
|
||||
def __init__(self, bot: MinearchyBot, /) -> None:
|
||||
def __init__(self, bot: MinearchyBot) -> None:
|
||||
self.bot = bot
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_command_error(
|
||||
self, ctx: commands.Context, error: commands.CommandError, /
|
||||
self, ctx: commands.Context, error: commands.CommandError
|
||||
) -> None:
|
||||
if hasattr(ctx.command, "on_error"):
|
||||
return
|
||||
|
@ -42,18 +42,17 @@ class ErrorHandler(commands.Cog):
|
|||
elif isinstance(error, commands.MissingPermissions):
|
||||
await ctx.reply("You can't use this command!")
|
||||
|
||||
elif isinstance(error, commands.MissingRequiredArgument):
|
||||
await ctx.reply(f"Missing a required argument: `{error.param.name}`")
|
||||
|
||||
elif isinstance(error, commands.ChannelNotFound):
|
||||
await ctx.reply("Invalid channel.")
|
||||
|
||||
else:
|
||||
trace = traceback.format_exception(
|
||||
type(error), error, error.__traceback__
|
||||
)
|
||||
print(f"Ignoring exception in command {ctx.command}:\n{trace}")
|
||||
await self.bot.log_webhook.send(
|
||||
f"<@512640455834337290>```{trace}```"
|
||||
)
|
||||
trace = traceback.format_exception(type(error), error, error.__traceback__)
|
||||
print(f"Ignoring exception in command {ctx.command}:\n{''.join(trace)}")
|
||||
await self.bot.log_webhook.send(f"<@512640455834337290>```{trace}```")
|
||||
|
||||
|
||||
async def setup(bot: MinearchyBot, /) -> None:
|
||||
async def setup(bot: MinearchyBot) -> None:
|
||||
await bot.add_cog(ErrorHandler(bot))
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from discord.ext import commands
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bot import MinearchyBot
|
||||
|
@ -13,7 +14,7 @@ class MinecraftServer(
|
|||
name="Minecraft Server",
|
||||
description="Utilites for the Minecraft server.",
|
||||
):
|
||||
def __init__(self, bot: MinearchyBot, /) -> None:
|
||||
def __init__(self, bot: MinearchyBot) -> None:
|
||||
self.bot = bot
|
||||
|
||||
@commands.group(
|
||||
|
@ -21,15 +22,13 @@ class MinecraftServer(
|
|||
brief="Sends the server IP.",
|
||||
help="Sends the server IP.",
|
||||
)
|
||||
async def ip(self, ctx: commands.Context, /) -> None:
|
||||
async def ip(self, ctx: commands.Context) -> None:
|
||||
await ctx.reply(
|
||||
f"Java edition IP: `{self.bot.mc_server.ip}`\nBedrock edition IP: `{self.bot.mc_server.bedrock_ip}` (Port: 19132)\nNote: Minecraft 1.18+ is required to join."
|
||||
)
|
||||
|
||||
@ip.command(
|
||||
brief="Sends the Java edition IP.", help="Sends the Java edition IP."
|
||||
)
|
||||
async def java(self, ctx: commands.Context, /) -> None:
|
||||
@ip.command(brief="Sends the Java edition IP.", help="Sends the Java edition IP.")
|
||||
async def java(self, ctx: commands.Context) -> None:
|
||||
await ctx.reply(
|
||||
f"The IP to connect on Minecraft Java edition is `{self.bot.mc_server.ip}`\nNote: Minecraft 1.18+ is required to join."
|
||||
)
|
||||
|
@ -38,7 +37,7 @@ class MinecraftServer(
|
|||
brief="Sends the Bedrock edition IP.",
|
||||
help="Sends the Bedrock edition IP.",
|
||||
)
|
||||
async def bedrock(self, ctx: commands.Context, /) -> None:
|
||||
async def bedrock(self, ctx: commands.Context) -> None:
|
||||
await ctx.reply(
|
||||
f"The IP to connect on Minecraft Bedrock edition is `{self.bot.mc_server.bedrock_ip}` (Port: 19132)\nNote: Minecraft 1.18+ is required to join."
|
||||
)
|
||||
|
@ -47,7 +46,7 @@ class MinecraftServer(
|
|||
brief="Shows information about the Minecraft server.",
|
||||
help="Shows the total player count, the Minecraft server IP and the server latency.",
|
||||
)
|
||||
async def status(self, ctx: commands.Context, /) -> None:
|
||||
async def status(self, ctx: commands.Context) -> None:
|
||||
server = self.bot.mc_server
|
||||
status = server.status()
|
||||
await ctx.reply(
|
||||
|
@ -58,7 +57,7 @@ class MinecraftServer(
|
|||
@commands.command(
|
||||
brief="Sends the link to the wiki.", help="Sends the link to the wiki."
|
||||
)
|
||||
async def wiki(self, ctx: commands.Context, /) -> None:
|
||||
async def wiki(self, ctx: commands.Context) -> None:
|
||||
view = discord.ui.View()
|
||||
view.add_item(
|
||||
discord.ui.Button(
|
||||
|
@ -72,7 +71,7 @@ class MinecraftServer(
|
|||
brief="Sends the link to the store.",
|
||||
help="Sends the link to the store.",
|
||||
)
|
||||
async def store(self, ctx: commands.Context, /) -> None:
|
||||
async def store(self, ctx: commands.Context) -> None:
|
||||
view = discord.ui.View()
|
||||
view.add_item(
|
||||
discord.ui.Button(
|
||||
|
|
30
cogs/misc.py
30
cogs/misc.py
|
@ -1,15 +1,15 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from discord.ext import commands
|
||||
import datetime
|
||||
from collections import defaultdict, deque
|
||||
import discord
|
||||
import inspect
|
||||
from discord.utils import escape_markdown as es_md
|
||||
import platform
|
||||
|
||||
import time
|
||||
from collections import defaultdict, deque
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from discord.utils import escape_markdown as es_md
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bot import MinearchyBot
|
||||
|
@ -20,7 +20,7 @@ class Miscellanious(
|
|||
name="Miscellanious",
|
||||
description="Various utilities.",
|
||||
):
|
||||
def __init__(self, bot: MinearchyBot, /) -> None:
|
||||
def __init__(self, bot: MinearchyBot) -> None:
|
||||
self.bot = bot
|
||||
self.bot.help_command.cog = self
|
||||
self.sniped = defaultdict(deque)
|
||||
|
@ -30,7 +30,7 @@ class Miscellanious(
|
|||
self.bot.help_command.hidden = True
|
||||
|
||||
@commands.command(brief="Sends the bots ping.", help="Sends the bots ping.")
|
||||
async def ping(self, ctx: commands.Context, /) -> None:
|
||||
async def ping(self, ctx: commands.Context) -> None:
|
||||
ts = time.time()
|
||||
message = await ctx.reply("Pong!")
|
||||
ts = time.time() - ts
|
||||
|
@ -39,7 +39,7 @@ class Miscellanious(
|
|||
@commands.command(
|
||||
brief="Sends info about the bot.", help="Sends info about the bot."
|
||||
)
|
||||
async def info(self, ctx: commands.Context, /) -> None:
|
||||
async def info(self, ctx: commands.Context) -> None:
|
||||
embed = discord.Embed(title="Bot Info", color=self.bot.embed_color)
|
||||
embed.add_field(
|
||||
name="Python Version", value=f"```v{platform.python_version()}```"
|
||||
|
@ -51,21 +51,19 @@ class Miscellanious(
|
|||
await ctx.reply(embed=embed)
|
||||
|
||||
@commands.command(brief="Hello!", help="Hello!")
|
||||
async def hello(self, ctx: commands.Context, /) -> None:
|
||||
await ctx.reply(
|
||||
f"Hi {es_md(ctx.author.name)}, yes the bot is running :)"
|
||||
)
|
||||
async def hello(self, ctx: commands.Context) -> None:
|
||||
await ctx.reply(f"Hi {es_md(ctx.author.name)}, yes the bot is running :)")
|
||||
|
||||
@commands.command(
|
||||
aliases=["server_count", "server-count"],
|
||||
brief="Sends how many servers the bot is in.",
|
||||
help="Sends how many servers the bot is in.",
|
||||
)
|
||||
async def count(self, ctx: commands.Context, /) -> None:
|
||||
async def count(self, ctx: commands.Context) -> None:
|
||||
await ctx.reply(f"Currently in `{len(self.bot.guilds)}` servers.")
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_message_delete(self, message: discord.Message, /) -> None:
|
||||
async def on_message_delete(self, message: discord.Message) -> None:
|
||||
if not message.guild:
|
||||
return
|
||||
|
||||
|
@ -84,7 +82,7 @@ class Miscellanious(
|
|||
manage_messages=True
|
||||
) # needs to be able to delete messages to run the command
|
||||
async def snipe(
|
||||
self, ctx: commands.Context, channel: discord.TextChannel = None, /
|
||||
self, ctx: commands.Context, channel: discord.TextChannel = None
|
||||
) -> None:
|
||||
if channel is None:
|
||||
channel = ctx.channel
|
||||
|
|
39
cogs/suggestions.py
Normal file
39
cogs/suggestions.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bot import MinearchyBot
|
||||
|
||||
|
||||
class Suggestions(commands.Cog):
|
||||
def __init__(self, bot: MinearchyBot) -> None:
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(brief="Make a suggestion.", help="Make a suggestion.")
|
||||
async def suggest(self, ctx: commands.Context, *, suggestion: str) -> None:
|
||||
embed = (
|
||||
discord.Embed(
|
||||
title=f"Suggestion from {ctx.author}",
|
||||
description=suggestion,
|
||||
color=self.bot.embed_color,
|
||||
)
|
||||
.set_thumbnail(url=ctx.author.display_avatar.url)
|
||||
.set_footer(text="=suggest <suggestion>")
|
||||
)
|
||||
|
||||
message = await self.bot.suggestions_channel.send(embed=embed)
|
||||
|
||||
await message.add_reaction("✅")
|
||||
await message.add_reaction("❌")
|
||||
|
||||
await ctx.reply(
|
||||
f"Suggestion submitted!\nYou can view it at {self.bot.suggestions_channel.mention}"
|
||||
)
|
||||
|
||||
|
||||
async def setup(bot: MinearchyBot) -> None:
|
||||
await bot.add_cog(Suggestions(bot))
|
|
@ -3,5 +3,6 @@
|
|||
"JAVA_IP": "play.landsofminearchy.com",
|
||||
"BOT_PREFIX": "=",
|
||||
"BOT_TOKEN": "XXX(ENV works too)",
|
||||
"WEBHOOK_URL": "XXX(ENV works too)"
|
||||
"WEBHOOK_URL": "XXX(ENV works too)",
|
||||
"SUGGESTIONS_CHANNEL_ID": 955972394885984276
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
discord.py @ git+https://github.com/Rapptz/discord.py
|
||||
jishaku==2.5.0
|
||||
mcstatus
|
17
webserver.py
17
webserver.py
|
@ -1,17 +0,0 @@
|
|||
from flask import Flask
|
||||
from threading import Thread
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def root() -> str:
|
||||
return "Online!"
|
||||
|
||||
|
||||
def run() -> None:
|
||||
app.run(host="0.0.0.0", port=8080)
|
||||
|
||||
|
||||
def keep_alive() -> None:
|
||||
Thread(target=run).start()
|
Loading…
Add table
Add a link
Reference in a new issue