diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 52e584525..e54627e35 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -29,9 +29,9 @@ checkerFramework = "3.42.0"
cobalt = { strictly = "0.9.5" }
commonsCli = "1.6.0"
jetbrainsAnnotations = "24.1.0"
-jsr305 = "3.0.2"
+jspecify = "1.0.0"
jzlib = "1.1.3"
-kotlin = "2.1.0"
+kotlin = "2.1.10"
kotlin-coroutines = "1.10.1"
nightConfig = "3.8.1"
@@ -59,9 +59,9 @@ jmh = "1.37"
# Build tools
cctJavadoc = "1.8.3"
-checkstyle = "10.20.1"
-errorProne-core = "2.27.0"
-errorProne-plugin = "3.1.0"
+checkstyle = "10.21.2"
+errorProne-core = "2.36.0"
+errorProne-plugin = "4.1.0"
fabric-loom = "1.9.2"
githubRelease = "2.5.2"
gradleVersions = "0.50.0"
@@ -70,7 +70,7 @@ illuaminate = "0.1.0-74-gf1551d5"
lwjgl = "3.3.3"
minotaur = "2.8.7"
modDevGradle = "2.0.74"
-nullAway = "0.10.25"
+nullAway = "0.12.3"
shadow = "8.3.1"
spotless = "6.23.3"
taskTree = "2.1.1"
@@ -90,7 +90,7 @@ fastutil = { module = "it.unimi.dsi:fastutil", version.ref = "fastutil" }
neoForgeSpi = { module = "net.neoforged:neoforgespi", version.ref = "neoForgeSpi" }
guava = { module = "com.google.guava:guava", version.ref = "guava" }
jetbrainsAnnotations = { module = "org.jetbrains:annotations", version.ref = "jetbrainsAnnotations" }
-jsr305 = { module = "com.google.code.findbugs:jsr305", version.ref = "jsr305" }
+jspecify = { module = "org.jspecify:jspecify", version.ref = "jspecify" }
jzlib = { module = "com.jcraft:jzlib", version.ref = "jzlib" }
kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" }
kotlin-platform = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
@@ -180,7 +180,7 @@ taskTree = { id = "com.dorongold.task-tree", version.ref = "taskTree" }
versionCatalogUpdate = { id = "nl.littlerobots.version-catalog-update", version.ref = "versionCatalogUpdate" }
[bundles]
-annotations = ["jsr305", "checkerFramework", "jetbrainsAnnotations"]
+annotations = ["checkerFramework", "jetbrainsAnnotations", "jspecify"]
kotlin = ["kotlin-stdlib", "kotlin-coroutines"]
# Minecraft
diff --git a/projects/common-api/src/client/java/dan200/computercraft/api/client/ModelLocation.java b/projects/common-api/src/client/java/dan200/computercraft/api/client/ModelLocation.java
index 0376fb786..6004a82bb 100644
--- a/projects/common-api/src/client/java/dan200/computercraft/api/client/ModelLocation.java
+++ b/projects/common-api/src/client/java/dan200/computercraft/api/client/ModelLocation.java
@@ -10,7 +10,7 @@ import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.resources.ResourceLocation;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import java.util.stream.Stream;
diff --git a/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModeller.java b/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModeller.java
index 8dfb5c173..6fb03e3f7 100644
--- a/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModeller.java
+++ b/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModeller.java
@@ -12,8 +12,8 @@ import dan200.computercraft.api.turtle.TurtleSide;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.resources.ResourceLocation;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.stream.Stream;
/**
diff --git a/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModellers.java b/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModellers.java
index 644c0a65a..1c0d4e5f1 100644
--- a/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModellers.java
+++ b/projects/common-api/src/client/java/dan200/computercraft/api/client/turtle/TurtleUpgradeModellers.java
@@ -13,8 +13,7 @@ import dan200.computercraft.impl.client.ClientPlatformHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.core.component.DataComponentPatch;
import org.joml.Matrix4f;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
final class TurtleUpgradeModellers {
private static final Transformation leftTransform = getMatrixFor(-0.4065f);
diff --git a/projects/common-api/src/client/java/dan200/computercraft/impl/client/ClientPlatformHelper.java b/projects/common-api/src/client/java/dan200/computercraft/impl/client/ClientPlatformHelper.java
index 7d104c0a3..542168ffa 100644
--- a/projects/common-api/src/client/java/dan200/computercraft/impl/client/ClientPlatformHelper.java
+++ b/projects/common-api/src/client/java/dan200/computercraft/impl/client/ClientPlatformHelper.java
@@ -12,8 +12,7 @@ import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.ApiStatus;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
@ApiStatus.Internal
public interface ClientPlatformHelper {
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java b/projects/common-api/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java
index 1a75ae954..8a8f31f23 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java
@@ -26,8 +26,7 @@ import net.minecraft.core.Direction;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* The static entry point to the ComputerCraft API.
@@ -148,7 +147,10 @@ public final class ComputerCraftAPI {
*
* @param provider The media provider to register.
* @see MediaProvider
+ * @deprecated Prefer {@code dan200.computercraft.api.media.MediaLookup} (Fabric) or
+ * {@code dan200.computercraft.api.media.MediaCapability} (NeoForge).
*/
+ @Deprecated
public static void registerMediaProvider(MediaProvider provider) {
getInstance().registerMediaProvider(provider);
}
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/detail/BasicItemDetailProvider.java b/projects/common-api/src/main/java/dan200/computercraft/api/detail/BasicItemDetailProvider.java
index c709b79f6..56fe0557c 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/detail/BasicItemDetailProvider.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/detail/BasicItemDetailProvider.java
@@ -6,8 +6,8 @@ package dan200.computercraft.api.detail;
import net.minecraft.world.item.Item;
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.Objects;
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/detail/BlockReference.java b/projects/common-api/src/main/java/dan200/computercraft/api/detail/BlockReference.java
index fc6f25bf6..b58f2da7a 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/detail/BlockReference.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/detail/BlockReference.java
@@ -8,8 +8,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
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;
/**
* A reference to a block in the world, used by block detail providers.
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/detail/ComponentDetailProvider.java b/projects/common-api/src/main/java/dan200/computercraft/api/detail/ComponentDetailProvider.java
index c79e526b4..c289d8d28 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/detail/ComponentDetailProvider.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/detail/ComponentDetailProvider.java
@@ -7,8 +7,8 @@ package dan200.computercraft.api.detail;
import net.minecraft.core.component.DataComponentHolder;
import net.minecraft.core.component.DataComponentType;
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.Objects;
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/lua/IComputerSystem.java b/projects/common-api/src/main/java/dan200/computercraft/api/lua/IComputerSystem.java
index 8d6de36e6..610824eec 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/lua/IComputerSystem.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/lua/IComputerSystem.java
@@ -9,8 +9,7 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import org.jetbrains.annotations.ApiStatus;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* An interface passed to {@link ILuaAPIFactory} in order to provide additional information
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/lua/ILuaAPIFactory.java b/projects/common-api/src/main/java/dan200/computercraft/api/lua/ILuaAPIFactory.java
index cb0f35500..b8abdfedc 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/lua/ILuaAPIFactory.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/lua/ILuaAPIFactory.java
@@ -5,8 +5,7 @@
package dan200.computercraft.api.lua;
import dan200.computercraft.api.ComputerCraftAPI;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Construct an {@link ILuaAPI} for a computer.
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/media/IMedia.java b/projects/common-api/src/main/java/dan200/computercraft/api/media/IMedia.java
index 1417a8e2f..10c1e006f 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/media/IMedia.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/media/IMedia.java
@@ -14,14 +14,14 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.JukeboxSong;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Represents an item that can be placed in a disk drive and used by a Computer.
*
- * Implement this interface on your {@link Item} class to allow it to be used in the drive. Alternatively, register
- * a {@link MediaProvider}.
+ * Implement this interface on your {@link Item} class to allow it to be used in the drive, or register via
+ * {@code dan200.computercraft.api.media.MediaLookup} (Fabric) or {@code dan200.computercraft.api.media.MediaCapability}
+ * (NeoForge).
*/
public interface IMedia {
/**
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/media/MediaProvider.java b/projects/common-api/src/main/java/dan200/computercraft/api/media/MediaProvider.java
index 6ffd306dd..02d7a3bb4 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/media/MediaProvider.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/media/MediaProvider.java
@@ -5,8 +5,7 @@
package dan200.computercraft.api.media;
import net.minecraft.world.item.ItemStack;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* This interface is used to provide {@link IMedia} implementations for {@link ItemStack}.
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/media/PrintoutContents.java b/projects/common-api/src/main/java/dan200/computercraft/api/media/PrintoutContents.java
index 2825d796c..8284cdd62 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/media/PrintoutContents.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/media/PrintoutContents.java
@@ -6,8 +6,8 @@ package dan200.computercraft.api.media;
import dan200.computercraft.impl.ComputerCraftAPIService;
import net.minecraft.world.item.ItemStack;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.stream.Stream;
/**
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java
index d3b9447c1..aaacd988a 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketAccess.java
@@ -12,8 +12,7 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.ApiStatus;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Wrapper class for pocket computers.
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java
index 2821590c8..afa7198e3 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/pocket/IPocketUpgrade.java
@@ -13,8 +13,7 @@ import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A peripheral which can be equipped to the back side of a pocket computer.
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java
index c726dfc3e..3e2452ad5 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java
@@ -17,8 +17,7 @@ import net.minecraft.world.Container;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.ApiStatus;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* The interface passed to turtle by turtles, providing methods that they can call.
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java
index babc5586b..51988eaac 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleUpgrade.java
@@ -16,8 +16,8 @@ import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Items;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.function.Function;
/**
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleCommandResult.java b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleCommandResult.java
index f048782b9..348e13b5b 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleCommandResult.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleCommandResult.java
@@ -5,8 +5,7 @@
package dan200.computercraft.api.turtle;
import net.minecraft.core.Direction;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Used to indicate the result of executing a turtle command.
@@ -60,9 +59,9 @@ public final class TurtleCommandResult {
private final boolean success;
private final @Nullable String errorMessage;
- private final @Nullable Object[] results;
+ private final @Nullable Object @Nullable [] results;
- private TurtleCommandResult(boolean success, @Nullable String errorMessage, @Nullable Object[] results) {
+ private TurtleCommandResult(boolean success, @Nullable String errorMessage, @Nullable Object @Nullable [] results) {
this.success = success;
this.errorMessage = errorMessage;
this.results = results;
@@ -92,8 +91,7 @@ public final class TurtleCommandResult {
*
* @return The command's result, or {@code null} if it was a failure.
*/
- @Nullable
- public Object[] getResults() {
+ public @Nullable Object @Nullable [] getResults() {
return results;
}
}
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleToolBuilder.java b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleToolBuilder.java
index d1b0cb1c0..38b46fa51 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleToolBuilder.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleToolBuilder.java
@@ -18,8 +18,8 @@ import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Optional;
/**
diff --git a/projects/common-api/src/main/java/dan200/computercraft/impl/ComputerCraftAPIService.java b/projects/common-api/src/main/java/dan200/computercraft/impl/ComputerCraftAPIService.java
index bed8eddab..d6fa12237 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/impl/ComputerCraftAPIService.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/impl/ComputerCraftAPIService.java
@@ -31,8 +31,7 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.ApiStatus;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Backing interface for {@link ComputerCraftAPI}
diff --git a/projects/common-api/src/main/java/dan200/computercraft/impl/ServiceException.java b/projects/common-api/src/main/java/dan200/computercraft/impl/ServiceException.java
index 81f45a6ee..766eddbb8 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/impl/ServiceException.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/impl/ServiceException.java
@@ -5,8 +5,8 @@
package dan200.computercraft.impl;
import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.Serial;
/**
diff --git a/projects/common-api/src/main/java/dan200/computercraft/impl/Services.java b/projects/common-api/src/main/java/dan200/computercraft/impl/Services.java
index 10f9c1a1d..45c1d8a0f 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/impl/Services.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/impl/Services.java
@@ -5,8 +5,8 @@
package dan200.computercraft.impl;
import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java b/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java
index 8df73d864..3f061a678 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java
@@ -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;
/**
diff --git a/projects/common/src/client/java/dan200/computercraft/client/ClientRegistry.java b/projects/common/src/client/java/dan200/computercraft/client/ClientRegistry.java
index 46711d758..2249d6600 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/ClientRegistry.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/ClientRegistry.java
@@ -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;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/ClientTableFormatter.java b/projects/common/src/client/java/dan200/computercraft/client/ClientTableFormatter.java
index d9f02178e..1faed7236 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/ClientTableFormatter.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/ClientTableFormatter.java
@@ -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;
/**
diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java
index 6e4f39020..e2a662ab4 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/gui/AbstractComputerScreen.java
@@ -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;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/GuiSprites.java b/projects/common/src/client/java/dan200/computercraft/client/gui/GuiSprites.java
index 16b84e388..9da1a6120 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/gui/GuiSprites.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/gui/GuiSprites.java
@@ -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;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/NoTermComputerScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/NoTermComputerScreen.java
index 36467a45a..31c47e078 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/gui/NoTermComputerScreen.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/gui/NoTermComputerScreen.java
@@ -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;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/OptionScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/OptionScreen.java
index 0cf39fa21..da9af2540 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/gui/OptionScreen.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/gui/OptionScreen.java
@@ -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;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/PrintoutScreen.java b/projects/common/src/client/java/dan200/computercraft/client/gui/PrintoutScreen.java
index 8df70c395..1a7e7054a 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/gui/PrintoutScreen.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/gui/PrintoutScreen.java
@@ -127,6 +127,7 @@ public final class PrintoutScreen extends AbstractContainerScreen
// Skip rendering labels.
}
+ @SuppressWarnings("ArrayRecordComponent")
record PrintoutInfo(int pages, boolean book, TextBuffer[] text, TextBuffer[] colour) {
public static final PrintoutInfo DEFAULT = of(PrintoutData.EMPTY, false);
diff --git a/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java b/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java
index 11b11694d..d46febe09 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/gui/widgets/DynamicImageButton.java
@@ -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;
/**
diff --git a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/ModelTransformer.java b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/ModelTransformer.java
index 72c7e3bd5..bade1fcdd 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/ModelTransformer.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/ModelTransformer.java
@@ -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;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java
index a6ef119ca..88fdaa24e 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java
@@ -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;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java b/projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java
index 45fc090a2..0458d760f 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/platform/ClientNetworkContextImpl.java
@@ -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;
/**
diff --git a/projects/common/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelper.java b/projects/common/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelper.java
index 665e22da2..03981432b 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelper.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelper.java
@@ -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);
}
diff --git a/projects/common/src/client/java/dan200/computercraft/client/pocket/ClientPocketComputers.java b/projects/common/src/client/java/dan200/computercraft/client/pocket/ClientPocketComputers.java
index c8cde6d79..8ec3d7a13 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/pocket/ClientPocketComputers.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/pocket/ClientPocketComputers.java
@@ -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;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/pocket/PocketComputerData.java b/projects/common/src/client/java/dan200/computercraft/client/pocket/PocketComputerData.java
index d2e5125ef..c12913c78 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/pocket/PocketComputerData.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/pocket/PocketComputerData.java
@@ -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.
diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/ModelRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/ModelRenderer.java
index 4e4019430..a0fa5bcf7 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/render/ModelRenderer.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/render/ModelRenderer.java
@@ -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 quads, int lightmapCoord, int overlayLight, @Nullable int[] tints) {
+ public static void renderQuads(PoseStack transform, VertexConsumer buffer, List quads, int lightmapCoord, int overlayLight, int @Nullable [] tints) {
var matrix = transform.last();
var inverted = matrix.pose().determinant() < 0;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/RenderTypes.java b/projects/common/src/client/java/dan200/computercraft/client/render/RenderTypes.java
index 3868c472d..3fb327c19 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/render/RenderTypes.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/render/RenderTypes.java
@@ -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;
diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java
index 03c2635aa..52ecac60c 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java
@@ -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 {
public static final ResourceLocation COLOUR_TURTLE_MODEL = ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "block/turtle_colour");
@@ -124,7 +123,7 @@ public class TurtleBlockEntityRenderer implements BlockEntityRenderer
diff --git a/projects/common/src/main/java/dan200/computercraft/impl/network/wired/NodeSet.java b/projects/common/src/main/java/dan200/computercraft/impl/network/wired/NodeSet.java
index 9d3f0808e..87994d1e8 100644
--- a/projects/common/src/main/java/dan200/computercraft/impl/network/wired/NodeSet.java
+++ b/projects/common/src/main/java/dan200/computercraft/impl/network/wired/NodeSet.java
@@ -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;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/impl/network/wired/WiredNodeImpl.java b/projects/common/src/main/java/dan200/computercraft/impl/network/wired/WiredNodeImpl.java
index f2ce69288..409fb7ddc 100644
--- a/projects/common/src/main/java/dan200/computercraft/impl/network/wired/WiredNodeImpl.java
+++ b/projects/common/src/main/java/dan200/computercraft/impl/network/wired/WiredNodeImpl.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/CommonHooks.java b/projects/common/src/main/java/dan200/computercraft/shared/CommonHooks.java
index 1602a1e10..8c4e98aca 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/CommonHooks.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/CommonHooks.java
@@ -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) {
+ public static LootPool.@Nullable Builder getExtraLootPool(ResourceKey lootTable) {
if (!TREASURE_DISK_LOOT_TABLES.contains(lootTable)) {
return null;
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java
index b7a7450dc..5ec1ced59 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java
@@ -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 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 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 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 The type of the component.
+ * @param The context parameter to the component.
+ */
+ public interface BlockComponent {
+ void registerForBlockEntity(BlockEntityType blockEntityType, BiFunction super B, C, @Nullable T> provider);
+ }
+
+ /**
+ * An abstraction for registering capabilities/block lookups for items.
+ *
+ * @param The type of the component.
+ */
+ public interface ItemComponent {
+ void registerForItems(BiFunction provider, ItemLike... items);
+
+ void registerFallback(BiFunction provider);
+ }
+
private static void addTurtle(CreativeModeTab.Output out, TurtleItem turtle, HolderLookup.Provider registries) {
out.accept(new ItemStack(turtle));
registries.lookupOrThrow(ITurtleUpgrade.REGISTRY).listElements()
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java b/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java
index 14195412d..95ca1c7fb 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/command/CommandComputerCraft.java
@@ -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.*;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/arguments/ComputerSelector.java b/projects/common/src/main/java/dan200/computercraft/shared/command/arguments/ComputerSelector.java
index 83cc96c93..c5334c379 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/command/arguments/ComputerSelector.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/command/arguments/ComputerSelector.java
@@ -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 options;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/builder/CommandBuilder.java b/projects/common/src/main/java/dan200/computercraft/shared/command/builder/CommandBuilder.java
index 02401973e..5f9372b71 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/command/builder/CommandBuilder.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/command/builder/CommandBuilder.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/builder/HelpingArgumentBuilder.java b/projects/common/src/main/java/dan200/computercraft/shared/command/builder/HelpingArgumentBuilder.java
index 1edf06554..de3ef8f18 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/command/builder/HelpingArgumentBuilder.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/command/builder/HelpingArgumentBuilder.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java b/projects/common/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java
index b307f5414..44549eefa 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java
@@ -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.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/text/ServerTableFormatter.java b/projects/common/src/main/java/dan200/computercraft/shared/command/text/ServerTableFormatter.java
index bd50c7ae3..af2e3e4ed 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/command/text/ServerTableFormatter.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/command/text/ServerTableFormatter.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java b/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java
index dbf719d12..8b3a5f2e2 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableBuilder.java
@@ -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 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;
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableFormatter.java b/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableFormatter.java
index d5a5c9306..d6f5ee145 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableFormatter.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/command/text/TableFormatter.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/common/HorizontalContainerBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/common/HorizontalContainerBlock.java
index 07a1f5472..8931b571c 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/common/HorizontalContainerBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/common/HorizontalContainerBlock.java
@@ -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.
*
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlock.java
index 643b99369..8608ba82a 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlock.java
@@ -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 extends HorizontalDirectionalBlock implements IBundledRedstoneBlock, EntityBlock {
protected final RegistryEntry> type;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java
index 60a2df25a..67df80b03 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlock.java
index 417834708..9da8ecc75 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlock.java
@@ -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 extends AbstractComputerBlock {
private static final MapCodec> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlockEntity.java
index 0879b570f..1cd56979b 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlockEntity.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerPeripheral.java
index 44db65e9f..4d4eb7528 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerPeripheral.java
@@ -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.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ComputerSystem.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ComputerSystem.java
index 7302fcccc..30b2ff5a7 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ComputerSystem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ComputerSystem.java
@@ -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;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java
index c2a351e5e..54fea5803 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java
@@ -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);
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java
index 48154c981..92f2c1735 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java
@@ -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 {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerContext.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerContext.java
index 3131c667a..169b46527 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerContext.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerContext.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/inventory/AbstractComputerMenu.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/inventory/AbstractComputerMenu.java
index 5f8197dce..0567e67e1 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/inventory/AbstractComputerMenu.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/inventory/AbstractComputerMenu.java
@@ -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 {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/items/AbstractComputerItem.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/items/AbstractComputerItem.java
index 56147f132..f41a0a8f6 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/items/AbstractComputerItem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/items/AbstractComputerItem.java
@@ -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);
- }
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/items/CommandComputerItem.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/items/CommandComputerItem.java
index 062bef8ad..c2478a0bb 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/items/CommandComputerItem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/items/CommandComputerItem.java
@@ -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;
- }
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/items/ServerComputerReference.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/items/ServerComputerReference.java
index 250ae30a9..6989d2ccd 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/items/ServerComputerReference.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/items/ServerComputerReference.java
@@ -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;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/menu/ServerInputState.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/menu/ServerInputState.java
index 7a70e76f9..4bfeeba2c 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/menu/ServerInputState.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/menu/ServerInputState.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/ComputerMBean.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/ComputerMBean.java
index 0da446e75..7b03d161e 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/ComputerMBean.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/ComputerMBean.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/basic/BasicComputerMetricsObserver.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/basic/BasicComputerMetricsObserver.java
index 90eefbb64..78beaa60c 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/basic/BasicComputerMetricsObserver.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/basic/BasicComputerMetricsObserver.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/basic/ComputerMetrics.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/basic/ComputerMetrics.java
index 91d63d58e..1ff2b0c2c 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/basic/ComputerMetrics.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/metrics/basic/ComputerMetrics.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/terminal/TerminalState.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/terminal/TerminalState.java
index b7f4d99af..33de1f487 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/terminal/TerminalState.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/terminal/TerminalState.java
@@ -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.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/upload/FileUpload.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/upload/FileUpload.java
index e1d371b99..4648b8161 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/computer/upload/FileUpload.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/upload/FileUpload.java
@@ -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());
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigFile.java b/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigFile.java
index 6f4feed74..cd0c7a396 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigFile.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigFile.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigSpec.java b/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigSpec.java
index c00e386ad..47e30bce2 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigSpec.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/config/ConfigSpec.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/config/ProxyPasswordConfig.java b/projects/common/src/main/java/dan200/computercraft/shared/config/ProxyPasswordConfig.java
index 3c45f64f4..feacea5ed 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/config/ProxyPasswordConfig.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/config/ProxyPasswordConfig.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/container/BasicWorldlyContainer.java b/projects/common/src/main/java/dan200/computercraft/shared/container/BasicWorldlyContainer.java
index e3f389913..6e63254e9 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/container/BasicWorldlyContainer.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/container/BasicWorldlyContainer.java
@@ -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}.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/details/ItemDetails.java b/projects/common/src/main/java/dan200/computercraft/shared/details/ItemDetails.java
index 5f443b98d..dfcfd8caa 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/details/ItemDetails.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/details/ItemDetails.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/integration/PermissionRegistry.java b/projects/common/src/main/java/dan200/computercraft/shared/integration/PermissionRegistry.java
index cb700c05f..9ba20f60a 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/integration/PermissionRegistry.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/integration/PermissionRegistry.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java b/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java
index 792721c6a..2a877e99c 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java
@@ -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 {
private class UpgradeInfo {
final ItemStack stack;
final Ingredient ingredient;
- final @Nullable Holder.Reference turtle;
- final @Nullable Holder.Reference pocket;
+ final Holder.@Nullable Reference turtle;
+ final Holder.@Nullable Reference pocket;
final UpgradeBase upgrade;
private @Nullable ArrayList recipes;
- UpgradeInfo(ItemStack stack, UpgradeBase upgrade, @Nullable Holder.Reference turtle, @Nullable Holder.Reference pocket) {
+ UpgradeInfo(ItemStack stack, UpgradeBase upgrade, Holder.@Nullable Reference turtle, Holder.@Nullable Reference pocket) {
this.stack = stack;
ingredient = Ingredient.of(stack);
this.turtle = turtle;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlock.java
index 43e79ef65..ff8487f6f 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlock.java
@@ -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}.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/media/MountMedia.java b/projects/common/src/main/java/dan200/computercraft/shared/media/MountMedia.java
new file mode 100644
index 000000000..9ffa835b3
--- /dev/null
+++ b/projects/common/src/main/java/dan200/computercraft/shared/media/MountMedia.java
@@ -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> id;
+ private final boolean createId;
+ private final Supplier 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> id,
+ boolean createId,
+ Supplier 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);
+ }
+}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/media/items/DiskItem.java b/projects/common/src/main/java/dan200/computercraft/shared/media/items/DiskItem.java
index 88f16d3e4..aa3bd8735 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/media/items/DiskItem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/media/items/DiskItem.java
@@ -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()));
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/media/items/RecordMedia.java b/projects/common/src/main/java/dan200/computercraft/shared/media/items/RecordMedia.java
index b15e6489e..7c7dc062a 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/media/items/RecordMedia.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/media/items/RecordMedia.java
@@ -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}.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/media/items/TreasureDiskItem.java b/projects/common/src/main/java/dan200/computercraft/shared/media/items/TreasureDiskItem.java
index 86a990863..bfc630921 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/media/items/TreasureDiskItem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/media/items/TreasureDiskItem.java
@@ -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;
- }
- }
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/media/items/TreasureDiskMedia.java b/projects/common/src/main/java/dan200/computercraft/shared/media/items/TreasureDiskMedia.java
new file mode 100644
index 000000000..30c3d5e07
--- /dev/null
+++ b/projects/common/src/main/java/dan200/computercraft/shared/media/items/TreasureDiskMedia.java
@@ -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;
+ }
+ }
+}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/network/client/ClientNetworkContext.java b/projects/common/src/main/java/dan200/computercraft/shared/network/client/ClientNetworkContext.java
index 5dc5bc3f7..7e02c4e4a 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/network/client/ClientNetworkContext.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/network/client/ClientNetworkContext.java
@@ -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;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/network/server/UploadFileMessage.java b/projects/common/src/main/java/dan200/computercraft/shared/network/server/UploadFileMessage.java
index bf4f35de8..e03f60454 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/network/server/UploadFileMessage.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/network/server/UploadFileMessage.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java
index e35080a48..143427420 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java
@@ -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.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlock.java
index ffab6ad79..38ac4b747 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlock.java
@@ -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 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);
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlockEntity.java
index f15fe6d55..fc54a8b7d 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDriveBlockEntity.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java
index 2c1b1630c..0725fa041 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java
@@ -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;
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/MediaStack.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/MediaStack.java
index e3c5a15e8..241bb323c 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/MediaStack.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/MediaStack.java
@@ -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
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/ComponentLookup.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/ComponentLookup.java
index 774faf8d1..340d489a8 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/ComponentLookup.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/ComponentLookup.java
@@ -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
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java
index ee4f1f299..567a3df9d 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheral.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralBuilder.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralBuilder.java
index 67d2ea8c4..f5759e084 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralBuilder.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralBuilder.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralProvider.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralProvider.java
index 1a9d92626..4c094aa7a 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralProvider.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/GenericPeripheralProvider.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/AbstractInventoryMethods.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/AbstractInventoryMethods.java
index e72d9f4de..1769dd53b 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/AbstractInventoryMethods.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/AbstractInventoryMethods.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java
index 7977ed342..58f7fb0aa 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java
index d1e9031b1..816b5a0f8 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java
@@ -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 {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlock.java
index b23cd3d85..961edb6e8 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlock.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockEntity.java
index b491b9888..70c3a2326 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockEntity.java
@@ -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 {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockItem.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockItem.java
index 3878f681e..b19d92969 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockItem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableBlockItem.java
@@ -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.*;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java
index e27749b0e..31a506e77 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/CableModemVariant.java
@@ -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),
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlock.java
index 0ddc14523..4a0023d4b 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlock.java
@@ -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");
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlockEntity.java
index 269743aa8..cbe5aa5f1 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemFullBlockEntity.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemLocalPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemLocalPeripheral.java
index 3893b4ac4..965a4cc63 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemLocalPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemLocalPeripheral.java
@@ -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;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemPeripheral.java
index ce1374b27..b47f4cbcc 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wired/WiredModemPeripheral.java
@@ -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 };
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlock.java
index f9c90612a..49b1d958d 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlock.java
@@ -26,8 +26,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED;
import static dan200.computercraft.shared.util.WaterloggableHelpers.getFluidStateForPlacement;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlockEntity.java
index 3e7e67e26..a7ae03f9e 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/modem/wireless/WirelessModemBlockEntity.java
@@ -16,8 +16,7 @@ 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 javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class WirelessModemBlockEntity extends BlockEntity {
private static class Peripheral extends WirelessModemPeripheral {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ClientMonitor.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ClientMonitor.java
index 850379096..ee2982efb 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ClientMonitor.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ClientMonitor.java
@@ -7,8 +7,8 @@ package dan200.computercraft.shared.peripheral.monitor;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.computer.terminal.NetworkedTerminal;
import dan200.computercraft.shared.computer.terminal.TerminalState;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.function.Supplier;
public final class ClientMonitor {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlock.java
index 36dee39b0..22ace8bdf 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlock.java
@@ -30,8 +30,7 @@ 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 net.minecraft.world.phys.BlockHitResult;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class MonitorBlock extends HorizontalDirectionalBlock implements EntityBlock {
private static final MapCodec CODEC = BlockCodecs.blockWithBlockEntityCodec(MonitorBlock::new, x -> x.type);
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java
index abdfa6cbc..1e8e94d96 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java
@@ -23,10 +23,10 @@ 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.AABB;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.util.function.Consumer;
public class MonitorBlockEntity extends BlockEntity {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java
index c07bfb41e..2c1cf681e 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java
@@ -11,8 +11,7 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.apis.TermMethods;
import dan200.computercraft.core.terminal.Terminal;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Monitors are a block which act as a terminal, displaying information on one side. This allows them to be read and
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorState.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorState.java
index ff8e4b406..7ec271ae6 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorState.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorState.java
@@ -4,7 +4,7 @@
package dan200.computercraft.shared.peripheral.monitor;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
final class MonitorState {
public static final MonitorState UNLOADED = new MonitorState(State.UNLOADED, null);
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java
index b22499490..4f066fe0e 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorWatcher.java
@@ -11,8 +11,8 @@ import dan200.computercraft.shared.network.server.ServerNetworking;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.chunk.LevelChunk;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.ArrayDeque;
import java.util.Optional;
import java.util.Queue;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java
index b7d43b8db..16aaf5cec 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/ServerMonitor.java
@@ -8,8 +8,8 @@ import com.google.common.annotations.VisibleForTesting;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.computer.terminal.NetworkedTerminal;
import dan200.computercraft.shared.util.TickScheduler;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.concurrent.atomic.AtomicBoolean;
public class ServerMonitor {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterBlock.java
index b3b17366d..1c0d2a581 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterBlock.java
@@ -15,8 +15,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
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 javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class PrinterBlock extends HorizontalContainerBlock {
private static final MapCodec CODEC = simpleCodec(PrinterBlock::new);
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterBlockEntity.java
index 549167b3a..6a0cad091 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterBlockEntity.java
@@ -25,8 +25,8 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
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.List;
public final class PrinterBlockEntity extends AbstractContainerBlockEntity implements BasicWorldlyContainer {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java
index 60943702e..c831bb705 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java
@@ -10,8 +10,8 @@ import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.util.StringUtil;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Optional;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlock.java
index 49ef22458..daa964997 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlock.java
@@ -19,7 +19,6 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
-import javax.annotation.Nonnull;
/**
* The block for redstone relays. This mostly just forwards method calls to the {@linkplain RedstoneRelayBlockEntity
@@ -58,13 +57,13 @@ public final class RedstoneRelayBlock extends HorizontalDirectionalBlock impleme
@Override
@Deprecated
- public boolean isSignalSource(@Nonnull BlockState state) {
+ public boolean isSignalSource(BlockState state) {
return true;
}
@Override
@Deprecated
- public int getDirectSignal(@Nonnull BlockState state, BlockGetter level, @Nonnull BlockPos pos, @Nonnull Direction incomingSide) {
+ public int getDirectSignal(BlockState state, BlockGetter level, BlockPos pos, Direction incomingSide) {
return level.getBlockEntity(pos) instanceof RedstoneRelayBlockEntity relay ? relay.getRedstoneOutput(incomingSide.getOpposite()) : 0;
}
@@ -81,7 +80,7 @@ public final class RedstoneRelayBlock extends HorizontalDirectionalBlock impleme
@Override
@Deprecated
- public void neighborChanged(@Nonnull BlockState state, @Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Block neighbourBlock, @Nonnull BlockPos neighbourPos, boolean isMoving) {
+ public void neighborChanged(BlockState state, Level world, BlockPos pos, Block neighbourBlock, BlockPos neighbourPos, boolean isMoving) {
if (world.getBlockEntity(pos) instanceof RedstoneRelayBlockEntity relay) relay.neighborChanged(neighbourPos);
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java
index 7f03cc9cd..74bde1829 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java
@@ -9,9 +9,7 @@ import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.apis.RedstoneAPI;
import dan200.computercraft.core.apis.RedstoneMethods;
import dan200.computercraft.core.redstone.RedstoneAccess;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* The redstone relay is a peripheral that allows reading and outputting redstone signals. While this is not very useful
@@ -46,7 +44,6 @@ public final class RedstoneRelayPeripheral extends RedstoneMethods implements IP
super(access);
}
- @Nonnull
@Override
public String getType() {
return "redstone_relay";
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/DfpwmState.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/DfpwmState.java
index f5988a198..9921fd234 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/DfpwmState.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/DfpwmState.java
@@ -7,8 +7,8 @@ package dan200.computercraft.shared.peripheral.speaker;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaTable;
import dan200.computercraft.shared.util.PauseAwareTimer;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlock.java
index 112060cb3..4f4635b79 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlock.java
@@ -19,8 +19,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.level.block.state.StateDefinition;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class SpeakerBlock extends HorizontalDirectionalBlock implements EntityBlock {
private static final MapCodec CODEC = simpleCodec(SpeakerBlock::new);
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlockEntity.java
index 972f67be5..041f0f212 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerBlockEntity.java
@@ -13,8 +13,7 @@ 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 javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class SpeakerBlockEntity extends BlockEntity {
private final SpeakerPeripheral peripheral;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java
index 8b92b426f..e1b16062e 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java
@@ -30,8 +30,8 @@ import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.*;
import static dan200.computercraft.api.lua.LuaValues.checkFinite;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPosition.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPosition.java
index 1bb33ce78..dc5004208 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPosition.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPosition.java
@@ -11,8 +11,8 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.OptionalInt;
public record SpeakerPosition(@Nullable Level level, Vec3 position, @Nullable Entity entity) {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/platform/ComponentAccess.java b/projects/common/src/main/java/dan200/computercraft/shared/platform/ComponentAccess.java
index 215adefd3..a66c697b7 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/platform/ComponentAccess.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/platform/ComponentAccess.java
@@ -5,8 +5,7 @@
package dan200.computercraft.shared.platform;
import net.minecraft.core.Direction;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A (possibly cached) provider of a component at a specific location.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java
index 67b060f63..00947757f 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java
@@ -6,6 +6,7 @@ package dan200.computercraft.shared.platform;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType;
+import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.impl.Services;
@@ -44,8 +45,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.List;
import java.util.function.Consumer;
@@ -340,4 +341,13 @@ public interface PlatformHelper {
private Instance() {
}
}
+
+ /**
+ * Find a {@link IMedia} instance for an item stack.
+ *
+ * @param stack The stack to look up the media for.
+ * @return The media instance, or {@code null} if not found.
+ */
+ @Nullable
+ IMedia getMedia(ItemStack stack);
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java
index 46f88bc5a..b09bea1ac 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java
@@ -13,8 +13,8 @@ import dan200.computercraft.impl.PocketUpgrades;
import net.minecraft.core.NonNullList;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Objects;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java
index 8ce2a36b0..1150b5c81 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java
@@ -19,8 +19,8 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.DyedItemColor;
import net.minecraft.world.phys.Vec3;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Objects;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java
index 670d29991..efa4a5c24 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java
@@ -14,8 +14,8 @@ import dan200.computercraft.shared.network.server.ServerNetworking;
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.ChunkPos;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Set;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java
index 39f504a6b..4e3690182 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java
@@ -6,8 +6,6 @@ package dan200.computercraft.shared.pocket.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.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.upgrades.UpgradeData;
import dan200.computercraft.core.computer.ComputerSide;
@@ -19,7 +17,6 @@ import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
import dan200.computercraft.shared.computer.core.ServerContext;
import dan200.computercraft.shared.computer.inventory.ComputerMenuWithoutInventory;
import dan200.computercraft.shared.computer.items.ServerComputerReference;
-import dan200.computercraft.shared.config.ConfigSpec;
import dan200.computercraft.shared.network.container.ComputerContainerData;
import dan200.computercraft.shared.platform.PlatformHelper;
import dan200.computercraft.shared.pocket.core.PocketBrain;
@@ -27,7 +24,6 @@ import dan200.computercraft.shared.pocket.core.PocketHolder;
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
import dan200.computercraft.shared.util.*;
import net.minecraft.ChatFormatting;
-import net.minecraft.core.HolderLookup;
import net.minecraft.network.chat.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
@@ -42,12 +38,12 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.List;
import java.util.Objects;
-public class PocketComputerItem extends Item implements IMedia {
+public class PocketComputerItem extends Item {
private final ComputerFamily family;
public PocketComputerItem(Properties settings, ComputerFamily family) {
@@ -95,7 +91,7 @@ public class PocketComputerItem extends Item implements IMedia {
var label = computer.getLabel();
if (!Objects.equals(label, getLabel(stack))) {
changed = true;
- setLabel(stack, label);
+ DataComponentUtil.setCustomName(stack, label);
}
var on = computer.isOn();
@@ -276,26 +272,6 @@ public class PocketComputerItem extends Item implements IMedia {
return DataComponentUtil.getCustomName(stack);
}
- @Override
- public @Nullable String getLabel(HolderLookup.Provider registries, ItemStack stack) {
- return getLabel(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);
- }
-
private static boolean isMarkedOn(ItemStack stack) {
return stack.getOrDefault(ModRegistry.DataComponents.ON.get(), false);
}
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java
index 65a1362ae..8deab5697 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java
@@ -15,8 +15,7 @@ import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemPeripheral;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.item.ItemStack;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class PocketModem extends AbstractPocketUpgrade {
public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java
index bd1d8b289..52fd55ea1 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java
@@ -10,8 +10,7 @@ import dan200.computercraft.shared.peripheral.modem.ModemState;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemPeripheral;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class PocketModemPeripheral extends WirelessModemPeripheral {
private final IPocketAccess access;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java
index 74824fc25..c025dba1e 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeaker.java
@@ -11,8 +11,7 @@ import dan200.computercraft.api.upgrades.UpgradeType;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral;
import net.minecraft.world.item.ItemStack;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class PocketSpeaker extends AbstractPocketUpgrade {
public PocketSpeaker(ItemStack item) {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java
index 58a8df873..6073b7046 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketSpeakerPeripheral.java
@@ -8,8 +8,7 @@ import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.pocket.IPocketAccess;
import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition;
import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class PocketSpeakerPeripheral extends UpgradeSpeakerPeripheral {
private final IPocketAccess access;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/TurtleOverlay.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/TurtleOverlay.java
index 1db355d2f..f0d8127fe 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/TurtleOverlay.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/TurtleOverlay.java
@@ -17,8 +17,7 @@ import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.RegistryFileCodec;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A cosmetic overlay on a turtle.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java
index f879fe3dd..fde53a991 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java
@@ -45,8 +45,7 @@ import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
import static dan200.computercraft.shared.util.WaterloggableHelpers.WATERLOGGED;
import static dan200.computercraft.shared.util.WaterloggableHelpers.getFluidStateForPlacement;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlockEntity.java
index dcb00f289..d5c5bb581 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlockEntity.java
@@ -42,8 +42,8 @@ import net.minecraft.world.item.component.DyedItemColor;
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.Collections;
import java.util.function.IntSupplier;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java
index 1724720a3..396bd7826 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java
@@ -44,8 +44,8 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.material.PushReaction;
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.TimeUnit;
@@ -749,7 +749,7 @@ public class TurtleBrain implements TurtleAccessInternal {
}
private static final class UpgradeInstance {
- private @Nullable Holder.Reference upgrade;
+ private Holder.@Nullable Reference upgrade;
private DataComponentPatch data = DataComponentPatch.EMPTY;
private @Nullable IPeripheral peripheral;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java
index df99a3336..c7b56bff2 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlaceCommand.java
@@ -34,8 +34,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.Vec3;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class TurtlePlaceCommand implements TurtleCommand {
private final InteractDirection direction;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java
index dd12e9829..1ff756451 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java
@@ -17,10 +17,10 @@ import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.item.ItemStack;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.util.UUID;
public final class TurtlePlayer {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleToolCommand.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleToolCommand.java
index 5889056f2..b1c32da54 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleToolCommand.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleToolCommand.java
@@ -5,8 +5,8 @@
package dan200.computercraft.shared.turtle.core;
import dan200.computercraft.api.turtle.*;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Locale;
public class TurtleToolCommand implements TurtleCommand {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/TurtleMenu.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/TurtleMenu.java
index d4709295b..5494617ec 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/TurtleMenu.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/TurtleMenu.java
@@ -21,8 +21,8 @@ import net.minecraft.world.inventory.ContainerData;
import net.minecraft.world.inventory.SimpleContainerData;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.function.Predicate;
public final class TurtleMenu extends AbstractComputerMenu {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeContainer.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeContainer.java
index a8dc08997..7d63770d0 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeContainer.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeContainer.java
@@ -13,8 +13,8 @@ import net.minecraft.core.NonNullList;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeSlot.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeSlot.java
index 4664414c6..5fa0391be 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeSlot.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/inventory/UpgradeSlot.java
@@ -14,8 +14,7 @@ import net.minecraft.world.Container;
import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A slot in the turtle UI which holds the turtle's current upgrade.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java
index 0b73f436e..8b09b3390 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java
@@ -20,8 +20,7 @@ import net.minecraft.network.chat.Component;
import net.minecraft.world.ItemInteractionResult;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.LayeredCauldronBlock;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class TurtleItem extends AbstractComputerItem {
public TurtleItem(TurtleBlock block, Properties settings) {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java
index b22a7ca45..96d77fecf 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java
@@ -10,8 +10,8 @@ import dan200.computercraft.api.lua.MethodResult;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.shared.turtle.core.TurtleCraftCommand;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Optional;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java
index 8a19e396b..6841b0560 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java
@@ -13,8 +13,8 @@ import net.minecraft.world.item.crafting.CraftingInput;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.Level;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java
index 6af5efe60..7f91cada4 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java
@@ -19,8 +19,7 @@ import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class TurtleModem extends AbstractTurtleUpgrade {
public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java
index 8c08e8763..67602d5bd 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleSpeaker.java
@@ -15,8 +15,7 @@ import dan200.computercraft.shared.peripheral.speaker.SpeakerPosition;
import dan200.computercraft.shared.peripheral.speaker.UpgradeSpeakerPeripheral;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class TurtleSpeaker extends AbstractTurtleUpgrade {
private static class Peripheral extends UpgradeSpeakerPeripheral {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java
index 65c059fc5..b12cc6959 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleTool.java
@@ -44,8 +44,8 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.GameMasterBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.EntityHitResult;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.function.Function;
public class TurtleTool extends AbstractTurtleUpgrade {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/BlockEntityHelpers.java b/projects/common/src/main/java/dan200/computercraft/shared/util/BlockEntityHelpers.java
index 4e70c55ec..da68ee0a7 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/BlockEntityHelpers.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/BlockEntityHelpers.java
@@ -8,8 +8,7 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public final class BlockEntityHelpers {
private BlockEntityHelpers() {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/ColourUtils.java b/projects/common/src/main/java/dan200/computercraft/shared/util/ColourUtils.java
index 8f66a6a0a..e00f9f65b 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/ColourUtils.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/ColourUtils.java
@@ -9,8 +9,8 @@ import net.minecraft.tags.TagKey;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.List;
public final class ColourUtils {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/ConsList.java b/projects/common/src/main/java/dan200/computercraft/shared/util/ConsList.java
index 909959642..67c0bdfc8 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/ConsList.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/ConsList.java
@@ -4,7 +4,7 @@
package dan200.computercraft.shared.util;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import java.util.AbstractList;
import java.util.Iterator;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/DataComponentUtil.java b/projects/common/src/main/java/dan200/computercraft/shared/util/DataComponentUtil.java
index 7ec99eeca..a78d84b32 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/DataComponentUtil.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/DataComponentUtil.java
@@ -12,8 +12,8 @@ import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;
import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.function.Predicate;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/DropConsumer.java b/projects/common/src/main/java/dan200/computercraft/shared/util/DropConsumer.java
index c287b3891..731e3935c 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/DropConsumer.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/DropConsumer.java
@@ -11,8 +11,8 @@ import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/IDAssigner.java b/projects/common/src/main/java/dan200/computercraft/shared/util/IDAssigner.java
index 30c17f2a0..d2d3408eb 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/IDAssigner.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/IDAssigner.java
@@ -7,10 +7,10 @@ package dan200.computercraft.shared.util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Reader;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/InventoryUtil.java b/projects/common/src/main/java/dan200/computercraft/shared/util/InventoryUtil.java
index bf1fc1b38..717b53d62 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/InventoryUtil.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/InventoryUtil.java
@@ -17,8 +17,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.Vec3;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public final class InventoryUtil {
private InventoryUtil() {
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/NBTUtil.java b/projects/common/src/main/java/dan200/computercraft/shared/util/NBTUtil.java
index e27dfd2a2..b4f65ceef 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/NBTUtil.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/NBTUtil.java
@@ -10,10 +10,10 @@ import com.mojang.serialization.Codec;
import dan200.computercraft.core.util.Nullability;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.*;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/NonNegativeId.java b/projects/common/src/main/java/dan200/computercraft/shared/util/NonNegativeId.java
index 3e9a71926..183dd3f92 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/NonNegativeId.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/NonNegativeId.java
@@ -13,8 +13,7 @@ import net.minecraft.network.codec.StreamCodec;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.item.ItemStack;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A non-negative integer id, used for computer and disk ids.
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/PrettyJsonWriter.java b/projects/common/src/main/java/dan200/computercraft/shared/util/PrettyJsonWriter.java
index d52459acc..30b91bf3d 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/PrettyJsonWriter.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/PrettyJsonWriter.java
@@ -11,8 +11,8 @@ import com.google.gson.JsonSyntaxException;
import com.google.gson.stream.JsonWriter;
import net.minecraft.data.DataProvider;
import net.minecraft.util.GsonHelper;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/StorageCapacity.java b/projects/common/src/main/java/dan200/computercraft/shared/util/StorageCapacity.java
index 369b7d6c9..181ab2598 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/StorageCapacity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/StorageCapacity.java
@@ -12,8 +12,8 @@ import dan200.computercraft.shared.config.ConfigSpec;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.function.Supplier;
/**
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/WorldUtil.java b/projects/common/src/main/java/dan200/computercraft/shared/util/WorldUtil.java
index c86dd0dd7..2d619985f 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/util/WorldUtil.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/util/WorldUtil.java
@@ -24,8 +24,7 @@ import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public final class WorldUtil {
@SuppressWarnings("deprecation")
diff --git a/projects/common/src/main/resources/assets/computercraft/lang/de_de.json b/projects/common/src/main/resources/assets/computercraft/lang/de_de.json
index 3f95d19d0..c4a6dbe43 100644
--- a/projects/common/src/main/resources/assets/computercraft/lang/de_de.json
+++ b/projects/common/src/main/resources/assets/computercraft/lang/de_de.json
@@ -99,24 +99,70 @@
"gui.computercraft.config.http.enabled": "HTTP-API aktivieren",
"gui.computercraft.config.http.max_requests": "Maximale Anzahl gleichzeitiger Anfragen",
"gui.computercraft.config.http.max_websockets": "Maximale Anzahl gleichzeitiger Websockets",
+ "gui.computercraft.config.http.max_websockets.tooltip": "Die Anzahl der Websockets die ein Computer gleichzeitig öffnen kann.",
+ "gui.computercraft.config.http.proxy": "Proxy",
+ "gui.computercraft.config.http.proxy.host": "Hostname",
+ "gui.computercraft.config.http.proxy.host.tooltip": "Der Hostname oder die IP-Adresse des Proxy-Servers.",
+ "gui.computercraft.config.http.proxy.port": "Port",
+ "gui.computercraft.config.http.proxy.port.tooltip": "Der Port des Proxy-Servers.",
+ "gui.computercraft.config.http.proxy.type": "Proxy-Typ",
+ "gui.computercraft.config.http.proxy.type.tooltip": "Der Typ des zu verwendenden Proxys.",
+ "gui.computercraft.config.http.rules": "Regeln zulassen/verweigern",
+ "gui.computercraft.config.http.tooltip": "Kontrolliert die HTTP-API",
"gui.computercraft.config.http.websocket_enabled": "Websockets aktivieren",
+ "gui.computercraft.config.http.websocket_enabled.tooltip": "Aktiviere die Verwendung von http Websockets. Dies erfordert auch die \"http_enable\"-Option, um wahr zu sein.",
"gui.computercraft.config.log_computer_errors": "Computerfehler loggen",
"gui.computercraft.config.maximum_open_files": "Maximalanzahl an gleichzeitig offenen Dateien je Computer",
+ "gui.computercraft.config.maximum_open_files.tooltip": "Legen Sie fest, wie viele Dateien gleichzeitig geöffnet werden können. Setzen Sie auf 0 für unbegrenzt.",
"gui.computercraft.config.peripheral": "Peripheriegeräte",
"gui.computercraft.config.peripheral.command_block_enabled": "Befehlsblöcke als Peripheriegerät erlauben",
+ "gui.computercraft.config.peripheral.command_block_enabled.tooltip": "Befehlsblock Peripherie Unterstützung aktivieren",
"gui.computercraft.config.peripheral.max_notes_per_tick": "Maximalanzahl an Noten, die ein Computer gleichzeitig spielen kann",
"gui.computercraft.config.peripheral.modem_high_altitude_range": "Modemreichweite (in großer Höhe)",
"gui.computercraft.config.peripheral.modem_high_altitude_range_during_storm": "Modemreichweite (in großer Höhe bei schlechtem Wetter)",
"gui.computercraft.config.peripheral.modem_range": "Modemreichweite (normal)",
"gui.computercraft.config.peripheral.modem_range_during_storm": "Modemreichweite (bei schlechtem Wetter)",
+ "gui.computercraft.config.term_sizes": "Terminalgröße",
+ "gui.computercraft.config.term_sizes.computer": "Computer",
+ "gui.computercraft.config.term_sizes.computer.height": "Terminalhöhe",
+ "gui.computercraft.config.term_sizes.computer.height.tooltip": "Höhe des Computerterminals",
+ "gui.computercraft.config.term_sizes.computer.tooltip": "Terminal Größe der Computer.",
+ "gui.computercraft.config.term_sizes.computer.width": "Terminalbreite",
+ "gui.computercraft.config.term_sizes.computer.width.tooltip": "Breite des Computerterminals",
+ "gui.computercraft.config.term_sizes.monitor": "Monitor",
+ "gui.computercraft.config.term_sizes.monitor.height": "Maximale Monitorhöhe",
+ "gui.computercraft.config.term_sizes.monitor.height.tooltip": "Maximale Höhe der Monitore",
+ "gui.computercraft.config.term_sizes.monitor.tooltip": "Maximale Größe der Monitore (in Blöcken).",
+ "gui.computercraft.config.term_sizes.monitor.width": "Maximale Monitorbreite",
+ "gui.computercraft.config.term_sizes.monitor.width.tooltip": "Maximale Breite der Monitore",
+ "gui.computercraft.config.term_sizes.pocket_computer": "Taschencomputer",
+ "gui.computercraft.config.term_sizes.pocket_computer.height": "Terminalhöhe",
+ "gui.computercraft.config.term_sizes.pocket_computer.height.tooltip": "Höhe des Taschenrechnerterminals",
+ "gui.computercraft.config.term_sizes.pocket_computer.tooltip": "Terminal Größe der Taschencomputer.",
+ "gui.computercraft.config.term_sizes.pocket_computer.width": "Terminalbreite",
+ "gui.computercraft.config.term_sizes.pocket_computer.width.tooltip": "Breite des Taschencomputer-Terminals",
"gui.computercraft.config.turtle": "Turtles",
"gui.computercraft.config.turtle.advanced_fuel_limit": "Treibstofflimit von Erweiterten Turtles",
"gui.computercraft.config.turtle.can_push": "Turtles können Entities bewegen",
"gui.computercraft.config.turtle.need_fuel": "Treibstoffverbrauch aktivieren",
"gui.computercraft.config.turtle.normal_fuel_limit": "Treibstofflimit von Turtles",
+ "gui.computercraft.terminal": "Computerterminal",
"gui.computercraft.tooltip.computer_id": "Computer ID: %s",
"gui.computercraft.tooltip.copy": "In die Zwischenablage kopieren",
"gui.computercraft.tooltip.disk_id": "Disketten ID: %s",
+ "gui.computercraft.tooltip.terminate.key": "Strg+T halten",
+ "gui.computercraft.tooltip.turn_off": "Computer ausschalten",
+ "gui.computercraft.tooltip.turn_off.key": "Strg+S halten",
+ "gui.computercraft.tooltip.turn_on": "Diesen Computer einschalten",
+ "gui.computercraft.upload.failed": "Fehler beim Upload",
+ "gui.computercraft.upload.failed.computer_off": "Sie müssen den Computer einschalten, bevor Sie Dateien hochladen.",
+ "gui.computercraft.upload.failed.corrupted": "Dateien beim Hochladen beschädigt. Bitte versuchen Sie es erneut.",
+ "gui.computercraft.upload.failed.generic": "Hochladen der Dateien fehlgeschlagen (%s)",
+ "gui.computercraft.upload.failed.name_too_long": "Dateinamen sind zu lang um hochgeladen zu werden.",
+ "gui.computercraft.upload.failed.too_many_files": "Kann nicht so viele Dateien hochladen.",
+ "gui.computercraft.upload.failed.too_much": "Ihre Dateien sind zu groß, um hochgeladen zu werden.",
+ "gui.computercraft.upload.no_response": "Dateien übertragen",
+ "gui.computercraft.upload.no_response.msg": "Ihr Computer hat Ihre übertragenen Dateien nicht verwendet. Eventuell müssen Sie das %s Programm ausführen und erneut versuchen.",
"item.computercraft.disk": "Diskette",
"item.computercraft.pocket_computer_advanced": "Erweiterter Taschencomputer",
"item.computercraft.pocket_computer_advanced.upgraded": "Erweiterter Taschencomputer (%s)",
@@ -127,10 +173,20 @@
"item.computercraft.printed_pages": "Gedruckte Seiten",
"item.computercraft.treasure_disk": "Diskette",
"itemGroup.computercraft": "ComputerCraft",
+ "tag.item.computercraft.computer": "Computer",
+ "tag.item.computercraft.monitor": "Monitore",
+ "tag.item.computercraft.turtle": "Turtles",
+ "tag.item.computercraft.wired_modem": "Verkabelte Modems",
+ "tracking_field.computercraft.avg": "%s (Durchschn.)",
+ "tracking_field.computercraft.computer_tasks.name": "Aufgaben",
+ "tracking_field.computercraft.count": "%s (Anzahl)",
"tracking_field.computercraft.fs.name": "Dateisystem Operationen",
"tracking_field.computercraft.http_download.name": "HTTP Download",
+ "tracking_field.computercraft.http_requests.name": "HTTP-Anfragen",
"tracking_field.computercraft.http_upload.name": "HTTP Upload",
+ "tracking_field.computercraft.max": "%s (max)",
"tracking_field.computercraft.peripheral.name": "Peripheriegeräte Aufrufe",
+ "tracking_field.computercraft.server_tasks.name": "Server-Aufgaben",
"tracking_field.computercraft.turtle_ops.name": "Turtle Operationen",
"tracking_field.computercraft.websocket_incoming.name": "Websocket eingehend",
"tracking_field.computercraft.websocket_outgoing.name": "Websocket ausgehend",
diff --git a/projects/common/src/main/resources/assets/computercraft/lang/pl_pl.json b/projects/common/src/main/resources/assets/computercraft/lang/pl_pl.json
index b899719cd..0f2f39809 100644
--- a/projects/common/src/main/resources/assets/computercraft/lang/pl_pl.json
+++ b/projects/common/src/main/resources/assets/computercraft/lang/pl_pl.json
@@ -1,5 +1,14 @@
{
"argument.computercraft.argument_expected": "Argument oczekiwany",
+ "argument.computercraft.computer.distance": "Odległość od obiektu",
+ "argument.computercraft.computer.family": "Rodzina komputerów",
+ "argument.computercraft.computer.id": "ID komputera",
+ "argument.computercraft.computer.instance": "Unikalne ID instancji",
+ "argument.computercraft.computer.label": "Etykieta komputera",
+ "argument.computercraft.computer.many_matching": "Wiele komputerów pasuje do '%s' (%s instancji)",
+ "argument.computercraft.computer.no_matching": "Żaden komputer nie pasuje do '%s'",
+ "argument.computercraft.tracking_field.no_field": "Nieznane pole '%s'",
+ "argument.computercraft.unknown_computer_family": "Nieznana rodzina komputerów '%s'",
"block.computercraft.cable": "Kabel Sieciowy",
"block.computercraft.computer_advanced": "Zaawansowany Komputer",
"block.computercraft.computer_command": "Komputer Komendowy",
@@ -8,9 +17,17 @@
"block.computercraft.monitor_advanced": "Zaawansowany Monitor",
"block.computercraft.monitor_normal": "Monitor",
"block.computercraft.printer": "Drukarka",
+ "block.computercraft.redstone_relay": "Przekaźnik redstone",
"block.computercraft.speaker": "Głośnik",
+ "block.computercraft.turtle_advanced": "Zaawansowany Żółw",
+ "block.computercraft.turtle_advanced.upgraded": "Zaawansowany Żółw %s",
+ "block.computercraft.turtle_advanced.upgraded_twice": "Zaawansowany %s Żółw %s",
+ "block.computercraft.turtle_normal": "Żółw",
+ "block.computercraft.turtle_normal.upgraded": "Żółw %s",
+ "block.computercraft.turtle_normal.upgraded_twice": "%s Żółw %s",
"block.computercraft.wired_modem": "Adapter Sieciowy",
"block.computercraft.wired_modem_full": "Adapter Sieciowy",
+ "block.computercraft.wireless_modem_advanced": "Enderowy modem",
"block.computercraft.wireless_modem_normal": "Bezprzewodowy Adapter Sieciowy",
"chat.computercraft.wired_modem.peripheral_connected": "Urządzenie \"%s\" zostało podłączone do sieci",
"chat.computercraft.wired_modem.peripheral_disconnected": "Urządzenie \"%s\" zostało odłączone od sieci",
@@ -19,7 +36,11 @@
"commands.computercraft.dump.desc": "Wyświetla status wszystkich komputerów lub informacje o jednym komputerze. Możesz wybrać numer sesji komputera (np. 123), ID komputera (np. #123) lub jego etykietę (np. \"@Mój Komputer\").",
"commands.computercraft.dump.open_path": "PrzeglÄ…daj pliki tego komputera",
"commands.computercraft.dump.synopsis": "Wyświetl stan komputerów.",
+ "commands.computercraft.generic.additional_rows": "%d dodatkowych wierszy…",
+ "commands.computercraft.generic.exception": "Nieobsłużony wyjątek (%s)",
+ "commands.computercraft.generic.no": "N",
"commands.computercraft.generic.yes": "T",
+ "commands.computercraft.help.desc": "Wyświetla tę wiadomość pomocy",
"commands.computercraft.help.no_children": "%s nie ma pod-komend",
"commands.computercraft.help.no_command": "Nie odnaleziono komendy '%s'",
"commands.computercraft.help.synopsis": "Uzyskaj pomoc do konkretnej komendy",
@@ -35,6 +56,33 @@
"commands.computercraft.turn_on.done": "Włączono %s z %s komputerów",
"commands.computercraft.turn_on.synopsis": "Zdalnie włącz komputery.",
"commands.computercraft.view.synopsis": "Wyświetl ekran komputera.",
+ "gui.computercraft.config.computer_space_limit": "Limit przestrzeni komputerowej (bajty)",
+ "gui.computercraft.config.computer_space_limit.tooltip": "Pojemność dysku komputerów i żółwi podana w bajtach.",
+ "gui.computercraft.config.default_computer_settings": "Domyślne ustawienia komputerów",
+ "gui.computercraft.config.execution": "Wykonywanie",
+ "gui.computercraft.config.execution.computer_threads": "WÄ…tki komputera",
+ "gui.computercraft.config.execution.computer_threads.tooltip": "Ustaw liczbę wątków, na których działają komputery. Większa liczba oznacza, że więcej komputerów\nmoże działać jednocześnie, ale może powodować opóźnienia. Należy pamiętać, że niektóre modyfikacje mogą\nnie działać z liczbą wątków większą niż 1. Używaj ostrożnie.",
+ "gui.computercraft.config.http": "HTTP",
+ "gui.computercraft.config.http.bandwidth": "Przepustowość",
+ "gui.computercraft.config.http.bandwidth.global_download": "Globalny limit pobierania",
+ "gui.computercraft.config.http.bandwidth.global_download.tooltip": "Liczba bajtów, które mogą być pobrane w sekundę. Wartość jest współdzielona między wszystkimi komputerami. (bajty/s).",
+ "gui.computercraft.config.http.bandwidth.global_upload": "Globalny limit wysyłania",
+ "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "Liczba bajtów, które mogą być wysłane w sekundę. Wartość jest współdzielona między wszystkimi komputerami. (bajty/s).",
+ "gui.computercraft.config.http.bandwidth.tooltip": "Nadaje ograniczenie przepustowości na komputery.",
+ "gui.computercraft.config.http.proxy": "Proxy",
+ "gui.computercraft.config.http.proxy.host": "Nazwa hosta",
+ "gui.computercraft.config.http.proxy.host.tooltip": "Nazwa hosta lub adres IP serwera proxy.",
+ "gui.computercraft.config.http.proxy.port": "Port",
+ "gui.computercraft.config.http.proxy.port.tooltip": "Port serwera proxy.",
+ "gui.computercraft.config.http.tooltip": "ZarzÄ…dza API HTTP",
+ "gui.computercraft.config.http.websocket_enabled.tooltip": "Włącz używanie websocketów http. Wymaga włączenia opcji \"http_enable\".",
+ "gui.computercraft.config.log_computer_errors": "Loguj błędy komputerów",
+ "gui.computercraft.config.maximum_open_files": "Maksymalna liczba plików otwartych przez komputer",
+ "gui.computercraft.config.monitor_distance": "Zasięg monitorów",
+ "gui.computercraft.config.monitor_renderer": "Renderer monitorów",
+ "gui.computercraft.config.peripheral.monitor_bandwidth": "Przepustowość monitorów",
+ "gui.computercraft.config.peripheral.monitor_bandwidth.tooltip": "Limit ile danych może być przesyłane do monitora *na tick*. Uwaga:\n - Przepustowość jest mierzona przed kompresją, więc ilość danych wysyłanych\n do klienta jest mniejsza.\n - To ustawienie ignoruje liczbę graczy, do których pakiet jest wysyłany. Aktualizacja\n monitora dla jednego gracza zużywa ten sam limit przepustowości co wysyłanie do 20.\n - Pełnowymiarowy monitor wysyła ~25kb danych. Zatem domyślna wartość (1MB)\n pozwala na aktualizację ~40 monitorów w pojedynczym ticku.\nUstaw wartość na 0 aby wyłączyć.",
+ "gui.computercraft.config.peripheral.tooltip": "Różne opcje dotyczące urządzeń peryferyjnych.",
"item.computercraft.disk": "Dyskietka",
"item.computercraft.pocket_computer_advanced": "Zaawansowany Komputer Przenośny",
"item.computercraft.pocket_computer_normal": "Komputer Przenośny",
@@ -43,5 +91,14 @@
"item.computercraft.printed_page": "Wydrukowana Strona",
"item.computercraft.printed_pages": "Wydrukowane Strony",
"item.computercraft.treasure_disk": "Dyskietka",
- "itemGroup.computercraft": "ComputerCraft"
+ "itemGroup.computercraft": "ComputerCraft",
+ "upgrade.computercraft.speaker.adjective": "Hałaśliwy",
+ "upgrade.computercraft.wireless_modem_advanced.adjective": "Enderowy",
+ "upgrade.computercraft.wireless_modem_normal.adjective": "Bezprzewodowy",
+ "upgrade.minecraft.crafting_table.adjective": "Rzemieślniczy",
+ "upgrade.minecraft.diamond_axe.adjective": "RÄ…biÄ…cy",
+ "upgrade.minecraft.diamond_hoe.adjective": "Rolny",
+ "upgrade.minecraft.diamond_pickaxe.adjective": "Górniczy",
+ "upgrade.minecraft.diamond_shovel.adjective": "KopiÄ…cy",
+ "upgrade.minecraft.diamond_sword.adjective": "Bojowy"
}
diff --git a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java
index 7eee90dff..bdcac484f 100644
--- a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java
+++ b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java
@@ -7,6 +7,8 @@ package dan200.computercraft;
import com.google.auto.service.AutoService;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType;
+import dan200.computercraft.api.media.IMedia;
+import dan200.computercraft.api.media.MediaProvider;
import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.impl.AbstractComputerCraftAPI;
@@ -18,8 +20,8 @@ import net.minecraft.commands.synchronization.ArgumentTypeInfo;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Registry;
-import net.minecraft.network.chat.Component;
import net.minecraft.network.RegistryFriendlyByteBuf;
+import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
@@ -40,8 +42,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.List;
import java.util.function.Consumer;
@@ -147,6 +149,11 @@ public class TestPlatformHelper extends AbstractComputerCraftAPI implements Plat
throw new UnsupportedOperationException("Cannot interact with the world inside tests");
}
+ @Override
+ public @Nullable IMedia getMedia(ItemStack stack) {
+ return null;
+ }
+
@Override
public ContainerTransfer.Slotted wrapContainer(Container container) {
throw new UnsupportedOperationException("Cannot wrap container");
@@ -158,6 +165,11 @@ public class TestPlatformHelper extends AbstractComputerCraftAPI implements Plat
throw new UnsupportedOperationException("Cannot interact with the world inside tests");
}
+ @Override
+ public void registerMediaProvider(MediaProvider provider) {
+ throw new UnsupportedOperationException("Cannot register media providers inside tests");
+ }
+
@Override
public String getInstalledVersion() {
return "1.0";
diff --git a/projects/common/src/test/java/dan200/computercraft/impl/network/wired/NetworkTest.java b/projects/common/src/test/java/dan200/computercraft/impl/network/wired/NetworkTest.java
index 2c459ac18..686303698 100644
--- a/projects/common/src/test/java/dan200/computercraft/impl/network/wired/NetworkTest.java
+++ b/projects/common/src/test/java/dan200/computercraft/impl/network/wired/NetworkTest.java
@@ -10,9 +10,9 @@ import dan200.computercraft.api.network.wired.WiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
-import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
diff --git a/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java b/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java
index c9e537a0c..f963e29c2 100644
--- a/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java
+++ b/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java
@@ -15,11 +15,11 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.gametest.core.TestHooks;
-import dan200.computercraft.shared.util.RegistryHelper;
import dan200.computercraft.shared.util.PrettyJsonWriter;
+import dan200.computercraft.shared.util.RegistryHelper;
import net.minecraft.client.Minecraft;
-import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.client.gui.GuiGraphics;
+import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeType;
diff --git a/projects/common/src/testMod/java/dan200/computercraft/gametest/api/ComputerState.java b/projects/common/src/testMod/java/dan200/computercraft/gametest/api/ComputerState.java
index 82a15b1f7..bf1693231 100644
--- a/projects/common/src/testMod/java/dan200/computercraft/gametest/api/ComputerState.java
+++ b/projects/common/src/testMod/java/dan200/computercraft/gametest/api/ComputerState.java
@@ -7,8 +7,8 @@ package dan200.computercraft.gametest.api;
import dan200.computercraft.gametest.core.TestAPI;
import net.minecraft.gametest.framework.GameTestAssertException;
import net.minecraft.gametest.framework.GameTestSequence;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
diff --git a/projects/common/src/testMod/java/dan200/computercraft/gametest/core/CCTestCommand.java b/projects/common/src/testMod/java/dan200/computercraft/gametest/core/CCTestCommand.java
index faa1e5120..4e2ed1c27 100644
--- a/projects/common/src/testMod/java/dan200/computercraft/gametest/core/CCTestCommand.java
+++ b/projects/common/src/testMod/java/dan200/computercraft/gametest/core/CCTestCommand.java
@@ -12,9 +12,9 @@ import dan200.computercraft.shared.util.NonNegativeId;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
-import net.minecraft.core.component.DataComponents;
import net.minecraft.commands.arguments.item.ItemArgument;
import net.minecraft.commands.arguments.item.ItemInput;
+import net.minecraft.core.component.DataComponents;
import net.minecraft.gametest.framework.GameTestRegistry;
import net.minecraft.gametest.framework.StructureUtils;
import net.minecraft.nbt.CompoundTag;
diff --git a/projects/common/src/testMod/java/dan200/computercraft/gametest/core/TestAPI.java b/projects/common/src/testMod/java/dan200/computercraft/gametest/core/TestAPI.java
index 0ae3a2847..d2887bb90 100644
--- a/projects/common/src/testMod/java/dan200/computercraft/gametest/core/TestAPI.java
+++ b/projects/common/src/testMod/java/dan200/computercraft/gametest/core/TestAPI.java
@@ -11,10 +11,10 @@ import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.gametest.api.ComputerState;
import dan200.computercraft.gametest.api.TestExtensionsKt;
import net.minecraft.gametest.framework.GameTestSequence;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.util.Optional;
/**
diff --git a/projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/client/MinecraftMixin.java b/projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/client/MinecraftMixin.java
index 743314d51..0711bbe1f 100644
--- a/projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/client/MinecraftMixin.java
+++ b/projects/common/src/testMod/java/dan200/computercraft/mixin/gametest/client/MinecraftMixin.java
@@ -9,6 +9,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.LevelRenderer;
+import org.jspecify.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -17,7 +18,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import javax.annotation.Nullable;
import java.util.concurrent.atomic.AtomicBoolean;
@Mixin(Minecraft.class)
diff --git a/projects/core-api/build.gradle.kts b/projects/core-api/build.gradle.kts
index 2005b8695..9d75f4b0d 100644
--- a/projects/core-api/build.gradle.kts
+++ b/projects/core-api/build.gradle.kts
@@ -23,3 +23,5 @@ tasks.javadoc {
// Depend on the common API when publishing javadoc
classpath += docApi.get()
}
+
+cct.linters(minecraft = false, loader = null)
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/filesystem/FileAttributes.java b/projects/core-api/src/main/java/dan200/computercraft/api/filesystem/FileAttributes.java
index 256ac8529..a2010b9c3 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/filesystem/FileAttributes.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/filesystem/FileAttributes.java
@@ -4,7 +4,8 @@
package dan200.computercraft.api.filesystem;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/filesystem/FileOperationException.java b/projects/core-api/src/main/java/dan200/computercraft/api/filesystem/FileOperationException.java
index 9d3ac4260..48656f43e 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/filesystem/FileOperationException.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/filesystem/FileOperationException.java
@@ -4,7 +4,8 @@
package dan200.computercraft.api.filesystem;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.io.IOException;
import java.io.Serial;
import java.util.Objects;
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/IArguments.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/IArguments.java
index 5acf256c4..5f8479a45 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/IArguments.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/IArguments.java
@@ -5,8 +5,8 @@
package dan200.computercraft.api.lua;
import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Optional;
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/ILuaAPI.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/ILuaAPI.java
index 4b28fd245..3f98e27a3 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/ILuaAPI.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/ILuaAPI.java
@@ -4,7 +4,7 @@
package dan200.computercraft.api.lua;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Represents a Lua object which is stored as a global variable on computer startup. This must either provide
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/ILuaCallback.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/ILuaCallback.java
index 0a9e25066..292b2d338 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/ILuaCallback.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/ILuaCallback.java
@@ -4,6 +4,8 @@
package dan200.computercraft.api.lua;
+import org.jspecify.annotations.Nullable;
+
/**
* A continuation which is called when this coroutine is resumed.
*
@@ -18,5 +20,5 @@ public interface ILuaCallback {
* @return The result of this continuation. Either the result to return to the callee, or another yield.
* @throws LuaException On an error.
*/
- MethodResult resume(Object[] args) throws LuaException;
+ MethodResult resume(@Nullable Object[] args) throws LuaException;
}
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaException.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaException.java
index c6d4371f2..aaef1cf01 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaException.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaException.java
@@ -4,7 +4,8 @@
package dan200.computercraft.api.lua;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.io.Serial;
/**
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaTable.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaTable.java
index b3a996820..006f6f51d 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaTable.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaTable.java
@@ -4,7 +4,8 @@
package dan200.computercraft.api.lua;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.util.Map;
import static dan200.computercraft.api.lua.LuaValues.*;
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaTask.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaTask.java
index c49473b07..045339014 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaTask.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaTask.java
@@ -4,7 +4,7 @@
package dan200.computercraft.api.lua;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A task which can be executed via {@link ILuaContext#issueMainThreadTask(LuaTask)} This will be run on the main
@@ -24,5 +24,5 @@ public interface LuaTask {
* arguments are supplied to your method.
*/
@Nullable
- Object[] execute() throws LuaException;
+ Object @Nullable [] execute() throws LuaException;
}
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaValues.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaValues.java
index ee710995a..61ec3635e 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaValues.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/LuaValues.java
@@ -4,7 +4,8 @@
package dan200.computercraft.api.lua;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.nio.ByteBuffer;
import java.util.Map;
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/MethodResult.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/MethodResult.java
index 8b834f54c..b861307e3 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/MethodResult.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/MethodResult.java
@@ -5,8 +5,8 @@
package dan200.computercraft.api.lua;
import dan200.computercraft.api.peripheral.IComputerAccess;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.*;
@@ -19,17 +19,17 @@ import java.util.*;
public final class MethodResult {
private static final MethodResult empty = new MethodResult(null, null);
- private final @Nullable Object[] result;
+ private final @Nullable Object @Nullable [] result;
private final @Nullable ILuaCallback callback;
private final int adjust;
- private MethodResult(@Nullable Object[] arguments, @Nullable ILuaCallback callback) {
+ private MethodResult(@Nullable Object @Nullable [] arguments, @Nullable ILuaCallback callback) {
result = arguments;
this.callback = callback;
adjust = 0;
}
- private MethodResult(@Nullable Object[] arguments, @Nullable ILuaCallback callback, int adjust) {
+ private MethodResult(@Nullable Object @Nullable [] arguments, @Nullable ILuaCallback callback, int adjust) {
result = arguments;
this.callback = callback;
this.adjust = adjust;
@@ -73,7 +73,7 @@ public final class MethodResult {
* @param values The values to return. See {@link #of(Object)} for acceptable values.
* @return A method result which returns immediately with the given values.
*/
- public static MethodResult of(@Nullable Object... values) {
+ public static MethodResult of(@Nullable Object @Nullable ... values) {
return values == null || values.length == 0 ? empty : new MethodResult(values, null);
}
@@ -121,13 +121,12 @@ public final class MethodResult {
* @see #pullEvent(String, ILuaCallback)
*/
@SuppressWarnings("NamedLikeContextualKeyword")
- public static MethodResult yield(@Nullable Object[] arguments, ILuaCallback callback) {
+ public static MethodResult yield(@Nullable Object @Nullable [] arguments, ILuaCallback callback) {
Objects.requireNonNull(callback, "callback cannot be null");
return new MethodResult(arguments, callback);
}
- @Nullable
- public Object[] getResult() {
+ public @Nullable Object @Nullable [] getResult() {
return result;
}
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/ObjectArguments.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/ObjectArguments.java
index 14e36fb44..769ee6976 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/ObjectArguments.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/ObjectArguments.java
@@ -4,7 +4,8 @@
package dan200.computercraft.api.lua;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/ObjectLuaTable.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/ObjectLuaTable.java
index db4ea75eb..5a133b742 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/ObjectLuaTable.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/ObjectLuaTable.java
@@ -4,7 +4,8 @@
package dan200.computercraft.api.lua;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/TaskCallback.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/TaskCallback.java
index 7b1385f58..608000f68 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/TaskCallback.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/TaskCallback.java
@@ -5,13 +5,12 @@
package dan200.computercraft.api.lua;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
final class TaskCallback implements ILuaCallback, LuaTask {
private final LuaTask task;
- private volatile @Nullable Object[] result;
+ private volatile @Nullable Object @Nullable [] result;
private volatile @MonotonicNonNull LuaException failure;
private final long taskId;
@@ -22,9 +21,8 @@ final class TaskCallback implements ILuaCallback, LuaTask {
taskId = context.issueMainThreadTask(this);
}
- @Nullable
@Override
- public Object[] execute() throws LuaException {
+ public @Nullable Object @Nullable [] execute() throws LuaException {
// Store the result/exception: we read these back when receiving the task_complete event.
try {
result = task.execute();
@@ -38,7 +36,7 @@ final class TaskCallback implements ILuaCallback, LuaTask {
}
@Override
- public MethodResult resume(Object[] response) throws LuaException {
+ public MethodResult resume(@Nullable Object[] response) throws LuaException {
if (response.length < 3 || !(response[1] instanceof Number eventTask) || !(response[2] instanceof Boolean isOk)) {
return pull;
}
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java
index 33fb31eb2..cd2caa8e1 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java
@@ -4,7 +4,8 @@
package dan200.computercraft.api.peripheral;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IComputerAccess.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IComputerAccess.java
index fc56bc6a9..7268cf0e0 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IComputerAccess.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IComputerAccess.java
@@ -10,8 +10,8 @@ import dan200.computercraft.api.lua.ILuaCallback;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaTask;
import dan200.computercraft.api.lua.MethodResult;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Map;
/**
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java
index 1b80787f0..319d7c3d5 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java
@@ -7,8 +7,8 @@ package dan200.computercraft.api.peripheral;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.lua.LuaTask;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Set;
/**
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/PeripheralType.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/PeripheralType.java
index e651df006..c8f1f2a01 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/PeripheralType.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/PeripheralType.java
@@ -4,7 +4,8 @@
package dan200.computercraft.api.peripheral;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.util.Collection;
import java.util.Set;
diff --git a/projects/core/build.gradle.kts b/projects/core/build.gradle.kts
index 5ae2dbe4d..bfea7628b 100644
--- a/projects/core/build.gradle.kts
+++ b/projects/core/build.gradle.kts
@@ -58,6 +58,8 @@ val checkChangelog by tasks.registering(cc.tweaked.gradle.CheckChangelog::class)
tasks.check { dependsOn(checkChangelog) }
+cct.linters(minecraft = false, loader = null)
+
// We configure the shadow jar to ship netty-codec and all its dependencies, relocating them under the
// dan200.computercraft.core package.
// This is used as part of the Forge build, so that our version of netty-codec is loaded under the GAME layer, and so
diff --git a/projects/core/src/main/java/dan200/computercraft/core/ComputerContext.java b/projects/core/src/main/java/dan200/computercraft/core/ComputerContext.java
index d77b21c95..ac2c182cd 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/ComputerContext.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/ComputerContext.java
@@ -4,6 +4,7 @@
package dan200.computercraft.core;
+import com.google.errorprone.annotations.CheckReturnValue;
import dan200.computercraft.core.asm.GenericMethod;
import dan200.computercraft.core.asm.LuaMethodSupplier;
import dan200.computercraft.core.asm.PeripheralMethodSupplier;
@@ -18,9 +19,8 @@ import dan200.computercraft.core.lua.MachineEnvironment;
import dan200.computercraft.core.methods.LuaMethod;
import dan200.computercraft.core.methods.MethodSupplier;
import dan200.computercraft.core.methods.PeripheralMethod;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
@@ -153,7 +153,7 @@ public final class ComputerContext {
private final GlobalEnvironment environment;
private @Nullable ComputerScheduler computerScheduler = null;
private @Nullable MainThreadScheduler mainThreadScheduler;
- private @Nullable ILuaMachine.Factory luaFactory;
+ private ILuaMachine.@Nullable Factory luaFactory;
private @Nullable List genericMethods;
Builder(GlobalEnvironment environment) {
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/ComputerAccess.java b/projects/core/src/main/java/dan200/computercraft/core/apis/ComputerAccess.java
index 8184f3639..dede7998c 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/ComputerAccess.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/ComputerAccess.java
@@ -9,10 +9,10 @@ import dan200.computercraft.api.filesystem.WritableMount;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.WorkMonitor;
import dan200.computercraft.core.filesystem.FileSystemException;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/FSAPI.java b/projects/core/src/main/java/dan200/computercraft/core/apis/FSAPI.java
index 09c37ba9c..9988e33a9 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/FSAPI.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/FSAPI.java
@@ -15,8 +15,8 @@ import dan200.computercraft.core.apis.handles.WriteHandle;
import dan200.computercraft.core.filesystem.FileSystem;
import dan200.computercraft.core.filesystem.FileSystemException;
import dan200.computercraft.core.metrics.Metrics;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.file.OpenOption;
import java.nio.file.StandardOpenOption;
import java.util.*;
@@ -410,9 +410,8 @@ public class FSAPI implements ILuaAPI {
* print("/rom/: " .. fs.getDrive("rom"))
* }
*/
- @Nullable
@LuaFunction
- public final Object[] getDrive(String path) throws LuaException {
+ public final Object @Nullable [] getDrive(String path) throws LuaException {
try {
return getFileSystem().exists(path) ? new Object[]{ getFileSystem().getMountLabel(path) } : null;
} catch (FileSystemException e) {
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/FastLuaException.java b/projects/core/src/main/java/dan200/computercraft/core/apis/FastLuaException.java
index efadf52c2..cca33130e 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/FastLuaException.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/FastLuaException.java
@@ -5,8 +5,8 @@
package dan200.computercraft.core.apis;
import dan200.computercraft.api.lua.LuaException;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.Serial;
/**
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java b/projects/core/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java
index 046fc3ac9..ee5fb41a3 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java
@@ -14,8 +14,7 @@ import dan200.computercraft.core.metrics.Metric;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.core.metrics.OperationTimer;
import dan200.computercraft.core.terminal.Terminal;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public interface IAPIEnvironment {
String TIMER_EVENT = "timer";
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/LuaDateTime.java b/projects/core/src/main/java/dan200/computercraft/core/apis/LuaDateTime.java
index d185f4fad..ccaf6b40e 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/LuaDateTime.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/LuaDateTime.java
@@ -5,8 +5,8 @@
package dan200.computercraft.core.apis;
import dan200.computercraft.api.lua.LuaException;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/OSAPI.java b/projects/core/src/main/java/dan200/computercraft/core/apis/OSAPI.java
index 3251004c3..477c83aac 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/OSAPI.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/OSAPI.java
@@ -11,8 +11,8 @@ import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.util.StringUtil;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
@@ -245,9 +245,8 @@ public class OSAPI implements ILuaAPI {
* @cc.treturn string|nil The label of the computer.
* @cc.since 1.3
*/
- @Nullable
@LuaFunction({ "getComputerLabel", "computerLabel" })
- public final Object[] getComputerLabel() {
+ public final Object @Nullable [] getComputerLabel() {
var label = apiEnvironment.getLabel();
return label == null ? null : new Object[]{ label };
}
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java b/projects/core/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java
index 0b5307fcd..dd065b00f 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java
@@ -16,8 +16,8 @@ import dan200.computercraft.core.methods.MethodSupplier;
import dan200.computercraft.core.methods.PeripheralMethod;
import dan200.computercraft.core.metrics.Metrics;
import dan200.computercraft.core.util.LuaUtil;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.*;
/**
@@ -268,9 +268,8 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
return false;
}
- @Nullable
@LuaFunction
- public final Object[] getType(String sideName) {
+ public final Object @Nullable [] getType(String sideName) {
var side = ComputerSide.valueOfInsensitive(sideName);
if (side == null) return null;
@@ -280,9 +279,8 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
}
}
- @Nullable
@LuaFunction
- public final Object[] hasType(String sideName, String type) {
+ public final Object @Nullable [] hasType(String sideName, String type) {
var side = ComputerSide.valueOfInsensitive(sideName);
if (side == null) return null;
@@ -295,9 +293,8 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
return null;
}
- @Nullable
@LuaFunction
- public final Object[] getMethods(String sideName) {
+ public final Object @Nullable [] getMethods(String sideName) {
var side = ComputerSide.valueOfInsensitive(sideName);
if (side == null) return null;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/TableHelper.java b/projects/core/src/main/java/dan200/computercraft/core/apis/TableHelper.java
index d4ed5dc9f..9ccb5f39e 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/TableHelper.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/TableHelper.java
@@ -6,8 +6,8 @@ package dan200.computercraft.core.apis;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaValues;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Map;
import java.util.Optional;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/handles/AbstractHandle.java b/projects/core/src/main/java/dan200/computercraft/core/apis/handles/AbstractHandle.java
index b46a2b1ba..b5e39e3c0 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/handles/AbstractHandle.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/handles/AbstractHandle.java
@@ -10,8 +10,8 @@ import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import dan200.computercraft.core.util.IoUtil;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -77,8 +77,7 @@ public abstract class AbstractHandle {
* @cc.treturn string The reason seeking failed.
* @cc.since 1.80pr1.9
*/
- @Nullable
- public Object[] seek(Optional whence, Optional offset) throws LuaException {
+ public Object @Nullable [] seek(Optional whence, Optional offset) throws LuaException {
checkOpen();
long actualOffset = offset.orElse(0L);
try {
@@ -111,8 +110,7 @@ public abstract class AbstractHandle {
* @cc.treturn [3] string The bytes read as a string. This is returned when the {@code count} is given.
* @cc.changed 1.80pr1 Now accepts an integer argument to read multiple bytes, returning a string instead of a number.
*/
- @Nullable
- public Object[] read(Optional countArg) throws LuaException {
+ public Object @Nullable [] read(Optional countArg) throws LuaException {
checkOpen();
try {
if (binary && countArg.isEmpty()) {
@@ -161,7 +159,7 @@ public abstract class AbstractHandle {
var bytes = new byte[totalRead];
var pos = 0;
for (var part : parts) {
- int length = part.remaining();
+ var length = part.remaining();
part.get(bytes, pos, length);
pos += length;
}
@@ -182,8 +180,7 @@ public abstract class AbstractHandle {
* @cc.treturn string|nil The remaining contents of the file, or {@code nil} in the event of an error.
* @cc.since 1.80pr1
*/
- @Nullable
- public Object[] readAll() throws LuaException {
+ public Object @Nullable [] readAll() throws LuaException {
checkOpen();
try {
var expected = 32;
@@ -214,8 +211,7 @@ public abstract class AbstractHandle {
* @cc.since 1.80pr1.9
* @cc.changed 1.81.0 `\r` is now stripped.
*/
- @Nullable
- public Object[] readLine(Optional withTrailingArg) throws LuaException {
+ public Object @Nullable [] readLine(Optional withTrailingArg) throws LuaException {
checkOpen();
boolean withTrailing = withTrailingArg.orElse(false);
try {
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/handles/ReadHandle.java b/projects/core/src/main/java/dan200/computercraft/core/apis/handles/ReadHandle.java
index 8a7b1b3b7..e3cbb8574 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/handles/ReadHandle.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/handles/ReadHandle.java
@@ -7,8 +7,8 @@ package dan200.computercraft.core.apis.handles;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.channels.SeekableByteChannel;
import java.util.Optional;
@@ -29,40 +29,36 @@ public class ReadHandle extends AbstractHandle {
/**
* {@inheritDoc}
*/
- @Nullable
@Override
@LuaFunction
- public final Object[] read(Optional countArg) throws LuaException {
+ public final Object @Nullable [] read(Optional countArg) throws LuaException {
return super.read(countArg);
}
/**
* {@inheritDoc}
*/
- @Nullable
@Override
@LuaFunction
- public final Object[] readAll() throws LuaException {
+ public final Object @Nullable [] readAll() throws LuaException {
return super.readAll();
}
/**
* {@inheritDoc}
*/
- @Nullable
@Override
@LuaFunction
- public final Object[] readLine(Optional withTrailingArg) throws LuaException {
+ public final Object @Nullable [] readLine(Optional withTrailingArg) throws LuaException {
return super.readLine(withTrailingArg);
}
/**
* {@inheritDoc}
*/
- @Nullable
@Override
@LuaFunction
- public final Object[] seek(Optional whence, Optional offset) throws LuaException {
+ public final Object @Nullable [] seek(Optional whence, Optional offset) throws LuaException {
return super.seek(whence, offset);
}
}
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/handles/ReadWriteHandle.java b/projects/core/src/main/java/dan200/computercraft/core/apis/handles/ReadWriteHandle.java
index d295a3763..29a454192 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/handles/ReadWriteHandle.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/handles/ReadWriteHandle.java
@@ -9,8 +9,8 @@ import dan200.computercraft.api.lua.IArguments;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.util.Optional;
@@ -28,40 +28,36 @@ public class ReadWriteHandle extends AbstractHandle {
/**
* {@inheritDoc}
*/
- @Nullable
@Override
@LuaFunction
- public final Object[] read(Optional countArg) throws LuaException {
+ public final Object @Nullable [] read(Optional countArg) throws LuaException {
return super.read(countArg);
}
/**
* {@inheritDoc}
*/
- @Nullable
@Override
@LuaFunction
- public final Object[] readAll() throws LuaException {
+ public final Object @Nullable [] readAll() throws LuaException {
return super.readAll();
}
/**
* {@inheritDoc}
*/
- @Nullable
@Override
@LuaFunction
- public final Object[] readLine(Optional withTrailingArg) throws LuaException {
+ public final Object @Nullable [] readLine(Optional withTrailingArg) throws LuaException {
return super.readLine(withTrailingArg);
}
/**
* {@inheritDoc}
*/
- @Nullable
@Override
@LuaFunction
- public final Object[] seek(Optional whence, Optional offset) throws LuaException {
+ public final Object @Nullable [] seek(Optional whence, Optional offset) throws LuaException {
return super.seek(whence, offset);
}
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/handles/WriteHandle.java b/projects/core/src/main/java/dan200/computercraft/core/apis/handles/WriteHandle.java
index c91bf37ac..ad1618d9a 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/handles/WriteHandle.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/handles/WriteHandle.java
@@ -9,8 +9,8 @@ import dan200.computercraft.api.lua.IArguments;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.util.Optional;
@@ -64,10 +64,9 @@ public class WriteHandle extends AbstractHandle {
/**
* {@inheritDoc}
*/
- @Nullable
@Override
@LuaFunction
- public final Object[] seek(Optional whence, Optional offset) throws LuaException {
+ public final Object @Nullable [] seek(Optional whence, Optional offset) throws LuaException {
return super.seek(whence, offset);
}
}
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/CheckUrl.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/CheckUrl.java
index 7d23b7973..addd9eaa7 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/CheckUrl.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/CheckUrl.java
@@ -5,8 +5,8 @@
package dan200.computercraft.core.apis.http;
import dan200.computercraft.core.apis.IAPIEnvironment;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.net.URI;
import java.util.concurrent.Future;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/NetworkUtils.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/NetworkUtils.java
index 054b5b250..594dfccfd 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/NetworkUtils.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/NetworkUtils.java
@@ -27,10 +27,10 @@ import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.ReadTimeoutException;
import io.netty.handler.traffic.AbstractTrafficShapingHandler;
import io.netty.handler.traffic.GlobalTrafficShapingHandler;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.net.InetSocketAddress;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/Resource.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/Resource.java
index c4396ff5e..e344a9fc8 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/Resource.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/Resource.java
@@ -6,8 +6,8 @@ package dan200.computercraft.core.apis.http;
import dan200.computercraft.core.util.IoUtil;
import io.netty.channel.ChannelFuture;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.Closeable;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/AddressRule.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/AddressRule.java
index 3673e8da0..f686d594a 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/AddressRule.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/AddressRule.java
@@ -8,8 +8,8 @@ import com.google.common.net.InetAddresses;
import dan200.computercraft.core.apis.http.options.AddressPredicate.DomainPattern;
import dan200.computercraft.core.apis.http.options.AddressPredicate.HostRange;
import dan200.computercraft.core.apis.http.options.AddressPredicate.PrivatePattern;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/PartialOptions.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/PartialOptions.java
index bd0c91c6f..2c8bd12b0 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/PartialOptions.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/options/PartialOptions.java
@@ -6,8 +6,8 @@ package dan200.computercraft.core.apis.http.options;
import com.google.errorprone.annotations.Immutable;
import com.google.errorprone.annotations.concurrent.LazyInit;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.OptionalLong;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequest.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequest.java
index fb28284e2..dc0b038d1 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequest.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequest.java
@@ -20,10 +20,10 @@ import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.timeout.ReadTimeoutHandler;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java
index 8ef3a099c..b23d6e12e 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java
@@ -14,8 +14,8 @@ import io.netty.buffer.CompositeByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.Closeable;
import java.net.URI;
import java.net.URISyntaxException;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/Websocket.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/Websocket.java
index 5695000ef..a4ebc4c9e 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/Websocket.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/Websocket.java
@@ -25,10 +25,10 @@ import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.concurrent.GenericFutureListener;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.concurrent.Future;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java
index f5182868a..c1b704b44 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java
@@ -7,6 +7,7 @@ package dan200.computercraft.core.apis.http.websocket;
import dan200.computercraft.api.lua.*;
import dan200.computercraft.core.apis.IAPIEnvironment;
import dan200.computercraft.core.apis.http.options.Options;
+import org.jspecify.annotations.Nullable;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
@@ -119,7 +120,7 @@ public class WebsocketHandle {
}
@Override
- public MethodResult resume(Object[] event) {
+ public MethodResult resume(@Nullable Object[] event) {
if (event.length >= 3 && Objects.equals(event[0], MESSAGE_EVENT) && Objects.equals(event[1], address)) {
environment.cancelTimer(timeoutId);
return MethodResult.of(Arrays.copyOfRange(event, 2, event.length));
diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/transfer/TransferredFiles.java b/projects/core/src/main/java/dan200/computercraft/core/apis/transfer/TransferredFiles.java
index a2afd7dd3..04e4e9306 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/apis/transfer/TransferredFiles.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/apis/transfer/TransferredFiles.java
@@ -5,8 +5,8 @@
package dan200.computercraft.core.apis.transfer;
import dan200.computercraft.api.lua.LuaFunction;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/asm/Generator.java b/projects/core/src/main/java/dan200/computercraft/core/asm/Generator.java
index 3272b3bc2..e31cac71e 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/asm/Generator.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/asm/Generator.java
@@ -11,10 +11,10 @@ import com.google.common.primitives.Primitives;
import com.google.common.reflect.TypeToken;
import dan200.computercraft.api.lua.*;
import dan200.computercraft.core.methods.LuaMethod;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/asm/GenericMethod.java b/projects/core/src/main/java/dan200/computercraft/core/asm/GenericMethod.java
index 1681c4ed2..ef3f70ce2 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/asm/GenericMethod.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/asm/GenericMethod.java
@@ -8,10 +8,10 @@ import dan200.computercraft.api.lua.GenericSource;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.peripheral.GenericPeripheral;
import dan200.computercraft.api.peripheral.PeripheralType;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/asm/MethodSupplierImpl.java b/projects/core/src/main/java/dan200/computercraft/core/asm/MethodSupplierImpl.java
index 92a2cb700..aa773ddde 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/asm/MethodSupplierImpl.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/asm/MethodSupplierImpl.java
@@ -11,10 +11,10 @@ import dan200.computercraft.core.methods.MethodSupplier;
import dan200.computercraft.core.methods.NamedMethod;
import dan200.computercraft.core.methods.ObjectSource;
import org.jetbrains.annotations.VisibleForTesting;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/asm/Reflect.java b/projects/core/src/main/java/dan200/computercraft/core/asm/Reflect.java
index 7c14a578c..f66dead23 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/asm/Reflect.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/asm/Reflect.java
@@ -5,10 +5,10 @@
package dan200.computercraft.core.asm;
import dan200.computercraft.api.lua.Coerced;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.lang.reflect.*;
import java.util.Optional;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/asm/ResultHelpers.java b/projects/core/src/main/java/dan200/computercraft/core/asm/ResultHelpers.java
index ef2e55a80..c8de48bf5 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/asm/ResultHelpers.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/asm/ResultHelpers.java
@@ -5,15 +5,13 @@
package dan200.computercraft.core.asm;
import dan200.computercraft.api.lua.MethodResult;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
final class ResultHelpers {
private ResultHelpers() {
}
- @Nullable
- static Object[] checkNormalResult(MethodResult result) {
+ static @Nullable Object @Nullable [] checkNormalResult(MethodResult result) {
if (result.getCallback() != null) {
// Due to how tasks are implemented, we can't currently return a MethodResult. This is an
// entirely artificial limitation - we can remove it if it ever becomes an issue.
diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/ApiWrapper.java b/projects/core/src/main/java/dan200/computercraft/core/computer/ApiWrapper.java
index 94394724a..ea4a3fdaf 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/computer/ApiWrapper.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/computer/ApiWrapper.java
@@ -5,8 +5,7 @@
package dan200.computercraft.core.computer;
import dan200.computercraft.api.lua.ILuaAPI;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A wrapper for {@link ILuaAPI}s which provides an optional shutdown hook to clean up resources.
@@ -28,8 +27,4 @@ record ApiWrapper(ILuaAPI api, @Nullable ApiLifecycle lifecycle) {
api.shutdown();
if (lifecycle != null) lifecycle.shutdown();
}
-
- public ILuaAPI api() {
- return api;
- }
}
diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/Computer.java b/projects/core/src/main/java/dan200/computercraft/core/computer/Computer.java
index bab208506..5973d0444 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/computer/Computer.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/computer/Computer.java
@@ -14,8 +14,8 @@ import dan200.computercraft.core.computer.mainthread.MainThreadScheduler;
import dan200.computercraft.core.filesystem.FileSystem;
import dan200.computercraft.core.redstone.RedstoneState;
import dan200.computercraft.core.terminal.Terminal;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.concurrent.atomic.AtomicLong;
/**
@@ -115,7 +115,7 @@ public class Computer implements ComputerEvents.Receiver {
}
@Override
- public void queueEvent(String event, @Nullable Object[] args) {
+ public void queueEvent(String event, @Nullable Object @Nullable [] args) {
executor.queueEvent(event, args);
}
diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerEnvironment.java b/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerEnvironment.java
index a9984aa1f..06fad0f90 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerEnvironment.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerEnvironment.java
@@ -7,8 +7,7 @@ package dan200.computercraft.core.computer;
import dan200.computercraft.api.filesystem.WritableMount;
import dan200.computercraft.core.filesystem.WritableFileMount;
import dan200.computercraft.core.metrics.MetricsObserver;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public interface ComputerEnvironment {
/**
diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerEvents.java b/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerEvents.java
index f3ed14372..678607cb1 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerEvents.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerEvents.java
@@ -5,8 +5,8 @@
package dan200.computercraft.core.computer;
import dan200.computercraft.core.util.StringUtil;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.ByteBuffer;
/**
@@ -67,6 +67,6 @@ public final class ComputerEvents {
*/
@FunctionalInterface
public interface Receiver {
- void queueEvent(String event, @Nullable Object[] arguments);
+ void queueEvent(String event, @Nullable Object @Nullable [] arguments);
}
}
diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java b/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java
index d9db83472..55d57ab39 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java
@@ -4,6 +4,7 @@
package dan200.computercraft.core.computer;
+import com.google.errorprone.annotations.concurrent.GuardedBy;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.filesystem.WritableMount;
import dan200.computercraft.api.lua.ILuaAPI;
@@ -22,11 +23,10 @@ import dan200.computercraft.core.methods.MethodSupplier;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.core.util.Colour;
import dan200.computercraft.core.util.Nullability;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayDeque;
@@ -266,7 +266,7 @@ final class ComputerExecutor implements ComputerScheduler.Worker {
* @param event The event's name
* @param args The event's arguments
*/
- void queueEvent(String event, @Nullable Object[] args) {
+ void queueEvent(String event, @Nullable Object @Nullable [] args) {
// Events should be skipped if we're not on.
if (!isOn) return;
@@ -552,7 +552,7 @@ final class ComputerExecutor implements ComputerScheduler.Worker {
terminal.write("ComputerCraft may be installed incorrectly");
}
- private void resumeMachine(@Nullable String event, @Nullable Object[] args) throws InterruptedException {
+ private void resumeMachine(@Nullable String event, @Nullable Object @Nullable [] args) throws InterruptedException {
var result = Nullability.assertNonNull(machine).handleEvent(event, args);
if (result.isError()) {
displayFailure("Error running computer", result.getMessage());
@@ -573,6 +573,7 @@ final class ComputerExecutor implements ComputerScheduler.Worker {
ABORT_WITH_ERROR,
}
- private record Event(String name, @Nullable Object[] args) {
+ @SuppressWarnings("ArrayRecordComponent")
+ private record Event(String name, @Nullable Object @Nullable [] args) {
}
}
diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerSide.java b/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerSide.java
index c35016080..439f7359f 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerSide.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerSide.java
@@ -4,7 +4,8 @@
package dan200.computercraft.core.computer;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.util.List;
/**
diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/Environment.java b/projects/core/src/main/java/dan200/computercraft/core/computer/Environment.java
index d1e10d5c4..a87903e41 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/computer/Environment.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/computer/Environment.java
@@ -14,8 +14,8 @@ import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.util.PeripheralHelpers;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Iterator;
/**
diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/GlobalEnvironment.java b/projects/core/src/main/java/dan200/computercraft/core/computer/GlobalEnvironment.java
index 36b018cd0..9051da12f 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/computer/GlobalEnvironment.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/computer/GlobalEnvironment.java
@@ -5,8 +5,8 @@
package dan200.computercraft.core.computer;
import dan200.computercraft.api.filesystem.Mount;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.InputStream;
/**
diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/computerthread/ComputerThread.java b/projects/core/src/main/java/dan200/computercraft/core/computer/computerthread/ComputerThread.java
index b38379a47..abbd03c74 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/computer/computerthread/ComputerThread.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/computer/computerthread/ComputerThread.java
@@ -6,6 +6,7 @@ package dan200.computercraft.core.computer.computerthread;
import com.google.common.annotations.VisibleForTesting;
import com.google.errorprone.annotations.Keep;
+import com.google.errorprone.annotations.concurrent.GuardedBy;
import dan200.computercraft.core.ComputerContext;
import dan200.computercraft.core.Logging;
import dan200.computercraft.core.computer.TimeoutState;
@@ -13,11 +14,10 @@ import dan200.computercraft.core.metrics.Metrics;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.core.metrics.ThreadAllocations;
import dan200.computercraft.core.util.ThreadUtils;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
import java.util.Arrays;
import java.util.Objects;
import java.util.TreeSet;
@@ -242,7 +242,7 @@ public final class ComputerThread implements ComputerScheduler {
// Encourage any currently running runners to terminate.
threadLock.lock();
try {
- for (@Nullable var worker : workers) {
+ for (var worker : workers) {
if (worker == null) continue;
var executor = worker.currentExecutor.get();
@@ -349,7 +349,7 @@ public final class ComputerThread implements ComputerScheduler {
// Update all the currently executing tasks
var now = System.nanoTime();
var tasks = 1 + computerQueue.size();
- for (@Nullable var runner : workersReadOnly()) {
+ for (var runner : workersReadOnly()) {
if (runner == null) continue;
var executor = runner.currentExecutor.get();
if (executor == null) continue;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/filesystem/AbstractInMemoryMount.java b/projects/core/src/main/java/dan200/computercraft/core/filesystem/AbstractInMemoryMount.java
index 188628a3b..361cbb735 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/filesystem/AbstractInMemoryMount.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/filesystem/AbstractInMemoryMount.java
@@ -7,8 +7,8 @@ package dan200.computercraft.core.filesystem;
import dan200.computercraft.api.filesystem.FileAttributes;
import dan200.computercraft.api.filesystem.FileOperationException;
import dan200.computercraft.api.filesystem.Mount;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.attribute.BasicFileAttributes;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/filesystem/ArchiveMount.java b/projects/core/src/main/java/dan200/computercraft/core/filesystem/ArchiveMount.java
index bac283ad9..388cc10de 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/filesystem/ArchiveMount.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/filesystem/ArchiveMount.java
@@ -7,8 +7,8 @@ package dan200.computercraft.core.filesystem;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import dan200.computercraft.core.apis.handles.ArrayByteChannel;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.channels.SeekableByteChannel;
import java.util.concurrent.TimeUnit;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/filesystem/JarMount.java b/projects/core/src/main/java/dan200/computercraft/core/filesystem/JarMount.java
index 635c1a076..fc4cd1d93 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/filesystem/JarMount.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/filesystem/JarMount.java
@@ -6,8 +6,8 @@ package dan200.computercraft.core.filesystem;
import dan200.computercraft.api.filesystem.FileAttributes;
import dan200.computercraft.api.filesystem.FileOperationException;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/filesystem/MemoryMount.java b/projects/core/src/main/java/dan200/computercraft/core/filesystem/MemoryMount.java
index 60c3aa4cb..49405a665 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/filesystem/MemoryMount.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/filesystem/MemoryMount.java
@@ -9,8 +9,8 @@ import dan200.computercraft.api.filesystem.FileOperationException;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.filesystem.WritableMount;
import dan200.computercraft.core.util.Nullability;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
@@ -208,8 +208,7 @@ public final class MemoryMount extends AbstractInMemoryMount {
FileTime created = EPOCH;
FileTime modified = EPOCH;
- @Nullable
- byte[] contents;
+ byte @Nullable [] contents;
int length;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/filesystem/MountWrapper.java b/projects/core/src/main/java/dan200/computercraft/core/filesystem/MountWrapper.java
index 10d9243e2..a77c3af18 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/filesystem/MountWrapper.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/filesystem/MountWrapper.java
@@ -7,8 +7,8 @@ package dan200.computercraft.core.filesystem;
import dan200.computercraft.api.filesystem.FileOperationException;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.api.filesystem.WritableMount;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.OpenOption;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/filesystem/WritableFileMount.java b/projects/core/src/main/java/dan200/computercraft/core/filesystem/WritableFileMount.java
index 69f6c5d62..e033c34ce 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/filesystem/WritableFileMount.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/filesystem/WritableFileMount.java
@@ -6,10 +6,10 @@ package dan200.computercraft.core.filesystem;
import dan200.computercraft.api.filesystem.FileOperationException;
import dan200.computercraft.api.filesystem.WritableMount;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java b/projects/core/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java
index 0bc3c4856..527bf03bc 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java
@@ -17,6 +17,7 @@ import dan200.computercraft.core.methods.MethodSupplier;
import dan200.computercraft.core.util.LuaUtil;
import dan200.computercraft.core.util.Nullability;
import dan200.computercraft.core.util.SanitisedError;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.squiddev.cobalt.*;
@@ -26,7 +27,6 @@ import org.squiddev.cobalt.interrupt.InterruptAction;
import org.squiddev.cobalt.lib.Bit32Lib;
import org.squiddev.cobalt.lib.CoreLibraries;
-import javax.annotation.Nullable;
import java.io.InputStream;
import java.io.Serial;
import java.nio.ByteBuffer;
@@ -114,7 +114,7 @@ public class CobaltLuaMachine implements ILuaMachine {
}
@Override
- public MachineResult handleEvent(@Nullable String eventName, @Nullable Object[] arguments) {
+ public MachineResult handleEvent(@Nullable String eventName, @Nullable Object @Nullable [] arguments) {
if (isDisposed) throw new IllegalStateException("Machine has been closed");
if (eventFilter != null && eventName != null && !eventName.equals(eventFilter) && !eventName.equals("terminate")) {
@@ -253,7 +253,7 @@ public class CobaltLuaMachine implements ILuaMachine {
return Constants.NIL;
}
- Varargs toValues(@Nullable Object[] objects) throws LuaError {
+ Varargs toValues(@Nullable Object @Nullable [] objects) throws LuaError {
if (objects == null || objects.length == 0) return Constants.NONE;
if (objects.length == 1) return toValue(objects[0], null);
@@ -266,8 +266,7 @@ public class CobaltLuaMachine implements ILuaMachine {
return ValueFactory.varargsOf(values);
}
- @Nullable
- static Object toObject(LuaValue value, @Nullable IdentityHashMap objects) {
+ static @Nullable Object toObject(LuaValue value, @Nullable IdentityHashMap objects) {
return switch (value.type()) {
case Constants.TNIL -> null;
case Constants.TINT, Constants.TNUMBER -> value.toDouble();
@@ -312,7 +311,7 @@ public class CobaltLuaMachine implements ILuaMachine {
};
}
- static Object[] toObjects(Varargs values) {
+ static @Nullable Object[] toObjects(Varargs values) {
var count = values.count();
var objects = new Object[count];
for (var i = 0; i < count; i++) objects[i] = toObject(values.arg(i + 1), null);
diff --git a/projects/core/src/main/java/dan200/computercraft/core/lua/ILuaMachine.java b/projects/core/src/main/java/dan200/computercraft/core/lua/ILuaMachine.java
index 1c939d997..8ff30d6d0 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/lua/ILuaMachine.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/lua/ILuaMachine.java
@@ -4,7 +4,8 @@
package dan200.computercraft.core.lua;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.io.IOException;
import java.io.InputStream;
@@ -28,7 +29,7 @@ public interface ILuaMachine {
* @return The result of loading this machine. Will either be OK, or the error message that occurred when
* executing.
*/
- MachineResult handleEvent(@Nullable String eventName, @Nullable Object[] arguments);
+ MachineResult handleEvent(@Nullable String eventName, @Nullable Object @Nullable [] arguments);
/**
* Print some information about the internal execution state.
diff --git a/projects/core/src/main/java/dan200/computercraft/core/lua/MachineResult.java b/projects/core/src/main/java/dan200/computercraft/core/lua/MachineResult.java
index a7e481fbc..731b5295a 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/lua/MachineResult.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/lua/MachineResult.java
@@ -5,8 +5,7 @@
package dan200.computercraft.core.lua;
import dan200.computercraft.core.computer.TimeoutState;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* The result of executing an action on a machine.
diff --git a/projects/core/src/main/java/dan200/computercraft/core/lua/TableImpl.java b/projects/core/src/main/java/dan200/computercraft/core/lua/TableImpl.java
index 0ffa65d76..d764db045 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/lua/TableImpl.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/lua/TableImpl.java
@@ -6,9 +6,9 @@ package dan200.computercraft.core.lua;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaValues;
+import org.jspecify.annotations.Nullable;
import org.squiddev.cobalt.*;
-import javax.annotation.Nullable;
import java.util.*;
import static dan200.computercraft.api.lua.LuaValues.badTableItem;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/lua/VarargArguments.java b/projects/core/src/main/java/dan200/computercraft/core/lua/VarargArguments.java
index d49d8d490..f4b4a607b 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/lua/VarargArguments.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/lua/VarargArguments.java
@@ -7,11 +7,11 @@ package dan200.computercraft.core.lua;
import dan200.computercraft.api.lua.IArguments;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaValues;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.squiddev.cobalt.*;
-import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.Optional;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/lua/errorinfo/ErrorInfoLib.java b/projects/core/src/main/java/dan200/computercraft/core/lua/errorinfo/ErrorInfoLib.java
index 5f23941f5..3f03f31c2 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/lua/errorinfo/ErrorInfoLib.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/lua/errorinfo/ErrorInfoLib.java
@@ -5,12 +5,12 @@
package dan200.computercraft.core.lua.errorinfo;
import com.google.common.annotations.VisibleForTesting;
+import org.jspecify.annotations.Nullable;
import org.squiddev.cobalt.*;
import org.squiddev.cobalt.debug.DebugFrame;
import org.squiddev.cobalt.function.LuaFunction;
import org.squiddev.cobalt.function.RegisteredFunction;
-import javax.annotation.Nullable;
import java.util.Objects;
import static org.squiddev.cobalt.Lua.*;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/methods/MethodSupplier.java b/projects/core/src/main/java/dan200/computercraft/core/methods/MethodSupplier.java
index 13f45b915..701148829 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/methods/MethodSupplier.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/methods/MethodSupplier.java
@@ -4,7 +4,8 @@
package dan200.computercraft.core.methods;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.util.HashMap;
import java.util.Map;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/methods/NamedMethod.java b/projects/core/src/main/java/dan200/computercraft/core/methods/NamedMethod.java
index f4f5de441..a848b36d4 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/methods/NamedMethod.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/methods/NamedMethod.java
@@ -8,8 +8,7 @@ import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.lua.MethodResult;
import dan200.computercraft.api.peripheral.GenericPeripheral;
import dan200.computercraft.api.peripheral.PeripheralType;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A method generated from a {@link LuaFunction}.
diff --git a/projects/core/src/main/java/dan200/computercraft/core/metrics/ThreadAllocations.java b/projects/core/src/main/java/dan200/computercraft/core/metrics/ThreadAllocations.java
index 940c0d232..953a832db 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/metrics/ThreadAllocations.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/metrics/ThreadAllocations.java
@@ -4,10 +4,10 @@
package dan200.computercraft.core.metrics;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneState.java b/projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneState.java
index e2a6f0d9f..5de2e9b8a 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneState.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneState.java
@@ -3,10 +3,10 @@
// SPDX-License-Identifier: LicenseRef-CCPL
package dan200.computercraft.core.redstone;
+import com.google.errorprone.annotations.concurrent.GuardedBy;
import dan200.computercraft.core.computer.ComputerSide;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
import java.util.Arrays;
import java.util.concurrent.locks.ReentrantLock;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/terminal/Terminal.java b/projects/core/src/main/java/dan200/computercraft/core/terminal/Terminal.java
index 983a277e0..0e3a87def 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/terminal/Terminal.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/terminal/Terminal.java
@@ -5,8 +5,8 @@
package dan200.computercraft.core.terminal;
import dan200.computercraft.core.util.Colour;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.ByteBuffer;
public class Terminal {
diff --git a/projects/core/src/main/java/dan200/computercraft/core/util/IoUtil.java b/projects/core/src/main/java/dan200/computercraft/core/util/IoUtil.java
index dc5e18e67..896b18503 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/util/IoUtil.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/util/IoUtil.java
@@ -4,7 +4,8 @@
package dan200.computercraft.core.util;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.io.Closeable;
import java.io.IOException;
diff --git a/projects/core/src/main/java/dan200/computercraft/core/util/Nullability.java b/projects/core/src/main/java/dan200/computercraft/core/util/Nullability.java
index 10b4e90fc..95383948d 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/util/Nullability.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/util/Nullability.java
@@ -4,7 +4,7 @@
package dan200.computercraft.core.util;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public final class Nullability {
private Nullability() {
diff --git a/projects/core/src/main/java/dan200/computercraft/core/util/PeripheralHelpers.java b/projects/core/src/main/java/dan200/computercraft/core/util/PeripheralHelpers.java
index 6ac48da4e..f304eafc3 100644
--- a/projects/core/src/main/java/dan200/computercraft/core/util/PeripheralHelpers.java
+++ b/projects/core/src/main/java/dan200/computercraft/core/util/PeripheralHelpers.java
@@ -5,8 +5,7 @@
package dan200.computercraft.core.util;
import dan200.computercraft.api.peripheral.IPeripheral;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Utilities for working with {@linkplain IPeripheral peripherals}.
diff --git a/projects/core/src/test/java/dan200/computercraft/core/ComputerTestDelegate.java b/projects/core/src/test/java/dan200/computercraft/core/ComputerTestDelegate.java
index 319057a84..43d61eafa 100644
--- a/projects/core/src/test/java/dan200/computercraft/core/ComputerTestDelegate.java
+++ b/projects/core/src/test/java/dan200/computercraft/core/ComputerTestDelegate.java
@@ -21,6 +21,7 @@ import dan200.computercraft.core.lua.MachineException;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.test.core.computer.BasicEnvironment;
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.function.Executable;
import org.opentest4j.AssertionFailedError;
@@ -34,7 +35,6 @@ import org.squiddev.cobalt.debug.DebugFrame;
import org.squiddev.cobalt.debug.DebugHook;
import org.squiddev.cobalt.debug.DebugState;
-import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
diff --git a/projects/core/src/test/java/dan200/computercraft/core/apis/handles/BinaryReadableHandleTest.java b/projects/core/src/test/java/dan200/computercraft/core/apis/handles/BinaryReadableHandleTest.java
index 465847b20..3aae43988 100644
--- a/projects/core/src/test/java/dan200/computercraft/core/apis/handles/BinaryReadableHandleTest.java
+++ b/projects/core/src/test/java/dan200/computercraft/core/apis/handles/BinaryReadableHandleTest.java
@@ -5,9 +5,9 @@
package dan200.computercraft.core.apis.handles;
import dan200.computercraft.api.lua.LuaException;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
-import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
diff --git a/projects/core/src/test/java/dan200/computercraft/core/asm/MethodTest.java b/projects/core/src/test/java/dan200/computercraft/core/asm/MethodTest.java
index 5dc674a98..98326a587 100644
--- a/projects/core/src/test/java/dan200/computercraft/core/asm/MethodTest.java
+++ b/projects/core/src/test/java/dan200/computercraft/core/asm/MethodTest.java
@@ -11,9 +11,9 @@ import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.computer.ComputerBootstrap;
import dan200.computercraft.core.computer.ComputerSide;
import dan200.computercraft.core.methods.ObjectSource;
+import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
-import javax.annotation.Nullable;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
diff --git a/projects/core/src/test/java/dan200/computercraft/core/computer/computerthread/ComputerThreadRunner.java b/projects/core/src/test/java/dan200/computercraft/core/computer/computerthread/ComputerThreadRunner.java
index 6a76d929a..002b95074 100644
--- a/projects/core/src/test/java/dan200/computercraft/core/computer/computerthread/ComputerThreadRunner.java
+++ b/projects/core/src/test/java/dan200/computercraft/core/computer/computerthread/ComputerThreadRunner.java
@@ -4,12 +4,12 @@
package dan200.computercraft.core.computer.computerthread;
+import com.google.errorprone.annotations.concurrent.GuardedBy;
import dan200.computercraft.core.computer.TimeoutState;
import dan200.computercraft.core.metrics.Metric;
import dan200.computercraft.core.metrics.MetricsObserver;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
-import javax.annotation.concurrent.GuardedBy;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
diff --git a/projects/core/src/testFixtures/java/dan200/computercraft/test/core/ArbitraryByteBuffer.java b/projects/core/src/testFixtures/java/dan200/computercraft/test/core/ArbitraryByteBuffer.java
index 2866e4206..fe3cdf963 100644
--- a/projects/core/src/testFixtures/java/dan200/computercraft/test/core/ArbitraryByteBuffer.java
+++ b/projects/core/src/testFixtures/java/dan200/computercraft/test/core/ArbitraryByteBuffer.java
@@ -6,8 +6,8 @@ package dan200.computercraft.test.core;
import net.jqwik.api.*;
import net.jqwik.api.arbitraries.SizableArbitrary;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.List;
diff --git a/projects/core/src/testFixtures/java/dan200/computercraft/test/core/CloseScope.java b/projects/core/src/testFixtures/java/dan200/computercraft/test/core/CloseScope.java
index 0b4d5b3d5..391596193 100644
--- a/projects/core/src/testFixtures/java/dan200/computercraft/test/core/CloseScope.java
+++ b/projects/core/src/testFixtures/java/dan200/computercraft/test/core/CloseScope.java
@@ -4,7 +4,8 @@
package dan200.computercraft.test.core;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
+
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Objects;
diff --git a/projects/core/src/testFixtures/java/dan200/computercraft/test/core/apis/BasicApiEnvironment.java b/projects/core/src/testFixtures/java/dan200/computercraft/test/core/apis/BasicApiEnvironment.java
index dd75d2a32..f82b50468 100644
--- a/projects/core/src/testFixtures/java/dan200/computercraft/test/core/apis/BasicApiEnvironment.java
+++ b/projects/core/src/testFixtures/java/dan200/computercraft/test/core/apis/BasicApiEnvironment.java
@@ -14,8 +14,7 @@ import dan200.computercraft.core.filesystem.FileSystem;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.test.core.computer.BasicEnvironment;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public abstract class BasicApiEnvironment implements IAPIEnvironment {
private final BasicEnvironment environment;
diff --git a/projects/core/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/KotlinLuaMachine.kt b/projects/core/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/KotlinLuaMachine.kt
index 1c3e193e4..cf15cdf63 100644
--- a/projects/core/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/KotlinLuaMachine.kt
+++ b/projects/core/src/testFixtures/kotlin/dan200/computercraft/test/core/computer/KotlinLuaMachine.kt
@@ -21,7 +21,7 @@ abstract class KotlinLuaMachine(environment: MachineEnvironment) : ILuaMachine,
for (api in environment.apis) addApi(api)
}
- override fun handleEvent(eventName: String?, arguments: Array?): MachineResult {
+ override fun handleEvent(eventName: String?, arguments: Array?): MachineResult {
if (hasEventListeners) {
queueEvent(eventName, arguments)
} else {
diff --git a/projects/fabric-api/src/client/java/dan200/computercraft/impl/client/FabricComputerCraftAPIClientService.java b/projects/fabric-api/src/client/java/dan200/computercraft/impl/client/FabricComputerCraftAPIClientService.java
index 94ae828cc..49b0d236f 100644
--- a/projects/fabric-api/src/client/java/dan200/computercraft/impl/client/FabricComputerCraftAPIClientService.java
+++ b/projects/fabric-api/src/client/java/dan200/computercraft/impl/client/FabricComputerCraftAPIClientService.java
@@ -9,8 +9,7 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.upgrades.UpgradeType;
import dan200.computercraft.impl.Services;
import org.jetbrains.annotations.ApiStatus;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Backing interface for CC's client-side API.
diff --git a/projects/fabric-api/src/main/java/dan200/computercraft/api/media/MediaLookup.java b/projects/fabric-api/src/main/java/dan200/computercraft/api/media/MediaLookup.java
new file mode 100644
index 000000000..6a331a421
--- /dev/null
+++ b/projects/fabric-api/src/main/java/dan200/computercraft/api/media/MediaLookup.java
@@ -0,0 +1,29 @@
+// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package dan200.computercraft.api.media;
+
+import dan200.computercraft.api.ComputerCraftAPI;
+import net.fabricmc.fabric.api.lookup.v1.item.ItemApiLookup;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.item.ItemStack;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * {@linkplain ItemApiLookup Item API lookup} for {@link IMedia}.
+ *
+ * The returned {@link IMedia} instance should be a singleton, and not reference the passed {@link ItemStack}.
+ */
+public final class MediaLookup {
+ public static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "media");
+
+ private static final ItemApiLookup lookup = ItemApiLookup.get(ID, IMedia.class, Void.class);
+
+ private MediaLookup() {
+ }
+
+ public static ItemApiLookup get() {
+ return lookup;
+ }
+}
diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/CompositeBakedModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/CompositeBakedModel.java
index 00880515a..608829f71 100644
--- a/projects/fabric/src/client/java/dan200/computercraft/client/model/CompositeBakedModel.java
+++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/CompositeBakedModel.java
@@ -15,8 +15,8 @@ import net.minecraft.util.RandomSource;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Stream;
diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/CustomModelLoader.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/CustomModelLoader.java
index 7addcdced..d72945da8 100644
--- a/projects/fabric/src/client/java/dan200/computercraft/client/model/CustomModelLoader.java
+++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/CustomModelLoader.java
@@ -19,10 +19,10 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.Resource;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.util.GsonHelper;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.io.IOException;
import java.io.Reader;
import java.util.Collection;
diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveBakedModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveBakedModel.java
index 3512eb896..4d3d18ea9 100644
--- a/projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveBakedModel.java
+++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/EmissiveBakedModel.java
@@ -16,8 +16,8 @@ import net.minecraft.util.RandomSource;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.function.Supplier;
/**
diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/FoiledModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/FoiledModel.java
index a0995211a..34313ebb5 100644
--- a/projects/fabric/src/client/java/dan200/computercraft/client/model/FoiledModel.java
+++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/FoiledModel.java
@@ -18,8 +18,8 @@ import net.minecraft.util.RandomSource;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.function.Supplier;
/**
diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/TransformedBakedModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/TransformedBakedModel.java
index 79f0dc03f..ac614c01c 100644
--- a/projects/fabric/src/client/java/dan200/computercraft/client/model/TransformedBakedModel.java
+++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/TransformedBakedModel.java
@@ -16,8 +16,8 @@ import net.minecraft.util.RandomSource;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.List;
import java.util.function.Supplier;
diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java
index 704350b1a..dc83ddde5 100644
--- a/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java
+++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java
@@ -12,8 +12,7 @@ import net.minecraft.client.renderer.block.model.ItemOverrides;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* The custom model for turtle items, which renders tools and overlays as part of the model.
diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java b/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java
index b8eaee2d2..82f60d149 100644
--- a/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java
+++ b/projects/fabric/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java
@@ -17,8 +17,7 @@ import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
@AutoService(dan200.computercraft.impl.client.ClientPlatformHelper.class)
public class ClientPlatformHelperImpl implements ClientPlatformHelper {
@@ -41,7 +40,7 @@ public class ClientPlatformHelperImpl implements ClientPlatformHelper {
}
@Override
- public void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, @Nullable int[] tints) {
+ public void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, int @Nullable [] tints) {
// Unfortunately we can't call Fabric's emitItemQuads here, as there's no way to obtain a RenderContext via the
// API. Instead, we special case our FoiledModel, and just render everything else normally.
var buffer = ItemRenderer.getFoilBuffer(buffers, Sheets.translucentCullBlockSheet(), true, model instanceof FoiledModel);
diff --git a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/BlockModelAccessor.java b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/BlockModelAccessor.java
index 497a5b9a4..10863f758 100644
--- a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/BlockModelAccessor.java
+++ b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/BlockModelAccessor.java
@@ -6,11 +6,10 @@ package dan200.computercraft.mixin.client;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.resources.ResourceLocation;
+import org.jspecify.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
-import javax.annotation.Nullable;
-
@Mixin(BlockModel.class)
public interface BlockModelAccessor {
@Accessor("parentLocation")
diff --git a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/SoundEngineMixin.java b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/SoundEngineMixin.java
index 943d3207a..b1d079e8f 100644
--- a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/SoundEngineMixin.java
+++ b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/SoundEngineMixin.java
@@ -9,14 +9,13 @@ import dan200.computercraft.client.sound.SpeakerManager;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.client.sounds.AudioStream;
import net.minecraft.client.sounds.SoundEngine;
+import org.jspecify.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import javax.annotation.Nullable;
-
import static dan200.computercraft.core.util.Nullability.assertNonNull;
@Mixin(SoundEngine.class)
diff --git a/projects/fabric/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java b/projects/fabric/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java
index 07f0b872a..414960fd2 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java
@@ -7,14 +7,15 @@ package dan200.computercraft.impl;
import com.google.auto.service.AutoService;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.detail.DetailRegistry;
+import dan200.computercraft.api.media.MediaLookup;
+import dan200.computercraft.api.media.MediaProvider;
import dan200.computercraft.impl.detail.DetailRegistryImpl;
import dan200.computercraft.shared.details.FluidDetails;
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.fabricmc.fabric.api.transfer.v1.storage.StorageView;
import net.fabricmc.loader.api.FabricLoader;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
@AutoService(ComputerCraftAPIService.class)
public final class ComputerCraftAPIImpl extends AbstractComputerCraftAPI implements ComputerCraftAPIFabricService {
@@ -42,4 +43,9 @@ public final class ComputerCraftAPIImpl extends AbstractComputerCraftAPI impleme
public DetailRegistry> getFluidDetailRegistry() {
return fluidDetails;
}
+
+ @Override
+ public void registerMediaProvider(MediaProvider provider) {
+ MediaLookup.get().registerFallback((stack, ctx) -> provider.getMedia(stack));
+ }
}
diff --git a/projects/fabric/src/main/java/dan200/computercraft/mixin/ChunkMapMixin.java b/projects/fabric/src/main/java/dan200/computercraft/mixin/ChunkMapMixin.java
index 4ba8045a2..907a95618 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/mixin/ChunkMapMixin.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/mixin/ChunkMapMixin.java
@@ -8,6 +8,7 @@ import dan200.computercraft.shared.CommonHooks;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerLevel;
+import org.jspecify.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -15,8 +16,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-import javax.annotation.Nullable;
-
@Mixin(ChunkMap.class)
class ChunkMapMixin {
@Final
diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java
index 6b583831b..8d5c6ce9d 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java
@@ -6,6 +6,7 @@ package dan200.computercraft.shared;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.detail.FabricDetailRegistries;
+import dan200.computercraft.api.media.MediaLookup;
import dan200.computercraft.api.network.wired.WiredElementLookup;
import dan200.computercraft.api.peripheral.PeripheralLookup;
import dan200.computercraft.api.pocket.IPocketUpgrade;
@@ -14,16 +15,11 @@ import dan200.computercraft.impl.Peripherals;
import dan200.computercraft.impl.PocketUpgrades;
import dan200.computercraft.impl.TurtleUpgrades;
import dan200.computercraft.shared.command.CommandComputerCraft;
-import dan200.computercraft.shared.config.Config;
import dan200.computercraft.shared.config.ConfigSpec;
import dan200.computercraft.shared.details.FluidDetails;
import dan200.computercraft.shared.integration.CreateIntegration;
import dan200.computercraft.shared.network.NetworkMessages;
-import dan200.computercraft.shared.peripheral.commandblock.CommandBlockPeripheral;
import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods;
-import dan200.computercraft.shared.peripheral.modem.wired.CableBlockEntity;
-import dan200.computercraft.shared.peripheral.modem.wired.WiredModemFullBlockEntity;
-import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemBlockEntity;
import dan200.computercraft.shared.platform.FabricConfigFile;
import dan200.computercraft.shared.recipe.function.RecipeFunction;
import dan200.computercraft.shared.turtle.TurtleOverlay;
@@ -37,6 +33,8 @@ import net.fabricmc.fabric.api.event.registry.DynamicRegistries;
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
import net.fabricmc.fabric.api.event.registry.RegistryAttribute;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
+import net.fabricmc.fabric.api.lookup.v1.block.BlockApiLookup;
+import net.fabricmc.fabric.api.lookup.v1.item.ItemApiLookup;
import net.fabricmc.fabric.api.loot.v3.LootTableEvents;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
@@ -51,11 +49,16 @@ import net.minecraft.server.packs.PackType;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.util.profiling.ProfilerFiller;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.ItemLike;
+import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.storage.LevelResource;
+import org.jspecify.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
+import java.util.function.BiFunction;
public class ComputerCraft {
private static final LevelResource SERVERCONFIG = new LevelResource("serverconfig");
@@ -77,28 +80,9 @@ public class ComputerCraft {
ModRegistry.register();
ModRegistry.registerMainThread();
- // Register peripherals
- PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.COMPUTER_NORMAL.get());
- PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.COMPUTER_ADVANCED.get());
- PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.TURTLE_NORMAL.get());
- PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.TURTLE_ADVANCED.get());
- PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.SPEAKER.get());
- PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.PRINTER.get());
- PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.DISK_DRIVE.get());
- PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.MONITOR_NORMAL.get());
- PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.MONITOR_ADVANCED.get());
- PeripheralLookup.get().registerForBlockEntity(
- (b, d) -> Config.enableCommandBlock ? new CommandBlockPeripheral(b) : null,
- BlockEntityType.COMMAND_BLOCK
- );
- PeripheralLookup.get().registerForBlockEntity(WirelessModemBlockEntity::getPeripheral, ModRegistry.BlockEntities.WIRELESS_MODEM_NORMAL.get());
- PeripheralLookup.get().registerForBlockEntity(WirelessModemBlockEntity::getPeripheral, ModRegistry.BlockEntities.WIRELESS_MODEM_ADVANCED.get());
- PeripheralLookup.get().registerForBlockEntity(WiredModemFullBlockEntity::getPeripheral, ModRegistry.BlockEntities.WIRED_MODEM_FULL.get());
- PeripheralLookup.get().registerForBlockEntity(CableBlockEntity::getPeripheral, ModRegistry.BlockEntities.CABLE.get());
- PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.REDSTONE_RELAY.get());
-
- WiredElementLookup.get().registerForBlockEntity((b, d) -> b.getElement(), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get());
- WiredElementLookup.get().registerForBlockEntity(CableBlockEntity::getWiredElement, ModRegistry.BlockEntities.CABLE.get());
+ ModRegistry.registerPeripherals(new BlockComponentImpl<>(PeripheralLookup.get()));
+ ModRegistry.registerWiredElements(new BlockComponentImpl<>(WiredElementLookup.get()));
+ ModRegistry.registerMedia(new ItemComponentImpl<>(MediaLookup.get()));
// Register commands
CommandRegistrationCallback.EVENT.register((dispatcher, context, environment) -> CommandComputerCraft.register(dispatcher));
@@ -163,4 +147,27 @@ public class ComputerCraft {
return listener.reload(preparationBarrier, resourceManager, preparationsProfiler, reloadProfiler, backgroundExecutor, gameExecutor);
}
}
+
+ private record BlockComponentImpl(
+ BlockApiLookup lookup
+ ) implements ModRegistry.BlockComponent {
+ @Override
+ public void registerForBlockEntity(BlockEntityType blockEntityType, BiFunction super B, C, @Nullable T> provider) {
+ lookup.registerForBlockEntity(provider, blockEntityType);
+ }
+ }
+
+ private record ItemComponentImpl(
+ ItemApiLookup lookup
+ ) implements ModRegistry.ItemComponent {
+ @Override
+ public void registerForItems(BiFunction provider, ItemLike... items) {
+ lookup().registerForItems(provider::apply, items);
+ }
+
+ @Override
+ public void registerFallback(BiFunction provider) {
+ lookup().registerFallback(provider::apply);
+ }
+ }
}
diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/FabricCommonHooks.java b/projects/fabric/src/main/java/dan200/computercraft/shared/FabricCommonHooks.java
index bfcbf2b0c..55b457390 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/shared/FabricCommonHooks.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/shared/FabricCommonHooks.java
@@ -18,8 +18,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
public class FabricCommonHooks {
public static boolean onBlockDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity) {
diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java b/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java
index f14753d37..5db5b9da3 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java
@@ -22,8 +22,8 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FabricConfigFile.java b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FabricConfigFile.java
index 69549bf9c..2c28bca18 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FabricConfigFile.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/FabricConfigFile.java
@@ -12,10 +12,10 @@ import com.electronwill.nightconfig.core.io.WritingMode;
import com.google.errorprone.annotations.concurrent.GuardedBy;
import dan200.computercraft.shared.config.ConfigFile;
import org.apache.commons.lang3.function.TriFunction;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
index 2edaf9e28..0cf190974 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
@@ -8,6 +8,8 @@ import com.google.auto.service.AutoService;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType;
import dan200.computercraft.api.ComputerCraftAPI;
+import dan200.computercraft.api.media.IMedia;
+import dan200.computercraft.api.media.MediaLookup;
import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.network.wired.WiredElementLookup;
import dan200.computercraft.api.peripheral.IPeripheral;
@@ -61,8 +63,8 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.Vec3;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -130,7 +132,7 @@ public class PlatformHelperImpl implements PlatformHelper {
}
@Override
- @SuppressWarnings({ "UnstableApiUsage", "NullAway" }) // FIXME: SIDED is treated as nullable by NullAway
+ @SuppressWarnings("UnstableApiUsage")
public @Nullable ContainerTransfer getContainer(ServerLevel level, BlockPos pos, Direction side) {
var storage = ItemStorage.SIDED.find(level, pos, side);
if (storage != null) return FabricContainerTransfer.of(storage);
@@ -179,7 +181,7 @@ public class PlatformHelperImpl implements PlatformHelper {
@Override
public int getBurnTime(ItemStack stack) {
- @Nullable var fuel = FuelRegistry.INSTANCE.get(stack.getItem());
+ var fuel = FuelRegistry.INSTANCE.get(stack.getItem());
return fuel == null ? 0 : fuel;
}
@@ -229,6 +231,12 @@ public class PlatformHelperImpl implements PlatformHelper {
return new UseOnResult.Continue(true, true);
}
+ @Override
+ @SuppressWarnings("NullAway") // NullAway doesn't like the null here.
+ public @Nullable IMedia getMedia(ItemStack stack) {
+ return MediaLookup.get().find(stack, null);
+ }
+
private static final class RegistrationHelperImpl implements RegistrationHelper {
private final Registry registry;
private final List> entries = new ArrayList<>();
diff --git a/projects/forge-api/src/main/java/dan200/computercraft/api/media/MediaCapability.java b/projects/forge-api/src/main/java/dan200/computercraft/api/media/MediaCapability.java
new file mode 100644
index 000000000..bd0c5ee51
--- /dev/null
+++ b/projects/forge-api/src/main/java/dan200/computercraft/api/media/MediaCapability.java
@@ -0,0 +1,29 @@
+// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package dan200.computercraft.api.media;
+
+import dan200.computercraft.api.ComputerCraftAPI;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.item.ItemStack;
+import net.neoforged.neoforge.capabilities.ItemCapability;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * {@linkplain ItemCapability Item API lookup} for {@link IMedia}.
+ *
+ * The returned {@link IMedia} instance should be a singleton, and not reference the passed {@link ItemStack}.
+ */
+public final class MediaCapability {
+ public static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, "media");
+
+ private static final ItemCapability lookup = ItemCapability.createVoid(ID, IMedia.class);
+
+ private MediaCapability() {
+ }
+
+ public static ItemCapability get() {
+ return lookup;
+ }
+}
diff --git a/projects/forge/src/client/java/dan200/computercraft/client/model/FoiledModel.java b/projects/forge/src/client/java/dan200/computercraft/client/model/FoiledModel.java
index 430582937..622ea110e 100644
--- a/projects/forge/src/client/java/dan200/computercraft/client/model/FoiledModel.java
+++ b/projects/forge/src/client/java/dan200/computercraft/client/model/FoiledModel.java
@@ -14,7 +14,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.client.model.BakedModelWrapper;
import net.neoforged.neoforge.client.model.data.ModelData;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import java.util.List;
diff --git a/projects/forge/src/client/java/dan200/computercraft/client/model/TransformedBakedModel.java b/projects/forge/src/client/java/dan200/computercraft/client/model/TransformedBakedModel.java
index 75919e248..a43226ab6 100644
--- a/projects/forge/src/client/java/dan200/computercraft/client/model/TransformedBakedModel.java
+++ b/projects/forge/src/client/java/dan200/computercraft/client/model/TransformedBakedModel.java
@@ -14,8 +14,8 @@ import net.minecraft.util.RandomSource;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.client.model.BakedModelWrapper;
import net.neoforged.neoforge.client.model.data.ModelData;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.List;
/**
diff --git a/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java b/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java
index 2e1c72ed6..ce9ba8cab 100644
--- a/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java
+++ b/projects/forge/src/client/java/dan200/computercraft/client/platform/ClientPlatformHelperImpl.java
@@ -17,8 +17,8 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.client.model.data.ModelData;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Arrays;
@AutoService(dan200.computercraft.impl.client.ClientPlatformHelper.class)
@@ -42,7 +42,7 @@ public class ClientPlatformHelperImpl implements ClientPlatformHelper {
}
@Override
- public void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, @Nullable int[] tints) {
+ public void renderBakedModel(PoseStack transform, MultiBufferSource buffers, BakedModel model, int lightmapCoord, int overlayLight, int @Nullable [] tints) {
for (var renderType : model.getRenderTypes(ItemStack.EMPTY, true)) {
var buffer = buffers.getBuffer(renderType);
for (var face : directions) {
diff --git a/projects/forge/src/main/java/dan200/computercraft/ComputerCraft.java b/projects/forge/src/main/java/dan200/computercraft/ComputerCraft.java
index a3d092b52..ca82852c0 100644
--- a/projects/forge/src/main/java/dan200/computercraft/ComputerCraft.java
+++ b/projects/forge/src/main/java/dan200/computercraft/ComputerCraft.java
@@ -7,16 +7,17 @@ package dan200.computercraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.ForgeComputerCraftAPI;
import dan200.computercraft.api.detail.ForgeDetailRegistries;
+import dan200.computercraft.api.media.MediaCapability;
import dan200.computercraft.api.network.wired.WiredElementCapability;
import dan200.computercraft.api.peripheral.PeripheralCapability;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
+import dan200.computercraft.impl.MediaProviders;
import dan200.computercraft.impl.PocketUpgrades;
import dan200.computercraft.impl.Services;
import dan200.computercraft.impl.TurtleUpgrades;
import dan200.computercraft.shared.CommonHooks;
import dan200.computercraft.shared.ModRegistry;
-import dan200.computercraft.shared.config.Config;
import dan200.computercraft.shared.config.ConfigSpec;
import dan200.computercraft.shared.details.FluidData;
import dan200.computercraft.shared.integration.CreateIntegration;
@@ -25,19 +26,19 @@ import dan200.computercraft.shared.network.NetworkMessage;
import dan200.computercraft.shared.network.NetworkMessages;
import dan200.computercraft.shared.network.client.ClientNetworkContext;
import dan200.computercraft.shared.network.server.ServerNetworkContext;
-import dan200.computercraft.shared.peripheral.commandblock.CommandBlockPeripheral;
import dan200.computercraft.shared.peripheral.generic.methods.EnergyMethods;
import dan200.computercraft.shared.peripheral.generic.methods.FluidMethods;
import dan200.computercraft.shared.peripheral.generic.methods.InventoryMethods;
-import dan200.computercraft.shared.peripheral.modem.wired.CableBlockEntity;
-import dan200.computercraft.shared.peripheral.modem.wired.WiredModemFullBlockEntity;
-import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemBlockEntity;
import dan200.computercraft.shared.platform.ForgeConfigFile;
import dan200.computercraft.shared.recipe.function.RecipeFunction;
import dan200.computercraft.shared.turtle.TurtleOverlay;
+import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.ItemLike;
+import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.bus.api.SubscribeEvent;
@@ -48,7 +49,9 @@ import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.ModConfig;
import net.neoforged.fml.event.config.ModConfigEvent;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
+import net.neoforged.neoforge.capabilities.BlockCapability;
import net.neoforged.neoforge.capabilities.Capabilities;
+import net.neoforged.neoforge.capabilities.ItemCapability;
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent;
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent;
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
@@ -56,9 +59,10 @@ import net.neoforged.neoforge.network.registration.PayloadRegistrar;
import net.neoforged.neoforge.registries.DataPackRegistryEvent;
import net.neoforged.neoforge.registries.NewRegistryEvent;
import net.neoforged.neoforge.registries.RegistryBuilder;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.file.Path;
+import java.util.function.BiFunction;
@Mod(ComputerCraftAPI.MOD_ID)
@EventBusSubscriber(modid = ComputerCraftAPI.MOD_ID, bus = EventBusSubscriber.Bus.MOD)
@@ -141,29 +145,36 @@ public final class ComputerCraft {
*/
@SubscribeEvent
public static void onRegisterCapabilities(RegisterCapabilitiesEvent event) {
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.COMPUTER_NORMAL.get(), (b, d) -> b.peripheral());
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.COMPUTER_ADVANCED.get(), (b, d) -> b.peripheral());
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.TURTLE_NORMAL.get(), (b, d) -> b.peripheral());
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.TURTLE_ADVANCED.get(), (b, d) -> b.peripheral());
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.SPEAKER.get(), (b, d) -> b.peripheral());
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.PRINTER.get(), (b, d) -> b.peripheral());
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.DISK_DRIVE.get(), (b, d) -> b.peripheral());
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.MONITOR_NORMAL.get(), (b, d) -> b.peripheral());
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.MONITOR_ADVANCED.get(), (b, d) -> b.peripheral());
+ ModRegistry.registerPeripherals(new BlockComponentImpl<>(event, PeripheralCapability.get()));
+ ModRegistry.registerWiredElements(new BlockComponentImpl<>(event, WiredElementCapability.get()));
- event.registerBlockEntity(
- PeripheralCapability.get(), BlockEntityType.COMMAND_BLOCK,
- (b, d) -> Config.enableCommandBlock ? new CommandBlockPeripheral(b) : null
- );
+ var media = new ItemComponentImpl<>(event, MediaCapability.get());
+ ModRegistry.registerMedia(media);
+ media.registerFallback((stack, ctx) -> MediaProviders.get(stack));
+ }
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.WIRELESS_MODEM_NORMAL.get(), WirelessModemBlockEntity::getPeripheral);
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.WIRELESS_MODEM_ADVANCED.get(), WirelessModemBlockEntity::getPeripheral);
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get(), WiredModemFullBlockEntity::getPeripheral);
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.CABLE.get(), CableBlockEntity::getPeripheral);
- event.registerBlockEntity(PeripheralCapability.get(), ModRegistry.BlockEntities.REDSTONE_RELAY.get(), (b, d) -> b.peripheral());
+ private record BlockComponentImpl(
+ RegisterCapabilitiesEvent event, BlockCapability capability
+ ) implements ModRegistry.BlockComponent {
+ @Override
+ public void registerForBlockEntity(BlockEntityType blockEntityType, BiFunction super B, C, @Nullable T> provider) {
+ event.registerBlockEntity(capability, blockEntityType, provider::apply);
+ }
+ }
- event.registerBlockEntity(WiredElementCapability.get(), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get(), (b, d) -> b.getElement());
- event.registerBlockEntity(WiredElementCapability.get(), ModRegistry.BlockEntities.CABLE.get(), CableBlockEntity::getWiredElement);
+ private record ItemComponentImpl(
+ RegisterCapabilitiesEvent event, ItemCapability capability
+ ) implements ModRegistry.ItemComponent {
+ @Override
+ public void registerForItems(BiFunction provider, ItemLike... items) {
+ event.registerItem(capability, provider::apply, items);
+ }
+
+ @Override
+ public void registerFallback(BiFunction provider) {
+ var items = BuiltInRegistries.ITEM.stream().toArray(ItemLike[]::new);
+ event.registerItem(capability, provider::apply, items);
+ }
}
@SubscribeEvent
diff --git a/projects/forge/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java b/projects/forge/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java
index 39de54f2b..4017c7a8a 100644
--- a/projects/forge/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java
+++ b/projects/forge/src/main/java/dan200/computercraft/impl/ComputerCraftAPIImpl.java
@@ -7,6 +7,7 @@ package dan200.computercraft.impl;
import com.google.auto.service.AutoService;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.detail.DetailRegistry;
+import dan200.computercraft.api.media.MediaProvider;
import dan200.computercraft.impl.detail.DetailRegistryImpl;
import dan200.computercraft.shared.details.FluidData;
import dan200.computercraft.shared.peripheral.generic.ComponentLookup;
@@ -19,8 +20,8 @@ import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.fml.ModList;
import net.neoforged.neoforge.capabilities.BlockCapability;
import net.neoforged.neoforge.fluids.FluidStack;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.Objects;
@AutoService(ComputerCraftAPIService.class)
@@ -48,6 +49,11 @@ public final class ComputerCraftAPIImpl extends AbstractComputerCraftAPI impleme
return fluidStackDetails;
}
+ @Override
+ public void registerMediaProvider(MediaProvider provider) {
+ MediaProviders.register(provider);
+ }
+
/**
* A {@link ComponentLookup} for {@linkplain BlockCapability capabilities}.
*
diff --git a/projects/common/src/main/java/dan200/computercraft/impl/MediaProviders.java b/projects/forge/src/main/java/dan200/computercraft/impl/MediaProviders.java
similarity index 66%
rename from projects/common/src/main/java/dan200/computercraft/impl/MediaProviders.java
rename to projects/forge/src/main/java/dan200/computercraft/impl/MediaProviders.java
index dc6590fd4..b644e600a 100644
--- a/projects/common/src/main/java/dan200/computercraft/impl/MediaProviders.java
+++ b/projects/forge/src/main/java/dan200/computercraft/impl/MediaProviders.java
@@ -7,17 +7,13 @@ 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 org.jspecify.annotations.Nullable;
-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 providers = new LinkedHashSet<>();
private MediaProviders() {
@@ -33,13 +29,8 @@ public final class MediaProviders {
// 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);
- }
+ var media = mediaProvider.getMedia(stack);
+ if (media != null) return media;
}
return null;
}
diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java b/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java
index c8183b9c5..7b1286a14 100644
--- a/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java
+++ b/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/FluidMethods.java
@@ -16,8 +16,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.fluids.FluidStack;
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java b/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java
index 78287e276..1216d68c0 100644
--- a/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java
+++ b/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java
@@ -17,8 +17,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.items.wrapper.InvWrapper;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/platform/FakePlayerExt.java b/projects/forge/src/main/java/dan200/computercraft/shared/platform/FakePlayerExt.java
index 27329ce79..b6bedcd93 100644
--- a/projects/forge/src/main/java/dan200/computercraft/shared/platform/FakePlayerExt.java
+++ b/projects/forge/src/main/java/dan200/computercraft/shared/platform/FakePlayerExt.java
@@ -13,8 +13,8 @@ import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.player.Player;
import net.neoforged.neoforge.common.util.FakePlayer;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.OptionalInt;
class FakePlayerExt extends FakePlayer {
diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
index 96d16873d..b3dca6d52 100644
--- a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
+++ b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
@@ -9,6 +9,8 @@ import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.arguments.ArgumentType;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
+import dan200.computercraft.api.media.IMedia;
+import dan200.computercraft.api.media.MediaCapability;
import dan200.computercraft.api.network.wired.WiredElement;
import dan200.computercraft.api.network.wired.WiredElementCapability;
import dan200.computercraft.api.peripheral.IPeripheral;
@@ -30,7 +32,10 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.TagKey;
-import net.minecraft.world.*;
+import net.minecraft.world.Container;
+import net.minecraft.world.InteractionHand;
+import net.minecraft.world.InteractionResult;
+import net.minecraft.world.SimpleMenuProvider;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
@@ -58,8 +63,8 @@ import net.neoforged.neoforge.event.EventHooks;
import net.neoforged.neoforge.items.wrapper.InvWrapper;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
@@ -234,6 +239,11 @@ public class PlatformHelperImpl implements PlatformHelper {
return new UseOnResult.Continue(!event.getUseBlock().isFalse(), !event.getUseItem().isFalse());
}
+ @Override
+ public @Nullable IMedia getMedia(ItemStack stack) {
+ return stack.getCapability(MediaCapability.get());
+ }
+
private record RegistrationHelperImpl(DeferredRegister registry) implements RegistrationHelper {
@Override
public RegistryEntry register(String name, Supplier create) {
diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/util/CapabilityUtil.java b/projects/forge/src/main/java/dan200/computercraft/shared/util/CapabilityUtil.java
index fc21af5d4..85fe526a0 100644
--- a/projects/forge/src/main/java/dan200/computercraft/shared/util/CapabilityUtil.java
+++ b/projects/forge/src/main/java/dan200/computercraft/shared/util/CapabilityUtil.java
@@ -10,7 +10,7 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.capabilities.BlockCapability;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
public final class CapabilityUtil {
private CapabilityUtil() {
diff --git a/projects/lints/src/main/kotlin/cc/tweaked/linter/ForbiddenImport.kt b/projects/lints/src/main/kotlin/cc/tweaked/linter/ForbiddenImport.kt
new file mode 100644
index 000000000..fa10f9795
--- /dev/null
+++ b/projects/lints/src/main/kotlin/cc/tweaked/linter/ForbiddenImport.kt
@@ -0,0 +1,56 @@
+// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
+//
+// SPDX-License-Identifier: MPL-2.0
+
+@file:Suppress("JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE")
+
+package cc.tweaked.linter
+
+import com.google.errorprone.BugPattern
+import com.google.errorprone.VisitorState
+import com.google.errorprone.bugpatterns.BugChecker
+import com.google.errorprone.fixes.SuggestedFix
+import com.google.errorprone.matchers.Description
+import com.google.errorprone.util.ASTHelpers
+import com.sun.source.tree.ImportTree
+import com.sun.source.tree.Tree
+
+@BugPattern(
+ summary = "Checks for forbidden imports.",
+ severity = BugPattern.SeverityLevel.ERROR,
+ tags = [BugPattern.StandardTags.LIKELY_ERROR],
+)
+class ForbiddenImport : BugChecker(), BugChecker.ImportTreeMatcher {
+ override fun matchImport(tree: ImportTree, state: VisitorState): Description {
+ if (tree.isStatic || tree.qualifiedIdentifier.kind != Tree.Kind.MEMBER_SELECT) return Description.NO_MATCH
+
+ val sym = ASTHelpers.getSymbol(tree.qualifiedIdentifier) ?: return Description.NO_MATCH
+ val importedName = sym.qualifiedName.toString()
+ if (!IMPORTS.contains(importedName)) return Description.NO_MATCH
+
+ val message = buildDescription(tree.qualifiedIdentifier).setMessage("Cannot import this symbol")
+ val replacement = ALTERNATIVE_IMPORTS[importedName]
+ if (replacement != null) message.addFix(SuggestedFix.replace(tree.qualifiedIdentifier, replacement))
+
+ return message.build()
+ }
+
+ companion object {
+ private val ALTERNATIVE_IMPORTS = mapOf(
+ // Ban JSR 305 and JetBrains @Nullable, and prefer the JSpecify one.
+ "org.javax.annotation.Nullable" to "org.jspecify.annotations.Nullable",
+ "org.jetbrains.annotations.Nullable" to "org.jspecify.annotations.Nullable",
+ // Prefer ErrorProne annotations over JSR ones.
+ "javax.annotation.CheckReturnValue" to "com.google.errorprone.annotations.CheckReturnValue",
+ "javax.annotation.OverridingMethodsMustInvokeSuper" to "com.google.errorprone.annotations.OverridingMethodsMustInvokeSuper",
+ "javax.annotation.concurrent.GuardedBy" to "com.google.errorprone.annotations.concurrent.GuardedBy",
+ )
+
+ private val IMPORTS: Set = setOf(
+ // We ban all @Nonnull annotations, because that should be default already.
+ "javax.annotation.Nonnull",
+ "org.jetbrains.annotations.NotNull",
+ "org.jspecify.annotations.NonNull",
+ ) + ALTERNATIVE_IMPORTS.keys
+ }
+}
diff --git a/projects/lints/src/main/resources/META-INF/services/com.google.errorprone.bugpatterns.BugChecker b/projects/lints/src/main/resources/META-INF/services/com.google.errorprone.bugpatterns.BugChecker
index 388a1372a..075ac218b 100644
--- a/projects/lints/src/main/resources/META-INF/services/com.google.errorprone.bugpatterns.BugChecker
+++ b/projects/lints/src/main/resources/META-INF/services/com.google.errorprone.bugpatterns.BugChecker
@@ -2,6 +2,7 @@
#
# SPDX-License-Identifier: MPL-2.0
cc.tweaked.linter.ExtraMustCallSuper
+cc.tweaked.linter.ForbiddenImport
cc.tweaked.linter.LoaderOverride
cc.tweaked.linter.MissingLoaderOverride
cc.tweaked.linter.SideChecker
diff --git a/projects/lints/src/test/java/cc/tweaked/linter/TestForbiddenImport.java b/projects/lints/src/test/java/cc/tweaked/linter/TestForbiddenImport.java
new file mode 100644
index 000000000..9e90dbcf9
--- /dev/null
+++ b/projects/lints/src/test/java/cc/tweaked/linter/TestForbiddenImport.java
@@ -0,0 +1,39 @@
+// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package cc.tweaked.linter;
+
+import com.google.common.base.Predicates;
+import com.google.errorprone.CompilationTestHelper;
+import org.junit.jupiter.api.Test;
+
+public class TestForbiddenImport {
+ private final CompilationTestHelper compilationHelper = CompilationTestHelper.newInstance(ForbiddenImport.class, getClass());
+
+ @Test
+ public void testForbiddenImport() {
+ compilationHelper
+ .addSourceLines("Import.java", """
+ // BUG: Diagnostic matches: X
+ import org.jspecify.annotations.NonNull;
+ class X {
+ }
+ """)
+ .expectErrorMessage("X", Predicates.containsPattern("Cannot import this symbol"))
+ .doTest();
+ }
+
+ @Test
+ public void testForbiddenImportSuggestion() {
+ compilationHelper
+ .addSourceLines("Import.java", """
+ // BUG: Diagnostic matches: X
+ import javax.annotation.concurrent.GuardedBy;
+ class X {
+ }
+ """)
+ .expectErrorMessage("X", Predicates.containsPattern("Did you mean 'import com.google.errorprone.annotations.concurrent.GuardedBy;'"))
+ .doTest();
+ }
+}
diff --git a/projects/standalone/src/main/java/cc/tweaked/standalone/Main.java b/projects/standalone/src/main/java/cc/tweaked/standalone/Main.java
index 35411959f..ad96dce4d 100644
--- a/projects/standalone/src/main/java/cc/tweaked/standalone/Main.java
+++ b/projects/standalone/src/main/java/cc/tweaked/standalone/Main.java
@@ -20,6 +20,7 @@ import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.core.util.Colour;
import org.apache.commons.cli.*;
import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL;
@@ -29,7 +30,6 @@ import org.lwjgl.system.MemoryStack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
diff --git a/projects/standalone/src/main/java/cc/tweaked/standalone/StandaloneComputerEnvironment.java b/projects/standalone/src/main/java/cc/tweaked/standalone/StandaloneComputerEnvironment.java
index 74527be6e..da10d46bd 100644
--- a/projects/standalone/src/main/java/cc/tweaked/standalone/StandaloneComputerEnvironment.java
+++ b/projects/standalone/src/main/java/cc/tweaked/standalone/StandaloneComputerEnvironment.java
@@ -9,10 +9,10 @@ import dan200.computercraft.core.computer.ComputerEnvironment;
import dan200.computercraft.core.filesystem.MemoryMount;
import dan200.computercraft.core.filesystem.WritableFileMount;
import dan200.computercraft.core.metrics.MetricsObserver;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.annotation.Nullable;
import java.nio.file.Path;
/**
diff --git a/projects/standalone/src/main/java/cc/tweaked/standalone/StandaloneGlobalEnvironment.java b/projects/standalone/src/main/java/cc/tweaked/standalone/StandaloneGlobalEnvironment.java
index c454645a8..a7a548be9 100644
--- a/projects/standalone/src/main/java/cc/tweaked/standalone/StandaloneGlobalEnvironment.java
+++ b/projects/standalone/src/main/java/cc/tweaked/standalone/StandaloneGlobalEnvironment.java
@@ -7,7 +7,7 @@ package cc.tweaked.standalone;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.core.computer.GlobalEnvironment;
import dan200.computercraft.core.filesystem.FileMount;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/projects/web/src/builder/java/cc/tweaked/web/builder/PatchCobalt.java b/projects/web/src/builder/java/cc/tweaked/web/builder/PatchCobalt.java
index 6b623f4a5..644e6929e 100644
--- a/projects/web/src/builder/java/cc/tweaked/web/builder/PatchCobalt.java
+++ b/projects/web/src/builder/java/cc/tweaked/web/builder/PatchCobalt.java
@@ -4,13 +4,12 @@
package cc.tweaked.web.builder;
+import org.jspecify.annotations.Nullable;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
-import javax.annotation.Nullable;
-
import static org.objectweb.asm.Opcodes.*;
/**
diff --git a/projects/web/src/builder/java/cc/tweaked/web/builder/TransformingClassLoader.java b/projects/web/src/builder/java/cc/tweaked/web/builder/TransformingClassLoader.java
index 23c50616c..0bd15b413 100644
--- a/projects/web/src/builder/java/cc/tweaked/web/builder/TransformingClassLoader.java
+++ b/projects/web/src/builder/java/cc/tweaked/web/builder/TransformingClassLoader.java
@@ -4,13 +4,13 @@
package cc.tweaked.web.builder;
+import org.jspecify.annotations.Nullable;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.ClassRemapper;
import org.objectweb.asm.commons.Remapper;
-import javax.annotation.Nullable;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
diff --git a/projects/web/src/main/java/cc/tweaked/web/EmulatedComputer.java b/projects/web/src/main/java/cc/tweaked/web/EmulatedComputer.java
index c39467d74..66e760443 100644
--- a/projects/web/src/main/java/cc/tweaked/web/EmulatedComputer.java
+++ b/projects/web/src/main/java/cc/tweaked/web/EmulatedComputer.java
@@ -21,13 +21,13 @@ import dan200.computercraft.core.computer.ComputerSide;
import dan200.computercraft.core.filesystem.MemoryMount;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.core.terminal.Terminal;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.teavm.jso.JSObject;
import org.teavm.jso.core.JSString;
import org.teavm.jso.typedarrays.ArrayBuffer;
-import javax.annotation.Nullable;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
diff --git a/projects/web/src/main/java/cc/tweaked/web/EmulatorEnvironment.java b/projects/web/src/main/java/cc/tweaked/web/EmulatorEnvironment.java
index 7230cfa23..bd1d418e9 100644
--- a/projects/web/src/main/java/cc/tweaked/web/EmulatorEnvironment.java
+++ b/projects/web/src/main/java/cc/tweaked/web/EmulatorEnvironment.java
@@ -7,8 +7,8 @@ package cc.tweaked.web;
import cc.tweaked.web.js.Callbacks;
import dan200.computercraft.api.filesystem.Mount;
import dan200.computercraft.core.computer.GlobalEnvironment;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
@@ -21,7 +21,7 @@ final class EmulatorEnvironment implements GlobalEnvironment {
private final String version = Callbacks.getModVersion();
private @Nullable ResourceMount romMount;
- private @Nullable byte[] bios;
+ private byte @Nullable [] bios;
private EmulatorEnvironment() {
}
diff --git a/projects/web/src/main/java/cc/tweaked/web/ResourceMount.java b/projects/web/src/main/java/cc/tweaked/web/ResourceMount.java
index b6877dd24..bbbc803c8 100644
--- a/projects/web/src/main/java/cc/tweaked/web/ResourceMount.java
+++ b/projects/web/src/main/java/cc/tweaked/web/ResourceMount.java
@@ -7,8 +7,8 @@ package cc.tweaked.web;
import cc.tweaked.web.js.Callbacks;
import dan200.computercraft.core.apis.handles.ArrayByteChannel;
import dan200.computercraft.core.filesystem.AbstractInMemoryMount;
+import org.jspecify.annotations.Nullable;
-import javax.annotation.Nullable;
import java.nio.channels.SeekableByteChannel;
/**
@@ -43,7 +43,7 @@ final class ResourceMount extends AbstractInMemoryMount
protected static final class FileEntry extends AbstractInMemoryMount.FileEntry {
private final String path;
- private @Nullable byte[] contents;
+ private byte @Nullable [] contents;
FileEntry(String path) {
this.path = path;
diff --git a/projects/web/src/main/java/cc/tweaked/web/js/ComputerDisplay.java b/projects/web/src/main/java/cc/tweaked/web/js/ComputerDisplay.java
index ecd5b9a2f..2cc6c194d 100644
--- a/projects/web/src/main/java/cc/tweaked/web/js/ComputerDisplay.java
+++ b/projects/web/src/main/java/cc/tweaked/web/js/ComputerDisplay.java
@@ -4,10 +4,9 @@
package cc.tweaked.web.js;
+import org.jspecify.annotations.Nullable;
import org.teavm.jso.JSObject;
-import javax.annotation.Nullable;
-
/**
* The Javascript-side terminal which displays this computer.
*
diff --git a/projects/web/src/main/java/cc/tweaked/web/js/ComputerHandle.java b/projects/web/src/main/java/cc/tweaked/web/js/ComputerHandle.java
index 87fd462f7..687271b8a 100644
--- a/projects/web/src/main/java/cc/tweaked/web/js/ComputerHandle.java
+++ b/projects/web/src/main/java/cc/tweaked/web/js/ComputerHandle.java
@@ -4,13 +4,12 @@
package cc.tweaked.web.js;
+import org.jspecify.annotations.Nullable;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
import org.teavm.jso.core.JSString;
import org.teavm.jso.typedarrays.ArrayBuffer;
-import javax.annotation.Nullable;
-
/**
* A Javascript-facing interface for controlling computers.
*/
diff --git a/projects/web/src/main/java/cc/tweaked/web/js/JavascriptConv.java b/projects/web/src/main/java/cc/tweaked/web/js/JavascriptConv.java
index 713fc0934..46216c579 100644
--- a/projects/web/src/main/java/cc/tweaked/web/js/JavascriptConv.java
+++ b/projects/web/src/main/java/cc/tweaked/web/js/JavascriptConv.java
@@ -5,6 +5,7 @@
package cc.tweaked.web.js;
import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.Nullable;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSByRef;
import org.teavm.jso.JSObject;
@@ -15,7 +16,6 @@ import org.teavm.jso.core.JSString;
import org.teavm.jso.typedarrays.ArrayBuffer;
import org.teavm.jso.typedarrays.Int8Array;
-import javax.annotation.Nullable;
import java.nio.ByteBuffer;
/**
@@ -29,7 +29,7 @@ public class JavascriptConv {
* @return The converted value.
*/
@Contract("null -> null; !null -> !null")
- public static @Nullable Object[] toJava(@Nullable JSObject[] value) {
+ public static @Nullable Object @Nullable [] toJava(@Nullable JSObject @Nullable [] value) {
if (value == null) return null;
var out = new Object[value.length];
for (var i = 0; i < value.length; i++) out[i] = toJava(value[i]);
diff --git a/projects/web/src/main/java/cc/tweaked/web/peripheral/AudioState.java b/projects/web/src/main/java/cc/tweaked/web/peripheral/AudioState.java
index 9e3f5838c..fc2194286 100644
--- a/projects/web/src/main/java/cc/tweaked/web/peripheral/AudioState.java
+++ b/projects/web/src/main/java/cc/tweaked/web/peripheral/AudioState.java
@@ -6,10 +6,10 @@ package cc.tweaked.web.peripheral;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaTable;
+import org.jspecify.annotations.Nullable;
import org.teavm.jso.webaudio.AudioBuffer;
import org.teavm.jso.webaudio.AudioContext;
-import javax.annotation.Nullable;
import java.util.Optional;
import static cc.tweaked.web.peripheral.SpeakerPeripheral.SAMPLE_RATE;
diff --git a/projects/web/src/main/java/cc/tweaked/web/peripheral/SpeakerPeripheral.java b/projects/web/src/main/java/cc/tweaked/web/peripheral/SpeakerPeripheral.java
index d4f57ad3b..930f70fd6 100644
--- a/projects/web/src/main/java/cc/tweaked/web/peripheral/SpeakerPeripheral.java
+++ b/projects/web/src/main/java/cc/tweaked/web/peripheral/SpeakerPeripheral.java
@@ -10,9 +10,9 @@ import dan200.computercraft.api.lua.LuaTable;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
+import org.jspecify.annotations.Nullable;
import org.teavm.jso.webaudio.AudioContext;
-import javax.annotation.Nullable;
import java.util.Optional;
import static dan200.computercraft.api.lua.LuaValues.checkFinite;
diff --git a/projects/web/src/main/java/dan200/computercraft/core/apis/http/request/THttpRequest.java b/projects/web/src/main/java/dan200/computercraft/core/apis/http/request/THttpRequest.java
index 13f9d48ee..08a2081da 100644
--- a/projects/web/src/main/java/dan200/computercraft/core/apis/http/request/THttpRequest.java
+++ b/projects/web/src/main/java/dan200/computercraft/core/apis/http/request/THttpRequest.java
@@ -16,12 +16,12 @@ import dan200.computercraft.core.apis.http.ResourceGroup;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
+import org.jspecify.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.teavm.jso.ajax.XMLHttpRequest;
import org.teavm.jso.typedarrays.ArrayBuffer;
-import javax.annotation.Nullable;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
diff --git a/projects/web/src/main/java/dan200/computercraft/core/apis/http/websocket/TWebsocket.java b/projects/web/src/main/java/dan200/computercraft/core/apis/http/websocket/TWebsocket.java
index 671eeb506..f9154cc5f 100644
--- a/projects/web/src/main/java/dan200/computercraft/core/apis/http/websocket/TWebsocket.java
+++ b/projects/web/src/main/java/dan200/computercraft/core/apis/http/websocket/TWebsocket.java
@@ -13,10 +13,10 @@ import dan200.computercraft.core.apis.http.ResourceGroup;
import dan200.computercraft.core.apis.http.options.Action;
import dan200.computercraft.core.apis.http.options.Options;
import io.netty.handler.codec.http.HttpHeaders;
+import org.jspecify.annotations.Nullable;
import org.teavm.jso.typedarrays.Int8Array;
import org.teavm.jso.websocket.WebSocket;
-import javax.annotation.Nullable;
import java.net.URI;
import java.nio.ByteBuffer;
diff --git a/projects/web/src/main/java/dan200/computercraft/core/asm/MethodReflection.java b/projects/web/src/main/java/dan200/computercraft/core/asm/MethodReflection.java
index 96c3ed889..350bd268b 100644
--- a/projects/web/src/main/java/dan200/computercraft/core/asm/MethodReflection.java
+++ b/projects/web/src/main/java/dan200/computercraft/core/asm/MethodReflection.java
@@ -13,9 +13,9 @@ import dan200.computercraft.api.lua.MethodResult;
import dan200.computercraft.api.peripheral.PeripheralType;
import dan200.computercraft.core.methods.LuaMethod;
import dan200.computercraft.core.methods.NamedMethod;
+import org.jspecify.annotations.Nullable;
import org.teavm.metaprogramming.*;
-import javax.annotation.Nullable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
diff --git a/projects/web/src/main/java/dan200/computercraft/core/asm/StaticGenerator.java b/projects/web/src/main/java/dan200/computercraft/core/asm/StaticGenerator.java
index dddf9a7af..945c86246 100644
--- a/projects/web/src/main/java/dan200/computercraft/core/asm/StaticGenerator.java
+++ b/projects/web/src/main/java/dan200/computercraft/core/asm/StaticGenerator.java
@@ -11,12 +11,12 @@ import com.google.common.primitives.Primitives;
import com.google.common.reflect.TypeToken;
import dan200.computercraft.api.lua.*;
import dan200.computercraft.core.methods.LuaMethod;
+import org.jspecify.annotations.Nullable;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.teavm.metaprogramming.ReflectClass;
-import javax.annotation.Nullable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.ByteBuffer;
@@ -124,8 +124,7 @@ public final class StaticGenerator {
}
}
- @Nullable
- private byte[] generate(String className, Class> target, Method targetMethod, boolean unsafe) {
+ private byte @Nullable [] generate(String className, Class> target, Method targetMethod, boolean unsafe) {
var internalName = className.replace(".", "/");
// Construct a public final class which extends Object and implements MethodInstance.Delegate
@@ -207,8 +206,7 @@ public final class StaticGenerator {
return cw.toByteArray();
}
- @Nullable
- private Boolean loadArg(MethodVisitor mw, Class> target, Method method, boolean unsafe, java.lang.reflect.Type genericArg, int argIndex) {
+ private @Nullable Boolean loadArg(MethodVisitor mw, Class> target, Method method, boolean unsafe, java.lang.reflect.Type genericArg, int argIndex) {
if (genericArg == target) {
mw.visitVarInsn(ALOAD, 1);
mw.visitTypeInsn(CHECKCAST, Type.getInternalName(target));