mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 05:33:00 +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:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -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. | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -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)) { | ||||||
|   | |||||||
| @@ -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(); | ||||||
|   | |||||||
| @@ -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(); | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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(); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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") | ||||||
| 
 | 
 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jonathan Coates
					Jonathan Coates