diff --git a/Difficult_Rocket/mods/__init__.py b/Difficult_Rocket/mods/__init__.py index c633ee7..49dae4c 100644 --- a/Difficult_Rocket/mods/__init__.py +++ b/Difficult_Rocket/mods/__init__.py @@ -15,11 +15,11 @@ gitee: @shenjackyuanjie from typing import Tuple # from libs -from libs.semver import VersionInfo +from semver import VersionInfo +from MCDR.serializer import Serializable # from DR from Difficult_Rocket import semver_game_version -from Difficult_Rocket.api.serializer import Serializable """ mod系统参数 diff --git a/libs/MCDR/LICENSE.txt b/libs/MCDR/LICENSE.txt new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/libs/MCDR/LICENSE.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/libs/MCDR/Version.py b/libs/MCDR/Version.py new file mode 100644 index 0000000..a32d82d --- /dev/null +++ b/libs/MCDR/Version.py @@ -0,0 +1,199 @@ +# 本文件以 GNU Lesser General Public License v3.0(GNU LGPL v3) 开源协议进行授权 (谢谢狐狸写出这么好的MCDR) +# 顺便说一句,我把所有的tab都改成了空格,因为我觉得空格比tab更好看(草,后半句是github copilot自动填充的) + +""" +Plugin Version +""" +import re +from typing import List, Callable, Tuple, Optional + +""" +This part of code come from MCDReforged(https://github.com/Fallen-Breath/MCDReforged) +Very thanks to Fallen_Breath and other coder who helped MCDR worked better +GNU Lesser General Public License v3.0(GNU LGPL v3) +# (hasn't some changes) +""" + + +# beta.3 -> (beta, 3), random -> (random, None) +class ExtraElement: + DIVIDER = '.' + body: str + num: Optional[int] + + def __init__(self, segment_str: str): + segments = segment_str.rsplit(self.DIVIDER, 1) + try: + self.body, self.num = segments[0], int(segments[1]) + except (IndexError, ValueError): + self.body, self.num = segment_str, None + + def __str__(self): + if self.num is None: + return self.body + return '{}{}{}'.format(self.body, self.DIVIDER, self.num) + + def __lt__(self, other): + if not isinstance(other, type(self)): + raise TypeError() + if self.num is None or other.num is None: + return str(self) < str(other) + else: + return (self.body, self.num) < (other.body, other.num) + + +class Version: + EXTRA_ID_PATTERN = re.compile(r'|[-+0-9A-Za-z]+(\.[-+0-9A-Za-z]+)*') + WILDCARDS = ('*', 'x', 'X') + WILDCARD = -1 + + component: List[int] + has_wildcard: bool + pre: Optional[ExtraElement] + build: Optional[ExtraElement] + + def __init__(self, version_str: str, allow_wildcard=True): + """ + :param str version_str: the version str like '1.2.3-pre4+build.5' + """ + if not isinstance(version_str, str): + raise VersionParsingError('Invalid input version string') + + def separate_extra(text, char) -> Tuple[str, Optional[ExtraElement]]: + if char in text: + text, extra_str = text.split(char, 1) + if not self.EXTRA_ID_PATTERN.fullmatch(extra_str): + raise VersionParsingError('Invalid build string: ' + extra_str) + extra = ExtraElement(extra_str) + else: + extra = None + return text, extra + + self.component = [] + self.has_wildcard = False + version_str, self.build = separate_extra(version_str, '+') + version_str, self.pre = separate_extra(version_str, '-') + if len(version_str) == 0: + raise VersionParsingError('Version string is empty') + for comp in version_str.split('.'): + if comp in self.WILDCARDS: + self.component.append(self.WILDCARD) + self.has_wildcard = True + if not allow_wildcard: + raise VersionParsingError('Wildcard {} is not allowed'.format(comp)) + else: + try: + num = int(comp) + except ValueError: + num = None + if num is None: + raise VersionParsingError('Invalid version number component: {}'.format(comp)) + if num < 0: + raise VersionParsingError('Unsupported negatived number component: {}'.format(num)) + self.component.append(num) + if len(self.component) == 0: + raise VersionParsingError('Empty version string') + + def __str__(self): + version_str = '.'.join(map(lambda c: str(c) if c != self.WILDCARD else self.WILDCARDS[0], self.component)) + if self.pre is not None: + version_str += '-' + str(self.pre) + if self.build is not None: + version_str += '+' + str(self.build) + return version_str + + def __getitem__(self, index): + if index < len(self.component): + return self.component[index] + else: + return self.WILDCARD if self.component[len(self.component) - 1] == self.WILDCARD else 0 + + def __lt__(self, other): + if not isinstance(other, Version): + raise TypeError('Cannot compare between instances of {} and {}'.format(Version.__name__, type(other).__name__)) + for i in range(max(len(self.component), len(other.component))): + if self[i] == self.WILDCARD or other[i] == self.WILDCARD: + continue + if self[i] != other[i]: + return self[i] < other[i] + if self.pre is not None and other.pre is not None: + return self.pre < other.pre + elif self.pre is not None: + return not other.has_wildcard + elif other.pre is not None: + return False + else: + return False + + def __eq__(self, other): + return not self < other and not other < self + + def __le__(self, other): + return self == other or self < other + + def compare_to(self, other): + if self < other: + return -1 + elif self > other: + return 1 + else: + return 0 + + +DEFAULT_CRITERION_OPERATOR = '=' + + +class Criterion: + def __init__(self, opt: str, base_version: Version, criterion: Callable[[Version, Version], bool]): + self.opt = opt + self.base_version = base_version + self.criterion = criterion + + def test(self, target: str or Version): + return self.criterion(self.base_version, target) + + def __str__(self): + return '{}{}'.format(self.opt if self.opt != DEFAULT_CRITERION_OPERATOR else '', self.base_version) + + +class VersionRequirement: + CRITERIONS = { + '<=': lambda base, ver: ver <= base, + '>=': lambda base, ver: ver >= base, + '<': lambda base, ver: ver < base, + '>': lambda base, ver: ver > base, + '=': lambda base, ver: ver == base, + '^': lambda base, ver: ver >= base and ver[0] == base[0], + '~': lambda base, ver: ver >= base and ver[0] == base[0] and ver[1] == base[1], + } + + def __init__(self, requirements: str): + if not isinstance(requirements, str): + raise VersionParsingError('Requirements should be a str, not {}'.format(type(requirements).__name__)) + self.criterions = [] # type: List[Criterion] + for requirement in requirements.split(' '): + if len(requirement) > 0: + for prefix, func in self.CRITERIONS.items(): + if requirement.startswith(prefix): + opt = prefix + base_version = requirement[len(prefix):] + break + else: + opt = DEFAULT_CRITERION_OPERATOR + base_version = requirement + self.criterions.append(Criterion(opt, Version(base_version), self.CRITERIONS[opt])) + + def accept(self, version: Version or str): + if isinstance(version, str): + version = Version(version) + for criterion in self.criterions: + if not criterion.test(version): + return False + return True + + def __str__(self): + return ' '.join(map(str, self.criterions)) + + +class VersionParsingError(ValueError): + pass diff --git a/libs/MCDR/__init__.py b/libs/MCDR/__init__.py new file mode 100644 index 0000000..43badfc --- /dev/null +++ b/libs/MCDR/__init__.py @@ -0,0 +1,12 @@ +# ------------------------------- +# Difficult Rocket +# Copyright © 2021-2022 by shenjackyuanjie +# All rights reserved +# ------------------------------- + +""" +writen by shenjackyuanjie +mail: 3695888@qq.com +github: @shenjackyuanjie +gitee: @shenjackyuanjie +""" diff --git a/Difficult_Rocket/api/serializer.py b/libs/MCDR/serializer.py similarity index 97% rename from Difficult_Rocket/api/serializer.py rename to libs/MCDR/serializer.py index 078c2c2..34ae479 100644 --- a/Difficult_Rocket/api/serializer.py +++ b/libs/MCDR/serializer.py @@ -1,12 +1,6 @@ -# ------------------------------- -# Difficult Rocket -# Copyright © 2021-2022 by shenjackyuanjie -# All rights reserved -# ------------------------------- # 本文件以 GNU Lesser General Public License v3.0(GNU LGPL v3) 开源协议进行授权 (谢谢狐狸写出这么好的MCDR) # 顺便说一句,我把所有的tab都改成了空格,因为我觉得空格比tab更好看(草,后半句是github copilot自动填充的) - import copy from abc import ABC from enum import EnumMeta