1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-09-07 04:47:55 +00:00

Merge branch 'mc-1.20.x' into mc-1.21.x

This commit is contained in:
Jonathan Coates
2025-02-16 21:04:28 +00:00
324 changed files with 1055 additions and 732 deletions

View File

@@ -38,8 +38,8 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.function.Consumer;
/**

View File

@@ -51,8 +51,8 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.DyedItemColor;
import net.minecraft.world.level.ItemLike;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.Collection;

View File

@@ -15,8 +15,8 @@ import net.minecraft.client.gui.components.ChatComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.util.Mth;
import org.apache.commons.lang3.StringUtils;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Objects;
/**

View File

@@ -26,11 +26,11 @@ import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.Files;

View File

@@ -11,8 +11,8 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.resources.TextureAtlasHolder;
import net.minecraft.resources.ResourceLocation;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.stream.Stream;

View File

@@ -15,9 +15,9 @@ import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.MenuAccess;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import org.jspecify.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
import javax.annotation.Nullable;
import java.util.Objects;
import static dan200.computercraft.core.util.Nullability.assertNonNull;

View File

@@ -12,8 +12,8 @@ import net.minecraft.client.gui.components.MultiLineLabel;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.List;
import static dan200.computercraft.core.util.Nullability.assertNonNull;

View File

@@ -127,6 +127,7 @@ public final class PrintoutScreen extends AbstractContainerScreen<PrintoutMenu>
// Skip rendering labels.
}
@SuppressWarnings("ArrayRecordComponent")
record PrintoutInfo(int pages, boolean book, TextBuffer[] text, TextBuffer[] colour) {
public static final PrintoutInfo DEFAULT = of(PrintoutData.EMPTY, false);

View File

@@ -12,8 +12,8 @@ import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.Tooltip;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.function.Supplier;
/**

View File

@@ -11,8 +11,8 @@ import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.Direction;
import org.joml.Matrix4f;
import org.joml.Vector4f;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;

View File

@@ -23,8 +23,8 @@ import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.core.component.DataComponents;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

View File

@@ -27,8 +27,8 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.JukeboxSong;
import net.minecraft.world.level.Level;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.UUID;
/**

View File

@@ -7,8 +7,7 @@ package dan200.computercraft.client.platform;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.resources.model.BakedModel;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public interface ClientPlatformHelper extends dan200.computercraft.impl.client.ClientPlatformHelper {
static ClientPlatformHelper get() {
@@ -25,5 +24,5 @@ public interface ClientPlatformHelper extends dan200.computercraft.impl.client.C
* @param overlayLight The current overlay light.
* @param tints Block colour tints to apply to the model.
*/
void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, @Nullable int[] tints);
void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, int @Nullable [] tints);
}

View File

@@ -10,8 +10,8 @@ import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.computer.terminal.TerminalState;
import dan200.computercraft.shared.network.client.PocketComputerDataMessage;
import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

View File

@@ -8,8 +8,7 @@ import dan200.computercraft.shared.computer.core.ComputerState;
import dan200.computercraft.shared.computer.terminal.NetworkedTerminal;
import dan200.computercraft.shared.computer.terminal.TerminalState;
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* Clientside data about a pocket computer.

View File

