Skip to content

Commit

Permalink
Merge pull request #31 from Asgore-Dreemur/master
Browse files Browse the repository at this point in the history
新增支持库识别
  • Loading branch information
David-xian66 committed Mar 18, 2023
2 parents b84cd09 + e06dcd9 commit 9c7d5ca
Show file tree
Hide file tree
Showing 8 changed files with 335 additions and 3 deletions.
35 changes: 35 additions & 0 deletions Code/MC_Code/DownloadAPIManager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class DownloadAPIRoot:
def __init__(self) -> None:
self.VersionManifest:str = None
self.Libraries:str = None
self.CoreJar:str = None
self.CoreJson:str = None
self.Assets:str = None
self.AssetIndex:str = None


class DownloadAPIManager:
Bmclapi = DownloadAPIRoot()
Mcbbs = DownloadAPIRoot()
Raw = DownloadAPIRoot()
# Bmclapi Start
Bmclapi.AssetIndex = "bmclapi2.bangbang93.com"
Bmclapi.Assets = "https://bmclapi2.bangbang93.com/assets/"
Bmclapi.CoreJar = "https://bmclapi2.bangbang93.com/version/<version>/client"
Bmclapi.CoreJson = "https://bmclapi2.bangbang93.com/version/<version>/json"
Bmclapi.Libraries = "https://bmclapi2.bangbang93.com/maven"
Bmclapi.VersionManifest = "https://bmclapi2.bangbang93.com/mc/game/version_manifest_v2.json"
# Mcbbs Start
Mcbbs.AssetIndex = "download.mcbbs.net"
Mcbbs.Assets = "https://download.mcbbs.net/assets/"
Mcbbs.CoreJar = "https://download.mcbbs.net/version/<version>/client"
Mcbbs.CoreJson = "https://download.mcbbs.net/version/<version>/json"
Mcbbs.VersionManifest = "https://download.mcbbs.net/mc/game/version_manifest_v2.json"
Mcbbs.Libraries = "https://download.mcbbs.net/maven"
# Raw Start
Raw.VersionManifest = "http://launchermeta.mojang.com/mc/game/version_manifest_v2.json"
Raw.Libraries = "https://libraries.minecraft.net"
Raw.Assets = "http://resources.download.minecraft.net"
# Current
Current:DownloadAPIRoot = None

4 changes: 4 additions & 0 deletions Code/MC_Code/DownloadSources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class DownloadSources:
BMCLAPI = 0
RAW = 1
MCBBS = 2
110 changes: 110 additions & 0 deletions Code/MC_Code/GameInstall/MCLibrary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import os,sys,platform
# 这里是模块导入需要
sys.path.append(os.path.abspath(os.path.join(os.path.realpath(__file__),"../../Models")))
sys.path.append(os.path.abspath(os.path.join(os.path.realpath(__file__),"../..")))
from DownloadAPIManager import DownloadAPIManager
from Models import CoreModel

class MCLibrary:
# GetAllLibrary 获取一个版本json里所有的library信息
# param GameJsonE:版本json实体
# result:一个LibraryInfo列表
'''
附录:
LibraryInfo成员:
- Json:library的原json实体
- name:library的命名空间
- path:library json中的path
- url:library的下载url
- isenable:该library是否需要在该系统上被下载
- isnative:该library是不是一个native
'''
@staticmethod
def GetAllLibrary(GameJsonE:CoreModel.LocalMCVersionJson):
libs:list = []
for i in GameJsonE.libraries:
info = CoreModel.LibraryInfo()
info.Json = i
info.name = i.name
if(i.rules is not None):
info.isenable = MCLibrary.isTheSystemNeedTheLibrary(i)
if(i.downloads is None):
if(i.name is None):continue
info.url = DownloadAPIManager.Current.Libraries.strip('/') + "/" + MCLibrary.GetMavenFilePathFromName(i.name)
info.path = MCLibrary.GetMavenFilePathFromName(i.name)
info.isenable = True if i.clientreq is None else i.clientreq
info.isnative = False
libs.append(info)
continue
if(i.downloads.classifiers is not None):
info.isnative = True
info.isenable = MCLibrary.isTheNativeHasTheSysSupport(i)
if(info.isenable):
natkey = i.natives[MCLibrary.GetSysPlatform()].replace(r"${arch}", platform.architecture()[0].strip('bit'))
info.name += ":" + natkey
nfile = i.downloads.classifiers[natkey]
info.size = nfile["size"]
info.path = nfile["path"]
info.url = nfile["url"]
info.checksum = nfile["sha1"]
libs.append(info)
elif(i.downloads.artifact is not None):
info.path = i.downloads.artifact.path
info.size = i.downloads.artifact.size
info.checksum = i.downloads.artifact.sha1
info.url = i.downloads.artifact.url
info.isnative = False
info.name = i.name
libs.append(info)

