Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

新增支持库识别 #31

Merged
merged 2 commits into from
Mar 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

后期可以优化一下

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.