Merge branch 'master' into mc-1.13.x

This commit is contained in:
SquidDev 2019-06-08 08:21:08 +01:00
commit 0f3c44c926
74 changed files with 669 additions and 231 deletions

6
.gitignore vendored
View File

@ -15,3 +15,9 @@
.idea
.gradle
*.DS_Store
.classpath
.project
.settings/
bin/
*.launch

View File

@ -16,7 +16,9 @@
}
plugins {
id 'com.matthewprenger.cursegradle' version '1.2.0'
id "checkstyle"
id "com.github.hierynomus.license" version "0.15.0"
id "com.matthewprenger.cursegradle" version "1.3.0"
id "com.github.breadmoirai.github-release" version "2.2.4"
}
@ -88,6 +90,8 @@ accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
}
dependencies {
checkstyle "com.puppycrawl.tools:checkstyle:8.21"
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
compileOnly fg.deobf("mezz.jei:jei-1.13.2:5.0.0.20:api")
@ -143,6 +147,8 @@ accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import com.hierynomus.gradle.license.tasks.LicenseCheck
import com.hierynomus.gradle.license.tasks.LicenseFormat
import org.ajoberstar.grgit.Grgit
import proguard.gradle.ProGuardTask
@ -242,6 +248,7 @@ task compressJson(dependsOn: jar) {
// Copy over all files in the current jar to the new one, running json files from GSON. As pretty printing
// is turned off, they should be minified.
new ZipFile(jarPath).withCloseable { inJar ->
tempPath.getParentFile().mkdirs()
new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tempPath))).withCloseable { outJar ->
inJar.entries().each { entry ->
if(entry.directory) {
@ -269,6 +276,42 @@ task compressJson(dependsOn: jar) {
assemble.dependsOn compressJson
/* Check tasks */
license {
mapping("java", "SLASHSTAR_STYLE")
strictCheck true
ext.year = Calendar.getInstance().get(Calendar.YEAR)
}
[licenseMain, licenseFormatMain].forEach {
it.configure {
include("**/*.java")
exclude("dan200/computercraft/api/**")
header rootProject.file('config/license/main.txt')
}
}
[licenseTest, licenseFormatTest].forEach {
it.configure {
include("**/*.java")
header rootProject.file('config/license/main.txt')
}
}
task licenseAPI(type: LicenseCheck);
task licenseFormatAPI(type: LicenseFormat);
[licenseAPI, licenseFormatAPI].forEach {
it.configure {
source = sourceSets.main.java
include("dan200/computercraft/api/**")
header rootProject.file('config/license/api.txt')
}
}
/* Upload tasks */
task checkRelease {
group "upload"
description "Verifies that everything is ready for a release"
@ -308,7 +351,6 @@ task compressJson(dependsOn: jar) {
}
}
curseforge {
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
project {
@ -413,5 +455,9 @@ task uploadAll(dependsOn: uploadTasks) {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint" << "-Xlint:-processing" // Causes Forge build to fail << "-Werror"
}
tasks.withType(LicenseFormat) {
outputs.upToDateWhen { false }
}
}

View File

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<property name="tabWidth" value="4"/>
<property name="charset" value="UTF-8" />
<module name="SuppressionFilter">
<property name="file" value="config/checkstyle/suppressions.xml" />
</module>
<module name="TreeWalker">
<!-- Annotations -->
<module name="AnnotationLocation" />
<module name="AnnotationUseStyle" />
<module name="MissingDeprecated">
<property name="skipNoJavadoc" value="true" />
</module>
<module name="MissingOverride" />
<!-- Blocks -->
<module name="EmptyBlock" />
<module name="EmptyCatchBlock">
<property name="exceptionVariableName" value="ignored" />
</module>
<module name="LeftCurly">
<property name="option" value="nl" />
<!-- The defaults, minus lambdas. -->
<property name="tokens" value="ANNOTATION_DEF,CLASS_DEF,CTOR_DEF,ENUM_CONSTANT_DEF,ENUM_DEF,INTERFACE_DEF,LITERAL_CASE,LITERAL_CATCH,LITERAL_DEFAULT,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,METHOD_DEF,OBJBLOCK,STATIC_INIT" />
</module>
<module name="NeedBraces">
<property name="allowSingleLineStatement" value="true"/>
</module>
<module name="RightCurly">
<property name="option" value="alone" />
</module>
<!-- Class design. As if we've ever followed good practice here. -->
<module name="FinalClass" />
<module name="InterfaceIsType" />
<module name="MutableException" />
<module name="OneTopLevelClass" />
<!-- Coding -->
<module name="ArrayTrailingComma" />
<module name="EqualsHashCode" />
<!-- FallThrough does not handle unreachable code well -->
<module name="IllegalInstantiation" />
<module name="IllegalThrows" />
<module name="ModifiedControlVariable" />
<module name="NoClone" />
<module name="NoFinalizer" />
<module name="OneStatementPerLine" />
<module name="PackageDeclaration" />
<module name="SimplifyBooleanExpression" />
<module name="SimplifyBooleanReturn" />
<module name="StringLiteralEquality" />
<module name="UnnecessaryParentheses" />
<!-- Imports -->
<module name="CustomImportOrder" />
<module name="IllegalImport" />
<module name="RedundantImport" />
<module name="UnusedImports" />
<!-- Javadoc -->
<module name="AtclauseOrder" />
<!-- TODO: Cleanup our documentation before enabling JavadocMethod, JavadocStyle, JavadocType and SummaryJavadoc. -->
<module name="NonEmptyAtclauseDescription" />
<module name="SingleLineJavadoc" />
<!-- Misc -->
<module name="ArrayTypeStyle" />
<module name="CommentsIndentation" />
<module name="Indentation" />
<module name="OuterTypeFilename" />
<!-- Modifiers -->
<module name="ModifierOrder" />
<module name="RedundantModifier" />
<!-- Naming -->
<module name="ClassTypeParameterName" />
<module name="InterfaceTypeParameterName" />
<module name="LambdaParameterName" />
<module name="LocalFinalVariableName" />
<module name="LocalVariableName" />
<!-- Allow an optional m_ on private members -->
<module name="MemberName">
<property name="applyToPrivate" value="false" />
<property name="applyToPackage" value="false" />
</module>
<module name="MemberName">
<property name="format" value="^(m_)?[a-z][a-zA-Z0-9]*$" />
<property name="applyToPrivate" value="true" />
<property name="applyToPackage" value="true" />
</module>
<module name="MethodName" />
<module name="MethodTypeParameterName" />
<module name="PackageName">
<property name="format" value="^dan200\.computercraf(\.[a-z][a-z0-9]*)*" />
</module>
<module name="ParameterName" />
<module name="StaticVariableName">
<property name="format" value="^[a-z][a-zA-Z0-9]*|CAPABILITY(_[A-Z]+)?$" />
<property name="applyToPrivate" value="false" />
</module>
<module name="StaticVariableName">
<property name="format" value="^(s_)?[a-z][a-zA-Z0-9]*|CAPABILITY(_[A-Z]+)?$" />
<property name="applyToPrivate" value="true" />
</module>
<module name="TypeName" />
<!-- Whitespace -->
<module name="EmptyForInitializerPad"/>
<module name="EmptyForIteratorPad">
<property name="option" value="space"/>
</module>
<module name="GenericWhitespace" />
<module name="MethodParamPad" />
<module name="NoLineWrap" />
<module name="NoWhitespaceAfter">
<property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP" />
</module>
<module name="NoWhitespaceBefore" />
<!-- TODO: Decide on an OperatorWrap style. -->
<module name="ParenPad">
<property name="option" value="space" />
<property name="tokens" value="ANNOTATION,ANNOTATION_FIELD_DEF,CTOR_CALL,CTOR_DEF,ENUM_CONSTANT_DEF,LITERAL_CATCH,LITERAL_DO,LITERAL_FOR,LITERAL_IF,LITERAL_NEW,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_WHILE,METHOD_CALL,METHOD_DEF,RESOURCE_SPECIFICATION,SUPER_CTOR_CALL,LAMBDA" />
</module>
<module name="ParenPad">
<property name="option" value="nospace" />
<property name="tokens" value="DOT,EXPR,QUESTION" />
</module>
<module name="SeparatorWrap">
<property name="option" value="eol" />
<property name="tokens" value="COMMA,SEMI,ELLIPSIS,ARRAY_DECLARATOR,RBRACK,METHOD_REF" />
</module>
<module name="SeparatorWrap">
<property name="option" value="nl" />
<property name="tokens" value="DOT,AT" />
</module>
<module name="SingleSpaceSeparator" />
<module name="TypecastParenPad" />
<module name="WhitespaceAfter">
<property name="tokens" value="COMMA" />
</module>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true" />
<property name="ignoreEnhancedForColon" value="false" />
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,DO_WHILE,EQUAL,GE,GT,LAMBDA,LAND,LCURLY,LE,LITERAL_RETURN,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND" />
</module>
</module>
<module name="FileTabCharacter" />
<module name="NewlineAtEndOfFile" />
</module>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suppressions PUBLIC
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
<!-- Has a public m_label field. We need to check if this is used in other projects before renaming it. -->
<suppress checks="MemberName" files=".*[\\/]TileComputerBase.java"
message="Name 'm_label' must match pattern .*" />
<!-- All the config options and method fields. -->
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" />
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" />
</suppressions>

3
config/license/api.txt Normal file
View File

@ -0,0 +1,3 @@
This file is part of the public ComputerCraft API - http://www.computercraft.info
Copyright Daniel Ratcliffe, 2011-${year}. 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.

3
config/license/main.txt Normal file
View File

@ -0,0 +1,3 @@
This file is part of ComputerCraft - http://www.computercraft.info
Copyright Daniel Ratcliffe, 2011-${year}. Do not distribute without permission.
Send enquiries to dratcliffe@gmail.com

View File

@ -1,9 +1,8 @@
/*
* 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
* 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;
import dan200.computercraft.api.turtle.ITurtleUpgrade;

View File

@ -0,0 +1,41 @@
/*
* 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.filesystem;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Objects;
/**
* An {@link IOException} which occurred on a specific file.
*
* This may be thrown from a {@link IMount} or {@link IWritableMount} to give more information about a failure.
*/
public class FileOperationException extends IOException
{
private static final long serialVersionUID = -8809108200853029849L;
private final String filename;
public FileOperationException( @Nullable String filename, @Nonnull String message )
{
super( Objects.requireNonNull( message, "message cannot be null" ) );
this.filename = filename;
}
public FileOperationException( String message )
{
super( Objects.requireNonNull( message, "message cannot be null" ) );
this.filename = null;
}
@Nullable
public String getFilename()
{
return filename;
}
}

View File

@ -90,7 +90,6 @@ public interface IMount
* @throws IOException If the file does not exist, or could not be opened.
*/
@Nonnull
@SuppressWarnings( "deprecation" )
default ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOException
{
return Channels.newChannel( openForRead( path ) );

View File

@ -67,7 +67,6 @@ public interface IWritableMount extends IMount
* @throws IOException If the file could not be opened for writing.
*/
@Nonnull
@SuppressWarnings( "deprecation" )
default WritableByteChannel openChannelForWrite( @Nonnull String path ) throws IOException
{
return Channels.newChannel( openForWrite( path ) );
@ -94,7 +93,6 @@ default WritableByteChannel openChannelForWrite( @Nonnull String path ) throws I
* @throws IOException If the file could not be opened for writing.
*/
@Nonnull
@SuppressWarnings( "deprecation" )
default WritableByteChannel openChannelForAppend( @Nonnull String path ) throws IOException
{
return Channels.newChannel( openForAppend( path ) );

View File

@ -1,9 +1,8 @@
/*
* 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
* 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.peripheral;
import javax.annotation.Nonnull;

View File

@ -1,9 +1,8 @@
/*
* 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
* 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.pocket;
import net.minecraft.item.ItemStack;

View File

@ -1,9 +1,8 @@
/*
* 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
* 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.turtle.event;
import dan200.computercraft.api.lua.ILuaContext;

View File

@ -1,9 +1,8 @@
/*
* 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
* 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.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess;

View File

@ -88,7 +88,7 @@ private void drawSelectionSlot( boolean advanced )
int slotX = slot % 4;
int slotY = slot / 4;
mc.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
drawTexturedModalRect( guiLeft + m_container.m_turtleInvStartX - 2 + slotX * 18, guiTop + m_container.m_playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24 );
drawTexturedModalRect( guiLeft + m_container.turtleInvStartX - 2 + slotX * 18, guiTop + m_container.playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24 );
}
}

View File

@ -94,7 +94,7 @@ private static class NormalAwareTransformer extends VertexTransformer
private final Point3f[] before = new Point3f[4];
private final Point3f[] after = new Point3f[4];
public NormalAwareTransformer( IVertexConsumer parent, Matrix4f positionMatrix, Matrix4f normalMatrix )
NormalAwareTransformer( IVertexConsumer parent, Matrix4f positionMatrix, Matrix4f normalMatrix )
{
super( parent );
this.positionMatrix = positionMatrix;

View File

@ -62,8 +62,8 @@ public static void drawHighlight( DrawBlockHighlightEvent event )
if( monitor.getYIndex() != monitor.getHeight() - 1 ) faces.remove( monitor.getDown() );
GlStateManager.enableBlend();
GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
GlStateManager.lineWidth(Math.max(2.5F, (float) Minecraft.getInstance().mainWindow.getFramebufferWidth() / 1920.0F * 2.5F));
GlStateManager.blendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO );
GlStateManager.lineWidth( Math.max( 2.5F, (float) Minecraft.getInstance().mainWindow.getFramebufferWidth() / 1920.0F * 2.5F ) );
GlStateManager.disableTexture2D();
GlStateManager.depthMask( false );
GlStateManager.pushMatrix();

View File

@ -70,7 +70,10 @@ private static final class TurtleModel implements IUnbakedModel
{
private final ResourceLocation family;
private TurtleModel( ResourceLocation family ) {this.family = family;}
private TurtleModel( ResourceLocation family )
{
this.family = family;
}
@Nonnull
@Override

View File

@ -93,7 +93,7 @@ private List<BakedQuad> buildQuads( IBlockState state, EnumFacing side, Random r
upgradeTransform = new Matrix4f( m_generalTransform );
upgradeTransform.mul( m_rightUpgradeTransform );
}
ModelTransformer.transformQuadsTo( quads, m_rightUpgradeModel.getQuads( state, side, rand , EmptyModelData.INSTANCE), upgradeTransform );
ModelTransformer.transformQuadsTo( quads, m_rightUpgradeModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
}
quads.trimToSize();
return quads;

View File

@ -43,9 +43,7 @@ public FSAPI( IAPIEnvironment env )
@Override
public String[] getNames()
{
return new String[] {
"fs"
};
return new String[] { "fs" };
}
@Override

View File

@ -42,9 +42,7 @@ public HTTPAPI( IAPIEnvironment environment )
@Override
public String[] getNames()
{
return new String[] {
"http"
};
return new String[] { "http" };
}
@Override
@ -83,6 +81,7 @@ public String[] getMethodNames()
}
@Override
@SuppressWarnings( "resource" )
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
{
switch( method )
@ -95,7 +94,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
if( args.length >= 1 && args[0] instanceof Map )
{
Map<?, ?> options = (Map) args[0];
Map<?, ?> options = (Map<?, ?>) args[0];
address = getStringField( options, "url" );
postString = optStringField( options, "body", null );
headerTable = optTableField( options, "headers", Collections.emptyMap() );
@ -135,7 +134,6 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
try
{
URI uri = HttpRequest.checkUri( address );
HttpRequest request = new HttpRequest( requests, m_apiEnvironment, address, postString, headers, binary, redirect );
long requestBody = request.body().readableBytes() + HttpRequest.getHeaderSize( headers );

View File

@ -10,6 +10,7 @@
* This exists purely to ensure binary compatibility.
*
* @see dan200.computercraft.api.lua.ILuaAPI
* @deprecated Use the version in the public API. Only exists for compatibility with CCEmuX.
*/
@Deprecated
public interface ILuaAPI extends dan200.computercraft.api.lua.ILuaAPI

View File

@ -36,9 +36,9 @@ public class OSAPI implements ILuaAPI
private static class Timer
{
public int m_ticksLeft;
int m_ticksLeft;
public Timer( int ticksLeft )
Timer( int ticksLeft )
{
m_ticksLeft = ticksLeft;
}
@ -46,10 +46,10 @@ public Timer( int ticksLeft )
private static class Alarm implements Comparable<Alarm>
{
public final double m_time;
public final int m_day;
final double m_time;
final int m_day;
public Alarm( double time, int day )
Alarm( double time, int day )
{
m_time = time;
m_day = day;
@ -78,9 +78,7 @@ public OSAPI( IAPIEnvironment environment )
@Override
public String[] getNames()
{
return new String[] {
"os"
};
return new String[] { "os" };
}
@Override
@ -385,9 +383,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
// Get in-game epoch
synchronized( m_alarms )
{
return new Object[] {
m_day * 86400000 + (int) (m_time * 3600000.0f)
};
return new Object[] { m_day * 86400000 + (int) (m_time * 3600000.0f) };
}
default:
throw new LuaException( "Unsupported operation" );
@ -401,7 +397,6 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
Instant instant = Instant.ofEpochSecond( time );
ZonedDateTime date;
ZoneOffset offset;
boolean isDst;
if( format.startsWith( "!" ) )
{
offset = ZoneOffset.UTC;

View File

@ -36,7 +36,7 @@ private class PeripheralWrapper extends ComputerAccess
private Map<String, Integer> m_methodMap;
private boolean m_attached;
public PeripheralWrapper( IPeripheral peripheral, String side )
PeripheralWrapper( IPeripheral peripheral, String side )
{
super( m_environment );
m_side = side;
@ -282,9 +282,7 @@ public void onPeripheralChanged( ComputerSide side, IPeripheral newPeripheral )
@Override
public String[] getNames()
{
return new String[] {
"peripheral"
};
return new String[] { "peripheral" };
}
@Override
@ -326,7 +324,7 @@ public String[] getMethodNames()
"isPresent",
"getType",
"getMethods",
"call"
"call",
};
}
@ -356,7 +354,6 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
ComputerSide side = ComputerSide.valueOfInsensitive( getString( args, 0 ) );
if( side != null )
{
String type = null;
synchronized( m_peripherals )
{
PeripheralWrapper p = m_peripherals[side.ordinal()];

View File

@ -29,9 +29,7 @@ public RedstoneAPI( IAPIEnvironment environment )
@Override
public String[] getNames()
{
return new String[] {
"rs", "redstone"
};
return new String[] { "rs", "redstone" };
}
@Nonnull

View File

@ -33,9 +33,7 @@ public TermAPI( IAPIEnvironment environment )
@Override
public String[] getNames()
{
return new String[] {
"term"
};
return new String[] { "term" };
}
@Nonnull
@ -89,9 +87,7 @@ public static int parseColour( Object[] args ) throws LuaException
public static Object[] encodeColour( int colour ) throws LuaException
{
return new Object[] {
1 << colour
};
return new Object[] { 1 << colour };
}
public static void setColour( Terminal terminal, int colour, double r, double g, double b )

View File

@ -212,6 +212,7 @@ else if( count == 0 && m_seekable != null )
}
}
case 3: // close
checkOpen();
close();
return null;
case 4: // seek

View File

@ -95,6 +95,7 @@ else if( args.length > 0 && args[0] instanceof String )
return null;
}
case 2: // close
checkOpen();
close();
return null;
case 3: // seek

View File

@ -152,6 +152,7 @@ else if( count <= BUFFER_SIZE )
return null;
}
case 3: // close
checkOpen();
close();
return null;
default:

View File

@ -93,6 +93,7 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O
return null;
}
case 3: // close
checkOpen();
close();
return null;
default:

View File

@ -37,8 +37,13 @@ protected void checkOpen() throws LuaException
protected final void close()
{
m_open = false;
IoUtil.closeQuietly( m_closable );
m_closable = null;
Closeable closeable = m_closable;
if( closeable != null )
{
IoUtil.closeQuietly( closeable );
m_closable = null;
}
}
/**

View File

@ -72,7 +72,8 @@ protected final boolean tryClose()
*/
protected void dispose()
{
@SuppressWarnings( "unchecked" ) T thisT = (T) this;
@SuppressWarnings( "unchecked" )
T thisT = (T) this;
limiter.release( thisT );
}
@ -95,7 +96,8 @@ public final void close()
public boolean queue( Consumer<T> task )
{
@SuppressWarnings( "unchecked" ) T thisT = (T) this;
@SuppressWarnings( "unchecked" )
T thisT = (T) this;
return limiter.queue( thisT, () -> task.accept( thisT ) );
}

View File

@ -30,7 +30,10 @@ public enum ComputerSide
private final String name;
ComputerSide( String name ) {this.name = name;}
ComputerSide( String name )
{
this.name = name;
}
@Nonnull
public static ComputerSide valueOf( int side )

View File

@ -6,6 +6,7 @@
package dan200.computercraft.core.filesystem;
import dan200.computercraft.api.filesystem.FileOperationException;
import dan200.computercraft.api.filesystem.IMount;
import javax.annotation.Nonnull;
@ -95,7 +96,7 @@ else if( foundDirs > 1 )
}
else
{
throw new IOException( "/" + path + ": Not a directory" );
throw new FileOperationException( path, "Not a directory" );
}
}
@ -110,7 +111,7 @@ public long getSize( @Nonnull String path ) throws IOException
return part.getSize( path );
}
}
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
@Nonnull
@ -126,7 +127,7 @@ public InputStream openForRead( @Nonnull String path ) throws IOException
return part.openForRead( path );
}
}
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
@Nonnull
@ -141,6 +142,6 @@ public ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOE
return part.openChannelForRead( path );
}
}
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
}

