add 1.20
This commit is contained in:
commit
7784fddd27
7
.gitattributes
vendored
Normal file
7
.gitattributes
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/gradlew text eol=lf
|
||||||
|
*.jar binary
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
*.class binary
|
||||||
|
* text=auto eol=lf
|
||||||
|
*.bat text eol=crlf
|
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Ignore Gradle project-specific cache directory
|
||||||
|
.gradle
|
||||||
|
|
||||||
|
# Ignore Gradle build output directory
|
||||||
|
build
|
||||||
|
|
||||||
|
.idea
|
||||||
|
mod_build
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
run
|
||||||
|
|
||||||
|
pnpm-lock.yaml
|
||||||
|
|
||||||
|
dist
|
35
.prettierrc
Normal file
35
.prettierrc
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/prettierrc",
|
||||||
|
"printWidth": 120,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"quoteProps": "as-needed",
|
||||||
|
"trailingComma": "all",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"arrowParens": "always",
|
||||||
|
"rangeStart": 0,
|
||||||
|
"vueIndentScriptAndStyle": false,
|
||||||
|
"endOfLine": "auto",
|
||||||
|
"semi": true,
|
||||||
|
"requirePragma": false,
|
||||||
|
"bracketSameLine": true,
|
||||||
|
"htmlWhitespaceSensitivity": "ignore",
|
||||||
|
"plugins": [
|
||||||
|
"prettier-plugin-java"
|
||||||
|
],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "*.json",
|
||||||
|
"options": {
|
||||||
|
"tabWidth": 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": "*.java",
|
||||||
|
"options": {
|
||||||
|
"tabWidth": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
202
LICENSE
Normal file
202
LICENSE
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
64
build.gradle.kts
Normal file
64
build.gradle.kts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
apply(plugin = "java")
|
||||||
|
apply(plugin = "idea")
|
||||||
|
tasks.withType<AbstractArchiveTask>().configureEach() {
|
||||||
|
destinationDirectory.set(
|
||||||
|
rootProject.projectDir.resolve("mod_build")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
tasks.named("jar") {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
|
tasks.withType<JavaCompile>().configureEach {
|
||||||
|
options.release.set(17)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tasks.withType<JavaExec> {
|
||||||
|
jvmArgs = listOf(
|
||||||
|
"-Dfile.encoding=UTF-8",
|
||||||
|
"-Dsun.stdout.encoding=UTF-8",
|
||||||
|
"-Dsun.stderr.encoding=UTF-8"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
tasks.withType<JavaCompile> {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
val loaders = listOf("Fabric", "Forge", "NeoForge")
|
||||||
|
val mod_minecrat_versions: String by project
|
||||||
|
|
||||||
|
val modVersions = mod_minecrat_versions.split(",")
|
||||||
|
|
||||||
|
modVersions.forEach {
|
||||||
|
tasks.register("build_$it") {
|
||||||
|
group = "mod_${it}"
|
||||||
|
dependsOn(":modsrc:${it}:shadowJar")
|
||||||
|
}
|
||||||
|
loaders.forEach { ti ->
|
||||||
|
run {
|
||||||
|
if (findProject(":modsrc:$it:$ti") != null) {
|
||||||
|
println("$it:$ti")
|
||||||
|
tasks.register("${ti}RunServer_$it") {
|
||||||
|
group = "mod_$it"
|
||||||
|
dependsOn(":modsrc:$it:$ti:runServer")
|
||||||
|
}
|
||||||
|
tasks.register("${ti}RunClient_$it") {
|
||||||
|
group = "mod_$it"
|
||||||
|
dependsOn(":modsrc:$it:$ti:runClient")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register("cleanAll", Delete::class) {
|
||||||
|
subprojects.forEach{
|
||||||
|
val task = it.tasks.findByName("clean")
|
||||||
|
if (task != null){
|
||||||
|
dependsOn(task)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
group = "build"
|
||||||
|
delete("mod_build")
|
||||||
|
}
|
37
common/build.gradle.kts
Normal file
37
common/build.gradle.kts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
plugins {
|
||||||
|
id("java-library")
|
||||||
|
id("java")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val java_version: String by project
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain {
|
||||||
|
languageVersion.set(JavaLanguageVersion.of(java_version))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java { srcDirs("src") }
|
||||||
|
resources { srcDirs("resources",rootProject.rootDir.resolve("dist")) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "mingliqiye repository"
|
||||||
|
url = uri("https://gitee.com/minglipro/maven-repository-raw/raw/master")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
implementation("io.javalin:javalin:6.7.0")
|
||||||
|
implementation("com.fasterxml.jackson.core:jackson-databind:2.19.1")
|
||||||
|
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.19.1")
|
||||||
|
implementation("com.mingliqiye:string-utils:1.0.4")
|
||||||
|
|
||||||
|
compileOnlyApi("org.slf4j:slf4j-api:2.0.7")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.jar {
|
||||||
|
enabled = true
|
||||||
|
}
|
1
common/gradle.properties
Normal file
1
common/gradle.properties
Normal file
@ -0,0 +1 @@
|
|||||||
|
java_version=17
|
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"enchantment.minecraft.damage": {
|
||||||
|
"allow": true,
|
||||||
|
"allowlist": [
|
||||||
|
"enchantment.minecraft.sharpness",
|
||||||
|
"enchantment.minecraft.smite",
|
||||||
|
"enchantment.minecraft.bane_of_arthropods"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"enchantment.minecraft.infinity": {
|
||||||
|
"allow": true,
|
||||||
|
"allowlist": ["enchantment.minecraft.infinity", "enchantment.minecraft.mending"]
|
||||||
|
},
|
||||||
|
"enchantment.minecraft.protection": {
|
||||||
|
"allow": true,
|
||||||
|
"allowlist": [
|
||||||
|
"enchantment.minecraft.protection",
|
||||||
|
"enchantment.minecraft.fire_protection",
|
||||||
|
"enchantment.minecraft.blast_protection",
|
||||||
|
"enchantment.minecraft.projectile_protection"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"enchantment.minecraft.piercing": {
|
||||||
|
"allow": true,
|
||||||
|
"allowlist": ["enchantment.minecraft.piercing", "enchantment.minecraft.multishot"]
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"minecraft:damage": {
|
||||||
|
"allow": true,
|
||||||
|
"allowlist": [
|
||||||
|
"minecraft:sharpness",
|
||||||
|
"minecraft:smite",
|
||||||
|
"minecraft:bane_of_arthropods",
|
||||||
|
"minecraft:density",
|
||||||
|
"minecraft:breach"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"minecraft:infinity": {
|
||||||
|
"allow": true,
|
||||||
|
"allowlist": [
|
||||||
|
"minecraft:infinity",
|
||||||
|
"minecraft:mending"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"minecraft:protection": {
|
||||||
|
"allow": true,
|
||||||
|
"allowlist": [
|
||||||
|
"minecraft:protection",
|
||||||
|
"minecraft:fire_protection",
|
||||||
|
"minecraft:blast_protection",
|
||||||
|
"minecraft:projectile_protection"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"minecraft:piercing": {
|
||||||
|
"allow": true,
|
||||||
|
"allowlist": [
|
||||||
|
"minecraft:piercing",
|
||||||
|
"minecraft:multishot"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
Binary file not shown.
After Width: | Height: | Size: 218 KiB |
@ -0,0 +1,113 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import static com.mingliqiye.minecraft.enchantment.conflict.common.DataFormat.JSONOBJECTMAPPER;
|
||||||
|
import static com.mingliqiye.minecraft.enchantment.conflict.common.DataFormat.YALMOBJECTMAPPER;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JavaType;
|
||||||
|
import com.mingliqiye.utils.StringUtil;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
public class ConfigManager {
|
||||||
|
|
||||||
|
private final String FILE_NAME = StringUtil.format("{}.yaml", MinecraftMod.MOD_ID);
|
||||||
|
private final DefConfig defConfig;
|
||||||
|
|
||||||
|
public static final JavaType MODCONFIGTYPE = JSONOBJECTMAPPER.getTypeFactory().constructMapType(
|
||||||
|
Map.class,
|
||||||
|
String.class,
|
||||||
|
ConfigPair.class
|
||||||
|
);
|
||||||
|
|
||||||
|
public static Map<String, ConfigPair> fromyaml(String s) {
|
||||||
|
try {
|
||||||
|
return YALMOBJECTMAPPER.readValue(s, MODCONFIGTYPE);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toyaml(Map<String, ConfigPair> c) {
|
||||||
|
try {
|
||||||
|
return YALMOBJECTMAPPER.writeValueAsString(c);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, ConfigPair> fromjson(String s) {
|
||||||
|
try {
|
||||||
|
return JSONOBJECTMAPPER.readValue(s, MODCONFIGTYPE);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String tojson(Map<String, ConfigPair> c) {
|
||||||
|
try {
|
||||||
|
return JSONOBJECTMAPPER.writeValueAsString(c);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ConfigPair> getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfig(Map<String, ConfigPair> config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, ConfigPair> config;
|
||||||
|
private final Path configPath;
|
||||||
|
private final Logger log;
|
||||||
|
private final Path configFile;
|
||||||
|
private final VersionsEnum versions;
|
||||||
|
|
||||||
|
public ConfigManager(Path configPath, Logger log, VersionsEnum versions) {
|
||||||
|
this.versions = versions;
|
||||||
|
defConfig = new DefConfig(versions);
|
||||||
|
this.log = log;
|
||||||
|
configFile = configPath.resolve(FILE_NAME);
|
||||||
|
this.configPath = configPath;
|
||||||
|
config = load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ConfigPair> load() {
|
||||||
|
try {
|
||||||
|
if (Files.exists(configFile)) {
|
||||||
|
log.info("{} 配置加载", MinecraftMod.MOD_ID);
|
||||||
|
return YALMOBJECTMAPPER.readValue(Files.readString(configFile), MODCONFIGTYPE);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to load config", e);
|
||||||
|
}
|
||||||
|
return save(defConfig.getConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ConfigPair> save() {
|
||||||
|
return save(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ConfigPair> save(Map<String, ConfigPair> configs) {
|
||||||
|
try {
|
||||||
|
Files.writeString(configFile, YALMOBJECTMAPPER.writeValueAsString(configs));
|
||||||
|
log.info("{} 配置已保存", MinecraftMod.MOD_ID);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to save config", e);
|
||||||
|
}
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VersionsEnum getVersions() {
|
||||||
|
return versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefConfig getDefConfig() {
|
||||||
|
return defConfig;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ConfigPair {
|
||||||
|
|
||||||
|
private Boolean allow;
|
||||||
|
private List<String> allowlist;
|
||||||
|
|
||||||
|
public ConfigPair() {}
|
||||||
|
|
||||||
|
ConfigPair(Boolean allow, List<String> allowlist) {
|
||||||
|
this.allow = allow;
|
||||||
|
this.allowlist = allowlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getAllowlist() {
|
||||||
|
return allowlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowlist(List<String> allowlist) {
|
||||||
|
this.allowlist = new ArrayList<>(allowlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigPair add(String item) {
|
||||||
|
allowlist.add(item);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigPair add(String... items) {
|
||||||
|
allowlist.addAll(List.of(items));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getAllow() {
|
||||||
|
return allow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllow(Boolean allow) {
|
||||||
|
this.allow = allow;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
|
|
||||||
|
public class DataFormat {
|
||||||
|
|
||||||
|
public static final ObjectMapper YALMOBJECTMAPPER = new ObjectMapper(new YAMLFactory());
|
||||||
|
public static final ObjectMapper JSONOBJECTMAPPER = new ObjectMapper();
|
||||||
|
}
|
@ -0,0 +1,248 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonView;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>自定义时间类
|
||||||
|
*
|
||||||
|
* @author MingLiPro|Armamem0t
|
||||||
|
* @version 1.0
|
||||||
|
* @see LocalDateTime
|
||||||
|
* @see Date
|
||||||
|
* @see ZoneId
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = DateTimeJsonSerializer.class)
|
||||||
|
@JsonDeserialize(using = DateTimeJsonDeserializer.class)
|
||||||
|
@JsonView(String.class)
|
||||||
|
public class DateTime implements Serializable {
|
||||||
|
|
||||||
|
public LocalDateTime getLocalDateTime() {
|
||||||
|
return localDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalDateTime(LocalDateTime localDateTime) {
|
||||||
|
this.localDateTime = localDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LocalDateTime localDateTime;
|
||||||
|
private ZoneId zoneId = ZoneId.systemDefault();
|
||||||
|
|
||||||
|
DateTime() {
|
||||||
|
this(Instant.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime(Instant instant) {
|
||||||
|
this(LocalDateTime.ofInstant(instant, ZoneId.systemDefault()));
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime(LocalDateTime localDateTime) {
|
||||||
|
this.localDateTime = localDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime(Instant instant, ZoneId zoneId) {
|
||||||
|
this(LocalDateTime.ofInstant(instant, zoneId));
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime(Date date) {
|
||||||
|
this(date.toInstant());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime now() {
|
||||||
|
return new DateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime ofCurrentTimeMillis(long time) {
|
||||||
|
return new DateTime(Instant.ofEpochMilli(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime of(Instant instant) {
|
||||||
|
return new DateTime(instant);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String format(Date date, String formater) {
|
||||||
|
return format(toLocalDateTime(date), formater);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String format(LocalDateTime date, String formater) {
|
||||||
|
return DateTimeFormatter.ofPattern(formater).format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LocalDateTime toLocalDateTime(Date date) {
|
||||||
|
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String format(LocalDateTime date, Formats formats) {
|
||||||
|
return format(date, formats.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime parse(String timestr, Formats formater) {
|
||||||
|
return parse(timestr, formater.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime parse(String timestr, String formater) {
|
||||||
|
DateTimeFormatter sdf = DateTimeFormatter.ofPattern(formater);
|
||||||
|
return of(LocalDateTime.parse(timestr, sdf));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime of(LocalDateTime localDateTime) {
|
||||||
|
return new DateTime(localDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return (
|
||||||
|
this.getClass().getName() +
|
||||||
|
'@' +
|
||||||
|
Integer.toHexString(hashCode()) +
|
||||||
|
'(' +
|
||||||
|
format(Formats.STANDARD_DATETIME_MILLISECOUND7) +
|
||||||
|
")"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format(Formats formater) {
|
||||||
|
return format(localDateTime, formater.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant toInstant() {
|
||||||
|
return toInstant(localDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Instant toInstant(LocalDateTime localDateTime) {
|
||||||
|
return toInstant(localDateTime, ZoneId.systemDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Instant toInstant(LocalDateTime localDateTime, ZoneId zoneId) {
|
||||||
|
return localDateTime.atZone(zoneId).toInstant();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant toInstant(ZoneId zoneId) {
|
||||||
|
return toInstant(localDateTime, zoneId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date toDate() {
|
||||||
|
return toDate(localDateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Date toDate(LocalDateTime localDateTime) {
|
||||||
|
return Date.from(toInstant(localDateTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format(String formater) {
|
||||||
|
return format(localDateTime, formater);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime plusYears(long years) {
|
||||||
|
return plusYears(this, years);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime plusYears(DateTime dateTime, long years) {
|
||||||
|
dateTime.setLocalDateTime(dateTime.getLocalDateTime().plusYears(years));
|
||||||
|
return dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime plusMonths(long months) {
|
||||||
|
return plusMonths(this, months);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime plusMonths(DateTime dateTime, long months) {
|
||||||
|
dateTime.setLocalDateTime(dateTime.getLocalDateTime().plusMonths(months));
|
||||||
|
return dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime plusWeeks(long weeks) {
|
||||||
|
return plusWeeks(this, weeks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime plusWeeks(DateTime dateTime, long weeks) {
|
||||||
|
dateTime.setLocalDateTime(dateTime.getLocalDateTime().plusWeeks(weeks));
|
||||||
|
return dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime plusDays(long days) {
|
||||||
|
return plusDays(this, days);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime plusDays(DateTime dateTime, long days) {
|
||||||
|
dateTime.setLocalDateTime(dateTime.getLocalDateTime().plusDays(days));
|
||||||
|
return dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime plusHours(long hours) {
|
||||||
|
return plusHours(this, hours);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime plusHours(DateTime dateTime, long hours) {
|
||||||
|
dateTime.setLocalDateTime(dateTime.getLocalDateTime().plusHours(hours));
|
||||||
|
return dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime plusMinutes(long minutes) {
|
||||||
|
return plusMinutes(this, minutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime plusMinutes(DateTime dateTime, long minutes) {
|
||||||
|
dateTime.setLocalDateTime(dateTime.getLocalDateTime().plusMinutes(minutes));
|
||||||
|
return dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime plusSeconds(long seconds) {
|
||||||
|
return plusSeconds(this, seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime plusSeconds(DateTime dateTime, long seconds) {
|
||||||
|
dateTime.setLocalDateTime(dateTime.getLocalDateTime().plusSeconds(seconds));
|
||||||
|
return dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime plusNanos(long nanos) {
|
||||||
|
return plusNanos(this, nanos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateTime plusNanos(DateTime dateTime, long nanos) {
|
||||||
|
dateTime.setLocalDateTime(dateTime.getLocalDateTime().plusNanos(nanos));
|
||||||
|
return dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZoneId getZoneId() {
|
||||||
|
return zoneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZoneId(ZoneId zoneId) {
|
||||||
|
this.zoneId = zoneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Formats {
|
||||||
|
STANDARD_DATETIME("yyyy-MM-dd HH:mm:ss"),
|
||||||
|
STANDARD_DATETIME_MILLISECOUND7("yyyy-MM-dd HH:mm:ss.SSSSSSS"),
|
||||||
|
STANDARD_DATETIME_MILLISECOUND6("yyyy-MM-dd HH:mm:ss.SSSSSS"),
|
||||||
|
STANDARD_DATETIME_MILLISECOUND5("yyyy-MM-dd HH:mm:ss.SSSSS"),
|
||||||
|
STANDARD_DATETIME_MILLISECOUND4("yyyy-MM-dd HH:mm:ss.SSSS"),
|
||||||
|
STANDARD_DATETIME_MILLISECOUND3("yyyy-MM-dd HH:mm:ss.SSS"),
|
||||||
|
STANDARD_DATETIME_MILLISECOUND2("yyyy-MM-dd HH:mm:ss.SS"),
|
||||||
|
STANDARD_DATETIME_MILLISECOUND1("yyyy-MM-dd HH:mm:ss.S"),
|
||||||
|
STANDARD_ISO("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"),
|
||||||
|
STANDARD_DATETIME_SECOUND("yyyy-MM-dd HH:mm:ss"),
|
||||||
|
STANDARD_DATE("yyyy-MM-dd"),
|
||||||
|
ISO8601("yyyy-MM-dd'T'HH:mm:ss.SSS'000'"),
|
||||||
|
COMPACT_DATETIME("yyyyMMddHHmmss");
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
Formats(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class DateTimeJsonDeserializer extends JsonDeserializer<DateTime> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||||
|
if (p.isNaN()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return DateTime.parse(p.getValueAsString(), DateTime.Formats.STANDARD_DATETIME_MILLISECOUND6);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.core.JsonToken;
|
||||||
|
import com.fasterxml.jackson.core.type.WritableTypeId;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class DateTimeJsonSerializer extends JsonSerializer<DateTime> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(DateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||||
|
if (value == null) {
|
||||||
|
gen.writeNull();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen.writeString(value.format(DateTime.Formats.STANDARD_DATETIME_MILLISECOUND6));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serializeWithType(
|
||||||
|
DateTime value,
|
||||||
|
JsonGenerator gen,
|
||||||
|
SerializerProvider serializers,
|
||||||
|
TypeSerializer typeSer
|
||||||
|
) throws IOException {
|
||||||
|
WritableTypeId typeId = typeSer.writeTypePrefix(gen, typeSer.typeId(value, JsonToken.VALUE_STRING));
|
||||||
|
serialize(value, gen, serializers);
|
||||||
|
typeSer.writeTypeSuffix(gen, typeId);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import static com.mingliqiye.minecraft.enchantment.conflict.common.DataFormat.JSONOBJECTMAPPER;
|
||||||
|
import static com.mingliqiye.minecraft.enchantment.conflict.common.DataFormat.YALMOBJECTMAPPER;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class DefConfig {
|
||||||
|
|
||||||
|
private static final String DEFCONFIGPATH = "/assets/enchantmentdoesnotconflict/config/";
|
||||||
|
private static final String DEFCONFIGV121PATH = DEFCONFIGPATH + "enchantmentdoesnotconflict_1.21.json";
|
||||||
|
private static final String DEFCONFIGV120PATH = DEFCONFIGPATH + "enchantmentdoesnotconflict_1.20.json";
|
||||||
|
private final Map<String, ConfigPair> config121;
|
||||||
|
private final Map<String, ConfigPair> config120;
|
||||||
|
private final VersionsEnum versionsEnum;
|
||||||
|
|
||||||
|
public static String getResByString(String path) {
|
||||||
|
try (InputStream i = DefConfig.class.getResourceAsStream(path)) {
|
||||||
|
byte[] data = i.readAllBytes();
|
||||||
|
return new String(data, StandardCharsets.UTF_8);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefConfig(VersionsEnum versionsEnum) {
|
||||||
|
try {
|
||||||
|
config121 = JSONOBJECTMAPPER.readValue(getResByString(DEFCONFIGV121PATH), ConfigManager.MODCONFIGTYPE);
|
||||||
|
config120 = JSONOBJECTMAPPER.readValue(getResByString(DEFCONFIGV120PATH), ConfigManager.MODCONFIGTYPE);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
this.versionsEnum = versionsEnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ConfigPair> getConfig121() {
|
||||||
|
return config121;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ConfigPair> getConfig120() {
|
||||||
|
return config120;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ConfigPair> getConfig() {
|
||||||
|
if (versionsEnum == VersionsEnum.V120) {
|
||||||
|
return getConfig120();
|
||||||
|
} else if (versionsEnum == VersionsEnum.V121) {
|
||||||
|
return getConfig121();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
public enum ExceptionCode {
|
||||||
|
ERROR_INTERNAL_SERVER(500),
|
||||||
|
ERROR_PAYMENT_REQUIRED(402),
|
||||||
|
ERROR_NOT_FOUND(404),
|
||||||
|
ERROR_METHOD_NOT_ALLOWED(405),
|
||||||
|
ERROR_UNAUTHORIZED(401),
|
||||||
|
ERROR_FORBIDDEN(403),
|
||||||
|
OK(200);
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
ExceptionCode(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExceptionCode getExceptionCode(int value) {
|
||||||
|
for (ExceptionCode exceptionCode : ExceptionCode.values()) {
|
||||||
|
if (exceptionCode.value == value) {
|
||||||
|
return exceptionCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
public final class Funs {
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface P1Fun<T> {
|
||||||
|
void call(T p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Fun {
|
||||||
|
void call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface R1Fun<T> {
|
||||||
|
T call();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
public class MinecraftMod {
|
||||||
|
|
||||||
|
public static final String MOD_ID = "enchantmentdoesnotconflict";
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
|
public class NetWorkUtils {
|
||||||
|
|
||||||
|
public static boolean isLocalAddress(SocketAddress address) {
|
||||||
|
if (!(address instanceof InetSocketAddress inetAddr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (inetAddr.getAddress().isLoopbackAddress() || inetAddr.getAddress().isAnyLocalAddress());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
public class Respose<T> {
|
||||||
|
|
||||||
|
private int code = ExceptionCode.OK.getValue();
|
||||||
|
private String message = "操作成功";
|
||||||
|
private T data;
|
||||||
|
private DateTime dateTime = DateTime.now();
|
||||||
|
|
||||||
|
public Respose(int code, String message, T data, DateTime dateTime) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
this.data = data;
|
||||||
|
this.dateTime = dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Respose(int code, String message, T data) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Respose(int code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Respose(T data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Respose() {}
|
||||||
|
|
||||||
|
public static <T> Respose<T> builder() {
|
||||||
|
return new Respose<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Respose<T> builder(T data) {
|
||||||
|
return new Respose<>().setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Respose<T> error(Class<T> type, Integer code, String message) {
|
||||||
|
return new Respose<T>().setCode(code).setMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Respose<T> error(Class<T> type, ExceptionCode code, String message) {
|
||||||
|
return error(type, code.getValue(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Respose<T> setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Respose<T> setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime getDateTime() {
|
||||||
|
return dateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <TD> Respose<TD> setData(TD data) {
|
||||||
|
return new Respose<>(code, message, data);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
public enum VersionsEnum {
|
||||||
|
V120,
|
||||||
|
V121,
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import io.javalin.Javalin;
|
||||||
|
import io.javalin.http.Context;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class WebApis {
|
||||||
|
|
||||||
|
private final ConfigManager configManager;
|
||||||
|
private final WebConfigCoreMeMethod webConfigCoreMeMethod;
|
||||||
|
|
||||||
|
WebApis(ConfigManager configManager, WebConfigCoreMeMethod webConfigCoreMeMethod) {
|
||||||
|
this.configManager = configManager;
|
||||||
|
this.webConfigCoreMeMethod = webConfigCoreMeMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadApis(Javalin javalin) {
|
||||||
|
javalin.get("/api/get/info", this::getInfo);
|
||||||
|
javalin.get("/api/get/enchantments", this::getAllEnchantments);
|
||||||
|
javalin.get("/api/get/client/config", this::getClientConfig);
|
||||||
|
javalin.post("/api/get/test", this::getTest);
|
||||||
|
javalin.post("/api/send/config", this::sendConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getAllEnchantments(Context context) {
|
||||||
|
context.json(Respose.builder(webConfigCoreMeMethod.getAllEnchantments()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getClientConfig(Context context) {
|
||||||
|
context.json(Respose.builder(webConfigCoreMeMethod.getConfig()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getInfo(Context context) {
|
||||||
|
context.json(
|
||||||
|
Respose.builder(
|
||||||
|
Map.of(
|
||||||
|
"LoaderVersion",
|
||||||
|
webConfigCoreMeMethod.getLoaderVersions(),
|
||||||
|
"LoaderName",
|
||||||
|
webConfigCoreMeMethod.getLoaderName(),
|
||||||
|
"GameVersions",
|
||||||
|
webConfigCoreMeMethod.getGameVersions(),
|
||||||
|
"ModVersions",
|
||||||
|
webConfigCoreMeMethod.getModVersions(),
|
||||||
|
"ModName",
|
||||||
|
webConfigCoreMeMethod.getModName()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getTest(Context context) {
|
||||||
|
record BD(Integer fid, Integer sid) {}
|
||||||
|
var d = context.bodyAsClass(BD.class);
|
||||||
|
context.json(Respose.builder(webConfigCoreMeMethod.getTest(d.fid, d.sid)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendConfig(Context context) {
|
||||||
|
webConfigCoreMeMethod.saveConfig(context.bodyAsClass(ConfigManager.MODCONFIGTYPE));
|
||||||
|
context.json(Respose.builder());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import io.javalin.Javalin;
|
||||||
|
import io.javalin.http.staticfiles.Location;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
public class WebConfigCore {
|
||||||
|
|
||||||
|
private Javalin javalin;
|
||||||
|
private final int port;
|
||||||
|
private final ConfigManager configManager;
|
||||||
|
private final WebConfigCoreMeMethod webConfigCoreMeMethod;
|
||||||
|
private final WebApis webApis;
|
||||||
|
private boolean started = false;
|
||||||
|
|
||||||
|
public WebConfigCore(ConfigManager configManager, WebConfigCoreMeMethod webConfigCoreMeMethod) {
|
||||||
|
this.configManager = configManager;
|
||||||
|
this.webConfigCoreMeMethod = webConfigCoreMeMethod;
|
||||||
|
port = getProt();
|
||||||
|
webApis = new WebApis(configManager, webConfigCoreMeMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
javalin = Javalin.create((config) -> {
|
||||||
|
config.staticFiles.add((staticFiles) -> {
|
||||||
|
staticFiles.directory = "/assets/enchantmentdoesnotconflict/web/assets";
|
||||||
|
staticFiles.location = Location.CLASSPATH;
|
||||||
|
staticFiles.hostedPath = "/assets";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
javalin.get("/", (ctx) -> {
|
||||||
|
ctx.html(DefConfig.getResByString("/assets/enchantmentdoesnotconflict/web/index.html"));
|
||||||
|
});
|
||||||
|
webApis.loadApis(javalin);
|
||||||
|
javalin.start(port);
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
if (started) {
|
||||||
|
javalin.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getProt() {
|
||||||
|
if (webConfigCoreMeMethod.getDevMode()) {
|
||||||
|
return 15563;
|
||||||
|
}
|
||||||
|
try (ServerSocket s = new ServerSocket(0)) {
|
||||||
|
return s.getLocalPort();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return 15563;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocalUrl() {
|
||||||
|
return "http://localhost:" + port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openWeb() {
|
||||||
|
WebOpener.openURL(getLocalUrl());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.enchantment.EnchantmentEntity;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public interface WebConfigCoreMeMethod {
|
||||||
|
void reloadConfig();
|
||||||
|
|
||||||
|
Map<String, ConfigPair> getDefConfig();
|
||||||
|
|
||||||
|
Map<String, ConfigPair> getConfig();
|
||||||
|
|
||||||
|
String getGameVersions();
|
||||||
|
|
||||||
|
String getModVersions();
|
||||||
|
|
||||||
|
String getLoaderVersions();
|
||||||
|
|
||||||
|
default boolean getDevMode() {
|
||||||
|
String classPath = Objects.requireNonNullElse(
|
||||||
|
WebConfigCoreMeMethod.class.getResource("WebConfigCoreMeMethod.class"),
|
||||||
|
""
|
||||||
|
).toString();
|
||||||
|
return classPath.contains("common.jar");
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getModName() {
|
||||||
|
return "[EDNC] Enchantment Does Not Conflict (附魔不冲突)";
|
||||||
|
}
|
||||||
|
|
||||||
|
String getLoaderName();
|
||||||
|
|
||||||
|
List<EnchantmentEntity> getAllEnchantments();
|
||||||
|
|
||||||
|
boolean getTest(Integer fid, Integer sid);
|
||||||
|
|
||||||
|
void saveConfig(Map<String, ConfigPair> configPairMap);
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common;
|
||||||
|
|
||||||
|
import java.awt.Desktop;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
public class WebOpener {
|
||||||
|
|
||||||
|
public static void openURL(String url) {
|
||||||
|
String os = System.getProperty("os.name").toLowerCase();
|
||||||
|
Runtime rt = Runtime.getRuntime();
|
||||||
|
try {
|
||||||
|
if (os.contains("win")) {
|
||||||
|
rt.exec("rundll32 url.dll,FileProtocolHandler " + url);
|
||||||
|
} else if (os.contains("mac")) {
|
||||||
|
rt.exec("open " + url);
|
||||||
|
} else if (os.contains("nix") || os.contains("nux")) {
|
||||||
|
rt.exec("xdg-open " + url);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common.enchantment;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface AddAllowEnchantmentFunInf {
|
||||||
|
Map<String, List<String>> call();
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common.enchantment;
|
||||||
|
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigManager;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigPair;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class EnchantmentController {
|
||||||
|
|
||||||
|
private final List<AddAllowEnchantmentFunInf> allowEnchantmentFunInfs = new ArrayList<>();
|
||||||
|
private final ConfigManager configManager;
|
||||||
|
|
||||||
|
public void registerAllowEnchantment(AddAllowEnchantmentFunInf fun) {
|
||||||
|
allowEnchantmentFunInfs.add(fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnchantmentController(ConfigManager configManager) {
|
||||||
|
this.configManager = configManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean canBeCombined(String enchantmentA, String enchantmentB) {
|
||||||
|
if (enchantmentA.equals(enchantmentB)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
List<EnchantmentEntity> groupsA = ofId(enchantmentA);
|
||||||
|
List<EnchantmentEntity> groupsB = ofId(enchantmentB);
|
||||||
|
if (groupsA.isEmpty() && groupsB.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (EnchantmentEntity groupA : groupsA) {
|
||||||
|
for (EnchantmentEntity groupB : groupsB) {
|
||||||
|
if (groupA.getFather().equals(groupB.getFather())) {
|
||||||
|
ConfigPair pair = configManager.getConfig().get(groupA.getFather());
|
||||||
|
if (pair == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return pair.getAllow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EnchantmentEntity> ofId(String id) {
|
||||||
|
final List<EnchantmentEntity> enchantmentList = new ArrayList<>();
|
||||||
|
for (String i : configManager.getConfig().keySet()) {
|
||||||
|
if (configManager.getConfig().get(i).getAllowlist().contains(id)) {
|
||||||
|
enchantmentList.add(new EnchantmentEntity(id, i, "", null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return enchantmentList;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.common.enchantment;
|
||||||
|
|
||||||
|
public class EnchantmentEntity {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String father;
|
||||||
|
private String name;
|
||||||
|
private Integer nid;
|
||||||
|
|
||||||
|
public EnchantmentEntity(String id, String father, String name, Integer nid) {
|
||||||
|
this.nid = nid;
|
||||||
|
this.id = id;
|
||||||
|
this.father = father;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFather(String father) {
|
||||||
|
this.father = father;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFather() {
|
||||||
|
return father;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getNid() {
|
||||||
|
return nid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNid(Integer nid) {
|
||||||
|
this.nid = nid;
|
||||||
|
}
|
||||||
|
}
|
28
gradle.properties
Normal file
28
gradle.properties
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
org.gradle.daemon=true
|
||||||
|
org.gradle.jvmargs=-Xmx8G
|
||||||
|
mod_name=Enchantment Does Not Conflict
|
||||||
|
mod_id=enchantmentdoesnotconflict
|
||||||
|
mod_version=2.0
|
||||||
|
maven_group=com.mingliqiye.minecraft.enchantment.conflict
|
||||||
|
archives_base_name=enchantmentdoesnotconflict
|
||||||
|
mod_description=Now, some enchantments are no longer involved in conflicts.
|
||||||
|
mod_author=mingliqiye
|
||||||
|
mod_contributor=minglipro
|
||||||
|
mod_contributor_2=Armamem0t
|
||||||
|
mod_license=Apache Licence 2.0
|
||||||
|
mod_sources=https://git.mingliqiye.com/MinecraftMod/EnchantmentDoNotConflict
|
||||||
|
mod_issues=https://git.mingliqiye.com/MinecraftMod/EnchantmentDoNotConflict/issues
|
||||||
|
mod_author_email=minglipro@163.com
|
||||||
|
java_version=17
|
||||||
|
mod_minecrat_versions=1.20
|
||||||
|
projects=:common,:modsrc:1.20:Fabric,:modsrc:1.20:Forge
|
||||||
|
mod_relocate_packs_id=\
|
||||||
|
com.fasterxml,\
|
||||||
|
com.mingliqiye.utils,\
|
||||||
|
io.javalin,\
|
||||||
|
jakarta,\
|
||||||
|
kotlin,\
|
||||||
|
org.yaml,\
|
||||||
|
org.jetbrains,\
|
||||||
|
org.intellij,\
|
||||||
|
org.eclipse
|
2
gradle/libs.versions.toml
Normal file
2
gradle/libs.versions.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# This file was generated by the Gradle 'init' task.
|
||||||
|
# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
251
gradlew
vendored
Normal file
251
gradlew
vendored
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright © 2015-2021 the original authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
app_path=$0
|
||||||
|
|
||||||
|
# Need this for daisy-chained symlinks.
|
||||||
|
while
|
||||||
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
|
[ -h "$app_path" ]
|
||||||
|
do
|
||||||
|
ls=$( ls -ld "$app_path" )
|
||||||
|
link=${ls#*' -> '}
|
||||||
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
APP_BASE_NAME=${0##*/}
|
||||||
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD=maximum
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "$( uname )" in #(
|
||||||
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
|
Darwin* ) darwin=true ;; #(
|
||||||
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
|
NONSTOP* ) nonstop=true ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH="\\\"\\\""
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
|
else
|
||||||
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD=java
|
||||||
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
|
case $MAX_FD in #(
|
||||||
|
max*)
|
||||||
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
|
warn "Could not query maximum file descriptor limit"
|
||||||
|
esac
|
||||||
|
case $MAX_FD in #(
|
||||||
|
'' | soft) :;; #(
|
||||||
|
*)
|
||||||
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
|
ulimit -n "$MAX_FD" ||
|
||||||
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
|
# * args from the command line
|
||||||
|
# * the main class name
|
||||||
|
# * -classpath
|
||||||
|
# * -D...appname settings
|
||||||
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Collect all arguments for the java command:
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
|
# and any embedded shellness will be escaped.
|
||||||
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
94
gradlew.bat
vendored
Normal file
94
gradlew.bat
vendored
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%"=="" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
|
echo. 1>&2
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
|
echo. 1>&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo. 1>&2
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
|
echo. 1>&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
13
index.html
Normal file
13
index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="/src/resources/icon.png">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>附魔不冲突 配置</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main></main>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
75
modsrc/1.20/Fabric/build.gradle
Normal file
75
modsrc/1.20/Fabric/build.gradle
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
plugins {
|
||||||
|
id 'fabric-loom' version "${fabric_loom_version}"
|
||||||
|
id 'maven-publish'
|
||||||
|
}
|
||||||
|
loom {
|
||||||
|
mixin {
|
||||||
|
defaultRefmapName.set("enchantmentdoesnotconflict.fabric.mixin.refmap.json")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
version = "${loader_name}-${minecraft_version}-${mod_version}"
|
||||||
|
group = project.maven_group
|
||||||
|
|
||||||
|
base {
|
||||||
|
archivesName = project.archives_base_name
|
||||||
|
}
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java { srcDirs = ['src'] }
|
||||||
|
resources { srcDirs = ['resources', project(":common").sourceSets.main.resources] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||||
|
mappings loom.officialMojangMappings()
|
||||||
|
modImplementation "net.fabricmc:fabric-loader:${project.fabric_loader_version}"
|
||||||
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
|
implementation project(":common")
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
inputs.property "mod_id", project.mod_id
|
||||||
|
inputs.property "mod_version", project.mod_version
|
||||||
|
inputs.property "mod_name", project.mod_name
|
||||||
|
inputs.property "mod_description", project.mod_description
|
||||||
|
inputs.property "mod_author", project.mod_author
|
||||||
|
inputs.property "mod_contributor", project.mod_contributor
|
||||||
|
inputs.property "mod_contributor_2", project.mod_contributor_2
|
||||||
|
inputs.property "mod_sources", project.mod_sources
|
||||||
|
inputs.property "mod_issues", project.mod_issues
|
||||||
|
inputs.property "mod_author_email", project.mod_author_email
|
||||||
|
filesMatching("fabric.mod.json") {
|
||||||
|
expand(["mod_id" : project.mod_id,
|
||||||
|
"mod_version" : project.mod_version,
|
||||||
|
"mod_name" : project.mod_name,
|
||||||
|
"mod_description" : project.mod_description,
|
||||||
|
"mod_author" : project.mod_author,
|
||||||
|
"mod_contributor" : project.mod_contributor,
|
||||||
|
"mod_contributor_2": project.mod_contributor_2,
|
||||||
|
"mod_sources" : project.mod_sources,
|
||||||
|
"mod_issues" : project.mod_issues,
|
||||||
|
"mod_author_email" : project.mod_author_email])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain { languageVersion.set(JavaLanguageVersion.of(java_version)) }
|
||||||
|
}
|
||||||
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
it.options.release.set(java_version as Integer)
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
enabled = true
|
||||||
|
inputs.property "archivesName", project.base.archivesName
|
||||||
|
from("LICENSE") {
|
||||||
|
rename { "${it}_${inputs.properties.archivesName}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remapJar{
|
||||||
|
}
|
1
modsrc/1.20/Fabric/gradle.properties
Normal file
1
modsrc/1.20/Fabric/gradle.properties
Normal file
@ -0,0 +1 @@
|
|||||||
|
loader_name=Fabric
|
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"package": "com.mingliqiye.minecraft.enchantment.conflict.fabric.mixin",
|
||||||
|
"compatibilityLevel": "JAVA_17",
|
||||||
|
"mixins": ["EnchantmentMixin", "PlayerListMixin"],
|
||||||
|
"injectors": {
|
||||||
|
"defaultRequire": 1
|
||||||
|
},
|
||||||
|
"overwrites": {
|
||||||
|
"requireAnnotations": true
|
||||||
|
}
|
||||||
|
}
|
31
modsrc/1.20/Fabric/resources/fabric.mod.json
Normal file
31
modsrc/1.20/Fabric/resources/fabric.mod.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "${mod_id}",
|
||||||
|
"version": "${mod_version}",
|
||||||
|
"name": "${mod_name}",
|
||||||
|
"description": "${mod_description}",
|
||||||
|
"authors": ["${mod_author}"],
|
||||||
|
"contributors": ["${mod_contributor}", "${mod_contributor_2}"],
|
||||||
|
"contact": {
|
||||||
|
"sources": "${mod_sources}",
|
||||||
|
"issues": "${mod_issues}",
|
||||||
|
"email": "${mod_author_email}"
|
||||||
|
},
|
||||||
|
"license": "Apache License 2.0",
|
||||||
|
"icon": "assets/enchantmentdoesnotconflict/textures/logo/icon.png",
|
||||||
|
"environment": "*",
|
||||||
|
"entrypoints": {
|
||||||
|
"main": ["com.mingliqiye.minecraft.enchantment.conflict.fabric.FabricMod"],
|
||||||
|
"client": ["com.mingliqiye.minecraft.enchantment.conflict.fabric.FabricModClient"]
|
||||||
|
},
|
||||||
|
"mixins": ["enchantmentdoesnotconflict.fabric.mixin.json"],
|
||||||
|
"depends": {
|
||||||
|
"fabricloader": "*",
|
||||||
|
"minecraft": "1.20",
|
||||||
|
"java": ">=17",
|
||||||
|
"fabric-api": "*"
|
||||||
|
},
|
||||||
|
"suggests": {
|
||||||
|
"another-mod": "*"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.fabric;
|
||||||
|
|
||||||
|
import static com.mingliqiye.minecraft.enchantment.conflict.common.NetWorkUtils.isLocalAddress;
|
||||||
|
import static net.minecraft.commands.Commands.literal;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigManager;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.MinecraftMod;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.VersionsEnum;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.WebConfigCore;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.enchantment.EnchantmentController;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.Style;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class FabricMod implements ModInitializer {
|
||||||
|
|
||||||
|
public static final Logger LOGGER = LoggerFactory.getLogger(MinecraftMod.MOD_ID);
|
||||||
|
public static MinecraftServer SERVER;
|
||||||
|
public static final ConfigManager CONFIGMANAGER = new ConfigManager(
|
||||||
|
FabricLoader.getInstance().getConfigDir(),
|
||||||
|
LOGGER,
|
||||||
|
VersionsEnum.V120
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final WebConfigCore WEBCONFIGCORE = new WebConfigCore(
|
||||||
|
CONFIGMANAGER,
|
||||||
|
new FabricWebConfigCoreMeMethod()
|
||||||
|
);
|
||||||
|
public static final EnchantmentController ENCHANTMENTCONTROLLER = new EnchantmentController(CONFIGMANAGER);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitialize() {
|
||||||
|
ServerLifecycleEvents.SERVER_STARTED.register((m) -> {
|
||||||
|
SERVER = m;
|
||||||
|
WEBCONFIGCORE.start();
|
||||||
|
});
|
||||||
|
ServerLifecycleEvents.SERVER_STOPPING.register((m) -> {
|
||||||
|
WEBCONFIGCORE.stop();
|
||||||
|
});
|
||||||
|
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
|
dispatcher.register(
|
||||||
|
literal("enchantmentdoesnotconflict-config").executes((context) -> {
|
||||||
|
var source = context.getSource();
|
||||||
|
boolean isLocal =
|
||||||
|
source.getServer().isSingleplayer() ||
|
||||||
|
source.getEntity() == null ||
|
||||||
|
(source.getPlayer() != null &&
|
||||||
|
isLocalAddress(source.getPlayer().connection.getRemoteAddress()));
|
||||||
|
if (isLocal) {
|
||||||
|
WEBCONFIGCORE.openWeb();
|
||||||
|
source.sendSuccess(
|
||||||
|
() ->
|
||||||
|
Component.literal("打开")
|
||||||
|
.append(Component.literal(WEBCONFIGCORE.getLocalUrl()))
|
||||||
|
.withStyle(
|
||||||
|
Style.EMPTY.withColor(ChatFormatting.BLUE).withUnderlined(true) // 蓝色带下划线
|
||||||
|
)
|
||||||
|
.append(Component.literal("成功"))
|
||||||
|
.withStyle(ChatFormatting.GREEN),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
source.sendFailure(
|
||||||
|
Component.literal("请使用服务器所在的机器执行该命令").withStyle(ChatFormatting.RED)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.fabric;
|
||||||
|
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.fabric.network.NetworkHandler;
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
|
||||||
|
public class FabricModClient implements ClientModInitializer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
NetworkHandler.registerReceivers();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.fabric;
|
||||||
|
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigPair;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.MinecraftMod;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.WebConfigCoreMeMethod;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.enchantment.EnchantmentEntity;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.fabric.network.NetworkHandler;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
import net.fabricmc.loader.api.ModContainer;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
|
||||||
|
public class FabricWebConfigCoreMeMethod implements WebConfigCoreMeMethod {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reloadConfig() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, ConfigPair> getDefConfig() {
|
||||||
|
return FabricMod.CONFIGMANAGER.getDefConfig().getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, ConfigPair> getConfig() {
|
||||||
|
return FabricMod.CONFIGMANAGER.getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGameVersions() {
|
||||||
|
Optional<ModContainer> minecraftContainer = FabricLoader.getInstance().getModContainer("minecraft");
|
||||||
|
if (minecraftContainer.isPresent()) {
|
||||||
|
return minecraftContainer.get().getMetadata().getVersion().getFriendlyString();
|
||||||
|
} else {
|
||||||
|
return "未知版本";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModVersions() {
|
||||||
|
Optional<ModContainer> EDNCContainer = FabricLoader.getInstance().getModContainer(MinecraftMod.MOD_ID);
|
||||||
|
if (EDNCContainer.isPresent()) {
|
||||||
|
return EDNCContainer.get().getMetadata().getVersion().getFriendlyString();
|
||||||
|
} else {
|
||||||
|
return "未知版本";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLoaderVersions() {
|
||||||
|
Optional<ModContainer> loaderContainer = FabricLoader.getInstance().getModContainer("fabricloader");
|
||||||
|
if (loaderContainer.isPresent()) {
|
||||||
|
return loaderContainer.get().getMetadata().getVersion().getFriendlyString();
|
||||||
|
} else {
|
||||||
|
return "未知版本";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLoaderName() {
|
||||||
|
return "Fabric";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EnchantmentEntity> getAllEnchantments() {
|
||||||
|
return BuiltInRegistries.ENCHANTMENT.stream()
|
||||||
|
.map((a) ->
|
||||||
|
new EnchantmentEntity(
|
||||||
|
a.getDescriptionId(),
|
||||||
|
"null",
|
||||||
|
a.getFullname(a.getMaxLevel()).getString(),
|
||||||
|
BuiltInRegistries.ENCHANTMENT.getId(a)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getTest(Integer fid, Integer sid) {
|
||||||
|
var f = BuiltInRegistries.ENCHANTMENT.byId(fid);
|
||||||
|
var s = BuiltInRegistries.ENCHANTMENT.byId(sid);
|
||||||
|
return f.isCompatibleWith(s) && s.isCompatibleWith(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveConfig(Map<String, ConfigPair> configPairMap) {
|
||||||
|
FabricMod.CONFIGMANAGER.setConfig(configPairMap);
|
||||||
|
FabricMod.CONFIGMANAGER.save();
|
||||||
|
NetworkHandler.sendConfigToAllClient();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.fabric.mixin;
|
||||||
|
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.fabric.FabricMod;
|
||||||
|
import net.minecraft.world.item.enchantment.Enchantment;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(Enchantment.class)
|
||||||
|
public class EnchantmentMixin {
|
||||||
|
|
||||||
|
@Inject(method = "isCompatibleWith", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void isCompatibleWith(Enchantment enchantment, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
var rb = FabricMod.ENCHANTMENTCONTROLLER.canBeCombined(
|
||||||
|
enchantment.getDescriptionId(),
|
||||||
|
getThis().getDescriptionId()
|
||||||
|
);
|
||||||
|
if (rb != null) {
|
||||||
|
cir.setReturnValue(rb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private Enchantment getThis() {
|
||||||
|
return (Enchantment) (Object) this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.fabric.mixin;
|
||||||
|
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.fabric.network.NetworkHandler;
|
||||||
|
import net.minecraft.network.Connection;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.server.players.PlayerList;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(PlayerList.class)
|
||||||
|
public abstract class PlayerListMixin {
|
||||||
|
|
||||||
|
@Inject(method = "placeNewPlayer", at = @At("RETURN"))
|
||||||
|
private void onPlayerConnect(Connection connection, ServerPlayer serverPlayer, CallbackInfo ci) {
|
||||||
|
NetworkHandler.sendConfigToClient(serverPlayer);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.fabric.network;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigManager;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.MinecraftMod;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.fabric.FabricMod;
|
||||||
|
import com.mojang.logging.LogUtils;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
public class NetworkHandler {
|
||||||
|
|
||||||
|
public static final ResourceLocation CONFIG_PACKET_ID = new ResourceLocation(MinecraftMod.MOD_ID, "config_packet");
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
|
|
||||||
|
public static void sendConfigToClient(ServerPlayer player) {
|
||||||
|
var config = FabricMod.CONFIGMANAGER.getConfig();
|
||||||
|
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||||
|
buf.writeUtf(ConfigManager.toyaml(config));
|
||||||
|
ServerPlayNetworking.send(player, NetworkHandler.CONFIG_PACKET_ID, buf);
|
||||||
|
LOGGER.info(
|
||||||
|
"Send Player({}) Server {} config {}",
|
||||||
|
player.getName().getString(),
|
||||||
|
MinecraftMod.MOD_ID,
|
||||||
|
ConfigManager.tojson(config)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendConfigToAllClient() {
|
||||||
|
FabricMod.SERVER.getPlayerList().getPlayers().forEach(NetworkHandler::sendConfigToClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerReceivers() {
|
||||||
|
ClientPlayNetworking.registerGlobalReceiver(
|
||||||
|
NetworkHandler.CONFIG_PACKET_ID,
|
||||||
|
(client, handler, buf, responseSender) -> {
|
||||||
|
var configData = ConfigManager.fromyaml(buf.readUtf());
|
||||||
|
client.execute(() -> {
|
||||||
|
FabricMod.CONFIGMANAGER.setConfig(configData);
|
||||||
|
LOGGER.info("Load Server {} config {}", MinecraftMod.MOD_ID, ConfigManager.tojson(configData));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
155
modsrc/1.20/Forge/build.gradle
Normal file
155
modsrc/1.20/Forge/build.gradle
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
plugins {
|
||||||
|
id 'eclipse'
|
||||||
|
id 'idea'
|
||||||
|
id 'maven-publish'
|
||||||
|
id 'net.minecraftforge.gradle' version '[6.0,6.2)'
|
||||||
|
id 'org.spongepowered.mixin' version '0.7+'
|
||||||
|
}
|
||||||
|
|
||||||
|
version = "${loader_name}-${minecraft_version}-${mod_version}"
|
||||||
|
group = maven_group
|
||||||
|
|
||||||
|
base {
|
||||||
|
archivesName = mod_id
|
||||||
|
}
|
||||||
|
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
|
||||||
|
println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}"
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java { srcDirs = ['src'] }
|
||||||
|
resources { srcDirs = ['resources', project(":common").sourceSets.main.resources] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
afterEvaluate {
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
|
options.annotationProcessorPath = files(configurations.annotationProcessor,
|
||||||
|
project(":common").sourceSets.main.output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
minecraft {
|
||||||
|
mappings channel: mapping_channel, version: mapping_version
|
||||||
|
copyIdeResources = true
|
||||||
|
runs {
|
||||||
|
client {
|
||||||
|
workingDirectory project.file('run')
|
||||||
|
property 'forge.logging.markers', 'REGISTRIES'
|
||||||
|
property 'forge.enabledGameTestNamespaces', mod_id
|
||||||
|
property 'forge.logging.console.level', 'info'
|
||||||
|
mods {
|
||||||
|
"${mod_id}" {
|
||||||
|
source sourceSets.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
workingDirectory project.file('run')
|
||||||
|
property 'forge.logging.markers', 'REGISTRIES'
|
||||||
|
property 'forge.enabledGameTestNamespaces', mod_id
|
||||||
|
property 'forge.logging.console.level', 'info'
|
||||||
|
mods {
|
||||||
|
"${mod_id}" {
|
||||||
|
source sourceSets.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gameTestServer {
|
||||||
|
workingDirectory project.file('run')
|
||||||
|
property 'forge.logging.markers', 'REGISTRIES'
|
||||||
|
property 'forge.enabledGameTestNamespaces', mod_id
|
||||||
|
property 'forge.logging.console.level', 'info'
|
||||||
|
mods {
|
||||||
|
"${mod_id}" {
|
||||||
|
source sourceSets.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data {
|
||||||
|
workingDirectory project.file('run')
|
||||||
|
property 'forge.logging.markers', 'REGISTRIES'
|
||||||
|
property 'forge.logging.console.level', 'debug'
|
||||||
|
args '--mod', mod_id, '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
||||||
|
mods {
|
||||||
|
"${mod_id}" {
|
||||||
|
source sourceSets.main
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mixin {
|
||||||
|
add sourceSets.main, "enchantmentdoesnotconflict.forge.mixin.refmap.json"
|
||||||
|
config "enchantmentdoesnotconflict.forge.mixin.json"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||||
|
minecraftLibrary(project(":common")) {
|
||||||
|
exclude group: 'org.jetbrains', module: 'annotations'
|
||||||
|
}
|
||||||
|
annotationProcessor 'org.spongepowered:mixin:0.8.5:processor'
|
||||||
|
}
|
||||||
|
|
||||||
|
def resourceTargets = ['META-INF/mods.toml', 'pack.mcmeta']
|
||||||
|
def replaceProperties = [minecraft_version : minecraft_version,
|
||||||
|
minecraft_version_range: minecraft_version_range,
|
||||||
|
forge_version : forge_version,
|
||||||
|
forge_version_range : forge_version_range,
|
||||||
|
loader_version_range : loader_version_range,
|
||||||
|
mod_id : mod_id,
|
||||||
|
mod_name : mod_name,
|
||||||
|
mod_license : mod_license,
|
||||||
|
mod_version : mod_version,
|
||||||
|
mod_authors : "${mod_author},${mod_contributor},${mod_contributor_2}",
|
||||||
|
mod_description : mod_description]
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
inputs.properties replaceProperties
|
||||||
|
replaceProperties.put 'project', project
|
||||||
|
|
||||||
|
filesMatching(resourceTargets) {
|
||||||
|
expand replaceProperties
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
jar {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
enabled = true
|
||||||
|
manifest {
|
||||||
|
attributes(["Specification-Title" : mod_id,
|
||||||
|
"Specification-Vendor" : mod_author,
|
||||||
|
"Specification-Version" : "1", // We are version 1 of ourselves
|
||||||
|
"Implementation-Title" : project.name,
|
||||||
|
"Implementation-Version" : project.jar.archiveVersion,
|
||||||
|
"Implementation-Vendor" : mod_author,
|
||||||
|
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
||||||
|
"MixinConfigs": "enchantmentdoesnotconflict.forge.mixin.json"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jar.finalizedBy('reobfJar')
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
mavenJava(MavenPublication) {
|
||||||
|
artifact jar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url "file://${project.projectDir}/mcmodsrepo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
options.encoding = 'UTF-8'
|
||||||
|
}
|
1
modsrc/1.20/Forge/gradle.properties
Normal file
1
modsrc/1.20/Forge/gradle.properties
Normal file
@ -0,0 +1 @@
|
|||||||
|
loader_name=Forge
|
23
modsrc/1.20/Forge/resources/META-INF/mods.toml
Normal file
23
modsrc/1.20/Forge/resources/META-INF/mods.toml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
modLoader="javafml"
|
||||||
|
loaderVersion="${loader_version_range}"
|
||||||
|
license="${mod_license}"
|
||||||
|
[[mods]]
|
||||||
|
modId="${mod_id}"
|
||||||
|
version="${mod_version}"
|
||||||
|
displayName="${mod_name}"
|
||||||
|
authors="${mod_authors}"
|
||||||
|
description='''${mod_description}'''
|
||||||
|
[[mixins]]
|
||||||
|
config="enchantmentdoesnotconflict.forge.mixins.json"
|
||||||
|
[[dependencies.${mod_id}]]
|
||||||
|
modId="forge"
|
||||||
|
mandatory=true
|
||||||
|
versionRange="${forge_version_range}"
|
||||||
|
ordering="NONE"
|
||||||
|
side="BOTH"
|
||||||
|
[[dependencies.${mod_id}]]
|
||||||
|
modId="minecraft"
|
||||||
|
mandatory=true
|
||||||
|
versionRange="${minecraft_version_range}"
|
||||||
|
ordering="NONE"
|
||||||
|
side="BOTH"
|
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"package": "com.mingliqiye.minecraft.enchantment.conflict.forge.mixin",
|
||||||
|
"compatibilityLevel": "JAVA_17",
|
||||||
|
"mixins": ["EnchantmentMixin"],
|
||||||
|
"injectors": {
|
||||||
|
"defaultRequire": 1
|
||||||
|
},
|
||||||
|
"minVersion": "0.8",
|
||||||
|
"overwrites": {
|
||||||
|
"requireAnnotations": true
|
||||||
|
},
|
||||||
|
"refmap": "enchantmentdoesnotconflict.forge.mixin.refmap.json"
|
||||||
|
}
|
8
modsrc/1.20/Forge/resources/pack.mcmeta
Normal file
8
modsrc/1.20/Forge/resources/pack.mcmeta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"pack": {
|
||||||
|
"description": {
|
||||||
|
"text": "${mod_id} resources"
|
||||||
|
},
|
||||||
|
"pack_format": 15
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.forge;
|
||||||
|
|
||||||
|
import static com.mingliqiye.minecraft.enchantment.conflict.common.NetWorkUtils.isLocalAddress;
|
||||||
|
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigManager;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.MinecraftMod;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.VersionsEnum;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.WebConfigCore;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.enchantment.EnchantmentController;
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.commands.Commands;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.Style;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.event.RegisterCommandsEvent;
|
||||||
|
import net.minecraftforge.event.server.ServerStartedEvent;
|
||||||
|
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||||
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
|
import net.minecraftforge.fml.loading.FMLPaths;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@Mod(MinecraftMod.MOD_ID)
|
||||||
|
public class ForgeMod {
|
||||||
|
|
||||||
|
public static final Logger LOGGER = LoggerFactory.getLogger(MinecraftMod.MOD_ID);
|
||||||
|
public static MinecraftServer SERVER;
|
||||||
|
|
||||||
|
public static final ConfigManager CONFIGMANAGER = new ConfigManager(
|
||||||
|
FMLPaths.CONFIGDIR.get(),
|
||||||
|
LOGGER,
|
||||||
|
VersionsEnum.V120
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final WebConfigCore WEBCONFIGCORE = new WebConfigCore(
|
||||||
|
CONFIGMANAGER,
|
||||||
|
new ForgeWebConfigCoreMeMethod()
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final EnchantmentController ENCHANTMENTCONTROLLER = new EnchantmentController(CONFIGMANAGER);
|
||||||
|
|
||||||
|
public ForgeMod() {
|
||||||
|
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||||
|
modEventBus.addListener(this::commonSetup);
|
||||||
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void commonSetup(final FMLCommonSetupEvent event) {}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onServerStarted(ServerStartedEvent event) {
|
||||||
|
SERVER = event.getServer();
|
||||||
|
WEBCONFIGCORE.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onServerStopping(ServerStoppingEvent event) {
|
||||||
|
WEBCONFIGCORE.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onRegisterCommands(RegisterCommandsEvent event) {
|
||||||
|
LOGGER.info("onRegisterCommands");
|
||||||
|
event
|
||||||
|
.getDispatcher()
|
||||||
|
.register(
|
||||||
|
Commands.literal("enchantmentdoesnotconflict-config").executes((context) -> {
|
||||||
|
var source = context.getSource();
|
||||||
|
boolean isLocal =
|
||||||
|
source.getServer().isSingleplayer() ||
|
||||||
|
source.getEntity() == null ||
|
||||||
|
(source.getPlayer() != null &&
|
||||||
|
isLocalAddress(source.getPlayer().connection.getRemoteAddress()));
|
||||||
|
if (isLocal) {
|
||||||
|
WEBCONFIGCORE.openWeb();
|
||||||
|
source.sendSuccess(
|
||||||
|
() ->
|
||||||
|
Component.literal("打开")
|
||||||
|
.append(Component.literal(WEBCONFIGCORE.getLocalUrl()))
|
||||||
|
.withStyle(
|
||||||
|
Style.EMPTY.withColor(ChatFormatting.BLUE).withUnderlined(true) // 蓝色带下划线
|
||||||
|
)
|
||||||
|
.append(Component.literal("成功"))
|
||||||
|
.withStyle(ChatFormatting.GREEN),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
source.sendFailure(
|
||||||
|
Component.literal("请使用服务器所在的机器执行该命令").withStyle(ChatFormatting.RED)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.forge;
|
||||||
|
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.ConfigPair;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.MinecraftMod;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.WebConfigCoreMeMethod;
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.common.enchantment.EnchantmentEntity;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
|
||||||
|
public class ForgeWebConfigCoreMeMethod implements WebConfigCoreMeMethod {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reloadConfig() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, ConfigPair> getDefConfig() {
|
||||||
|
return ForgeMod.CONFIGMANAGER.getDefConfig().getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, ConfigPair> getConfig() {
|
||||||
|
return ForgeMod.CONFIGMANAGER.getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGameVersions() {
|
||||||
|
return ModList.get()
|
||||||
|
.getModContainerById("minecraft")
|
||||||
|
.map((mod) -> mod.getModInfo().getVersion().toString())
|
||||||
|
.orElse("未知版本");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取 Mod 版本
|
||||||
|
@Override
|
||||||
|
public String getModVersions() {
|
||||||
|
return ModList.get()
|
||||||
|
.getModContainerById(MinecraftMod.MOD_ID)
|
||||||
|
.map((mod) -> mod.getModInfo().getVersion().toString())
|
||||||
|
.orElse("未知版本");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLoaderVersions() {
|
||||||
|
return ModList.get()
|
||||||
|
.getModContainerById("forge")
|
||||||
|
.map((mod) -> mod.getModInfo().getVersion().toString())
|
||||||
|
.orElse("未知版本");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLoaderName() {
|
||||||
|
return "Forge";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EnchantmentEntity> getAllEnchantments() {
|
||||||
|
var registry = ForgeMod.SERVER.registryAccess().registryOrThrow(Registries.ENCHANTMENT);
|
||||||
|
return registry
|
||||||
|
.stream()
|
||||||
|
.map((a) ->
|
||||||
|
new EnchantmentEntity(
|
||||||
|
a.getDescriptionId(),
|
||||||
|
"null",
|
||||||
|
a.getFullname(a.getMaxLevel()).getString(),
|
||||||
|
registry.getId(a)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getTest(Integer fid, Integer sid) {
|
||||||
|
var registry = ForgeMod.SERVER.registryAccess().registryOrThrow(Registries.ENCHANTMENT);
|
||||||
|
var f = registry.byId(fid);
|
||||||
|
var s = registry.byId(sid);
|
||||||
|
return f.isCompatibleWith(s) && s.isCompatibleWith(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveConfig(Map<String, ConfigPair> configPairMap) {
|
||||||
|
ForgeMod.CONFIGMANAGER.setConfig(configPairMap);
|
||||||
|
ForgeMod.CONFIGMANAGER.save();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.mingliqiye.minecraft.enchantment.conflict.forge.mixin;
|
||||||
|
|
||||||
|
import com.mingliqiye.minecraft.enchantment.conflict.forge.ForgeMod;
|
||||||
|
import net.minecraft.world.item.enchantment.Enchantment;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(Enchantment.class)
|
||||||
|
public class EnchantmentMixin {
|
||||||
|
|
||||||
|
@Inject(method = "isCompatibleWith", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void isCompatibleWith(Enchantment enchantment, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
var rb = ForgeMod.ENCHANTMENTCONTROLLER.canBeCombined(
|
||||||
|
enchantment.getDescriptionId(),
|
||||||
|
getThis().getDescriptionId()
|
||||||
|
);
|
||||||
|
if (rb != null) {
|
||||||
|
cir.setReturnValue(rb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
private Enchantment getThis() {
|
||||||
|
return (Enchantment) (Object) this;
|
||||||
|
}
|
||||||
|
}
|
98
modsrc/1.20/build.gradle
Normal file
98
modsrc/1.20/build.gradle
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import java.util.jar.JarInputStream
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'com.gradleup.shadow' version '9.0.0-rc1'
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
withSourcesJar()
|
||||||
|
}
|
||||||
|
version = "${minecraft_version}-${mod_version}"
|
||||||
|
base {
|
||||||
|
archivesName = project.archives_base_name
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def jars = mod_loaders.split(',').toList()
|
||||||
|
def add_outer = mod_add_outer.split(',').toList()
|
||||||
|
|
||||||
|
def getManifestAttributes(File jarFile) {
|
||||||
|
def manifestMap = [:]
|
||||||
|
if (!jarFile.exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
new JarInputStream(jarFile.newInputStream()).withCloseable { jarStream ->
|
||||||
|
def manifest = jarStream.manifest
|
||||||
|
if (manifest == null) {
|
||||||
|
println "警告: ${jarFile.name} 中没有MANIFEST.MF"
|
||||||
|
return manifestMap
|
||||||
|
}
|
||||||
|
manifest.mainAttributes.each { key, value -> manifestMap[key.toString()] = value.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return manifestMap
|
||||||
|
}
|
||||||
|
|
||||||
|
def getJarName(String s) {
|
||||||
|
return rootProject.projectDir.toPath().resolve("mod_build/${mod_id}-${s}-${minecraft_version}-${mod_version}.jar")
|
||||||
|
}
|
||||||
|
|
||||||
|
def getJarNameOuther(String s, String v) {
|
||||||
|
return rootProject.projectDir.toPath().resolve("mod_build/${mod_id}-${s}-${v}-${mod_version}.jar")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tasks.shadowJar {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
mod_relocate_packs_id.split(",").toList().forEach {
|
||||||
|
relocate("$it", "com.mingliqiye.minecraft.enchantment.conflict.library.$it")
|
||||||
|
}
|
||||||
|
dependsOn("sourcesJar")
|
||||||
|
jars.forEach { t ->
|
||||||
|
{
|
||||||
|
dependsOn(":modsrc:${minecraft_version}:${t}:clean")
|
||||||
|
dependsOn(":modsrc:${minecraft_version}:${t}:build")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_outer.forEach { t ->
|
||||||
|
{
|
||||||
|
dependsOn(":modsrc:${t}:clean")
|
||||||
|
dependsOn(":modsrc:${t}:build")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def allAttributes = [:]
|
||||||
|
doFirst {
|
||||||
|
jars.forEach { jar ->
|
||||||
|
def file = getJarName(jar).toFile()
|
||||||
|
if (file.exists()) {
|
||||||
|
from(zipTree(file))
|
||||||
|
allAttributes.putAll(getManifestAttributes(file))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_outer.forEach { t ->
|
||||||
|
if (!t.isEmpty()) {
|
||||||
|
def sp = t.split(":")
|
||||||
|
def file = getJarNameOuther(sp[1], sp[0]).toFile()
|
||||||
|
if (file.exists()) {
|
||||||
|
from(zipTree(file))
|
||||||
|
allAttributes.putAll(getManifestAttributes(file))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
manifest.attributes(allAttributes)
|
||||||
|
}
|
||||||
|
archiveClassifier = ''
|
||||||
|
from project(':common').sourceSets.main.output
|
||||||
|
from {
|
||||||
|
project(':common').configurations.runtimeClasspath
|
||||||
|
.filter { it.exists() }
|
||||||
|
.collect { it.isDirectory() ? it : zipTree(it) }
|
||||||
|
} {
|
||||||
|
exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA',
|
||||||
|
'LICENSE', 'org/slf4j/**', "META-INF/maven/**", "META-INF/*LICENSE*",
|
||||||
|
"META-INF/*NOTICE*", "META-INF/versions/**"
|
||||||
|
}
|
||||||
|
mergeServiceFiles()
|
||||||
|
minimize()
|
||||||
|
}
|
15
modsrc/1.20/gradle.properties
Normal file
15
modsrc/1.20/gradle.properties
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
minecraft_version=1.20
|
||||||
|
fabric_version=0.83.0+1.20
|
||||||
|
fabric_loader_version=0.16.14
|
||||||
|
fabric_loom_version=1.10.5
|
||||||
|
java_version=17
|
||||||
|
|
||||||
|
mod_loaders=Fabric,Forge
|
||||||
|
mod_add_outer=
|
||||||
|
|
||||||
|
mapping_channel=official
|
||||||
|
mapping_version=1.20
|
||||||
|
forge_version=46.0.14
|
||||||
|
minecraft_version_range=[1.20,1.21)
|
||||||
|
forge_version_range=[46,)
|
||||||
|
loader_version_range=[46,)
|
44
package.json
Normal file
44
package.json
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"name": "enchantmentdoesnotconflict",
|
||||||
|
"version": "2.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "run-p type-check \"build-only {@}\" --",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"build-only": "vite build",
|
||||||
|
"type-check": "vue-tsc --build",
|
||||||
|
"format": "prettier --write \"**/*.{js,ts,jsx,tsx,vue,astro,java,json}\""
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "Apache License 2.0",
|
||||||
|
"packageManager": "pnpm@10.4.1",
|
||||||
|
"dependencies": {
|
||||||
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
|
"alova": "^3.3.4",
|
||||||
|
"bluebird": "^3.7.2",
|
||||||
|
"element-plus": "^2.10.4",
|
||||||
|
"vue": "^3.5.17"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tsconfig/node22": "^22.0.2",
|
||||||
|
"@types/bluebird": "^3.5.42",
|
||||||
|
"@types/node": "^22.15.32",
|
||||||
|
"@vitejs/plugin-vue": "^6.0.0",
|
||||||
|
"@vue/tsconfig": "^0.7.0",
|
||||||
|
"npm-run-all2": "^8.0.4",
|
||||||
|
"prettier": "^3.6.2",
|
||||||
|
"prettier-plugin-java": "^2.7.1",
|
||||||
|
"typescript": "~5.8.0",
|
||||||
|
"vite": "^7.0.0",
|
||||||
|
"vite-plugin-vue-devtools": "^7.7.7",
|
||||||
|
"vue-tsc": "^2.2.10"
|
||||||
|
},
|
||||||
|
"pnpm": {
|
||||||
|
"onlyBuiltDependencies": [
|
||||||
|
"esbuild"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
8
prettierrc
Normal file
8
prettierrc
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/prettierrc",
|
||||||
|
"plugins": [
|
||||||
|
"prettier-plugin-java"
|
||||||
|
],
|
||||||
|
"tabWidth": 4,
|
||||||
|
"useTabs": false
|
||||||
|
}
|
28
settings.gradle.kts
Normal file
28
settings.gradle.kts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
rootProject.name = "EnchantmentDoesNotConflict"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
val projects: String by settings.extra
|
||||||
|
val mod_name: String by settings.extra
|
||||||
|
val mod_version: String by settings.extra
|
||||||
|
|
||||||
|
include(projects.split(","))
|
||||||
|
|
||||||
|
rootProject.name = "${mod_name} V${mod_version}"
|
||||||
|
|
||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "mingliqiye"
|
||||||
|
url = uri("https://repository.mingliqiye.com/repository/maven-public/")
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
name = "Fabric"
|
||||||
|
url = uri("https://maven.fabricmc.net/")
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
name = "MinecraftForge"
|
||||||
|
url = uri("https://maven.minecraftforge.net/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
205
src/App.vue
Normal file
205
src/App.vue
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
<template>
|
||||||
|
<ElConfigProvider :locale="zhCn">
|
||||||
|
<div style="margin-bottom: 30px">
|
||||||
|
<div style="margin: 15px 0" f-c-c>
|
||||||
|
<h2>{{ info.ModName }} {{ info.ModVersions }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div f-c-c style="flex-direction: column">
|
||||||
|
<label>Minecraft 版本 {{ info.GameVersions }}</label>
|
||||||
|
<label>{{ info.LoaderName }} 版本 {{ info.LoaderVersion }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div f-c-c style="flex-direction: column">
|
||||||
|
<ElCard style="width: 90%; margin-bottom: 20px">
|
||||||
|
<template #header>
|
||||||
|
<div f-c-c>
|
||||||
|
<h2>配置</h2>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<ElCard class="card-config" v-for="(v, index) in config" style="width: 100%">
|
||||||
|
<div style="display: flex">
|
||||||
|
<div f-c-c style="height: auto">
|
||||||
|
<label style="text-wrap: nowrap; margin-right: 10px">配置组</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="!v.ed" f-c-c style="height: auto">
|
||||||
|
<label>{{ v.name }}</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ElInput style="width: 100%" v-else v-model="v.name">
|
||||||
|
<template #append>
|
||||||
|
<ElButton :icon="Select" @click="v.ed = false" />
|
||||||
|
</template>
|
||||||
|
</ElInput>
|
||||||
|
|
||||||
|
<div style="flex-grow: 1; height: 1px"></div>
|
||||||
|
<el-button v-if="!v.ed" style="margin-left: 12px" type="primary" :icon="Edit" circle @click="v.ed = true" />
|
||||||
|
<ElSwitch style="margin-left: 12px" v-model="v.e.allow" class="mb-2" />
|
||||||
|
<ElPopconfirm title="确认删除?" @confirm="config = config.filter((item) => item !== v)">
|
||||||
|
<template #reference>
|
||||||
|
<el-button style="margin-left: 12px" type="danger" :icon="Delete" circle />
|
||||||
|
</template>
|
||||||
|
</ElPopconfirm>
|
||||||
|
<el-button
|
||||||
|
style="margin-left: 12px"
|
||||||
|
type="success"
|
||||||
|
:icon="FullScreen"
|
||||||
|
circle
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
dialogVisible = true;
|
||||||
|
configtempM = v;
|
||||||
|
}
|
||||||
|
" />
|
||||||
|
<el-button
|
||||||
|
v-if="index === config.length - 1"
|
||||||
|
style="margin-left: 12px"
|
||||||
|
type="warning"
|
||||||
|
:icon="Plus"
|
||||||
|
@click="
|
||||||
|
config.push({
|
||||||
|
e: {
|
||||||
|
allow: false,
|
||||||
|
allowlist: [],
|
||||||
|
},
|
||||||
|
ed: false,
|
||||||
|
name: '新组',
|
||||||
|
})
|
||||||
|
"
|
||||||
|
circle />
|
||||||
|
</div>
|
||||||
|
</ElCard>
|
||||||
|
</ElCard>
|
||||||
|
<ElCard style="width: 90%">
|
||||||
|
<template #header>
|
||||||
|
<div f-c-c>
|
||||||
|
<h2>测试是否冲突</h2>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div>
|
||||||
|
<div f-c-c style="justify-content: center">
|
||||||
|
<ElSelect @change="test" style="width: 45%" v-model="testE.f">
|
||||||
|
<ElOption
|
||||||
|
v-for="item in enchantments"
|
||||||
|
:key="item.id"
|
||||||
|
:label="getEnlang(item.id, item.name)"
|
||||||
|
:value="item.nid" />
|
||||||
|
</ElSelect>
|
||||||
|
<div style="flex-grow: 1"></div>
|
||||||
|
{{ iscongtu ? '不冲突' : '冲突' }}
|
||||||
|
<div style="flex-grow: 1"></div>
|
||||||
|
<ElSelect @change="test" style="width: 45%" v-model="testE.s">
|
||||||
|
<ElOption
|
||||||
|
v-for="item in enchantments"
|
||||||
|
:key="item.id"
|
||||||
|
:label="getEnlang(item.id, item.name)"
|
||||||
|
:value="item.nid" />
|
||||||
|
</ElSelect>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ElCard>
|
||||||
|
</div>
|
||||||
|
<ElDialog v-model="dialogVisible" :title="'修改配置组 ' + configtempM.name" align-center width="800">
|
||||||
|
<div class="card-config" f-c-c v-for="(item, index) in configtempM.e.allowlist">
|
||||||
|
<label style="margin-right: 20px">{{ index + 1 }}</label>
|
||||||
|
<ElSelect v-model="configtempM.e.allowlist[index]">
|
||||||
|
<ElOption
|
||||||
|
v-for="item in enchantments"
|
||||||
|
:key="item.id"
|
||||||
|
:label="getEnlang(item.id, item.name)"
|
||||||
|
:value="item.id" />
|
||||||
|
</ElSelect>
|
||||||
|
<ElButton
|
||||||
|
style="margin-left: 10px"
|
||||||
|
type="danger"
|
||||||
|
@click="() => (configtempM.e.allowlist = configtempM.e.allowlist.filter((ee) => ee !== item))">
|
||||||
|
删除
|
||||||
|
</ElButton>
|
||||||
|
</div>
|
||||||
|
<ElButton type="primary" style="margin-left: 28px" @click="() => configtempM.e.allowlist.push('')">添加</ElButton>
|
||||||
|
</ElDialog>
|
||||||
|
</ElConfigProvider>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ElConfigProvider, ElOption, ElSelect } from 'element-plus';
|
||||||
|
import zhCn from 'element-plus/es/locale/lang/zh-cn';
|
||||||
|
import Apis from '@/api/apis.ts';
|
||||||
|
import EnLangs from '@/resources/enLangs.json';
|
||||||
|
import { onMounted, ref, watch } from 'vue';
|
||||||
|
import type { Config, ConfigPair, EnchantmentEntity, ModInfoType } from '@/api/types.ts';
|
||||||
|
import { ElButton, ElCard, ElDialog, ElInput, ElPopconfirm, ElSwitch } from 'element-plus';
|
||||||
|
import { Delete, Edit, FullScreen, Plus, Select } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
|
const getEnlang = (i: string, def: string) => {
|
||||||
|
i = i.replace('minecraft:', 'enchantment.minecraft.');
|
||||||
|
return Object.keys(EnLangs).includes(i) ? EnLangs[i] : def;
|
||||||
|
};
|
||||||
|
const testE = ref<{
|
||||||
|
f: number | null;
|
||||||
|
s: number | null;
|
||||||
|
}>({
|
||||||
|
f: null,
|
||||||
|
s: null,
|
||||||
|
});
|
||||||
|
const test = () => {
|
||||||
|
if (testE.value.f != null && testE.value.s != null) {
|
||||||
|
Apis.getTest(testE.value.f, testE.value.s).then((r) => (iscongtu.value = r.data));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
type ConfigTem = { e: ConfigPair; ed: boolean; name: string };
|
||||||
|
const info = ref<ModInfoType>({ GameVersions: '', LoaderName: '', LoaderVersion: '', ModName: '', ModVersions: '' });
|
||||||
|
const config = ref<ConfigTem[]>([]);
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const iscongtu = ref(false);
|
||||||
|
const configtempM = ref<ConfigTem>({
|
||||||
|
e: {
|
||||||
|
allow: false,
|
||||||
|
allowlist: [],
|
||||||
|
},
|
||||||
|
ed: false,
|
||||||
|
name: '',
|
||||||
|
});
|
||||||
|
const enchantments = ref<{ [key: string]: EnchantmentEntity }>({});
|
||||||
|
const getdata = () => {
|
||||||
|
Apis.getInfo().then((r) => (info.value = r.data));
|
||||||
|
Apis.getConfig().then((r) => {
|
||||||
|
Object.keys(r.data).forEach((a) => config.value.push({ ed: false, name: a, e: r.data[a] }));
|
||||||
|
startw();
|
||||||
|
});
|
||||||
|
Apis.getEnchantments().then((r) => {
|
||||||
|
r.data.forEach((a) => {
|
||||||
|
enchantments.value[a.id] = a;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const startw = () => {
|
||||||
|
watch(
|
||||||
|
() => config.value,
|
||||||
|
() => {
|
||||||
|
const data: Config = {};
|
||||||
|
config.value.forEach((a) => {
|
||||||
|
data[a.name] = a.e;
|
||||||
|
});
|
||||||
|
Apis.sendConfig(data).then();
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
onMounted(getdata);
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-config {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-config:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
13
src/api/alova.ts
Normal file
13
src/api/alova.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { createAlova } from 'alova';
|
||||||
|
import adapterFetch from 'alova/fetch';
|
||||||
|
|
||||||
|
const alovaInstance = createAlova({
|
||||||
|
requestAdapter: adapterFetch(),
|
||||||
|
responded: (response) => {
|
||||||
|
if (response.status == 200) return response.json();
|
||||||
|
else throw new Error('请求失败');
|
||||||
|
},
|
||||||
|
cacheFor: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default alovaInstance;
|
16
src/api/apis.ts
Normal file
16
src/api/apis.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import alovaInstance from '@/api/alova.ts';
|
||||||
|
import type { Config, ModInfoType, Respose, EnchantmentEntity } from '@/api/types.ts';
|
||||||
|
|
||||||
|
const map: Map<string, string> = new Map();
|
||||||
|
const baseURL = '/api';
|
||||||
|
export default {
|
||||||
|
getInfo: () => alovaInstance.Get<Respose<ModInfoType>>(baseURL + '/get/info'),
|
||||||
|
getEnchantments: () => alovaInstance.Get<Respose<EnchantmentEntity[]>>(baseURL + '/get/enchantments'),
|
||||||
|
getConfig: () => alovaInstance.Get<Respose<Config>>(baseURL + '/get/client/config'),
|
||||||
|
getTest: (fid: number, sid: number) =>
|
||||||
|
alovaInstance.Post<Respose<boolean>>(baseURL + '/get/test', {
|
||||||
|
fid,
|
||||||
|
sid,
|
||||||
|
}),
|
||||||
|
sendConfig: (config: Config) => alovaInstance.Post(baseURL + '/send/config', config),
|
||||||
|
};
|
30
src/api/types.ts
Normal file
30
src/api/types.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
export interface Respose<T> {
|
||||||
|
code: number;
|
||||||
|
message: string;
|
||||||
|
data: T;
|
||||||
|
dateTime: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ModInfoType {
|
||||||
|
LoaderVersion: string;
|
||||||
|
LoaderName: string;
|
||||||
|
GameVersions: string;
|
||||||
|
ModVersions: string;
|
||||||
|
ModName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnchantmentEntity {
|
||||||
|
id: string;
|
||||||
|
father: string;
|
||||||
|
name: string;
|
||||||
|
nid: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Config {
|
||||||
|
[key: string]: ConfigPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConfigPair {
|
||||||
|
allow: boolean;
|
||||||
|
allowlist: string[];
|
||||||
|
}
|
12
src/main.ts
Normal file
12
src/main.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { createApp } from 'vue';
|
||||||
|
import App from './App.vue';
|
||||||
|
import '/src/resources/index.css';
|
||||||
|
import 'element-plus/es/components/card/style/css';
|
||||||
|
import 'element-plus/es/components/switch/style/css';
|
||||||
|
import 'element-plus/es/components/button/style/css';
|
||||||
|
import 'element-plus/es/components/input/style/css';
|
||||||
|
import 'element-plus/es/components/dialog/style/css';
|
||||||
|
import 'element-plus/es/components/popconfirm/style/css';
|
||||||
|
import 'element-plus/es/components/option/style/css';
|
||||||
|
import 'element-plus/es/components/select/style/css';
|
||||||
|
createApp(App).mount('main');
|
45
src/resources/enLangs.json
Normal file
45
src/resources/enLangs.json
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"enchantment.minecraft.aqua_affinity": "水下速掘",
|
||||||
|
"enchantment.minecraft.bane_of_arthropods": "节肢杀手",
|
||||||
|
"enchantment.minecraft.binding_curse": "绑定诅咒",
|
||||||
|
"enchantment.minecraft.blast_protection": "爆炸保护",
|
||||||
|
"enchantment.minecraft.breach": "破甲",
|
||||||
|
"enchantment.minecraft.channeling": "引雷",
|
||||||
|
"enchantment.minecraft.density": "致密",
|
||||||
|
"enchantment.minecraft.depth_strider": "深海探索者",
|
||||||
|
"enchantment.minecraft.efficiency": "效率",
|
||||||
|
"enchantment.minecraft.feather_falling": "摔落缓冲",
|
||||||
|
"enchantment.minecraft.fire_aspect": "火焰附加",
|
||||||
|
"enchantment.minecraft.fire_protection": "火焰保护",
|
||||||
|
"enchantment.minecraft.flame": "火矢",
|
||||||
|
"enchantment.minecraft.fortune": "时运",
|
||||||
|
"enchantment.minecraft.frost_walker": "冰霜行者",
|
||||||
|
"enchantment.minecraft.impaling": "穿刺",
|
||||||
|
"enchantment.minecraft.infinity": "无限",
|
||||||
|
"enchantment.minecraft.knockback": "击退",
|
||||||
|
"enchantment.minecraft.looting": "抢夺",
|
||||||
|
"enchantment.minecraft.loyalty": "忠诚",
|
||||||
|
"enchantment.minecraft.luck_of_the_sea": "海之眷顾",
|
||||||
|
"enchantment.minecraft.lure": "饵钓",
|
||||||
|
"enchantment.minecraft.mending": "经验修补",
|
||||||
|
"enchantment.minecraft.multishot": "多重射击",
|
||||||
|
"enchantment.minecraft.piercing": "穿透",
|
||||||
|
"enchantment.minecraft.power": "力量",
|
||||||
|
"enchantment.minecraft.projectile_protection": "弹射物保护",
|
||||||
|
"enchantment.minecraft.protection": "保护",
|
||||||
|
"enchantment.minecraft.punch": "冲击",
|
||||||
|
"enchantment.minecraft.quick_charge": "快速装填",
|
||||||
|
"enchantment.minecraft.respiration": "水下呼吸",
|
||||||
|
"enchantment.minecraft.riptide": "激流",
|
||||||
|
"enchantment.minecraft.sharpness": "锋利",
|
||||||
|
"enchantment.minecraft.silk_touch": "精准采集",
|
||||||
|
"enchantment.minecraft.smite": "亡灵杀手",
|
||||||
|
"enchantment.minecraft.soul_speed": "灵魂疾行",
|
||||||
|
"enchantment.minecraft.sweeping": "横扫之刃",
|
||||||
|
"enchantment.minecraft.sweeping_edge": "横扫之刃",
|
||||||
|
"enchantment.minecraft.swift_sneak": "迅捷潜行",
|
||||||
|
"enchantment.minecraft.thorns": "荆棘",
|
||||||
|
"enchantment.minecraft.unbreaking": "耐久",
|
||||||
|
"enchantment.minecraft.vanishing_curse": "消失诅咒",
|
||||||
|
"enchantment.minecraft.wind_burst": "风爆"
|
||||||
|
}
|
BIN
src/resources/icon.png
Normal file
BIN
src/resources/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
5
src/resources/index.css
Normal file
5
src/resources/index.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
*[f-c-c]{
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
BIN
src/resources/title_full.png
Normal file
BIN
src/resources/title_full.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 218 KiB |
12
tsconfig.app.json
Normal file
12
tsconfig.app.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||||
|
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
|
||||||
|
"exclude": ["src/**/__tests__/*"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
tsconfig.json
Normal file
11
tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.app.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
19
tsconfig.node.json
Normal file
19
tsconfig.node.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"extends": "@tsconfig/node22/tsconfig.json",
|
||||||
|
"include": [
|
||||||
|
"vite.config.*",
|
||||||
|
"vitest.config.*",
|
||||||
|
"cypress.config.*",
|
||||||
|
"nightwatch.conf.*",
|
||||||
|
"playwright.config.*",
|
||||||
|
"eslint.config.*"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"noEmit": true,
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"types": ["node"]
|
||||||
|
}
|
||||||
|
}
|
22
vite.config.ts
Normal file
22
vite.config.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { fileURLToPath, URL } from 'node:url';
|
||||||
|
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import vue from '@vitejs/plugin-vue';
|
||||||
|
import vueDevTools from 'vite-plugin-vue-devtools';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue(), vueDevTools()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: 'dist/assets/enchantmentdoesnotconflict/web',
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
proxy: {
|
||||||
|
'/api': 'http://localhost:1355/',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user