Rewrite argument validation

This uses a new utility class ArgumentHelper, which provides convenience
methods for parsing arguments from an array of Objects.

The format of error messages has also changed. It now follows a format
similar to Lua's native error messages - including the invalid argument
index, the expected type and the type actually received.
This commit is contained in:
SquidDev 2017-06-12 10:28:31 +01:00
parent 0f982e6199
commit bffc3c18cc
21 changed files with 451 additions and 650 deletions

View File

@ -0,0 +1,246 @@
package dan200.computercraft.core.apis;
import dan200.computercraft.api.lua.LuaException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
/**
* Various helpers for arguments
*/
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();
}
}
@Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nullable Object actual )
{
return badArgument( index, expected, getType( 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 + ")" );
}
public static double getNumber( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "no value" );
Object value = args[ index ];
if( value instanceof Number )
{
return ((Number) value).doubleValue();
}
else
{
throw badArgument( index, "number", value );
}
}
public static int getInt( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "no value" );
Object value = args[ index ];
if( value instanceof Number )
{
return (int) ((Number) value).longValue();
}
else
{
throw badArgument( index, "number", value );
}
}
public static double getReal( @Nonnull Object[] args, int index ) throws LuaException
{
return checkReal( index, getNumber( args, index ) );
}
public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "boolean", "no value" );
Object value = args[ index ];
if( value instanceof Boolean )
{
return (Boolean) value;
}
else
{
throw badArgument( index, "boolean", value );
}
}
@Nonnull
public static String getString( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "string", "no value" );
Object value = args[ index ];
if( value instanceof String )
{
return (String) value;
}
else
{
throw badArgument( index, "string", value );
}
}
@SuppressWarnings("unchecked")
@Nonnull
public static Map<Object, Object> getTable( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "table", "no value" );
Object value = args[ index ];
if( value instanceof Map )
{
return (Map<Object, Object>) value;
}
else
{
throw badArgument( index, "table", value );
}
}
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 );
}
}
public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException
{
Object value = index < args.length ? args[ index ] : null;
if( value == null )
{
return def;
}
else if( value instanceof Number )
{
return (int) ((Number) value).longValue();
}
else
{
throw badArgument( index, "number", value );
}
}
public static double optReal( @Nonnull Object[] args, int index, double def ) throws LuaException
{
return checkReal( index, optNumber( 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 );
}
}
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 );
}
}
@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 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;
}
}
}

View File