View File

@ -6,6 +6,7 @@
package dan200.computercraft.core.filesystem;
import dan200.computercraft.api.filesystem.FileOperationException;
import dan200.computercraft.api.filesystem.IMount;
import javax.annotation.Nonnull;
@ -44,7 +45,7 @@ public long getSize( @Nonnull String path )
@Deprecated
public InputStream openForRead( @Nonnull String path ) throws IOException
{
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
@Nonnull
@ -52,6 +53,6 @@ public InputStream openForRead( @Nonnull String path ) throws IOException
@Deprecated
public ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOException
{
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
}

View File

@ -7,6 +7,7 @@
package dan200.computercraft.core.filesystem;
import com.google.common.collect.Sets;
import dan200.computercraft.api.filesystem.FileOperationException;
import dan200.computercraft.api.filesystem.IWritableMount;
import javax.annotation.Nonnull;
@ -167,12 +168,12 @@ public void list( @Nonnull String path, @Nonnull List<String> contents ) throws
{
if( !created() )
{
if( !path.isEmpty() ) throw new IOException( "/" + path + ": Not a directory" );
if( !path.isEmpty() ) throw new FileOperationException( path, "Not a directory" );
return;
}
File file = getRealPath( path );
if( !file.exists() || !file.isDirectory() ) throw new IOException( "/" + path + ": Not a directory" );
if( !file.exists() || !file.isDirectory() ) throw new FileOperationException( path, "Not a directory" );
String[] paths = file.list();
for( String subPath : paths )
@ -194,7 +195,7 @@ public long getSize( @Nonnull String path ) throws IOException
if( file.exists() ) return file.isDirectory() ? 0 : file.length();
}
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
@Nonnull
@ -208,7 +209,7 @@ public InputStream openForRead( @Nonnull String path ) throws IOException
if( file.exists() && !file.isDirectory() ) return new FileInputStream( file );
}
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
@Nonnull
@ -221,7 +222,7 @@ public ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOE
if( file.exists() && !file.isDirectory() ) return FileChannel.open( file.toPath(), READ_OPTIONS );
}
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
// IWritableMount implementation
@ -233,7 +234,7 @@ public void makeDirectory( @Nonnull String path ) throws IOException
File file = getRealPath( path );
if( file.exists() )
{
if( !file.isDirectory() ) throw new IOException( "/" + path + ": File exists" );
if( !file.isDirectory() ) throw new FileOperationException( path, "File exists" );
return;
}
@ -247,7 +248,7 @@ public void makeDirectory( @Nonnull String path ) throws IOException
if( getRemainingSpace() < dirsToCreate * MINIMUM_FILE_SIZE )
{
throw new IOException( "/" + path + ": Out of space" );
throw new FileOperationException( path, "Out of space" );
}
if( file.mkdirs() )
@ -256,14 +257,14 @@ public void makeDirectory( @Nonnull String path ) throws IOException
}
else
{
throw new IOException( "/" + path + ": Access denied" );
throw new FileOperationException( path, "Access denied" );
}
}
@Override
public void delete( @Nonnull String path ) throws IOException
{
if( path.isEmpty() ) throw new IOException( "/" + path + ": Access denied" );
if( path.isEmpty() ) throw new FileOperationException( path, "Access denied" );
if( created() )
{
@ -319,7 +320,7 @@ public WritableByteChannel openChannelForWrite( @Nonnull String path ) throws IO
{
create();
File file = getRealPath( path );
if( file.exists() && file.isDirectory() ) throw new IOException( "/" + path + ": Cannot write to directory" );
if( file.exists() && file.isDirectory() ) throw new FileOperationException( path, "Cannot write to directory" );
if( file.exists() )
{
@ -327,7 +328,7 @@ public WritableByteChannel openChannelForWrite( @Nonnull String path ) throws IO
}
else if( getRemainingSpace() < MINIMUM_FILE_SIZE )
{
throw new IOException( "/" + path + ": Out of space" );
throw new FileOperationException( path, "Out of space" );
}
m_usedSpace += MINIMUM_FILE_SIZE;
@ -340,12 +341,12 @@ public WritableByteChannel openChannelForAppend( @Nonnull String path ) throws I
{
if( !created() )
{
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
File file = getRealPath( path );
if( !file.exists() ) throw new IOException( "/" + path + ": No such file" );
if( file.isDirectory() ) throw new IOException( "/" + path + ": Cannot write to directory" );
if( !file.exists() ) throw new FileOperationException( path, "No such file" );
if( file.isDirectory() ) throw new FileOperationException( path, "Cannot write to directory" );
// Allowing seeking when appending is not recommended, so we use a separate channel.
return new WritableCountingChannel(

View File

@ -8,6 +8,7 @@
import com.google.common.io.ByteStreams;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.filesystem.FileOperationException;
import dan200.computercraft.api.filesystem.IFileSystem;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount;
@ -45,7 +46,7 @@ private static class MountWrapper
m_writableMount = null;
}
public MountWrapper( String label, String location, IWritableMount mount )
MountWrapper( String label, String location, IWritableMount mount )
{
this( label, location, (IMount) mount );
m_writableMount = mount;
@ -107,7 +108,7 @@ public boolean isDirectory( String path ) throws FileSystemException
}
catch( IOException e )
{
throw new FileSystemException( e.getMessage() );
throw localExceptionOf( e );
}
}
@ -122,12 +123,12 @@ public void list( String path, List<String> contents ) throws FileSystemExceptio
}
else
{
throw new FileSystemException( "/" + path + ": Not a directory" );
throw localExceptionOf( path, "Not a directory" );
}
}
catch( IOException e )
{
throw new FileSystemException( e.getMessage() );
throw localExceptionOf( e );
}
}
@ -149,12 +150,12 @@ public long getSize( String path ) throws FileSystemException
}
else
{
throw new FileSystemException( "/" + path + ": No such file" );
throw localExceptionOf( path, "No such file" );
}
}
catch( IOException e )
{
throw new FileSystemException( e.getMessage() );
throw localExceptionOf( e );
}
}
@ -169,12 +170,12 @@ public ReadableByteChannel openForRead( String path ) throws FileSystemException
}
else
{
throw new FileSystemException( "/" + path + ": No such file" );
throw localExceptionOf( path, "No such file" );
}
}
catch( IOException e )
{
throw new FileSystemException( e.getMessage() );
throw localExceptionOf( e );
}
}
@ -182,19 +183,14 @@ public ReadableByteChannel openForRead( String path ) throws FileSystemException
public void makeDirectory( String path ) throws FileSystemException
{
if( m_writableMount == null )
{
throw new FileSystemException( "/" + path + ": Access denied" );
}
if( m_writableMount == null ) throw exceptionOf( path, "Access denied" );
path = toLocal( path );
try
{
path = toLocal( path );
if( m_mount.exists( path ) )
{
if( !m_mount.isDirectory( path ) )
{
throw new FileSystemException( "/" + path + ": File exists" );
}
if( !m_mount.isDirectory( path ) ) throw localExceptionOf( path, "File exists" );
}
else
{
@ -203,16 +199,14 @@ public void makeDirectory( String path ) throws FileSystemException
}
catch( IOException e )
{
throw new FileSystemException( e.getMessage() );
throw localExceptionOf( e );
}
}
public void delete( String path ) throws FileSystemException
{
if( m_writableMount == null )
{
throw new FileSystemException( "/" + path + ": Access denied" );
}
if( m_writableMount == null ) throw exceptionOf( path, "Access denied" );
try
{
path = toLocal( path );
@ -227,22 +221,20 @@ public void delete( String path ) throws FileSystemException
}
catch( IOException e )
{
throw new FileSystemException( e.getMessage() );
throw localExceptionOf( e );
}
}
public WritableByteChannel openForWrite( String path ) throws FileSystemException
{
if( m_writableMount == null )
{
throw new FileSystemException( "/" + path + ": Access denied" );
}
if( m_writableMount == null ) throw exceptionOf( path, "Access denied" );
path = toLocal( path );
try
{
path = toLocal( path );
if( m_mount.exists( path ) && m_mount.isDirectory( path ) )
{
throw new FileSystemException( "/" + path + ": Cannot write to directory" );
throw localExceptionOf( path, "Cannot write to directory" );
}
else
{
@ -263,19 +255,17 @@ public WritableByteChannel openForWrite( String path ) throws FileSystemExceptio
}
catch( IOException e )
{
throw new FileSystemException( e.getMessage() );
throw localExceptionOf( e );
}
}
public WritableByteChannel openForAppend( String path ) throws FileSystemException
{
if( m_writableMount == null )
{
throw new FileSystemException( "/" + path + ": Access denied" );
}
if( m_writableMount == null ) throw exceptionOf( path, "Access denied" );
path = toLocal( path );
try
{
path = toLocal( path );
if( !m_mount.exists( path ) )
{
if( !path.isEmpty() )
@ -290,7 +280,7 @@ public WritableByteChannel openForAppend( String path ) throws FileSystemExcepti
}
else if( m_mount.isDirectory( path ) )
{
throw new FileSystemException( "/" + path + ": Cannot write to directory" );
throw localExceptionOf( path, "Cannot write to directory" );
}
else
{
@ -303,16 +293,36 @@ else if( m_mount.isDirectory( path ) )
}
catch( IOException e )
{
throw new FileSystemException( e.getMessage() );
throw localExceptionOf( e );
}
}
// private members
private String toLocal( String path )
{
return FileSystem.toLocal( path, m_location );
}
private FileSystemException localExceptionOf( IOException e )
{
if( !m_location.isEmpty() && e instanceof FileOperationException )
{
FileOperationException ex = (FileOperationException) e;
if( ex.getFilename() != null ) return localExceptionOf( ex.getFilename(), ex.getMessage() );
}
return new FileSystemException( e.getMessage() );
}
private FileSystemException localExceptionOf( String path, String message )
{
if( !m_location.isEmpty() ) path = path.isEmpty() ? m_location : m_location + "/" + path;
return exceptionOf( path, message );
}
private static FileSystemException exceptionOf( String path, String message )
{
return new FileSystemException( "/" + path + ": " + message );
}
}
private final FileSystemWrapperMount m_wrapper = new FileSystemWrapperMount( this );
@ -769,7 +779,7 @@ private static String sanitizePath( String path, boolean allowWildcards )
// Clean the path or illegal characters.
final char[] specialChars = new char[] {
'"', ':', '<', '>', '?', '|' // Sorted by ascii value (important)
'"', ':', '<', '>', '?', '|', // Sorted by ascii value (important)
};
StringBuilder cleanName = new StringBuilder();

View File

@ -9,6 +9,7 @@
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.io.ByteStreams;
import dan200.computercraft.api.filesystem.FileOperationException;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.core.apis.handles.ArrayByteChannel;
import dan200.computercraft.shared.util.IoUtil;
@ -92,7 +93,7 @@ public JarMount( File jarFile, String subPath ) throws IOException
new MountReference( this );
// Read in all the entries
root = new FileEntry( "" );
root = new FileEntry();
Enumeration<? extends ZipEntry> zipEntries = zip.entries();
while( zipEntries.hasMoreElements() )
{
@ -139,7 +140,7 @@ private void create( ZipEntry entry, String localPath )
FileEntry nextEntry = lastEntry.children.get( part );
if( nextEntry == null || !nextEntry.isDirectory() )
{
lastEntry.children.put( part, nextEntry = new FileEntry( part ) );
lastEntry.children.put( part, nextEntry = new FileEntry() );
}
lastEntry = nextEntry;
@ -166,7 +167,7 @@ public boolean isDirectory( @Nonnull String path )
public void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException
{
FileEntry file = get( path );
if( file == null || !file.isDirectory() ) throw new IOException( "/" + path + ": Not a directory" );
if( file == null || !file.isDirectory() ) throw new FileOperationException( path, "Not a directory" );
file.list( contents );
}
@ -176,7 +177,7 @@ public long getSize( @Nonnull String path ) throws IOException
{
FileEntry file = get( path );
if( file != null ) return file.size;
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
@Nonnull
@ -218,22 +219,15 @@ public ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOE
}
}
throw new IOException( "/" + path + ": No such file" );
throw new FileOperationException( path, "No such file" );
}
private static class FileEntry
{
final String name;
String path;
long size;
Map<String, FileEntry> children;
FileEntry( String name )
{
this.name = name;
}
void setup( ZipEntry entry )
{
path = entry.getName();

View File

@ -170,7 +170,7 @@ public long getSize( @Nonnull String path ) throws IOException
{
total += read;
read = s.read( TEMP_BUFFER );
} while( read > 0 );
} while ( read > 0 );
return file.size = total;
}

View File

@ -550,7 +550,7 @@ public long issueMainThreadTask( @Nonnull final ILuaTask task ) throws LuaExcept
{
if( ComputerCraft.logPeripheralErrors ) ComputerCraft.log.error( "Error running task", t );
m_computer.queueEvent( "task_complete", new Object[] {
taskID, false, "Java Exception Thrown: " + t
taskID, false, "Java Exception Thrown: " + t,
} );
}
};