@@ -14,8 +14,8 @@ import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.world.item.ItemStack;
import org.joml.Vector4f;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.List;
/**
@@ -39,7 +39,7 @@ public final class ModelRenderer {
* @param overlayLight The current overlay light.
* @param tints Block colour tints to apply to the model.
*/
public static void renderQuads(PoseStack transform, VertexConsumer buffer, List<BakedQuad> quads, int lightmapCoord, int overlayLight, @Nullable int[] tints) {
public static void renderQuads(PoseStack transform, VertexConsumer buffer, List<BakedQuad> quads, int lightmapCoord, int overlayLight, int @Nullable [] tints) {
var matrix = transform.last();
var inverted = matrix.pose().determinant() < 0;

View File

@@ -16,8 +16,8 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceProvider;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Objects;
import java.util.function.BiConsumer;

View File

@@ -26,8 +26,7 @@ import net.minecraft.util.CommonColors;
import net.minecraft.util.FastColor;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public class TurtleBlockEntityRenderer implements BlockEntityRenderer<TurtleBlockEntity> {
public static final ResourceLocation COLOUR_TURTLE_MODEL = ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "block/turtle_colour");
@@ -124,7 +123,7 @@ public class TurtleBlockEntityRenderer implements BlockEntityRenderer<TurtleBloc
transform.popPose();
}
private void renderModel(PoseStack transform, MultiBufferSource buffers, int lightmapCoord, int overlayLight, ResourceLocation modelLocation, @Nullable int[] tints) {
private void renderModel(PoseStack transform, MultiBufferSource buffers, int lightmapCoord, int overlayLight, ResourceLocation modelLocation, int @Nullable [] tints) {
var modelManager = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getModelManager();
renderModel(transform, buffers, lightmapCoord, overlayLight, ClientPlatformHelper.get().getModel(modelManager, modelLocation), tints);
}
@@ -140,7 +139,7 @@ public class TurtleBlockEntityRenderer implements BlockEntityRenderer<TurtleBloc
* @param tints Tints for the quads, as an array of RGB values.
* @see net.minecraft.client.renderer.block.ModelBlockRenderer#renderModel
*/
private void renderModel(PoseStack transform, MultiBufferSource renderer, int lightmapCoord, int overlayLight, BakedModel model, @Nullable int[] tints) {
private void renderModel(PoseStack transform, MultiBufferSource renderer, int lightmapCoord, int overlayLight, BakedModel model, int @Nullable [] tints) {
ClientPlatformHelper.get().renderBakedModel(transform, renderer, model, lightmapCoord, overlayLight, tints);
}

View File

@@ -31,12 +31,12 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.world.phys.AABB;
import org.joml.Matrix4f;
import org.jspecify.annotations.Nullable;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL31;
import org.lwjgl.system.MemoryUtil;
import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.function.Consumer;

View File

@@ -11,12 +11,12 @@ import dan200.computercraft.client.render.vbo.DirectVertexBuffer;
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
import net.minecraft.core.BlockPos;
import org.jspecify.annotations.Nullable;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL31;
import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Set;

View File

@@ -14,12 +14,12 @@ import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.core.util.Colour;
import net.minecraft.client.renderer.ShaderInstance;
import net.minecraft.server.packs.resources.ResourceProvider;
import org.jspecify.annotations.Nullable;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL31;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.ByteBuffer;

View File

@@ -10,9 +10,9 @@ import dan200.computercraft.shared.peripheral.speaker.SpeakerPeripheral;
import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition;
import net.minecraft.client.sounds.AudioStream;
import net.minecraft.client.sounds.SoundEngine;
import org.jspecify.annotations.Nullable;
import org.lwjgl.BufferUtils;
import javax.annotation.Nullable;
import javax.sound.sampled.AudioFormat;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

View File

@@ -10,8 +10,7 @@ import dan200.computercraft.shared.peripheral.speaker.EncodedAudio;
import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* An instance of a speaker, which is either playing a {@link DfpwmStream} stream or a normal sound.

View File

@@ -16,8 +16,8 @@ import net.minecraft.client.sounds.SoundBufferLibrary;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Entity;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.concurrent.CompletableFuture;
/**

View File

@@ -15,7 +15,7 @@ import dan200.computercraft.shared.turtle.upgrades.TurtleModem;
import dan200.computercraft.shared.util.DataComponentUtil;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;
import java.util.stream.Stream;

View File

@@ -6,7 +6,7 @@ import dan200.computercraft.api.lua.Coerced;
import dan200.computercraft.api.lua.ILuaAPI;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.turtle.ITurtleAccess;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;
/**
* An example API that will be available on every turtle. This demonstrates both registering an API, and how to write

View File

@@ -3,7 +3,7 @@ package com.example.examplemod.peripheral;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.world.level.block.entity.BrewingStandBlockEntity;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;
/**
* A peripheral that adds a {@code getFuel()} method to brewing stands. This demonstrates the usage of

View File

@@ -4,7 +4,7 @@ import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.AttachedComputerSet;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;
/**
* A peripheral that tracks what computers it is attached to.

View File

@@ -12,7 +12,6 @@ import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.filesystem.WritableMount;
import dan200.computercraft.api.lua.GenericSource;
import dan200.computercraft.api.lua.ILuaAPIFactory;
import dan200.computercraft.api.media.MediaProvider;
import dan200.computercraft.api.media.PrintoutContents;
import dan200.computercraft.api.network.PacketNetwork;
import dan200.computercraft.api.network.wired.WiredElement;
@@ -40,8 +39,8 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -96,11 +95,6 @@ public abstract class AbstractComputerCraftAPI implements ComputerCraftAPIServic
return BundledRedstone.getDefaultOutput(world, pos, side);
}
@Override
public final void registerMediaProvider(MediaProvider provider) {
MediaProviders.register(provider);
}
@Override
public final PacketNetwork getWirelessNetwork(MinecraftServer server) {
return ServerContext.get(server).wirelessNetwork();

View File

@@ -1,46 +0,0 @@
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
//
// SPDX-License-Identifier: LicenseRef-CCPL
package dan200.computercraft.impl;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.media.MediaProvider;
import net.minecraft.world.item.ItemStack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
public final class MediaProviders {
private static final Logger LOG = LoggerFactory.getLogger(MediaProviders.class);
private static final Set<MediaProvider> providers = new LinkedHashSet<>();
private MediaProviders() {
}
public static synchronized void register(MediaProvider provider) {
Objects.requireNonNull(provider, "provider cannot be null");
providers.add(provider);
}
public static @Nullable IMedia get(ItemStack stack) {
if (stack.isEmpty()) return null;
// Try the handlers in order:
for (var mediaProvider : providers) {
try {
var media = mediaProvider.getMedia(stack);
if (media != null) return media;
} catch (Exception e) {
// Mod misbehaved, ignore it
LOG.error("Media provider " + mediaProvider + " errored.", e);
}
}
return null;
}
}

View File

@@ -11,8 +11,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.entity.BlockEntity;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* The registry for peripheral providers.

View File

@@ -21,8 +21,8 @@ import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.RegistryFixedCodec;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.function.Function;
/**

View File

@@ -5,11 +5,10 @@
package dan200.computercraft.impl.network.wired;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
/**
* Verifies certain elements of a network are well-formed.
* <p>

View File

@@ -5,8 +5,8 @@
package dan200.computercraft.impl.network.wired;
import dan200.computercraft.api.network.wired.WiredNode;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Objects;
/**

View File

@@ -11,8 +11,8 @@ import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.network.wired.WiredNode;
import dan200.computercraft.api.network.wired.WiredSender;
import dan200.computercraft.api.peripheral.IPeripheral;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;

View File

@@ -38,8 +38,8 @@ import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.world.level.storage.loot.entries.NestedLootTable;
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
import net.minecraft.world.phys.BlockHitResult;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Set;
import java.util.function.BiConsumer;
@@ -129,7 +129,7 @@ public final class CommonHooks {
BuiltInLootTables.VILLAGE_CARTOGRAPHER
);
public static @Nullable LootPool.Builder getExtraLootPool(ResourceKey<LootTable> lootTable) {
public static LootPool.@Nullable Builder getExtraLootPool(ResourceKey<LootTable> lootTable) {
if (!TREASURE_DISK_LOOT_TABLES.contains(lootTable)) {
return null;
}

View File

@@ -12,6 +12,8 @@ import dan200.computercraft.api.component.ComputerComponents;
import dan200.computercraft.api.detail.DetailProvider;
import dan200.computercraft.api.detail.VanillaDetailRegistries;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.upgrades.UpgradeBase;
@@ -46,12 +48,14 @@ import dan200.computercraft.shared.details.ItemDetails;
import dan200.computercraft.shared.integration.PermissionRegistry;
import dan200.computercraft.shared.lectern.CustomLecternBlock;
import dan200.computercraft.shared.lectern.CustomLecternBlockEntity;
import dan200.computercraft.shared.media.MountMedia;
import dan200.computercraft.shared.media.PrintoutMenu;
import dan200.computercraft.shared.media.items.*;
import dan200.computercraft.shared.media.recipes.DiskRecipe;
import dan200.computercraft.shared.media.recipes.PrintoutRecipe;
import dan200.computercraft.shared.network.container.ComputerContainerData;
import dan200.computercraft.shared.network.container.ContainerData;
import dan200.computercraft.shared.peripheral.commandblock.CommandBlockPeripheral;
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveBlock;
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveBlockEntity;
import dan200.computercraft.shared.peripheral.diskdrive.DiskDriveMenu;
@@ -97,6 +101,7 @@ import dan200.computercraft.shared.util.StorageCapacity;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.synchronization.ArgumentTypeInfo;
import net.minecraft.commands.synchronization.SingletonArgumentInfo;
import net.minecraft.core.Direction;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.cauldron.CauldronInteraction;
@@ -117,6 +122,7 @@ import net.minecraft.world.item.crafting.CustomRecipe;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.entity.BlockEntity;
@@ -125,6 +131,7 @@ import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
import net.minecraft.world.level.material.MapColor;
import net.minecraft.world.level.storage.loot.predicates.LootItemConditionType;
import org.jspecify.annotations.Nullable;
import java.util.Objects;
import java.util.function.BiFunction;
@@ -607,11 +614,6 @@ public final class ModRegistry {
// Register bundled power providers
ComputerCraftAPI.registerBundledRedstoneProvider(new DefaultBundledRedstoneProvider());
ComputerCraftAPI.registerRefuelHandler(new FurnaceRefuelHandler());
ComputerCraftAPI.registerMediaProvider(stack -> {
if (stack.getItem() instanceof IMedia media) return media;
if (stack.has(net.minecraft.core.component.DataComponents.JUKEBOX_PLAYABLE)) return RecordMedia.INSTANCE;
return null;
});
ComputerCraftAPI.registerAPIFactory(computer -> {
var turtle = computer.getComponent(ComputerComponents.TURTLE);
@@ -641,6 +643,76 @@ public final class ModRegistry {
CauldronInteraction.WATER.map().put(Items.TURTLE_ADVANCED.get(), TurtleItem.CAULDRON_INTERACTION);
}
/**
* Register our peripherals.
*
* @param peripherals The object to register our peripheral capability/lookups with.
*/
public static void registerPeripherals(BlockComponent<IPeripheral, Direction> peripherals) {
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.COMPUTER_NORMAL.get(), (b, d) -> b.peripheral());
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.COMPUTER_ADVANCED.get(), (b, d) -> b.peripheral());
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.TURTLE_NORMAL.get(), (b, d) -> b.peripheral());
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.TURTLE_ADVANCED.get(), (b, d) -> b.peripheral());
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.SPEAKER.get(), (b, d) -> b.peripheral());
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.PRINTER.get(), (b, d) -> b.peripheral());
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.DISK_DRIVE.get(), (b, d) -> b.peripheral());
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.MONITOR_NORMAL.get(), (b, d) -> b.peripheral());
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.MONITOR_ADVANCED.get(), (b, d) -> b.peripheral());
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.WIRELESS_MODEM_NORMAL.get(), WirelessModemBlockEntity::getPeripheral);
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.WIRELESS_MODEM_ADVANCED.get(), WirelessModemBlockEntity::getPeripheral);
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.WIRED_MODEM_FULL.get(), WiredModemFullBlockEntity::getPeripheral);
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.CABLE.get(), CableBlockEntity::getPeripheral);
peripherals.registerForBlockEntity(ModRegistry.BlockEntities.REDSTONE_RELAY.get(), (b, d) -> b.peripheral());
peripherals.registerForBlockEntity(BlockEntityType.COMMAND_BLOCK, (b, d) -> Config.enableCommandBlock ? new CommandBlockPeripheral(b) : null);
}
public static void registerWiredElements(BlockComponent<WiredElement, Direction> wiredElements) {
wiredElements.registerForBlockEntity(ModRegistry.BlockEntities.WIRED_MODEM_FULL.get(), (b, d) -> b.getElement());
wiredElements.registerForBlockEntity(ModRegistry.BlockEntities.CABLE.get(), CableBlockEntity::getWiredElement);
}
/**
* Register our custom {@link IMedia} implementations.
*
* @param media The object to register our media capabilities/lookups with.
*/
public static void registerMedia(ItemComponent<IMedia> media) {
media.registerForItems((s, c) -> MountMedia.COMPUTER,
ModRegistry.Items.COMPUTER_NORMAL.get(), ModRegistry.Items.COMPUTER_ADVANCED.get(),
ModRegistry.Items.TURTLE_NORMAL.get(), ModRegistry.Items.TURTLE_ADVANCED.get(),
ModRegistry.Items.POCKET_COMPUTER_NORMAL.get(), ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get()
);
media.registerForItems((s, c) -> MountMedia.DISK, ModRegistry.Items.DISK.get());
media.registerForItems((s, c) -> TreasureDiskMedia.INSTANCE, ModRegistry.Items.TREASURE_DISK.get());
media.registerFallback((stack, ctx) -> {
if (stack.getItem() instanceof IMedia m) return m;
if (stack.has(net.minecraft.core.component.DataComponents.JUKEBOX_PLAYABLE)) return RecordMedia.INSTANCE;
return null;
});
}
/**
* An abstraction for registering capabilities/block lookups for blocks and block entities.
*
* @param <T> The type of the component.
* @param <C> The context parameter to the component.
*/
public interface BlockComponent<T, C extends @Nullable Object> {
<B extends BlockEntity> void registerForBlockEntity(BlockEntityType<B> blockEntityType, BiFunction<? super B, C, @Nullable T> provider);
}
/**
* An abstraction for registering capabilities/block lookups for items.
*
* @param <T> The type of the component.
*/
public interface ItemComponent<T> {
void registerForItems(BiFunction<ItemStack, @Nullable Void, @Nullable T> provider, ItemLike... items);
void registerFallback(BiFunction<ItemStack, @Nullable Void, @Nullable T> provider);
}
private static void addTurtle(CreativeModeTab.Output out, TurtleItem turtle, HolderLookup.Provider registries) {
out.accept(new ItemStack(turtle));
registries.lookupOrThrow(ITurtleUpgrade.REGISTRY).listElements()

View File

@@ -34,8 +34,8 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.io.File;
import java.util.*;

View File

@@ -20,8 +20,8 @@ import net.minecraft.commands.arguments.UuidArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
@@ -40,7 +40,7 @@ public record ComputerSelector(
@Nullable String label,
@Nullable ComputerFamily family,
@Nullable AABB bounds,
@Nullable MinMaxBounds.Doubles range
MinMaxBounds.@Nullable Doubles range
) {
private static final ComputerSelector all = new ComputerSelector("@c[]", null, OptionalInt.empty(), null, null, null, null);
@@ -258,7 +258,7 @@ public record ComputerSelector(
private @Nullable String label;
private @Nullable ComputerFamily family;
private @Nullable AABB bounds;
private @Nullable MinMaxBounds.Doubles range;
private MinMaxBounds.@Nullable Doubles range;
}
private static final Map<String, Option> options;

View File

@@ -12,8 +12,8 @@ import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.tree.CommandNode;
import dan200.computercraft.shared.command.arguments.RepeatArgumentType;
import net.minecraft.commands.CommandSourceStack;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

View File

@@ -14,8 +14,8 @@ import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Predicate;

View File

@@ -11,8 +11,7 @@ import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.MutableComponent;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* Various helpers for building chat messages.

View File

@@ -7,8 +7,7 @@ package dan200.computercraft.shared.command.text;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.chat.Component;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public class ServerTableFormatter implements TableFormatter {
private final CommandSourceStack source;

View File

@@ -11,15 +11,15 @@ import dan200.computercraft.shared.network.server.ServerNetworking;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class TableBuilder {
private final String id;
private int columns = -1;
private final @Nullable Component[] headers;
private final Component @Nullable [] headers;
private final ArrayList<Component[]> rows = new ArrayList<>();
private int additional;
@@ -72,8 +72,7 @@ public class TableBuilder {
return columns;
}
@Nullable
public Component[] getHeaders() {
public Component @Nullable [] getHeaders() {
return headers;
}

View File

@@ -7,8 +7,7 @@ package dan200.computercraft.shared.command.text;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import static dan200.computercraft.shared.command.text.ChatHelpers.coloured;

View File

@@ -21,7 +21,6 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.phys.BlockHitResult;
/**
* A block which has a container and can be placed in a horizontal direction.
*

View File

@@ -28,8 +28,7 @@ import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public abstract class AbstractComputerBlock<T extends AbstractComputerBlockEntity> extends HorizontalDirectionalBlock implements IBundledRedstoneBlock, EntityBlock {
protected final RegistryEntry<BlockEntityType<T>> type;

View File

@@ -36,8 +36,8 @@ import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.UUID;

View File

@@ -18,8 +18,7 @@ import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public class ComputerBlock<T extends ComputerBlockEntity> extends AbstractComputerBlock<T> {
private static final MapCodec<ComputerBlock<?>> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(

View File

@@ -20,8 +20,7 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public class ComputerBlockEntity extends AbstractComputerBlockEntity {
private @Nullable IPeripheral peripheral;

View File

@@ -7,8 +7,7 @@ package dan200.computercraft.shared.computer.blocks;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.apis.OSAPI;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* A computer or turtle wrapped as a peripheral.

View File

@@ -13,8 +13,8 @@ import dan200.computercraft.core.apis.IAPIEnvironment;
import dan200.computercraft.core.computer.ApiLifecycle;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Map;
/**

View File

@@ -30,8 +30,8 @@ import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@@ -213,7 +213,7 @@ public class ServerComputer implements ComputerEnvironment, ComputerEvents.Recei
}
@Override
public final void queueEvent(String event, @Nullable Object[] arguments) {
public final void queueEvent(String event, @Nullable Object @Nullable [] arguments) {
computer.queueEvent(event, arguments);
}

View File

@@ -4,7 +4,8 @@
package dan200.computercraft.shared.computer.core;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import java.util.*;
public class ServerComputerRegistry {

View File

@@ -26,10 +26,10 @@ import dan200.computercraft.shared.util.IDAssigner;
import net.minecraft.SharedConstants;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.storage.LevelResource;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Objects;

View File

@@ -21,8 +21,8 @@ import net.minecraft.world.inventory.ContainerData;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.inventory.SimpleContainerData;
import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.function.Predicate;
public abstract class AbstractComputerMenu extends AbstractContainerMenu implements ComputerMenu {

View File

@@ -4,27 +4,18 @@
package dan200.computercraft.shared.computer.items;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.computer.blocks.AbstractComputerBlock;
import dan200.computercraft.shared.config.ConfigSpec;
import dan200.computercraft.shared.util.DataComponentUtil;
import dan200.computercraft.shared.util.StorageCapacity;
import net.minecraft.ChatFormatting;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import javax.annotation.Nullable;
import java.util.List;
public class AbstractComputerItem extends BlockItem implements IMedia {
public class AbstractComputerItem extends BlockItem {
public AbstractComputerItem(AbstractComputerBlock<?> block, Properties settings) {
super(block, settings);
}
@@ -39,24 +30,4 @@ public class AbstractComputerItem extends BlockItem implements IMedia {
}
}
}
@Override
public @Nullable String getLabel(HolderLookup.Provider registries, ItemStack stack) {
return DataComponentUtil.getCustomName(stack);
}
@Override
public boolean setLabel(ItemStack stack, @Nullable String label) {
DataComponentUtil.setCustomName(stack, label);
return true;
}
@Override
public @Nullable Mount createDataMount(ItemStack stack, ServerLevel level) {
var id = stack.get(ModRegistry.DataComponents.COMPUTER_ID.get());
if (id == null) return null;
var capacity = StorageCapacity.getOrDefault(stack.get(ModRegistry.DataComponents.STORAGE_CAPACITY.get()), ConfigSpec.computerSpaceLimit);
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "computer/" + id.id(), capacity);
}
}

View File

@@ -4,13 +4,10 @@
package dan200.computercraft.shared.computer.items;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.shared.computer.blocks.ComputerBlock;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;
/**
* A {@link ComputerItem} which prevents players placing it without permission.
@@ -29,10 +26,4 @@ public class CommandComputerItem extends ComputerItem {
var player = context.getPlayer();
return player != null && !player.canUseGameMasterBlocks() ? null : super.getPlacementState(context);
}
@Override
public @Nullable Mount createDataMount(ItemStack stack, ServerLevel level) {
// Don't allow command computers to be mounted in disk drives.
return null;
}
}

View File

@@ -14,8 +14,8 @@ import net.minecraft.core.component.DataComponentHolder;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.UUID;
/**

View File

@@ -19,10 +19,10 @@ import it.unimi.dsi.fastutil.ints.IntSet;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.inventory.AbstractContainerMenu;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.UUID;

View File

@@ -14,10 +14,10 @@ import dan200.computercraft.shared.computer.metrics.basic.AggregatedMetric;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.server.MinecraftServer;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import javax.management.*;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;

View File

@@ -5,12 +5,12 @@
package dan200.computercraft.shared.computer.metrics.basic;
import com.google.common.collect.MapMaker;
import com.google.errorprone.annotations.concurrent.GuardedBy;
import dan200.computercraft.core.metrics.Metric;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.computer.metrics.ComputerMetricsObserver;
import dan200.computercraft.shared.computer.metrics.GlobalMetrics;
import javax.annotation.concurrent.GuardedBy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

View File

@@ -6,8 +6,8 @@ package dan200.computercraft.shared.computer.metrics.basic;
import dan200.computercraft.core.metrics.Metric;
import dan200.computercraft.shared.computer.core.ServerComputer;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Arrays;

View File

@@ -7,8 +7,7 @@ package dan200.computercraft.shared.computer.terminal;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import org.jetbrains.annotations.Contract;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* A snapshot of a terminal's state.

View File

@@ -4,10 +4,10 @@
package dan200.computercraft.shared.computer.upload;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -52,8 +52,7 @@ public class FileUpload {
return digest != null && Arrays.equals(checksum, digest);
}
@Nullable
public static byte[] getDigest(ByteBuffer bytes) {
public static byte @Nullable [] getDigest(ByteBuffer bytes) {
try {
var digest = MessageDigest.getInstance("SHA-256");
digest.update(bytes.duplicate());

View File

@@ -5,9 +5,9 @@
package dan200.computercraft.shared.config;
import com.google.common.base.Splitter;
import com.google.errorprone.annotations.OverridingMethodsMustInvokeSuper;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import javax.annotation.OverridingMethodsMustInvokeSuper;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Predicate;

View File

@@ -16,8 +16,8 @@ import dan200.computercraft.shared.platform.PlatformHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.filter.MarkerFilter;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.TimeUnit;

View File

@@ -5,10 +5,10 @@
package dan200.computercraft.shared.config;
import dan200.computercraft.core.CoreConfig;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

View File

@@ -7,8 +7,7 @@ package dan200.computercraft.shared.container;
import net.minecraft.core.Direction;
import net.minecraft.world.WorldlyContainer;
import net.minecraft.world.item.ItemStack;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* A basic implementation of {@link WorldlyContainer} which operates on a {@linkplain #getItems() list of stacks}.

View File

@@ -16,8 +16,8 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.ItemEnchantments;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

View File

@@ -4,13 +4,13 @@
package dan200.computercraft.shared.integration;
import com.google.errorprone.annotations.OverridingMethodsMustInvokeSuper;
import com.mojang.brigadier.builder.ArgumentBuilder;
import dan200.computercraft.shared.command.CommandComputerCraft;
import dan200.computercraft.shared.command.UserLevel;
import dan200.computercraft.shared.platform.RegistrationHelper;
import net.minecraft.commands.CommandSourceStack;
import javax.annotation.OverridingMethodsMustInvokeSuper;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.function.Predicate;

View File

@@ -22,8 +22,8 @@ import net.minecraft.world.item.crafting.CraftingBookCategory;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.ShapedRecipe;
import net.minecraft.world.item.crafting.ShapedRecipePattern;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.*;
import java.util.function.Function;
@@ -251,12 +251,12 @@ public class UpgradeRecipeGenerator<T> {
private class UpgradeInfo {
final ItemStack stack;
final Ingredient ingredient;
final @Nullable Holder.Reference<ITurtleUpgrade> turtle;
final @Nullable Holder.Reference<IPocketUpgrade> pocket;
final Holder.@Nullable Reference<ITurtleUpgrade> turtle;
final Holder.@Nullable Reference<IPocketUpgrade> pocket;
final UpgradeBase upgrade;
private @Nullable ArrayList<T> recipes;
UpgradeInfo(ItemStack stack, UpgradeBase upgrade, @Nullable Holder.Reference<ITurtleUpgrade> turtle, @Nullable Holder.Reference<IPocketUpgrade> pocket) {
UpgradeInfo(ItemStack stack, UpgradeBase upgrade, Holder.@Nullable Reference<ITurtleUpgrade> turtle, Holder.@Nullable Reference<IPocketUpgrade> pocket) {
this.stack = stack;
ingredient = Ingredient.of(stack);
this.turtle = turtle;

View File

@@ -27,7 +27,7 @@ import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;
/**
* Extends {@link LecternBlock} with support for {@linkplain PrintoutItem printouts}.

View File

@@ -0,0 +1,85 @@
// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package dan200.computercraft.shared.media;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.computer.items.AbstractComputerItem;
import dan200.computercraft.shared.config.ConfigSpec;
import dan200.computercraft.shared.media.items.DiskItem;
import dan200.computercraft.shared.util.DataComponentUtil;
import dan200.computercraft.shared.util.NonNegativeId;
import dan200.computercraft.shared.util.StorageCapacity;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
import java.util.function.Supplier;
/**
* Media that provides a {@link Mount}.
*/
public final class MountMedia implements IMedia {
/**
* A {@link MountMedia} implementation for {@linkplain AbstractComputerItem computers}.
*/
public static final IMedia COMPUTER = new MountMedia("computer", ModRegistry.DataComponents.COMPUTER_ID, false, ConfigSpec.computerSpaceLimit);
/**
* A {@link MountMedia} implementation for {@linkplain DiskItem disks}.
*/
public static final IMedia DISK = new MountMedia("disk", ModRegistry.DataComponents.DISK_ID, true, ConfigSpec.floppySpaceLimit);
private final String subPath;
private final Supplier<DataComponentType<NonNegativeId>> id;
private final boolean createId;
private final Supplier<Integer> defaultCapacity;
/**
* Create a new {@link MountMedia}.
*
* @param subPath The sub-path to expose the mount under, for instance {@code "computer"}.
* @param id The component that stores the ID.
* @param createId Whether to allocate a new ID if the item does not yet have one.
* @param defaultCapacity A function to get the default capacity of the stack.
*/
public MountMedia(
String subPath,
Supplier<DataComponentType<NonNegativeId>> id,
boolean createId,
Supplier<Integer> defaultCapacity
) {
this.subPath = subPath;
this.id = id;
this.createId = createId;
this.defaultCapacity = defaultCapacity;
}
@Override
public @Nullable String getLabel(HolderLookup.Provider registries, ItemStack stack) {
return DataComponentUtil.getCustomName(stack);
}
@Override
public boolean setLabel(ItemStack stack, @Nullable String label) {
DataComponentUtil.setCustomName(stack, label);
return true;
}
@Override
public @Nullable Mount createDataMount(ItemStack stack, ServerLevel level) {
var id = createId
? NonNegativeId.getOrCreate(level.getServer(), stack, this.id.get(), subPath)
: NonNegativeId.getId(stack.get(this.id.get()));
if (id < 0) return null;
var capacity = StorageCapacity.getOrDefault(stack.get(ModRegistry.DataComponents.STORAGE_CAPACITY.get()), defaultCapacity);
return ComputerCraftAPI.createSaveDirMount(level.getServer(), subPath + "/" + id, capacity);
}
}

View File

@@ -5,20 +5,12 @@
package dan200.computercraft.shared.media.items;
import dan200.computercraft.annotations.ForgeOverride;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.core.util.Colour;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.config.ConfigSpec;
import dan200.computercraft.shared.util.NonNegativeId;
import dan200.computercraft.shared.util.StorageCapacity;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
@@ -26,10 +18,9 @@ import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.DyedItemColor;
import net.minecraft.world.level.LevelReader;
import javax.annotation.Nullable;
import java.util.List;
public class DiskItem extends Item implements IMedia {
public class DiskItem extends Item {
public DiskItem(Properties settings) {
super(settings);
}
@@ -50,25 +41,6 @@ public class DiskItem extends Item implements IMedia {
return true;
}
@Override
public @Nullable String getLabel(HolderLookup.Provider registries, ItemStack stack) {
var label = stack.get(DataComponents.CUSTOM_NAME);
return label != null ? label.getString() : null;
}
@Override
public boolean setLabel(ItemStack stack, @Nullable String label) {
stack.set(DataComponents.CUSTOM_NAME, label != null ? Component.literal(label) : null);
return true;
}
@Override
public @Nullable Mount createDataMount(ItemStack stack, ServerLevel level) {
var diskID = NonNegativeId.getOrCreate(level.getServer(), stack, ModRegistry.DataComponents.DISK_ID.get(), "disk");
var capacity = StorageCapacity.getOrDefault(stack.get(ModRegistry.DataComponents.STORAGE_CAPACITY.get()), ConfigSpec.floppySpaceLimit);
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "disk/" + diskID, capacity);
}
public static int getDiskID(ItemStack stack) {
return NonNegativeId.getId(stack.get(ModRegistry.DataComponents.DISK_ID.get()));
}

View File

@@ -8,8 +8,7 @@ import dan200.computercraft.api.media.IMedia;
import net.minecraft.core.HolderLookup;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.JukeboxSong;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* An implementation of {@link IMedia} for items with a {@link JukeboxSong}.

View File

@@ -5,26 +5,17 @@
package dan200.computercraft.shared.media.items;
import dan200.computercraft.annotations.ForgeOverride;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.core.filesystem.SubMount;
import dan200.computercraft.shared.ModRegistry;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.LevelReader;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.List;
public class TreasureDiskItem extends Item implements IMedia {
public class TreasureDiskItem extends Item {
public TreasureDiskItem(Properties settings) {
super(settings);
}
@@ -38,31 +29,4 @@ public class TreasureDiskItem extends Item implements IMedia {
public boolean doesSneakBypassUse(ItemStack stack, LevelReader world, BlockPos pos, Player player) {
return true;
}
@Override
public String getLabel(HolderLookup.Provider registries, ItemStack stack) {
return TreasureDisk.getTitle(stack);
}
@Override
public @Nullable Mount createDataMount(ItemStack stack, ServerLevel level) {
var rootTreasure = ComputerCraftAPI.createResourceMount(level.getServer(), "computercraft", "lua/treasure");
if (rootTreasure == null) return null;
var treasureDisk = stack.get(ModRegistry.DataComponents.TREASURE_DISK.get());
if (treasureDisk == null) return null;
var subPath = treasureDisk.path();
try {
if (rootTreasure.exists(subPath)) {
return new SubMount(rootTreasure, subPath);
} else if (rootTreasure.exists("deprecated/" + subPath)) {
return new SubMount(rootTreasure, "deprecated/" + subPath);
} else {
return null;
}
} catch (IOException e) {
return null;
}
}
}

View File

@@ -0,0 +1,54 @@
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
//
// SPDX-License-Identifier: LicenseRef-CCPL
package dan200.computercraft.shared.media.items;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.core.filesystem.SubMount;
import dan200.computercraft.shared.ModRegistry;
import net.minecraft.core.HolderLookup;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
import java.io.IOException;
/**
* An {@link IMedia} instance for {@linkplain TreasureDiskItem treasure disks}.
*/
public final class TreasureDiskMedia implements IMedia {
public static final IMedia INSTANCE = new TreasureDiskMedia();
private TreasureDiskMedia() {
}
@Override
public String getLabel(HolderLookup.Provider registries, ItemStack stack) {
return TreasureDisk.getTitle(stack);
}
@Override
public @Nullable Mount createDataMount(ItemStack stack, ServerLevel level) {
var rootTreasure = ComputerCraftAPI.createResourceMount(level.getServer(), "computercraft", "lua/treasure");
if (rootTreasure == null) return null;
var treasureDisk = stack.get(ModRegistry.DataComponents.TREASURE_DISK.get());
if (treasureDisk == null) return null;
var subPath = treasureDisk.path();
try {
if (rootTreasure.exists(subPath)) {
return new SubMount(rootTreasure, subPath);
} else if (rootTreasure.exists("deprecated/" + subPath)) {
return new SubMount(rootTreasure, "deprecated/" + subPath);
} else {
return null;
}
} catch (IOException e) {
return null;
}
}
}

View File

@@ -15,8 +15,8 @@ import net.minecraft.core.Holder;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.JukeboxSong;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.UUID;
/**

View File

@@ -16,8 +16,8 @@ import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.world.inventory.AbstractContainerMenu;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

View File

@@ -8,8 +8,7 @@ import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.computer.apis.CommandAPI;
import net.minecraft.world.level.block.entity.CommandBlockEntity;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* This peripheral allows you to interact with command blocks.

View File

@@ -5,9 +5,9 @@
package dan200.computercraft.shared.peripheral.diskdrive;
import com.mojang.serialization.MapCodec;
import dan200.computercraft.impl.MediaProviders;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.common.HorizontalContainerBlock;
import dan200.computercraft.shared.platform.PlatformHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
@@ -24,8 +24,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.phys.BlockHitResult;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public class DiskDriveBlock extends HorizontalContainerBlock {
private static final MapCodec<DiskDriveBlock> CODEC = simpleCodec(DiskDriveBlock::new);
@@ -57,7 +56,7 @@ public class DiskDriveBlock extends HorizontalContainerBlock {
// Try to put a disk into the drive
if (stack.isEmpty()) return ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION;
if (!level.isClientSide && drive.getDiskStack().isEmpty() && MediaProviders.get(stack) != null) {
if (!level.isClientSide && drive.getDiskStack().isEmpty() && PlatformHelper.get().getMedia(stack) != null) {
drive.setDiskStack(stack.split(1));
}
return ItemInteractionResult.sidedSuccess(level.isClientSide);

View File

@@ -28,8 +28,8 @@ import net.minecraft.world.level.block.LevelEvent;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

View File

@@ -10,8 +10,8 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.util.StringUtil;
import dan200.computercraft.shared.media.items.DiskItem;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Optional;
/**
@@ -60,9 +60,8 @@ public class DiskDrivePeripheral implements IPeripheral {
* @return The label of the disk, or {@code nil} if either no disk is inserted or the disk doesn't have a label.
* @cc.treturn string|nil The label of the disk, or {@code nil} if either no disk is inserted or the disk doesn't have a label.
*/
@Nullable
@LuaFunction
public final Object[] getDiskLabel() {
public final @Nullable Object @Nullable [] getDiskLabel() {
var media = diskDrive.getMedia();
return media.media() == null ? null : new Object[]{ media.media().getLabel(diskDrive.getLevel().registryAccess(), media.stack()) };
}
@@ -169,9 +168,8 @@ public class DiskDrivePeripheral implements IPeripheral {
* @cc.treturn number|nil The ID of the disk in the drive, or {@code nil} if no disk with an ID is inserted.
* @cc.since 1.4
*/
@Nullable
@LuaFunction
public final Object[] getDiskID() {
public final @Nullable Object @Nullable [] getDiskID() {
var disk = diskDrive.getMedia().stack();
return disk.getItem() instanceof DiskItem ? new Object[]{ DiskItem.getDiskID(disk) } : null;
}

View File

@@ -5,13 +5,12 @@
package dan200.computercraft.shared.peripheral.diskdrive;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.impl.MediaProviders;
import dan200.computercraft.shared.platform.PlatformHelper;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.JukeboxSong;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* An immutable snapshot of the current disk. This allows us to read the stack in a thread-safe manner.
@@ -26,7 +25,7 @@ record MediaStack(ItemStack stack, @Nullable IMedia media) {
if (stack.isEmpty()) return EMPTY;
var freshStack = stack.copy();
return new MediaStack(freshStack, MediaProviders.get(freshStack));
return new MediaStack(freshStack, PlatformHelper.get().getMedia(freshStack));
}
@Nullable

View File

@@ -9,8 +9,7 @@ import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* Extract some component (for instance a capability on Forge, or a {@code BlockApiLookup} on Fabric) from a block and

View File

@@ -14,8 +14,8 @@ import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.computer.GuardedLuaContext;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntity;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Set;

View File

@@ -11,10 +11,10 @@ import dan200.computercraft.core.methods.PeripheralMethod;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

View File

@@ -13,8 +13,8 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.entity.BlockEntity;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

View File

@@ -11,8 +11,8 @@ import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.GenericPeripheral;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.PeripheralType;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.Optional;

View File

@@ -13,8 +13,8 @@ import dan200.computercraft.api.network.PacketReceiver;
import dan200.computercraft.api.network.PacketSender;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Set;

View File

@@ -7,8 +7,8 @@ package dan200.computercraft.shared.peripheral.modem;
import dan200.computercraft.api.lua.LuaException;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.concurrent.atomic.AtomicBoolean;
public class ModemState {

View File

@@ -34,8 +34,8 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.EnumMap;
import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED;

View File

@@ -25,8 +25,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Objects;
public class CableBlockEntity extends BlockEntity {

View File

@@ -4,8 +4,8 @@
package dan200.computercraft.shared.peripheral.modem.wired;
import dan200.computercraft.shared.util.RegistryHelper;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.util.RegistryHelper;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
@@ -15,8 +15,7 @@ import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
import static dan200.computercraft.shared.peripheral.modem.wired.CableBlock.*;

View File

@@ -6,8 +6,7 @@ package dan200.computercraft.shared.peripheral.modem.wired;
import net.minecraft.core.Direction;
import net.minecraft.util.StringRepresentable;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public enum CableModemVariant implements StringRepresentable {
None("none", null, false, false),

View File

@@ -22,8 +22,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.BlockHitResult;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public class WiredModemFullBlock extends Block implements EntityBlock {
public static final BooleanProperty MODEM_ON = BooleanProperty.create("modem");

View File

@@ -25,8 +25,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.*;
import static dan200.computercraft.shared.peripheral.modem.wired.WiredModemFullBlock.MODEM_ON;

View File

@@ -14,8 +14,8 @@ import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.level.Level;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Map;
import static dan200.computercraft.core.util.Nullability.assertNonNull;

View File

@@ -24,10 +24,10 @@ import dan200.computercraft.shared.peripheral.modem.ModemState;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -130,7 +130,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements Wi
* @see PeripheralAPI#getType
*/
@LuaFunction
public final @Nullable Object[] getTypeRemote(IComputerAccess computer, String name) {
public final Object @Nullable [] getTypeRemote(IComputerAccess computer, String name) {
var wrapper = getWrapper(computer, name);
return wrapper == null ? null : LuaUtil.consArray(wrapper.getType(), wrapper.getAdditionalTypes());
}
@@ -150,7 +150,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements Wi
* @see PeripheralAPI#getType
*/
@LuaFunction
public final @Nullable Object[] hasTypeRemote(IComputerAccess computer, String name, String type) {
public final Object @Nullable [] hasTypeRemote(IComputerAccess computer, String name, String type) {
var wrapper = getWrapper(computer, name);
return wrapper == null ? null : new Object[]{ wrapper.getType().equals(type) || wrapper.getAdditionalTypes().contains(type) };
}
@@ -168,7 +168,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements Wi
* @see PeripheralAPI#getMethods
*/
@LuaFunction
public final @Nullable Object[] getMethodsRemote(IComputerAccess computer, String name) {
public final Object @Nullable [] getMethodsRemote(IComputerAccess computer, String name) {
var wrapper = getWrapper(computer, name);
if (wrapper == null) return null;
@@ -215,7 +215,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements Wi
* @cc.since 1.80pr1.7
*/
@LuaFunction
public final @Nullable Object[] getNameLocal() {
public final Object @Nullable [] getNameLocal() {
var local = localPeripheral.getConnectedName();
return local == null ? null : new Object[]{ local };
}

Some files were not shown because too many files have changed in this diff Show More