1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-01 06:03:00 +00:00

Compare commits

...

36 Commits

Author SHA1 Message Date
SquidDev
0dde859582 Bump version 2019-12-23 22:10:32 +00:00
SquidDev
e59c043fb6 Fix a couple of comments to use the new config names 2019-12-23 21:34:03 +00:00
SquidDev
ae928c4397 Make http domain configuration a little clearer 2019-12-23 18:59:36 +00:00
SquidDev
da41c65128 Update proguard configuration
- Remove redundant preservation of cobalt lib constructors. We use
   lambdas now, so this is no longer needed.
 - Fix Java crypto lib not being included.
2019-12-23 18:54:19 +00:00
SquidDev
4d18234714 Use a fake network handler too
It appears that WB opens containers manually, and thus all of our stubs
network stubs are entirely ignored. Thus the only solution here is to
stub out the whole network handler code.

Thankfully this is simple enough - we do the same for Plethora and 1.14.

Fixes #328
2019-12-23 17:17:32 +00:00
JakobDev
d254c6464b Add more MOTD messages again (#241) 2019-12-23 14:43:48 +00:00
Jonathan Coates
3a5d50e572 Basic Minetweaker support (#327)
This provides the following methods:

 - dan200.computercraft.turtle.removeUpgrade(id: String)
 - dan200.computercraft.turtle.removeUpgrade(stack: IItemStack)
 - dan200.computercraft.turtle.addTool(id: String, craftItem: IItemStack[, toolItem: IItemStack][, kind: string])

While it's pretty minimal, it should allow for a reasonable amount of
functionality.

Closes #327 and #97.
2019-12-18 15:29:24 +00:00
Jonathan Coates
03b6d2f1ab Replace string.len with # 2019-12-10 18:55:11 +00:00
Jared Allard
b0397ed3c5 Add support for HTTP PATCH and TRACE (#324) 2019-12-08 17:10:58 +00:00
Jonathan Coates
fa70ebcac2 Fix spacing on all of the rom (#323) 2019-12-07 10:33:47 +00:00
SquidDev
86e0330100 Lint bios and the rom (#321)
We now use illuaminate[1]'s linting facilities to check the rom and
bios.lua for a couple of common bugs and other problems.

Right now this doesn't detect any especially important bugs, though it
has caught lots of small things (unused variables, some noisy code). In
the future, the linter will grow in scope and features, which should
allow us to be stricter and catch most issues.

As a fun aside, we started off with ~150 bugs, and illuaminate was able
to fix all but 30 of them, which is pretty neat.

[1]: https://github.com/SquidDev/illuaminate
2019-12-03 23:26:13 +00:00
SquidDev
0ae70fed13 Correctly implement mouse movement within read
Note to self: if you're going to modify the rom, make sure you test on a
computer which doesn't overwrite the rom with something else.
2019-11-29 20:15:58 +00:00
SquidDev
121802a683 Bump version 2019-11-25 08:58:36 +00:00
SquidDev
08cf55e55f Correct implementation of clamp
That's what I get for inlining definitions.
2019-11-23 14:36:43 +00:00
SquidDev
3c8c0d78ef Use correct render type for turtles
This fixes them not rendering particles when broken. Particle rendering
is a little janky right now, as it uses the whole texture - we should
probably split up the texture into smaller images. Fixes #315
2019-11-23 13:24:36 +00:00
SquidDev
c4d18aa9ca Allow navigating read's input using the mouse 2019-11-23 13:21:07 +00:00
SquidDev
a8fadabaf1 Correct spelling in error message 2019-11-23 09:59:37 +00:00
SquidDev
38f9a015ca Wrap all remaining uses of Grgit
This allows you to build from a zip folder of CC:T. Fixes #307. Also fix
the build, woops.
2019-10-30 17:07:29 +00:00
SquidDev
c311cdc6f5 Make our Javadoc validation a little stricter
I'm not sure there's much utility in this, but still feels worth doing.
2019-10-27 15:16:47 +00:00
SquidDev
a93e0f3284 Expose ArgumentHelper in the public API
This is sufficiently useful a class, that it's worthwhile exposing it.
Hopefully we can slowly encourage other mods to migrate to it (well, at
least in 1.14), and so make error messages more consistent.

Also:
 - Add Javadoc for all public methods
 - Clarify the method names a little (getNumber -> getDouble,
   getReal -> getFiniteDouble).
 - Make the *Table methods return a Map<?,?> instead of
   Map<Object, Object>.
2019-10-27 14:29:07 +00:00
SquidDev
14b3065ba4 Check for trailing whitespace
I'd rather assumed one of the existing checkers did this already, but
apparently not.
2019-10-16 09:22:38 +01:00
SquidDev
c802290437 Bump version 2019-10-04 19:52:02 +01:00
SquidDev
418420523a Proxy the current turtle's inventory
Previously we were just returning the current tile. However, if someone
was holding a reference to this inventory (such as a GUI), then it'd be
outdated and invalid once the turtle had moved.

This caused a couple of issues:
 - turtle_inventory events would not be fired when moving items in the
   turtle GUI.
 - As of 75e2845c01, turtles would no
   longer share their inventory state after moving. Thus, removing items
   from a GUI using an invalid inventory would move them from an old
   tile, duplicating the items.

Fixes #298, fixes #300
2019-10-04 16:53:48 +01:00
Jonathan Coates
813e91073d Merge pull request #302 from Wendelstein7/master
Fixed turtle property category
2019-09-30 15:59:55 +01:00
Jonathan Coates
7250f22ff6 Update CI to also run on PRs 2019-09-30 15:37:52 +01:00
Wendelstein7
db31a53bba Fixed turtle property category
Likely was a leftover from copy pasting and a tired programmer.
2019-09-30 15:15:22 +02:00
SquidDev
3023f235a4 Goodbye Travis, I'm with GH Actions now 2019-09-27 08:56:53 +01:00
SquidDev
79cd8b4da5 Also return the number of affected entities
Closes #293. Doesn't really solve anything there aside from exposing the
number, but sadly there's not really anything obvious I can do on my end
- the command API just doesn't expose anything else.
2019-09-15 18:48:51 +01:00
Jonathan Coates
8e4d311cd9 Refactor shell completion into a separate module (#281)
- Adds cc.completions module, with a couple of helper functions for
   working with the more general completion functionality (i.e. that
   provided by read).
 - Adds cc.shell.completions module, which provides shell-specific
   completion functions.
 - Add a "program completion builder", which allows you to write stuff
   like this:

       shell.setCompletionFunction( "rom/programs/redstone.lua", 
         completion.build(
           { completion.choice, { "probe", "set ", "pulse " } },
           completion.side) )

Closes #232
2019-09-15 18:48:40 +01:00
SquidDev
9bd8c86a94 Change event priority to HIGHEST
See the comments in a802f25dd6 -
effectively we want to make sure we arrive before any other thing which
may capture items (some magnet mods, etc...).
2019-09-15 16:42:21 +01:00
Jonathan Coates
cbc0c1d0b6 A little experiment with GitHub actions
Let's give this a go.
2019-09-14 09:16:13 +01:00
SquidDev
49c37857d4 Window.reposition now allow changing the redirect buffer
See #270
2019-09-13 20:55:20 +01:00
SquidDev
a802f25dd6 Do not listen to block/entity drop events
It appears several mods inject their own drops on the LOWEST priority,
meaning that we capture the existing drops, and the other mod will clear
the (now empty) drop list and add its own, resulting in dupe bugs.

While I'd argue it's somewhat dubious doing this on the LOWEST priority,
it's not a battle I'm prepared to fight. For now, we just remove the
block/entity drop handlers, and handle all drop logic when entities are
spawned.

Fixes #288
2019-08-19 10:33:53 +01:00
Jonathan Coates
a80302c513 Merge pull request #287 from Lignum/patch-1
The pettiest of spelling fixes
2019-08-15 06:59:59 +01:00
Lignum
1c46949da7 Available 2019-08-15 07:37:02 +02:00
SquidDev
46d78af068 Fix changelog being out-of-sync 2019-08-04 11:05:44 +01:00
201 changed files with 3140 additions and 1890 deletions

View File

@@ -11,5 +11,8 @@ insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[*.sexp]
indent_size = 2
[*.properties]
insert_final_newline = false

33
.github/workflows/main-ci.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: Build
on: [push, pull_request]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Gradle
run: ./gradlew build --no-daemon
lint-lua:
name: Lint Lua
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Lint Lua code
run: |
test -d bin || mkdir bin
test -f bin/illuaminate || wget -q -Obin/illuaminate https://squiddev.cc/illuaminate/bin/illuaminate
chmod +x bin/illuaminate
bin/illuaminate lint

View File

@@ -1,35 +0,0 @@
std = "max"
ignore = {
-- Allow access to undefined globals or their fields. In the future we'll
-- define all of CC's globals within this file
'113', '143',
-- FIXME: Ignore unused arguments and loop variables
'212', '213',
-- Disable line is too long for now. It would be possible to clean
-- this up in the future.
'631',
}
-- Only run the linter on ROM and bios for now, as the treasure disks
-- are largely unsupported.
include_files = {
'src/main/resources/assets/computercraft/lua/rom',
'src/main/resources/assets/computercraft/lua/bios.lua',
'src/test/resources/test-rom',
}
files['src/main/resources/assets/computercraft/lua/bios.lua'] = {
-- Allow declaring and mutating globals
allow_defined_top = true,
ignore = { '112', '121', '122', '131', '142' },
}
files['src/main/resources/assets/computercraft/lua/rom/apis'] = {
-- APIs may define globals on the top level. We'll ignore unused globals,
-- as obviously they may be used outside that API.
allow_defined_top = true,
ignore = { '131' },
}

View File

@@ -1,14 +0,0 @@
language: java
script: ./gradlew build --no-daemon
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/s
jdk:
- openjdk8

View File

@@ -1,5 +1,5 @@
# ![CC: Tweaked](logo.png)
[![Current build status](https://travis-ci.org/SquidDev-CC/CC-Tweaked.svg?branch=master)](https://travis-ci.org/SquidDev-CC/CC-Tweaked "Current build status") [![Download CC: Tweaked on CurseForge](http://cf.way2muchnoise.eu/title/cc-tweaked.svg)](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
[![Current build status](https://github.com/SquidDev-CC/CC-Tweaked/workflows/Build/badge.svg)](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [![Download CC: Tweaked on CurseForge](http://cf.way2muchnoise.eu/title/cc-tweaked.svg)](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
turtles and more to Minecraft.

View File

@@ -59,6 +59,10 @@ repositories {
name "Amadornes"
url "https://maven.amadornes.com/"
}
maven {
name "CraftTweaker"
url "https://maven.blamejared.com/"
}
}
configurations {
@@ -68,11 +72,12 @@ configurations {
}
dependencies {
checkstyle "com.puppycrawl.tools:checkstyle:8.21"
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
deobfProvided "CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.554"
deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
deobfProvided "mezz.jei:jei_1.12.2:4.15.0.269:api"
deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
runtime "mezz.jei:jei_1.12.2:4.15.0.269"
@@ -132,6 +137,7 @@ task proguard(type: ProGuardTask, dependsOn: jar) {
// Add the main runtime jar and all non-shadowed dependencies
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
libraryjars "${System.getProperty('java.home')}/lib/jce.jar"
doFirst {
sourceSets.main.compileClasspath
.filter { !it.name.contains("Cobalt") }
@@ -146,9 +152,6 @@ task proguard(type: ProGuardTask, dependsOn: jar) {
// Preserve ComputerCraft classes - we only want to strip shadowed files.
keep 'class dan200.computercraft.** { *; }'
// Preserve the constructors in Cobalt library class, as we init them via reflection
keepclassmembers 'class org.squiddev.cobalt.lib.** { <init>(...); }'
}
task proguardMove(dependsOn: proguard) {
@@ -331,6 +334,7 @@ task checkRelease {
if (!ok) throw new IllegalStateException("Could not check release")
}
}
check.dependsOn checkRelease
curseforge {
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
@@ -402,7 +406,9 @@ githubRelease {
token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
owner 'SquidDev-CC'
repo 'CC-Tweaked'
targetCommitish { Grgit.open(dir: '.').branch.current().name }
try {
targetCommitish = Grgit.open(dir: '.').branch.current().name
} catch(Exception ignored) { }
tagName "v${mc_version}-${mod_version}"
releaseName "[${mc_version}] ${mod_version}"

View File

@@ -14,9 +14,7 @@
<!-- Annotations -->
<module name="AnnotationLocation" />
<module name="AnnotationUseStyle" />
<module name="MissingDeprecated">
<property name="skipNoJavadoc" value="true" />
</module>
<module name="MissingDeprecated" />
<module name="MissingOverride" />
<!-- Blocks -->
@@ -57,6 +55,9 @@
<module name="SimplifyBooleanReturn" />
<module name="StringLiteralEquality" />
<module name="UnnecessaryParentheses" />
<module name="UnnecessarySemicolonAfterTypeMemberDeclaration" />
<module name="UnnecessarySemicolonInTryWithResources" />
<module name="UnnecessarySemicolonInEnumeration" />
<!-- Imports -->
<module name="CustomImportOrder" />
@@ -65,10 +66,16 @@
<module name="UnusedImports" />
<!-- Javadoc -->
<!-- TODO: Missing* checks for the dan200.computercraft.api package? -->
<module name="AtclauseOrder" />
<!-- TODO: Cleanup our documentation before enabling JavadocMethod, JavadocStyle, JavadocType and SummaryJavadoc. -->
<module name="InvalidJavadocPosition" />
<module name="JavadocBlockTagLocation" />
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocStyle" />
<module name="NonEmptyAtclauseDescription" />
<module name="SingleLineJavadoc" />
<module name="SummaryJavadocCheck"/>
<!-- Misc -->
<module name="ArrayTypeStyle" />
@@ -155,5 +162,8 @@
<module name="FileTabCharacter" />
<module name="NewlineAtEndOfFile" />
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="message" value="Trailing whitespace"/>
</module>
</module>

View File

@@ -6,4 +6,7 @@
<!-- All the config options and method fields. -->
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" />
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" />
<!-- Do not check for missing package Javadoc. -->
<suppress checks="JavadocStyle" files=".*[\\/]package-info.java" />
</suppressions>

View File

@@ -1,5 +1,5 @@
# Mod properties
mod_version=1.84.0
mod_version=1.86.0
# Minecraft properties
mc_version=1.12.2

28
illuaminate.sexp Normal file
View File

@@ -0,0 +1,28 @@
; -*- mode: Lisp;-*-
(sources
/src/main/resources/assets/computercraft/lua/bios.lua
/src/main/resources/assets/computercraft/lua/rom/
/src/test/resources/test-rom)
(at /
(linters
;; It'd be nice to avoid this, but right now there's a lot of instances of
;; it.
-var:set-loop
;; It's useful to name arguments for documentation, so we allow this. It'd
;; be good to find a compromise in the future, but this works for now.
-var:unused-arg))
;; We disable the unused global linter in bios.lua and the APIs. In the future
;; hopefully we'll get illuaminate to handle this.
(at
(/src/main/resources/assets/computercraft/lua/bios.lua
/src/main/resources/assets/computercraft/lua/rom/apis/)
(linters -var:unused-global)
(lint
(allow-toplevel-global true)))
;; These warnings are broken right now
(at (bios.lua worm.lua) (linters -control:unreachable))

View File

@@ -32,8 +32,9 @@ import java.lang.reflect.Method;
/**
* The static entry point to the ComputerCraft API.
* Members in this class must be called after mod_ComputerCraft has been initialised,
* but may be called before it is fully loaded.
*
* Members in this class must be called after mod_ComputerCraft has been initialised, but may be called before it is
* fully loaded.
*/
public final class ComputerCraftAPI
{
@@ -269,7 +270,7 @@ public final class ComputerCraftAPI
}
/**
* Registers a media provider to provide {@link IMedia} implementations for Items
* Registers a media provider to provide {@link IMedia} implementations for Items.
*
* @param provider The media provider to register.
* @see IMediaProvider
@@ -370,7 +371,7 @@ public final class ComputerCraftAPI
}
/**
* Construct a new wired node for a given wired element
* Construct a new wired node for a given wired element.
*
* @param element The element to construct it for
* @return The element's node
@@ -398,7 +399,7 @@ public final class ComputerCraftAPI
}
/**
* Get the wired network element for a block in world
* Get the wired network element for a block in world.
*
* @param world The world the block exists in
* @param pos The position the block exists in

View File

@@ -19,7 +19,7 @@ import java.util.List;
/**
* Represents a read only part of a virtual filesystem that can be mounted onto a computer using
* {@link IComputerAccess#mount(String, IMount)}
* {@link IComputerAccess#mount(String, IMount)}.
*
* Ready made implementations of this interface can be created using
* {@link ComputerCraftAPI#createSaveDirMount(World, String, long)} or
@@ -60,7 +60,7 @@ public interface IMount
void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException;
/**
* Returns the size of a file with a given path, in bytes
* Returns the size of a file with a given path, in bytes.
*
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
* @return The size of the file, in bytes.

View File

@@ -0,0 +1,335 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
/**
* Provides methods for extracting values and validating Lua arguments, such as those provided to
* {@link ILuaObject#callMethod(ILuaContext, int, Object[])} or
* {@link IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}.
*
* This provides two sets of functions: the {@code get*} methods, which require an argument to be valid, and
* {@code opt*}, which accept a default value and return that if the argument was not present or was {@code null}.
* If the argument is of the wrong type, a suitable error message will be thrown, with a similar format to Lua's own
* error messages.
*
* <h2>Example usage:</h2>
* <pre>
* {@code
* int slot = getInt( args, 0 );
* int amount = optInt( args, 1, 64 );
* }
* </pre>
*/
public final class ArgumentHelper
{
private ArgumentHelper()
{
}
/**
* Get a string representation of the given value's type.
*
* @param value The value whose type we are trying to compute.
* @return A string representation of the given value's type, in a similar format to that provided by Lua's
* {@code type} function.
*/
@Nonnull
public static String getType( @Nullable Object value )
{
if( value == null ) return "nil";
if( value instanceof String ) return "string";
if( value instanceof Boolean ) return "boolean";
if( value instanceof Number ) return "number";
if( value instanceof Map ) return "table";
return "userdata";
}
/**
* Construct a "bad argument" exception, from an expected type and the actual value provided.
*
* @param index The argument number, starting from 0.
* @param expected The expected type for this argument.
* @param actual The actual value provided for this argument.
* @return The constructed exception, which should be thrown immediately.
*/
@Nonnull
public static LuaException badArgumentOf( int index, @Nonnull String expected, @Nullable Object actual )
{
return badArgument( index, expected, getType( actual ) );
}
/**
* Construct a "bad argument" exception, from an expected and actual type.
*
* @param index The argument number, starting from 0.
* @param expected The expected type for this argument.
* @param actual The provided type for this argument.
* @return The constructed exception, which should be thrown immediately.
*/
@Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
{
return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
}
/**
* Get an argument as a double.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a number.
* @see #getFiniteDouble(Object[], int) if you require this to be finite (i.e. not infinite or NaN).
*/
public static double getDouble( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return ((Number) value).doubleValue();
}
/**
* Get an argument as an integer.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not an integer.
*/
public static int getInt( @Nonnull Object[] args, int index ) throws LuaException
{
return (int) getLong( args, index );
}
/**
* Get an argument as a long.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a long.
*/
public static long getLong( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return checkFinite( index, (Number) value ).longValue();
}
/**
* Get an argument as a finite number (not infinite or NaN).
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not finite.
*/
public static double getFiniteDouble( @Nonnull Object[] args, int index ) throws LuaException
{
return checkFinite( index, getDouble( args, index ) );
}
/**
* Get an argument as a boolean.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a boolean.
*/
public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "boolean", "nil" );
Object value = args[index];
if( !(value instanceof Boolean) ) throw badArgumentOf( index, "boolean", value );
return (Boolean) value;
}
/**
* Get an argument as a string.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a string.
*/
@Nonnull
public static String getString( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "string", "nil" );
Object value = args[index];
if( !(value instanceof String) ) throw badArgumentOf( index, "string", value );
return (String) value;
}
/**
* Get an argument as a table.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a table.
*/
@Nonnull
public static Map<?, ?> getTable( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "table", "nil" );
Object value = args[index];
if( !(value instanceof Map) ) throw badArgumentOf( index, "table", value );
return (Map<?, ?>) value;
}
/**
* Get an argument as a double.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static double optDouble( @Nonnull Object[] args, int index, double def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return ((Number) value).doubleValue();
}
/**
* Get an argument as an int.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException
{
return (int) optLong( args, index, def );
}
/**
* Get an argument as a long.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return checkFinite( index, (Number) value ).longValue();
}
/**
* Get an argument as a finite number (not infinite or NaN).
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not finite.
*/
public static double optFiniteDouble( @Nonnull Object[] args, int index, double def ) throws LuaException
{
return checkFinite( index, optDouble( args, index, def ) );
}
/**
* Get an argument as a boolean.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a boolean.
*/
public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Boolean) ) throw badArgumentOf( index, "boolean", value );
return (Boolean) value;
}
/**
* Get an argument as a string.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a string.
*/
public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof String) ) throw badArgumentOf( index, "string", value );
return (String) value;
}
/**
* Get an argument as a table.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a table.
*/
public static Map<?, ?> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Map) ) throw badArgumentOf( index, "table", value );
return (Map<?, ?>) value;
}
private static Number checkFinite( int index, Number value ) throws LuaException
{
checkFinite( index, value.doubleValue() );
return value;
}
private static double checkFinite( int index, double value ) throws LuaException
{
if( !Double.isFinite( value ) ) throw badArgument( index, "number", getNumericType( value ) );
return value;
}
/**
* Returns a more detailed representation of this number's type. If this is finite, it will just return "number",
* otherwise it returns whether it is infinite or NaN.
*
* @param value The value to extract the type for.
* @return This value's numeric type.
*/
@Nonnull
public static String getNumericType( double value )
{
if( Double.isNaN( value ) ) return "nan";
if( value == Double.POSITIVE_INFINITY ) return "inf";
if( value == Double.NEGATIVE_INFINITY ) return "-inf";
return "number";
}
}

View File

@@ -26,7 +26,7 @@ public interface IComputerSystem extends IComputerAccess
IFileSystem getFileSystem();
/**
* Get the label for this computer
* Get the label for this computer.
*
* @return This computer's label, or {@code null} if it is not set.
*/

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.api.peripheral;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
@@ -58,9 +59,11 @@ public interface IPeripheral
* Lua values of type "table" will be represented by Object type Map.<br>
* Lua values of any other type will be represented by a null object.<br>
* This array will be empty if no arguments are passed.
*
* It is recommended you use {@link ArgumentHelper} in order to validate and process arguments.
* @return An array of objects, representing values you wish to return to the lua program. Integers, Doubles, Floats,
* Strings, Booleans, Maps and ILuaObject and null be converted to their corresponding lua type. All other types
* will be converted to nil.
* Strings, Booleans, Maps, ILuaObject and null be converted to their corresponding lua type. All other types will
* be converted to nil.
*
* You may return null to indicate no values should be returned.
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the
@@ -70,6 +73,7 @@ public interface IPeripheral
* InterruptedException will be thrown. This exception must not be caught or
* intercepted, or the computer will leak memory and end up in a broken state.
* @see #getMethodNames
* @see ArgumentHelper
*/
@Nullable
Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException;

View File

@@ -16,7 +16,7 @@ import javax.annotation.Nullable;
import java.util.Map;
/**
* Wrapper class for pocket computers
* Wrapper class for pocket computers.
*/
public interface IPocketAccess
{

View File

@@ -12,12 +12,12 @@ package dan200.computercraft.api.turtle;
public enum TurtleSide
{
/**
* The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle)
* The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle).
*/
Left,
/**
* The turtle's right side (where the modem usually is on a Wireless Mining Turtle)
* The turtle's right side (where the modem usually is on a Wireless Mining Turtle).
*/
Right,
}

View File

@@ -18,12 +18,12 @@ import net.minecraft.util.EnumFacing;
public enum TurtleVerb
{
/**
* The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}
* The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}.
*/
Dig,
/**
* The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()}
* The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()}.
*/
Attack,
}

View File

@@ -71,7 +71,7 @@ public enum TurtleAction
EQUIP,
/**
* Inspect a block in world
* Inspect a block in world.
*
* @see TurtleBlockEvent.Inspect
*/

View File

@@ -112,7 +112,7 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
}
/**
* Get the upgrade doing the digging
* Get the upgrade doing the digging.
*
* @return The upgrade doing the digging.
*/

View File

@@ -31,7 +31,7 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
}
/**
* Get the inventory being interacted with
* Get the inventory being interacted with.
*
* @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world.
*/

View File

@@ -18,7 +18,7 @@ import net.minecraft.util.math.MathHelper;
public abstract class ItemMapLikeRenderer
{
/**
* The main rendering method for the item
* The main rendering method for the item.
*
* @param stack The stack to render
* @see ItemRenderer#renderMapFirstPerson(ItemStack)
@@ -87,7 +87,7 @@ public abstract class ItemMapLikeRenderer
}
/**
* Render an item in the middle of the screen
* Render an item in the middle of the screen.
*
* @param pitch The pitch of the player
* @param equipProgress The equip progress of this item

View File

@@ -32,7 +32,7 @@ import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*;
import static dan200.computercraft.client.gui.GuiComputer.*;
/**
* Emulates map rendering for pocket computers
* Emulates map rendering for pocket computers.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
public final class ItemPocketRenderer extends ItemMapLikeRenderer

View File

@@ -23,7 +23,7 @@ import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAG
import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH;
/**
* Emulates map and item-frame rendering for printouts
* Emulates map and item-frame rendering for printouts.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
public final class ItemPrintoutRenderer extends ItemMapLikeRenderer

View File

@@ -28,32 +28,32 @@ public final class PrintoutRenderer
private static final double BG_SIZE = 256.0;
/**
* Width of a page
* Width of a page.
*/
public static final int X_SIZE = 172;
/**
* Height of a page
* Height of a page.
*/
public static final int Y_SIZE = 209;
/**
* Padding between the left and right of a page and the text
* Padding between the left and right of a page and the text.
*/
public static final int X_TEXT_MARGIN = 13;
/**
* Padding between the top and bottom of a page and the text
* Padding between the top and bottom of a page and the text.
*/
public static final int Y_TEXT_MARGIN = 11;
/**
* Width of the extra page texture
* Width of the extra page texture.
*/
private static final int X_FOLD_SIZE = 12;
/**
* Size of the leather cover
* Size of the leather cover.
*/
public static final int COVER_SIZE = 12;

View File

@@ -97,6 +97,8 @@ public class TileEntityCableRenderer extends TileEntitySpecialRenderer<TileCable
}
/**
* Set up the state for rendering block-breaking progress.
*
* @see RenderGlobal#preRenderDamagedBlocks()
*/
private void preRenderDamagedBlocks()
@@ -115,6 +117,8 @@ public class TileEntityCableRenderer extends TileEntitySpecialRenderer<TileCable
}
/**
* Tear down the state for rendering block-breaking progress.
*
* @see RenderGlobal#postRenderDamagedBlocks()
*/
private void postRenderDamagedBlocks()