return libs


# GetMavenFilePathFromName:从library的命名空间中拼出path
# param name:library命名空间
@staticmethod
def GetMavenFilePathFromName(name:str):
array = name.split(":")
namespacepath = array[0].replace('.', os.path.sep)
packagename = array[1]
packagever = array[2]
if(len(array) > 3):
extarray = array[3:]
jarname = packagever + "-" + "-".join(extarray)
return f"{namespacepath}{os.path.sep}{packagename}{os.path.sep}{packagever}{os.path.sep}{packagename}-{jarname}.jar"
return f"{namespacepath}{os.path.sep}{packagename}{os.path.sep}{packagever}{os.path.sep}{packagename}-{packagever}.jar"

# isTheSystemNeedTheLibrary:判断该系统是否需要该支持库
# param lib:library实体json
# result:bool,是否需要
@staticmethod
def isTheSystemNeedTheLibrary(lib:CoreModel.CoreLibraryJson):
windows = unix = macos = False
for i in lib.rules:
if(i.os is None):
windows = unix = macos = True if i.action == "allow" else False
else:
for os in i.os.items():
if(os[1] == "windows"):
windows = True if i.action == "allow" else False
elif(os[1] == "linux"):
unix = True if i.action == "allow" else False
elif(os[1] == "osx"):
macos = True if i.action == "allow" else False
if(sys.platform == "win32"):return windows
elif(sys.platform == "linux"):return unix
elif(sys.platform == "darwin"):return macos
return False

# isTheNativeHasTheSysSupport 用于判断该native是否有该系统需要的版本
# lib:library 实体json
# result:bool,是否有
@staticmethod
def isTheNativeHasTheSysSupport(lib:CoreModel.CoreLibraryJson):
return MCLibrary.GetSysPlatform() in lib.natives

# GetSysPlatform:获取系统平台名
def GetSysPlatform():
if(sys.platform == "win32"):return "windows"
elif(sys.platform == "linux"):return "linux"
elif(sys.platform == "darwin"):return "osx"
101 changes: 101 additions & 0 deletions Code/MC_Code/Models/CoreModel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# 该模块为版本json构造的实体类,可用PyJsonEntity转化
class MCVersions:
def __init__(self) -> None:
self.latest = LatestVersions()
self.versions = [MCVersion()]

class LatestVersions:
def __init__(self) -> None:
self.release = None
self.snapshot = None

class MCVersion:
def __init__(self) -> None:
self.id = None
self.type = None
self.url = None
self.time = None
self.releaseTime = None
self.sha1 = None

class LocalMCVersionJson:
def __init__(self) -> None:
self.arguments = CoreArgumentJson()
self.assetIndex = CoreAssetIndexJson()
self.downloads = CoreDownloadsJson()
self.id = None
self.javaVersion = CoreJavaVersion()
self.libraries = [CoreLibraryJson()]
self.mainClass = None
self.minecraftArguments = None
self.releaseTime = None
self.time = None
self.type = None

class CoreArgumentJson:
def __init__(self) -> None:
self.game = []
self.jvm = []

class CoreAssetIndexJson:
def __init__(self) -> None:
self.id = None
self.sha1 = None
self.size = None
self.totalSize = None
self.url = None

class CoreDownloadsJson:
def __init__(self) -> None:
self.client = CoreDownloadsItemJson()

class CoreDownloadsItemJson:
def __init__(self) -> None:
self.sha1 = None
self.size = None
self.url = None

class CoreJavaVersion:
def __init__(self) -> None:
self.component = None
self.majorVersion = None

class CoreLibraryJson:
def __init__(self) -> None:
self.downloads = CoreLibraryDownloadsJson()
self.name = None
self.rules = [CoreLibraryRuleJson()]
self.checksums = []
self.clientreq = None
self.natives = {}

