1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-08-31 01:27:55 +00:00

It now compiles.

This commit is contained in:
Jacob Farley
2020-08-31 19:09:22 -05:00
parent cb549d8f43
commit 76fe33760d
212 changed files with 3518 additions and 5783 deletions

View File

@@ -50,7 +50,7 @@ dependencies {
compile 'javax.vecmath:vecmath:1.5.2'
shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT'
shade 'org.squiddev:Cobalt:0.5.1-SNAPSHOT'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.1.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.1.0'

View File

@@ -6,8 +6,9 @@
package dan200.computercraft;
import static dan200.computercraft.shared.Registry.*;
import static dan200.computercraft.shared.ComputerCraftRegistry.*;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
@@ -17,15 +18,17 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.AddressPredicate;
import dan200.computercraft.core.apis.http.options.Action;
import dan200.computercraft.core.apis.http.options.AddressRule;
import dan200.computercraft.core.asm.GenericSource;
import dan200.computercraft.shared.Config;
import dan200.computercraft.core.apis.http.websocket.Websocket;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
import dan200.computercraft.shared.turtle.upgrades.TurtleAxe;
import dan200.computercraft.shared.turtle.upgrades.TurtleCraftingTable;
import dan200.computercraft.shared.turtle.upgrades.TurtleHoe;
@@ -34,7 +37,12 @@ import dan200.computercraft.shared.turtle.upgrades.TurtleShovel;
import dan200.computercraft.shared.turtle.upgrades.TurtleSpeaker;
import dan200.computercraft.shared.turtle.upgrades.TurtleSword;
import dan200.computercraft.shared.turtle.upgrades.TurtleTool;
import dan200.computercraft.shared.util.ServiceUtil;
import dan200.computercraft.shared.util.Config;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -43,52 +51,59 @@ import net.fabricmc.api.ModInitializer;
public final class ComputerCraft implements ModInitializer {
public static final String MOD_ID = "computercraft";
public static ItemGroup MAIN_GROUP = FabricItemGroupBuilder.build(new Identifier(MOD_ID, "main"), () -> new ItemStack(ModBlocks.COMPUTER_NORMAL));
// Configuration options
public static final String[] DEFAULT_HTTP_ALLOW = new String[] {"*"};
public static final String[] DEFAULT_HTTP_DENY = new String[] {
public static final String[] DEFAULT_HTTP_WHITELIST = new String[] {"*"};
public static final String[] DEFAULT_HTTP_BLACKLIST = new String[] {
"127.0.0.0/8",
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"fd00::/8",
};
};
public static List<AddressRule> httpRules = Collections.unmodifiableList( Stream.concat(
Stream.of( DEFAULT_HTTP_BLACKLIST )
.map( x -> AddressRule.parse( x, Action.DENY.toPartial() ) )
.filter( Objects::nonNull ),
Stream.of( DEFAULT_HTTP_WHITELIST )
.map( x -> AddressRule.parse( x, Action.ALLOW.toPartial() ) )
.filter( Objects::nonNull )
).collect( Collectors.toList() ) );
public static boolean commandRequireCreative = false;
public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST;
public static final int terminalWidth_computer = 51;
public static final int terminalHeight_computer = 19;
public static final int terminalWidth_turtle = 39;
public static final int terminalHeight_turtle = 13;
public static final int terminalWidth_pocketComputer = 26;
public static final int terminalHeight_pocketComputer = 20;
public static int computerSpaceLimit = 1000 * 1000;
public static int floppySpaceLimit = 125 * 1000;
public static int maximumFilesOpen = 128;
public static boolean disableLua51Features = false;
public static String defaultComputerSettings = "";
public static boolean debugEnable = true;
public static boolean logComputerErrors = true;
public static boolean commandRequireCreative = true;
public static int computerThreads = 1;
public static boolean disable_lua51_features = false;
public static String default_computer_settings = "";
public static boolean debug_enable = true;
public static boolean logPeripheralErrors = false;
public static int computer_threads = 1;
public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(10);
public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(5);
public static boolean httpEnabled = true;
public static boolean httpWebsocketEnabled = true;
public static List<AddressRule> httpRules = Collections.unmodifiableList(Stream.concat(Stream.of(DEFAULT_HTTP_DENY)
.map(x -> AddressRule.parse(x, Action.DENY.toPartial()))
.filter(Objects::nonNull),
Stream.of(DEFAULT_HTTP_ALLOW)
.map(x -> AddressRule.parse(x, Action.ALLOW.toPartial()))
.filter(Objects::nonNull))
.collect(Collectors.toList()));
public static boolean http_enable = true;
public static boolean http_websocket_enable = true;
public static AddressPredicate http_whitelist = new AddressPredicate(DEFAULT_HTTP_WHITELIST);
public static AddressPredicate http_blacklist = new AddressPredicate(DEFAULT_HTTP_BLACKLIST);
public static int httpTimeout = 30000;
public static int httpMaxRequests = 16;
public static long httpMaxDownload = 16 * 1024 * 1024;
public static long httpMaxUpload = 4 * 1024 * 1024;
public static int httpMaxWebsockets = 4;
public static int httpMaxWebsocketMessage = Websocket.MAX_MESSAGE_SIZE;
public static boolean enableCommandBlock = false;
public static int modemRange = 64;
public static int modemHighAltitudeRange = 384;
public static int modemRangeDuringStorm = 64;
public static int modemHighAltitudeRangeDuringStorm = 384;
public static int modem_range = 64;
public static int modem_highAltitudeRange = 384;
public static int modem_rangeDuringStorm = 64;
public static int modem_highAltitudeRangeDuringStorm = 384;
public static int maxNotesPerTick = 8;
public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST;
public static double monitorDistanceSq = 4096;
public static long monitorBandwidth = 1_000_000;
public static boolean turtlesNeedFuel = true;
public static int turtleFuelLimit = 20000;
public static int advancedTurtleFuelLimit = 100000;
@@ -96,19 +111,9 @@ public final class ComputerCraft implements ModInitializer {
public static boolean turtlesCanPush = true;
public static EnumSet<TurtleAction> turtleDisabledActions = EnumSet.noneOf(TurtleAction.class);
public static boolean genericPeripheral = false;
public static int computerTermWidth = 51;
public static int computerTermHeight = 19;
public static final int turtleTermWidth = 39;
public static final int turtleTermHeight = 13;
public static int pocketTermWidth = 26;
public static int pocketTermHeight = 20;
public static int monitorWidth = 8;
public static int monitorHeight = 6;
public static double monitorDistanceSq = 4096;
public static final class TurtleUpgrades {
public static TurtleModem wirelessModemNormal;
@@ -139,10 +144,8 @@ public final class ComputerCraft implements ModInitializer {
@Override
public void onInitialize() {
Config.setup();
GenericSource.setup(() -> ServiceUtil.loadServicesForge(GenericSource.class));
Config.load(Paths.get(FabricLoader.getInstance().getConfigDir().toFile().getPath(), MOD_ID + ".json5"));
ComputerCraftProxyCommon.init();
init();
}
}

View File

@@ -21,10 +21,13 @@ import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.*;
import dan200.computercraft.shared.peripheral.modem.wired.TileCable;
import dan200.computercraft.shared.peripheral.modem.wired.TileWiredModemFull;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.wired.WiredNode;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.resource.ReloadableResourceManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.Identifier;
@@ -34,14 +37,11 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.swing.text.html.Option;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
import static dan200.computercraft.shared.Capabilities.CAPABILITY_WIRED_ELEMENT;
public final class ComputerCraftAPIImpl implements IComputerCraftAPI
{
public static final ComputerCraftAPIImpl INSTANCE = new ComputerCraftAPIImpl();
@@ -163,11 +163,14 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Nonnull
@Override
public Optional<IWiredElement> getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side )
public IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
// TODO Fix this thing
// BlockEntity tile = world.getBlockEntity( pos );
// return tile == null ? Optional.empty() : tile.getCapability( CAPABILITY_WIRED_ELEMENT, side );
return Optional.empty();
BlockEntity tile = world.getBlockEntity(pos);
if (tile instanceof TileCable) {
return ((TileCable) tile).getElement(side);
} else if (tile instanceof TileWiredModemFull) {
return ((TileWiredModemFull) tile).getElement();
}
return null;
}
}

View File

@@ -218,7 +218,7 @@ public final class ComputerCraftAPI
* @see IWiredElement#getNode()
*/
@Nonnull
public static Optional<IWiredElement> getWiredElementAt(@Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side )
public static IWiredElement getWiredElementAt(@Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
return getInstance().getWiredElementAt( world, pos, side );
}
@@ -275,6 +275,6 @@ public final class ComputerCraftAPI
IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element );
@Nonnull
Optional<IWiredElement> getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side );
IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side );
}
}

View File

@@ -5,6 +5,8 @@
*/
package dan200.computercraft.api.client;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedModelManager;
@@ -17,6 +19,7 @@ import java.util.Objects;
/**
* A model to render, combined with a transformation matrix to apply.
*/
@Environment(EnvType.CLIENT)
public final class TransformedModel
{
private final BakedModel model;

View File

@@ -0,0 +1,21 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
public interface ILuaObject {
@Nonnull
String[] getMethodNames();
@Nullable
Object[] callMethod(@Nonnull ILuaContext context, int method, @Nonnull Object[] arguments) throws LuaException, InterruptedException;
}

View File

@@ -28,7 +28,7 @@ public interface IPeripheral
* @return A string identifying the type of peripheral.
*/
@Nonnull
String getType0();
String getType();
/**
* Is called when when a computer is attaching to the peripheral.

View File

@@ -34,5 +34,5 @@ public interface IPeripheralProvider
* @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
*/
@Nonnull
Optional<IPeripheral> getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
}

View File