View File

@@ -154,7 +154,7 @@ public class AddressPredicate
}
/**
* Determine whether the given address matches a series of patterns
* Determine whether the given address matches a series of patterns.
*
* @param address The address to check.
* @return Whether it matches any of these patterns.

View File

@@ -13,256 +13,106 @@ import javax.annotation.Nullable;
import java.util.Map;
/**
* Various helpers for arguments
* A stub for any mods which depended on this version of the argument helper.
*
* @deprecated Use {@link dan200.computercraft.api.lua.ArgumentHelper}.
*/
@Deprecated
public final class ArgumentHelper
{
private ArgumentHelper()
{
throw new IllegalStateException( "Cannot instantiate singleton " + getClass().getName() );
}
@Nonnull
public static String getType( @Nullable Object type )
{
if( type == null ) return "nil";
if( type instanceof String ) return "string";
if( type instanceof Boolean ) return "boolean";
if( type instanceof Number ) return "number";
if( type instanceof Map ) return "table";
Class<?> klass = type.getClass();
if( klass.isArray() )
{
StringBuilder name = new StringBuilder();
while( klass.isArray() )
{
name.append( "[]" );
klass = klass.getComponentType();
}
name.insert( 0, klass.getName() );
return name.toString();
}
else
{
return klass.getName();
}
return dan200.computercraft.api.lua.ArgumentHelper.getType( type );
}
@Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nullable Object actual )
{
return badArgument( index, expected, getType( actual ) );
return dan200.computercraft.api.lua.ArgumentHelper.badArgumentOf( index, expected, actual );
}
@Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
{
return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
return dan200.computercraft.api.lua.ArgumentHelper.badArgument( index, expected, actual );
}
public static double getNumber( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( value instanceof Number )
{
return ((Number) value).doubleValue();
}
else
{
throw badArgument( index, "number", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.getDouble( args, index );
}
public static int getInt( @Nonnull Object[] args, int index ) throws LuaException
{
return (int) getLong( args, index );
return dan200.computercraft.api.lua.ArgumentHelper.getInt( args, index );
}
public static long getLong( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( value instanceof Number )
{
return checkReal( index, (Number) value ).longValue();
}
else
{
throw badArgument( index, "number", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.getLong( args, index );
}
public static double getReal( @Nonnull Object[] args, int index ) throws LuaException
{
return checkReal( index, getNumber( args, index ) );
return dan200.computercraft.api.lua.ArgumentHelper.getFiniteDouble( args, index );
}
public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "boolean", "nil" );
Object value = args[index];
if( value instanceof Boolean )
{
return (Boolean) value;
}
else
{
throw badArgument( index, "boolean", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.getBoolean( args, index );
}
@Nonnull
public static String getString( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "string", "nil" );
Object value = args[index];
if( value instanceof String )
{
return (String) value;
}
else
{
throw badArgument( index, "string", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.getString( args, index );
}
@SuppressWarnings( "unchecked" )
@Nonnull
@SuppressWarnings( "unchecked" )
public static Map<Object, Object> getTable( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "table", "nil" );
Object value = args[index];
if( value instanceof Map )
{
return (Map<Object, Object>) value;
}
else
{
throw badArgument( index, "table", value );
}
return (Map<Object, Object>) dan200.computercraft.api.lua.ArgumentHelper.getTable( args, index );
}
public static double optNumber( @Nonnull Object[] args, int index, double def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof Number )
{
return ((Number) value).doubleValue();
}
else
{
throw badArgument( index, "number", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.optDouble( args, index, def );
}
public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException
{
return (int) optLong( args, index, def );
return dan200.computercraft.api.lua.ArgumentHelper.optInt( args, index, def );
}
public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof Number )
{
return checkReal( index, (Number) value ).longValue();
}
else
{
throw badArgument( index, "number", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.optLong( args, index, def );
}
public static double optReal( @Nonnull Object[] args, int index, double def ) throws LuaException
{
return checkReal( index, optNumber( args, index, def ) );
return dan200.computercraft.api.lua.ArgumentHelper.optFiniteDouble( args, index, def );
}
public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof Boolean )
{
return (Boolean) value;
}
else
{
throw badArgument( index, "boolean", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.optBoolean( args, index, def );
}
public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof String )
{
return (String) value;
}
else
{
throw badArgument( index, "string", value );
}
return dan200.computercraft.api.lua.ArgumentHelper.optString( args, index, def );
}
@SuppressWarnings( "unchecked" )
public static Map<Object, Object> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null )
{
return def;
}
else if( value instanceof Map )
{
return (Map<Object, Object>) value;
}
else
{
throw badArgument( index, "table", value );
}
}
private static Number checkReal( int index, Number value ) throws LuaException
{
checkReal( index, value.doubleValue() );
return value;
}
private static double checkReal( int index, double value ) throws LuaException
{
if( Double.isNaN( value ) )
{
throw badArgument( index, "number", "nan" );
}
else if( value == Double.POSITIVE_INFINITY )
{
throw badArgument( index, "number", "inf" );
}
else if( value == Double.NEGATIVE_INFINITY )
{
throw badArgument( index, "number", "-inf" );
}
else
{
return value;
}
return (Map<Object, Object>) dan200.computercraft.api.lua.ArgumentHelper.optTable( args, index, def );
}
}

