This repository has been archived on 2022-12-28. You can view files and clone it, but cannot push or open issues or pull requests.
gmclcore/GMCLCore.py
2020-12-06 11:48:13 +08:00

249 lines
13 KiB
Python

#------------------#
import os,requests,json,time,sys,psutil,string,platform,glob,getpass,shutil,hashlib,random,subprocess,math,zipfile,threading
#------------------#
class GMCLCore(object):
'''The Main Class of the Launcher Core'''
#-----------------------------------------------------------------------#
#Class Functions
def __init__(self,LauncherName=None,LauncherVersion=None):
'''The global variable set function'''
''':LauncherName The name of your launcher,the default value is "GMCLCore"'''
''':LauncherVersion The version of your launcher,the default value is the version of core'''
self.__CoreName="GMCLCore"
self.__CoreVersion=["A0.2.0","Alpha"]
self.__LauncherName=LauncherName if(LauncherName!=None) else self.__CoreName
self.__LauncherVersion=LauncherVersion if(LauncherVersion!=None) else self.__CoreVersion
self.__UserAgent={'User-Agent':self.__LauncherName+'/'+self.__LauncherVersion[0]+' (('+self.__CoreName+' '+self.__CoreVersion[0]+';'+self.__CoreVersion[1]+'))'}
self.__Log=[]
self.__AuthWay=""
self.__AutoLogOutput=False
self.__AutoLogPrint=False
self.__AriaDownload=False
self.Log("info","Successful.","__init__")
#-----------------------------------------------------------------------#
#Log Functions
def Log(self,Type,Text,Function="Anonymous Function",ErrorType="TypeError"):
'''The function which was used to manager the log output system'''
''':Type Type of the log info'''
''':Text The main text of log info'''
''':Function The function that cause the log,the default value is "Anonymous Function"'''
''':Type The type of the error,the default value is "TypeError",Support "TypeError","ValueError","UserWarning"'''
if(Text!=""):
if(Type=="info"):
self.__Log.append(("INFO",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()),Function,Text))
if(self.__AutoLogPrint==True):
print("[INFO]["+time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())+"]["+Function+"]"+Text)
return ("INFO",Text)
elif(Type=="warn"):
self.__Log.append(("WARN",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()),Function,Text))
if(self.__AutoLogPrint==True):
print("[WARN]["+time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())+"]["+Function+"]"+Text)
return ("WARN",Text)
elif(Type=="error"):
self.__Log.append(("ERROR",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()),Function,Text,ErrorType))
if(ErrorType=="TypeError"):
raise TypeError(Text)
elif(ErrorType=="ValueError"):
raise ValueError(Text)
else:
raise UserWarning(Text)
else:
self.__Log.append(("OTHER",time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()),Function,Text))
if(self.__AutoLogPrint==True):
print("[OTHER]["+time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())+"]["+Function+"]"+Text)
return ("OTHER",Text)
def OutputLog(self,Path):
'''The function which was used to output text file of program logs'''
if(os.path.isdir(Path)):
return self.Log("warn","Not File.","OutputLog")
else:
self.Log("info","Successful.","OutputLog")
with open(Path,"w+") as FileObject:
FileObject.write(self.__LauncherName+"/"+self.__LauncherVersion[0]+" "+self.__LauncherVersion[1]+" | "+self.__CoreName+"/"+self.__CoreVersion[0]+" "+self.__CoreVersion[1]+" Logs "+time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())+"\n")
for text in self.__Log:
FileObject.write("["+text[0]+"]["+text[1]+"]["+text[2]+"]"+text[3]+"\n")
def ReturnLog(self):
'''The function which was used to return the list of program logs'''
self.Log("info","Successful.","ReturnLog")
return self.__Log
def PrintLastLog(self):
'''The function which was used to print the last logs of program'''
self.Log("info","Successful.","PrintLastLog")
print("["+self.__Log[-1][0]+"]["+self.__Log[-1][1]+"]["+self.__Log[-1][2]+"]"+self.__Log[-1][3])
def PrintAllLog(self):
'''The function which was used to print all logs of program'''
self.Log("info","Successful.","PrintAllLog")
for text in self.__Log:
print("["+text[0]+"]["+text[1]+"]["+text[2]+"]"+text[3])
def EnableAutoLogPrint(self):
'''The function which was used to enable the function of log auto print'''
self.__AutoLogPrint=True
self.Log("info","Successful.","EnableAutoLogPrint")
def DisableAutoLogPrint(self):
'''The function which was used to disable the function of log auto print'''
self.__AutoLogPrint=False
self.Log("info","Successful.","DisableAutoLogPrint")
#-----------------------------------------------------------------------#
#Download Functions
def Download(self,DownloadFrom,DownloadTo):
'''The multi-thread download function'''
''':DownloadFrom The online url for the file'''
''':DownloadTo The local path for the file'''
if(DownloadFrom=="" or DownloadTo==""):
self.Log("warn","Wrong online address or local address for download.","Download")
else:
StartTime=time.time()
FileSize=int(requests.head(DownloadFrom,headers=self.__UserAgent).headers['Content-Length'])
if(self.__AriaDownload==True):
if(platform.system()=="Windows"):
if(os.path.isfile(self.__LauncherName+"\\rely\\"+"aria2c.exe")):
os.system(self.__LauncherName+"\\rely\\"+"aria2c.exe -o "+DownloadTo+" "+DownloadFrom+" -U \""+self.__UserAgent['User-Agent']+"\"")
else:
self.Log("warn","Missed Aria.","Download")
self.DownloadAriaWin()
os.system(self.__LauncherName+"\\rely\\"+"aria2c.exe -o "+DownloadTo+" "+DownloadFrom+" -U \""+self.__UserAgent['User-Agent']+"\"")
else:
os.system(self.__LauncherName+"\\rely\\"+"aria2c.exe -o "+DownloadTo+" "+DownloadFrom+" -U \""+self.__UserAgent['User-Agent']+"\"")
else:
with open(DownloadTo,"wb") as FileObject:
FileObject.write(requests.get(DownloadFrom).content)
self.Log("info","Success.","Download")
return (str(time.time()-StartTime),FileSize // (time.time()-StartTime))
def DownloadAriaWin(self):
'''The function which was used to download Aria environment for windows'''
if(not os.path.isdir(self.__LauncherName+"\\rely")):
self.MakeDir(self.__LauncherName+"\\rely")
if(os.path.isdir("C:\\Program Files (x86)")):
with open(self.__LauncherName+"\\rely\\"+"aria2c.exe","wb") as FileObject:
FileObject.write(requests.get("https://resource.ghink.net/aria2c/win64/aria2c.exe",headers=self.__UserAgent).content)
else:
with open(self.__LauncherName+"\\rely\\"+"aria2c.exe","wb") as FileObject:
FileObject.write(requests.get("https://resource.ghink.net/aria2c/win32/aria2c.exe",headers=self.__UserAgent).content)
self.Log("info","Success.","DownloadAriaWin")
def EnableAriaDownload(self):
'''The function which was used to enable the function of Aria download'''
self.__AriaDownload=True
self.Log("info","Successful.","EnableAriaDownload")
def DisableAriaDownload(self):
'''The function which was used to disable the function of Aria download'''
self.__AriaDownload=False
self.Log("info","Successful.","DisbleAriaDownload")
#-----------------------------------------------------------------------#
#File and Dir Functions
def MakeDir(self,Path):
'''The function which was used to create a dir with determination'''
''':Path The path of the dir you want to create'''
if(not os.path.isdir(Path)):
os.makedirs(Path)
self.Log("info","Successful.","MakeDir")
else:
return self.Log("warn","Exist.","MakeDir")
def SearchFile(self,Path,Tag,Depth=1):
'''The function which was used to search files'''
''':Path The root path you want to search'''
''':Tag The name keyword of the file you want to search'''
''':Depth The depth of dir you want to search,you should set as "all" if you want to search all dirs,the default value is 1'''
List=[]
i=0
for root,dirs,files in os.walk(Path,topdown=True):
if Tag in files:
i+=1
List.append(root+'\\'+Tag)
if(i==Depth):
break
else:
pass
self.Log("info","Success.","SearchFile")
return List
#-----------------------------------------------------------------------#
#Game Environment Set Functions
def GetUUID(self,Account="Steve"):
'''The function which was used to generate UUID'''
''':Account Your account,the default value is "Steve"'''
if(self.__AuthWay=="offline"):
result="OfflinePlayer:"+Account
md5=hashlib.md5()
md5.update(result.encode(encoding='utf-8'))
self.Log("info","Success.","GetUUID")
return md5.hexdigest()
else:
return self.Log("warn","Wrong auth way","GetUUID")
def GetJavaPath(self,Depth=1):
'''The function which was used to search java'''
''':Depth The depth of dir you want to search,you should set as "all" if you want to search all dirs,the default value is 1'''
if(platform.system()=="Windows"):
self.Log("info","Success.","GetJavaPath")
return self.SearchFile('C:\\','javaw.exe',Depth)
elif(platform.system()=="Linux"):
self.Log("info","Success.","GetJavaPath")
return self.SearchFile('\\','java',Depth)
else:
self.Log("info","Success.","GetJavaPath")
return self.SearchFile('\\','java',Depth)
def SetAccount(self,Account="Steve",Password=""):
'''The function which was used to set game account data'''
''':Account Your account,the default value is "Steve"'''
''':Password Your password'''
if(self.__AuthWay=="online_mojang"):
if(Account.count("@")==1):
if(json.loads(requests.get("https://authserver.mojang.com/",headers=self.__UserAgent).text)['status']=="OK"):
result=json.loads(requests.post("https://authserver.mojang.com/authenticate",'{"agent":{"name":"Minecraft","Version":1},"username":"'+Account+'","password":"'+Password+'"}',headers=self.__UserAgent).text)
self.__Token=result['accessToken']
self.__UUID=result['selectedProfile']['id']
self.__ID=result['selectedProfile']['name']
self.Log("info","Success.","GetAccount")
else:
return self.Log("warn","Fail to request Mojang\'s auth server.","SetAccount")
else:
return self.Log("warn","Wrong Account.","SetAccount")
elif(self.__AuthWay=="offline"):
if(Account.count("@")==1):
return self.Log("warn","Wrong Account.","SetAccount")
else:
self.__ID=Account
self.__UUID=self.GetUUID(Account)
self.__Token=""
self.Log("info","Success.","GetAccount")
else:
pass
def SetAuthWay(self,AuthWay):
'''The auth way set function'''
''':AuthWay Your auth way,must be "offline" or "online"'''
if(AuthWay=="offline"):
self.__AuthWay="offline"
self.Log("info","Success.","SetAuthWay")
elif(AuthWay=="online"):
self.__AuthWay="online"
self.Log("info","Success.","SetAuthWay")
else:
return self.Log("warn","Wrong Auth Way.","SetAccount")
def SetRecomMem(self):
'''The recommendation memory value set function'''
self.__Memory = float(psutil.virtual_memory().free / 1024 ** 3) * 0.8
self.Log("info","Success.","SetRecomMem")
def SetJavaPath(self,path):
'''The java path set function'''
''':Path Your java path'''
if(path==None):
return self.Log("warn","Wrong local address for java.","SetJavaPath")
else:
if(os.path.exists(path)):
self.__JAVA=path
self.Log("info","Success.","SetJavaPath")
else:
return self.Log("warn","Wrong local address for java.","SetJavaPath")
def SetGameMem(self,Memory):
'''The game memory value set function'''
''':Memory The memory of the game,the unit is GiBytes'''
try:
self.__Memory=float(Memory)
self.Log("info","Success.","SetGameMem")
except:
return self.Log("warn","Wrong parameter for game memory.","SetGameMem")
#-----------------------------------------------------------------------#
#Game Resouces Functions
#-----------------------------------------------------------------------#
#Game Launch Function
l=GMCLCore()
l.EnableAutoLogPrint()
l.OutputLog("1.txt")