View File

@ -8,7 +8,7 @@
public class TextBuffer
{
public char[] m_text;
private final char[] m_text;
public TextBuffer( char c, int length )
{

View File

@ -54,7 +54,6 @@ public final boolean onBlockActivated( IBlockState state, World world, BlockPos
@Override
@Deprecated
@SuppressWarnings( "deprecation" )
public final void neighborChanged( IBlockState state, World world, BlockPos pos, Block neighbourBlock, BlockPos neighbourPos )
{
TileEntity tile = world.getTileEntity( pos );

View File

@ -49,9 +49,7 @@ public CommandAPI( TileCommandComputer computer )
@Override
public String[] getNames()
{
return new String[] {
"commands"
};
return new String[] { "commands" };
}
@Nonnull
@ -64,7 +62,7 @@ public String[] getMethodNames()
"list",
"getBlockPosition",
"getBlockInfos",
"getBlockInfo"
"getBlockInfo",
};
}

View File

@ -11,9 +11,9 @@
import java.util.Map;
import java.util.Random;
public class ComputerRegistry<TComputer extends IComputer>
public class ComputerRegistry<T extends IComputer>
{
private Map<Integer, TComputer> m_computers;
private Map<Integer, T> m_computers;
private int m_nextUnusedInstanceID;
private int m_sessionID;
@ -33,12 +33,12 @@ public int getUnusedInstanceID()
return m_nextUnusedInstanceID++;
}
public Collection<TComputer> getComputers()
public Collection<T> getComputers()
{
return m_computers.values();
}
public TComputer get( int instanceID )
public T get( int instanceID )
{
if( instanceID >= 0 )
{
@ -55,7 +55,7 @@ public boolean contains( int instanceID )
return m_computers.containsKey( instanceID );
}
public void add( int instanceID, TComputer computer )
public void add( int instanceID, T computer )
{
if( m_computers.containsKey( instanceID ) )
{

View File

@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.charset;
import dan200.computercraft.shared.common.TileGeneric;

View File

@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.charset;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;

View File

@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.charset;
import dan200.computercraft.ComputerCraft;

View File

@ -52,7 +52,7 @@ public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaCont
{
case 0: // getCommand
return context.executeMainThreadTask( () -> new Object[] {
m_commandBlock.getCommandBlockLogic().getCommand()
m_commandBlock.getCommandBlockLogic().getCommand(),
} );
case 1:
{

View File

@ -50,7 +50,7 @@ public String[] getMethodNames()
"playAudio",
"stopAudio",
"ejectDisk",
"getDiskID"
"getDiskID",
};
}

View File

@ -73,7 +73,7 @@ public void receiveSameDimension( @Nonnull Packet packet, double distance )
for( IComputerAccess computer : m_computers )
{
computer.queueEvent( "modem_message", new Object[] {
computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload(), distance
computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload(), distance,
} );
}
}
@ -89,7 +89,7 @@ public void receiveDifferentDimension( @Nonnull Packet packet )
for( IComputerAccess computer : m_computers )
{
computer.queueEvent( "modem_message", new Object[] {
computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload()
computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload(),
} );
}
}

View File

@ -277,7 +277,7 @@ private static class RemotePeripheralWrapper implements IComputerAccess
private final String[] m_methods;
private final Map<String, Integer> m_methodMap;
public RemotePeripheralWrapper( WiredModemElement element, IPeripheral peripheral, IComputerAccess computer, String name )
RemotePeripheralWrapper( WiredModemElement element, IPeripheral peripheral, IComputerAccess computer, String name )
{
m_element = element;
m_peripheral = peripheral;

View File

@ -155,7 +155,7 @@ public void blockTick()
for( IComputerAccess computer : monitor.m_computers )
{
computer.queueEvent( "monitor_resize", new Object[] {
computer.getAttachmentName()
computer.getAttachmentName(),
} );
}
}
@ -625,7 +625,7 @@ private void monitorTouched( float xPos, float yPos, float zPos )
for( IComputerAccess computer : monitor.m_computers )
{
computer.queueEvent( "monitor_touch", new Object[] {
computer.getAttachmentName(), xCharPos, yCharPos
computer.getAttachmentName(), xCharPos, yCharPos,
} );
}
}

View File

@ -59,8 +59,8 @@ public String getType()
public String[] getMethodNames()
{
return new String[] {
"playSound", // Plays sound at resourceLocator
"playNote" // Plays note
"playSound",
"playNote",
};
}

View File

@ -35,9 +35,7 @@ public PocketAPI( PocketServerComputer computer )
@Override
public String[] getNames()
{
return new String[] {
"pocket"
};
return new String[] { "pocket" };
}
@Nonnull
@ -46,7 +44,7 @@ public String[] getMethodNames()
{
return new String[] {
"equipBack",
"unequipBack"
"unequipBack",
};
}

View File

@ -46,9 +46,7 @@ public TurtleAPI( IAPIEnvironment environment, ITurtleAccess turtle )
@Override
public String[] getNames()
{
return new String[] {
"turtle"
};
return new String[] { "turtle" };
}
@Nonnull

View File

@ -811,14 +811,14 @@ private void updateCommands()
else
{
computer.queueEvent( "turtle_response", new Object[] {
callbackID, true
callbackID, true,
} );
}
}
else
{
computer.queueEvent( "turtle_response", new Object[] {
callbackID, false, result != null ? result.getErrorMessage() : null
callbackID, false, result != null ? result.getErrorMessage() : null,
} );
}
}