View File

@@ -27,7 +27,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class FSAPI implements ILuaAPI
{

View File

@@ -23,7 +23,7 @@ import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
import static dan200.computercraft.core.apis.TableHelper.*;
public class HTTPAPI implements ILuaAPI
@@ -89,7 +89,7 @@ public class HTTPAPI implements ILuaAPI
case 0: // request
{
String address, postString, requestMethod;
Map<Object, Object> headerTable;
Map<?, ?> headerTable;
boolean binary, redirect;
if( args.length >= 1 && args[0] instanceof Map )
@@ -172,7 +172,7 @@ public class HTTPAPI implements ILuaAPI
case 2: // websocket
{
String address = getString( args, 0 );
Map<Object, Object> headerTbl = optTable( args, 1, Collections.emptyMap() );
Map<?, ?> headerTbl = optTable( args, 1, Collections.emptyMap() );
if( !ComputerCraft.http_websocket_enable )
{

View File

@@ -19,7 +19,7 @@ import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatterBuilder;
import java.util.*;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class OSAPI implements ILuaAPI
{
@@ -229,7 +229,7 @@ public class OSAPI implements ILuaAPI
case 1:
{
// startTimer
double timer = getReal( args, 0 );
double timer = getFiniteDouble( args, 0 );
synchronized( m_timers )
{
m_timers.put( m_nextTimerToken, new Timer( (int) Math.round( timer / 0.05 ) ) );
@@ -239,7 +239,7 @@ public class OSAPI implements ILuaAPI
case 2:
{
// setAlarm
double time = getReal( args, 0 );
double time = getFiniteDouble( args, 0 );
if( time < 0.0 || time >= 24.0 )
{
throw new LuaException( "Number out of range" );

View File

@@ -22,7 +22,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChangeListener
{

View File

@@ -15,7 +15,7 @@ import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class RedstoneAPI implements ILuaAPI
{

View File

@@ -6,14 +6,17 @@
package dan200.computercraft.core.apis;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.LuaException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
import static dan200.computercraft.api.lua.ArgumentHelper.getNumericType;
/**
* Various helpers for tables
* Various helpers for tables.
*/
public final class TableHelper
{
@@ -200,21 +203,7 @@ public final class TableHelper
private static double checkReal( @Nonnull String key, double value ) throws LuaException
{
if( Double.isNaN( value ) )
{
throw badKey( key, "number", "nan" );
}
else if( value == Double.POSITIVE_INFINITY )
{
throw badKey( key, "number", "inf" );
}
else if( value == Double.NEGATIVE_INFINITY )
{
throw badKey( key, "number", "-inf" );
}
else
{
return value;
}
if( !Double.isFinite( value ) ) throw badKey( key, "number", getNumericType( value ) );
return value;
}
}

View File

@@ -17,7 +17,7 @@ import org.apache.commons.lang3.ArrayUtils;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class TermAPI implements ILuaAPI
{
@@ -242,9 +242,9 @@ public class TermAPI implements ILuaAPI
}
else
{
double r = getReal( args, 1 );
double g = getReal( args, 2 );
double b = getReal( args, 3 );
double r = getFiniteDouble( args, 1 );
double g = getFiniteDouble( args, 2 );
double b = getFiniteDouble( args, 3 );
setColour( m_terminal, colour, r, g, b );
}
return null;

View File

@@ -21,8 +21,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean;
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
public class BinaryReadableHandle extends HandleGeneric
{

View File

@@ -7,9 +7,9 @@
package dan200.computercraft.core.apis.handles;
import com.google.common.collect.ObjectArrays;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.core.apis.ArgumentHelper;
import dan200.computercraft.shared.util.StringUtil;
import javax.annotation.Nonnull;
@@ -73,7 +73,7 @@ public class BinaryWritableHandle extends HandleGeneric
}
else
{
throw ArgumentHelper.badArgument( 0, "string or number", args.length > 0 ? args[0] : null );
throw ArgumentHelper.badArgumentOf( 0, "string or number", args.length > 0 ? args[0] : null );
}
return null;
}

View File

@@ -20,8 +20,8 @@ import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean;
import static dan200.computercraft.core.apis.ArgumentHelper.optInt;
import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
import static dan200.computercraft.api.lua.ArgumentHelper.optInt;
public class EncodedReadableHandle extends HandleGeneric
{

View File

@@ -16,8 +16,8 @@ import java.io.IOException;
import java.nio.channels.Channel;
import java.nio.channels.SeekableByteChannel;
import static dan200.computercraft.core.apis.ArgumentHelper.optLong;
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
import static dan200.computercraft.api.lua.ArgumentHelper.optLong;
import static dan200.computercraft.api.lua.ArgumentHelper.optString;
public abstract class HandleGeneric implements ILuaObject
{
@@ -47,7 +47,7 @@ public abstract class HandleGeneric implements ILuaObject
}
/**
* Shared implementation for various file handle types
* Shared implementation for various file handle types.
*
* @param channel The channel to seek in
* @param args The Lua arguments to process, like Lua's {@code file:seek}.

View File

@@ -99,7 +99,7 @@ public final class NetworkUtils
}
/**
* Checks a host is allowed
* Checks a host is allowed.
*
* @param host The domain to check against
* @throws HTTPRequestException If the host is not permitted.

View File

@@ -20,6 +20,8 @@ import java.util.function.Consumer;
/**
* A holder for one or more resources, with a lifetime.
*
* @param <T> The type of this resource. Should be the class extending from {@link Resource}.
*/
public abstract class Resource<T extends Resource<T>> implements Closeable
{
@@ -42,8 +44,9 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
}
/**
* Checks if this has been cancelled. If so, it'll clean up any
* existing resources and cancel any pending futures.
* Checks if this has been cancelled. If so, it'll clean up any existing resources and cancel any pending futures.
*
* @return Whether this resource has been closed.
*/
public final boolean checkClosed()
{
@@ -80,6 +83,7 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
/**
* Create a {@link WeakReference} which will close {@code this} when collected.
*
* @param <R> The object we are wrapping in a reference.
* @param object The object to reference to
* @return The weak reference.
*/

View File

@@ -14,6 +14,8 @@ import java.util.function.Supplier;
/**
* A collection of {@link Resource}s, with an upper bound on capacity.
*
* @param <T> The type of the resource this group manages.
*/
public class ResourceGroup<T extends Resource<T>>
{

View File

@@ -12,6 +12,8 @@ import java.util.function.Supplier;
/**
* A {@link ResourceGroup} which will queue items when the group at capacity.
*
* @param <T> The type of the resource this queue manages.
*/
public class ResourceQueue<T extends Resource<T>> extends ResourceGroup<T>
{

View File

@@ -40,7 +40,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Represents one or more
* Represents an in-progress HTTP request.
*/
public class HttpRequest extends Resource<HttpRequest>
{

View File

@@ -226,7 +226,11 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpOb
}
/**
* Determine the redirect from this response
* Determine the redirect from this response.
*
* @param status The status of the HTTP response.
* @param headers The headers of the HTTP response.
* @return The URI to redirect to, or {@code null} if no redirect should occur.
*/
private URI getRedirect( HttpResponseStatus status, HttpHeaders headers )
{

View File

@@ -23,7 +23,7 @@ import javax.annotation.Nullable;
import java.io.Closeable;
import java.util.Arrays;
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean;
import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
import static dan200.computercraft.core.apis.http.websocket.Websocket.CLOSE_EVENT;
import static dan200.computercraft.core.apis.http.websocket.Websocket.MESSAGE_EVENT;

View File

@@ -268,7 +268,7 @@ final class ComputerExecutor
}
/**
* Queue an event if the computer is on
* Queue an event if the computer is on.
*
* @param event The event's name
* @param args The event's arguments

View File

@@ -50,7 +50,7 @@ import static dan200.computercraft.core.computer.TimeoutState.TIMEOUT;
public final class ComputerThread
{
/**
* How often the computer thread monitor should run, in milliseconds
* How often the computer thread monitor should run, in milliseconds.
*
* @see Monitor
*/
@@ -83,7 +83,7 @@ public final class ComputerThread
private static final Object threadLock = new Object();
/**
* Whether the computer thread system is currently running
* Whether the computer thread system is currently running.
*/
private static volatile boolean running = false;
@@ -105,7 +105,7 @@ public final class ComputerThread
private static final Condition hasWork = computerLock.newCondition();
/**
* Active queues to execute
* Active queues to execute.
*/
private static final TreeSet<ComputerExecutor> computerQueue = new TreeSet<>( ( a, b ) -> {
if( a == b ) return 0; // Should never happen, but let's be consistent here
@@ -126,7 +126,7 @@ public final class ComputerThread
private ComputerThread() {}
/**
* Start the computer thread
* Start the computer thread.
*/
static void start()
{
@@ -194,7 +194,7 @@ public final class ComputerThread
}
/**
* Mark a computer as having work, enqueuing it on the thread
* Mark a computer as having work, enqueuing it on the thread.
*
* You must be holding {@link ComputerExecutor}'s {@code queueLock} when calling this method - it should only
* be called from {@code enqueue}.
@@ -244,6 +244,8 @@ public final class ComputerThread
* {@link #minimumVirtualRuntime} based on the current tasks.
*
* This is called before queueing tasks, to ensure that {@link #minimumVirtualRuntime} is up-to-date.
*
* @param current The machine which we updating runtimes from.
*/
private static void updateRuntimes( @Nullable ComputerExecutor current )
{
@@ -321,7 +323,7 @@ public final class ComputerThread
}
/**
* The scaled period for a single task
* The scaled period for a single task.
*
* @return The scaled period for the task
* @see #DEFAULT_LATENCY
@@ -336,7 +338,7 @@ public final class ComputerThread
}
/**
* Determine if the thread has computers queued up
* Determine if the thread has computers queued up.
*
* @return If we have work queued up.
*/

View File

@@ -36,12 +36,12 @@ import java.util.concurrent.TimeUnit;
public final class TimeoutState
{
/**
* The total time a task is allowed to run before aborting in nanoseconds
* The total time a task is allowed to run before aborting in nanoseconds.
*/
static final long TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 7000 );
/**
* The time the task is allowed to run after each abort in nanoseconds
* The time the task is allowed to run after each abort in nanoseconds.
*/
static final long ABORT_TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 1500 );
@@ -111,6 +111,8 @@ public final class TimeoutState
/**
* If the machine should be passively aborted.
*
* @return {@code true} if we should throw a timeout error.
*/
public boolean isSoftAborted()
{
@@ -118,7 +120,9 @@ public final class TimeoutState
}
/**
* If the machine should be forcibly aborted.
* Determine if the machine should be forcibly aborted.
*
* @return {@code true} if the machine should be forcibly shut down.
*/
public boolean isHardAborted()
{
@@ -146,7 +150,7 @@ public final class TimeoutState
}
/**
* Pauses the cumulative time, to be resumed by {@link #startTimer()}
* Pauses the cumulative time, to be resumed by {@link #startTimer()}.
*
* @see #nanoCumulative()
*/

View File

@@ -38,7 +38,7 @@ public final class MachineResult
public static final MachineResult TIMEOUT = new MachineResult( true, false, TimeoutState.ABORT_MESSAGE );
/**
* An error with no user-friendly error message
* An error with no user-friendly error message.
*/
public static final MachineResult GENERIC_ERROR = new MachineResult( true, false, null );

View File

@@ -314,6 +314,9 @@ public class Terminal
}
/**
* Determine whether this terminal has changed.
*
* @return If this terminal is dirty.
* @deprecated All {@code *Changed()} methods are deprecated: one should pass in a callback
* instead.
*/

View File

@@ -54,8 +54,8 @@ public final class Config
private static Property httpEnable;
private static Property httpWebsocketEnable;
private static Property httpWhitelist;
private static Property httpBlacklist;
private static Property httpAllowedDomains;
private static Property httpBlockedDomains;
private static Property httpTimeout;
private static Property httpMaxRequests;
@@ -163,30 +163,32 @@ public final class Config
{ // HTTP
renameProperty( CATEGORY_GENERAL, "http_enable", CATEGORY_HTTP, "enabled" );
renameProperty( CATEGORY_GENERAL, "http_websocket_enable", CATEGORY_HTTP, "websocket_enabled" );
renameProperty( CATEGORY_GENERAL, "http_whitelist", CATEGORY_HTTP, "whitelist" );
renameProperty( CATEGORY_GENERAL, "http_blacklist", CATEGORY_HTTP, "blacklist" );
renameProperty( CATEGORY_GENERAL, "http_whitelist", CATEGORY_HTTP, "allowed_domains" );
renameProperty( CATEGORY_GENERAL, "http_blacklist", CATEGORY_HTTP, "blocked_domains" );
renameProperty( CATEGORY_HTTP, "whitelist", CATEGORY_HTTP, "allowed_domains" );
renameProperty( CATEGORY_HTTP, "blacklist", CATEGORY_HTTP, "blocked_domains" );
config.getCategory( CATEGORY_HTTP )
.setComment( "Controls the HTTP API" );
httpEnable = config.get( CATEGORY_HTTP, "enabled", ComputerCraft.http_enable );
httpEnable.setComment( "Enable the \"http\" API on Computers (see \"http_whitelist\" and \"http_blacklist\" for " +
"more fine grained control than this)" );
httpEnable.setComment( "Enable the \"http\" API on Computers (see \"allowed_domains\" and \"blocked_domains\" " +
"for more fine grained control than this)" );
httpWebsocketEnable = config.get( CATEGORY_HTTP, "websocket_enabled", ComputerCraft.http_websocket_enable );
httpWebsocketEnable.setComment( "Enable use of http websockets. This requires the \"http_enable\" option to also be true." );
httpWhitelist = config.get( CATEGORY_HTTP, "whitelist", DEFAULT_HTTP_WHITELIST );
httpWhitelist.setComment( "A list of wildcards for domains or IP ranges that can be accessed through the " +
httpAllowedDomains = config.get( CATEGORY_HTTP, "allowed_domains", DEFAULT_HTTP_WHITELIST );
httpAllowedDomains.setComment( "A list of wildcards for domains or IP ranges that can be accessed through the " +
"\"http\" API on Computers.\n" +
"Set this to \"*\" to access to the entire internet. Example: \"*.pastebin.com\" will restrict access to " +
"just subdomains of pastebin.com.\n" +
"You can use domain names (\"pastebin.com\"), wilcards (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\")." );
httpBlacklist = config.get( CATEGORY_HTTP, "blacklist", DEFAULT_HTTP_BLACKLIST );
httpBlacklist.setComment( "A list of wildcards for domains or IP ranges that cannot be accessed through the " +
httpBlockedDomains = config.get( CATEGORY_HTTP, "blocked_domains", DEFAULT_HTTP_BLACKLIST );
httpBlockedDomains.setComment( "A list of wildcards for domains or IP ranges that cannot be accessed through the " +
"\"http\" API on Computers.\n" +
"If this is empty then all whitelisted domains will be accessible. Example: \"*.github.com\" will block " +
"If this is empty then all explicitly allowed domains will be accessible. Example: \"*.github.com\" will block " +
"access to all subdomains of github.com.\n" +
"You can use domain names (\"pastebin.com\"), wilcards (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\")." );
@@ -220,7 +222,7 @@ public final class Config
setOrder(
CATEGORY_HTTP,
httpEnable, httpWebsocketEnable, httpWhitelist, httpBlacklist,
httpEnable, httpWebsocketEnable, httpAllowedDomains, httpBlockedDomains,
httpTimeout, httpMaxRequests, httpMaxDownload, httpMaxUpload, httpMaxWebsockets, httpMaxWebsocketMessage
);
}
@@ -277,7 +279,7 @@ public final class Config
renameProperty( CATEGORY_GENERAL, "turtlesCanPush", CATEGORY_TURTLE, "can_push" );
renameProperty( CATEGORY_GENERAL, "turtle_disabled_actions", CATEGORY_TURTLE, "disabled_actions" );
config.getCategory( CATEGORY_HTTP )
config.getCategory( CATEGORY_TURTLE )
.setComment( "Various options relating to turtles." );
turtlesNeedFuel = config.get( CATEGORY_TURTLE, "need_fuel", ComputerCraft.turtlesNeedFuel );
@@ -441,8 +443,8 @@ public final class Config
// HTTP
ComputerCraft.http_enable = httpEnable.getBoolean();
ComputerCraft.http_websocket_enable = httpWebsocketEnable.getBoolean();
ComputerCraft.http_whitelist = new AddressPredicate( httpWhitelist.getStringList() );
ComputerCraft.http_blacklist = new AddressPredicate( httpBlacklist.getStringList() );
ComputerCraft.http_whitelist = new AddressPredicate( httpAllowedDomains.getStringList() );
ComputerCraft.http_blacklist = new AddressPredicate( httpBlockedDomains.getStringList() );
ComputerCraft.httpTimeout = Math.max( 0, httpTimeout.getInt() );
ComputerCraft.httpMaxRequests = Math.max( 1, httpMaxRequests.getInt() );

View File

@@ -19,12 +19,35 @@ import net.minecraftforge.fml.common.ModContainer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Stream;
public final class TurtleUpgrades
{
public static class Wrapper
{
final ITurtleUpgrade upgrade;
final int legacyId;
final String id;
final String modId;
boolean enabled;
public Wrapper( ITurtleUpgrade upgrade )
{
ModContainer mc = Loader.instance().activeModContainer();
this.upgrade = upgrade;
this.legacyId = upgrade.getLegacyUpgradeID();
this.id = upgrade.getUpgradeID().toString();
this.modId = mc != null && mc.getModId() != null ? mc.getModId() : null;
this.enabled = true;
}
}
private static ITurtleUpgrade[] vanilla;
private static final Map<String, ITurtleUpgrade> upgrades = new HashMap<>();
private static final Int2ObjectMap<ITurtleUpgrade> legacyUpgrades = new Int2ObjectOpenHashMap<>();
private static final IdentityHashMap<ITurtleUpgrade, String> upgradeOwners = new IdentityHashMap<>();
private static final IdentityHashMap<ITurtleUpgrade, Wrapper> wrappers = new IdentityHashMap<>();
private TurtleUpgrades() {}
@@ -35,9 +58,7 @@ public final class TurtleUpgrades
int id = upgrade.getLegacyUpgradeID();
if( id >= 0 && id < 64 )
{
String message = getMessage( upgrade, "Legacy UpgradeID '" + id + "' is reserved by ComputerCraft" );
ComputerCraft.log.error( message );
throw new RuntimeException( message );
throw registrationError( upgrade, "Legacy Upgrade ID '" + id + "' is reserved by ComputerCraft" );
}
registerInternal( upgrade );
@@ -47,58 +68,63 @@ public final class TurtleUpgrades
{
Objects.requireNonNull( upgrade, "upgrade cannot be null" );
Wrapper wrapper = new Wrapper( upgrade );
// Check conditions
int legacyId = upgrade.getLegacyUpgradeID();
int legacyId = wrapper.legacyId;
if( legacyId >= 0 )
{
if( legacyId >= Short.MAX_VALUE )
{
String message = getMessage( upgrade, "UpgradeID '" + legacyId + "' is out of range" );
ComputerCraft.log.error( message );
throw new RuntimeException( message );
throw registrationError( upgrade, "Upgrade ID '" + legacyId + "' is out of range" );
}
ITurtleUpgrade existing = legacyUpgrades.get( legacyId );
if( existing != null )
{
String message = getMessage( upgrade, "UpgradeID '" + legacyId + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
ComputerCraft.log.error( message );
throw new RuntimeException( message );
throw registrationError( upgrade, "Upgrade ID '" + legacyId + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
}
}
String id = upgrade.getUpgradeID().toString();
String id = wrapper.id;
ITurtleUpgrade existing = upgrades.get( id );
if( existing != null )
{
String message = getMessage( upgrade, "UpgradeID '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
ComputerCraft.log.error( message );
throw new RuntimeException( message );
throw registrationError( upgrade, "Upgrade '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
}
// Register
if( legacyId >= 0 ) legacyUpgrades.put( legacyId, upgrade );
upgrades.put( id, upgrade );
ModContainer mc = Loader.instance().activeModContainer();
if( mc != null && mc.getModId() != null ) upgradeOwners.put( upgrade, mc.getModId() );
wrappers.put( upgrade, wrapper );
}
private static String getMessage( ITurtleUpgrade upgrade, String rest )
private static RuntimeException registrationError( ITurtleUpgrade upgrade, String rest )
{
return "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. " + rest;
String message = "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. " + rest;
ComputerCraft.log.error( message );
throw new IllegalArgumentException( message );
}
@Nullable
public static ITurtleUpgrade get( String id )
{
return upgrades.get( id );
}
@Nullable
public static ITurtleUpgrade get( int id )
{
return legacyUpgrades.get( id );
}
@Nullable
public static String getOwner( @Nonnull ITurtleUpgrade upgrade )
{
Wrapper wrapper = wrappers.get( upgrade );
return wrapper != null ? wrapper.modId : null;
}
public static ITurtleUpgrade get( @Nonnull ItemStack stack )
{
if( stack.isEmpty() ) return null;
@@ -115,25 +141,24 @@ public final class TurtleUpgrades
return null;
}
public static Iterable<ITurtleUpgrade> getVanillaUpgrades()
public static Stream<ITurtleUpgrade> getVanillaUpgrades()
{
List<ITurtleUpgrade> vanilla = new ArrayList<>();
vanilla.add( ComputerCraft.TurtleUpgrades.diamondPickaxe );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondAxe );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondSword );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondShovel );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondHoe );
vanilla.add( ComputerCraft.TurtleUpgrades.craftingTable );
vanilla.add( ComputerCraft.TurtleUpgrades.wirelessModem );
vanilla.add( ComputerCraft.TurtleUpgrades.advancedModem );
vanilla.add( ComputerCraft.TurtleUpgrades.speaker );
return vanilla;
}
if( vanilla == null )
{
vanilla = new ITurtleUpgrade[] {
ComputerCraft.TurtleUpgrades.diamondPickaxe,
ComputerCraft.TurtleUpgrades.diamondAxe,
ComputerCraft.TurtleUpgrades.diamondSword,
ComputerCraft.TurtleUpgrades.diamondShovel,
ComputerCraft.TurtleUpgrades.diamondHoe,
ComputerCraft.TurtleUpgrades.craftingTable,
ComputerCraft.TurtleUpgrades.wirelessModem,
ComputerCraft.TurtleUpgrades.advancedModem,
ComputerCraft.TurtleUpgrades.speaker,
};
}
@Nullable
public static String getOwner( @Nonnull ITurtleUpgrade upgrade )
{
return upgradeOwners.get( upgrade );
return Arrays.stream( vanilla ).filter( x -> x != null && wrappers.get( x ).enabled );
}
public static Iterable<ITurtleUpgrade> getUpgrades()
@@ -145,4 +170,14 @@ public final class TurtleUpgrades
{
return true;
}
public static void disable( ITurtleUpgrade upgrade )
{
Wrapper wrapper = wrappers.get( upgrade );
if( !wrapper.enabled ) return;
wrapper.enabled = false;
upgrades.remove( wrapper.id );
if( wrapper.legacyId >= 0 ) legacyUpgrades.remove( wrapper.legacyId );
}
}

View File

@@ -18,7 +18,7 @@ import java.util.List;
import java.util.Map;
/**
* A command which delegates to a series of sub commands
* A command which delegates to a series of sub commands.
*/
public class CommandRoot implements ISubCommand
{

View File

@@ -22,7 +22,7 @@ import java.util.List;
public interface ISubCommand
{
/**
* Get the name of this command
* Get the name of this command.
*
* @return The name of this command
* @see ICommand#getName()
@@ -40,7 +40,7 @@ public interface ISubCommand
String getFullName();
/**
* Get the usage of this command
* Get the usage of this command.
*
* @param context The context this command is executed in
* @return The usage of this command
@@ -62,16 +62,17 @@ public interface ISubCommand
boolean checkPermission( @Nonnull CommandContext context );
/**
* Execute this command
* Execute this command.
*
* @param context The current command context.
* @param arguments The arguments passed @throws CommandException When an error occurs
* @param arguments The arguments passed
* @throws CommandException When an error occurs
* @see ICommand#execute(MinecraftServer, ICommandSender, String[])
*/
void execute( @Nonnull CommandContext context, @Nonnull List<String> arguments ) throws CommandException;
/**
* Get a list of possible completions
* Get a list of possible completions.
*
* @param context The current command context.
* @param arguments The arguments passed. You should complete the last one.

View File

@@ -15,7 +15,7 @@ import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent;
/**
* Various helpers for building chat messages
* Various helpers for building chat messages.
*/
public final class ChatHelpers
{

View File

@@ -107,7 +107,7 @@ public class TableBuilder
}
/**
* Trim this table to a given height
* Trim this table to a given height.
*
* @param height The desired height.
*/

View File

@@ -22,7 +22,7 @@ public interface TableFormatter
ITextComponent HEADER = coloured( "=", TextFormatting.GRAY );
/**
* Get additional padding for the component
* Get additional padding for the component.
*
* @param component The component to pad
* @param width The desired width for the component
@@ -32,7 +32,7 @@ public interface TableFormatter
ITextComponent getPadding( ITextComponent component, int width );
/**
* Get the minimum padding between each column
* Get the minimum padding between each column.
*
* @return The minimum padding.
*/

View File

@@ -30,8 +30,8 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class CommandAPI implements ILuaAPI
{
@@ -83,7 +83,7 @@ public class CommandAPI implements ILuaAPI
{
sender.clearOutput();
int result = commandManager.executeCommand( sender, command );
return new Object[] { result > 0, sender.copyOutput() };
return new Object[] { result > 0, sender.copyOutput(), result };
}
catch( Throwable t )
{
@@ -204,7 +204,7 @@ public class CommandAPI implements ILuaAPI
);
if( !world.isValid( min ) || !world.isValid( max ) )
{
throw new LuaException( "Co-ordinates out or range" );
throw new LuaException( "Co-ordinates out of range" );
}
if( (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1) > 4096 )
{
@@ -243,7 +243,7 @@ public class CommandAPI implements ILuaAPI
}
else
{
throw new LuaException( "co-ordinates out or range" );
throw new LuaException( "Co-ordinates out of range" );
}
} );
}

View File

@@ -280,7 +280,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
}
/**
* Gets the redstone input for an adjacent block
* Gets the redstone input for an adjacent block.
*
* @param world The world we exist in
* @param pos The position of the neighbour

View File

@@ -7,7 +7,7 @@
package dan200.computercraft.shared.computer.core;
/**
* Receives some input and forwards it to a computer
* Receives some input and forwards it to a computer.
*
* @see InputState
* @see IComputer

View File

@@ -0,0 +1,70 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker;
import crafttweaker.CraftTweakerAPI;
import crafttweaker.annotations.ModOnly;
import crafttweaker.annotations.ZenDoc;
import crafttweaker.annotations.ZenRegister;
import crafttweaker.api.item.IItemStack;
import crafttweaker.api.minecraft.CraftTweakerMC;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.integration.crafttweaker.actions.AddTurtleTool;
import dan200.computercraft.shared.integration.crafttweaker.actions.RemoveTurtleUpgradeByItem;
import dan200.computercraft.shared.integration.crafttweaker.actions.RemoveTurtleUpgradeByName;
import stanhebben.zenscript.annotations.ZenClass;
import stanhebben.zenscript.annotations.ZenMethod;
@ZenRegister
@ZenClass( "dan200.computercraft.turtle" )
@ModOnly( ComputerCraft.MOD_ID )
public class TurtleTweaker
{
@ZenMethod
@ZenDoc( "Remove a turtle upgrade with the given id" )
public static void removeUpgrade( String upgrade )
{
CraftTweakerAPI.apply( new RemoveTurtleUpgradeByName( upgrade ) );
}
@ZenMethod
@ZenDoc( "Remove a turtle upgrade crafted with the given item stack" )
public static void removeUpgrade( IItemStack stack )
{
CraftTweakerAPI.apply( new RemoveTurtleUpgradeByItem( CraftTweakerMC.getItemStack( stack ) ) );
}
@ZenMethod
@ZenDoc( "Add a new turtle tool with the given id, which crafts and acts using the given stack." )
public static void addTool( String id, IItemStack stack )
{
addTool( id, stack, stack, "tool" );
}
@ZenMethod
@ZenDoc( "Add a new turtle tool with the given id, which is crafted with one item, and uses another." )
public static void addTool( String id, IItemStack craftingStack, IItemStack toolStack )
{
addTool( id, craftingStack, toolStack, "tool" );
}
@ZenMethod
@ZenDoc( "Add a new turtle tool with the given id, which crafts and acts using the given stack. You may also" +
"specify a 'kind' of tool, which limits what blocks the turtle can break (for instance, an 'axe' may only break wood)." )
public static void addTool( String id, IItemStack stack, String kind )
{
addTool( id, stack, stack, kind );
}
@ZenMethod
@ZenDoc( "Add a new turtle tool with the given id, which is crafted with one item, and uses another. You may also" +
"specify a 'kind' of tool, which limits what blocks the turtle can break (for instance, an 'axe' may only break wood)." )
public static void addTool( String id, IItemStack craftingStack, IItemStack toolStack, String kind )
{
CraftTweakerAPI.apply( new AddTurtleTool( id, CraftTweakerMC.getItemStack( craftingStack ), CraftTweakerMC.getItemStack( toolStack ), kind ) );
}
}

View File

@@ -0,0 +1,96 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.TurtleUpgrades;
import dan200.computercraft.shared.turtle.upgrades.*;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* Register a new turtle tool.
*/
public class AddTurtleTool implements IAction
{
private interface Factory
{
TurtleTool create( ResourceLocation location, ItemStack craftItem, ItemStack toolItem );
}
private static final Map<String, Factory> kinds = new HashMap<>();
static
{
kinds.put( "tool", TurtleTool::new );
kinds.put( "axe", TurtleAxe::new );
kinds.put( "hoe", TurtleHoe::new );
kinds.put( "shovel", TurtleShovel::new );
kinds.put( "sword", TurtleSword::new );
}
private final String id;
private final ItemStack craftItem;
private final ItemStack toolItem;
private final String kind;
public AddTurtleTool( String id, ItemStack craftItem, ItemStack toolItem, String kind )
{
this.id = id;
this.craftItem = craftItem;
this.toolItem = toolItem;
this.kind = kind;
}
@Override
public void apply()
{
Factory factory = kinds.get( kind );
if( factory == null )
{
ComputerCraft.log.error( "Unknown turtle upgrade kind '{}' (this should have been rejected by verify!)", kind );
return;
}
try
{
TurtleUpgrades.register( factory.create( new ResourceLocation( id ), craftItem, toolItem ) );
}
catch( RuntimeException e )
{
ComputerCraft.log.error( "Registration of turtle tool failed", e );
}
}
@Override
public String describe()
{
return String.format( "Add new turtle %s '%s' (crafted with '%s', uses a '%s')", kind, id, craftItem, toolItem );
}
public Optional<String> getValidationProblem()
{
if( craftItem.isEmpty() ) return Optional.of( "Crafting item stack is empty." );
if( craftItem.hasTagCompound() && !craftItem.getTagCompound().isEmpty() )
{
return Optional.of( "Crafting item has NBT." );
}
if( toolItem.isEmpty() ) return Optional.of( "Tool item stack is empty." );
if( !kinds.containsKey( kind ) ) return Optional.of( String.format( "Unknown kind '%s'.", kind ) );
if( TurtleUpgrades.get( id ) != null )
{
return Optional.of( String.format( "An upgrade with the same name ('%s') has already been registered.", id ) );
}
return Optional.empty();
}
}

View File

@@ -0,0 +1,32 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import java.util.Optional;
/**
* An extension of {@link IAction} with a single validation function, rather than two.
*/
public interface IAction extends crafttweaker.IAction
{
default Optional<String> getValidationProblem()
{
return Optional.empty();
}
@Override
default boolean validate()
{
return !getValidationProblem().isPresent();
}
@Override
default String describeInvalid()
{
return getValidationProblem().orElse( "No problems found." );
}
}

View File

@@ -0,0 +1,50 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.TurtleUpgrades;
import net.minecraft.item.ItemStack;
import java.util.Optional;
/**
* Removes a turtle upgrade crafted with the given stack.
*/
public class RemoveTurtleUpgradeByItem implements IAction
{
private final ItemStack stack;
public RemoveTurtleUpgradeByItem( ItemStack stack )
{
this.stack = stack;
}
@Override
public void apply()
{
ITurtleUpgrade upgrade = TurtleUpgrades.get( stack );
if( upgrade != null ) TurtleUpgrades.disable( upgrade );
}
@Override
public String describe()
{
return String.format( "Remove turtle upgrades crafted with '%s'", stack );
}
@Override
public Optional<String> getValidationProblem()
{
if( TurtleUpgrades.get( stack ) == null )
{
return Optional.of( String.format( "Unknown turtle upgrade crafted with '%s'.", stack ) );
}
return Optional.empty();
}
}

View File

@@ -0,0 +1,49 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.TurtleUpgrades;
import java.util.Optional;
/**
* Removes a turtle upgrade with the given id.
*/
public class RemoveTurtleUpgradeByName implements IAction
{
private final String id;
public RemoveTurtleUpgradeByName( String id )
{
this.id = id;
}
@Override
public void apply()
{
ITurtleUpgrade upgrade = TurtleUpgrades.get( id );
if( upgrade != null ) TurtleUpgrades.disable( upgrade );
}
@Override
public String describe()
{
return String.format( "Remove turtle upgrade '%s'", id );
}
@Override
public Optional<String> getValidationProblem()
{
if( TurtleUpgrades.get( id ) == null )
{
return Optional.of( String.format( "Unknown turtle upgrade '%s'.", id ) );
}
return Optional.empty();
}
}

View File

@@ -108,7 +108,7 @@ public class JEIComputerCraft implements IModPlugin
}
/**
* Distinguishes turtles by upgrades and family
* Distinguishes turtles by upgrades and family.
*/
private static final ISubtypeInterpreter turtleSubtype = stack -> {
Item item = stack.getItem();
@@ -132,7 +132,7 @@ public class JEIComputerCraft implements IModPlugin
};
/**
* Distinguishes pocket computers by upgrade and family
* Distinguishes pocket computers by upgrade and family.
*/
private static final ISubtypeInterpreter pocketSubtype = stack -> {
Item item = stack.getItem();
@@ -152,7 +152,7 @@ public class JEIComputerCraft implements IModPlugin
};
/**
* Distinguishes disks by colour
* Distinguishes disks by colour.
*/
private static final ISubtypeInterpreter diskSubtype = stack -> {
Item item = stack.getItem();

View File

@@ -6,7 +6,6 @@
package dan200.computercraft.shared.media.inventory;
import dan200.computercraft.shared.util.InventoryUtil;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
@@ -22,7 +21,7 @@ public class ContainerHeldItem extends Container
public ContainerHeldItem( EntityPlayer player, EnumHand hand )
{
m_hand = hand;
m_stack = InventoryUtil.copyItem( player.getHeldItem( hand ) );
m_stack = player.getHeldItem( hand ).copy();
}
@Nonnull

View File

@@ -15,7 +15,7 @@ import net.minecraft.util.SoundEvent;
import javax.annotation.Nonnull;
/**
* An implementation of IMedia for ItemRecord's
* An implementation of IMedia for ItemRecords.
*/
public final class RecordMedia implements IMedia
{

View File

@@ -72,6 +72,7 @@ public final class NetworkHandler
* /**
* Register packet, and a thread-unsafe handler for it.
*
* @param <T> The type of the packet to send.
* @param id The identifier for this packet type
* @param side The side to register this packet handler under
* @param factory The factory for this type of packet.

View File

@@ -14,7 +14,7 @@ import net.minecraft.tileentity.TileEntityCommandBlock;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public class CommandBlockPeripheral implements IPeripheral
{

View File

@@ -19,7 +19,7 @@ import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
import static dan200.computercraft.api.lua.ArgumentHelper.optString;
class DiskDrivePeripheral implements IPeripheral
{

View File

@@ -21,7 +21,7 @@ import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Set;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPacketReceiver
{

View File

@@ -7,8 +7,11 @@
package dan200.computercraft.shared.peripheral.modem;
/**
* This only exists for backwards compatibility
* This only exists for backwards compatibility.
*
* @deprecated Use {@link dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemPeripheral} instead.
*/
@Deprecated
public abstract class WirelessModemPeripheral extends dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemPeripheral
{
@Deprecated

View File

@@ -23,7 +23,7 @@ import java.util.Collections;
import java.util.Map;
/**
* Represents a local peripheral exposed on the wired network
* Represents a local peripheral exposed on the wired network.
*
* This is responsible for getting the peripheral in world, tracking id and type and determining whether
* it has changed.
@@ -39,7 +39,7 @@ public final class WiredModemLocalPeripheral
private IPeripheral peripheral;
/**
* Attach a new peripheral from the world
* Attach a new peripheral from the world.
*
* @param world The world to search in
* @param origin The position to search from
@@ -76,7 +76,7 @@ public final class WiredModemLocalPeripheral
}
/**
* Detach the current peripheral
* Detach the current peripheral.
*
* @return Whether the peripheral changed
*/

View File

@@ -28,7 +28,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
public abstract class WiredModemPeripheral extends ModemPeripheral implements IWiredSender
{

View File

@@ -17,7 +17,7 @@ import org.apache.commons.lang3.ArrayUtils;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class MonitorPeripheral implements IPeripheral
{
@@ -123,7 +123,7 @@ public class MonitorPeripheral implements IPeripheral
case 8:
{
// setTextScale
int scale = (int) (getReal( args, 0 ) * 2.0);
int scale = (int) (getFiniteDouble( args, 0 ) * 2.0);
if( scale < 1 || scale > 10 )
{
throw new LuaException( "Expected number in range 0.5-5" );
@@ -184,9 +184,9 @@ public class MonitorPeripheral implements IPeripheral
}
else
{
double r = getReal( args, 1 );
double g = getReal( args, 2 );
double b = getReal( args, 3 );
double r = getFiniteDouble( args, 1 );
double g = getFiniteDouble( args, 2 );
double b = getFiniteDouble( args, 3 );
TermAPI.setColour( terminal, colour, r, g, b );
}
return null;

View File

@@ -15,8 +15,8 @@ import dan200.computercraft.shared.util.StringUtil;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
import static dan200.computercraft.api.lua.ArgumentHelper.optString;
public class PrinterPeripheral implements IPeripheral
{

View File

@@ -23,8 +23,8 @@ import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.concurrent.atomic.AtomicInteger;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.core.apis.ArgumentHelper.optReal;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
import static dan200.computercraft.api.lua.ArgumentHelper.optFiniteDouble;
public abstract class SpeakerPeripheral implements IPeripheral
{
@@ -84,8 +84,8 @@ public abstract class SpeakerPeripheral implements IPeripheral
case 0: // playSound
{
String name = getString( args, 0 );
float volume = (float) optReal( args, 1, 1.0 );
float pitch = (float) optReal( args, 2, 1.0 );
float volume = (float) optFiniteDouble( args, 1, 1.0 );
float pitch = (float) optFiniteDouble( args, 2, 1.0 );
return new Object[] { playSound( context, name, volume, pitch, false ) };
}
@@ -102,8 +102,8 @@ public abstract class SpeakerPeripheral implements IPeripheral
private synchronized Object[] playNote( Object[] arguments, ILuaContext context ) throws LuaException
{
String name = getString( arguments, 0 );
float volume = (float) optReal( arguments, 1, 1.0 );
float pitch = (float) optReal( arguments, 2, 1.0 );
float volume = (float) optFiniteDouble( arguments, 1, 1.0 );
float pitch = (float) optFiniteDouble( arguments, 2, 1.0 );
String noteName = "block.note." + name;

View File

@@ -27,7 +27,7 @@ import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
public class TurtleAPI implements ILuaAPI
{

View File

@@ -58,7 +58,7 @@ public class BlockTurtle extends BlockComputerBase
@Deprecated
public EnumBlockRenderType getRenderType( IBlockState state )
{
return EnumBlockRenderType.INVISIBLE;
return EnumBlockRenderType.ENTITYBLOCK_ANIMATED;
}
@Override

View File

@@ -224,7 +224,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
m_inventoryChanged = false;
for( int n = 0; n < getSizeInventory(); n++ )
{
m_previousInventory.set( n, InventoryUtil.copyItem( getStackInSlot( n ) ) );
m_previousInventory.set( n, getStackInSlot( n ).copy() );
}
}
}
@@ -268,7 +268,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
if( slot < getSizeInventory() )
{
m_inventory.set( slot, new ItemStack( tag ) );
m_previousInventory.set( slot, InventoryUtil.copyItem( m_inventory.get( slot ) ) );
m_previousInventory.set( slot, m_inventory.get( slot ).copy() );
}
}

View File

@@ -20,10 +20,7 @@ import dan200.computercraft.shared.computer.blocks.TileComputerBase;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.ColourUtils;
import dan200.computercraft.shared.util.Holiday;
import dan200.computercraft.shared.util.HolidayUtil;
import dan200.computercraft.shared.util.*;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.MoverType;
@@ -40,6 +37,7 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.InvWrapper;
import javax.annotation.Nonnull;
import java.util.*;
@@ -53,6 +51,9 @@ public class TurtleBrain implements ITurtleAccess
private ComputerProxy m_proxy;
private GameProfile m_owningPlayer;
private final IInventory m_inventory = (InventoryDelegate) () -> m_owner;
private final IItemHandlerModifiable m_inventoryWrapper = new InvWrapper( m_inventory );
private Queue<TurtleCommandQueueEntry> m_commandQueue = new ArrayDeque<>();
private int m_commandsIssued = 0;
@@ -531,14 +532,14 @@ public class TurtleBrain implements ITurtleAccess
@Override
public IInventory getInventory()
{
return m_owner;
return m_inventory;
}
@Nonnull
@Override
public IItemHandlerModifiable getItemHandler()
{
return m_owner.getItemHandler();
return m_inventoryWrapper;
}
@Override

View File

@@ -8,6 +8,7 @@ package dan200.computercraft.shared.turtle.core;
import com.mojang.authlib.GameProfile;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.shared.util.FakeNetHandler;
import dan200.computercraft.shared.util.InventoryUtil;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.entity.Entity;
@@ -37,7 +38,7 @@ public class TurtlePlayer extends FakePlayer
);
/**
* Construct a TurtlePlayer which exists in the world
* Construct a TurtlePlayer which exists in the world.
*
* @param world The world the player exists in
* @deprecated This is required by {@link Entity}.
@@ -46,11 +47,13 @@ public class TurtlePlayer extends FakePlayer
public TurtlePlayer( World world )
{
super( (WorldServer) world, DEFAULT_PROFILE );
connection = new FakeNetHandler( this );
}
private TurtlePlayer( ITurtleAccess turtle )
{
super( (WorldServer) turtle.getWorld(), getProfile( turtle.getOwningPlayer() ) );
connection = new FakeNetHandler( this );
setState( turtle );
}

View File

@@ -48,13 +48,11 @@ public abstract class ItemTurtleBase extends ItemComputerBase implements ITurtle
ItemStack normalStack = TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null );
if( !normalStack.isEmpty() && normalStack.getItem() == this ) list.add( normalStack );
for( ITurtleUpgrade upgrade : TurtleUpgrades.getVanillaUpgrades() )
{
if( !TurtleUpgrades.suitableForFamily( family, upgrade ) ) continue;
ItemStack stack = TurtleItemFactory.create( -1, null, -1, family, null, upgrade, 0, null );
if( !stack.isEmpty() && stack.getItem() == this ) list.add( stack );
}
TurtleUpgrades.getVanillaUpgrades()
.filter( x -> TurtleUpgrades.suitableForFamily( family, x ) )
.map( x -> TurtleItemFactory.create( -1, null, -1, family, null, x, 0, null ) )
.filter( x -> !x.isEmpty() && x.getItem() == this )
.forEach( list::add );
}
@Nonnull

View File

@@ -15,7 +15,7 @@ import dan200.computercraft.shared.turtle.core.TurtleCraftCommand;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.optInt;
import static dan200.computercraft.api.lua.ArgumentHelper.optInt;
public class CraftingTablePeripheral implements IPeripheral
{

View File

@@ -7,6 +7,7 @@
package dan200.computercraft.shared.turtle.upgrades;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
public class TurtleAxe extends TurtleTool
@@ -21,6 +22,11 @@ public class TurtleAxe extends TurtleTool
super( id, legacyId, item );
}
public TurtleAxe( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
{
super( id, craftItem, toolItem );
}
@Override
protected float getDamageMultiplier()
{

View File

@@ -35,6 +35,11 @@ public class TurtleHoe extends TurtleTool
super( id, legacyId, item );
}
public TurtleHoe( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
{
super( id, craftItem, toolItem );
}
@Override
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
{

View File

@@ -35,6 +35,11 @@ public class TurtleShovel extends TurtleTool
super( id, legacyId, item );
}
public TurtleShovel( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
{
super( id, craftItem, toolItem );
}
@Override
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
{

View File

@@ -10,6 +10,7 @@ import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -26,6 +27,11 @@ public class TurtleSword extends TurtleTool
super( id, legacyId, item );
}
public TurtleSword( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
{
super( id, craftItem, toolItem );
}
@Override
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
{

View File

@@ -62,6 +62,12 @@ public class TurtleTool extends AbstractTurtleUpgrade
this.item = new ItemStack( item, 1, 0 );
}
public TurtleTool( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
{
super( id, -1, TurtleUpgradeType.Tool, craftItem );
this.item = toolItem;
}
@Nonnull
@Override
@SideOnly( Side.CLIENT )
@@ -76,7 +82,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
);
Minecraft mc = Minecraft.getMinecraft();
return Pair.of(
mc.getRenderItem().getItemModelMesher().getItemModel( item ),
mc.getRenderItem().getItemModelMesher().getItemModel( getCraftingItem() ),
transform
);
}

View File

@@ -14,8 +14,6 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingDropsEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -35,7 +33,6 @@ public final class DropConsumer
private static Function<ItemStack, ItemStack> dropConsumer;
private static List<ItemStack> remainingDrops;
private static WeakReference<World> dropWorld;
private static BlockPos dropPos;
private static AxisAlignedBB dropBounds;
private static WeakReference<Entity> dropEntity;
@@ -45,7 +42,6 @@ public final class DropConsumer
remainingDrops = new ArrayList<>();
dropEntity = new WeakReference<>( entity );
dropWorld = new WeakReference<>( entity.world );
dropPos = null;
dropBounds = new AxisAlignedBB( entity.getPosition() ).grow( 2, 2, 2 );
entity.captureDrops = true;
@@ -54,10 +50,9 @@ public final class DropConsumer
public static void set( World world, BlockPos pos, Function<ItemStack, ItemStack> consumer )
{
dropConsumer = consumer;
remainingDrops = new ArrayList<>();
remainingDrops = new ArrayList<>( 2 );
dropEntity = null;
dropWorld = new WeakReference<>( world );
dropPos = pos;
dropBounds = new AxisAlignedBB( pos ).grow( 2, 2, 2 );
}
@@ -83,7 +78,6 @@ public final class DropConsumer
remainingDrops = null;
dropEntity = null;
dropWorld = null;
dropPos = null;
dropBounds = null;
return remainingStacks;
@@ -95,34 +89,7 @@ public final class DropConsumer
if( !remaining.isEmpty() ) remainingDrops.add( remaining );
}
@SubscribeEvent( priority = EventPriority.LOWEST )
public static void onEntityLivingDrops( LivingDropsEvent event )
{
// Capture any mob drops for the current entity
if( dropEntity != null && event.getEntity() == dropEntity.get() )
{
List<EntityItem> drops = event.getDrops();
for( EntityItem entityItem : drops ) handleDrops( entityItem.getItem() );
drops.clear();
}
}
@SubscribeEvent( priority = EventPriority.LOWEST )
public static void onHarvestDrops( BlockEvent.HarvestDropsEvent event )
{
// Capture block drops for the current entity
if( dropWorld != null && dropWorld.get() == event.getWorld()
&& dropPos != null && dropPos.equals( event.getPos() ) )
{
for( ItemStack item : event.getDrops() )
{
if( event.getWorld().rand.nextFloat() < event.getDropChance() ) handleDrops( item );
}
event.getDrops().clear();
}
}
@SubscribeEvent( priority = EventPriority.LOWEST )
@SubscribeEvent( priority = EventPriority.HIGHEST )
public static void onEntitySpawn( EntityJoinWorldEvent event )
{
// Capture any nearby item spawns

View File

@@ -0,0 +1,234 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.util;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import net.minecraft.network.*;
import net.minecraft.network.play.client.*;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.common.util.FakePlayer;
import javax.annotation.Nonnull;
import javax.crypto.SecretKey;
public class FakeNetHandler extends NetHandlerPlayServer
{
public static class FakeNetworkManager extends NetworkManager
{
private INetHandler handler;
public FakeNetworkManager()
{
super( EnumPacketDirection.CLIENTBOUND );
}
@Override
public void channelActive( ChannelHandlerContext context )
{
}
@Override
public void setConnectionState( @Nonnull EnumConnectionState state )
{
}
@Override
public void channelInactive( ChannelHandlerContext context )
{
}
@Override
public void exceptionCaught( ChannelHandlerContext context, @Nonnull Throwable e )
{
}
@Override
public void setNetHandler( INetHandler handler )
{
this.handler = handler;
}
@Override
public void processReceivedPackets()
{
}
@Override
public void closeChannel( @Nonnull ITextComponent channel )
{
}
@Override
public boolean isLocalChannel()
{
return false;
}
@Override
public void enableEncryption( SecretKey key )
{
}
@Override
public boolean isChannelOpen()
{
return false;
}
@Nonnull
@Override
public INetHandler getNetHandler()
{
return handler;
}
@Nonnull
@Override
public ITextComponent getExitMessage()
{
return null;
}
@Override
public void disableAutoRead()
{
}
@Nonnull
@Override
public Channel channel()
{
return null;
}
}
public FakeNetHandler( FakePlayer player )
{
this( player.server, player );
}
public FakeNetHandler( MinecraftServer server, FakePlayer player )
{
super( server, new FakeNetworkManager(), player );
}
@Override
public void processInput( CPacketInput packet )
{
}
@Override
public void processPlayer( CPacketPlayer packet )
{
}
@Override
public void setPlayerLocation( double x, double y, double z, float yaw, float pitch )
{
}
@Override
public void processPlayerDigging( CPacketPlayerDigging packet )
{
}
@Override
public void onDisconnect( @Nonnull ITextComponent chat )
{
}
@Override
@SuppressWarnings( "rawtypes" )
public void sendPacket( @Nonnull final Packet packet )
{
}
@Override
public void processHeldItemChange( CPacketHeldItemChange packet )
{
}
@Override
public void processChatMessage( @Nonnull CPacketChatMessage packet )
{
}
@Override
public void processEntityAction( CPacketEntityAction packet )
{
}
@Override
public void processUseEntity( CPacketUseEntity packet )
{
}
@Override
public void processClientStatus( CPacketClientStatus packet )
{
}
@Override
public void processCloseWindow( @Nonnull CPacketCloseWindow packet )
{
}
@Override
public void processClickWindow( CPacketClickWindow packet )
{
}
@Override
public void processEnchantItem( CPacketEnchantItem packet )
{
}
@Override
public void processCreativeInventoryAction( @Nonnull CPacketCreativeInventoryAction packet )
{
}
@Override
public void processConfirmTransaction( @Nonnull CPacketConfirmTransaction packet )
{
}
@Override
public void processUpdateSign( CPacketUpdateSign packet )
{
}
@Override
public void processKeepAlive( @Nonnull CPacketKeepAlive packet )
{
}
@Override
public void processPlayerAbilities( CPacketPlayerAbilities packet )
{
}
@Override
public void processTabComplete( CPacketTabComplete packet )
{
}
@Override
public void processClientSettings( @Nonnull CPacketClientSettings packet )
{
}
@Override
public void processCustomPayload( CPacketCustomPayload packetIn )
{
}
}

View File

@@ -0,0 +1,146 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.util;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import javax.annotation.Nonnull;
/**
* Provides a delegate over inventories.
*
* This may be used both on {@link net.minecraft.tileentity.TileEntity}s to redirect the inventory to another tile,
* and by other interfaces to have inventories which change their backing store.
*/
@FunctionalInterface
public interface InventoryDelegate extends IInventory
{
IInventory getInventory();
@Override
default int getSizeInventory()
{
return getInventory().getSizeInventory();
}
@Override
default boolean isEmpty()
{
return getInventory().isEmpty();
}
@Nonnull
@Override
default ItemStack getStackInSlot( int slot )
{
return getInventory().getStackInSlot( slot );
}
@Nonnull
@Override
default ItemStack decrStackSize( int slot, int count )
{
return getInventory().decrStackSize( slot, count );
}
@Nonnull
@Override
default ItemStack removeStackFromSlot( int slot )
{
return getInventory().removeStackFromSlot( slot );
}
@Override
default void setInventorySlotContents( int slot, ItemStack stack )
{
getInventory().setInventorySlotContents( slot, stack );
}
@Override
default int getInventoryStackLimit()
{
return getInventory().getInventoryStackLimit();
}
@Override
default void markDirty()
{
getInventory().markDirty();
}
@Override
default boolean isUsableByPlayer( @Nonnull EntityPlayer player )
{
return getInventory().isUsableByPlayer( player );
}
@Override
default void openInventory( @Nonnull EntityPlayer player )
{
getInventory().openInventory( player );
}
@Override
default void closeInventory( @Nonnull EntityPlayer player )
{
getInventory().closeInventory( player );
}
@Override
default boolean isItemValidForSlot( int slot, @Nonnull ItemStack stack )
{
return getInventory().isItemValidForSlot( slot, stack );
}
@Override
default int getField( int id )
{
return getInventory().getField( id );
}
@Override
default void setField( int id, int val )
{
getInventory().setField( id, val );
}
@Override
default int getFieldCount()
{
return getInventory().getFieldCount();
}
@Override
default void clear()
{
getInventory().clear();
}
@Nonnull
@Override
default String getName()
{
return getInventory().getName();
}
@Override
default boolean hasCustomName()
{
return getInventory().hasCustomName();
}
@Nonnull
@Override
default ITextComponent getDisplayName()
{
return getInventory().getDisplayName();
}
}

View File

@@ -69,12 +69,6 @@ public final class InventoryUtil
return shareTagA.equals( shareTagB );
}
@Nonnull
public static ItemStack copyItem( @Nonnull ItemStack a )
{
return a.copy();
}
// Methods for finding inventories:
public static IItemHandler getInventory( World world, BlockPos pos, EnumFacing side )

View File

@@ -6,6 +6,8 @@
package dan200.computercraft.shared.util;
import net.minecraft.util.text.TextComponentTranslation;
public final class StringUtil
{
private StringUtil() {}
@@ -33,7 +35,12 @@ public final class StringUtil
}
/**
* Translates a Stat name
* Translates a string.
*
* Try to avoid using this where possible - it is generally preferred to use {@link TextComponentTranslation}.
*
* @param key The key to translate.
* @return The translated string.
*/
@SuppressWarnings( "deprecation" )
public static String translate( String key )
@@ -42,12 +49,18 @@ public final class StringUtil
}
/**
* Translates a Stat name with format args
* Translates and formats a string.
*
* Try to avoid using this where possible - it is generally preferred to use {@link TextComponentTranslation}.
*
* @param key The key to translate.
* @param args The arguments to supply to {@link String#format(String, Object...)}.
* @return The translated and formatted string.
*/
@SuppressWarnings( "deprecation" )
public static String translateFormatted( String key, Object... format )
public static String translateFormatted( String key, Object... args )
{
return net.minecraft.util.text.translation.I18n.translateToLocalFormatted( key, format );
return net.minecraft.util.text.translation.I18n.translateToLocalFormatted( key, args );
}
public static byte[] encodeString( String string )

View File

@@ -12,7 +12,7 @@ import dan200.computercraft.ComputerCraft;
import java.util.concurrent.ThreadFactory;
/**
* Provides some utilities to create thread groups
* Provides some utilities to create thread groups.
*/
public final class ThreadUtils
{
@@ -33,7 +33,7 @@ public final class ThreadUtils
}
/**
* Construct a group under ComputerCraft's shared group
* Construct a group under ComputerCraft's shared group.
*
* @param name The group's name. This will be prefixed with "ComputerCraft-".
* @return The constructed thread group.

View File

@@ -168,8 +168,8 @@ gui.computercraft:config.execution.max_main_computer_time=Computer Servertick Ze
gui.computercraft:config.http=HTTP
gui.computercraft:config.http.enabled=HTTP-API aktivieren
gui.computercraft:config.http.websocket_enabled=Websockets aktivieren
gui.computercraft:config.http.whitelist=HTTP-Whitelist
gui.computercraft:config.http.blacklist=HTTP-Blacklist
gui.computercraft:config.http.allowed_domains=HTTP-Whitelist
gui.computercraft:config.http.blocked_domains=HTTP-Blacklist
gui.computercraft:config.http.timeout=Zeitüberschreitung
gui.computercraft:config.http.max_requests=Maximale Anzahl gleichzeitiger Anfragen

View File

@@ -168,8 +168,8 @@ gui.computercraft:config.execution.max_main_computer_time=Server tick computer t
gui.computercraft:config.http=HTTP
gui.computercraft:config.http.enabled=Enable the HTTP API
gui.computercraft:config.http.websocket_enabled=Enable websockets
gui.computercraft:config.http.whitelist=HTTP whitelist
gui.computercraft:config.http.blacklist=HTTP blacklist
gui.computercraft:config.http.allowed_domains=Allowed domains
gui.computercraft:config.http.blocked_domains=Blocked domains
gui.computercraft:config.http.timeout=Timeout
gui.computercraft:config.http.max_requests=Maximum concurrent requests

View File

@@ -57,8 +57,8 @@ gui.computercraft:config.default_computer_settings=Configuración de Ordenador p
gui.computercraft:config.log_computer_errors=Grabar errores periféricos
gui.computercraft:config.http.enabled=Habilitar API de HTTP
gui.computercraft:config.http.whitelist=Lista blanca de HTTP
gui.computercraft:config.http.blacklist=Lista negra de HTTP
gui.computercraft:config.http.allowed_domains=Lista blanca de HTTP
gui.computercraft:config.http.blocked_domains=Lista negra de HTTP
gui.computercraft:config.peripheral.command_block_enabled=Habilitar bloque de comandos periférico
gui.computercraft:config.peripheral.modem_range=Rango del módem (Por defecto)

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