mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 04:00:30 +00:00
Remove ClientComputer
Historically CC has maintained two computer registries; one on the server (which runs the actual computer) and one on the client (which stores the terminal and some small bits of additional data). This means when a user opens the computer UI, we send the terminal contents and store it in the client computer registry. We then send the instance id alongside the "open container" packet, which is used to look up the client computer (and thus terminal) in our client-side registry. This patch makes the computer menu syncing behaviour more consistent with vanilla. The initial terminal contents is sent alongside the "open container" packet, and subsequent terminal changes apply /just/ to the open container. Computer on/off state is synced via a vanilla ContainerData/IIntArray. Likewise, sending user input to the server now targets the open container, rather than an arbitrary instance id. The one remaining usage of ClientComputer is for pocket computers. For these, we still need to sync the current on/off/blinking state and the pocket computer light. We don't need the full ClientComputer interface for this case (after all, you can't send input to a pocket computer someone else is holding!). This means we can tear out ClientComputer and ClientComputerRegistry, replacing it with a much simpler ClientPocketComputers store. This in turn allows the following changes: - Remove IComputer, as we no longer need to abstract over client and server computers. - Likewise, we can merge ComputerRegistry into the server registry. This commit also cleans up the handling of instance IDs a little bit: ServerComputers are now responsible for generating their ID and adding/removing themselves from the registry. - As the client-side terminal will never be null, we can remove a whole bunch of null checks throughout the codebase. - As the terminal is available immediately, we don't need to explicitly pass in terminal sizes to the computer GUIs. This means we're no longer reliant on those config values on the client side! - Remove the "request computer state" packet. Pocket computers now store which players need to know the computer state, automatically sending data when a new player starts tracking the computer.
This commit is contained in:
parent
a9b74dc979
commit
c49547b962
@ -10,8 +10,6 @@ import dan200.computercraft.core.apis.http.options.Action;
|
|||||||
import dan200.computercraft.core.apis.http.options.AddressRule;
|
import dan200.computercraft.core.apis.http.options.AddressRule;
|
||||||
import dan200.computercraft.shared.Config;
|
import dan200.computercraft.shared.Config;
|
||||||
import dan200.computercraft.shared.Registry;
|
import dan200.computercraft.shared.Registry;
|
||||||
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.peripheral.monitor.MonitorRenderer;
|
||||||
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
|
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
|
||||||
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
|
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
|
||||||
@ -105,11 +103,6 @@ public final class ComputerCraft
|
|||||||
public static PocketSpeaker speaker;
|
public static PocketSpeaker speaker;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registries
|
|
||||||
public static final ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry();
|
|
||||||
public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();
|
|
||||||
|
|
||||||
// Logging
|
|
||||||
public static final Logger log = LogManager.getLogger( MOD_ID );
|
public static final Logger log = LogManager.getLogger( MOD_ID );
|
||||||
|
|
||||||
public ComputerCraft()
|
public ComputerCraft()
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package dan200.computercraft.client;
|
package dan200.computercraft.client;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.client.pocket.ClientPocketComputers;
|
||||||
import dan200.computercraft.client.sound.SpeakerManager;
|
import dan200.computercraft.client.sound.SpeakerManager;
|
||||||
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
@ -30,12 +31,12 @@ public class ClientHooks
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onLogIn( ClientPlayerNetworkEvent.LoggedInEvent event )
|
public static void onLogIn( ClientPlayerNetworkEvent.LoggedInEvent event )
|
||||||
{
|
{
|
||||||
ComputerCraft.clientComputerRegistry.reset();
|
ClientPocketComputers.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onLogOut( ClientPlayerNetworkEvent.LoggedOutEvent event )
|
public static void onLogOut( ClientPlayerNetworkEvent.LoggedOutEvent event )
|
||||||
{
|
{
|
||||||
ComputerCraft.clientComputerRegistry.reset();
|
ClientPocketComputers.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ package dan200.computercraft.client;
|
|||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.client.gui.*;
|
import dan200.computercraft.client.gui.*;
|
||||||
|
import dan200.computercraft.client.pocket.ClientPocketComputers;
|
||||||
import dan200.computercraft.client.render.TileEntityMonitorRenderer;
|
import dan200.computercraft.client.render.TileEntityMonitorRenderer;
|
||||||
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
|
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
|
||||||
import dan200.computercraft.client.render.TurtleModelLoader;
|
import dan200.computercraft.client.render.TurtleModelLoader;
|
||||||
@ -16,7 +17,6 @@ import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
|||||||
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
||||||
import dan200.computercraft.shared.media.items.ItemDisk;
|
import dan200.computercraft.shared.media.items.ItemDisk;
|
||||||
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
|
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
|
||||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
|
||||||
import dan200.computercraft.shared.util.Colour;
|
import dan200.computercraft.shared.util.Colour;
|
||||||
import net.minecraft.client.gui.ScreenManager;
|
import net.minecraft.client.gui.ScreenManager;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
@ -106,7 +106,7 @@ public final class ClientRegistry
|
|||||||
return IColouredItem.getColourBasic( stack );
|
return IColouredItem.getColourBasic( stack );
|
||||||
case 2: // Light colour
|
case 2: // Light colour
|
||||||
{
|
{
|
||||||
int light = ItemPocketComputer.getLightState( stack );
|
int light = ClientPocketComputers.get( stack ).getLightState();
|
||||||
return light == -1 ? Colour.BLACK.getHex() : light;
|
return light == -1 ? Colour.BLACK.getHex() : light;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ public final class ClientRegistry
|
|||||||
registerContainers();
|
registerContainers();
|
||||||
|
|
||||||
registerItemProperty( "state",
|
registerItemProperty( "state",
|
||||||
( stack, world, player ) -> ItemPocketComputer.getState( stack ).ordinal(),
|
( stack, world, player ) -> ClientPocketComputers.get( stack ).getState().ordinal(),
|
||||||
Registry.ModItems.POCKET_COMPUTER_NORMAL, Registry.ModItems.POCKET_COMPUTER_ADVANCED
|
Registry.ModItems.POCKET_COMPUTER_NORMAL, Registry.ModItems.POCKET_COMPUTER_ADVANCED
|
||||||
);
|
);
|
||||||
registerItemProperty( "coloured",
|
registerItemProperty( "coloured",
|
||||||
@ -165,8 +165,8 @@ public final class ClientRegistry
|
|||||||
{
|
{
|
||||||
// My IDE doesn't think so, but we do actually need these generics.
|
// My IDE doesn't think so, but we do actually need these generics.
|
||||||
|
|
||||||
ScreenManager.<ContainerComputerBase, GuiComputer<ContainerComputerBase>>register( Registry.ModContainers.COMPUTER.get(), GuiComputer::create );
|
ScreenManager.<ContainerComputerBase, GuiComputer<ContainerComputerBase>>register( Registry.ModContainers.COMPUTER.get(), GuiComputer::new );
|
||||||
ScreenManager.<ContainerComputerBase, GuiComputer<ContainerComputerBase>>register( Registry.ModContainers.POCKET_COMPUTER.get(), GuiComputer::createPocket );
|
ScreenManager.<ContainerComputerBase, GuiComputer<ContainerComputerBase>>register( Registry.ModContainers.POCKET_COMPUTER.get(), GuiComputer::new );
|
||||||
ScreenManager.<ContainerComputerBase, NoTermComputerScreen<ContainerComputerBase>>register( Registry.ModContainers.POCKET_COMPUTER_NO_TERM.get(), NoTermComputerScreen::new );
|
ScreenManager.<ContainerComputerBase, NoTermComputerScreen<ContainerComputerBase>>register( Registry.ModContainers.POCKET_COMPUTER_NO_TERM.get(), NoTermComputerScreen::new );
|
||||||
ScreenManager.register( Registry.ModContainers.TURTLE.get(), GuiTurtle::new );
|
ScreenManager.register( Registry.ModContainers.TURTLE.get(), GuiTurtle::new );
|
||||||
|
|
||||||
@ -174,6 +174,6 @@ public final class ClientRegistry
|
|||||||
ScreenManager.register( Registry.ModContainers.DISK_DRIVE.get(), GuiDiskDrive::new );
|
ScreenManager.register( Registry.ModContainers.DISK_DRIVE.get(), GuiDiskDrive::new );
|
||||||
ScreenManager.register( Registry.ModContainers.PRINTOUT.get(), GuiPrintout::new );
|
ScreenManager.register( Registry.ModContainers.PRINTOUT.get(), GuiPrintout::new );
|
||||||
|
|
||||||
ScreenManager.<ContainerViewComputer, GuiComputer<ContainerViewComputer>>register( Registry.ModContainers.VIEW_COMPUTER.get(), GuiComputer::createView );
|
ScreenManager.<ContainerViewComputer, GuiComputer<ContainerViewComputer>>register( Registry.ModContainers.VIEW_COMPUTER.get(), GuiComputer::new );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.client.gui;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.computer.core.InputHandler;
|
||||||
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
|
import dan200.computercraft.shared.network.server.ComputerActionServerMessage;
|
||||||
|
import dan200.computercraft.shared.network.server.KeyEventServerMessage;
|
||||||
|
import dan200.computercraft.shared.network.server.MouseEventServerMessage;
|
||||||
|
import dan200.computercraft.shared.network.server.QueueEventServerMessage;
|
||||||
|
import net.minecraft.inventory.container.Container;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link InputHandler} which for use on the client.
|
||||||
|
* <p>
|
||||||
|
* This queues events on the remote player's open {@link ComputerMenu}
|
||||||
|
*/
|
||||||
|
public final class ClientInputHandler implements InputHandler
|
||||||
|
{
|
||||||
|
private final Container menu;
|
||||||
|
|
||||||
|
public ClientInputHandler( Container menu )
|
||||||
|
{
|
||||||
|
this.menu = menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void turnOn()
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( new ComputerActionServerMessage( menu, ComputerActionServerMessage.Action.TURN_ON ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown()
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( new ComputerActionServerMessage( menu, ComputerActionServerMessage.Action.SHUTDOWN ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reboot()
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( new ComputerActionServerMessage( menu, ComputerActionServerMessage.Action.REBOOT ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueEvent( String event, @Nullable Object[] arguments )
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( new QueueEventServerMessage( menu, event, arguments ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyDown( int key, boolean repeat )
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( new KeyEventServerMessage( menu, repeat ? KeyEventServerMessage.TYPE_REPEAT : KeyEventServerMessage.TYPE_DOWN, key ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyUp( int key )
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( new KeyEventServerMessage( menu, KeyEventServerMessage.TYPE_UP, key ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClick( int button, int x, int y )
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( new MouseEventServerMessage( menu, MouseEventServerMessage.TYPE_CLICK, button, x, y ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseUp( int button, int x, int y )
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( new MouseEventServerMessage( menu, MouseEventServerMessage.TYPE_UP, button, x, y ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDrag( int button, int x, int y )
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( new MouseEventServerMessage( menu, MouseEventServerMessage.TYPE_DRAG, button, x, y ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseScroll( int direction, int x, int y )
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( new MouseEventServerMessage( menu, MouseEventServerMessage.TYPE_SCROLL, direction, x, y ) );
|
||||||
|
}
|
||||||
|
}
|
@ -10,8 +10,9 @@ import dan200.computercraft.ComputerCraft;
|
|||||||
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
|
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
|
||||||
import dan200.computercraft.client.gui.widgets.DynamicImageButton;
|
import dan200.computercraft.client.gui.widgets.DynamicImageButton;
|
||||||
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
|
import dan200.computercraft.shared.computer.core.InputHandler;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
||||||
import dan200.computercraft.shared.computer.upload.FileUpload;
|
import dan200.computercraft.shared.computer.upload.FileUpload;
|
||||||
import dan200.computercraft.shared.computer.upload.UploadResult;
|
import dan200.computercraft.shared.computer.upload.UploadResult;
|
||||||
@ -42,16 +43,18 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
|
|||||||
private static final ITextComponent OVERWRITE = new TranslationTextComponent( "gui.computercraft.upload.overwrite_button" );
|
private static final ITextComponent OVERWRITE = new TranslationTextComponent( "gui.computercraft.upload.overwrite_button" );
|
||||||
|
|
||||||
protected WidgetTerminal terminal;
|
protected WidgetTerminal terminal;
|
||||||
protected final ClientComputer computer;
|
protected Terminal terminalData;
|
||||||
protected final ComputerFamily family;
|
protected final ComputerFamily family;
|
||||||
|
protected final InputHandler input;
|
||||||
|
|
||||||
protected final int sidebarYOffset;
|
protected final int sidebarYOffset;
|
||||||
|
|
||||||
public ComputerScreenBase( T container, PlayerInventory player, ITextComponent title, int sidebarYOffset )
|
public ComputerScreenBase( T container, PlayerInventory player, ITextComponent title, int sidebarYOffset )
|
||||||
{
|
{
|
||||||
super( container, player, title );
|
super( container, player, title );
|
||||||
computer = (ClientComputer) container.getComputer();
|
terminalData = container.getTerminal();
|
||||||
family = container.getFamily();
|
family = container.getFamily();
|
||||||
|
input = new ClientInputHandler( menu );
|
||||||
this.sidebarYOffset = sidebarYOffset;
|
this.sidebarYOffset = sidebarYOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +67,7 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
|
|||||||
minecraft.keyboardHandler.setSendRepeatsToGui( true );
|
minecraft.keyboardHandler.setSendRepeatsToGui( true );
|
||||||
|
|
||||||
terminal = addButton( createTerminal() );
|
terminal = addButton( createTerminal() );
|
||||||
ComputerSidebar.addButtons( this, computer, this::addButton, leftPos, topPos + sidebarYOffset );
|
ComputerSidebar.addButtons( this, menu::isOn, input, this::addButton, leftPos, topPos + sidebarYOffset );
|
||||||
setFocused( terminal );
|
setFocused( terminal );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +135,7 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
|
|||||||
{
|
{
|
||||||
if( files.isEmpty() ) return;
|
if( files.isEmpty() ) return;
|
||||||
|
|
||||||
if( computer == null || !computer.isOn() )
|
if( !menu.isOn() )
|
||||||
{
|
{
|
||||||
alert( UploadResult.FAILED_TITLE, UploadResult.COMPUTER_OFF_MSG );
|
alert( UploadResult.FAILED_TITLE, UploadResult.COMPUTER_OFF_MSG );
|
||||||
return;
|
return;
|
||||||
@ -188,10 +191,7 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( toUpload.size() > 0 )
|
if( toUpload.size() > 0 ) UploadFileMessage.send( menu, toUpload );
|
||||||
{
|
|
||||||
UploadFileMessage.send( computer.getInstanceID(), toUpload );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uploadResult( UploadResult result, ITextComponent message )
|
public void uploadResult( UploadResult result, ITextComponent message )
|
||||||
@ -220,13 +220,13 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
|
|||||||
private void continueUpload()
|
private void continueUpload()
|
||||||
{
|
{
|
||||||
if( minecraft.screen instanceof OptionScreen ) ((OptionScreen) minecraft.screen).disable();
|
if( minecraft.screen instanceof OptionScreen ) ((OptionScreen) minecraft.screen).disable();
|
||||||
NetworkHandler.sendToServer( new ContinueUploadMessage( computer.getInstanceID(), true ) );
|
NetworkHandler.sendToServer( new ContinueUploadMessage( menu, true ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelUpload()
|
private void cancelUpload()
|
||||||
{
|
{
|
||||||
minecraft.setScreen( this );
|
minecraft.setScreen( this );
|
||||||
NetworkHandler.sendToServer( new ContinueUploadMessage( computer.getInstanceID(), false ) );
|
NetworkHandler.sendToServer( new ContinueUploadMessage( menu, false ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void alert( ITextComponent title, ITextComponent message )
|
private void alert( ITextComponent title, ITextComponent message )
|
||||||
|
@ -6,12 +6,11 @@
|
|||||||
package dan200.computercraft.client.gui;
|
package dan200.computercraft.client.gui;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
|
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
|
||||||
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||||
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
||||||
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
|
||||||
@ -22,50 +21,20 @@ import static dan200.computercraft.client.render.RenderTypes.FULL_BRIGHT_LIGHTMA
|
|||||||
|
|
||||||
public final class GuiComputer<T extends ContainerComputerBase> extends ComputerScreenBase<T>
|
public final class GuiComputer<T extends ContainerComputerBase> extends ComputerScreenBase<T>
|
||||||
{
|
{
|
||||||
private final int termWidth;
|
public GuiComputer( T container, PlayerInventory player, ITextComponent title )
|
||||||
private final int termHeight;
|
|
||||||
|
|
||||||
private GuiComputer(
|
|
||||||
T container, PlayerInventory player, ITextComponent title, int termWidth, int termHeight
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
super( container, player, title, BORDER );
|
super( container, player, title, BORDER );
|
||||||
this.termWidth = termWidth;
|
|
||||||
this.termHeight = termHeight;
|
|
||||||
|
|
||||||
imageWidth = WidgetTerminal.getWidth( termWidth ) + BORDER * 2 + ComputerSidebar.WIDTH;
|
imageWidth = WidgetTerminal.getWidth( terminalData.getWidth() ) + BORDER * 2 + ComputerSidebar.WIDTH;
|
||||||
imageHeight = WidgetTerminal.getHeight( termHeight ) + BORDER * 2;
|
imageHeight = WidgetTerminal.getHeight( terminalData.getHeight() ) + BORDER * 2;
|
||||||
}
|
|
||||||
|
|
||||||
public static GuiComputer<ContainerComputerBase> create( ContainerComputerBase container, PlayerInventory inventory, ITextComponent component )
|
|
||||||
{
|
|
||||||
return new GuiComputer<>(
|
|
||||||
container, inventory, component,
|
|
||||||
ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GuiComputer<ContainerComputerBase> createPocket( ContainerComputerBase container, PlayerInventory inventory, ITextComponent component )
|
|
||||||
{
|
|
||||||
return new GuiComputer<>(
|
|
||||||
container, inventory, component,
|
|
||||||
ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GuiComputer<ContainerViewComputer> createView( ContainerViewComputer container, PlayerInventory inventory, ITextComponent component )
|
|
||||||
{
|
|
||||||
return new GuiComputer<>(
|
|
||||||
container, inventory, component,
|
|
||||||
container.getWidth(), container.getHeight()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WidgetTerminal createTerminal()
|
protected WidgetTerminal createTerminal()
|
||||||
{
|
{
|
||||||
return new WidgetTerminal( computer,
|
return new WidgetTerminal(
|
||||||
leftPos + ComputerSidebar.WIDTH + BORDER, topPos + BORDER, termWidth, termHeight
|
getMenu().getFamily() != ComputerFamily.NORMAL, terminalData, input,
|
||||||
|
leftPos + ComputerSidebar.WIDTH + BORDER, topPos + BORDER
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ public class GuiTurtle extends ComputerScreenBase<ContainerTurtle>
|
|||||||
protected WidgetTerminal createTerminal()
|
protected WidgetTerminal createTerminal()
|
||||||
{
|
{
|
||||||
return new WidgetTerminal(
|
return new WidgetTerminal(
|
||||||
computer, leftPos + BORDER + ComputerSidebar.WIDTH, topPos + BORDER,
|
getMenu().getFamily() != ComputerFamily.NORMAL, terminalData, input,
|
||||||
ComputerCraft.turtleTermWidth, ComputerCraft.turtleTermHeight
|
leftPos + BORDER + ComputerSidebar.WIDTH, topPos + BORDER
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
package dan200.computercraft.client.gui;
|
package dan200.computercraft.client.gui;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
||||||
import net.minecraft.client.gui.FontRenderer;
|
import net.minecraft.client.gui.FontRenderer;
|
||||||
import net.minecraft.client.gui.IHasContainer;
|
import net.minecraft.client.gui.IHasContainer;
|
||||||
@ -26,12 +26,14 @@ import java.util.List;
|
|||||||
public class NoTermComputerScreen<T extends ContainerComputerBase> extends Screen implements IHasContainer<T>
|
public class NoTermComputerScreen<T extends ContainerComputerBase> extends Screen implements IHasContainer<T>
|
||||||
{
|
{
|
||||||
private final T menu;
|
private final T menu;
|
||||||
|
private final Terminal terminalData;
|
||||||
private WidgetTerminal terminal;
|
private WidgetTerminal terminal;
|
||||||
|
|
||||||
public NoTermComputerScreen( T menu, PlayerInventory player, ITextComponent title )
|
public NoTermComputerScreen( T menu, PlayerInventory player, ITextComponent title )
|
||||||
{
|
{
|
||||||
super( title );
|
super( title );
|
||||||
this.menu = menu;
|
this.menu = menu;
|
||||||
|
terminalData = menu.getTerminal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -54,7 +56,7 @@ public class NoTermComputerScreen<T extends ContainerComputerBase> extends Scree
|
|||||||
super.init();
|
super.init();
|
||||||
minecraft.keyboardHandler.setSendRepeatsToGui( true );
|
minecraft.keyboardHandler.setSendRepeatsToGui( true );
|
||||||
|
|
||||||
terminal = addWidget( new WidgetTerminal( (ClientComputer) menu.getComputer(), 0, 0, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight ) );
|
terminal = addWidget( new WidgetTerminal( getMenu().getFamily() != ComputerFamily.NORMAL, terminalData, new ClientInputHandler( menu ), 0, 0 ) );
|
||||||
terminal.visible = false;
|
terminal.visible = false;
|
||||||
terminal.active = false;
|
terminal.active = false;
|
||||||
setFocused( terminal );
|
setFocused( terminal );
|
||||||
|
@ -8,7 +8,7 @@ package dan200.computercraft.client.gui.widgets;
|
|||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
||||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
import dan200.computercraft.shared.computer.core.InputHandler;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import net.minecraft.client.gui.widget.Widget;
|
import net.minecraft.client.gui.widget.Widget;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
@ -16,6 +16,7 @@ import net.minecraft.util.text.TextFormatting;
|
|||||||
import net.minecraft.util.text.TranslationTextComponent;
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,15 +45,15 @@ public final class ComputerSidebar
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addButtons( Screen screen, ClientComputer computer, Consumer<Widget> add, int x, int y )
|
public static void addButtons( Screen screen, BooleanSupplier isOn, InputHandler input, Consumer<Widget> add, int x, int y )
|
||||||
{
|
{
|
||||||
x += CORNERS_BORDER + 1;
|
x += CORNERS_BORDER + 1;
|
||||||
y += CORNERS_BORDER + ICON_MARGIN;
|
y += CORNERS_BORDER + ICON_MARGIN;
|
||||||
|
|
||||||
add.accept( new DynamicImageButton(
|
add.accept( new DynamicImageButton(
|
||||||
screen, x, y, ICON_WIDTH, ICON_HEIGHT, () -> computer.isOn() ? 15 : 1, 1, ICON_TEX_Y_DIFF,
|
screen, x, y, ICON_WIDTH, ICON_HEIGHT, () -> isOn.getAsBoolean() ? 15 : 1, 1, ICON_TEX_Y_DIFF,
|
||||||
TEXTURE, TEX_SIZE, TEX_SIZE, b -> toggleComputer( computer ),
|
TEXTURE, TEX_SIZE, TEX_SIZE, b -> toggleComputer( isOn, input ),
|
||||||
() -> computer.isOn() ? Arrays.asList(
|
() -> isOn.getAsBoolean() ? Arrays.asList(
|
||||||
new TranslationTextComponent( "gui.computercraft.tooltip.turn_off" ),
|
new TranslationTextComponent( "gui.computercraft.tooltip.turn_off" ),
|
||||||
new TranslationTextComponent( "gui.computercraft.tooltip.turn_off.key" ).withStyle( TextFormatting.GRAY )
|
new TranslationTextComponent( "gui.computercraft.tooltip.turn_off.key" ).withStyle( TextFormatting.GRAY )
|
||||||
) : Arrays.asList(
|
) : Arrays.asList(
|
||||||
@ -65,7 +66,7 @@ public final class ComputerSidebar
|
|||||||
|
|
||||||
add.accept( new DynamicImageButton(
|
add.accept( new DynamicImageButton(
|
||||||
screen, x, y, ICON_WIDTH, ICON_HEIGHT, 29, 1, ICON_TEX_Y_DIFF,
|
screen, x, y, ICON_WIDTH, ICON_HEIGHT, 29, 1, ICON_TEX_Y_DIFF,
|
||||||
TEXTURE, TEX_SIZE, TEX_SIZE, b -> computer.queueEvent( "terminate" ),
|
TEXTURE, TEX_SIZE, TEX_SIZE, b -> input.queueEvent( "terminate" ),
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
new TranslationTextComponent( "gui.computercraft.tooltip.terminate" ),
|
new TranslationTextComponent( "gui.computercraft.tooltip.terminate" ),
|
||||||
new TranslationTextComponent( "gui.computercraft.tooltip.terminate.key" ).withStyle( TextFormatting.GRAY )
|
new TranslationTextComponent( "gui.computercraft.tooltip.terminate.key" ).withStyle( TextFormatting.GRAY )
|
||||||
@ -92,15 +93,15 @@ public final class ComputerSidebar
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void toggleComputer( ClientComputer computer )
|
private static void toggleComputer( BooleanSupplier isOn, InputHandler input )
|
||||||
{
|
{
|
||||||
if( computer.isOn() )
|
if( isOn.getAsBoolean() )
|
||||||
{
|
{
|
||||||
computer.shutdown();
|
input.shutdown();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
computer.turnOn();
|
input.turnOn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import com.mojang.blaze3d.vertex.IVertexBuilder;
|
|||||||
import dan200.computercraft.client.render.RenderTypes;
|
import dan200.computercraft.client.render.RenderTypes;
|
||||||
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
import dan200.computercraft.shared.computer.core.InputHandler;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.widget.Widget;
|
import net.minecraft.client.gui.widget.Widget;
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
@ -33,7 +33,10 @@ public class WidgetTerminal extends Widget
|
|||||||
{
|
{
|
||||||
private static final float TERMINATE_TIME = 0.5f;
|
private static final float TERMINATE_TIME = 0.5f;
|
||||||
|
|
||||||
private final ClientComputer computer;
|
private final boolean isColour;
|
||||||
|
private final @Nonnull Terminal terminal;
|
||||||
|
private final @Nonnull InputHandler computer;
|
||||||
|
|
||||||
|
|
||||||
// The positions of the actual terminal
|
// The positions of the actual terminal
|
||||||
private final int innerX;
|
private final int innerX;
|
||||||
@ -51,16 +54,18 @@ public class WidgetTerminal extends Widget
|
|||||||
|
|
||||||
private final BitSet keysDown = new BitSet( 256 );
|
private final BitSet keysDown = new BitSet( 256 );
|
||||||
|
|
||||||
public WidgetTerminal( @Nonnull ClientComputer computer, int x, int y, int termWidth, int termHeight )
|
public WidgetTerminal( boolean isColour, @Nonnull Terminal terminal, @Nonnull InputHandler computer, int x, int y )
|
||||||
{
|
{
|
||||||
super( x, y, termWidth * FONT_WIDTH + MARGIN * 2, termHeight * FONT_HEIGHT + MARGIN * 2, StringTextComponent.EMPTY );
|
super( x, y, terminal.getWidth() * FONT_WIDTH + MARGIN * 2, terminal.getHeight() * FONT_HEIGHT + MARGIN * 2, StringTextComponent.EMPTY );
|
||||||
|
|
||||||
|
this.isColour = isColour;
|
||||||
|
this.terminal = terminal;
|
||||||
this.computer = computer;
|
this.computer = computer;
|
||||||
|
|
||||||
innerX = x + MARGIN;
|
innerX = x + MARGIN;
|
||||||
innerY = y + MARGIN;
|
innerY = y + MARGIN;
|
||||||
innerWidth = termWidth * FONT_WIDTH;
|
innerWidth = terminal.getWidth() * FONT_WIDTH;
|
||||||
innerHeight = termHeight * FONT_HEIGHT;
|
innerHeight = terminal.getHeight() * FONT_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -173,22 +178,18 @@ public class WidgetTerminal extends Widget
|
|||||||
public boolean mouseClicked( double mouseX, double mouseY, int button )
|
public boolean mouseClicked( double mouseX, double mouseY, int button )
|
||||||
{
|
{
|
||||||
if( !inTermRegion( mouseX, mouseY ) ) return false;
|
if( !inTermRegion( mouseX, mouseY ) ) return false;
|
||||||
if( !computer.isColour() || button < 0 || button > 2 ) return false;
|
if( !isColour || button < 0 || button > 2 ) return false;
|
||||||
|
|
||||||
Terminal term = computer.getTerminal();
|
int charX = (int) ((mouseX - innerX) / FONT_WIDTH);
|
||||||
if( term != null )
|
int charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
|
||||||
{
|
charX = Math.min( Math.max( charX, 0 ), terminal.getWidth() - 1 );
|
||||||
int charX = (int) ((mouseX - innerX) / FONT_WIDTH);
|
charY = Math.min( Math.max( charY, 0 ), terminal.getHeight() - 1 );
|
||||||
int charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
|
|
||||||
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
|
|
||||||
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
|
|
||||||
|
|
||||||
computer.mouseClick( button + 1, charX + 1, charY + 1 );
|
computer.mouseClick( button + 1, charX + 1, charY + 1 );
|
||||||
|
|
||||||
lastMouseButton = button;
|
lastMouseButton = button;
|
||||||
lastMouseX = charX;
|
lastMouseX = charX;
|
||||||
lastMouseY = charY;
|
lastMouseY = charY;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -197,26 +198,22 @@ public class WidgetTerminal extends Widget
|
|||||||
public boolean mouseReleased( double mouseX, double mouseY, int button )
|
public boolean mouseReleased( double mouseX, double mouseY, int button )
|
||||||
{
|
{
|
||||||
if( !inTermRegion( mouseX, mouseY ) ) return false;
|
if( !inTermRegion( mouseX, mouseY ) ) return false;
|
||||||
if( !computer.isColour() || button < 0 || button > 2 ) return false;
|
if( !isColour || button < 0 || button > 2 ) return false;
|
||||||
|
|
||||||
Terminal term = computer.getTerminal();
|
int charX = (int) ((mouseX - innerX) / FONT_WIDTH);
|
||||||
if( term != null )
|
int charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
|
||||||
|
charX = Math.min( Math.max( charX, 0 ), terminal.getWidth() - 1 );
|
||||||
|
charY = Math.min( Math.max( charY, 0 ), terminal.getHeight() - 1 );
|
||||||
|
|
||||||
|
if( lastMouseButton == button )
|
||||||
{
|
{
|
||||||
int charX = (int) ((mouseX - innerX) / FONT_WIDTH);
|
computer.mouseUp( lastMouseButton + 1, charX + 1, charY + 1 );
|
||||||
int charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
|
lastMouseButton = -1;
|
||||||
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
|
|
||||||
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
|
|
||||||
|
|
||||||
if( lastMouseButton == button )
|
|
||||||
{
|
|
||||||
computer.mouseUp( lastMouseButton + 1, charX + 1, charY + 1 );
|
|
||||||
lastMouseButton = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastMouseX = charX;
|
|
||||||
lastMouseY = charY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastMouseX = charX;
|
||||||
|
lastMouseY = charY;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,22 +221,18 @@ public class WidgetTerminal extends Widget
|
|||||||
public boolean mouseDragged( double mouseX, double mouseY, int button, double v2, double v3 )
|
public boolean mouseDragged( double mouseX, double mouseY, int button, double v2, double v3 )
|
||||||
{
|
{
|
||||||
if( !inTermRegion( mouseX, mouseY ) ) return false;
|
if( !inTermRegion( mouseX, mouseY ) ) return false;
|
||||||
if( !computer.isColour() || button < 0 || button > 2 ) return false;
|
if( !isColour || button < 0 || button > 2 ) return false;
|
||||||
|
|
||||||
Terminal term = computer.getTerminal();
|
int charX = (int) ((mouseX - innerX) / FONT_WIDTH);
|
||||||
if( term != null )
|
int charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
|
||||||
|
charX = Math.min( Math.max( charX, 0 ), terminal.getWidth() - 1 );
|
||||||
|
charY = Math.min( Math.max( charY, 0 ), terminal.getHeight() - 1 );
|
||||||
|
|
||||||
|
if( button == lastMouseButton && (charX != lastMouseX || charY != lastMouseY) )
|
||||||
{
|
{
|
||||||
int charX = (int) ((mouseX - innerX) / FONT_WIDTH);
|
computer.mouseDrag( button + 1, charX + 1, charY + 1 );
|
||||||
int charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
|
lastMouseX = charX;
|
||||||
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
|
lastMouseY = charY;
|
||||||
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
|
|
||||||
|
|
||||||
if( button == lastMouseButton && (charX != lastMouseX || charY != lastMouseY) )
|
|
||||||
{
|
|
||||||
computer.mouseDrag( button + 1, charX + 1, charY + 1 );
|
|
||||||
lastMouseX = charX;
|
|
||||||
lastMouseY = charY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -249,21 +242,17 @@ public class WidgetTerminal extends Widget
|
|||||||
public boolean mouseScrolled( double mouseX, double mouseY, double delta )
|
public boolean mouseScrolled( double mouseX, double mouseY, double delta )
|
||||||
{
|
{
|
||||||
if( !inTermRegion( mouseX, mouseY ) ) return false;
|
if( !inTermRegion( mouseX, mouseY ) ) return false;
|
||||||
if( !computer.isColour() || delta == 0 ) return false;
|
if( !isColour || delta == 0 ) return false;
|
||||||
|
|
||||||
Terminal term = computer.getTerminal();
|
int charX = (int) ((mouseX - innerX) / FONT_WIDTH);
|
||||||
if( term != null )
|
int charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
|
||||||
{
|
charX = Math.min( Math.max( charX, 0 ), terminal.getWidth() - 1 );
|
||||||
int charX = (int) ((mouseX - innerX) / FONT_WIDTH);
|
charY = Math.min( Math.max( charY, 0 ), terminal.getHeight() - 1 );
|
||||||
int charY = (int) ((mouseY - innerY) / FONT_HEIGHT);
|
|
||||||
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
|
|
||||||
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
|
|
||||||
|
|
||||||
computer.mouseScroll( delta < 0 ? 1 : -1, charX + 1, charY + 1 );
|
computer.mouseScroll( delta < 0 ? 1 : -1, charX + 1, charY + 1 );
|
||||||
|
|
||||||
lastMouseX = charX;
|
lastMouseX = charX;
|
||||||
lastMouseY = charY;
|
lastMouseY = charY;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -319,7 +308,6 @@ public class WidgetTerminal extends Widget
|
|||||||
{
|
{
|
||||||
if( !visible ) return;
|
if( !visible ) return;
|
||||||
Matrix4f matrix = transform.last().pose();
|
Matrix4f matrix = transform.last().pose();
|
||||||
Terminal terminal = computer.getTerminal();
|
|
||||||
|
|
||||||
Minecraft.getInstance().getTextureManager().bind( FixedWidthFontRenderer.FONT );
|
Minecraft.getInstance().getTextureManager().bind( FixedWidthFontRenderer.FONT );
|
||||||
RenderSystem.texParameter( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
|
RenderSystem.texParameter( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
|
||||||
@ -329,7 +317,7 @@ public class WidgetTerminal extends Widget
|
|||||||
|
|
||||||
if( terminal != null )
|
if( terminal != null )
|
||||||
{
|
{
|
||||||
FixedWidthFontRenderer.drawTerminal( matrix, buffer, innerX, innerY, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN );
|
FixedWidthFontRenderer.drawTerminal( matrix, buffer, innerX, innerY, terminal, !isColour, MARGIN, MARGIN, MARGIN, MARGIN );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.client.pocket;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
|
import dan200.computercraft.shared.computer.items.ItemComputer;
|
||||||
|
import dan200.computercraft.shared.network.client.PocketComputerDataMessage;
|
||||||
|
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps {@link ServerComputer#getInstanceID()} to locals {@link PocketComputerData}.
|
||||||
|
* <p>
|
||||||
|
* This is populated by {@link PocketComputerDataMessage} and accessed when rendering pocket computers
|
||||||
|
*/
|
||||||
|
public final class ClientPocketComputers
|
||||||
|
{
|
||||||
|
private static final Int2ObjectMap<PocketComputerData> instances = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
private ClientPocketComputers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void reset()
|
||||||
|
{
|
||||||
|
instances.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void remove( int id )
|
||||||
|
{
|
||||||
|
instances.remove( id );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or create a pocket computer.
|
||||||
|
*
|
||||||
|
* @param instanceId The instance ID of the pocket computer.
|
||||||
|
* @param advanced Whether this computer has an advanced terminal.
|
||||||
|
* @return The pocket computer data.
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public static PocketComputerData get( int instanceId, boolean advanced )
|
||||||
|
{
|
||||||
|
PocketComputerData computer = instances.get( instanceId );
|
||||||
|
if( computer == null ) instances.put( instanceId, computer = new PocketComputerData( advanced ) );
|
||||||
|
return computer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static PocketComputerData get( ItemStack stack )
|
||||||
|
{
|
||||||
|
ComputerFamily family = stack.getItem() instanceof ItemComputer ? ((ItemComputer) stack.getItem()).getFamily() : ComputerFamily.NORMAL;
|
||||||
|
return get( ItemPocketComputer.getInstanceID( stack ), family != ComputerFamily.NORMAL );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.client.pocket;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
|
import dan200.computercraft.shared.computer.core.ComputerState;
|
||||||
|
import dan200.computercraft.shared.network.client.TerminalState;
|
||||||
|
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clientside data about a pocket computer.
|
||||||
|
* <p>
|
||||||
|
* Normal computers don't store any state long-term on the client - everything is tied to the container and only synced
|
||||||
|
* while the UI is open. Pocket computers are a little more complex, as their on/off state is visible on the item's
|
||||||
|
* texture, and the terminal can be viewed at any time. This class is what holds this needed data clientside.
|
||||||
|
*
|
||||||
|
* @see ClientPocketComputers The registry which holds pocket computers.
|
||||||
|
* @see PocketServerComputer The server-side pocket computer.
|
||||||
|
*/
|
||||||
|
public class PocketComputerData
|
||||||
|
{
|
||||||
|
private boolean isColour;
|
||||||
|
private Terminal terminal;
|
||||||
|
private ComputerState state = ComputerState.OFF;
|
||||||
|
private int lightColour = -1;
|
||||||
|
|
||||||
|
public PocketComputerData( boolean colour )
|
||||||
|
{
|
||||||
|
isColour = colour;
|
||||||
|
terminal = new Terminal( ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLightState()
|
||||||
|
{
|
||||||
|
return state != ComputerState.OFF ? lightColour : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isColour()
|
||||||
|
{
|
||||||
|
return isColour;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public Terminal getTerminal()
|
||||||
|
{
|
||||||
|
return terminal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComputerState getState()
|
||||||
|
{
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState( ComputerState state, int lightColour )
|
||||||
|
{
|
||||||
|
this.state = state;
|
||||||
|
this.lightColour = lightColour;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTerminal( TerminalState state )
|
||||||
|
{
|
||||||
|
isColour = state.colour;
|
||||||
|
if( state.width != terminal.getWidth() || state.height != terminal.getHeight() )
|
||||||
|
{
|
||||||
|
terminal = state.create();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.apply( terminal );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,9 +8,10 @@ package dan200.computercraft.client.render;
|
|||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.client.pocket.ClientPocketComputers;
|
||||||
|
import dan200.computercraft.client.pocket.PocketComputerData;
|
||||||
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||||
import dan200.computercraft.shared.util.Colour;
|
import dan200.computercraft.shared.util.Colour;
|
||||||
@ -56,20 +57,11 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
|
|||||||
@Override
|
@Override
|
||||||
protected void renderItem( MatrixStack transform, IRenderTypeBuffer bufferSource, ItemStack stack, int light )
|
protected void renderItem( MatrixStack transform, IRenderTypeBuffer bufferSource, ItemStack stack, int light )
|
||||||
{
|
{
|
||||||
ClientComputer computer = ItemPocketComputer.createClientComputer( stack );
|
PocketComputerData computer = ClientPocketComputers.get( stack );
|
||||||
Terminal terminal = computer == null ? null : computer.getTerminal();
|
Terminal terminal = computer.getTerminal();
|
||||||
|
|
||||||
int termWidth, termHeight;
|
int termWidth = terminal.getWidth();
|
||||||
if( terminal == null )
|
int termHeight = terminal.getHeight();
|
||||||
{
|
|
||||||
termWidth = ComputerCraft.pocketTermWidth;
|
|
||||||
termHeight = ComputerCraft.pocketTermHeight;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
termWidth = terminal.getWidth();
|
|
||||||
termHeight = terminal.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
int width = termWidth * FONT_WIDTH + MARGIN * 2;
|
int width = termWidth * FONT_WIDTH + MARGIN * 2;
|
||||||
int height = termHeight * FONT_HEIGHT + MARGIN * 2;
|
int height = termHeight * FONT_HEIGHT + MARGIN * 2;
|
||||||
@ -94,28 +86,18 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
|
|||||||
renderFrame( matrix, bufferSource, family, frameColour, light, width, height );
|
renderFrame( matrix, bufferSource, family, frameColour, light, width, height );
|
||||||
|
|
||||||
// Render the light
|
// Render the light
|
||||||
int lightColour = ItemPocketComputer.getLightState( stack );
|
int lightColour = ClientPocketComputers.get( stack ).getLightState();
|
||||||
if( lightColour == -1 ) lightColour = Colour.BLACK.getHex();
|
if( lightColour == -1 ) lightColour = Colour.BLACK.getHex();
|
||||||
renderLight( matrix, bufferSource, lightColour, width, height );
|
renderLight( matrix, bufferSource, lightColour, width, height );
|
||||||
|
|
||||||
if( computer != null && terminal != null )
|
FixedWidthFontRenderer.drawTerminal(
|
||||||
{
|
matrix, bufferSource.getBuffer( RenderTypes.TERMINAL_WITHOUT_DEPTH ),
|
||||||
FixedWidthFontRenderer.drawTerminal(
|
MARGIN, MARGIN, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN
|
||||||
matrix, bufferSource.getBuffer( RenderTypes.TERMINAL_WITHOUT_DEPTH ),
|
);
|
||||||
MARGIN, MARGIN, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN
|
FixedWidthFontRenderer.drawBlocker(
|
||||||
);
|
matrix, bufferSource.getBuffer( RenderTypes.TERMINAL_BLOCKER ),
|
||||||
FixedWidthFontRenderer.drawBlocker(
|
0, 0, width, height
|
||||||
matrix, bufferSource.getBuffer( RenderTypes.TERMINAL_BLOCKER ),
|
);
|
||||||
0, 0, width, height
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FixedWidthFontRenderer.drawEmptyTerminal(
|
|
||||||
matrix, bufferSource.getBuffer( RenderTypes.TERMINAL_WITH_DEPTH ),
|
|
||||||
0, 0, width, height
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
transform.popPose();
|
transform.popPose();
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,9 @@ import dan200.computercraft.core.filesystem.ResourceMount;
|
|||||||
import dan200.computercraft.core.tracking.ComputerMBean;
|
import dan200.computercraft.core.tracking.ComputerMBean;
|
||||||
import dan200.computercraft.core.tracking.Tracking;
|
import dan200.computercraft.core.tracking.Tracking;
|
||||||
import dan200.computercraft.shared.command.CommandComputerCraft;
|
import dan200.computercraft.shared.command.CommandComputerCraft;
|
||||||
import dan200.computercraft.shared.computer.core.IComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
|
||||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
|
||||||
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
|
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.inventory.container.Container;
|
|
||||||
import net.minecraft.loot.ConstantRange;
|
import net.minecraft.loot.ConstantRange;
|
||||||
import net.minecraft.loot.LootPool;
|
import net.minecraft.loot.LootPool;
|
||||||
import net.minecraft.loot.LootTables;
|
import net.minecraft.loot.LootTables;
|
||||||
@ -26,7 +23,6 @@ import net.minecraft.server.MinecraftServer;
|
|||||||
import net.minecraft.server.dedicated.DedicatedServer;
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraftforge.event.*;
|
import net.minecraftforge.event.*;
|
||||||
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||||
@ -56,22 +52,7 @@ public final class CommonHooks
|
|||||||
if( event.phase == TickEvent.Phase.START )
|
if( event.phase == TickEvent.Phase.START )
|
||||||
{
|
{
|
||||||
MainThread.executePendingTasks();
|
MainThread.executePendingTasks();
|
||||||
ComputerCraft.serverComputerRegistry.update();
|
ServerComputerRegistry.INSTANCE.update();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onContainerOpen( PlayerContainerEvent.Open event )
|
|
||||||
{
|
|
||||||
// If we're opening a computer container then broadcast the terminal state
|
|
||||||
Container container = event.getContainer();
|
|
||||||
if( container instanceof IContainerComputer )
|
|
||||||
{
|
|
||||||
IComputer computer = ((IContainerComputer) container).getComputer();
|
|
||||||
if( computer instanceof ServerComputer )
|
|
||||||
{
|
|
||||||
((ServerComputer) computer).sendTerminalState( event.getPlayer() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +83,7 @@ public final class CommonHooks
|
|||||||
|
|
||||||
private static void resetState()
|
private static void resetState()
|
||||||
{
|
{
|
||||||
ComputerCraft.serverComputerRegistry.reset();
|
ServerComputerRegistry.INSTANCE.reset();
|
||||||
MainThread.reset();
|
MainThread.reset();
|
||||||
WirelessNetwork.resetNetworks();
|
WirelessNetwork.resetNetworks();
|
||||||
Tracking.reset();
|
Tracking.reset();
|
||||||
|
@ -37,7 +37,6 @@ import dan200.computercraft.shared.network.NetworkHandler;
|
|||||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||||
import dan200.computercraft.shared.network.container.ContainerData;
|
import dan200.computercraft.shared.network.container.ContainerData;
|
||||||
import dan200.computercraft.shared.network.container.HeldItemContainerData;
|
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.BlockDiskDrive;
|
||||||
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
|
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
|
||||||
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
|
||||||
@ -306,7 +305,7 @@ public final class Registry
|
|||||||
() -> ContainerData.toType( ComputerContainerData::new, ComputerMenuWithoutInventory::new ) );
|
() -> ContainerData.toType( ComputerContainerData::new, ComputerMenuWithoutInventory::new ) );
|
||||||
|
|
||||||
public static final RegistryObject<ContainerType<ContainerTurtle>> TURTLE = CONTAINERS.register( "turtle",
|
public static final RegistryObject<ContainerType<ContainerTurtle>> TURTLE = CONTAINERS.register( "turtle",
|
||||||
() -> ContainerData.toType( ComputerContainerData::new, ContainerTurtle::new ) );
|
() -> ContainerData.toType( ComputerContainerData::new, ContainerTurtle::ofMenuData ) );
|
||||||
|
|
||||||
public static final RegistryObject<ContainerType<ContainerDiskDrive>> DISK_DRIVE = CONTAINERS.register( "disk_drive",
|
public static final RegistryObject<ContainerType<ContainerDiskDrive>> DISK_DRIVE = CONTAINERS.register( "disk_drive",
|
||||||
() -> new ContainerType<>( ContainerDiskDrive::new ) );
|
() -> new ContainerType<>( ContainerDiskDrive::new ) );
|
||||||
@ -318,7 +317,7 @@ public final class Registry
|
|||||||
() -> ContainerData.toType( HeldItemContainerData::new, ContainerHeldItem::createPrintout ) );
|
() -> ContainerData.toType( HeldItemContainerData::new, ContainerHeldItem::createPrintout ) );
|
||||||
|
|
||||||
public static final RegistryObject<ContainerType<ContainerViewComputer>> VIEW_COMPUTER = CONTAINERS.register( "view_computer",
|
public static final RegistryObject<ContainerType<ContainerViewComputer>> VIEW_COMPUTER = CONTAINERS.register( "view_computer",
|
||||||
() -> ContainerData.toType( ViewComputerContainerData::new, ContainerViewComputer::new ) );
|
() -> ContainerData.toType( ComputerContainerData::new, ContainerViewComputer::new ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -8,7 +8,6 @@ package dan200.computercraft.shared.command;
|
|||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.core.computer.Computer;
|
import dan200.computercraft.core.computer.Computer;
|
||||||
import dan200.computercraft.core.computer.ComputerSide;
|
import dan200.computercraft.core.computer.ComputerSide;
|
||||||
@ -19,8 +18,9 @@ import dan200.computercraft.core.tracking.TrackingField;
|
|||||||
import dan200.computercraft.shared.command.text.TableBuilder;
|
import dan200.computercraft.shared.command.text.TableBuilder;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
|
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
||||||
import dan200.computercraft.shared.network.container.ViewComputerContainerData;
|
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||||
import dan200.computercraft.shared.util.IDAssigner;
|
import dan200.computercraft.shared.util.IDAssigner;
|
||||||
import net.minecraft.command.CommandSource;
|
import net.minecraft.command.CommandSource;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
@ -75,7 +75,7 @@ public final class CommandComputerCraft
|
|||||||
TableBuilder table = new TableBuilder( DUMP_LIST_ID, "Computer", "On", "Position" );
|
TableBuilder table = new TableBuilder( DUMP_LIST_ID, "Computer", "On", "Position" );
|
||||||
|
|
||||||
CommandSource source = context.getSource();
|
CommandSource source = context.getSource();
|
||||||
List<ServerComputer> computers = new ArrayList<>( ComputerCraft.serverComputerRegistry.getComputers() );
|
List<ServerComputer> computers = new ArrayList<>( ServerComputerRegistry.INSTANCE.getComputers() );
|
||||||
|
|
||||||
// Unless we're on a server, limit the number of rows we can send.
|
// Unless we're on a server, limit the number of rows we can send.
|
||||||
World world = source.getLevel();
|
World world = source.getLevel();
|
||||||
@ -140,7 +140,7 @@ public final class CommandComputerCraft
|
|||||||
|
|
||||||
.then( command( "shutdown" )
|
.then( command( "shutdown" )
|
||||||
.requires( UserLevel.OWNER_OP )
|
.requires( UserLevel.OWNER_OP )
|
||||||
.argManyValue( "computers", manyComputers(), s -> ComputerCraft.serverComputerRegistry.getComputers() )
|
.argManyValue( "computers", manyComputers(), s -> ServerComputerRegistry.INSTANCE.getComputers() )
|
||||||
.executes( ( context, computerSelectors ) -> {
|
.executes( ( context, computerSelectors ) -> {
|
||||||
int shutdown = 0;
|
int shutdown = 0;
|
||||||
Set<ServerComputer> computers = unwrap( context.getSource(), computerSelectors );
|
Set<ServerComputer> computers = unwrap( context.getSource(), computerSelectors );
|
||||||
@ -155,7 +155,7 @@ public final class CommandComputerCraft
|
|||||||
|
|
||||||
.then( command( "turn-on" )
|
.then( command( "turn-on" )
|
||||||
.requires( UserLevel.OWNER_OP )
|
.requires( UserLevel.OWNER_OP )
|
||||||
.argManyValue( "computers", manyComputers(), s -> ComputerCraft.serverComputerRegistry.getComputers() )
|
.argManyValue( "computers", manyComputers(), s -> ServerComputerRegistry.INSTANCE.getComputers() )
|
||||||
.executes( ( context, computerSelectors ) -> {
|
.executes( ( context, computerSelectors ) -> {
|
||||||
int on = 0;
|
int on = 0;
|
||||||
Set<ServerComputer> computers = unwrap( context.getSource(), computerSelectors );
|
Set<ServerComputer> computers = unwrap( context.getSource(), computerSelectors );
|
||||||
@ -226,7 +226,7 @@ public final class CommandComputerCraft
|
|||||||
.executes( context -> {
|
.executes( context -> {
|
||||||
ServerPlayerEntity player = context.getSource().getPlayerOrException();
|
ServerPlayerEntity player = context.getSource().getPlayerOrException();
|
||||||
ServerComputer computer = getComputerArgument( context, "computer" );
|
ServerComputer computer = getComputerArgument( context, "computer" );
|
||||||
new ViewComputerContainerData( computer ).open( player, new INamedContainerProvider()
|
new ComputerContainerData( computer ).open( player, new INamedContainerProvider()
|
||||||
{
|
{
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
@ -382,7 +382,7 @@ public final class CommandComputerCraft
|
|||||||
|
|
||||||
Map<Computer, ServerComputer> lookup = new HashMap<>();
|
Map<Computer, ServerComputer> lookup = new HashMap<>();
|
||||||
int maxId = 0, maxInstance = 0;
|
int maxId = 0, maxInstance = 0;
|
||||||
for( ServerComputer server : ComputerCraft.serverComputerRegistry.getComputers() )
|
for( ServerComputer server : ServerComputerRegistry.INSTANCE.getComputers() )
|
||||||
{
|
{
|
||||||
lookup.put( server.getComputer(), server );
|
lookup.put( server.getComputer(), server );
|
||||||
|
|
||||||
|
@ -12,9 +12,9 @@ import com.mojang.brigadier.context.CommandContext;
|
|||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
|
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
|
||||||
import net.minecraft.command.CommandSource;
|
import net.minecraft.command.CommandSource;
|
||||||
import net.minecraft.command.arguments.IArgumentSerializer;
|
import net.minecraft.command.arguments.IArgumentSerializer;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
@ -89,7 +89,7 @@ public final class ComputersArgumentType implements ArgumentType<ComputersArgume
|
|||||||
{
|
{
|
||||||
int instance = reader.readInt();
|
int instance = reader.readInt();
|
||||||
computers = s -> {
|
computers = s -> {
|
||||||
ServerComputer computer = ComputerCraft.serverComputerRegistry.get( instance );
|
ServerComputer computer = ServerComputerRegistry.INSTANCE.get( instance );
|
||||||
return computer == null ? Collections.emptyList() : Collections.singletonList( computer );
|
return computer == null ? Collections.emptyList() : Collections.singletonList( computer );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ public final class ComputersArgumentType implements ArgumentType<ComputersArgume
|
|||||||
private static void suggestComputers( SuggestionsBuilder builder, String remaining, Function<ServerComputer, String> renderer )
|
private static void suggestComputers( SuggestionsBuilder builder, String remaining, Function<ServerComputer, String> renderer )
|
||||||
{
|
{
|
||||||
remaining = remaining.toLowerCase( Locale.ROOT );
|
remaining = remaining.toLowerCase( Locale.ROOT );
|
||||||
for( ServerComputer computer : ComputerCraft.serverComputerRegistry.getComputers() )
|
for( ServerComputer computer : ServerComputerRegistry.INSTANCE.getComputers() )
|
||||||
{
|
{
|
||||||
String converted = renderer.apply( computer );
|
String converted = renderer.apply( computer );
|
||||||
if( converted != null && converted.toLowerCase( Locale.ROOT ).startsWith( remaining ) )
|
if( converted != null && converted.toLowerCase( Locale.ROOT ).startsWith( remaining ) )
|
||||||
@ -163,7 +163,7 @@ public final class ComputersArgumentType implements ArgumentType<ComputersArgume
|
|||||||
|
|
||||||
private static ComputersSupplier getComputers( Predicate<ServerComputer> predicate )
|
private static ComputersSupplier getComputers( Predicate<ServerComputer> predicate )
|
||||||
{
|
{
|
||||||
return s -> Collections.unmodifiableList( ComputerCraft.serverComputerRegistry
|
return s -> Collections.unmodifiableList( ServerComputerRegistry.INSTANCE
|
||||||
.getComputers()
|
.getComputers()
|
||||||
.stream()
|
.stream()
|
||||||
.filter( predicate )
|
.filter( predicate )
|
||||||
|
@ -56,7 +56,7 @@ public class ServerTerminal implements ITerminal
|
|||||||
terminalChanged.set( true );
|
terminalChanged.set( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update()
|
public void tickServer()
|
||||||
{
|
{
|
||||||
terminalChangedLastFrame = terminalChanged.getAndSet( false );
|
terminalChangedLastFrame = terminalChanged.getAndSet( false );
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,12 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.computer.blocks;
|
package dan200.computercraft.shared.computer.blocks;
|
||||||
|
|
||||||
import dan200.computercraft.shared.computer.core.IComputer;
|
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A proxy object for computer objects, delegating to {@link IComputer} or {@link TileComputer} where appropriate.
|
* A proxy object for computer objects, delegating to {@link ServerComputer} or {@link TileComputer} where appropriate.
|
||||||
*/
|
*/
|
||||||
public final class ComputerProxy
|
public final class ComputerProxy
|
||||||
{
|
{
|
||||||
|
@ -105,9 +105,9 @@ public class TileCommandComputer extends TileComputer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ServerComputer createComputer( int instanceID, int id )
|
protected ServerComputer createComputer( int id )
|
||||||
{
|
{
|
||||||
ServerComputer computer = super.createComputer( instanceID, id );
|
ServerComputer computer = super.createComputer( id );
|
||||||
computer.addAPI( new CommandAPI( this ) );
|
computer.addAPI( new CommandAPI( this ) );
|
||||||
return computer;
|
return computer;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import net.minecraft.entity.player.PlayerInventory;
|
|||||||
import net.minecraft.inventory.container.Container;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
|
||||||
@ -39,13 +40,12 @@ public class TileComputer extends TileComputerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ServerComputer createComputer( int instanceID, int id )
|
protected ServerComputer createComputer( int id )
|
||||||
{
|
{
|
||||||
ComputerFamily family = getFamily();
|
ComputerFamily family = getFamily();
|
||||||
ServerComputer computer = new ServerComputer(
|
ServerComputer computer = new ServerComputer(
|
||||||
getLevel(), id, label, instanceID, family,
|
(ServerWorld) getLevel(), id, label, family,
|
||||||
ComputerCraft.computerTermWidth,
|
ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight
|
||||||
ComputerCraft.computerTermHeight
|
|
||||||
);
|
);
|
||||||
computer.setPosition( getBlockPos() );
|
computer.setPosition( getBlockPos() );
|
||||||
return computer;
|
return computer;
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.computer.blocks;
|
package dan200.computercraft.shared.computer.blocks;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.core.computer.ComputerSide;
|
import dan200.computercraft.core.computer.ComputerSide;
|
||||||
import dan200.computercraft.shared.BundledRedstone;
|
import dan200.computercraft.shared.BundledRedstone;
|
||||||
@ -14,6 +13,7 @@ import dan200.computercraft.shared.common.TileGeneric;
|
|||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerState;
|
import dan200.computercraft.shared.computer.core.ComputerState;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
|
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
|
||||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||||
import dan200.computercraft.shared.util.DirectionUtil;
|
import dan200.computercraft.shared.util.DirectionUtil;
|
||||||
import dan200.computercraft.shared.util.RedstoneUtil;
|
import dan200.computercraft.shared.util.RedstoneUtil;
|
||||||
@ -81,11 +81,11 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
|
|
||||||
protected void unload()
|
protected void unload()
|
||||||
{
|
{
|
||||||
if( instanceID >= 0 )
|
if( getLevel().isClientSide ) return;
|
||||||
{
|
|
||||||
if( !getLevel().isClientSide ) ComputerCraft.serverComputerRegistry.remove( instanceID );
|
ServerComputer computer = getServerComputer();
|
||||||
instanceID = -1;
|
if( computer != null ) computer.close();
|
||||||
}
|
instanceID = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -142,8 +142,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
// Regular right click to activate computer
|
// Regular right click to activate computer
|
||||||
if( !getLevel().isClientSide && isUsable( player ) )
|
if( !getLevel().isClientSide && isUsable( player ) )
|
||||||
{
|
{
|
||||||
createServerComputer().turnOn();
|
ServerComputer computer = createServerComputer();
|
||||||
new ComputerContainerData( createServerComputer() ).open( player, this );
|
computer.turnOn();
|
||||||
|
new ComputerContainerData( computer ).open( player, this );
|
||||||
}
|
}
|
||||||
return ActionResultType.SUCCESS;
|
return ActionResultType.SUCCESS;
|
||||||
}
|
}
|
||||||
@ -327,7 +328,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ServerComputer createComputer( int instanceID, int id );
|
protected abstract ServerComputer createComputer( int id );
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int getComputerID()
|
public final int getComputerID()
|
||||||
@ -375,17 +376,12 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
if( getLevel().isClientSide ) throw new IllegalStateException( "Cannot access server computer on the client." );
|
if( getLevel().isClientSide ) throw new IllegalStateException( "Cannot access server computer on the client." );
|
||||||
|
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
if( instanceID < 0 )
|
|
||||||
{
|
|
||||||
instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerComputer computer = ComputerCraft.serverComputerRegistry.get( instanceID );
|
ServerComputer computer = ServerComputerRegistry.INSTANCE.get( instanceID );
|
||||||
if( computer == null )
|
if( computer == null )
|
||||||
{
|
{
|
||||||
computer = createComputer( instanceID, computerID );
|
computer = createComputer( computerID );
|
||||||
ComputerCraft.serverComputerRegistry.add( instanceID, computer );
|
instanceID = computer.register();
|
||||||
fresh = true;
|
fresh = true;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
@ -397,7 +393,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
@Nullable
|
@Nullable
|
||||||
public ServerComputer getServerComputer()
|
public ServerComputer getServerComputer()
|
||||||
{
|
{
|
||||||
return getLevel().isClientSide ? null : ComputerCraft.serverComputerRegistry.get( instanceID );
|
return getLevel().isClientSide ? null : ServerComputerRegistry.INSTANCE.get( instanceID );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Networking stuff
|
// Networking stuff
|
||||||
|
@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.computer.core;
|
|
||||||
|
|
||||||
import dan200.computercraft.shared.common.ClientTerminal;
|
|
||||||
import dan200.computercraft.shared.network.NetworkHandler;
|
|
||||||
import dan200.computercraft.shared.network.server.*;
|
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
|
||||||
|
|
||||||
public class ClientComputer extends ClientTerminal implements IComputer
|
|
||||||
{
|
|
||||||
private final int instanceID;
|
|
||||||
|
|
||||||
private boolean on = false;
|
|
||||||
private boolean blinking = false;
|
|
||||||
private CompoundNBT userData = null;
|
|
||||||
|
|
||||||
public ClientComputer( int instanceID )
|
|
||||||
{
|
|
||||||
super( false );
|
|
||||||
this.instanceID = instanceID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompoundNBT getUserData()
|
|
||||||
{
|
|
||||||
return userData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void requestState()
|
|
||||||
{
|
|
||||||
// Request state from server
|
|
||||||
NetworkHandler.sendToServer( new RequestComputerMessage( getInstanceID() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// IComputer
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInstanceID()
|
|
||||||
{
|
|
||||||
return instanceID;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOn()
|
|
||||||
{
|
|
||||||
return on;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isCursorDisplayed()
|
|
||||||
{
|
|
||||||
return on && blinking;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void turnOn()
|
|
||||||
{
|
|
||||||
// Send turnOn to server
|
|
||||||
NetworkHandler.sendToServer( new ComputerActionServerMessage( instanceID, ComputerActionServerMessage.Action.TURN_ON ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void shutdown()
|
|
||||||
{
|
|
||||||
// Send shutdown to server
|
|
||||||
NetworkHandler.sendToServer( new ComputerActionServerMessage( instanceID, ComputerActionServerMessage.Action.SHUTDOWN ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reboot()
|
|
||||||
{
|
|
||||||
// Send reboot to server
|
|
||||||
NetworkHandler.sendToServer( new ComputerActionServerMessage( instanceID, ComputerActionServerMessage.Action.REBOOT ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void queueEvent( String event, Object[] arguments )
|
|
||||||
{
|
|
||||||
// Send event to server
|
|
||||||
NetworkHandler.sendToServer( new QueueEventServerMessage( instanceID, event, arguments ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyDown( int key, boolean repeat )
|
|
||||||
{
|
|
||||||
NetworkHandler.sendToServer( new KeyEventServerMessage( instanceID, repeat ? KeyEventServerMessage.TYPE_REPEAT : KeyEventServerMessage.TYPE_DOWN, key ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyUp( int key )
|
|
||||||
{
|
|
||||||
NetworkHandler.sendToServer( new KeyEventServerMessage( instanceID, KeyEventServerMessage.TYPE_UP, key ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClick( int button, int x, int y )
|
|
||||||
{
|
|
||||||
NetworkHandler.sendToServer( new MouseEventServerMessage( instanceID, MouseEventServerMessage.TYPE_CLICK, button, x, y ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseUp( int button, int x, int y )
|
|
||||||
{
|
|
||||||
NetworkHandler.sendToServer( new MouseEventServerMessage( instanceID, MouseEventServerMessage.TYPE_UP, button, x, y ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDrag( int button, int x, int y )
|
|
||||||
{
|
|
||||||
NetworkHandler.sendToServer( new MouseEventServerMessage( instanceID, MouseEventServerMessage.TYPE_DRAG, button, x, y ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseScroll( int direction, int x, int y )
|
|
||||||
{
|
|
||||||
NetworkHandler.sendToServer( new MouseEventServerMessage( instanceID, MouseEventServerMessage.TYPE_SCROLL, direction, x, y ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState( ComputerState state, CompoundNBT userData )
|
|
||||||
{
|
|
||||||
on = state != ComputerState.OFF;
|
|
||||||
blinking = state == ComputerState.BLINKING;
|
|
||||||
this.userData = userData;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.computer.core;
|
|
||||||
|
|
||||||
public class ClientComputerRegistry extends ComputerRegistry<ClientComputer>
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void add( int instanceID, ClientComputer computer )
|
|
||||||
{
|
|
||||||
super.add( instanceID, computer );
|
|
||||||
computer.requestState();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.computer.core;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class ComputerRegistry<T extends IComputer>
|
|
||||||
{
|
|
||||||
private final Map<Integer, T> computers = new HashMap<>();
|
|
||||||
private int nextUnusedInstanceID;
|
|
||||||
private int sessionID;
|
|
||||||
|
|
||||||
protected ComputerRegistry()
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSessionID()
|
|
||||||
{
|
|
||||||
return sessionID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getUnusedInstanceID()
|
|
||||||
{
|
|
||||||
return nextUnusedInstanceID++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<T> getComputers()
|
|
||||||
{
|
|
||||||
return computers.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
public T get( int instanceID )
|
|
||||||
{
|
|
||||||
if( instanceID >= 0 )
|
|
||||||
{
|
|
||||||
if( computers.containsKey( instanceID ) )
|
|
||||||
{
|
|
||||||
return computers.get( instanceID );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains( int instanceID )
|
|
||||||
{
|
|
||||||
return computers.containsKey( instanceID );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add( int instanceID, T computer )
|
|
||||||
{
|
|
||||||
if( computers.containsKey( instanceID ) )
|
|
||||||
{
|
|
||||||
remove( instanceID );
|
|
||||||
}
|
|
||||||
computers.put( instanceID, computer );
|
|
||||||
nextUnusedInstanceID = Math.max( nextUnusedInstanceID, instanceID + 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove( int instanceID )
|
|
||||||
{
|
|
||||||
computers.remove( instanceID );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
computers.clear();
|
|
||||||
nextUnusedInstanceID = 0;
|
|
||||||
sessionID = new Random().nextInt();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.computer.core;
|
|
||||||
|
|
||||||
import dan200.computercraft.shared.common.ITerminal;
|
|
||||||
|
|
||||||
public interface IComputer extends ITerminal, InputHandler
|
|
||||||
{
|
|
||||||
int getInstanceID();
|
|
||||||
|
|
||||||
boolean isOn();
|
|
||||||
|
|
||||||
boolean isCursorDisplayed();
|
|
||||||
|
|
||||||
void turnOn();
|
|
||||||
|
|
||||||
void shutdown();
|
|
||||||
|
|
||||||
void reboot();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void queueEvent( String event, Object[] arguments );
|
|
||||||
|
|
||||||
default void queueEvent( String event )
|
|
||||||
{
|
|
||||||
queueEvent( event, null );
|
|
||||||
}
|
|
||||||
|
|
||||||
default ComputerState getState()
|
|
||||||
{
|
|
||||||
if( !isOn() ) return ComputerState.OFF;
|
|
||||||
return isCursorDisplayed() ? ComputerState.BLINKING : ComputerState.ON;
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,15 +5,24 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.computer.core;
|
package dan200.computercraft.shared.computer.core;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.computer.menu.ServerInputHandler;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives some input and forwards it to a computer.
|
* Handles user-provided input, forwarding it to a computer. This is used
|
||||||
*
|
*
|
||||||
* @see InputState
|
* @see ServerInputHandler
|
||||||
* @see IComputer
|
* @see ServerComputer
|
||||||
*/
|
*/
|
||||||
public interface InputHandler
|
public interface InputHandler
|
||||||
{
|
{
|
||||||
void queueEvent( String event, Object[] arguments );
|
void queueEvent( String event, @Nullable Object[] arguments );
|
||||||
|
|
||||||
|
default void queueEvent( String event )
|
||||||
|
{
|
||||||
|
queueEvent( event, null );
|
||||||
|
}
|
||||||
|
|
||||||
default void keyDown( int key, boolean repeat )
|
default void keyDown( int key, boolean repeat )
|
||||||
{
|
{
|
||||||
@ -44,4 +53,10 @@ public interface InputHandler
|
|||||||
{
|
{
|
||||||
queueEvent( "mouse_scroll", new Object[] { direction, x, y } );
|
queueEvent( "mouse_scroll", new Object[] { direction, x, y } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
void turnOn();
|
||||||
|
|
||||||
|
void reboot();
|
||||||
}
|
}
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.computer.core;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntIterator;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An {@link InputHandler} which keeps track of the current key and mouse state, and releases them when the container
|
|
||||||
* is closed.
|
|
||||||
*/
|
|
||||||
public class InputState implements InputHandler
|
|
||||||
{
|
|
||||||
private final IContainerComputer owner;
|
|
||||||
private final IntSet keysDown = new IntOpenHashSet( 4 );
|
|
||||||
|
|
||||||
private int lastMouseX;
|
|
||||||
private int lastMouseY;
|
|
||||||
private int lastMouseDown = -1;
|
|
||||||
|
|
||||||
public InputState( IContainerComputer owner )
|
|
||||||
{
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void queueEvent( String event, Object[] arguments )
|
|
||||||
{
|
|
||||||
IComputer computer = owner.getComputer();
|
|
||||||
if( computer != null ) computer.queueEvent( event, arguments );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyDown( int key, boolean repeat )
|
|
||||||
{
|
|
||||||
keysDown.add( key );
|
|
||||||
IComputer computer = owner.getComputer();
|
|
||||||
if( computer != null ) computer.keyDown( key, repeat );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyUp( int key )
|
|
||||||
{
|
|
||||||
keysDown.remove( key );
|
|
||||||
IComputer computer = owner.getComputer();
|
|
||||||
if( computer != null ) computer.keyUp( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClick( int button, int x, int y )
|
|
||||||
{
|
|
||||||
lastMouseX = x;
|
|
||||||
lastMouseY = y;
|
|
||||||
lastMouseDown = button;
|
|
||||||
|
|
||||||
IComputer computer = owner.getComputer();
|
|
||||||
if( computer != null ) computer.mouseClick( button, x, y );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseUp( int button, int x, int y )
|
|
||||||
{
|
|
||||||
lastMouseX = x;
|
|
||||||
lastMouseY = y;
|
|
||||||
lastMouseDown = -1;
|
|
||||||
|
|
||||||
IComputer computer = owner.getComputer();
|
|
||||||
if( computer != null ) computer.mouseUp( button, x, y );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDrag( int button, int x, int y )
|
|
||||||
{
|
|
||||||
lastMouseX = x;
|
|
||||||
lastMouseY = y;
|
|
||||||
lastMouseDown = button;
|
|
||||||
|
|
||||||
IComputer computer = owner.getComputer();
|
|
||||||
if( computer != null ) computer.mouseDrag( button, x, y );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseScroll( int direction, int x, int y )
|
|
||||||
{
|
|
||||||
lastMouseX = x;
|
|
||||||
lastMouseY = y;
|
|
||||||
|
|
||||||
IComputer computer = owner.getComputer();
|
|
||||||
if( computer != null ) computer.mouseScroll( direction, x, y );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close()
|
|
||||||
{
|
|
||||||
IComputer computer = owner.getComputer();
|
|
||||||
if( computer != null )
|
|
||||||
{
|
|
||||||
IntIterator keys = keysDown.iterator();
|
|
||||||
while( keys.hasNext() ) computer.keyUp( keys.nextInt() );
|
|
||||||
|
|
||||||
if( lastMouseDown != -1 ) computer.mouseUp( lastMouseDown, lastMouseX, lastMouseY );
|
|
||||||
}
|
|
||||||
|
|
||||||
keysDown.clear();
|
|
||||||
lastMouseDown = -1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,62 +16,69 @@ import dan200.computercraft.core.apis.IAPIEnvironment;
|
|||||||
import dan200.computercraft.core.computer.Computer;
|
import dan200.computercraft.core.computer.Computer;
|
||||||
import dan200.computercraft.core.computer.ComputerSide;
|
import dan200.computercraft.core.computer.ComputerSide;
|
||||||
import dan200.computercraft.core.computer.IComputerEnvironment;
|
import dan200.computercraft.core.computer.IComputerEnvironment;
|
||||||
import dan200.computercraft.shared.common.ServerTerminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
import dan200.computercraft.shared.network.NetworkHandler;
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
import dan200.computercraft.shared.network.NetworkMessage;
|
import dan200.computercraft.shared.network.NetworkMessage;
|
||||||
import dan200.computercraft.shared.network.client.ComputerDataClientMessage;
|
|
||||||
import dan200.computercraft.shared.network.client.ComputerDeletedClientMessage;
|
|
||||||
import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage;
|
import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import dan200.computercraft.shared.network.client.TerminalState;
|
||||||
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.inventory.container.Container;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.server.ServerWorld;
|
||||||
import net.minecraftforge.fml.server.ServerLifecycleHooks;
|
|
||||||
import net.minecraftforge.versions.mcp.MCPVersion;
|
import net.minecraftforge.versions.mcp.MCPVersion;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class ServerComputer extends ServerTerminal implements IComputer, IComputerEnvironment
|
public class ServerComputer implements InputHandler, IComputerEnvironment
|
||||||
{
|
{
|
||||||
private final int instanceID;
|
private final int instanceID;
|
||||||
|
|
||||||
private World world;
|
private ServerWorld world;
|
||||||
private BlockPos position;
|
private BlockPos position;
|
||||||
|
|
||||||
private final ComputerFamily family;
|
private final ComputerFamily family;
|
||||||
private final Computer computer;
|
private final Computer computer;
|
||||||
private CompoundNBT userData;
|
|
||||||
private boolean changed;
|
private final Terminal terminal;
|
||||||
|
private final AtomicBoolean terminalChanged = new AtomicBoolean( false );
|
||||||
|
|
||||||
private boolean changedLastFrame;
|
private boolean changedLastFrame;
|
||||||
private int ticksSincePing;
|
private int ticksSincePing;
|
||||||
|
|
||||||
public ServerComputer( World world, int computerID, String label, int instanceID, ComputerFamily family, int terminalWidth, int terminalHeight )
|
public ServerComputer( ServerWorld world, int computerID, String label, ComputerFamily family, int terminalWidth, int terminalHeight )
|
||||||
{
|
{
|
||||||
super( family != ComputerFamily.NORMAL, terminalWidth, terminalHeight );
|
|
||||||
this.instanceID = instanceID;
|
|
||||||
|
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.family = family;
|
this.family = family;
|
||||||
computer = new Computer( this, getTerminal(), computerID );
|
|
||||||
|
instanceID = ServerComputerRegistry.INSTANCE.getUnusedInstanceID();
|
||||||
|
terminal = new Terminal( terminalWidth, terminalHeight, this::markTerminalChanged );
|
||||||
|
|
||||||
|
computer = new Computer( this, terminal, computerID );
|
||||||
computer.setLabel( label );
|
computer.setLabel( label );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isColour()
|
||||||
|
{
|
||||||
|
return family != ComputerFamily.NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
public ComputerFamily getFamily()
|
public ComputerFamily getFamily()
|
||||||
{
|
{
|
||||||
return family;
|
return family;
|
||||||
}
|
}
|
||||||
|
|
||||||
public World getWorld()
|
public ServerWorld getWorld()
|
||||||
{
|
{
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWorld( World world )
|
public void setWorld( ServerWorld world )
|
||||||
{
|
{
|
||||||
this.world = world;
|
this.world = world;
|
||||||
}
|
}
|
||||||
@ -96,16 +103,30 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
return computer;
|
return computer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected void markTerminalChanged()
|
||||||
public void update()
|
|
||||||
{
|
{
|
||||||
super.update();
|
terminalChanged.set( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void tickServer()
|
||||||
|
{
|
||||||
|
ticksSincePing++;
|
||||||
|
|
||||||
computer.tick();
|
computer.tick();
|
||||||
|
|
||||||
changedLastFrame = computer.pollAndResetChanged() || changed;
|
changedLastFrame = computer.pollAndResetChanged();
|
||||||
changed = false;
|
if( terminalChanged.getAndSet( false ) ) onTerminalChanged();
|
||||||
|
}
|
||||||
|
|
||||||
ticksSincePing++;
|
protected void onTerminalChanged()
|
||||||
|
{
|
||||||
|
sendToAllInteracting( c -> new ComputerTerminalClientMessage( c, getTerminalState() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerminalState getTerminalState()
|
||||||
|
{
|
||||||
|
return new TerminalState( isColour(), terminal );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void keepAlive()
|
public void keepAlive()
|
||||||
@ -123,76 +144,38 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
return changedLastFrame;
|
return changedLastFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unload()
|
public int register()
|
||||||
|
{
|
||||||
|
ServerComputerRegistry.INSTANCE.add( instanceID, this );
|
||||||
|
return instanceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unload()
|
||||||
{
|
{
|
||||||
computer.unload();
|
computer.unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundNBT getUserData()
|
public void close()
|
||||||
{
|
{
|
||||||
if( userData == null )
|
unload();
|
||||||
|
ServerComputerRegistry.INSTANCE.remove( instanceID );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendToAllInteracting( Function<Container, NetworkMessage> createPacket )
|
||||||
|
{
|
||||||
|
MinecraftServer server = world.getServer();
|
||||||
|
|
||||||
|
for( ServerPlayerEntity player : server.getPlayerList().getPlayers() )
|
||||||
{
|
{
|
||||||
userData = new CompoundNBT();
|
if( player.containerMenu instanceof ComputerMenu && ((ComputerMenu) player.containerMenu).getComputer() == this )
|
||||||
}
|
|
||||||
return userData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateUserData()
|
|
||||||
{
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private NetworkMessage createComputerPacket()
|
|
||||||
{
|
|
||||||
return new ComputerDataClientMessage( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected NetworkMessage createTerminalPacket()
|
|
||||||
{
|
|
||||||
return new ComputerTerminalClientMessage( getInstanceID(), write() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void broadcastState( boolean force )
|
|
||||||
{
|
|
||||||
if( hasOutputChanged() || force )
|
|
||||||
{
|
|
||||||
// Send computer state to all clients
|
|
||||||
NetworkHandler.sendToAllPlayers( createComputerPacket() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( hasTerminalChanged() || force )
|
|
||||||
{
|
|
||||||
// Send terminal state to clients who are currently interacting with the computer.
|
|
||||||
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
|
|
||||||
|
|
||||||
NetworkMessage packet = null;
|
|
||||||
for( PlayerEntity player : server.getPlayerList().getPlayers() )
|
|
||||||
{
|
{
|
||||||
if( isInteracting( player ) )
|
NetworkHandler.sendToPlayer( player, createPacket.apply( player.containerMenu ) );
|
||||||
{
|
|
||||||
if( packet == null ) packet = createTerminalPacket();
|
|
||||||
NetworkHandler.sendToPlayer( player, packet );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendComputerState( PlayerEntity player )
|
protected void onRemoved()
|
||||||
{
|
{
|
||||||
// Send state to client
|
|
||||||
NetworkHandler.sendToPlayer( player, createComputerPacket() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendTerminalState( PlayerEntity player )
|
|
||||||
{
|
|
||||||
// Send terminal state to client
|
|
||||||
NetworkHandler.sendToPlayer( player, createTerminalPacket() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void broadcastDelete()
|
|
||||||
{
|
|
||||||
// Send deletion to client
|
|
||||||
NetworkHandler.sendToAllPlayers( new ComputerDeletedClientMessage( getInstanceID() ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setID( int id )
|
public void setID( int id )
|
||||||
@ -200,9 +183,6 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
computer.setID( id );
|
computer.setID( id );
|
||||||
}
|
}
|
||||||
|
|
||||||
// IComputer
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInstanceID()
|
public int getInstanceID()
|
||||||
{
|
{
|
||||||
return instanceID;
|
return instanceID;
|
||||||
@ -218,16 +198,15 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
return computer.getLabel();
|
return computer.getLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOn()
|
public boolean isOn()
|
||||||
{
|
{
|
||||||
return computer.isOn();
|
return computer.isOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public ComputerState getState()
|
||||||
public boolean isCursorDisplayed()
|
|
||||||
{
|
{
|
||||||
return computer.isOn() && computer.isBlinking();
|
if( !isOn() ) return ComputerState.OFF;
|
||||||
|
return computer.isBlinking() ? ComputerState.BLINKING : ComputerState.ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -355,21 +334,4 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
{
|
{
|
||||||
return ComputerCraftAPI.createUniqueNumberedSaveDir( world, "computer" );
|
return ComputerCraftAPI.createUniqueNumberedSaveDir( world, "computer" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public IContainerComputer getContainer( PlayerEntity player )
|
|
||||||
{
|
|
||||||
if( player == null ) return null;
|
|
||||||
|
|
||||||
Container container = player.containerMenu;
|
|
||||||
if( !(container instanceof IContainerComputer) ) return null;
|
|
||||||
|
|
||||||
IContainerComputer computerContainer = (IContainerComputer) container;
|
|
||||||
return computerContainer.getComputer() != this ? null : computerContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isInteracting( PlayerEntity player )
|
|
||||||
{
|
|
||||||
return getContainer( player ) != null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,45 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.computer.core;
|
package dan200.computercraft.shared.computer.core;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
|
||||||
public class ServerComputerRegistry extends ComputerRegistry<ServerComputer>
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class ServerComputerRegistry
|
||||||
{
|
{
|
||||||
|
private static final Random RANDOM = new Random();
|
||||||
|
public static final ServerComputerRegistry INSTANCE = new ServerComputerRegistry();
|
||||||
|
|
||||||
|
private int sessionId = RANDOM.nextInt();
|
||||||
|
private final Int2ObjectMap<ServerComputer> computers = new Int2ObjectOpenHashMap<>();
|
||||||
|
private int nextInstanceId;
|
||||||
|
|
||||||
|
public int getSessionID()
|
||||||
|
{
|
||||||
|
return sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getUnusedInstanceID()
|
||||||
|
{
|
||||||
|
return nextInstanceId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ServerComputer get( int instanceID )
|
||||||
|
{
|
||||||
|
return instanceID >= 0 ? computers.get( instanceID ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ServerComputer get( int sessionId, int instanceId )
|
||||||
|
{
|
||||||
|
return sessionId == this.sessionId ? get( instanceId ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
public void update()
|
public void update()
|
||||||
{
|
{
|
||||||
Iterator<ServerComputer> it = getComputers().iterator();
|
Iterator<ServerComputer> it = getComputers().iterator();
|
||||||
@ -17,66 +52,45 @@ public class ServerComputerRegistry extends ComputerRegistry<ServerComputer>
|
|||||||
ServerComputer computer = it.next();
|
ServerComputer computer = it.next();
|
||||||
if( computer.hasTimedOut() )
|
if( computer.hasTimedOut() )
|
||||||
{
|
{
|
||||||
//System.out.println( "TIMED OUT SERVER COMPUTER " + computer.getInstanceID() );
|
|
||||||
computer.unload();
|
computer.unload();
|
||||||
computer.broadcastDelete();
|
computer.onRemoved();
|
||||||
it.remove();
|
it.remove();
|
||||||
//System.out.println( getComputers().size() + " SERVER COMPUTERS" );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
computer.update();
|
computer.tickServer();
|
||||||
if( computer.hasTerminalChanged() || computer.hasOutputChanged() )
|
|
||||||
{
|
|
||||||
computer.broadcastState( false );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
void add( int instanceID, ServerComputer computer )
|
||||||
public void add( int instanceID, ServerComputer computer )
|
|
||||||
{
|
{
|
||||||
//System.out.println( "ADD SERVER COMPUTER " + instanceID );
|
remove( instanceID );
|
||||||
super.add( instanceID, computer );
|
computers.put( instanceID, computer );
|
||||||
computer.broadcastState( true );
|
nextInstanceId = Math.max( nextInstanceId, instanceID + 1 );
|
||||||
//System.out.println( getComputers().size() + " SERVER COMPUTERS" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
void remove( int instanceID )
|
||||||
public void remove( int instanceID )
|
|
||||||
{
|
{
|
||||||
//System.out.println( "REMOVE SERVER COMPUTER " + instanceID );
|
|
||||||
ServerComputer computer = get( instanceID );
|
ServerComputer computer = get( instanceID );
|
||||||
if( computer != null )
|
if( computer != null )
|
||||||
{
|
{
|
||||||
computer.unload();
|
computer.unload();
|
||||||
computer.broadcastDelete();
|
computer.onRemoved();
|
||||||
}
|
}
|
||||||
super.remove( instanceID );
|
|
||||||
//System.out.println( getComputers().size() + " SERVER COMPUTERS" );
|
computers.remove( instanceID );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset()
|
public void reset()
|
||||||
{
|
{
|
||||||
//System.out.println( "RESET SERVER COMPUTERS" );
|
for( ServerComputer computer : getComputers() ) computer.unload();
|
||||||
for( ServerComputer computer : getComputers() )
|
computers.clear();
|
||||||
{
|
sessionId = RANDOM.nextInt();
|
||||||
computer.unload();
|
|
||||||
}
|
|
||||||
super.reset();
|
|
||||||
//System.out.println( getComputers().size() + " SERVER COMPUTERS" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerComputer lookup( int computerID )
|
public Collection<ServerComputer> getComputers()
|
||||||
{
|
{
|
||||||
if( computerID < 0 ) return null;
|
return computers.values();
|
||||||
|
|
||||||
for( ServerComputer computer : getComputers() )
|
|
||||||
{
|
|
||||||
if( computer.getID() == computerID ) return computer;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,15 @@
|
|||||||
package dan200.computercraft.shared.computer.inventory;
|
package dan200.computercraft.shared.computer.inventory;
|
||||||
|
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.IComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||||
import dan200.computercraft.shared.util.InvisibleSlot;
|
import dan200.computercraft.shared.util.InvisibleSlot;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.inventory.container.ContainerType;
|
import net.minecraft.inventory.container.ContainerType;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,15 +24,18 @@ import java.util.function.Predicate;
|
|||||||
*/
|
*/
|
||||||
public class ComputerMenuWithoutInventory extends ContainerComputerBase
|
public class ComputerMenuWithoutInventory extends ContainerComputerBase
|
||||||
{
|
{
|
||||||
public ComputerMenuWithoutInventory( ContainerType<? extends ContainerComputerBase> type, int id, PlayerInventory player, Predicate<PlayerEntity> canUse, IComputer computer, ComputerFamily family )
|
public ComputerMenuWithoutInventory(
|
||||||
|
ContainerType<? extends ContainerComputerBase> type, int id, PlayerInventory player, Predicate<PlayerEntity> canUse,
|
||||||
|
ServerComputer computer, ComputerFamily family
|
||||||
|
)
|
||||||
{
|
{
|
||||||
super( type, id, canUse, computer, family );
|
super( type, id, canUse, family, computer, null );
|
||||||
addSlots( player );
|
addSlots( player );
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComputerMenuWithoutInventory( ContainerType<? extends ContainerComputerBase> type, int id, PlayerInventory player, ComputerContainerData data )
|
public ComputerMenuWithoutInventory( ContainerType<? extends ContainerComputerBase> type, int id, PlayerInventory player, ComputerContainerData menuData )
|
||||||
{
|
{
|
||||||
super( type, id, player, data );
|
super( type, id, p -> true, menuData.family(), null, menuData );
|
||||||
addSlots( player );
|
addSlots( player );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,4 +43,11 @@ public class ComputerMenuWithoutInventory extends ContainerComputerBase
|
|||||||
{
|
{
|
||||||
for( int i = 0; i < 9; i++ ) addSlot( new InvisibleSlot( player, i ) );
|
for( int i = 0; i < 9; i++ ) addSlot( new InvisibleSlot( player, i ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public ItemStack quickMoveStack( @Nonnull PlayerEntity player, int slot )
|
||||||
|
{
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,68 +5,49 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.computer.inventory;
|
package dan200.computercraft.shared.computer.inventory;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.core.filesystem.FileSystem;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.core.filesystem.FileSystemException;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.core.filesystem.FileSystemWrapper;
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
import dan200.computercraft.shared.computer.core.*;
|
import dan200.computercraft.shared.computer.menu.ServerInputState;
|
||||||
import dan200.computercraft.shared.computer.upload.FileSlice;
|
import dan200.computercraft.shared.network.client.TerminalState;
|
||||||
import dan200.computercraft.shared.computer.upload.FileUpload;
|
|
||||||
import dan200.computercraft.shared.computer.upload.UploadResult;
|
|
||||||
import dan200.computercraft.shared.network.NetworkHandler;
|
|
||||||
import dan200.computercraft.shared.network.client.UploadResultMessage;
|
|
||||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||||
|
import dan200.computercraft.shared.util.SingleIntArray;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
|
||||||
import net.minecraft.inventory.container.Container;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.inventory.container.ContainerType;
|
import net.minecraft.inventory.container.ContainerType;
|
||||||
import net.minecraft.util.text.TranslationTextComponent;
|
import net.minecraft.util.IIntArray;
|
||||||
|
import net.minecraft.util.IntArray;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.channels.WritableByteChannel;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.StringJoiner;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public abstract class ContainerComputerBase extends Container implements IContainerComputer
|
public abstract class ContainerComputerBase extends Container implements ComputerMenu
|
||||||
{
|
{
|
||||||
private static final String LIST_PREFIX = "\n \u2022 ";
|
|
||||||
|
|
||||||
private final Predicate<PlayerEntity> canUse;
|
private final Predicate<PlayerEntity> canUse;
|
||||||
private final IComputer computer;
|
|
||||||
private final ComputerFamily family;
|
private final ComputerFamily family;
|
||||||
private final InputState input = new InputState( this );
|
private final IIntArray data;
|
||||||
|
|
||||||
private UUID toUploadId;
|
private final @Nullable ServerComputer computer;
|
||||||
private List<FileUpload> toUpload;
|
private final @Nullable ServerInputState input;
|
||||||
|
|
||||||
public ContainerComputerBase( ContainerType<? extends ContainerComputerBase> type, int id, Predicate<PlayerEntity> canUse, IComputer computer, ComputerFamily family )
|
private final @Nullable Terminal terminal;
|
||||||
|
|
||||||
|
public ContainerComputerBase(
|
||||||
|
ContainerType<? extends ContainerComputerBase> type, int id, Predicate<PlayerEntity> canUse,
|
||||||
|
ComputerFamily family, @Nullable ServerComputer computer, @Nullable ComputerContainerData containerData
|
||||||
|
)
|
||||||
{
|
{
|
||||||
super( type, id );
|
super( type, id );
|
||||||
this.canUse = canUse;
|
this.canUse = canUse;
|
||||||
this.computer = computer;
|
|
||||||
this.family = family;
|
this.family = family;
|
||||||
}
|
data = computer == null ? new IntArray( 1 ) : (SingleIntArray) () -> computer.isOn() ? 1 : 0;
|
||||||
|
addDataSlots( data );
|
||||||
|
|
||||||
public ContainerComputerBase( ContainerType<? extends ContainerComputerBase> type, int id, PlayerInventory player, ComputerContainerData data )
|
this.computer = computer;
|
||||||
{
|
input = computer == null ? null : new ServerInputState( this );
|
||||||
this( type, id, x -> true, getComputer( player, data ), data.getFamily() );
|
terminal = containerData == null ? null : containerData.terminal().create();
|
||||||
}
|
|
||||||
|
|
||||||
protected static IComputer getComputer( PlayerInventory player, ComputerContainerData data )
|
|
||||||
{
|
|
||||||
int id = data.getInstanceId();
|
|
||||||
if( !player.player.level.isClientSide ) return ComputerCraft.serverComputerRegistry.get( id );
|
|
||||||
|
|
||||||
ClientComputer computer = ComputerCraft.clientComputerRegistry.get( id );
|
|
||||||
if( computer == null ) ComputerCraft.clientComputerRegistry.add( id, computer = new ClientComputer( id ) );
|
|
||||||
return computer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -81,141 +62,48 @@ public abstract class ContainerComputerBase extends Container implements IContai
|
|||||||
return family;
|
return family;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public boolean isOn()
|
||||||
@Override
|
|
||||||
public IComputer getComputer()
|
|
||||||
{
|
{
|
||||||
|
return data.get( 0 ) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerComputer getComputer()
|
||||||
|
{
|
||||||
|
if( computer == null ) throw new UnsupportedOperationException( "Cannot access server computer on the client" );
|
||||||
return computer;
|
return computer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
@Override
|
||||||
public InputState getInput()
|
public ServerInputState getInput()
|
||||||
{
|
{
|
||||||
|
if( input == null ) throw new UnsupportedOperationException( "Cannot access server computer on the client" );
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startUpload( @Nonnull UUID uuid, @Nonnull List<FileUpload> files )
|
public void updateTerminal( TerminalState state )
|
||||||
{
|
{
|
||||||
toUploadId = uuid;
|
if( terminal == null ) throw new UnsupportedOperationException( "Cannot update terminal on the server" );
|
||||||
toUpload = files;
|
state.apply( terminal );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void continueUpload( @Nonnull UUID uploadId, @Nonnull List<FileSlice> slices )
|
* Get the current terminal state.
|
||||||
|
*
|
||||||
|
* @return The current terminal state.
|
||||||
|
* @throws IllegalStateException When accessed on the server.
|
||||||
|
*/
|
||||||
|
public Terminal getTerminal()
|
||||||
{
|
{
|
||||||
if( toUploadId == null || toUpload == null || !toUploadId.equals( uploadId ) )
|
if( terminal == null ) throw new IllegalStateException( "Cannot update terminal on the server" );
|
||||||
{
|
return terminal;
|
||||||
ComputerCraft.log.warn( "Invalid continueUpload call, skipping." );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( FileSlice slice : slices ) slice.apply( toUpload );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void finishUpload( @Nonnull ServerPlayerEntity uploader, @Nonnull UUID uploadId )
|
|
||||||
{
|
|
||||||
if( toUploadId == null || toUpload == null || toUpload.isEmpty() || !toUploadId.equals( uploadId ) )
|
|
||||||
{
|
|
||||||
ComputerCraft.log.warn( "Invalid finishUpload call, skipping." );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UploadResultMessage message = finishUpload( false );
|
|
||||||
NetworkHandler.sendToPlayer( uploader, message );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void confirmUpload( @Nonnull ServerPlayerEntity uploader, boolean overwrite )
|
|
||||||
{
|
|
||||||
if( toUploadId == null || toUpload == null || toUpload.isEmpty() )
|
|
||||||
{
|
|
||||||
ComputerCraft.log.warn( "Invalid finishUpload call, skipping." );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UploadResultMessage message = finishUpload( true );
|
|
||||||
NetworkHandler.sendToPlayer( uploader, message );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private UploadResultMessage finishUpload( boolean forceOverwrite )
|
|
||||||
{
|
|
||||||
ServerComputer computer = (ServerComputer) getComputer();
|
|
||||||
if( computer == null ) return UploadResultMessage.COMPUTER_OFF;
|
|
||||||
|
|
||||||
FileSystem fs = computer.getComputer().getEnvironment().getFileSystem();
|
|
||||||
if( fs == null ) return UploadResultMessage.COMPUTER_OFF;
|
|
||||||
|
|
||||||
for( FileUpload upload : toUpload )
|
|
||||||
{
|
|
||||||
if( !upload.checksumMatches() )
|
|
||||||
{
|
|
||||||
ComputerCraft.log.warn( "Checksum failed to match for {}.", upload.getName() );
|
|
||||||
return new UploadResultMessage( UploadResult.ERROR, new TranslationTextComponent( "gui.computercraft.upload.failed.corrupted" ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
List<String> overwrite = new ArrayList<>();
|
|
||||||
List<FileUpload> files = toUpload;
|
|
||||||
toUpload = null;
|
|
||||||
for( FileUpload upload : files )
|
|
||||||
{
|
|
||||||
if( !fs.exists( upload.getName() ) ) continue;
|
|
||||||
if( fs.isDir( upload.getName() ) )
|
|
||||||
{
|
|
||||||
return new UploadResultMessage(
|
|
||||||
UploadResult.ERROR,
|
|
||||||
new TranslationTextComponent( "gui.computercraft.upload.failed.overwrite_dir", upload.getName() )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
overwrite.add( upload.getName() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !overwrite.isEmpty() && !forceOverwrite )
|
|
||||||
{
|
|
||||||
StringJoiner joiner = new StringJoiner( LIST_PREFIX, LIST_PREFIX, "" );
|
|
||||||
for( String value : overwrite ) joiner.add( value );
|
|
||||||
toUpload = files;
|
|
||||||
return new UploadResultMessage(
|
|
||||||
UploadResult.CONFIRM_OVERWRITE,
|
|
||||||
new TranslationTextComponent( "gui.computercraft.upload.overwrite.detail", joiner.toString() )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
long availableSpace = fs.getFreeSpace( "/" );
|
|
||||||
long neededSpace = 0;
|
|
||||||
for( FileUpload upload : files ) neededSpace += Math.max( 512, upload.getBytes().remaining() );
|
|
||||||
if( neededSpace > availableSpace ) return UploadResultMessage.OUT_OF_SPACE;
|
|
||||||
|
|
||||||
for( FileUpload file : files )
|
|
||||||
{
|
|
||||||
try( FileSystemWrapper<WritableByteChannel> channel = fs.openForWrite( file.getName(), false, Function.identity() ) )
|
|
||||||
{
|
|
||||||
channel.get().write( file.getBytes() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UploadResultMessage(
|
|
||||||
UploadResult.SUCCESS, new TranslationTextComponent( "gui.computercraft.upload.success.msg", files.size() )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch( FileSystemException | IOException e )
|
|
||||||
{
|
|
||||||
ComputerCraft.log.error( "Error uploading files", e );
|
|
||||||
return new UploadResultMessage( UploadResult.ERROR, new TranslationTextComponent( "gui.computercraft.upload.failed.generic", e.getMessage() ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed( @Nonnull PlayerEntity player )
|
public void removed( @Nonnull PlayerEntity player )
|
||||||
{
|
{
|
||||||
super.removed( player );
|
super.removed( player );
|
||||||
input.close();
|
if( input != null ) input.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.computer.inventory;
|
package dan200.computercraft.shared.computer.inventory;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.shared.Registry;
|
import dan200.computercraft.shared.Registry;
|
||||||
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
|
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.network.container.ViewComputerContainerData;
|
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
|
||||||
|
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
|
||||||
@ -18,26 +18,20 @@ import javax.annotation.Nonnull;
|
|||||||
|
|
||||||
public class ContainerViewComputer extends ComputerMenuWithoutInventory
|
public class ContainerViewComputer extends ComputerMenuWithoutInventory
|
||||||
{
|
{
|
||||||
private final int width;
|
|
||||||
private final int height;
|
|
||||||
|
|
||||||
public ContainerViewComputer( int id, PlayerInventory player, ServerComputer computer )
|
public ContainerViewComputer( int id, PlayerInventory player, ServerComputer computer )
|
||||||
{
|
{
|
||||||
super( Registry.ModContainers.VIEW_COMPUTER.get(), id, player, p -> canInteractWith( computer, p ), computer, computer.getFamily() );
|
super( Registry.ModContainers.VIEW_COMPUTER.get(), id, player, p -> canInteractWith( computer, p ), computer, computer.getFamily() );
|
||||||
width = height = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContainerViewComputer( int id, PlayerInventory player, ViewComputerContainerData data )
|
public ContainerViewComputer( int id, PlayerInventory player, ComputerContainerData data )
|
||||||
{
|
{
|
||||||
super( Registry.ModContainers.VIEW_COMPUTER.get(), id, player, data );
|
super( Registry.ModContainers.VIEW_COMPUTER.get(), id, player, data );
|
||||||
width = data.getWidth();
|
|
||||||
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 this computer no longer exists then discard it.
|
||||||
if( ComputerCraft.serverComputerRegistry.get( computer.getInstanceID() ) != computer )
|
if( ServerComputerRegistry.INSTANCE.get( computer.getInstanceID() ) != computer )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -50,14 +44,4 @@ public class ContainerViewComputer extends ComputerMenuWithoutInventory
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWidth()
|
|
||||||
{
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHeight()
|
|
||||||
{
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.computer.menu;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
|
import dan200.computercraft.shared.network.client.TerminalState;
|
||||||
|
import net.minecraft.inventory.container.Container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An instance of {@link Container} which provides a computer. You should implement this if you provide custom computer
|
||||||
|
* GUIs.
|
||||||
|
*/
|
||||||
|
public interface ComputerMenu
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the computer you are interacting with.
|
||||||
|
*
|
||||||
|
* @return The computer you are interacting with.
|
||||||
|
* @throws UnsupportedOperationException When used on the client side.
|
||||||
|
*/
|
||||||
|
ServerComputer getComputer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the input controller for this container. This should be used when receiving events from the client.
|
||||||
|
*
|
||||||
|
* @return This container's input.
|
||||||
|
* @throws UnsupportedOperationException When used on the client side.
|
||||||
|
*/
|
||||||
|
ServerInputHandler getInput();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current terminal state. This is called on the client when the server syncs a computer's terminal
|
||||||
|
* contents.
|
||||||
|
*
|
||||||
|
* @param state The new terminal state.
|
||||||
|
* @throws UnsupportedOperationException When used on the server.
|
||||||
|
*/
|
||||||
|
void updateTerminal( TerminalState state );
|
||||||
|
}
|
@ -3,49 +3,33 @@
|
|||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.computer.core;
|
package dan200.computercraft.shared.computer.menu;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.computer.core.InputHandler;
|
||||||
import dan200.computercraft.shared.computer.upload.FileSlice;
|
import dan200.computercraft.shared.computer.upload.FileSlice;
|
||||||
import dan200.computercraft.shared.computer.upload.FileUpload;
|
import dan200.computercraft.shared.computer.upload.FileUpload;
|
||||||
|
import dan200.computercraft.shared.network.server.ComputerServerMessage;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.inventory.container.Container;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instance of {@link Container} which provides a computer. You should implement this
|
* An {@link InputHandler} which operates on the server, receiving data from the client over the network.
|
||||||
* if you provide custom computers/GUIs to interact with them.
|
*
|
||||||
|
* @see ServerInputState The default implementation of this interface.
|
||||||
|
* @see ComputerServerMessage Packets which consume this interface.
|
||||||
|
* @see ComputerMenu
|
||||||
*/
|
*/
|
||||||
public interface IContainerComputer
|
public interface ServerInputHandler extends InputHandler
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Get the computer you are interacting with.
|
|
||||||
*
|
|
||||||
* This will only be called on the server.
|
|
||||||
*
|
|
||||||
* @return The computer you are interacting with.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
IComputer getComputer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the input controller for this container.
|
|
||||||
*
|
|
||||||
* @return This container's input.
|
|
||||||
*/
|
|
||||||
@Nonnull
|
|
||||||
InputState getInput();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a file upload into this container.
|
* Start a file upload into this container.
|
||||||
*
|
*
|
||||||
* @param uploadId The unique ID of this upload.
|
* @param uploadId The unique ID of this upload.
|
||||||
* @param files The files to upload.
|
* @param files The files to upload.
|
||||||
*/
|
*/
|
||||||
void startUpload( @Nonnull UUID uploadId, @Nonnull List<FileUpload> files );
|
void startUpload( UUID uploadId, List<FileUpload> files );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append more data to partially uploaded files.
|
* Append more data to partially uploaded files.
|
||||||
@ -53,7 +37,7 @@ public interface IContainerComputer
|
|||||||
* @param uploadId The unique ID of this upload.
|
* @param uploadId The unique ID of this upload.
|
||||||
* @param slices Additional parts of file data to upload.
|
* @param slices Additional parts of file data to upload.
|
||||||
*/
|
*/
|
||||||
void continueUpload( @Nonnull UUID uploadId, @Nonnull List<FileSlice> slices );
|
void continueUpload( UUID uploadId, List<FileSlice> slices );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish off an upload. This either writes the uploaded files or informs the user that files will be overwritten.
|
* Finish off an upload. This either writes the uploaded files or informs the user that files will be overwritten.
|
||||||
@ -61,7 +45,7 @@ public interface IContainerComputer
|
|||||||
* @param uploader The player uploading files.
|
* @param uploader The player uploading files.
|
||||||
* @param uploadId The unique ID of this upload.
|
* @param uploadId The unique ID of this upload.
|
||||||
*/
|
*/
|
||||||
void finishUpload( @Nonnull ServerPlayerEntity uploader, @Nonnull UUID uploadId );
|
void finishUpload( ServerPlayerEntity uploader, UUID uploadId );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Continue an upload.
|
* Continue an upload.
|
||||||
@ -69,5 +53,5 @@ public interface IContainerComputer
|
|||||||
* @param uploader The player uploading files.
|
* @param uploader The player uploading files.
|
||||||
* @param overwrite Whether the files should be overwritten or not.
|
* @param overwrite Whether the files should be overwritten or not.
|
||||||
*/
|
*/
|
||||||
void confirmUpload( @Nonnull ServerPlayerEntity uploader, boolean overwrite );
|
void confirmUpload( ServerPlayerEntity uploader, boolean overwrite );
|
||||||
}
|
}
|
@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.computer.menu;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.core.filesystem.FileSystem;
|
||||||
|
import dan200.computercraft.core.filesystem.FileSystemException;
|
||||||
|
import dan200.computercraft.core.filesystem.FileSystemWrapper;
|
||||||
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
|
import dan200.computercraft.shared.computer.upload.FileSlice;
|
||||||
|
import dan200.computercraft.shared.computer.upload.FileUpload;
|
||||||
|
import dan200.computercraft.shared.computer.upload.UploadResult;
|
||||||
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
|
import dan200.computercraft.shared.network.NetworkMessage;
|
||||||
|
import dan200.computercraft.shared.network.client.UploadResultMessage;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntIterator;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default concrete implementation of {@link ServerInputHandler}.
|
||||||
|
* <p>
|
||||||
|
* This keeps track of the current key and mouse state, and releases them when the container is closed.
|
||||||
|
*/
|
||||||
|
public class ServerInputState implements ServerInputHandler
|
||||||
|
{
|
||||||
|
private static final String LIST_PREFIX = "\n \u2022 ";
|
||||||
|
|
||||||
|
private final ComputerMenu owner;
|
||||||
|
private final IntSet keysDown = new IntOpenHashSet( 4 );
|
||||||
|
|
||||||
|
private int lastMouseX;
|
||||||
|
private int lastMouseY;
|
||||||
|
private int lastMouseDown = -1;
|
||||||
|
|
||||||
|
private @Nullable UUID toUploadId;
|
||||||
|
private @Nullable List<FileUpload> toUpload;
|
||||||
|
|
||||||
|
public ServerInputState( ComputerMenu owner )
|
||||||
|
{
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueEvent( String event, @Nullable Object[] arguments )
|
||||||
|
{
|
||||||
|
owner.getComputer().queueEvent( event, arguments );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyDown( int key, boolean repeat )
|
||||||
|
{
|
||||||
|
keysDown.add( key );
|
||||||
|
owner.getComputer().keyDown( key, repeat );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyUp( int key )
|
||||||
|
{
|
||||||
|
keysDown.remove( key );
|
||||||
|
owner.getComputer().keyUp( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClick( int button, int x, int y )
|
||||||
|
{
|
||||||
|
lastMouseX = x;
|
||||||
|
lastMouseY = y;
|
||||||
|
lastMouseDown = button;
|
||||||
|
|
||||||
|
owner.getComputer().mouseClick( button, x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseUp( int button, int x, int y )
|
||||||
|
{
|
||||||
|
lastMouseX = x;
|
||||||
|
lastMouseY = y;
|
||||||
|
lastMouseDown = -1;
|
||||||
|
|
||||||
|
owner.getComputer().mouseUp( button, x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDrag( int button, int x, int y )
|
||||||
|
{
|
||||||
|
lastMouseX = x;
|
||||||
|
lastMouseY = y;
|
||||||
|
lastMouseDown = button;
|
||||||
|
|
||||||
|
owner.getComputer().mouseDrag( button, x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseScroll( int direction, int x, int y )
|
||||||
|
{
|
||||||
|
lastMouseX = x;
|
||||||
|
lastMouseY = y;
|
||||||
|
|
||||||
|
owner.getComputer().mouseScroll( direction, x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown()
|
||||||
|
{
|
||||||
|
owner.getComputer().shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void turnOn()
|
||||||
|
{
|
||||||
|
owner.getComputer().turnOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reboot()
|
||||||
|
{
|
||||||
|
owner.getComputer().reboot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startUpload( UUID uuid, List<FileUpload> files )
|
||||||
|
{
|
||||||
|
toUploadId = uuid;
|
||||||
|
toUpload = files;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void continueUpload( UUID uploadId, List<FileSlice> slices )
|
||||||
|
{
|
||||||
|
if( toUploadId == null || toUpload == null || !toUploadId.equals( uploadId ) )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.warn( "Invalid continueUpload call, skipping." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( FileSlice slice : slices ) slice.apply( toUpload );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finishUpload( ServerPlayerEntity uploader, UUID uploadId )
|
||||||
|
{
|
||||||
|
if( toUploadId == null || toUpload == null || toUpload.isEmpty() || !toUploadId.equals( uploadId ) )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.warn( "Invalid finishUpload call, skipping." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkMessage message = finishUpload( false );
|
||||||
|
NetworkHandler.sendToPlayer( uploader, message );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void confirmUpload( ServerPlayerEntity uploader, boolean overwrite )
|
||||||
|
{
|
||||||
|
if( toUploadId == null || toUpload == null || toUpload.isEmpty() )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.warn( "Invalid finishUpload call, skipping." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkMessage message = finishUpload( true );
|
||||||
|
NetworkHandler.sendToPlayer( uploader, message );
|
||||||
|
}
|
||||||
|
|
||||||
|
private UploadResultMessage finishUpload( boolean forceOverwrite )
|
||||||
|
{
|
||||||
|
ServerComputer computer = owner.getComputer();
|
||||||
|
if( toUpload == null ) return UploadResultMessage.COMPUTER_OFF;
|
||||||
|
|
||||||
|
FileSystem fs = computer.getComputer().getAPIEnvironment().getFileSystem();
|
||||||
|
|
||||||
|
for( FileUpload upload : toUpload )
|
||||||
|
{
|
||||||
|
if( !upload.checksumMatches() )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.warn( "Checksum failed to match for {}.", upload.getName() );
|
||||||
|
return new UploadResultMessage( UploadResult.ERROR, new TranslationTextComponent( "gui.computercraft.upload.failed.corrupted" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<String> overwrite = new ArrayList<>();
|
||||||
|
List<FileUpload> files = toUpload;
|
||||||
|
toUpload = null;
|
||||||
|
for( FileUpload upload : files )
|
||||||
|
{
|
||||||
|
if( !fs.exists( upload.getName() ) ) continue;
|
||||||
|
if( fs.isDir( upload.getName() ) )
|
||||||
|
{
|
||||||
|
return new UploadResultMessage(
|
||||||
|
UploadResult.ERROR,
|
||||||
|
new TranslationTextComponent( "gui.computercraft.upload.failed.overwrite_dir", upload.getName() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
overwrite.add( upload.getName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !overwrite.isEmpty() && !forceOverwrite )
|
||||||
|
{
|
||||||
|
StringJoiner joiner = new StringJoiner( LIST_PREFIX, LIST_PREFIX, "" );
|
||||||
|
for( String value : overwrite ) joiner.add( value );
|
||||||
|
toUpload = files;
|
||||||
|
return new UploadResultMessage(
|
||||||
|
UploadResult.CONFIRM_OVERWRITE,
|
||||||
|
new TranslationTextComponent( "gui.computercraft.upload.overwrite.detail", joiner.toString() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
long availableSpace = fs.getFreeSpace( "/" );
|
||||||
|
long neededSpace = 0;
|
||||||
|
for( FileUpload upload : files ) neededSpace += Math.max( 512, upload.getBytes().remaining() );
|
||||||
|
if( neededSpace > availableSpace ) return UploadResultMessage.OUT_OF_SPACE;
|
||||||
|
|
||||||
|
for( FileUpload file : files )
|
||||||
|
{
|
||||||
|
try( FileSystemWrapper<WritableByteChannel> channel = fs.openForWrite( file.getName(), false, Function.identity() ) )
|
||||||
|
{
|
||||||
|
channel.get().write( file.getBytes() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UploadResultMessage(
|
||||||
|
UploadResult.SUCCESS, new TranslationTextComponent( "gui.computercraft.upload.success.msg", files.size() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch( FileSystemException | IOException e )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.error( "Error uploading files", e );
|
||||||
|
return new UploadResultMessage( UploadResult.ERROR, new TranslationTextComponent( "gui.computercraft.upload.failed.generic", e.getMessage() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
ServerComputer computer = owner.getComputer();
|
||||||
|
IntIterator keys = keysDown.iterator();
|
||||||
|
while( keys.hasNext() ) computer.keyUp( keys.nextInt() );
|
||||||
|
|
||||||
|
if( lastMouseDown != -1 ) computer.mouseUp( lastMouseDown, lastMouseX, lastMouseY );
|
||||||
|
|
||||||
|
keysDown.clear();
|
||||||
|
lastMouseDown = -1;
|
||||||
|
}
|
||||||
|
}
|
@ -11,8 +11,8 @@ import dan200.computercraft.shared.network.client.*;
|
|||||||
import dan200.computercraft.shared.network.server.*;
|
import dan200.computercraft.shared.network.server.*;
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.network.IPacket;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
@ -24,6 +24,7 @@ import net.minecraftforge.fml.network.NetworkRegistry;
|
|||||||
import net.minecraftforge.fml.network.PacketDistributor;
|
import net.minecraftforge.fml.network.PacketDistributor;
|
||||||
import net.minecraftforge.fml.network.simple.SimpleChannel;
|
import net.minecraftforge.fml.network.simple.SimpleChannel;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public final class NetworkHandler
|
public final class NetworkHandler
|
||||||
@ -46,16 +47,15 @@ public final class NetworkHandler
|
|||||||
// Server messages
|
// Server messages
|
||||||
registerMainThread( 0, NetworkDirection.PLAY_TO_SERVER, ComputerActionServerMessage.class, ComputerActionServerMessage::new );
|
registerMainThread( 0, NetworkDirection.PLAY_TO_SERVER, ComputerActionServerMessage.class, ComputerActionServerMessage::new );
|
||||||
registerMainThread( 1, NetworkDirection.PLAY_TO_SERVER, QueueEventServerMessage.class, QueueEventServerMessage::new );
|
registerMainThread( 1, NetworkDirection.PLAY_TO_SERVER, QueueEventServerMessage.class, QueueEventServerMessage::new );
|
||||||
registerMainThread( 2, NetworkDirection.PLAY_TO_SERVER, RequestComputerMessage.class, RequestComputerMessage::new );
|
registerMainThread( 2, NetworkDirection.PLAY_TO_SERVER, KeyEventServerMessage.class, KeyEventServerMessage::new );
|
||||||
registerMainThread( 3, NetworkDirection.PLAY_TO_SERVER, KeyEventServerMessage.class, KeyEventServerMessage::new );
|
registerMainThread( 3, NetworkDirection.PLAY_TO_SERVER, MouseEventServerMessage.class, MouseEventServerMessage::new );
|
||||||
registerMainThread( 4, NetworkDirection.PLAY_TO_SERVER, MouseEventServerMessage.class, MouseEventServerMessage::new );
|
registerMainThread( 4, NetworkDirection.PLAY_TO_SERVER, UploadFileMessage.class, UploadFileMessage::new );
|
||||||
registerMainThread( 5, NetworkDirection.PLAY_TO_SERVER, UploadFileMessage.class, UploadFileMessage::new );
|
registerMainThread( 5, NetworkDirection.PLAY_TO_SERVER, ContinueUploadMessage.class, ContinueUploadMessage::new );
|
||||||
registerMainThread( 6, NetworkDirection.PLAY_TO_SERVER, ContinueUploadMessage.class, ContinueUploadMessage::new );
|
|
||||||
|
|
||||||
// Client messages
|
// Client messages
|
||||||
registerMainThread( 10, NetworkDirection.PLAY_TO_CLIENT, ChatTableClientMessage.class, ChatTableClientMessage::new );
|
registerMainThread( 10, NetworkDirection.PLAY_TO_CLIENT, ChatTableClientMessage.class, ChatTableClientMessage::new );
|
||||||
registerMainThread( 11, NetworkDirection.PLAY_TO_CLIENT, ComputerDataClientMessage.class, ComputerDataClientMessage::new );
|
registerMainThread( 11, NetworkDirection.PLAY_TO_CLIENT, PocketComputerDataMessage.class, PocketComputerDataMessage::new );
|
||||||
registerMainThread( 12, NetworkDirection.PLAY_TO_CLIENT, ComputerDeletedClientMessage.class, ComputerDeletedClientMessage::new );
|
registerMainThread( 12, NetworkDirection.PLAY_TO_CLIENT, PocketComputerDeletedClientMessage.class, PocketComputerDeletedClientMessage::new );
|
||||||
registerMainThread( 13, NetworkDirection.PLAY_TO_CLIENT, ComputerTerminalClientMessage.class, ComputerTerminalClientMessage::new );
|
registerMainThread( 13, NetworkDirection.PLAY_TO_CLIENT, ComputerTerminalClientMessage.class, ComputerTerminalClientMessage::new );
|
||||||
registerMainThread( 14, NetworkDirection.PLAY_TO_CLIENT, PlayRecordClientMessage.class, PlayRecordClientMessage::new );
|
registerMainThread( 14, NetworkDirection.PLAY_TO_CLIENT, PlayRecordClientMessage.class, PlayRecordClientMessage::new );
|
||||||
registerMainThread( 15, NetworkDirection.PLAY_TO_CLIENT, MonitorClientMessage.class, MonitorClientMessage::new );
|
registerMainThread( 15, NetworkDirection.PLAY_TO_CLIENT, MonitorClientMessage.class, MonitorClientMessage::new );
|
||||||
@ -66,9 +66,9 @@ public final class NetworkHandler
|
|||||||
registerMainThread( 20, NetworkDirection.PLAY_TO_CLIENT, UploadResultMessage.class, UploadResultMessage::new );
|
registerMainThread( 20, NetworkDirection.PLAY_TO_CLIENT, UploadResultMessage.class, UploadResultMessage::new );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendToPlayer( PlayerEntity player, NetworkMessage packet )
|
public static void sendToPlayer( ServerPlayerEntity player, NetworkMessage packet )
|
||||||
{
|
{
|
||||||
network.sendTo( packet, ((ServerPlayerEntity) player).connection.connection, NetworkDirection.PLAY_TO_CLIENT );
|
network.sendTo( packet, player.connection.connection, NetworkDirection.PLAY_TO_CLIENT );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendToAllPlayers( NetworkMessage packet )
|
public static void sendToAllPlayers( NetworkMessage packet )
|
||||||
@ -92,6 +92,15 @@ public final class NetworkHandler
|
|||||||
network.send( PacketDistributor.TRACKING_CHUNK.with( () -> chunk ), packet );
|
network.send( PacketDistributor.TRACKING_CHUNK.with( () -> chunk ), packet );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void sendToPlayers( NetworkMessage packet, Collection<ServerPlayerEntity> players )
|
||||||
|
{
|
||||||
|
if( players.isEmpty() ) return;
|
||||||
|
|
||||||
|
IPacket<?> vanillaPacket = network.toVanillaPacket( packet, NetworkDirection.PLAY_TO_CLIENT );
|
||||||
|
for( ServerPlayerEntity player : players ) player.connection.send( vanillaPacket );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register packet, and a thread-unsafe handler for it.
|
* Register packet, and a thread-unsafe handler for it.
|
||||||
*
|
*
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.network.client;
|
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
|
||||||
import dan200.computercraft.shared.network.NetworkMessage;
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A packet, which performs an action on a {@link ClientComputer}.
|
|
||||||
*/
|
|
||||||
public abstract class ComputerClientMessage implements NetworkMessage
|
|
||||||
{
|
|
||||||
private final int instanceId;
|
|
||||||
|
|
||||||
public ComputerClientMessage( int instanceId )
|
|
||||||
{
|
|
||||||
this.instanceId = instanceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ComputerClientMessage( @Nonnull PacketBuffer buf )
|
|
||||||
{
|
|
||||||
instanceId = buf.readVarInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getInstanceId()
|
|
||||||
{
|
|
||||||
return instanceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
|
||||||
{
|
|
||||||
buf.writeVarInt( instanceId );
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClientComputer getComputer()
|
|
||||||
{
|
|
||||||
ClientComputer computer = ComputerCraft.clientComputerRegistry.get( instanceId );
|
|
||||||
if( computer == null )
|
|
||||||
{
|
|
||||||
ComputerCraft.clientComputerRegistry.add( instanceId, computer = new ClientComputer( instanceId ) );
|
|
||||||
}
|
|
||||||
return computer;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.network.client;
|
|
||||||
|
|
||||||
import dan200.computercraft.shared.computer.core.ComputerState;
|
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides additional data about a client computer, such as its ID and current state.
|
|
||||||
*/
|
|
||||||
public class ComputerDataClientMessage extends ComputerClientMessage
|
|
||||||
{
|
|
||||||
private final ComputerState state;
|
|
||||||
private final CompoundNBT userData;
|
|
||||||
|
|
||||||
public ComputerDataClientMessage( ServerComputer computer )
|
|
||||||
{
|
|
||||||
super( computer.getInstanceID() );
|
|
||||||
state = computer.getState();
|
|
||||||
userData = computer.getUserData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ComputerDataClientMessage( @Nonnull PacketBuffer buf )
|
|
||||||
{
|
|
||||||
super( buf );
|
|
||||||
state = buf.readEnum( ComputerState.class );
|
|
||||||
userData = buf.readNbt();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
|
||||||
{
|
|
||||||
super.toBytes( buf );
|
|
||||||
buf.writeEnum( state );
|
|
||||||
buf.writeNbt( userData );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle( NetworkEvent.Context context )
|
|
||||||
{
|
|
||||||
getComputer().setState( state, userData );
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.network.client;
|
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
|
||||||
|
|
||||||
public class ComputerDeletedClientMessage extends ComputerClientMessage
|
|
||||||
{
|
|
||||||
public ComputerDeletedClientMessage( int instanceId )
|
|
||||||
{
|
|
||||||
super( instanceId );
|
|
||||||
}
|
|
||||||
|
|
||||||
public ComputerDeletedClientMessage( PacketBuffer buffer )
|
|
||||||
{
|
|
||||||
super( buffer );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle( NetworkEvent.Context context )
|
|
||||||
{
|
|
||||||
ComputerCraft.clientComputerRegistry.remove( getInstanceId() );
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,37 +5,50 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.network.client;
|
package dan200.computercraft.shared.network.client;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
|
import dan200.computercraft.shared.network.NetworkMessage;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class ComputerTerminalClientMessage extends ComputerClientMessage
|
public class ComputerTerminalClientMessage implements NetworkMessage
|
||||||
{
|
{
|
||||||
private final TerminalState state;
|
private final int containerId;
|
||||||
|
private final TerminalState terminal;
|
||||||
|
|
||||||
public ComputerTerminalClientMessage( int instanceId, TerminalState state )
|
public ComputerTerminalClientMessage( Container menu, TerminalState terminal )
|
||||||
{
|
{
|
||||||
super( instanceId );
|
containerId = menu.containerId;
|
||||||
this.state = state;
|
this.terminal = terminal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComputerTerminalClientMessage( @Nonnull PacketBuffer buf )
|
public ComputerTerminalClientMessage( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
super( buf );
|
containerId = buf.readVarInt();
|
||||||
state = new TerminalState( buf );
|
terminal = new TerminalState( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
super.toBytes( buf );
|
buf.writeVarInt( containerId );
|
||||||
state.write( buf );
|
terminal.write( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@OnlyIn( Dist.CLIENT )
|
||||||
public void handle( NetworkEvent.Context context )
|
public void handle( NetworkEvent.Context context )
|
||||||
{
|
{
|
||||||
getComputer().read( state );
|
PlayerEntity player = Minecraft.getInstance().player;
|
||||||
|
if( player != null && player.containerMenu.containerId == containerId && player.containerMenu instanceof ComputerMenu )
|
||||||
|
{
|
||||||
|
((ComputerMenu) player.containerMenu).updateTerminal( terminal );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ import net.minecraft.client.entity.player.ClientPlayerEntity;
|
|||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -41,6 +43,7 @@ public class MonitorClientMessage implements NetworkMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@OnlyIn( Dist.CLIENT )
|
||||||
public void handle( NetworkEvent.Context context )
|
public void handle( NetworkEvent.Context context )
|
||||||
{
|
{
|
||||||
ClientPlayerEntity player = Minecraft.getInstance().player;
|
ClientPlayerEntity player = Minecraft.getInstance().player;
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.network.client;
|
||||||
|
|
||||||
|
import dan200.computercraft.client.pocket.ClientPocketComputers;
|
||||||
|
import dan200.computercraft.client.pocket.PocketComputerData;
|
||||||
|
import dan200.computercraft.shared.computer.core.ComputerState;
|
||||||
|
import dan200.computercraft.shared.network.NetworkMessage;
|
||||||
|
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides additional data about a client computer, such as its ID and current state.
|
||||||
|
*/
|
||||||
|
public class PocketComputerDataMessage implements NetworkMessage
|
||||||
|
{
|
||||||
|
private final int instanceId;
|
||||||
|
private final ComputerState state;
|
||||||
|
private final int lightState;
|
||||||
|
private final TerminalState terminal;
|
||||||
|
|
||||||
|
public PocketComputerDataMessage( PocketServerComputer computer, boolean sendTerminal )
|
||||||
|
{
|
||||||
|
instanceId = computer.getInstanceID();
|
||||||
|
state = computer.getState();
|
||||||
|
lightState = computer.getLight();
|
||||||
|
terminal = sendTerminal ? computer.getTerminalState() : new TerminalState( false, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public PocketComputerDataMessage( PacketBuffer buf )
|
||||||
|
{
|
||||||
|
instanceId = buf.readVarInt();
|
||||||
|
state = buf.readEnum( ComputerState.class );
|
||||||
|
lightState = buf.readVarInt();
|
||||||
|
terminal = new TerminalState( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toBytes( PacketBuffer buf )
|
||||||
|
{
|
||||||
|
buf.writeVarInt( instanceId );
|
||||||
|
buf.writeEnum( state );
|
||||||
|
buf.writeVarInt( lightState );
|
||||||
|
terminal.write( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle( NetworkEvent.Context context )
|
||||||
|
{
|
||||||
|
PocketComputerData computer = ClientPocketComputers.get( instanceId, terminal.colour );
|
||||||
|
computer.setState( state, lightState );
|
||||||
|
if( terminal.hasTerminal() ) computer.setTerminal( terminal );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.network.client;
|
||||||
|
|
||||||
|
import dan200.computercraft.client.pocket.ClientPocketComputers;
|
||||||
|
import dan200.computercraft.shared.network.NetworkMessage;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class PocketComputerDeletedClientMessage implements NetworkMessage
|
||||||
|
{
|
||||||
|
private final int instanceId;
|
||||||
|
|
||||||
|
public PocketComputerDeletedClientMessage( int instanceId )
|
||||||
|
{
|
||||||
|
this.instanceId = instanceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PocketComputerDeletedClientMessage( PacketBuffer buffer )
|
||||||
|
{
|
||||||
|
instanceId = buffer.readVarInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
|
{
|
||||||
|
buf.writeVarInt( instanceId );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle( NetworkEvent.Context context )
|
||||||
|
{
|
||||||
|
ClientPocketComputers.remove( instanceId );
|
||||||
|
}
|
||||||
|
}
|
@ -120,6 +120,14 @@ public class TerminalState
|
|||||||
terminal.read( new PacketBuffer( buffer ) );
|
terminal.read( new PacketBuffer( buffer ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Terminal create()
|
||||||
|
{
|
||||||
|
if( buffer == null ) throw new NullPointerException( "Terminal does not exist" );
|
||||||
|
Terminal terminal = new Terminal( width, height );
|
||||||
|
terminal.read( new PacketBuffer( buffer ) );
|
||||||
|
return terminal;
|
||||||
|
}
|
||||||
|
|
||||||
private ByteBuf getCompressed()
|
private ByteBuf getCompressed()
|
||||||
{
|
{
|
||||||
if( buffer == null ) throw new NullPointerException( "buffer" );
|
if( buffer == null ) throw new NullPointerException( "buffer" );
|
||||||
|
@ -7,39 +7,40 @@ package dan200.computercraft.shared.network.container;
|
|||||||
|
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
|
import dan200.computercraft.shared.network.client.TerminalState;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
|
||||||
public class ComputerContainerData implements ContainerData
|
public class ComputerContainerData implements ContainerData
|
||||||
{
|
{
|
||||||
private final int id;
|
|
||||||
private final ComputerFamily family;
|
private final ComputerFamily family;
|
||||||
|
private final TerminalState terminal;
|
||||||
|
|
||||||
public ComputerContainerData( ServerComputer computer )
|
public ComputerContainerData( ServerComputer computer )
|
||||||
{
|
{
|
||||||
id = computer.getInstanceID();
|
|
||||||
family = computer.getFamily();
|
family = computer.getFamily();
|
||||||
|
terminal = computer.getTerminalState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComputerContainerData( PacketBuffer buf )
|
public ComputerContainerData( PacketBuffer buf )
|
||||||
{
|
{
|
||||||
id = buf.readInt();
|
|
||||||
family = buf.readEnum( ComputerFamily.class );
|
family = buf.readEnum( ComputerFamily.class );
|
||||||
|
terminal = new TerminalState( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBytes( PacketBuffer buf )
|
public void toBytes( PacketBuffer buf )
|
||||||
{
|
{
|
||||||
buf.writeInt( id );
|
|
||||||
buf.writeEnum( family );
|
buf.writeEnum( family );
|
||||||
|
terminal.write( buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInstanceId()
|
public ComputerFamily family()
|
||||||
{
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ComputerFamily getFamily()
|
|
||||||
{
|
{
|
||||||
return family;
|
return family;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TerminalState terminal()
|
||||||
|
{
|
||||||
|
return terminal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.network.container;
|
|
||||||
|
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* View an arbitrary computer on the client.
|
|
||||||
*
|
|
||||||
* @see dan200.computercraft.shared.command.CommandComputerCraft
|
|
||||||
*/
|
|
||||||
public class ViewComputerContainerData extends ComputerContainerData
|
|
||||||
{
|
|
||||||
private final int width;
|
|
||||||
private final int height;
|
|
||||||
|
|
||||||
public ViewComputerContainerData( ServerComputer computer )
|
|
||||||
{
|
|
||||||
super( computer );
|
|
||||||
Terminal terminal = computer.getTerminal();
|
|
||||||
if( terminal != null )
|
|
||||||
{
|
|
||||||
width = terminal.getWidth();
|
|
||||||
height = terminal.getHeight();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
width = height = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ViewComputerContainerData( PacketBuffer buffer )
|
|
||||||
{
|
|
||||||
super( buffer );
|
|
||||||
width = buffer.readVarInt();
|
|
||||||
height = buffer.readVarInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
|
||||||
{
|
|
||||||
super.toBytes( buf );
|
|
||||||
buf.writeVarInt( width );
|
|
||||||
buf.writeVarInt( height );
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWidth()
|
|
||||||
{
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHeight()
|
|
||||||
{
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,8 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
@ -16,9 +16,9 @@ public class ComputerActionServerMessage extends ComputerServerMessage
|
|||||||
{
|
{
|
||||||
private final Action action;
|
private final Action action;
|
||||||
|
|
||||||
public ComputerActionServerMessage( int instanceId, Action action )
|
public ComputerActionServerMessage( Container menu, Action action )
|
||||||
{
|
{
|
||||||
super( instanceId );
|
super( menu );
|
||||||
this.action = action;
|
this.action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,18 +36,18 @@ public class ComputerActionServerMessage extends ComputerServerMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handle( NetworkEvent.Context context, @Nonnull ServerComputer computer, @Nonnull IContainerComputer container )
|
protected void handle( NetworkEvent.Context context, @Nonnull ComputerMenu container )
|
||||||
{
|
{
|
||||||
switch( action )
|
switch( action )
|
||||||
{
|
{
|
||||||
case TURN_ON:
|
case TURN_ON:
|
||||||
computer.turnOn();
|
container.getInput().turnOn();
|
||||||
break;
|
break;
|
||||||
case REBOOT:
|
case REBOOT:
|
||||||
computer.reboot();
|
container.getInput().reboot();
|
||||||
break;
|
break;
|
||||||
case SHUTDOWN:
|
case SHUTDOWN:
|
||||||
computer.shutdown();
|
container.getInput().shutdown();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,52 +5,49 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
|
||||||
import dan200.computercraft.shared.network.NetworkMessage;
|
import dan200.computercraft.shared.network.NetworkMessage;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.OverridingMethodsMustInvokeSuper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A packet, which performs an action on a {@link ServerComputer}.
|
* A packet, which performs an action on the currently open {@link ComputerMenu}.
|
||||||
*
|
|
||||||
* This requires that the sending player is interacting with that computer via a
|
|
||||||
* {@link IContainerComputer}.
|
|
||||||
*/
|
*/
|
||||||
public abstract class ComputerServerMessage implements NetworkMessage
|
public abstract class ComputerServerMessage implements NetworkMessage
|
||||||
{
|
{
|
||||||
private final int instanceId;
|
private final int containerId;
|
||||||
|
|
||||||
public ComputerServerMessage( int instanceId )
|
protected ComputerServerMessage( Container menu )
|
||||||
{
|
{
|
||||||
this.instanceId = instanceId;
|
containerId = menu.containerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComputerServerMessage( @Nonnull PacketBuffer buf )
|
protected ComputerServerMessage( PacketBuffer buffer )
|
||||||
{
|
{
|
||||||
instanceId = buf.readVarInt();
|
containerId = buffer.readVarInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@OverridingMethodsMustInvokeSuper
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
buf.writeVarInt( instanceId );
|
buf.writeVarInt( containerId );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle( NetworkEvent.Context context )
|
public void handle( NetworkEvent.Context context )
|
||||||
{
|
{
|
||||||
ServerComputer computer = ComputerCraft.serverComputerRegistry.get( instanceId );
|
PlayerEntity player = context.getSender();
|
||||||
if( computer == null ) return;
|
if( player.containerMenu.containerId == containerId && player.containerMenu instanceof ComputerMenu )
|
||||||
|
{
|
||||||
IContainerComputer container = computer.getContainer( context.getSender() );
|
handle( context, (ComputerMenu) player.containerMenu );
|
||||||
if( container == null ) return;
|
}
|
||||||
|
|
||||||
handle( context, computer, container );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void handle( NetworkEvent.Context context, @Nonnull ServerComputer computer, @Nonnull IContainerComputer container );
|
protected abstract void handle( NetworkEvent.Context context, @Nonnull ComputerMenu container );
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
@ -17,9 +17,9 @@ public class ContinueUploadMessage extends ComputerServerMessage
|
|||||||
{
|
{
|
||||||
private final boolean overwrite;
|
private final boolean overwrite;
|
||||||
|
|
||||||
public ContinueUploadMessage( int instanceId, boolean overwrite )
|
public ContinueUploadMessage( Container menu, boolean overwrite )
|
||||||
{
|
{
|
||||||
super( instanceId );
|
super( menu );
|
||||||
this.overwrite = overwrite;
|
this.overwrite = overwrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,9 +37,9 @@ public class ContinueUploadMessage extends ComputerServerMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handle( NetworkEvent.Context context, @Nonnull ServerComputer computer, @Nonnull IContainerComputer container )
|
protected void handle( NetworkEvent.Context context, @Nonnull ComputerMenu container )
|
||||||
{
|
{
|
||||||
ServerPlayerEntity player = context.getSender();
|
ServerPlayerEntity player = context.getSender();
|
||||||
if( player != null ) container.confirmUpload( player, overwrite );
|
if( player != null ) container.getInput().confirmUpload( player, overwrite );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
import dan200.computercraft.shared.computer.core.InputState;
|
import dan200.computercraft.shared.computer.menu.ServerInputHandler;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
@ -22,9 +22,9 @@ public class KeyEventServerMessage extends ComputerServerMessage
|
|||||||
private final int type;
|
private final int type;
|
||||||
private final int key;
|
private final int key;
|
||||||
|
|
||||||
public KeyEventServerMessage( int instanceId, int type, int key )
|
public KeyEventServerMessage( Container menu, int type, int key )
|
||||||
{
|
{
|
||||||
super( instanceId );
|
super( menu );
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
@ -39,15 +39,14 @@ public class KeyEventServerMessage extends ComputerServerMessage
|
|||||||
@Override
|
@Override
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
public void toBytes( @Nonnull PacketBuffer buf )
|
||||||
{
|
{
|
||||||
super.toBytes( buf );
|
|
||||||
buf.writeByte( type );
|
buf.writeByte( type );
|
||||||
buf.writeVarInt( key );
|
buf.writeVarInt( key );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handle( NetworkEvent.Context context, @Nonnull ServerComputer computer, @Nonnull IContainerComputer container )
|
protected void handle( NetworkEvent.Context context, @Nonnull ComputerMenu container )
|
||||||
{
|
{
|
||||||
InputState input = container.getInput();
|
ServerInputHandler input = container.getInput();
|
||||||
if( type == TYPE_UP )
|
if( type == TYPE_UP )
|
||||||
{
|
{
|
||||||
input.keyUp( key );
|
input.keyUp( key );
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
import dan200.computercraft.shared.computer.core.InputState;
|
import dan200.computercraft.shared.computer.menu.ServerInputHandler;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
@ -25,9 +25,9 @@ public class MouseEventServerMessage extends ComputerServerMessage
|
|||||||
private final int y;
|
private final int y;
|
||||||
private final int arg;
|
private final int arg;
|
||||||
|
|
||||||
public MouseEventServerMessage( int instanceId, int type, int arg, int x, int y )
|
public MouseEventServerMessage( Container menu, int type, int arg, int x, int y )
|
||||||
{
|
{
|
||||||
super( instanceId );
|
super( menu );
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.arg = arg;
|
this.arg = arg;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
@ -54,9 +54,9 @@ public class MouseEventServerMessage extends ComputerServerMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handle( NetworkEvent.Context context, @Nonnull ServerComputer computer, @Nonnull IContainerComputer container )
|
protected void handle( NetworkEvent.Context context, @Nonnull ComputerMenu container )
|
||||||
{
|
{
|
||||||
InputState input = container.getInput();
|
ServerInputHandler input = container.getInput();
|
||||||
switch( type )
|
switch( type )
|
||||||
{
|
{
|
||||||
case TYPE_CLICK:
|
case TYPE_CLICK:
|
||||||
|
@ -5,9 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
|
import dan200.computercraft.shared.computer.menu.ServerInputHandler;
|
||||||
import dan200.computercraft.shared.util.NBTUtil;
|
import dan200.computercraft.shared.util.NBTUtil;
|
||||||
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
@ -18,17 +20,16 @@ import javax.annotation.Nullable;
|
|||||||
/**
|
/**
|
||||||
* Queue an event on a {@link ServerComputer}.
|
* Queue an event on a {@link ServerComputer}.
|
||||||
*
|
*
|
||||||
* @see dan200.computercraft.shared.computer.core.ClientComputer#queueEvent(String)
|
* @see ServerInputHandler#queueEvent(String)
|
||||||
* @see ServerComputer#queueEvent(String)
|
|
||||||
*/
|
*/
|
||||||
public class QueueEventServerMessage extends ComputerServerMessage
|
public class QueueEventServerMessage extends ComputerServerMessage
|
||||||
{
|
{
|
||||||
private final String event;
|
private final String event;
|
||||||
private final Object[] args;
|
private final Object[] args;
|
||||||
|
|
||||||
public QueueEventServerMessage( int instanceId, @Nonnull String event, @Nullable Object[] args )
|
public QueueEventServerMessage( Container menu, @Nonnull String event, @Nullable Object[] args )
|
||||||
{
|
{
|
||||||
super( instanceId );
|
super( menu );
|
||||||
this.event = event;
|
this.event = event;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
}
|
}
|
||||||
@ -51,8 +52,8 @@ public class QueueEventServerMessage extends ComputerServerMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handle( NetworkEvent.Context context, @Nonnull ServerComputer computer, @Nonnull IContainerComputer container )
|
protected void handle( NetworkEvent.Context context, @Nonnull ComputerMenu container )
|
||||||
{
|
{
|
||||||
computer.queueEvent( event, args );
|
container.getInput().queueEvent( event, args );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.network.server;
|
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
|
||||||
import dan200.computercraft.shared.network.NetworkMessage;
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
public class RequestComputerMessage implements NetworkMessage
|
|
||||||
{
|
|
||||||
private final int instance;
|
|
||||||
|
|
||||||
public RequestComputerMessage( int instance )
|
|
||||||
{
|
|
||||||
this.instance = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RequestComputerMessage( @Nonnull PacketBuffer buf )
|
|
||||||
{
|
|
||||||
instance = buf.readVarInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes( @Nonnull PacketBuffer buf )
|
|
||||||
{
|
|
||||||
buf.writeVarInt( instance );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle( NetworkEvent.Context context )
|
|
||||||
{
|
|
||||||
ServerComputer computer = ComputerCraft.serverComputerRegistry.get( instance );
|
|
||||||
if( computer != null ) computer.sendComputerState( context.getSender() );
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,13 +5,14 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
import dan200.computercraft.shared.computer.menu.ComputerMenu;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.menu.ServerInputHandler;
|
||||||
import dan200.computercraft.shared.computer.upload.FileSlice;
|
import dan200.computercraft.shared.computer.upload.FileSlice;
|
||||||
import dan200.computercraft.shared.computer.upload.FileUpload;
|
import dan200.computercraft.shared.computer.upload.FileUpload;
|
||||||
import dan200.computercraft.shared.network.NetworkHandler;
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
import io.netty.handler.codec.DecoderException;
|
import io.netty.handler.codec.DecoderException;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
|
|
||||||
@ -37,9 +38,9 @@ public class UploadFileMessage extends ComputerServerMessage
|
|||||||
private final List<FileUpload> files;
|
private final List<FileUpload> files;
|
||||||
private final List<FileSlice> slices;
|
private final List<FileSlice> slices;
|
||||||
|
|
||||||
UploadFileMessage( int instanceId, UUID uuid, int flag, List<FileUpload> files, List<FileSlice> slices )
|
UploadFileMessage( Container menu, UUID uuid, int flag, List<FileUpload> files, List<FileSlice> slices )
|
||||||
{
|
{
|
||||||
super( instanceId );
|
super( menu );
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.flag = flag;
|
this.flag = flag;
|
||||||
this.files = files;
|
this.files = files;
|
||||||
@ -127,7 +128,7 @@ public class UploadFileMessage extends ComputerServerMessage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void send( int instanceId, List<FileUpload> files )
|
public static void send( Container container, List<FileUpload> files )
|
||||||
{
|
{
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
|
|
||||||
@ -148,8 +149,8 @@ public class UploadFileMessage extends ComputerServerMessage
|
|||||||
if( remaining <= 0 )
|
if( remaining <= 0 )
|
||||||
{
|
{
|
||||||
NetworkHandler.sendToServer( first
|
NetworkHandler.sendToServer( first
|
||||||
? new UploadFileMessage( instanceId, uuid, FLAG_FIRST, files, new ArrayList<>( slices ) )
|
? new UploadFileMessage( container, uuid, FLAG_FIRST, files, new ArrayList<>( slices ) )
|
||||||
: new UploadFileMessage( instanceId, uuid, 0, null, new ArrayList<>( slices ) ) );
|
: new UploadFileMessage( container, uuid, 0, null, new ArrayList<>( slices ) ) );
|
||||||
slices.clear();
|
slices.clear();
|
||||||
remaining = MAX_PACKET_SIZE;
|
remaining = MAX_PACKET_SIZE;
|
||||||
first = false;
|
first = false;
|
||||||
@ -167,19 +168,20 @@ public class UploadFileMessage extends ComputerServerMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
NetworkHandler.sendToServer( first
|
NetworkHandler.sendToServer( first
|
||||||
? new UploadFileMessage( instanceId, uuid, FLAG_FIRST | FLAG_LAST, files, new ArrayList<>( slices ) )
|
? new UploadFileMessage( container, uuid, FLAG_FIRST | FLAG_LAST, files, new ArrayList<>( slices ) )
|
||||||
: new UploadFileMessage( instanceId, uuid, FLAG_LAST, null, new ArrayList<>( slices ) ) );
|
: new UploadFileMessage( container, uuid, FLAG_LAST, null, new ArrayList<>( slices ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handle( NetworkEvent.Context context, @Nonnull ServerComputer computer, @Nonnull IContainerComputer container )
|
protected void handle( NetworkEvent.Context context, @Nonnull ComputerMenu container )
|
||||||
{
|
{
|
||||||
ServerPlayerEntity player = context.getSender();
|
ServerPlayerEntity player = context.getSender();
|
||||||
if( player != null )
|
if( player != null )
|
||||||
{
|
{
|
||||||
if( (flag & FLAG_FIRST) != 0 ) container.startUpload( uuid, files );
|
ServerInputHandler input = container.getInput();
|
||||||
container.continueUpload( uuid, slices );
|
if( (flag & FLAG_FIRST) != 0 ) input.startUpload( uuid, files );
|
||||||
if( (flag & FLAG_LAST) != 0 ) container.finishUpload( player, uuid );
|
input.continueUpload( uuid, slices );
|
||||||
|
if( (flag & FLAG_LAST) != 0 ) input.finishUpload( player, uuid );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class ServerMonitor extends ServerTerminal
|
|||||||
|
|
||||||
public boolean pollTerminalChanged()
|
public boolean pollTerminalChanged()
|
||||||
{
|
{
|
||||||
update();
|
tickServer();
|
||||||
return hasTerminalChanged();
|
return hasTerminalChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ import dan200.computercraft.shared.common.IColouredItem;
|
|||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.network.NetworkHandler;
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
|
import dan200.computercraft.shared.network.client.PocketComputerDataMessage;
|
||||||
|
import dan200.computercraft.shared.network.client.PocketComputerDeletedClientMessage;
|
||||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
@ -24,15 +26,11 @@ import net.minecraft.entity.player.ServerPlayerEntity;
|
|||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.server.ServerWorld;
|
||||||
import net.minecraftforge.common.util.Constants;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static dan200.computercraft.shared.pocket.items.ItemPocketComputer.NBT_LIGHT;
|
|
||||||
|
|
||||||
public class PocketServerComputer extends ServerComputer implements IPocketAccess
|
public class PocketServerComputer extends ServerComputer implements IPocketAccess
|
||||||
{
|
{
|
||||||
@ -40,9 +38,14 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
|||||||
private Entity entity;
|
private Entity entity;
|
||||||
private ItemStack stack;
|
private ItemStack stack;
|
||||||
|
|
||||||
public PocketServerComputer( World world, int computerID, String label, int instanceID, ComputerFamily family )
|
private int lightColour = -1;
|
||||||
|
private boolean lightChanged = false;
|
||||||
|
|
||||||
|
private final Set<ServerPlayerEntity> tracking = new HashSet<>();
|
||||||
|
|
||||||
|
public PocketServerComputer( ServerWorld world, int computerID, String label, ComputerFamily family )
|
||||||
{
|
{
|
||||||
super( world, computerID, label, instanceID, family, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight );
|
super( world, computerID, label, family, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -89,27 +92,17 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
|||||||
@Override
|
@Override
|
||||||
public int getLight()
|
public int getLight()
|
||||||
{
|
{
|
||||||
CompoundNBT tag = getUserData();
|
return lightColour;
|
||||||
return tag.contains( NBT_LIGHT, Constants.NBT.TAG_ANY_NUMERIC ) ? tag.getInt( NBT_LIGHT ) : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLight( int colour )
|
public void setLight( int colour )
|
||||||
{
|
{
|
||||||
CompoundNBT tag = getUserData();
|
if( colour < 0 || colour > 0xFFFFFF ) colour = -1;
|
||||||
if( colour >= 0 && colour <= 0xFFFFFF )
|
|
||||||
{
|
if( lightColour == colour ) return;
|
||||||
if( !tag.contains( NBT_LIGHT, Constants.NBT.TAG_ANY_NUMERIC ) || tag.getInt( NBT_LIGHT ) != colour )
|
lightColour = colour;
|
||||||
{
|
lightChanged = true;
|
||||||
tag.putInt( NBT_LIGHT, colour );
|
|
||||||
updateUserData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( tag.contains( NBT_LIGHT, Constants.NBT.TAG_ANY_NUMERIC ) )
|
|
||||||
{
|
|
||||||
tag.remove( NBT_LIGHT );
|
|
||||||
updateUserData();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -168,7 +161,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
|||||||
{
|
{
|
||||||
if( entity != null )
|
if( entity != null )
|
||||||
{
|
{
|
||||||
setWorld( entity.getCommandSenderWorld() );
|
setWorld( (ServerWorld) entity.getCommandSenderWorld() );
|
||||||
setPosition( entity.blockPosition() );
|
setPosition( entity.blockPosition() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,18 +179,53 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void broadcastState( boolean force )
|
public void tickServer()
|
||||||
{
|
{
|
||||||
super.broadcastState( force );
|
super.tickServer();
|
||||||
|
|
||||||
if( (hasTerminalChanged() || force) && entity instanceof ServerPlayerEntity )
|
// Find any players which have gone missing and remove them from the tracking list.
|
||||||
|
tracking.removeIf( player -> !player.isAlive() || player.level != getWorld() );
|
||||||
|
|
||||||
|
// And now find any new players, add them to the tracking list, and broadcast state where appropriate.
|
||||||
|
boolean sendState = hasOutputChanged() || lightChanged;
|
||||||
|
lightChanged = false;
|
||||||
|
if( sendState )
|
||||||
{
|
{
|
||||||
// Broadcast the state to the current entity if they're not already interacting with it.
|
// Broadcast the state to all players
|
||||||
ServerPlayerEntity player = (ServerPlayerEntity) entity;
|
tracking.addAll( getWorld().players() );
|
||||||
if( player.connection != null && !isInteracting( player ) )
|
NetworkHandler.sendToPlayers( new PocketComputerDataMessage( this, false ), tracking );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Broadcast the state to new players.
|
||||||
|
List<ServerPlayerEntity> added = new ArrayList<>();
|
||||||
|
for( ServerPlayerEntity player : getWorld().players() )
|
||||||
{
|
{
|
||||||
NetworkHandler.sendToPlayer( player, createTerminalPacket() );
|
if( tracking.add( player ) ) added.add( player );
|
||||||
|
}
|
||||||
|
if( !added.isEmpty() )
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToPlayers( new PocketComputerDataMessage( this, false ), added );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onTerminalChanged()
|
||||||
|
{
|
||||||
|
super.onTerminalChanged();
|
||||||
|
|
||||||
|
if( entity instanceof ServerPlayerEntity && entity.isAlive() )
|
||||||
|
{
|
||||||
|
// Broadcast the terminal to the current player.
|
||||||
|
NetworkHandler.sendToPlayer( (ServerPlayerEntity) entity, new PocketComputerDataMessage( this, true ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRemoved()
|
||||||
|
{
|
||||||
|
super.onRemoved();
|
||||||
|
NetworkHandler.sendToAllPlayers( new PocketComputerDeletedClientMessage( getInstanceID() ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,8 @@ import dan200.computercraft.api.pocket.IPocketUpgrade;
|
|||||||
import dan200.computercraft.core.computer.ComputerSide;
|
import dan200.computercraft.core.computer.ComputerSide;
|
||||||
import dan200.computercraft.shared.PocketUpgrades;
|
import dan200.computercraft.shared.PocketUpgrades;
|
||||||
import dan200.computercraft.shared.common.IColouredItem;
|
import dan200.computercraft.shared.common.IColouredItem;
|
||||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerState;
|
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
|
||||||
import dan200.computercraft.shared.computer.items.IComputerItem;
|
import dan200.computercraft.shared.computer.items.IComputerItem;
|
||||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||||
import dan200.computercraft.shared.pocket.apis.PocketAPI;
|
import dan200.computercraft.shared.pocket.apis.PocketAPI;
|
||||||
@ -40,6 +39,7 @@ import net.minecraft.util.text.StringTextComponent;
|
|||||||
import net.minecraft.util.text.TextFormatting;
|
import net.minecraft.util.text.TextFormatting;
|
||||||
import net.minecraft.util.text.TranslationTextComponent;
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -88,7 +88,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
|
|||||||
{
|
{
|
||||||
IPocketUpgrade upgrade = getUpgrade( stack );
|
IPocketUpgrade upgrade = getUpgrade( stack );
|
||||||
|
|
||||||
computer.setWorld( world );
|
computer.setWorld( (ServerWorld) world );
|
||||||
computer.updateValues( entity, stack, upgrade );
|
computer.updateValues( entity, stack, upgrade );
|
||||||
|
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
@ -125,19 +125,13 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
|
|||||||
@Override
|
@Override
|
||||||
public void inventoryTick( @Nonnull ItemStack stack, World world, @Nonnull Entity entity, int slotNum, boolean selected )
|
public void inventoryTick( @Nonnull ItemStack stack, World world, @Nonnull Entity entity, int slotNum, boolean selected )
|
||||||
{
|
{
|
||||||
if( !world.isClientSide )
|
if( world.isClientSide ) return;
|
||||||
{
|
IInventory inventory = entity instanceof PlayerEntity ? ((PlayerEntity) entity).inventory : null;
|
||||||
IInventory inventory = entity instanceof PlayerEntity ? ((PlayerEntity) entity).inventory : null;
|
PocketServerComputer computer = createServerComputer( (ServerWorld) world, entity, inventory, stack );
|
||||||
PocketServerComputer computer = createServerComputer( world, entity, inventory, stack );
|
computer.keepAlive();
|
||||||
computer.keepAlive();
|
|
||||||
|
|
||||||
boolean changed = tick( stack, world, entity, computer );
|
boolean changed = tick( stack, world, entity, computer );
|
||||||
if( changed && inventory != null ) inventory.setChanged();
|
if( changed && inventory != null ) inventory.setChanged();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
createClientComputer( stack );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -157,7 +151,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
|
|||||||
ItemStack stack = player.getItemInHand( hand );
|
ItemStack stack = player.getItemInHand( hand );
|
||||||
if( !world.isClientSide )
|
if( !world.isClientSide )
|
||||||
{
|
{
|
||||||
PocketServerComputer computer = createServerComputer( world, player, player.inventory, stack );
|
PocketServerComputer computer = createServerComputer( (ServerWorld) world, player, player.inventory, stack );
|
||||||
computer.turnOn();
|
computer.turnOn();
|
||||||
|
|
||||||
boolean stop = false;
|
boolean stop = false;
|
||||||
@ -227,37 +221,29 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public PocketServerComputer createServerComputer( World world, Entity entity, @Nullable IInventory inventory, @Nonnull ItemStack stack )
|
public PocketServerComputer createServerComputer( ServerWorld world, Entity entity, @Nullable IInventory inventory, @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
if( world.isClientSide ) throw new IllegalStateException( "Cannot call createServerComputer on the client" );
|
if( world.isClientSide ) throw new IllegalStateException( "Cannot call createServerComputer on the client" );
|
||||||
|
|
||||||
PocketServerComputer computer;
|
|
||||||
int instanceID = getInstanceID( stack );
|
|
||||||
int sessionID = getSessionID( stack );
|
int sessionID = getSessionID( stack );
|
||||||
int correctSessionID = ComputerCraft.serverComputerRegistry.getSessionID();
|
|
||||||
|
|
||||||
if( instanceID >= 0 && sessionID == correctSessionID && ComputerCraft.serverComputerRegistry.contains( instanceID ) )
|
PocketServerComputer computer = (PocketServerComputer) ServerComputerRegistry.INSTANCE.get( sessionID, getInstanceID( stack ) );
|
||||||
|
if( computer == null )
|
||||||
{
|
{
|
||||||
computer = (PocketServerComputer) ComputerCraft.serverComputerRegistry.get( instanceID );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( instanceID < 0 || sessionID != correctSessionID )
|
|
||||||
{
|
|
||||||
instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
|
|
||||||
setInstanceID( stack, instanceID );
|
|
||||||
setSessionID( stack, correctSessionID );
|
|
||||||
}
|
|
||||||
int computerID = getComputerID( stack );
|
int computerID = getComputerID( stack );
|
||||||
if( computerID < 0 )
|
if( computerID < 0 )
|
||||||
{
|
{
|
||||||
computerID = ComputerCraftAPI.createUniqueNumberedSaveDir( world, "computer" );
|
computerID = ComputerCraftAPI.createUniqueNumberedSaveDir( world, "computer" );
|
||||||
setComputerID( stack, computerID );
|
setComputerID( stack, computerID );
|
||||||
}
|
}
|
||||||
computer = new PocketServerComputer( world, computerID, getLabel( stack ), instanceID, getFamily() );
|
|
||||||
|
computer = new PocketServerComputer( world, getComputerID( stack ), getLabel( stack ), getFamily() );
|
||||||
|
|
||||||
|
setInstanceID( stack, computer.register() );
|
||||||
|
setSessionID( stack, ServerComputerRegistry.INSTANCE.getSessionID() );
|
||||||
|
|
||||||
computer.updateValues( entity, stack, getUpgrade( stack ) );
|
computer.updateValues( entity, stack, getUpgrade( stack ) );
|
||||||
computer.addAPI( new PocketAPI( computer ) );
|
computer.addAPI( new PocketAPI( computer ) );
|
||||||
ComputerCraft.serverComputerRegistry.add( instanceID, computer );
|
|
||||||
|
|
||||||
// Only turn on when initially creating the computer, rather than each tick.
|
// Only turn on when initially creating the computer, rather than each tick.
|
||||||
if( isMarkedOn( stack ) && entity instanceof PlayerEntity ) computer.turnOn();
|
if( isMarkedOn( stack ) && entity instanceof PlayerEntity ) computer.turnOn();
|
||||||
@ -271,33 +257,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static PocketServerComputer getServerComputer( @Nonnull ItemStack stack )
|
public static PocketServerComputer getServerComputer( @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
int session = getSessionID( stack );
|
return (PocketServerComputer) ServerComputerRegistry.INSTANCE.get( getSessionID( stack ), getInstanceID( stack ) );
|
||||||
if( session != ComputerCraft.serverComputerRegistry.getSessionID() ) return null;
|
|
||||||
|
|
||||||
int instanceID = getInstanceID( stack );
|
|
||||||
return instanceID >= 0 ? (PocketServerComputer) ComputerCraft.serverComputerRegistry.get( instanceID ) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static ClientComputer createClientComputer( @Nonnull ItemStack stack )
|
|
||||||
{
|
|
||||||
int instanceID = getInstanceID( stack );
|
|
||||||
if( instanceID >= 0 )
|
|
||||||
{
|
|
||||||
if( !ComputerCraft.clientComputerRegistry.contains( instanceID ) )
|
|
||||||
{
|
|
||||||
ComputerCraft.clientComputerRegistry.add( instanceID, new ClientComputer( instanceID ) );
|
|
||||||
}
|
|
||||||
return ComputerCraft.clientComputerRegistry.get( instanceID );
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static ClientComputer getClientComputer( @Nonnull ItemStack stack )
|
|
||||||
{
|
|
||||||
int instanceID = getInstanceID( stack );
|
|
||||||
return instanceID >= 0 ? ComputerCraft.clientComputerRegistry.get( instanceID ) : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IComputerItem implementation
|
// IComputerItem implementation
|
||||||
@ -355,7 +315,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getInstanceID( @Nonnull ItemStack stack )
|
public static int getInstanceID( @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
CompoundNBT nbt = stack.getTag();
|
CompoundNBT nbt = stack.getTag();
|
||||||
return nbt != null && nbt.contains( NBT_INSTANCE ) ? nbt.getInt( NBT_INSTANCE ) : -1;
|
return nbt != null && nbt.contains( NBT_INSTANCE ) ? nbt.getInt( NBT_INSTANCE ) : -1;
|
||||||
@ -383,26 +343,6 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
|
|||||||
return nbt != null && nbt.getBoolean( NBT_ON );
|
return nbt != null && nbt.getBoolean( NBT_ON );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ComputerState getState( @Nonnull ItemStack stack )
|
|
||||||
{
|
|
||||||
ClientComputer computer = getClientComputer( stack );
|
|
||||||
return computer == null ? ComputerState.OFF : computer.getState();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getLightState( @Nonnull ItemStack stack )
|
|
||||||
{
|
|
||||||
ClientComputer computer = getClientComputer( stack );
|
|
||||||
if( computer != null && computer.isOn() )
|
|
||||||
{
|
|
||||||
CompoundNBT computerNBT = computer.getUserData();
|
|
||||||
if( computerNBT != null && computerNBT.contains( NBT_LIGHT ) )
|
|
||||||
{
|
|
||||||
return computerNBT.getInt( NBT_LIGHT );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IPocketUpgrade getUpgrade( @Nonnull ItemStack stack )
|
public static IPocketUpgrade getUpgrade( @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
CompoundNBT compound = stack.getTag();
|
CompoundNBT compound = stack.getTag();
|
||||||
|
@ -38,6 +38,7 @@ import net.minecraft.util.*;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.BlockRayTraceResult;
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.util.Constants;
|
import net.minecraftforge.common.util.Constants;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
@ -84,10 +85,10 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ServerComputer createComputer( int instanceID, int id )
|
protected ServerComputer createComputer( int id )
|
||||||
{
|
{
|
||||||
ServerComputer computer = new ServerComputer(
|
ServerComputer computer = new ServerComputer(
|
||||||
getLevel(), id, label, instanceID, getFamily(),
|
(ServerWorld) getLevel(), id, label, getFamily(),
|
||||||
ComputerCraft.turtleTermWidth, ComputerCraft.turtleTermHeight
|
ComputerCraft.turtleTermWidth, ComputerCraft.turtleTermHeight
|
||||||
);
|
);
|
||||||
computer.setPosition( getBlockPos() );
|
computer.setPosition( getBlockPos() );
|
||||||
@ -576,6 +577,6 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
|||||||
@Override
|
@Override
|
||||||
public Container createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player )
|
public Container createMenu( int id, @Nonnull PlayerInventory inventory, @Nonnull PlayerEntity player )
|
||||||
{
|
{
|
||||||
return new ContainerTurtle( id, inventory, brain );
|
return ContainerTurtle.ofBrain( id, inventory, brain );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ import net.minecraft.util.math.AxisAlignedBB;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
import net.minecraftforge.common.util.Constants;
|
import net.minecraftforge.common.util.Constants;
|
||||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||||
@ -339,7 +340,7 @@ public class TurtleBrain implements ITurtleAccess
|
|||||||
newTurtle.transferStateFrom( oldOwner );
|
newTurtle.transferStateFrom( oldOwner );
|
||||||
|
|
||||||
ServerComputer computer = newTurtle.createServerComputer();
|
ServerComputer computer = newTurtle.createServerComputer();
|
||||||
computer.setWorld( world );
|
computer.setWorld( (ServerWorld) world );
|
||||||
computer.setPosition( pos );
|
computer.setPosition( pos );
|
||||||
|
|
||||||
// Remove the old turtle
|
// Remove the old turtle
|
||||||
|
@ -8,7 +8,7 @@ package dan200.computercraft.shared.turtle.inventory;
|
|||||||
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
|
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
|
||||||
import dan200.computercraft.shared.Registry;
|
import dan200.computercraft.shared.Registry;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.IComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
||||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||||
@ -24,26 +24,26 @@ import net.minecraft.util.IIntArray;
|
|||||||
import net.minecraft.util.IntArray;
|
import net.minecraft.util.IntArray;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class ContainerTurtle extends ContainerComputerBase
|
public final class ContainerTurtle extends ContainerComputerBase
|
||||||
{
|
{
|
||||||
public static final int BORDER = 8;
|
public static final int BORDER = 8;
|
||||||
public static final int PLAYER_START_Y = 134;
|
public static final int PLAYER_START_Y = 134;
|
||||||
public static final int TURTLE_START_X = ComputerSidebar.WIDTH + 175;
|
public static final int TURTLE_START_X = ComputerSidebar.WIDTH + 175;
|
||||||
public static final int PLAYER_START_X = ComputerSidebar.WIDTH + BORDER;
|
public static final int PLAYER_START_X = ComputerSidebar.WIDTH + BORDER;
|
||||||
|
|
||||||
private final IIntArray properties;
|
private final IIntArray data;
|
||||||
|
|
||||||
private ContainerTurtle(
|
private ContainerTurtle(
|
||||||
int id, Predicate<PlayerEntity> canUse, IComputer computer, ComputerFamily family,
|
int id, Predicate<PlayerEntity> canUse, ComputerFamily family, @Nullable ServerComputer computer, @Nullable ComputerContainerData menuData,
|
||||||
PlayerInventory playerInventory, IInventory inventory, IIntArray properties
|
PlayerInventory playerInventory, IInventory inventory, IIntArray data
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
super( Registry.ModContainers.TURTLE.get(), id, canUse, computer, family );
|
super( Registry.ModContainers.TURTLE.get(), id, canUse, family, computer, menuData );
|
||||||
this.properties = properties;
|
this.data = data;
|
||||||
|
addDataSlots( data );
|
||||||
addDataSlots( properties );
|
|
||||||
|
|
||||||
// Turtle inventory
|
// Turtle inventory
|
||||||
for( int y = 0; y < 4; y++ )
|
for( int y = 0; y < 4; y++ )
|
||||||
@ -70,25 +70,25 @@ public class ContainerTurtle extends ContainerComputerBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContainerTurtle( int id, PlayerInventory player, TurtleBrain turtle )
|
public static ContainerTurtle ofBrain( int id, PlayerInventory player, TurtleBrain turtle )
|
||||||
{
|
{
|
||||||
this(
|
return new ContainerTurtle(
|
||||||
id, p -> turtle.getOwner().stillValid( p ), turtle.getOwner().createServerComputer(), turtle.getFamily(),
|
// Laziness in turtle.getOwner() is important here!
|
||||||
|
id, p -> turtle.getOwner().stillValid( p ), turtle.getFamily(), turtle.getOwner().createServerComputer(), null,
|
||||||
player, turtle.getInventory(), (SingleIntArray) turtle::getSelectedSlot
|
player, turtle.getInventory(), (SingleIntArray) turtle::getSelectedSlot
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContainerTurtle( int id, PlayerInventory player, ComputerContainerData data )
|
public static ContainerTurtle ofMenuData( int id, PlayerInventory player, ComputerContainerData data )
|
||||||
{
|
{
|
||||||
this(
|
return new ContainerTurtle(
|
||||||
id, x -> true, getComputer( player, data ), data.getFamily(),
|
id, x -> true, data.family(), null, data, player, new Inventory( TileTurtle.INVENTORY_SIZE ), new IntArray( 1 )
|
||||||
player, new Inventory( TileTurtle.INVENTORY_SIZE ), new IntArray( 1 )
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSelectedSlot()
|
public int getSelectedSlot()
|
||||||
{
|
{
|
||||||
return properties.get( 0 );
|
return data.get( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
Loading…
Reference in New Issue
Block a user