mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-01 06:03:00 +00:00
Merge branch 'mc-1.19.x' into mc-1.20.x
This commit is contained in:
@@ -21,15 +21,25 @@ cct {
|
||||
}
|
||||
|
||||
fun addRemappedConfiguration(name: String) {
|
||||
// There was a regression in Loom 1.1 which means that targetConfigurationName doesn't do anything, and remap
|
||||
// configurations just get added to the main source set (https://github.com/FabricMC/fabric-loom/issues/843).
|
||||
// To get around that, we create our own source set and register a remap configuration with that. This does
|
||||
// introduce a bit of noise, but it's not the end of the world.
|
||||
val ourSourceSet = sourceSets.register(name) {
|
||||
// Try to make this source set as much of a non-entity as possible.
|
||||
listOf(allSource, java, resources, kotlin).forEach { it.setSrcDirs(emptyList<File>()) }
|
||||
}
|
||||
val capitalName = name.replaceFirstChar { it.titlecase(Locale.ROOT) }
|
||||
loom.addRemapConfiguration("mod$capitalName") {
|
||||
onCompileClasspath.set(false)
|
||||
onRuntimeClasspath.set(true)
|
||||
sourceSet.set(ourSourceSet)
|
||||
targetConfigurationName.set(name)
|
||||
}
|
||||
configurations.create(name) {
|
||||
isCanBeConsumed = false
|
||||
isCanBeResolved = true
|
||||
}
|
||||
val capitalName = name.capitalize(Locale.ROOT)
|
||||
loom.addRemapConfiguration("mod$capitalName") {
|
||||
onCompileClasspath.set(false)
|
||||
onRuntimeClasspath.set(false)
|
||||
targetConfigurationName.set(name)
|
||||
extendsFrom(configurations["${name}RuntimeClasspath"])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,10 @@ public class CompositeBakedModel extends CustomBakedModel {
|
||||
this.models = models;
|
||||
}
|
||||
|
||||
public static BakedModel of(List<BakedModel> models) {
|
||||
return models.size() == 1 ? models.get(0) : new CompositeBakedModel(models);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState blockState, @Nullable Direction face, RandomSource rand) {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
|
||||
@@ -14,8 +14,6 @@ import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The custom model for turtle items, which renders tools and overlays as part of the model.
|
||||
@@ -23,28 +21,22 @@ import java.util.Map;
|
||||
* @see TurtleModelParts
|
||||
*/
|
||||
public class TurtleModel extends ForwardingBakedModel {
|
||||
private final TurtleModelParts parts;
|
||||
private final TurtleModelParts<BakedModel> parts;
|
||||
|
||||
private final Map<TurtleModelParts.Combination, BakedModel> cachedModels = new HashMap<>();
|
||||
private final ItemOverrides overrides = new ItemOverrides() {
|
||||
@Override
|
||||
public BakedModel resolve(BakedModel model, ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) {
|
||||
return cachedModels.computeIfAbsent(parts.getCombination(stack), TurtleModel.this::buildModel);
|
||||
return parts.getModel(stack);
|
||||
}
|
||||
};
|
||||
|
||||
public TurtleModel(BakedModel familyModel, BakedModel colourModel) {
|
||||
wrapped = familyModel;
|
||||
parts = new TurtleModelParts(familyModel, colourModel, TransformedBakedModel::new);
|
||||
parts = new TurtleModelParts<>(familyModel, colourModel, TransformedBakedModel::new, CompositeBakedModel::of);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrides getOverrides() {
|
||||
return overrides;
|
||||
}
|
||||
|
||||
private BakedModel buildModel(TurtleModelParts.Combination combo) {
|
||||
var models = parts.buildModel(combo);
|
||||
return models.size() == 1 ? models.get(0) : new CompositeBakedModel(models);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
"gui.computercraft.config.http.bandwidth.global_upload.tooltip": "The number of bytes which can be uploaded in a second. This is shared across all computers. (bytes/s).\nRange: > 1",
|
||||
"gui.computercraft.config.http.bandwidth.tooltip": "Limits bandwidth used by computers.",
|
||||
"gui.computercraft.config.http.enabled": "Enable the HTTP API",
|
||||
"gui.computercraft.config.http.enabled.tooltip": "Enable the \"http\" API on Computers. This also disables the \"pastebin\" and \"wget\"\nprograms, that many users rely on. It's recommended to leave this on and use the\n\"rules\" config option to impose more fine-grained control.",
|
||||
"gui.computercraft.config.http.enabled.tooltip": "Enable the \"http\" API on Computers. Disabling this also disables the \"pastebin\" and\n\"wget\" programs, that many users rely on. It's recommended to leave this on and use\nthe \"rules\" config option to impose more fine-grained control.",
|
||||
"gui.computercraft.config.http.max_requests": "Maximum concurrent requests",
|
||||
"gui.computercraft.config.http.max_requests.tooltip": "The number of http requests a computer can make at one time. Additional requests\nwill be queued, and sent when the running requests have finished. Set to 0 for\nunlimited.\nRange: > 0",
|
||||
"gui.computercraft.config.http.max_websockets": "Maximum concurrent websockets",
|
||||
@@ -113,7 +113,7 @@
|
||||
"gui.computercraft.config.http.proxy.type": "Proxy type",
|
||||
"gui.computercraft.config.http.proxy.type.tooltip": "The type of proxy to use.\nAllowed Values: HTTP, HTTPS, SOCKS4, SOCKS5",
|
||||
"gui.computercraft.config.http.rules": "Allow/deny rules",
|
||||
"gui.computercraft.config.http.rules.tooltip": "A list of rules which control behaviour of the \"http\" API for specific domains or\nIPs. Each rule is an item with a 'host' to match against, and a series of\nproperties. Rules are evaluated in order, meaning earlier rules override later\nones.\nThe host may be a domain name (\"pastebin.com\"), wildcard (\"*.pastebin.com\") or\nCIDR notation (\"127.0.0.0/8\").\nIf no rules, the domain is blocked.",
|
||||
"gui.computercraft.config.http.rules.tooltip": "A list of rules which control behaviour of the \"http\" API for specific domains or\nIPs. Each rule matches against a hostname and an optional port, and then sets several\nproperties for the request. Rules are evaluated in order, meaning earlier rules override\nlater ones.\n\nValid properties:\n - \"host\" (required): The domain or IP address this rule matches. This may be a domain name\n (\"pastebin.com\"), wildcard (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\").\n - \"port\" (optional): Only match requests for a specific port, such as 80 or 443.\n\n - \"action\" (optional): Whether to allow or deny this request.\n - \"max_download\" (optional): The maximum size (in bytes) that a computer can download in this\n request.\n - \"max_upload\" (optional): The maximum size (in bytes) that a computer can upload in a this request.\n - \"max_websocket_message\" (optional): The maximum size (in bytes) that a computer can send or\n receive in one websocket packet.\n - \"use_proxy\" (optional): Enable use of the HTTP/SOCKS proxy if it is configured.",
|
||||
"gui.computercraft.config.http.tooltip": "Controls the HTTP API",
|
||||
"gui.computercraft.config.http.websocket_enabled": "Enable websockets",
|
||||
"gui.computercraft.config.http.websocket_enabled.tooltip": "Enable use of http websockets. This requires the \"http_enable\" option to also be true.",
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.mixin;
|
||||
|
||||
import dan200.computercraft.shared.platform.FakePlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.Constant;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyConstant;
|
||||
|
||||
@Mixin(Item.class)
|
||||
class ItemMixin {
|
||||
/**
|
||||
* Replace the reach distance in {@link Item#getPlayerPOVHitResult(Level, Player, ClipContext.Fluid)}.
|
||||
*
|
||||
* @param reach The original reach distance.
|
||||
* @param level The current level.
|
||||
* @param player The current player.
|
||||
* @return The new reach distance.
|
||||
* @see FakePlayer#getBlockReach()
|
||||
*/
|
||||
@ModifyConstant(method = "getPlayerPOVHitResult", constant = @Constant(doubleValue = 5))
|
||||
@SuppressWarnings("UnusedMethod")
|
||||
private static double getReachDistance(double reach, Level level, Player player) {
|
||||
return player instanceof FakePlayer fp ? fp.getBlockReach() : reach;
|
||||
}
|
||||
}
|
||||
@@ -5,22 +5,21 @@
|
||||
package dan200.computercraft.shared.peripheral.generic;
|
||||
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.asm.NamedMethod;
|
||||
import dan200.computercraft.core.asm.PeripheralMethod;
|
||||
import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class GenericPeripheralProvider {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GenericPeripheralProvider.class);
|
||||
|
||||
interface Lookup<T> {
|
||||
@Nullable
|
||||
T find(Level world, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, Direction context);
|
||||
@@ -31,53 +30,23 @@ public class GenericPeripheralProvider {
|
||||
);
|
||||
|
||||
@Nullable
|
||||
public static IPeripheral getPeripheral(Level world, BlockPos pos, Direction side, @Nullable BlockEntity blockEntity) {
|
||||
public static IPeripheral getPeripheral(Level level, BlockPos pos, Direction side, @Nullable BlockEntity blockEntity) {
|
||||
if (blockEntity == null) return null;
|
||||
|
||||
var saturated = new GenericPeripheralBuilder();
|
||||
var server = level.getServer();
|
||||
if (server == null) {
|
||||
LOG.warn("Fetching peripherals on a non-server level {}.", level, new IllegalStateException("Fetching peripherals on a non-server level."));
|
||||
return null;
|
||||
}
|
||||
|
||||
var tileMethods = PeripheralMethod.GENERATOR.getMethods(blockEntity.getClass());
|
||||
if (!tileMethods.isEmpty()) saturated.addMethods(blockEntity, tileMethods);
|
||||
var builder = new GenericPeripheralBuilder(server);
|
||||
builder.addMethods(blockEntity);
|
||||
|
||||
for (var lookup : lookups) {
|
||||
var contents = lookup.find(world, pos, blockEntity.getBlockState(), blockEntity, side);
|
||||
if (contents == null) continue;
|
||||
|
||||
var methods = PeripheralMethod.GENERATOR.getMethods(contents.getClass());
|
||||
if (!methods.isEmpty()) saturated.addMethods(contents, methods);
|
||||
var contents = lookup.find(level, pos, blockEntity.getBlockState(), blockEntity, side);
|
||||
if (contents != null) builder.addMethods(contents);
|
||||
}
|
||||
|
||||
return saturated.toPeripheral(blockEntity);
|
||||
}
|
||||
|
||||
private static class GenericPeripheralBuilder {
|
||||
private @Nullable String name;
|
||||
private final Set<String> additionalTypes = new HashSet<>(0);
|
||||
private final ArrayList<SaturatedMethod> methods = new ArrayList<>(0);
|
||||
|
||||
@Nullable
|
||||
IPeripheral toPeripheral(BlockEntity tile) {
|
||||
if (methods.isEmpty()) return null;
|
||||
|
||||
methods.trimToSize();
|
||||
return new GenericPeripheral(tile, name, additionalTypes, methods);
|
||||
}
|
||||
|
||||
void addMethods(Object target, List<NamedMethod<PeripheralMethod>> methods) {
|
||||
var saturatedMethods = this.methods;
|
||||
saturatedMethods.ensureCapacity(saturatedMethods.size() + methods.size());
|
||||
for (var method : methods) {
|
||||
saturatedMethods.add(new SaturatedMethod(target, method));
|
||||
|
||||
// If we have a peripheral type, use it. Always pick the smallest one, so it's consistent (assuming mods
|
||||
// don't change).
|
||||
var type = method.getGenericType();
|
||||
if (type != null && type.getPrimaryType() != null) {
|
||||
var name = type.getPrimaryType();
|
||||
if (this.name == null || this.name.compareTo(name) > 0) this.name = name;
|
||||
}
|
||||
if (type != null) additionalTypes.addAll(type.getAdditionalTypes());
|
||||
}
|
||||
}
|
||||
return builder.toPeripheral(blockEntity, side);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.shared.peripheral.generic;
|
||||
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class SidedGenericPeripheral extends GenericPeripheral {
|
||||
private final Direction direction;
|
||||
|
||||
SidedGenericPeripheral(BlockEntity tile, Direction direction, @Nullable String name, Set<String> additionalTypes, List<SaturatedMethod> methods) {
|
||||
super(tile, name, additionalTypes, methods);
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public Direction direction() {
|
||||
return direction;
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import dan200.computercraft.api.peripheral.GenericPeripheral;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.peripheral.PeripheralType;
|
||||
import dan200.computercraft.shared.peripheral.generic.SidedGenericPeripheral;
|
||||
import dan200.computercraft.shared.platform.FabricContainerTransfer;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
|
||||
@@ -157,7 +156,7 @@ public class InventoryMethods implements GenericPeripheral {
|
||||
@Nullable
|
||||
private static SlottedStorage<ItemVariant> extractHandler(IPeripheral peripheral) {
|
||||
var object = peripheral.getTarget();
|
||||
var direction = peripheral instanceof SidedGenericPeripheral sided ? sided.direction() : null;
|
||||
var direction = peripheral instanceof dan200.computercraft.shared.peripheral.generic.GenericPeripheral sided ? sided.side() : null;
|
||||
|
||||
if (object instanceof BlockEntity blockEntity) {
|
||||
if (blockEntity.isRemoved()) return null;
|
||||
|
||||
@@ -6,12 +6,15 @@ package dan200.computercraft.shared.platform;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.EntityDimensions;
|
||||
import net.minecraft.world.entity.Pose;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
final class FakePlayer extends net.fabricmc.fabric.api.entity.FakePlayer {
|
||||
import static dan200.computercraft.shared.platform.FakePlayerConstants.MAX_REACH;
|
||||
|
||||
public final class FakePlayer extends net.fabricmc.fabric.api.entity.FakePlayer {
|
||||
private FakePlayer(ServerLevel serverLevel, GameProfile gameProfile) {
|
||||
super(serverLevel, gameProfile);
|
||||
}
|
||||
@@ -33,4 +36,13 @@ final class FakePlayer extends net.fabricmc.fabric.api.entity.FakePlayer {
|
||||
public float getStandingEyeHeight(Pose pose, EntityDimensions dimensions) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getBlockReach() {
|
||||
return MAX_REACH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean broadcastToPlayer(ServerPlayer player) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType;
|
||||
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalItemTags;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.InventoryStorage;
|
||||
import net.fabricmc.fabric.api.transfer.v1.item.ItemStorage;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.commands.synchronization.ArgumentTypeInfo;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
@@ -73,7 +74,6 @@ import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -83,6 +83,11 @@ import java.util.function.*;
|
||||
|
||||
@AutoService(dan200.computercraft.impl.PlatformHelper.class)
|
||||
public class PlatformHelperImpl implements PlatformHelper {
|
||||
@Override
|
||||
public boolean isDevelopmentEnvironment() {
|
||||
return FabricLoader.getInstance().isDevelopmentEnvironment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigFile.Builder createConfigBuilder() {
|
||||
return new FabricConfigFile.Builder();
|
||||
@@ -290,7 +295,7 @@ public class PlatformHelperImpl implements PlatformHelper {
|
||||
public boolean hasToolUsage(ItemStack stack) {
|
||||
var item = stack.getItem();
|
||||
return item instanceof ShovelItem || stack.is(ItemTags.SHOVELS) ||
|
||||
item instanceof HoeItem || stack.is(ItemTags.HOES);
|
||||
item instanceof HoeItem || stack.is(ItemTags.HOES);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -356,7 +361,6 @@ public class PlatformHelperImpl implements PlatformHelper {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return registry.iterator();
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"EntityMixin",
|
||||
"ExplosionDamageCalculatorMixin",
|
||||
"ItemEntityMixin",
|
||||
"ItemMixin",
|
||||
"ServerLevelMixin",
|
||||
"ShapedRecipeMixin",
|
||||
"TagEntryAccessor",
|
||||
|
||||
Reference in New Issue
Block a user