-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
anticheat.py
115 lines (99 loc) · 4.12 KB
/
anticheat.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import asyncio
import re
import typing
import aiohttp
import discord
from yaml import load
try:
from yaml import CLoader as Loader
except ImportError:
from yaml import Loader
class DiscordClient(discord.Client):
# request headers
gdq_headers = {"headers": {"User-Agent": "rush-schedule-updater"}}
murphy_ping = re.compile(r"<@!?(?:187684157181132800|460906275400843274)>")
channel_id = 442082610785550337
amount_regex = re.compile(r"^\$?((?:\d{1,3},?){1,3}(?:\.\d+)?)(?: ?([MKmk]))?")
suffix_map = {
'm': 1000000,
'k': 1000
}
current_amount: float = 0
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.config = load(open('config.yaml', 'r'), Loader)
# aiohttp session, do not change
# (it gets defined later because it yelled at me for creating in non-async func)
self.session: typing.Optional[aiohttp.ClientSession] = None
async def load_gdq_json(self, query):
"""
Loads and processes a GDQ API page
:param query: the search parameters to query
:return: json object
"""
url = f"{self.config['gdq_url']}{query}"
async with self.session.get(url, **self.gdq_headers) as r:
if r.status == 200:
jsondata = await r.json()
else:
print("GET {} returned {} {} -- aborting".format(url, r.status, await r.text()))
exit()
return jsondata
async def load_gdq_index(self):
"""
Returns the GDQ index (main) page, includes donation totals
:return: json object
"""
return (await self.load_gdq_json(f"?type=event&id={self.config['event_id']}"))[0]['fields']
async def load_donation_total(self) -> float:
"""
Returns the current GDQ donation total
:return: float
"""
return float((await self.load_gdq_index())['amount'])
async def on_ready(self):
self.session = aiohttp.ClientSession()
print('Logged in as')
print(self.user.name)
print(self.user.id)
print('------')
# load event info
if not isinstance(self.config['event_id'], int):
orig_id = self.config['event_id'].lower()
events = await self.load_gdq_json(f"?type=event")
self.config['event_id'] = next((event['pk'] for event in events if event['fields']['short'].lower() == orig_id), None)
if self.config['event_id'] is None:
print(f"Could not find event {orig_id}")
exit()
async def handle(self, msg: discord.Message):
if self.session is None:
return
if msg.channel.id != self.channel_id:
return
content = self.murphy_ping.sub("", msg.content).strip()
if content == msg.content or len(content) == 0:
return
match = self.amount_regex.match(content)
if not match:
return
amount = float(match.group(1).replace(',', ''))
if match.group(2):
amount *= self.suffix_map[match.group(2).lower()]
if self.current_amount < amount:
self.current_amount = await self.load_donation_total()
# conversion to int gives users benefit of the doubt in regard to rounding errors
if int(self.current_amount) >= int(amount):
print(f"${msg.author} (${msg.author.id}) is HONEST about ${amount:,.2f}!")
await msg.add_reaction("✅")
else:
print(f"${msg.author} (${msg.author.id}) is LYING about ${amount:,.2f}!")
await msg.reply(f"liar! >:( we're at only ${self.current_amount:,.2f}, not ${amount:,.2f}.")
async def on_message(self, msg: discord.Message):
await self.handle(msg)
async def on_message_edit(self, before: discord.Message, after: discord.Message):
await self.handle(after)
if __name__ == '__main__':
intents = discord.Intents.default()
intents.message_content = True
client = DiscordClient(intents=intents, allowed_mentions=discord.AllowedMentions(users=False, roles=False, everyone=False))
client.run(client.config['token'])