Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions bot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
os.environ["SSL_CERT_FILE"] = certifi.where()
from discord.ext import commands, tasks


from utils import files
from utils.config import Config
import utils.console as console
Expand Down Expand Up @@ -42,6 +43,9 @@ def __init__(self, controller):
self.files = files
self.allowed_users = []
self.allowed_cogs = ["fun", "text", "general", "img", "info"]




async def _setup_scripts(self):
scripts = self.cfg.get_scripts()
Expand Down Expand Up @@ -133,6 +137,7 @@ async def on_message(self, message):
async def on_ready(self):
try:
self.start_time = time.time()

self.cfg.add_token(self.cfg.get("token"), self.user.name, self.user.id)
await self.load_cogs()

Expand Down
13 changes: 12 additions & 1 deletion bot/commands/mod.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,18 @@ def is_me(m):

@commands.command(name="dmpurge", description="Purge a number of messages in a DM.", usage="[number] [user id]")
async def dmpurge(self, ctx, number: int, user_id: int):
user = self.bot.get_user(user_id)
if self.cfg.get("message_settings")["edit_og"]:
await cmdhelper.send_message(ctx, {
"title": "DM Purge",
"description": f"Purging {number} messages..."
})
else:
try:
await ctx.message.delete()
except:
pass

user = discord.utils.get(self.bot.users, id=user_id)

if isinstance(user, discord.User):
latest_msg = [msg async for msg in user.dm_channel.history(limit=1)][0]
Expand Down
29 changes: 29 additions & 0 deletions bot/commands/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,35 @@ async def sessionspoofer(self, ctx, device = None):
cfg.save()
await self.restart(ctx, no_response=True)

@commands.command(name="st", description="Toggle silent typing.", usage="", aliases=["silenttype", "silenttyping"])
async def st(self, ctx):
from utils import typing_blocker

cfg = self.cfg
current = cfg.get("message_settings").get("silent_typing", False)
new_val = not current

cfg.set("message_settings.silent_typing", new_val)
cfg.save()

typing_blocker.set_enabled(new_val)

status = "enabled" if new_val else "disabled"
desc = f"Silent typing {status}"

if not typing_blocker.is_injected():
success, msg = typing_blocker.inject()
if success:
desc += "\nRestart Discord for injection to take effect."
else:
desc += f"\nInjection failed: {msg}"

await cmdhelper.send_message(ctx, {
"title": "Silent Typing",
"description": desc,
"colour": "#00ff00" if new_val else "#ff0000"
})

@commands.command(name="uptime", description="View the bot's uptime", usage="")
async def uptime(self, ctx):
uptime = time.time() - self.bot.start_time
Expand Down
127 changes: 127 additions & 0 deletions utils/typing_blocker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import os
import glob
import re

_FLAG_FILE = os.path.join(os.path.expanduser("~"), ".ghost_silent_typing")

_INJECTED_JS = r"""const _ghostFs = require('fs');
const _ghostPath = require('path');
const _ghostOs = require('os');
const _ghostFlagPath = _ghostPath.join(_ghostOs.homedir(), '.ghost_silent_typing');
const _ghostElectron = require('electron');

function _ghostInstallTypingBlock(ses) {
ses.webRequest.onBeforeRequest({ urls: ['https://*.discord.com/*'] }, (details, callback) => {
if (details.url.endsWith('/typing') && details.method === 'POST') {
try {
if (_ghostFs.existsSync(_ghostFlagPath)) {
callback({ cancel: true });
return;
}
} catch (e) {}
}
callback({});
});
}

_ghostElectron.app.on('ready', () => {
_ghostInstallTypingBlock(_ghostElectron.session.defaultSession);
});

_ghostElectron.app.on('browser-window-created', (e, w) => {
if (w.webContents.session !== _ghostElectron.session.defaultSession) {
_ghostInstallTypingBlock(w.webContents.session);
}
});"""


import sys

def find_discord_index():
app_dirs = []

if os.name == "nt":
base = os.environ.get("LOCALAPPDATA", "")
if base:
for c in ["Discord", "DiscordPTB", "DiscordCanary"]:
app_dirs.extend(glob.glob(os.path.join(base, c, "app-*")))
elif sys.platform == "darwin":
base = os.path.join(os.path.expanduser("~"), "Library", "Application Support")
for c in ["discord", "discordptb", "discordcanary"]:
app_dirs.extend(glob.glob(os.path.join(base, c, "[0-9]*.[0-9]*.[0-9]*")))

app_dirs.sort(reverse=True)

for app_dir in app_dirs:
if os.name == "nt":
pattern = os.path.join(app_dir, "modules", "discord_desktop_core-*", "discord_desktop_core", "index.js")
else:
pattern = os.path.join(app_dir, "modules", "discord_desktop_core", "index.js")

matches = glob.glob(pattern)
if matches:
return matches[0]

return None


def is_injected(index_path=None):
if index_path is None:
index_path = find_discord_index()
if index_path is None or not os.path.isfile(index_path):
return False

with open(index_path, "r", encoding="utf-8") as f:
return _INJECTED_JS in f.read()


def inject(index_path=None):
if index_path is None:
index_path = find_discord_index()
if index_path is None or not os.path.isfile(index_path):
return False, "Discord installation not found"

if is_injected(index_path):
return True, ""

with open(index_path, "r", encoding="utf-8") as f:
original_content = f.read()

new_content = _INJECTED_JS + "\n" + original_content

with open(index_path, "w", encoding="utf-8") as f:
f.write(new_content)

return True, ""


def uninject(index_path=None):
if index_path is None:
index_path = find_discord_index()
if index_path is None or not os.path.isfile(index_path):
return False, "Discord installation not found"

if not is_injected(index_path):
return True, ""

with open(index_path, "r", encoding="utf-8") as f:
content = f.read()

cleaned = content.replace(_INJECTED_JS + "\n", "")

with open(index_path, "w", encoding="utf-8") as f:
f.write(cleaned)

return True, ""


def set_enabled(enabled):
if enabled:
with open(_FLAG_FILE, "w") as f:
f.write("1")
elif os.path.isfile(_FLAG_FILE):
os.remove(_FLAG_FILE)


def is_enabled():
return os.path.isfile(_FLAG_FILE)