forked from duino-coin/duino-coin
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArduino_Miner.py
More file actions
445 lines (360 loc) · 20.9 KB
/
Arduino_Miner.py
File metadata and controls
445 lines (360 loc) · 20.9 KB
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
#!/usr/bin/env python3
##########################################
# Duino-Coin PC Miner (v1.5)
# https://github.com/revoxhere/duino-coin
# Distributed under MIT license
# © revox, MrKris7100 2020
##########################################
import socket, statistics, threading, time, random, re, subprocess, hashlib, platform, getpass, configparser, sys, datetime, os, signal # Import libraries
from pathlib import Path
from signal import signal, SIGINT
try: # Check if colorama is installed
from colorama import init, Fore, Back, Style
except:
now = datetime.datetime.now()
print(now.strftime("%H:%M:%S ") + "Colorama is not installed. Please install it using: python3 -m pip install colorama.\nExiting in 15s.")
time.sleep(15)
os._exit(1)
try: # Check if requests is installed
import requests
except:
now = datetime.datetime.now()
print(now.strftime("%H:%M:%S ") + "Requests is not installed. Please install it using: python3 -m pip install requests.\nExiting in 15s.")
time.sleep(15)
os._exit(1)
try:
import serial
except:
now = datetime.datetime.now()
print(now.strftime("%H:%M:%S ") + "Pyserial is not installed. Please install it using: python3 -m pip install pyserial.\nExiting in 15s.")
time.sleep(15)
os._exit(1)
try:
import serial.tools.list_ports
except:
now = datetime.datetime.now()
print(now.strftime("%H:%M:%S ") + "Serial tools is not installed. Please install it using: python3 -m pip install serial.tools.list_ports.\nExiting in 15s.")
time.sleep(15)
os._exit(1)
# Global variables
VER = "1.5" # Version number
timeout = 5 # Socket timeout
resources = "ArduinoMiner_"+str(VER)+"_resources"
shares = [0, 0]
diff = 0
donatorrunning = False
balance = 0
job = ""
res = "https://raw.githubusercontent.com/revoxhere/duino-coin/gh-pages/serverip.txt" # Serverip file
config = configparser.ConfigParser()
autorestart = 0
donationlevel = 0
pcusername = getpass.getuser() # Username
platform = str(platform.system()) + " " + str(platform.release()) # Platform information
publicip = requests.get("https://api.ipify.org").text # Public IP
try:
os.mkdir(str(resources)) # Create resources folder if it doesn't exist
except:
pass
def title(title):
if os.name == 'nt':
os.system("title "+title)
else:
print('\33]0;'+title+'\a', end='')
sys.stdout.flush()
def handler(signal_received, frame): # If CTRL+C or SIGINT received, send CLOSE request to server in order to exit gracefully.
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "\n%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.GREEN + Fore.WHITE + " sys " + Back.RESET + Fore.YELLOW + " SIGINT detected - Exiting gracefully." + Style.NORMAL + " See you soon!")
try:
soc.send(bytes("CLOSE", encoding="utf8"))
except:
pass
os._exit(0)
signal(SIGINT, handler) # Enable signal handler
def Greeting(): # Greeting message depending on time
global greeting, message, autorestart, st, bytereturn, miningmethod
print(Style.RESET_ALL)
if float(autorestart) <= 0:
autorestart = 0
autorestartmessage = "disabled"
if float(autorestart) > 0:
autorestartmessage = "restarting every " + str(autorestart) + "s"
current_hour = time.strptime(time.ctime(time.time())).tm_hour
if current_hour < 12 :
greeting = "Good morning"
elif current_hour == 12 :
greeting = "Good noon"
elif current_hour > 12 and current_hour < 18 :
greeting = "Good afternoon"
elif current_hour >= 18 :
greeting = "Good evening"
else:
greeting = "Welcome back"
print(" * " + Fore.YELLOW + Style.BRIGHT + "Duino-Coin © Arduino Miner " + Style.RESET_ALL + Fore.YELLOW+ "(v" + str(VER) +".8" + ") 2019-2020") # Startup message
time.sleep(0.15)
print(" * " + Fore.YELLOW + "https://github.com/revoxhere/duino-coin")
time.sleep(0.15)
print(" * " + Fore.YELLOW + "Arduino on port: " + Style.BRIGHT + str(arduinoport))
time.sleep(0.15)
print(" * " + Fore.YELLOW + "Donation level: " + Style.BRIGHT + str(donationlevel))
time.sleep(0.15)
print(" * " + Fore.YELLOW + "Autorestarter: " + Style.BRIGHT + str(autorestartmessage))
time.sleep(0.15)
print(" * " + Fore.YELLOW + str(greeting) + ", " + Style.BRIGHT + str(username) + "\n")
if not Path(str(resources) + "/Miner_executable.exe").is_file(): # Initial miner executable section
url = 'https://github.com/revoxhere/duino-coin/blob/useful-tools/PoT_auto.exe?raw=true'
r = requests.get(url)
with open(str(resources) + '/Miner_executable.exe', 'wb') as f:
f.write(r.content)
def autorestarter(): # Autorestarter
time.sleep(float(autorestart))
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.GREEN + Fore.WHITE + " sys " + Back.RESET + Fore.YELLOW + " Restarting the miner")
os.execl(sys.executable, sys.executable, *sys.argv)
def loadConfig(): # Config loading section
global pool_address, pool_port, username, password, autorestart, donationlevel, arduinoport
if not Path(str(resources) + "/Miner_config.ini").is_file(): # Initial configuration section
print(Style.BRIGHT + "Duino-Coin basic configuration tool.\nEdit "+str(resources) + "/Miner_config.ini file later if you want to change it.")
print(Style.RESET_ALL + "Don't have an Duino-Coin account yet? Use " + Fore.YELLOW + "Wallet" + Fore.WHITE + " to register on server.\n")
username = input(Style.RESET_ALL + Fore.YELLOW + "Enter your username: " + Style.BRIGHT)
password = input(Style.RESET_ALL + Fore.YELLOW + "Enter your password: " + Style.BRIGHT)
print(Style.RESET_ALL + Fore.YELLOW + "Configuration tool has found the following ports:")
portlist = serial.tools.list_ports.comports()
for port in portlist:
print(Style.RESET_ALL + Style.BRIGHT + Fore.YELLOW + " " + str(port))
print(Style.RESET_ALL + Fore.YELLOW + "If you can't see your board port, make sure the board is properly connected and Miner has access to it.")
arduinoport = input(Style.RESET_ALL + Fore.YELLOW + "Enter your board serial port (e.g. COM1 or /dev/ttyUSB1): " + Style.BRIGHT)
autorestart = input(Style.RESET_ALL + Fore.YELLOW + "Set after how many seconds miner shall restart (0 = disable autorestarter): " + Style.BRIGHT)
donationlevel = input(Style.RESET_ALL + Fore.YELLOW + "Set donation level (0-5): " + Style.BRIGHT)
donationlevel = re.sub("\D", "", donationlevel) # Check wheter donationlevel is correct
if float(donationlevel) > int(5):
donationlevel = 5
if float(donationlevel) < int(0):
donationlevel = 0
config['arduminer'] = { # Format data
"username": username,
"password": password,
"arduinoport": arduinoport,
"autorestart": autorestart,
"donate": donationlevel}
with open(str(resources) + "/Miner_config.ini", "w") as configfile: # Write data to file
config.write(configfile)
else: # If config already exists, load from it
config.read(str(resources) + "/Miner_config.ini")
username = config["arduminer"]["username"]
password = config["arduminer"]["password"]
arduinoport = config["arduminer"]["arduinoport"]
autorestart = config["arduminer"]["autorestart"]
donationlevel = config["arduminer"]["donate"]
def Connect(): # Connect to pool section
global soc, connection_counter, res, pool_address, pool_port
while True: # Grab data grom GitHub section
try:
try:
res = requests.get(res, data = None) #Use request to grab data from raw github file
except:
pass
if res.status_code == 200: #Check for response
content = res.content.decode().splitlines() #Read content and split into lines
pool_address = content[0] #Line 1 = pool address
pool_port = content[1] #Line 2 = pool port
now = datetime.datetime.now()
break # Continue
else:
time.sleep(0.025) # Restart if wrong status code
except:
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.BLUE + Fore.WHITE + " net " + Back.RESET + Fore.RED + " Cannot receive pool address and IP.\nExiting in 15 seconds.")
time.sleep(15)
os._exit(1)
time.sleep(0.025)
while True:
try: # Shutdown previous connections if any
soc.shutdown(socket.SHUT_RDWR)
soc.close()
except:
pass
try:
soc = socket.socket()
except:
Connect() # Reconnect if pool down
try: # Try to connect
soc.connect((str(pool_address), int(pool_port)))
soc.settimeout(timeout)
break # If connection was established, continue
except: # If it wasn't, display a message and exit
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.BLUE + Fore.WHITE + " net " + Back.RESET + Fore.RED + " Cannot connect to the server. It is probably under maintenance or temporarily down.\nRetrying in 15 seconds.")
time.sleep(15)
os.execl(sys.executable, sys.executable, *sys.argv)
Connect()
time.sleep(0.025)
def checkVersion():
try:
try:
SERVER_VER = soc.recv(1024).decode() # Check server version
except:
Connect() # Reconnect if pool down
if len(SERVER_VER) != 3:
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.BLUE + Fore.WHITE + " net " + Back.RESET + Fore.RED + " Cannot connect to the server." + Style.RESET_ALL + Fore.RED + " It is probably under maintenance or temporarily down.\nRetrying in 15 seconds.")
time.sleep(15)
os.execl(sys.executable, sys.executable, *sys.argv)
if float(SERVER_VER) <= float(VER) and len(SERVER_VER) == 3: # If miner is up-to-date, display a message and continue
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.BLUE + Fore.WHITE + " net " + Back.RESET + Fore.YELLOW + " Connected" + Style.RESET_ALL + Fore.YELLOW + " to master Duino-Coin server (v"+str(SERVER_VER)+")")
else:
now = datetime.datetime.now()
cont = input(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.GREEN + Fore.WHITE + " sys " + Back.RESET + Fore.RED + " Miner is outdated (v"+VER+")," + Style.RESET_ALL + Fore.RED + " server is on v"+SERVER_VER+", please download latest version from https://github.com/revoxhere/duino-coin/releases/ or type \'continue\' if you wish to continue anyway.\n")
if cont != "continue":
os._exit(1)
except:
Connect() # Reconnect if pool down
def ConnectToArduino():
global com
com = serial.Serial(arduinoport, 115200)
def Login():
global autorestart
while True:
try:
try:
soc.send(bytes("LOGI," + username + "," + password, encoding="utf8")) # Send login data
except:
Connect() # Reconnect if pool down
try:
resp = soc.recv(1024).decode()
except:
Connect() # Reconnect if pool down
if resp == "OK": # Check wheter login information was correct
soc.send(bytes("FROM," + "Arduino_Miner," + str(pcusername) + "," + str(publicip) + "," + str(platform), encoding="utf8")) # Send info to server about client
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.BLUE + Fore.WHITE + " net " + Back.RESET + Fore.YELLOW + " Logged in successfully " + Style.RESET_ALL + Fore.YELLOW + "as " + str(username))
soc.send(bytes("BALA", encoding="utf8")) # Get and round balance from the server
balance = round(float(soc.recv(1024).decode()), 6)
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.BLUE + Fore.WHITE + " net " + Back.RESET + Style.NORMAL + Fore.YELLOW + " Your account balance is " + Style.RESET_ALL + Style.BRIGHT + Fore.YELLOW + str(balance) + " DUCO")
break # If it was, continue
if resp == "NO":
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.BLUE + Fore.WHITE + " net " + Back.RESET + Fore.RED + " Error! Wrong credentials or account doesn't exist!" + Style.RESET_ALL + Fore.RED + "\nIf you don't have an account, register using Wallet!\nExiting in 15 seconds.")
soc.close()
time.sleep(15)
os._exit(1) # If it wasn't, display a message and exit
else:
os.execl(sys.executable, sys.executable, *sys.argv)
except:
os.execl(sys.executable, sys.executable, *sys.argv) # Reconnect if pool down
time.sleep(0.025) # Try again if no response
def ArduinoMine(): # Mining section
global donationlevel, donatorrunning
if int(donationlevel) > 0:
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.GREEN + Fore.WHITE + " sys " + Back.RESET + Fore.RED + " Thank You for being an awesome donator! <3")
else:
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.GREEN + Fore.WHITE + " sys " + Back.RESET + Fore.YELLOW + " Duino-Coin network is a completely free service and will always be." + Style.BRIGHT + Fore.YELLOW + "\n You can help us maintain the server and low-fee payouts by donating.\n Visit " + Style.RESET_ALL + Fore.GREEN + "https://revoxhere.github.io/duino-coin/donate" + Style.BRIGHT + Fore.YELLOW + " to learn more.")
if not donatorrunning: # Check wheter donation was already started
if int(donationlevel) == int(5): # Check donationlevel and if it's more than 0 launch Magi Miner as donation
cmd = "cd " + str(resources) + " & Miner_executable.exe -o stratum+tcp://mining.m-hash.com:3334 -u revox.duinocoin_arduino -p x -e 100 -s 4"
if int(donationlevel) == int(4):
cmd = "cd " + str(resources) + " & Miner_executable.exe -o stratum+tcp://mining.m-hash.com:3334 -u revox.duinocoin_arduino -p x -e 70 -s 4"
if int(donationlevel) == int(3):
cmd = "cd " + str(resources) + " & Miner_executable.exe -o stratum+tcp://mining.m-hash.com:3334 -u revox.duinocoin_arduino -p x -e 50 -s 4"
if int(donationlevel) == int(2):
cmd = "cd " + str(resources) + " & Miner_executable.exe -o stratum+tcp://mining.m-hash.com:3334 -u revox.duinocoin_arduino -p x -e 30 -s 4"
if int(donationlevel) == int(1):
cmd = "cd " + str(resources) + " & Miner_executable.exe -o stratum+tcp://mining.m-hash.com:3334 -u revox.duinocoin_arduino -p x -e 10 -s 4"
if int(donationlevel) == int(0):
cmd = "cd " + str(resources)
try: # Start cmd set above
subprocess.Popen(cmd, shell=True, stderr=subprocess.DEVNULL) # Open command
donatorrunning = True
except:
pass
now = datetime.datetime.now()
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.GREEN + Fore.WHITE + " sys " + Back.RESET + Fore.YELLOW + " Arduino mining thread started" + Style.RESET_ALL + Fore.YELLOW + " using DUCO-S1A algorithm, be aware that finding first share may take a while")
ready = com.readline().decode().rstrip().lstrip() # Arduino will send ready signal
while True:
com.write(bytes("start\n", encoding="utf8")) # hash
soc.send(bytes("Job",encoding="utf8")) # Send job request to server
job = soc.recv(1024).decode().split(",") # Split received job
com.write(bytes(str(job[0])+"\n", encoding="utf8")) # hash
time.sleep(0.05)
com.write(bytes(str(job[1])+"\n", encoding="utf8")) # job
time.sleep(0.05)
com.write(bytes(str(job[2])+"\n", encoding="utf8")) # diff
computestart = datetime.datetime.now() # Get timestamp of start of the computing
result = com.readline().decode().rstrip().lstrip() # Send hash, job and difficulty to the board using serial
soc.send(bytes(str(result), encoding="utf8")) # Send result of hashing algorithm to pool
while True:
feedback = soc.recv(1024).decode() # Get feedback
time.sleep(0.025)
if feedback == "GOOD": # If result was good
now = datetime.datetime.now()
computetime = now - computestart # Time from start of hash computing to finding the result
computetime = str(int(computetime.microseconds / 1000)) # Convert to ms
shares[0] = shares[0] + 1 # Share rejected = increment correct shares counter by 1
title("Duino-Coin Arduino Miner (v"+str(VER)+") - " + str(shares[0]) + "/" + str(shares[0] + shares[1]) + " accepted shares")
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.YELLOW + Fore.WHITE + " avr " + Back.RESET + Fore.GREEN + " Accepted " + Fore.YELLOW + str(shares[0]) + "/" + str(shares[0] + shares[1]) + Back.RESET + Style.DIM + " (" + str(round((shares[0] / (shares[0] + shares[1]) * 100), 2)) + "%) " + Style.NORMAL + Fore.WHITE + "• diff " + str(job[2]) + " • " + Style.BRIGHT + Fore.BLUE + computetime + "ms avr time " + Style.RESET_ALL + Style.BRIGHT + Fore.YELLOW + "(yay!!!)")
break # Repeat
elif feedback == "GOOD": # If result was good
now = datetime.datetime.now()
computetime = now - computestart # Time from start of hash computing to finding the result
computetime = str(int(computetime.microseconds / 1000)) # Convert to ms
shares[0] = shares[0] + 1 # Share rejected = increment correct shares counter by 1
title("Duino-Coin Arduino Miner (v"+str(VER)+") - " + str(shares[0]) + "/" + str(shares[0] + shares[1]) + " accepted shares")
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.YELLOW + Fore.WHITE + " avr " + Back.RESET + Fore.GREEN + " Block accepted ("+str(job[0])[:8]+") " + Fore.YELLOW + str(shares[0]) + "/" + str(shares[0] + shares[1]) + Back.RESET + Style.DIM + " (" + str(round((shares[0] / (shares[0] + shares[1]) * 100), 2)) + "%) " + Style.NORMAL + Fore.WHITE + "• diff " + str(job[2]) + " • " + Style.BRIGHT + Fore.BLUE + computetime + "ms avr time " + Style.RESET_ALL + Style.BRIGHT + Fore.YELLOW + "(yay!!!)")
break # Repeat
elif feedback == "BAD": # If result was bad
now = datetime.datetime.now()
computetime = now - computestart # Time from start of hash computing to finding the result
computetime = str(int(computetime.microseconds / 1000)) # Convert to ms
shares[1] = shares[1] + 1 # Share rejected = increment rejected shares counter by 1
title("Duino-Coin Arduino Miner (v"+str(VER)+") - " + str(shares[0]) + "/" + str(shares[0] + shares[1]) + " accepted shares")
print(now.strftime(Style.DIM + "%H:%M:%S ") + Style.RESET_ALL + Style.BRIGHT + Back.YELLOW + Fore.WHITE + " avr " + Back.RESET + Fore.RED + " Rejected " + Fore.YELLOW + str(shares[1]) + "/" + str(shares[1] + shares[1]) + Back.RESET + Style.DIM + " (" + str(round((shares[0] / (shares[0] + shares[1]) * 100), 2)) + "%) " + Style.NORMAL + Fore.WHITE + "• diff " + str(job[2]) + " • " + Style.BRIGHT + Fore.BLUE + computetime + "ms avr time " + Style.RESET_ALL + Style.BRIGHT + Fore.RED + "(boo!!!)")
break # Repeat
init(autoreset=True) # Enable colorama
while True:
title("Duino-Coin Arduino Miner (v"+str(VER)+")")
try:
loadConfig() # Load configfile
except:
print(Style.RESET_ALL + Style.BRIGHT + Fore.RED + " There was an error loading the configfile. Try removing it and re-running configuration. Exiting in 15s." + Style.RESET_ALL)
time.sleep(15)
os._exit(1)
try: # Setup autorestarter
if float(autorestart) > 0:
threading.Thread(target=autorestarter).start()
except:
print(Style.RESET_ALL + Style.BRIGHT + Fore.RED + " There was an error in autorestarter. Check configuration file. Exiting in 15s." + Style.RESET_ALL)
time.sleep(15)
os._exit(1)
try:
Greeting() # Display greeting message
except:
pass
try:
Connect() # Connect to pool
except:
print(Style.RESET_ALL + Style.BRIGHT + Fore.RED + " There was an error while connecting to the server. Restarting in 15 seconds." + Style.RESET_ALL)
time.sleep(15)
os.execl(sys.executable, sys.executable, *sys.argv)
try:
checkVersion() # Check version
except:
print(Style.RESET_ALL + Style.BRIGHT + Fore.RED + " There was an error while connecting to the server. Restarting in 15 seconds." + Style.RESET_ALL)
time.sleep(15)
os.execl(sys.executable, sys.executable, *sys.argv)
try:
Login() # Login
except:
print(Style.RESET_ALL + Style.BRIGHT + Fore.RED + " There was an error while logging-in. Restarting." + Style.RESET_ALL)
os.execl(sys.executable, sys.executable, *sys.argv)
ConnectToArduino() # Connect to AVR board
try:
ArduinoMine()
except:
print(Style.RESET_ALL + Style.BRIGHT + Fore.RED + " There was an error while mining. Restarting." + Style.RESET_ALL)
os.execl(sys.executable, sys.executable, *sys.argv)
print(Style.RESET_ALL + Style.RESET_ALL)
time.sleep(0.025) # Restart