forked from lilyyy411/mudaeautoclaimer-roller
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbot.py
216 lines (183 loc) · 12.8 KB
/
bot.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#imports
import discord
import asyncio
import json
import re
import time
from colorama import init
from termcolor import colored
Channels=open('channels.txt','r').read().splitlines() #channels config
characters=open('characters.txt','r').read().splitlines() #characters config
Series=open('series.txt','r').read().splitlines()
#load all config.json shit and create variables
config_file=open("config.json",'r')
config=json.load(config_file)
TOKEN = config["TOKEN"]
reactionDelay=config["reactionDelay"]
command=config["command"]
timeBetweenRolls=config["timeBetweenRolls"]
numberOfRolls=config["numberOfRolls"]
typingTime=config["typingTime"]
dkCommand=config["dkCommand"]
dailyCommand=config["dailyCommand"]
claimByClaimRank=config["claimByClaimRank"]
claimRank=config["claimRank"]
claimByKakeraValue=config["claimByKakeraValue"]
kakeraValue=config["kakeraValue"]
client=discord.Client()
searchOffset=0
#Regex update
init() #initiate colorama for colors in the console
def search(string):
temp = re.findall(r'\d+', string) #search string for any amount of digits
res = list(map(int, temp)) #apply the int function to every int in the string, and create a list of them
return res
async def doRollsInner(channel): #this function is an infinite loop
chanel=client.get_channel(int(channel)) #I love mispelling on purpose
name=chanel.name
await chanel.send(command)
current_time = time.strftime("%D %H:%M:%S", time.localtime())
print(colored(f"[{current_time}] Rolling in channel '{name}'","cyan"))
norolls=False
i=1
while norolls==False: #guarentee Mudae sending the No Rolls left message.
current_time = time.strftime("%D %H:%M:%S", time.localtime())
print(colored(f"\t[{current_time}] Attempting roll {i} of {numberOfRolls} in channel: '{name}' ",'blue'))
async for message in chanel.history(limit=2):
if 'the roulette is limited to' in message.content and client.user.name in message.content and message.author.bot==True:
current_time = time.strftime("%D %H:%M:%S", time.localtime())
norolls=message.content
print(f"[{current_time}] No rolls left in '{name}', Sleeping in '{name}' for {search(norolls)[1+searchOffset]+1} minutes")
await asyncio.sleep((search(norolls)[1+searchOffset]+1)*60)
await doRollsInner(channel) #start again after sleeping. Done asyncronously.
if norolls==False:
async with chanel.typing():
await asyncio.sleep(typingTime)
await chanel.send(command)
await asyncio.sleep(timeBetweenRolls-typingTime)
i+=1 #move on to next roll
async def doRolls():
await asyncio.sleep(2*timeBetweenRolls)
for future in asyncio.as_completed(map(doRollsInner, Channels)): #basically do rolls asyncronously
result = await future #because they have different wait times
async def dailyClaim(channel):
current_time = time.strftime("%D %H:%M:%S", time.localtime())
chanel=client.get_channel(int(channel))
print(colored(f"[{current_time}] Attempting to claim daily kakera in {chanel.name}",'magenta'))
async with chanel.typing():
await asyncio.sleep(typingTime)
await chanel.send(f"{dkCommand}")
await asyncio.sleep(timeBetweenRolls)
async for message in chanel.history(limit=5): #in case other users busy rolling, make the limit higher
if f"Next {dkCommand} reset" in message.content and message.author.bot==True:
try:
current_time = time.strftime("%D %H:%M:%S", time.localtime())
t=search(message.content)
if len(t)<=1: #basically if there's either only hours or only minutes
#idk if only hours is a thing, but just in case
if 'h' in message.content:
print(colored(f"[{current_time}] Next {dkCommand} in '{chanel.name}' in {t[0+searchOffset]}h 0m. Asyncronously sleeping in '{chanel.name}' that amount of time.",'cyan'))
await asyncio.sleep(3600*t[0+searchOffset])
if 'min' in message.content:
print(colored(f"[{current_time}] Next {dkCommand} in '{chanel.name}' in 0h {t[0+searchOffset]}m. Asyncronously sleeping in '{chanel.name}' that amount of time.",'cyan'))
await asyncio.sleep(60*t[0+searchOffset])
print(colored(f"[{current_time}] Next {dkCommand} in '{chanel.name}' in {t[0+searchOffset]}h {t[1+searchOffset]}m. Asyncronously sleeping in '{chanel.name}' that amount of time.",'cyan'))
await asyncio.sleep(3600*t[0+searchOffset]+60*t[1+searchOffset]+1) #first integer in the message is the hour, second integer is the minutes
await dailyClaim(channel)
except IndexError: continue #when search() doesn't return anything, ignore the error raised and try again
else: #if daily claim fails due to Mudae being ratelimited or something, try again
await asyncio.sleep(3*timeBetweenRolls-typingTime)
await dailyClaim(channel)
await asyncio.sleep(timeBetweenRolls-typingTime)
async def doDailyClaim():
for future in asyncio.as_completed(map(dailyClaim, Channels)): #basically do dk claiming asyncronously
result = await future #because they have different wait times
async def daily(channel):
await asyncio.sleep(5*timeBetweenRolls-typingTime)
current_time = time.strftime("%D %H:%M:%S", time.localtime())
chanel=client.get_channel(int(channel))
print(colored(f"[{current_time}] Attempting to claim {dailyCommand} in {chanel.name}",'magenta'))
async with chanel.typing():
await asyncio.sleep(typingTime)
await chanel.send(f"{dailyCommand}")
await asyncio.sleep(timeBetweenRolls)
async for message in chanel.history(limit=5): #in case other users busy rolling, make the limit higher
if f"Next {dailyCommand} reset" in message.content and message.author.bot==True:
try:
current_time = time.strftime("%D %H:%M:%S", time.localtime())
t=search(message.content)
if len(t)<=1: #basically if there's either only hours or only minutes
#idk if only hours is a thing, but just in case
if 'h' in message.content:
print(colored(f"[{current_time}] Next {dailyCommand} in '{chanel.name}' in {t[0+searchOffset]}h 0m. Asyncronously sleeping in '{chanel.name}' that amount of time.",'cyan'))
await asyncio.sleep(3600*t[0+searchOffset])
if 'min' in message.content:
print(colored(f"[{current_time}] Next {dailyCommand} in '{chanel.name}' in 0h {t[0+searchOffset]}m. Asyncronously sleeping in '{chanel.name}' that amount of time.",'cyan'))
await asyncio.sleep(60*t[0+searchOffset])
print(colored(f"[{current_time}] Next {dailyCommand} in '{chanel.name}' in {t[0+searchOffset]}h {t[1+searchOffset]}m. Asyncronously sleeping in '{chanel.name}' that amount of time.",'cyan'))
await asyncio.sleep(3600*t[0+searchOffset]+60*(t[1+searchOffset]+1)) #first integer in the message is the hour, second integer is the minutes
await daily(channel)
except IndexError: continue #when search() doesn't return anything, ignore the error raised and try again
else: #if daily claim fails due to Mudae being ratelimited or something, try again
await asyncio.sleep(3*timeBetweenRolls-typingTime)
await daily(channel)
await asyncio.sleep(timeBetweenRolls-typingTime)
async def doDaily():
for future in asyncio.as_completed(map(daily, Channels)): #basically do daily claiming asyncronously
result = await future #because they have different wait times
@client.event
async def on_ready():
current_time = time.strftime("%D %H:%M:%S", time.localtime())
print(colored(f'[{current_time}] Logged in as {client.user.name}','green'))
global searchOffset
searchOffset= len(search(client.user.name)) #get the amount of integers in a user's name
print(searchOffset)
await asyncio.gather(doRolls(), doDailyClaim(),doDaily()) #when user logs on, call doRolls(), doDailyClaim() and doDaily()
@client.event
async def on_message(message):
if str(message.channel.id) not in Channels:
return #return when a message is not in the user-provided list of channels
#autoclaimer by name and series
try:
title=message.embeds[0].author.name
description=message.embeds[0].description
channelName=message.channel.name
messageClaimRank=list(map(int,re.findall(r"Claims: #(\d+)",description)))[0]
messageKakera=list(map(int,re.findall(r"\*\*(\d+)\*\*<:kakera:469835869059153940>",description)))[0]
if title in characters or any(series in description for series in Series) or (messageClaimRank<=claimRank and claimByClaimRank==True) or (messageKakera>=kakeraValue and claimByKakeraValue==True):
#mudae uses the author field for character names in its embeds.
try:
current_time = time.strftime("%D %H:%M:%S", time.localtime())
print(colored(f"\n[{current_time}] Trying to claim: {str(title)}",'blue'))
await asyncio.sleep(reactionDelay)
try:
if '/' in message.embeds[0].footer.text: #if a character's image card is shown, say someone tried to fool the bot
current_time = time.strftime("%D %H:%M:%S", time.localtime()) #Only image cards contain a "/" in the footer.'
#The reason I don't only search to see if the footer exists
#is because the 2 rolls left message is in the footer too by default
print(colored(f'[{current_time}] Someone tried to fool the bot in channel \'{channelName}\' by sending {title}\'s info card','yellow'))
return
except TypeError: #There won't be a footer on normal sent characters or wishes
pass #because empty embed fields are not iterable
await message.add_reaction(message.reactions[0])
current_time = time.strftime("%D %H:%M:%S", time.localtime())
print(colored(f'\t[{current_time}] Reacted to {title} in channel \'{channelName}\' with ','blue')+colored(f'\'{message.reactions[0]}\'','cyan'))
print(colored(f"\t[{current_time}] Probably claimed {title} in channel '{channelName}'",'green')+'\n\t The above could be a false positive if the if your claim timer is on cooldown.')
except IndexError: #if no reactions
try:
await message.add_reaction("❤️")
current_time = time.strftime("%D %H:%M:%S", time.localtime())
print(colored(f"[{current_time}] \tProbably claimed {title} in channel '{channelName}'",'green', 'on_yellow')+'\n\tThe above could be a false positive if the list of wanted characters has the name of another user\'s harem name in it, or if your claim timer is on cooldown, \nor if somebody is searched for an image of the character you wanted')
except Exception as e: #if anything goes wrong claiming by adding our own reaction, print the exception
current_time = time.strftime("%D %H:%M:%S", time.localtime())
print(colored(f'\t[{current_time}] Could not claim {title} in channel \'{channelName}\' because {e}', 'red'))
except Exception as e: #if anything goes wrong claiming normally
current_time = time.strftime("%D %H:%M:%S", time.localtime())
print(colored(f'\t[{current_time}] Could not claim {title} in channel \'{channelName}\' because {e}', 'red'))
else: #used so the user knows the program is reading the messages successfully.
current_time = time.strftime("%D %H:%M:%S", time.localtime())
print(colored(f"\n[{current_time}] Ignoring {title}, in channel '{channelName}' because they are not wanted",'yellow'))
except IndexError: #This IndexError is used to return when there is no Embed
return
client.run(TOKEN, bot=False) #if you are reading this, have a nice day OwO,
#and you are probably better than me at this lmao