@@ -8,10 +8,9 @@ package dan200.computercraft.client;
import java.util.HashSet;
import java.util.function.Consumer;
import java.util.function.Function;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.common.IColouredItem;
import dan200.computercraft.shared.media.items.ItemDisk;
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
@@ -23,7 +22,6 @@ import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.render.model.ModelRotation;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.resource.ResourceManager;
@@ -87,9 +85,9 @@ public final class ClientRegistry {
public static void onItemColours() {
ColorProviderRegistry.ITEM.register((stack, layer) -> {
return layer == 1 ? ((ItemDisk) stack.getItem()).getColour(stack) : 0xFFFFFF;
}, Registry.ModItems.DISK);
}, ComputerCraftRegistry.ModItems.DISK);
ColorProviderRegistry.ITEM.register((stack, layer) -> layer == 1 ? ItemTreasureDisk.getColour(stack) : 0xFFFFFF, Registry.ModItems.TREASURE_DISK);
ColorProviderRegistry.ITEM.register((stack, layer) -> layer == 1 ? ItemTreasureDisk.getColour(stack) : 0xFFFFFF, ComputerCraftRegistry.ModItems.TREASURE_DISK);
ColorProviderRegistry.ITEM.register((stack, layer) -> {
switch (layer) {
@@ -104,12 +102,12 @@ public final class ClientRegistry {
return light == -1 ? Colour.BLACK.getHex() : light;
}
}
}, Registry.ModItems.POCKET_COMPUTER_NORMAL, Registry.ModItems.POCKET_COMPUTER_ADVANCED);
}, ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL, ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED);
// Setup turtle colours
ColorProviderRegistry.ITEM.register((stack, tintIndex) -> tintIndex == 0 ? ((IColouredItem) stack.getItem()).getColour(stack) : 0xFFFFFF,
Registry.ModBlocks.TURTLE_NORMAL,
Registry.ModBlocks.TURTLE_ADVANCED);
ComputerCraftRegistry.ModBlocks.TURTLE_NORMAL,
ComputerCraftRegistry.ModBlocks.TURTLE_ADVANCED);
}
private static BakedModel bake(ModelLoader loader, UnbakedModel model, Identifier identifier) {

View File

@@ -3,38 +3,32 @@
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER;
import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
import javax.annotation.Nonnull;
import com.mojang.blaze3d.systems.RenderSystem;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.client.gui.widgets.WidgetWrapper;
import dan200.computercraft.client.render.ComputerBorderRenderer;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.IContainerComputer;
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW;
public final class GuiComputer<T extends ScreenHandler & IContainerComputer> extends HandledScreen<T> {
import javax.annotation.Nonnull;
import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER;
import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
public final class GuiComputer<T extends ContainerComputerBase> extends HandledScreen<T>
{
private final ComputerFamily family;
private final ClientComputer computer;
private final int termWidth;
@@ -43,102 +37,123 @@ public final class GuiComputer<T extends ScreenHandler & IContainerComputer> ext
private WidgetTerminal terminal;
private WidgetWrapper terminalWrapper;
public GuiComputer(T container, PlayerInventory player, ComputerFamily family, ClientComputer computer, int termWidth, int termHeight) {
super(container, player, new LiteralText(""));
this.family = family;
this.computer = computer;
private GuiComputer(
T container, PlayerInventory player, Text title, int termWidth, int termHeight
)
{
super( container, player, title );
family = container.getFamily();
computer = (ClientComputer) container.getComputer();
this.termWidth = termWidth;
this.termHeight = termHeight;
this.terminal = null;
terminal = null;
}
private GuiComputer(T container, PlayerInventory player, ComputerFamily family, Text title, int termWidth, int termHeight) {
super(container, player, title);
this.family = family;
this.computer = (ClientComputer) container.getComputer();
this.termWidth = termWidth;
this.termHeight = termHeight;
this.terminal = null;
public static GuiComputer<ContainerComputer> create( ContainerComputer container, PlayerInventory inventory, Text component )
{
return new GuiComputer<>(
container, inventory, component,
ComputerCraft.terminalWidth_computer, ComputerCraft.terminalHeight_computer
);
}
public static GuiComputer<ContainerComputer> create(int id, TileComputer computer, PlayerInventory player) {
return create(new ContainerComputer(id, computer), player, computer.getDisplayName());
public static GuiComputer<ContainerPocketComputer> createPocket( ContainerPocketComputer container, PlayerInventory inventory, Text component )
{
return new GuiComputer<>(
container, inventory, component,
ComputerCraft.terminalWidth_pocketComputer, ComputerCraft.terminalHeight_pocketComputer
);
}
public static GuiComputer<ContainerComputer> create(ContainerComputer container, PlayerInventory inventory, Text component) {
return new GuiComputer<>(container, inventory, container.getFamily(), component, ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight);
public static GuiComputer<ContainerViewComputer> createView( ContainerViewComputer container, PlayerInventory inventory, Text component )
{
return new GuiComputer<>(
container, inventory, component,
container.getWidth(), container.getHeight()
);
}
@Override
protected void init() {
this.client.keyboard.setRepeatEvents(true);
protected void init()
{
client.keyboard.setRepeatEvents( true );
int termPxWidth = this.termWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = this.termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
int termPxWidth = termWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
this.backgroundWidth = termPxWidth + MARGIN * 2 + BORDER * 2;
this.backgroundHeight = termPxHeight + MARGIN * 2 + BORDER * 2;
backgroundWidth = termPxWidth + MARGIN * 2 + BORDER * 2;
backgroundHeight = termPxHeight + MARGIN * 2 + BORDER * 2;
super.init();
this.terminal = new WidgetTerminal(this.client, () -> this.computer, this.termWidth, this.termHeight, MARGIN, MARGIN, MARGIN, MARGIN);
this.terminalWrapper = new WidgetWrapper(this.terminal, MARGIN + BORDER + this.x, MARGIN + BORDER + this.y, termPxWidth, termPxHeight);
terminal = new WidgetTerminal( client, () -> computer, termWidth, termHeight, MARGIN, MARGIN, MARGIN, MARGIN );
terminalWrapper = new WidgetWrapper( terminal, MARGIN + BORDER + x, MARGIN + BORDER + y, termPxWidth, termPxHeight );
this.children.add(this.terminalWrapper);
this.setFocused(this.terminalWrapper);
children.add( terminalWrapper );
setFocused( terminalWrapper );
}
@Override
public void removed() {
public void removed()
{
super.removed();
this.children.remove(this.terminal);
this.terminal = null;
this.client.keyboard.setRepeatEvents(false);
children.remove( terminal );
terminal = null;
client.keyboard.setRepeatEvents( false );
}
@Override
public void tick() {
public void tick()
{
super.tick();
this.terminal.update();
terminal.update();
}
@Override
public boolean keyPressed(int key, int scancode, int modifiers) {
public boolean keyPressed( int key, int scancode, int modifiers )
{
// Forward the tab key to the terminal, rather than moving between controls.
if (key == GLFW.GLFW_KEY_TAB && this.getFocused() != null && this.getFocused() == this.terminalWrapper) {
return this.getFocused().keyPressed(key, scancode, modifiers);
if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper )
{
return getFocused().keyPressed( key, scancode, modifiers );
}
return super.keyPressed(key, scancode, modifiers);
return super.keyPressed( key, scancode, modifiers );
}
@Override
public void drawBackground(@Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY) {
public void drawBackground( @Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY )
{
// Draw terminal
this.terminal.draw(this.terminalWrapper.getX(), this.terminalWrapper.getY());
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
// Draw a border around the terminal
RenderSystem.color4f(1, 1, 1, 1);
this.client.getTextureManager()
.bindTexture(ComputerBorderRenderer.getTexture(this.family));
ComputerBorderRenderer.render(this.terminalWrapper.getX() - MARGIN, this.terminalWrapper.getY() - MARGIN,
this.getZOffset(), this.terminalWrapper.getWidth() + MARGIN * 2, this.terminalWrapper.getHeight() + MARGIN * 2);
RenderSystem.color4f( 1, 1, 1, 1 );
client.getTextureManager().bindTexture( ComputerBorderRenderer.getTexture( family ) );
ComputerBorderRenderer.render(
terminalWrapper.getX() - MARGIN, terminalWrapper.getY() - MARGIN, getZOffset(),
terminalWrapper.getWidth() + MARGIN * 2, terminalWrapper.getHeight() + MARGIN * 2
);
}
@Override
public void render(@Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks) {
super.render(stack, mouseX, mouseY, partialTicks);
this.drawMouseoverTooltip(stack, mouseX, mouseY);
public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks )
{
super.render( stack, mouseX, mouseY, partialTicks );
drawMouseoverTooltip( stack, mouseX, mouseY );
}
@Override
public boolean mouseDragged(double x, double y, int button, double deltaX, double deltaY) {
return (this.getFocused() != null && this.getFocused().mouseDragged(x, y, button, deltaX, deltaY)) || super.mouseDragged(x, y, button, deltaX, deltaY);
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
{
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|| super.mouseDragged( x, y, button, deltaX, deltaY );
}
@Override
protected void drawForeground(@Nonnull MatrixStack transform, int mouseX, int mouseY) {
protected void drawForeground( @Nonnull MatrixStack transform, int mouseX, int mouseY )
{
// Skip rendering labels.
}
}

View File

@@ -6,7 +6,6 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.util.math.MatrixStack;
@@ -19,9 +18,9 @@ public class GuiDiskDrive extends HandledScreen<ContainerDiskDrive>
{
private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/disk_drive.png" );
public GuiDiskDrive( ContainerDiskDrive container, PlayerInventory player)
public GuiDiskDrive( ContainerDiskDrive container, PlayerInventory player, Text title )
{
super(container, player, Registry.ModBlocks.DISK_DRIVE.getName() );
super( container, player, title );
}
@Override

View File

@@ -1,35 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class GuiPocketComputer extends GuiComputer<ContainerPocketComputer>
{
public GuiPocketComputer( ContainerPocketComputer container, PlayerInventory player )
{
super(
container, player,
getFamily( container.getStack() ),
ItemPocketComputer.createClientComputer( container.getStack() ),
ComputerCraft.terminalWidth_pocketComputer,
ComputerCraft.terminalHeight_pocketComputer
);
}
private static ComputerFamily getFamily( ItemStack stack )
{
Item item = stack.getItem();
return item instanceof ItemPocketComputer ? ((ItemPocketComputer) item).getFamily() : ComputerFamily.NORMAL;
}
}

View File

@@ -6,7 +6,6 @@
package dan200.computercraft.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.util.math.MatrixStack;
@@ -19,9 +18,9 @@ public class GuiPrinter extends HandledScreen<ContainerPrinter>
{
private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/printer.png" );
public GuiPrinter( ContainerPrinter container, PlayerInventory player)
public GuiPrinter( ContainerPrinter container, PlayerInventory player, Text title )
{
super(container, player, Registry.ModBlocks.PRINTER.getName());
super( container, player, title );
}
/*@Override

View File

@@ -30,9 +30,9 @@ public class GuiPrintout extends HandledScreen<ContainerHeldItem>
private final TextBuffer[] m_colours;
private int m_page;
public GuiPrintout( ContainerHeldItem container, PlayerInventory player )
public GuiPrintout( ContainerHeldItem container, PlayerInventory player, Text title )
{
super( container, player, container.getStack().getName() );
super( container, player, title );
backgroundHeight = Y_SIZE;

View File

@@ -11,7 +11,6 @@ import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.client.gui.widgets.WidgetWrapper;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.util.math.MatrixStack;
@@ -35,12 +34,12 @@ public class GuiTurtle extends HandledScreen<ContainerTurtle>
private WidgetTerminal terminal;
private WidgetWrapper terminalWrapper;
public GuiTurtle(TileTurtle turtle, ContainerTurtle container, PlayerInventory player )
public GuiTurtle( ContainerTurtle container, PlayerInventory player, Text title )
{
super( container, player, turtle.getDisplayName() );
super( container, player, title );
m_container = container;
m_family = turtle.getFamily();
m_family = container.getFamily();
m_computer = (ClientComputer) container.getComputer();
backgroundWidth = 254;
@@ -53,13 +52,13 @@ public class GuiTurtle extends HandledScreen<ContainerTurtle>
super.init();
client.keyboard.setRepeatEvents( true );
int termPxWidth = ComputerCraft.turtleTermWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = ComputerCraft.turtleTermHeight * FixedWidthFontRenderer.FONT_HEIGHT;
int termPxWidth = ComputerCraft.terminalWidth_turtle * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = ComputerCraft.terminalHeight_turtle * FixedWidthFontRenderer.FONT_HEIGHT;
terminal = new WidgetTerminal(
client, () -> m_computer,
ComputerCraft.turtleTermWidth,
ComputerCraft.turtleTermHeight,
ComputerCraft.terminalWidth_turtle,
ComputerCraft.terminalHeight_turtle,
2, 2, 2, 2
);
terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + x, 2 + 8 + y, termPxWidth, termPxHeight );
@@ -115,8 +114,8 @@ public class GuiTurtle extends HandledScreen<ContainerTurtle>
int slotX = slot % 4;
int slotY = slot / 4;
drawTexture( transform,
x + m_container.m_turtleInvStartX - 2 + slotX * 18,
y + m_container.m_playerInvStartY - 2 + slotY * 18,
x + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18,
y + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18,
0, 217, 24, 24
);
}

View File

@@ -6,83 +6,118 @@
package dan200.computercraft.client.proxy;
import java.util.function.Supplier;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.ClientRegistry;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.gui.GuiComputer;
import dan200.computercraft.client.gui.GuiDiskDrive;
import dan200.computercraft.client.gui.GuiPocketComputer;
import dan200.computercraft.client.gui.GuiPrinter;
import dan200.computercraft.client.gui.GuiPrintout;
import dan200.computercraft.client.gui.GuiTurtle;
import dan200.computercraft.client.render.TileEntityMonitorRenderer;
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
import dan200.computercraft.client.render.TurtleModelLoader;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.client.render.TurtlePlayerRenderer;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.common.IColouredItem;
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
import dan200.computercraft.shared.network.container.ContainerType;
import dan200.computercraft.shared.network.container.PocketComputerContainerType;
import dan200.computercraft.shared.network.container.PrintoutContainerType;
import dan200.computercraft.shared.network.container.TileEntityContainerType;
import dan200.computercraft.shared.network.container.ViewComputerContainerType;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.screen.ArrayPropertyDelegate;
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry;
import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback;
import net.fabricmc.fabric.api.event.client.ClientTickCallback;
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.mixin.object.builder.ModelPredicateProviderRegistrySpecificAccessor;
@SuppressWarnings ({
"MethodCallSideOnly",
"NewExpressionSideOnly"
})
public final class ComputerCraftProxyClient {
public static void setup() {
registerContainers();
BlockEntityRendererRegistry.INSTANCE.register(Registry.ModTiles.MONITOR_NORMAL, TileEntityMonitorRenderer::new);
BlockEntityRendererRegistry.INSTANCE.register(Registry.ModTiles.MONITOR_ADVANCED, TileEntityMonitorRenderer::new);
BlockEntityRendererRegistry.INSTANCE.register(Registry.ModTiles.TURTLE_NORMAL, TileEntityTurtleRenderer::new);
BlockEntityRendererRegistry.INSTANCE.register(Registry.ModTiles.TURTLE_ADVANCED, TileEntityTurtleRenderer::new);
import net.minecraft.client.item.ModelPredicateProvider;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.item.Item;
import net.minecraft.util.Identifier;
ClientSpriteRegistryCallback.event(SpriteAtlasTexture.BLOCK_ATLAS_TEX)
.register(ClientRegistry::onTextureStitchEvent);
ModelLoadingRegistry.INSTANCE.registerAppender(ClientRegistry::onModelBakeEvent);
ModelLoadingRegistry.INSTANCE.registerResourceProvider(loader -> (name, context) -> TurtleModelLoader.INSTANCE.accepts(name) ?
TurtleModelLoader.INSTANCE.loadModel(
name) : null);
import net.fabricmc.api.ClientModInitializer;
ClientTickCallback.EVENT.register(client -> FrameInfo.onTick());
@SuppressWarnings ("MethodCallSideOnly")
public final class ComputerCraftProxyClient implements ClientModInitializer {
@SafeVarargs
private static void registerItemProperty(String name, ModelPredicateProvider getter, Supplier<? extends Item>... items) {
Identifier id = new Identifier(ComputerCraft.MOD_ID, name);
for (Supplier<? extends Item> item : items) {
ModelPredicateProviderRegistrySpecificAccessor.callRegister(item.get(), id, getter);
}
}
private static void registerContainers() {
// My IDE doesn't think so, but we do actually need these generics.
ContainerType.registerGui(TileEntityContainerType::computer,
(id, packet, player) -> GuiComputer.create(id, (TileComputer) packet.getTileEntity(player), player.inventory));
ContainerType.registerGui(TileEntityContainerType::diskDrive, GuiDiskDrive::new);
ContainerType.registerGui(TileEntityContainerType::printer, GuiPrinter::new);
ContainerType.registerGui(TileEntityContainerType::turtle, (id, packet, player) -> {
TileTurtle turtle = (TileTurtle) packet.getTileEntity(player);
return new GuiTurtle(turtle,
new ContainerTurtle(id, player.inventory, new SimpleInventory(TileTurtle.INVENTORY_SIZE), new ArrayPropertyDelegate(1)),
player.inventory);
});
ContainerType.registerGui(PocketComputerContainerType::new, GuiPocketComputer::new);
ContainerType.registerGui(PrintoutContainerType::new, GuiPrintout::new);
ContainerType.registerGui(ViewComputerContainerType::new, (id, packet, player) -> {
ClientComputer computer = ComputerCraft.clientComputerRegistry.get(packet.instanceId);
if (computer == null) {
ComputerCraft.clientComputerRegistry.add(packet.instanceId, computer = new ClientComputer(packet.instanceId));
}
ContainerViewComputer container = new ContainerViewComputer(id, computer);
return new GuiComputer<>(container, player.inventory, packet.family, computer, packet.width, packet.height);
});
ScreenRegistry.<ContainerComputer, GuiComputer<ContainerComputer>>register(ComputerCraftRegistry.ModContainers.COMPUTER, GuiComputer::create);
ScreenRegistry.<ContainerPocketComputer, GuiComputer<ContainerPocketComputer>>register(ComputerCraftRegistry.ModContainers.POCKET_COMPUTER,
GuiComputer::createPocket);
ScreenRegistry.register(ComputerCraftRegistry.ModContainers.TURTLE, GuiTurtle::new);
ScreenRegistry.register(ComputerCraftRegistry.ModContainers.PRINTER, GuiPrinter::new);
ScreenRegistry.register(ComputerCraftRegistry.ModContainers.DISK_DRIVE, GuiDiskDrive::new);
ScreenRegistry.register(ComputerCraftRegistry.ModContainers.PRINTOUT, GuiPrintout::new);
ScreenRegistry.<ContainerViewComputer, GuiComputer<ContainerViewComputer>>register(ComputerCraftRegistry.ModContainers.VIEW_COMPUTER,
GuiComputer::createView);
}
@Override
public void onInitializeClient() {
FrameInfo.init();
registerContainers();
// While turtles themselves are not transparent, their upgrades may be.
BlockRenderLayerMap.INSTANCE.putBlock(ComputerCraftRegistry.ModBlocks.TURTLE_NORMAL, RenderLayer.getTranslucent());
BlockRenderLayerMap.INSTANCE.putBlock(ComputerCraftRegistry.ModBlocks.TURTLE_ADVANCED, RenderLayer.getTranslucent());
// Monitors' textures have transparent fronts and so count as cutouts.
BlockRenderLayerMap.INSTANCE.putBlock(ComputerCraftRegistry.ModBlocks.MONITOR_NORMAL, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(ComputerCraftRegistry.ModBlocks.MONITOR_ADVANCED, RenderLayer.getCutout());
// Setup TESRs
BlockEntityRendererRegistry.INSTANCE.register(ComputerCraftRegistry.ModTiles.MONITOR_NORMAL, TileEntityMonitorRenderer::new);
BlockEntityRendererRegistry.INSTANCE.register(ComputerCraftRegistry.ModTiles.MONITOR_ADVANCED, TileEntityMonitorRenderer::new);
BlockEntityRendererRegistry.INSTANCE.register(ComputerCraftRegistry.ModTiles.TURTLE_NORMAL, TileEntityTurtleRenderer::new);
BlockEntityRendererRegistry.INSTANCE.register(ComputerCraftRegistry.ModTiles.TURTLE_ADVANCED, TileEntityTurtleRenderer::new);
// TODO: ClientRegistry.bindTileEntityRenderer( TileCable.FACTORY, x -> new TileEntityCableRenderer() );
EntityRendererRegistry.INSTANCE.register(ComputerCraftRegistry.ModEntities.TURTLE_PLAYER, TurtlePlayerRenderer::new);
registerItemProperty("state",
(stack, world, player) -> ItemPocketComputer.getState(stack)
.ordinal(),
() -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL,
() -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED);
registerItemProperty("state",
(stack, world, player) -> IColouredItem.getColourBasic(stack) != -1 ? 1 : 0,
() -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL,
() -> ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED);
ClientRegistry.onItemColours();
// TODO Verify this does things properly
ServerWorldEvents.UNLOAD.register(((minecraftServer, serverWorld) -> {
ClientMonitor.destroyAll();
}));
}
public static void initEvents() {
}
// @Mod.EventBusSubscriber (modid = ComputerCraft.MOD_ID, value = Dist.CLIENT)
// public static final class ForgeHandlers {
// @SubscribeEvent
// public static void onWorldUnload(WorldEvent.Unload event) {
// if (event.getWorld()
// .isClient()) {
// ClientMonitor.destroyAll();
// }
// }
// }
}

View File

@@ -5,28 +5,25 @@
*/
package dan200.computercraft.client.render;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
import dan200.computercraft.shared.peripheral.modem.wired.CableShapes;
import dan200.computercraft.shared.util.WorldUtil;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.DrawHighlightEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
@Environment(EnvType.CLIENT)
public final class CableHighlightRenderer
{
private CableHighlightRenderer()
@@ -35,29 +32,19 @@ public final class CableHighlightRenderer
/**
* Draw an outline for a specific part of a cable "Multipart".
*
* @param event The event to observe
* @see WorldRenderer#drawSelectionBox(MatrixStack, IVertexBuilder, Entity, double, double, double, BlockPos, BlockState)
*/
@SubscribeEvent
public static void drawHighlight( DrawHighlightEvent.HighlightBlock event )
public static boolean drawHighlight(MatrixStack stack, VertexConsumer consumer, Entity entity, double d, double e, double f, BlockPos pos, BlockState state)
{
BlockHitResult hit = event.getTarget();
BlockPos pos = hit.getBlockPos();
World world = event.getInfo().getFocusedEntity().getEntityWorld();
Camera info = event.getInfo();
BlockState state = world.getBlockState( pos );
World world = entity.getEntityWorld();
Camera info = MinecraftClient.getInstance().gameRenderer.getCamera();
// We only care about instances with both cable and modem.
if( state.getBlock() != Registry.ModBlocks.CABLE.get() || state.get( BlockCable.MODEM ).getFacing() == null || !state.get( BlockCable.CABLE ) )
if( state.getBlock() != ComputerCraftRegistry.ModBlocks.CABLE || state.get( BlockCable.MODEM ).getFacing() == null || !state.get( BlockCable.CABLE ) )
{
return;
return false;
}
event.setCanceled( true );
VoxelShape shape = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.getPos().subtract( pos.getX(), pos.getY(), pos.getZ() ) )
VoxelShape shape = WorldUtil.isVecInside( CableShapes.getModemShape( state ), new Vec3d(d, e, f).subtract( pos.getX(), pos.getY(), pos.getZ() ) )
? CableShapes.getModemShape( state )
: CableShapes.getCableShape( state );
@@ -65,14 +52,14 @@ public final class CableHighlightRenderer
double xOffset = pos.getX() - cameraPos.getX();
double yOffset = pos.getY() - cameraPos.getY();
double zOffset = pos.getZ() - cameraPos.getZ();
VertexConsumer buffer = event.getBuffers().getBuffer( RenderLayer.getLines() );
Matrix4f matrix4f = event.getMatrix().peek().getModel();
Matrix4f matrix4f = stack.peek().getModel();
shape.forEachEdge( ( x1, y1, z1, x2, y2, z2 ) -> {
buffer.vertex( matrix4f, (float) (x1 + xOffset), (float) (y1 + yOffset), (float) (z1 + zOffset) )
consumer.vertex( matrix4f, (float) (x1 + xOffset), (float) (y1 + yOffset), (float) (z1 + zOffset) )
.color( 0, 0, 0, 0.4f ).next();
buffer.vertex( matrix4f, (float) (x2 + xOffset), (float) (y2 + yOffset), (float) (z2 + zOffset) )
consumer.vertex( matrix4f, (float) (x2 + xOffset), (float) (y2 + yOffset), (float) (z2 + zOffset) )
.color( 0, 0, 0, 0.4f ).next();
} );
return true;
}
}

View File

@@ -5,6 +5,8 @@
*/
package dan200.computercraft.client.render;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.item.HeldItemRenderer;
@@ -16,6 +18,7 @@ import net.minecraft.util.Arm;
import net.minecraft.util.Hand;
import net.minecraft.util.math.MathHelper;
@Environment(EnvType.CLIENT)
public abstract class ItemMapLikeRenderer
{
/**
@@ -24,11 +27,10 @@ public abstract class ItemMapLikeRenderer
* @param transform The matrix transformation stack
* @param render The buffer to render to
* @param stack The stack to render
* @see FirstPersonRenderer#renderItemInFirstPerson(AbstractClientPlayerEntity, float, float, Hand, float, ItemStack, float, MatrixStack, IRenderTypeBuffer, int)
*/
protected abstract void renderItem( MatrixStack transform, VertexConsumerProvider render, ItemStack stack );
protected void renderItemFirstPerson( MatrixStack transform, VertexConsumerProvider render, int lightTexture, Hand hand, float pitch, float equipProgress, float swingProgress, ItemStack stack )
public void renderItemFirstPerson(MatrixStack transform, VertexConsumerProvider render, int lightTexture, Hand hand, float pitch, float equipProgress, float swingProgress, ItemStack stack)
{
PlayerEntity player = MinecraftClient.getInstance().player;
@@ -58,7 +60,6 @@ public abstract class ItemMapLikeRenderer
* @param equipProgress The equip progress of this item
* @param swingProgress The swing progress of this item
* @param stack The stack to render
* @see FirstPersonRenderer#renderMapFirstPersonSide(MatrixStack, IRenderTypeBuffer, int, float, HandSide, float, ItemStack)
*/
private void renderItemFirstPersonSide( MatrixStack transform, VertexConsumerProvider render, int combinedLight, Arm side, float equipProgress, float swingProgress, ItemStack stack )
{
@@ -103,7 +104,6 @@ public abstract class ItemMapLikeRenderer
* @param equipProgress The equip progress of this item
* @param swingProgress The swing progress of this item
* @param stack The stack to render
* @see FirstPersonRenderer#renderMapFirstPerson(MatrixStack, IRenderTypeBuffer, int, float, float, float)
*/
private void renderItemFirstPersonCenter( MatrixStack transform, VertexConsumerProvider render, int combinedLight, float pitch, float equipProgress, float swingProgress, ItemStack stack )
{

View File

@@ -22,10 +22,6 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.util.math.Vector3f;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.Matrix4f;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderHandEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.lwjgl.opengl.GL11;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
@@ -36,30 +32,16 @@ import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
/**
* Emulates map rendering for pocket computers.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class ItemPocketRenderer extends ItemMapLikeRenderer
{
private static final int LIGHT_HEIGHT = 8;
private static final ItemPocketRenderer INSTANCE = new ItemPocketRenderer();
public static final ItemPocketRenderer INSTANCE = new ItemPocketRenderer();
private ItemPocketRenderer()
{
}
@SubscribeEvent
public static void onRenderInHand( RenderHandEvent event )
{
ItemStack stack = event.getItemStack();
if( !(stack.getItem() instanceof ItemPocketComputer) ) return;
event.setCanceled( true );
INSTANCE.renderItemFirstPerson(
event.getMatrixStack(), event.getBuffers(), event.getLight(),
event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack()
);
}
@Override
protected void renderItem( MatrixStack transform, VertexConsumerProvider render, ItemStack stack )
{
@@ -69,8 +51,8 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
int termWidth, termHeight;
if( terminal == null )
{
termWidth = ComputerCraft.pocketTermWidth;
termHeight = ComputerCraft.pocketTermHeight;
termWidth = ComputerCraft.terminalWidth_pocketComputer;
termHeight = ComputerCraft.terminalHeight_pocketComputer;
}
else
{

View File

@@ -7,16 +7,12 @@ package dan200.computercraft.client.render;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.media.items.ItemPrintout;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.util.math.Vector3f;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.Matrix4f;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderHandEvent;
import net.minecraftforge.client.event.RenderItemInFrameEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
@@ -27,28 +23,14 @@ import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENG
/**
* Emulates map and item-frame rendering for printouts.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
{
private static final ItemPrintoutRenderer INSTANCE = new ItemPrintoutRenderer();
public static final ItemPrintoutRenderer INSTANCE = new ItemPrintoutRenderer();
private ItemPrintoutRenderer()
{
}
@SubscribeEvent
public static void onRenderInHand( RenderHandEvent event )
{
ItemStack stack = event.getItemStack();
if( !(stack.getItem() instanceof ItemPrintout) ) return;
event.setCanceled( true );
INSTANCE.renderItemFirstPerson(
event.getMatrixStack(), event.getBuffers(), event.getLight(),
event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack()
);
}
@Override
protected void renderItem( MatrixStack transform, VertexConsumerProvider render, ItemStack stack )
{
@@ -59,22 +41,19 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
drawPrintout( transform, render, stack );
}
@SubscribeEvent
public static void onRenderInFrame( RenderItemInFrameEvent event )
public boolean renderInFrame(MatrixStack matrixStack, VertexConsumerProvider consumerProvider, ItemStack stack )
{
ItemStack stack = event.getItem();
if( !(stack.getItem() instanceof ItemPrintout) ) return;
event.setCanceled( true );
MatrixStack transform = event.getMatrix();
if( !(stack.getItem() instanceof ItemPrintout) ) return false;
// Move a little bit forward to ensure we're not clipping with the frame
transform.translate( 0.0f, 0.0f, -0.001f );
transform.multiply( Vector3f.POSITIVE_Z.getDegreesQuaternion( 180f ) );
transform.scale( 0.95f, 0.95f, -0.95f );
transform.translate( -0.5f, -0.5f, 0.0f );
matrixStack.translate( 0.0f, 0.0f, -0.001f );
matrixStack.multiply( Vector3f.POSITIVE_Z.getDegreesQuaternion( 180f ) );
matrixStack.scale( 0.95f, 0.95f, -0.95f );
matrixStack.translate( -0.5f, -0.5f, 0.0f );
drawPrintout( transform, event.getBuffers(), stack );
drawPrintout( matrixStack, consumerProvider, stack );
return true;
}
private static void drawPrintout( MatrixStack transform, VertexConsumerProvider render, ItemStack stack )

View File

@@ -5,21 +5,20 @@
*/
package dan200.computercraft.client.render;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.DrawHighlightEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import java.util.EnumSet;
@@ -29,27 +28,24 @@ import static net.minecraft.util.math.Direction.*;
* Overrides monitor highlighting to only render the outline of the <em>whole</em> monitor, rather than the current
* block. This means you do not get an intrusive outline on top of the screen.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
@Environment(EnvType.CLIENT)
public final class MonitorHighlightRenderer
{
private MonitorHighlightRenderer()
{
}
@SubscribeEvent
public static void drawHighlight( DrawHighlightEvent.HighlightBlock event )
public static boolean drawHighlight(MatrixStack matrixStack, VertexConsumer vertexConsumer, Entity entity, double d, double e, double f, BlockPos pos, BlockState blockState)
{
// Preserve normal behaviour when crouching.
if( event.getInfo().getFocusedEntity().isInSneakingPose() ) return;
if( entity.isInSneakingPose() ) return false;
World world = event.getInfo().getFocusedEntity().getEntityWorld();
BlockPos pos = event.getTarget().getBlockPos();
World world = entity.getEntityWorld();
BlockEntity tile = world.getBlockEntity( pos );
if( !(tile instanceof TileMonitor) ) return;
if( !(tile instanceof TileMonitor) ) return false;
TileMonitor monitor = (TileMonitor) tile;
event.setCanceled( true );
// Determine which sides are part of the external faces of the monitor, and so which need to be rendered.
EnumSet<Direction> faces = EnumSet.allOf( Direction.class );
@@ -60,28 +56,28 @@ public final class MonitorHighlightRenderer
if( monitor.getYIndex() != 0 ) faces.remove( monitor.getDown().getOpposite() );
if( monitor.getYIndex() != monitor.getHeight() - 1 ) faces.remove( monitor.getDown() );
MatrixStack transformStack = event.getMatrix();
Vec3d cameraPos = event.getInfo().getPos();
transformStack.push();
transformStack.translate( pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ() );
Vec3d cameraPos = MinecraftClient.getInstance().gameRenderer.getCamera().getPos();
matrixStack.push();
matrixStack.translate( pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ() );
// I wish I could think of a better way to do this
VertexConsumer buffer = event.getBuffers().getBuffer( RenderLayer.getLines() );
Matrix4f transform = transformStack.peek().getModel();
if( faces.contains( NORTH ) || faces.contains( WEST ) ) line( buffer, transform, 0, 0, 0, UP );
if( faces.contains( SOUTH ) || faces.contains( WEST ) ) line( buffer, transform, 0, 0, 1, UP );
if( faces.contains( NORTH ) || faces.contains( EAST ) ) line( buffer, transform, 1, 0, 0, UP );
if( faces.contains( SOUTH ) || faces.contains( EAST ) ) line( buffer, transform, 1, 0, 1, UP );
if( faces.contains( NORTH ) || faces.contains( DOWN ) ) line( buffer, transform, 0, 0, 0, EAST );
if( faces.contains( SOUTH ) || faces.contains( DOWN ) ) line( buffer, transform, 0, 0, 1, EAST );
if( faces.contains( NORTH ) || faces.contains( UP ) ) line( buffer, transform, 0, 1, 0, EAST );
if( faces.contains( SOUTH ) || faces.contains( UP ) ) line( buffer, transform, 0, 1, 1, EAST );
if( faces.contains( WEST ) || faces.contains( DOWN ) ) line( buffer, transform, 0, 0, 0, SOUTH );
if( faces.contains( EAST ) || faces.contains( DOWN ) ) line( buffer, transform, 1, 0, 0, SOUTH );
if( faces.contains( WEST ) || faces.contains( UP ) ) line( buffer, transform, 0, 1, 0, SOUTH );
if( faces.contains( EAST ) || faces.contains( UP ) ) line( buffer, transform, 1, 1, 0, SOUTH );
Matrix4f transform = matrixStack.peek().getModel();
if( faces.contains( NORTH ) || faces.contains( WEST ) ) line( vertexConsumer, transform, 0, 0, 0, UP );
if( faces.contains( SOUTH ) || faces.contains( WEST ) ) line( vertexConsumer, transform, 0, 0, 1, UP );
if( faces.contains( NORTH ) || faces.contains( EAST ) ) line( vertexConsumer, transform, 1, 0, 0, UP );
if( faces.contains( SOUTH ) || faces.contains( EAST ) ) line( vertexConsumer, transform, 1, 0, 1, UP );
if( faces.contains( NORTH ) || faces.contains( DOWN ) ) line( vertexConsumer, transform, 0, 0, 0, EAST );
if( faces.contains( SOUTH ) || faces.contains( DOWN ) ) line( vertexConsumer, transform, 0, 0, 1, EAST );
if( faces.contains( NORTH ) || faces.contains( UP ) ) line( vertexConsumer, transform, 0, 1, 0, EAST );
if( faces.contains( SOUTH ) || faces.contains( UP ) ) line( vertexConsumer, transform, 0, 1, 1, EAST );
if( faces.contains( WEST ) || faces.contains( DOWN ) ) line( vertexConsumer, transform, 0, 0, 0, SOUTH );
if( faces.contains( EAST ) || faces.contains( DOWN ) ) line( vertexConsumer, transform, 1, 0, 0, SOUTH );
if( faces.contains( WEST ) || faces.contains( UP ) ) line( vertexConsumer, transform, 0, 1, 0, SOUTH );
if( faces.contains( EAST ) || faces.contains( UP ) ) line( vertexConsumer, transform, 1, 1, 0, SOUTH );
transformStack.pop();
matrixStack.pop();
return true;
}
private static void line( VertexConsumer buffer, Matrix4f transform, float x, float y, float z, Direction direction )

View File

@@ -32,7 +32,6 @@ import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.model.data.EmptyModelData;
import javax.annotation.Nonnull;
import java.util.List;
@@ -80,7 +79,7 @@ public class TileEntityTurtleRenderer extends BlockEntityRenderer<TileTurtle>
if( label != null && hit.getType() == HitResult.Type.BLOCK && turtle.getPos().equals( ((BlockHitResult) hit).getBlockPos() ) )
{
MinecraftClient mc = MinecraftClient.getInstance();
TextRenderer font = dispatcher.textRenderer;
TextRenderer font = mc.textRenderer;
transform.push();
transform.translate( 0.5, 1.2, 0.5 );
@@ -146,7 +145,7 @@ public class TileEntityTurtleRenderer extends BlockEntityRenderer<TileTurtle>
transform.translate( 0.0f, -0.5f, -0.5f );
TransformedModel model = upgrade.getModel( turtle.getAccess(), side );
model.getMatrix().push( transform );
// model.getMatrix().multiply(transform);
renderModel( transform, renderer, lightmapCoord, overlayLight, model.getModel(), null );
transform.pop();
@@ -162,10 +161,10 @@ public class TileEntityTurtleRenderer extends BlockEntityRenderer<TileTurtle>
private void renderModel( @Nonnull MatrixStack transform, @Nonnull VertexConsumer renderer, int lightmapCoord, int overlayLight, BakedModel model, int[] tints )
{
random.setSeed( 0 );
renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, null, random, EmptyModelData.INSTANCE ), tints );
renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, null, random ), tints );
for( Direction facing : DirectionUtil.FACINGS )
{
renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, facing, random, EmptyModelData.INSTANCE ), tints );
renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, facing, random ), tints );
}
}
@@ -185,7 +184,7 @@ public class TileEntityTurtleRenderer extends BlockEntityRenderer<TileTurtle>
float f = (float) (tint >> 16 & 255) / 255.0F;
float f1 = (float) (tint >> 8 & 255) / 255.0F;
float f2 = (float) (tint & 255) / 255.0F;
buffer.addVertexData( matrix, bakedquad, f, f1, f2, lightmapCoord, overlayLight, true );
buffer.quad( matrix, bakedquad, new float[]{1.0F, 1.0F, 1.0F, 1.0F}, f, f1, f2, new int[] {lightmapCoord, lightmapCoord, lightmapCoord, lightmapCoord}, overlayLight, true );
}
}
}

View File

@@ -1,82 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.render;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.mojang.datafixers.util.Pair;
import dan200.computercraft.ComputerCraft;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.renderer.model.*;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.IModelLoader;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Function;
public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.TurtleModel>
{
private static final Identifier COLOUR_TURTLE_MODEL = new Identifier( ComputerCraft.MOD_ID, "block/turtle_colour" );
public static final TurtleModelLoader INSTANCE = new TurtleModelLoader();
private TurtleModelLoader() {
}
@Override
public void apply( @Nonnull ResourceManager manager )
{
}
@Nonnull
@Override
public TurtleModel read( @Nonnull JsonDeserializationContext deserializationContext, @Nonnull JsonObject modelContents )
{
Identifier model = new Identifier( JsonHelper.getString( modelContents, "model" ) );
return new TurtleModel( model );
}
public static final class TurtleModel implements IModelGeometry<TurtleModel>
{
private final Identifier family;
private TurtleModel( Identifier family )
{
this.family = family;
}
@Override
public Collection<SpriteIdentifier> getTextures( IModelConfiguration owner, Function<Identifier, UnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors )
{
Set<SpriteIdentifier> materials = new HashSet<>();
materials.addAll( modelGetter.apply( family ).getTextureDependencies( modelGetter, missingTextureErrors ) );
materials.addAll( modelGetter.apply( COLOUR_TURTLE_MODEL ).getTextureDependencies( modelGetter, missingTextureErrors ) );
return materials;
}
@Override
public BakedModel bake( IModelConfiguration owner, ModelLoader bakery, Function<SpriteIdentifier, Sprite> spriteGetter, ModelBakeSettings transform, ModelOverrideList overrides, Identifier modelLocation )
{
return new TurtleSmartItemModel(
bakery.getBakedModel( family, transform, spriteGetter ),
bakery.getBakedModel( COLOUR_TURTLE_MODEL, transform, spriteGetter )
);
}
}
}

View File

@@ -6,6 +6,8 @@
package dan200.computercraft.client.render;
import dan200.computercraft.api.client.TransformedModel;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedQuad;
@@ -13,14 +15,11 @@ import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.math.AffineTransformation;
import net.minecraft.util.math.Direction;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
import net.minecraftforge.client.model.pipeline.TRSRTransformer;
import javax.annotation.Nonnull;
import java.util.*;
@Environment(EnvType.CLIENT)
public class TurtleMultiModel implements BakedModel
{
private final BakedModel m_baseModel;
@@ -43,15 +42,7 @@ public class TurtleMultiModel implements BakedModel
@Nonnull
@Override
@Deprecated
public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull Random rand )
{
return getQuads( state, side, rand, EmptyModelData.INSTANCE );
}
@Nonnull
@Override
public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull Random rand, @Nonnull IModelData data )
{
if( side != null )
{
@@ -70,20 +61,20 @@ public class TurtleMultiModel implements BakedModel
ArrayList<BakedQuad> quads = new ArrayList<>();
transformQuadsTo( quads, m_baseModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), m_generalTransform );
transformQuadsTo( quads, m_baseModel.getQuads( state, side, rand ), m_generalTransform );
if( m_overlayModel != null )
{
transformQuadsTo( quads, m_overlayModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), m_generalTransform );
transformQuadsTo( quads, m_overlayModel.getQuads( state, side, rand ), m_generalTransform );
}
if( m_leftUpgradeModel != null )
{
AffineTransformation upgradeTransform = m_generalTransform.compose( m_leftUpgradeModel.getMatrix() );
transformQuadsTo( quads, m_leftUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
AffineTransformation upgradeTransform = m_generalTransform.multiply( m_leftUpgradeModel.getMatrix() );
transformQuadsTo( quads, m_leftUpgradeModel.getModel().getQuads( state, side, rand ), upgradeTransform );
}
if( m_rightUpgradeModel != null )
{
AffineTransformation upgradeTransform = m_generalTransform.compose( m_rightUpgradeModel.getMatrix() );
transformQuadsTo( quads, m_rightUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
AffineTransformation upgradeTransform = m_generalTransform.multiply( m_rightUpgradeModel.getMatrix() );
transformQuadsTo( quads, m_rightUpgradeModel.getModel().getQuads( state, side, rand ), upgradeTransform );
}
quads.trimToSize();
return quads;
@@ -140,10 +131,11 @@ public class TurtleMultiModel implements BakedModel
{
for( BakedQuad quad : quads )
{
BakedQuadBuilder builder = new BakedQuadBuilder();
TRSRTransformer transformer = new TRSRTransformer( builder, transform );
quad.pipe( transformer );
output.add( builder.build() );
// TODO Figure out what the fuck to do here
// BakedQuadBuilder builder = new BakedQuadBuilder();
// TRSRTransformer transformer = new TRSRTransformer( builder, transform );
// quad.pipe( transformer );
// output.add( builder.build() );
}
}
}

View File

@@ -8,6 +8,8 @@ package dan200.computercraft.client.render;
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import javax.annotation.Nonnull;
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.EntityRenderer;
@@ -21,9 +23,13 @@ public class TurtlePlayerRenderer extends EntityRenderer<TurtlePlayer>
super( renderManager );
}
public TurtlePlayerRenderer(EntityRenderDispatcher entityRenderDispatcher, EntityRendererRegistry.Context context) {
super(entityRenderDispatcher);
}
@Nonnull
@Override
public Identifier getEntityTexture( @Nonnull TurtlePlayer entity )
public Identifier getTexture( @Nonnull TurtlePlayer entity )
{
return ComputerBorderRenderer.BACKGROUND_NORMAL;
}

View File

@@ -5,13 +5,6 @@
*/
package dan200.computercraft.client.render;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.google.common.base.Objects;
import dan200.computercraft.api.client.TransformedModel;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
@@ -19,8 +12,8 @@ import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.turtle.items.ItemTurtle;
import dan200.computercraft.shared.util.Holiday;
import dan200.computercraft.shared.util.HolidayUtil;
import net.minecraftforge.client.model.data.IModelData;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.model.BakedModel;
@@ -28,7 +21,6 @@ import net.minecraft.client.render.model.BakedModelManager;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.renderer.model.*;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.client.util.math.AffineTransformation;
@@ -39,11 +31,13 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
@SuppressWarnings ({
"MethodCallSideOnly",
"LocalVariableDeclarationSideOnly",
"NewExpressionSideOnly"
})
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
@Environment(EnvType.CLIENT)
public class TurtleSmartItemModel implements BakedModel
{
private static final AffineTransformation identity, flip;
@@ -170,14 +164,6 @@ public class TurtleSmartItemModel implements BakedModel
return familyModel.getQuads( state, facing, rand );
}
@Nonnull
@Override
@Deprecated
public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull Random rand, @Nonnull IModelData data )
{
return familyModel.getQuads( state, facing, rand, data );
}
@Override
public boolean useAmbientOcclusion()
{

View File

@@ -0,0 +1,165 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.core.apis;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import com.google.common.net.InetAddresses;
import dan200.computercraft.ComputerCraft;
/**
* Used to determine whether a domain or IP address matches a series of patterns.
*/
public class AddressPredicate {
private final List<Pattern> wildcards;
private final List<HostRange> ranges;
public AddressPredicate(String... filters) {
this(Arrays.asList(filters));
}
public AddressPredicate(Iterable<? extends String> filters) {
List<Pattern> wildcards = this.wildcards = new ArrayList<>();
List<HostRange> ranges = this.ranges = new ArrayList<>();
for (String filter : filters) {
int cidr = filter.indexOf('/');
if (cidr >= 0) {
String addressStr = filter.substring(0, cidr);
String prefixSizeStr = filter.substring(cidr + 1);
int prefixSize;
try {
prefixSize = Integer.parseInt(prefixSizeStr);
} catch (NumberFormatException e) {
ComputerCraft.log.error("Malformed http whitelist/blacklist entry '{}': Cannot extract size of CIDR mask from '{}'.",
filter,
prefixSizeStr);
continue;
}
InetAddress address;
try {
address = InetAddresses.forString(addressStr);
} catch (IllegalArgumentException e) {
ComputerCraft.log.error("Malformed http whitelist/blacklist entry '{}': Cannot extract IP address from '{}'.", filter, prefixSizeStr);
continue;
}
// Mask the bytes of the IP address.
byte[] minBytes = address.getAddress(), maxBytes = address.getAddress();
int size = prefixSize;
for (int i = 0; i < minBytes.length; i++) {
if (size <= 0) {
minBytes[i] &= 0;
maxBytes[i] |= 0xFF;
} else if (size < 8) {
minBytes[i] &= 0xFF << (8 - size);
maxBytes[i] |= ~(0xFF << (8 - size));
}
size -= 8;
}
ranges.add(new HostRange(minBytes, maxBytes));
} else {
wildcards.add(Pattern.compile("^\\Q" + filter.replaceAll("\\*", "\\\\E.*\\\\Q") + "\\E$"));
}
}
}
/**
* Determine whether the given address matches a series of patterns
*
* @param address The address to check.
* @return Whether it matches any of these patterns.
*/
public boolean matches(InetAddress address) {
// Match the host name
String host = address.getHostName();
if (host != null && this.matches(host)) {
return true;
}
// Match the normal address
if (this.matchesAddress(address)) {
return true;
}
// If we're an IPv4 address in disguise then let's check that.
return address instanceof Inet6Address && InetAddresses.is6to4Address((Inet6Address) address) && this.matchesAddress(InetAddresses.get6to4IPv4Address((Inet6Address) address));
}
/**
* Determine whether a host name matches a series of patterns.
*
* This is intended to allow early exiting, before one has to look up the IP address. You should use {@link #matches(InetAddress)} instead of/in
* addition to this one.
*
* @param domain The domain to match.
* @return Whether the patterns were matched.
*/
public boolean matches(String domain) {
for (Pattern domainPattern : this.wildcards) {
if (domainPattern.matcher(domain)
.matches()) {
return true;
}
}
return false;
}
private boolean matchesAddress(InetAddress address) {
String addressString = address.getHostAddress();
for (Pattern domainPattern : this.wildcards) {
if (domainPattern.matcher(addressString)
.matches()) {
return true;
}
}
for (HostRange range : this.ranges) {
if (range.contains(address)) {
return true;
}
}
return false;
}
private static final class HostRange {
private final byte[] min;
private final byte[] max;
private HostRange(byte[] min, byte[] max) {
this.min = min;
this.max = max;
}
public boolean contains(InetAddress address) {
byte[] entry = address.getAddress();
if (entry.length != this.min.length) {
return false;
}
for (int i = 0; i < entry.length; i++) {
int value = 0xFF & entry[i];
if (value < (0xFF & this.min[i]) || value > (0xFF & this.max[i])) {
return false;
}
}
return true;
}
}
}

View File

@@ -155,7 +155,7 @@ public class HTTPAPI implements ILuaAPI
@LuaFunction
public final Object[] websocket( String address, Optional<Map<?, ?>> headerTbl ) throws LuaException
{
if( !ComputerCraft.httpWebsocketEnabled )
if( !ComputerCraft.http_websocket_enable )
{
throw new LuaException( "Websocket connections are disabled" );
}

View File

@@ -46,7 +46,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
this.peripheral = peripheral;
attached = false;
type = Objects.requireNonNull(peripheral.getType0(), "Peripheral type cannot be null" );
type = Objects.requireNonNull( peripheral.getType(), "Peripheral type cannot be null" );
methodMap = PeripheralAPI.getMethods( peripheral );
}

View File

@@ -6,127 +6,115 @@
package dan200.computercraft.core.apis.http.options;
import com.electronwill.nightconfig.core.CommentedConfig;
import com.electronwill.nightconfig.core.Config;
import com.electronwill.nightconfig.core.InMemoryCommentedFormat;
import com.electronwill.nightconfig.core.UnmodifiableConfig;
import dan200.computercraft.ComputerCraft;
import javax.annotation.Nullable;
import java.util.Locale;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
/**
* Parses, checks and generates {@link Config}s for {@link AddressRule}.
*/
public class AddressRuleConfig
{
public static UnmodifiableConfig makeRule( String host, Action action )
{
CommentedConfig config = InMemoryCommentedFormat.defaultInstance().createConfig( ConcurrentHashMap::new );
config.add( "host", host );
config.add( "action", action.name().toLowerCase( Locale.ROOT ) );
// TODO haha config is gone, do fix
if( host.equals( "*" ) && action == Action.ALLOW )
{
config.setComment( "timeout", "The period of time (in milliseconds) to wait before a HTTP request times out. Set to 0 for unlimited." );
config.add( "timeout", AddressRule.TIMEOUT );
config.setComment( "max_download", "The maximum size (in bytes) that a computer can download in a single request. Note that responses may receive more data than allowed, but this data will not be returned to the client." );
config.set( "max_download", AddressRule.MAX_DOWNLOAD );
config.setComment( "max_upload", "The maximum size (in bytes) that a computer can upload in a single request. This includes headers and POST text." );
config.set( "max_upload", AddressRule.MAX_UPLOAD );
config.setComment( "max_websocket_message", "The maximum size (in bytes) that a computer can send or receive in one websocket packet." );
config.set( "max_websocket_message", AddressRule.WEBSOCKET_MESSAGE );
}
return config;
}
public static boolean checkRule( UnmodifiableConfig builder )
{
String hostObj = get( builder, "host", String.class ).orElse( null );
return hostObj != null && checkEnum( builder, "action", Action.class )
&& check( builder, "timeout", Number.class )
&& check( builder, "max_upload", Number.class )
&& check( builder, "max_download", Number.class )
&& check( builder, "websocket_message", Number.class )
&& AddressRule.parse( hostObj, PartialOptions.DEFAULT ) != null;
}
@Nullable
public static AddressRule parseRule( UnmodifiableConfig builder )
{
String hostObj = get( builder, "host", String.class ).orElse( null );
if( hostObj == null ) return null;
Action action = getEnum( builder, "action", Action.class ).orElse( null );
Integer timeout = get( builder, "timeout", Number.class ).map( Number::intValue ).orElse( null );
Long maxUpload = get( builder, "max_upload", Number.class ).map( Number::longValue ).orElse( null );
Long maxDownload = get( builder, "max_download", Number.class ).map( Number::longValue ).orElse( null );
Integer websocketMessage = get( builder, "websocket_message", Number.class ).map( Number::intValue ).orElse( null );
PartialOptions options = new PartialOptions(
action,
maxUpload,
maxDownload,
timeout,
websocketMessage
);
return AddressRule.parse( hostObj, options );
}
private static <T> boolean check( UnmodifiableConfig config, String field, Class<T> klass )
{
Object value = config.get( field );
if( value == null || klass.isInstance( value ) ) return true;
ComputerCraft.log.warn( "HTTP rule's {} is not a {}.", field, klass.getSimpleName() );
return false;
}
private static <T extends Enum<T>> boolean checkEnum( UnmodifiableConfig config, String field, Class<T> klass )
{
Object value = config.get( field );
if( value == null ) return true;
if( !(value instanceof String) )
{
ComputerCraft.log.warn( "HTTP rule's {} is not a string", field );
return false;
}
if( parseEnum( klass, (String) value ) == null )
{
ComputerCraft.log.warn( "HTTP rule's {} is not a known option", field );
return false;
}
return true;
}
private static <T> Optional<T> get( UnmodifiableConfig config, String field, Class<T> klass )
{
Object value = config.get( field );
return klass.isInstance( value ) ? Optional.of( klass.cast( value ) ) : Optional.empty();
}
private static <T extends Enum<T>> Optional<T> getEnum( UnmodifiableConfig config, String field, Class<T> klass )
{
return get( config, field, String.class ).map( x -> parseEnum( klass, x ) );
}
@Nullable
private static <T extends Enum<T>> T parseEnum( Class<T> klass, String x )
{
for( T value : klass.getEnumConstants() )
{
if( value.name().equalsIgnoreCase( x ) ) return value;
}
return null;
}
// public static UnmodifiableConfig makeRule( String host, Action action )
// {
// CommentedConfig config = InMemoryCommentedFormat.defaultInstance().createConfig( ConcurrentHashMap::new );
// config.add( "host", host );
// config.add( "action", action.name().toLowerCase( Locale.ROOT ) );
//
// if( host.equals( "*" ) && action == Action.ALLOW )
// {
// config.setComment( "timeout", "The period of time (in milliseconds) to wait before a HTTP request times out. Set to 0 for unlimited." );
// config.add( "timeout", AddressRule.TIMEOUT );
//
// config.setComment( "max_download", "The maximum size (in bytes) that a computer can download in a single request. Note that responses may receive more data than allowed, but this data will not be returned to the client." );
// config.set( "max_download", AddressRule.MAX_DOWNLOAD );
//
// config.setComment( "max_upload", "The maximum size (in bytes) that a computer can upload in a single request. This includes headers and POST text." );
// config.set( "max_upload", AddressRule.MAX_UPLOAD );
//
// config.setComment( "max_websocket_message", "The maximum size (in bytes) that a computer can send or receive in one websocket packet." );
// config.set( "max_websocket_message", AddressRule.WEBSOCKET_MESSAGE );
// }
//
// return config;
// }
//
// public static boolean checkRule( UnmodifiableConfig builder )
// {
// String hostObj = get( builder, "host", String.class ).orElse( null );
// return hostObj != null && checkEnum( builder, "action", Action.class )
// && check( builder, "timeout", Number.class )
// && check( builder, "max_upload", Number.class )
// && check( builder, "max_download", Number.class )
// && check( builder, "websocket_message", Number.class )
// && AddressRule.parse( hostObj, PartialOptions.DEFAULT ) != null;
// }
//
// @Nullable
// public static AddressRule parseRule( UnmodifiableConfig builder )
// {
// String hostObj = get( builder, "host", String.class ).orElse( null );
// if( hostObj == null ) return null;
//
// Action action = getEnum( builder, "action", Action.class ).orElse( null );
// Integer timeout = get( builder, "timeout", Number.class ).map( Number::intValue ).orElse( null );
// Long maxUpload = get( builder, "max_upload", Number.class ).map( Number::longValue ).orElse( null );
// Long maxDownload = get( builder, "max_download", Number.class ).map( Number::longValue ).orElse( null );
// Integer websocketMessage = get( builder, "websocket_message", Number.class ).map( Number::intValue ).orElse( null );
//
// PartialOptions options = new PartialOptions(
// action,
// maxUpload,
// maxDownload,
// timeout,
// websocketMessage
// );
//
// return AddressRule.parse( hostObj, options );
// }
//
// private static <T> boolean check( UnmodifiableConfig config, String field, Class<T> klass )
// {
// Object value = config.get( field );
// if( value == null || klass.isInstance( value ) ) return true;
//
// ComputerCraft.log.warn( "HTTP rule's {} is not a {}.", field, klass.getSimpleName() );
// return false;
// }
//
// private static <T extends Enum<T>> boolean checkEnum( UnmodifiableConfig config, String field, Class<T> klass )
// {
// Object value = config.get( field );
// if( value == null ) return true;
//
// if( !(value instanceof String) )
// {
// ComputerCraft.log.warn( "HTTP rule's {} is not a string", field );
// return false;
// }
//
// if( parseEnum( klass, (String) value ) == null )
// {
// ComputerCraft.log.warn( "HTTP rule's {} is not a known option", field );
// return false;
// }
//
// return true;
// }
//
// private static <T> Optional<T> get( UnmodifiableConfig config, String field, Class<T> klass )
// {
// Object value = config.get( field );
// return klass.isInstance( value ) ? Optional.of( klass.cast( value ) ) : Optional.empty();
// }
//
// private static <T extends Enum<T>> Optional<T> getEnum( UnmodifiableConfig config, String field, Class<T> klass )
// {
// return get( config, field, String.class ).map( x -> parseEnum( klass, x ) );
// }
//
// @Nullable
// private static <T extends Enum<T>> T parseEnum( Class<T> klass, String x )
// {
// for( T value : klass.getEnumConstants() )
// {
// if( value.name().equalsIgnoreCase( x ) ) return value;
// }
// return null;
// }
}

View File

@@ -203,7 +203,7 @@ public class HttpRequest extends Resource<HttpRequest>
catch( Exception e )
{
failure( "Could not connect" );
if( ComputerCraft.logComputerErrors ) ComputerCraft.log.error( "Error in HTTP request", e );
if( ComputerCraft.logPeripheralErrors ) ComputerCraft.log.error( "Error in HTTP request", e );
}
}

View File

@@ -188,7 +188,7 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpOb
@Override
public void exceptionCaught( ChannelHandlerContext ctx, Throwable cause )
{
if( ComputerCraft.logComputerErrors ) ComputerCraft.log.error( "Error handling HTTP response", cause );
if( ComputerCraft.logPeripheralErrors ) ComputerCraft.log.error( "Error handling HTTP response", cause );
request.failure( cause );
}

View File

@@ -180,7 +180,7 @@ public class Websocket extends Resource<Websocket>
catch( Exception e )
{
failure( "Could not connect" );
if( ComputerCraft.logComputerErrors ) ComputerCraft.log.error( "Error in websocket", e );
if( ComputerCraft.logPeripheralErrors ) ComputerCraft.log.error( "Error in websocket", e );
}
}

View File

@@ -8,8 +8,6 @@ package dan200.computercraft.core.asm;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
import dan200.computercraft.shared.util.ServiceUtil;
import javax.annotation.Nonnull;
import net.minecraft.util.Identifier;
import java.lang.reflect.Method;
@@ -28,10 +26,6 @@ import java.util.stream.Stream;
*
* Unlike conventional Lua objects, the annotated methods should be {@code static}, with their target as the first
* parameter.
*
* This is used by the generic peripheral system ({@link GenericPeripheralProvider}) to provide methods for arbitrary
* tile entities. Eventually this'll be be exposed in the public API. Until it is stabilised, it will remain in this
* package - do not use it in external mods!
*/
public interface GenericSource
{
@@ -47,8 +41,6 @@ public interface GenericSource
* Register a stream of generic sources.
*
* @param sources The source of generic methods.
* @see ServiceUtil For ways to load this. Sadly {@link java.util.ServiceLoader} is broken under Forge, but we don't
* want to add a hard-dep on Forge within core either.
*/
static void setup( Supplier<Stream<GenericSource>> sources )
{

View File

@@ -171,7 +171,7 @@ final class ComputerExecutor
apis.add( new FSAPI( environment ) );
apis.add( new PeripheralAPI( environment ) );
apis.add( new OSAPI( environment ) );
if( ComputerCraft.httpEnabled ) apis.add( new HTTPAPI( environment ) );
if( ComputerCraft.http_enable ) apis.add( new HTTPAPI( environment ) );
// Load in the externally registered APIs.
for( ILuaAPIFactory factory : ApiFactories.getAll() )

View File

@@ -136,7 +136,7 @@ public final class ComputerThread
if( runners == null )
{
// TODO: Change the runners length on config reloads
runners = new TaskRunner[ComputerCraft.computerThreads];
runners = new TaskRunner[ComputerCraft.computer_threads];
// latency and minPeriod are scaled by 1 + floor(log2(threads)). We can afford to execute tasks for
// longer when executing on more than one thread.
@@ -518,7 +518,7 @@ public final class ComputerThread
private static void timeoutTask( ComputerExecutor executor, Thread thread, long time )
{
if( !ComputerCraft.logComputerErrors ) return;
if( !ComputerCraft.logPeripheralErrors ) return;
StringBuilder builder = new StringBuilder()
.append( "Terminating computer #" ).append( executor.getComputer().getID() )

View File

@@ -12,14 +12,13 @@ import com.google.common.io.ByteStreams;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.core.apis.handles.ArrayByteChannel;
import dan200.computercraft.core.filesystem.ResourceMount.Listener;
import net.minecraft.resource.ReloadableResourceManager;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.ResourceReloadListener;
import net.minecraft.util.Identifier;
import net.minecraft.util.InvalidIdentifierException;
import net.minecraftforge.resource.IResourceType;
import net.minecraftforge.resource.ISelectiveResourceReloadListener;
import net.minecraft.util.profiler.Profiler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -29,6 +28,8 @@ import java.io.InputStream;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
@@ -271,12 +272,10 @@ public final class ResourceMount implements IMount
}
/**
* A {@link ISelectiveResourceReloadListener} which reloads any associated mounts.
*
* While people should really be keeping a permanent reference to this, some people construct it every
* method call, so let's make this as small as possible.
*/
static class Listener implements ISelectiveResourceReloadListener
static class Listener implements ResourceReloadListener
{
private static final Listener INSTANCE = new Listener();
@@ -284,22 +283,25 @@ public final class ResourceMount implements IMount
private final Set<ReloadableResourceManager> managers = Collections.newSetFromMap( new WeakHashMap<>() );
@Override
public void apply( @Nonnull ResourceManager manager )
{
// FIXME: Remove this. We need this patch in order to prevent trying to load ReloadRequirements.
onResourceManagerReload( manager, x -> true );
public CompletableFuture<Void> reload(Synchronizer synchronizer, ResourceManager resourceManager, Profiler profiler, Profiler profiler1,
Executor executor, Executor executor1) {
return CompletableFuture.runAsync(() -> {
profiler.push("Mount reloading");
try {
for (ResourceMount mount : this.mounts) {
mount.load();
}
} finally {
profiler.pop();
}
}, executor);
}
@Override
public synchronized void onResourceManagerReload( @Nonnull ResourceManager manager, @Nonnull Predicate<IResourceType> predicate )
{
for( ResourceMount mount : mounts ) mount.load();
}
synchronized void add( ReloadableResourceManager manager, ResourceMount mount )
{
if( managers.add( manager ) ) manager.registerListener( this );
mounts.add( mount );
synchronized void add(ReloadableResourceManager manager, ResourceMount mount) {
if (this.managers.add(manager)) {
manager.registerListener(this);
}
this.mounts.add(mount);
}
}
}

View File

@@ -54,7 +54,7 @@ class BasicFunction extends VarArgFunction
}
catch( Throwable t )
{
if( ComputerCraft.logComputerErrors )
if( ComputerCraft.logPeripheralErrors )
{
ComputerCraft.log.error( "Error calling " + name + " on " + instance, t );
}

View File

@@ -97,7 +97,7 @@ public class CobaltLuaMachine implements ILuaMachine
m_globals.load( state, new CoroutineLib() );
m_globals.load( state, new Bit32Lib() );
m_globals.load( state, new Utf8Lib() );
if( ComputerCraft.debugEnable ) m_globals.load( state, new DebugLib() );
if( ComputerCraft.debug_enable ) m_globals.load( state, new DebugLib() );
// Remove globals we don't want to expose
m_globals.rawset( "collectgarbage", Constants.NIL );
@@ -108,8 +108,8 @@ public class CobaltLuaMachine implements ILuaMachine
// Add version globals
m_globals.rawset( "_VERSION", valueOf( "Lua 5.1" ) );
m_globals.rawset( "_HOST", valueOf( computer.getAPIEnvironment().getComputerEnvironment().getHostString() ) );
m_globals.rawset( "_CC_DEFAULT_SETTINGS", valueOf( ComputerCraft.defaultComputerSettings ) );
if( ComputerCraft.disableLua51Features )
m_globals.rawset( "_CC_DEFAULT_SETTINGS", valueOf( ComputerCraft.default_computer_settings ) );
if( ComputerCraft.disable_lua51_features )
{
m_globals.rawset( "_CC_DISABLE_LUA51_FEATURES", Constants.TRUE );
}
@@ -237,10 +237,10 @@ public class CobaltLuaMachine implements ILuaMachine
table.rawset( method, new ResultInterpreterFunction( this, LuaMethod.DYNAMIC.get( i ), object, context, method ) );
}
ObjectSource.allMethods( LuaMethod.GENERATOR, object, ( instance, method ) ->
ObjectSource.allMethods( LuaMethod.GENERATOR, object, (instance, method ) ->
table.rawset( method.getName(), method.nonYielding()
? new BasicFunction( this, method.getMethod(), instance, context, method.getName() )
: new ResultInterpreterFunction( this, method.getMethod(), instance, context, method.getName() ) ) );
? new BasicFunction( this, (LuaMethod) method.getMethod(), instance, context, method.getName() )
: new ResultInterpreterFunction( this, (LuaMethod) method.getMethod(), instance, context, method.getName() ) ) );
try
{
@@ -330,7 +330,7 @@ public class CobaltLuaMachine implements ILuaMachine
return wrapped;
}
if( ComputerCraft.logComputerErrors )
if( ComputerCraft.logPeripheralErrors )
{
ComputerCraft.log.warn( "Received unknown type '{}', returning nil.", object.getClass().getName() );
}
@@ -539,7 +539,7 @@ public class CobaltLuaMachine implements ILuaMachine
}
catch( Throwable t )
{
if( ComputerCraft.logComputerErrors ) ComputerCraft.log.error( "Error running task", t );
if( ComputerCraft.logPeripheralErrors ) ComputerCraft.log.error( "Error running task", t );
m_computer.queueEvent( "task_complete", new Object[] {
taskID, false, "Java Exception Thrown: " + t,
} );

View File

@@ -65,7 +65,7 @@ class ResultInterpreterFunction extends ResumableVarArgFunction<ResultInterprete
}
catch( Throwable t )
{
if( ComputerCraft.logComputerErrors )
if( ComputerCraft.logPeripheralErrors )
{
ComputerCraft.log.error( "Error calling " + name + " on " + instance, t );
}
@@ -96,7 +96,7 @@ class ResultInterpreterFunction extends ResumableVarArgFunction<ResultInterprete
}
catch( Throwable t )
{
if( ComputerCraft.logComputerErrors )
if( ComputerCraft.logPeripheralErrors )
{
ComputerCraft.log.error( "Error calling " + name + " on " + container.callback, t );
}

View File

@@ -1,29 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.data;
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.server.BlockTagsProvider;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
@Mod.EventBusSubscriber( bus = Mod.EventBusSubscriber.Bus.MOD )
public class Generators
{
@SubscribeEvent
public static void gather( GatherDataEvent event )
{
ComputerCraftProxyCommon.registerLoot();
DataGenerator generator = event.getGenerator();
generator.install( new Recipes( generator ) );
generator.install( new LootTables( generator ) );
generator.install( new Tags( generator, new BlockTagsProvider( generator ) ) );
}
}

View File

@@ -1,91 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.data;
import com.google.common.collect.Multimap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import dan200.computercraft.ComputerCraft;
import net.minecraft.data.DataCache;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.DataProvider;
import net.minecraft.loot.LootManager;
import net.minecraft.loot.LootTable;
import net.minecraft.loot.LootTableReporter;
import net.minecraft.loot.context.LootContextTypes;
import net.minecraft.util.Identifier;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
/**
* An alternative to {@link net.minecraft.data.LootTableProvider}, with a more flexible interface.
*/
public abstract class LootTableProvider implements DataProvider
{
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
private final DataGenerator generator;
public LootTableProvider( DataGenerator generator )
{
this.generator = generator;
}
@Override
public void run( @Nonnull DataCache cache )
{
Map<Identifier, LootTable> tables = new HashMap<>();
LootTableReporter validation = new LootTableReporter( LootContextTypes.GENERIC, x -> null, tables::get );
registerLoot( ( id, table ) -> {
if( tables.containsKey( id ) ) validation.report( "Duplicate loot tables for " + id );
tables.put( id, table );
} );
tables.forEach( ( key, value ) -> LootManager.validate( validation, key, value ) );
Multimap<String, String> problems = validation.getMessages();
if( !problems.isEmpty() )
{
problems.forEach( ( child, problem ) ->
ComputerCraft.log.warn( "Found validation problem in " + child + ": " + problem ) );
throw new IllegalStateException( "Failed to validate loot tables, see logs" );
}
tables.forEach( ( key, value ) -> {
Path path = getPath( key );
try
{
DataProvider.writeToPath( GSON, cache, LootManager.toJson( value ), path );
}
catch( IOException e )
{
ComputerCraft.log.error( "Couldn't save loot table {}", path, e );
}
} );
}
protected abstract void registerLoot( BiConsumer<Identifier, LootTable> add );
@Nonnull
@Override
public String getName()
{
return "LootTables";
}
private Path getPath( Identifier id )
{
return generator.getOutput()
.resolve( "data" ).resolve( id.getNamespace() ).resolve( "loot_tables" )
.resolve( id.getPath() + ".json" );
}
}

View File

@@ -1,89 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.data;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.data.BlockNamedEntityLootCondition;
import dan200.computercraft.shared.data.HasComputerIdLootCondition;
import dan200.computercraft.shared.data.PlayerCreativeLootCondition;
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
import net.minecraft.block.Block;
import net.minecraft.data.DataGenerator;
import net.minecraft.loot.*;
import net.minecraft.loot.condition.AlternativeLootCondition;
import net.minecraft.loot.condition.SurvivesExplosionLootCondition;
import net.minecraft.loot.context.LootContextTypes;
import net.minecraft.loot.entry.DynamicEntry;
import net.minecraft.loot.entry.ItemEntry;
import net.minecraft.util.Identifier;
import net.minecraftforge.fml.RegistryObject;
import java.util.function.BiConsumer;
public class LootTables extends LootTableProvider
{
public LootTables( DataGenerator generator )
{
super( generator );
}
@Override
protected void registerLoot( BiConsumer<Identifier, LootTable> add )
{
basicDrop( add, Registry.ModBlocks.DISK_DRIVE );
basicDrop( add, Registry.ModBlocks.MONITOR_NORMAL );
basicDrop( add, Registry.ModBlocks.MONITOR_ADVANCED );
basicDrop( add, Registry.ModBlocks.PRINTER );
basicDrop( add, Registry.ModBlocks.SPEAKER );
basicDrop( add, Registry.ModBlocks.WIRED_MODEM_FULL );
basicDrop( add, Registry.ModBlocks.WIRELESS_MODEM_NORMAL );
basicDrop( add, Registry.ModBlocks.WIRELESS_MODEM_ADVANCED );
computerDrop( add, Registry.ModBlocks.COMPUTER_NORMAL );
computerDrop( add, Registry.ModBlocks.COMPUTER_ADVANCED );
computerDrop( add, Registry.ModBlocks.TURTLE_NORMAL );
computerDrop( add, Registry.ModBlocks.TURTLE_ADVANCED );
add.accept( ComputerCraftProxyCommon.ForgeHandlers.LOOT_TREASURE_DISK, LootTable
.builder()
.type( LootContextTypes.GENERIC )
.build() );
}
private static <T extends Block> void basicDrop( BiConsumer<Identifier, LootTable> add, RegistryObject<T> wrapper )
{
Block block = wrapper.get();
add.accept( block.getLootTableId(), LootTable
.builder()
.type( LootContextTypes.BLOCK )
.pool( LootPool.builder()
.name( "main" )
.rolls( ConstantLootTableRange.create( 1 ) )
.with( ItemEntry.builder( block ) )
.conditionally( SurvivesExplosionLootCondition.builder() )
).build() );
}
private static <T extends Block> void computerDrop( BiConsumer<Identifier, LootTable> add, RegistryObject<T> wrapper )
{
Block block = wrapper.get();
add.accept( block.getLootTableId(), LootTable
.builder()
.type( LootContextTypes.BLOCK )
.pool( LootPool.builder()
.name( "main" )
.rolls( ConstantLootTableRange.create( 1 ) )
.with( DynamicEntry.builder( new Identifier( ComputerCraft.MOD_ID, "computer" ) ) )
.conditionally( AlternativeLootCondition.builder(
BlockNamedEntityLootCondition.BUILDER,
HasComputerIdLootCondition.BUILDER,
PlayerCreativeLootCondition.BUILDER.invert()
) )
).build() );
}
}

View File

@@ -1,91 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.data;
import com.google.gson.JsonObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.data.server.recipe.RecipeJsonProvider;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import java.util.function.Consumer;
/**
* Adapter for recipes which overrides the serializer and adds custom item NBT.
*/
public final class RecipeWrapper implements RecipeJsonProvider
{
private final RecipeJsonProvider recipe;
private final CompoundTag resultData;
private final RecipeSerializer<?> serializer;
private RecipeWrapper( RecipeJsonProvider recipe, CompoundTag resultData, RecipeSerializer<?> serializer )
{
this.resultData = resultData;
this.recipe = recipe;
this.serializer = serializer;
}
public static Consumer<RecipeJsonProvider> wrap( RecipeSerializer<?> serializer, Consumer<RecipeJsonProvider> original )
{
return x -> original.accept( new RecipeWrapper( x, null, serializer ) );
}
public static Consumer<RecipeJsonProvider> wrap( RecipeSerializer<?> serializer, Consumer<RecipeJsonProvider> original, CompoundTag resultData )
{
return x -> original.accept( new RecipeWrapper( x, resultData, serializer ) );
}
public static Consumer<RecipeJsonProvider> wrap( RecipeSerializer<?> serializer, Consumer<RecipeJsonProvider> original, Consumer<CompoundTag> resultData )
{
CompoundTag tag = new CompoundTag();
resultData.accept( tag );
return x -> original.accept( new RecipeWrapper( x, tag, serializer ) );
}
@Override
public void serialize( @Nonnull JsonObject jsonObject )
{
recipe.serialize( jsonObject );
if( resultData != null )
{
JsonObject object = JsonHelper.getObject( jsonObject, "result" );
object.addProperty( "nbt", resultData.toString() );
}
}
@Nonnull
@Override
public Identifier getRecipeId()
{
return recipe.getRecipeId();
}
@Nonnull
@Override
public RecipeSerializer<?> getSerializer()
{
return serializer;
}
@Nullable
@Override
public JsonObject toAdvancementJson()
{
return recipe.toAdvancementJson();
}
@Nullable
@Override
public Identifier getAdvancementId()
{
return recipe.getAdvancementId();
}
}

View File

@@ -1,325 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.data;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.data.Tags.CCTags;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.TurtleUpgrades;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory;
import dan200.computercraft.shared.turtle.items.TurtleItemFactory;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.ImpostorRecipe;
import dan200.computercraft.shared.util.ImpostorShapelessRecipe;
import net.minecraft.advancement.criterion.InventoryChangedCriterion;
import net.minecraft.block.Blocks;
import net.minecraft.data.*;
import net.minecraft.data.server.RecipesProvider;
import net.minecraft.data.server.recipe.RecipeJsonProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonFactory;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonFactory;
import net.minecraft.item.*;
import net.minecraft.predicate.item.ItemPredicate;
import net.minecraft.tag.Tag;
import net.minecraft.util.DyeColor;
import net.minecraft.util.Identifier;
import net.minecraftforge.common.Tags;
import javax.annotation.Nonnull;
import java.util.Locale;
import java.util.function.Consumer;
public class Recipes extends RecipesProvider
{
public Recipes( DataGenerator generator )
{
super( generator );
}
@Override
protected void generate( @Nonnull Consumer<RecipeJsonProvider> add )
{
basicRecipes( add );
diskColours( add );
pocketUpgrades( add );
turtleUpgrades( add );
}
/**
* Register a crafting recipe for a disk of every dye colour.
*
* @param add The callback to add recipes.
*/
private void diskColours( @Nonnull Consumer<RecipeJsonProvider> add )
{
for( Colour colour : Colour.VALUES )
{
ShapelessRecipeJsonFactory
.create( Registry.ModItems.DISK.get() )
.input( Tags.Items.DUSTS_REDSTONE )
.input( Items.PAPER )
.input( DyeItem.byColor( ofColour( colour ) ) )
.group( "computercraft:disk" )
.criterion( "has_drive", inventoryChange( Registry.ModBlocks.DISK_DRIVE.get() ) )
.offerTo( RecipeWrapper.wrap(
ImpostorShapelessRecipe.SERIALIZER, add,
x -> x.putInt( "color", colour.getHex() )
), new Identifier( ComputerCraft.MOD_ID, "disk_" + (colour.ordinal() + 1) ) );
}
}
/**
* Register a crafting recipe for each turtle upgrade.
*
* @param add The callback to add recipes.
*/
private void turtleUpgrades( @Nonnull Consumer<RecipeJsonProvider> add )
{
for( ComputerFamily family : ComputerFamily.values() )
{
ItemStack base = TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null );
if( base.isEmpty() ) continue;
String nameId = family.name().toLowerCase( Locale.ROOT );
TurtleUpgrades.getVanillaUpgrades().forEach( upgrade -> {
ItemStack result = TurtleItemFactory.create( -1, null, -1, family, null, upgrade, -1, null );
ShapedRecipeJsonFactory
.create( result.getItem() )
.group( String.format( "%s:turtle_%s", ComputerCraft.MOD_ID, nameId ) )
.pattern( "#T" )
.input( '#', base.getItem() )
.input( 'T', upgrade.getCraftingItem().getItem() )
.criterion( "has_items",
inventoryChange( base.getItem(), upgrade.getCraftingItem().getItem() ) )
.offerTo(
RecipeWrapper.wrap( ImpostorRecipe.SERIALIZER, add, result.getTag() ),
new Identifier( ComputerCraft.MOD_ID, String.format( "turtle_%s/%s/%s",
nameId, upgrade.getUpgradeID().getNamespace(), upgrade.getUpgradeID().getPath()
) )
);
} );
}
}
/**
* Register a crafting recipe for each pocket upgrade.
*
* @param add The callback to add recipes.
*/
private void pocketUpgrades( @Nonnull Consumer<RecipeJsonProvider> add )
{
for( ComputerFamily family : ComputerFamily.values() )
{
ItemStack base = PocketComputerItemFactory.create( -1, null, -1, family, null );
if( base.isEmpty() ) continue;
String nameId = family.name().toLowerCase( Locale.ROOT );
TurtleUpgrades.getVanillaUpgrades().forEach( upgrade -> {
ItemStack result = PocketComputerItemFactory.create( -1, null, -1, family, null );
ShapedRecipeJsonFactory
.create( result.getItem() )
.group( String.format( "%s:pocket_%s", ComputerCraft.MOD_ID, nameId ) )
.pattern( "#" )
.pattern( "P" )
.input( '#', base.getItem() )
.input( 'P', upgrade.getCraftingItem().getItem() )
.criterion( "has_items",
inventoryChange( base.getItem(), upgrade.getCraftingItem().getItem() ) )
.offerTo(
RecipeWrapper.wrap( ImpostorRecipe.SERIALIZER, add, result.getTag() ),
new Identifier( ComputerCraft.MOD_ID, String.format( "pocket_%s/%s/%s",
nameId, upgrade.getUpgradeID().getNamespace(), upgrade.getUpgradeID().getPath()
) )
);
} );
}
}
private void basicRecipes( @Nonnull Consumer<RecipeJsonProvider> add )
{
ShapedRecipeJsonFactory
.create( Registry.ModItems.CABLE.get(), 6 )
.pattern( " # " )
.pattern( "#R#" )
.pattern( " # " )
.input( '#', Tags.Items.STONE )
.input( 'R', Tags.Items.DUSTS_REDSTONE )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.criterion( "has_modem", inventoryChange( CCTags.COMPUTER ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModBlocks.COMPUTER_NORMAL.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "#G#" )
.input( '#', Tags.Items.STONE )
.input( 'R', Tags.Items.DUSTS_REDSTONE )
.input( 'G', Tags.Items.GLASS_PANES )
.criterion( "has_redstone", inventoryChange( Tags.Items.DUSTS_REDSTONE ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModBlocks.COMPUTER_ADVANCED.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "#G#" )
.input( '#', Tags.Items.INGOTS_GOLD )
.input( 'R', Tags.Items.DUSTS_REDSTONE )
.input( 'G', Tags.Items.GLASS_PANES )
.criterion( "has_components", inventoryChange( Items.REDSTONE, Items.GOLD_INGOT ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModBlocks.COMPUTER_COMMAND.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "#G#" )
.input( '#', Tags.Items.INGOTS_GOLD )
.input( 'R', Blocks.COMMAND_BLOCK )
.input( 'G', Tags.Items.GLASS_PANES )
.criterion( "has_components", inventoryChange( Blocks.COMMAND_BLOCK ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModBlocks.DISK_DRIVE.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "#R#" )
.input( '#', Tags.Items.STONE )
.input( 'R', Tags.Items.DUSTS_REDSTONE )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModBlocks.MONITOR_NORMAL.get() )
.pattern( "###" )
.pattern( "#G#" )
.pattern( "###" )
.input( '#', Tags.Items.STONE )
.input( 'G', Tags.Items.GLASS_PANES )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModBlocks.MONITOR_ADVANCED.get(), 4 )
.pattern( "###" )
.pattern( "#G#" )
.pattern( "###" )
.input( '#', Tags.Items.INGOTS_GOLD )
.input( 'G', Tags.Items.GLASS_PANES )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModItems.POCKET_COMPUTER_NORMAL.get() )
.pattern( "###" )
.pattern( "#A#" )
.pattern( "#G#" )
.input( '#', Tags.Items.STONE )
.input( 'A', Items.GOLDEN_APPLE )
.input( 'G', Tags.Items.GLASS_PANES )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.criterion( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModItems.POCKET_COMPUTER_ADVANCED.get() )
.pattern( "###" )
.pattern( "#A#" )
.pattern( "#G#" )
.input( '#', Tags.Items.INGOTS_GOLD )
.input( 'A', Items.GOLDEN_APPLE )
.input( 'G', Tags.Items.GLASS_PANES )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.criterion( "has_apple", inventoryChange( Items.GOLDEN_APPLE ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModBlocks.PRINTER.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "#D#" )
.input( '#', Tags.Items.STONE )
.input( 'R', Tags.Items.DUSTS_REDSTONE )
.input( 'D', Tags.Items.DYES )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModBlocks.SPEAKER.get() )
.pattern( "###" )
.pattern( "#N#" )
.pattern( "#R#" )
.input( '#', Tags.Items.STONE )
.input( 'N', Blocks.NOTE_BLOCK )
.input( 'R', Tags.Items.DUSTS_REDSTONE )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModItems.WIRED_MODEM.get() )
.pattern( "###" )
.pattern( "#R#" )
.pattern( "###" )
.input( '#', Tags.Items.STONE )
.input( 'R', Tags.Items.DUSTS_REDSTONE )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.criterion( "has_cable", inventoryChange( Registry.ModItems.CABLE.get() ) )
.offerTo( add );
ShapelessRecipeJsonFactory
.create( Registry.ModBlocks.WIRED_MODEM_FULL.get() )
.input( Registry.ModItems.WIRED_MODEM.get() )
.criterion( "has_modem", inventoryChange( CCTags.WIRED_MODEM ) )
.offerTo( add, new Identifier( ComputerCraft.MOD_ID, "wired_modem_full_from" ) );
ShapelessRecipeJsonFactory
.create( Registry.ModItems.WIRED_MODEM.get() )
.input( Registry.ModBlocks.WIRED_MODEM_FULL.get() )
.criterion( "has_modem", inventoryChange( CCTags.WIRED_MODEM ) )
.offerTo( add, new Identifier( ComputerCraft.MOD_ID, "wired_modem_full_to" ) );
ShapedRecipeJsonFactory
.create( Registry.ModBlocks.WIRELESS_MODEM_NORMAL.get() )
.pattern( "###" )
.pattern( "#E#" )
.pattern( "###" )
.input( '#', Tags.Items.STONE )
.input( 'E', Tags.Items.ENDER_PEARLS )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.offerTo( add );
ShapedRecipeJsonFactory
.create( Registry.ModBlocks.WIRELESS_MODEM_ADVANCED.get() )
.pattern( "###" )
.pattern( "#E#" )
.pattern( "###" )
.input( '#', Tags.Items.INGOTS_GOLD )
.input( 'E', Items.ENDER_EYE )
.criterion( "has_computer", inventoryChange( CCTags.COMPUTER ) )
.criterion( "has_wireless", inventoryChange( Registry.ModBlocks.WIRELESS_MODEM_NORMAL.get() ) )
.offerTo( add );
}
private static DyeColor ofColour( Colour colour )
{
return DyeColor.byId( 15 - colour.ordinal() );
}
private static InventoryChangedCriterion.Conditions inventoryChange( Tag<Item> stack )
{
return InventoryChangedCriterion.Conditions.items( ItemPredicate.Builder.create().tag( stack ).build() );
}
private static InventoryChangedCriterion.Conditions inventoryChange( ItemConvertible... stack )
{
return InventoryChangedCriterion.Conditions.items( stack );
}
}

View File

@@ -1,61 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.data;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.Registry;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.server.BlockTagsProvider;
import net.minecraft.data.server.ItemTagsProvider;
import net.minecraft.item.Item;
import net.minecraft.tag.ItemTags;
import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier;
import static dan200.computercraft.data.Tags.CCTags.*;
public class Tags extends ItemTagsProvider
{
private static final Tag.Identified<Item> PIGLIN_LOVED = ItemTags.PIGLIN_LOVED;
public static class CCTags
{
public static final Tag.Identified<Item> COMPUTER = item( "computer" );
public static final Tag.Identified<Item> TURTLE = item( "turtle" );
public static final Tag.Identified<Item> WIRED_MODEM = item( "wired_modem" );
public static final Tag.Identified<Item> MONITOR = item( "monitor" );
}
public Tags( DataGenerator generator, BlockTagsProvider tags )
{
super( generator, tags );
}
@Override
protected void configure()
{
getOrCreateTagBuilder( COMPUTER ).add(
Registry.ModItems.COMPUTER_NORMAL.get(),
Registry.ModItems.COMPUTER_ADVANCED.get(),
Registry.ModItems.COMPUTER_COMMAND.get()
);
getOrCreateTagBuilder( TURTLE ).add( Registry.ModItems.TURTLE_NORMAL.get(), Registry.ModItems.TURTLE_ADVANCED.get() );
getOrCreateTagBuilder( WIRED_MODEM ).add( Registry.ModItems.WIRED_MODEM.get(), Registry.ModItems.WIRED_MODEM_FULL.get() );
getOrCreateTagBuilder( MONITOR ).add( Registry.ModItems.MONITOR_NORMAL.get(), Registry.ModItems.MONITOR_ADVANCED.get() );
getOrCreateTagBuilder( PIGLIN_LOVED ).add(
Registry.ModItems.COMPUTER_ADVANCED.get(), Registry.ModItems.TURTLE_ADVANCED.get(),
Registry.ModItems.WIRELESS_MODEM_ADVANCED.get(), Registry.ModItems.POCKET_COMPUTER_ADVANCED.get(),
Registry.ModItems.MONITOR_ADVANCED.get()
);
}
private static Tag.Identified<Item> item( String name )
{
return ItemTags.register( new Identifier( ComputerCraft.MOD_ID, name ).toString() );
}
}

View File

@@ -1,13 +0,0 @@
package dan200.computercraft.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
@Mixin (BlockEntityType.class)
public interface BlockEntityTypeAccessor {
@Invoker
static <T extends BlockEntity> BlockEntityType<T> callCreate(String string, BlockEntityType.Builder<T> builder) { throw new UnsupportedOperationException(); }
}

View File

@@ -1,13 +0,0 @@
package dan200.computercraft.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerType;
@Mixin (ScreenHandlerType.class)
public interface ScreenHandlerTypeAccessor {
@Invoker
static <T extends ScreenHandler> ScreenHandlerType<T> callRegister(String id, ScreenHandlerType.Factory<T> factory) { throw new UnsupportedOperationException(); }
}

View File

@@ -22,10 +22,6 @@ import dan200.computercraft.shared.computer.items.ItemComputer;
import dan200.computercraft.shared.media.items.ItemDisk;
import dan200.computercraft.shared.media.items.ItemPrintout;
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
import dan200.computercraft.shared.network.container.ComputerContainerData;
import dan200.computercraft.shared.network.container.ContainerData;
import dan200.computercraft.shared.network.container.HeldItemContainerData;
import dan200.computercraft.shared.network.container.ViewComputerContainerData;
import dan200.computercraft.shared.peripheral.diskdrive.BlockDiskDrive;
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
@@ -50,9 +46,9 @@ import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import dan200.computercraft.shared.turtle.items.ItemTurtle;
import dan200.computercraft.shared.util.CreativeTabMain;
import dan200.computercraft.shared.util.FixedPointTileEntityType;
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntity;
@@ -66,7 +62,7 @@ import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.util.Identifier;
public final class Registry {
public final class ComputerCraftRegistry {
public static final String MOD_ID = ComputerCraft.MOD_ID;
public static void init() {
@@ -125,10 +121,10 @@ public final class Registry {
"monitor_advanced",
new BlockMonitor(properties(), ModTiles.MONITOR_ADVANCED));
public static final BlockWirelessModem WIRELESS_EM_NORMAL = net.minecraft.util.registry.Registry.register(net.minecraft.util.registry.Registry.BLOCK,
public static final BlockWirelessModem WIRELESS_MODEM_NORMAL = net.minecraft.util.registry.Registry.register(net.minecraft.util.registry.Registry.BLOCK,
"wireless_em_normal",
new BlockWirelessModem(properties(), ModTiles.WIRELESS_MODEM_NORMAL));
public static final BlockWirelessModem WIRELESS_EM_ADVANCED = net.minecraft.util.registry.Registry.register(net.minecraft.util.registry.Registry.BLOCK,
public static final BlockWirelessModem WIRELESS_MODEM_ADVANCED = net.minecraft.util.registry.Registry.register(net.minecraft.util.registry.Registry.BLOCK,
"wireless_em_advanced",
new BlockWirelessModem(properties(),
ModTiles.WIRELESS_MODEM_ADVANCED));
@@ -164,13 +160,13 @@ public final class Registry {
public static final BlockEntityType<TileWiredModemFull> WIRED_MODEM_FULL = ofBlock(ModBlocks.WIRED_MODEM_FULL, TileWiredModemFull::new);
public static final BlockEntityType<TileCable> CABLE = ofBlock(ModBlocks.CABLE, TileCable::new);
public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_NORMAL = ofBlock(ModBlocks.WIRELESS_EM_NORMAL, f -> new TileWirelessModem(f,
public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_NORMAL = ofBlock(ModBlocks.WIRELESS_MODEM_NORMAL, f -> new TileWirelessModem(f,
false));
public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_ADVANCED = ofBlock(ModBlocks.WIRELESS_EM_ADVANCED, f -> new TileWirelessModem(f, true));
public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_ADVANCED = ofBlock(ModBlocks.WIRELESS_MODEM_ADVANCED, f -> new TileWirelessModem(f, true));
}
public static final class ModItems {
private static final ItemGroup mainItemGroup = new CreativeTabMain();
private static final ItemGroup mainItemGroup = ComputerCraft.MAIN_GROUP;
private static Item.Settings properties() {
return new Item.Settings().group(mainItemGroup);
@@ -210,12 +206,12 @@ public final class Registry {
public static final BlockItem PRINTER = ofBlock(ModBlocks.PRINTER, BlockItem::new);
public static final BlockItem MONITOR_NORMAL = ofBlock(ModBlocks.MONITOR_NORMAL, BlockItem::new);
public static final BlockItem MONITOR_ADVANCED = ofBlock(ModBlocks.MONITOR_ADVANCED, BlockItem::new);
public static final BlockItem WIRELESS_EM_NORMAL = ofBlock(ModBlocks.WIRELESS_EM_NORMAL, BlockItem::new);
public static final BlockItem WIRELESS_EM_ADVANCED = ofBlock(ModBlocks.WIRELESS_EM_ADVANCED, BlockItem::new);
public static final BlockItem WIRED_EM_FULL = ofBlock(ModBlocks.WIRED_MODEM_FULL, BlockItem::new);
public static final BlockItem WIRELESS_MODEM_NORMAL = ofBlock(ModBlocks.WIRELESS_MODEM_NORMAL, BlockItem::new);
public static final BlockItem WIRELESS_MODEM_ADVANCED = ofBlock(ModBlocks.WIRELESS_MODEM_ADVANCED, BlockItem::new);
public static final BlockItem WIRED_MODEM_FULL = ofBlock(ModBlocks.WIRED_MODEM_FULL, BlockItem::new);
public static final ItemBlockCable.Cable CABLE = register("cable", new ItemBlockCable.Cable(ModBlocks.CABLE, properties()));
public static final ItemBlockCable.WiredModem WIRED_EM = register("wired_em", new ItemBlockCable.WiredModem(ModBlocks.CABLE, properties()));
public static final ItemBlockCable.WiredModem WIRED_MODEM = register("wired_em", new ItemBlockCable.WiredModem(ModBlocks.CABLE, properties()));
}
public static class ModEntities {
@@ -230,34 +226,27 @@ public final class Registry {
}
public static class ModContainers {
private static <B extends ScreenHandler, T extends ScreenHandlerType<B>> T register(String id, T item) {
return net.minecraft.util.registry.Registry.register(net.minecraft.util.registry.Registry.SCREEN_HANDLER, new Identifier(MOD_ID, id), item);
private static <T extends ScreenHandler> ScreenHandlerType<T> registerSimple(String id, ScreenHandlerRegistry.SimpleClientHandlerFactory<T> function) {
return ScreenHandlerRegistry.registerSimple(new Identifier(MOD_ID, id), function);
}
public static final ScreenHandlerType<ContainerComputer> COMPUTER = register("computer",
ContainerData.toType(ComputerContainerData::new,
ContainerComputer::new));
private static <T extends ScreenHandler> ScreenHandlerType<T> registerExtended(String id, ScreenHandlerRegistry.ExtendedClientHandlerFactory<T> function) {
return ScreenHandlerRegistry.registerExtended(new Identifier(MOD_ID, id), function);
}
public static final ScreenHandlerType<ContainerPocketComputer> POCKET_COMPUTER = register("pocket_computer",
ContainerData.toType(ComputerContainerData::new,
ContainerPocketComputer::new));
public static final ScreenHandlerType<ContainerComputer> COMPUTER = registerExtended("computer", ContainerComputer::new);
public static final ScreenHandlerType<ContainerTurtle> TURTLE = register("turtle",
ContainerData.toType(ComputerContainerData::new,
ContainerTurtle::new));
public static final ScreenHandlerType<ContainerPocketComputer> POCKET_COMPUTER = registerExtended("pocket_computer", ContainerPocketComputer::new);
public static final ScreenHandlerType<ContainerTurtle> TURTLE = registerExtended("turtle", ContainerTurtle::new);
public static final ScreenHandlerType<ContainerDiskDrive> DISK_DRIVE = register("disk_drive",
new ScreenHandlerType<>(ContainerDiskDrive::new));
public static final ScreenHandlerType<ContainerDiskDrive> DISK_DRIVE = registerSimple("disk_drive", ContainerDiskDrive::new);
public static final ScreenHandlerType<ContainerPrinter> PRINTER = register("printer", new ScreenHandlerType<>(ContainerPrinter::new));
public static final ScreenHandlerType<ContainerPrinter> PRINTER = registerSimple("printer", ContainerPrinter::new);
public static final ScreenHandlerType<ContainerHeldItem> PRINTOUT = register("printout",
ContainerData.toType(HeldItemContainerData::new,
ContainerHeldItem::createPrintout));
public static final ScreenHandlerType<ContainerHeldItem> PRINTOUT = registerExtended("printout", ContainerHeldItem::createPrintout);
public static final ScreenHandlerType<ContainerViewComputer> VIEW_COMPUTER = register("view_computer",
ContainerData.toType(ViewComputerContainerData::new,
ContainerViewComputer::new));
public static final ScreenHandlerType<ContainerViewComputer> VIEW_COMPUTER = registerExtended("view_computer", ContainerViewComputer::new);
}
}

View File

@@ -1,421 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared;
import com.electronwill.nightconfig.core.CommentedConfig;
import com.electronwill.nightconfig.core.UnmodifiableConfig;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.google.common.base.CaseFormat;
import com.google.common.base.Converter;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.http.options.Action;
import dan200.computercraft.core.apis.http.options.AddressRuleConfig;
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.common.ForgeConfigSpec.Builder;
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static net.minecraftforge.common.ForgeConfigSpec.Builder;
import static net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD )
public final class Config
{
private static final int MODEM_MAX_RANGE = 100000;
private static final String TRANSLATION_PREFIX = "gui.computercraft.config.";
private static final ConfigValue<Integer> computerSpaceLimit;
private static final ConfigValue<Integer> floppySpaceLimit;
private static final ConfigValue<Integer> maximumFilesOpen;
private static final ConfigValue<Boolean> disableLua51Features;
private static final ConfigValue<String> defaultComputerSettings;
private static final ConfigValue<Boolean> debugEnabled;
private static final ConfigValue<Boolean> logComputerErrors;
private static final ConfigValue<Boolean> commandRequireCreative;
private static final ConfigValue<Integer> computerThreads;
private static final ConfigValue<Integer> maxMainGlobalTime;
private static final ConfigValue<Integer> maxMainComputerTime;
private static final ConfigValue<Boolean> httpEnabled;
private static final ConfigValue<Boolean> httpWebsocketEnabled;
private static final ConfigValue<List<? extends UnmodifiableConfig>> httpRules;
private static final ConfigValue<Integer> httpMaxRequests;
private static final ConfigValue<Integer> httpMaxWebsockets;
private static final ConfigValue<Boolean> commandBlockEnabled;
private static final ConfigValue<Integer> modemRange;
private static final ConfigValue<Integer> modemHighAltitudeRange;
private static final ConfigValue<Integer> modemRangeDuringStorm;
private static final ConfigValue<Integer> modemHighAltitudeRangeDuringStorm;
private static final ConfigValue<Integer> maxNotesPerTick;
private static final ConfigValue<Integer> monitorBandwidth;
private static final ConfigValue<Boolean> turtlesNeedFuel;
private static final ConfigValue<Integer> turtleFuelLimit;
private static final ConfigValue<Integer> advancedTurtleFuelLimit;
private static final ConfigValue<Boolean> turtlesObeyBlockProtection;
private static final ConfigValue<Boolean> turtlesCanPush;
private static final ConfigValue<List<? extends String>> turtleDisabledActions;
private static final ConfigValue<Integer> computerTermWidth;
private static final ConfigValue<Integer> computerTermHeight;
private static final ConfigValue<Integer> pocketTermWidth;
private static final ConfigValue<Integer> pocketTermHeight;
private static final ConfigValue<Integer> monitorWidth;
private static final ConfigValue<Integer> monitorHeight;
private static final ConfigValue<Boolean> genericPeripheral;
private static final ConfigValue<MonitorRenderer> monitorRenderer;
private static final ConfigValue<Integer> monitorDistance;
private static final ForgeConfigSpec serverSpec;
private static final ForgeConfigSpec clientSpec;
private Config() {}
static
{
Builder builder = new Builder();
{ // General computers
computerSpaceLimit = builder
.comment( "The disk space limit for computers and turtles, in bytes" )
.translation( TRANSLATION_PREFIX + "computer_space_limit" )
.define( "computer_space_limit", ComputerCraft.computerSpaceLimit );
floppySpaceLimit = builder
.comment( "The disk space limit for floppy disks, in bytes" )
.translation( TRANSLATION_PREFIX + "floppy_space_limit" )
.define( "floppy_space_limit", ComputerCraft.floppySpaceLimit );
maximumFilesOpen = builder
.comment( "Set how many files a computer can have open at the same time. Set to 0 for unlimited." )
.translation( TRANSLATION_PREFIX + "maximum_open_files" )
.defineInRange( "maximum_open_files", ComputerCraft.maximumFilesOpen, 0, Integer.MAX_VALUE );
disableLua51Features = builder
.comment( "Set this to true to disable Lua 5.1 functions that will be removed in a future update. " +
"Useful for ensuring forward compatibility of your programs now." )
.define( "disable_lua51_features", ComputerCraft.disableLua51Features );
defaultComputerSettings = builder
.comment( "A comma separated list of default system settings to set on new computers. Example: " +
"\"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\" will disable all " +
"autocompletion" )
.define( "default_computer_settings", ComputerCraft.defaultComputerSettings );
debugEnabled = builder
.comment( "Enable Lua's debug library. This is sandboxed to each computer, so is generally safe to be used by players." )
.define( "debug_enabled", ComputerCraft.debugEnable );
logComputerErrors = builder
.comment( "Log exceptions thrown by peripherals and other Lua objects.\n" +
"This makes it easier for mod authors to debug problems, but may result in log spam should people use buggy methods." )
.define( "log_computer_errors", ComputerCraft.logComputerErrors );
commandRequireCreative = builder
.comment( "Require players to be in creative mode and be opped in order to interact with command computers." +
"This is the default behaviour for vanilla's Command blocks." )
.define( "command_require_creative", ComputerCraft.commandRequireCreative );
}
{
builder.comment( "Controls execution behaviour of computers. This is largely intended for fine-tuning " +
"servers, and generally shouldn't need to be touched" );
builder.push( "execution" );
computerThreads = builder
.comment( "Set the number of threads computers can run on. A higher number means more computers can run " +
"at once, but may induce lag.\n" +
"Please note that some mods may not work with a thread count higher than 1. Use with caution." )
.worldRestart()
.defineInRange( "computer_threads", ComputerCraft.computerThreads, 1, Integer.MAX_VALUE );
maxMainGlobalTime = builder
.comment( "The maximum time that can be spent executing tasks in a single tick, in milliseconds.\n" +
"Note, we will quite possibly go over this limit, as there's no way to tell how long a will take " +
"- this aims to be the upper bound of the average time." )
.defineInRange( "max_main_global_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainGlobalTime ), 1, Integer.MAX_VALUE );
maxMainComputerTime = builder
.comment( "The ideal maximum time a computer can execute for in a tick, in milliseconds.\n" +
"Note, we will quite possibly go over this limit, as there's no way to tell how long a will take " +
"- this aims to be the upper bound of the average time." )
.defineInRange( "max_main_computer_time", (int) TimeUnit.NANOSECONDS.toMillis( ComputerCraft.maxMainComputerTime ), 1, Integer.MAX_VALUE );
builder.pop();
}
{ // HTTP
builder.comment( "Controls the HTTP API" );
builder.push( "http" );
httpEnabled = builder
.comment( "Enable the \"http\" API on Computers (see \"rules\" for more fine grained control than this)." )
.define( "enabled", ComputerCraft.httpEnabled );
httpWebsocketEnabled = builder
.comment( "Enable use of http websockets. This requires the \"http_enable\" option to also be true." )
.define( "websocket_enabled", ComputerCraft.httpWebsocketEnabled );
httpRules = builder
.comment( "A list of rules which control behaviour of the \"http\" API for specific domains or IPs.\n" +
"Each rule is an item with a 'host' to match against, and a series of properties. " +
"The host may be a domain name (\"pastebin.com\"),\n" +
"wildcard (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\"). If no rules, the domain is blocked." )
.defineList( "rules",
Stream.concat(
Stream.of( ComputerCraft.DEFAULT_HTTP_DENY ).map( x -> AddressRuleConfig.makeRule( x, Action.DENY ) ),
Stream.of( ComputerCraft.DEFAULT_HTTP_ALLOW ).map( x -> AddressRuleConfig.makeRule( x, Action.ALLOW ) )
).collect( Collectors.toList() ),
x -> x instanceof UnmodifiableConfig && AddressRuleConfig.checkRule( (UnmodifiableConfig) x ) );
httpMaxRequests = builder
.comment( "The number of http requests a computer can make at one time. Additional requests will be queued, and sent when the running requests have finished. Set to 0 for unlimited." )
.defineInRange( "max_requests", ComputerCraft.httpMaxRequests, 0, Integer.MAX_VALUE );
httpMaxWebsockets = builder
.comment( "The number of websockets a computer can have open at one time. Set to 0 for unlimited." )
.defineInRange( "max_websockets", ComputerCraft.httpMaxWebsockets, 1, Integer.MAX_VALUE );
builder.pop();
}
{ // Peripherals
builder.comment( "Various options relating to peripherals." );
builder.push( "peripheral" );
commandBlockEnabled = builder
.comment( "Enable Command Block peripheral support" )
.define( "command_block_enabled", ComputerCraft.enableCommandBlock );
modemRange = builder
.comment( "The range of Wireless Modems at low altitude in clear weather, in meters" )
.defineInRange( "modem_range", ComputerCraft.modemRange, 0, MODEM_MAX_RANGE );
modemHighAltitudeRange = builder
.comment( "The range of Wireless Modems at maximum altitude in clear weather, in meters" )
.defineInRange( "modem_high_altitude_range", ComputerCraft.modemHighAltitudeRange, 0, MODEM_MAX_RANGE );
modemRangeDuringStorm = builder
.comment( "The range of Wireless Modems at low altitude in stormy weather, in meters" )
.defineInRange( "modem_range_during_storm", ComputerCraft.modemRangeDuringStorm, 0, MODEM_MAX_RANGE );
modemHighAltitudeRangeDuringStorm = builder
.comment( "The range of Wireless Modems at maximum altitude in stormy weather, in meters" )
.defineInRange( "modem_high_altitude_range_during_storm", ComputerCraft.modemHighAltitudeRangeDuringStorm, 0, MODEM_MAX_RANGE );
maxNotesPerTick = builder
.comment( "Maximum amount of notes a speaker can play at once" )
.defineInRange( "max_notes_per_tick", ComputerCraft.maxNotesPerTick, 1, Integer.MAX_VALUE );
monitorBandwidth = builder
.comment( "The limit to how much monitor data can be sent *per tick*. Note:\n" +
" - Bandwidth is measured before compression, so the data sent to the client is smaller.\n" +
" - This ignores the number of players a packet is sent to. Updating a monitor for one player consumes " +
"the same bandwidth limit as sending to 20.\n" +
" - A full sized monitor sends ~25kb of data. So the default (1MB) allows for ~40 monitors to be updated " +
"in a single tick. \n" +
"Set to 0 to disable." )
.defineInRange( "monitor_bandwidth", (int) ComputerCraft.monitorBandwidth, 0, Integer.MAX_VALUE );
builder.pop();
}
{ // Turtles
builder.comment( "Various options relating to turtles." );
builder.push( "turtle" );
turtlesNeedFuel = builder
.comment( "Set whether Turtles require fuel to move" )
.define( "need_fuel", ComputerCraft.turtlesNeedFuel );
turtleFuelLimit = builder
.comment( "The fuel limit for Turtles" )
.defineInRange( "normal_fuel_limit", ComputerCraft.turtleFuelLimit, 0, Integer.MAX_VALUE );
advancedTurtleFuelLimit = builder
.comment( "The fuel limit for Advanced Turtles" )
.defineInRange( "advanced_fuel_limit", ComputerCraft.advancedTurtleFuelLimit, 0, Integer.MAX_VALUE );
turtlesObeyBlockProtection = builder
.comment( "If set to true, Turtles will be unable to build, dig, or enter protected areas (such as near the server spawn point)" )
.define( "obey_block_protection", ComputerCraft.turtlesObeyBlockProtection );
turtlesCanPush = builder
.comment( "If set to true, Turtles will push entities out of the way instead of stopping if there is space to do so" )
.define( "can_push", ComputerCraft.turtlesCanPush );
turtleDisabledActions = builder
.comment( "A list of turtle actions which are disabled." )
.defineList( "disabled_actions", Collections.emptyList(), x -> x instanceof String && getAction( (String) x ) != null );
builder.pop();
}
{
builder.comment( "Configure the size of various computer's terminals.\n" +
"Larger terminals require more bandwidth, so use with care." ).push( "term_sizes" );
builder.comment( "Terminal size of computers" ).push( "computer" );
computerTermWidth = builder.defineInRange( "width", ComputerCraft.computerTermWidth, 1, 255 );
computerTermHeight = builder.defineInRange( "height", ComputerCraft.computerTermHeight, 1, 255 );
builder.pop();
builder.comment( "Terminal size of pocket computers" ).push( "pocket_computer" );
pocketTermWidth = builder.defineInRange( "width", ComputerCraft.pocketTermWidth, 1, 255 );
pocketTermHeight = builder.defineInRange( "height", ComputerCraft.pocketTermHeight, 1, 255 );
builder.pop();
builder.comment( "Maximum size of monitors (in blocks)" ).push( "monitor" );
monitorWidth = builder.defineInRange( "width", ComputerCraft.monitorWidth, 1, 32 );
monitorHeight = builder.defineInRange( "height", ComputerCraft.monitorHeight, 1, 32 );
builder.pop();
builder.pop();
}
{
builder.comment( "Options for various experimental features. These are not guaranteed to be stable, and may change or be removed across versions." );
builder.push( "experimental" );
genericPeripheral = builder
.comment( "Attempt to make any existing block (or tile entity) a peripheral.\n" +
"This provides peripheral methods for any inventory, fluid tank or energy storage block. It will" +
"_not_ provide methods which have an existing peripheral provider." )
.define( "generic_peripherals", false );
}
serverSpec = builder.build();
Builder clientBuilder = new Builder();
monitorRenderer = clientBuilder
.comment( "The renderer to use for monitors. Generally this should be kept at \"best\" - if " +
"monitors have performance issues, you may wish to experiment with alternative renderers." )
.defineEnum( "monitor_renderer", MonitorRenderer.BEST );
monitorDistance = clientBuilder
.comment( "The maximum distance monitors will render at. This defaults to the standard tile entity limit, " +
"but may be extended if you wish to build larger monitors." )
.defineInRange( "monitor_distance", 64, 16, 1024 );
clientSpec = clientBuilder.build();
}
public static void setup()
{
ModLoadingContext.get().registerConfig( ModConfig.Type.SERVER, serverSpec );
ModLoadingContext.get().registerConfig( ModConfig.Type.CLIENT, clientSpec );
}
public static void sync()
{
// General
ComputerCraft.computerSpaceLimit = computerSpaceLimit.get();
ComputerCraft.floppySpaceLimit = floppySpaceLimit.get();
ComputerCraft.maximumFilesOpen = maximumFilesOpen.get();
ComputerCraft.disableLua51Features = disableLua51Features.get();
ComputerCraft.defaultComputerSettings = defaultComputerSettings.get();
ComputerCraft.debugEnable = debugEnabled.get();
ComputerCraft.computerThreads = computerThreads.get();
ComputerCraft.logComputerErrors = logComputerErrors.get();
ComputerCraft.commandRequireCreative = commandRequireCreative.get();
// Execution
ComputerCraft.computerThreads = computerThreads.get();
ComputerCraft.maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos( maxMainGlobalTime.get() );
ComputerCraft.maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos( maxMainComputerTime.get() );
// HTTP
ComputerCraft.httpEnabled = httpEnabled.get();
ComputerCraft.httpWebsocketEnabled = httpWebsocketEnabled.get();
ComputerCraft.httpRules = Collections.unmodifiableList( httpRules.get().stream()
.map( AddressRuleConfig::parseRule ).filter( Objects::nonNull ).collect( Collectors.toList() ) );
ComputerCraft.httpMaxRequests = httpMaxRequests.get();
ComputerCraft.httpMaxWebsockets = httpMaxWebsockets.get();
// Peripheral
ComputerCraft.enableCommandBlock = commandBlockEnabled.get();
ComputerCraft.maxNotesPerTick = maxNotesPerTick.get();
ComputerCraft.modemRange = modemRange.get();
ComputerCraft.modemHighAltitudeRange = modemHighAltitudeRange.get();
ComputerCraft.modemRangeDuringStorm = modemRangeDuringStorm.get();
ComputerCraft.modemHighAltitudeRangeDuringStorm = modemHighAltitudeRangeDuringStorm.get();
ComputerCraft.monitorBandwidth = monitorBandwidth.get();
// Turtles
ComputerCraft.turtlesNeedFuel = turtlesNeedFuel.get();
ComputerCraft.turtleFuelLimit = turtleFuelLimit.get();
ComputerCraft.advancedTurtleFuelLimit = advancedTurtleFuelLimit.get();
ComputerCraft.turtlesObeyBlockProtection = turtlesObeyBlockProtection.get();
ComputerCraft.turtlesCanPush = turtlesCanPush.get();
ComputerCraft.turtleDisabledActions.clear();
for( String value : turtleDisabledActions.get() ) ComputerCraft.turtleDisabledActions.add( getAction( value ) );
// Terminal size
ComputerCraft.computerTermWidth = computerTermWidth.get();
ComputerCraft.computerTermHeight = computerTermHeight.get();
ComputerCraft.pocketTermWidth = pocketTermWidth.get();
ComputerCraft.pocketTermHeight = pocketTermHeight.get();
ComputerCraft.monitorWidth = monitorWidth.get();
ComputerCraft.monitorHeight = monitorHeight.get();
// Experimental
ComputerCraft.genericPeripheral = genericPeripheral.get();
// Client
ComputerCraft.monitorRenderer = monitorRenderer.get();
ComputerCraft.monitorDistanceSq = monitorDistance.get() * monitorDistance.get();
}
@SubscribeEvent
public static void sync( ModConfig.Loading event )
{
sync();
}
@SubscribeEvent
public static void sync( ModConfig.Reloading event )
{
// Ensure file configs are reloaded. Forge should probably do this, so worth checking in the future.
CommentedConfig config = event.getConfig().getConfigData();
if( config instanceof CommentedFileConfig ) ((CommentedFileConfig) config).load();
sync();
}
private static final Converter<String, String> converter = CaseFormat.LOWER_CAMEL.converterTo( CaseFormat.UPPER_UNDERSCORE );
private static TurtleAction getAction( String value )
{
try
{
return TurtleAction.valueOf( converter.convert( value ) );
}
catch( IllegalArgumentException e )
{
return null;
}
}
}

View File

@@ -3,53 +3,56 @@
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
import dan200.computercraft.shared.util.CapabilityUtil;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
public final class Peripherals {
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Objects;
public final class Peripherals
{
private static final Collection<IPeripheralProvider> providers = new LinkedHashSet<>();
private Peripherals() {}
public static synchronized void register(@Nonnull IPeripheralProvider provider) {
Objects.requireNonNull(provider, "provider cannot be null");
providers.add(provider);
public static synchronized void register( @Nonnull IPeripheralProvider provider )
{
Objects.requireNonNull( provider, "provider cannot be null" );
providers.add( provider );
}
@Nullable
public static IPeripheral getPeripheral(World world, BlockPos pos, Direction side) {
return World.method_24794(pos) && !world.isClient ? getPeripheralAt(world, pos, side) : null;
public static IPeripheral getPeripheral( World world, BlockPos pos, Direction side )
{
return World.method_24794( pos ) && !world.isClient ? getPeripheralAt( world, pos, side ) : null;
}
@Nullable
private static IPeripheral getPeripheralAt(World world, BlockPos pos, Direction side) {
private static IPeripheral getPeripheralAt( World world, BlockPos pos, Direction side )
{
BlockEntity block = world.getBlockEntity( pos );
// Try the handlers in order:
for (IPeripheralProvider peripheralProvider : providers) {
try {
Optional<IPeripheral> peripheral = peripheralProvider.getPeripheral(world, pos, side);
if (peripheral.isPresent()) {
return peripheral.get();
}
} catch (Exception e) {
ComputerCraft.log.error("Peripheral provider " + peripheralProvider + " errored.", e);
for( IPeripheralProvider peripheralProvider : providers )
{
try
{
IPeripheral peripheral = peripheralProvider.getPeripheral( world, pos, side );
if( peripheral != null ) return peripheral;
}
catch( Exception e )
{
ComputerCraft.log.error( "Peripheral provider " + peripheralProvider + " errored.", e );
}
}

View File

@@ -9,8 +9,6 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.shared.util.InventoryUtil;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModLoadingContext;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -35,9 +33,6 @@ public final class PocketUpgrades
}
upgrades.put( id, upgrade );
ModContainer mc = ModLoadingContext.get().getActiveContainer();
if( mc != null && mc.getModId() != null ) upgradeOwners.put( upgrade, mc.getModId() );
}
public static IPocketUpgrade get( String id )

View File

@@ -5,6 +5,7 @@
*/
package dan200.computercraft.shared;
import com.google.common.eventbus.Subscribe;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.turtle.event.TurtleActionEvent;
import net.minecraft.entity.player.PlayerEntity;
@@ -12,10 +13,7 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID )
public final class TurtlePermissions
{
public static boolean isBlockEnterable( World world, BlockPos pos, PlayerEntity player )
@@ -29,12 +27,10 @@ public final class TurtlePermissions
return isBlockEnterable( world, pos, player );
}
@SubscribeEvent
public static void onTurtleAction( TurtleActionEvent event )
{
if( ComputerCraft.turtleDisabledActions.contains( event.getAction() ) )
{
event.setCanceled( true, "Action has been disabled" );
@Subscribe
public void onTurtleAction(TurtleActionEvent event) {
if (ComputerCraft.turtleDisabledActions.contains(event.getAction())) {
event.setCanceled(true, "Action has been disabled");
}
}
}

View File

@@ -9,8 +9,8 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.util.InventoryUtil;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.ModLoadingContext;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -30,7 +30,8 @@ public final class TurtleUpgrades
{
this.upgrade = upgrade;
this.id = upgrade.getUpgradeID().toString();
this.modId = ModLoadingContext.get().getActiveNamespace();
// TODO This should be the mod id of the mod the peripheral comes from
this.modId = ComputerCraft.MOD_ID;
this.enabled = true;
}
}

View File

@@ -59,11 +59,11 @@ public final class CommandComputerCraft
private static final int DUMP_SINGLE_ID = 1844510720;
private static final int TRACK_ID = 373882880;
private CommandComputerCraft()
public CommandComputerCraft()
{
}
public static void register( CommandDispatcher<ServerCommandSource> dispatcher )
public static void register( CommandDispatcher<ServerCommandSource> dispatcher, boolean bool )
{
dispatcher.register( choice( "computercraft" )
.then( literal( "dump" )
@@ -127,7 +127,7 @@ public final class CommandComputerCraft
IPeripheral peripheral = computer.getPeripheral( side );
if( peripheral != null )
{
table.row( header( "Peripheral " + side.getName() ), text( peripheral.getType0() ) );
table.row( header( "Peripheral " + side.getName() ), text( peripheral.getType() ) );
}
}

View File

@@ -7,7 +7,8 @@ package dan200.computercraft.shared.command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import dan200.computercraft.ComputerCraft;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.ClickEvent;
@@ -16,15 +17,11 @@ import net.minecraft.text.LiteralText;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ClientChatEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal;
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
@Environment(EnvType.CLIENT)
public final class CommandCopy
{
private static final String PREFIX = "/computercraft copy ";
@@ -45,15 +42,15 @@ public final class CommandCopy
);
}
@SubscribeEvent
public static void onClientSendMessage( ClientChatEvent event )
public static boolean onClientSendMessage( String message )
{
// Emulate the command on the client side
if( event.getMessage().startsWith( PREFIX ) )
if( message.startsWith( PREFIX ) )
{
MinecraftClient.getInstance().keyboard.setClipboard( event.getMessage().substring( PREFIX.length() ) );
event.setCanceled( true );
MinecraftClient.getInstance().keyboard.setClipboard( message.substring( PREFIX.length() ) );
return true;
}
return false;
}
public static Text createCopyText( String text )

View File

@@ -8,11 +8,11 @@ package dan200.computercraft.shared.command;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import dan200.computercraft.api.turtle.FakePlayer;
import net.minecraft.entity.Entity;
import net.minecraft.server.command.CommandSource;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraftforge.common.util.FakePlayer;
import java.util.Arrays;
import java.util.Locale;

View File

@@ -174,7 +174,7 @@ public final class ComputersArgumentType implements ArgumentType<ComputersArgume
{
@Override
public void write( @Nonnull ComputersArgumentType arg, @Nonnull PacketByteBuf buf )
public void toPacket( @Nonnull ComputersArgumentType arg, @Nonnull PacketByteBuf buf )
{
buf.writeBoolean( arg.requireSome );
}
@@ -187,7 +187,7 @@ public final class ComputersArgumentType implements ArgumentType<ComputersArgume
}
@Override
public void write( @Nonnull ComputersArgumentType arg, @Nonnull JsonObject json )
public void toJson( @Nonnull ComputersArgumentType arg, @Nonnull JsonObject json )
{
json.addProperty( "requireSome", arg.requireSome );
}

View File

@@ -127,7 +127,7 @@ public final class RepeatArgumentType<T, U> implements ArgumentType<List<T>>
public static class Serializer implements ArgumentSerializer<RepeatArgumentType<?, ?>>
{
@Override
public void write( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull PacketByteBuf buf )
public void toPacket( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull PacketByteBuf buf )
{
buf.writeBoolean( arg.flatten );
ArgumentTypes.toPacket( buf, arg.child );
@@ -147,7 +147,7 @@ public final class RepeatArgumentType<T, U> implements ArgumentType<List<T>>
}
@Override
public void write( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull JsonObject json )
public void toJson( @Nonnull RepeatArgumentType<?, ?> arg, @Nonnull JsonObject json )
{
json.addProperty( "flatten", arg.flatten );
json.addProperty( "child", "<<cannot serialize>>" ); // TODO: Potentially serialize this using reflection.

View File

@@ -6,7 +6,9 @@
package dan200.computercraft.shared.common;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.BlockWithEntity;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.player.PlayerEntity;
@@ -15,16 +17,17 @@ import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.WorldView;
import net.minecraftforge.fml.RegistryObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Random;
public abstract class BlockGeneric extends Block
public abstract class BlockGeneric extends BlockWithEntity
{
private final BlockEntityType<? extends TileGeneric> type;
@@ -63,13 +66,6 @@ public abstract class BlockGeneric extends Block
if( tile instanceof TileGeneric ) ((TileGeneric) tile).onNeighbourChange( neighbourPos );
}
@Override
public final void onNeighborChange( BlockState state, WorldView world, BlockPos pos, BlockPos neighbour )
{
BlockEntity tile = world.getBlockEntity( pos );
if( tile instanceof TileGeneric ) ((TileGeneric) tile).onNeighbourTileEntityChange( neighbour );
}
@Override
@Deprecated
public void scheduledTick( @Nonnull BlockState state, ServerWorld world, @Nonnull BlockPos pos, @Nonnull Random rand )
@@ -78,22 +74,10 @@ public abstract class BlockGeneric extends Block
if( te instanceof TileGeneric ) ((TileGeneric) te).blockTick();
}
@Override
public boolean hasTileEntity( BlockState state )
{
return true;
}
@Nullable
@Override
public BlockEntity createTileEntity( @Nonnull BlockState state, @Nonnull BlockView world )
public BlockEntity createBlockEntity(@Nonnull BlockView world )
{
return type.get().instantiate();
}
@Override
public boolean canBeReplacedByLeaves( BlockState state, WorldView world, BlockPos pos )
{
return false;
return type.instantiate();
}
}

View File

@@ -56,7 +56,7 @@ public final class ColourableRecipe extends SpecialCraftingRecipe
@Nonnull
@Override
public ItemStack getCraftingResult( @Nonnull CraftingInventory inv )
public ItemStack craft( @Nonnull CraftingInventory inv )
{
ItemStack colourable = ItemStack.EMPTY;

View File

@@ -5,14 +5,17 @@
*/
package dan200.computercraft.shared.common;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.network.container.HeldItemContainerData;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Hand;
import javax.annotation.Nonnull;
@@ -31,9 +34,14 @@ public class ContainerHeldItem extends ScreenHandler
stack = player.getStackInHand( hand ).copy();
}
public static ContainerHeldItem createPrintout( int id, PlayerInventory inventory, PacketByteBuf data )
{
return createPrintout(id, inventory, new HeldItemContainerData(data));
}
public static ContainerHeldItem createPrintout( int id, PlayerInventory inventory, HeldItemContainerData data )
{
return new ContainerHeldItem( Registry.ModContainers.PRINTOUT.get(), id, inventory.player, data.getHand() );
return new ContainerHeldItem( ComputerCraftRegistry.ModContainers.PRINTOUT, id, inventory.player, data.getHand() );
}
@Nonnull
@@ -51,7 +59,7 @@ public class ContainerHeldItem extends ScreenHandler
return stack == this.stack || !stack.isEmpty() && !this.stack.isEmpty() && stack.getItem() == this.stack.getItem();
}
public static class Factory implements NamedScreenHandlerFactory
public static class Factory implements NamedScreenHandlerFactory, ExtendedScreenHandlerFactory
{
private final ScreenHandlerType<ContainerHeldItem> type;
private final Text name;
@@ -77,5 +85,10 @@ public class ContainerHeldItem extends ScreenHandler
{
return new ContainerHeldItem( type, id, player, hand );
}
@Override
public void writeScreenOpeningData(ServerPlayerEntity serverPlayerEntity, PacketByteBuf packetByteBuf) {
packetByteBuf.writeEnumConstant(hand);
}
}
}

View File

@@ -5,6 +5,7 @@
*/
package dan200.computercraft.shared.common;
import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
@@ -18,7 +19,7 @@ import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nonnull;
public abstract class TileGeneric extends BlockEntity
public abstract class TileGeneric extends BlockEntity implements BlockEntityClientSerializable
{
public TileGeneric( BlockEntityType<? extends TileGeneric> type )
{
@@ -89,9 +90,14 @@ public abstract class TileGeneric extends BlockEntity
}
@Override
public final void onDataPacket( ClientConnection net, BlockEntityUpdateS2CPacket packet )
{
if( packet.getBlockEntityType() == 0 ) readDescription( packet.getCompoundTag() );
public CompoundTag toClientTag(CompoundTag compoundTag) {
writeDescription(compoundTag);
return compoundTag;
}
@Override
public void fromClientTag(CompoundTag compoundTag) {
readDescription(compoundTag);
}
@Nonnull
@@ -102,11 +108,4 @@ public abstract class TileGeneric extends BlockEntity
writeDescription( tag );
return tag;
}
@Override
public void handleUpdateTag( @Nonnull BlockState state, @Nonnull CompoundTag tag )
{
super.handleUpdateTag( state, tag );
readDescription( tag );
}
}

View File

@@ -5,20 +5,23 @@
*/
package dan200.computercraft.shared.computer.apis;
import com.google.common.collect.ImmutableMap;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.lua.*;
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
import dan200.computercraft.shared.peripheral.generic.data.BlockData;
import dan200.computercraft.shared.util.NBTUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.state.property.Property;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import java.util.*;
@@ -64,7 +67,7 @@ public class CommandAPI implements ILuaAPI
}
catch( Throwable t )
{
if( ComputerCraft.logComputerErrors ) ComputerCraft.log.error( "Error running command.", t );
if( ComputerCraft.logPeripheralErrors ) ComputerCraft.log.error( "Error running command.", t );
return new Object[] { false, createOutput( "Java Exception Thrown: " + t ) };
}
}
@@ -72,15 +75,42 @@ public class CommandAPI implements ILuaAPI
private static Map<?, ?> getBlockInfo( World world, BlockPos pos )
{
// Get the details of the block
BlockState state = world.getBlockState( pos );
Map<String, Object> table = BlockData.fill( new HashMap<>(), state );
BlockState state = world.getBlockState(pos);
Block block = state.getBlock();
BlockEntity tile = world.getBlockEntity( pos );
if( tile != null ) table.put( "nbt", NBTUtil.toLua( tile.toTag( new CompoundTag() ) ) );
Map<Object, Object> table = new HashMap<>();
table.put("name",
Registry.BLOCK.getId(block)
.toString());
table.put("world", world.getRegistryKey());
Map<Object, Object> stateTable = new HashMap<>();
for (ImmutableMap.Entry<Property<?>, Comparable<?>> entry : state.getEntries()
.entrySet()) {
Property<?> property = entry.getKey();
stateTable.put(property.getName(), getPropertyValue(property, entry.getValue()));
}
table.put("state", stateTable);
BlockEntity tile = world.getBlockEntity(pos);
if (tile != null) {
table.put("nbt", NBTUtil.toLua(tile.toTag(new CompoundTag())));
}
return table;
}
@SuppressWarnings ({
"unchecked",
"rawtypes"
})
private static Object getPropertyValue(Property property, Comparable value) {
if (value instanceof String || value instanceof Number || value instanceof Boolean) {
return value;
}
return property.name(value);
}
/**
* Execute a specific command.
*

View File

@@ -18,7 +18,6 @@ import net.minecraft.state.property.DirectionProperty;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.Direction;
import net.minecraftforge.fml.RegistryObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

View File

@@ -29,7 +29,6 @@ import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraftforge.fml.RegistryObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -115,7 +114,7 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
@Nonnull
@Override
public ItemStack getPickBlock( BlockState state, HitResult target, BlockView world, BlockPos pos, PlayerEntity player )
public ItemStack getPickStack( BlockView world, BlockPos pos, BlockState state )
{
BlockEntity tile = world.getBlockEntity( pos );
if( tile instanceof TileComputerBase )
@@ -124,7 +123,7 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
if( !result.isEmpty() ) return result;
}
return super.getPickBlock( state, target, world, pos, player );
return super.getPickStack(world, pos, state);
}
@Override

View File

@@ -33,7 +33,7 @@ public class ComputerPeripheral implements IPeripheral
@Nonnull
@Override
public String getType0()
public String getType()
{
return type;
}

View File

@@ -22,12 +22,9 @@ import net.minecraft.util.math.Direction;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Optional;
public class TileComputer extends TileComputerBase
{
private ComputerProxy proxy;
private Optional<IPeripheral> peripheral;
public TileComputer( ComputerFamily family, BlockEntityType<? extends TileComputer> type )
{
@@ -40,8 +37,8 @@ public class TileComputer extends TileComputerBase
ComputerFamily family = getFamily();
ServerComputer computer = new ServerComputer(
getWorld(), id, label, instanceID, family,
ComputerCraft.computerTermWidth,
ComputerCraft.computerTermHeight
ComputerCraft.terminalWidth_computer,
ComputerCraft.terminalHeight_computer
);
computer.setPosition( getPos() );
return computer;

View File

@@ -3,28 +3,22 @@
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.computer.blocks;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.computer.ComputerSide;
import dan200.computercraft.shared.BundledRedstone;
import dan200.computercraft.shared.Peripherals;
import dan200.computercraft.shared.common.TileGeneric;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ComputerState;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.network.container.ComputerContainerData;
import dan200.computercraft.shared.util.DirectionUtil;
import dan200.computercraft.shared.util.RedstoneUtil;
import joptsimple.internal.Strings;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.RedstoneWireBlock;
@@ -33,7 +27,9 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
@@ -46,10 +42,14 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
public abstract class TileComputerBase extends TileGeneric implements IComputerTile, Tickable, Nameable, NamedScreenHandlerFactory, IPeripheral {
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Objects;
public abstract class TileComputerBase extends TileGeneric implements IComputerTile, Tickable, Nameable, NamedScreenHandlerFactory, ExtendedScreenHandlerFactory
{
private static final String NBT_ID = "ComputerId";
private static final String NBT_LABEL = "Label";
private static final String NBT_INSTANCE = "InstanceId";
private static final String NBT_ON = "On";
private int m_instanceID = -1;
@@ -61,64 +61,65 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
private final ComputerFamily family;
public TileComputerBase(BlockEntityType<? extends TileGeneric> type, ComputerFamily family) {
super(type);
public TileComputerBase( BlockEntityType<? extends TileGeneric> type, ComputerFamily family )
{
super( type );
this.family = family;
}
protected void unload() {
if (m_instanceID >= 0) {
if (!getWorld().isClient) {
ComputerCraft.serverComputerRegistry.remove(m_instanceID);
}
protected void unload()
{
if( m_instanceID >= 0 )
{
if( !getWorld().isClient ) ComputerCraft.serverComputerRegistry.remove( m_instanceID );
m_instanceID = -1;
}
}
public abstract void openGui(PlayerEntity entity);
@Override
public void destroy() {
public void destroy()
{
unload();
for (Direction dir : DirectionUtil.FACINGS) {
RedstoneUtil.propagateRedstoneOutput(getWorld(), getPos(), dir);
for( Direction dir : DirectionUtil.FACINGS )
{
RedstoneUtil.propagateRedstoneOutput( getWorld(), getPos(), dir );
}
}
/*@Override
public void onChunkUnloaded()
{
unload();
}*/
@Override
public void markRemoved() {
public void markRemoved()
{
unload();
super.markRemoved();
}
protected boolean canNameWithTag(PlayerEntity player) {
protected boolean canNameWithTag( PlayerEntity player )
{
return false;
}
@Nonnull
@Override
public ActionResult onActivate(PlayerEntity player, Hand hand, BlockHitResult hit) {
ItemStack currentItem = player.getStackInHand(hand);
if (!currentItem.isEmpty() && currentItem.getItem() == Items.NAME_TAG && canNameWithTag(player) && currentItem.hasCustomName()) {
public ActionResult onActivate( PlayerEntity player, Hand hand, BlockHitResult hit )
{
ItemStack currentItem = player.getStackInHand( hand );
if( !currentItem.isEmpty() && currentItem.getItem() == Items.NAME_TAG && canNameWithTag( player ) && currentItem.hasCustomName() )
{
// Label to rename computer
if (!getWorld().isClient) {
setLabel(currentItem.getName()
.getString());
currentItem.decrement(1);
if( !getWorld().isClient )
{
setLabel( currentItem.getName().getString() );
currentItem.decrement( 1 );
}
return ActionResult.SUCCESS;
} else if (!player.isInSneakingPose()) {
}
else if( !player.isInSneakingPose() )
{
// Regular right click to activate computer
if (!getWorld().isClient && isUsable(player, false)) {
if( !getWorld().isClient && isUsable( player, false ) )
{
createServerComputer().turnOn();
openGui(player);
new ComputerContainerData( createServerComputer() ).open( player, this );
}
return ActionResult.SUCCESS;
}
@@ -126,25 +127,28 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
}
@Override
public void onNeighbourChange(@Nonnull BlockPos neighbour) {
updateInput(neighbour);
public void onNeighbourChange( @Nonnull BlockPos neighbour )
{
updateInput( neighbour );
}
@Override
public void onNeighbourTileEntityChange(@Nonnull BlockPos neighbour) {
updateInput(neighbour);
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
{
updateInput( neighbour );
}
@Override
public void tick() {
if (!getWorld().isClient) {
public void tick()
{
if( !getWorld().isClient )
{
ServerComputer computer = createServerComputer();
if (computer == null) {
return;
}
if( computer == null ) return;
// If the computer isn't on and should be, then turn it on
if (m_startOn || (m_fresh && m_on)) {
if( m_startOn || (m_fresh && m_on) )
{
computer.turnOn();
m_startOn = false;
}
@@ -156,74 +160,69 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
label = computer.getLabel();
m_on = computer.isOn();
if (computer.hasOutputChanged()) {
updateOutput();
}
if( computer.hasOutputChanged() ) updateOutput();
// Update the block state if needed. We don't fire a block update intentionally,
// as this only really is needed on the client side.
updateBlockState(computer.getState());
updateBlockState( computer.getState() );
if (computer.hasOutputChanged()) {
updateOutput();
}
if( computer.hasOutputChanged() ) updateOutput();
}
/* else todo is needed?
{
ClientComputer computer = createClientComputer();
if( computer != null && computer.hasOutputChanged() ) updateBlock();
}*/
}
protected abstract void updateBlockState(ComputerState newState);
protected abstract void updateBlockState( ComputerState newState );
@Nonnull
@Override
public CompoundTag toTag(@Nonnull CompoundTag nbt) {
public CompoundTag toTag( @Nonnull CompoundTag nbt )
{
// Save ID, label and power state
if (m_computerID >= 0) {
nbt.putInt(NBT_ID, m_computerID);
}
if (label != null) {
nbt.putString(NBT_LABEL, label);
}
nbt.putBoolean(NBT_ON, m_on);
if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID );
if( label != null ) nbt.putString( NBT_LABEL, label );
nbt.putBoolean( NBT_ON, m_on );
return super.toTag(nbt);
return super.toTag( nbt );
}
@Override
public void fromTag(@Nonnull BlockState state, @Nonnull CompoundTag nbt) {
super.fromTag(state, nbt);
public void fromTag( @Nonnull BlockState state, @Nonnull CompoundTag nbt )
{
super.fromTag( state, nbt );
// Load ID, label and power state
m_computerID = nbt.contains(NBT_ID) ? nbt.getInt(NBT_ID) : -1;
label = nbt.contains(NBT_LABEL) ? nbt.getString(NBT_LABEL) : null;
m_on = m_startOn = nbt.getBoolean(NBT_ON);
m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
m_on = m_startOn = nbt.getBoolean( NBT_ON );
}
protected boolean isPeripheralBlockedOnSide(ComputerSide localSide) {
protected boolean isPeripheralBlockedOnSide( ComputerSide localSide )
{
return false;
}
protected abstract Direction getDirection();
protected ComputerSide remapToLocalSide(Direction globalSide) {
return remapLocalSide(DirectionUtil.toLocal(getDirection(), globalSide));
protected ComputerSide remapToLocalSide( Direction globalSide )
{
return remapLocalSide( DirectionUtil.toLocal( getDirection(), globalSide ) );
}
protected ComputerSide remapLocalSide(ComputerSide localSide) {
protected ComputerSide remapLocalSide( ComputerSide localSide )
{
return localSide;
}
private void updateSideInput(ServerComputer computer, Direction dir, BlockPos offset) {
private void updateSideInput( ServerComputer computer, Direction dir, BlockPos offset )
{
Direction offsetSide = dir.getOpposite();
ComputerSide localDir = remapToLocalSide(dir);
ComputerSide localDir = remapToLocalSide( dir );
computer.setRedstoneInput(localDir, getRedstoneInput(world, offset, dir));
computer.setBundledRedstoneInput(localDir, BundledRedstone.getOutput(getWorld(), offset, offsetSide));
if (!isPeripheralBlockedOnSide(localDir)) {
computer.setPeripheral(localDir, Peripherals.getPeripheral(getWorld(), offset, offsetSide));
computer.setRedstoneInput( localDir, getRedstoneInput( world, offset, dir ) );
computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getWorld(), offset, offsetSide ) );
if( !isPeripheralBlockedOnSide( localDir ) )
{
IPeripheral peripheral = Peripherals.getPeripheral( getWorld(), offset, offsetSide);
computer.setPeripheral( localDir, peripheral );
}
}
@@ -231,52 +230,50 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
* Gets the redstone input for an adjacent block.
*
* @param world The world we exist in
* @param pos The position of the neighbour
* @param side The side we are reading from
* @param pos The position of the neighbour
* @param side The side we are reading from
* @return The effective redstone power
*/
protected static int getRedstoneInput(World world, BlockPos pos, Direction side) {
int power = world.getEmittedRedstonePower(pos, side);
if (power >= 15) {
return power;
}
protected static int getRedstoneInput( World world, BlockPos pos, Direction side )
{
int power = world.getEmittedRedstonePower( pos, side );
if( power >= 15 ) return power;
BlockState neighbour = world.getBlockState(pos);
return neighbour.getBlock() == Blocks.REDSTONE_WIRE ? Math.max(power, neighbour.get(RedstoneWireBlock.POWER)) : power;
BlockState neighbour = world.getBlockState( pos );
return neighbour.getBlock() == Blocks.REDSTONE_WIRE
? Math.max( power, neighbour.get( RedstoneWireBlock.POWER ) )
: power;
}
public void updateInput() {
if (getWorld() == null || getWorld().isClient) {
return;
}
public void updateInput()
{
if( getWorld() == null || getWorld().isClient ) return;
// Update all sides
ServerComputer computer = getServerComputer();
if (computer == null) {
return;
}
if( computer == null ) return;
BlockPos pos = computer.getPosition();
for (Direction dir : DirectionUtil.FACINGS) {
updateSideInput(computer, dir, pos.offset(dir));
for( Direction dir : DirectionUtil.FACINGS )
{
updateSideInput( computer, dir, pos.offset( dir ) );
}
}
private void updateInput(BlockPos neighbour) {
if (getWorld() == null || getWorld().isClient) {
return;
}
private void updateInput( BlockPos neighbour )
{
if( getWorld() == null || getWorld().isClient ) return;
ServerComputer computer = getServerComputer();
if (computer == null) {
return;
}
if( computer == null ) return;
for (Direction dir : DirectionUtil.FACINGS) {
BlockPos offset = pos.offset(dir);
if (offset.equals(neighbour)) {
updateSideInput(computer, dir, offset);
return; // todo break;?
for( Direction dir : DirectionUtil.FACINGS )
{
BlockPos offset = pos.offset( dir );
if( offset.equals( neighbour ) )
{
updateSideInput( computer, dir, offset );
return;
}
}
@@ -284,110 +281,120 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
updateInput();
}
public void updateOutput() {
private void updateInput( Direction dir )
{
if( getWorld() == null || getWorld().isClient ) return;
ServerComputer computer = getServerComputer();
if( computer == null ) return;
updateSideInput( computer, dir, pos.offset( dir ) );
}
public void updateOutput()
{
// Update redstone
updateBlock();
for (Direction dir : DirectionUtil.FACINGS) {
RedstoneUtil.propagateRedstoneOutput(getWorld(), getPos(), dir);
for( Direction dir : DirectionUtil.FACINGS )
{
RedstoneUtil.propagateRedstoneOutput( getWorld(), getPos(), dir );
}
}
public abstract ComputerProxy createProxy();
protected abstract ServerComputer createComputer(int instanceID, int id);
protected abstract ServerComputer createComputer( int instanceID, int id );
@Override
public final int getComputerID() {
public final int getComputerID()
{
return m_computerID;
}
@Override
public final String getLabel() {
public final String getLabel()
{
return label;
}
@Override
public final void setComputerID(int id) {
if (getWorld().isClient || m_computerID == id) {
return;
}
public final void setComputerID( int id )
{
if( getWorld().isClient || m_computerID == id ) return;
m_computerID = id;
ServerComputer computer = getServerComputer();
if (computer != null) {
computer.setID(m_computerID);
}
if( computer != null ) computer.setID( m_computerID );
markDirty();
}
@Override
public final void setLabel(String label) {
if (getWorld().isClient || Objects.equals(this.label, label)) {
return;
}
public final void setLabel( String label )
{
if( getWorld().isClient || Objects.equals( this.label, label ) ) return;
this.label = label;
ServerComputer computer = getServerComputer();
if (computer != null) {
computer.setLabel(label);
}
if( computer != null ) computer.setLabel( label );
markDirty();
}
@Override
public ComputerFamily getFamily() {
public ComputerFamily getFamily()
{
return family;
}
public ServerComputer createServerComputer() {
if (getWorld().isClient) {
return null;
}
public ServerComputer createServerComputer()
{
if( getWorld().isClient ) return null;
boolean changed = false;
if (m_instanceID < 0) {
if( m_instanceID < 0 )
{
m_instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
changed = true;
}
if (!ComputerCraft.serverComputerRegistry.contains(m_instanceID)) {
ServerComputer computer = createComputer(m_instanceID, m_computerID);
ComputerCraft.serverComputerRegistry.add(m_instanceID, computer);
if( !ComputerCraft.serverComputerRegistry.contains( m_instanceID ) )
{
ServerComputer computer = createComputer( m_instanceID, m_computerID );
ComputerCraft.serverComputerRegistry.add( m_instanceID, computer );
m_fresh = true;
changed = true;
}
if (changed) {
if( changed )
{
updateBlock();
updateInput();
}
return ComputerCraft.serverComputerRegistry.get(m_instanceID);
return ComputerCraft.serverComputerRegistry.get( m_instanceID );
}
public ServerComputer getServerComputer() {
return getWorld().isClient ? null : ComputerCraft.serverComputerRegistry.get(m_instanceID);
public ServerComputer getServerComputer()
{
return getWorld().isClient ? null : ComputerCraft.serverComputerRegistry.get( m_instanceID );
}
// Networking stuff
@Override
protected void writeDescription(@Nonnull CompoundTag nbt) {
super.writeDescription(nbt);
if (label != null) {
nbt.putString(NBT_LABEL, label);
}
if (m_computerID >= 0) {
nbt.putInt(NBT_ID, m_computerID);
}
protected void writeDescription( @Nonnull CompoundTag nbt )
{
super.writeDescription( nbt );
if( label != null ) nbt.putString( NBT_LABEL, label );
if( m_computerID >= 0 ) nbt.putInt( NBT_ID, m_computerID );
}
@Override
protected void readDescription(@Nonnull CompoundTag nbt) {
super.readDescription(nbt);
label = nbt.contains(NBT_LABEL) ? nbt.getString(NBT_LABEL) : null;
m_computerID = nbt.contains(NBT_ID) ? nbt.getInt(NBT_ID) : -1;
protected void readDescription( @Nonnull CompoundTag nbt )
{
super.readDescription( nbt );
label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
m_computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
}
protected void transferStateFrom(TileComputerBase copy) {
if (copy.m_computerID != m_computerID || copy.m_instanceID != m_instanceID) {
protected void transferStateFrom( TileComputerBase copy )
{
if( copy.m_computerID != m_computerID || copy.m_instanceID != m_instanceID )
{
unload();
m_instanceID = copy.m_instanceID;
m_computerID = copy.m_computerID;
@@ -401,25 +408,36 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
@Nonnull
@Override
public Text getName() {
return hasCustomName() ? new LiteralText(label) : new TranslatableText(getCachedState().getBlock()
.getTranslationKey());
public Text getName()
{
return hasCustomName()
? new LiteralText( label )
: new TranslatableText( getCachedState().getBlock().getTranslationKey() );
}
@Override
public boolean hasCustomName() {
return !Strings.isNullOrEmpty(label);
public boolean hasCustomName()
{
return !Strings.isNullOrEmpty( label );
}
@Nullable
@Override
public Text getCustomName() {
return hasCustomName() ? new LiteralText(label) : null;
public Text getCustomName()
{
return hasCustomName() ? new LiteralText( label ) : null;
}
@Nonnull
@Override
public Text getDisplayName() {
public Text getDisplayName()
{
return Nameable.super.getDisplayName();
}
@Override
public void writeScreenOpeningData(ServerPlayerEntity serverPlayerEntity, PacketByteBuf packetByteBuf) {
packetByteBuf.writeInt(getServerComputer().getInstanceID());
packetByteBuf.writeEnumConstant(getServerComputer().getFamily());
}
}

View File

@@ -163,7 +163,8 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
if( hasOutputChanged() || force )
{
// Send computer state to all clients
NetworkHandler.sendToAllPlayers( createComputerPacket() );
if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer)
NetworkHandler.sendToAllPlayers((MinecraftServer) FabricLoader.getInstance().getGameInstance(), createComputerPacket() );
}
if( hasTerminalChanged() || force )
@@ -198,7 +199,8 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
public void broadcastDelete()
{
// Send deletion to client
NetworkHandler.sendToAllPlayers( new ComputerDeletedClientMessage( getInstanceID() ) );
if (FabricLoader.getInstance().getGameInstance() instanceof MinecraftServer)
NetworkHandler.sendToAllPlayers((MinecraftServer) FabricLoader.getInstance().getGameInstance(), new ComputerDeletedClientMessage( getInstanceID() ) );
}
public void setID( int id )

View File

@@ -5,20 +5,20 @@
*/
package dan200.computercraft.shared.computer.inventory;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.network.container.ComputerContainerData;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.network.PacketByteBuf;
public class ContainerComputer extends ContainerComputerBase
{
public ContainerComputer( int id, TileComputer tile )
{
super( Registry.ModContainers.COMPUTER.get(), id, tile::isUsableByPlayer, tile.createServerComputer(), tile.getFamily() );
super( ComputerCraftRegistry.ModContainers.COMPUTER, id, tile::isUsableByPlayer, tile.createServerComputer(), tile.getFamily() );
}
public ContainerComputer( int id, PlayerInventory player, ComputerContainerData data )
{
super( Registry.ModContainers.COMPUTER.get(), id, player, data );
public ContainerComputer(int i, PlayerInventory playerInventory, PacketByteBuf packetByteBuf) {
super(ComputerCraftRegistry.ModContainers.COMPUTER, i, playerInventory, packetByteBuf);
}
}

View File

@@ -10,6 +10,7 @@ import dan200.computercraft.shared.computer.core.*;
import dan200.computercraft.shared.network.container.ComputerContainerData;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerType;
import javax.annotation.Nonnull;
@@ -31,9 +32,9 @@ public class ContainerComputerBase extends ScreenHandler implements IContainerCo
this.family = family;
}
protected ContainerComputerBase( ScreenHandlerType<? extends ContainerComputerBase> type, int id, PlayerInventory player, ComputerContainerData data )
protected ContainerComputerBase(ScreenHandlerType<? extends ContainerComputerBase> type, int id, PlayerInventory player, PacketByteBuf packetByteBuf)
{
this( type, id, x -> true, getComputer( player, data ), data.getFamily() );
this( type, id, x -> true, getComputer( player, new ComputerContainerData((PacketByteBuf) packetByteBuf.copy()) ), new ComputerContainerData(packetByteBuf).getFamily() );
}
protected static IComputer getComputer( PlayerInventory player, ComputerContainerData data )

View File

@@ -3,85 +3,63 @@
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.computer.inventory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.IComputer;
import dan200.computercraft.shared.computer.core.IContainerComputer;
import dan200.computercraft.shared.computer.core.InputState;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.network.container.ViewComputerContainerData;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.MinecraftServer;
import net.minecraft.text.TranslatableText;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.network.PacketByteBuf;
public class ContainerViewComputer extends ScreenHandler implements IContainerComputer {
private final IComputer computer;
private final InputState input = new InputState(this);
import javax.annotation.Nonnull;
public ContainerViewComputer(int id, IComputer computer) {
super(null, id);
this.computer = computer;
public class ContainerViewComputer extends ContainerComputerBase implements IContainerComputer
{
private final int width;
private final int height;
public ContainerViewComputer( int id, ServerComputer computer )
{
super( ComputerCraftRegistry.ModContainers.VIEW_COMPUTER, id, player -> canInteractWith( computer, player ), computer, computer.getFamily() );
this.width = this.height = 0;
}
public ContainerViewComputer(int id, PlayerInventory player, PacketByteBuf packetByteBuf)
{
super( ComputerCraftRegistry.ModContainers.VIEW_COMPUTER, id, player, packetByteBuf );
ViewComputerContainerData data = new ViewComputerContainerData((PacketByteBuf) packetByteBuf.copy());
this.width = data.getWidth();
this.height = data.getHeight();
}
private static boolean canInteractWith(@Nonnull ServerComputer computer, @Nonnull PlayerEntity player) {
private static boolean canInteractWith( @Nonnull ServerComputer computer, @Nonnull PlayerEntity player )
{
// If this computer no longer exists then discard it.
if (ComputerCraft.serverComputerRegistry.get(computer.getInstanceID()) != computer) {
if( ComputerCraft.serverComputerRegistry.get( computer.getInstanceID() ) != computer )
{
return false;
}
// If we're a command computer then ensure we're in creative
return computer.getFamily() != ComputerFamily.COMMAND || TileCommandComputer.isUsable(player);
}
@Nullable
@Override
public IComputer getComputer() {
return this.computer;
}
@Override
public boolean canUse(PlayerEntity player) {
if (this.computer instanceof ServerComputer) {
ServerComputer serverComputer = (ServerComputer) this.computer;
// If this computer no longer exists then discard it.
if (ComputerCraft.serverComputerRegistry.get(serverComputer.getInstanceID()) != serverComputer) {
return false;
}
// If we're a command computer then ensure we're in creative
if (serverComputer.getFamily() == ComputerFamily.COMMAND) {
MinecraftServer server = player.getServer();
if (server == null || !server.areCommandBlocksEnabled()) {
player.sendMessage(new TranslatableText("advMode.notEnabled"), false);
return false;
} else if (!player.isCreativeLevelTwoOp()) {
player.sendMessage(new TranslatableText("advMode.notAllowed"), false);
return false;
}
}
if( computer.getFamily() == ComputerFamily.COMMAND && !TileCommandComputer.isUsable( player ) )
{
return false;
}
return true;
}
@Nonnull
@Override
public InputState getInput() {
return this.input;
public int getWidth()
{
return width;
}
@Override
public void close(PlayerEntity player) {
super.close(player);
this.input.close();
public int getHeight()
{
return height;
}
}

View File

@@ -5,7 +5,7 @@
*/
package dan200.computercraft.shared.computer.items;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import net.minecraft.item.ItemStack;
@@ -28,11 +28,11 @@ public final class ComputerItemFactory
switch( family )
{
case NORMAL:
return Registry.ModItems.COMPUTER_NORMAL.get().create( id, label );
return ComputerCraftRegistry.ModItems.COMPUTER_NORMAL.create( id, label );
case ADVANCED:
return Registry.ModItems.COMPUTER_ADVANCED.get().create( id, label );
return ComputerCraftRegistry.ModItems.COMPUTER_ADVANCED.create( id, label );
case COMMAND:
return Registry.ModItems.COMPUTER_COMMAND.get().create( id, label );
return ComputerCraftRegistry.ModItems.COMPUTER_COMMAND.create( id, label );
default:
return ItemStack.EMPTY;
}

View File

@@ -7,11 +7,11 @@ package dan200.computercraft.shared.computer.recipe;
import com.google.gson.JsonObject;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.util.BasicRecipeSerializer;
import dan200.computercraft.shared.util.RecipeUtil;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.collection.DefaultedList;
@@ -32,8 +32,7 @@ public abstract class ComputerFamilyRecipe extends ComputerConvertRecipe
return family;
}
public abstract static class Serializer<T extends ComputerFamilyRecipe> extends BasicRecipeSerializer<T>
{
public abstract static class Serializer<T extends ComputerFamilyRecipe> implements RecipeSerializer<T> {
protected abstract T create( Identifier identifier, String group, int width, int height, DefaultedList<Ingredient> ingredients, ItemStack result, ComputerFamily family );
@Nonnull

View File

@@ -28,7 +28,7 @@ public final class ConstantLootConditionSerializer<T extends LootCondition> impl
}
@Override
public void func_230424_a_( @Nonnull JsonObject json, @Nonnull T object, @Nonnull JsonSerializationContext context )
public void toJson( @Nonnull JsonObject json, @Nonnull T object, @Nonnull JsonSerializationContext context )
{
}

View File

@@ -10,7 +10,7 @@ import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.PocketUpgrades;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.TurtleUpgrades;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.media.items.ItemDisk;
@@ -51,13 +51,13 @@ public class JEIComputerCraft implements IModPlugin
@Override
public void registerItemSubtypes( ISubtypeRegistration subtypeRegistry )
{
subtypeRegistry.registerSubtypeInterpreter( Registry.ModItems.TURTLE_NORMAL.get(), turtleSubtype );
subtypeRegistry.registerSubtypeInterpreter( Registry.ModItems.TURTLE_ADVANCED.get(), turtleSubtype );
subtypeRegistry.registerSubtypeInterpreter( ComputerCraftRegistry.ModItems.TURTLE_NORMAL.get(), turtleSubtype );
subtypeRegistry.registerSubtypeInterpreter( ComputerCraftRegistry.ModItems.TURTLE_ADVANCED.get(), turtleSubtype );
subtypeRegistry.registerSubtypeInterpreter( Registry.ModItems.POCKET_COMPUTER_NORMAL.get(), pocketSubtype );
subtypeRegistry.registerSubtypeInterpreter( Registry.ModItems.POCKET_COMPUTER_ADVANCED.get(), pocketSubtype );
subtypeRegistry.registerSubtypeInterpreter( ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL.get(), pocketSubtype );
subtypeRegistry.registerSubtypeInterpreter( ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED.get(), pocketSubtype );
subtypeRegistry.registerSubtypeInterpreter( Registry.ModItems.DISK.get(), diskSubtype );
subtypeRegistry.registerSubtypeInterpreter( ComputerCraftRegistry.ModItems.DISK.get(), diskSubtype );
}
@Override

View File

@@ -9,7 +9,7 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.common.IColouredItem;
import dan200.computercraft.shared.util.Colour;
import net.minecraft.client.item.TooltipContext;
@@ -42,9 +42,9 @@ public class ItemDisk extends Item implements IMedia, IColouredItem
@Nonnull
public static ItemStack createFromIDAndColour( int id, String label, int colour )
{
ItemStack stack = new ItemStack( Registry.ModItems.DISK.get() );
ItemStack stack = new ItemStack( ComputerCraftRegistry.ModItems.DISK );
setDiskID( stack, id );
Registry.ModItems.DISK.get().setLabel( stack, label );
ComputerCraftRegistry.ModItems.DISK.setLabel( stack, label );
IColouredItem.setColourBasic( stack, colour );
return stack;
}
@@ -73,12 +73,6 @@ public class ItemDisk extends Item implements IMedia, IColouredItem
}
}
@Override
public boolean doesSneakBypassUse( ItemStack stack, WorldView world, BlockPos pos, PlayerEntity player )
{
return true;
}
@Override
public String getLabel( @Nonnull ItemStack stack )
{

View File

@@ -5,7 +5,7 @@
*/
package dan200.computercraft.shared.media.items;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.common.ContainerHeldItem;
import dan200.computercraft.shared.network.container.HeldItemContainerData;
import net.minecraft.client.item.TooltipContext;
@@ -63,7 +63,7 @@ public class ItemPrintout extends Item
if( !world.isClient )
{
new HeldItemContainerData( hand )
.open( player, new ContainerHeldItem.Factory( Registry.ModContainers.PRINTOUT.get(), player.getStackInHand( hand ), hand ) );
.open( player, new ContainerHeldItem.Factory( ComputerCraftRegistry.ModContainers.PRINTOUT, player.getStackInHand( hand ), hand ) );
}
return new TypedActionResult<>( ActionResult.SUCCESS, player.getStackInHand( hand ) );
}
@@ -100,19 +100,19 @@ public class ItemPrintout extends Item
@Nonnull
public static ItemStack createSingleFromTitleAndText( String title, String[] text, String[] colours )
{
return Registry.ModItems.PRINTED_PAGE.get().createFromTitleAndText( title, text, colours );
return ComputerCraftRegistry.ModItems.PRINTED_PAGE.createFromTitleAndText( title, text, colours );
}
@Nonnull
public static ItemStack createMultipleFromTitleAndText( String title, String[] text, String[] colours )
{
return Registry.ModItems.PRINTED_PAGES.get().createFromTitleAndText( title, text, colours );
return ComputerCraftRegistry.ModItems.PRINTED_PAGES.createFromTitleAndText( title, text, colours );
}
@Nonnull
public static ItemStack createBookFromTitleAndText( String title, String[] text, String[] colours )
{
return Registry.ModItems.PRINTED_BOOK.get().createFromTitleAndText( title, text, colours );
return ComputerCraftRegistry.ModItems.PRINTED_BOOK.createFromTitleAndText( title, text, colours );
}
public Type getType()

View File

@@ -9,7 +9,7 @@ import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.media.IMedia;
import dan200.computercraft.core.filesystem.SubMount;
import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.util.Colour;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.player.PlayerEntity;
@@ -51,12 +51,6 @@ public class ItemTreasureDisk extends Item implements IMedia
if( !label.isEmpty() ) list.add( new LiteralText( label ) );
}
@Override
public boolean doesSneakBypassUse( @Nonnull ItemStack stack, WorldView world, BlockPos pos, PlayerEntity player )
{
return true;
}
@Override
public String getLabel( @Nonnull ItemStack stack )
{
@@ -91,7 +85,7 @@ public class ItemTreasureDisk extends Item implements IMedia
public static ItemStack create( String subPath, int colourIndex )
{
ItemStack result = new ItemStack( Registry.ModItems.TREASURE_DISK.get() );
ItemStack result = new ItemStack( ComputerCraftRegistry.ModItems.TREASURE_DISK );
CompoundTag nbt = result.getOrCreateTag();
nbt.putString( NBT_SUB_PATH, subPath );

View File

@@ -12,9 +12,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.item.MusicDiscItem;
import net.minecraft.sound.SoundEvent;
import net.minecraft.text.TranslatableText;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper.UnableToAccessFieldException;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper.UnableToFindFieldException;
import javax.annotation.Nonnull;
@@ -47,17 +44,6 @@ public final class RecordMedia implements IMedia
@Override
public SoundEvent getAudio( @Nonnull ItemStack stack )
{
Item item = stack.getItem();
if( !(item instanceof MusicDiscItem) ) return null;
try
{
return ObfuscationReflectionHelper.getPrivateValue( MusicDiscItem.class, (MusicDiscItem) item, "field_185076_b" );
}
catch( UnableToAccessFieldException | UnableToFindFieldException e )
{
ComputerCraft.log.error( "Cannot get disk sound", e );
return null;
}
return ((MusicDiscItem) stack.getItem()).getSound();
}
}

View File

@@ -67,7 +67,7 @@ public class DiskRecipe extends SpecialCraftingRecipe
@Nonnull
@Override
public ItemStack getCraftingResult( @Nonnull CraftingInventory inv )
public ItemStack craft( @Nonnull CraftingInventory inv )
{
ColourTracker tracker = new ColourTracker();

View File

@@ -45,12 +45,12 @@ public final class PrintoutRecipe extends SpecialCraftingRecipe
@Override
public boolean matches( @Nonnull CraftingInventory inventory, @Nonnull World world )
{
return !getCraftingResult( inventory ).isEmpty();
return !craft( inventory ).isEmpty();
}
@Nonnull
@Override
public ItemStack getCraftingResult( @Nonnull CraftingInventory inventory )
public ItemStack craft( @Nonnull CraftingInventory inventory )
{
// See if we match the recipe, and extract the input disk ID and dye colour
int numPages = 0;

View File

@@ -0,0 +1,17 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.mixed;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Arm;
public interface MixedFirstPersonRenderer {
void renderArmFirstPerson_CC(MatrixStack stack, VertexConsumerProvider consumerProvider, int light, float equip, float swing, Arm hand);
float getMapAngleFromPitch_CC(float pitch);
}

View File

@@ -0,0 +1,33 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.mixin;
import dan200.computercraft.shared.util.DropConsumer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
/**
* @see Block#dropStack(World, BlockPos, ItemStack)
*/
@Mixin (Block.class)
public class MixinBlock {
@Inject (method = "dropStack",
at = @At (value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z"),
cancellable = true)
private static void dropStack(World world, BlockPos pos, ItemStack stack, CallbackInfo callbackInfo) {
if (DropConsumer.onHarvestDrops(world, pos, stack)) {
callbackInfo.cancel();
}
}
}

View File

@@ -0,0 +1,32 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.mixin;
import dan200.computercraft.shared.util.DropConsumer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.item.ItemStack;
/**
* @see Entity#dropStack(ItemStack, float)
*/
@Mixin (Entity.class)
public class MixinEntity {
@Inject (method = "dropStack(Lnet/minecraft/item/ItemStack;F)Lnet/minecraft/entity/ItemEntity;",
at = @At (value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z"),
cancellable = true)
public void dropStack(ItemStack stack, float height, CallbackInfoReturnable<ItemEntity> callbackInfo) {
if (DropConsumer.onLivingDrops((Entity) (Object) this, stack)) {
callbackInfo.setReturnValue(null);
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.mixin;
import dan200.computercraft.client.render.ItemPocketRenderer;
import dan200.computercraft.client.render.ItemPrintoutRenderer;
import dan200.computercraft.shared.media.items.ItemPrintout;
import dan200.computercraft.shared.mixed.MixedFirstPersonRenderer;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.math.MatrixStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.item.HeldItemRenderer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Arm;
import net.minecraft.util.Hand;
@Mixin (HeldItemRenderer.class)
@Environment(EnvType.CLIENT)
public class MixinHeldItemRenderer implements MixedFirstPersonRenderer {
@Override
public void renderArmFirstPerson_CC(MatrixStack stack, VertexConsumerProvider consumerProvider, int light, float equip, float swing, Arm hand) {
this.renderArmHoldingItem(stack, consumerProvider, light, equip, swing, hand);
}
@Shadow
private void renderArmHoldingItem(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, float equipProgress, float swingProgress, Arm arm) {
}
@Override
public float getMapAngleFromPitch_CC(float pitch) {
return this.getMapAngle(pitch);
}
@Shadow
private float getMapAngle(float pitch) {
return 0;
}
@Inject (method = "Lnet/minecraft/client/render/item/HeldItemRenderer;renderFirstPersonItem(Lnet/minecraft/client/network/AbstractClientPlayerEntity;FFLnet/minecraft/util/Hand;FLnet/minecraft/item/ItemStack;FLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V",
at = @At ("HEAD"),
cancellable = true)
public void renderFirstPersonItem_Injected(AbstractClientPlayerEntity player, float var2, float pitch, Hand hand, float swingProgress,
ItemStack stack, float equipProgress, MatrixStack matrixStack, VertexConsumerProvider provider, int light, CallbackInfo callback) {
if (stack.getItem() instanceof ItemPrintout) {
ItemPrintoutRenderer.INSTANCE.renderItemFirstPerson(matrixStack, provider, light, hand, pitch, equipProgress, swingProgress, stack);
callback.cancel();
} else if (stack.getItem() instanceof ItemPocketComputer) {
ItemPocketRenderer.INSTANCE.renderItemFirstPerson(matrixStack, provider, light, hand, pitch, equipProgress, swingProgress, stack);
callback.cancel();
}
}
}

View File

@@ -0,0 +1,35 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.mixin;
import dan200.computercraft.client.render.ItemPrintoutRenderer;
import dan200.computercraft.shared.media.items.ItemPrintout;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.math.MatrixStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.render.entity.ItemFrameEntityRenderer;
import net.minecraft.entity.decoration.ItemFrameEntity;
import net.minecraft.item.ItemStack;
@Mixin (ItemFrameEntityRenderer.class)
@Environment(EnvType.CLIENT)
public class MixinItemFrameEntityRenderer {
@Inject (method = "render", at = @At ("HEAD"), cancellable = true)
private void renderItem_Injected(ItemFrameEntity itemFrameEntity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo info) {
ItemStack stack = itemFrameEntity.getHeldItemStack();
if (stack.getItem() instanceof ItemPrintout) {
ItemPrintoutRenderer.INSTANCE.renderInFrame(matrixStack, vertexConsumerProvider, stack);
info.cancel();
}
}
}

View File

@@ -0,0 +1,23 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.mixin;
import dan200.computercraft.client.FrameInfo;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.MinecraftClient;
@Mixin (MinecraftClient.class)
public abstract class MixinMinecraftGame {
@Inject (method = "render", at = @At ("HEAD"))
private void onRender(CallbackInfo info) {
FrameInfo.onRenderFrame();
}
}

View File

@@ -0,0 +1,28 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.mixin;
import dan200.computercraft.shared.command.CommandCopy;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.gui.screen.Screen;
@Mixin (Screen.class)
@Environment(EnvType.CLIENT)
public class MixinScreen {
@Inject (method = "sendMessage(Ljava/lang/String;Z)V", at = @At ("HEAD"), cancellable = true)
public void sendClientCommand(String message, boolean add, CallbackInfo info) {
if (CommandCopy.onClientSendMessage(message)) {
info.cancel();
}
}
}

View File

@@ -0,0 +1,29 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.mixin;
import dan200.computercraft.shared.util.DropConsumer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.Entity;
import net.minecraft.server.world.ServerWorld;
/**
* @see ServerWorld#spawnEntity(Entity)
*/
@Mixin (ServerWorld.class)
public class MixinServerWorld {
@Inject (method = "spawnEntity", at = @At ("HEAD"), cancellable = true)
public void spawnEntity(Entity entity, CallbackInfoReturnable<Boolean> callbackInfo) {
if (DropConsumer.onEntitySpawn(entity)) {
callbackInfo.setReturnValue(false);
}
}
}

View File

@@ -0,0 +1,54 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.mixin;
import java.util.Collection;
import javax.annotation.Nullable;
import dan200.computercraft.shared.common.TileGeneric;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
/**
* Horrible bodge to ensure a {@link BlockEntity}'s world is always present when setting a TE during another TE's tick.
*
* Forge does this, this is just a bodge to get Fabric in line with that behaviour.
*/
@Mixin (World.class)
public class MixinWorld {
@Shadow protected boolean iteratingTickingBlockEntities;
@Inject (method = "setBlockEntity", at = @At ("HEAD"))
public void setBlockEntity(BlockPos pos, @Nullable BlockEntity entity, CallbackInfo info) {
if (!World.isHeightInvalid(pos) && entity != null && !entity.isRemoved() && this.iteratingTickingBlockEntities) {
setWorld(entity, this);
}
}
private static void setWorld(BlockEntity entity, Object world) {
if (entity.getWorld() != world && entity instanceof TileGeneric) {
entity.setLocation((World) world, entity.getPos());
}
}
@Inject (method = "addBlockEntities", at = @At ("HEAD"))
public void addBlockEntities(Collection<BlockEntity> entities, CallbackInfo info) {
if (this.iteratingTickingBlockEntities) {
for (BlockEntity entity : entities) {
setWorld(entity, this);
}
}
}
}

View File

@@ -0,0 +1,37 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.mixin;
import dan200.computercraft.client.render.CableHighlightRenderer;
import dan200.computercraft.client.render.MonitorHighlightRenderer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
@Mixin (WorldRenderer.class)
@Environment(EnvType.CLIENT)
public class MixinWorldRenderer {
@Inject (method = "drawBlockOutline", cancellable = true, at = @At ("HEAD"))
public void drawBlockOutline(MatrixStack matrixStack, VertexConsumer vertexConsumer, Entity entity, double d, double e, double f, BlockPos blockPos, BlockState blockState, CallbackInfo info) {
if (CableHighlightRenderer.drawHighlight(matrixStack, vertexConsumer, entity, d, e, f, blockPos, blockState) || MonitorHighlightRenderer.drawHighlight(matrixStack, vertexConsumer, entity, d, e, f, blockPos, blockState)) {
info.cancel();
}
}
}

View File

@@ -1,109 +0,0 @@
package dan200.computercraft.shared.network;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.mixin.ScreenHandlerTypeAccessor;
import dan200.computercraft.shared.common.ContainerHeldItem;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
import dan200.computercraft.shared.media.items.ItemPrintout;
import dan200.computercraft.shared.network.container.ContainerType;
import dan200.computercraft.shared.network.container.PocketComputerContainerType;
import dan200.computercraft.shared.network.container.PrintoutContainerType;
import dan200.computercraft.shared.network.container.TileEntityContainerType;
import dan200.computercraft.shared.network.container.ViewComputerContainerType;
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.util.Hand;
public final class Containers
{
private Containers()
{
}
public static void openDiskDriveGUI(PlayerEntity player, TileDiskDrive drive )
{
TileEntityContainerType.diskDrive( drive.getPos() ).open( player );
}
public static void openComputerGUI( PlayerEntity player, TileComputer computer )
{
computer.createServerComputer().sendTerminalState( player );
TileEntityContainerType.computer( computer.getPos() ).open( player );
}
public static void openPrinterGUI( PlayerEntity player, TilePrinter printer )
{
TileEntityContainerType.printer( printer.getPos() ).open( player );
}
public static void openTurtleGUI( PlayerEntity player, TileTurtle turtle )
{
turtle.createServerComputer().sendTerminalState( player );
TileEntityContainerType.turtle( turtle.getPos() ).open( player );
}
public static void openPrintoutGUI( PlayerEntity player, Hand hand )
{
ItemStack stack = player.getStackInHand( hand );
Item item = stack.getItem();
if (!(item instanceof ItemPrintout)) {
return;
}
new PrintoutContainerType( hand ).open( player );
}
public static void openPocketComputerGUI( PlayerEntity player, Hand hand )
{
ItemStack stack = player.getStackInHand(hand );
Item item = stack.getItem();
if (!(item instanceof ItemPocketComputer)) {
return;
}
ServerComputer computer = ItemPocketComputer.getServerComputer(stack );
if (computer != null) {
computer.sendTerminalState(player);
}
new PocketComputerContainerType( hand ).open( player );
}
public static void openComputerGUI( PlayerEntity player, ServerComputer computer )
{
computer.sendTerminalState( player );
new ViewComputerContainerType( computer ).open( player );
}
public static void setup()
{
ContainerType.register(TileEntityContainerType::computer, (id, packet, player ) ->
new ContainerComputer(id, (TileComputer) packet.getTileEntity(player ) ) );
ContainerType.register( TileEntityContainerType::turtle, ( id, packet, player ) -> {
TileTurtle turtle = (TileTurtle) packet.getTileEntity( player );
return new ContainerTurtle(id, player.inventory, turtle.getAccess(), turtle.getServerComputer() );
} );
ContainerType.register(TileEntityContainerType::diskDrive, (id, packet, player ) ->
new ContainerDiskDrive(id, player.inventory, (TileDiskDrive) packet.getTileEntity(player ) ) );
ContainerType.register( TileEntityContainerType::printer, ( id, packet, player ) ->
new ContainerPrinter(id, player.inventory, (TilePrinter) packet.getTileEntity(player ) ) );
ContainerType.register(PocketComputerContainerType::new, (id, packet, player ) -> new ContainerPocketComputer(id, player, packet.hand ) );
ContainerType.register(PrintoutContainerType::new, (id, packet, player ) -> new ContainerHeldItem(id, player, packet.hand ) );
ContainerType.register(ViewComputerContainerType::new, (id, packet, player ) -> new ContainerViewComputer(id, ComputerCraft.serverComputerRegistry.get(packet.instanceId ) ) );
}
}

View File

@@ -9,26 +9,43 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.shared.network.client.*;
import dan200.computercraft.shared.network.server.*;
import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
import net.fabricmc.fabric.api.network.PacketContext;
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket;
import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.registry.BuiltinRegistries;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World;
import net.minecraft.world.chunk.WorldChunk;
import net.minecraftforge.fml.network.NetworkDirection;
import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.fml.network.PacketDistributor;
import net.minecraftforge.fml.network.simple.SimpleChannel;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import net.minecraft.world.dimension.DimensionType;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
public final class NetworkHandler
{
public static SimpleChannel network;
private static final Int2ObjectMap<BiConsumer<PacketContext, PacketByteBuf>> packetReaders = new Int2ObjectOpenHashMap<>();
private static final Object2IntMap<Class<?>> packetIds = new Object2IntOpenHashMap<>();
private static final Identifier ID = new Identifier(ComputerCraft.MOD_ID, "main");
private NetworkHandler()
{
@@ -36,101 +53,98 @@ public final class NetworkHandler
public static void setup()
{
String version = ComputerCraftAPI.getInstalledVersion();
network = NetworkRegistry.ChannelBuilder.named( new Identifier( ComputerCraft.MOD_ID, "network" ) )
.networkProtocolVersion( () -> version )
.clientAcceptedVersions( version::equals ).serverAcceptedVersions( version::equals )
.simpleChannel();
ServerSidePacketRegistry.INSTANCE.register(ID, NetworkHandler::receive);
if (FabricLoader.getInstance()
.getEnvironmentType() == EnvType.CLIENT) {
ClientSidePacketRegistry.INSTANCE.register(ID, NetworkHandler::receive);
}
// Server messages
registerMainThread( 0, NetworkDirection.PLAY_TO_SERVER, ComputerActionServerMessage::new );
registerMainThread( 1, NetworkDirection.PLAY_TO_SERVER, QueueEventServerMessage::new );
registerMainThread( 2, NetworkDirection.PLAY_TO_SERVER, RequestComputerMessage::new );
registerMainThread( 3, NetworkDirection.PLAY_TO_SERVER, KeyEventServerMessage::new );
registerMainThread( 4, NetworkDirection.PLAY_TO_SERVER, MouseEventServerMessage::new );
registerMainThread(0, ComputerActionServerMessage::new);
registerMainThread(1, QueueEventServerMessage::new);
registerMainThread(2, RequestComputerMessage::new);
registerMainThread(3, KeyEventServerMessage::new);
registerMainThread(4, MouseEventServerMessage::new);
// Client messages
registerMainThread( 10, NetworkDirection.PLAY_TO_CLIENT, ChatTableClientMessage::new );
registerMainThread( 11, NetworkDirection.PLAY_TO_CLIENT, ComputerDataClientMessage::new );
registerMainThread( 12, NetworkDirection.PLAY_TO_CLIENT, ComputerDeletedClientMessage::new );
registerMainThread( 13, NetworkDirection.PLAY_TO_CLIENT, ComputerTerminalClientMessage::new );
registerMainThread( 14, NetworkDirection.PLAY_TO_CLIENT, PlayRecordClientMessage.class, PlayRecordClientMessage::new );
registerMainThread( 15, NetworkDirection.PLAY_TO_CLIENT, MonitorClientMessage.class, MonitorClientMessage::new );
registerMainThread(10, ChatTableClientMessage::new);
registerMainThread(11, ComputerDataClientMessage::new);
registerMainThread(12, ComputerDeletedClientMessage::new);
registerMainThread(13, ComputerTerminalClientMessage::new);
registerMainThread(14, PlayRecordClientMessage.class, PlayRecordClientMessage::new);
}
public static void sendToPlayer( PlayerEntity player, NetworkMessage packet )
{
network.sendTo( packet, ((ServerPlayerEntity) player).networkHandler.connection, NetworkDirection.PLAY_TO_CLIENT );
}
public static void sendToAllPlayers( NetworkMessage packet )
{
for( ServerPlayerEntity player : ServerLifecycleHooks.getCurrentServer().getPlayerManager().getPlayerList() )
{
sendToPlayer( player, packet );
}
}
public static void sendToServer( NetworkMessage packet )
{
network.sendToServer( packet );
}
public static void sendToAllAround( NetworkMessage packet, World world, Vec3d pos, double range )
{
PacketDistributor.TargetPoint target = new PacketDistributor.TargetPoint( pos.x, pos.y, pos.z, range, world.getRegistryKey() );
network.send( PacketDistributor.NEAR.with( () -> target ), packet );
}
public static void sendToAllTracking( NetworkMessage packet, WorldChunk chunk )
{
network.send( PacketDistributor.TRACKING_CHUNK.with( () -> chunk ), packet );
private static void receive(PacketContext context, PacketByteBuf buffer) {
int type = buffer.readByte();
packetReaders.get(type)
.accept(context, buffer);
}
/**
* /**
* Register packet, and a thread-unsafe handler for it.
* /** Register packet, and a thread-unsafe handler for it.
*
* @param <T> The type of the packet to send.
* @param id The identifier for this packet type.
* @param direction A network direction which will be asserted before any processing of this message occurs.
* @param factory The factory for this type of packet.
* @param id The identifier for this packet type
* @param factory The factory for this type of packet.
*/
private static <T extends NetworkMessage> void registerMainThread( int id, NetworkDirection direction, Supplier<T> factory )
{
registerMainThread( id, direction, getType( factory ), buf -> {
private static <T extends NetworkMessage> void registerMainThread(int id, Supplier<T> factory) {
registerMainThread(id, getType(factory), buf -> {
T instance = factory.get();
instance.fromBytes( buf );
instance.fromBytes(buf);
return instance;
} );
});
}
/**
* /**
* Register packet, and a thread-unsafe handler for it.
* /** Register packet, and a thread-unsafe handler for it.
*
* @param <T> The type of the packet to send.
* @param type The class of the type of packet to send.
* @param id The identifier for this packet type.
* @param direction A network direction which will be asserted before any processing of this message occurs
* @param decoder The factory for this type of packet.
* @param id The identifier for this packet type
* @param decoder The factory for this type of packet.
*/
private static <T extends NetworkMessage> void registerMainThread( int id, NetworkDirection direction, Class<T> type, Function<PacketByteBuf, T> decoder )
{
network.messageBuilder( type, id, direction )
.encoder( NetworkMessage::toBytes )
.decoder( decoder )
.consumer( ( packet, contextSup ) -> {
NetworkEvent.Context context = contextSup.get();
context.enqueueWork( () -> packet.handle( context ) );
context.setPacketHandled( true );
} )
.add();
private static <T extends NetworkMessage> void registerMainThread(int id, Class<T> type, Function<PacketByteBuf, T> decoder) {
packetIds.put(type, id);
packetReaders.put(id, (context, buf) -> {
T result = decoder.apply(buf);
context.getTaskQueue()
.execute(() -> result.handle(context));
});
}
@SuppressWarnings( "unchecked" )
private static <T> Class<T> getType( Supplier<T> supplier )
{
return (Class<T>) supplier.get().getClass();
@SuppressWarnings ("unchecked")
private static <T> Class<T> getType(Supplier<T> supplier) {
return (Class<T>) supplier.get()
.getClass();
}
public static void sendToPlayer(PlayerEntity player, NetworkMessage packet) {
((ServerPlayerEntity) player).networkHandler.sendPacket(new CustomPayloadS2CPacket(ID, encode(packet)));
}
private static PacketByteBuf encode(NetworkMessage message) {
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
buf.writeByte(packetIds.getInt(message.getClass()));
message.toBytes(buf);
return buf;
}
public static void sendToAllPlayers(MinecraftServer server, NetworkMessage packet) {
server.getPlayerManager()
.sendToAll(new CustomPayloadS2CPacket(ID, encode(packet)));
}
@Environment(EnvType.CLIENT)
public static void sendToServer(NetworkMessage packet) {
MinecraftClient.getInstance().player.networkHandler.sendPacket(new CustomPayloadC2SPacket(ID, encode(packet)));
}
public static void sendToAllAround(NetworkMessage packet, World world, Vec3d pos, double range) {
world.getServer()
.getPlayerManager()
.sendToAround(null,
pos.x,
pos.y,
pos.z,
range,
world.getRegistryKey(),
new CustomPayloadS2CPacket(ID, encode(packet)));
}
}

View File

@@ -5,11 +5,10 @@
*/
package dan200.computercraft.shared.network;
import javax.annotation.Nonnull;
import net.fabricmc.fabric.api.network.PacketContext;
import net.minecraft.network.PacketByteBuf;
import net.fabricmc.fabric.api.network.PacketContext;
import javax.annotation.Nonnull;
/**
* The base interface for any message which will be sent to the client or server.

View File

@@ -10,11 +10,9 @@ import dan200.computercraft.shared.command.text.TableBuilder;
import dan200.computercraft.shared.network.NetworkMessage;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.network.PacketContext;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.text.Text;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.network.NetworkEvent;
import javax.annotation.Nonnull;
@@ -83,7 +81,7 @@ public class ChatTableClientMessage implements NetworkMessage
@Override
@Environment(EnvType.CLIENT)
public void handle( NetworkEvent.Context context )
public void handle( PacketContext context )
{
ClientTableFormatter.INSTANCE.display( table );
}

View File

@@ -7,9 +7,9 @@ package dan200.computercraft.shared.network.client;
import dan200.computercraft.shared.computer.core.ComputerState;
import dan200.computercraft.shared.computer.core.ServerComputer;
import net.fabricmc.fabric.api.network.PacketContext;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.PacketByteBuf;
import net.minecraftforge.fml.network.NetworkEvent;
import javax.annotation.Nonnull;
@@ -49,7 +49,7 @@ public class ComputerDataClientMessage extends ComputerClientMessage
}
@Override
public void handle( NetworkEvent.Context context )
public void handle( PacketContext context )
{
getComputer().setState( state, userData );
}

View File

@@ -6,7 +6,7 @@
package dan200.computercraft.shared.network.client;
import dan200.computercraft.ComputerCraft;
import net.minecraftforge.fml.network.NetworkEvent;
import net.fabricmc.fabric.api.network.PacketContext;
public class ComputerDeletedClientMessage extends ComputerClientMessage
{
@@ -20,7 +20,7 @@ public class ComputerDeletedClientMessage extends ComputerClientMessage
}
@Override
public void handle( NetworkEvent.Context context )
public void handle( PacketContext context )
{
ComputerCraft.clientComputerRegistry.remove( getInstanceId() );
}

View File

@@ -5,8 +5,8 @@
*/
package dan200.computercraft.shared.network.client;
import net.fabricmc.fabric.api.network.PacketContext;
import net.minecraft.network.PacketByteBuf;
import net.minecraftforge.fml.network.NetworkEvent;
import javax.annotation.Nonnull;
@@ -39,7 +39,7 @@ public class ComputerTerminalClientMessage extends ComputerClientMessage
}
@Override
public void handle( NetworkEvent.Context context )
public void handle( PacketContext context )
{
getComputer().read( state );
}

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