diff --git a/build.gradle b/build.gradle index c113580..2bd2892 100644 --- a/build.gradle +++ b/build.gradle @@ -8,12 +8,11 @@ plugins { id 'net.neoforged.moddev.legacyforge' version '2.0.103' } +java { + toolchain.languageVersion = JavaLanguageVersion.of(17) +} + tasks.named('wrapper', Wrapper).configure { - // Define wrapper values here so as to not have to always do so when updating gradlew.properties. - // Switching this to Wrapper.DistributionType.ALL will download the full gradle sources that comes with - // documentation attached on cursor hover of gradle classes and methods. However, this comes with increased - // file size for Gradle. If you do switch this to ALL, run the Gradle wrapper task twice afterwards. - // (Verify by checking gradle/wrapper/gradle-wrapper.properties to see if distributionUrl now points to `-all`) distributionType = Wrapper.DistributionType.BIN } @@ -25,6 +24,11 @@ repositories { maven { url = "https://libraries.minecraft.net/" } maven { url = "https://neoforged.forgecdn.net/releases" } maven { url = "https://neoforged.forgecdn.net/mojang-meta" } + maven { url = "https://maven.neoforged.net/releases" } + maven { + name = "LTD Maven" + url = "https://nexus.bot.leisuretimedock.top/repository/maven-public/" + } flatDir { dir "libs" } @@ -46,16 +50,10 @@ legacyForge { minecraftVersion = project.parchment_minecraft_version } - // This line is optional. Access Transformers are automatically detected - // accessTransformers = project.files('src/main/resources/META-INF/accesstransformer.cfg') - // Default run configurations. - // These can be tweaked, removed, or duplicated as needed. runs { client { client() - - // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. systemProperty 'forge.enabledGameTestNamespaces', project.mod_id } clientAuth{ @@ -70,9 +68,6 @@ legacyForge { systemProperty 'forge.enabledGameTestNamespaces', project.mod_id } - // This run config launches GameTestServer and runs all registered gametests, then exits. - // By default, the server will crash when no gametests are provided. - // The gametest system is also enabled by default for other run configs under the /test command. gameTestServer { type = "gameTestServer" systemProperty 'forge.enabledGameTestNamespaces', project.mod_id @@ -80,35 +75,16 @@ legacyForge { data { data() - - // example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it - // gameDirectory = project.file('run-data') - - // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() } - // applies to all the run configs above configureEach { - // Recommended logging data for a userdev environment - // The markers can be added/remove as needed separated by commas. - // "SCAN": For mods scan. - // "REGISTRIES": For firing of registry events. - // "REGISTRYDUMP": For getting the contents of all registries. systemProperty 'forge.logging.markers', 'REGISTRIES' - - // Recommended logging level for the console - // You can set various levels here. - // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels logLevel = org.slf4j.event.Level.DEBUG } } mods { - // define mod <-> source bindings - // these are used to tell the game which sources are for which mod - // mostly optional in a single mod project - // but multi mod projects should define one per mod "${mod_id}" { sourceSet(sourceSets.main) } @@ -118,10 +94,6 @@ legacyForge { // Include resources generated by data generators. sourceSets.main.resources { srcDir 'src/generated/resources' } -// Sets up a dependency configuration called 'localRuntime' and a deobfuscating one called 'modLocalRuntime' -// These configurations should be used instead of 'runtimeOnly' to declare -// a dependency that will be present for runtime testing but that is -// "optional", meaning it will not be pulled by dependents of this mod. configurations { runtimeClasspath.extendsFrom localRuntime } @@ -130,52 +102,11 @@ obfuscation { } dependencies { - // If you wish to declare dependencies against mods, make sure to use the 'mod*' configurations so that they're remapped. - // See https://github.com/neoforged/ModDevGradle/blob/main/LEGACY.md#remapping-mod-dependencies for more information. - - // Example optional mod dependency with JEI - // The JEI API is declared for compile time use, while the full JEI artifact is used at runtime - // modCompileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}" - // modCompileOnly "mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}" - // We add the full version to localRuntime, not runtimeOnly, so that we do not publish a dependency on it - // modLocalRuntime "mezz.jei:jei-${mc_version}-neoforge:${jei_version}" + // 依赖项可以在这里添加 - // Example mod dependency using a mod jar from ./libs with a flat dir repository - // This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar - // The group id is ignored when searching -- in this case, it is "blank" - // modImplementation "blank:coolmod-${mc_version}:${coolmod_version}" - - // Example mod dependency using a file as dependency - // modImplementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar") - - // Example project dependency using a sister or child project: - // modImplementation project(":myproject") - - // For more info: - // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html - // http://www.gradle.org/docs/current/userguide/dependency_management.html } -// Uncomment the lines below if you wish to configure mixin. The mixin file should be named modid.mixins.json. -/* -mixin { - add sourceSets.main, "${mod_id}.refmap.json" - config "${mod_id}.mixins.json" -} - -dependencies { - annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' -} - -jar { - manifest.attributes([ - "MixinConfigs": "${mod_id}.mixins.json" - ]) -} -*/ - // This block of code expands all declared replace properties in the specified resource targets. -// A missing property will result in an error. Properties are expanded using ${} Groovy notation. var generateModMetadata = tasks.register("generateModMetadata", ProcessResources) { var replaceProperties = [ minecraft_version : minecraft_version, @@ -191,39 +122,239 @@ var generateModMetadata = tasks.register("generateModMetadata", ProcessResources mod_description : mod_description, mod_credits : mod_credits ] + duplicatesStrategy = DuplicatesStrategy.EXCLUDE inputs.properties replaceProperties expand replaceProperties from "src/main/templates" into "build/generated/sources/modMetadata" } -// Include the output of "generateModMetadata" as an input directory for the build -// this works with both building through Gradle and the IDE. + sourceSets.main.resources.srcDir generateModMetadata -// To avoid having to run "generateModMetadata" manually, make it run on every project reload legacyForge.ideSyncTask generateModMetadata -// Example configuration to allow publishing using the maven-publish plugin +// ==================== Javadoc 配置 ==================== +javadoc { + options { + encoding = 'UTF-8' + charSet = 'UTF-8' + author = true + version = true + windowTitle = "Lib39 ${project.mod_version} API" + docTitle = "Lib39 ${project.mod_version} API" + memberLevel = JavadocMemberLevel.PROTECTED + links = [ + 'https://docs.oracle.com/javase/8/docs/api/' + ] + addBooleanOption('Xdoclint:none', true) + addBooleanOption('html5', true) + } + + source = sourceSets.main.allJava + classpath = configurations.compileClasspath + exclude '**/test/**' + exclude '**/internal/**' +} + +tasks.register('javadocJar', Jar) { + archiveClassifier.set('javadoc') + from tasks.javadoc + dependsOn tasks.javadoc +} + +// ===================== 主包完整 Jar(class + java) ===================== +tasks.register('deobfJar', Jar) { + archiveFileName = "${mod_id}-${minecraft_version}-${mod_version}.jar" + from(sourceSets.main.output) + + // === 避免重复打包资源(即使混入其他 jar 时也不会重复) === + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + + manifest { + attributes( + 'Specification-Title': mod_id, + 'Specification-Vendor': mod_authors, + 'Implementation-Title': project.name, + 'Implementation-Version': archiveVersion, + 'Implementation-Vendor': mod_authors, + 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ) + } + + dependsOn classes +} + + + + +// ==================== 发布配置 ==================== publishing { publications { - register('mavenJava', MavenPublication) { - from components.java + mavenJava(MavenPublication) { + artifactId = mod_id + artifact deobfJar + artifact javadocJar + + pom { + name = 'Lib39' + description = 'Lib39 is a general-purpose dependency library for Minecraft mods.' + url = 'https://github.com/3944Realms/lib39' + + properties = [ + 'minecraft.version': project.minecraft_version, + 'mod.version': project.mod_version, + 'forge.version': project.forge_version, + 'java.version': '17' + ] + + licenses { + license { + name = 'MIT' + url = 'https://raw.githubusercontent.com/3944Realms/lib39/refs/heads/main/LICENSE' + distribution = 'repo' + } + } + + developers { + developer { + id = 'R3944Realms' + name = "${mod_authors}" + email = 'f256198830@hotmail.com' + } + } + + scm { + connection = 'scm:git:https://github.com/3944Realms/lib39.git' + developerConnection = 'scm:git:ssh://git@github.com:3944Realms/lib39.git' + url = 'https://github.com/3944Realms/lib39' + tag = 'main' + } + + issueManagement { + system = 'GitHub' + url = 'https://github.com/3944Realms/lib39/issues' + } + } } } + repositories { + // 本地仓库 maven { - url "file://${project.projectDir}/repo" + name = 'local' + url = layout.buildDirectory.dir("repo") + } + + // Nexus 远程仓库 + maven { + name = 'LTDNexus' + url = 'https://nexus.bot.leisuretimedock.top/repository/maven-releases/' + credentials { + username = System.getenv('LTDNexusUsername') ?: '' + password = System.getenv('LTDNexusPassword') ?: '' + } } } } +// ==================== 任务配置 ==================== tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation + options.encoding = 'UTF-8' + options.compilerArgs += ['-Xlint:unchecked', '-Xlint:deprecation'] } -// IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior. +// 配置 Javadoc JAR - 使用标准 javadoc 任务输出 +tasks.named('javadocJar') { + from javadoc.destinationDir +} +// ==================== 验证任务 ==================== +tasks.register('verifyNexusCredentials') { + doLast { + def username = System.getenv('LTDNexusUsername') + def password = System.getenv('LTDNexusPassword') + + // 安全地显示用户名和密码(只显示最后两位) + def displayUsername = username ? "***${username.length() > 2 ? username.substring(username.length() - 2) : '**'}" : 'NOT SET' + def displayPassword = password ? "***${password.length() > 2 ? password.substring(password.length() - 2) : '**'}" : 'NOT SET' + + println "Nexus Username: ${displayUsername}" + println "Nexus Password: ${displayPassword}" + + if (!username || !password) { + throw new GradleException('LTDNexusUsername or LTDNexusPassword environment variables are not set') + } + } +} + +tasks.register('checkPublicationContents') { + doLast { + def publication = publishing.publications.mavenJava + println "=== Publication Details ===" + println "Group: ${publication.groupId}" + println "Artifact: ${publication.artifactId}" + println "Version: ${publication.version}" + println "Artifacts:" + publication.artifacts.each { artifact -> + def file = artifact.file + def exists = file.exists() + println " - ${file.name} (${artifact.classifier ?: 'main'}) - Exists: ${exists}" + + if (!exists) { + throw new GradleException("Publication artifact missing: ${file.absolutePath}") + } + } + } +} + +// ==================== 任务依赖 ==================== +tasks.named('publishMavenJavaPublicationToLTDNexusRepository') { + dependsOn verifyNexusCredentials + dependsOn checkPublicationContents +} + +tasks.withType(PublishToMavenRepository) { + dependsOn assemble + dependsOn javadocJar +} + +// ==================== 便捷任务 ==================== +tasks.register('publishToNexus') { + group = 'publishing' + description = 'Publishes all publications to LTD Nexus' + dependsOn 'publishMavenJavaPublicationToLTDNexusRepository' +} + +tasks.register('publishLocal') { + group = 'publishing' + description = 'Publishes all publications to the local Maven repository' + dependsOn 'publishToMavenLocal' +} + +tasks.register('cleanRepo', Delete) { + delete layout.buildDirectory.dir("repo") +} + +tasks.named('clean') { + dependsOn cleanRepo +} + +// ==================== IDEA 配置 ==================== idea { module { downloadSources = true downloadJavadoc = true } } + +// 禁用模块元数据生成 +tasks.withType(GenerateModuleMetadata) { + enabled = false +} + +afterEvaluate { + tasks.named('deobfJar') { + doLast { + def jar = file(layout.buildDirectory.dir("repo") + "${mod_id}-${minecraft_version}-${mod_version}.jar") + if (jar.exists()) ant.delete(jar) + } + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 6ef9218..f707d4d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -33,7 +33,7 @@ mod_name=3944Realms 's Lib Mod # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=MIT # The mod version. See https://semver.org/ -mod_version=0.0.14 +mod_version=0.0.16 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/main/java/top/r3944realms/lib39/Lib39.java b/src/main/java/top/r3944realms/lib39/Lib39.java index 7f91b39..8658e95 100644 --- a/src/main/java/top/r3944realms/lib39/Lib39.java +++ b/src/main/java/top/r3944realms/lib39/Lib39.java @@ -6,20 +6,44 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import top.r3944realms.lib39.core.network.NetworkHandler; +/** + * The type Lib 39. + */ @Mod(Lib39.MOD_ID) public class Lib39 { + /** + * The constant MOD_ID. + */ public static final String MOD_ID = "lib39"; + /** + * The constant LOGGER. + */ public static final Logger LOGGER = LoggerFactory.getLogger(Lib39.class); + + /** + * Instantiates a new Lib 39. + */ public Lib39() { initialize(); } + + /** + * Initialize. + */ public static void initialize() { LOGGER.info("[Lib39] Initializing Lib39"); NetworkHandler.register(); LOGGER.info("[Lib39] Initialized Lib39"); } + + /** + * The type Mod info. + */ public static class ModInfo { + /** + * The constant VERSION. + */ public static final String VERSION; static { // 从 ModList 获取当前 ModContainer 的元数据 diff --git a/src/main/java/top/r3944realms/lib39/api/event/RegisterCompatEvent.java b/src/main/java/top/r3944realms/lib39/api/event/RegisterCompatEvent.java new file mode 100644 index 0000000..f34b815 --- /dev/null +++ b/src/main/java/top/r3944realms/lib39/api/event/RegisterCompatEvent.java @@ -0,0 +1,69 @@ +package top.r3944realms.lib39.api.event; + +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.eventbus.api.Event; +import net.minecraftforge.fml.event.IModBusEvent; +import top.r3944realms.lib39.core.compat.CompatManager; +import top.r3944realms.lib39.core.compat.ICompat; + +/** + * The type Register compat event. + */ +public class RegisterCompatEvent extends Event implements IModBusEvent { + /** + * The Compat manager. + */ + protected final CompatManager compatManager; + + /** + * Instantiates a new Register compat event. + * + * @param compatManager the compat manager + */ + public RegisterCompatEvent(CompatManager compatManager) { + this.compatManager = compatManager; + } + + /** + * Gets compat manager. + * + * @return the compat manager + */ + public CompatManager getCompatManager() { + return compatManager; + } + + /** + * Register compat. + * + * @param id the id + * @param compat the compat + */ +// 注册兼容模块 + public void registerCompat(ResourceLocation id, ICompat compat) { + compatManager.registerCompat(id, compat); + } + + /** + * Register compat. + * + * @param namespace the namespace + * @param path the path + * @param compat the compat + */ +// 注册兼容模块(简化版本) + public void registerCompat(String namespace, String path, ICompat compat) { + compatManager.registerCompat(namespace, path, compat); + } + + /** + * Unregister compat. + * + * @param id the id + */ +// 取消注册兼容模块 + public void unregisterCompat(ResourceLocation id) { + compatManager.unregisterCompat(id); + } + +} diff --git a/src/main/java/top/r3944realms/lib39/api/event/SyncManagerRegisterEvent.java b/src/main/java/top/r3944realms/lib39/api/event/SyncManagerRegisterEvent.java index c781aed..ebb61a4 100644 --- a/src/main/java/top/r3944realms/lib39/api/event/SyncManagerRegisterEvent.java +++ b/src/main/java/top/r3944realms/lib39/api/event/SyncManagerRegisterEvent.java @@ -1,43 +1,93 @@ package top.r3944realms.lib39.api.event; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.eventbus.api.Event; import top.r3944realms.lib39.core.sync.ISyncData; import top.r3944realms.lib39.core.sync.ISyncManager; import top.r3944realms.lib39.core.sync.SyncData2Manager; +import java.util.Optional; +import java.util.function.Function; + +/** + * The type Sync manager register event. + */ @SuppressWarnings("unused") public class SyncManagerRegisterEvent extends Event { + /** + * The Syncs 2 manager. + */ protected final SyncData2Manager syncs2Manager; + /** + * Instantiates a new Sync manager register event. + * + * @param syncsManager the syncs manager + */ public SyncManagerRegisterEvent(SyncData2Manager syncsManager) { this.syncs2Manager = syncsManager; } + /** + * Gets syncs manager. + * + * @return the syncs manager + */ public SyncData2Manager getSyncsManager() { return syncs2Manager; } /** * 类型安全的同步管理器注册 + * + * @param the type parameter + * @param the type parameter + * @param id the id + * @param syncManager the sync manager + * @param capability the capability */ public > void registerSyncManager( ResourceLocation id, ISyncManager syncManager, Capability capability ) { - syncs2Manager.registerManager(id, syncManager, capability); + syncs2Manager.registerManager(id, syncManager, entity -> entity.getCapability(capability).resolve()); + } + + /** + * 类型安全的同步管理器注册 + * + * @param the type parameter + * @param the type parameter + * @param id the id + * @param syncManager the sync manager + * @param dataProvider the dataProvider + */ + public > void registerSyncManager( + ResourceLocation id, + ISyncManager syncManager, + Function> dataProvider + ) { + syncs2Manager.registerManager(id, syncManager, dataProvider); } - + /** + * Unregister sync manager. + * + * @param id the id + */ public void unregisterSyncManager(ResourceLocation id) { syncs2Manager.removeManager(id); } /** * 允许实体类 + * + * @param id the id + * @param entityClasses the entity classes */ public final void addAllowEntityClass(ResourceLocation id, Class... entityClasses) { syncs2Manager.allowEntityClass(id, entityClasses); @@ -45,6 +95,9 @@ public class SyncManagerRegisterEvent extends Event { /** * 移除允许的实体类 + * + * @param id the id + * @param entityClasses the entity classes */ public final void removeAllowEntityClass(ResourceLocation id, Class... entityClasses) { syncs2Manager.disallowEntityClass(id, entityClasses); @@ -52,21 +105,33 @@ public class SyncManagerRegisterEvent extends Event { /** * 绑定能力(用于分离注册的情况) - * @param id 必须先注册安全同步管理器,再绑定Cap,否则会抛出{@link IllegalStateException 未找到对应安全同步管理器} + * + * @param the type parameter + * @param id 必须先注册安全同步管理器,再绑定Cap,否则会抛出{@link IllegalStateException 未找到对应安全同步管理器} + * @param capability the capability */ public > void bindCapability(ResourceLocation id, Capability capability) { - syncs2Manager.bindCapability(id, capability); + syncs2Manager.bindDataGetter(id, entity -> entity.getCapability(capability).resolve()); } /** - * 解绑能力 + * 解绑数据提供者 + * + * @param id the id */ - public void unbindCapability(ResourceLocation id) { - syncs2Manager.unbindCapability(id); + public void unbindDataProvider(ResourceLocation id) { + syncs2Manager.unbindDataProvider(id); } /** * 完整的类型安全注册 + * + * @param the type parameter + * @param the type parameter + * @param id the id + * @param syncManager the sync manager + * @param capability the capability + * @param allowedEntityClasses the allowed entity classes */ public > void registerComplete( ResourceLocation id, @@ -79,4 +144,26 @@ public class SyncManagerRegisterEvent extends Event { addAllowEntityClass(id, allowedEntityClasses); } } + + /** + * 完整的类型安全注册 + * + * @param the type parameter + * @param the type parameter + * @param id the id + * @param syncManager the sync manager + * @param dataProvider the capability + * @param allowedEntityClasses the allowed entity classes + */ + public > void registerComplete( + ResourceLocation id, + ISyncManager syncManager, + Function> dataProvider, + Class... allowedEntityClasses + ) { + registerSyncManager(id, syncManager, dataProvider); + if (allowedEntityClasses.length > 0) { + addAllowEntityClass(id, allowedEntityClasses); + } + } } \ No newline at end of file diff --git a/src/main/java/top/r3944realms/lib39/core/compat/CompatManager.java b/src/main/java/top/r3944realms/lib39/core/compat/CompatManager.java new file mode 100644 index 0000000..952e9f8 --- /dev/null +++ b/src/main/java/top/r3944realms/lib39/core/compat/CompatManager.java @@ -0,0 +1,332 @@ +package top.r3944realms.lib39.core.compat; + +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.common.Mod; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import top.r3944realms.lib39.Lib39; + +import java.util.*; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +/** + * The type Compat manager. + */ +@SuppressWarnings("unused") +public class CompatManager { + private final Map compats = new HashMap<>(); + private final IEventBus modEventBus, gameEventBus; + + // 存储事件监听器配置 + private final List listenerConfigs = new ArrayList<>(); + + + /** + * Instantiates a new Compat manager. + * + * @param modEventBus the mod event bus + * @param gameEventBus the game event bus + */ + public CompatManager(IEventBus modEventBus, IEventBus gameEventBus) { + this.modEventBus = modEventBus; + this.gameEventBus = gameEventBus; + } + + /** + * Register compat. + * + * @param id the id + * @param compat the compat + */ + public void registerCompat(ResourceLocation id, ICompat compat) { + if (compats.containsKey(id)) { + Lib39.LOGGER.warn("Compat with id {} is already registered!", id); + return; + } + compats.put(id, compat); + Lib39.LOGGER.debug("Registered compat: {}", id); + } + + /** + * Register compat. + * + * @param namespace the namespace + * @param path the path + * @param compat the compat + */ + public void registerCompat(String namespace, String path, ICompat compat) { + registerCompat(new ResourceLocation(namespace, path), compat); + } + + /** + * 为所有兼容模块配置事件监听器 + * + * @param dists the dists + * @param bus the bus + */ + public void addListenerForAll(@Nullable Dist dists, Mod.EventBusSubscriber.Bus bus) { + listenerConfigs.add(new ListenerConfig(null, dists, bus)); + } + + /** + * 为特定兼容模块配置事件监听器 + * + * @param compatId the compat id + * @param dists the dists + * @param bus the bus + */ + public void addListenerForCompat(ResourceLocation compatId, @Nullable Dist dists, Mod.EventBusSubscriber.Bus bus) { + listenerConfigs.add(new ListenerConfig(compatId, dists, bus)); + } + + /** + * 为已加载的兼容模块配置事件监听器 + * + * @param dists the dists + * @param bus the bus + * @param consumer the consumer + */ + public void addListenerForLoaded(@Nullable Dist dists, Mod.EventBusSubscriber.Bus bus, Consumer consumer) { + listenerConfigs.add(new ListenerConfig(null, dists, bus) { + @Override + boolean shouldApply(@NotNull ICompat compat) { + return super.shouldApply(compat); + } + }); + } + + // ===================== 初始化和管理 ===================== + + /** + * 初始化所有兼容模块并应用事件监听器 + */ + public void initializeAll() { + Lib39.LOGGER.info("Initializing {} compatibility modules", compats.size()); + + // 1. 先初始化所有兼容模块 + for (Map.Entry entry : compats.entrySet()) { + try { + entry.getValue().initialize(); + Lib39.LOGGER.info("Initialized compat: {}", entry.getKey()); + } catch (Exception e) { + Lib39.LOGGER.error("Failed to initialize compat: {}", entry.getKey(), e); + } + } + + // 2. 然后应用所有事件监听器 + applyAllEventListeners(); + } + + /** + * 应用所有配置的事件监听器到对应的 ICompat 实例 + */ + private void applyAllEventListeners() { + Lib39.LOGGER.info("Applying {} event listener configurations", listenerConfigs.size()); + + for (ListenerConfig config : listenerConfigs) { + if (config.compatId == null) { + // 应用到所有兼容模块 + applyListenerToAllCompats(config); + } else { + // 应用到特定兼容模块 + applyListenerToCompat(config.compatId, config); + } + } + } + + /** + * 将监听器应用到所有兼容模块 + */ + private void applyListenerToAllCompats(ListenerConfig config) { + for (ICompat compat : compats.values()) { + if (config.shouldApply(compat)) { + applyListenerToCompat(compat, config); + } + } + } + + /** + * 将监听器应用到特定兼容模块 + */ + private void applyListenerToCompat(ResourceLocation compatId, ListenerConfig config) { + ICompat compat = compats.get(compatId); + if (compat != null && config.shouldApply(compat)) { + applyListenerToCompat(compat, config); + } + } + + /** + * 将监听器应用到具体的 ICompat 实例 + */ + private void applyListenerToCompat(ICompat compat, ListenerConfig config) { + try { + // 根据配置调用对应的 ICompat 方法 + if (config.dists != null) { + switch (config.dists) { + case CLIENT -> { + if (config.bus == Mod.EventBusSubscriber.Bus.FORGE) { + compat.addClientGameListener(gameEventBus); + } else { + compat.addClientModListener(modEventBus); + } + } + case DEDICATED_SERVER -> { + if (config.bus == Mod.EventBusSubscriber.Bus.FORGE) { + compat.addServerGameListener(gameEventBus); + } else { + compat.addServerModListener(modEventBus); + } + } + } + } else { + // 通用监听器 + if (config.bus == Mod.EventBusSubscriber.Bus.FORGE) { + compat.addCommonGameListener(gameEventBus); + } else { + compat.addCommonModListener(modEventBus); + } + } + + Lib39.LOGGER.debug("Applied {} listener to compat: {}", + getListenerTypeName(config), compat.id()); + + } catch (Exception e) { + Lib39.LOGGER.error("Failed to apply listener to compat: {}", compat.id(), e); + } + } + + /** + * 获取监听器类型名称(用于日志) + */ + private @NotNull String getListenerTypeName(@NotNull ListenerConfig config) { + if (config.dists != null) { + return config.dists.name().toLowerCase() + " " + + (config.bus == Mod.EventBusSubscriber.Bus.FORGE ? "game" : "mod"); + } else { + return "common " + (config.bus == Mod.EventBusSubscriber.Bus.FORGE ? "game" : "mod"); + } + } + + // ===================== 便捷方法 ===================== + + /** + * Add listener for all. + * + * @param bus the bus + */ + public void addListenerForAll(Mod.EventBusSubscriber.Bus bus) { + addListenerForAll(null, bus); + } + + /** + * Add listener for compat. + * + * @param compatId the compat id + * @param bus the bus + */ + public void addListenerForCompat(ResourceLocation compatId, Mod.EventBusSubscriber.Bus bus) { + addListenerForCompat(compatId, null, bus); + } + + private static class ListenerConfig { + /** + * The Compat id. + */ + final ResourceLocation compatId; + /** + * The Dists. + */ + final Dist dists; + /** + * The Bus. + */ + final Mod.EventBusSubscriber.Bus bus; + + /** + * Instantiates a new Listener config. + * + * @param compatId the compat id + * @param dists the dists + * @param bus the bus + */ + ListenerConfig(ResourceLocation compatId, Dist dists, Mod.EventBusSubscriber.Bus bus) { + this.compatId = compatId; + this.dists = dists; + this.bus = bus; + } + + /** + * Should apply boolean. + * + * @param compat the compat + * @return the boolean + */ + boolean shouldApply(@NotNull ICompat compat) { + return compat.isModLoaded(); + } + } + + // ===================== 其他方法 ===================== + + /** + * On load complete. + */ + public void onLoadComplete() { + Lib39.LOGGER.info("Calling onLoadComplete for {} compatibility modules", compats.size()); + for (Map.Entry entry : compats.entrySet()) { + try { + entry.getValue().onLoadComplete(); + } catch (Exception e) { + Lib39.LOGGER.error("Error in onLoadComplete for compat: {}", entry.getKey(), e); + } + } + } + + /** + * Gets compat. + * + * @param id the id + * @return the compat + */ + public Optional getCompat(ResourceLocation id) { + return Optional.ofNullable(compats.get(id)); + } + + /** + * Has compat boolean. + * + * @param id the id + * @return the boolean + */ + public boolean hasCompat(ResourceLocation id) { + return compats.containsKey(id); + } + + /** + * Unregister compat. + * + * @param id the id + */ + public void unregisterCompat(ResourceLocation id) { + ICompat removed = compats.remove(id); + if (removed != null) { + Lib39.LOGGER.debug("Unregistered compat: {}", id); + } + } + + /** + * Gets loaded compats. + * + * @return the loaded compats + */ + public List getLoadedCompats() { + return compats.values().stream() + .filter(ICompat::isModLoaded) + .collect(Collectors.toList()); + } + + +} \ No newline at end of file diff --git a/src/main/java/top/r3944realms/lib39/core/compat/ICompat.java b/src/main/java/top/r3944realms/lib39/core/compat/ICompat.java new file mode 100644 index 0000000..90fd8c8 --- /dev/null +++ b/src/main/java/top/r3944realms/lib39/core/compat/ICompat.java @@ -0,0 +1,132 @@ +package top.r3944realms.lib39.core.compat; + +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.eventbus.api.IEventBus; + +import java.util.concurrent.Callable; +import java.util.function.Consumer; + +/** + * The interface Compat. + */ +public interface ICompat { + + /** + * Id resource location. + * + * @return the resource location + */ + ResourceLocation id(); + + /** + * Initialize. + */ + void initialize(); + + /** + * On load complete. + */ + default void onLoadComplete() {} + + /** + * Is mod loaded boolean. + * + * @return the boolean + */ + default boolean isModLoaded() { + return false; + } + + /** + * Call if present t. + * + * @param the type parameter + * @param callable the callable + * @return the t + * @throws Exception the exception + */ + default T callIfPresent(Callable callable) throws Exception { + if (isModLoaded()) return callable.call(); + else return null; + } + + /** + * Call if pesent t. + * + * @param the type parameter + * @param callable the callable + * @param elseCall the else call + * @return the t + * @throws Exception the exception + */ + default T callIfPresent(Callable callable, Callable elseCall) throws Exception { + if (isModLoaded()) return callable.call(); + else return elseCall.call(); + } + + /** + * Run if present boolean. + * + * @param runnable the runnable + * @return the boolean + * @throws Exception the exception + */ + default boolean runIfPresent(Runnable runnable) throws Exception { + if (isModLoaded()) runnable.run(); else return false; + return true; + } + + /** + * Add common game listener. + * + * @param gameBus the game bus + */ + default void addCommonGameListener(IEventBus gameBus) { + // 实现通用游戏事件监听器添加逻辑 + } + + /** + * Add common mod listener. + * + * @param modBus the mod bus + */ + default void addCommonModListener(IEventBus modBus) { + // 实现通用模组事件监听器添加逻辑 + } + + /** + * Add client game listener. + * + * @param gameBus the game bus + */ + default void addClientGameListener(IEventBus gameBus) { + // 实现客户端游戏事件监听器添加逻辑 + } + + /** + * Add client mod listener. + * + * @param modBus the mod bus + */ + default void addClientModListener(IEventBus modBus) { + // 实现客户端模组事件监听器添加逻辑 + } + + /** + * Add server game listener. + * + * @param gameBus the game bus + */ + default void addServerGameListener(IEventBus gameBus) { + // 实现服务端游戏事件监听器添加逻辑 + } + + /** + * Add server mod listener. + * + * @param modBus the mod bus + */ + default void addServerModListener(IEventBus modBus) { + // 实现服务端模组事件监听器添加逻辑 + } +} diff --git a/src/main/java/top/r3944realms/lib39/core/event/ClientEventHandler.java b/src/main/java/top/r3944realms/lib39/core/event/ClientEventHandler.java new file mode 100644 index 0000000..847720e --- /dev/null +++ b/src/main/java/top/r3944realms/lib39/core/event/ClientEventHandler.java @@ -0,0 +1,7 @@ +package top.r3944realms.lib39.core.event; + +/** + * The type Client handler. + */ +public class ClientEventHandler { +} diff --git a/src/main/java/top/r3944realms/lib39/core/event/ClientHandler.java b/src/main/java/top/r3944realms/lib39/core/event/ClientHandler.java deleted file mode 100644 index da0dc08..0000000 --- a/src/main/java/top/r3944realms/lib39/core/event/ClientHandler.java +++ /dev/null @@ -1,4 +0,0 @@ -package top.r3944realms.lib39.core.event; - -public class ClientHandler { -} diff --git a/src/main/java/top/r3944realms/lib39/core/event/CommonHandler.java b/src/main/java/top/r3944realms/lib39/core/event/CommonEventHandler.java similarity index 66% rename from src/main/java/top/r3944realms/lib39/core/event/CommonHandler.java rename to src/main/java/top/r3944realms/lib39/core/event/CommonEventHandler.java index 1e10b5f..64748af 100644 --- a/src/main/java/top/r3944realms/lib39/core/event/CommonHandler.java +++ b/src/main/java/top/r3944realms/lib39/core/event/CommonEventHandler.java @@ -13,11 +13,16 @@ import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.entity.EntityJoinLevelEvent; import net.minecraftforge.event.entity.EntityLeaveLevelEvent; import net.minecraftforge.event.level.LevelEvent; +import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.registries.RegistryObject; import top.r3944realms.lib39.Lib39; +import top.r3944realms.lib39.api.event.RegisterCompatEvent; import top.r3944realms.lib39.api.event.SyncManagerRegisterEvent; import top.r3944realms.lib39.core.sync.ISyncData; +import top.r3944realms.lib39.core.compat.CompatManager; import top.r3944realms.lib39.core.sync.SyncData2Manager; import java.util.ArrayList; @@ -25,44 +30,82 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -public class CommonHandler { +/** + * The type Common handler. + */ +public class CommonEventHandler { + /** + * The type Game. + */ @SuppressWarnings("unused") @net.minecraftforge.fml.common.Mod.EventBusSubscriber(modid = Lib39.MOD_ID, bus = net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus.FORGE) - public static class Game extends CommonHandler { + public static class Game extends CommonEventHandler { private static ServerLevel sl; + + /** + * Gets server level. + * + * @return the server level + */ public static ServerLevel getServerLevel() { return sl; } + + /** + * The Sync data 2 manager. + */ static volatile SyncData2Manager syncData2Manager; - private static boolean isInitialized = false; + private static boolean isSync2MInitialized = false; + + /** + * Gets sync data 2 manager. + * + * @return the sync data 2 manager + */ public static SyncData2Manager getSyncData2Manager() { return syncData2Manager; } + /** + * On world load. + * + * @param event the event + */ @SubscribeEvent public static void onWorldLoad(LevelEvent.Load event) { if (event.getLevel().isClientSide() || !(event.getLevel() instanceof ServerLevel serverLevel)) return; // 只处理主世界(避免多次初始化) if (!serverLevel.dimension().equals(Level.OVERWORLD)) return; synchronized (Game.class) { - if (!isInitialized) { + if (!isSync2MInitialized) { syncData2Manager = new SyncData2Manager(); MinecraftForge.EVENT_BUS.post(new SyncManagerRegisterEvent(syncData2Manager)); - isInitialized = true; + isSync2MInitialized = true; sl = serverLevel; Lib39.LOGGER.info("SyncData2Manager initialized on world load"); } } } + + /** + * On world unload. + * + * @param event the event + */ @SubscribeEvent public static void onWorldUnload(LevelEvent.Unload event) { if (event.getLevel().isClientSide() || !(event.getLevel() instanceof ServerLevel serverLevel)) return; if (!serverLevel.dimension().equals(Level.OVERWORLD)) return; sl = null; - isInitialized = false; + isSync2MInitialized = false; } + /** + * On server tick. + * + * @param event the event + */ @SubscribeEvent public static void onServerTick(TickEvent.ServerTickEvent event) { if (event.phase == TickEvent.Phase.END) { @@ -72,6 +115,12 @@ public class CommonHandler { syncData2Manager.forEach(((resourceLocation, iSyncManager) -> iSyncManager.foreach(ISyncData::checkIfDirtyThenUpdate))); } } + + /** + * On entity join world. + * + * @param event the event + */ @SubscribeEvent public static void onEntityJoinWorld(EntityJoinLevelEvent event) { Entity entity = event.getEntity(); @@ -83,6 +132,12 @@ public class CommonHandler { } } } + + /** + * On entity leave world. + * + * @param event the event + */ @SubscribeEvent public static void onEntityLeaveWorld(EntityLeaveLevelEvent event) { Entity entity = event.getEntity(); @@ -95,12 +150,51 @@ public class CommonHandler { } } } + + /** + * The type Mod. + */ @SuppressWarnings("unused") @net.minecraftforge.fml.common.Mod.EventBusSubscriber(modid = Lib39.MOD_ID, bus = net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus.MOD) - public static class Mod extends CommonHandler { + public static class Mod extends CommonEventHandler { private static final Map, ResourceKey[]> itemAddMap = new ConcurrentHashMap<>(); private static final Map, List>> tabToItemsMap = new ConcurrentHashMap<>(); + /** + * Gets compat manager. + * + * @return the compat manager + */ + public static CompatManager getCompatManager() { + return compatManager; + } + + /** + * The Compat manager. + */ + static volatile CompatManager compatManager; + + /** + * On fml common setup. + * + * @param event the event + */ + @SubscribeEvent + public static void onFMLCommonSetup (FMLCommonSetupEvent event) { + event.enqueueWork(() -> { + IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus(); + IEventBus gameBus = MinecraftForge.EVENT_BUS; + compatManager = new CompatManager(modBus, gameBus); + MinecraftForge.EVENT_BUS.post(new RegisterCompatEvent(compatManager)); + }); + } + + /** + * Add item to tabs. + * + * @param item the item + * @param tabs the tabs + */ @SafeVarargs public static void addItemToTabs(RegistryObject item, ResourceKey... tabs) { itemAddMap.put(item, tabs); @@ -111,6 +205,11 @@ public class CommonHandler { } } + /** + * On build creative tab contents. + * + * @param event the event + */ @SubscribeEvent public static void onBuildCreativeTabContents(BuildCreativeModeTabContentsEvent event) { List> itemsForTab = tabToItemsMap.get(event.getTabKey()); @@ -119,6 +218,11 @@ public class CommonHandler { } } + /** + * Gets item add map. + * + * @return the item add map + */ public static Map, ResourceKey[]> getItemAddMap() { return itemAddMap; } diff --git a/src/main/java/top/r3944realms/lib39/core/event/ServerEventHandler.java b/src/main/java/top/r3944realms/lib39/core/event/ServerEventHandler.java new file mode 100644 index 0000000..1f36852 --- /dev/null +++ b/src/main/java/top/r3944realms/lib39/core/event/ServerEventHandler.java @@ -0,0 +1,7 @@ +package top.r3944realms.lib39.core.event; + +/** + * The type Server handler. + */ +public class ServerEventHandler { +} diff --git a/src/main/java/top/r3944realms/lib39/core/event/ServerHandler.java b/src/main/java/top/r3944realms/lib39/core/event/ServerHandler.java deleted file mode 100644 index e1a33bc..0000000 --- a/src/main/java/top/r3944realms/lib39/core/event/ServerHandler.java +++ /dev/null @@ -1,4 +0,0 @@ -package top.r3944realms.lib39.core.event; - -public class ServerHandler { -} diff --git a/src/main/java/top/r3944realms/lib39/core/network/NetworkHandler.java b/src/main/java/top/r3944realms/lib39/core/network/NetworkHandler.java index 5adc388..78e13ad 100644 --- a/src/main/java/top/r3944realms/lib39/core/network/NetworkHandler.java +++ b/src/main/java/top/r3944realms/lib39/core/network/NetworkHandler.java @@ -8,28 +8,66 @@ import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.simple.SimpleChannel; import org.jetbrains.annotations.NotNull; import top.r3944realms.lib39.Lib39; -import top.r3944realms.lib39.core.network.toClient.SyncNBTDataS2CPack; +import top.r3944realms.lib39.core.network.toClient.SyncNBTCapDataEntityS2CPack; +/** + * The type Network handler. + */ @SuppressWarnings("unused") public class NetworkHandler { private static int cid = 0; + /** + * The constant INSTANCE. + */ public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel( new ResourceLocation(Lib39.MOD_ID, "main"), () -> Lib39.ModInfo.VERSION, Lib39.ModInfo.VERSION::equals, Lib39.ModInfo.VERSION::equals ); + + /** + * Register. + */ public static void register() { - INSTANCE.messageBuilder(SyncNBTDataS2CPack.class, cid++, NetworkDirection.PLAY_TO_CLIENT) - .encoder(SyncNBTDataS2CPack::encode) - .decoder(SyncNBTDataS2CPack::decode) - .consumerNetworkThread(SyncNBTDataS2CPack::handle) + INSTANCE.messageBuilder(SyncNBTCapDataEntityS2CPack.class, cid++, NetworkDirection.PLAY_TO_CLIENT) + .encoder(SyncNBTCapDataEntityS2CPack::encode) + .decoder(SyncNBTCapDataEntityS2CPack::decode) + .consumerNetworkThread(SyncNBTCapDataEntityS2CPack::handle) .add(); } + + /** + * Send to player. + * + * @param the type parameter + * @param message the message + * @param player the player + */ public static void sendToPlayer(MSG message, ServerPlayer player){ INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), message); } + + /** + * Send to player. + * + * @param the type parameter + * @param the type parameter + * @param message the message + * @param entity the entity + * @param packetDistributor the packet distributor + */ public static void sendToPlayer(MSG message, T entity, @NotNull PacketDistributor packetDistributor){ INSTANCE.send(packetDistributor.with(() -> entity), message); } + + /** + * Send to player. + * + * @param the type parameter + * @param message the message + */ + public static void sendToAllPlayer(MSG message){ + INSTANCE.send(PacketDistributor.ALL.noArg(), message); + } } diff --git a/src/main/java/top/r3944realms/lib39/core/network/toClient/SyncNBTCapDataEntityS2CPack.java b/src/main/java/top/r3944realms/lib39/core/network/toClient/SyncNBTCapDataEntityS2CPack.java new file mode 100644 index 0000000..aa02b52 --- /dev/null +++ b/src/main/java/top/r3944realms/lib39/core/network/toClient/SyncNBTCapDataEntityS2CPack.java @@ -0,0 +1,95 @@ +package top.r3944realms.lib39.core.network.toClient; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.network.NetworkEvent; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import top.r3944realms.lib39.Lib39; +import top.r3944realms.lib39.core.event.CommonEventHandler; +import top.r3944realms.lib39.core.sync.ISyncData; +import top.r3944realms.lib39.core.sync.NBTEntitySyncData; +import top.r3944realms.lib39.core.sync.SyncData2Manager; + +import java.util.Optional; +import java.util.function.Supplier; + +/** + * The type Sync nbt data s 2 c pack. + */ +@SuppressWarnings("unused") +public record SyncNBTCapDataEntityS2CPack(int entityId, ResourceLocation id, CompoundTag data) { + + /** + * Instantiates a new Sync nbt data s 2 c pack. + * + * @param entityId the entity id + * @param id the id + * @param data the data + */ + public SyncNBTCapDataEntityS2CPack(int entityId, ResourceLocation id, @NotNull NBTEntitySyncData data) { + this(entityId, data.id(), data.serializeNBT()); + } + + /** + * Encode. + * + * @param msg the msg + * @param buffer the buffer + */ + public static void encode(@NotNull SyncNBTCapDataEntityS2CPack msg, @NotNull FriendlyByteBuf buffer) { + buffer.writeInt(msg.entityId); + buffer.writeResourceLocation(msg.id); + buffer.writeNbt(msg.data); + } + + /** + * Decode sync nbt data s 2 c pack. + * + * @param buffer the buffer + * @return the sync nbt data s 2 c pack + */ + @Contract("_ -> new") + public static @NotNull SyncNBTCapDataEntityS2CPack decode(@NotNull FriendlyByteBuf buffer) { + return new SyncNBTCapDataEntityS2CPack(buffer.readInt(), buffer.readResourceLocation(), buffer.readNbt()); + } + + /** + * Handle. + * + * @param msg the msg + * @param ctx the ctx + */ + public static void handle(SyncNBTCapDataEntityS2CPack msg, @NotNull Supplier ctx) { + NetworkEvent.Context context = ctx.get(); + context.enqueueWork(() -> { + ClientLevel level = Minecraft.getInstance().level; + if (level != null) { + Entity entity = level.getEntity(msg.entityId); + if (entity != null) { + Optional>> capability = + CommonEventHandler.Game + .getSyncData2Manager() + .getDataProvider(msg.id); + capability.flatMap(dataProvider -> dataProvider.getData(entity)) + .ifPresent(cap -> { + if (cap instanceof NBTEntitySyncData nbtCap) { + CompoundTag current = nbtCap.serializeNBT(); + if (!current.equals(msg.data)) { + nbtCap.deserializeNBT(msg.data); + } + } else Lib39.LOGGER.debug("Unhandled sync data: {}", msg.data); + } + ); + } + } + }); + context.setPacketHandled(true); + } + +} diff --git a/src/main/java/top/r3944realms/lib39/core/network/toClient/SyncNBTDataS2CPack.java b/src/main/java/top/r3944realms/lib39/core/network/toClient/SyncNBTDataS2CPack.java deleted file mode 100644 index 64ab01d..0000000 --- a/src/main/java/top/r3944realms/lib39/core/network/toClient/SyncNBTDataS2CPack.java +++ /dev/null @@ -1,60 +0,0 @@ -package top.r3944realms.lib39.core.network.toClient; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.Entity; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.network.NetworkEvent; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import top.r3944realms.lib39.Lib39; -import top.r3944realms.lib39.core.event.CommonHandler; -import top.r3944realms.lib39.core.sync.ISyncData; -import top.r3944realms.lib39.core.sync.NBTSyncData; - -import java.util.Optional; -import java.util.function.Supplier; - -public record SyncNBTDataS2CPack(int entityId, ResourceLocation id, CompoundTag data) { - - public SyncNBTDataS2CPack(int entityId, ResourceLocation id, @NotNull NBTSyncData data) { - this(entityId, data.id(), data.serializeNBT()); - } - - public static void encode(@NotNull SyncNBTDataS2CPack msg, @NotNull FriendlyByteBuf buffer) { - buffer.writeInt(msg.entityId); - buffer.writeResourceLocation(msg.id); - buffer.writeNbt(msg.data); - } - - @Contract("_ -> new") - public static @NotNull SyncNBTDataS2CPack decode(@NotNull FriendlyByteBuf buffer) { - return new SyncNBTDataS2CPack(buffer.readInt(), buffer.readResourceLocation(), buffer.readNbt()); - } - - public static void handle(SyncNBTDataS2CPack msg, @NotNull Supplier ctx) { - NetworkEvent.Context context = ctx.get(); - context.enqueueWork(() -> { - ClientLevel level = Minecraft.getInstance().level; - if (level != null) { - Entity entity = level.getEntity(msg.entityId); - if (entity != null) { - Optional>> capability = CommonHandler.Game.getSyncData2Manager().getCapability(msg.id); - capability.ifPresent(dataCapability -> entity.getCapability(dataCapability).ifPresent(cap -> { - if (cap instanceof NBTSyncData nbtCap){ - CompoundTag current = nbtCap.serializeNBT(); - if (!current.equals(msg.data)) { - nbtCap.deserializeNBT(msg.data); - } - } else Lib39.LOGGER.debug("Unhandled sync data: {}", msg.data); - })); - } - } - }); - context.setPacketHandled(true); - } - -} diff --git a/src/main/java/top/r3944realms/lib39/core/registry/LocaleRegistry.java b/src/main/java/top/r3944realms/lib39/core/registry/LocaleRegistry.java index 0695dec..6e02b3a 100644 --- a/src/main/java/top/r3944realms/lib39/core/registry/LocaleRegistry.java +++ b/src/main/java/top/r3944realms/lib39/core/registry/LocaleRegistry.java @@ -8,6 +8,9 @@ import top.r3944realms.lib39.datagen.value.McLocale; import java.util.*; +/** + * The type Locale registry. + */ @SuppressWarnings("unused") public class LocaleRegistry { private static final Map REGISTRY = new LinkedHashMap<>(); @@ -19,23 +22,43 @@ public class LocaleRegistry { } } - /** 注册(覆盖已有时直接返回旧值) */ + /** + * 注册(覆盖已有时直接返回旧值) @param entry the entry + * + * @param entry the entry + * @return the locale entry + */ @SuppressWarnings("UnusedReturnValue") public static ILocaleEntry register(ILocaleEntry entry) { return REGISTRY.putIfAbsent(entry.mcCode().toLowerCase(), entry); } - /** 通过 Minecraft 代码查找 */ + /** + * 通过 Minecraft 代码查找 @param code the code + * + * @param code the code + * @return the locale entry + */ public static ILocaleEntry fromMcCode(@NotNull String code) { return REGISTRY.get(code.toLowerCase()); } - /** 列出所有 */ + /** + * 列出所有 @return the collection + * + * @return the collection + */ public static @NotNull @UnmodifiableView Collection allValues() { return Collections.unmodifiableCollection(REGISTRY.values()); } - /** 动态注册一个扩展 Locale */ + /** + * 动态注册一个扩展 Locale @param mcCode the mc code + * + * @param mcCode the mc code + * @param locale the locale + * @return the locale entry + */ public static ILocaleEntry registerDynamic(@NotNull String mcCode, Locale locale) { return REGISTRY.computeIfAbsent(mcCode.toLowerCase(), k -> new ExtendedLocale(mcCode.toLowerCase(), locale)); diff --git a/src/main/java/top/r3944realms/lib39/core/sync/CachedSyncManager.java b/src/main/java/top/r3944realms/lib39/core/sync/CachedSyncManager.java index 5a64c1d..1c5d91b 100644 --- a/src/main/java/top/r3944realms/lib39/core/sync/CachedSyncManager.java +++ b/src/main/java/top/r3944realms/lib39/core/sync/CachedSyncManager.java @@ -3,6 +3,12 @@ package top.r3944realms.lib39.core.sync; import java.util.Map; import java.util.Set; +/** + * The type Cached sync manager. + * + * @param the type parameter + * @param the type parameter + */ @SuppressWarnings("unused") public abstract class CachedSyncManager> implements ISyncManager { diff --git a/src/main/java/top/r3944realms/lib39/core/sync/IEntity.java b/src/main/java/top/r3944realms/lib39/core/sync/IEntity.java new file mode 100644 index 0000000..249b1af --- /dev/null +++ b/src/main/java/top/r3944realms/lib39/core/sync/IEntity.java @@ -0,0 +1,13 @@ +package top.r3944realms.lib39.core.sync; + +/** + * The interface Entity. + */ +public interface IEntity { + /** + * Entity id int. + * + * @return the int + */ + int entityId(); +} diff --git a/src/main/java/top/r3944realms/lib39/core/sync/ISyncData.java b/src/main/java/top/r3944realms/lib39/core/sync/ISyncData.java index ad3b577..4960272 100644 --- a/src/main/java/top/r3944realms/lib39/core/sync/ISyncData.java +++ b/src/main/java/top/r3944realms/lib39/core/sync/ISyncData.java @@ -2,13 +2,49 @@ package top.r3944realms.lib39.core.sync; import net.minecraft.resources.ResourceLocation; +/** + * The interface Sync data. + * + * @param the type parameter + */ public interface ISyncData { + /** + * Id resource location. + * + * @return the resource location + */ ResourceLocation id(); + + /** + * Is dirty boolean. + * + * @return the boolean + */ boolean isDirty(); + + /** + * Sets dirty. + * + * @param dirty the dirty + */ void setDirty(boolean dirty); + + /** + * Make dirty. + */ default void makeDirty() { setDirty(true); } + + /** + * Copy from. + * + * @param src the src + */ void copyFrom(T src); + + /** + * Check if dirty then update. + */ void checkIfDirtyThenUpdate(); } diff --git a/src/main/java/top/r3944realms/lib39/core/sync/ISyncManager.java b/src/main/java/top/r3944realms/lib39/core/sync/ISyncManager.java index f0b0a2a..661d22e 100644 --- a/src/main/java/top/r3944realms/lib39/core/sync/ISyncManager.java +++ b/src/main/java/top/r3944realms/lib39/core/sync/ISyncManager.java @@ -4,16 +4,26 @@ import java.util.Map; import java.util.Set; import java.util.function.Consumer; +/** + * The interface Sync manager. + * + * @param the type parameter + * @param the type parameter + */ @SuppressWarnings("unused") public interface ISyncManager> { /** * 获取同步映射 + * + * @return the sync map */ Map getSyncMap(); /** * 获取同步集合 + * + * @return the sync set */ default Set getSyncSet() { Map syncMap = getSyncMap(); @@ -22,6 +32,9 @@ public interface ISyncManager> { /** * 跟踪实例 + * + * @param key the key + * @param instance the instance */ default void track(K key, T instance) { Map syncMap = getSyncMap(); @@ -33,6 +46,9 @@ public interface ISyncManager> { /** * 取消跟踪 + * + * @param key the key + * @param instance the instance */ default void untrack(K key, T instance) { Map syncMap = getSyncMap(); @@ -45,6 +61,8 @@ public interface ISyncManager> { /** * 遍历操作 + * + * @param consumer the consumer */ default void foreach(Consumer consumer) { Map syncMap = getSyncMap(); @@ -56,6 +74,8 @@ public interface ISyncManager> { /** * 批量操作 + * + * @param instances the instances */ default void trackAll(Map instances) { Map syncMap = getSyncMap(); @@ -67,6 +87,8 @@ public interface ISyncManager> { /** * 获取大小 + * + * @return the int */ default int size() { Map syncMap = getSyncMap(); @@ -75,6 +97,9 @@ public interface ISyncManager> { /** * 检查是否包含key + * + * @param key the key + * @return the boolean */ default boolean containsKey(K key) { Map syncMap = getSyncMap(); @@ -83,6 +108,9 @@ public interface ISyncManager> { /** * 检查是否包含value + * + * @param value the value + * @return the boolean */ default boolean containsValue(T value) { Map syncMap = getSyncMap(); diff --git a/src/main/java/top/r3944realms/lib39/core/sync/NBTEntitySyncData.java b/src/main/java/top/r3944realms/lib39/core/sync/NBTEntitySyncData.java new file mode 100644 index 0000000..859a4a6 --- /dev/null +++ b/src/main/java/top/r3944realms/lib39/core/sync/NBTEntitySyncData.java @@ -0,0 +1,58 @@ +package top.r3944realms.lib39.core.sync; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.common.util.INBTSerializable; +import org.jetbrains.annotations.NotNull; +import top.r3944realms.lib39.core.network.NetworkHandler; +import top.r3944realms.lib39.core.network.toClient.SyncNBTCapDataEntityS2CPack; + +/** + * The type Nbt sync data. + */ +public abstract class NBTEntitySyncData implements IEntity, ISyncData, INBTSerializable { + /** + * The Dirty. + */ + protected boolean dirty; + /** + * The Id. + */ + protected final ResourceLocation id; + + /** + * Instantiates a new Nbt sync data. + * + * @param id the id + */ + protected NBTEntitySyncData(ResourceLocation id) { + this.id = id; + } + + @Override + public ResourceLocation id() { + return id; + } + + @Override + public boolean isDirty() { + return dirty; + } + + @Override + public void setDirty(boolean dirty) { + this.dirty = dirty; + } + + @Override + public void copyFrom(@NotNull NBTEntitySyncData src) { + this.dirty = src.isDirty(); + } + + @Override + public void checkIfDirtyThenUpdate() { + if (isDirty()) { + NetworkHandler.sendToAllPlayer(new SyncNBTCapDataEntityS2CPack(entityId(), id(), serializeNBT())); + } + } +} diff --git a/src/main/java/top/r3944realms/lib39/core/sync/NBTSyncData.java b/src/main/java/top/r3944realms/lib39/core/sync/NBTSyncData.java deleted file mode 100644 index 05841e9..0000000 --- a/src/main/java/top/r3944realms/lib39/core/sync/NBTSyncData.java +++ /dev/null @@ -1,36 +0,0 @@ -package top.r3944realms.lib39.core.sync; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.common.util.INBTSerializable; -import org.jetbrains.annotations.NotNull; - -public abstract class NBTSyncData implements ISyncData, INBTSerializable { - protected boolean dirty; - protected final ResourceLocation id; - - protected NBTSyncData(ResourceLocation id) { - this.id = id; - } - - @Override - public ResourceLocation id() { - return id; - } - - @Override - public boolean isDirty() { - return dirty; - } - - @Override - public void setDirty(boolean dirty) { - this.dirty = dirty; - } - - @Override - public void copyFrom(@NotNull NBTSyncData src) { - this.dirty = src.isDirty(); - } - -} diff --git a/src/main/java/top/r3944realms/lib39/core/sync/SyncData2CapManager.java b/src/main/java/top/r3944realms/lib39/core/sync/SyncData2CapManager.java new file mode 100644 index 0000000..71919d6 --- /dev/null +++ b/src/main/java/top/r3944realms/lib39/core/sync/SyncData2CapManager.java @@ -0,0 +1,390 @@ +package top.r3944realms.lib39.core.sync; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import net.minecraftforge.common.capabilities.Capability; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.function.BiConsumer; + +/** + * The type Sync data 2 manager. + */ +@SuppressWarnings("unused") +public class SyncData2CapManager { + private final Map> typedEntries = Maps.newConcurrentMap(); + + private static class TypedSyncEntry> { + /** + * The Manager. + */ + final ISyncManager manager; + /** + * The Capability. + */ + @Nullable + Capability capability; + /** + * The Allowed classes. + */ + final Set> allowedClasses; + + /** + * Instantiates a new Typed sync entry. + * + * @param manager the manager + * @param capability the capability + */ + TypedSyncEntry(ISyncManager manager, @Nullable Capability capability) { + this.manager = manager; + this.capability = capability; + this.allowedClasses = Sets.newConcurrentHashSet(); + } + } + + /** + * Register manager. + * + * @param the type parameter + * @param the type parameter + * @param key the key + * @param manager the manager + * @param capability the capability + */ + public > void registerManager( + ResourceLocation key, + ISyncManager manager, + Capability capability + ) { + Objects.requireNonNull(key, "ResourceLocation key cannot be null"); + Objects.requireNonNull(manager, "Sync manager cannot be null"); + Objects.requireNonNull(capability, "Capability cannot be null"); + + typedEntries.put(key, new TypedSyncEntry<>(manager, capability)); + } + + /** + * 向后兼容的注册方法(只注册管理器,不注册能力) + * + * @param key the key + * @param manager the manager + */ + @SuppressWarnings("unchecked") + public void registerManager(ResourceLocation key, ISyncManager> manager) { + Objects.requireNonNull(key, "ResourceLocation key cannot be null"); + Objects.requireNonNull(manager, "Sync manager cannot be null"); + + // 创建一个虚拟的 TypedSyncEntry,但 capability 为 null + // 注意:这种方法会限制类型安全的功能 + typedEntries.put(key, new TypedSyncEntry<>( + (ISyncManager>) manager, + null + )); + } + + /** + * Gets manager. + * + * @param the type parameter + * @param the type parameter + * @param key the key + * @return the manager + */ + @SuppressWarnings("unchecked") + public > Optional> getManager(ResourceLocation key) { + TypedSyncEntry entry = typedEntries.get(key); + return entry != null ? Optional.of((ISyncManager) entry.manager) : Optional.empty(); + } + + /** + * Gets capability. + * + * @param the type parameter + * @param key the key + * @return the capability + */ + @SuppressWarnings("unchecked") + public > Optional> getCapability(ResourceLocation key) { + TypedSyncEntry entry = typedEntries.get(key); + if (entry != null && entry.capability != null) { + return Optional.of((Capability) entry.capability); + } + return Optional.empty(); + } + + /** + * Allow entity class. + * + * @param key the key + * @param classes the classes + */ + public final void allowEntityClass(ResourceLocation key, Class... classes) { + Objects.requireNonNull(key, "ResourceLocation key cannot be null"); + Objects.requireNonNull(classes, "Classes array cannot be null"); + + if (classes.length == 0) { + return; + } + + TypedSyncEntry entry = typedEntries.get(key); + if (entry != null) { + entry.allowedClasses.addAll(Arrays.asList(classes)); + } + } + + /** + * 移除允许的实体类 + * + * @param key the key + * @param classes the classes + */ + public final void disallowEntityClass(ResourceLocation key, Class... classes) { + Objects.requireNonNull(key, "ResourceLocation key cannot be null"); + Objects.requireNonNull(classes, "Classes array cannot be null"); + + TypedSyncEntry entry = typedEntries.get(key); + if (entry != null && classes.length > 0) { + Arrays.asList(classes).forEach(entry.allowedClasses::remove); + + } + } + + /** + * 绑定能力(用于分离注册的情况) + * + * @param the type parameter + * @param key the key + * @param capability the capability + */ + public > void bindCapability(ResourceLocation key, Capability capability) { + Objects.requireNonNull(key, "ResourceLocation key cannot be null"); + Objects.requireNonNull(capability, "Capability cannot be null"); + + TypedSyncEntry entry = typedEntries.get(key); + if (entry != null) { + // 更新现有条目的能力 + updateCapabilityInEntry(key, entry, capability); + } else throw new IllegalArgumentException("No manager found for " + key); + } + + /** + * 解绑能力 + * + * @param key the key + */ + public void unbindCapability(ResourceLocation key) { + Objects.requireNonNull(key, "ResourceLocation key cannot be null"); + + TypedSyncEntry entry = typedEntries.get(key); + if (entry != null) { + // 将能力设置为null,但保留管理器和其他配置 + updateCapabilityInEntry(key, entry, null); + } + } + + /** + * 清除允许的实体类 + * + * @param key the key + */ + public void clearAllowedEntityClasses(ResourceLocation key) { + Objects.requireNonNull(key, "ResourceLocation key cannot be null"); + + TypedSyncEntry entry = typedEntries.get(key); + if (entry != null) { + entry.allowedClasses.clear(); + } + } + + /** + * Is entity class allowed boolean. + * + * @param key the key + * @param entityClass the entity class + * @return the boolean + */ + public boolean isEntityClassAllowed(ResourceLocation key, Class entityClass) { + Objects.requireNonNull(key, "ResourceLocation key cannot be null"); + Objects.requireNonNull(entityClass, "Entity class cannot be null"); + + TypedSyncEntry entry = typedEntries.get(key); + boolean isAllowed = false; + if (entry != null) { + for (Class allowedClass : entry.allowedClasses) { + if (entityClass.isAssignableFrom(allowedClass)) { + isAllowed = true; + break; + } + } + } + return entry != null && isAllowed ; + } + + /** + * Track entity for manager. + * + * @param entity the entity + * @param managerId the manager id + */ +// 类型安全的事件处理 + @SuppressWarnings("unchecked") + public void trackEntityForManager(Entity entity, ResourceLocation managerId) { + TypedSyncEntry entry = (TypedSyncEntry) typedEntries.get(managerId); + if (entry != null) { + trackEntityWithTypedEntry(entity, entry); + } + } + + private > void trackEntityWithTypedEntry(Entity entity, @NotNull TypedSyncEntry entry) { + if (entry.capability != null) { + entity.getCapability(entry.capability) + .ifPresent(cap -> entry.manager.track(entity.getUUID(), cap)); + } + } + + /** + * Untrack entity for manager. + * + * @param entity the entity + * @param managerId the manager id + */ +// 类型安全的事件处理 - 取消跟踪实体 + @SuppressWarnings("unchecked") + public void untrackEntityForManager(Entity entity, ResourceLocation managerId) { + TypedSyncEntry entry = (TypedSyncEntry) typedEntries.get(managerId); + if (entry != null) { + untrackEntityWithTypedEntry(entity, entry); + } + } + + private > void untrackEntityWithTypedEntry(Entity entity, @NotNull TypedSyncEntry entry) { + if (entry.capability != null) { + entity.getCapability(entry.capability) + .ifPresent(cap -> entry.manager.untrack(entity.getUUID(), cap)); + } + } + + /** + * 从所有管理器中移除实体跟踪 + * + * @param entity the entity + */ + public void untrackEntityFromAllManagers(Entity entity) { + for (ResourceLocation id : getRegisteredKeys()) { + if (isEntityClassAllowed(id, entity.getClass())) { + untrackEntityForManager(entity, id); + } + } + } + + /** + * 批量从管理器中移除实体跟踪 + * + * @param entities the entities + * @param managerId the manager id + */ + public void untrackEntitiesForManager(@NotNull Iterable entities, ResourceLocation managerId) { + for (Entity entity : entities) { + untrackEntityForManager(entity, managerId); + } + } + + /** + * 从所有管理器中批量移除实体跟踪 + * + * @param entities the entities + */ + public void untrackEntitiesFromAllManagers(@NotNull Iterable entities) { + for (Entity entity : entities) { + untrackEntityFromAllManagers(entity); + } + } + + /** + * 强制清理管理器中的所有跟踪数据 + * + * @param managerId the manager id + */ + public void clearAllTrackedData(ResourceLocation managerId) { + TypedSyncEntry entry = typedEntries.get(managerId); + if (entry != null) { + clearTrackedDataForEntry(entry); + } + } + + private > void clearTrackedDataForEntry(@NotNull TypedSyncEntry entry) { + // 获取当前跟踪的集合并清空 + Set syncSet = entry.manager.getSyncSet(); + if (syncSet != null) { + syncSet.clear(); + } + } + + /** + * 清理所有管理器的跟踪数据 + */ + public void clearAllTrackedData() { + for (ResourceLocation id : getRegisteredKeys()) { + clearAllTrackedData(id); + } + } + + // 辅助方法:更新条目的能力 + @SuppressWarnings("unchecked") + private > void updateCapabilityInEntry(ResourceLocation id, TypedSyncEntry entry, Capability newCapability) { + TypedSyncEntry typedEntry = (TypedSyncEntry) entry; + //重构了 TypedSyncEntry 使 capability 可变 + typedEntry.capability = newCapability; + typedEntries.computeIfPresent(id, (resourceLocation, typedSyncEntry) -> typedEntry); + } + + + /** + * Gets registered keys. + * + * @return the registered keys + */ + public Set getRegisteredKeys() { + return Collections.unmodifiableSet(typedEntries.keySet()); + } + + /** + * For each. + * + * @param consumer the consumer + */ + public void forEach(BiConsumer> consumer) { + Objects.requireNonNull(consumer, "Consumer cannot be null"); + typedEntries.forEach((key, entry) -> consumer.accept(key, entry.manager)); + } + + /** + * Gets manager count. + * + * @return the manager count + */ + public int getManagerCount() { + return typedEntries.size(); + } + + /** + * Clear all. + */ + public void clearAll() { + typedEntries.clear(); + } + + /** + * 移除管理器(包括所有相关配置) + * + * @param key the key + */ + public void removeManager(ResourceLocation key) { + Objects.requireNonNull(key, "ResourceLocation key cannot be null"); + typedEntries.remove(key); + } +} \ No newline at end of file diff --git a/src/main/java/top/r3944realms/lib39/core/sync/SyncData2Manager.java b/src/main/java/top/r3944realms/lib39/core/sync/SyncData2Manager.java index 0bb275d..bc6e93c 100644 --- a/src/main/java/top/r3944realms/lib39/core/sync/SyncData2Manager.java +++ b/src/main/java/top/r3944realms/lib39/core/sync/SyncData2Manager.java @@ -4,73 +4,178 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; -import net.minecraftforge.common.capabilities.Capability; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.BiConsumer; +import java.util.function.Function; -@SuppressWarnings("unused") +/** + * The type Sync data 2 manager. + */ +@SuppressWarnings({"unused", "DuplicatedCode"}) public class SyncData2Manager { private final Map> typedEntries = Maps.newConcurrentMap(); + /** + * 数据提供者接口 - 用于通过键获取数据 + * + * @param the type parameter + * @param the type parameter + */ + @FunctionalInterface + public interface DataProvider { + /** + * 通过键获取数据的 Optional + * + * @param key 键 + * @return 数据的 Optional + */ + Optional getData(K key); + } + private static class TypedSyncEntry> { + /** + * The Manager. + */ final ISyncManager manager; + /** + * The Data provider. + */ @Nullable - Capability capability; + final DataProvider dataProvider; + /** + * The Allowed classes. + */ final Set> allowedClasses; - TypedSyncEntry(ISyncManager manager, @Nullable Capability capability) { + /** + * Instantiates a new Typed sync entry. + * + * @param manager the manager + * @param dataProvider the data provider + */ + TypedSyncEntry(ISyncManager manager, @Nullable DataProvider dataProvider) { this.manager = manager; - this.capability = capability; + this.dataProvider = dataProvider; this.allowedClasses = Sets.newConcurrentHashSet(); } } - public > void registerManager( + /** + * Register manager with data provider. + * + * @param the type parameter + * @param the type parameter + * @param key the key + * @param manager the manager + * @param dataProvider the data provider + */ + public > void registerManagerWithProvider( ResourceLocation key, ISyncManager manager, - Capability capability + DataProvider dataProvider ) { Objects.requireNonNull(key, "ResourceLocation key cannot be null"); Objects.requireNonNull(manager, "Sync manager cannot be null"); - Objects.requireNonNull(capability, "Capability cannot be null"); + Objects.requireNonNull(dataProvider, "Data provider cannot be null"); - typedEntries.put(key, new TypedSyncEntry<>(manager, capability)); + typedEntries.put(key, new TypedSyncEntry<>(manager, dataProvider)); } /** - * 向后兼容的注册方法(只注册管理器,不注册能力) + * Register manager with function getter. + * + * @param the type parameter + * @param the type parameter + * @param key the key + * @param manager the manager + * @param getter the data getter function + */ + public > void registerManager( + ResourceLocation key, + ISyncManager manager, + Function> getter + ) { + Objects.requireNonNull(key, "ResourceLocation key cannot be null"); + Objects.requireNonNull(manager, "Sync manager cannot be null"); + Objects.requireNonNull(getter, "Data getter function cannot be null"); + + typedEntries.put(key, new TypedSyncEntry<>(manager, getter::apply)); + } + + /** + * 向后兼容的注册方法(只注册管理器,不注册数据提供者) + * + * @param key the key + * @param manager the manager */ @SuppressWarnings("unchecked") public void registerManager(ResourceLocation key, ISyncManager> manager) { Objects.requireNonNull(key, "ResourceLocation key cannot be null"); Objects.requireNonNull(manager, "Sync manager cannot be null"); - // 创建一个虚拟的 TypedSyncEntry,但 capability 为 null - // 注意:这种方法会限制类型安全的功能 + // 创建一个没有数据提供者的 TypedSyncEntry typedEntries.put(key, new TypedSyncEntry<>( (ISyncManager>) manager, null )); } + /** + * Gets manager. + * + * @param the type parameter + * @param the type parameter + * @param key the key + * @return the manager + */ @SuppressWarnings("unchecked") public > Optional> getManager(ResourceLocation key) { TypedSyncEntry entry = typedEntries.get(key); return entry != null ? Optional.of((ISyncManager) entry.manager) : Optional.empty(); } + /** + * Gets data provider. + * + * @param the type parameter + * @param key the key + * @return the data provider + */ @SuppressWarnings("unchecked") - public > Optional> getCapability(ResourceLocation key) { + public > Optional> getDataProvider(ResourceLocation key) { TypedSyncEntry entry = typedEntries.get(key); - if (entry != null && entry.capability != null) { - return Optional.of((Capability) entry.capability); + if (entry != null && entry.dataProvider != null) { + return Optional.of((DataProvider) entry.dataProvider); } return Optional.empty(); } + /** + * 获取实体数据 + * + * @param the type parameter + * @param key the key + * @param entity the entity + * @return the entity data + */ + @SuppressWarnings("unchecked") + public > Optional getEntityData(ResourceLocation key, Entity entity) { + return getDataProvider(key) + .flatMap(provider -> { + Optional> result = provider.getData(entity); + return (Optional) result; + }); + } + + /** + * Allow entity class. + * + * @param key the key + * @param classes the classes + */ public final void allowEntityClass(ResourceLocation key, Class... classes) { Objects.requireNonNull(key, "ResourceLocation key cannot be null"); Objects.requireNonNull(classes, "Classes array cannot be null"); @@ -87,6 +192,9 @@ public class SyncData2Manager { /** * 移除允许的实体类 + * + * @param key the key + * @param classes the classes */ public final void disallowEntityClass(ResourceLocation key, Class... classes) { Objects.requireNonNull(key, "ResourceLocation key cannot be null"); @@ -95,39 +203,59 @@ public class SyncData2Manager { TypedSyncEntry entry = typedEntries.get(key); if (entry != null && classes.length > 0) { Arrays.asList(classes).forEach(entry.allowedClasses::remove); - } } /** - * 绑定能力(用于分离注册的情况) + * 绑定数据提供者(用于分离注册的情况) + * + * @param the type parameter + * @param key the key + * @param dataProvider the data provider */ - public > void bindCapability(ResourceLocation key, Capability capability) { + public > void bindDataProvider(ResourceLocation key, DataProvider dataProvider) { Objects.requireNonNull(key, "ResourceLocation key cannot be null"); - Objects.requireNonNull(capability, "Capability cannot be null"); + Objects.requireNonNull(dataProvider, "Data provider cannot be null"); TypedSyncEntry entry = typedEntries.get(key); if (entry != null) { - // 更新现有条目的能力 - updateCapabilityInEntry(key, entry, capability); - } else throw new IllegalArgumentException("No manager found for " + key); + // 更新现有条目的数据提供者 + updateDataProviderInEntry(key, entry, dataProvider); + } else { + throw new IllegalArgumentException("No manager found for " + key); + } } /** - * 解绑能力 + * 绑定简单的数据获取器 + * + * @param the type parameter + * @param key the key + * @param getter the data getter function */ - public void unbindCapability(ResourceLocation key) { + public > void bindDataGetter(ResourceLocation key, Function> getter) { + bindDataProvider(key, getter::apply); + } + + /** + * 解绑数据提供者 + * + * @param key the key + */ + public void unbindDataProvider(ResourceLocation key) { Objects.requireNonNull(key, "ResourceLocation key cannot be null"); TypedSyncEntry entry = typedEntries.get(key); if (entry != null) { - // 将能力设置为null,但保留管理器和其他配置 - updateCapabilityInEntry(key, entry, null); + // 将数据提供者设置为null,但保留管理器和其他配置 + updateDataProviderInEntry(key, entry, null); } } /** * 清除允许的实体类 + * + * @param key the key */ public void clearAllowedEntityClasses(ResourceLocation key) { Objects.requireNonNull(key, "ResourceLocation key cannot be null"); @@ -138,24 +266,38 @@ public class SyncData2Manager { } } + /** + * Is entity class allowed boolean. + * + * @param key the key + * @param entityClass the entity class + * @return the boolean + */ public boolean isEntityClassAllowed(ResourceLocation key, Class entityClass) { Objects.requireNonNull(key, "ResourceLocation key cannot be null"); Objects.requireNonNull(entityClass, "Entity class cannot be null"); TypedSyncEntry entry = typedEntries.get(key); - boolean isAllowed = false; - if (entry != null) { - for (Class allowedClass : entry.allowedClasses) { - if (entityClass.isAssignableFrom(allowedClass)) { - isAllowed = true; - break; - } - } + if (entry == null) { + return false; } - return entry != null && isAllowed ; + + // 如果没有设置允许的类,则默认允许所有类 + if (entry.allowedClasses.isEmpty()) { + return true; + } + + // 检查实体类是否在允许的类中 + return entry.allowedClasses.stream() + .anyMatch(allowedClass -> allowedClass.isAssignableFrom(entityClass)); } - // 类型安全的事件处理 + /** + * Track entity for manager. + * + * @param entity the entity + * @param managerId the manager id + */ @SuppressWarnings("unchecked") public void trackEntityForManager(Entity entity, ResourceLocation managerId) { TypedSyncEntry entry = (TypedSyncEntry) typedEntries.get(managerId); @@ -165,12 +307,18 @@ public class SyncData2Manager { } private > void trackEntityWithTypedEntry(Entity entity, @NotNull TypedSyncEntry entry) { - if (entry.capability != null) { - entity.getCapability(entry.capability) - .ifPresent(cap -> entry.manager.track(entity.getUUID(), cap)); + if (entry.dataProvider != null) { + entry.dataProvider.getData(entity) + .ifPresent(data -> entry.manager.track(entity.getUUID(), data)); } } - // 类型安全的事件处理 - 取消跟踪实体 + + /** + * Untrack entity for manager. + * + * @param entity the entity + * @param managerId the manager id + */ @SuppressWarnings("unchecked") public void untrackEntityForManager(Entity entity, ResourceLocation managerId) { TypedSyncEntry entry = (TypedSyncEntry) typedEntries.get(managerId); @@ -180,14 +328,16 @@ public class SyncData2Manager { } private > void untrackEntityWithTypedEntry(Entity entity, @NotNull TypedSyncEntry entry) { - if (entry.capability != null) { - entity.getCapability(entry.capability) - .ifPresent(cap -> entry.manager.untrack(entity.getUUID(), cap)); + if (entry.dataProvider != null) { + entry.dataProvider.getData(entity) + .ifPresent(data -> entry.manager.untrack(entity.getUUID(), data)); } } /** * 从所有管理器中移除实体跟踪 + * + * @param entity the entity */ public void untrackEntityFromAllManagers(Entity entity) { for (ResourceLocation id : getRegisteredKeys()) { @@ -199,6 +349,9 @@ public class SyncData2Manager { /** * 批量从管理器中移除实体跟踪 + * + * @param entities the entities + * @param managerId the manager id */ public void untrackEntitiesForManager(@NotNull Iterable entities, ResourceLocation managerId) { for (Entity entity : entities) { @@ -208,6 +361,8 @@ public class SyncData2Manager { /** * 从所有管理器中批量移除实体跟踪 + * + * @param entities the entities */ public void untrackEntitiesFromAllManagers(@NotNull Iterable entities) { for (Entity entity : entities) { @@ -217,6 +372,8 @@ public class SyncData2Manager { /** * 强制清理管理器中的所有跟踪数据 + * + * @param managerId the manager id */ public void clearAllTrackedData(ResourceLocation managerId) { TypedSyncEntry entry = typedEntries.get(managerId); @@ -226,7 +383,6 @@ public class SyncData2Manager { } private > void clearTrackedDataForEntry(@NotNull TypedSyncEntry entry) { - // 获取当前跟踪的集合并清空 Set syncSet = entry.manager.getSyncSet(); if (syncSet != null) { syncSet.clear(); @@ -242,36 +398,62 @@ public class SyncData2Manager { } } - // 辅助方法:更新条目的能力 + // 辅助方法:更新条目的数据提供者 @SuppressWarnings("unchecked") - private > void updateCapabilityInEntry(ResourceLocation id, TypedSyncEntry entry, Capability newCapability) { - TypedSyncEntry typedEntry = (TypedSyncEntry) entry; - //重构了 TypedSyncEntry 使 capability 可变 - typedEntry.capability = newCapability; - typedEntries.computeIfPresent(id, (resourceLocation, typedSyncEntry) -> typedEntry); + private > void updateDataProviderInEntry( + ResourceLocation id, + TypedSyncEntry entry, + DataProvider newDataProvider + ) { + // 由于 DataProvider 是 final,我们需要创建一个新的 TypedSyncEntry + TypedSyncEntry newEntry = new TypedSyncEntry<>( + (ISyncManager) entry.manager, + newDataProvider + ); + newEntry.allowedClasses.addAll(entry.allowedClasses); + + typedEntries.put(id, newEntry); } - - + /** + * Gets registered keys. + * + * @return the registered keys + */ public Set getRegisteredKeys() { return Collections.unmodifiableSet(typedEntries.keySet()); } + /** + * For each. + * + * @param consumer the consumer + */ public void forEach(BiConsumer> consumer) { Objects.requireNonNull(consumer, "Consumer cannot be null"); typedEntries.forEach((key, entry) -> consumer.accept(key, entry.manager)); } + /** + * Gets manager count. + * + * @return the manager count + */ public int getManagerCount() { return typedEntries.size(); } + /** + * Clear all. + */ public void clearAll() { typedEntries.clear(); } /** * 移除管理器(包括所有相关配置) + * + * @param key the key */ public void removeManager(ResourceLocation key) { Objects.requireNonNull(key, "ResourceLocation key cannot be null"); diff --git a/src/main/java/top/r3944realms/lib39/datagen/provider/SimpleLanguageProvider.java b/src/main/java/top/r3944realms/lib39/datagen/provider/SimpleLanguageProvider.java index d561032..edd7631 100644 --- a/src/main/java/top/r3944realms/lib39/datagen/provider/SimpleLanguageProvider.java +++ b/src/main/java/top/r3944realms/lib39/datagen/provider/SimpleLanguageProvider.java @@ -11,12 +11,24 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +/** + * The type Simple language provider. + */ @SuppressWarnings("unused") public class SimpleLanguageProvider extends LanguageProvider { private final McLocale language; private final ILangKeyValue langKeyValue; private final Map lanKeyMap; private static final List objects = new ArrayList<>(); + + /** + * Instantiates a new Simple language provider. + * + * @param output the output + * @param modId the mod id + * @param Lan the lan + * @param langKeyValue the lang key value + */ public SimpleLanguageProvider(PackOutput output, String modId, @NotNull McLocale Lan, ILangKeyValue langKeyValue) { super(output, modId, Lan.mcCode()); this.language = Lan; diff --git a/src/main/java/top/r3944realms/lib39/datagen/value/ILangKeyValue.java b/src/main/java/top/r3944realms/lib39/datagen/value/ILangKeyValue.java index 5621f18..93da8f9 100644 --- a/src/main/java/top/r3944realms/lib39/datagen/value/ILangKeyValue.java +++ b/src/main/java/top/r3944realms/lib39/datagen/value/ILangKeyValue.java @@ -4,10 +4,33 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +/** + * The interface Lang key value. + */ public interface ILangKeyValue { + /** + * Gets lang. + * + * @param locale the locale + * @param key the key + * @return the lang + */ static String getLang(McLocale locale, @NotNull ILangKeyValue key) { return key.getLang(locale); } + + /** + * Gets lang. + * + * @param locale the locale + * @return the lang + */ String getLang(McLocale locale); + + /** + * Gets values. + * + * @return the values + */ List getValues(); } diff --git a/src/main/java/top/r3944realms/lib39/datagen/value/ILocaleEntry.java b/src/main/java/top/r3944realms/lib39/datagen/value/ILocaleEntry.java index 9757f7c..ea4a83b 100644 --- a/src/main/java/top/r3944realms/lib39/datagen/value/ILocaleEntry.java +++ b/src/main/java/top/r3944realms/lib39/datagen/value/ILocaleEntry.java @@ -2,7 +2,21 @@ package top.r3944realms.lib39.datagen.value; import java.util.Locale; +/** + * The interface Locale entry. + */ public interface ILocaleEntry { + /** + * Mc code string. + * + * @return the string + */ String mcCode(); + + /** + * Java locale locale. + * + * @return the locale + */ Locale javaLocale(); } diff --git a/src/main/java/top/r3944realms/lib39/datagen/value/LangKeyValue.java b/src/main/java/top/r3944realms/lib39/datagen/value/LangKeyValue.java index 46dabc8..aeb05b2 100644 --- a/src/main/java/top/r3944realms/lib39/datagen/value/LangKeyValue.java +++ b/src/main/java/top/r3944realms/lib39/datagen/value/LangKeyValue.java @@ -6,15 +6,42 @@ import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.function.Supplier; +/** + * The type Lang key value. + */ @SuppressWarnings("unused") public class LangKeyValue implements ILangKeyValue { + /** + * The Supplier. + */ protected final Supplier supplier; + /** + * The Key. + */ protected String key; + /** + * The Us en. + */ protected final String US_EN; + /** + * The Sim cn. + */ protected final String SIM_CN; + /** + * The Tra cn. + */ protected final String TRA_CN; + /** + * The Lzh. + */ protected final String LZH; + /** + * The Default. + */ protected final Boolean Default; + /** + * The Mpe. + */ protected final ModPartEnum MPE; private LangKeyValue(Supplier supplier, String key, ModPartEnum MPE, String US_EN, String SIM_CN, String TRA_CN, String LZH, Boolean isDefault) { @@ -28,42 +55,111 @@ public class LangKeyValue implements ILangKeyValue { this.Default = isDefault; } + /** + * Of supplier lang key value. + * + * @param supplier the supplier + * @param MPE the mpe + * @param US_EN the us en + * @param SIM_CN the sim cn + * @param TRA_CN the tra cn + * @return the lang key value + */ @Contract(value = "_, _, _, _, _ -> new", pure = true) public static @NotNull LangKeyValue ofSupplier(Supplier supplier, ModPartEnum MPE, String US_EN, String SIM_CN, String TRA_CN) { return new LangKeyValue(supplier, null, MPE, US_EN, SIM_CN, TRA_CN, null, false); } + /** + * Of supplier lang key value. + * + * @param supplier the supplier + * @param MPE the mpe + * @param US_EN the us en + * @param SIM_CN the sim cn + * @param TRA_CN the tra cn + * @param LZH the lzh + * @return the lang key value + */ @Contract(value = "_, _, _, _, _, _ -> new", pure = true) public static @NotNull LangKeyValue ofSupplier(Supplier supplier, ModPartEnum MPE, String US_EN, String SIM_CN, String TRA_CN, String LZH) { return new LangKeyValue(supplier, null, MPE, US_EN, SIM_CN, TRA_CN, LZH, false); } + /** + * Of supplier lang key value. + * + * @param supplier the supplier + * @param MPE the mpe + * @param US_EN the us en + * @param SIM_CN the sim cn + * @param TRA_CN the tra cn + * @param isDefault the is default + * @return the lang key value + */ @Contract(value = "_, _, _, _, _, _ -> new", pure = true) public static @NotNull LangKeyValue ofSupplier(Supplier supplier, ModPartEnum MPE, String US_EN, String SIM_CN, String TRA_CN, Boolean isDefault) { return new LangKeyValue(supplier, null, MPE, US_EN, SIM_CN, TRA_CN, null, isDefault); } + /** + * Of key lang key value. + * + * @param key the key + * @param MPE the mpe + * @param US_EN the us en + * @param SIM_CN the sim cn + * @param TRA_CN the tra cn + * @return the lang key value + */ @Contract(value = "_, _, _, _, _ -> new", pure = true) public static @NotNull LangKeyValue ofKey(String key, ModPartEnum MPE, String US_EN, String SIM_CN, String TRA_CN) { return new LangKeyValue(null, key, MPE, US_EN, SIM_CN, TRA_CN, null, false); } + /** + * Of key lang key value. + * + * @param key the key + * @param MPE the mpe + * @param US_EN the us en + * @param SIM_CN the sim cn + * @param TRA_CN the tra cn + * @param LZH the lzh + * @return the lang key value + */ @Contract(value = "_, _, _, _, _, _ -> new", pure = true) public static @NotNull LangKeyValue ofKey(String key, ModPartEnum MPE, String US_EN, String SIM_CN, String TRA_CN, String LZH) { return new LangKeyValue(null, key, MPE, US_EN, SIM_CN, TRA_CN, LZH, false); } + /** + * Of key lang key value. + * + * @param key the key + * @param MPE the mpe + * @param US_EN the us en + * @param SIM_CN the sim cn + * @param TRA_CN the tra cn + * @param isDefault the is default + * @return the lang key value + */ @Contract(value = "_, _, _, _, _, _ -> new", pure = true) public static @NotNull LangKeyValue ofKey(String key, ModPartEnum MPE, String US_EN, String SIM_CN, String TRA_CN, Boolean isDefault) { return new LangKeyValue(null, key, MPE, US_EN, SIM_CN, TRA_CN, null, isDefault); } + /** + * Gets key. + * + * @return the key + */ public String getKey() { return key; } diff --git a/src/main/java/top/r3944realms/lib39/datagen/value/McLocale.java b/src/main/java/top/r3944realms/lib39/datagen/value/McLocale.java index ac2169d..91cd9b6 100644 --- a/src/main/java/top/r3944realms/lib39/datagen/value/McLocale.java +++ b/src/main/java/top/r3944realms/lib39/datagen/value/McLocale.java @@ -2,16 +2,49 @@ package top.r3944realms.lib39.datagen.value; import java.util.Locale; +/** + * The enum Mc locale. + */ public enum McLocale implements ILocaleEntry { + /** + * En us mc locale. + */ EN_US("en_us", Locale.US), + /** + * Zh cn mc locale. + */ ZH_CN("zh_cn", Locale.SIMPLIFIED_CHINESE), + /** + * Zh tw mc locale. + */ ZH_TW("zh_tw", Locale.TRADITIONAL_CHINESE), + /** + * The Lzh. + */ LZH("lzh", new Locale("lzh", "ZH")), + /** + * Ja jp mc locale. + */ JA_JP("ja_jp", Locale.JAPAN), + /** + * Ko kr mc locale. + */ KO_KR("ko_kr", Locale.KOREA), + /** + * The Ru ru. + */ RU_RU("ru_ru", new Locale("ru", "RU")), + /** + * Fr fr mc locale. + */ FR_FR("fr_fr", Locale.FRANCE), + /** + * De de mc locale. + */ DE_DE("de_de", Locale.GERMANY), + /** + * The Es es. + */ ES_ES("es_es", new Locale("es", "ES")); private final String mcCode; diff --git a/src/main/java/top/r3944realms/lib39/datagen/value/ModPartEnum.java b/src/main/java/top/r3944realms/lib39/datagen/value/ModPartEnum.java index 0ddc759..cefc189 100644 --- a/src/main/java/top/r3944realms/lib39/datagen/value/ModPartEnum.java +++ b/src/main/java/top/r3944realms/lib39/datagen/value/ModPartEnum.java @@ -7,62 +7,101 @@ import org.jetbrains.annotations.NotNull; * 模组各部分的类型枚举,用于数据生成与分类。 */ public enum ModPartEnum { - /** 默认/未指定类型 */ + /** + * 默认/未指定类型 + */ DEFAULT, - /** 物品 */ + /** + * 物品 + */ ITEM, - /** 方块 */ + /** + * 方块 + */ BLOCK, - /** 附魔 */ + /** + * 附魔 + */ ENCHANTMENT, - /** 成就 / 进度 */ + /** + * 成就 / 进度 + */ ADVANCEMENT, - /** 创造模式物品栏 */ + /** + * 创造模式物品栏 + */ CREATIVE_TAB, - /** 配置项 */ + /** + * 配置项 + */ CONFIG, - /** 实体(生物、载具等) */ + /** + * 实体(生物、载具等) + */ ENTITY, - /** 图形界面 */ + /** + * 图形界面 + */ GUI, - /** 作者信息 */ + /** + * 作者信息 + */ AUTHOR, - /** 标题 */ + /** + * 标题 + */ TITLE, - /** 名称 */ + /** + * 名称 + */ NAME, - /** 游戏规则(/gamerule) */ + /** + * 游戏规则(/gamerule) + */ GAME_RULE, - /** 描述文本 */ + /** + * 描述文本 + */ DESCRIPTION, - /** 一般信息 */ + /** + * 一般信息 + */ INFO, - /** 消息(聊天、提示等) */ + /** + * 消息(聊天、提示等) + */ MESSAGE, - /** 命令 */ + /** + * 命令 + */ COMMAND, - /** 声音资源 */ + /** + * 声音资源 + */ SOUND; + /** * 根据枚举类型生成标准化 key 前缀 * 例如 ITEM -> "item.", BLOCK -> "block." + * + * @return the key prefix */ @Contract(pure = true) public @NotNull String getKeyPrefix() { @@ -91,6 +130,9 @@ public enum ModPartEnum { /** * 根据枚举类型和具体名称生成完整 key * 例如 ITEM + "example_item" -> "item.example_item" + * + * @param name the name + * @return the full key */ @Contract(pure = true) public @NotNull String getFullKey(String name) { diff --git a/src/main/java/top/r3944realms/lib39/util/block/BlockRegistryBuilder.java b/src/main/java/top/r3944realms/lib39/util/block/BlockRegistryBuilder.java index 84e817e..2415ad1 100644 --- a/src/main/java/top/r3944realms/lib39/util/block/BlockRegistryBuilder.java +++ b/src/main/java/top/r3944realms/lib39/util/block/BlockRegistryBuilder.java @@ -6,10 +6,15 @@ import net.minecraft.world.item.CreativeModeTabs; import net.minecraft.world.level.block.Block; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.RegistryObject; -import top.r3944realms.lib39.core.event.CommonHandler; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import top.r3944realms.lib39.core.event.CommonEventHandler; import java.util.function.Supplier; +/** + * The type Block registry builder. + */ @SuppressWarnings({"UnusedReturnValue", "unused"}) public class BlockRegistryBuilder { private String registryName; @@ -17,22 +22,33 @@ public class BlockRegistryBuilder { /** * 创建新的构建器实例 + * + * @return the block registry builder */ - public static BlockRegistryBuilder create() { + @Contract(value = " -> new", pure = true) + public static @NotNull BlockRegistryBuilder create() { return new BlockRegistryBuilder(); } /** * 设置注册名称 + * + * @param name the name + * @return the block registry builder */ public BlockRegistryBuilder withName(String name) { this.registryName = name; return this; } + /** * 注册方块(不自动注册物品) + * + * @param blockRegister the block register + * @param blockSupplier the block supplier + * @return the block registry builder */ - public BlockRegistryBuilder registerBlock(DeferredRegister blockRegister, Supplier blockSupplier) { + public BlockRegistryBuilder registerBlock(@NotNull DeferredRegister blockRegister, Supplier blockSupplier) { this.blockObject = blockRegister.register(this.registryName, blockSupplier); return this; } @@ -42,11 +58,15 @@ public class BlockRegistryBuilder { */ @SafeVarargs private void registerBlockItem(RegistryObject blockObject, ResourceKey... creativeTabs) { - CommonHandler.Mod.addItemToTabs(blockObject, creativeTabs); + CommonEventHandler.Mod.addItemToTabs(blockObject, creativeTabs); } /** * 注册方块和物品到建筑标签页 + * + * @param blockRegister the block register + * @param blockSupplier the block supplier + * @return the block registry builder */ public BlockRegistryBuilder registerWithBuildingTab(DeferredRegister blockRegister, Supplier blockSupplier) { registerBlock(blockRegister, blockSupplier); @@ -56,6 +76,10 @@ public class BlockRegistryBuilder { /** * 注册方块和物品到功能标签页 + * + * @param blockRegister the block register + * @param blockSupplier the block supplier + * @return the block registry builder */ public BlockRegistryBuilder registerWithFunctionalTab(DeferredRegister blockRegister, Supplier blockSupplier) { registerBlock(blockRegister, blockSupplier); @@ -65,6 +89,8 @@ public class BlockRegistryBuilder { /** * 获取注册的方块对象 + * + * @return the registry object */ public RegistryObject build() { return this.blockObject; diff --git a/src/main/java/top/r3944realms/lib39/util/command/CommandAliasHelper.java b/src/main/java/top/r3944realms/lib39/util/command/CommandAliasHelper.java index 4c05005..704f764 100644 --- a/src/main/java/top/r3944realms/lib39/util/command/CommandAliasHelper.java +++ b/src/main/java/top/r3944realms/lib39/util/command/CommandAliasHelper.java @@ -12,11 +12,18 @@ import net.minecraft.commands.Commands; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * The type Command alias helper. + */ @SuppressWarnings("unused") public class CommandAliasHelper { /** * 注册命令及其别名 + * + * @param dispatcher the dispatcher + * @param mainCommand the main command + * @param aliases the aliases */ public static void registerWithAliases(@NotNull CommandDispatcher dispatcher, LiteralArgumentBuilder mainCommand, diff --git a/src/main/java/top/r3944realms/lib39/util/lang/Pair.java b/src/main/java/top/r3944realms/lib39/util/lang/Pair.java index 53116d3..9dcc7ca 100644 --- a/src/main/java/top/r3944realms/lib39/util/lang/Pair.java +++ b/src/main/java/top/r3944realms/lib39/util/lang/Pair.java @@ -3,8 +3,20 @@ package top.r3944realms.lib39.util.lang; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +/** + * The type Pair. + * + * @param the type parameter + * @param the type parameter + */ public final class Pair { + /** + * The First. + */ public F first; + /** + * The Second. + */ public S second; private Pair(F first, S second) { @@ -12,6 +24,15 @@ public final class Pair { this.second = second; } + /** + * Of @ not null pair. + * + * @param the type parameter + * @param the type parameter + * @param first the first + * @param second the second + * @return the @ not null pair + */ @Contract("null, _ -> fail; !null, null -> fail; !null, !null -> new") public static @NotNull Pair of(F first, S second) { if (first == null || second == null) { diff --git a/src/main/java/top/r3944realms/lib39/util/lang/Triple.java b/src/main/java/top/r3944realms/lib39/util/lang/Triple.java index 8843589..d81a4d4 100644 --- a/src/main/java/top/r3944realms/lib39/util/lang/Triple.java +++ b/src/main/java/top/r3944realms/lib39/util/lang/Triple.java @@ -5,10 +5,26 @@ import org.jetbrains.annotations.NotNull; import java.util.Objects; +/** + * The type Triple. + * + * @param the type parameter + * @param the type parameter + * @param the type parameter + */ @SuppressWarnings("unused") public final class Triple { + /** + * The First. + */ public A first; + /** + * The Second. + */ public B second; + /** + * The Third. + */ public C third; private Triple(A first, B second, C third) { @@ -17,6 +33,17 @@ public final class Triple { this.third = third; } + /** + * Of @ not null triple. + * + * @param the type parameter + * @param the type parameter + * @param the type parameter + * @param first the first + * @param second the second + * @param third the third + * @return the @ not null triple + */ @Contract(value = "_, _, _ -> new", pure = true) public static @NotNull Triple of(A first, B second, C third) { return new Triple<>(first, second, third); @@ -37,8 +64,9 @@ public final class Triple { return Objects.hash(first, second, third); } + @Contract(pure = true) @Override - public String toString() { + public @NotNull String toString() { return "Triple{" + "first=" + first + ", second=" + second + diff --git a/src/main/java/top/r3944realms/lib39/util/lang/Tuple.java b/src/main/java/top/r3944realms/lib39/util/lang/Tuple.java index 2fd3bc3..8406d0d 100644 --- a/src/main/java/top/r3944realms/lib39/util/lang/Tuple.java +++ b/src/main/java/top/r3944realms/lib39/util/lang/Tuple.java @@ -8,6 +8,9 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; +/** + * The type Tuple. + */ @SuppressWarnings("unused") public final class Tuple { private final List elements; @@ -16,15 +19,33 @@ public final class Tuple { this.elements = List.of(elements); } + /** + * Of tuple. + * + * @param elements the elements + * @return the tuple + */ @Contract(value = "_ -> new", pure = true) public static @NotNull Tuple of(Object... elements) { return new Tuple(elements); } + /** + * Size int. + * + * @return the int + */ public int size() { return elements.size(); } + /** + * Get t. + * + * @param the type parameter + * @param index the index + * @return the t + */ @SuppressWarnings("unchecked") public T get(int index) { if (index < 0 || index >= elements.size()) { @@ -33,27 +54,63 @@ public final class Tuple { return (T) elements.get(index); } + /** + * First t. + * + * @param the type parameter + * @return the t + */ public T first() { return get(0); } + /** + * Second t. + * + * @param the type parameter + * @return the t + */ public T second() { return get(1); } + /** + * Third t. + * + * @param the type parameter + * @return the t + */ public T third() { return get(2); } + /** + * Last t. + * + * @param the type parameter + * @return the t + */ public T last() { return get(elements.size() - 1); } - public List toList() { + /** + * To list list. + * + * @return the list + */ + @Contract(value = " -> new", pure = true) + public @NotNull List toList() { return new ArrayList<>(elements); } - public Object[] toArray() { + /** + * To array object [ ]. + * + * @return the object [ ] + */ + @Contract(pure = true) + public Object @NotNull [] toArray() { return elements.toArray(); } @@ -70,15 +127,26 @@ public final class Tuple { return Objects.hash(elements); } + @Contract(pure = true) @Override - public String toString() { + public @NotNull String toString() { return "Tuple" + elements; } - public Iterator iterator() { + /** + * Iterator iterator. + * + * @return the iterator + */ + public @NotNull Iterator iterator() { return elements.iterator(); } + /** + * Stream java . util . stream . stream. + * + * @return the java . util . stream . stream + */ public java.util.stream.Stream stream() { return elements.stream(); } diff --git a/src/main/java/top/r3944realms/lib39/util/nbt/NBTReader.java b/src/main/java/top/r3944realms/lib39/util/nbt/NBTReader.java index 8c450b6..86a4a08 100644 --- a/src/main/java/top/r3944realms/lib39/util/nbt/NBTReader.java +++ b/src/main/java/top/r3944realms/lib39/util/nbt/NBTReader.java @@ -24,6 +24,9 @@ import org.jetbrains.annotations.Nullable; import java.util.UUID; import java.util.function.Consumer; +/** + * The type Nbt reader. + */ @SuppressWarnings("unused") public class NBTReader { private final CompoundTag nbt; @@ -34,13 +37,23 @@ public class NBTReader { /** * 从CompoundTag创建读取器 + * + * @param nbt the nbt + * @return the nbt reader */ @NotNull public static NBTReader of(@NotNull CompoundTag nbt) { return new NBTReader(nbt); } - // 基本读取方法 - 直接赋值给成员变量 + /** + * String nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ +// 基本读取方法 - 直接赋值给成员变量 public NBTReader string(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getString(key)); @@ -48,11 +61,26 @@ public class NBTReader { return this; } + /** + * String nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader string(String key, @NotNull Consumer setter, String defaultValue) { setter.accept(nbt.contains(key) ? nbt.getString(key) : defaultValue); return this; } + /** + * Byte value nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ public NBTReader byteValue(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getByte(key)); @@ -60,11 +88,26 @@ public class NBTReader { return this; } + /** + * Byte value nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader byteValue(String key, @NotNull Consumer setter, byte defaultValue) { setter.accept(nbt.contains(key) ? nbt.getByte(key) : defaultValue); return this; } + /** + * Short value nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ public NBTReader shortValue(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getShort(key)); @@ -72,11 +115,26 @@ public class NBTReader { return this; } + /** + * Short value nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader shortValue(String key, @NotNull Consumer setter, short defaultValue) { setter.accept(nbt.contains(key) ? nbt.getShort(key) : defaultValue); return this; } + /** + * Int value nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ public NBTReader intValue(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getInt(key)); @@ -84,11 +142,26 @@ public class NBTReader { return this; } + /** + * Int value nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader intValue(String key, @NotNull Consumer setter, int defaultValue) { setter.accept(nbt.contains(key) ? nbt.getInt(key) : defaultValue); return this; } + /** + * Long value nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ public NBTReader longValue(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getLong(key)); @@ -96,11 +169,26 @@ public class NBTReader { return this; } + /** + * Long value nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader longValue(String key, @NotNull Consumer setter, long defaultValue) { setter.accept(nbt.contains(key) ? nbt.getLong(key) : defaultValue); return this; } + /** + * Float value nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ public NBTReader floatValue(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getFloat(key)); @@ -108,11 +196,26 @@ public class NBTReader { return this; } + /** + * Float value nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader floatValue(String key, @NotNull Consumer setter, float defaultValue) { setter.accept(nbt.contains(key) ? nbt.getFloat(key) : defaultValue); return this; } + /** + * Double value nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ public NBTReader doubleValue(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getDouble(key)); @@ -120,11 +223,26 @@ public class NBTReader { return this; } + /** + * Double value nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader doubleValue(String key, @NotNull Consumer setter, double defaultValue) { setter.accept(nbt.contains(key) ? nbt.getDouble(key) : defaultValue); return this; } + /** + * Boolean value nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ public NBTReader booleanValue(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getBoolean(key)); @@ -132,12 +250,27 @@ public class NBTReader { return this; } + /** + * Boolean value nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader booleanValue(String key, @NotNull Consumer setter, boolean defaultValue) { setter.accept(nbt.contains(key) ? nbt.getBoolean(key) : defaultValue); return this; } - // 数组类型 + /** + * Byte array nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ +// 数组类型 public NBTReader byteArray(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getByteArray(key)); @@ -145,6 +278,13 @@ public class NBTReader { return this; } + /** + * Int array nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ public NBTReader intArray(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getIntArray(key)); @@ -152,6 +292,13 @@ public class NBTReader { return this; } + /** + * Long array nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ public NBTReader longArray(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getLongArray(key)); @@ -159,7 +306,14 @@ public class NBTReader { return this; } - // UUID + /** + * Uuid nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ +// UUID public NBTReader uuid(String key, Consumer setter) { if (nbt.hasUUID(key)) { setter.accept(nbt.getUUID(key)); @@ -167,12 +321,27 @@ public class NBTReader { return this; } + /** + * Uuid nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader uuid(String key, @NotNull Consumer setter, UUID defaultValue) { setter.accept(nbt.hasUUID(key) ? nbt.getUUID(key) : defaultValue); return this; } - // CompoundTag + /** + * Compound nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ +// CompoundTag public NBTReader compound(String key, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getCompound(key)); @@ -180,12 +349,28 @@ public class NBTReader { return this; } + /** + * Compound nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader compound(String key, @NotNull Consumer setter, CompoundTag defaultValue) { setter.accept(nbt.contains(key) ? nbt.getCompound(key) : defaultValue); return this; } - // ListTag + /** + * List nbt reader. + * + * @param key the key + * @param type the type + * @param setter the setter + * @return the nbt reader + */ +// ListTag public NBTReader list(String key, int type, Consumer setter) { if (nbt.contains(key)) { setter.accept(nbt.getList(key, type)); @@ -193,7 +378,14 @@ public class NBTReader { return this; } - // Vec3支持 + /** + * Vec 3 nbt reader. + * + * @param key the key + * @param setter the setter + * @return the nbt reader + */ +// Vec3支持 public NBTReader vec3(String key, Consumer setter) { if (nbt.contains(key)) { CompoundTag vecTag = nbt.getCompound(key); @@ -208,6 +400,14 @@ public class NBTReader { return this; } + /** + * Vec 3 nbt reader. + * + * @param key the key + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public NBTReader vec3(String key, Consumer setter, Vec3 defaultValue) { if (nbt.contains(key)) { CompoundTag vecTag = nbt.getCompound(key); @@ -224,7 +424,16 @@ public class NBTReader { return this; } - // 枚举支持 + /** + * Enum value nbt reader. + * + * @param the type parameter + * @param key the key + * @param enumClass the enum class + * @param setter the setter + * @return the nbt reader + */ +// 枚举支持 public > NBTReader enumValue(String key, Class enumClass, Consumer setter) { if (nbt.contains(key)) { String value = nbt.getString(key); @@ -237,6 +446,16 @@ public class NBTReader { return this; } + /** + * Enum value nbt reader. + * + * @param the type parameter + * @param key the key + * @param enumClass the enum class + * @param setter the setter + * @param defaultValue the default value + * @return the nbt reader + */ public > NBTReader enumValue(String key, Class enumClass, Consumer setter, T defaultValue) { if (nbt.contains(key)) { String value = nbt.getString(key); @@ -250,7 +469,14 @@ public class NBTReader { return this; } - // 嵌套读取支持 + /** + * Nested nbt reader. + * + * @param key the key + * @param consumer the consumer + * @return the nbt reader + */ +// 嵌套读取支持 public NBTReader nested(String key, Consumer consumer) { if (nbt.contains(key)) { consumer.accept(new NBTReader(nbt.getCompound(key))); @@ -258,6 +484,14 @@ public class NBTReader { return this; } + /** + * Nested nbt reader. + * + * @param key the key + * @param consumer the consumer + * @param orElse the or else + * @return the nbt reader + */ public NBTReader nested(String key, Consumer consumer, Runnable orElse) { if (nbt.contains(key)) { consumer.accept(new NBTReader(nbt.getCompound(key))); @@ -267,7 +501,14 @@ public class NBTReader { return this; } - // 条件读取 + /** + * If present nbt reader. + * + * @param key the key + * @param action the action + * @return the nbt reader + */ +// 条件读取 public NBTReader ifPresent(String key, Runnable action) { if (nbt.contains(key)) { action.run(); @@ -275,6 +516,13 @@ public class NBTReader { return this; } + /** + * If absent nbt reader. + * + * @param key the key + * @param action the action + * @return the nbt reader + */ public NBTReader ifAbsent(String key, Runnable action) { if (!nbt.contains(key)) { action.run(); @@ -282,13 +530,24 @@ public class NBTReader { return this; } - // 获取原始NBT + /** + * Gets raw. + * + * @return the raw + */ +// 获取原始NBT @NotNull public CompoundTag getRaw() { return nbt; } - // 便捷的静态方法(保持原有功能) + /** + * Read vec 3 vec 3. + * + * @param nbt the nbt + * @return the vec 3 + */ +// 便捷的静态方法(保持原有功能) @NotNull public static Vec3 readVec3(@NotNull CompoundTag nbt) { if (nbt.contains("X") && nbt.contains("Y") && nbt.contains("Z")) { @@ -302,6 +561,12 @@ public class NBTReader { } } + /** + * Read vec 3 safe vec 3. + * + * @param nbt the nbt + * @return the vec 3 + */ @Nullable public static Vec3 readVec3Safe(@NotNull CompoundTag nbt) { if (nbt.contains("X") && nbt.contains("Y") && nbt.contains("Z")) { diff --git a/src/main/java/top/r3944realms/lib39/util/nbt/NBTWriter.java b/src/main/java/top/r3944realms/lib39/util/nbt/NBTWriter.java index 80dcce3..7235330 100644 --- a/src/main/java/top/r3944realms/lib39/util/nbt/NBTWriter.java +++ b/src/main/java/top/r3944realms/lib39/util/nbt/NBTWriter.java @@ -9,6 +9,9 @@ import org.jetbrains.annotations.Nullable; import java.util.UUID; import java.util.function.Consumer; +/** + * The type Nbt writer. + */ @SuppressWarnings("unused") public class NBTWriter { private final CompoundTag root; @@ -23,6 +26,8 @@ public class NBTWriter { /** * 创建一个新的NBT构建器 + * + * @return the nbt writer */ @Contract(value = " -> new", pure = true) public static @NotNull NBTWriter builder() { @@ -31,53 +36,122 @@ public class NBTWriter { /** * 基于现有CompoundTag创建构建器 + * + * @param existingTag the existing tag + * @return the nbt writer */ @Contract(value = "_ -> new", pure = true) public static @NotNull NBTWriter of(CompoundTag existingTag) { return new NBTWriter(existingTag); } + /** + * Byte value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter byteValue(String key, byte value) { root.putByte(key, value); return this; } + /** + * Short value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter shortValue(String key, short value) { root.putShort(key, value); return this; } + /** + * Int value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter intValue(String key, int value) { root.putInt(key, value); return this; } + /** + * Long value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter longValue(String key, long value) { root.putLong(key, value); return this; } + /** + * Float value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter floatValue(String key, float value) { root.putFloat(key, value); return this; } + /** + * Double value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter doubleValue(String key, double value) { root.putDouble(key, value); return this; } + /** + * Boolean value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter booleanValue(String key, boolean value) { root.putBoolean(key, value); return this; } + + /** + * String nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter string(String key, String value) { if (value != null) { root.putString(key, value); } return this; } - // 包装类型 - null安全的版本 + + /** + * String nbt writer. + * + * @param key the key + * @param value the value + * @param defaultValue the default value + * @return the nbt writer + */ +// 包装类型 - null安全的版本 public NBTWriter string(String key, String value, String defaultValue) { if (value != null) { root.putString(key, value); @@ -88,6 +162,13 @@ public class NBTWriter { } + /** + * Byte value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter byteValue(String key, Byte value) { if (value != null) { root.putByte(key, value); @@ -95,11 +176,26 @@ public class NBTWriter { return this; } + /** + * Byte value nbt writer. + * + * @param key the key + * @param value the value + * @param defaultValue the default value + * @return the nbt writer + */ public NBTWriter byteValue(String key, Byte value, byte defaultValue) { root.putByte(key, value != null ? value : defaultValue); return this; } + /** + * Short value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter shortValue(String key, Short value) { if (value != null) { root.putShort(key, value); @@ -107,11 +203,26 @@ public class NBTWriter { return this; } + /** + * Short value nbt writer. + * + * @param key the key + * @param value the value + * @param defaultValue the default value + * @return the nbt writer + */ public NBTWriter shortValue(String key, Short value, short defaultValue) { root.putShort(key, value != null ? value : defaultValue); return this; } + /** + * Int value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter intValue(String key, Integer value) { if (value != null) { root.putInt(key, value); @@ -119,11 +230,26 @@ public class NBTWriter { return this; } + /** + * Int value nbt writer. + * + * @param key the key + * @param value the value + * @param defaultValue the default value + * @return the nbt writer + */ public NBTWriter intValue(String key, Integer value, int defaultValue) { root.putInt(key, value != null ? value : defaultValue); return this; } + /** + * Long value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter longValue(String key, Long value) { if (value != null) { root.putLong(key, value); @@ -131,11 +257,26 @@ public class NBTWriter { return this; } + /** + * Long value nbt writer. + * + * @param key the key + * @param value the value + * @param defaultValue the default value + * @return the nbt writer + */ public NBTWriter longValue(String key, Long value, long defaultValue) { root.putLong(key, value != null ? value : defaultValue); return this; } + /** + * Float value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter floatValue(String key, Float value) { if (value != null) { root.putFloat(key, value); @@ -143,11 +284,26 @@ public class NBTWriter { return this; } + /** + * Float value nbt writer. + * + * @param key the key + * @param value the value + * @param defaultValue the default value + * @return the nbt writer + */ public NBTWriter floatValue(String key, Float value, float defaultValue) { root.putFloat(key, value != null ? value : defaultValue); return this; } + /** + * Double value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter doubleValue(String key, Double value) { if (value != null) { root.putDouble(key, value); @@ -155,11 +311,26 @@ public class NBTWriter { return this; } + /** + * Double value nbt writer. + * + * @param key the key + * @param value the value + * @param defaultValue the default value + * @return the nbt writer + */ public NBTWriter doubleValue(String key, Double value, double defaultValue) { root.putDouble(key, value != null ? value : defaultValue); return this; } + /** + * Boolean value nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter booleanValue(String key, Boolean value) { if (value != null) { root.putBoolean(key, value); @@ -167,12 +338,27 @@ public class NBTWriter { return this; } + /** + * Boolean value nbt writer. + * + * @param key the key + * @param value the value + * @param defaultValue the default value + * @return the nbt writer + */ public NBTWriter booleanValue(String key, Boolean value, boolean defaultValue) { root.putBoolean(key, value != null ? value : defaultValue); return this; } - // 数组类型 - 原始数组 + /** + * Byte array nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ +// 数组类型 - 原始数组 public NBTWriter byteArray(String key, byte[] value) { if (value != null) { root.putByteArray(key, value); @@ -180,6 +366,13 @@ public class NBTWriter { return this; } + /** + * Int array nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter intArray(String key, int[] value) { if (value != null) { root.putIntArray(key, value); @@ -187,6 +380,13 @@ public class NBTWriter { return this; } + /** + * Long array nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ public NBTWriter longArray(String key, long[] value) { if (value != null) { root.putLongArray(key, value); @@ -194,7 +394,14 @@ public class NBTWriter { return this; } - // UUID支持 + /** + * Uuid nbt writer. + * + * @param key the key + * @param value the value + * @return the nbt writer + */ +// UUID支持 public NBTWriter uuid(String key, UUID value) { if (value != null) { root.putUUID(key, value); @@ -202,6 +409,14 @@ public class NBTWriter { return this; } + /** + * Uuid nbt writer. + * + * @param key the key + * @param value the value + * @param defaultValue the default value + * @return the nbt writer + */ public NBTWriter uuid(String key, UUID value, UUID defaultValue) { if (value != null) { root.putUUID(key, value); @@ -211,7 +426,14 @@ public class NBTWriter { return this; } - // 嵌套CompoundTag + /** + * Compound nbt writer. + * + * @param key the key + * @param consumer the consumer + * @return the nbt writer + */ +// 嵌套CompoundTag public NBTWriter compound(String key, Consumer consumer) { if (consumer != null) { NBTWriter nestedBuilder = new NBTWriter(); @@ -224,6 +446,13 @@ public class NBTWriter { return this; } + /** + * Compound nbt writer. + * + * @param key the key + * @param compoundTag the compound tag + * @return the nbt writer + */ public NBTWriter compound(String key, CompoundTag compoundTag) { if (compoundTag != null && !compoundTag.isEmpty()) { root.put(key, compoundTag); @@ -231,6 +460,14 @@ public class NBTWriter { return this; } + /** + * Compound if nbt writer. + * + * @param key the key + * @param condition the condition + * @param consumer the consumer + * @return the nbt writer + */ public NBTWriter compoundIf(String key, boolean condition, Consumer consumer) { if (condition && consumer != null) { return compound(key, consumer); @@ -238,7 +475,14 @@ public class NBTWriter { return this; } - // ListTag支持 + /** + * List nbt writer. + * + * @param key the key + * @param consumer the consumer + * @return the nbt writer + */ +// ListTag支持 public NBTWriter list(String key, Consumer consumer) { if (consumer != null) { ListNBTBuilder listBuilder = new ListNBTBuilder(); @@ -251,6 +495,13 @@ public class NBTWriter { return this; } + /** + * List nbt writer. + * + * @param key the key + * @param listTag the list tag + * @return the nbt writer + */ public NBTWriter list(String key, ListTag listTag) { if (listTag != null && !listTag.isEmpty()) { root.put(key, listTag); @@ -258,6 +509,14 @@ public class NBTWriter { return this; } + /** + * List if nbt writer. + * + * @param key the key + * @param condition the condition + * @param consumer the consumer + * @return the nbt writer + */ public NBTWriter listIf(String key, boolean condition, Consumer consumer) { if (condition && consumer != null) { return list(key, consumer); @@ -265,7 +524,14 @@ public class NBTWriter { return this; } - // 直接操作Tag + /** + * Tag nbt writer. + * + * @param key the key + * @param tag the tag + * @return the nbt writer + */ +// 直接操作Tag public NBTWriter tag(String key, Tag tag) { if (tag != null) { root.put(key, tag); @@ -273,7 +539,15 @@ public class NBTWriter { return this; } - // 条件添加方法 + /** + * String if nbt writer. + * + * @param key the key + * @param value the value + * @param condition the condition + * @return the nbt writer + */ +// 条件添加方法 public NBTWriter stringIf(String key, String value, boolean condition) { if (condition && value != null) { root.putString(key, value); @@ -281,6 +555,14 @@ public class NBTWriter { return this; } + /** + * Int value if nbt writer. + * + * @param key the key + * @param value the value + * @param condition the condition + * @return the nbt writer + */ public NBTWriter intValueIf(String key, Integer value, boolean condition) { if (condition && value != null) { root.putInt(key, value); @@ -288,6 +570,14 @@ public class NBTWriter { return this; } + /** + * Long value if nbt writer. + * + * @param key the key + * @param value the value + * @param condition the condition + * @return the nbt writer + */ public NBTWriter longValueIf(String key, Long value, boolean condition) { if (condition && value != null) { root.putLong(key, value); @@ -295,6 +585,14 @@ public class NBTWriter { return this; } + /** + * Boolean value if nbt writer. + * + * @param key the key + * @param value the value + * @param condition the condition + * @return the nbt writer + */ public NBTWriter booleanValueIf(String key, Boolean value, boolean condition) { if (condition && value != null) { root.putBoolean(key, value); @@ -302,13 +600,24 @@ public class NBTWriter { return this; } - // 移除标签 + /** + * Remove nbt writer. + * + * @param key the key + * @return the nbt writer + */ +// 移除标签 public NBTWriter remove(String key) { root.remove(key); return this; } - // 构建最终的CompoundTag + /** + * Build compound tag. + * + * @return the compound tag + */ +// 构建最终的CompoundTag public CompoundTag build() { return root; } @@ -324,47 +633,101 @@ public class NBTWriter { this.list = new ListTag(); } - // 原始类型方法 + /** + * Add string list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ +// 原始类型方法 public ListNBTBuilder addString(String value) { list.add(StringTag.valueOf(value)); return this; } + /** + * Add byte list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addByte(byte value) { list.add(ByteTag.valueOf(value)); return this; } + /** + * Add short list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addShort(short value) { list.add(ShortTag.valueOf(value)); return this; } + /** + * Add int list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addInt(int value) { list.add(IntTag.valueOf(value)); return this; } + /** + * Add long list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addLong(long value) { list.add(LongTag.valueOf(value)); return this; } + /** + * Add float list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addFloat(float value) { list.add(FloatTag.valueOf(value)); return this; } + /** + * Add double list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addDouble(double value) { list.add(DoubleTag.valueOf(value)); return this; } + /** + * Add boolean list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addBoolean(boolean value) { list.add(ByteTag.valueOf(value)); return this; } + /** + * Add byte array list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addByteArray(byte[] value) { if (value != null) { list.add(new ByteArrayTag(value)); @@ -372,6 +735,12 @@ public class NBTWriter { return this; } + /** + * Add int array list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addIntArray(int[] value) { if (value != null) { list.add(new IntArrayTag(value)); @@ -379,6 +748,12 @@ public class NBTWriter { return this; } + /** + * Add long array list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addLongArray(long[] value) { if (value != null) { list.add(new LongArrayTag(value)); @@ -386,12 +761,25 @@ public class NBTWriter { return this; } - // 包装类型方法 - null安全 + /** + * Add string list nbt builder. + * + * @param value the value + * @param defaultValue the default value + * @return the list nbt builder + */ +// 包装类型方法 - null安全 public ListNBTBuilder addString(String value, String defaultValue) { list.add(StringTag.valueOf(value != null ? value : defaultValue)); return this; } + /** + * Add string if list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addStringIf(String value) { if (value != null) { list.add(StringTag.valueOf(value)); @@ -399,6 +787,12 @@ public class NBTWriter { return this; } + /** + * Add byte list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addByte(Byte value) { if (value != null) { list.add(ByteTag.valueOf(value)); @@ -406,11 +800,24 @@ public class NBTWriter { return this; } + /** + * Add byte list nbt builder. + * + * @param value the value + * @param defaultValue the default value + * @return the list nbt builder + */ public ListNBTBuilder addByte(Byte value, byte defaultValue) { list.add(ByteTag.valueOf(value != null ? value : defaultValue)); return this; } + /** + * Add short list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addShort(Short value) { if (value != null) { list.add(ShortTag.valueOf(value)); @@ -418,11 +825,24 @@ public class NBTWriter { return this; } + /** + * Add short list nbt builder. + * + * @param value the value + * @param defaultValue the default value + * @return the list nbt builder + */ public ListNBTBuilder addShort(Short value, short defaultValue) { list.add(ShortTag.valueOf(value != null ? value : defaultValue)); return this; } + /** + * Add int list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addInt(Integer value) { if (value != null) { list.add(IntTag.valueOf(value)); @@ -430,11 +850,24 @@ public class NBTWriter { return this; } + /** + * Add int list nbt builder. + * + * @param value the value + * @param defaultValue the default value + * @return the list nbt builder + */ public ListNBTBuilder addInt(Integer value, int defaultValue) { list.add(IntTag.valueOf(value != null ? value : defaultValue)); return this; } + /** + * Add long list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addLong(Long value) { if (value != null) { list.add(LongTag.valueOf(value)); @@ -442,11 +875,24 @@ public class NBTWriter { return this; } + /** + * Add long list nbt builder. + * + * @param value the value + * @param defaultValue the default value + * @return the list nbt builder + */ public ListNBTBuilder addLong(Long value, long defaultValue) { list.add(LongTag.valueOf(value != null ? value : defaultValue)); return this; } + /** + * Add float list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addFloat(Float value) { if (value != null) { list.add(FloatTag.valueOf(value)); @@ -454,11 +900,24 @@ public class NBTWriter { return this; } + /** + * Add float list nbt builder. + * + * @param value the value + * @param defaultValue the default value + * @return the list nbt builder + */ public ListNBTBuilder addFloat(Float value, float defaultValue) { list.add(FloatTag.valueOf(value != null ? value : defaultValue)); return this; } + /** + * Add double list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addDouble(Double value) { if (value != null) { list.add(DoubleTag.valueOf(value)); @@ -466,11 +925,24 @@ public class NBTWriter { return this; } + /** + * Add double list nbt builder. + * + * @param value the value + * @param defaultValue the default value + * @return the list nbt builder + */ public ListNBTBuilder addDouble(Double value, double defaultValue) { list.add(DoubleTag.valueOf(value != null ? value : defaultValue)); return this; } + /** + * Add boolean list nbt builder. + * + * @param value the value + * @return the list nbt builder + */ public ListNBTBuilder addBoolean(Boolean value) { if (value != null) { list.add(ByteTag.valueOf(value)); @@ -478,11 +950,24 @@ public class NBTWriter { return this; } + /** + * Add boolean list nbt builder. + * + * @param value the value + * @param defaultValue the default value + * @return the list nbt builder + */ public ListNBTBuilder addBoolean(Boolean value, boolean defaultValue) { list.add(ByteTag.valueOf(value != null ? value : defaultValue)); return this; } + /** + * Add compound list nbt builder. + * + * @param consumer the consumer + * @return the list nbt builder + */ public ListNBTBuilder addCompound(Consumer consumer) { if (consumer != null) { NBTWriter compoundBuilder = new NBTWriter(); @@ -495,6 +980,12 @@ public class NBTWriter { return this; } + /** + * Add tag list nbt builder. + * + * @param tag the tag + * @return the list nbt builder + */ public ListNBTBuilder addTag(Tag tag) { if (tag != null) { list.add(tag); @@ -502,6 +993,13 @@ public class NBTWriter { return this; } + /** + * Add if list nbt builder. + * + * @param condition the condition + * @param consumer the consumer + * @return the list nbt builder + */ public ListNBTBuilder addIf(boolean condition, Consumer consumer) { if (condition && consumer != null) { consumer.accept(this); @@ -509,12 +1007,23 @@ public class NBTWriter { return this; } + /** + * Build list tag. + * + * @return the list tag + */ public ListTag build() { return list; } } - // 便捷静态方法 + /** + * Create compound tag. + * + * @param consumer the consumer + * @return the compound tag + */ +// 便捷静态方法 public static CompoundTag create(Consumer consumer) { NBTWriter builder = new NBTWriter(); if (consumer != null) { @@ -523,6 +1032,12 @@ public class NBTWriter { return builder.build(); } + /** + * Create list list tag. + * + * @param consumer the consumer + * @return the list tag + */ public static ListTag createList(Consumer consumer) { ListNBTBuilder builder = new ListNBTBuilder(); if (consumer != null) { @@ -533,6 +1048,8 @@ public class NBTWriter { /** * 检查构建的NBT是否为空 + * + * @return the boolean */ public boolean isEmpty() { return root.isEmpty(); @@ -540,10 +1057,19 @@ public class NBTWriter { /** * 获取NBT中所有键的集合 + * + * @return the all keys */ public java.util.Set getAllKeys() { return root.getAllKeys(); } + + /** + * Write vec 3 compound tag. + * + * @param vec the vec + * @return the compound tag + */ @Contract("null -> fail") public static @NotNull CompoundTag writeVec3(Vec3 vec) { CompoundTag nbt = new CompoundTag(); @@ -555,6 +1081,12 @@ public class NBTWriter { return nbt; } + /** + * Write vec 3 safe compound tag. + * + * @param vec the vec + * @return the compound tag + */ public static @Nullable CompoundTag writeVec3Safe(Vec3 vec) { CompoundTag nbt = new CompoundTag(); if (vec == null) return null; diff --git a/src/main/java/top/r3944realms/lib39/util/riding/RidingApplier.java b/src/main/java/top/r3944realms/lib39/util/riding/RidingApplier.java index 84f6822..d17a77e 100644 --- a/src/main/java/top/r3944realms/lib39/util/riding/RidingApplier.java +++ b/src/main/java/top/r3944realms/lib39/util/riding/RidingApplier.java @@ -24,13 +24,17 @@ import java.util.Queue; import java.util.UUID; import java.util.function.Function; +/** + * The type Riding applier. + */ @SuppressWarnings("unused") public class RidingApplier { /** * 应用骑乘关系(在服务器端调用) - * @param relationship 骑乘关系 + * + * @param relationship 骑乘关系 * @param entityProvider 实体提供器(根据UUID获取实体) - * @return 应用成功的实体数量 + * @return 应用成功的实体数量 int */ public static int applyRidingRelationship(RidingRelationship relationship, Function entityProvider) { @@ -87,8 +91,12 @@ public class RidingApplier { return appliedCount; } + /** * 批量应用骑乘关系(适用于世界加载时) + * + * @param relationships the relationships + * @param entityProvider the entity provider */ public static void applyRidingRelationships(Collection relationships, Function entityProvider) { @@ -108,6 +116,10 @@ public class RidingApplier { /** * 从JSON字符串应用骑乘关系 + * + * @param json the json + * @param entityProvider the entity provider + * @return the int */ public static int applyRidingRelationshipFromJson(String json, Function entityProvider) { diff --git a/src/main/java/top/r3944realms/lib39/util/riding/RidingCycleException.java b/src/main/java/top/r3944realms/lib39/util/riding/RidingCycleException.java index 87e7d43..fda781f 100644 --- a/src/main/java/top/r3944realms/lib39/util/riding/RidingCycleException.java +++ b/src/main/java/top/r3944realms/lib39/util/riding/RidingCycleException.java @@ -17,11 +17,20 @@ package top.r3944realms.lib39.util.riding; import java.util.UUID; +/** + * The type Riding cycle exception. + */ @SuppressWarnings("unused") public class RidingCycleException extends IllegalStateException { private final UUID entityId; private final UUID vehicleId; + /** + * Instantiates a new Riding cycle exception. + * + * @param entityId the entity id + * @param vehicleId the vehicle id + */ public RidingCycleException(UUID entityId, UUID vehicleId) { super(String.format("Cyclic riding reference detected. " + "Entity %s cannot be added as passenger to vehicle %s " + @@ -31,10 +40,20 @@ public class RidingCycleException extends IllegalStateException { this.vehicleId = vehicleId; } + /** + * Gets entity id. + * + * @return the entity id + */ public UUID getEntityId() { return entityId; } + /** + * Gets vehicle id. + * + * @return the vehicle id + */ public UUID getVehicleId() { return vehicleId; } diff --git a/src/main/java/top/r3944realms/lib39/util/riding/RidingDismounts.java b/src/main/java/top/r3944realms/lib39/util/riding/RidingDismounts.java index 1fe0995..30c57d7 100644 --- a/src/main/java/top/r3944realms/lib39/util/riding/RidingDismounts.java +++ b/src/main/java/top/r3944realms/lib39/util/riding/RidingDismounts.java @@ -20,10 +20,15 @@ import net.minecraft.world.entity.Entity; import java.util.*; import java.util.function.Function; +/** + * The type Riding dismounts. + */ @SuppressWarnings("unused") public class RidingDismounts { /** * 解除单个实体的骑乘关系 + * + * @param entity the entity */ public static void dismountEntity(Entity entity) { if (entity == null) { @@ -41,6 +46,8 @@ public class RidingDismounts { /** * 解除实体及其所有乘客的骑乘关系(非递归) + * + * @param entity the entity */ public static void dismountAllPassengers(Entity entity) { if (entity == null) { @@ -65,6 +72,8 @@ public class RidingDismounts { /** * 解除根实体的骑乘关系(包括从载具下车) + * + * @param entity the entity */ public static void dismountRootEntity(Entity entity) { if (entity == null) { @@ -86,6 +95,10 @@ public class RidingDismounts { /** * 安全解除骑乘关系(带超时保护) + * + * @param entity the entity + * @param maxIterations the max iterations + * @return the boolean */ public static boolean safeDismountAll(Entity entity, int maxIterations) { if (entity == null) { @@ -118,6 +131,8 @@ public class RidingDismounts { /** * 批量解除多个实体的骑乘关系 + * + * @param entities the entities */ public static void dismountEntities(Collection entities) { if (entities == null || entities.isEmpty()) { @@ -151,6 +166,9 @@ public class RidingDismounts { /** * 根据骑乘关系数据结构解除骑乘 + * + * @param relationship the relationship + * @param entityProvider the entity provider */ public static void dismountByRelationship(RidingRelationship relationship, Function entityProvider) { @@ -181,6 +199,8 @@ public class RidingDismounts { /** * 立即解除所有骑乘关系(强制方式) + * + * @param entity the entity */ public static void forceDismountAll(Entity entity) { if (entity == null) { diff --git a/src/main/java/top/r3944realms/lib39/util/riding/RidingFinder.java b/src/main/java/top/r3944realms/lib39/util/riding/RidingFinder.java index 6ff5201..0fa3c3c 100644 --- a/src/main/java/top/r3944realms/lib39/util/riding/RidingFinder.java +++ b/src/main/java/top/r3944realms/lib39/util/riding/RidingFinder.java @@ -22,10 +22,17 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.Function; +/** + * The type Riding finder. + */ @SuppressWarnings("unused") public class RidingFinder { /** * 从JSON字符串应用骑乘关系 + * + * @param ship the ship + * @param entityProvider the entity provider + * @return the entity from riding ship */ public static @NotNull List getEntityFromRidingShip(RidingRelationship ship, Function entityProvider) { @@ -42,8 +49,12 @@ public class RidingFinder { } return ret; } + /** * 查找根载具 + * + * @param entity the entity + * @return the entity */ @Nullable public static Entity findRootVehicle(@Nullable Entity entity) { @@ -64,6 +75,9 @@ public class RidingFinder { /** * 获取所有乘客(包括嵌套乘客) + * + * @param entity the entity + * @return the all passengers */ public static List getAllPassengers(@Nullable Entity entity) { return getAllPassengers(entity, true); @@ -71,6 +85,10 @@ public class RidingFinder { /** * 获取所有乘客(包括嵌套乘客) + * + * @param entity the entity + * @param findRoot the find root + * @return the all passengers */ public static List getAllPassengers(@Nullable Entity entity, boolean findRoot) { if (entity == null) { diff --git a/src/main/java/top/r3944realms/lib39/util/riding/RidingRelationship.java b/src/main/java/top/r3944realms/lib39/util/riding/RidingRelationship.java index 94b2f66..5886d19 100644 --- a/src/main/java/top/r3944realms/lib39/util/riding/RidingRelationship.java +++ b/src/main/java/top/r3944realms/lib39/util/riding/RidingRelationship.java @@ -26,46 +26,93 @@ public class RidingRelationship { private UUID vehicleId; private List passengers; + /** + * Instantiates a new Riding relationship. + */ public RidingRelationship() { this.passengers = new ArrayList<>(); } + /** + * Instantiates a new Riding relationship. + * + * @param passengers the passengers + * @param vehicleId the vehicle id + * @param entityId the entity id + */ public RidingRelationship(List passengers, UUID vehicleId, UUID entityId) { this.passengers = passengers != null ? passengers : new ArrayList<>(); this.vehicleId = vehicleId; this.entityId = entityId; } + /** + * Gets entity id. + * + * @return the entity id + */ public UUID getEntityId() { return entityId; } + /** + * Sets entity id. + * + * @param entityId the entity id + */ public void setEntityId(UUID entityId) { this.entityId = entityId; } + /** + * Gets passengers. + * + * @return the passengers + */ public List getPassengers() { return Collections.unmodifiableList(passengers); } + /** + * Sets passengers. + * + * @param passengers the passengers + */ public void setPassengers(List passengers) { this.passengers = passengers != null ? passengers : new ArrayList<>(); } + /** + * Add passenger. + * + * @param passenger the passenger + */ public void addPassenger(RidingRelationship passenger) { this.passengers.add(passenger); } + /** + * Gets vehicle id. + * + * @return the vehicle id + */ public UUID getVehicleId() { return vehicleId; } + /** + * Sets vehicle id. + * + * @param vehicleId the vehicle id + */ public void setVehicleId(UUID vehicleId) { this.vehicleId = vehicleId; } /** * 获取所有嵌套乘客的数量 + * + * @return the total passenger count */ public int getTotalPassengerCount() { int count = passengers.size(); @@ -77,6 +124,9 @@ public class RidingRelationship { /** * 检查是否包含特定实体 + * + * @param entityId the entity id + * @return the boolean */ public boolean containsEntity(UUID entityId) { if (Objects.equals(this.entityId, entityId)) { diff --git a/src/main/java/top/r3944realms/lib39/util/riding/RidingSaver.java b/src/main/java/top/r3944realms/lib39/util/riding/RidingSaver.java index 3002084..613eef9 100644 --- a/src/main/java/top/r3944realms/lib39/util/riding/RidingSaver.java +++ b/src/main/java/top/r3944realms/lib39/util/riding/RidingSaver.java @@ -25,10 +25,16 @@ import top.r3944realms.lib39.util.lang.Pair; import java.util.*; import java.util.function.Function; +/** + * The type Riding saver. + */ @SuppressWarnings("unused") public class RidingSaver { /** * 保存骑乘关系 + * + * @param entity the entity + * @return the riding relationship */ @Contract("null -> new") public static @NotNull RidingRelationship save(@Nullable Entity entity) { @@ -37,6 +43,10 @@ public class RidingSaver { /** * 保存骑乘关系 + * + * @param entity the entity + * @param findRoot the find root + * @return the riding relationship */ @Contract("null, _ -> new") public static @NotNull RidingRelationship save(@Nullable Entity entity, boolean findRoot) { @@ -98,6 +108,11 @@ public class RidingSaver { // 传入一个实体提供器 Function,通常在服务器侧就是 level::getEntity private static Function entityProvider; + /** + * Sets entity provider. + * + * @param provider the provider + */ public static void setEntityProvider(Function provider) { entityProvider = provider; } diff --git a/src/main/java/top/r3944realms/lib39/util/riding/RidingSerializer.java b/src/main/java/top/r3944realms/lib39/util/riding/RidingSerializer.java index a50505d..b75ac76 100644 --- a/src/main/java/top/r3944realms/lib39/util/riding/RidingSerializer.java +++ b/src/main/java/top/r3944realms/lib39/util/riding/RidingSerializer.java @@ -17,11 +17,18 @@ package top.r3944realms.lib39.util.riding; import com.google.gson.Gson; +/** + * The type Riding serializer. + */ @SuppressWarnings("unused") public class RidingSerializer { private static final Gson GSON = new Gson(); + /** * 序列化骑乘关系 + * + * @param relationship the relationship + * @return the string */ public static String serialize(RidingRelationship relationship) { return GSON.toJson(relationship); @@ -29,6 +36,9 @@ public class RidingSerializer { /** * 反序列化骑乘关系 + * + * @param json the json + * @return the riding relationship */ public static RidingRelationship deserialize(String json) { return GSON.fromJson(json, RidingRelationship.class); diff --git a/src/main/java/top/r3944realms/lib39/util/riding/RidingValidator.java b/src/main/java/top/r3944realms/lib39/util/riding/RidingValidator.java index e9a2db1..5a68abb 100644 --- a/src/main/java/top/r3944realms/lib39/util/riding/RidingValidator.java +++ b/src/main/java/top/r3944realms/lib39/util/riding/RidingValidator.java @@ -20,10 +20,17 @@ import net.minecraft.world.entity.Entity; import java.util.LinkedList; import java.util.Queue; +/** + * The type Riding validator. + */ @SuppressWarnings("unused") public class RidingValidator { /** * 检查骑乘是否会产生循环引用 + * + * @param entity the entity + * @param vehicle the vehicle + * @return the boolean */ public static boolean wouldCreateCycle(Entity entity, Entity vehicle) { // 如果实体就是载具本身,直接产生循环 @@ -37,6 +44,10 @@ public class RidingValidator { /** * 检查target是否是entity的间接乘客 + * + * @param target the target + * @param entity the entity + * @return the boolean */ public static boolean isIndirectPassenger(Entity target, Entity entity) { Queue queue = new LinkedList<>(); diff --git a/src/main/java/top/r3944realms/lib39/util/shape/Quaternions.java b/src/main/java/top/r3944realms/lib39/util/shape/Quaternions.java index e9c1fd7..9b12763 100644 --- a/src/main/java/top/r3944realms/lib39/util/shape/Quaternions.java +++ b/src/main/java/top/r3944realms/lib39/util/shape/Quaternions.java @@ -4,16 +4,43 @@ package top.r3944realms.lib39.util.shape; import com.mojang.math.Axis; import org.joml.Quaternionf; +/** + * The type Quaternions. + */ public final class Quaternions { + /** + * The constant XP_90. + */ public static final Quaternionf XP_90 = Axis.XP.rotationDegrees(90); + /** + * The constant XP_180. + */ public static final Quaternionf XP_180 = Axis.XP.rotationDegrees(180); + /** + * The constant XN_90. + */ public static final Quaternionf XN_90 = Axis.XN.rotationDegrees(90); + /** + * The constant YP_90. + */ public static final Quaternionf YP_90 = Axis.YP.rotationDegrees(90); + /** + * The constant YN_90. + */ public static final Quaternionf YN_90 = Axis.YN.rotationDegrees(90); + /** + * The constant ZP_90. + */ public static final Quaternionf ZP_90 = Axis.ZP.rotationDegrees(90); + /** + * The constant ZP_180. + */ public static final Quaternionf ZP_180 = Axis.ZP.rotationDegrees(180); + /** + * The constant ZN_90. + */ public static final Quaternionf ZN_90 = Axis.ZN.rotationDegrees(90); diff --git a/src/main/java/top/r3944realms/lib39/util/shape/ShapeUtil.java b/src/main/java/top/r3944realms/lib39/util/shape/ShapeUtil.java index fe3a5db..6531549 100644 --- a/src/main/java/top/r3944realms/lib39/util/shape/ShapeUtil.java +++ b/src/main/java/top/r3944realms/lib39/util/shape/ShapeUtil.java @@ -4,10 +4,14 @@ import net.minecraft.core.Direction; import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.*; +/** + * The type Shape util. + */ @SuppressWarnings("unused") public class ShapeUtil { @@ -15,6 +19,14 @@ public class ShapeUtil { /** * 创建基于像素的碰撞箱(将像素坐标转换为方块坐标) + * + * @param minX the min x + * @param minY the min y + * @param minZ the min z + * @param maxX the max x + * @param maxY the max y + * @param maxZ the max z + * @return the voxel shape */ public static @NotNull VoxelShape createPixelBasedShape(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { @@ -24,6 +36,14 @@ public class ShapeUtil { /** * 便捷方法:创建方块碰撞箱 + * + * @param minX the min x + * @param minY the min y + * @param minZ the min z + * @param maxX the max x + * @param maxY the max y + * @param maxZ the max z + * @return the voxel shape */ public static @NotNull VoxelShape createBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { @@ -34,15 +54,22 @@ public class ShapeUtil { /** * 创建单一形状的方向映射 + * + * @param shape the shape + * @return the map */ - public static Map createUniformDirectionMap(VoxelShape shape) { + public static @NotNull Map createUniformDirectionMap(VoxelShape shape) { return createRotatedDirectionMap(shape); } /** * 创建原版双方块的形状映射 + * + * @param lowerShape the lower shape + * @param upperShape the upper shape + * @return the map */ - public static Map> createDoubleBlockShapeMap(VoxelShape lowerShape, VoxelShape upperShape) { + public static @NotNull Map> createDoubleBlockShapeMap(VoxelShape lowerShape, VoxelShape upperShape) { EnumMap> shapeMap = new EnumMap<>(DoubleBlockHalf.class); shapeMap.put(DoubleBlockHalf.LOWER, createRotatedDirectionMap(lowerShape)); shapeMap.put(DoubleBlockHalf.UPPER, createRotatedDirectionMap(upperShape)); @@ -53,6 +80,9 @@ public class ShapeUtil { /** * 顺时针旋转碰撞箱(Y轴旋转) + * + * @param shape the shape + * @return the voxel shape */ public static @NotNull VoxelShape rotateVoxelShapeClockwise(@NotNull VoxelShape shape) { final List generatedShapes = new ArrayList<>(); @@ -65,6 +95,9 @@ public class ShapeUtil { /** * 绕X轴旋转碰撞箱 + * + * @param shape the shape + * @return the voxel shape */ public static @NotNull VoxelShape rotateVoxelShapeXAxis(@NotNull VoxelShape shape) { final List generatedShapes = new ArrayList<>(); @@ -77,6 +110,9 @@ public class ShapeUtil { /** * 绕Z轴旋转碰撞箱 + * + * @param shape the shape + * @return the voxel shape */ @SuppressWarnings("SuspiciousNameCombination") public static @NotNull VoxelShape rotateVoxelShapeZAxis(@NotNull VoxelShape shape) { @@ -90,6 +126,10 @@ public class ShapeUtil { /** * 按指定角度旋转碰撞箱 + * + * @param shape the shape + * @param degrees the degrees + * @return the voxel shape */ public static @NotNull VoxelShape rotateShape(@NotNull VoxelShape shape, int degrees) { int rotations = (degrees / 90) % 4; @@ -107,7 +147,7 @@ public class ShapeUtil { * 组合多个形状列表 */ @NotNull - private static VoxelShape combineShapes(List shapes) { + private static VoxelShape combineShapes(@NotNull List shapes) { if (shapes.isEmpty()) { return Shapes.block(); } @@ -122,6 +162,9 @@ public class ShapeUtil { /** * 组合多个形状 + * + * @param shapes the shapes + * @return the voxel shape */ public static @NotNull VoxelShape combineShapes(VoxelShape... shapes) { return combineShapes(Arrays.asList(shapes)); @@ -132,7 +175,7 @@ public class ShapeUtil { /** * 创建旋转方向映射 */ - private static Map createRotatedDirectionMap(VoxelShape baseShape) { + private static @NotNull Map createRotatedDirectionMap(VoxelShape baseShape) { EnumMap directionMap = new EnumMap<>(Direction.class); directionMap.put(Direction.NORTH, baseShape); directionMap.put(Direction.EAST, rotateShape(baseShape, 90)); @@ -150,23 +193,56 @@ public class ShapeUtil { public static class ShapeBuilder { private final List shapes = new ArrayList<>(); + /** + * Add pixel box shape builder. + * + * @param minX the min x + * @param minY the min y + * @param minZ the min z + * @param maxX the max x + * @param maxY the max y + * @param maxZ the max z + * @return the shape builder + */ public ShapeBuilder addPixelBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { shapes.add(createPixelBasedShape(minX, minY, minZ, maxX, maxY, maxZ)); return this; } + /** + * Add box shape builder. + * + * @param minX the min x + * @param minY the min y + * @param minZ the min z + * @param maxX the max x + * @param maxY the max y + * @param maxZ the max z + * @return the shape builder + */ public ShapeBuilder addBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { shapes.add(createBox(minX, minY, minZ, maxX, maxY, maxZ)); return this; } + /** + * Add shape shape builder. + * + * @param shape the shape + * @return the shape builder + */ public ShapeBuilder addShape(VoxelShape shape) { shapes.add(shape); return this; } + /** + * Build voxel shape. + * + * @return the voxel shape + */ public VoxelShape build() { return combineShapes(shapes); } @@ -174,8 +250,11 @@ public class ShapeUtil { /** * 创建形状构建器 + * + * @return the shape builder */ - public static ShapeBuilder builder() { + @Contract(" -> new") + public static @NotNull ShapeBuilder builder() { return new ShapeBuilder(); } } \ No newline at end of file diff --git a/src/main/java/top/r3944realms/lib39/util/sound/SoundUtil.java b/src/main/java/top/r3944realms/lib39/util/sound/SoundUtil.java index 3ec905d..2fb4395 100644 --- a/src/main/java/top/r3944realms/lib39/util/sound/SoundUtil.java +++ b/src/main/java/top/r3944realms/lib39/util/sound/SoundUtil.java @@ -3,12 +3,22 @@ package top.r3944realms.lib39.util.sound; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundSource; import net.minecraft.world.entity.LivingEntity; +import org.jetbrains.annotations.NotNull; +/** + * The type Sound util. + */ public class SoundUtil { /** * 为实体播放声音 + * + * @param entity the entity + * @param soundEvent the sound event + * @param soundCategory the sound category + * @param volume the volume + * @param pitch the pitch */ - public static void playSoundForEntity(LivingEntity entity, SoundEvent soundEvent, SoundSource soundCategory, float volume, float pitch) { + public static void playSoundForEntity(@NotNull LivingEntity entity, SoundEvent soundEvent, SoundSource soundCategory, float volume, float pitch) { entity.level().playSound(null, entity.getX(), entity.getY(), entity.getZ(), soundEvent, soundCategory, volume, pitch); } }