View File

@ -64,7 +64,6 @@ public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle )
// Remember old block
EnumFacing direction = m_direction.toWorldDir( turtle );
World world = turtle.getWorld();
BlockPos coordinates = turtle.getPosition().offset( direction );
// Create a fake player, and orient it appropriately

View File

@ -26,8 +26,8 @@ public class ContainerTurtle extends Container implements IContainerComputer
{
private static final int PROGRESS_ID_SELECTED_SLOT = 0;
public final int m_playerInvStartY;
public final int m_turtleInvStartX;
public final int playerInvStartY;
public final int turtleInvStartX;
private final ITurtleAccess m_turtle;
private IComputer m_computer;
@ -36,8 +36,8 @@ public class ContainerTurtle extends Container implements IContainerComputer
protected ContainerTurtle( IInventory playerInventory, ITurtleAccess turtle, int playerInvStartY, int turtleInvStartX )
{
m_playerInvStartY = playerInvStartY;
m_turtleInvStartX = turtleInvStartX;
this.playerInvStartY = playerInvStartY;
this.turtleInvStartX = turtleInvStartX;
m_turtle = turtle;
m_selectedSlot = m_turtle.getWorld().isRemote ? 0 : m_turtle.getSelectedSlot();

View File

@ -55,7 +55,7 @@ public TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull Turt
{
if( verb == TurtleVerb.Dig )
{
ItemStack hoe = m_item.copy();
ItemStack hoe = item.copy();
ItemStack remainder = TurtlePlaceCommand.deploy( hoe, turtle, direction, null, null );
if( remainder != hoe )
{

View File

@ -60,7 +60,7 @@ public TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull Turt
{
if( verb == TurtleVerb.Dig )
{
ItemStack shovel = m_item.copy();
ItemStack shovel = item.copy();
ItemStack remainder = TurtlePlaceCommand.deploy( shovel, turtle, direction, null, null );
if( remainder != shovel )
{

View File

@ -49,18 +49,18 @@
public class TurtleTool extends AbstractTurtleUpgrade
{
protected ItemStack m_item;
protected final ItemStack item;
public TurtleTool( ResourceLocation id, String adjective, Item item )
{
super( id, TurtleUpgradeType.Tool, adjective, item );
m_item = new ItemStack( item );
this.item = new ItemStack( item );
}
public TurtleTool( ResourceLocation id, Item item )
{
super( id, TurtleUpgradeType.Tool, item );
m_item = new ItemStack( item );
this.item = new ItemStack( item );
}
@Nonnull
@ -77,7 +77,7 @@ public Pair<IBakedModel, Matrix4f> getModel( ITurtleAccess turtle, @Nonnull Turt
);
Minecraft mc = Minecraft.getInstance();
return Pair.of(
mc.getItemRenderer().getItemModelMesher().getItemModel( m_item ),
mc.getItemRenderer().getItemModelMesher().getItemModel( item ),
transform
);
}
@ -125,7 +125,7 @@ private TurtleCommandResult attack( final ITurtleAccess turtle, EnumFacing direc
if( hit != null )
{
// Load up the turtle's inventory
ItemStack stackCopy = m_item.copy();
ItemStack stackCopy = item.copy();
turtlePlayer.loadInventory( stackCopy );
Entity hitEntity = hit.getKey();
@ -204,7 +204,7 @@ private TurtleCommandResult dig( ITurtleAccess turtle, EnumFacing direction, Tur
IFluidState fluidState = world.getFluidState( blockPosition );
TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer( turtle, turtlePosition, direction );
turtlePlayer.loadInventory( m_item.copy() );
turtlePlayer.loadInventory( item.copy() );
if( ComputerCraft.turtlesObeyBlockProtection )
{

View File

@ -28,7 +28,9 @@
public final class IDAssigner
{
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final Type ID_TOKEN = new TypeToken<Map<String, Integer>>() {}.getType();
private static final Type ID_TOKEN = new TypeToken<Map<String, Integer>>()
{
}.getType();
private IDAssigner()
{

View File

@ -72,12 +72,11 @@ public static int encodeRGB8( double[] rgb )
public static double[] decodeRGB8( int rgb )
{
return new double[]
{
((rgb >> 16) & 0xFF) / 255.0f,
((rgb >> 8) & 0xFF) / 255.0f,
(rgb & 0xFF) / 255.0f
};
return new double[] {
((rgb >> 16) & 0xFF) / 255.0f,
((rgb >> 8) & 0xFF) / 255.0f,
(rgb & 0xFF) / 255.0f,
};
}
public NBTTagCompound writeToNBT( NBTTagCompound nbt )

View File

@ -9,7 +9,10 @@ for i = 1, args.n do
local files = fs.find(shell.resolve(args[i]))
if #files > 0 then
for n, file in ipairs(files) do
fs.delete(file)
local ok, err = pcall(fs.delete, file)
if not ok then
printError((err:gsub("^pcall: ", "")))
end
end
else
printError(args[i] .. ": No matching files")

View File

@ -95,7 +95,7 @@ public InputStream createResourceFile( String domain, String subPath )
public static IMount createMount( Class<?> klass, String path, String fallback )
{
File file = getContainingFile(klass);
File file = getContainingFile( klass );
if( file.isFile() )
{
@ -127,7 +127,7 @@ public static IMount createMount( Class<?> klass, String path, String fallback )
}
private static File getContainingFile(Class<?> klass)
private static File getContainingFile( Class<?> klass )
{
String path = klass.getProtectionDomain().getCodeSource().getLocation().getPath();
int bangIndex = path.indexOf( "!" );

View File

@ -7,7 +7,6 @@
package dan200.computercraft.core.computer;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount;
import dan200.computercraft.api.lua.ILuaAPI;
import dan200.computercraft.api.lua.ILuaContext;
@ -36,7 +35,7 @@ public static void run( String program )
.addFile( "test.lua", program )
.addFile( "startup", "assertion.assert(pcall(loadfile('test.lua', _ENV))) os.shutdown()" );
run( mount, x -> {} );
run( mount, x -> { } );
}
public static void run( IWritableMount mount, Consumer<Computer> setup )

View File

@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.core.filesystem;
import dan200.computercraft.api.filesystem.IMount;

View File

@ -245,14 +245,14 @@ public void testRemoveSplit()
assertEquals( Sets.newHashSet(), cE.allPeripherals().keySet(), "C's peripheral set should be empty" );
}
private static final int BRUTE_SIZE = 16;
private static final int TOGGLE_CONNECTION_TIMES = 5;
private static final int TOGGLE_NODE_TIMES = 5;
@Test
@Disabled( "Takes a long time to run, mostly for stress testing" )
public void testLarge()
{
final int BRUTE_SIZE = 16;
final int TOGGLE_CONNECTION_TIMES = 5;
final int TOGGLE_NODE_TIMES = 5;
Grid<IWiredNode> grid = new Grid<>( BRUTE_SIZE );
grid.map( ( existing, pos ) -> new NetworkElement( null, null, "n_" + pos ).getNode() );
@ -316,7 +316,7 @@ public void testLarge()
}
}
private static class NetworkElement implements IWiredElement
private static final class NetworkElement implements IWiredElement
{
private final World world;
private final Vec3d position;
@ -425,26 +425,12 @@ private static class Grid<T>
private final T[] box;
@SuppressWarnings( "unchecked" )
public Grid( int size )
Grid( int size )
{
this.size = size;
this.box = (T[]) new Object[size * size * size];
}
public void set( BlockPos pos, T elem )
{
int x = pos.getX(), y = pos.getY(), z = pos.getZ();
if( x >= 0 && x < size && y >= 0 && y < size && z >= 0 && z < size )
{
box[x * size * size + y * size + z] = elem;
}
else
{
throw new IndexOutOfBoundsException( pos.toString() );
}
}
public T get( BlockPos pos )
{
int x = pos.getX(), y = pos.getY(), z = pos.getZ();

View File

@ -34,10 +34,12 @@ local active_stubs = {}
-- @tparam string var The variable to stub
-- @param value The value to stub it with
local function stub(tbl, var, value)
table.insert(active_stubs, { tbl = tbl, var = var, value = tbl[var] })
_G[var] = value
end
check('stub', 1, 'table', tbl)
check('stub', 2, 'string', var)
table.insert(active_stubs, { tbl = tbl, var = var, value = tbl[var] })
rawset(tbl, var, value)
end
--- Capture the current global state of the computer
local function push_state()
@ -55,7 +57,7 @@ end
local function pop_state(state)
for i = #active_stubs, 1, -1 do
local stub = active_stubs[i]
stub.tbl[stub.var] = stub.value
rawset(stub.tbl, stub.var, stub.value)
end
active_stubs = state.stubs
@ -353,6 +355,9 @@ if not fs.isDir(root_dir) then
error()
end
-- Ensure the test folder is also on the package path
package.path = ("/%s/?.lua;/%s/?/init.lua;%s"):format(root_dir, root_dir, package.path)
do
-- Load in the tests from all our files
local env = setmetatable({}, { __index = _ENV })

View File

@ -11,4 +11,127 @@ describe("The fs library", function()
expect.error(fs.complete, "", "", true, 1):eq("bad argument #4 (expected boolean, got number)")
end)
end)
describe("fs.list", function()
it("fails on files", function()
expect.error(fs.list, "rom/startup.lua"):eq("/rom/startup.lua: Not a directory")
expect.error(fs.list, "startup.lua"):eq("/startup.lua: Not a directory")
end)
it("fails on non-existent nodes", function()
expect.error(fs.list, "rom/x"):eq("/rom/x: Not a directory")
expect.error(fs.list, "x"):eq("/x: Not a directory")
end)
end)
describe("fs.list", function()
it("fails on files", function()
expect.error(fs.list, "rom/startup.lua"):eq("/rom/startup.lua: Not a directory")
expect.error(fs.list, "startup.lua"):eq("/startup.lua: Not a directory")
end)
it("fails on non-existent nodes", function()
expect.error(fs.list, "rom/x"):eq("/rom/x: Not a directory")
expect.error(fs.list, "x"):eq("/x: Not a directory")
end)
end)
describe("fs.getSize", function()
it("fails on non-existent nodes", function()
expect.error(fs.getSize, "rom/x"):eq("/rom/x: No such file")
expect.error(fs.getSize, "x"):eq("/x: No such file")
end)
end)
describe("fs.open", function()
describe("reading", function()
it("fails on directories", function()
expect { fs.open("rom", "r") }:same { nil, "/rom: No such file" }
expect { fs.open("", "r") }:same { nil, "/: No such file" }
end)
it("fails on non-existent nodes", function()
expect { fs.open("rom/x", "r") }:same { nil, "/rom/x: No such file" }
expect { fs.open("x", "r") }:same { nil, "/x: No such file" }
end)
it("errors when closing twice", function()
local handle = fs.open("rom/startup.lua", "r")
handle.close()
expect.error(handle.close):eq("attempt to use a closed file")
end)
end)
describe("reading in binary mode", function()
it("errors when closing twice", function()
local handle = fs.open("rom/startup.lua", "rb")
handle.close()
expect.error(handle.close):eq("attempt to use a closed file")
end)
end)
describe("writing", function()
it("fails on directories", function()
expect { fs.open("", "w") }:same { nil, "/: Cannot write to directory" }
end)
it("fails on read-only mounts", function()
expect { fs.open("rom/x", "w") }:same { nil, "/rom/x: Access denied" }
end)
it("errors when closing twice", function()
local handle = fs.open("test-files/out.txt", "w")
handle.close()
expect.error(handle.close):eq("attempt to use a closed file")
end)
end)
describe("writing in binary mode", function()
it("errors when closing twice", function()
local handle = fs.open("test-files/out.txt", "wb")
handle.close()
expect.error(handle.close):eq("attempt to use a closed file")
end)
end)
describe("appending", function()
it("fails on directories", function()
expect { fs.open("", "a") }:same { nil, "/: Cannot write to directory" }
end)
it("fails on read-only mounts", function()
expect { fs.open("rom/x", "a") }:same { nil, "/rom/x: Access denied" }
end)
end)
end)
describe("fs.makeDir", function()
it("fails on files", function()
expect.error(fs.makeDir, "startup.lua"):eq("/startup.lua: File exists")
end)
it("fails on read-only mounts", function()
expect.error(fs.makeDir, "rom/x"):eq("/rom/x: Access denied")
end)
end)
describe("fs.delete", function()
it("fails on read-only mounts", function()
expect.error(fs.delete, "rom/x"):eq("/rom/x: Access denied")
end)
end)
describe("fs.copy", function()
it("fails on read-only mounts", function()
expect.error(fs.copy, "rom", "rom/startup"):eq("/rom/startup: Access denied")
end)
end)
describe("fs.move", function()
it("fails on read-only mounts", function()
expect.error(fs.move, "rom", "rom/move"):eq("Access denied")
expect.error(fs.move, "test-files", "rom/move"):eq("Access denied")
expect.error(fs.move, "rom", "test-files"):eq("Access denied")
end)
end)
end)

View File

@ -1,3 +1,5 @@
local capture = require "test_helpers".capture_program
describe("The rm program", function()
local function touch(file)
io.open(file, "w"):close()
@ -32,4 +34,19 @@ describe("The rm program", function()
expect(fs.exists("/test-files/a.txt")):eq(false)
expect(fs.exists("/test-files/b.txt")):eq(false)
end)
it("displays the usage with no arguments", function()
expect(capture(stub, "rm"))
:matches { ok = true, output = "Usage: rm <paths>\n", error = "" }
end)
it("errors when trying to delete a read-only file", function()
expect(capture(stub, "rm /rom/startup.lua"))
:matches { ok = true, output = "", error = "/rom/startup.lua: Access denied\n" }
end)
it("errors when a glob fails to match", function()
expect(capture(stub, "rm", "never-existed"))
:matches { ok = true, output = "", error = "never-existed: No matching files\n" }
end)
end)

View File

@ -0,0 +1,46 @@
--- Run a program and capture its output
--
-- @tparam function(tbl:table, var:string, value:string) stub The active stub function.
-- @tparam string program The program name.
-- @tparam string ... Arguments to this program.
-- @treturn { ok = boolean, output = string, error = string, combined = string }
-- Whether this program terminated successfully, and the various output streams.
local function capture_program(stub, program, ...)
local output, error, combined = {}, {}, {}
local function out(stream, msg)
table.insert(stream, msg)
table.insert(combined, msg)
end
stub(_G, "print", function(...)
for i = 1, select('#', ...) do
if i > 1 then out(output, " ") end
out(output, tostring(select(i, ...)))
end
out(output, "\n")
end)
stub(_G, "printError", function(...)
for i = 1, select('#', ...) do
if i > 1 then out(error, " ") end
out(error, tostring(select(i, ...)))
end
out(error, "\n")
end)
stub(_G, "write", function(msg) out(output, tostring(msg)) end)
local ok = shell.run(program, ...)
return {
output = table.concat(output),
error = table.concat(error),
combined = table.concat(combined),
ok = ok
}
end
return {
capture_program = capture_program,
}