Compare commits

..

6 Commits

Author SHA1 Message Date
9118626f0f fix:移除错误的包引入导致的编译错误 2026-05-27 23:28:57 +08:00
7f117eca3e build:提升版本号 2026-05-27 23:26:53 +08:00
cc1a4153e0 fix:修复 Components not bound yet问题 2026-05-27 23:21:33 +08:00
MasatoNakajima20
4d2b856553 Bugfix release 3.0.1 for Minecraft 26.1.2
- Fixed crash on startup (Components not bound yet) caused by InventoryMixin
  creating an ItemStack as a static field before data components were
  initialized. Replaced with lazy creation via method call.
2026-05-08 07:19:57 +08:00
MasatoNakajima20
dc24c2c39a Fix crash: defer ItemStack creation in InventoryMixin to avoid premature class init 2026-05-08 07:18:22 +08:00
MasatoNakajima20
983ee89eda Port CarryOn to Minecraft 26.1.2 (version 3.0.0) 2026-05-08 06:58:11 +08:00
18 changed files with 84 additions and 227 deletions

View File

@ -19,10 +19,6 @@ neoForge {
if (at.exists()) {
accessTransformers.from(at.absolutePath)
}
parchment {
minecraftVersion = parchment_game_version
mappingsVersion = parchment_version
}
}
dependencies {
@ -48,4 +44,4 @@ configurations {
artifacts {
commonJava sourceSets.main.java.sourceDirectories.singleFile
commonResources sourceSets.main.resources.sourceDirectories.singleFile
}
}

View File

@ -26,14 +26,15 @@ import com.mojang.datafixers.util.Either;
import com.mojang.serialization.DataResult;
import net.minecraft.commands.arguments.blocks.BlockStateParser;
import net.minecraft.commands.arguments.blocks.BlockStateParser.BlockResult;
import net.minecraft.commands.arguments.item.ItemInput;
import net.minecraft.commands.arguments.item.ItemParser;
import net.minecraft.commands.arguments.item.ItemParser.ItemResult;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.Property;
import tschipp.carryon.Constants;
import tschipp.carryon.common.scripting.Matchables.NBTCondition;
import javax.annotation.Nullable;
@ -42,22 +43,40 @@ import java.util.Map;
public class ModelOverride {
private BlockResult parsedBlock;
private Either<ItemStack, BlockState> renderObject;
private Either<ItemInput, BlockResult> parsedRHS; // 保存原始数据
private boolean initialized = false;
private ModelOverride(String raw, BlockResult parsedBlock, Type type, Either<ItemResult, BlockResult> parsedRHS)
private ModelOverride(String raw, BlockResult parsedBlock, Type type, Either<ItemInput, BlockResult> parsedRHS)
{
this.parsedBlock = parsedBlock;
this.parsedRHS = parsedRHS;
// 延迟创建renderObject
this.renderObject = null;
}
// 延迟初始化方法
private void ensureInitialized() {
if (initialized) return;
parsedRHS.ifLeft(res -> {
ItemStack stack = new ItemStack(res.item());
if(res.components() != null)
stack.applyComponents(res.components());
this.renderObject = Either.left(stack);
try {
ItemStack stack = new ItemStack(res.item());
if(res.components() != null)
stack.applyComponents(res.components());
this.renderObject = Either.left(stack);
} catch (NullPointerException e) {
this.renderObject = Either.left(ItemStack.EMPTY);
Constants.LOG.warn("Delayed init failed for item: {}", res.item().getRegisteredName());
}
});
parsedRHS.ifRight(res -> {
BlockState state = res.blockState();
this.renderObject = Either.right(state);
});
initialized = true;
}
public static DataResult<ModelOverride> of(String str, HolderLookup.Provider provider)
@ -86,7 +105,7 @@ public class ModelOverride {
to = to.substring(to.indexOf(")") + 1);
}
Either<ItemResult, BlockResult> either;
Either<ItemInput, BlockResult> either;
try {
if(type == Type.ITEM)
either = Either.left(new ItemParser(provider).parse(new StringReader(to)));
@ -114,6 +133,7 @@ public class ModelOverride {
public Either<ItemStack, BlockState> getRenderObject()
{
ensureInitialized();
return this.renderObject;
}

View File

@ -26,8 +26,7 @@ import net.minecraft.client.renderer.SubmitNodeCollector;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.client.renderer.entity.state.EntityRenderState;
import net.minecraft.client.renderer.item.ItemStackRenderState;
import net.minecraft.client.renderer.rendertype.RenderTypes;
import net.minecraft.client.renderer.state.CameraRenderState;
import net.minecraft.client.renderer.state.level.CameraRenderState;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.HumanoidArm;
@ -79,8 +78,6 @@ public class CarriedObjectRender
{
CarryOnData carry = CarryOnDataManager.getCarryData(player);
ItemStackRenderState renderState = new ItemStackRenderState();
var layer = renderState.newLayer();
layer.setRenderType(RenderTypes.glint());
matrix.pushPose();

View File

@ -98,7 +98,7 @@ public class ListHandler {
if(regular.contains(name))
return true;
for(TagKey<EntityType<?>> tag : tags)
if(entity.getType().is(tag))
if(entity.getType().builtInRegistryHolder().is(tag))
return true;
return false;
}

View File

@ -40,7 +40,9 @@ import tschipp.carryon.common.carry.CarryOnDataManager;
public class InventoryMixin
{
@Unique
private static final ItemStack DUMMY_STACK = new ItemStack(Blocks.COBBLESTONE, 1);
private static ItemStack getDummyStack() {
return new ItemStack(Blocks.COBBLESTONE, 1);
}
@Shadow
public Player player;
@ -56,7 +58,7 @@ public class InventoryMixin
{
if(slot == selected && CarryOnDataManager.getCarryData(player).isCarrying())
{
return DUMMY_STACK;
return getDummyStack();
}
else
return original.call(instance, slot);

View File

@ -2,7 +2,7 @@
"required": true,
"minVersion": "0.8",
"package": "tschipp.carryon.mixin",
"compatibilityLevel": "JAVA_21",
"compatibilityLevel": "JAVA_25",
"mixins": [
"EntityMixin",
"InventoryMixin",

View File

@ -1,6 +1,6 @@
plugins {
id 'multiloader-loader'
id 'fabric-loom' version "${loom_version}"
id 'net.fabricmc.fabric-loom' version "${loom_version}"
}
repositories {
@ -21,18 +21,14 @@ repositories {
dependencies {
minecraft "com.mojang:minecraft:${minecraft_version}"
mappings loom.layered() {
officialMojangMappings()
parchment("org.parchmentmc.data:parchment-${parchment_mappings_fabric}@zip")
}
modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}"
implementation "net.fabricmc:fabric-loader:${fabric_loader_version}"
implementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}"
implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1'
modApi("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}") {
compileOnly("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}") {
exclude(group: "net.fabricmc.fabric-api")
}
modApi "com.terraformersmc:modmenu:17.0.0-beta.1"
compileOnly "com.terraformersmc:modmenu:18.0.0-alpha.8"
}
loom {

View File

@ -21,7 +21,7 @@
package tschipp.carryon;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.client.keymapping.v1.KeyMappingHelper;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.world.entity.player.Player;
@ -36,7 +36,7 @@ public class CarryOnFabricClientMod implements ClientModInitializer
@Override
public void onInitializeClient()
{
CarryOnKeybinds.registerKeybinds(KeyBindingHelper::registerKeyBinding);
CarryOnKeybinds.registerKeybinds(KeyMappingHelper::registerKeyMapping);
ClientEvents.registerEvents();
CarryOnCommon.registerClientPackets(true);
}

View File

@ -68,7 +68,7 @@ public class FabricPlatformHelper implements IPlatformHelper {
@Override
public <T extends PacketBase, B extends FriendlyByteBuf> void registerServerboundPacket(CustomPacketPayload.Type<T> type, Class<T> clazz, StreamCodec<B, T> codec, BiConsumer<T, Player> handler, Object... args)
{
PayloadTypeRegistry.playC2S().register(type, (StreamCodec<RegistryFriendlyByteBuf, T>)codec);
PayloadTypeRegistry.serverboundPlay().register(type, (StreamCodec<RegistryFriendlyByteBuf, T>)codec);
ServerPlayNetworking.registerGlobalReceiver(type, (T packet, ServerPlayNetworking.Context context) -> {
context.server().execute(() -> {
@ -84,7 +84,7 @@ public class FabricPlatformHelper implements IPlatformHelper {
boolean client = (boolean)args[0];
if(!client)
PayloadTypeRegistry.playS2C().register(type, (StreamCodec<RegistryFriendlyByteBuf, T>)codec);
PayloadTypeRegistry.clientboundPlay().register(type, (StreamCodec<RegistryFriendlyByteBuf, T>)codec);
else
CarryOnFabricClientMod.registerClientboundPacket(type, handler);
}

View File

@ -2,7 +2,7 @@
"required": true,
"minVersion": "0.8",
"package": "tschipp.carryon.mixin",
"compatibilityLevel": "JAVA_21",
"compatibilityLevel": "JAVA_25",
"mixins": [
"PlayerMixinFabric"
],

View File

@ -19,14 +19,10 @@ neoForge {
if (at.exists()) {
accessTransformers.from(at.absolutePath)
}
parchment {
minecraftVersion = parchment_game_version
mappingsVersion = parchment_version
}
runs {
configureEach {
systemProperty('neoforge.enabledGameTestNamespaces', mod_id)
ideName = "NeoForge ${it.name.capitalize()} (${project.path})" // Unify the run config names with fabric
ideName = "NeoForge ${it.name.capitalize()} (${project.path})"
}
client {
client()
@ -51,124 +47,3 @@ dependencies {
}
sourceSets.main.resources { srcDir 'src/generated/resources' }
//plugins {
// id 'idea'
// id 'maven-publish'
// id 'net.neoforged.gradle.userdev' version '7.0.168'
// id 'java-library'
//}
//
//
//if (System.getenv('BUILD_NUMBER') != null) {
// version += "." + System.getenv('BUILD_NUMBER')
//}
//
//base {
// archivesName = "${mod_id}-neoforge-${minecraft_version}"
//}
//
////jarJar.enable()
//
////archivesBaseName = "${mod_id}-neoforge-${minecraft_version}"
//
///*
//mixin {
// add sourceSets.main, "${mod_id}.refmap.json"
//
// config "${mod_id}.mixins.json"
// config "${mod_id}.forge.mixins.json"
//}
//*/
//
//if (file('src/main/resources/META-INF/accesstransformer.cfg').exists()) {
// minecraft.accessTransformers.file file('src/main/resources/META-INF/accesstransformer.cfg')
//}
//
//runs {
// // applies to all the run configs below
// configureEach {
// systemProperty 'forge.logging.markers', 'REGISTRIES'
// systemProperty 'forge.logging.console.level', 'debug'
// modSource project.sourceSets.main
// }
//
// client {
// // Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
// systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
// }
//
// server {
// systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
// programArgument '--nogui'
// }
//
// // 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 {
// systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
// }
//
// /*
// data {
// // example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
// // workingDirectory 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()
// }*/
//}
//
//sourceSets.main.resources { srcDir 'src/generated/resources' }
//
//configurations {
// runtimeClasspath.extendsFrom localRuntime
//}
//
//
//tasks.named("test").configure {
// enabled = false
//}
//
//dependencies {
// implementation "net.neoforged:neoforge:${neoforge_version}"
// compileOnly project(":Common")
//
// api "me.shedaniel.cloth:cloth-config-neoforge:${cloth_config_version}"
// //implementation fg.deobf("net.darkhax.gamestages:GameStages-Forge-1.19.2:11.0.2")
// //implementation fg.deobf("net.darkhax.bookshelf:Bookshelf-Forge-1.19.3:17.0.2")
//}
//
//// NeoGradle compiles the game, but we don't want to add our common code to the game's code
//Spec<Task> notNeoTask = { Task it -> !it.name.startsWith("neo") } as Spec<Task>
//
//tasks.withType(JavaCompile).matching(notNeoTask).configureEach {
// source(project(":Common").sourceSets.main.allSource)
//}
//
//tasks.withType(Javadoc).matching(notNeoTask).configureEach {
// source(project(":Common").sourceSets.main.allJava)
//}
//
//tasks.named("sourcesJar", Jar) {
// from(project(":Common").sourceSets.main.allSource)
//}
//
//tasks.withType(ProcessResources).matching(notNeoTask).configureEach {
// from project(":Common").sourceSets.main.resources
//}
//
//publishing {
// publications {
// mavenJava(MavenPublication) {
// artifactId base.archivesName.get()
// from components.java
// }
// }
// repositories {
// maven {
// url "file://" + System.getenv("local_maven")
// }
// }
//}

View File

@ -46,6 +46,7 @@ import net.neoforged.neoforge.event.entity.player.AttackEntityEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
import net.neoforged.neoforge.event.level.BlockEvent;
import net.neoforged.neoforge.event.level.block.BreakBlockEvent;
import net.neoforged.neoforge.event.tick.ServerTickEvent;
import tschipp.carryon.CarryOnCommon;
import tschipp.carryon.Constants;
@ -78,7 +79,7 @@ public class CommonEvents
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if (!carry.isCarrying()) {
if (PickupHandler.tryPickUpBlock((ServerPlayer) player, pos, level, (pState, pPos) -> {
BlockEvent.BreakEvent breakEvent = new BlockEvent.BreakEvent(level, pPos, pState, player);
BreakBlockEvent breakEvent = new BreakBlockEvent(level, pPos, pState, player);
NeoForge.EVENT_BUS.post(breakEvent);
return !breakEvent.isCanceled();
})) {
@ -201,7 +202,7 @@ public class CommonEvents
}
@SubscribeEvent
public static void onBreakBlock(BlockEvent.BreakEvent event)
public static void onBreakBlock(BreakBlockEvent event)
{
if (!CarryOnCommon.onTryBreakBlock(event.getPlayer())) {
event.setCanceled(true);

View File

@ -2,7 +2,7 @@
"required": true,
"minVersion": "0.8",
"package": "tschipp.carryon.mixin",
"compatibilityLevel": "JAVA_21",
"compatibilityLevel": "JAVA_25",
"mixins": [
],
"client": [

View File

@ -1,6 +1,6 @@
plugins {
// see https://fabricmc.net/develop/ for new versions
id 'fabric-loom' version "${loom_version}" apply false
id 'net.fabricmc.fabric-loom' version "${loom_version}" apply false
// see https://projects.neoforged.net/neoforged/moddevgradle for new versions
id 'net.neoforged.moddev' version "${mod_dev_version}" apply false
}
}

View File

@ -25,18 +25,9 @@ repositories {
}
filter { includeGroupAndSubgroups('org.spongepowered') }
}
exclusiveContent {
forRepositories(
maven {
name = 'ParchmentMC'
url = 'https://maven.parchmentmc.org/'
},
maven {
name = "NeoForge"
url = 'https://maven.neoforged.net/releases'
}
)
filter { includeGroup('org.parchmentmc.data') }
maven {
name = "NeoForge"
url = 'https://maven.neoforged.net/releases'
}
maven {
name = 'BlameJared'
@ -97,8 +88,6 @@ processResources {
'description' : project.description,
'neoforge_version' : neoforge_version,
'neoforge_loader_version_range': neoforge_loader_version_range,
"forge_version": forge_version,
"forge_loader_version_range": forge_loader_version_range,
'credits' : credits,
'java_version' : java_version,
'minecraft_version_range_fabric' : minecraft_version_range_fabric,
@ -127,8 +116,18 @@ publishing {
}
}
repositories {
maven {
name = 'local'
url = layout.buildDirectory.dir("repo")
}
maven {
url System.getenv('local_maven_url')
name = 'LTDNexus'
url = 'https://nexus.bot.leisuretimedock.top/repository/maven-releases/'
credentials {
username = System.getenv('LTDNexusUsername') ?: ''
password = System.getenv('LTDNexusPassword') ?: ''
}
}
}
}

View File

@ -1,44 +1,33 @@
# Project
version=2.9.1
version=3.0.2
group=tschipp.carryon
# Common
minecraft_version=1.21.11
minecraft_version=26.1.2
mod_name=Carry On
mod_author=Tschipp, PurpliciousCow
mod_id=carryon
license=GNU LGPLv3
credits=
description=Carry On is a simple mod that improves game interaction by allowing players to pick up, carry, and place single block Tile Entities using only their empty hands.
minecraft_version_range=[1.21.11, 26)
minecraft_version_range_fabric=>=1.21.11 <26
neo_form_version=1.21.11-20251209.172050
java_version=21
parchment_version=2025.12.20
parchment_game_version=1.21.11
mod_dev_version=2.0.134
# Forge
forge_version=61.0.3
forge_loader_version_range=[61,)
parchment_mappings=2025.12.20-1.21.11
//forge_ats_enabled=true
minecraft_version_range=[26.1, 27)
minecraft_version_range_fabric=>=26.1 <27
neo_form_version=26.1.2-1
java_version=25
mod_dev_version=2.0.141
# Fabric
fabric_version=0.140.2+1.21.11
fabric_version=0.148.0+26.1.2
fabric_loader_version=0.18.4
parchment_mappings_fabric=1.21.11:2025.12.20
loom_version=1.13-SNAPSHOT
loom_version=1.15.5
# Neoforge
neoforge_version=21.11.14-beta
neoforge_version=26.1.2.43-beta
neoforge_loader_version_range=[4,)
neogradle.subsystems.parchment.minecraftVersion=1.21.11
neogradle.subsystems.parchment.mappingsVersion=2025.12.20
# Gradle
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false
mixinextras_version=0.5.0
cloth_config_version=20.0.148
cloth_config_version=26.1.154

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@ -3,19 +3,9 @@ pluginManagement {
gradlePluginPortal()
mavenLocal()
mavenCentral()
exclusiveContent {
forRepository {
maven {
name = 'Fabric'
url = uri('https://maven.fabricmc.net')
}
}
filter {
includeGroup('net.fabricmc')
includeGroup('net.fabricmc.unpick')
includeGroup('fabric-loom')
includeGroup('net.fabricmc.unpick')
}
maven {
name = 'Fabric'
url = uri('https://maven.fabricmc.net')
}
exclusiveContent {
forRepository {
@ -31,21 +21,14 @@ pluginManagement {
exclusiveContent {
forRepository {
maven {
name = 'Forge'
url = uri('https://maven.minecraftforge.net')
name = 'NeoForged'
url = 'https://maven.neoforged.net/releases'
}
}
filter {
includeGroupAndSubgroups('net.minecraftforge')
includeGroupAndSubgroups("net.neoforged")
}
}
maven {
name = 'ParchmentMC'
url = 'https://maven.parchmentmc.org'
}
}
}
@ -60,5 +43,4 @@ if (System.getenv('BUILD_NUMBER') != null) {
}
rootProject.name = 'CarryOn'
//include("Common", "Fabric", "NeoForge")
include("Common", "Fabric", "Forge", "NeoForge")
include("Common", "Fabric", "NeoForge")