@ -11,6 +11,8 @@
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
// Contributed by Nia
// Based on LuaBit (http://luaforge.net/projects/bit)
@ -23,25 +25,6 @@ public class BitAPI implements ILuaAPI
private static final int BRSHIFT = 4;
private static final int BLSHIFT = 5;
private static final int BLOGIC_RSHIFT = 6;
private static int checkInt( Object o, int count ) throws LuaException
{
if( o instanceof Number )
{
return (int)(((Number)o).longValue());
}
else
{
if( count == 2 )
{
throw new LuaException( "Expected number, number" );
}
else
{
throw new LuaException( "Expected number" );
}
}
}
public BitAPI( IAPIEnvironment _environment )
{
@ -82,31 +65,28 @@ public String[] getMethodNames() {
@Override
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
{
Object a = args.length>0?args[0]:null;
Object b = args.length>1?args[1]:null;
int ret = 0;
switch(method) {
case BNOT:
ret = ~checkInt(a, 1);
ret = ~getInt( args, 0 );
break;
case BAND:
ret = checkInt(a, 2) & checkInt(b, 2);
ret = getInt( args, 0 ) & getInt( args, 1 );
break;
case BOR:
ret = checkInt(a, 2) | checkInt(b, 2);
ret = getInt( args, 0 ) | getInt( args, 1 );
break;
case BXOR:
ret = checkInt(a, 2) ^ checkInt(b, 2);
ret = getInt( args, 0 ) ^ getInt( args, 1 );
break;
case BRSHIFT:
ret = checkInt(a, 2) >> checkInt(b, 2);
ret = getInt( args, 0 ) >> getInt( args, 1 );
break;
case BLSHIFT:
ret = checkInt(a, 2) << checkInt(b, 2);
ret = getInt( args, 0 ) << getInt( args, 1 );
break;
case BLOGIC_RSHIFT:
ret = checkInt(a, 2) >>> checkInt(b, 2);
ret = getInt( args, 0 ) >>> getInt( args, 1 );
break;
}

View File

@ -13,6 +13,9 @@
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.core.apis.ArgumentHelper.optInt;
public class BufferAPI implements ILuaAPI
{
private static class BufferLuaObject implements ILuaObject
@ -55,81 +58,25 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 2:
{
// read
int start = 0;
if( arguments.length >= 1 && (arguments[0] != null) )
{
if( !(arguments[0] instanceof Number) )
{
throw new LuaException( "Expected number" );
}
start = ((Number)arguments[1]).intValue() - 1;
}
int end = m_buffer.length();
if( arguments.length >= 2 && (arguments[1] != null) )
{
if( !(arguments[1] instanceof Number) )
{
throw new LuaException( "Expected number, number" );
}
end = ((Number)arguments[1]).intValue();
}
int start = optInt( arguments, 0, 0 );
int end = optInt( arguments, 1, m_buffer.length() );
return new Object[] { m_buffer.read( start, end ) };
}
case 3:
{
// write
if( arguments.length < 1 || !(arguments[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String text = (String)(arguments[0]);
int start = 0;
if( arguments.length >= 2 && (arguments[1] != null) )
{
if( !(arguments[1] instanceof Number) )
{
throw new LuaException( "Expected string, number" );
}
start = ((Number)arguments[1]).intValue() - 1;
}
int end = start + text.length();
if( arguments.length >= 3 && (arguments[2] != null) )
{
if( !(arguments[2] instanceof Number) )
{
throw new LuaException( "Expected string, number, number" );
}
end = ((Number)arguments[2]).intValue();
}
String text = getString( arguments, 0 );
int start = optInt( arguments, 1, 0 );
int end = optInt( arguments, 2, start + text.length() );
m_buffer.write( text, start, end );
return null;
}
case 4:
{
// fill
if( arguments.length < 1 || !(arguments[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String text = (String)(arguments[0]);
int start = 0;
if( arguments.length >= 2 && (arguments[1] != null) )
{
if( !(arguments[1] instanceof Number) )
{
throw new LuaException( "Expected string, number" );
}
start = ((Number)arguments[1]).intValue() - 1;
}
int end = m_buffer.length();
if( arguments.length >= 3 && (arguments[2] != null) )
{
if( !(arguments[2] instanceof Number) )
{
throw new LuaException( "Expected string, number, number" );
}
end = ((Number)arguments[2]).intValue();
}
String text = getString( arguments, 0 );
int start = optInt( arguments, 1, 0 );
int end = optInt( arguments, 2, m_buffer.length() );
m_buffer.fill( text, start, end );
return null;
}
@ -184,23 +131,11 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
{
case 0:
{
if( arguments.length < 1 || !(arguments[0] instanceof String) )
String text = getString( arguments, 0 );
int repetitions = optInt( arguments, 1, 1 );
if( repetitions < 0 )
{
throw new LuaException( "Expected string" );
}
String text = (String)(arguments[0]);
int repetitions = 1;
if( arguments.length >= 2 && arguments[1] != null )
{
if( !(arguments[1] instanceof Number) )
{
throw new LuaException( "Expected string, number" );
}
repetitions = ((Number)arguments[1]).intValue();
if( repetitions < 0 )
{
throw new LuaException( "Expected positive number" );
}
throw ArgumentHelper.badArgument( 1, "positive number", Integer.toString( repetitions ) );
}
TextBuffer buffer = new TextBuffer( text, repetitions );
return new Object[] { new BufferLuaObject( buffer ) };

View File

@ -21,6 +21,8 @@
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
public class FSAPI implements ILuaAPI
{
private IAPIEnvironment m_env;
@ -89,11 +91,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 0:
{
// list
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
try {
String[] results = m_fileSystem.list( path );
Map<Object,Object> table = new HashMap<Object,Object>();
@ -110,32 +108,20 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 1:
{
// combine
if( args.length != 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof String) )
{
throw new LuaException( "Expected string, string" );
}
String pathA = (String)args[0];
String pathB = (String)args[1];
String pathA = getString( args, 0 );
String pathB = getString( args, 1 );
return new Object[] { m_fileSystem.combine( pathA, pathB ) };
}
case 2:
{
// getName
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
return new Object[]{ FileSystem.getName( path ) };
}
case 3:
{
// getSize
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
try
{
return new Object[]{ m_fileSystem.getSize( path ) };
@ -148,11 +134,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 4:
{
// exists
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
try {
return new Object[]{ m_fileSystem.exists( path ) };
} catch( FileSystemException e ) {
@ -162,11 +144,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 5:
{
// isDir
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
try {
return new Object[]{ m_fileSystem.isDir( path ) };
} catch( FileSystemException e ) {
@ -176,11 +154,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 6:
{
// isReadOnly
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
try {
return new Object[]{ m_fileSystem.isReadOnly( path ) };
} catch( FileSystemException e ) {
@ -190,11 +164,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 7:
{
// makeDir
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
try {
m_fileSystem.makeDir( path );
return null;
@ -205,12 +175,8 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 8:
{
// move
if( args.length != 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof String) )
{
throw new LuaException( "Expected string, string" );
}
String path = (String)args[0];
String dest = (String)args[1];
String path = getString( args, 0 );
String dest = getString( args, 1 );
try {
m_fileSystem.move( path, dest );
return null;
@ -221,12 +187,8 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 9:
{
// copy
if( args.length != 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof String) )
{
throw new LuaException( "Expected string, string" );
}
String path = (String)args[0];
String dest = (String)args[1];
String path = getString( args, 0 );
String dest = getString( args, 1 );
try {
m_fileSystem.copy( path, dest );
return null;
@ -237,11 +199,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 10:
{
// delete
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
try {
m_fileSystem.delete( path );
return null;
@ -252,12 +210,8 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 11:
{
// open
if( args.length < 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof String) )
{
throw new LuaException( "Expected string, string" );
}
String path = (String)args[0];
String mode = (String)args[1];
String path = getString( args, 0 );
String mode = getString( args, 1 );
try {
if( mode.equals( "r" ) ) {
// Open the file for reading, then create a wrapper around the reader
@ -300,11 +254,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 12:
{
// getDrive
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
try {
if( !m_fileSystem.exists( path ) )
{
@ -318,11 +268,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 13:
{
// getFreeSpace
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
try {
long freeSpace = m_fileSystem.getFreeSpace( path );
if( freeSpace >= 0 )
@ -337,11 +283,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 14:
{
// find
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
try {
String[] results = m_fileSystem.find( path );
Map<Object,Object> table = new HashMap<Object,Object>();
@ -356,11 +298,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 15:
{
// getDir
if( args.length != 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String path = (String)args[0];
String path = getString( args, 0 );
return new Object[]{ FileSystem.getDirectory( path ) };
}
default:

View File

@ -16,6 +16,8 @@
import java.io.InputStream;
import java.util.*;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
public class HTTPAPI implements ILuaAPI
{
private final IAPIEnvironment m_apiEnvironment;
@ -155,24 +157,16 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
{
// request
// Get URL
if( args.length < 1 || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String urlString = args[0].toString();
String urlString = getString( args, 0 );
// Get POST
String postString = null;
if( args.length >= 2 && args[1] instanceof String )
{
postString = args[1].toString();
}
String postString = optString( args, 1, null );
// Get Headers
Map<String, String> headers = null;
if( args.length >= 3 && args[2] instanceof Map )
Map<Object, Object> table = optTable( args, 2, null );
if( table != null )
{
Map<?, ?> table = (Map<?, ?>)args[2];
headers = new HashMap<String, String>( table.size() );
for( Object key : table.keySet() )
{
@ -210,11 +204,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
{
// checkURL
// Get URL
if( args.length < 1 || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String urlString = args[0].toString();
String urlString = getString( args, 0 );
// Check URL
try

View File

@ -13,6 +13,8 @@
import javax.annotation.Nonnull;
import java.util.*;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
public class OSAPI implements ILuaAPI
{
private IAPIEnvironment m_apiEnvironment;
@ -225,21 +227,13 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 0:
{
// queueEvent
if( args.length == 0 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
queueLuaEvent( (String)args[0], trimArray( args, 1 ) );
queueLuaEvent( getString( args, 0 ), trimArray( args, 1 ) );
return null;
}
case 1:
{
// startTimer
if( args.length < 1 || args[0] == null || !(args[0] instanceof Number) )
{
throw new LuaException( "Expected number" );
}
double timer = ((Number)args[0]).doubleValue();
double timer = getReal( args, 0 );
synchronized( m_timers )
{
m_timers.put( m_nextTimerToken, new Timer( (int)Math.round( timer / 0.05 ) ) );
@ -249,11 +243,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 2:
{
// setAlarm
if( args.length < 1 || args[0] == null || !(args[0] instanceof Number) )
{
throw new LuaException( "Expected number" );
}
double time = ((Number)args[0]).doubleValue();
double time = getReal( args, 0 );
if( time < 0.0 || time >= 24.0 )
{
throw new LuaException( "Number out of range" );
@ -286,16 +276,8 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 7:
{
// setComputerLabel
String label = null;
if( args.length > 0 && args[0] != null )
{
if(!(args[0] instanceof String))
{
throw new LuaException( "Expected string or nil" );
}
label = StringUtil.normaliseLabel( (String) args[0] );
}
m_apiEnvironment.setLabel( label );
String label = optString( args, 0, null );
m_apiEnvironment.setLabel( StringUtil.normaliseLabel( label ) );
return null;
}
case 8:
@ -320,13 +302,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 11:
{
// time
String param = "ingame";
if (args.length > 0 && args[0] != null) {
if (!(args[0] instanceof String)) {
throw new LuaException("Expected string");
}
param = (String)args[0];
}
String param = optString( args, 0, "ingame" );
if (param.equals("utc")) {
// Get Hour of day (UTC)
@ -351,13 +327,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 12:
{
// day
String param = "ingame";
if (args.length > 0 && args[0] != null) {
if (!(args[0] instanceof String)) {
throw new LuaException("Expected string");
}
param = (String)args[0];
}
String param = optString( args, 0, "ingame" );
if (param.equals("utc")) {
// Get numbers of days since 1970-01-01 (utc)
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
@ -381,11 +351,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 13:
{
// cancelTimer
if( args.length < 1 || args[0] == null || !(args[0] instanceof Number) )
{
throw new LuaException( "Expected number" );
}
int token = ((Number)args[0]).intValue();
int token = getInt( args, 0 );
synchronized( m_timers )
{
if( m_timers.containsKey( token ) )
@ -398,11 +364,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 14:
{
// cancelAlarm
if( args.length < 1 || args[0] == null || !(args[0] instanceof Number) )
{
throw new LuaException( "Expected number" );
}
int token = ((Number)args[0]).intValue();
int token = getInt( args, 0 );
synchronized( m_alarms )
{
if( m_alarms.containsKey( token ) )
@ -415,13 +377,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 15:
{
// epoch
String param = "ingame";
if (args.length > 0 && args[0] != null) {
if (!(args[0] instanceof String)) {
throw new LuaException("Expected string");
}
param = (String)args[0];
}
String param = optString( args, 0, "ingame" );
if (param.equals("utc")) {
// Get utc epoch
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC"));

View File

@ -21,6 +21,8 @@
import javax.annotation.Nonnull;
import java.util.*;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChangeListener
{
private class PeripheralWrapper implements IComputerAccess
@ -460,14 +462,10 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 3:
{
// call
if( args.length < 2 || args[1] == null || !(args[1] instanceof String) )
{
throw new LuaException( "Expected string, string" );
}
String methodName = (String)args[1];
int side = parseSide( args );
String methodName = getString( args, 1 );
Object[] methodArgs = trimArray( args, 2 );
int side = parseSide( args );
if( side >= 0 )
{
PeripheralWrapper p;
@ -498,11 +496,7 @@ private Object[] trimArray( Object[] array, int skip )
private int parseSide( Object[] args ) throws LuaException
{
if( args.length < 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String side = (String)args[0];
String side = getString( args, 0 );
for( int n=0; n<Computer.s_sideNames.length; ++n )
{
if( side.equals( Computer.s_sideNames[n] ) )

View File

@ -14,6 +14,8 @@
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
public class RedstoneAPI implements ILuaAPI
{
private IAPIEnvironment m_environment;
@ -86,12 +88,8 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 1:
{
// setOutput
if( args.length < 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof Boolean) )
{
throw new LuaException( "Expected string, boolean" );
}
int side = parseSide( args );
boolean output = (Boolean) args[ 1 ];
boolean output = getBoolean( args, 1 );
m_environment.setOutput( side, output ? 15 : 0 );
return null;
}
@ -110,12 +108,8 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 4:
{
// setBundledOutput
if( args.length < 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof Double) )
{
throw new LuaException( "Expected string, number" );
}
int side = parseSide( args );
int output = ((Double)args[1]).intValue();
int output = getInt( args, 1 );
m_environment.setBundledOutput( side, output );
return null;
}
@ -134,12 +128,8 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 7:
{
// testBundledInput
if( args.length < 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof Double) )
{
throw new LuaException( "Expected string, number" );
}
int side = parseSide( args );
int mask = ((Double)args[1]).intValue();
int mask = getInt( args, 1 );
int input = m_environment.getBundledInput( side );
return new Object[] { ((input & mask) == mask) };
}
@ -147,12 +137,8 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 9:
{
// setAnalogOutput/setAnalogueOutput
if( args.length < 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof Double) )
{
throw new LuaException( "Expected string, number" );
}
int side = parseSide( args );
int output = ((Double)args[1]).intValue();
int output = getInt( args, 1 );
if( output < 0 || output > 15 )
{
throw new LuaException( "Expected number in range 0-15" );
@ -183,11 +169,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
private int parseSide( Object[] args ) throws LuaException
{
if( args.length < 1 || args[0] == null || !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
String side = (String)args[0];
String side = getString( args, 0 );
for( int n=0; n<Computer.s_sideNames.length; ++n )
{
if( side.equals( Computer.s_sideNames[n] ) )

View File

@ -13,12 +13,10 @@
import dan200.computercraft.shared.util.Palette;
import org.apache.commons.lang3.ArrayUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
public class TermAPI implements ILuaAPI
{
private final Terminal m_terminal;
@ -86,11 +84,7 @@ public String[] getMethodNames()
public static int parseColour( Object[] args ) throws LuaException
{
if( args.length < 1 || args[0] == null || !(args[0] instanceof Double) )
{
throw new LuaException( "Expected number" );
}
int colour = (int)((Double)args[0]).doubleValue();
int colour = getInt( args, 0 );
if( colour <= 0 )
{
throw new LuaException( "Colour out of range" );
@ -144,12 +138,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 1:
{
// scroll
if( args.length != 1 || args[0] == null || !(args[0] instanceof Double) )
{
throw new LuaException( "Expected number" );
}
int y = (int)((Double)args[0]).doubleValue();
int y = getInt( args, 0 );
synchronized( m_terminal )
{
m_terminal.scroll(y);
@ -159,12 +148,8 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 2:
{
// setCursorPos
if( args.length != 2 || args[0] == null || !(args[0] instanceof Double) || args[1] == null || !(args[1] instanceof Double) )
{
throw new LuaException( "Expected number, number" );
}
int x = (int)((Double)args[0]).doubleValue() - 1;
int y = (int)((Double)args[1]).doubleValue() - 1;
int x = getInt( args, 0 ) - 1;
int y = getInt( args, 1 ) - 1;
synchronized( m_terminal )
{
m_terminal.setCursorPos( x, y );
@ -174,11 +159,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 3:
{
// setCursorBlink
if( args.length != 1 || args[0] == null || !(args[0] instanceof Boolean) )
{
throw new LuaException( "Expected boolean" );
}
boolean b = (Boolean) args[ 0 ];
boolean b = getBoolean( args, 0 );
synchronized( m_terminal )
{
m_terminal.setCursorBlink( b );
@ -268,14 +249,9 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 18:
{
// blit
if( args.length < 3 || !(args[0] instanceof String) || !(args[1] instanceof String) || !(args[2] instanceof String) )
{
throw new LuaException( "Expected string, string, string" );
}
String text = (String)args[0];
String textColour = (String)args[1];
String backgroundColour = (String)args[2];
String text = getString( args, 0 );
String textColour = getString( args, 1 );
String backgroundColour = getString( args, 2 );
if( textColour.length() != text.length() || backgroundColour.length() != text.length() )
{
throw new LuaException( "Arguments must be the same length" );
@ -292,36 +268,26 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 20:
{
// setPaletteColour/setPaletteColor
if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double)
int colour = 15 - parseColour( args );
if( args.length == 2 )
{
int colour = 15 - parseColour( args );
int hex = ((Double)args[1]).intValue();
int hex = getInt( args, 1 );
double[] rgb = Palette.decodeRGB8( hex );
setColour( m_terminal, colour, rgb[0], rgb[1], rgb[2] );
return null;
setColour( m_terminal, colour, rgb[ 0 ], rgb[ 1 ], rgb[ 2 ] );
}
if(args.length >= 4 && args[0] instanceof Double && args[1] instanceof Double && args[2] instanceof Double && args[3] instanceof Double)
else
{
int colour = 15 - parseColour( args );
double r = (Double)args[1];
double g = (Double)args[2];
double b = (Double)args[3];
double r = getReal( args, 1 );
double g = getReal( args, 2 );
double b = getReal( args, 3 );
setColour( m_terminal, colour, r, g, b );
return null;
}
throw new LuaException( "Expected number, number or number, number, number, number" );
return null;
}
case 21:
case 22:
{
// getPaletteColour/getPaletteColor
if(args.length < 1 || !(args[0] instanceof Double))
{
throw new LuaException( "Expected number" );
}
int colour = 15 - parseColour( args );
synchronized( m_terminal )
{

View File

@ -9,6 +9,8 @@
import java.io.InputStream;
import java.util.Arrays;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
public class BinaryInputHandle extends HandleGeneric
{
private final InputStream m_stream;
@ -42,13 +44,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
{
if( args.length > 0 && args[ 0 ] != null )
{
if( !(args[ 0 ] instanceof Number) )
{
throw new LuaException( "Expected number" );
}
int count = ((Number) args[ 0 ]).intValue();
int count = getInt( args, 0 );
if( count <= 0 || count >= 1024 * 16 )
{
throw new LuaException( "Count out of range" );

View File

@ -2,6 +2,7 @@
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;
@ -51,7 +52,7 @@ else if( args.length > 0 && args[ 0 ] instanceof String )
}
else
{
throw new LuaException( "Expected number" );
throw ArgumentHelper.badArgument( 0, "string or number", args.length > 0 ? args[ 0 ] : null );
}
return null;
}

View File

@ -28,6 +28,9 @@
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
public class CommandAPI implements ILuaAPI
{
private TileCommandComputer m_computer;
@ -151,11 +154,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 0:
{
// exec
if( arguments.length < 1 || !(arguments[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
final String command = (String)arguments[0];
final String command = getString( arguments, 0 );
return context.executeMainThreadTask( new ILuaTask()
{
@Override
@ -168,11 +167,7 @@ public Object[] execute() throws LuaException
case 1:
{
// execAsync
if( arguments.length < 1 || !(arguments[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
final String command = (String)arguments[0];
final String command = getString( arguments, 0 );
long taskID = context.issueMainThreadTask( new ILuaTask()
{
@Override
@ -234,22 +229,12 @@ public Object[] execute() throws LuaException
case 4:
{
// getBlockInfos
if( arguments.length < 6 ||
!(arguments[0] instanceof Number) ||
!(arguments[1] instanceof Number) ||
!(arguments[2] instanceof Number) ||
!(arguments[3] instanceof Number) ||
!(arguments[4] instanceof Number) ||
!(arguments[5] instanceof Number) )
{
throw new LuaException( "Expected number, number, number, number, number, number" );
}
final int minx = ((Number)arguments[0]).intValue();
final int miny = ((Number)arguments[1]).intValue();
final int minz = ((Number)arguments[2]).intValue();
final int maxx = ((Number)arguments[3]).intValue();
final int maxy = ((Number)arguments[4]).intValue();
final int maxz = ((Number)arguments[5]).intValue();
final int minx = getInt( arguments, 0 );
final int miny = getInt( arguments, 1 );
final int minz = getInt( arguments, 2 );
final int maxx = getInt( arguments, 3 );
final int maxy = getInt( arguments, 4 );
final int maxz = getInt( arguments, 5 );
return context.executeMainThreadTask( new ILuaTask()
{
@Override
@ -295,16 +280,9 @@ public Object[] execute() throws LuaException
case 5:
{
// getBlockInfo
if( arguments.length < 3 ||
!(arguments[0] instanceof Number) ||
!(arguments[1] instanceof Number) ||
!(arguments[2] instanceof Number) )
{
throw new LuaException( "Expected number, number, number" );
}
final int x = ((Number)arguments[0]).intValue();
final int y = ((Number)arguments[1]).intValue();
final int z = ((Number)arguments[2]).intValue();
final int x = getInt( arguments, 0 );
final int y = getInt( arguments, 1 );
final int z = getInt( arguments, 2 );
return context.executeMainThreadTask( new ILuaTask()
{
@Override

View File

@ -16,6 +16,8 @@
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
public class CommandBlockPeripheral implements IPeripheral
{
private final TileEntityCommandBlock m_commandBlock;
@ -67,12 +69,7 @@ public Object[] execute() throws LuaException
case 1:
{
// setCommand
if( arguments.length < 1 || !(arguments[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
final String command = (String) arguments[ 0 ];
final String command = getString( arguments, 0 );
context.issueMainThreadTask( new ILuaTask()
{
@Override

View File

@ -18,6 +18,8 @@
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
public class DiskDrivePeripheral implements IPeripheral
{
private final TileDiskDrive m_diskDrive;
@ -78,15 +80,7 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 2:
{
// setDiskLabel
String label = null;
if( arguments.length > 0 )
{
if( arguments[0] != null && !(arguments[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
label = (String)arguments[0];
}
String label = optString( arguments, 0, null );
IMedia media = m_diskDrive.getDiskMedia();
if( media != null )

View File

@ -21,6 +21,8 @@
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
public abstract class ModemPeripheral
implements IPeripheral, IPacketSender, IPacketReceiver
{
@ -147,11 +149,7 @@ public String[] getMethodNames()
private static int parseChannel( Object[] arguments, int index ) throws LuaException
{
if( arguments.length <= index || !(arguments[index] instanceof Double) )
{
throw new LuaException( "Expected number" );
}
int channel = (int)((Double)arguments[index]).doubleValue();
int channel = getInt( arguments, index );
if( channel < 0 || channel > 65535 )
{
throw new LuaException( "Expected number in range 0-65535" );

View File

@ -40,6 +40,8 @@
import java.io.File;
import java.util.*;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
public class TileCable extends TileModemBase
implements IPacketNetwork
{
@ -116,15 +118,6 @@ public String[] getMethodNames()
return newMethods;
}
private String parseString( Object[] arguments, int index ) throws LuaException
{
if( arguments.length < (index + 1) || !(arguments[index] instanceof String) )
{
throw new LuaException( "Expected string" );
}
return (String)arguments[index];
}
@Override
public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException
{
@ -148,13 +141,13 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 1:
{
// isPresentRemote
String type = m_entity.getTypeRemote( parseString( arguments, 0 ) );
String type = m_entity.getTypeRemote( getString( arguments, 0 ) );
return new Object[] { type != null };
}
case 2:
{
// getTypeRemote
String type = m_entity.getTypeRemote( parseString( arguments, 0 ) );
String type = m_entity.getTypeRemote( getString( arguments, 0 ) );
if( type != null )
{
return new Object[] { type };
@ -164,7 +157,7 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 3:
{
// getMethodsRemote
String[] methodNames = m_entity.getMethodNamesRemote( parseString( arguments, 0 ) );
String[] methodNames = m_entity.getMethodNamesRemote( getString( arguments, 0 ) );
if( methodNames != null )
{
Map<Object,Object> table = new HashMap<Object,Object>();
@ -178,8 +171,8 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 4:
{
// callRemote
String remoteName = parseString( arguments, 0 );
String methodName = parseString( arguments, 1 );
String remoteName = getString( arguments, 0 );
String methodName = getString( arguments, 1 );
Object[] methodArgs = new Object[ arguments.length - 2 ];
System.arraycopy( arguments, 2, methodArgs, 0, arguments.length - 2 );
return m_entity.callMethodRemote( remoteName, context, methodName, methodArgs );

View File

@ -10,14 +10,15 @@
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.apis.TermAPI;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.util.Palette;
import org.apache.commons.lang3.ArrayUtils;
import java.util.HashMap;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
public class MonitorPeripheral implements IPeripheral
{
private final TileMonitor m_monitor;
@ -90,23 +91,16 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 1:
{
// scroll
if( args.length < 1 || !(args[0] instanceof Number) )
{
throw new LuaException( "Expected number" );
}
int value = getInt( args, 0 );
Terminal terminal = m_monitor.getTerminal().getTerminal();
terminal.scroll( ((Number)(args[0])).intValue() );
terminal.scroll( value );
return null;
}
case 2:
{
// setCursorPos
if( args.length < 2 || !(args[0] instanceof Number) || !(args[1] instanceof Number) )
{
throw new LuaException( "Expected number, number" );
}
int x = ((Number)args[0]).intValue() - 1;
int y = ((Number)args[1]).intValue() - 1;
int x = getInt( args, 0 ) - 1;
int y = getInt( args, 1 ) - 1;
Terminal terminal = m_monitor.getTerminal().getTerminal();
terminal.setCursorPos( x, y );
return null;
@ -114,12 +108,9 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 3:
{
// setCursorBlink
if( args.length < 1 || !(args[0] instanceof Boolean) )
{
throw new LuaException( "Expected boolean" );
}
boolean blink = getBoolean( args, 0 );
Terminal terminal = m_monitor.getTerminal().getTerminal();
terminal.setCursorBlink( (Boolean) args[ 0 ] );
terminal.setCursorBlink( blink );
return null;
}
case 4:
@ -157,11 +148,7 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 8:
{
// setTextScale
if( args.length < 1 || !(args[0] instanceof Number) )
{
throw new LuaException( "Expected number" );
}
int scale = (int)(((Number)args[0]).doubleValue() * 2.0);
int scale = (int) (getReal( args, 0 ) * 2.0);
if( scale < 1 || scale > 10 )
{
throw new LuaException( "Expected number in range 0.5-5" );
@ -173,7 +160,7 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 10:
{
// setTextColour/setTextColor
int colour = dan200.computercraft.core.apis.TermAPI.parseColour( args );
int colour = TermAPI.parseColour( args );
Terminal terminal = m_monitor.getTerminal().getTerminal();
terminal.setTextColour( colour );
return null;
@ -182,7 +169,7 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 12:
{
// setBackgroundColour/setBackgroundColor
int colour = dan200.computercraft.core.apis.TermAPI.parseColour( args );
int colour = TermAPI.parseColour( args );
Terminal terminal = m_monitor.getTerminal().getTerminal();
terminal.setBackgroundColour( colour );
return null;
@ -200,26 +187,21 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
{
// getTextColour/getTextColor
Terminal terminal = m_monitor.getTerminal().getTerminal();
return dan200.computercraft.core.apis.TermAPI.encodeColour( terminal.getTextColour() );
return TermAPI.encodeColour( terminal.getTextColour() );
}
case 17:
case 18:
{
// getBackgroundColour/getBackgroundColor
Terminal terminal = m_monitor.getTerminal().getTerminal();
return dan200.computercraft.core.apis.TermAPI.encodeColour( terminal.getBackgroundColour() );
return TermAPI.encodeColour( terminal.getBackgroundColour() );
}
case 19:
{
// blit
if( args.length < 3 || !(args[0] instanceof String) || !(args[1] instanceof String) || !(args[2] instanceof String) )
{
throw new LuaException( "Expected string, string, string" );
}
String text = (String)args[0];
String textColour = (String)args[1];
String backgroundColour = (String)args[2];
String text = getString( args, 0 );
String textColour = getString( args, 1 );
String backgroundColour = getString( args, 2 );
if( textColour.length() != text.length() || backgroundColour.length() != text.length() )
{
throw new LuaException( "Arguments must be the same length" );
@ -236,26 +218,21 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
// setPaletteColour/setPaletteColor
Terminal terminal = m_monitor.getTerminal().getTerminal();
if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double)
int colour = 15 - TermAPI.parseColour( args );
if( args.length == 2 )
{
int colour = 15 - dan200.computercraft.core.apis.TermAPI.parseColour( args );
int hex = ((Double)args[1]).intValue();
int hex = getInt( args, 1 );
double[] rgb = Palette.decodeRGB8( hex );
dan200.computercraft.core.apis.TermAPI.setColour( terminal, colour, rgb[0], rgb[1], rgb[2] );
return null;
TermAPI.setColour( terminal, colour, rgb[ 0 ], rgb[ 1 ], rgb[ 2 ] );
}
if (args.length >= 4 && args[0] instanceof Double && args[1] instanceof Double && args[2] instanceof Double && args[3] instanceof Double)
else
{
int colour = 15 - dan200.computercraft.core.apis.TermAPI.parseColour( args );
double r = (Double)args[1];
double g = (Double)args[2];
double b = (Double)args[3];
dan200.computercraft.core.apis.TermAPI.setColour( terminal, colour, r, g, b );
return null;
double r = getReal( args, 1 );
double g = getReal( args, 2 );
double b = getReal( args, 3 );
TermAPI.setColour( terminal, colour, r, g, b );
}
throw new LuaException( "Expected number, number, number, number" );
return null;
}
case 22:
case 23:
@ -264,7 +241,7 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
Terminal terminal = m_monitor.getTerminal().getTerminal();
Palette palette = terminal.getPalette();
int colour = 15 - dan200.computercraft.core.apis.TermAPI.parseColour( args );
int colour = 15 - TermAPI.parseColour( args );
if( palette != null )
{

View File

@ -14,6 +14,9 @@
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
public class PrinterPeripheral implements IPeripheral
{
private final TilePrinter m_printer;
@ -70,13 +73,8 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 1:
{
// setCursorPos
if( args.length != 2 || args[0] == null || !(args[0] instanceof Number) || args[1] == null || !(args[1] instanceof Number) )
{
throw new LuaException( "Expected number, number" );
}
int x = ((Number)args[0]).intValue() - 1;
int y = ((Number)args[1]).intValue() - 1;
int x = getInt( args, 0 ) - 1;
int y = getInt( args, 1 ) - 1;
Terminal page = getCurrentPage();
page.setCursorPos( x, y );
return null;
@ -116,16 +114,7 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
case 7:
{
// setPageTitle
String title = "";
if( args.length > 0 && args[0] != null )
{
if( !(args[0] instanceof String) )
{
throw new LuaException( "Expected string" );
}
title = (String)args[0];
}
String title = optString( args, 0, "" );
getCurrentPage();
m_printer.setPageTitle( title );
return null;

View File

@ -17,9 +17,13 @@
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
import static dan200.computercraft.core.apis.ArgumentHelper.optReal;
public class SpeakerPeripheral implements IPeripheral {
private TileSpeaker m_speaker;
private long m_clock;
@ -127,47 +131,20 @@ public Object[] callMethod( @Nonnull IComputerAccess computerAccess, @Nonnull IL
@Nonnull
private synchronized Object[] playNote( Object[] arguments, ILuaContext context ) throws LuaException
{
float volume = 1.0f;
float pitch = 1.0f;
String name = getString(arguments, 0);
float volume = (float) optReal( arguments, 1, 1.0 );
float pitch = (float) optReal( arguments, 2, 1.0 );
// Check if arguments are correct
if( arguments.length == 0 ) // Too few args
{
throw new LuaException( "Expected string, number (optional), number (optional)" );
}
if( !(arguments[0] instanceof String) ) // Arg wrong type
{
throw new LuaException("Expected string, number (optional), number (optional)");
}
if ( !SoundEvent.REGISTRY.containsKey( new ResourceLocation( "block.note." + arguments[0] ) ) )
// Check if sound exists
if ( !SoundEvent.REGISTRY.containsKey( new ResourceLocation( "block.note." + name ) ) )
{
throw new LuaException("Invalid instrument, \"" + arguments[0] + "\"!");
}
if ( arguments.length > 1 )
{
if ( arguments[1] != null && !(arguments[1] instanceof Double) ) // Arg wrong type
{
throw new LuaException( "Expected string, number (optional), number (optional)" );
}
volume = arguments[1] != null ? ((Double) arguments[1]).floatValue() : 1f;
}
if( arguments.length > 2 )
{
if( arguments[2] != null && !(arguments[2] instanceof Double) ) // Arg wrong type
{
throw new LuaException("Expected string, number (optional), number (optional)");
}
pitch = arguments[2] != null ? ((Double) arguments[2]).floatValue() : 1f;
}
// If the resource location for note block notes changes, this method call will need to be updated
Object[] returnValue = playSound(
new Object[] {
"block.note." + arguments[0],
"block.note." + name,
(double)Math.min( volume, 3f ),
Math.pow( 2.0f, ( pitch - 12.0f ) / 12.0f)
}, context, true
@ -184,42 +161,11 @@ private synchronized Object[] playNote( Object[] arguments, ILuaContext context
@Nonnull
private synchronized Object[] playSound( Object[] arguments, ILuaContext context, boolean isNote ) 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 = 1.0f;
float pitch = 1.0f;
// Check if arguments are correct
if( arguments.length == 0 ) // Too few args
{
throw new LuaException( "Expected string, number (optional), number (optional)" );
}
if( !(arguments[0] instanceof String) ) // Arg wrong type
{
throw new LuaException( "Expected string, number (optional), number (optional)" );
}
if( arguments.length > 1 )
{
if( arguments[1] != null && !(arguments[1] instanceof Double) ) // Arg wrong type
{
throw new LuaException( "Expected string, number (optional), number (optional)" );
}
volume = arguments[1] != null ? ((Double) arguments[1]).floatValue() : 1f;
}
if( arguments.length > 2 )
{
if( arguments[2] != null && !(arguments[2] instanceof Double) ) // Arg wrong type
{
throw new LuaException( "Expected string, number (optional), number (optional)" );
}
pitch = arguments[2] != null ? ((Double) arguments[2]).floatValue() : 1f;
}
ResourceLocation resourceName = new ResourceLocation( (String) arguments[0] );
ResourceLocation resourceName = new ResourceLocation( name );
if( m_clock - m_lastPlayTime >= TileSpeaker.MIN_TICKS_BETWEEN_SOUNDS || ( ( m_clock - m_lastPlayTime == 0 ) && ( m_notesThisTick < ComputerCraft.maxNotesPerTick ) && isNote ) )
{

View File

@ -22,6 +22,8 @@
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.core.apis.ArgumentHelper.*;
public class TurtleAPI implements ILuaAPI
{
private IAPIEnvironment m_environment;
@ -115,38 +117,23 @@ private Object[] tryCommand( ILuaContext context, ITurtleCommand command ) throw
private int parseSlotNumber( Object[] arguments, int index ) throws LuaException
{
int slot = parseOptionalSlotNumber( arguments, index, 99 );
if( slot == 99 )
{
throw new LuaException( "Expected number" );
}
return slot;
int slot = getInt( arguments, index );
if( slot < 1 || slot > 16 ) throw new LuaException( "Slot number " + slot + " out of range" );
return slot - 1;
}
private int parseOptionalSlotNumber( Object[] arguments, int index, int fallback ) throws LuaException
{
if( arguments.length <= index || !(arguments[index] instanceof Number) )
{
return fallback;
}
int slot = ((Number)arguments[index]).intValue();
if( slot >= 1 && slot <= 16 )
{
return slot - 1;
}
else
{
throw new LuaException( "Slot number " + slot + " out of range" );
}
if( index >= arguments.length || arguments[ index ] == null ) return fallback;
int slot = getInt( arguments, index );
if( slot < 1 || slot > 16 ) throw new LuaException( "Slot number " + slot + " out of range" );
return slot - 1;
}
private int parseCount( Object[] arguments, int index ) throws LuaException
{
if( arguments.length <= index || !(arguments[index] instanceof Number) )
{
throw new LuaException( "Expected number" );
}
int count = ((Number)arguments[index]).intValue();
int count = optInt( arguments, index, 64 );
if( count >= 0 && count <= 64 )
{
return count;
@ -159,19 +146,16 @@ private int parseCount( Object[] arguments, int index ) throws LuaException
private Optional<TurtleSide> parseSide( Object[] arguments, int index ) throws LuaException
{
if( arguments.length <= index || arguments[index] == null )
String side = optString( arguments, index, null );
if( side == null )
{
return Optional.absent();
}
if( !(arguments[ index ] instanceof String) )
{
throw new LuaException( "Expected string" );
}
if( arguments[ index ].equals( "left" ) )
else if( side.equalsIgnoreCase( "left" ) )
{
return Optional.of( TurtleSide.Left );
}
else if( arguments[ index ].equals( "right" ) )
else if( side.equalsIgnoreCase( "right" ) )
{
return Optional.of( TurtleSide.Right );
}
@ -252,11 +236,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 12:
{
// drop
int count = 64;
if( args.length > 0 )
{
count = parseCount( args, 0 );
}
int count = parseCount( args, 0 );
return tryCommand( context, new TurtleDropCommand( InteractDirection.Forward, count ) );
}
case 13:
@ -343,51 +323,31 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 25:
{
// dropUp
int count = 64;
if( args.length > 0 )
{
count = parseCount( args, 0 );
}
int count = parseCount( args, 0 );
return tryCommand( context, new TurtleDropCommand( InteractDirection.Up, count ) );
}
case 26:
{
// dropDown
int count = 64;
if( args.length > 0 )
{
count = parseCount( args, 0 );
}
int count = parseCount( args, 0 );
return tryCommand( context, new TurtleDropCommand( InteractDirection.Down, count ) );
}
case 27:
{
// suck
int count = 64;
if( args.length > 0 )
{
count = parseCount( args, 0 );
}
int count = parseCount( args, 0 );
return tryCommand( context, new TurtleSuckCommand( InteractDirection.Forward, count ) );
}
case 28:
{
// suckUp
int count = 64;
if( args.length > 0 )
{
count = parseCount( args, 0 );
}
int count = parseCount( args, 0 );
return tryCommand( context, new TurtleSuckCommand( InteractDirection.Up, count ) );
}
case 29:
{
// suckDown
int count = 64;
if( args.length > 0 )
{
count = parseCount( args, 0 );
}
int count = parseCount( args, 0 );
return tryCommand( context, new TurtleSuckCommand( InteractDirection.Down, count ) );
}
case 30:
@ -405,11 +365,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
case 31:
{
// refuel
int count = 64;
if( args.length > 0 )
{
count = parseCount( args, 0 );
}
int count = parseCount( args, 0 );
return tryCommand( context, new TurtleRefuelCommand( count ) );
}
case 32:
@ -422,11 +378,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
{
// transferTo
int slot = parseSlotNumber( args, 0 );
int count = 64;
if( args.length > 1 )
{
count = parseCount( args, 1 );
}
int count = parseCount( args, 1 );
return tryCommand( context, new TurtleTransferToCommand( slot, count ) );
}
case 34:

View File

@ -15,6 +15,8 @@
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.optInt;
public class CraftingTablePeripheral
implements IPeripheral
{
@ -45,16 +47,7 @@ public String[] getMethodNames()
private int parseCount( Object[] arguments ) throws LuaException
{
if( arguments.length < 1 )
{
return 64;
}
if( !(arguments[0] instanceof Number) )
{
throw new LuaException( "Expected number" );
}
int count = ((Number)arguments[0]).intValue();
int count = optInt( arguments, 0, 64 );
if( count < 0 || count > 64 )
{
throw new LuaException( "Crafting count " + count + " out of range" );