1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-01-10 01:10:30 +00:00

Backport small changes from the 1.20.4 branch

- Add support for version overrides/exclusions in our dependency check.
   Sometimes mod loaders use different versions to vanilla, and we need
   some way to handle that.

 - Rescan wired network connections on the tick after invalidation,
   rather than when invalidated.

 - Convert some constant lambdas to static method references. Lambdas
   don't allocate if they don't capture variables, so this has the same
   performance and is a little less ugly.

 - Small code-style/formatting changes.
This commit is contained in:
Jonathan Coates 2024-01-16 21:41:15 +00:00
parent 1d6e3f4fc0
commit 36599b321e
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
11 changed files with 64 additions and 20 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
/logs /logs
/build /build
/projects/*/logs /projects/*/logs
/projects/fabric/fabricloader.log
/projects/*/build /projects/*/build
/buildSrc/build /buildSrc/build
/out /out

View File

@ -7,12 +7,15 @@ package cc.tweaked.gradle
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.GradleException import org.gradle.api.GradleException
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.artifacts.component.ModuleComponentIdentifier import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.artifacts.component.ModuleComponentSelector import org.gradle.api.artifacts.component.ModuleComponentSelector
import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.artifacts.result.DependencyResult import org.gradle.api.artifacts.result.DependencyResult
import org.gradle.api.artifacts.result.ResolvedDependencyResult import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.provider.ListProperty import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskAction
import org.gradle.language.base.plugins.LifecycleBasePlugin import org.gradle.language.base.plugins.LifecycleBasePlugin
@ -21,9 +24,25 @@ abstract class DependencyCheck : DefaultTask() {
@get:Input @get:Input
abstract val configuration: ListProperty<Configuration> abstract val configuration: ListProperty<Configuration>
/**
* A mapping of module coordinates (`group:module`) to versions, overriding the requested version.
*/
@get:Input
abstract val overrides: MapProperty<String, String>
init { init {
description = "Check :core's dependencies are consistent with Minecraft's." description = "Check :core's dependencies are consistent with Minecraft's."
group = LifecycleBasePlugin.VERIFICATION_GROUP group = LifecycleBasePlugin.VERIFICATION_GROUP
configuration.finalizeValueOnRead()
overrides.finalizeValueOnRead()
}
/**
* Override a module with a different version.
*/
fun override(module: Provider<MinimalExternalModuleDependency>, version: String) {
overrides.putAll(project.provider { mutableMapOf(module.get().module.toString() to version) })
} }
@TaskAction @TaskAction
@ -60,7 +79,8 @@ abstract class DependencyCheck : DefaultTask() {
) { ) {
// If the version is different between the requested and selected version, report an error. // If the version is different between the requested and selected version, report an error.
val selected = dependency.selected.moduleVersion!!.version val selected = dependency.selected.moduleVersion!!.version
if (requested.version != selected) { val requestedVersion = overrides.get()["${requested.group}:${requested.module}"] ?: requested.version
if (requestedVersion != selected) {
logger.error("Requested dependency {} (via {}) but got version {}", requested, from, selected) logger.error("Requested dependency {} (via {}) but got version {}", requested, from, selected)
return false return false
} }

View File

@ -12,7 +12,10 @@ import net.minecraft.client.Minecraft;
/** /**
* Methods for sending packets from clients to the server. * Methods for sending packets from clients to the server.
*/ */
public class ClientNetworking { public final class ClientNetworking {
private ClientNetworking() {
}
/** /**
* Send a network message to the server. * Send a network message to the server.
* *

View File

@ -123,7 +123,7 @@ public class UpgradeManager<R extends UpgradeSerialiser<? extends T>, T extends
// TODO: Can we track which mod this resource came from and use that instead? It's theoretically possible, // TODO: Can we track which mod this resource came from and use that instead? It's theoretically possible,
// but maybe not ideal for datapacks. // but maybe not ideal for datapacks.
var modId = id.getNamespace(); var modId = id.getNamespace();
if (modId.equals("minecraft") || modId.equals("")) modId = ComputerCraftAPI.MOD_ID; if (modId.equals("minecraft") || modId.isEmpty()) modId = ComputerCraftAPI.MOD_ID;
var upgrade = serialiser.fromJson(id, root); var upgrade = serialiser.fromJson(id, root);
if (!upgrade.getUpgradeID().equals(id)) { if (!upgrade.getUpgradeID().equals(id)) {

View File

@ -63,6 +63,7 @@ public class CableBlockEntity extends BlockEntity {
private @Nullable Runnable modemChanged; private @Nullable Runnable modemChanged;
private boolean connectionsFormed = false; private boolean connectionsFormed = false;
private boolean connectionsChanged = false;
private final WiredModemElement cable = new CableElement(); private final WiredModemElement cable = new CableElement();
private final WiredNode node = cable.getNode(); private final WiredNode node = cable.getNode();
@ -87,7 +88,7 @@ public class CableBlockEntity extends BlockEntity {
} }
}; };
private final ComponentAccess<WiredElement> connectedElements = PlatformHelper.get().createWiredElementAccess(this, x -> connectionsChanged()); private final ComponentAccess<WiredElement> connectedElements = PlatformHelper.get().createWiredElementAccess(this, x -> scheduleConnectionsChanged());
public CableBlockEntity(BlockEntityType<? extends CableBlockEntity> type, BlockPos pos, BlockState state) { public CableBlockEntity(BlockEntityType<? extends CableBlockEntity> type, BlockPos pos, BlockState state) {
super(type, pos, state); super(type, pos, state);
@ -236,10 +237,18 @@ public class CableBlockEntity extends BlockEntity {
updateConnectedPeripherals(); updateConnectedPeripherals();
} }
} }
if (connectionsChanged) connectionsChanged();
}
private void scheduleConnectionsChanged() {
connectionsChanged = true;
TickScheduler.schedule(tickToken);
} }
void connectionsChanged() { void connectionsChanged() {
if (getLevel().isClientSide) return; if (getLevel().isClientSide) return;
connectionsChanged = false;
var state = getBlockState(); var state = getBlockState();
var world = getLevel(); var world = getLevel();

View File

@ -74,13 +74,14 @@ public class WiredModemFullBlockEntity extends BlockEntity {
private final WiredModemLocalPeripheral[] peripherals = new WiredModemLocalPeripheral[6]; private final WiredModemLocalPeripheral[] peripherals = new WiredModemLocalPeripheral[6];
private boolean connectionsFormed = false; private boolean connectionsFormed = false;
private boolean connectionsChanged = false;
private final TickScheduler.Token tickToken = new TickScheduler.Token(this); private final TickScheduler.Token tickToken = new TickScheduler.Token(this);
private final ModemState modemState = new ModemState(() -> TickScheduler.schedule(tickToken)); private final ModemState modemState = new ModemState(() -> TickScheduler.schedule(tickToken));
private final WiredModemElement element = new FullElement(this); private final WiredModemElement element = new FullElement(this);
private final WiredNode node = element.getNode(); private final WiredNode node = element.getNode();
private final ComponentAccess<WiredElement> connectedElements = PlatformHelper.get().createWiredElementAccess(this, x -> connectionsChanged()); private final ComponentAccess<WiredElement> connectedElements = PlatformHelper.get().createWiredElementAccess(this, x -> scheduleConnectionsChanged());
private int invalidSides = 0; private int invalidSides = 0;
@ -204,10 +205,18 @@ public class WiredModemFullBlockEntity extends BlockEntity {
updateConnectedPeripherals(); updateConnectedPeripherals();
} }
} }
if (connectionsChanged) connectionsChanged();
}
private void scheduleConnectionsChanged() {
connectionsChanged = true;
TickScheduler.schedule(tickToken);
} }
private void connectionsChanged() { private void connectionsChanged() {
if (getLevel().isClientSide) return; if (getLevel().isClientSide) return;
connectionsChanged = false;
var world = getLevel(); var world = getLevel();
var current = getBlockPos(); var current = getBlockPos();

View File

@ -42,7 +42,6 @@ import net.minecraft.world.phys.Vec3;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import static dan200.computercraft.shared.common.IColouredItem.NBT_COLOUR; import static dan200.computercraft.shared.common.IColouredItem.NBT_COLOUR;
import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED; import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED;
@ -59,8 +58,6 @@ public class TurtleBrain implements TurtleAccessInternal {
private static final int ANIM_DURATION = 8; private static final int ANIM_DURATION = 8;
public static final Predicate<Entity> PUSHABLE_ENTITY = entity -> !entity.isSpectator() && entity.getPistonPushReaction() != PushReaction.IGNORE;
private TurtleBlockEntity owner; private TurtleBlockEntity owner;
private @Nullable GameProfile owningPlayer; private @Nullable GameProfile owningPlayer;
@ -694,7 +691,7 @@ public class TurtleBrain implements TurtleAccessInternal {
} }
var aabb = new AABB(minX, minY, minZ, maxX, maxY, maxZ); var aabb = new AABB(minX, minY, minZ, maxX, maxY, maxZ);
var list = world.getEntitiesOfClass(Entity.class, aabb, PUSHABLE_ENTITY); var list = world.getEntitiesOfClass(Entity.class, aabb, TurtleBrain::canPush);
if (!list.isEmpty()) { if (!list.isEmpty()) {
double pushStep = 1.0f / ANIM_DURATION; double pushStep = 1.0f / ANIM_DURATION;
var pushStepX = moveDir.getStepX() * pushStep; var pushStepX = moveDir.getStepX() * pushStep;
@ -737,6 +734,10 @@ public class TurtleBrain implements TurtleAccessInternal {
} }
} }
private static boolean canPush(Entity entity) {
return !entity.isSpectator() && entity.getPistonPushReaction() != PushReaction.IGNORE;
}
private float getAnimationFraction(float f) { private float getAnimationFraction(float f) {
var next = (float) animationProgress / ANIM_DURATION; var next = (float) animationProgress / ANIM_DURATION;
var previous = (float) lastAnimationProgress / ANIM_DURATION; var previous = (float) lastAnimationProgress / ANIM_DURATION;

View File

@ -27,12 +27,8 @@ import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.function.Predicate;
public final class WorldUtil { public final class WorldUtil {
@SuppressWarnings("UnnecessaryLambda")
private static final Predicate<Entity> CAN_COLLIDE = x -> x != null && x.isAlive() && x.isPickable();
public static boolean isLiquidBlock(Level world, BlockPos pos) { public static boolean isLiquidBlock(Level world, BlockPos pos) {
if (!world.isInWorldBounds(pos)) return false; if (!world.isInWorldBounds(pos)) return false;
return world.getBlockState(pos).liquid(); return world.getBlockState(pos).liquid();
@ -84,7 +80,7 @@ public final class WorldUtil {
Entity bestEntity = null; Entity bestEntity = null;
Vec3 bestHit = null; Vec3 bestHit = null;
for (var entity : level.getEntities(source, bounds, WorldUtil.CAN_COLLIDE)) { for (var entity : level.getEntities(source, bounds, WorldUtil::canCollide)) {
var aabb = entity.getBoundingBox().inflate(entity.getPickRadius()); var aabb = entity.getBoundingBox().inflate(entity.getPickRadius());
// clip doesn't work when inside the entity. Just assume we've got a perfect match and break. // clip doesn't work when inside the entity. Just assume we've got a perfect match and break.
@ -109,6 +105,10 @@ public final class WorldUtil {
return bestEntity == null ? null : new EntityHitResult(bestEntity, bestHit); return bestEntity == null ? null : new EntityHitResult(bestEntity, bestHit);
} }
private static boolean canCollide(Entity entity) {
return entity != null && entity.isAlive() && entity.isPickable();
}
public static Vec3 getRayStart(Player entity) { public static Vec3 getRayStart(Player entity) {
return entity.getEyePosition(); return entity.getEyePosition();
} }

View File

@ -7,7 +7,10 @@ package dan200.computercraft.gametest
import dan200.computercraft.api.lua.ObjectArguments import dan200.computercraft.api.lua.ObjectArguments
import dan200.computercraft.core.apis.PeripheralAPI import dan200.computercraft.core.apis.PeripheralAPI
import dan200.computercraft.core.computer.ComputerSide import dan200.computercraft.core.computer.ComputerSide
import dan200.computercraft.gametest.api.* import dan200.computercraft.gametest.api.getBlockEntity
import dan200.computercraft.gametest.api.sequence
import dan200.computercraft.gametest.api.thenOnComputer
import dan200.computercraft.gametest.api.thenStartComputer
import dan200.computercraft.shared.ModRegistry import dan200.computercraft.shared.ModRegistry
import dan200.computercraft.shared.peripheral.modem.wired.CableBlock import dan200.computercraft.shared.peripheral.modem.wired.CableBlock
import dan200.computercraft.test.core.assertArrayEquals import dan200.computercraft.test.core.assertArrayEquals

View File

@ -21,7 +21,6 @@ import net.minecraft.world.entity.EntityType
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.Blocks import net.minecraft.world.level.block.Blocks
import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Assertions.*
import java.util.*
class Monitor_Test { class Monitor_Test {
@GameTest @GameTest

View File

@ -19,7 +19,6 @@ import net.minecraft.world.inventory.MenuType
import net.minecraft.world.inventory.TransientCraftingContainer import net.minecraft.world.inventory.TransientCraftingContainer
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items import net.minecraft.world.item.Items
import net.minecraft.world.item.crafting.CraftingRecipe
import net.minecraft.world.item.crafting.RecipeType import net.minecraft.world.item.crafting.RecipeType
import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertEquals
import java.util.* import java.util.*
@ -37,11 +36,11 @@ class Recipe_Test {
container.setItem(0, ItemStack(Items.SKELETON_SKULL)) container.setItem(0, ItemStack(Items.SKELETON_SKULL))
container.setItem(1, ItemStack(ModRegistry.Items.COMPUTER_ADVANCED.get())) container.setItem(1, ItemStack(ModRegistry.Items.COMPUTER_ADVANCED.get()))
val recipe: Optional<CraftingRecipe> = context.level.server.recipeManager val recipe = context.level.server.recipeManager
.getRecipeFor(RecipeType.CRAFTING, container, context.level) .getRecipeFor(RecipeType.CRAFTING, container, context.level)
if (!recipe.isPresent) throw GameTestAssertException("No recipe matches") .orElseThrow { GameTestAssertException("No recipe matches") }
val result = recipe.get().assemble(container, context.level.registryAccess()) val result = recipe.assemble(container, context.level.registryAccess())
val profile = GameProfile(UUID.fromString("f3c8d69b-0776-4512-8434-d1b2165909eb"), "dan200") val profile = GameProfile(UUID.fromString("f3c8d69b-0776-4512-8434-d1b2165909eb"), "dan200")