Files
pymcstatus/srvstatus.py
T
2023-09-04 09:26:57 -06:00

156 lines
4.2 KiB
Python

import io
import math
import base64
import sys
from time import sleep
from threading import Thread
from PIL import Image
from mcstatus import JavaServer
from openpyxl import load_workbook
from openpyxl import Workbook
imgsize = (16,16)
sleeptime = 0.1
nullimg = b"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAaklEQVQ4T62TWw7AIAgEl/sf2qoRY4ywa1tD/JvhoRjGKUAN/RhQY1y3sKdpEltht2Z17Mmm4A3cW3AjE+yVTk4RnNqUBdGMJEE2YCpgr5MKGNymHwoUOBSo8FGw/j72J1LBDfzPMn1d5wfNZUf5qKNxAQAAAABJRU5ErkJggg=="
threadcount = 1
outputfilename = None
def appenddata(ip, latency, pver, ver, cplayers, mplayers, motd, isicon):
book = None
sheet = None
try:
book = load_workbook(filename=outputfilename)
sheet = book.active
except:
book = Workbook()
sheet = book.active
sheet.append(("ip", "latency", "pver", "ver", "cplayers", "mplayers", "motd", "isicon"))
sheet.append((ip, latency, pver, ver, cplayers, mplayers, motd, isicon))
book.save(outputfilename)
def img2ascii(icon):
img = Image.open(io.BytesIO(base64.b64decode(icon)))
img = img.resize(imgsize)
imageSizeW, imageSizeH = img.size
asciiimg = []
for i in range(0, imageSizeW):
curline = ""
for j in range(0, imageSizeH):
pixVal = img.getpixel((j, i))
curline += (f"\033[38;2;{pixVal[0]};{pixVal[1]};{pixVal[2]}m██")
asciiimg.append(curline+"\033[38;2;255;255;255m > ")
return asciiimg
def scanip(ip):
global threadcount
threadcount += 1
try:
server = JavaServer.lookup(ip)
status = server.status()
except:
threadcount -= 1
return False
isicon = None
if status.icon == None:
b64img = nullimg
isicon = False
else:
b64img = status.icon[22:]
isicon = True
try: # In case an icon is invalid
ascii = img2ascii(b64img)
except:
ascii = img2ascii(nullimg)
isicon = False
ver = status.version
players = status.players
motdtxt = status.motd.to_plain()
if outputfilename != None:
appenddata(ip, status.latency, ver.protocol, ver.name, players.online, players.max, motdtxt, isicon)
motd = ["", ""]
if "\n" in motdtxt:
split = motdtxt.split("\n")
motd[0] = split[0]
motd[1] = split[1]
else:
motd[0] = motdtxt
output = ""
for ln in range(0,imgsize[1],1):
line = ascii[ln]
match ln:
case 0:
print("\r\033[K", end="")
line += f"IP: {ip}"
case 1:
line += f"Latency: {math.ceil(status.latency)}ms"
case 2:
line += f"P: {ver.protocol}, V: {ver.name}"
case 3:
line += f"{players.online}/{players.max} Players"
case 5:
line += f"{motd[0]}"
case 6:
line += f"{motd[1]}"
output += f"{line}\n"
#with open("output.txt", "a") as file:
# file.write(f"{output}\n")
print(f"{output}\n") # If everything isn't printed at the same time, the output text could become mixed.
threadcount -= 1
return True
threads = []
if sys.argv[1] == "-p":
if not scanip(sys.argv[2]):
print("Server not online")
elif sys.argv[1] == "-f":
if sys.argv[3] == "-o":
outputfilename = sys.argv[4]
with open(sys.argv[2]) as file:
length = sum(1 for line in open(sys.argv[2]))
for index, ip in enumerate(file):
ip = ip.rstrip()
ipgap = ' '*(15-len(ip))
per = round(100*(index/length), 2)
pergap = ' '*(6-len(str(per)))
thrgap = ' '*(3-len(str(threadcount)))
print(f"Scanning IP: {ip}{ipgap} {pergap}{per}% done {thrgap} {threadcount} pending", end='\r')
thread = Thread(target = scanip, args = (ip, ))
thread.start()
threads.append(thread)
sleep(sleeptime)
scanip(sys.argv[1])
for thread in threads:
thread.join()
else:
print("Usage:\n"+\
"srvstatus.py -p IP\n"+\
"srvstatus.py -f inlist.txt\n"+\
"srvstatus.py -f inlist.txt -o outfile.xlsx")