1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-04-20 09:43:15 +00:00

Switch to JSpecify annotations

Now, hear me out, what if instead of having three @Nullable annotations,
we had *four*?

I've been wanting to switch away from javax.annoations for a while. The
library has been deprecated for ever and, unlike other @Nullable
annotations, the annotation is attached to the parameter/function
itself, rather than the type.

We use JSpecify rather than one of the alternatives (JetBrains,
CheckerFramework) mostly because it's what NullAway recommends. We keep
CheckerFramework around for @DefaultQualifier, and JB's for @Contract.

There are some ugly changes here — for instance, `@Nullable byte[]` is
replace by `byte @Nullable`, and `@Nullable ILuaMachine.Factory` is
`ILuaMachine.@Nullable Factory`. Ughr, I understand why, but it does not
spark joy :).
This commit is contained in:
Jonathan Coates 2025-02-16 18:09:15 +00:00
parent 12a44fed6f
commit 0998acaa82
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
326 changed files with 542 additions and 540 deletions
buildSrc/src/main/kotlin
config/checkstyle
gradle
projects
common-api/src
common/src
client/java/dan200/computercraft/client
datagen/java/dan200/computercraft/data
examples/java/com/example/examplemod
main/java/dan200/computercraft

@ -84,7 +84,6 @@ sourceSets.all {
options.errorprone {
check("InvalidBlockTag", CheckSeverity.OFF) // Broken by @cc.xyz
check("InvalidParam", CheckSeverity.OFF) // Broken by records.
check("InlineMeSuggester", CheckSeverity.OFF) // Minecraft uses @Deprecated liberally
// Too many false positives right now. Maybe we need an indirection for it later on.
check("ReferenceEquality", CheckSeverity.OFF)

@ -92,7 +92,10 @@ SPDX-License-Identifier: MPL-2.0
<module name="InvalidJavadocPosition" />
<module name="JavadocBlockTagLocation" />
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocType">
<!-- Seems to complain about @hidden!? -->
<property name="allowUnknownTags" value="true" />
</module>
<module name="JavadocStyle">
<property name="checkHtml" value="false" />
</module>
@ -143,7 +146,10 @@ SPDX-License-Identifier: MPL-2.0
<module name="NoWhitespaceAfter">
<property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP,METHOD_REF" />
</module>
<module name="NoWhitespaceBefore" />
<module name="NoWhitespaceBefore">
<!-- Allow whitespace before "..." for @Nullable annotations -->
<property name="tokens" value="COMMA,SEMI,POST_INC,POST_DEC,LABELED_STAT" />
</module>
<!-- TODO: Decide on an OperatorWrap style. -->
<module name="ParenPad" />
<module name="SeparatorWrap">

@ -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"
@ -58,9 +58,9 @@ jmh = "1.37"
# Build tools
cctJavadoc = "1.8.3"
checkstyle = "10.14.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"
@ -69,7 +69,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"
@ -89,7 +89,7 @@ fastutil = { module = "it.unimi.dsi:fastutil", version.ref = "fastutil" }
forgeSpi = { module = "net.minecraftforge:forgespi", version.ref = "forgeSpi" }
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" }
@ -178,7 +178,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

@ -12,8 +12,8 @@ import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;

@ -14,8 +14,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import org.joml.Matrix4f;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
final class TurtleUpgradeModellers {
private static final Transformation leftTransform = getMatrixFor(-0.4065f);

@ -11,8 +11,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 {

@ -10,8 +10,7 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
import dan200.computercraft.impl.Services;
import org.jetbrains.annotations.ApiStatus;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* Backing interface for {@link ComputerCraftAPIClient}

@ -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.

@ -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;

@ -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.

@ -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

@ -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.

@ -12,8 +12,7 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
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.

@ -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}.

@ -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;
/**

@ -14,8 +14,8 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Map;
/**

@ -7,8 +7,7 @@ package dan200.computercraft.api.pocket;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.upgrades.UpgradeBase;
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.

@ -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.

@ -9,8 +9,8 @@ import dan200.computercraft.api.upgrades.UpgradeBase;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.Items;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.function.BiFunction;
/**

@ -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;
}
}

@ -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.function.Consumer;
/**

@ -9,8 +9,7 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Contract;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* An upgrade (i.e. a {@link ITurtleUpgrade}) and its current upgrade data.

@ -19,8 +19,8 @@ import net.minecraft.data.PackOutput;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

@ -28,8 +28,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}

@ -12,8 +12,7 @@ import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* Abstraction layer for Forge and Fabric. See implementations for more details.

@ -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;
/**

@ -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;

@ -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;
/**

@ -46,8 +46,8 @@ import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
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.function.BiConsumer;

@ -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;
/**

@ -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;

@ -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;

@ -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;

@ -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;

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

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

@ -13,8 +13,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;

@ -20,8 +20,8 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.BakedModel;
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;

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

@ -13,8 +13,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ServerGamePacketListener;
import net.minecraft.sounds.SoundEvent;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public interface ClientPlatformHelper extends dan200.computercraft.impl.client.ClientPlatformHelper {
static ClientPlatformHelper get() {
@ -39,7 +38,7 @@ 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);
/**
* Play a record at a particular position.

@ -10,8 +10,8 @@ import dan200.computercraft.shared.computer.terminal.TerminalState;
import dan200.computercraft.shared.network.client.PocketComputerDataMessage;
import dan200.computercraft.shared.pocket.items.PocketComputerItem;
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;

@ -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.

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

@ -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;

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

@ -27,11 +27,11 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.jspecify.annotations.Nullable;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL31;
import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.function.Consumer;

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

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

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

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

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

@ -11,7 +11,7 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.turtle.upgrades.TurtleModem;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;
import java.util.Collection;
import java.util.List;

@ -10,8 +10,8 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.item.crafting.RecipeSerializer;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

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

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

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

@ -36,8 +36,8 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

@ -7,10 +7,10 @@ package dan200.computercraft.impl;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.api.media.MediaProvider;
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.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

@ -18,10 +18,10 @@ import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener;
import net.minecraft.util.GsonHelper;
import net.minecraft.util.profiling.ProfilerFiller;
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.Collection;
import java.util.Collections;
import java.util.HashMap;

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

@ -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;
/**

@ -11,8 +11,8 @@ import dan200.computercraft.api.network.wired.WiredNetwork;
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;

@ -30,8 +30,8 @@ import net.minecraft.world.level.storage.loot.BuiltInLootTables;
import net.minecraft.world.level.storage.loot.LootPool;
import net.minecraft.world.level.storage.loot.entries.LootTableReference;
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.Set;
import java.util.function.BiConsumer;
@ -101,7 +101,7 @@ public final class CommonHooks {
BuiltInLootTables.VILLAGE_CARTOGRAPHER
);
public static @Nullable LootPool.Builder getExtraLootPool(ResourceLocation lootTable) {
public static LootPool.@Nullable Builder getExtraLootPool(ResourceLocation lootTable) {
if (!lootTable.getNamespace().equals("minecraft") || !TREASURE_DISK_LOOT_TABLES.contains(lootTable)) {
return null;
}

@ -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.*;

@ -22,8 +22,8 @@ import net.minecraft.network.chat.ComponentContents;
import net.minecraft.network.chat.MutableComponent;
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;
@ -43,11 +43,11 @@ 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[]", OptionalInt.empty(), null, OptionalInt.empty(), null, null, null, null);
private static UuidArgument uuidArgument = UuidArgument.uuid();
private static final UuidArgument uuidArgument = UuidArgument.uuid();
/**
* A {@link ComputerSelector} which matches all computers.
@ -279,7 +279,7 @@ public record ComputerSelector(
private @Nullable String label;
private @Nullable ComputerFamily family;
private @Nullable AABB bounds;
private @Nullable MinMaxBounds.Doubles range;
private MinMaxBounds.@Nullable Doubles range;
}
private static final Map<String, Option> options;

@ -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;

@ -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;

@ -12,8 +12,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.

@ -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;

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

@ -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;

@ -23,8 +23,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.phys.BlockHitResult;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
/**
* A block which has a container and can be placed in a horizontal direction.

@ -36,8 +36,8 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.loot.LootParams;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.BlockHitResult;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.List;
public abstract class AbstractComputerBlock<T extends AbstractComputerBlockEntity> extends HorizontalDirectionalBlock implements IBundledRedstoneBlock, EntityBlock {

@ -34,8 +34,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;

@ -17,8 +17,7 @@ import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public class ComputerBlock<T extends ComputerBlockEntity> extends AbstractComputerBlock<T> {
public static final EnumProperty<ComputerState> STATE = EnumProperty.create("state", ComputerState.class);

@ -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;

@ -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.

@ -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;
/**

@ -29,8 +29,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;
@ -214,7 +214,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);
}

@ -6,8 +6,8 @@ package dan200.computercraft.shared.computer.core;
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.*;
public class ServerComputerRegistry {

@ -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;

@ -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 {

@ -16,8 +16,8 @@ import net.minecraft.world.item.BlockItem;
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;
public abstract class AbstractComputerItem extends BlockItem implements IComputerItem, IMedia {

@ -10,7 +10,7 @@ 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.

@ -8,8 +8,7 @@ import dan200.computercraft.shared.computer.blocks.ComputerBlock;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public class ComputerItem extends AbstractComputerItem {
public ComputerItem(ComputerBlock<?> block, Properties settings) {

@ -6,8 +6,7 @@ package dan200.computercraft.shared.computer.items;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import javax.annotation.Nullable;
import org.jspecify.annotations.Nullable;
public interface IComputerItem {
String NBT_ID = "ComputerId";

@ -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;

@ -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;

@ -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;

@ -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;

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

@ -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());

@ -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;

@ -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;

@ -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;

@ -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 #getContents() list of stacks}.

@ -13,8 +13,8 @@ import net.minecraft.network.chat.Component;
import net.minecraft.world.item.EnchantedBookItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.*;
/**

@ -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;

@ -22,8 +22,8 @@ import net.minecraft.world.item.crafting.CraftingBookCategory;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.ShapedRecipe;
import org.jspecify.annotations.Nullable;
import javax.annotation.Nullable;
import java.util.*;
import java.util.function.Function;

@ -28,7 +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 org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.Nullable;
/**
* Extends {@link LecternBlock} with support for {@linkplain PrintoutItem printouts}.

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