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/core.py

213 lines
9.8 KiB
Python
Raw Normal View History

2020-10-23 05:25:17 +00:00
#------------------#
import os,requests,json,time,sys,psutil,string,platform,glob,getpass,shutil,hashlib,random,subprocess,math,zipfile,threading
2020-10-23 05:25:17 +00:00
#------------------#
class MultiThreadDownload(threading.Thread):
'''The Class for Multi-Thread Download'''
'''Get from Internet and improved by Ghink Network Studio'''
2020-11-07 14:26:28 +00:00
def __init__(self,url,startpos,endpos,f,UA):
super(MultiThreadDownload,self).__init__()
2020-11-07 14:26:28 +00:00
self.url=url
self.startpos=startpos
self.endpos=endpos
self.fd=f
self.UA=UA
def download(self):
2020-11-07 14:26:28 +00:00
headers=self.UA.update({"Range":"bytes=%s-%s"%(self.startpos,self.endpos)})
res=requests.get(self.url,headers=headers)
self.fd.seek(self.startpos)
self.fd.write(res.content)
def run(self):
self.download()
2020-10-23 05:25:17 +00:00
class GMCLCore(object):
'''The Main Class of the Launcher Core'''
2020-11-15 04:30:26 +00:00
def __init__(self,LauncherName="GMCLCore",LauncherVersion="A0.2.0",LogOutput=False):
'''The global variable set function'''
2020-11-15 04:30:26 +00:00
''':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'''
''':LogOutput The switch of the log output function,the default value is False'''
self.__LauncherName=LauncherName
self.__LauncherVersion=LauncherVersion
2020-11-15 04:30:26 +00:00
self.__LogOutput=LogOutput
2020-10-23 05:25:17 +00:00
self.__UserAgent={'User-Agent':LauncherName+'/'+LauncherVersion+' ((GMCL Core Alpha 0.2.0;Alpha))'}
2020-11-15 04:30:26 +00:00
self.__Log=[]
2020-11-20 18:17:32 +00:00
self.__AuthWay=""
self.Log("info","Successful.","__init__")
def __del__(self):
self.Log("info","Successful.","__del__")
2020-11-18 07:38:23 +00:00
def Log(self,Type,Text,Function="Anonymous Function",ErrorType="TypeError"):
2020-11-15 07:54:41 +00:00
'''The function which was used to manager the log output system'''
''':Type Type of the log info'''
''':Text The main text of log info'''
2020-11-18 07:38:23 +00:00
''':Function The function that cause the log,the default value is "Anonymous Function"'''
2020-11-18 07:46:35 +00:00
''':Type The type of the error,the default value is "TypeError",Support "TypeError","ValueError","UserWarning"'''
2020-11-15 07:54:41 +00:00
if(Text!="" or None):
if(Type=="info"):
self.__Log.append(("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))
return ("WARN",Text)
elif(Type=="error"):
2020-11-18 07:38:23 +00:00
self.__Log.append(("ERROR",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),Function,Text,ErrorType))
2020-11-18 07:46:35 +00:00
if(ErrorType=="TypeError"):
raise TypeError(Text)
elif(ErrorType=="ValueError"):
raise ValueError(Text)
else:
raise UserWarning(Text)
2020-11-15 07:54:41 +00:00
else:
self.__Log.append(("OTHER",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),Function,Text))
return ("OTHER",Text)
2020-11-20 18:17:32 +00:00
def ReturnLog(self):
'''The function which was used to return the list of program log'''
self.Log("info","Successful.","ReturnLog")
return self.__Log
def PrintLog(self):
'''The function which was used to print the list of program log'''
self.Log("info","Successful.","PrintLog")
print(self.__Log)
2020-11-15 07:54:41 +00:00
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(os.path.isdir(Path)==False):
os.mkdir(Path)
2020-11-18 08:00:11 +00:00
self.Log("info","Successful.","MakeDir")
2020-11-15 07:54:41 +00:00
else:
return self.Log("warn","Exist.","MakeDir")
def SearchFile(self,Path,Tag,Num=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'''
''':Num How much result you want to get,you should set as "all" if you want to return all result,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==Num):
break
else:
pass
2020-11-18 08:00:11 +00:00
self.Log("info","Success.","SearchFile")
return List
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'))
2020-11-18 08:00:11 +00:00
self.Log("info","Success.","GetUUID")
return md5.hexdigest()
2020-10-23 05:25:17 +00:00
else:
2020-11-18 08:00:11 +00:00
return self.Log("warn","Wrong auth way","GetUUID")
def GetJavaPath(self,Num=1):
'''The function which was used to search java'''
''':Num How much result you want to get,you should set as "all" if you want to return all result,the default value is 1'''
if(platform.system()=="Windows"):
2020-11-18 08:00:11 +00:00
self.Log("info","Success.","GetJavaPath")
return self.SearchFile('C:\\','javaw.exe',Num)
elif(platform.system()=="Linux"):
2020-11-18 08:00:11 +00:00
self.Log("info","Success.","GetJavaPath")
return self.SearchFile('\\','java',Num)
else:
2020-11-18 08:00:11 +00:00
self.Log("info","Success.","GetJavaPath")
return self.SearchFile('\\','java',Num)
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'''
2020-10-30 08:04:26 +00:00
if(self.__AuthWay=="online"):
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']
2020-11-18 08:00:11 +00:00
self.Log("info","Success.","GetAccount")
else:
2020-11-20 18:17:32 +00:00
return self.Log("warn","Fail to request Mojang\'s auth server.","SetAccount")
2020-10-30 08:04:26 +00:00
else:
2020-11-20 18:17:32 +00:00
return self.Log("warn","Wrong Account.","SetAccount")
2020-10-30 08:04:26 +00:00
elif(self.__AuthWay=="offline"):
if(Account.count("@")==1):
2020-11-20 18:17:32 +00:00
return self.Log("warn","Wrong Account.","SetAccount")
2020-10-30 08:04:26 +00:00
else:
self.__ID=Account
self.__UUID=self.GetUUID(Account)
self.__Token=""
2020-11-18 08:00:11 +00:00
self.Log("info","Success.","GetAccount")
2020-10-30 08:04:26 +00:00
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"
2020-11-20 18:17:32 +00:00
self.Log("info","Success.","SetAuthWay")
elif(AuthWay=="online"):
self.__AuthWay="online"
2020-11-20 18:17:32 +00:00
self.Log("info","Success.","SetAuthWay")
2020-10-30 08:04:26 +00:00
else:
2020-11-20 18:17:32 +00:00
self.Log("warn","Wrong Auth Way.","SetAccount")
2020-10-30 12:00:43 +00:00
def SetRecomMem(self):
2020-11-18 07:49:12 +00:00
'''The recommendation memory value set function'''
2020-10-30 12:00:43 +00:00
self.__Memory = float(psutil.virtual_memory().free / 1024 ** 3) * 0.8
2020-11-20 18:17:32 +00:00
self.Log("info","Success.","SetRecomMem")
def SetJavaPath(self,path):
2020-11-18 07:52:35 +00:00
'''The java path set function'''
''':Path Your java path'''
if(path==None):
2020-11-20 18:17:32 +00:00
self.Log("warn","Wrong local address for java.","SetJavaPath")
else:
2020-10-30 12:00:43 +00:00
if(os.path.exists(path)):
self.__JAVA=path
2020-11-20 18:17:32 +00:00
self.Log("info","Success.","SetJavaPath")
2020-10-30 12:00:43 +00:00
else:
2020-11-20 18:17:32 +00:00
self.Log("warn","Wrong local address for java.","SetJavaPath")
2020-10-30 12:00:43 +00:00
def SetGameMem(self,Memory):
2020-11-18 07:52:35 +00:00
'''The game memory value set function'''
''':Memory The memory of the game,the unit is GiBytes'''
2020-10-30 12:00:43 +00:00
try:
self.__Memory=float(Memory)
2020-11-20 18:17:32 +00:00
self.Log("info","Success.","SetGameMem")
2020-10-30 12:00:43 +00:00
except:
2020-11-20 18:17:32 +00:00
self.Log("warn","Wrong parameter for game memory.","SetGameMem")
def Download(self,DownloadFrom,DownloadTo,ThreadNum=3):
2020-11-18 07:52:35 +00:00
'''The multi-thread download function'''
''':DownloadFrom The online url for the file'''
''':DownloadTo The local path for the file'''
''':ThreadNum The number of the thread,the default value is 3'''
2020-10-30 08:04:26 +00:00
if(DownloadFrom=="" or DownloadTo==""):
2020-11-20 18:17:32 +00:00
self.Log("warn","Wrong online address or local address for download.","Download")
2020-10-30 08:04:26 +00:00
else:
2020-11-20 18:17:32 +00:00
url=DownloadFrom
filename=DownloadTo
filesize=int(requests.head(url,headers=self.__UserAgent).headers['Content-Length'])
threadnum=ThreadNum
threading.BoundedSemaphore(threadnum)
2020-11-20 18:17:32 +00:00
step=filesize // threadnum
mtd_list=[]
start=0
end=-1
tempf=open(filename,'w')
tempf.close()
with open(filename,'rb+') as f:
2020-11-20 18:17:32 +00:00
fileno=f.fileno()
while end < filesize -1:
2020-11-20 18:17:32 +00:00
start=end +1
end=start + step -1
if end > filesize:
2020-11-20 18:17:32 +00:00
end=filesize
dup=os.dup(fileno)
fd=os.fdopen(dup,'rb+',-1)
t=MultiThreadDownload(url,start,end,fd,self.__UserAgent)
t.start()
mtd_list.append(t)
2020-11-07 14:26:28 +00:00
for i in mtd_list:
2020-11-20 18:17:32 +00:00
i.join()
self.Log("info","Success.","Download")