mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-11-19 00:04:53 +00:00
Merge branch 'mc-1.16.x' into mc-1.17.x
This commit is contained in:
commit
0d6528aaf0
1
.github/workflows/main-ci.yml
vendored
1
.github/workflows/main-ci.yml
vendored
@ -27,6 +27,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir -p ~/.gradle
|
mkdir -p ~/.gradle
|
||||||
echo "org.gradle.daemon=false" >> ~/.gradle/gradle.properties
|
echo "org.gradle.daemon=false" >> ~/.gradle/gradle.properties
|
||||||
|
echo "cc.tweaked.clientTests=true" >> ~/.gradle/gradle.properties
|
||||||
|
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
run: |
|
run: |
|
||||||
|
@ -26,7 +26,12 @@ on is present.
|
|||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://squiddev.cc/maven/' }
|
maven {
|
||||||
|
url 'https://squiddev.cc/maven/'
|
||||||
|
content {
|
||||||
|
includeGroup 'org.squiddev'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -436,8 +436,12 @@ task setupServer(type: Copy) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name != "Client" || project.findProperty('cc.tweaked.clientTests') == 'true') {
|
||||||
|
// Don't run client tests unless explicitly opted into them. They're a bit of a faff
|
||||||
|
// to run and pretty flakey.
|
||||||
check.dependsOn("jacocoTest${name}Report")
|
check.dependsOn("jacocoTest${name}Report")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Upload tasks
|
// Upload tasks
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
-- @treturn boolean If the path is mounted, rather than a normal file/folder.
|
-- @treturn boolean If the path is mounted, rather than a normal file/folder.
|
||||||
-- @throws If the path does not exist.
|
-- @throws If the path does not exist.
|
||||||
-- @see getDrive
|
-- @see getDrive
|
||||||
|
-- @since 1.87.0
|
||||||
function isDriveRoot(path) end
|
function isDriveRoot(path) end
|
||||||
|
|
||||||
--[[- Provides completion for a file or directory name, suitable for use with
|
--[[- Provides completion for a file or directory name, suitable for use with
|
||||||
@ -30,5 +31,6 @@ included in the returned list.
|
|||||||
@tparam[opt] boolean include_dirs When @{false}, "raw" directories will not be
|
@tparam[opt] boolean include_dirs When @{false}, "raw" directories will not be
|
||||||
included in the returned list.
|
included in the returned list.
|
||||||
@treturn { string... } A list of possible completion candidates.
|
@treturn { string... } A list of possible completion candidates.
|
||||||
|
@since 1.74
|
||||||
]]
|
]]
|
||||||
function complete(path, location, include_files, include_dirs) end
|
function complete(path, location, include_files, include_dirs) end
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
-- receiving data from them.
|
-- receiving data from them.
|
||||||
--
|
--
|
||||||
-- @module http
|
-- @module http
|
||||||
|
-- @since 1.1
|
||||||
|
|
||||||
--- Asynchronously make a HTTP request to the given url.
|
--- Asynchronously make a HTTP request to the given url.
|
||||||
--
|
--
|
||||||
@ -35,6 +36,11 @@
|
|||||||
--
|
--
|
||||||
-- @see http.get For a synchronous way to make GET requests.
|
-- @see http.get For a synchronous way to make GET requests.
|
||||||
-- @see http.post For a synchronous way to make POST requests.
|
-- @see http.post For a synchronous way to make POST requests.
|
||||||
|
--
|
||||||
|
-- @changed 1.63 Added argument for headers.
|
||||||
|
-- @changed 1.80pr1 Added argument for binary handles.
|
||||||
|
-- @changed 1.80pr1.6 Added support for table argument.
|
||||||
|
-- @changed 1.86.0 Added PATCH and TRACE methods.
|
||||||
function request(...) end
|
function request(...) end
|
||||||
|
|
||||||
--- Make a HTTP GET request to the given url.
|
--- Make a HTTP GET request to the given url.
|
||||||
@ -58,6 +64,12 @@ function request(...) end
|
|||||||
-- @treturn string A message detailing why the request failed.
|
-- @treturn string A message detailing why the request failed.
|
||||||
-- @treturn Response|nil The failing http response, if available.
|
-- @treturn Response|nil The failing http response, if available.
|
||||||
--
|
--
|
||||||
|
-- @changed 1.63 Added argument for headers.
|
||||||
|
-- @changed 1.80pr1 Response handles are now returned on error if available.
|
||||||
|
-- @changed 1.80pr1 Added argument for binary handles.
|
||||||
|
-- @changed 1.80pr1.6 Added support for table argument.
|
||||||
|
-- @changed 1.86.0 Added PATCH and TRACE methods.
|
||||||
|
--
|
||||||
-- @usage Make a request to [example.tweaked.cc](https://example.tweaked.cc),
|
-- @usage Make a request to [example.tweaked.cc](https://example.tweaked.cc),
|
||||||
-- and print the returned page.
|
-- and print the returned page.
|
||||||
-- ```lua
|
-- ```lua
|
||||||
@ -89,6 +101,13 @@ function get(...) end
|
|||||||
-- error or connection timeout.
|
-- error or connection timeout.
|
||||||
-- @treturn string A message detailing why the request failed.
|
-- @treturn string A message detailing why the request failed.
|
||||||
-- @treturn Response|nil The failing http response, if available.
|
-- @treturn Response|nil The failing http response, if available.
|
||||||
|
--
|
||||||
|
-- @since 1.31
|
||||||
|
-- @changed 1.63 Added argument for headers.
|
||||||
|
-- @changed 1.80pr1 Response handles are now returned on error if available.
|
||||||
|
-- @changed 1.80pr1 Added argument for binary handles.
|
||||||
|
-- @changed 1.80pr1.6 Added support for table argument.
|
||||||
|
-- @changed 1.86.0 Added PATCH and TRACE methods.
|
||||||
function post(...) end
|
function post(...) end
|
||||||
|
|
||||||
--- Asynchronously determine whether a URL can be requested.
|
--- Asynchronously determine whether a URL can be requested.
|
||||||
@ -142,6 +161,9 @@ function checkURL(url) end
|
|||||||
-- @treturn Websocket The websocket connection.
|
-- @treturn Websocket The websocket connection.
|
||||||
-- @treturn[2] false If the websocket connection failed.
|
-- @treturn[2] false If the websocket connection failed.
|
||||||
-- @treturn string An error message describing why the connection failed.
|
-- @treturn string An error message describing why the connection failed.
|
||||||
|
-- @since 1.80pr1.1
|
||||||
|
-- @changed 1.80pr1.3 No longer asynchronous.
|
||||||
|
-- @changed 1.95.3 Added User-Agent to default headers.
|
||||||
function websocket(url, headers) end
|
function websocket(url, headers) end
|
||||||
|
|
||||||
--- Asynchronously open a websocket.
|
--- Asynchronously open a websocket.
|
||||||
@ -154,4 +176,6 @@ function websocket(url, headers) end
|
|||||||
-- `ws://` or `wss://` protocol.
|
-- `ws://` or `wss://` protocol.
|
||||||
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
-- @tparam[opt] { [string] = string } headers Additional headers to send as part
|
||||||
-- of the initial websocket connection.
|
-- of the initial websocket connection.
|
||||||
|
-- @since 1.80pr1.3
|
||||||
|
-- @changed 1.95.3 Added User-Agent to default headers.
|
||||||
function websocketAsync(url, headers) end
|
function websocketAsync(url, headers) end
|
||||||
|
@ -8,6 +8,7 @@ variables and functions exported by it will by available through the use of
|
|||||||
|
|
||||||
@tparam string path The path of the API to load.
|
@tparam string path The path of the API to load.
|
||||||
@treturn boolean Whether or not the API was successfully loaded.
|
@treturn boolean Whether or not the API was successfully loaded.
|
||||||
|
@since 1.2
|
||||||
|
|
||||||
@deprecated When possible it's best to avoid using this function. It pollutes
|
@deprecated When possible it's best to avoid using this function. It pollutes
|
||||||
the global table and can mask errors.
|
the global table and can mask errors.
|
||||||
@ -21,6 +22,7 @@ function loadAPI(path) end
|
|||||||
-- This effectively removes the specified table from `_G`.
|
-- This effectively removes the specified table from `_G`.
|
||||||
--
|
--
|
||||||
-- @tparam string name The name of the API to unload.
|
-- @tparam string name The name of the API to unload.
|
||||||
|
-- @since 1.2
|
||||||
-- @deprecated See @{os.loadAPI} for why.
|
-- @deprecated See @{os.loadAPI} for why.
|
||||||
function unloadAPI(name) end
|
function unloadAPI(name) end
|
||||||
|
|
||||||
@ -58,6 +60,7 @@ event, printing the error "Terminated".
|
|||||||
end
|
end
|
||||||
|
|
||||||
@see os.pullEventRaw To pull the terminate event.
|
@see os.pullEventRaw To pull the terminate event.
|
||||||
|
@changed 1.3 Added filter argument.
|
||||||
]]
|
]]
|
||||||
function pullEvent(filter) end
|
function pullEvent(filter) end
|
||||||
|
|
||||||
|
@ -9,5 +9,6 @@ empty, including those outside the crafting "grid".
|
|||||||
@treturn[1] true If crafting succeeds.
|
@treturn[1] true If crafting succeeds.
|
||||||
@treturn[2] false If crafting fails.
|
@treturn[2] false If crafting fails.
|
||||||
@treturn string A string describing why crafting failed.
|
@treturn string A string describing why crafting failed.
|
||||||
|
@since 1.4
|
||||||
]]
|
]]
|
||||||
function craft(limit) end
|
function craft(limit) end
|
||||||
|
@ -13,11 +13,10 @@ import dan200.computercraft.client.render.TurtleModelLoader;
|
|||||||
import dan200.computercraft.client.render.TurtlePlayerRenderer;
|
import dan200.computercraft.client.render.TurtlePlayerRenderer;
|
||||||
import dan200.computercraft.shared.Registry;
|
import dan200.computercraft.shared.Registry;
|
||||||
import dan200.computercraft.shared.common.IColouredItem;
|
import dan200.computercraft.shared.common.IColouredItem;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
import dan200.computercraft.shared.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.inventory.ContainerPocketComputer;
|
|
||||||
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;
|
||||||
import net.minecraft.client.gui.screens.MenuScreens;
|
import net.minecraft.client.gui.screens.MenuScreens;
|
||||||
@ -173,8 +172,9 @@ 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.
|
||||||
|
|
||||||
MenuScreens.<ContainerComputer, GuiComputer<ContainerComputer>>register( Registry.ModContainers.COMPUTER.get(), GuiComputer::create );
|
MenuScreens.<ContainerComputerBase, GuiComputer<ContainerComputerBase>>register( Registry.ModContainers.COMPUTER.get(), GuiComputer::create );
|
||||||
MenuScreens.<ContainerPocketComputer, GuiComputer<ContainerPocketComputer>>register( Registry.ModContainers.POCKET_COMPUTER.get(), GuiComputer::createPocket );
|
MenuScreens.<ContainerComputerBase, GuiComputer<ContainerComputerBase>>register( Registry.ModContainers.POCKET_COMPUTER.get(), GuiComputer::createPocket );
|
||||||
|
MenuScreens.<ContainerComputerBase, NoTermComputerScreen<ContainerComputerBase>>register( Registry.ModContainers.POCKET_COMPUTER_NO_TERM.get(), NoTermComputerScreen::new );
|
||||||
MenuScreens.register( Registry.ModContainers.TURTLE.get(), GuiTurtle::new );
|
MenuScreens.register( Registry.ModContainers.TURTLE.get(), GuiTurtle::new );
|
||||||
|
|
||||||
MenuScreens.register( Registry.ModContainers.PRINTER.get(), GuiPrinter::new );
|
MenuScreens.register( Registry.ModContainers.PRINTER.get(), GuiPrinter::new );
|
||||||
|
@ -144,22 +144,43 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String name = file.getFileName().toString();
|
||||||
|
if( name.length() > UploadFileMessage.MAX_FILE_NAME )
|
||||||
|
{
|
||||||
|
alert( UploadResult.FAILED_TITLE, new TranslatableComponent( "gui.computercraft.upload.failed.name_too_long" ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect( (int) fileSize );
|
ByteBuffer buffer = ByteBuffer.allocateDirect( (int) fileSize );
|
||||||
sbc.read( buffer );
|
sbc.read( buffer );
|
||||||
buffer.flip();
|
buffer.flip();
|
||||||
|
|
||||||
toUpload.add( new FileUpload( file.getFileName().toString(), buffer ) );
|
byte[] digest = FileUpload.getDigest( buffer );
|
||||||
|
if( digest == null )
|
||||||
|
{
|
||||||
|
alert( UploadResult.FAILED_TITLE, new TranslatableComponent( "gui.computercraft.upload.failed.corrupted" ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.rewind();
|
||||||
|
toUpload.add( new FileUpload( name, buffer, digest ) );
|
||||||
}
|
}
|
||||||
catch( IOException e )
|
catch( IOException e )
|
||||||
{
|
{
|
||||||
ComputerCraft.log.error( "Failed uploading files", e );
|
ComputerCraft.log.error( "Failed uploading files", e );
|
||||||
alert( UploadResult.FAILED_TITLE, new TranslatableComponent( "computercraft.gui.upload.failed.generic", e.getMessage() ) );
|
alert( UploadResult.FAILED_TITLE, new TranslatableComponent( "gui.computercraft.upload.failed.generic", "Cannot compute checksum" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( toUpload.size() > UploadFileMessage.MAX_FILES )
|
||||||
|
{
|
||||||
|
alert( UploadResult.FAILED_TITLE, new TranslatableComponent( "gui.computercraft.upload.failed.too_many_files" ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( toUpload.size() > 0 )
|
if( toUpload.size() > 0 )
|
||||||
{
|
{
|
||||||
NetworkHandler.sendToServer( new UploadFileMessage( computer.getInstanceID(), toUpload ) );
|
UploadFileMessage.send( computer.getInstanceID(), toUpload );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,10 +11,8 @@ 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.inventory.ContainerComputer;
|
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
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.pocket.inventory.ContainerPocketComputer;
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
|
||||||
@ -40,7 +38,7 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Computer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static GuiComputer<ContainerComputer> create( ContainerComputer container, Inventory inventory, Component component )
|
public static GuiComputer<ContainerComputerBase> create( ContainerComputerBase container, Inventory inventory, Component component )
|
||||||
{
|
{
|
||||||
return new GuiComputer<>(
|
return new GuiComputer<>(
|
||||||
container, inventory, component,
|
container, inventory, component,
|
||||||
@ -49,7 +47,7 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Computer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static GuiComputer<ContainerPocketComputer> createPocket( ContainerPocketComputer container, Inventory inventory, Component component )
|
public static GuiComputer<ContainerComputerBase> createPocket( ContainerComputerBase container, Inventory inventory, Component component )
|
||||||
{
|
{
|
||||||
return new GuiComputer<>(
|
return new GuiComputer<>(
|
||||||
container, inventory, component,
|
container, inventory, component,
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.client.gui;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||||
|
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||||
|
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
||||||
|
import net.minecraft.client.gui.Font;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import net.minecraft.client.gui.screens.inventory.MenuAccess;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
|
import net.minecraft.util.FormattedCharSequence;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NoTermComputerScreen<T extends ContainerComputerBase> extends Screen implements MenuAccess<T>
|
||||||
|
{
|
||||||
|
private final T menu;
|
||||||
|
private WidgetTerminal terminal;
|
||||||
|
|
||||||
|
public NoTermComputerScreen( T menu, Inventory player, Component title )
|
||||||
|
{
|
||||||
|
super( title );
|
||||||
|
this.menu = menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public T getMenu()
|
||||||
|
{
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init()
|
||||||
|
{
|
||||||
|
super.init();
|
||||||
|
minecraft.keyboardHandler.setSendRepeatsToGui( true );
|
||||||
|
|
||||||
|
terminal = addWidget( new WidgetTerminal( (ClientComputer) menu.getComputer(), 0, 0, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight ) );
|
||||||
|
terminal.visible = false;
|
||||||
|
terminal.active = false;
|
||||||
|
setFocused( terminal );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void removed()
|
||||||
|
{
|
||||||
|
super.removed();
|
||||||
|
minecraft.keyboardHandler.setSendRepeatsToGui( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void tick()
|
||||||
|
{
|
||||||
|
super.tick();
|
||||||
|
terminal.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose()
|
||||||
|
{
|
||||||
|
minecraft.player.closeContainer();
|
||||||
|
super.onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPauseScreen()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean keyPressed( int key, int scancode, int modifiers )
|
||||||
|
{
|
||||||
|
// Forward the tab key to the terminal, rather than moving between controls.
|
||||||
|
if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminal )
|
||||||
|
{
|
||||||
|
return getFocused().keyPressed( key, scancode, modifiers );
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.keyPressed( key, scancode, modifiers );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render( PoseStack transform, int mouseX, int mouseY, float partialTicks )
|
||||||
|
{
|
||||||
|
super.render( transform, mouseX, mouseY, partialTicks );
|
||||||
|
|
||||||
|
Font font = minecraft.font;
|
||||||
|
List<FormattedCharSequence> lines = font.split( new TranslatableComponent( "gui.computercraft.pocket_computer_overlay" ), (int) (width * 0.8) );
|
||||||
|
float y = 10.0f;
|
||||||
|
for( FormattedCharSequence line : lines )
|
||||||
|
{
|
||||||
|
font.drawShadow( transform, line, (float) ((width / 2) - (minecraft.font.width( line ) / 2)), y, 0xFFFFFF );
|
||||||
|
y += 9.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -312,6 +312,7 @@ public class WidgetTerminal extends AbstractWidget
|
|||||||
@Override
|
@Override
|
||||||
public void render( @Nonnull PoseStack transform, int mouseX, int mouseY, float partialTicks )
|
public void render( @Nonnull PoseStack transform, int mouseX, int mouseY, float partialTicks )
|
||||||
{
|
{
|
||||||
|
if( !visible ) return;
|
||||||
Matrix4f matrix = transform.last().pose();
|
Matrix4f matrix = transform.last().pose();
|
||||||
Terminal terminal = computer.getTerminal();
|
Terminal terminal = computer.getTerminal();
|
||||||
if( terminal != null )
|
if( terminal != null )
|
||||||
|
@ -99,6 +99,7 @@ public class FSAPI implements ILuaAPI
|
|||||||
* @throws LuaException On argument errors.
|
* @throws LuaException On argument errors.
|
||||||
* @cc.tparam string path The first part of the path. For example, a parent directory path.
|
* @cc.tparam string path The first part of the path. For example, a parent directory path.
|
||||||
* @cc.tparam string ... Additional parts of the path to combine.
|
* @cc.tparam string ... Additional parts of the path to combine.
|
||||||
|
* @cc.changed 1.95.0 Now supports multiple arguments.
|
||||||
* @cc.usage Combine several file paths together
|
* @cc.usage Combine several file paths together
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* fs.combine("/rom/programs", "../apis", "parallel.lua")
|
* fs.combine("/rom/programs", "../apis", "parallel.lua")
|
||||||
@ -126,6 +127,7 @@ public class FSAPI implements ILuaAPI
|
|||||||
*
|
*
|
||||||
* @param path The path to get the name from.
|
* @param path The path to get the name from.
|
||||||
* @return The final part of the path (the file name).
|
* @return The final part of the path (the file name).
|
||||||
|
* @cc.since 1.2
|
||||||
* @cc.usage Get the file name of {@code rom/startup.lua}
|
* @cc.usage Get the file name of {@code rom/startup.lua}
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* fs.getName("rom/startup.lua")
|
* fs.getName("rom/startup.lua")
|
||||||
@ -143,6 +145,7 @@ public class FSAPI implements ILuaAPI
|
|||||||
*
|
*
|
||||||
* @param path The path to get the directory from.
|
* @param path The path to get the directory from.
|
||||||
* @return The path with the final part removed (the parent directory).
|
* @return The path with the final part removed (the parent directory).
|
||||||
|
* @cc.since 1.63
|
||||||
* @cc.usage Get the directory name of {@code rom/startup.lua}
|
* @cc.usage Get the directory name of {@code rom/startup.lua}
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* fs.getDir("rom/startup.lua")
|
* fs.getDir("rom/startup.lua")
|
||||||
@ -161,6 +164,7 @@ public class FSAPI implements ILuaAPI
|
|||||||
* @param path The file to get the file size of.
|
* @param path The file to get the file size of.
|
||||||
* @return The size of the file, in bytes.
|
* @return The size of the file, in bytes.
|
||||||
* @throws LuaException If the path doesn't exist.
|
* @throws LuaException If the path doesn't exist.
|
||||||
|
* @cc.since 1.3
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final long getSize( String path ) throws LuaException
|
public final long getSize( String path ) throws LuaException
|
||||||
@ -458,6 +462,7 @@ public class FSAPI implements ILuaAPI
|
|||||||
* @return The amount of free space available, in bytes.
|
* @return The amount of free space available, in bytes.
|
||||||
* @throws LuaException If the path doesn't exist.
|
* @throws LuaException If the path doesn't exist.
|
||||||
* @cc.treturn number|"unlimited" The amount of free space available, in bytes, or "unlimited".
|
* @cc.treturn number|"unlimited" The amount of free space available, in bytes, or "unlimited".
|
||||||
|
* @cc.since 1.4
|
||||||
* @see #getCapacity To get the capacity of this drive.
|
* @see #getCapacity To get the capacity of this drive.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -485,6 +490,7 @@ public class FSAPI implements ILuaAPI
|
|||||||
* @param path The wildcard-qualified path to search for.
|
* @param path The wildcard-qualified path to search for.
|
||||||
* @return A list of paths that match the search string.
|
* @return A list of paths that match the search string.
|
||||||
* @throws LuaException If the path doesn't exist.
|
* @throws LuaException If the path doesn't exist.
|
||||||
|
* @cc.since 1.6
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final String[] find( String path ) throws LuaException
|
public final String[] find( String path ) throws LuaException
|
||||||
@ -508,6 +514,7 @@ public class FSAPI implements ILuaAPI
|
|||||||
* @throws LuaException If the capacity cannot be determined.
|
* @throws LuaException If the capacity cannot be determined.
|
||||||
* @cc.treturn number|nil This drive's capacity. This will be nil for "read-only" drives, such as the ROM or
|
* @cc.treturn number|nil This drive's capacity. This will be nil for "read-only" drives, such as the ROM or
|
||||||
* treasure disks.
|
* treasure disks.
|
||||||
|
* @cc.since 1.87.0
|
||||||
* @see #getFreeSpace To get the free space available on this drive.
|
* @see #getFreeSpace To get the free space available on this drive.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -537,6 +544,9 @@ public class FSAPI implements ILuaAPI
|
|||||||
* @return The resulting attributes.
|
* @return The resulting attributes.
|
||||||
* @throws LuaException If the path does not exist.
|
* @throws LuaException If the path does not exist.
|
||||||
* @cc.treturn { size = number, isDir = boolean, isReadOnly = boolean, created = number, modified = number } The resulting attributes.
|
* @cc.treturn { size = number, isDir = boolean, isReadOnly = boolean, created = number, modified = number } The resulting attributes.
|
||||||
|
* @cc.since 1.87.0
|
||||||
|
* @cc.changed 1.91.0 Renamed `modification` field to `modified`.
|
||||||
|
* @cc.changed 1.95.2 Added `isReadOnly` to attributes.
|
||||||
* @see #getSize If you only care about the file's size.
|
* @see #getSize If you only care about the file's size.
|
||||||
* @see #isDir If you only care whether a path is a directory or not.
|
* @see #isDir If you only care whether a path is a directory or not.
|
||||||
*/
|
*/
|
||||||
|
@ -204,14 +204,15 @@ public class OSAPI implements ILuaAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an alarm that will fire at the specified world time. When it fires,
|
* Sets an alarm that will fire at the specified in-game time. When it
|
||||||
* an {@code alarm} event will be added to the event queue with the ID
|
* fires, * an {@code alarm} event will be added to the event queue with the
|
||||||
* returned from this function as the first parameter.
|
* ID * returned from this function as the first parameter.
|
||||||
*
|
*
|
||||||
* @param time The time at which to fire the alarm, in the range [0.0, 24.0).
|
* @param time The time at which to fire the alarm, in the range [0.0, 24.0).
|
||||||
* @return The ID of the new alarm. This can be used to filter the
|
* @return The ID of the new alarm. This can be used to filter the
|
||||||
* {@code alarm} event, or {@link #cancelAlarm cancel the alarm}.
|
* {@code alarm} event, or {@link #cancelAlarm cancel the alarm}.
|
||||||
* @throws LuaException If the time is out of range.
|
* @throws LuaException If the time is out of range.
|
||||||
|
* @cc.since 1.2
|
||||||
* @see #cancelAlarm To cancel an alarm.
|
* @see #cancelAlarm To cancel an alarm.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -232,6 +233,7 @@ public class OSAPI implements ILuaAPI
|
|||||||
* alarm from firing.
|
* alarm from firing.
|
||||||
*
|
*
|
||||||
* @param token The ID of the alarm to cancel.
|
* @param token The ID of the alarm to cancel.
|
||||||
|
* @cc.since 1.2
|
||||||
* @see #setAlarm To set an alarm.
|
* @see #setAlarm To set an alarm.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -277,6 +279,7 @@ public class OSAPI implements ILuaAPI
|
|||||||
*
|
*
|
||||||
* @return The label of the computer.
|
* @return The label of the computer.
|
||||||
* @cc.treturn string The label of the computer.
|
* @cc.treturn string The label of the computer.
|
||||||
|
* @cc.since 1.3
|
||||||
*/
|
*/
|
||||||
@LuaFunction( { "getComputerLabel", "computerLabel" } )
|
@LuaFunction( { "getComputerLabel", "computerLabel" } )
|
||||||
public final Object[] getComputerLabel()
|
public final Object[] getComputerLabel()
|
||||||
@ -289,6 +292,7 @@ public class OSAPI implements ILuaAPI
|
|||||||
* Set the label of this computer.
|
* Set the label of this computer.
|
||||||
*
|
*
|
||||||
* @param label The new label. May be {@code nil} in order to clear it.
|
* @param label The new label. May be {@code nil} in order to clear it.
|
||||||
|
* @cc.since 1.3
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final void setComputerLabel( Optional<String> label )
|
public final void setComputerLabel( Optional<String> label )
|
||||||
@ -300,6 +304,7 @@ public class OSAPI implements ILuaAPI
|
|||||||
* Returns the number of seconds that the computer has been running.
|
* Returns the number of seconds that the computer has been running.
|
||||||
*
|
*
|
||||||
* @return The computer's uptime.
|
* @return The computer's uptime.
|
||||||
|
* @cc.since 1.2
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final double clock()
|
public final double clock()
|
||||||
@ -325,6 +330,15 @@ public class OSAPI implements ILuaAPI
|
|||||||
* @return The hour of the selected locale, or a UNIX timestamp from the table, depending on the argument passed in.
|
* @return The hour of the selected locale, or a UNIX timestamp from the table, depending on the argument passed in.
|
||||||
* @throws LuaException If an invalid locale is passed.
|
* @throws LuaException If an invalid locale is passed.
|
||||||
* @cc.tparam [opt] string|table locale The locale of the time, or a table filled by {@code os.date("*t")} to decode. Defaults to {@code dan200.computercraft.ingame} locale if not specified.
|
* @cc.tparam [opt] string|table locale The locale of the time, or a table filled by {@code os.date("*t")} to decode. Defaults to {@code dan200.computercraft.ingame} locale if not specified.
|
||||||
|
* @cc.see textutils.formatTime To convert times into a user-readable string.
|
||||||
|
* @cc.usage Print the current in-game time.
|
||||||
|
* <pre>{@code
|
||||||
|
* textutils.formatTime(os.time())
|
||||||
|
* }</pre>
|
||||||
|
* @cc.since 1.2
|
||||||
|
* @cc.changed 1.80pr1 Add support for getting the local local and UTC time.
|
||||||
|
* @cc.changed 1.82.0 Arguments are now case insensitive.
|
||||||
|
* @cc.changed 1.83.0 {@link #time(IArguments)} now accepts table arguments and converts them to UNIX timestamps.
|
||||||
* @see #date To get a date table that can be converted with this function.
|
* @see #date To get a date table that can be converted with this function.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -360,6 +374,8 @@ public class OSAPI implements ILuaAPI
|
|||||||
* @param args The locale to get the day for. Defaults to {@code dan200.computercraft.ingame} if not set.
|
* @param args The locale to get the day for. Defaults to {@code dan200.computercraft.ingame} if not set.
|
||||||
* @return The day depending on the selected locale.
|
* @return The day depending on the selected locale.
|
||||||
* @throws LuaException If an invalid locale is passed.
|
* @throws LuaException If an invalid locale is passed.
|
||||||
|
* @cc.since 1.48
|
||||||
|
* @cc.changed 1.82.0 Arguments are now case insensitive.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final int day( Optional<String> args ) throws LuaException
|
public final int day( Optional<String> args ) throws LuaException
|
||||||
@ -390,6 +406,14 @@ public class OSAPI implements ILuaAPI
|
|||||||
* @param args The locale to get the milliseconds for. Defaults to {@code dan200.computercraft.ingame} if not set.
|
* @param args The locale to get the milliseconds for. Defaults to {@code dan200.computercraft.ingame} if not set.
|
||||||
* @return The milliseconds since the epoch depending on the selected locale.
|
* @return The milliseconds since the epoch depending on the selected locale.
|
||||||
* @throws LuaException If an invalid locale is passed.
|
* @throws LuaException If an invalid locale is passed.
|
||||||
|
* @cc.since 1.80pr1
|
||||||
|
* @cc.usage Get the current time and use {@link #date} to convert it to a table.
|
||||||
|
* <pre>{@code
|
||||||
|
* -- Dividing by 1000 converts it from milliseconds to seconds.
|
||||||
|
* local time = os.epoch("local") / 1000
|
||||||
|
* local time_table = os.date("*t", time)
|
||||||
|
* print(textutils.serialize(time_table))
|
||||||
|
* }</pre>
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final long epoch( Optional<String> args ) throws LuaException
|
public final long epoch( Optional<String> args ) throws LuaException
|
||||||
@ -438,6 +462,11 @@ public class OSAPI implements ILuaAPI
|
|||||||
* @param timeA The time to convert to a string. This defaults to the current time.
|
* @param timeA The time to convert to a string. This defaults to the current time.
|
||||||
* @return The resulting format string.
|
* @return The resulting format string.
|
||||||
* @throws LuaException If an invalid format is passed.
|
* @throws LuaException If an invalid format is passed.
|
||||||
|
* @cc.since 1.83.0
|
||||||
|
* @cc.usage Print the current date in a user-friendly string.
|
||||||
|
* <pre>{@code
|
||||||
|
* os.date("%A %d %B %Y") -- See the reference above!
|
||||||
|
* }</pre>
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object date( Optional<String> formatA, Optional<Long> timeA ) throws LuaException
|
public final Object date( Optional<String> formatA, Optional<Long> timeA ) throws LuaException
|
||||||
|
@ -46,6 +46,7 @@ public class TermAPI extends TermMethods implements ILuaAPI
|
|||||||
* @cc.treturn number The red channel, will be between 0 and 1.
|
* @cc.treturn number The red channel, will be between 0 and 1.
|
||||||
* @cc.treturn number The green channel, will be between 0 and 1.
|
* @cc.treturn number The green channel, will be between 0 and 1.
|
||||||
* @cc.treturn number The blue channel, will be between 0 and 1.
|
* @cc.treturn number The blue channel, will be between 0 and 1.
|
||||||
|
* @cc.since 1.81.0
|
||||||
* @see TermMethods#setPaletteColour(IArguments) To change the palette colour.
|
* @see TermMethods#setPaletteColour(IArguments) To change the palette colour.
|
||||||
*/
|
*/
|
||||||
@LuaFunction( { "nativePaletteColour", "nativePaletteColor" } )
|
@LuaFunction( { "nativePaletteColour", "nativePaletteColor" } )
|
||||||
|
@ -112,6 +112,7 @@ public abstract class TermMethods
|
|||||||
*
|
*
|
||||||
* @return If the cursor is blinking.
|
* @return If the cursor is blinking.
|
||||||
* @throws LuaException (hidden) If the terminal cannot be found.
|
* @throws LuaException (hidden) If the terminal cannot be found.
|
||||||
|
* @cc.since 1.80pr1.9
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final boolean getCursorBlink() throws LuaException
|
public final boolean getCursorBlink() throws LuaException
|
||||||
@ -179,6 +180,7 @@ public abstract class TermMethods
|
|||||||
* @return The current text colour.
|
* @return The current text colour.
|
||||||
* @throws LuaException (hidden) If the terminal cannot be found.
|
* @throws LuaException (hidden) If the terminal cannot be found.
|
||||||
* @cc.see colors For a list of colour constants, returned by this function.
|
* @cc.see colors For a list of colour constants, returned by this function.
|
||||||
|
* @cc.since 1.74
|
||||||
*/
|
*/
|
||||||
@LuaFunction( { "getTextColour", "getTextColor" } )
|
@LuaFunction( { "getTextColour", "getTextColor" } )
|
||||||
public final int getTextColour() throws LuaException
|
public final int getTextColour() throws LuaException
|
||||||
@ -192,6 +194,8 @@ public abstract class TermMethods
|
|||||||
* @param colourArg The new text colour.
|
* @param colourArg The new text colour.
|
||||||
* @throws LuaException (hidden) If the terminal cannot be found.
|
* @throws LuaException (hidden) If the terminal cannot be found.
|
||||||
* @cc.see colors For a list of colour constants.
|
* @cc.see colors For a list of colour constants.
|
||||||
|
* @cc.since 1.45
|
||||||
|
* @cc.changed 1.80pr1 Standard computers can now use all 16 colors, being changed to grayscale on screen.
|
||||||
*/
|
*/
|
||||||
@LuaFunction( { "setTextColour", "setTextColor" } )
|
@LuaFunction( { "setTextColour", "setTextColor" } )
|
||||||
public final void setTextColour( int colourArg ) throws LuaException
|
public final void setTextColour( int colourArg ) throws LuaException
|
||||||
@ -211,6 +215,7 @@ public abstract class TermMethods
|
|||||||
* @return The current background colour.
|
* @return The current background colour.
|
||||||
* @throws LuaException (hidden) If the terminal cannot be found.
|
* @throws LuaException (hidden) If the terminal cannot be found.
|
||||||
* @cc.see colors For a list of colour constants, returned by this function.
|
* @cc.see colors For a list of colour constants, returned by this function.
|
||||||
|
* @cc.since 1.74
|
||||||
*/
|
*/
|
||||||
@LuaFunction( { "getBackgroundColour", "getBackgroundColor" } )
|
@LuaFunction( { "getBackgroundColour", "getBackgroundColor" } )
|
||||||
public final int getBackgroundColour() throws LuaException
|
public final int getBackgroundColour() throws LuaException
|
||||||
@ -225,6 +230,8 @@ public abstract class TermMethods
|
|||||||
* @param colourArg The new background colour.
|
* @param colourArg The new background colour.
|
||||||
* @throws LuaException (hidden) If the terminal cannot be found.
|
* @throws LuaException (hidden) If the terminal cannot be found.
|
||||||
* @cc.see colors For a list of colour constants.
|
* @cc.see colors For a list of colour constants.
|
||||||
|
* @cc.since 1.45
|
||||||
|
* @cc.changed 1.80pr1 Standard computers can now use all 16 colors, being changed to grayscale on screen.
|
||||||
*/
|
*/
|
||||||
@LuaFunction( { "setBackgroundColour", "setBackgroundColor" } )
|
@LuaFunction( { "setBackgroundColour", "setBackgroundColor" } )
|
||||||
public final void setBackgroundColour( int colourArg ) throws LuaException
|
public final void setBackgroundColour( int colourArg ) throws LuaException
|
||||||
@ -245,6 +252,7 @@ public abstract class TermMethods
|
|||||||
*
|
*
|
||||||
* @return Whether this terminal supports colour.
|
* @return Whether this terminal supports colour.
|
||||||
* @throws LuaException (hidden) If the terminal cannot be found.
|
* @throws LuaException (hidden) If the terminal cannot be found.
|
||||||
|
* @cc.since 1.45
|
||||||
*/
|
*/
|
||||||
@LuaFunction( { "isColour", "isColor" } )
|
@LuaFunction( { "isColour", "isColor" } )
|
||||||
public final boolean getIsColour() throws LuaException
|
public final boolean getIsColour() throws LuaException
|
||||||
@ -267,6 +275,8 @@ public abstract class TermMethods
|
|||||||
* @param backgroundColour The corresponding background colours.
|
* @param backgroundColour The corresponding background colours.
|
||||||
* @throws LuaException If the three inputs are not the same length.
|
* @throws LuaException If the three inputs are not the same length.
|
||||||
* @cc.see colors For a list of colour constants, and their hexadecimal values.
|
* @cc.see colors For a list of colour constants, and their hexadecimal values.
|
||||||
|
* @cc.since 1.74
|
||||||
|
* @cc.changed 1.80pr1 Standard computers can now use all 16 colors, being changed to grayscale on screen.
|
||||||
* @cc.usage Prints "Hello, world!" in rainbow text.
|
* @cc.usage Prints "Hello, world!" in rainbow text.
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* term.blit("Hello, world!","01234456789ab","0000000000000")
|
* term.blit("Hello, world!","01234456789ab","0000000000000")
|
||||||
@ -319,6 +329,7 @@ public abstract class TermMethods
|
|||||||
* }</pre>
|
* }</pre>
|
||||||
* @cc.see colors.unpackRGB To convert from the 24-bit format to three separate channels.
|
* @cc.see colors.unpackRGB To convert from the 24-bit format to three separate channels.
|
||||||
* @cc.see colors.packRGB To convert from three separate channels to the 24-bit format.
|
* @cc.see colors.packRGB To convert from three separate channels to the 24-bit format.
|
||||||
|
* @cc.since 1.80pr1
|
||||||
*/
|
*/
|
||||||
@LuaFunction( { "setPaletteColour", "setPaletteColor" } )
|
@LuaFunction( { "setPaletteColour", "setPaletteColor" } )
|
||||||
public final void setPaletteColour( IArguments args ) throws LuaException
|
public final void setPaletteColour( IArguments args ) throws LuaException
|
||||||
@ -348,6 +359,7 @@ public abstract class TermMethods
|
|||||||
* @cc.treturn number The red channel, will be between 0 and 1.
|
* @cc.treturn number The red channel, will be between 0 and 1.
|
||||||
* @cc.treturn number The green channel, will be between 0 and 1.
|
* @cc.treturn number The green channel, will be between 0 and 1.
|
||||||
* @cc.treturn number The blue channel, will be between 0 and 1.
|
* @cc.treturn number The blue channel, will be between 0 and 1.
|
||||||
|
* @cc.since 1.80pr1
|
||||||
*/
|
*/
|
||||||
@LuaFunction( { "getPaletteColour", "getPaletteColor" } )
|
@LuaFunction( { "getPaletteColour", "getPaletteColor" } )
|
||||||
public final Object[] getPaletteColour( int colourArg ) throws LuaException
|
public final Object[] getPaletteColour( int colourArg ) throws LuaException
|
||||||
|
@ -61,6 +61,7 @@ public class BinaryReadableHandle extends HandleGeneric
|
|||||||
* @cc.treturn [1] nil If we are at the end of the file.
|
* @cc.treturn [1] nil If we are at the end of the file.
|
||||||
* @cc.treturn [2] number The value of the byte read. This is returned when the {@code count} is absent.
|
* @cc.treturn [2] number The value of the byte read. This is returned when the {@code count} is absent.
|
||||||
* @cc.treturn [3] string The bytes read as a string. This is returned when the {@code count} is given.
|
* @cc.treturn [3] string The bytes read as a string. This is returned when the {@code count} is given.
|
||||||
|
* @cc.changed 1.80pr1 Now accepts an integer argument to read multiple bytes, returning a string instead of a number.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] read( Optional<Integer> countArg ) throws LuaException
|
public final Object[] read( Optional<Integer> countArg ) throws LuaException
|
||||||
@ -145,6 +146,7 @@ public class BinaryReadableHandle extends HandleGeneric
|
|||||||
* @return The file, or {@code null} if at the end of it.
|
* @return The file, or {@code null} if at the end of it.
|
||||||
* @throws LuaException If the file has been closed.
|
* @throws LuaException If the file has been closed.
|
||||||
* @cc.treturn string|nil The remaining contents of the file, or {@code nil} if we are at the end.
|
* @cc.treturn string|nil The remaining contents of the file, or {@code nil} if we are at the end.
|
||||||
|
* @cc.since 1.80pr1
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] readAll() throws LuaException
|
public final Object[] readAll() throws LuaException
|
||||||
@ -182,6 +184,8 @@ public class BinaryReadableHandle extends HandleGeneric
|
|||||||
* @return The read string.
|
* @return The read string.
|
||||||
* @throws LuaException If the file has been closed.
|
* @throws LuaException If the file has been closed.
|
||||||
* @cc.treturn string|nil The read line or {@code nil} if at the end of the file.
|
* @cc.treturn string|nil The read line or {@code nil} if at the end of the file.
|
||||||
|
* @cc.since 1.80pr1.9
|
||||||
|
* @cc.changed 1.81.0 `\r` is now stripped.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] readLine( Optional<Boolean> withTrailingArg ) throws LuaException
|
public final Object[] readLine( Optional<Boolean> withTrailingArg ) throws LuaException
|
||||||
@ -259,6 +263,7 @@ public class BinaryReadableHandle extends HandleGeneric
|
|||||||
* @cc.treturn [1] number The new position.
|
* @cc.treturn [1] number The new position.
|
||||||
* @cc.treturn [2] nil If seeking failed.
|
* @cc.treturn [2] nil If seeking failed.
|
||||||
* @cc.treturn string The reason seeking failed.
|
* @cc.treturn string The reason seeking failed.
|
||||||
|
* @cc.since 1.80pr1.9
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] seek( Optional<String> whence, Optional<Long> offset ) throws LuaException
|
public final Object[] seek( Optional<String> whence, Optional<Long> offset ) throws LuaException
|
||||||
|
@ -55,6 +55,7 @@ public class BinaryWritableHandle extends HandleGeneric
|
|||||||
* @throws LuaException If the file has been closed.
|
* @throws LuaException If the file has been closed.
|
||||||
* @cc.tparam [1] number The byte to write.
|
* @cc.tparam [1] number The byte to write.
|
||||||
* @cc.tparam [2] string The string to write.
|
* @cc.tparam [2] string The string to write.
|
||||||
|
* @cc.changed 1.80pr1 Now accepts a string to write multiple bytes.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final void write( IArguments arguments ) throws LuaException
|
public final void write( IArguments arguments ) throws LuaException
|
||||||
@ -130,6 +131,7 @@ public class BinaryWritableHandle extends HandleGeneric
|
|||||||
* @cc.treturn [1] number The new position.
|
* @cc.treturn [1] number The new position.
|
||||||
* @cc.treturn [2] nil If seeking failed.
|
* @cc.treturn [2] nil If seeking failed.
|
||||||
* @cc.treturn string The reason seeking failed.
|
* @cc.treturn string The reason seeking failed.
|
||||||
|
* @cc.since 1.80pr1.9
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] seek( Optional<String> whence, Optional<Long> offset ) throws LuaException
|
public final Object[] seek( Optional<String> whence, Optional<Long> offset ) throws LuaException
|
||||||
|
@ -50,6 +50,7 @@ public class EncodedReadableHandle extends HandleGeneric
|
|||||||
* @return The read string.
|
* @return The read string.
|
||||||
* @throws LuaException If the file has been closed.
|
* @throws LuaException If the file has been closed.
|
||||||
* @cc.treturn string|nil The read line or {@code nil} if at the end of the file.
|
* @cc.treturn string|nil The read line or {@code nil} if at the end of the file.
|
||||||
|
* @cc.changed 1.81.0 Added option to return trailing newline.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] readLine( Optional<Boolean> withTrailingArg ) throws LuaException
|
public final Object[] readLine( Optional<Boolean> withTrailingArg ) throws LuaException
|
||||||
@ -116,6 +117,7 @@ public class EncodedReadableHandle extends HandleGeneric
|
|||||||
* @throws LuaException When trying to read a negative number of characters.
|
* @throws LuaException When trying to read a negative number of characters.
|
||||||
* @throws LuaException If the file has been closed.
|
* @throws LuaException If the file has been closed.
|
||||||
* @cc.treturn string|nil The read characters, or {@code nil} if at the of the file.
|
* @cc.treturn string|nil The read characters, or {@code nil} if at the of the file.
|
||||||
|
* @cc.since 1.80pr1.4
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] read( Optional<Integer> countA ) throws LuaException
|
public final Object[] read( Optional<Integer> countA ) throws LuaException
|
||||||
|
@ -46,6 +46,7 @@ public class HttpResponseHandle implements ObjectSource
|
|||||||
* @return The response code and message.
|
* @return The response code and message.
|
||||||
* @cc.treturn number The response code (i.e. 200)
|
* @cc.treturn number The response code (i.e. 200)
|
||||||
* @cc.treturn string The response message (i.e. "OK")
|
* @cc.treturn string The response message (i.e. "OK")
|
||||||
|
* @cc.changed 1.80pr1.13 Added response message return value.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] getResponseCode()
|
public final Object[] getResponseCode()
|
||||||
|
@ -55,6 +55,8 @@ public class WebsocketHandle implements Closeable
|
|||||||
* @cc.treturn [1] string The received message.
|
* @cc.treturn [1] string The received message.
|
||||||
* @cc.treturn boolean If this was a binary message.
|
* @cc.treturn boolean If this was a binary message.
|
||||||
* @cc.treturn [2] nil If the websocket was closed while waiting, or if we timed out.
|
* @cc.treturn [2] nil If the websocket was closed while waiting, or if we timed out.
|
||||||
|
* @cc.changed 1.80pr1.13 Added return value indicating whether the message was binary.
|
||||||
|
* @cc.changed 1.87.0 Added timeout argument.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult receive( Optional<Double> timeout ) throws LuaException
|
public final MethodResult receive( Optional<Double> timeout ) throws LuaException
|
||||||
@ -74,6 +76,7 @@ public class WebsocketHandle implements Closeable
|
|||||||
* @param binary Whether this message should be treated as a
|
* @param binary Whether this message should be treated as a
|
||||||
* @throws LuaException If the message is too large.
|
* @throws LuaException If the message is too large.
|
||||||
* @throws LuaException If the websocket has been closed.
|
* @throws LuaException If the websocket has been closed.
|
||||||
|
* @cc.changed 1.81.0 Added argument for binary mode.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final void send( Object message, Optional<Boolean> binary ) throws LuaException
|
public final void send( Object message, Optional<Boolean> binary ) throws LuaException
|
||||||
|
@ -18,7 +18,8 @@ import dan200.computercraft.shared.computer.blocks.BlockComputer;
|
|||||||
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
|
import dan200.computercraft.shared.computer.blocks.TileCommandComputer;
|
||||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
import dan200.computercraft.shared.computer.inventory.ComputerMenuWithoutInventory;
|
||||||
|
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.computer.items.ItemComputer;
|
import dan200.computercraft.shared.computer.items.ItemComputer;
|
||||||
import dan200.computercraft.shared.computer.recipe.ComputerUpgradeRecipe;
|
import dan200.computercraft.shared.computer.recipe.ComputerUpgradeRecipe;
|
||||||
@ -52,7 +53,6 @@ import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
|
|||||||
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
|
||||||
import dan200.computercraft.shared.peripheral.speaker.BlockSpeaker;
|
import dan200.computercraft.shared.peripheral.speaker.BlockSpeaker;
|
||||||
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
|
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
|
||||||
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
|
|
||||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||||
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;
|
||||||
@ -312,11 +312,14 @@ public final class Registry
|
|||||||
{
|
{
|
||||||
static final DeferredRegister<MenuType<?>> CONTAINERS = DeferredRegister.create( ForgeRegistries.CONTAINERS, ComputerCraft.MOD_ID );
|
static final DeferredRegister<MenuType<?>> CONTAINERS = DeferredRegister.create( ForgeRegistries.CONTAINERS, ComputerCraft.MOD_ID );
|
||||||
|
|
||||||
public static final RegistryObject<MenuType<ContainerComputer>> COMPUTER = CONTAINERS.register( "computer",
|
public static final RegistryObject<MenuType<ContainerComputerBase>> COMPUTER = CONTAINERS.register( "computer",
|
||||||
() -> ContainerData.toType( ComputerContainerData::new, ContainerComputer::new ) );
|
() -> ContainerData.toType( ComputerContainerData::new, ComputerMenuWithoutInventory::new ) );
|
||||||
|
|
||||||
public static final RegistryObject<MenuType<ContainerPocketComputer>> POCKET_COMPUTER = CONTAINERS.register( "pocket_computer",
|
public static final RegistryObject<MenuType<ContainerComputerBase>> POCKET_COMPUTER = CONTAINERS.register( "pocket_computer",
|
||||||
() -> ContainerData.toType( ComputerContainerData::new, ContainerPocketComputer::new ) );
|
() -> ContainerData.toType( ComputerContainerData::new, ComputerMenuWithoutInventory::new ) );
|
||||||
|
|
||||||
|
public static final RegistryObject<MenuType<ContainerComputerBase>> POCKET_COMPUTER_NO_TERM = CONTAINERS.register( "pocket_computer_no_term",
|
||||||
|
() -> ContainerData.toType( ComputerContainerData::new, ComputerMenuWithoutInventory::new ) );
|
||||||
|
|
||||||
public static final RegistryObject<MenuType<ContainerTurtle>> TURTLE = CONTAINERS.register( "turtle",
|
public static final RegistryObject<MenuType<ContainerTurtle>> TURTLE = CONTAINERS.register( "turtle",
|
||||||
() -> ContainerData.toType( ComputerContainerData::new, ContainerTurtle::new ) );
|
() -> ContainerData.toType( ComputerContainerData::new, ContainerTurtle::new ) );
|
||||||
|
@ -236,7 +236,7 @@ public final class CommandComputerCraft
|
|||||||
@Override
|
@Override
|
||||||
public AbstractContainerMenu createMenu( int id, @Nonnull Inventory player, @Nonnull Player entity )
|
public AbstractContainerMenu createMenu( int id, @Nonnull Inventory player, @Nonnull Player entity )
|
||||||
{
|
{
|
||||||
return new ContainerViewComputer( id, computer );
|
return new ContainerViewComputer( id, player, computer );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -56,18 +56,17 @@ public enum UserLevel implements Predicate<CommandSourceStack>
|
|||||||
public boolean test( CommandSourceStack source )
|
public boolean test( CommandSourceStack source )
|
||||||
{
|
{
|
||||||
if( this == ANYONE ) return true;
|
if( this == ANYONE ) return true;
|
||||||
|
if( this == OWNER ) return isOwner( source );
|
||||||
|
if( this == OWNER_OP && isOwner( source ) ) return true;
|
||||||
|
return source.hasPermission( toLevel() );
|
||||||
|
}
|
||||||
|
|
||||||
if( this == OWNER || this == OWNER_OP )
|
private static boolean isOwner( CommandSourceStack source )
|
||||||
{
|
{
|
||||||
MinecraftServer server = source.getServer();
|
MinecraftServer server = source.getServer();
|
||||||
Entity sender = source.getEntity();
|
Entity sender = source.getEntity();
|
||||||
if( server.isSingleplayer() && sender instanceof Player &&
|
return server.isDedicatedServer()
|
||||||
((Player) sender).getGameProfile().getName().equalsIgnoreCase( server.getServerModName() ) )
|
? source.getEntity() == null && source.hasPermission( 4 ) && source.getTextName().equals( "Server" )
|
||||||
{
|
: sender instanceof Player && ((Player) sender).getGameProfile().getName().equalsIgnoreCase( server.getServerModName() );
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return source.hasPermission( toLevel() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import java.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @cc.module commands
|
* @cc.module commands
|
||||||
|
* @cc.since 1.7
|
||||||
*/
|
*/
|
||||||
public class CommandAPI implements ILuaAPI
|
public class CommandAPI implements ILuaAPI
|
||||||
{
|
{
|
||||||
@ -90,6 +91,8 @@ public class CommandAPI implements ILuaAPI
|
|||||||
* @cc.treturn { string... } The output of this command, as a list of lines.
|
* @cc.treturn { string... } The output of this command, as a list of lines.
|
||||||
* @cc.treturn number|nil The number of "affected" objects, or `nil` if the command failed. The definition of this
|
* @cc.treturn number|nil The number of "affected" objects, or `nil` if the command failed. The definition of this
|
||||||
* varies from command to command.
|
* varies from command to command.
|
||||||
|
* @cc.changed 1.71 Added return value with command output.
|
||||||
|
* @cc.changed 1.85.0 Added return value with the number of affected objects.
|
||||||
* @cc.usage Set the block above the command computer to stone.
|
* @cc.usage Set the block above the command computer to stone.
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* commands.exec("setblock ~ ~1 ~ minecraft:stone")
|
* commands.exec("setblock ~ ~1 ~ minecraft:stone")
|
||||||
@ -118,7 +121,7 @@ public class CommandAPI implements ILuaAPI
|
|||||||
* @throws LuaException (hidden) If the task cannot be created.
|
* @throws LuaException (hidden) If the task cannot be created.
|
||||||
* @cc.usage Asynchronously sets the block above the computer to stone.
|
* @cc.usage Asynchronously sets the block above the computer to stone.
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* commands.execAsync("~ ~1 ~ minecraft:stone")
|
* commands.execAsync("setblock ~ ~1 ~ minecraft:stone")
|
||||||
* }</pre>
|
* }</pre>
|
||||||
* @cc.see parallel One may also use the parallel API to run multiple commands at once.
|
* @cc.see parallel One may also use the parallel API to run multiple commands at once.
|
||||||
*/
|
*/
|
||||||
@ -193,6 +196,7 @@ public class CommandAPI implements ILuaAPI
|
|||||||
* @return A list of information about each block.
|
* @return A list of information about each block.
|
||||||
* @throws LuaException If the coordinates are not within the world.
|
* @throws LuaException If the coordinates are not within the world.
|
||||||
* @throws LuaException If trying to get information about more than 4096 blocks.
|
* @throws LuaException If trying to get information about more than 4096 blocks.
|
||||||
|
* @cc.since 1.76
|
||||||
*/
|
*/
|
||||||
@LuaFunction( mainThread = true )
|
@LuaFunction( mainThread = true )
|
||||||
public final List<Map<?, ?>> getBlockInfos( int minX, int minY, int minZ, int maxX, int maxY, int maxZ ) throws LuaException
|
public final List<Map<?, ?>> getBlockInfos( int minX, int minY, int minZ, int maxX, int maxY, int maxZ ) throws LuaException
|
||||||
@ -245,6 +249,7 @@ public class CommandAPI implements ILuaAPI
|
|||||||
* @param z The z position of the block to query.
|
* @param z The z position of the block to query.
|
||||||
* @return The given block's information.
|
* @return The given block's information.
|
||||||
* @throws LuaException If the coordinates are not within the world, or are not currently loaded.
|
* @throws LuaException If the coordinates are not within the world, or are not currently loaded.
|
||||||
|
* @cc.changed 1.76 Added block state info to return value
|
||||||
*/
|
*/
|
||||||
@LuaFunction( mainThread = true )
|
@LuaFunction( mainThread = true )
|
||||||
public final Map<?, ?> getBlockInfo( int x, int y, int z ) throws LuaException
|
public final Map<?, ?> getBlockInfo( int x, int y, int z ) throws LuaException
|
||||||
|
@ -8,10 +8,11 @@ package dan200.computercraft.shared.computer.blocks;
|
|||||||
import dan200.computercraft.ComputerCraft;
|
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.Registry;
|
||||||
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.inventory.ContainerComputer;
|
import dan200.computercraft.shared.computer.inventory.ComputerMenuWithoutInventory;
|
||||||
import dan200.computercraft.shared.util.CapabilityUtil;
|
import dan200.computercraft.shared.util.CapabilityUtil;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
@ -51,7 +52,7 @@ public class TileComputer extends TileComputerBase
|
|||||||
return computer;
|
return computer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUsableByPlayer( Player player )
|
protected boolean isUsableByPlayer( Player player )
|
||||||
{
|
{
|
||||||
return isUsable( player, false );
|
return isUsable( player, false );
|
||||||
}
|
}
|
||||||
@ -86,7 +87,7 @@ public class TileComputer extends TileComputerBase
|
|||||||
@Override
|
@Override
|
||||||
public AbstractContainerMenu createMenu( int id, @Nonnull Inventory inventory, @Nonnull Player player )
|
public AbstractContainerMenu createMenu( int id, @Nonnull Inventory inventory, @Nonnull Player player )
|
||||||
{
|
{
|
||||||
return new ContainerComputer( id, this );
|
return new ComputerMenuWithoutInventory( Registry.ModContainers.COMPUTER.get(), id, inventory, this::isUsableByPlayer, createServerComputer(), getFamily() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.computer.core;
|
package dan200.computercraft.shared.computer.core;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.computer.upload.FileSlice;
|
||||||
import dan200.computercraft.shared.computer.upload.FileUpload;
|
import dan200.computercraft.shared.computer.upload.FileUpload;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
@ -12,6 +13,7 @@ import net.minecraft.world.inventory.AbstractContainerMenu;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instance of {@link AbstractContainerMenu} which provides a computer. You should implement this
|
* An instance of {@link AbstractContainerMenu} which provides a computer. You should implement this
|
||||||
@ -38,12 +40,28 @@ public interface IContainerComputer
|
|||||||
InputState getInput();
|
InputState getInput();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to upload a series of files to this computer.
|
* Start a file upload into this container.
|
||||||
*
|
*
|
||||||
* @param uploader The player uploading files.
|
* @param uploadId The unique ID of this upload.
|
||||||
* @param files The files to upload.
|
* @param files The files to upload.
|
||||||
*/
|
*/
|
||||||
void upload( @Nonnull ServerPlayer uploader, @Nonnull List<FileUpload> files );
|
void startUpload( @Nonnull UUID uploadId, @Nonnull List<FileUpload> files );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append more data to partially uploaded files.
|
||||||
|
*
|
||||||
|
* @param uploadId The unique ID of this upload.
|
||||||
|
* @param slices Additional parts of file data to upload.
|
||||||
|
*/
|
||||||
|
void continueUpload( @Nonnull UUID uploadId, @Nonnull List<FileSlice> slices );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish off an upload. This either writes the uploaded files or
|
||||||
|
*
|
||||||
|
* @param uploader The player uploading files.
|
||||||
|
* @param uploadId The unique ID of this upload.
|
||||||
|
*/
|
||||||
|
void finishUpload( @Nonnull ServerPlayer uploader, @Nonnull UUID uploadId );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Continue an upload.
|
* Continue an upload.
|
||||||
@ -51,5 +69,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 continueUpload( @Nonnull ServerPlayer uploader, boolean overwrite );
|
void confirmUpload( @Nonnull ServerPlayer uploader, boolean overwrite );
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.computer.inventory;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
|
import dan200.computercraft.shared.computer.core.IComputer;
|
||||||
|
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
||||||
|
import dan200.computercraft.shared.util.InvisibleSlot;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.inventory.MenuType;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A computer menu which does not have any visible inventory.
|
||||||
|
*
|
||||||
|
* This adds invisible versions of the player's hotbars slots, to ensure they're synced to the client when changed.
|
||||||
|
*/
|
||||||
|
public class ComputerMenuWithoutInventory extends ContainerComputerBase
|
||||||
|
{
|
||||||
|
public ComputerMenuWithoutInventory( MenuType<? extends ContainerComputerBase> type, int id, Inventory player, Predicate<Player> canUse, IComputer computer, ComputerFamily family )
|
||||||
|
{
|
||||||
|
super( type, id, canUse, computer, family );
|
||||||
|
addSlots( player );
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComputerMenuWithoutInventory( MenuType<? extends ContainerComputerBase> type, int id, Inventory player, ComputerContainerData data )
|
||||||
|
{
|
||||||
|
super( type, id, player, data );
|
||||||
|
addSlots( player );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSlots( Inventory player )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 9; i++ ) addSlot( new InvisibleSlot( player, i ) );
|
||||||
|
}
|
||||||
|
}
|
@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.computer.inventory;
|
|
||||||
|
|
||||||
import dan200.computercraft.shared.Registry;
|
|
||||||
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
|
||||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
|
||||||
|
|
||||||
public class ContainerComputer extends ContainerComputerBase
|
|
||||||
{
|
|
||||||
public ContainerComputer( int id, TileComputer tile )
|
|
||||||
{
|
|
||||||
super( Registry.ModContainers.COMPUTER.get(), id, tile::isUsableByPlayer, tile.createServerComputer(), tile.getFamily() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContainerComputer( int id, Inventory player, ComputerContainerData data )
|
|
||||||
{
|
|
||||||
super( Registry.ModContainers.COMPUTER.get(), id, player, data );
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,6 +10,7 @@ import dan200.computercraft.core.filesystem.FileSystem;
|
|||||||
import dan200.computercraft.core.filesystem.FileSystemException;
|
import dan200.computercraft.core.filesystem.FileSystemException;
|
||||||
import dan200.computercraft.core.filesystem.FileSystemWrapper;
|
import dan200.computercraft.core.filesystem.FileSystemWrapper;
|
||||||
import dan200.computercraft.shared.computer.core.*;
|
import dan200.computercraft.shared.computer.core.*;
|
||||||
|
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.computer.upload.UploadResult;
|
import dan200.computercraft.shared.computer.upload.UploadResult;
|
||||||
import dan200.computercraft.shared.network.NetworkHandler;
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
@ -29,10 +30,11 @@ import java.nio.channels.WritableByteChannel;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class ContainerComputerBase extends AbstractContainerMenu implements IContainerComputer
|
public abstract class ContainerComputerBase extends AbstractContainerMenu implements IContainerComputer
|
||||||
{
|
{
|
||||||
private static final String LIST_PREFIX = "\n \u2022 ";
|
private static final String LIST_PREFIX = "\n \u2022 ";
|
||||||
|
|
||||||
@ -40,9 +42,11 @@ public class ContainerComputerBase extends AbstractContainerMenu implements ICon
|
|||||||
private final IComputer computer;
|
private final IComputer computer;
|
||||||
private final ComputerFamily family;
|
private final ComputerFamily family;
|
||||||
private final InputState input = new InputState( this );
|
private final InputState input = new InputState( this );
|
||||||
|
|
||||||
|
private UUID toUploadId;
|
||||||
private List<FileUpload> toUpload;
|
private List<FileUpload> toUpload;
|
||||||
|
|
||||||
protected ContainerComputerBase( MenuType<? extends ContainerComputerBase> type, int id, Predicate<Player> canUse, IComputer computer, ComputerFamily family )
|
public ContainerComputerBase( MenuType<? extends ContainerComputerBase> type, int id, Predicate<Player> canUse, IComputer computer, ComputerFamily family )
|
||||||
{
|
{
|
||||||
super( type, id );
|
super( type, id );
|
||||||
this.canUse = canUse;
|
this.canUse = canUse;
|
||||||
@ -50,7 +54,7 @@ public class ContainerComputerBase extends AbstractContainerMenu implements ICon
|
|||||||
this.family = family;
|
this.family = family;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ContainerComputerBase( MenuType<? extends ContainerComputerBase> type, int id, Inventory player, ComputerContainerData data )
|
public ContainerComputerBase( MenuType<? extends ContainerComputerBase> type, int id, Inventory player, ComputerContainerData data )
|
||||||
{
|
{
|
||||||
this( type, id, x -> true, getComputer( player, data ), data.getFamily() );
|
this( type, id, x -> true, getComputer( player, data ), data.getFamily() );
|
||||||
}
|
}
|
||||||
@ -92,25 +96,52 @@ public class ContainerComputerBase extends AbstractContainerMenu implements ICon
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void upload( @Nonnull ServerPlayer uploader, @Nonnull List<FileUpload> files )
|
public void startUpload( @Nonnull UUID uuid, @Nonnull List<FileUpload> files )
|
||||||
{
|
{
|
||||||
UploadResultMessage message = upload( files, false );
|
toUploadId = uuid;
|
||||||
|
toUpload = files;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void continueUpload( @Nonnull UUID uploadId, @Nonnull 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( @Nonnull ServerPlayer 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 );
|
NetworkHandler.sendToPlayer( uploader, message );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void continueUpload( @Nonnull ServerPlayer uploader, boolean overwrite )
|
public void confirmUpload( @Nonnull ServerPlayer uploader, boolean overwrite )
|
||||||
{
|
{
|
||||||
List<FileUpload> files = this.toUpload;
|
if( toUploadId == null || toUpload == null || toUpload.isEmpty() )
|
||||||
toUpload = null;
|
{
|
||||||
if( files == null || files.isEmpty() || !overwrite ) return;
|
ComputerCraft.log.warn( "Invalid finishUpload call, skipping." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
UploadResultMessage message = upload( files, true );
|
UploadResultMessage message = finishUpload( true );
|
||||||
NetworkHandler.sendToPlayer( uploader, message );
|
NetworkHandler.sendToPlayer( uploader, message );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private UploadResultMessage upload( @Nonnull List<FileUpload> files, boolean forceOverwrite )
|
private UploadResultMessage finishUpload( boolean forceOverwrite )
|
||||||
{
|
{
|
||||||
ServerComputer computer = (ServerComputer) getComputer();
|
ServerComputer computer = (ServerComputer) getComputer();
|
||||||
if( computer == null ) return UploadResultMessage.COMPUTER_OFF;
|
if( computer == null ) return UploadResultMessage.COMPUTER_OFF;
|
||||||
@ -118,9 +149,20 @@ public class ContainerComputerBase extends AbstractContainerMenu implements ICon
|
|||||||
FileSystem fs = computer.getComputer().getEnvironment().getFileSystem();
|
FileSystem fs = computer.getComputer().getEnvironment().getFileSystem();
|
||||||
if( fs == null ) return UploadResultMessage.COMPUTER_OFF;
|
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 TranslatableComponent( "gui.computercraft.upload.failed.corrupted" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<String> overwrite = new ArrayList<>();
|
List<String> overwrite = new ArrayList<>();
|
||||||
|
List<FileUpload> files = toUpload;
|
||||||
|
toUpload = null;
|
||||||
for( FileUpload upload : files )
|
for( FileUpload upload : files )
|
||||||
{
|
{
|
||||||
if( !fs.exists( upload.getName() ) ) continue;
|
if( !fs.exists( upload.getName() ) ) continue;
|
||||||
@ -139,7 +181,6 @@ public class ContainerComputerBase extends AbstractContainerMenu implements ICon
|
|||||||
{
|
{
|
||||||
StringJoiner joiner = new StringJoiner( LIST_PREFIX, LIST_PREFIX, "" );
|
StringJoiner joiner = new StringJoiner( LIST_PREFIX, LIST_PREFIX, "" );
|
||||||
for( String value : overwrite ) joiner.add( value );
|
for( String value : overwrite ) joiner.add( value );
|
||||||
|
|
||||||
toUpload = files;
|
toUpload = files;
|
||||||
return new UploadResultMessage(
|
return new UploadResultMessage(
|
||||||
UploadResult.CONFIRM_OVERWRITE,
|
UploadResult.CONFIRM_OVERWRITE,
|
||||||
@ -167,7 +208,7 @@ public class ContainerComputerBase extends AbstractContainerMenu implements ICon
|
|||||||
catch( FileSystemException | IOException e )
|
catch( FileSystemException | IOException e )
|
||||||
{
|
{
|
||||||
ComputerCraft.log.error( "Error uploading files", e );
|
ComputerCraft.log.error( "Error uploading files", e );
|
||||||
return new UploadResultMessage( UploadResult.ERROR, new TranslatableComponent( "computercraft.gui.upload.failed.generic", e.getMessage() ) );
|
return new UploadResultMessage( UploadResult.ERROR, new TranslatableComponent( "gui.computercraft.upload.failed.generic", e.getMessage() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,14 +16,14 @@ import net.minecraft.world.entity.player.Player;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class ContainerViewComputer extends ContainerComputerBase
|
public class ContainerViewComputer extends ComputerMenuWithoutInventory
|
||||||
{
|
{
|
||||||
private final int width;
|
private final int width;
|
||||||
private final int height;
|
private final int height;
|
||||||
|
|
||||||
public ContainerViewComputer( int id, ServerComputer computer )
|
public ContainerViewComputer( int id, Inventory player, ServerComputer computer )
|
||||||
{
|
{
|
||||||
super( Registry.ModContainers.VIEW_COMPUTER.get(), id, player -> canInteractWith( computer, player ), computer, computer.getFamily() );
|
super( Registry.ModContainers.VIEW_COMPUTER.get(), id, player, p -> canInteractWith( computer, p ), computer, computer.getFamily() );
|
||||||
width = height = 0;
|
width = height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.computer.upload;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class FileSlice
|
||||||
|
{
|
||||||
|
private final int fileId;
|
||||||
|
private final int offset;
|
||||||
|
private final ByteBuffer bytes;
|
||||||
|
|
||||||
|
public FileSlice( int fileId, int offset, ByteBuffer bytes )
|
||||||
|
{
|
||||||
|
this.fileId = fileId;
|
||||||
|
this.offset = offset;
|
||||||
|
this.bytes = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFileId()
|
||||||
|
{
|
||||||
|
return fileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOffset()
|
||||||
|
{
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer getBytes()
|
||||||
|
{
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void apply( List<FileUpload> files )
|
||||||
|
{
|
||||||
|
if( fileId < 0 || fileId >= files.size() )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.warn( "File ID is out-of-bounds (0 <= {} < {})", fileId, files.size() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer file = files.get( fileId ).getBytes();
|
||||||
|
if( offset < 0 || offset + bytes.remaining() > file.capacity() )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.warn( "File offset is out-of-bounds (0 <= {} <= {})", offset, file.capacity() - offset );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes.rewind();
|
||||||
|
file.position( offset );
|
||||||
|
file.put( bytes );
|
||||||
|
file.rewind();
|
||||||
|
|
||||||
|
if( bytes.remaining() != 0 ) throw new IllegalStateException( "Should have read the whole buffer" );
|
||||||
|
}
|
||||||
|
}
|
@ -5,26 +5,76 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.computer.upload;
|
package dan200.computercraft.shared.computer.upload;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class FileUpload
|
public class FileUpload
|
||||||
{
|
{
|
||||||
private final String name;
|
public static final int CHECKSUM_LENGTH = 32;
|
||||||
private final ByteBuffer bytes;
|
|
||||||
|
|
||||||
public FileUpload( String name, ByteBuffer bytes )
|
private final String name;
|
||||||
|
private final int length;
|
||||||
|
private final ByteBuffer bytes;
|
||||||
|
private final byte[] checksum;
|
||||||
|
|
||||||
|
public FileUpload( String name, ByteBuffer bytes, byte[] checksum )
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.bytes = bytes;
|
this.bytes = bytes;
|
||||||
|
length = bytes.remaining();
|
||||||
|
this.checksum = checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public ByteBuffer getBytes()
|
public ByteBuffer getBytes()
|
||||||
{
|
{
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getLength()
|
||||||
|
{
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public byte[] getChecksum()
|
||||||
|
{
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checksumMatches()
|
||||||
|
{
|
||||||
|
// This is meant to be a checksum. Doesn't need to be cryptographically secure, hence non constant time.
|
||||||
|
byte[] digest = getDigest( bytes );
|
||||||
|
return digest != null && Arrays.equals( checksum, digest );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static byte[] getDigest( ByteBuffer bytes )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bytes.rewind();
|
||||||
|
MessageDigest digest = MessageDigest.getInstance( "SHA-256" );
|
||||||
|
digest.update( bytes );
|
||||||
|
return digest.digest();
|
||||||
|
}
|
||||||
|
catch( NoSuchAlgorithmException e )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.warn( "Failed to compute digest ({})", e.toString() );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import net.minecraft.world.entity.player.Player;
|
|||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
import net.minecraft.world.inventory.MenuType;
|
import net.minecraft.world.inventory.MenuType;
|
||||||
import net.minecraftforge.common.extensions.IForgeContainerType;
|
import net.minecraftforge.common.extensions.IForgeContainerType;
|
||||||
|
import net.minecraftforge.fmllegacy.network.IContainerFactory;
|
||||||
import net.minecraftforge.fmllegacy.network.NetworkHooks;
|
import net.minecraftforge.fmllegacy.network.NetworkHooks;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -37,8 +38,36 @@ public interface ContainerData
|
|||||||
return IForgeContainerType.create( ( id, player, data ) -> factory.create( id, player, reader.apply( data ) ) );
|
return IForgeContainerType.create( ( id, player, data ) -> factory.create( id, player, reader.apply( data ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static <C extends AbstractContainerMenu, T extends ContainerData> MenuType<C> toType( Function<FriendlyByteBuf, T> reader, FixedFactory<C, T> factory )
|
||||||
|
{
|
||||||
|
return new FixedPointContainerFactory<>( reader, factory ).type;
|
||||||
|
}
|
||||||
|
|
||||||
interface Factory<C extends AbstractContainerMenu, T extends ContainerData>
|
interface Factory<C extends AbstractContainerMenu, T extends ContainerData>
|
||||||
{
|
{
|
||||||
C create( int id, @Nonnull Inventory inventory, T data );
|
C create( int id, @Nonnull Inventory inventory, T data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface FixedFactory<C extends AbstractContainerMenu, T extends ContainerData>
|
||||||
|
{
|
||||||
|
C create( MenuType<C> type, int id, @Nonnull Inventory inventory, T data );
|
||||||
|
}
|
||||||
|
|
||||||
|
class FixedPointContainerFactory<C extends AbstractContainerMenu, T extends ContainerData> implements IContainerFactory<C>
|
||||||
|
{
|
||||||
|
private final IContainerFactory<C> impl;
|
||||||
|
private final MenuType<C> type;
|
||||||
|
|
||||||
|
private FixedPointContainerFactory( Function<FriendlyByteBuf, T> reader, FixedFactory<C, T> factory )
|
||||||
|
{
|
||||||
|
MenuType<C> type = this.type = IForgeContainerType.create( this );
|
||||||
|
impl = ( id, player, data ) -> factory.create( type, id, player, reader.apply( data ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public C create( int windowId, Inventory inv, FriendlyByteBuf data )
|
||||||
|
{
|
||||||
|
return impl.create( windowId, inv, data );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,6 @@ public class ContinueUploadMessage extends ComputerServerMessage
|
|||||||
protected void handle( NetworkEvent.Context context, @Nonnull ServerComputer computer, @Nonnull IContainerComputer container )
|
protected void handle( NetworkEvent.Context context, @Nonnull ServerComputer computer, @Nonnull IContainerComputer container )
|
||||||
{
|
{
|
||||||
ServerPlayer player = context.getSender();
|
ServerPlayer player = context.getSender();
|
||||||
if( player != null ) container.continueUpload( player, overwrite );
|
if( player != null ) container.confirmUpload( player, overwrite );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.network.server;
|
package dan200.computercraft.shared.network.server;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.computer.core.IContainerComputer;
|
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.upload.FileSlice;
|
||||||
import dan200.computercraft.shared.computer.upload.FileUpload;
|
import dan200.computercraft.shared.computer.upload.FileUpload;
|
||||||
|
import dan200.computercraft.shared.network.NetworkHandler;
|
||||||
|
import io.netty.handler.codec.DecoderException;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraftforge.fmllegacy.network.NetworkEvent;
|
import net.minecraftforge.fmllegacy.network.NetworkEvent;
|
||||||
@ -16,34 +20,81 @@ import javax.annotation.Nonnull;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class UploadFileMessage extends ComputerServerMessage
|
public class UploadFileMessage extends ComputerServerMessage
|
||||||
{
|
{
|
||||||
public static final int MAX_SIZE = 30 * 1024; // Max packet size is 32767. TODO: Bump this in the future
|
public static final int MAX_SIZE = 512 * 1024;
|
||||||
private final List<FileUpload> files;
|
static final int MAX_PACKET_SIZE = 30 * 1024; // Max packet size is 32767.
|
||||||
|
|
||||||
public UploadFileMessage( int instanceId, List<FileUpload> files )
|
public static final int MAX_FILES = 32;
|
||||||
|
public static final int MAX_FILE_NAME = 128;
|
||||||
|
|
||||||
|
private static final int FLAG_FIRST = 1;
|
||||||
|
private static final int FLAG_LAST = 2;
|
||||||
|
|
||||||
|
private final UUID uuid;
|
||||||
|
private final int flag;
|
||||||
|
private final List<FileUpload> files;
|
||||||
|
private final List<FileSlice> slices;
|
||||||
|
|
||||||
|
UploadFileMessage( int instanceId, UUID uuid, int flag, List<FileUpload> files, List<FileSlice> slices )
|
||||||
{
|
{
|
||||||
super( instanceId );
|
super( instanceId );
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.flag = flag;
|
||||||
this.files = files;
|
this.files = files;
|
||||||
|
this.slices = slices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UploadFileMessage( @Nonnull FriendlyByteBuf buf )
|
public UploadFileMessage( @Nonnull FriendlyByteBuf buf )
|
||||||
{
|
{
|
||||||
super( buf );
|
super( buf );
|
||||||
|
uuid = buf.readUUID();
|
||||||
|
int flag = this.flag = buf.readByte();
|
||||||
|
|
||||||
|
int totalSize = 0;
|
||||||
|
if( (flag & FLAG_FIRST) != 0 )
|
||||||
|
{
|
||||||
int nFiles = buf.readVarInt();
|
int nFiles = buf.readVarInt();
|
||||||
|
if( nFiles >= MAX_FILES ) throw new DecoderException( "Too many files" );
|
||||||
|
|
||||||
List<FileUpload> files = this.files = new ArrayList<>( nFiles );
|
List<FileUpload> files = this.files = new ArrayList<>( nFiles );
|
||||||
for( int i = 0; i < nFiles; i++ )
|
for( int i = 0; i < nFiles; i++ )
|
||||||
{
|
{
|
||||||
String name = buf.readUtf( 32767 );
|
String name = buf.readUtf( MAX_FILE_NAME );
|
||||||
int size = buf.readVarInt();
|
int size = buf.readVarInt();
|
||||||
if( size > MAX_SIZE ) break;
|
if( size > MAX_SIZE || (totalSize += size) >= MAX_SIZE )
|
||||||
|
{
|
||||||
|
throw new DecoderException( "Files are too large" );
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] digest = new byte[FileUpload.CHECKSUM_LENGTH];
|
||||||
|
buf.readBytes( digest );
|
||||||
|
|
||||||
|
files.add( new FileUpload( name, ByteBuffer.allocateDirect( size ), digest ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
files = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nSlices = buf.readVarInt();
|
||||||
|
List<FileSlice> slices = this.slices = new ArrayList<>( nSlices );
|
||||||
|
for( int i = 0; i < nSlices; i++ )
|
||||||
|
{
|
||||||
|
int fileId = buf.readUnsignedByte();
|
||||||
|
int offset = buf.readVarInt();
|
||||||
|
|
||||||
|
int size = buf.readUnsignedShort();
|
||||||
|
if( size > MAX_PACKET_SIZE ) throw new DecoderException( "File is too large" );
|
||||||
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect( size );
|
ByteBuffer buffer = ByteBuffer.allocateDirect( size );
|
||||||
buf.readBytes( buffer );
|
buf.readBytes( buffer );
|
||||||
buffer.flip();
|
buffer.flip();
|
||||||
|
|
||||||
files.add( new FileUpload( name, buffer ) );
|
slices.add( new FileSlice( fileId, offset, buffer ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,19 +102,85 @@ public class UploadFileMessage extends ComputerServerMessage
|
|||||||
public void toBytes( @Nonnull FriendlyByteBuf buf )
|
public void toBytes( @Nonnull FriendlyByteBuf buf )
|
||||||
{
|
{
|
||||||
super.toBytes( buf );
|
super.toBytes( buf );
|
||||||
|
buf.writeUUID( uuid );
|
||||||
|
buf.writeByte( flag );
|
||||||
|
|
||||||
|
if( (flag & FLAG_FIRST) != 0 )
|
||||||
|
{
|
||||||
buf.writeVarInt( files.size() );
|
buf.writeVarInt( files.size() );
|
||||||
for( FileUpload file : files )
|
for( FileUpload file : files )
|
||||||
{
|
{
|
||||||
buf.writeUtf( file.getName() );
|
buf.writeUtf( file.getName(), MAX_FILE_NAME );
|
||||||
buf.writeVarInt( file.getBytes().remaining() );
|
buf.writeVarInt( file.getLength() );
|
||||||
buf.writeBytes( file.getBytes() );
|
buf.writeBytes( file.getChecksum() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf.writeVarInt( slices.size() );
|
||||||
|
for( FileSlice slice : slices )
|
||||||
|
{
|
||||||
|
buf.writeByte( slice.getFileId() );
|
||||||
|
buf.writeVarInt( slice.getOffset() );
|
||||||
|
|
||||||
|
slice.getBytes().rewind();
|
||||||
|
buf.writeShort( slice.getBytes().remaining() );
|
||||||
|
buf.writeBytes( slice.getBytes() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void send( int instanceId, List<FileUpload> files )
|
||||||
|
{
|
||||||
|
UUID uuid = UUID.randomUUID();
|
||||||
|
|
||||||
|
int remaining = MAX_PACKET_SIZE;
|
||||||
|
for( FileUpload file : files ) remaining -= file.getName().length() * 4 + FileUpload.CHECKSUM_LENGTH;
|
||||||
|
|
||||||
|
boolean first = true;
|
||||||
|
List<FileSlice> slices = new ArrayList<>( files.size() );
|
||||||
|
for( int fileId = 0; fileId < files.size(); fileId++ )
|
||||||
|
{
|
||||||
|
FileUpload file = files.get( fileId );
|
||||||
|
ByteBuffer contents = file.getBytes();
|
||||||
|
int capacity = contents.limit();
|
||||||
|
|
||||||
|
int currentOffset = 0;
|
||||||
|
while( currentOffset < capacity )
|
||||||
|
{
|
||||||
|
if( remaining <= 0 )
|
||||||
|
{
|
||||||
|
NetworkHandler.sendToServer( first
|
||||||
|
? new UploadFileMessage( instanceId, uuid, FLAG_FIRST, files, new ArrayList<>( slices ) )
|
||||||
|
: new UploadFileMessage( instanceId, uuid, 0, null, new ArrayList<>( slices ) ) );
|
||||||
|
slices.clear();
|
||||||
|
remaining = MAX_PACKET_SIZE;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int canWrite = Math.min( remaining, capacity - currentOffset );
|
||||||
|
|
||||||
|
ComputerCraft.log.info( "Adding slice from {} to {}", currentOffset, currentOffset + canWrite - 1 );
|
||||||
|
contents.position( currentOffset ).limit( currentOffset + canWrite );
|
||||||
|
slices.add( new FileSlice( fileId, currentOffset, contents.slice() ) );
|
||||||
|
currentOffset += canWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
contents.position( 0 ).limit( capacity );
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkHandler.sendToServer( first
|
||||||
|
? new UploadFileMessage( instanceId, uuid, FLAG_FIRST | FLAG_LAST, files, new ArrayList<>( slices ) )
|
||||||
|
: new UploadFileMessage( instanceId, 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 ServerComputer computer, @Nonnull IContainerComputer container )
|
||||||
{
|
{
|
||||||
ServerPlayer player = context.getSender();
|
ServerPlayer player = context.getSender();
|
||||||
if( player != null ) container.upload( player, files );
|
if( player != null )
|
||||||
|
{
|
||||||
|
if( (flag & FLAG_FIRST) != 0 ) container.startUpload( uuid, files );
|
||||||
|
container.continueUpload( uuid, slices );
|
||||||
|
if( (flag & FLAG_LAST) != 0 ) container.finishUpload( player, uuid );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,6 +186,7 @@ public class DiskDrivePeripheral implements IPeripheral
|
|||||||
*
|
*
|
||||||
* @return The ID of the disk in the drive, or {@code nil} if no disk with an ID is inserted.
|
* @return The ID of the disk in the drive, or {@code nil} if no disk with an ID is inserted.
|
||||||
* @cc.treturn number The The ID of the disk in the drive, or {@code nil} if no disk with an ID is inserted.
|
* @cc.treturn number The The ID of the disk in the drive, or {@code nil} if no disk with an ID is inserted.
|
||||||
|
* @cc.since 1.4
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] getDiskID()
|
public final Object[] getDiskID()
|
||||||
|
@ -187,6 +187,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW
|
|||||||
*
|
*
|
||||||
* @return The current computer's name.
|
* @return The current computer's name.
|
||||||
* @cc.treturn string|nil The current computer's name on the wired network.
|
* @cc.treturn string|nil The current computer's name on the wired network.
|
||||||
|
* @cc.since 1.80pr1.7
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] getNameLocal()
|
public final Object[] getNameLocal()
|
||||||
|
@ -71,6 +71,7 @@ public class MonitorPeripheral extends TermMethods implements IPeripheral
|
|||||||
*
|
*
|
||||||
* @return The monitor's current scale.
|
* @return The monitor's current scale.
|
||||||
* @throws LuaException If the monitor cannot be found.
|
* @throws LuaException If the monitor cannot be found.
|
||||||
|
* @cc.since 1.81.0
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final double getTextScale() throws LuaException
|
public final double getTextScale() throws LuaException
|
||||||
|
@ -35,6 +35,7 @@ import static dan200.computercraft.api.lua.LuaValues.checkFinite;
|
|||||||
* Speakers allow playing notes and other sounds.
|
* Speakers allow playing notes and other sounds.
|
||||||
*
|
*
|
||||||
* @cc.module speaker
|
* @cc.module speaker
|
||||||
|
* @cc.since 1.80pr1
|
||||||
*/
|
*/
|
||||||
public abstract class SpeakerPeripheral implements IPeripheral
|
public abstract class SpeakerPeripheral implements IPeripheral
|
||||||
{
|
{
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.shared.pocket.inventory;
|
|
||||||
|
|
||||||
import dan200.computercraft.shared.Registry;
|
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
|
||||||
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
|
||||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import net.minecraft.world.InteractionHand;
|
|
||||||
import net.minecraft.world.MenuProvider;
|
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public final class ContainerPocketComputer extends ContainerComputerBase
|
|
||||||
{
|
|
||||||
private ContainerPocketComputer( int id, ServerComputer computer, ItemPocketComputer item, InteractionHand hand )
|
|
||||||
{
|
|
||||||
super( Registry.ModContainers.POCKET_COMPUTER.get(), id, p -> {
|
|
||||||
ItemStack stack = p.getItemInHand( hand );
|
|
||||||
return stack.getItem() == item && ItemPocketComputer.getServerComputer( stack ) == computer;
|
|
||||||
}, computer, item.getFamily() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContainerPocketComputer( int id, Inventory player, ComputerContainerData data )
|
|
||||||
{
|
|
||||||
super( Registry.ModContainers.POCKET_COMPUTER.get(), id, player, data );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Factory implements MenuProvider
|
|
||||||
{
|
|
||||||
private final ServerComputer computer;
|
|
||||||
private final Component name;
|
|
||||||
private final ItemPocketComputer item;
|
|
||||||
private final InteractionHand hand;
|
|
||||||
|
|
||||||
public Factory( ServerComputer computer, ItemStack stack, ItemPocketComputer item, InteractionHand hand )
|
|
||||||
{
|
|
||||||
this.computer = computer;
|
|
||||||
name = stack.getHoverName();
|
|
||||||
this.item = item;
|
|
||||||
this.hand = hand;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Component getDisplayName()
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public AbstractContainerMenu createMenu( int id, @Nonnull Inventory inventory, @Nonnull Player entity )
|
|
||||||
{
|
|
||||||
return new ContainerPocketComputer( id, computer, item, hand );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.pocket.inventory;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.Registry;
|
||||||
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
|
import dan200.computercraft.shared.computer.inventory.ComputerMenuWithoutInventory;
|
||||||
|
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.MenuProvider;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class PocketComputerMenuProvider implements MenuProvider
|
||||||
|
{
|
||||||
|
private final ServerComputer computer;
|
||||||
|
private final Component name;
|
||||||
|
private final ItemPocketComputer item;
|
||||||
|
private final InteractionHand hand;
|
||||||
|
private final boolean isTypingOnly;
|
||||||
|
|
||||||
|
public PocketComputerMenuProvider( ServerComputer computer, ItemStack stack, ItemPocketComputer item, InteractionHand hand, boolean isTypingOnly )
|
||||||
|
{
|
||||||
|
this.computer = computer;
|
||||||
|
name = stack.getHoverName();
|
||||||
|
this.item = item;
|
||||||
|
this.hand = hand;
|
||||||
|
this.isTypingOnly = isTypingOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Component getDisplayName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public AbstractContainerMenu createMenu( int id, @Nonnull Inventory inventory, @Nonnull Player entity )
|
||||||
|
{
|
||||||
|
return new ComputerMenuWithoutInventory(
|
||||||
|
isTypingOnly ? Registry.ModContainers.POCKET_COMPUTER_NO_TERM.get() : Registry.ModContainers.POCKET_COMPUTER.get(), id, inventory,
|
||||||
|
p -> {
|
||||||
|
ItemStack stack = p.getItemInHand( hand );
|
||||||
|
return stack.getItem() == item && ItemPocketComputer.getServerComputer( stack ) == computer;
|
||||||
|
},
|
||||||
|
computer, item.getFamily()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,7 @@ 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;
|
||||||
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
|
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
|
||||||
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
|
import dan200.computercraft.shared.pocket.inventory.PocketComputerMenuProvider;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.core.NonNullList;
|
import net.minecraft.core.NonNullList;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
@ -154,7 +154,8 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
|
|||||||
|
|
||||||
if( !stop && computer != null )
|
if( !stop && computer != null )
|
||||||
{
|
{
|
||||||
new ComputerContainerData( computer ).open( player, new ContainerPocketComputer.Factory( computer, stack, this, hand ) );
|
boolean isTypingOnly = hand == InteractionHand.OFF_HAND;
|
||||||
|
new ComputerContainerData( computer ).open( player, new PocketComputerMenuProvider( computer, stack, this, hand, isTypingOnly ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new InteractionResultHolder<>( InteractionResult.SUCCESS, stack );
|
return new InteractionResultHolder<>( InteractionResult.SUCCESS, stack );
|
||||||
|
@ -26,6 +26,7 @@ import java.util.Optional;
|
|||||||
* The turtle API allows you to control your turtle.
|
* The turtle API allows you to control your turtle.
|
||||||
*
|
*
|
||||||
* @cc.module turtle
|
* @cc.module turtle
|
||||||
|
* @cc.since 1.3
|
||||||
*/
|
*/
|
||||||
public class TurtleAPI implements ILuaAPI
|
public class TurtleAPI implements ILuaAPI
|
||||||
{
|
{
|
||||||
@ -139,6 +140,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether a block was broken.
|
* @cc.treturn boolean Whether a block was broken.
|
||||||
* @cc.treturn string|nil The reason no block was broken.
|
* @cc.treturn string|nil The reason no block was broken.
|
||||||
|
* @cc.changed 1.6 Added optional side argument.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult dig( Optional<TurtleSide> side )
|
public final MethodResult dig( Optional<TurtleSide> side )
|
||||||
@ -154,6 +156,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether a block was broken.
|
* @cc.treturn boolean Whether a block was broken.
|
||||||
* @cc.treturn string|nil The reason no block was broken.
|
* @cc.treturn string|nil The reason no block was broken.
|
||||||
|
* @cc.changed 1.6 Added optional side argument.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult digUp( Optional<TurtleSide> side )
|
public final MethodResult digUp( Optional<TurtleSide> side )
|
||||||
@ -169,6 +172,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether a block was broken.
|
* @cc.treturn boolean Whether a block was broken.
|
||||||
* @cc.treturn string|nil The reason no block was broken.
|
* @cc.treturn string|nil The reason no block was broken.
|
||||||
|
* @cc.changed 1.6 Added optional side argument.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult digDown( Optional<TurtleSide> side )
|
public final MethodResult digDown( Optional<TurtleSide> side )
|
||||||
@ -189,6 +193,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @cc.tparam [opt] string text When placing a sign, set its contents to this text.
|
* @cc.tparam [opt] string text When placing a sign, set its contents to this text.
|
||||||
* @cc.treturn boolean Whether the block could be placed.
|
* @cc.treturn boolean Whether the block could be placed.
|
||||||
* @cc.treturn string|nil The reason the block was not placed.
|
* @cc.treturn string|nil The reason the block was not placed.
|
||||||
|
* @cc.since 1.4
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult place( IArguments args )
|
public final MethodResult place( IArguments args )
|
||||||
@ -204,6 +209,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @cc.tparam [opt] string text When placing a sign, set its contents to this text.
|
* @cc.tparam [opt] string text When placing a sign, set its contents to this text.
|
||||||
* @cc.treturn boolean Whether the block could be placed.
|
* @cc.treturn boolean Whether the block could be placed.
|
||||||
* @cc.treturn string|nil The reason the block was not placed.
|
* @cc.treturn string|nil The reason the block was not placed.
|
||||||
|
* @cc.since 1.4
|
||||||
* @see #place For more information about placing items.
|
* @see #place For more information about placing items.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -220,6 +226,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @cc.tparam [opt] string text When placing a sign, set its contents to this text.
|
* @cc.tparam [opt] string text When placing a sign, set its contents to this text.
|
||||||
* @cc.treturn boolean Whether the block could be placed.
|
* @cc.treturn boolean Whether the block could be placed.
|
||||||
* @cc.treturn string|nil The reason the block was not placed.
|
* @cc.treturn string|nil The reason the block was not placed.
|
||||||
|
* @cc.since 1.4
|
||||||
* @see #place For more information about placing items.
|
* @see #place For more information about placing items.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -237,6 +244,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @throws LuaException If dropping an invalid number of items.
|
* @throws LuaException If dropping an invalid number of items.
|
||||||
* @cc.treturn boolean Whether items were dropped.
|
* @cc.treturn boolean Whether items were dropped.
|
||||||
* @cc.treturn string|nil The reason the no items were dropped.
|
* @cc.treturn string|nil The reason the no items were dropped.
|
||||||
|
* @cc.since 1.31
|
||||||
* @see #select
|
* @see #select
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -254,6 +262,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @throws LuaException If dropping an invalid number of items.
|
* @throws LuaException If dropping an invalid number of items.
|
||||||
* @cc.treturn boolean Whether items were dropped.
|
* @cc.treturn boolean Whether items were dropped.
|
||||||
* @cc.treturn string|nil The reason the no items were dropped.
|
* @cc.treturn string|nil The reason the no items were dropped.
|
||||||
|
* @cc.since 1.4
|
||||||
* @see #select
|
* @see #select
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -271,6 +280,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @throws LuaException If dropping an invalid number of items.
|
* @throws LuaException If dropping an invalid number of items.
|
||||||
* @cc.treturn boolean Whether items were dropped.
|
* @cc.treturn boolean Whether items were dropped.
|
||||||
* @cc.treturn string|nil The reason the no items were dropped.
|
* @cc.treturn string|nil The reason the no items were dropped.
|
||||||
|
* @cc.since 1.4
|
||||||
* @see #select
|
* @see #select
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -374,6 +384,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
*
|
*
|
||||||
* @return If the block and item are equal.
|
* @return If the block and item are equal.
|
||||||
* @cc.treturn boolean If the block and item are equal.
|
* @cc.treturn boolean If the block and item are equal.
|
||||||
|
* @cc.since 1.31
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult compare()
|
public final MethodResult compare()
|
||||||
@ -386,6 +397,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
*
|
*
|
||||||
* @return If the block and item are equal.
|
* @return If the block and item are equal.
|
||||||
* @cc.treturn boolean If the block and item are equal.
|
* @cc.treturn boolean If the block and item are equal.
|
||||||
|
* @cc.since 1.31
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult compareUp()
|
public final MethodResult compareUp()
|
||||||
@ -398,6 +410,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
*
|
*
|
||||||
* @return If the block and item are equal.
|
* @return If the block and item are equal.
|
||||||
* @cc.treturn boolean If the block and item are equal.
|
* @cc.treturn boolean If the block and item are equal.
|
||||||
|
* @cc.since 1.31
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult compareDown()
|
public final MethodResult compareDown()
|
||||||
@ -412,6 +425,8 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether an entity was attacked.
|
* @cc.treturn boolean Whether an entity was attacked.
|
||||||
* @cc.treturn string|nil The reason nothing was attacked.
|
* @cc.treturn string|nil The reason nothing was attacked.
|
||||||
|
* @cc.since 1.4
|
||||||
|
* @cc.changed 1.6 Added optional side argument.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult attack( Optional<TurtleSide> side )
|
public final MethodResult attack( Optional<TurtleSide> side )
|
||||||
@ -426,6 +441,8 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether an entity was attacked.
|
* @cc.treturn boolean Whether an entity was attacked.
|
||||||
* @cc.treturn string|nil The reason nothing was attacked.
|
* @cc.treturn string|nil The reason nothing was attacked.
|
||||||
|
* @cc.since 1.4
|
||||||
|
* @cc.changed 1.6 Added optional side argument.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult attackUp( Optional<TurtleSide> side )
|
public final MethodResult attackUp( Optional<TurtleSide> side )
|
||||||
@ -440,6 +457,8 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether an entity was attacked.
|
* @cc.treturn boolean Whether an entity was attacked.
|
||||||
* @cc.treturn string|nil The reason nothing was attacked.
|
* @cc.treturn string|nil The reason nothing was attacked.
|
||||||
|
* @cc.since 1.4
|
||||||
|
* @cc.changed 1.6 Added optional side argument.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult attackDown( Optional<TurtleSide> side )
|
public final MethodResult attackDown( Optional<TurtleSide> side )
|
||||||
@ -457,6 +476,8 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @throws LuaException If given an invalid number of items.
|
* @throws LuaException If given an invalid number of items.
|
||||||
* @cc.treturn boolean Whether items were picked up.
|
* @cc.treturn boolean Whether items were picked up.
|
||||||
* @cc.treturn string|nil The reason the no items were picked up.
|
* @cc.treturn string|nil The reason the no items were picked up.
|
||||||
|
* @cc.since 1.4
|
||||||
|
* @cc.changed 1.6 Added an optional limit argument.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult suck( Optional<Integer> count ) throws LuaException
|
public final MethodResult suck( Optional<Integer> count ) throws LuaException
|
||||||
@ -472,6 +493,8 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @throws LuaException If given an invalid number of items.
|
* @throws LuaException If given an invalid number of items.
|
||||||
* @cc.treturn boolean Whether items were picked up.
|
* @cc.treturn boolean Whether items were picked up.
|
||||||
* @cc.treturn string|nil The reason the no items were picked up.
|
* @cc.treturn string|nil The reason the no items were picked up.
|
||||||
|
* @cc.since 1.4
|
||||||
|
* @cc.changed 1.6 Added an optional limit argument.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult suckUp( Optional<Integer> count ) throws LuaException
|
public final MethodResult suckUp( Optional<Integer> count ) throws LuaException
|
||||||
@ -487,6 +510,8 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @throws LuaException If given an invalid number of items.
|
* @throws LuaException If given an invalid number of items.
|
||||||
* @cc.treturn boolean Whether items were picked up.
|
* @cc.treturn boolean Whether items were picked up.
|
||||||
* @cc.treturn string|nil The reason the no items were picked up.
|
* @cc.treturn string|nil The reason the no items were picked up.
|
||||||
|
* @cc.since 1.4
|
||||||
|
* @cc.changed 1.6 Added an optional limit argument.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult suckDown( Optional<Integer> count ) throws LuaException
|
public final MethodResult suckDown( Optional<Integer> count ) throws LuaException
|
||||||
@ -500,6 +525,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The fuel level, or "unlimited".
|
* @return The fuel level, or "unlimited".
|
||||||
* @cc.treturn [1] number The current amount of fuel a turtle this turtle has.
|
* @cc.treturn [1] number The current amount of fuel a turtle this turtle has.
|
||||||
* @cc.treturn [2] "unlimited" If turtles do not consume fuel when moving.
|
* @cc.treturn [2] "unlimited" If turtles do not consume fuel when moving.
|
||||||
|
* @cc.since 1.4
|
||||||
* @see #getFuelLimit()
|
* @see #getFuelLimit()
|
||||||
* @see #refuel(Optional)
|
* @see #refuel(Optional)
|
||||||
*/
|
*/
|
||||||
@ -542,6 +568,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* local is_fuel, reason = turtle.refuel(0)
|
* local is_fuel, reason = turtle.refuel(0)
|
||||||
* if not is_fuel then printError(reason) end
|
* if not is_fuel then printError(reason) end
|
||||||
* }</pre>
|
* }</pre>
|
||||||
|
* @cc.since 1.4
|
||||||
* @see #getFuelLevel()
|
* @see #getFuelLevel()
|
||||||
* @see #getFuelLimit()
|
* @see #getFuelLimit()
|
||||||
*/
|
*/
|
||||||
@ -560,6 +587,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return If the items are the same.
|
* @return If the items are the same.
|
||||||
* @throws LuaException If the slot is out of range.
|
* @throws LuaException If the slot is out of range.
|
||||||
* @cc.treturn boolean If the two items are equal.
|
* @cc.treturn boolean If the two items are equal.
|
||||||
|
* @cc.since 1.4
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult compareTo( int slot ) throws LuaException
|
public final MethodResult compareTo( int slot ) throws LuaException
|
||||||
@ -576,6 +604,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @throws LuaException If the slot is out of range.
|
* @throws LuaException If the slot is out of range.
|
||||||
* @throws LuaException If the number of items is out of range.
|
* @throws LuaException If the number of items is out of range.
|
||||||
* @cc.treturn boolean If some items were successfully moved.
|
* @cc.treturn boolean If some items were successfully moved.
|
||||||
|
* @cc.since 1.45
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult transferTo( int slotArg, Optional<Integer> countArg ) throws LuaException
|
public final MethodResult transferTo( int slotArg, Optional<Integer> countArg ) throws LuaException
|
||||||
@ -589,6 +618,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* Get the currently selected slot.
|
* Get the currently selected slot.
|
||||||
*
|
*
|
||||||
* @return The current slot.
|
* @return The current slot.
|
||||||
|
* @cc.since 1.6
|
||||||
* @see #select
|
* @see #select
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -605,6 +635,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The limit, or "unlimited".
|
* @return The limit, or "unlimited".
|
||||||
* @cc.treturn [1] number The maximum amount of fuel a turtle can hold.
|
* @cc.treturn [1] number The maximum amount of fuel a turtle can hold.
|
||||||
* @cc.treturn [2] "unlimited" If turtles do not consume fuel when moving.
|
* @cc.treturn [2] "unlimited" If turtles do not consume fuel when moving.
|
||||||
|
* @cc.since 1.6
|
||||||
* @see #getFuelLevel()
|
* @see #getFuelLevel()
|
||||||
* @see #refuel(Optional)
|
* @see #refuel(Optional)
|
||||||
*/
|
*/
|
||||||
@ -625,6 +656,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @cc.treturn [1] true If the item was equipped.
|
* @cc.treturn [1] true If the item was equipped.
|
||||||
* @cc.treturn [2] false If we could not equip the item.
|
* @cc.treturn [2] false If we could not equip the item.
|
||||||
* @cc.treturn [2] string The reason equipping this item failed.
|
* @cc.treturn [2] string The reason equipping this item failed.
|
||||||
|
* @cc.since 1.6
|
||||||
* @see #equipRight()
|
* @see #equipRight()
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@ -644,7 +676,8 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @cc.treturn [1] true If the item was equipped.
|
* @cc.treturn [1] true If the item was equipped.
|
||||||
* @cc.treturn [2] false If we could not equip the item.
|
* @cc.treturn [2] false If we could not equip the item.
|
||||||
* @cc.treturn [2] string The reason equipping this item failed.
|
* @cc.treturn [2] string The reason equipping this item failed.
|
||||||
* @see #equipRight()
|
* @cc.since 1.6
|
||||||
|
* @see #equipLeft()
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult equipRight()
|
public final MethodResult equipRight()
|
||||||
@ -658,6 +691,8 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether there is a block in front of the turtle.
|
* @cc.treturn boolean Whether there is a block in front of the turtle.
|
||||||
* @cc.treturn table|string Information about the block in front, or a message explaining that there is no block.
|
* @cc.treturn table|string Information about the block in front, or a message explaining that there is no block.
|
||||||
|
* @cc.since 1.64
|
||||||
|
* @cc.changed 1.76 Added block state to return value.
|
||||||
* @cc.usage <pre>{@code
|
* @cc.usage <pre>{@code
|
||||||
* local has_block, data = turtle.inspect()
|
* local has_block, data = turtle.inspect()
|
||||||
* if has_block then
|
* if has_block then
|
||||||
@ -683,6 +718,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether there is a block above the turtle.
|
* @cc.treturn boolean Whether there is a block above the turtle.
|
||||||
* @cc.treturn table|string Information about the above below, or a message explaining that there is no block.
|
* @cc.treturn table|string Information about the above below, or a message explaining that there is no block.
|
||||||
|
* @cc.since 1.64
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult inspectUp()
|
public final MethodResult inspectUp()
|
||||||
@ -696,6 +732,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The turtle command result.
|
* @return The turtle command result.
|
||||||
* @cc.treturn boolean Whether there is a block below the turtle.
|
* @cc.treturn boolean Whether there is a block below the turtle.
|
||||||
* @cc.treturn table|string Information about the block below, or a message explaining that there is no block.
|
* @cc.treturn table|string Information about the block below, or a message explaining that there is no block.
|
||||||
|
* @cc.since 1.64
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final MethodResult inspectDown()
|
public final MethodResult inspectDown()
|
||||||
@ -713,6 +750,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
* @return The command result.
|
* @return The command result.
|
||||||
* @throws LuaException If the slot is out of range.
|
* @throws LuaException If the slot is out of range.
|
||||||
* @cc.treturn nil|table Information about the given slot, or {@code nil} if it is empty.
|
* @cc.treturn nil|table Information about the given slot, or {@code nil} if it is empty.
|
||||||
|
* @cc.since 1.64
|
||||||
* @cc.usage Print the current slot, assuming it contains 13 dirt.
|
* @cc.usage Print the current slot, assuming it contains 13 dirt.
|
||||||
*
|
*
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.util;
|
||||||
|
|
||||||
|
import net.minecraft.world.Container;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.inventory.Slot;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class InvisibleSlot extends Slot
|
||||||
|
{
|
||||||
|
public InvisibleSlot( Container container, int slot )
|
||||||
|
{
|
||||||
|
super( container, slot, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mayPlace( @Nonnull ItemStack stack )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean mayPickup( @Nonnull Player player )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -123,9 +123,13 @@
|
|||||||
"gui.computercraft.upload.failed.out_of_space": "Not enough space on the computer for these files.",
|
"gui.computercraft.upload.failed.out_of_space": "Not enough space on the computer for these files.",
|
||||||
"gui.computercraft.upload.failed.computer_off": "You must turn the computer on before uploading files.",
|
"gui.computercraft.upload.failed.computer_off": "You must turn the computer on before uploading files.",
|
||||||
"gui.computercraft.upload.failed.too_much": "Your files are too large to be uploaded.",
|
"gui.computercraft.upload.failed.too_much": "Your files are too large to be uploaded.",
|
||||||
|
"gui.computercraft.upload.failed.name_too_long": "File names are too long to be uploaded.",
|
||||||
|
"gui.computercraft.upload.failed.too_many_files": "Cannot upload this many files.",
|
||||||
"gui.computercraft.upload.failed.overwrite_dir": "Cannot upload %s, as there is already a directory with the same name.",
|
"gui.computercraft.upload.failed.overwrite_dir": "Cannot upload %s, as there is already a directory with the same name.",
|
||||||
"computercraft.gui.upload.failed.generic": "Uploading files failed (%s)",
|
"gui.computercraft.upload.failed.generic": "Uploading files failed (%s)",
|
||||||
|
"gui.computercraft.upload.failed.corrupted": "Files corrupted when uploading. Please try again.",
|
||||||
"gui.computercraft.upload.overwrite": "Files would be overwritten",
|
"gui.computercraft.upload.overwrite": "Files would be overwritten",
|
||||||
"gui.computercraft.upload.overwrite.detail": "The following files will be overwritten when uploading. Continue?%s",
|
"gui.computercraft.upload.overwrite.detail": "The following files will be overwritten when uploading. Continue?%s",
|
||||||
"gui.computercraft.upload.overwrite_button": "Overwrite"
|
"gui.computercraft.upload.overwrite_button": "Overwrite",
|
||||||
|
"gui.computercraft.pocket_computer_overlay": "Pocket computer open. Press ESC to close."
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@
|
|||||||
"gui.computercraft.upload.failed.out_of_space": "これらのファイルに必要なスペースがコンピュータ上にありません。",
|
"gui.computercraft.upload.failed.out_of_space": "これらのファイルに必要なスペースがコンピュータ上にありません。",
|
||||||
"gui.computercraft.upload.failed.too_much": "アップロードするにはファイルが大きスギます。",
|
"gui.computercraft.upload.failed.too_much": "アップロードするにはファイルが大きスギます。",
|
||||||
"gui.computercraft.upload.failed.overwrite_dir": "同じ名前のディレクトリがすでにあるため、%s をアップロードできません。",
|
"gui.computercraft.upload.failed.overwrite_dir": "同じ名前のディレクトリがすでにあるため、%s をアップロードできません。",
|
||||||
"computercraft.gui.upload.failed.generic": "ファイルのアップロードに失敗しました(%s)",
|
"gui.computercraft.upload.failed.generic": "ファイルのアップロードに失敗しました(%s)",
|
||||||
"gui.computercraft.upload.overwrite": "ファイルは上書きされます",
|
"gui.computercraft.upload.overwrite": "ファイルは上書きされます",
|
||||||
"gui.computercraft.upload.overwrite_button": "上書き",
|
"gui.computercraft.upload.overwrite_button": "上書き",
|
||||||
"block.computercraft.wireless_modem_normal": "無線モデム",
|
"block.computercraft.wireless_modem_normal": "無線モデム",
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
"gui.computercraft.upload.failed.computer_off": "Ты должен включить компьютер перед загрузой файлов.",
|
"gui.computercraft.upload.failed.computer_off": "Ты должен включить компьютер перед загрузой файлов.",
|
||||||
"gui.computercraft.upload.failed.too_much": "Твои файлы слишком большие для загрузки.",
|
"gui.computercraft.upload.failed.too_much": "Твои файлы слишком большие для загрузки.",
|
||||||
"gui.computercraft.upload.failed.overwrite_dir": "Нельзя загрузить %s, поскольку папка с таким же названием уже существует.",
|
"gui.computercraft.upload.failed.overwrite_dir": "Нельзя загрузить %s, поскольку папка с таким же названием уже существует.",
|
||||||
"computercraft.gui.upload.failed.generic": "Загрузка файлов не удалась (%s)",
|
"gui.computercraft.upload.failed.generic": "Загрузка файлов не удалась (%s)",
|
||||||
"gui.computercraft.upload.overwrite": "Файлы будут перезаписаны",
|
"gui.computercraft.upload.overwrite": "Файлы будут перезаписаны",
|
||||||
"gui.computercraft.upload.overwrite.detail": "При загрузке следующие файлы будут перезаписаны. Продолжить?%s",
|
"gui.computercraft.upload.overwrite.detail": "При загрузке следующие файлы будут перезаписаны. Продолжить?%s",
|
||||||
"gui.computercraft.upload.overwrite_button": "Перезаписать"
|
"gui.computercraft.upload.overwrite_button": "Перезаписать"
|
||||||
|
@ -204,6 +204,7 @@ black = 0x8000
|
|||||||
--
|
--
|
||||||
-- @tparam number ... The colors to combine.
|
-- @tparam number ... The colors to combine.
|
||||||
-- @treturn number The union of the color sets given in `...`
|
-- @treturn number The union of the color sets given in `...`
|
||||||
|
-- @since 1.2
|
||||||
-- @usage
|
-- @usage
|
||||||
-- ```lua
|
-- ```lua
|
||||||
-- colors.combine(colors.white, colors.magenta, colours.lightBlue)
|
-- colors.combine(colors.white, colors.magenta, colours.lightBlue)
|
||||||
@ -229,6 +230,7 @@ end
|
|||||||
-- @tparam number colors The color from which to subtract.
|
-- @tparam number colors The color from which to subtract.
|
||||||
-- @tparam number ... The colors to subtract.
|
-- @tparam number ... The colors to subtract.
|
||||||
-- @treturn number The resulting color.
|
-- @treturn number The resulting color.
|
||||||
|
-- @since 1.2
|
||||||
-- @usage
|
-- @usage
|
||||||
-- ```lua
|
-- ```lua
|
||||||
-- colours.subtract(colours.lime, colours.orange, colours.white)
|
-- colours.subtract(colours.lime, colours.orange, colours.white)
|
||||||
@ -251,6 +253,7 @@ end
|
|||||||
-- @tparam number colors A color, or color set
|
-- @tparam number colors A color, or color set
|
||||||
-- @tparam number color A color or set of colors that `colors` should contain.
|
-- @tparam number color A color or set of colors that `colors` should contain.
|
||||||
-- @treturn boolean If `colors` contains all colors within `color`.
|
-- @treturn boolean If `colors` contains all colors within `color`.
|
||||||
|
-- @since 1.2
|
||||||
-- @usage
|
-- @usage
|
||||||
-- ```lua
|
-- ```lua
|
||||||
-- colors.test(colors.combine(colors.white, colors.magenta, colours.lightBlue), colors.lightBlue)
|
-- colors.test(colors.combine(colors.white, colors.magenta, colours.lightBlue), colors.lightBlue)
|
||||||
@ -273,6 +276,7 @@ end
|
|||||||
-- colors.packRGB(0.7, 0.2, 0.6)
|
-- colors.packRGB(0.7, 0.2, 0.6)
|
||||||
-- -- => 0xb23399
|
-- -- => 0xb23399
|
||||||
-- ```
|
-- ```
|
||||||
|
-- @since 1.81.0
|
||||||
function packRGB(r, g, b)
|
function packRGB(r, g, b)
|
||||||
expect(1, r, "number")
|
expect(1, r, "number")
|
||||||
expect(2, g, "number")
|
expect(2, g, "number")
|
||||||
@ -295,6 +299,7 @@ end
|
|||||||
-- -- => 0.7, 0.2, 0.6
|
-- -- => 0.7, 0.2, 0.6
|
||||||
-- ```
|
-- ```
|
||||||
-- @see colors.packRGB
|
-- @see colors.packRGB
|
||||||
|
-- @since 1.81.0
|
||||||
function unpackRGB(rgb)
|
function unpackRGB(rgb)
|
||||||
expect(1, rgb, "number")
|
expect(1, rgb, "number")
|
||||||
return
|
return
|
||||||
@ -325,6 +330,8 @@ end
|
|||||||
-- colors.rgb8(0.7, 0.2, 0.6)
|
-- colors.rgb8(0.7, 0.2, 0.6)
|
||||||
-- -- => 0xb23399
|
-- -- => 0xb23399
|
||||||
-- ```
|
-- ```
|
||||||
|
-- @since 1.80pr1
|
||||||
|
-- @changed 1.81.0 Deprecated in favor of colors.(un)packRGB.
|
||||||
function rgb8(r, g, b)
|
function rgb8(r, g, b)
|
||||||
if g == nil and b == nil then
|
if g == nil and b == nil then
|
||||||
return unpackRGB(r)
|
return unpackRGB(r)
|
||||||
@ -345,6 +352,7 @@ end
|
|||||||
--
|
--
|
||||||
-- @tparam number color The color to convert.
|
-- @tparam number color The color to convert.
|
||||||
-- @treturn string The blit hex code of the color.
|
-- @treturn string The blit hex code of the color.
|
||||||
|
-- @since 1.94.0
|
||||||
function toBlit(color)
|
function toBlit(color)
|
||||||
expect(1, color, "number")
|
expect(1, color, "number")
|
||||||
return color_hex_lookup[color] or
|
return color_hex_lookup[color] or
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
--
|
--
|
||||||
-- @see colors
|
-- @see colors
|
||||||
-- @module colours
|
-- @module colours
|
||||||
|
-- @since 1.2
|
||||||
|
|
||||||
local colours = _ENV
|
local colours = _ENV
|
||||||
for k, v in pairs(colors) do
|
for k, v in pairs(colors) do
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
-- like a disk.
|
-- like a disk.
|
||||||
--
|
--
|
||||||
-- @module disk
|
-- @module disk
|
||||||
|
-- @since 1.2
|
||||||
|
|
||||||
local function isDrive(name)
|
local function isDrive(name)
|
||||||
if type(name) ~= "string" then
|
if type(name) ~= "string" then
|
||||||
@ -163,6 +164,7 @@ end
|
|||||||
--
|
--
|
||||||
-- @tparam string name The name of the disk drive.
|
-- @tparam string name The name of the disk drive.
|
||||||
-- @treturn string|nil The disk ID, or `nil` if the drive does not contain a floppy disk.
|
-- @treturn string|nil The disk ID, or `nil` if the drive does not contain a floppy disk.
|
||||||
|
-- @since 1.4
|
||||||
function getID(name)
|
function getID(name)
|
||||||
if isDrive(name) then
|
if isDrive(name) then
|
||||||
return peripheral.call(name, "getDiskID")
|
return peripheral.call(name, "getDiskID")
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
-- [1]: http://www.computercraft.info/forums2/index.php?/topic/3088-how-to-guide-gps-global-position-system/
|
-- [1]: http://www.computercraft.info/forums2/index.php?/topic/3088-how-to-guide-gps-global-position-system/
|
||||||
--
|
--
|
||||||
-- @module gps
|
-- @module gps
|
||||||
|
-- @since 1.31
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
--- Provides an API to read help files.
|
--- Provides an API to read help files.
|
||||||
--
|
--
|
||||||
-- @module help
|
-- @module help
|
||||||
|
-- @since 1.2
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||||
|
|
||||||
@ -35,6 +36,8 @@ local extensions = { "", ".md", ".txt" }
|
|||||||
-- @treturn string|nil The path to the given topic's help file, or `nil` if it
|
-- @treturn string|nil The path to the given topic's help file, or `nil` if it
|
||||||
-- cannot be found.
|
-- cannot be found.
|
||||||
-- @usage help.lookup("disk")
|
-- @usage help.lookup("disk")
|
||||||
|
-- @changed 1.80pr1 Now supports finding .txt files.
|
||||||
|
-- @changed 1.97.0 Now supports finding Markdown files.
|
||||||
function lookup(topic)
|
function lookup(topic)
|
||||||
expect(1, topic, "string")
|
expect(1, topic, "string")
|
||||||
-- Look on the path variable
|
-- Look on the path variable
|
||||||
@ -96,6 +99,7 @@ end
|
|||||||
--
|
--
|
||||||
-- @tparam string prefix The prefix to match
|
-- @tparam string prefix The prefix to match
|
||||||
-- @treturn table A list of matching topics.
|
-- @treturn table A list of matching topics.
|
||||||
|
-- @since 1.74
|
||||||
function completeTopic(sText)
|
function completeTopic(sText)
|
||||||
expect(1, sText, "string")
|
expect(1, sText, "string")
|
||||||
local tTopics = topics()
|
local tTopics = topics()
|
||||||
|
@ -65,6 +65,30 @@ handleMetatable = {
|
|||||||
return true
|
return true
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
--[[- Returns an iterator that, each time it is called, returns a new
|
||||||
|
line from the file.
|
||||||
|
|
||||||
|
This can be used in a for loop to iterate over all lines of a file
|
||||||
|
|
||||||
|
Once the end of the file has been reached, @{nil} will be returned. The file is
|
||||||
|
*not* automatically closed.
|
||||||
|
|
||||||
|
@param ... The argument to pass to @{Handle:read} for each line.
|
||||||
|
@treturn function():string|nil The line iterator.
|
||||||
|
@throws If the file cannot be opened for reading
|
||||||
|
@since 1.3
|
||||||
|
|
||||||
|
@see io.lines
|
||||||
|
@usage Iterate over every line in a file and print it out.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local file = io.open("/rom/help/intro.txt")
|
||||||
|
for line in file:lines() do
|
||||||
|
print(line)
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
```
|
||||||
|
]]
|
||||||
lines = function(self, ...)
|
lines = function(self, ...)
|
||||||
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||||
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
||||||
@ -81,6 +105,23 @@ handleMetatable = {
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
--[[- Reads data from the file, using the specified formats. For each
|
||||||
|
format provided, the function returns either the data read, or `nil` if
|
||||||
|
no data could be read.
|
||||||
|
|
||||||
|
The following formats are available:
|
||||||
|
- `l`: Returns the next line (without a newline on the end).
|
||||||
|
- `L`: Returns the next line (with a newline on the end).
|
||||||
|
- `a`: Returns the entire rest of the file.
|
||||||
|
- ~~`n`: Returns a number~~ (not implemented in CC).
|
||||||
|
|
||||||
|
These formats can be preceded by a `*` to make it compatible with Lua 5.1.
|
||||||
|
|
||||||
|
If no format is provided, `l` is assumed.
|
||||||
|
|
||||||
|
@param ... The formats to use.
|
||||||
|
@treturn (string|nil)... The data read from the file.
|
||||||
|
]]
|
||||||
read = function(self, ...)
|
read = function(self, ...)
|
||||||
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||||
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
||||||
@ -124,6 +165,23 @@ handleMetatable = {
|
|||||||
return table.unpack(output, 1, n)
|
return table.unpack(output, 1, n)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
--[[- Seeks the file cursor to the specified position, and returns the
|
||||||
|
new position.
|
||||||
|
|
||||||
|
`whence` controls where the seek operation starts, and is a string that
|
||||||
|
may be one of these three values:
|
||||||
|
- `set`: base position is 0 (beginning of the file)
|
||||||
|
- `cur`: base is current position
|
||||||
|
- `end`: base is end of file
|
||||||
|
|
||||||
|
The default value of `whence` is `cur`, and the default value of `offset`
|
||||||
|
is 0. This means that `file:seek()` without arguments returns the current
|
||||||
|
position without moving.
|
||||||
|
|
||||||
|
@tparam[opt] string whence The place to set the cursor from.
|
||||||
|
@tparam[opt] number offset The offset from the start to move to.
|
||||||
|
@treturn number The new location of the file cursor.
|
||||||
|
]]
|
||||||
seek = function(self, whence, offset)
|
seek = function(self, whence, offset)
|
||||||
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||||
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
||||||
@ -154,6 +212,7 @@ handleMetatable = {
|
|||||||
-- @treturn[1] Handle The current file, allowing chained calls.
|
-- @treturn[1] Handle The current file, allowing chained calls.
|
||||||
-- @treturn[2] nil If the file could not be written to.
|
-- @treturn[2] nil If the file could not be written to.
|
||||||
-- @treturn[2] string The error message which occurred while writing.
|
-- @treturn[2] string The error message which occurred while writing.
|
||||||
|
-- @changed 1.81.0 Multiple arguments are now allowed.
|
||||||
write = function(self, ...)
|
write = function(self, ...)
|
||||||
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
if type_of(self) ~= "table" or getmetatable(self) ~= handleMetatable then
|
||||||
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
error("bad argument #1 (FILE expected, got " .. type_of(self) .. ")", 2)
|
||||||
@ -217,6 +276,7 @@ stderr = defaultError
|
|||||||
--
|
--
|
||||||
-- @see Handle:close
|
-- @see Handle:close
|
||||||
-- @see io.output
|
-- @see io.output
|
||||||
|
-- @since 1.55
|
||||||
function close(file)
|
function close(file)
|
||||||
if file == nil then return currentOutput:close() end
|
if file == nil then return currentOutput:close() end
|
||||||
|
|
||||||
@ -230,6 +290,7 @@ end
|
|||||||
--
|
--
|
||||||
-- @see Handle:flush
|
-- @see Handle:flush
|
||||||
-- @see io.output
|
-- @see io.output
|
||||||
|
-- @since 1.55
|
||||||
function flush()
|
function flush()
|
||||||
return currentOutput:flush()
|
return currentOutput:flush()
|
||||||
end
|
end
|
||||||
@ -239,6 +300,7 @@ end
|
|||||||
-- @tparam[opt] Handle|string file The new input file, either as a file path or pre-existing handle.
|
-- @tparam[opt] Handle|string file The new input file, either as a file path or pre-existing handle.
|
||||||
-- @treturn Handle The current input file.
|
-- @treturn Handle The current input file.
|
||||||
-- @throws If the provided filename cannot be opened for reading.
|
-- @throws If the provided filename cannot be opened for reading.
|
||||||
|
-- @since 1.55
|
||||||
function input(file)
|
function input(file)
|
||||||
if type_of(file) == "string" then
|
if type_of(file) == "string" then
|
||||||
local res, err = open(file, "rb")
|
local res, err = open(file, "rb")
|
||||||
@ -271,6 +333,7 @@ In this case, the handle is not used.
|
|||||||
|
|
||||||
@see Handle:lines
|
@see Handle:lines
|
||||||
@see io.input
|
@see io.input
|
||||||
|
@since 1.55
|
||||||
@usage Iterate over every line in a file and print it out.
|
@usage Iterate over every line in a file and print it out.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
@ -326,6 +389,7 @@ end
|
|||||||
-- @tparam[opt] Handle|string file The new output file, either as a file path or pre-existing handle.
|
-- @tparam[opt] Handle|string file The new output file, either as a file path or pre-existing handle.
|
||||||
-- @treturn Handle The current output file.
|
-- @treturn Handle The current output file.
|
||||||
-- @throws If the provided filename cannot be opened for writing.
|
-- @throws If the provided filename cannot be opened for writing.
|
||||||
|
-- @since 1.55
|
||||||
function output(file)
|
function output(file)
|
||||||
if type_of(file) == "string" then
|
if type_of(file) == "string" then
|
||||||
local res, err = open(file, "wb")
|
local res, err = open(file, "wb")
|
||||||
@ -374,6 +438,7 @@ end
|
|||||||
-- documentation} there for full details.
|
-- documentation} there for full details.
|
||||||
--
|
--
|
||||||
-- @tparam string ... The strings to write
|
-- @tparam string ... The strings to write
|
||||||
|
-- @changed 1.81.0 Multiple arguments are now allowed.
|
||||||
function write(...)
|
function write(...)
|
||||||
return currentOutput:write(...)
|
return currentOutput:write(...)
|
||||||
end
|
end
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
-- the underlying numerical values.
|
-- the underlying numerical values.
|
||||||
--
|
--
|
||||||
-- @module keys
|
-- @module keys
|
||||||
|
-- @since 1.4
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ tKeys[269] = 'end'
|
|||||||
tKeys[280] = 'capsLock'
|
tKeys[280] = 'capsLock'
|
||||||
tKeys[281] = 'scrollLock'
|
tKeys[281] = 'scrollLock'
|
||||||
tKeys[282] = 'numLock'
|
tKeys[282] = 'numLock'
|
||||||
-- tKeys[283] = 'printScreen'
|
tKeys[283] = 'printScreen'
|
||||||
tKeys[284] = 'pause'
|
tKeys[284] = 'pause'
|
||||||
tKeys[290] = 'f1'
|
tKeys[290] = 'f1'
|
||||||
tKeys[291] = 'f2'
|
tKeys[291] = 'f2'
|
||||||
@ -115,7 +116,7 @@ tKeys[328] = 'numPad8'
|
|||||||
tKeys[329] = 'numPad9'
|
tKeys[329] = 'numPad9'
|
||||||
tKeys[330] = 'numPadDecimal'
|
tKeys[330] = 'numPadDecimal'
|
||||||
tKeys[331] = 'numPadDivide'
|
tKeys[331] = 'numPadDivide'
|
||||||
-- tKeys[332] = 'numPadMultiply'
|
tKeys[332] = 'numPadMultiply'
|
||||||
tKeys[333] = 'numPadSubtract'
|
tKeys[333] = 'numPadSubtract'
|
||||||
tKeys[334] = 'numPadAdd'
|
tKeys[334] = 'numPadAdd'
|
||||||
tKeys[335] = 'numPadEnter'
|
tKeys[335] = 'numPadEnter'
|
||||||
@ -123,12 +124,12 @@ tKeys[336] = 'numPadEqual'
|
|||||||
tKeys[340] = 'leftShift'
|
tKeys[340] = 'leftShift'
|
||||||
tKeys[341] = 'leftCtrl'
|
tKeys[341] = 'leftCtrl'
|
||||||
tKeys[342] = 'leftAlt'
|
tKeys[342] = 'leftAlt'
|
||||||
-- tKeys[343] = 'leftSuper'
|
tKeys[343] = 'leftSuper'
|
||||||
tKeys[344] = 'rightShift'
|
tKeys[344] = 'rightShift'
|
||||||
tKeys[345] = 'rightCtrl'
|
tKeys[345] = 'rightCtrl'
|
||||||
tKeys[346] = 'rightAlt'
|
tKeys[346] = 'rightAlt'
|
||||||
-- tKeys[347] = 'rightSuper'
|
-- tKeys[347] = 'rightSuper'
|
||||||
-- tKeys[348] = 'menu'
|
tKeys[348] = 'menu'
|
||||||
|
|
||||||
local keys = _ENV
|
local keys = _ENV
|
||||||
for nKey, sKey in pairs(tKeys) do
|
for nKey, sKey in pairs(tKeys) do
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
-- image files. You can use the `colors` API for easier color manipulation.
|
-- image files. You can use the `colors` API for easier color manipulation.
|
||||||
--
|
--
|
||||||
-- @module paintutils
|
-- @module paintutils
|
||||||
|
-- @since 1.45
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||||
|
|
||||||
@ -47,6 +48,7 @@ end
|
|||||||
-- @tparam string image The string containing the raw-image data.
|
-- @tparam string image The string containing the raw-image data.
|
||||||
-- @treturn table The parsed image data, suitable for use with
|
-- @treturn table The parsed image data, suitable for use with
|
||||||
-- @{paintutils.drawImage}.
|
-- @{paintutils.drawImage}.
|
||||||
|
-- @since 1.80pr1
|
||||||
function parseImage(image)
|
function parseImage(image)
|
||||||
expect(1, image, "string")
|
expect(1, image, "string")
|
||||||
local tImage = {}
|
local tImage = {}
|
||||||
|
@ -13,6 +13,7 @@ etc) can safely be used in one without affecting the event queue accessed by
|
|||||||
the other.
|
the other.
|
||||||
|
|
||||||
@module parallel
|
@module parallel
|
||||||
|
@since 1.2
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local function create(...)
|
local function create(...)
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
-- determine where given messages should be sent in the first place.
|
-- determine where given messages should be sent in the first place.
|
||||||
--
|
--
|
||||||
-- @module rednet
|
-- @module rednet
|
||||||
|
-- @since 1.2
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||||
|
|
||||||
@ -80,6 +81,7 @@ end
|
|||||||
-- @tparam[opt] string modem Which modem to check. If not given, all connected
|
-- @tparam[opt] string modem Which modem to check. If not given, all connected
|
||||||
-- modems will be checked.
|
-- modems will be checked.
|
||||||
-- @treturn boolean If the given modem is open.
|
-- @treturn boolean If the given modem is open.
|
||||||
|
-- @since 1.31
|
||||||
function isOpen(modem)
|
function isOpen(modem)
|
||||||
expect(1, modem, "string", "nil")
|
expect(1, modem, "string", "nil")
|
||||||
if modem then
|
if modem then
|
||||||
@ -114,6 +116,8 @@ particular protocol.
|
|||||||
@treturn boolean If this message was successfully sent (i.e. if rednet is
|
@treturn boolean If this message was successfully sent (i.e. if rednet is
|
||||||
currently @{rednet.open|open}). Note, this does not guarantee the message was
|
currently @{rednet.open|open}). Note, this does not guarantee the message was
|
||||||
actually _received_.
|
actually _received_.
|
||||||
|
@changed 1.6 Added protocol parameter.
|
||||||
|
@changed 1.82.0 Now returns whether the message was successfully sent.
|
||||||
@see rednet.receive
|
@see rednet.receive
|
||||||
@usage Send a message to computer #2.
|
@usage Send a message to computer #2.
|
||||||
|
|
||||||
@ -166,6 +170,7 @@ end
|
|||||||
-- using @{rednet.receive} one can filter to only receive messages sent under a
|
-- using @{rednet.receive} one can filter to only receive messages sent under a
|
||||||
-- particular protocol.
|
-- particular protocol.
|
||||||
-- @see rednet.receive
|
-- @see rednet.receive
|
||||||
|
-- @changed 1.6 Added protocol parameter.
|
||||||
function broadcast(message, sProtocol)
|
function broadcast(message, sProtocol)
|
||||||
expect(2, sProtocol, "string", "nil")
|
expect(2, sProtocol, "string", "nil")
|
||||||
send(CHANNEL_BROADCAST, message, sProtocol)
|
send(CHANNEL_BROADCAST, message, sProtocol)
|
||||||
@ -185,6 +190,7 @@ received.
|
|||||||
@treturn[2] nil If the timeout elapsed and no message was received.
|
@treturn[2] nil If the timeout elapsed and no message was received.
|
||||||
@see rednet.broadcast
|
@see rednet.broadcast
|
||||||
@see rednet.send
|
@see rednet.send
|
||||||
|
@changed 1.6 Added protocol filter parameter.
|
||||||
@usage Receive a rednet message.
|
@usage Receive a rednet message.
|
||||||
|
|
||||||
local id, message = rednet.receive()
|
local id, message = rednet.receive()
|
||||||
@ -262,6 +268,7 @@ end
|
|||||||
-- @throws If trying to register a hostname which is reserved, or currently in use.
|
-- @throws If trying to register a hostname which is reserved, or currently in use.
|
||||||
-- @see rednet.unhost
|
-- @see rednet.unhost
|
||||||
-- @see rednet.lookup
|
-- @see rednet.lookup
|
||||||
|
-- @since 1.6
|
||||||
function host(sProtocol, sHostname)
|
function host(sProtocol, sHostname)
|
||||||
expect(1, sProtocol, "string")
|
expect(1, sProtocol, "string")
|
||||||
expect(2, sHostname, "string")
|
expect(2, sHostname, "string")
|
||||||
@ -280,6 +287,7 @@ end
|
|||||||
-- respond to @{rednet.lookup} requests.
|
-- respond to @{rednet.lookup} requests.
|
||||||
--
|
--
|
||||||
-- @tparam string sProtocol The protocol to unregister your self from.
|
-- @tparam string sProtocol The protocol to unregister your self from.
|
||||||
|
-- @since 1.6
|
||||||
function unhost(sProtocol)
|
function unhost(sProtocol)
|
||||||
expect(1, sProtocol, "string")
|
expect(1, sProtocol, "string")
|
||||||
tHostnames[sProtocol] = nil
|
tHostnames[sProtocol] = nil
|
||||||
@ -299,6 +307,7 @@ end
|
|||||||
-- protocol, or @{nil} if none exist.
|
-- protocol, or @{nil} if none exist.
|
||||||
-- @treturn[2] number|nil The computer ID with the provided hostname and protocol,
|
-- @treturn[2] number|nil The computer ID with the provided hostname and protocol,
|
||||||
-- or @{nil} if none exists.
|
-- or @{nil} if none exists.
|
||||||
|
-- @since 1.6
|
||||||
function lookup(sProtocol, sHostname)
|
function lookup(sProtocol, sHostname)
|
||||||
expect(1, sProtocol, "string")
|
expect(1, sProtocol, "string")
|
||||||
expect(2, sHostname, "string", "nil")
|
expect(2, sHostname, "string", "nil")
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
-- `/.settings` file. One can then use @{settings.save} to update the file.
|
-- `/.settings` file. One can then use @{settings.save} to update the file.
|
||||||
--
|
--
|
||||||
-- @module settings
|
-- @module settings
|
||||||
|
-- @since 1.78
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua")
|
local expect = dofile("rom/modules/main/cc/expect.lua")
|
||||||
local type, expect, field = type, expect.expect, expect.field
|
local type, expect, field = type, expect.expect, expect.field
|
||||||
@ -40,6 +41,7 @@ for _, v in ipairs(valid_types) do valid_types[v] = true end
|
|||||||
-- setting has not been changed.
|
-- setting has not been changed.
|
||||||
-- - `type`: Require values to be of this type. @{set|Setting} the value to another type
|
-- - `type`: Require values to be of this type. @{set|Setting} the value to another type
|
||||||
-- will error.
|
-- will error.
|
||||||
|
-- @since 1.87.0
|
||||||
function define(name, options)
|
function define(name, options)
|
||||||
expect(1, name, "string")
|
expect(1, name, "string")
|
||||||
expect(2, options, "table", "nil")
|
expect(2, options, "table", "nil")
|
||||||
@ -67,6 +69,7 @@ end
|
|||||||
-- for that.
|
-- for that.
|
||||||
--
|
--
|
||||||
-- @tparam string name The name of this option
|
-- @tparam string name The name of this option
|
||||||
|
-- @since 1.87.0
|
||||||
function undefine(name)
|
function undefine(name)
|
||||||
expect(1, name, "string")
|
expect(1, name, "string")
|
||||||
details[name] = nil
|
details[name] = nil
|
||||||
@ -111,6 +114,7 @@ end
|
|||||||
-- this setting. If not given, it will use the setting's default value if given,
|
-- this setting. If not given, it will use the setting's default value if given,
|
||||||
-- or `nil` otherwise.
|
-- or `nil` otherwise.
|
||||||
-- @return The setting's, or the default if the setting has not been changed.
|
-- @return The setting's, or the default if the setting has not been changed.
|
||||||
|
-- @changed 1.87.0 Now respects default value if pre-defined and `default` is unset.
|
||||||
function get(name, default)
|
function get(name, default)
|
||||||
expect(1, name, "string")
|
expect(1, name, "string")
|
||||||
local result = values[name]
|
local result = values[name]
|
||||||
@ -130,6 +134,7 @@ end
|
|||||||
-- @treturn { description? = string, default? = any, type? = string, value? = any }
|
-- @treturn { description? = string, default? = any, type? = string, value? = any }
|
||||||
-- Information about this setting. This includes all information from @{settings.define},
|
-- Information about this setting. This includes all information from @{settings.define},
|
||||||
-- as well as this setting's value.
|
-- as well as this setting's value.
|
||||||
|
-- @since 1.87.0
|
||||||
function getDetails(name)
|
function getDetails(name)
|
||||||
expect(1, name, "string")
|
expect(1, name, "string")
|
||||||
local deets = copy(details[name]) or {}
|
local deets = copy(details[name]) or {}
|
||||||
@ -189,6 +194,7 @@ end
|
|||||||
-- corrupted.
|
-- corrupted.
|
||||||
--
|
--
|
||||||
-- @see settings.save
|
-- @see settings.save
|
||||||
|
-- @changed 1.87.0 `sPath` is now optional.
|
||||||
function load(sPath)
|
function load(sPath)
|
||||||
expect(1, sPath, "string", "nil")
|
expect(1, sPath, "string", "nil")
|
||||||
local file = fs.open(sPath or ".settings", "r")
|
local file = fs.open(sPath or ".settings", "r")
|
||||||
@ -226,6 +232,7 @@ end
|
|||||||
-- @treturn boolean If the settings were successfully saved.
|
-- @treturn boolean If the settings were successfully saved.
|
||||||
--
|
--
|
||||||
-- @see settings.load
|
-- @see settings.load
|
||||||
|
-- @changed 1.87.0 `sPath` is now optional.
|
||||||
function save(sPath)
|
function save(sPath)
|
||||||
expect(1, sPath, "string", "nil")
|
expect(1, sPath, "string", "nil")
|
||||||
local file = fs.open(sPath or ".settings", "w")
|
local file = fs.open(sPath or ".settings", "w")
|
||||||
|
@ -31,6 +31,7 @@ local term = _ENV
|
|||||||
-- @tparam Redirect target The terminal redirect the @{term} API will draw to.
|
-- @tparam Redirect target The terminal redirect the @{term} API will draw to.
|
||||||
-- @treturn Redirect The previous redirect object, as returned by
|
-- @treturn Redirect The previous redirect object, as returned by
|
||||||
-- @{term.current}.
|
-- @{term.current}.
|
||||||
|
-- @since 1.31
|
||||||
-- @usage
|
-- @usage
|
||||||
-- Redirect to a monitor on the right of the computer.
|
-- Redirect to a monitor on the right of the computer.
|
||||||
-- term.redirect(peripheral.wrap("right"))
|
-- term.redirect(peripheral.wrap("right"))
|
||||||
@ -56,6 +57,7 @@ end
|
|||||||
--- Returns the current terminal object of the computer.
|
--- Returns the current terminal object of the computer.
|
||||||
--
|
--
|
||||||
-- @treturn Redirect The current terminal redirect
|
-- @treturn Redirect The current terminal redirect
|
||||||
|
-- @since 1.6
|
||||||
-- @usage
|
-- @usage
|
||||||
-- Create a new @{window} which draws to the current redirect target
|
-- Create a new @{window} which draws to the current redirect target
|
||||||
-- window.create(term.current(), 1, 1, 10, 10)
|
-- window.create(term.current(), 1, 1, 10, 10)
|
||||||
@ -70,6 +72,7 @@ end
|
|||||||
-- terminal object, and so drawing may interfere with other programs.
|
-- terminal object, and so drawing may interfere with other programs.
|
||||||
--
|
--
|
||||||
-- @treturn Redirect The native terminal redirect.
|
-- @treturn Redirect The native terminal redirect.
|
||||||
|
-- @since 1.6
|
||||||
term.native = function()
|
term.native = function()
|
||||||
return native
|
return native
|
||||||
end
|
end
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
-- manipulating strings.
|
-- manipulating strings.
|
||||||
--
|
--
|
||||||
-- @module textutils
|
-- @module textutils
|
||||||
|
-- @since 1.2
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua")
|
local expect = dofile("rom/modules/main/cc/expect.lua")
|
||||||
local expect, field = expect.expect, expect.field
|
local expect, field = expect.expect, expect.field
|
||||||
@ -17,6 +18,7 @@ local wrap = dofile("rom/modules/main/cc/strings.lua").wrap
|
|||||||
-- Defaults to 20.
|
-- Defaults to 20.
|
||||||
-- @usage textutils.slowWrite("Hello, world!")
|
-- @usage textutils.slowWrite("Hello, world!")
|
||||||
-- @usage textutils.slowWrite("Hello, world!", 5)
|
-- @usage textutils.slowWrite("Hello, world!", 5)
|
||||||
|
-- @since 1.3
|
||||||
function slowWrite(text, rate)
|
function slowWrite(text, rate)
|
||||||
expect(2, rate, "number", "nil")
|
expect(2, rate, "number", "nil")
|
||||||
rate = rate or 20
|
rate = rate or 20
|
||||||
@ -55,7 +57,12 @@ end
|
|||||||
-- @tparam[opt] boolean bTwentyFourHour Whether to format this as a 24-hour
|
-- @tparam[opt] boolean bTwentyFourHour Whether to format this as a 24-hour
|
||||||
-- clock (`18:30`) rather than a 12-hour one (`6:30 AM`)
|
-- clock (`18:30`) rather than a 12-hour one (`6:30 AM`)
|
||||||
-- @treturn string The formatted time
|
-- @treturn string The formatted time
|
||||||
-- @usage textutils.formatTime(os.time())
|
-- @usage Print the current in-game time as a 12-hour clock.
|
||||||
|
--
|
||||||
|
-- textutils.formatTime(os.time())
|
||||||
|
-- @usage Print the local time as a 24-hour clock.
|
||||||
|
--
|
||||||
|
-- textutils.formatTime(os.time("local"), true)
|
||||||
function formatTime(nTime, bTwentyFourHour)
|
function formatTime(nTime, bTwentyFourHour)
|
||||||
expect(1, nTime, "number")
|
expect(1, nTime, "number")
|
||||||
expect(2, bTwentyFourHour, "boolean", "nil")
|
expect(2, bTwentyFourHour, "boolean", "nil")
|
||||||
@ -217,6 +224,7 @@ end
|
|||||||
--
|
--
|
||||||
-- @tparam {string...}|number ... The rows and text colors to display.
|
-- @tparam {string...}|number ... The rows and text colors to display.
|
||||||
-- @usage textutils.tabulate(colors.orange, { "1", "2", "3" }, colors.lightBlue, { "A", "B", "C" })
|
-- @usage textutils.tabulate(colors.orange, { "1", "2", "3" }, colors.lightBlue, { "A", "B", "C" })
|
||||||
|
-- @since 1.3
|
||||||
function tabulate(...)
|
function tabulate(...)
|
||||||
return tabulateCommon(false, ...)
|
return tabulateCommon(false, ...)
|
||||||
end
|
end
|
||||||
@ -231,6 +239,7 @@ end
|
|||||||
-- @usage textutils.tabulate(colors.orange, { "1", "2", "3" }, colors.lightBlue, { "A", "B", "C" })
|
-- @usage textutils.tabulate(colors.orange, { "1", "2", "3" }, colors.lightBlue, { "A", "B", "C" })
|
||||||
-- @see textutils.tabulate
|
-- @see textutils.tabulate
|
||||||
-- @see textutils.pagedPrint
|
-- @see textutils.pagedPrint
|
||||||
|
-- @since 1.3
|
||||||
function pagedTabulate(...)
|
function pagedTabulate(...)
|
||||||
return tabulateCommon(true, ...)
|
return tabulateCommon(true, ...)
|
||||||
end
|
end
|
||||||
@ -259,12 +268,17 @@ local g_tLuaKeywords = {
|
|||||||
["while"] = true,
|
["while"] = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local serialize_infinity = math.huge
|
||||||
local function serialize_impl(t, tracking, indent, opts)
|
local function serialize_impl(t, tracking, indent, opts)
|
||||||
local sType = type(t)
|
local sType = type(t)
|
||||||
if sType == "table" then
|
if sType == "table" then
|
||||||
if tracking[t] ~= nil then
|
if tracking[t] ~= nil then
|
||||||
|
if tracking[t] == false then
|
||||||
|
error("Cannot serialize table with repeated entries", 0)
|
||||||
|
else
|
||||||
error("Cannot serialize table with recursive entries", 0)
|
error("Cannot serialize table with recursive entries", 0)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
tracking[t] = true
|
tracking[t] = true
|
||||||
|
|
||||||
local result
|
local result
|
||||||
@ -298,13 +312,28 @@ local function serialize_impl(t, tracking, indent, opts)
|
|||||||
result = result .. indent .. "}"
|
result = result .. indent .. "}"
|
||||||
end
|
end
|
||||||
|
|
||||||
if opts.allow_repetitions then tracking[t] = nil end
|
if opts.allow_repetitions then
|
||||||
|
tracking[t] = nil
|
||||||
|
else
|
||||||
|
tracking[t] = false
|
||||||
|
end
|
||||||
return result
|
return result
|
||||||
|
|
||||||
elseif sType == "string" then
|
elseif sType == "string" then
|
||||||
return string.format("%q", t)
|
return string.format("%q", t)
|
||||||
|
|
||||||
elseif sType == "number" or sType == "boolean" or sType == "nil" then
|
elseif sType == "number" then
|
||||||
|
if t ~= t then --nan
|
||||||
|
return "0/0"
|
||||||
|
elseif t == serialize_infinity then
|
||||||
|
return "1/0"
|
||||||
|
elseif t == -serialize_infinity then
|
||||||
|
return "-1/0"
|
||||||
|
else
|
||||||
|
return tostring(t)
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif sType == "boolean" or sType == "nil" then
|
||||||
return tostring(t)
|
return tostring(t)
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -620,6 +649,7 @@ do
|
|||||||
-- @return[1] The deserialised object
|
-- @return[1] The deserialised object
|
||||||
-- @treturn[2] nil If the object could not be deserialised.
|
-- @treturn[2] nil If the object could not be deserialised.
|
||||||
-- @treturn string A message describing why the JSON string is invalid.
|
-- @treturn string A message describing why the JSON string is invalid.
|
||||||
|
-- @since 1.87.0
|
||||||
unserialise_json = function(s, options)
|
unserialise_json = function(s, options)
|
||||||
expect(1, s, "string")
|
expect(1, s, "string")
|
||||||
expect(2, options, "table", "nil")
|
expect(2, options, "table", "nil")
|
||||||
@ -664,6 +694,8 @@ serialised. This includes functions and tables which appear multiple
|
|||||||
times.
|
times.
|
||||||
@see cc.pretty.pretty An alternative way to display a table, often more suitable for
|
@see cc.pretty.pretty An alternative way to display a table, often more suitable for
|
||||||
pretty printing.
|
pretty printing.
|
||||||
|
@since 1.3
|
||||||
|
@changed 1.97.0 Added `opts` argument.
|
||||||
@usage Pretty print a basic table.
|
@usage Pretty print a basic table.
|
||||||
|
|
||||||
textutils.serialise({ 1, 2, 3, a = 1, ["another key"] = { true } })
|
textutils.serialise({ 1, 2, 3, a = 1, ["another key"] = { true } })
|
||||||
@ -697,6 +729,7 @@ serialise = serialize -- GB version
|
|||||||
-- @tparam string s The serialised string to deserialise.
|
-- @tparam string s The serialised string to deserialise.
|
||||||
-- @return[1] The deserialised object
|
-- @return[1] The deserialised object
|
||||||
-- @treturn[2] nil If the object could not be deserialised.
|
-- @treturn[2] nil If the object could not be deserialised.
|
||||||
|
-- @since 1.3
|
||||||
function unserialize(s)
|
function unserialize(s)
|
||||||
expect(1, s, "string")
|
expect(1, s, "string")
|
||||||
local func = load("return " .. s, "unserialize", "t", {})
|
local func = load("return " .. s, "unserialize", "t", {})
|
||||||
@ -729,6 +762,7 @@ unserialise = unserialize -- GB version
|
|||||||
-- serialised. This includes functions and tables which appear multiple
|
-- serialised. This includes functions and tables which appear multiple
|
||||||
-- times.
|
-- times.
|
||||||
-- @usage textutils.serializeJSON({ values = { 1, "2", true } })
|
-- @usage textutils.serializeJSON({ values = { 1, "2", true } })
|
||||||
|
-- @since 1.7
|
||||||
function serializeJSON(t, bNBTStyle)
|
function serializeJSON(t, bNBTStyle)
|
||||||
expect(1, t, "table", "string", "number", "boolean")
|
expect(1, t, "table", "string", "number", "boolean")
|
||||||
expect(2, bNBTStyle, "boolean", "nil")
|
expect(2, bNBTStyle, "boolean", "nil")
|
||||||
@ -746,6 +780,7 @@ unserialiseJSON = unserialise_json
|
|||||||
-- @tparam string str The string to encode
|
-- @tparam string str The string to encode
|
||||||
-- @treturn string The encoded string.
|
-- @treturn string The encoded string.
|
||||||
-- @usage print("https://example.com/?view=" .. textutils.urlEncode("some text&things"))
|
-- @usage print("https://example.com/?view=" .. textutils.urlEncode("some text&things"))
|
||||||
|
-- @since 1.31
|
||||||
function urlEncode(str)
|
function urlEncode(str)
|
||||||
expect(1, str, "string")
|
expect(1, str, "string")
|
||||||
if str then
|
if str then
|
||||||
@ -785,6 +820,7 @@ local tEmpty = {}
|
|||||||
-- @see shell.setCompletionFunction
|
-- @see shell.setCompletionFunction
|
||||||
-- @see _G.read
|
-- @see _G.read
|
||||||
-- @usage textutils.complete( "pa", _ENV )
|
-- @usage textutils.complete( "pa", _ENV )
|
||||||
|
-- @since 1.74
|
||||||
function complete(sSearchText, tSearchTable)
|
function complete(sSearchText, tSearchTable)
|
||||||
expect(1, sSearchText, "string")
|
expect(1, sSearchText, "string")
|
||||||
expect(2, tSearchTable, "table", "nil")
|
expect(2, tSearchTable, "table", "nil")
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
-- [wiki]: http://en.wikipedia.org/wiki/Euclidean_vector
|
-- [wiki]: http://en.wikipedia.org/wiki/Euclidean_vector
|
||||||
--
|
--
|
||||||
-- @module vector
|
-- @module vector
|
||||||
|
-- @since 1.31
|
||||||
|
|
||||||
--- A 3-dimensional vector, with `x`, `y`, and `z` values.
|
--- A 3-dimensional vector, with `x`, `y`, and `z` values.
|
||||||
--
|
--
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
-- terminal display as its parent, and only one of which is visible at a time.
|
-- terminal display as its parent, and only one of which is visible at a time.
|
||||||
--
|
--
|
||||||
-- @module window
|
-- @module window
|
||||||
|
-- @since 1.6
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||||
|
|
||||||
@ -52,24 +53,40 @@ local type = type
|
|||||||
local string_rep = string.rep
|
local string_rep = string.rep
|
||||||
local string_sub = string.sub
|
local string_sub = string.sub
|
||||||
|
|
||||||
--- Returns a terminal object that is a space within the specified parent
|
--[[- Returns a terminal object that is a space within the specified parent
|
||||||
-- terminal object. This can then be used (or even redirected to) in the same
|
terminal object. This can then be used (or even redirected to) in the same
|
||||||
-- manner as eg a wrapped monitor. Refer to @{term|the term API} for a list of
|
manner as eg a wrapped monitor. Refer to @{term|the term API} for a list of
|
||||||
-- functions available to it.
|
functions available to it.
|
||||||
--
|
|
||||||
-- @{term} itself may not be passed as the parent, though @{term.native} is
|
@{term} itself may not be passed as the parent, though @{term.native} is
|
||||||
-- acceptable. Generally, @{term.current} or a wrapped monitor will be most
|
acceptable. Generally, @{term.current} or a wrapped monitor will be most
|
||||||
-- suitable, though windows may even have other windows assigned as their
|
suitable, though windows may even have other windows assigned as their
|
||||||
-- parents.
|
parents.
|
||||||
--
|
|
||||||
-- @tparam term.Redirect parent The parent terminal redirect to draw to.
|
@tparam term.Redirect parent The parent terminal redirect to draw to.
|
||||||
-- @tparam number nX The x coordinate this window is drawn at in the parent terminal
|
@tparam number nX The x coordinate this window is drawn at in the parent terminal
|
||||||
-- @tparam number nY The y coordinate this window is drawn at in the parent terminal
|
@tparam number nY The y coordinate this window is drawn at in the parent terminal
|
||||||
-- @tparam number nWidth The width of this window
|
@tparam number nWidth The width of this window
|
||||||
-- @tparam number nHeight The height of this window
|
@tparam number nHeight The height of this window
|
||||||
-- @tparam[opt] boolean bStartVisible Whether this window is visible by
|
@tparam[opt] boolean bStartVisible Whether this window is visible by
|
||||||
-- default. Defaults to `true`.
|
default. Defaults to `true`.
|
||||||
-- @treturn Window The constructed window
|
@treturn Window The constructed window
|
||||||
|
@since 1.6
|
||||||
|
@usage Create a smaller window, fill it red and write some text to it.
|
||||||
|
|
||||||
|
local my_window = window.create(term.current(), 1, 1, 20, 5)
|
||||||
|
my_window.setBackgroundColour(colours.red)
|
||||||
|
my_window.setTextColour(colours.white)
|
||||||
|
my_window.clear()
|
||||||
|
my_window.write("Testing my window!")
|
||||||
|
|
||||||
|
@usage Create a smaller window and redirect to it.
|
||||||
|
|
||||||
|
local my_window = window.create(term.current(), 1, 1, 25, 5)
|
||||||
|
term.redirect(my_window)
|
||||||
|
print("Writing some long text which will wrap around and show the bounds of this window.")
|
||||||
|
|
||||||
|
]]
|
||||||
function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
||||||
expect(1, parent, "table")
|
expect(1, parent, "table")
|
||||||
expect(2, nX, "number")
|
expect(2, nX, "number")
|
||||||
@ -446,6 +463,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
|||||||
-- @treturn string The text colours of this line, suitable for use with @{term.blit}.
|
-- @treturn string The text colours of this line, suitable for use with @{term.blit}.
|
||||||
-- @treturn string The background colours of this line, suitable for use with @{term.blit}.
|
-- @treturn string The background colours of this line, suitable for use with @{term.blit}.
|
||||||
-- @throws If `y` is not between 1 and this window's height.
|
-- @throws If `y` is not between 1 and this window's height.
|
||||||
|
-- @since 1.84.0
|
||||||
function window.getLine(y)
|
function window.getLine(y)
|
||||||
if type(y) ~= "number" then expect(1, y, "number") end
|
if type(y) ~= "number" then expect(1, y, "number") end
|
||||||
|
|
||||||
@ -479,6 +497,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
|||||||
--
|
--
|
||||||
-- @treturn boolean Whether this window is visible.
|
-- @treturn boolean Whether this window is visible.
|
||||||
-- @see Window:setVisible
|
-- @see Window:setVisible
|
||||||
|
-- @since 1.94.0
|
||||||
function window.isVisible()
|
function window.isVisible()
|
||||||
return bVisible
|
return bVisible
|
||||||
end
|
end
|
||||||
@ -525,6 +544,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
|||||||
-- @tparam number new_height The new height of this window.
|
-- @tparam number new_height The new height of this window.
|
||||||
-- @tparam[opt] term.Redirect new_parent The new redirect object this
|
-- @tparam[opt] term.Redirect new_parent The new redirect object this
|
||||||
-- window should draw to.
|
-- window should draw to.
|
||||||
|
-- @changed 1.85.0 Add `new_parent` parameter.
|
||||||
function window.reposition(new_x, new_y, new_width, new_height, new_parent)
|
function window.reposition(new_x, new_y, new_width, new_height, new_parent)
|
||||||
if type(new_x) ~= "number" then expect(1, new_x, "number") end
|
if type(new_x) ~= "number" then expect(1, new_x, "number") end
|
||||||
if type(new_y) ~= "number" then expect(2, new_y, "number") end
|
if type(new_y) ~= "number" then expect(2, new_y, "number") end
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
-- @module cc.completion
|
-- @module cc.completion
|
||||||
-- @see cc.shell.completion For additional helpers to use with
|
-- @see cc.shell.completion For additional helpers to use with
|
||||||
-- @{shell.setCompletionFunction}.
|
-- @{shell.setCompletionFunction}.
|
||||||
|
-- @since 1.85.0
|
||||||
|
|
||||||
local expect = require "cc.expect".expect
|
local expect = require "cc.expect".expect
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
function arguments are well-formed and of the correct type.
|
function arguments are well-formed and of the correct type.
|
||||||
|
|
||||||
@module cc.expect
|
@module cc.expect
|
||||||
|
@since 1.84.0
|
||||||
|
@changed 1.96.0 The module can now be called directly as a function, which wraps around `expect.expect`.
|
||||||
@usage Define a basic function and check it has the correct arguments.
|
@usage Define a basic function and check it has the correct arguments.
|
||||||
|
|
||||||
local expect = require "cc.expect"
|
local expect = require "cc.expect"
|
||||||
@ -97,6 +99,7 @@ end
|
|||||||
-- @tparam number max The maximum value, if nil then `math.huge` is used.
|
-- @tparam number max The maximum value, if nil then `math.huge` is used.
|
||||||
-- @return The given `value`.
|
-- @return The given `value`.
|
||||||
-- @throws If the value is outside of the allowed range.
|
-- @throws If the value is outside of the allowed range.
|
||||||
|
-- @since 1.96.0
|
||||||
local function range(num, min, max)
|
local function range(num, min, max)
|
||||||
expect(1, num, "number")
|
expect(1, num, "number")
|
||||||
min = expect(2, min, "number", "nil") or -math.huge
|
min = expect(2, min, "number", "nil") or -math.huge
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
-- text.
|
-- text.
|
||||||
--
|
--
|
||||||
-- @module cc.image.nft
|
-- @module cc.image.nft
|
||||||
|
-- @since 1.90.0
|
||||||
-- @usage Load an image from `example.nft` and draw it.
|
-- @usage Load an image from `example.nft` and draw it.
|
||||||
--
|
--
|
||||||
-- local nft = require "cc.image.nft"
|
-- local nft = require "cc.image.nft"
|
||||||
|
@ -15,6 +15,7 @@ The structure of this module is based on [A Prettier Printer][prettier].
|
|||||||
[prettier]: https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf "A Prettier Printer"
|
[prettier]: https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf "A Prettier Printer"
|
||||||
|
|
||||||
@module cc.pretty
|
@module cc.pretty
|
||||||
|
@since 1.87.0
|
||||||
@usage Print a table to the terminal
|
@usage Print a table to the terminal
|
||||||
|
|
||||||
local pretty = require "cc.pretty"
|
local pretty = require "cc.pretty"
|
||||||
@ -457,6 +458,7 @@ end
|
|||||||
-- - `function_source`: Show where the function was defined, instead of
|
-- - `function_source`: Show where the function was defined, instead of
|
||||||
-- `function: xxxxxxxx` (`false` by default).
|
-- `function: xxxxxxxx` (`false` by default).
|
||||||
-- @treturn Doc The object formatted as a document.
|
-- @treturn Doc The object formatted as a document.
|
||||||
|
-- @changed 1.88.0 Added `options` argument.
|
||||||
-- @usage Display a table on the screen
|
-- @usage Display a table on the screen
|
||||||
--
|
--
|
||||||
-- local pretty = require "cc.pretty"
|
-- local pretty = require "cc.pretty"
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
-- custom shell or when running programs yourself.
|
-- custom shell or when running programs yourself.
|
||||||
--
|
--
|
||||||
-- @module cc.require
|
-- @module cc.require
|
||||||
|
-- @since 1.88.0
|
||||||
-- @usage Construct the package and require function, and insert them into a
|
-- @usage Construct the package and require function, and insert them into a
|
||||||
-- custom environment.
|
-- custom environment.
|
||||||
--
|
--
|
||||||
|
@ -8,6 +8,7 @@ and so are not directly usable with the @{shell.setCompletionFunction}. Instead,
|
|||||||
wrap them using @{build}, or your own custom function.
|
wrap them using @{build}, or your own custom function.
|
||||||
|
|
||||||
@module cc.shell.completion
|
@module cc.shell.completion
|
||||||
|
@since 1.85.0
|
||||||
@see cc.completion For more general helpers, suitable for use with @{_G.read}.
|
@see cc.completion For more general helpers, suitable for use with @{_G.read}.
|
||||||
@see shell.setCompletionFunction
|
@see shell.setCompletionFunction
|
||||||
|
|
||||||
@ -89,6 +90,7 @@ end
|
|||||||
-- @tparam { string... } previous The shell arguments before this one.
|
-- @tparam { string... } previous The shell arguments before this one.
|
||||||
-- @tparam number starting Which argument index this program and args start at.
|
-- @tparam number starting Which argument index this program and args start at.
|
||||||
-- @treturn { string... } A list of suffixes of matching programs or arguments.
|
-- @treturn { string... } A list of suffixes of matching programs or arguments.
|
||||||
|
-- @since 1.97.0
|
||||||
local function programWithArgs(shell, text, previous, starting)
|
local function programWithArgs(shell, text, previous, starting)
|
||||||
if #previous + 1 == starting then
|
if #previous + 1 == starting then
|
||||||
local tCompletionInfo = shell.getCompletionInfo()
|
local tCompletionInfo = shell.getCompletionInfo()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
--- Various utilities for working with strings and text.
|
--- Various utilities for working with strings and text.
|
||||||
--
|
--
|
||||||
-- @module cc.strings
|
-- @module cc.strings
|
||||||
|
-- @since 1.95.0
|
||||||
-- @see textutils For additional string related utilities.
|
-- @see textutils For additional string related utilities.
|
||||||
|
|
||||||
local expect = (require and require("cc.expect") or dofile("rom/modules/main/cc/expect.lua")).expect
|
local expect = (require and require("cc.expect") or dofile("rom/modules/main/cc/expect.lua")).expect
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
-- not available to @{os.loadAPI|APIs}.
|
-- not available to @{os.loadAPI|APIs}.
|
||||||
--
|
--
|
||||||
-- @module[module] multishell
|
-- @module[module] multishell
|
||||||
|
-- @since 1.6
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ end
|
|||||||
-- @tparam string command The program to execute.
|
-- @tparam string command The program to execute.
|
||||||
-- @tparam string ... Arguments to this program.
|
-- @tparam string ... Arguments to this program.
|
||||||
-- @treturn boolean Whether the program exited successfully.
|
-- @treturn boolean Whether the program exited successfully.
|
||||||
|
-- @since 1.88.0
|
||||||
-- @usage Run `paint my-image` from within your program:
|
-- @usage Run `paint my-image` from within your program:
|
||||||
--
|
--
|
||||||
-- shell.execute("paint", "my-image")
|
-- shell.execute("paint", "my-image")
|
||||||
@ -131,6 +132,8 @@ end
|
|||||||
--
|
--
|
||||||
-- shell.run("paint", "my-image")
|
-- shell.run("paint", "my-image")
|
||||||
-- @see shell.execute Run a program directly without parsing the arguments.
|
-- @see shell.execute Run a program directly without parsing the arguments.
|
||||||
|
-- @changed 1.80pr1 Programs now get their own environment instead of sharing the same one.
|
||||||
|
-- @changed 1.83.0 `arg` is now added to the environment.
|
||||||
function shell.run(...)
|
function shell.run(...)
|
||||||
local tWords = tokenise(...)
|
local tWords = tokenise(...)
|
||||||
local sCommand = tWords[1]
|
local sCommand = tWords[1]
|
||||||
@ -193,6 +196,7 @@ end
|
|||||||
-- for from the @{shell.dir|current directory}, rather than the computer's root.
|
-- for from the @{shell.dir|current directory}, rather than the computer's root.
|
||||||
--
|
--
|
||||||
-- @tparam string path The new program path.
|
-- @tparam string path The new program path.
|
||||||
|
-- @since 1.2
|
||||||
function shell.setPath(path)
|
function shell.setPath(path)
|
||||||
expect(1, path, "string")
|
expect(1, path, "string")
|
||||||
sPath = path
|
sPath = path
|
||||||
@ -235,6 +239,7 @@ end
|
|||||||
-- @tparam string command The name of the program
|
-- @tparam string command The name of the program
|
||||||
-- @treturn string|nil The absolute path to the program, or @{nil} if it could
|
-- @treturn string|nil The absolute path to the program, or @{nil} if it could
|
||||||
-- not be found.
|
-- not be found.
|
||||||
|
-- @since 1.2
|
||||||
-- @usage Locate the `hello` program.
|
-- @usage Locate the `hello` program.
|
||||||
--
|
--
|
||||||
-- shell.resolveProgram("hello")
|
-- shell.resolveProgram("hello")
|
||||||
@ -283,6 +288,7 @@ end
|
|||||||
-- start with `.`.
|
-- start with `.`.
|
||||||
-- @treturn { string } A list of available programs.
|
-- @treturn { string } A list of available programs.
|
||||||
-- @usage textutils.tabulate(shell.programs())
|
-- @usage textutils.tabulate(shell.programs())
|
||||||
|
-- @since 1.2
|
||||||
function shell.programs(include_hidden)
|
function shell.programs(include_hidden)
|
||||||
expect(1, include_hidden, "boolean", "nil")
|
expect(1, include_hidden, "boolean", "nil")
|
||||||
|
|
||||||
@ -387,6 +393,7 @@ end
|
|||||||
-- @see shell.completeProgram
|
-- @see shell.completeProgram
|
||||||
-- @see shell.setCompletionFunction
|
-- @see shell.setCompletionFunction
|
||||||
-- @see shell.getCompletionInfo
|
-- @see shell.getCompletionInfo
|
||||||
|
-- @since 1.74
|
||||||
function shell.complete(sLine)
|
function shell.complete(sLine)
|
||||||
expect(1, sLine, "string")
|
expect(1, sLine, "string")
|
||||||
if #sLine > 0 then
|
if #sLine > 0 then
|
||||||
@ -462,6 +469,7 @@ end
|
|||||||
-- @see cc.shell.completion Various utilities to help with writing completion functions.
|
-- @see cc.shell.completion Various utilities to help with writing completion functions.
|
||||||
-- @see shell.complete
|
-- @see shell.complete
|
||||||
-- @see _G.read For more information about completion.
|
-- @see _G.read For more information about completion.
|
||||||
|
-- @since 1.74
|
||||||
function shell.setCompletionFunction(program, complete)
|
function shell.setCompletionFunction(program, complete)
|
||||||
expect(1, program, "string")
|
expect(1, program, "string")
|
||||||
expect(2, complete, "function")
|
expect(2, complete, "function")
|
||||||
@ -484,6 +492,7 @@ end
|
|||||||
--- Returns the path to the currently running program.
|
--- Returns the path to the currently running program.
|
||||||
--
|
--
|
||||||
-- @treturn string The absolute path to the running program.
|
-- @treturn string The absolute path to the running program.
|
||||||
|
-- @since 1.3
|
||||||
function shell.getRunningProgram()
|
function shell.getRunningProgram()
|
||||||
if #tProgramStack > 0 then
|
if #tProgramStack > 0 then
|
||||||
return tProgramStack[#tProgramStack]
|
return tProgramStack[#tProgramStack]
|
||||||
@ -495,6 +504,7 @@ end
|
|||||||
--
|
--
|
||||||
-- @tparam string command The name of the alias to add.
|
-- @tparam string command The name of the alias to add.
|
||||||
-- @tparam string program The name or path to the program.
|
-- @tparam string program The name or path to the program.
|
||||||
|
-- @since 1.2
|
||||||
-- @usage Alias `vim` to the `edit` program
|
-- @usage Alias `vim` to the `edit` program
|
||||||
--
|
--
|
||||||
-- shell.setAlias("vim", "edit")
|
-- shell.setAlias("vim", "edit")
|
||||||
@ -543,6 +553,7 @@ if multishell then
|
|||||||
-- @tparam string ... The command line to run.
|
-- @tparam string ... The command line to run.
|
||||||
-- @see shell.run
|
-- @see shell.run
|
||||||
-- @see multishell.launch
|
-- @see multishell.launch
|
||||||
|
-- @since 1.6
|
||||||
-- @usage Launch the Lua interpreter and switch to it.
|
-- @usage Launch the Lua interpreter and switch to it.
|
||||||
--
|
--
|
||||||
-- local id = shell.openTab("lua")
|
-- local id = shell.openTab("lua")
|
||||||
@ -566,6 +577,7 @@ if multishell then
|
|||||||
--
|
--
|
||||||
-- @tparam number id The tab to switch to.
|
-- @tparam number id The tab to switch to.
|
||||||
-- @see multishell.setFocus
|
-- @see multishell.setFocus
|
||||||
|
-- @since 1.6
|
||||||
function shell.switchTab(id)
|
function shell.switchTab(id)
|
||||||
expect(1, id, "number")
|
expect(1, id, "number")
|
||||||
multishell.setFocus(id)
|
multishell.setFocus(id)
|
||||||
|
@ -81,14 +81,17 @@ describe("The textutils library", function()
|
|||||||
it("serialises basic tables", function()
|
it("serialises basic tables", function()
|
||||||
expect(textutils.serialise({ 1, 2, 3, a = 1, b = {} }))
|
expect(textutils.serialise({ 1, 2, 3, a = 1, b = {} }))
|
||||||
:eq("{\n 1,\n 2,\n 3,\n a = 1,\n b = {},\n}")
|
:eq("{\n 1,\n 2,\n 3,\n a = 1,\n b = {},\n}")
|
||||||
|
|
||||||
|
expect(textutils.serialise({ 0 / 0, 1 / 0, -1 / 0 }))
|
||||||
|
:eq("{\n 0/0,\n 1/0,\n -1/0,\n}")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("fails on recursive tables", function()
|
it("fails on recursive/repeated tables", function()
|
||||||
local rep = {}
|
local rep = {}
|
||||||
expect.error(textutils.serialise, { rep, rep }):eq("Cannot serialize table with recursive entries")
|
expect.error(textutils.serialise, { rep, rep }):eq("Cannot serialize table with repeated entries")
|
||||||
|
|
||||||
local rep2 = { 1 }
|
local rep2 = { 1 }
|
||||||
expect.error(textutils.serialise, { rep2, rep2 }):eq("Cannot serialize table with recursive entries")
|
expect.error(textutils.serialise, { rep2, rep2 }):eq("Cannot serialize table with repeated entries")
|
||||||
|
|
||||||
local recurse = {}
|
local recurse = {}
|
||||||
recurse[1] = recurse
|
recurse[1] = recurse
|
||||||
|
Loading…
Reference in New Issue
Block a user