class CoreLibraryDownloadsJson:
def __init__(self) -> None:
self.artifact = CoreLibraryDownloadFileJson()
self.classifiers = None


class CoreLibraryDownloadFileJson:
def __init__(self) -> None:
self.path = None
self.sha1 = None
self.size = None
self.url = None

class CoreLibraryRuleJson:
def __init__(self) -> None:
self.action:str = None
self.os = {}


# ---- Not Json Classes ----
class LibraryInfo:
def __init__(self) -> None:
self.Json = CoreLibraryJson()
self.url = None
self.size = None
self.name = None
self.path = None
self.checksum = None
self.isenable = None
self.isnative = None
75 changes: 75 additions & 0 deletions Code/MC_Code/Models/PyJsonEntity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import json
class PyJsonEntity:
@staticmethod
def JsonToEntity(jsonstr: str, classobj):
def handlejsonobj(classobj, jdict: dict):
for i in classobj.__dict__.keys():
if (i in jdict.keys()):
value = jdict[i]
if(value is None):
setattr(classobj, i, None)
continue
if (type(value) == dict):
if ("__dict__" not in dir(classobj.__dict__[i])):
setattr(classobj, i, value)
else:
objvalue = handlejsonobj(classobj.__dict__[i], value)
setattr(classobj, i, objvalue)
elif (type(value) == list):
clist = classobj.__dict__[i]
if (type(clist) != list or len(clist) == 0):
setattr(classobj, i, value)
else:
arrvalue = handlejsonarray(clist[0], value)
setattr(classobj, i, arrvalue)
else:
setattr(classobj, i, value)
else:
setattr(classobj, i, None)
return classobj
def handlejsonarray(classobj, listobj):
array = []
for i in listobj:
if(type(i) == list and type(classobj) == list):
array2 = handlejsonarray(classobj[0], i)
array.append(array2)
else:
array.append(handlejsonobj(classobj.__class__(), i))
return array
jdict = json.loads(jsonstr)
return handlejsonobj(classobj, jdict)

@staticmethod
def EntityToJson(classobj):
def handlejsonobj(classobj):
jdict:dict = {}
for i in classobj.__dict__.items():
if(i[1] is None):
continue
if(type(i[1]) == list):
value = handlejsonarray(i[1])
jdict[i[0]] = value
elif("__dict__" in dir(i[1])):
value = handlejsonobj(i[1])
jdict[i[0]] = value
else:
jdict[i[0]] = i[1]
return jdict

def handlejsonarray(listobj:list):
array = []
for i in listobj:
value = None
if(type(i) == list):
value = handlejsonarray(i)
elif("__dict__" in dir(i)):
value = handlejsonobj(i)
else:
value = i
array.append(value)
return array

return handlejsonobj(classobj)



Empty file added Code/MC_Code/Models/__init__.py
Empty file.
13 changes: 10 additions & 3 deletions Code/MC_Code/PyJsonEntity.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ class PyJsonEntity:
@staticmethod
def JsonToEntity(jsonstr: str, classobj):
def handlejsonobj(classobj, jdict: dict):
for i in jdict.keys():
if (i in classobj.__dict__.keys()):
for i in classobj.__dict__.keys():
if (i in jdict.keys()):
value = jdict[i]
if(value is None):
setattr(classobj, i, None)
continue
if (type(value) == dict):
if ("__dict__" not in dir(classobj.__dict__[i])):
setattr(classobj, i, value)
Expand All @@ -21,6 +24,8 @@ def handlejsonobj(classobj, jdict: dict):
setattr(classobj, i, arrvalue)
else:
setattr(classobj, i, value)
else:
setattr(classobj, i, None)
return classobj
def handlejsonarray(classobj, listobj):
array = []
Expand All @@ -39,14 +44,16 @@ def EntityToJson(classobj):
def handlejsonobj(classobj):
jdict:dict = {}
for i in classobj.__dict__.items():
if(i[1] is None):
continue
if(type(i[1]) == list):
value = handlejsonarray(i[1])
jdict[i[0]] = value
elif("__dict__" in dir(i[1])):
value = handlejsonobj(i[1])
jdict[i[0]] = value
else:
jdict[i[0]] =i[1]
jdict[i[0]] = i[1]
return jdict

def handlejsonarray(listobj:list):
Expand Down
Empty file added Code/MC_Code/__init__.py
Empty file.

0 comments on commit 9c7d5ca

Please sign in to comment.