mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-15 22:17:39 +00:00
Compare commits
54 Commits
v1.96.1-rc
...
v1.12.2-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c802290437 | ||
![]() |
418420523a | ||
![]() |
813e91073d | ||
![]() |
7250f22ff6 | ||
![]() |
db31a53bba | ||
![]() |
3023f235a4 | ||
![]() |
79cd8b4da5 | ||
![]() |
8e4d311cd9 | ||
![]() |
9bd8c86a94 | ||
![]() |
cbc0c1d0b6 | ||
![]() |
49c37857d4 | ||
![]() |
a802f25dd6 | ||
![]() |
a80302c513 | ||
![]() |
1c46949da7 | ||
![]() |
46d78af068 | ||
![]() |
eb5cff1045 | ||
![]() |
35c7792aa2 | ||
![]() |
521688d630 | ||
![]() |
75e2845c01 | ||
![]() |
2f96283286 | ||
![]() |
cbe6e9b5f5 | ||
![]() |
2ab79cf474 | ||
![]() |
6ce34aba79 | ||
![]() |
5eeb320b60 | ||
![]() |
93310850d2 | ||
![]() |
a2880b12ca | ||
![]() |
303b57779a | ||
![]() |
6279816ecc | ||
![]() |
4ae77261fa | ||
![]() |
4b7d843b78 | ||
![]() |
1c28df65c3 | ||
![]() |
85b740f484 | ||
![]() |
f9929cb27d | ||
![]() |
bafab1ac07 | ||
![]() |
e05c262468 | ||
![]() |
7a3f7d3bba | ||
![]() |
95aa48c456 | ||
![]() |
904a168d5c | ||
![]() |
724441eddc | ||
![]() |
f68ab3edd1 | ||
![]() |
29dce26bf6 | ||
![]() |
717ab69093 | ||
![]() |
138a2cf08f | ||
![]() |
81daf82647 | ||
![]() |
f3798bfb63 | ||
![]() |
bc07dfad2e | ||
![]() |
309cbdb8be | ||
![]() |
a0e7c4a74c | ||
![]() |
7d428030df | ||
![]() |
00c395f689 | ||
![]() |
d8e1c73d26 | ||
![]() |
ffa4cc241b | ||
![]() |
6f1b740c8f | ||
![]() |
3406ba3ebf |
18
.github/workflows/main-ci.yml
vendored
Normal file
18
.github/workflows/main-ci.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build --no-daemon
|
6
.gitignore
vendored
6
.gitignore
vendored
@@ -15,3 +15,9 @@
|
||||
.idea
|
||||
.gradle
|
||||
*.DS_Store
|
||||
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
bin/
|
||||
*.launch
|
||||
|
@@ -17,7 +17,8 @@ ignore = {
|
||||
-- are largely unsupported.
|
||||
include_files = {
|
||||
'src/main/resources/assets/computercraft/lua/rom',
|
||||
'src/main/resources/assets/computercraft/lua/bios.lua'
|
||||
'src/main/resources/assets/computercraft/lua/bios.lua',
|
||||
'src/test/resources/test-rom',
|
||||
}
|
||||
|
||||
files['src/main/resources/assets/computercraft/lua/bios.lua'] = {
|
||||
|
14
.travis.yml
14
.travis.yml
@@ -1,14 +0,0 @@
|
||||
language: java
|
||||
|
||||
script: ./gradlew build --no-daemon
|
||||
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/s
|
||||
|
||||
jdk:
|
||||
- oraclejdk8
|
@@ -1,5 +1,5 @@
|
||||
# 
|
||||
[](https://travis-ci.org/SquidDev-CC/CC-Tweaked "Current build status") [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
|
||||
[](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
|
||||
|
||||
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
|
||||
turtles and more to Minecraft.
|
||||
|
93
build.gradle
93
build.gradle
@@ -5,7 +5,7 @@ buildscript {
|
||||
jcenter()
|
||||
maven {
|
||||
name = "forge"
|
||||
url = "http://files.minecraftforge.net/maven"
|
||||
url = "https://files.minecraftforge.net/maven"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
@@ -17,7 +17,9 @@ buildscript {
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
@@ -43,7 +45,7 @@ minecraft {
|
||||
repositories {
|
||||
maven {
|
||||
name "JEI"
|
||||
url "http://dvs1.progwml6.com/files/maven"
|
||||
url "https://dvs1.progwml6.com/files/maven"
|
||||
}
|
||||
maven {
|
||||
name "SquidDev"
|
||||
@@ -55,7 +57,7 @@ repositories {
|
||||
}
|
||||
maven {
|
||||
name "Amadornes"
|
||||
url "http://maven.amadornes.com/"
|
||||
url "https://maven.amadornes.com/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +68,8 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
checkstyle "com.puppycrawl.tools:checkstyle:8.21"
|
||||
|
||||
deobfProvided "mezz.jei:jei_1.12.2:4.15.0.269:api"
|
||||
deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
|
||||
deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
|
||||
@@ -74,12 +78,14 @@ dependencies {
|
||||
|
||||
shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT'
|
||||
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.1.0'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.1.0'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2'
|
||||
|
||||
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
|
||||
}
|
||||
|
||||
// Compile tasks
|
||||
|
||||
javadoc {
|
||||
include "dan200/computercraft/api/**/*.java"
|
||||
}
|
||||
@@ -98,12 +104,22 @@ jar {
|
||||
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
|
||||
}
|
||||
|
||||
[compileJava, compileTestJava].forEach {
|
||||
it.configure {
|
||||
options.compilerArgs << "-Xlint" << "-Xlint:-processing" << "-Werror"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.*
|
||||
import java.util.zip.*
|
||||
|
||||
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
|
||||
|
||||
@@ -199,6 +215,7 @@ task compressJson(dependsOn: extractAnnotationsJar) {
|
||||
// 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) {
|
||||
@@ -226,6 +243,56 @@ task compressJson(dependsOn: extractAnnotationsJar) {
|
||||
|
||||
assemble.dependsOn compressJson
|
||||
|
||||
// Check tasks
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events "skipped", "failed"
|
||||
}
|
||||
}
|
||||
|
||||
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')
|
||||
}
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
tasks.withType(LicenseFormat) {
|
||||
outputs.upToDateWhen { false }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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"
|
||||
@@ -265,7 +332,6 @@ task checkRelease {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
curseforge {
|
||||
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
|
||||
project {
|
||||
@@ -357,18 +423,5 @@ task uploadAll(dependsOn: uploadTasks) {
|
||||
description "Uploads to all repositories (Maven, Curse, GitHub release)"
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events "passed", "skipped", "failed"
|
||||
}
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs << "-Xlint" << "-Xlint:-processing" << "-Werror"
|
||||
}
|
||||
}
|
||||
|
||||
runClient.outputs.upToDateWhen { false }
|
||||
runServer.outputs.upToDateWhen { false }
|
||||
|
159
config/checkstyle/checkstyle.xml
Normal file
159
config/checkstyle/checkstyle.xml
Normal 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>
|
||||
|
9
config/checkstyle/suppressions.xml
Normal file
9
config/checkstyle/suppressions.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?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>
|
||||
<!-- 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
3
config/license/api.txt
Normal 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
3
config/license/main.txt
Normal 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
|
@@ -1,5 +1,5 @@
|
||||
# Mod properties
|
||||
mod_version=1.83.1
|
||||
mod_version=1.85.0
|
||||
|
||||
# Minecraft properties
|
||||
mc_version=1.12.2
|
||||
|
@@ -72,9 +72,7 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.SidedProxy;
|
||||
import net.minecraftforge.fml.common.*;
|
||||
import net.minecraftforge.fml.common.event.*;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -83,9 +81,7 @@ import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
@@ -394,6 +390,27 @@ public class ComputerCraft
|
||||
}
|
||||
}
|
||||
|
||||
private static void loadFromFile( List<IMount> mounts, File file, String path, boolean allowMissing )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( file.isFile() )
|
||||
{
|
||||
mounts.add( new JarMount( file, path ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
File subResource = new File( file, path );
|
||||
if( subResource.exists() ) mounts.add( new FileMount( subResource, 0 ) );
|
||||
}
|
||||
}
|
||||
catch( IOException | RuntimeException e )
|
||||
{
|
||||
if( allowMissing && e instanceof FileNotFoundException ) return;
|
||||
ComputerCraft.log.error( "Could not load mount '" + path + " 'from '" + file.getName() + "'", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static IMount createResourceMount( Class<?> modClass, String domain, String subPath )
|
||||
{
|
||||
@@ -413,18 +430,26 @@ public class ComputerCraft
|
||||
}
|
||||
}
|
||||
|
||||
// Mount from mod jar
|
||||
// Mount from mod jars, preferring the specified one.
|
||||
File modJar = getContainingJar( modClass );
|
||||
Set<File> otherMods = new HashSet<>();
|
||||
for( ModContainer container : Loader.instance().getActiveModList() )
|
||||
{
|
||||
File modFile = container.getSource();
|
||||
if( modFile != null && !modFile.equals( modJar ) && modFile.exists() )
|
||||
{
|
||||
otherMods.add( container.getSource() );
|
||||
}
|
||||
}
|
||||
|
||||
for( File file : otherMods )
|
||||
{
|
||||
loadFromFile( mounts, file, subPath, true );
|
||||
}
|
||||
|
||||
if( modJar != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
mounts.add( new JarMount( modJar, subPath ) );
|
||||
}
|
||||
catch( IOException | RuntimeException e )
|
||||
{
|
||||
ComputerCraft.log.error( "Could not load mount from mod jar", e );
|
||||
}
|
||||
loadFromFile( mounts, modJar, subPath, false );
|
||||
}
|
||||
|
||||
// Mount from resource packs
|
||||
@@ -434,28 +459,8 @@ public class ComputerCraft
|
||||
String[] resourcePacks = resourcePackDir.list();
|
||||
for( String resourcePackName : resourcePacks )
|
||||
{
|
||||
try
|
||||
{
|
||||
File resourcePack = new File( resourcePackDir, resourcePackName );
|
||||
if( !resourcePack.isDirectory() )
|
||||
{
|
||||
// Mount a resource pack from a jar
|
||||
mounts.add( new JarMount( resourcePack, subPath ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mount a resource pack from a folder
|
||||
File subResource = new File( resourcePack, subPath );
|
||||
if( subResource.exists() ) mounts.add( new FileMount( subResource, 0 ) );
|
||||
}
|
||||
}
|
||||
catch( FileNotFoundException ignored )
|
||||
{
|
||||
}
|
||||
catch( IOException | RuntimeException e )
|
||||
{
|
||||
ComputerCraft.log.error( "Could not load resource pack '" + resourcePackName + "'", e );
|
||||
}
|
||||
File resourcePack = new File( resourcePackDir, resourcePackName );
|
||||
loadFromFile( mounts, resourcePack, subPath, true );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -438,45 +438,45 @@ public final class ComputerCraftAPI
|
||||
computerCraft_getVersion = findCCMethod( "getVersion", new Class<?>[] {
|
||||
} );
|
||||
computerCraft_createUniqueNumberedSaveDir = findCCMethod( "createUniqueNumberedSaveDir", new Class<?>[] {
|
||||
World.class, String.class
|
||||
World.class, String.class,
|
||||
} );
|
||||
computerCraft_createSaveDirMount = findCCMethod( "createSaveDirMount", new Class<?>[] {
|
||||
World.class, String.class, Long.TYPE
|
||||
World.class, String.class, Long.TYPE,
|
||||
} );
|
||||
computerCraft_createResourceMount = findCCMethod( "createResourceMount", new Class<?>[] {
|
||||
Class.class, String.class, String.class
|
||||
Class.class, String.class, String.class,
|
||||
} );
|
||||
computerCraft_registerPeripheralProvider = findCCMethod( "registerPeripheralProvider", new Class<?>[] {
|
||||
IPeripheralProvider.class
|
||||
IPeripheralProvider.class,
|
||||
} );
|
||||
computerCraft_registerTurtleUpgrade = findCCMethod( "registerTurtleUpgrade", new Class<?>[] {
|
||||
ITurtleUpgrade.class
|
||||
ITurtleUpgrade.class,
|
||||
} );
|
||||
computerCraft_registerBundledRedstoneProvider = findCCMethod( "registerBundledRedstoneProvider", new Class<?>[] {
|
||||
IBundledRedstoneProvider.class
|
||||
IBundledRedstoneProvider.class,
|
||||
} );
|
||||
computerCraft_getDefaultBundledRedstoneOutput = findCCMethod( "getDefaultBundledRedstoneOutput", new Class<?>[] {
|
||||
World.class, BlockPos.class, EnumFacing.class
|
||||
World.class, BlockPos.class, EnumFacing.class,
|
||||
} );
|
||||
computerCraft_registerMediaProvider = findCCMethod( "registerMediaProvider", new Class<?>[] {
|
||||
IMediaProvider.class
|
||||
IMediaProvider.class,
|
||||
} );
|
||||
computerCraft_registerPermissionProvider = findCCMethod( "registerPermissionProvider", new Class<?>[] {
|
||||
ITurtlePermissionProvider.class
|
||||
ITurtlePermissionProvider.class,
|
||||
} );
|
||||
computerCraft_registerPocketUpgrade = findCCMethod( "registerPocketUpgrade", new Class<?>[] {
|
||||
IPocketUpgrade.class
|
||||
IPocketUpgrade.class,
|
||||
} );
|
||||
computerCraft_getWirelessNetwork = findCCMethod( "getWirelessNetwork", new Class<?>[] {
|
||||
} );
|
||||
computerCraft_registerAPIFactory = findCCMethod( "registerAPIFactory", new Class<?>[] {
|
||||
ILuaAPIFactory.class
|
||||
ILuaAPIFactory.class,
|
||||
} );
|
||||
computerCraft_createWiredNodeForElement = findCCMethod( "createWiredNodeForElement", new Class<?>[] {
|
||||
IWiredElement.class
|
||||
IWiredElement.class,
|
||||
} );
|
||||
computerCraft_getWiredElementAt = findCCMethod( "getWiredElementAt", new Class<?>[] {
|
||||
IBlockAccess.class, BlockPos.class, EnumFacing.class
|
||||
IBlockAccess.class, BlockPos.class, EnumFacing.class,
|
||||
} );
|
||||
}
|
||||
catch( Exception e )
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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 ) );
|
||||
|
@@ -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 @@ public interface IWritableMount extends IMount
|
||||
* @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 ) );
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -145,7 +145,9 @@ public interface ITurtleAccess
|
||||
GameProfile getOwningPlayer();
|
||||
|
||||
/**
|
||||
* Get the inventory of this turtle
|
||||
* Get the inventory of this turtle.
|
||||
*
|
||||
* Note: this inventory should only be accessed and modified on the server thread.
|
||||
*
|
||||
* @return This turtle's inventory
|
||||
* @see #getItemHandler()
|
||||
@@ -156,6 +158,8 @@ public interface ITurtleAccess
|
||||
/**
|
||||
* Get the inventory of this turtle as an {@link IItemHandlerModifiable}.
|
||||
*
|
||||
* Note: this inventory should only be accessed and modified on the server thread.
|
||||
*
|
||||
* @return This turtle's inventory
|
||||
* @see #getInventory()
|
||||
* @see IItemHandlerModifiable
|
||||
|
@@ -109,8 +109,8 @@ public interface ITurtleUpgrade
|
||||
* Will only be called for Tool turtle. Called when turtle.dig() or turtle.attack() is called
|
||||
* by the turtle, and the tool is required to do some work.
|
||||
*
|
||||
* Conforming implementations should fire {@link BlockEvent.BreakEvent} and {@link TurtleBlockEvent.Dig}for digging,
|
||||
* {@link AttackEntityEvent} and {@link TurtleAttackEvent} for attacking.
|
||||
* Conforming implementations should fire {@link BlockEvent.BreakEvent} and {@link TurtleBlockEvent.Dig} for
|
||||
* digging, {@link AttackEntityEvent} and {@link TurtleAttackEvent} for attacking.
|
||||
*
|
||||
* @param turtle Access to the turtle that the tool resides on.
|
||||
* @param side Which side of the turtle (left or right) the tool resides on.
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -120,7 +120,7 @@ public class GuiTurtle extends GuiContainer
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -94,7 +94,7 @@ public final class ModelTransformer
|
||||
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;
|
||||
|
@@ -43,9 +43,7 @@ public class FSAPI implements ILuaAPI
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"fs"
|
||||
};
|
||||
return new String[] { "fs" };
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -42,9 +42,7 @@ public class HTTPAPI implements ILuaAPI
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"http"
|
||||
};
|
||||
return new String[] { "http" };
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,6 +81,7 @@ public class HTTPAPI implements ILuaAPI
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( "resource" )
|
||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
|
||||
{
|
||||
switch( method )
|
||||
@@ -95,7 +94,7 @@ public class HTTPAPI implements ILuaAPI
|
||||
|
||||
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 class HTTPAPI implements ILuaAPI
|
||||
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 );
|
||||
|
@@ -10,6 +10,7 @@ package dan200.computercraft.core.apis;
|
||||
* 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
|
||||
|
@@ -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 class OSAPI implements ILuaAPI
|
||||
|
||||
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 class OSAPI implements ILuaAPI
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"os"
|
||||
};
|
||||
return new String[] { "os" };
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -385,9 +383,7 @@ public class OSAPI implements ILuaAPI
|
||||
// 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 class OSAPI implements ILuaAPI
|
||||
Instant instant = Instant.ofEpochSecond( time );
|
||||
ZonedDateTime date;
|
||||
ZoneOffset offset;
|
||||
boolean isDst;
|
||||
if( format.startsWith( "!" ) )
|
||||
{
|
||||
offset = ZoneOffset.UTC;
|
||||
|
@@ -36,7 +36,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
||||
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 class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"peripheral"
|
||||
};
|
||||
return new String[] { "peripheral" };
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -326,7 +324,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
||||
"isPresent",
|
||||
"getType",
|
||||
"getMethods",
|
||||
"call"
|
||||
"call",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -356,7 +354,6 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
||||
ComputerSide side = ComputerSide.valueOfInsensitive( getString( args, 0 ) );
|
||||
if( side != null )
|
||||
{
|
||||
String type = null;
|
||||
synchronized( m_peripherals )
|
||||
{
|
||||
PeripheralWrapper p = m_peripherals[side.ordinal()];
|
||||
|
@@ -29,9 +29,7 @@ public class RedstoneAPI implements ILuaAPI
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"rs", "redstone"
|
||||
};
|
||||
return new String[] { "rs", "redstone" };
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@@ -33,9 +33,7 @@ public class TermAPI implements ILuaAPI
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"term"
|
||||
};
|
||||
return new String[] { "term" };
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@@ -89,9 +87,7 @@ public class TermAPI implements ILuaAPI
|
||||
|
||||
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 )
|
||||
|
@@ -212,6 +212,7 @@ public class BinaryReadableHandle extends HandleGeneric
|
||||
}
|
||||
}
|
||||
case 3: // close
|
||||
checkOpen();
|
||||
close();
|
||||
return null;
|
||||
case 4: // seek
|
||||
|
@@ -95,6 +95,7 @@ public class BinaryWritableHandle extends HandleGeneric
|
||||
return null;
|
||||
}
|
||||
case 2: // close
|
||||
checkOpen();
|
||||
close();
|
||||
return null;
|
||||
case 3: // seek
|
||||
|
@@ -152,6 +152,7 @@ public class EncodedReadableHandle extends HandleGeneric
|
||||
return null;
|
||||
}
|
||||
case 3: // close
|
||||
checkOpen();
|
||||
close();
|
||||
return null;
|
||||
default:
|
||||
|
@@ -93,6 +93,7 @@ public class EncodedWritableHandle extends HandleGeneric
|
||||
return null;
|
||||
}
|
||||
case 3: // close
|
||||
checkOpen();
|
||||
close();
|
||||
return null;
|
||||
default:
|
||||
|
@@ -37,8 +37,13 @@ public abstract class HandleGeneric implements ILuaObject
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -72,7 +72,8 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
|
||||
*/
|
||||
protected void dispose()
|
||||
{
|
||||
@SuppressWarnings( "unchecked" ) T thisT = (T) this;
|
||||
@SuppressWarnings( "unchecked" )
|
||||
T thisT = (T) this;
|
||||
limiter.release( thisT );
|
||||
}
|
||||
|
||||
@@ -95,7 +96,8 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
|
||||
|
||||
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 ) );
|
||||
}
|
||||
|
||||
|
@@ -239,7 +239,6 @@ public class Computer
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@SuppressWarnings( "unused" )
|
||||
public void advance( double dt )
|
||||
{
|
||||
tick();
|
||||
|
@@ -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 )
|
||||
|
@@ -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 @@ public class ComboMount implements IMount
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException( "/" + path + ": Not a directory" );
|
||||
throw new FileOperationException( path, "Not a directory" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +111,7 @@ public class ComboMount implements IMount
|
||||
return part.getSize( path );
|
||||
}
|
||||
}
|
||||
throw new IOException( "/" + path + ": No such file" );
|
||||
throw new FileOperationException( path, "No such file" );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@@ -126,7 +127,7 @@ public class ComboMount implements IMount
|
||||
return part.openForRead( path );
|
||||
}
|
||||
}
|
||||
throw new IOException( "/" + path + ": No such file" );
|
||||
throw new FileOperationException( path, "No such file" );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@@ -141,6 +142,6 @@ public class ComboMount implements IMount
|
||||
return part.openChannelForRead( path );
|
||||
}
|
||||
}
|
||||
throw new IOException( "/" + path + ": No such file" );
|
||||
throw new FileOperationException( path, "No such 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 class EmptyMount implements IMount
|
||||
@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 class EmptyMount implements IMount
|
||||
@Deprecated
|
||||
public ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOException
|
||||
{
|
||||
throw new IOException( "/" + path + ": No such file" );
|
||||
throw new FileOperationException( path, "No such 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 class FileMount implements IWritableMount
|
||||
{
|
||||
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 class FileMount implements IWritableMount
|
||||
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 class FileMount implements IWritableMount
|
||||
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 class FileMount implements IWritableMount
|
||||
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 class FileMount implements IWritableMount
|
||||
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 class FileMount implements IWritableMount
|
||||
|
||||
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 class FileMount implements IWritableMount
|
||||
}
|
||||
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 class FileMount implements IWritableMount
|
||||
{
|
||||
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 class FileMount implements IWritableMount
|
||||
}
|
||||
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 class FileMount implements IWritableMount
|
||||
{
|
||||
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(
|
||||
|
@@ -8,6 +8,7 @@ package dan200.computercraft.core.filesystem;
|
||||
|
||||
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 @@ public class FileSystem
|
||||
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 class FileSystem
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
throw new FileSystemException( e.getMessage() );
|
||||
throw localExceptionOf( e );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,12 +123,12 @@ public class FileSystem
|
||||
}
|
||||
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 class FileSystem
|
||||
}
|
||||
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 class FileSystem
|
||||
}
|
||||
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 class FileSystem
|
||||
|
||||
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 class FileSystem
|
||||
}
|
||||
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 class FileSystem
|
||||
}
|
||||
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 class FileSystem
|
||||
}
|
||||
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 class FileSystem
|
||||
}
|
||||
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 @@ public class FileSystem
|
||||
}
|
||||
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 @@ public class FileSystem
|
||||
|
||||
// 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();
|
||||
|
@@ -9,6 +9,7 @@ package dan200.computercraft.core.filesystem;
|
||||
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 class JarMount implements IMount
|
||||
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 @@ public class JarMount implements IMount
|
||||
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 class JarMount implements IMount
|
||||
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 class JarMount implements IMount
|
||||
{
|
||||
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 class JarMount implements IMount
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
@@ -550,7 +550,7 @@ public class CobaltLuaMachine implements ILuaMachine
|
||||
{
|
||||
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,
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
@@ -8,7 +8,7 @@ package dan200.computercraft.core.terminal;
|
||||
|
||||
public class TextBuffer
|
||||
{
|
||||
public char[] m_text;
|
||||
private final char[] m_text;
|
||||
|
||||
public TextBuffer( char c, int length )
|
||||
{
|
||||
|
@@ -277,7 +277,7 @@ public final class Config
|
||||
renameProperty( CATEGORY_GENERAL, "turtlesCanPush", CATEGORY_TURTLE, "can_push" );
|
||||
renameProperty( CATEGORY_GENERAL, "turtle_disabled_actions", CATEGORY_TURTLE, "disabled_actions" );
|
||||
|
||||
config.getCategory( CATEGORY_HTTP )
|
||||
config.getCategory( CATEGORY_TURTLE )
|
||||
.setComment( "Various options relating to turtles." );
|
||||
|
||||
turtlesNeedFuel = config.get( CATEGORY_TURTLE, "need_fuel", ComputerCraft.turtlesNeedFuel );
|
||||
|
@@ -51,7 +51,6 @@ public abstract class BlockGeneric extends Block implements ITileEntityProvider
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
@SuppressWarnings( "deprecation" )
|
||||
public final void neighborChanged( IBlockState state, World world, BlockPos pos, Block neighbourBlock, BlockPos neighbourPos )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
|
@@ -63,7 +63,6 @@ public abstract class TileGeneric extends TileEntity
|
||||
{
|
||||
}
|
||||
|
||||
@SuppressWarnings( "deprecation" )
|
||||
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||
{
|
||||
onNeighbourChange();
|
||||
|
@@ -47,9 +47,7 @@ public class CommandAPI implements ILuaAPI
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"commands"
|
||||
};
|
||||
return new String[] { "commands" };
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@@ -62,7 +60,7 @@ public class CommandAPI implements ILuaAPI
|
||||
"list",
|
||||
"getBlockPosition",
|
||||
"getBlockInfos",
|
||||
"getBlockInfo"
|
||||
"getBlockInfo",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -85,7 +83,7 @@ public class CommandAPI implements ILuaAPI
|
||||
{
|
||||
sender.clearOutput();
|
||||
int result = commandManager.executeCommand( sender, command );
|
||||
return new Object[] { result > 0, sender.copyOutput() };
|
||||
return new Object[] { result > 0, sender.copyOutput(), result };
|
||||
}
|
||||
catch( Throwable t )
|
||||
{
|
||||
|
@@ -32,7 +32,7 @@ public class TileComputer extends TileComputerBase
|
||||
ServerComputer computer = new ServerComputer(
|
||||
getWorld(),
|
||||
id,
|
||||
m_label,
|
||||
label,
|
||||
instanceID,
|
||||
family,
|
||||
ComputerCraft.terminalWidth_computer,
|
||||
|
@@ -47,7 +47,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
{
|
||||
private int m_instanceID = -1;
|
||||
private int m_computerID = -1;
|
||||
protected String m_label = null;
|
||||
protected String label = null;
|
||||
private boolean m_on = false;
|
||||
boolean m_startOn = false;
|
||||
private boolean m_fresh = false;
|
||||
@@ -190,7 +190,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
|
||||
m_fresh = false;
|
||||
m_computerID = computer.getID();
|
||||
m_label = computer.getLabel();
|
||||
label = computer.getLabel();
|
||||
m_on = computer.isOn();
|
||||
|
||||
if( computer.hasOutputChanged() ) updateOutput();
|
||||
@@ -212,9 +212,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
{
|
||||
nbt.setInteger( "computerID", m_computerID );
|
||||
}
|
||||
if( m_label != null )
|
||||
if( label != null )
|
||||
{
|
||||
nbt.setString( "label", m_label );
|
||||
nbt.setString( "label", label );
|
||||
}
|
||||
nbt.setBoolean( "on", m_on );
|
||||
return super.writeToNBT( nbt );
|
||||
@@ -248,7 +248,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
m_computerID = id;
|
||||
|
||||
// Load label
|
||||
m_label = nbt.hasKey( "label" ) ? nbt.getString( "label" ) : null;
|
||||
label = nbt.hasKey( "label" ) ? nbt.getString( "label" ) : null;
|
||||
|
||||
// Load power state
|
||||
m_startOn = nbt.getBoolean( "on" );
|
||||
@@ -361,7 +361,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
@Override
|
||||
public final String getLabel()
|
||||
{
|
||||
return m_label;
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -378,9 +378,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
@Override
|
||||
public final void setLabel( String label )
|
||||
{
|
||||
if( getWorld().isRemote || Objects.equals( m_label, label ) ) return;
|
||||
if( getWorld().isRemote || Objects.equals( this.label, label ) ) return;
|
||||
|
||||
m_label = label;
|
||||
this.label = label;
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null ) computer.setLabel( label );
|
||||
markDirty();
|
||||
@@ -453,8 +453,8 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
protected void writeDescription( @Nonnull NBTTagCompound nbt )
|
||||
{
|
||||
super.writeDescription( nbt );
|
||||
nbt.setInteger( "instanceID", createServerComputer().getInstanceID() );
|
||||
if( m_label != null ) nbt.setString( "label", m_label );
|
||||
if( m_instanceID >= 0 ) nbt.setInteger( "instanceID", m_instanceID );
|
||||
if( label != null ) nbt.setString( "label", label );
|
||||
if( m_computerID >= 0 ) nbt.setInteger( "computerID", m_computerID );
|
||||
}
|
||||
|
||||
@@ -463,7 +463,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
{
|
||||
super.readDescription( nbt );
|
||||
m_instanceID = nbt.getInteger( "instanceID" );
|
||||
m_label = nbt.hasKey( "label" ) ? nbt.getString( "label" ) : null;
|
||||
label = nbt.hasKey( "label" ) ? nbt.getString( "label" ) : null;
|
||||
m_computerID = nbt.hasKey( "computerID" ) ? nbt.getInteger( "computerID" ) : -1;
|
||||
}
|
||||
|
||||
@@ -474,7 +474,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
unload();
|
||||
m_instanceID = copy.m_instanceID;
|
||||
m_computerID = copy.m_computerID;
|
||||
m_label = copy.m_label;
|
||||
label = copy.label;
|
||||
m_on = copy.m_on;
|
||||
m_startOn = copy.m_startOn;
|
||||
updateBlock();
|
||||
@@ -493,13 +493,13 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return hasCustomName() ? m_label : getBlockType().getTranslationKey();
|
||||
return hasCustomName() ? label : getBlockType().getTranslationKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName()
|
||||
{
|
||||
return !Strings.isNullOrEmpty( m_label );
|
||||
return !Strings.isNullOrEmpty( label );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@@ -11,9 +11,9 @@ import java.util.HashMap;
|
||||
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 class ComputerRegistry<TComputer extends IComputer>
|
||||
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 class ComputerRegistry<TComputer extends IComputer>
|
||||
return m_computers.containsKey( instanceID );
|
||||
}
|
||||
|
||||
public void add( int instanceID, TComputer computer )
|
||||
public void add( int instanceID, T computer )
|
||||
{
|
||||
if( m_computers.containsKey( instanceID ) )
|
||||
{
|
||||
|
@@ -220,6 +220,13 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
||||
return m_instanceID;
|
||||
}
|
||||
|
||||
/*
|
||||
* getID and getLabel are deprecated on IComputer, as they do not make sense in ClientComputer.
|
||||
* However, for compatibility reasons, we still need these here, and have no choice but to override the IComputer methods.
|
||||
*
|
||||
* Hence, we suppress the deprecation warning.
|
||||
*/
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( "deprecation" )
|
||||
public int getID()
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -90,6 +90,7 @@ public class JEIComputerCraft implements IModPlugin
|
||||
ingredients.addIngredientsAtRuntime( VanillaTypes.ITEM, upgradeItems );
|
||||
|
||||
// Hide all upgrade recipes
|
||||
@SuppressWarnings( "unchecked" )
|
||||
IRecipeCategory<? extends IRecipeWrapper> category = (IRecipeCategory<? extends IRecipeWrapper>) registry.getRecipeCategory( VanillaRecipeCategoryUid.CRAFTING );
|
||||
if( category != null )
|
||||
{
|
||||
|
@@ -6,7 +6,6 @@
|
||||
|
||||
package dan200.computercraft.shared.media.inventory;
|
||||
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -22,7 +21,7 @@ public class ContainerHeldItem extends Container
|
||||
public ContainerHeldItem( EntityPlayer player, EnumHand hand )
|
||||
{
|
||||
m_hand = hand;
|
||||
m_stack = InventoryUtil.copyItem( player.getHeldItem( hand ) );
|
||||
m_stack = player.getHeldItem( hand ).copy();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@@ -39,5 +39,8 @@ public enum PeripheralType implements IStringSerializable
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return name; }
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
@@ -52,7 +52,7 @@ public class CommandBlockPeripheral implements IPeripheral
|
||||
{
|
||||
case 0: // getCommand
|
||||
return context.executeMainThreadTask( () -> new Object[] {
|
||||
m_commandBlock.getCommandBlockLogic().getCommand()
|
||||
m_commandBlock.getCommandBlockLogic().getCommand(),
|
||||
} );
|
||||
case 1:
|
||||
{
|
||||
|
@@ -11,6 +11,7 @@ import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.media.IMedia;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.MediaProviders;
|
||||
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
|
||||
import dan200.computercraft.shared.util.StringUtil;
|
||||
import net.minecraft.item.Item;
|
||||
@@ -20,11 +21,11 @@ import javax.annotation.Nonnull;
|
||||
|
||||
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
|
||||
|
||||
public class DiskDrivePeripheral implements IPeripheral
|
||||
class DiskDrivePeripheral implements IPeripheral
|
||||
{
|
||||
private final TileDiskDrive m_diskDrive;
|
||||
|
||||
public DiskDrivePeripheral( TileDiskDrive diskDrive )
|
||||
DiskDrivePeripheral( TileDiskDrive diskDrive )
|
||||
{
|
||||
m_diskDrive = diskDrive;
|
||||
}
|
||||
@@ -51,12 +52,12 @@ public class DiskDrivePeripheral implements IPeripheral
|
||||
"playAudio",
|
||||
"stopAudio",
|
||||
"ejectDisk",
|
||||
"getDiskID"
|
||||
"getDiskID",
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException
|
||||
public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException
|
||||
{
|
||||
switch( method )
|
||||
{
|
||||
@@ -64,21 +65,26 @@ public class DiskDrivePeripheral implements IPeripheral
|
||||
return new Object[] { !m_diskDrive.getDiskStack().isEmpty() };
|
||||
case 1: // getDiskLabel
|
||||
{
|
||||
IMedia media = m_diskDrive.getDiskMedia();
|
||||
return media == null ? null : new Object[] { media.getLabel( m_diskDrive.getDiskStack() ) };
|
||||
ItemStack stack = m_diskDrive.getDiskStack();
|
||||
IMedia media = MediaProviders.get( stack );
|
||||
return media == null ? null : new Object[] { media.getLabel( stack ) };
|
||||
}
|
||||
case 2: // setDiskLabel
|
||||
{
|
||||
String label = optString( arguments, 0, null );
|
||||
|
||||
IMedia media = m_diskDrive.getDiskMedia();
|
||||
if( media == null ) return null;
|
||||
return context.executeMainThreadTask( () -> {
|
||||
ItemStack stack = m_diskDrive.getDiskStack();
|
||||
IMedia media = MediaProviders.get( stack );
|
||||
if( media == null ) return null;
|
||||
|
||||
ItemStack disk = m_diskDrive.getDiskStack();
|
||||
label = StringUtil.normaliseLabel( label );
|
||||
if( !media.setLabel( disk, label ) ) throw new LuaException( "Disk label cannot be changed" );
|
||||
m_diskDrive.setDiskStack( disk );
|
||||
return null;
|
||||
if( !media.setLabel( stack, StringUtil.normaliseLabel( label ) ) )
|
||||
{
|
||||
throw new LuaException( "Disk label cannot be changed" );
|
||||
}
|
||||
m_diskDrive.setDiskStack( stack );
|
||||
return null;
|
||||
} );
|
||||
}
|
||||
case 3: // hasData
|
||||
return new Object[] { m_diskDrive.getDiskMountPath( computer ) != null };
|
||||
@@ -87,14 +93,16 @@ public class DiskDrivePeripheral implements IPeripheral
|
||||
case 5:
|
||||
{
|
||||
// hasAudio
|
||||
IMedia media = m_diskDrive.getDiskMedia();
|
||||
return new Object[] { media != null && media.getAudio( m_diskDrive.getDiskStack() ) != null };
|
||||
ItemStack stack = m_diskDrive.getDiskStack();
|
||||
IMedia media = MediaProviders.get( stack );
|
||||
return new Object[] { media != null && media.getAudio( stack ) != null };
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
// getAudioTitle
|
||||
IMedia media = m_diskDrive.getDiskMedia();
|
||||
return new Object[] { media != null ? media.getAudioTitle( m_diskDrive.getDiskStack() ) : false };
|
||||
ItemStack stack = m_diskDrive.getDiskStack();
|
||||
IMedia media = MediaProviders.get( stack );
|
||||
return new Object[] { media != null ? media.getAudioTitle( stack ) : false };
|
||||
}
|
||||
case 7: // playAudio
|
||||
m_diskDrive.playDiskAudio();
|
||||
@@ -131,8 +139,7 @@ public class DiskDrivePeripheral implements IPeripheral
|
||||
@Override
|
||||
public boolean equals( IPeripheral other )
|
||||
{
|
||||
if( this == other ) return true;
|
||||
return other instanceof DiskDrivePeripheral && ((DiskDrivePeripheral) other).m_diskDrive == m_diskDrive;
|
||||
return this == other || other instanceof DiskDrivePeripheral && ((DiskDrivePeripheral) other).m_diskDrive == m_diskDrive;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@@ -318,35 +318,31 @@ public class TileDiskDrive extends TilePeripheralBase implements DefaultInventor
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public ItemStack getDiskStack()
|
||||
ItemStack getDiskStack()
|
||||
{
|
||||
return getStackInSlot( 0 );
|
||||
}
|
||||
|
||||
public void setDiskStack( @Nonnull ItemStack stack )
|
||||
void setDiskStack( @Nonnull ItemStack stack )
|
||||
{
|
||||
setInventorySlotContents( 0, stack );
|
||||
}
|
||||
|
||||
public IMedia getDiskMedia()
|
||||
private IMedia getDiskMedia()
|
||||
{
|
||||
return MediaProviders.get( getDiskStack() );
|
||||
}
|
||||
|
||||
public String getDiskMountPath( IComputerAccess computer )
|
||||
String getDiskMountPath( IComputerAccess computer )
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
if( m_computers.containsKey( computer ) )
|
||||
{
|
||||
MountInfo info = m_computers.get( computer );
|
||||
return info.mountPath;
|
||||
}
|
||||
MountInfo info = m_computers.get( computer );
|
||||
return info != null ? info.mountPath : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void mount( IComputerAccess computer )
|
||||
void mount( IComputerAccess computer )
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
@@ -355,7 +351,7 @@ public class TileDiskDrive extends TilePeripheralBase implements DefaultInventor
|
||||
}
|
||||
}
|
||||
|
||||
public void unmount( IComputerAccess computer )
|
||||
void unmount( IComputerAccess computer )
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
@@ -364,7 +360,7 @@ public class TileDiskDrive extends TilePeripheralBase implements DefaultInventor
|
||||
}
|
||||
}
|
||||
|
||||
public void playDiskAudio()
|
||||
void playDiskAudio()
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
@@ -377,7 +373,7 @@ public class TileDiskDrive extends TilePeripheralBase implements DefaultInventor
|
||||
}
|
||||
}
|
||||
|
||||
public void stopDiskAudio()
|
||||
void stopDiskAudio()
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
@@ -386,7 +382,7 @@ public class TileDiskDrive extends TilePeripheralBase implements DefaultInventor
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectDisk()
|
||||
void ejectDisk()
|
||||
{
|
||||
synchronized( this )
|
||||
{
|
||||
|
@@ -87,7 +87,7 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
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,
|
||||
} );
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,7 @@ public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPa
|
||||
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(),
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
@@ -277,7 +277,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW
|
||||
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;
|
||||
|
@@ -142,7 +142,7 @@ public class TileMonitor extends TileGeneric implements ITilePeripheral, IPeriph
|
||||
for( IComputerAccess computer : monitor.m_computers )
|
||||
{
|
||||
computer.queueEvent( "monitor_resize", new Object[] {
|
||||
computer.getAttachmentName()
|
||||
computer.getAttachmentName(),
|
||||
} );
|
||||
}
|
||||
}
|
||||
@@ -660,7 +660,7 @@ public class TileMonitor extends TileGeneric implements ITilePeripheral, IPeriph
|
||||
for( IComputerAccess computer : monitor.m_computers )
|
||||
{
|
||||
computer.queueEvent( "monitor_touch", new Object[] {
|
||||
computer.getAttachmentName(), xCharPos, yCharPos
|
||||
computer.getAttachmentName(), xCharPos, yCharPos,
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@ import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.shared.util.StringUtil;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@@ -51,8 +52,13 @@ public class PrinterPeripheral implements IPeripheral
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
|
||||
public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException, InterruptedException
|
||||
{
|
||||
// FIXME: There's a theoretical race condition here between getCurrentPage and then using the page. Ideally
|
||||
// we'd lock on the page, consume it, and unlock.
|
||||
|
||||
// FIXME: None of our page modification functions actually mark the tile as dirty, so the page may not be
|
||||
// persisted correctly.
|
||||
switch( method )
|
||||
{
|
||||
case 0: // write
|
||||
@@ -89,10 +95,13 @@ public class PrinterPeripheral implements IPeripheral
|
||||
return new Object[] { width, height };
|
||||
}
|
||||
case 4: // newPage
|
||||
return new Object[] { m_printer.startNewPage() };
|
||||
return context.executeMainThreadTask( () -> new Object[] { m_printer.startNewPage() } );
|
||||
case 5: // endPage
|
||||
getCurrentPage();
|
||||
return new Object[] { m_printer.endCurrentPage() };
|
||||
return context.executeMainThreadTask( () -> {
|
||||
getCurrentPage();
|
||||
return new Object[] { m_printer.endCurrentPage() };
|
||||
} );
|
||||
case 6: // getInkLevel
|
||||
return new Object[] { m_printer.getInkLevel() };
|
||||
case 7:
|
||||
@@ -100,7 +109,7 @@ public class PrinterPeripheral implements IPeripheral
|
||||
// setPageTitle
|
||||
String title = optString( args, 0, "" );
|
||||
getCurrentPage();
|
||||
m_printer.setPageTitle( title );
|
||||
m_printer.setPageTitle( StringUtil.normaliseLabel( title ) );
|
||||
return null;
|
||||
}
|
||||
case 8: // getPaperLevel
|
||||
@@ -123,13 +132,11 @@ public class PrinterPeripheral implements IPeripheral
|
||||
return m_printer;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Terminal getCurrentPage() throws LuaException
|
||||
{
|
||||
Terminal currentPage = m_printer.getCurrentPage();
|
||||
if( currentPage == null )
|
||||
{
|
||||
throw new LuaException( "Page not started" );
|
||||
}
|
||||
if( currentPage == null ) throw new LuaException( "Page not started" );
|
||||
return currentPage;
|
||||
}
|
||||
}
|
||||
|
@@ -45,9 +45,9 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
||||
{
|
||||
// Statics
|
||||
|
||||
private static final int[] bottomSlots = new int[] { 7, 8, 9, 10, 11, 12 };
|
||||
private static final int[] topSlots = new int[] { 1, 2, 3, 4, 5, 6 };
|
||||
private static final int[] sideSlots = new int[] { 0 };
|
||||
private static final int[] BOTTOM_SLOTS = new int[] { 7, 8, 9, 10, 11, 12 };
|
||||
private static final int[] TOP_SLOTS = new int[] { 1, 2, 3, 4, 5, 6 };
|
||||
private static final int[] SIDE_SLOTS = new int[] { 0 };
|
||||
|
||||
// Members
|
||||
|
||||
@@ -88,18 +88,12 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
||||
}
|
||||
|
||||
// Read inventory
|
||||
synchronized( m_inventory )
|
||||
NBTTagList itemList = nbt.getTagList( "Items", Constants.NBT.TAG_COMPOUND );
|
||||
for( int i = 0; i < itemList.tagCount(); i++ )
|
||||
{
|
||||
NBTTagList nbttaglist = nbt.getTagList( "Items", Constants.NBT.TAG_COMPOUND );
|
||||
for( int i = 0; i < nbttaglist.tagCount(); i++ )
|
||||
{
|
||||
NBTTagCompound itemTag = nbttaglist.getCompoundTagAt( i );
|
||||
int j = itemTag.getByte( "Slot" ) & 0xff;
|
||||
if( j < m_inventory.size() )
|
||||
{
|
||||
m_inventory.set( j, new ItemStack( itemTag ) );
|
||||
}
|
||||
}
|
||||
NBTTagCompound itemTag = itemList.getCompoundTagAt( i );
|
||||
int slot = itemTag.getByte( "Slot" ) & 0xff;
|
||||
if( slot < m_inventory.size() ) m_inventory.set( slot, new ItemStack( itemTag ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,21 +110,18 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
||||
}
|
||||
|
||||
// Write inventory
|
||||
synchronized( m_inventory )
|
||||
NBTTagList itemList = new NBTTagList();
|
||||
for( int i = 0; i < m_inventory.size(); i++ )
|
||||
{
|
||||
NBTTagList nbttaglist = new NBTTagList();
|
||||
for( int i = 0; i < m_inventory.size(); i++ )
|
||||
{
|
||||
if( !m_inventory.get( i ).isEmpty() )
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setByte( "Slot", (byte) i );
|
||||
m_inventory.get( i ).writeToNBT( tag );
|
||||
nbttaglist.appendTag( tag );
|
||||
}
|
||||
}
|
||||
nbt.setTag( "Items", nbttaglist );
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
if( stack.isEmpty() ) continue;
|
||||
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setByte( "Slot", (byte) i );
|
||||
stack.writeToNBT( tag );
|
||||
itemList.appendTag( tag );
|
||||
}
|
||||
nbt.setTag( "Items", itemList );
|
||||
|
||||
return super.writeToNBT( nbt );
|
||||
}
|
||||
@@ -148,7 +139,7 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
||||
return super.shouldRefresh( world, pos, oldState, newState ) || BlockPeripheral.getPeripheralType( newState ) != PeripheralType.Printer;
|
||||
}
|
||||
|
||||
public boolean isPrinting()
|
||||
boolean isPrinting()
|
||||
{
|
||||
return m_printing;
|
||||
}
|
||||
@@ -173,73 +164,59 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack getStackInSlot( int i )
|
||||
public ItemStack getStackInSlot( int slot )
|
||||
{
|
||||
return m_inventory.get( i );
|
||||
return m_inventory.get( slot );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack removeStackFromSlot( int i )
|
||||
public ItemStack removeStackFromSlot( int slot )
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack result = m_inventory.get( i );
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
markDirty();
|
||||
updateAnim();
|
||||
return result;
|
||||
}
|
||||
ItemStack result = m_inventory.get( slot );
|
||||
m_inventory.set( slot, ItemStack.EMPTY );
|
||||
markDirty();
|
||||
updateAnim();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack decrStackSize( int i, int j )
|
||||
public ItemStack decrStackSize( int slot, int count )
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
ItemStack stack = m_inventory.get( slot );
|
||||
if( stack.isEmpty() ) return ItemStack.EMPTY;
|
||||
|
||||
if( stack.getCount() <= count )
|
||||
{
|
||||
if( m_inventory.get( i ).isEmpty() ) return ItemStack.EMPTY;
|
||||
|
||||
if( m_inventory.get( i ).getCount() <= j )
|
||||
{
|
||||
ItemStack itemstack = m_inventory.get( i );
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
markDirty();
|
||||
updateAnim();
|
||||
return itemstack;
|
||||
}
|
||||
|
||||
ItemStack part = m_inventory.get( i ).splitStack( j );
|
||||
if( m_inventory.get( i ).isEmpty() )
|
||||
{
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
updateAnim();
|
||||
}
|
||||
markDirty();
|
||||
return part;
|
||||
setInventorySlotContents( slot, ItemStack.EMPTY );
|
||||
return stack;
|
||||
}
|
||||
|
||||
ItemStack part = stack.splitStack( count );
|
||||
if( m_inventory.get( slot ).isEmpty() )
|
||||
{
|
||||
m_inventory.set( slot, ItemStack.EMPTY );
|
||||
updateAnim();
|
||||
}
|
||||
markDirty();
|
||||
return part;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents( int i, @Nonnull ItemStack stack )
|
||||
public void setInventorySlotContents( int slot, @Nonnull ItemStack stack )
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
m_inventory.set( i, stack );
|
||||
markDirty();
|
||||
updateAnim();
|
||||
}
|
||||
m_inventory.set( slot, stack );
|
||||
markDirty();
|
||||
updateAnim();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
for( int i = 0; i < m_inventory.size(); i++ ) m_inventory.set( i, ItemStack.EMPTY );
|
||||
markDirty();
|
||||
updateAnim();
|
||||
}
|
||||
for( int i = 0; i < m_inventory.size(); i++ ) m_inventory.set( i, ItemStack.EMPTY );
|
||||
markDirty();
|
||||
updateAnim();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -249,7 +226,7 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
||||
{
|
||||
return isInk( stack );
|
||||
}
|
||||
else if( slot >= topSlots[0] && slot <= topSlots[topSlots.length - 1] )
|
||||
else if( slot >= TOP_SLOTS[0] && slot <= TOP_SLOTS[TOP_SLOTS.length - 1] )
|
||||
{
|
||||
return isPaper( stack );
|
||||
}
|
||||
@@ -295,11 +272,11 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
||||
switch( side )
|
||||
{
|
||||
case DOWN: // Bottom (Out tray)
|
||||
return bottomSlots;
|
||||
return BOTTOM_SLOTS;
|
||||
case UP: // Top (In tray)
|
||||
return topSlots;
|
||||
return TOP_SLOTS;
|
||||
default: // Sides (Ink)
|
||||
return sideSlots;
|
||||
return SIDE_SLOTS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,14 +288,18 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
||||
return new PrinterPeripheral( this );
|
||||
}
|
||||
|
||||
public Terminal getCurrentPage()
|
||||
@Nullable
|
||||
Terminal getCurrentPage()
|
||||
{
|
||||
return m_printing ? m_page : null;
|
||||
synchronized( m_page )
|
||||
{
|
||||
return m_printing ? m_page : null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean startNewPage()
|
||||
boolean startNewPage()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
synchronized( m_page )
|
||||
{
|
||||
if( !canInputPage() ) return false;
|
||||
if( m_printing && !outputPage() ) return false;
|
||||
@@ -326,49 +307,36 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
||||
}
|
||||
}
|
||||
|
||||
public boolean endCurrentPage()
|
||||
boolean endCurrentPage()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
synchronized( m_page )
|
||||
{
|
||||
if( m_printing && outputPage() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getInkLevel()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
return isInk( inkStack ) ? inkStack.getCount() : 0;
|
||||
return m_printing && outputPage();
|
||||
}
|
||||
}
|
||||
|
||||
public int getPaperLevel()
|
||||
int getInkLevel()
|
||||
{
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
return isInk( inkStack ) ? inkStack.getCount() : 0;
|
||||
}
|
||||
|
||||
int getPaperLevel()
|
||||
{
|
||||
int count = 0;
|
||||
synchronized( m_inventory )
|
||||
for( int i = 1; i < 7; i++ )
|
||||
{
|
||||
for( int i = 1; i < 7; i++ )
|
||||
{
|
||||
ItemStack paperStack = m_inventory.get( i );
|
||||
if( !paperStack.isEmpty() && isPaper( paperStack ) )
|
||||
{
|
||||
count += paperStack.getCount();
|
||||
}
|
||||
}
|
||||
ItemStack paperStack = m_inventory.get( i );
|
||||
if( isPaper( paperStack ) ) count += paperStack.getCount();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setPageTitle( String title )
|
||||
void setPageTitle( String title )
|
||||
{
|
||||
if( m_printing )
|
||||
synchronized( m_page )
|
||||
{
|
||||
m_pageTitle = title;
|
||||
if( m_printing ) m_pageTitle = title;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,145 +353,126 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
||||
|
||||
private boolean canInputPage()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
return !inkStack.isEmpty() && isInk( inkStack ) && getPaperLevel() > 0;
|
||||
}
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
return !inkStack.isEmpty() && isInk( inkStack ) && getPaperLevel() > 0;
|
||||
}
|
||||
|
||||
private boolean inputPage()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
if( !isInk( inkStack ) ) return false;
|
||||
|
||||
for( int i = 1; i < 7; i++ )
|
||||
{
|
||||
ItemStack inkStack = m_inventory.get( 0 );
|
||||
if( !isInk( inkStack ) ) return false;
|
||||
ItemStack paperStack = m_inventory.get( i );
|
||||
if( paperStack.isEmpty() || !isPaper( paperStack ) ) continue;
|
||||
|
||||
for( int i = 1; i < 7; i++ )
|
||||
// Setup the new page
|
||||
int colour = inkStack.getItemDamage();
|
||||
m_page.setTextColour( colour >= 0 && colour < 16 ? 15 - colour : 15 );
|
||||
|
||||
m_page.clear();
|
||||
if( paperStack.getItem() instanceof ItemPrintout )
|
||||
{
|
||||
ItemStack paperStack = m_inventory.get( i );
|
||||
if( !paperStack.isEmpty() && isPaper( paperStack ) )
|
||||
m_pageTitle = ItemPrintout.getTitle( paperStack );
|
||||
String[] text = ItemPrintout.getText( paperStack );
|
||||
String[] textColour = ItemPrintout.getColours( paperStack );
|
||||
for( int y = 0; y < m_page.getHeight(); y++ )
|
||||
{
|
||||
// Setup the new page
|
||||
int colour = inkStack.getItemDamage();
|
||||
m_page.setTextColour( colour >= 0 && colour < 16 ? 15 - colour : 15 );
|
||||
|
||||
m_page.clear();
|
||||
if( paperStack.getItem() instanceof ItemPrintout )
|
||||
{
|
||||
m_pageTitle = ItemPrintout.getTitle( paperStack );
|
||||
String[] text = ItemPrintout.getText( paperStack );
|
||||
String[] textColour = ItemPrintout.getColours( paperStack );
|
||||
for( int y = 0; y < m_page.getHeight(); y++ )
|
||||
{
|
||||
m_page.setLine( y, text[y], textColour[y], "" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pageTitle = "";
|
||||
}
|
||||
m_page.setCursorPos( 0, 0 );
|
||||
|
||||
// Decrement ink
|
||||
inkStack.shrink( 1 );
|
||||
if( inkStack.isEmpty() ) m_inventory.set( 0, ItemStack.EMPTY );
|
||||
|
||||
// Decrement paper
|
||||
paperStack.shrink( 1 );
|
||||
if( paperStack.isEmpty() )
|
||||
{
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
updateAnim();
|
||||
}
|
||||
|
||||
markDirty();
|
||||
m_printing = true;
|
||||
return true;
|
||||
m_page.setLine( y, text[y], textColour[y], "" );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
m_pageTitle = "";
|
||||
}
|
||||
m_page.setCursorPos( 0, 0 );
|
||||
|
||||
// Decrement ink
|
||||
inkStack.shrink( 1 );
|
||||
if( inkStack.isEmpty() ) m_inventory.set( 0, ItemStack.EMPTY );
|
||||
|
||||
// Decrement paper
|
||||
paperStack.shrink( 1 );
|
||||
if( paperStack.isEmpty() )
|
||||
{
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
updateAnim();
|
||||
}
|
||||
|
||||
markDirty();
|
||||
m_printing = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean outputPage()
|
||||
{
|
||||
synchronized( m_page )
|
||||
int height = m_page.getHeight();
|
||||
String[] lines = new String[height];
|
||||
String[] colours = new String[height];
|
||||
for( int i = 0; i < height; i++ )
|
||||
{
|
||||
int height = m_page.getHeight();
|
||||
String[] lines = new String[height];
|
||||
String[] colours = new String[height];
|
||||
for( int i = 0; i < height; i++ )
|
||||
{
|
||||
lines[i] = m_page.getLine( i ).toString();
|
||||
colours[i] = m_page.getTextColourLine( i ).toString();
|
||||
}
|
||||
|
||||
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( m_pageTitle, lines, colours );
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
for( int slot : bottomSlots )
|
||||
{
|
||||
if( m_inventory.get( slot ).isEmpty() )
|
||||
{
|
||||
setInventorySlotContents( slot, stack );
|
||||
m_printing = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
lines[i] = m_page.getLine( i ).toString();
|
||||
colours[i] = m_page.getTextColourLine( i ).toString();
|
||||
}
|
||||
|
||||
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( m_pageTitle, lines, colours );
|
||||
for( int slot : BOTTOM_SLOTS )
|
||||
{
|
||||
if( m_inventory.get( slot ).isEmpty() )
|
||||
{
|
||||
setInventorySlotContents( slot, stack );
|
||||
m_printing = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ejectContents()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
for( int i = 0; i < 13; i++ )
|
||||
{
|
||||
for( int i = 0; i < 13; i++ )
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
// Remove the stack from the inventory
|
||||
setInventorySlotContents( i, ItemStack.EMPTY );
|
||||
// Remove the stack from the inventory
|
||||
setInventorySlotContents( i, ItemStack.EMPTY );
|
||||
|
||||
// Spawn the item in the world
|
||||
BlockPos pos = getPos();
|
||||
double x = pos.getX() + 0.5;
|
||||
double y = pos.getY() + 0.75;
|
||||
double z = pos.getZ() + 0.5;
|
||||
WorldUtil.dropItemStack( stack, getWorld(), x, y, z );
|
||||
}
|
||||
// Spawn the item in the world
|
||||
BlockPos pos = getPos();
|
||||
double x = pos.getX() + 0.5;
|
||||
double y = pos.getY() + 0.75;
|
||||
double z = pos.getZ() + 0.5;
|
||||
WorldUtil.dropItemStack( stack, getWorld(), x, y, z );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAnim()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
int anim = 0;
|
||||
for( int i = 1; i < 7; i++ )
|
||||
{
|
||||
int anim = 0;
|
||||
for( int i = 1; i < 7; i++ )
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
if( !stack.isEmpty() && isPaper( stack ) )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
if( !stack.isEmpty() && isPaper( stack ) )
|
||||
{
|
||||
anim += 1;
|
||||
break;
|
||||
}
|
||||
anim += 1;
|
||||
break;
|
||||
}
|
||||
for( int i = 7; i < 13; i++ )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
if( !stack.isEmpty() && isPaper( stack ) )
|
||||
{
|
||||
anim += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setAnim( anim );
|
||||
}
|
||||
for( int i = 7; i < 13; i++ )
|
||||
{
|
||||
ItemStack stack = m_inventory.get( i );
|
||||
if( !stack.isEmpty() && isPaper( stack ) )
|
||||
{
|
||||
anim += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setAnim( anim );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -44,7 +44,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
|
||||
{
|
||||
// FIXME: Should be abstract, but we need this for Plethora compat. We'll
|
||||
// be able to change this in a few versions as we implement both there.
|
||||
@SuppressWarnings( "deprecation" ) BlockPos pos = getPos();
|
||||
BlockPos pos = getPos();
|
||||
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ public abstract class SpeakerPeripheral implements IPeripheral
|
||||
public String[] getMethodNames()
|
||||
{
|
||||
return new String[] {
|
||||
"playSound", // Plays sound at resourceLocator
|
||||
"playNote" // Plays note
|
||||
"playSound",
|
||||
"playNote",
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -35,9 +35,7 @@ public class PocketAPI implements ILuaAPI
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"pocket"
|
||||
};
|
||||
return new String[] { "pocket" };
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@@ -46,7 +44,7 @@ public class PocketAPI implements ILuaAPI
|
||||
{
|
||||
return new String[] {
|
||||
"equipBack",
|
||||
"unequipBack"
|
||||
"unequipBack",
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -30,9 +30,13 @@ public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler
|
||||
@Override
|
||||
public int refuel( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack currentStack, int slot, int limit )
|
||||
{
|
||||
ItemStack stack = turtle.getItemHandler().extractItem( slot, limit, false );
|
||||
int fuelToGive = getFuelPerItem( stack ) * stack.getCount();
|
||||
int fuelSpaceLeft = turtle.getFuelLimit() - turtle.getFuelLevel();
|
||||
int fuelPerItem = getFuelPerItem( turtle.getItemHandler().getStackInSlot( slot ) );
|
||||
int fuelItemLimit = (int) Math.ceil( fuelSpaceLeft / (double) fuelPerItem );
|
||||
if( limit > fuelItemLimit ) limit = fuelItemLimit;
|
||||
|
||||
ItemStack stack = turtle.getItemHandler().extractItem( slot, limit, false );
|
||||
int fuelToGive = fuelPerItem * stack.getCount();
|
||||
// Store the replacement item in the inventory
|
||||
ItemStack replacementStack = stack.getItem().getContainerItem( stack );
|
||||
if( !replacementStack.isEmpty() )
|
||||
|
@@ -45,9 +45,7 @@ public class TurtleAPI implements ILuaAPI
|
||||
@Override
|
||||
public String[] getNames()
|
||||
{
|
||||
return new String[] {
|
||||
"turtle"
|
||||
};
|
||||
return new String[] { "turtle" };
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@@ -336,9 +334,11 @@ public class TurtleAPI implements ILuaAPI
|
||||
return tryCommand( context, new TurtleInspectCommand( InteractDirection.Up ) );
|
||||
case 40: // inspectDown
|
||||
return tryCommand( context, new TurtleInspectCommand( InteractDirection.Down ) );
|
||||
case 41:
|
||||
case 41: // getItemDetail
|
||||
{
|
||||
// getItemDetail
|
||||
// FIXME: There's a race condition here if the stack is being modified (mutating NBT, etc...)
|
||||
// on another thread. The obvious solution is to move this into a command, but some programs rely
|
||||
// on this having a 0-tick delay.
|
||||
int slot = parseOptionalSlotNumber( args, 0, m_turtle.getSelectedSlot() );
|
||||
ItemStack stack = m_turtle.getInventory().getStackInSlot( slot );
|
||||
if( stack.isEmpty() ) return new Object[] { null };
|
||||
|
@@ -218,7 +218,7 @@ public class BlockTurtle extends BlockComputerBase
|
||||
@Deprecated
|
||||
public float getExplosionResistance( Entity exploder )
|
||||
{
|
||||
if( getFamily() == ComputerFamily.Advanced && (exploder instanceof EntityLivingBase || exploder instanceof EntityFireball) )
|
||||
if( getFamily() == ComputerFamily.Advanced || exploder instanceof EntityLivingBase || exploder instanceof EntityFireball )
|
||||
{
|
||||
return 2000;
|
||||
}
|
||||
|
@@ -43,19 +43,16 @@ import net.minecraftforge.items.wrapper.InvWrapper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
|
||||
import static net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY;
|
||||
|
||||
public class TileTurtle extends TileComputerBase implements ITurtleTile, DefaultInventory
|
||||
{
|
||||
// Statics
|
||||
|
||||
public static final int INVENTORY_SIZE = 16;
|
||||
public static final int INVENTORY_WIDTH = 4;
|
||||
public static final int INVENTORY_HEIGHT = 4;
|
||||
|
||||
// Members
|
||||
|
||||
enum MoveState
|
||||
{
|
||||
NOT_MOVED,
|
||||
@@ -63,12 +60,12 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
MOVED
|
||||
}
|
||||
|
||||
private NonNullList<ItemStack> m_inventory;
|
||||
private NonNullList<ItemStack> m_previousInventory;
|
||||
private final NonNullList<ItemStack> m_inventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
private final NonNullList<ItemStack> m_previousInventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
private final IItemHandlerModifiable m_itemHandler = new InvWrapper( this );
|
||||
private boolean m_inventoryChanged;
|
||||
private TurtleBrain m_brain;
|
||||
private MoveState m_moveState;
|
||||
private boolean m_inventoryChanged = false;
|
||||
private TurtleBrain m_brain = new TurtleBrain( this );
|
||||
private MoveState m_moveState = MoveState.NOT_MOVED;
|
||||
private ComputerFamily m_family;
|
||||
|
||||
public TileTurtle()
|
||||
@@ -78,15 +75,10 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
|
||||
public TileTurtle( ComputerFamily family )
|
||||
{
|
||||
m_inventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
m_previousInventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
m_inventoryChanged = false;
|
||||
m_brain = new TurtleBrain( this );
|
||||
m_moveState = MoveState.NOT_MOVED;
|
||||
m_family = family;
|
||||
}
|
||||
|
||||
public boolean hasMoved()
|
||||
private boolean hasMoved()
|
||||
{
|
||||
return m_moveState == MoveState.MOVED;
|
||||
}
|
||||
@@ -95,7 +87,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
protected ServerComputer createComputer( int instanceID, int id )
|
||||
{
|
||||
ServerComputer computer = new ServerComputer(
|
||||
getWorld(), id, m_label, instanceID, getFamily(),
|
||||
getWorld(), id, label, instanceID, getFamily(),
|
||||
ComputerCraft.terminalWidth_turtle, ComputerCraft.terminalHeight_turtle
|
||||
);
|
||||
computer.setPosition( getPos() );
|
||||
@@ -224,18 +216,15 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
{
|
||||
super.update();
|
||||
m_brain.update();
|
||||
synchronized( m_inventory )
|
||||
if( !getWorld().isRemote && m_inventoryChanged )
|
||||
{
|
||||
if( !getWorld().isRemote && m_inventoryChanged )
|
||||
{
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null ) computer.queueEvent( "turtle_inventory" );
|
||||
ServerComputer computer = getServerComputer();
|
||||
if( computer != null ) computer.queueEvent( "turtle_inventory" );
|
||||
|
||||
m_inventoryChanged = false;
|
||||
for( int n = 0; n < getSizeInventory(); n++ )
|
||||
{
|
||||
m_previousInventory.set( n, InventoryUtil.copyItem( getStackInSlot( n ) ) );
|
||||
}
|
||||
m_inventoryChanged = false;
|
||||
for( int n = 0; n < getSizeInventory(); n++ )
|
||||
{
|
||||
m_previousInventory.set( n, getStackInSlot( n ).copy() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,8 +259,8 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
|
||||
// Read inventory
|
||||
NBTTagList nbttaglist = nbt.getTagList( "Items", Constants.NBT.TAG_COMPOUND );
|
||||
m_inventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
m_previousInventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||
m_inventory.clear();
|
||||
m_previousInventory.clear();
|
||||
for( int i = 0; i < nbttaglist.tagCount(); i++ )
|
||||
{
|
||||
NBTTagCompound tag = nbttaglist.getCompoundTagAt( i );
|
||||
@@ -279,7 +268,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
if( slot < getSizeInventory() )
|
||||
{
|
||||
m_inventory.set( slot, new ItemStack( tag ) );
|
||||
m_previousInventory.set( slot, InventoryUtil.copyItem( m_inventory.get( slot ) ) );
|
||||
m_previousInventory.set( slot, m_inventory.get( slot ).copy() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,7 +371,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
return m_family;
|
||||
}
|
||||
|
||||
public void setOwningPlayer( GameProfile player )
|
||||
void setOwningPlayer( GameProfile player )
|
||||
{
|
||||
m_brain.setOwningPlayer( player );
|
||||
markDirty();
|
||||
@@ -410,109 +399,76 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
@Override
|
||||
public ItemStack getStackInSlot( int slot )
|
||||
{
|
||||
if( slot >= 0 && slot < INVENTORY_SIZE )
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
return m_inventory.get( slot );
|
||||
}
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
return slot >= 0 && slot < INVENTORY_SIZE ? m_inventory.get( slot ) : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack removeStackFromSlot( int slot )
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack result = getStackInSlot( slot );
|
||||
setInventorySlotContents( slot, ItemStack.EMPTY );
|
||||
return result;
|
||||
}
|
||||
ItemStack result = getStackInSlot( slot );
|
||||
setInventorySlotContents( slot, ItemStack.EMPTY );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemStack decrStackSize( int slot, int count )
|
||||
{
|
||||
if( count == 0 )
|
||||
if( count == 0 ) return ItemStack.EMPTY;
|
||||
|
||||
ItemStack stack = getStackInSlot( slot );
|
||||
if( stack.isEmpty() ) return ItemStack.EMPTY;
|
||||
|
||||
if( stack.getCount() <= count )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
setInventorySlotContents( slot, ItemStack.EMPTY );
|
||||
return stack;
|
||||
}
|
||||
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
ItemStack stack = getStackInSlot( slot );
|
||||
if( stack.isEmpty() )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if( stack.getCount() <= count )
|
||||
{
|
||||
setInventorySlotContents( slot, ItemStack.EMPTY );
|
||||
return stack;
|
||||
}
|
||||
|
||||
ItemStack part = stack.splitStack( count );
|
||||
onInventoryDefinitelyChanged();
|
||||
return part;
|
||||
}
|
||||
ItemStack part = stack.splitStack( count );
|
||||
onInventoryDefinitelyChanged();
|
||||
return part;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents( int i, @Nonnull ItemStack stack )
|
||||
{
|
||||
if( i >= 0 && i < INVENTORY_SIZE )
|
||||
if( i >= 0 && i < INVENTORY_SIZE && !InventoryUtil.areItemsEqual( stack, m_inventory.get( i ) ) )
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
{
|
||||
if( !InventoryUtil.areItemsEqual( stack, m_inventory.get( i ) ) )
|
||||
{
|
||||
m_inventory.set( i, stack );
|
||||
onInventoryDefinitelyChanged();
|
||||
}
|
||||
}
|
||||
m_inventory.set( i, stack );
|
||||
onInventoryDefinitelyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
synchronized( m_inventory )
|
||||
boolean changed = false;
|
||||
for( int i = 0; i < INVENTORY_SIZE; i++ )
|
||||
{
|
||||
boolean changed = false;
|
||||
for( int i = 0; i < INVENTORY_SIZE; i++ )
|
||||
if( !m_inventory.get( i ).isEmpty() )
|
||||
{
|
||||
if( !m_inventory.get( i ).isEmpty() )
|
||||
{
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if( changed )
|
||||
{
|
||||
onInventoryDefinitelyChanged();
|
||||
m_inventory.set( i, ItemStack.EMPTY );
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( changed ) onInventoryDefinitelyChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty()
|
||||
{
|
||||
super.markDirty();
|
||||
synchronized( m_inventory )
|
||||
if( !m_inventoryChanged )
|
||||
{
|
||||
if( !m_inventoryChanged )
|
||||
for( int n = 0; n < getSizeInventory(); n++ )
|
||||
{
|
||||
for( int n = 0; n < getSizeInventory(); n++ )
|
||||
if( !ItemStack.areItemStacksEqual( getStackInSlot( n ), m_previousInventory.get( n ) ) )
|
||||
{
|
||||
if( !ItemStack.areItemStacksEqual( getStackInSlot( n ), m_previousInventory.get( n ) ) )
|
||||
{
|
||||
m_inventoryChanged = true;
|
||||
break;
|
||||
}
|
||||
m_inventoryChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -574,8 +530,8 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
public void transferStateFrom( TileTurtle copy )
|
||||
{
|
||||
super.transferStateFrom( copy );
|
||||
m_inventory = copy.m_inventory;
|
||||
m_previousInventory = copy.m_previousInventory;
|
||||
Collections.copy( m_inventory, copy.m_inventory );
|
||||
Collections.copy( m_previousInventory, copy.m_previousInventory );
|
||||
m_inventoryChanged = copy.m_inventoryChanged;
|
||||
m_brain = copy.m_brain;
|
||||
m_brain.setOwner( this );
|
||||
|
@@ -20,10 +20,7 @@ import dan200.computercraft.shared.computer.blocks.TileComputerBase;
|
||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import dan200.computercraft.shared.util.ColourUtils;
|
||||
import dan200.computercraft.shared.util.Holiday;
|
||||
import dan200.computercraft.shared.util.HolidayUtil;
|
||||
import dan200.computercraft.shared.util.*;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.MoverType;
|
||||
@@ -40,6 +37,7 @@ import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.*;
|
||||
@@ -53,6 +51,9 @@ public class TurtleBrain implements ITurtleAccess
|
||||
private ComputerProxy m_proxy;
|
||||
private GameProfile m_owningPlayer;
|
||||
|
||||
private final IInventory m_inventory = (InventoryDelegate) () -> m_owner;
|
||||
private final IItemHandlerModifiable m_inventoryWrapper = new InvWrapper( m_inventory );
|
||||
|
||||
private Queue<TurtleCommandQueueEntry> m_commandQueue = new ArrayDeque<>();
|
||||
private int m_commandsIssued = 0;
|
||||
|
||||
@@ -531,14 +532,14 @@ public class TurtleBrain implements ITurtleAccess
|
||||
@Override
|
||||
public IInventory getInventory()
|
||||
{
|
||||
return m_owner;
|
||||
return m_inventory;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IItemHandlerModifiable getItemHandler()
|
||||
{
|
||||
return m_owner.getItemHandler();
|
||||
return m_inventoryWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -908,14 +909,14 @@ public class TurtleBrain implements ITurtleAccess
|
||||
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,
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
@@ -65,7 +65,6 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
||||
|
||||
// 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
|
||||
|
@@ -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();
|
||||
|
@@ -73,7 +73,10 @@ public class ItemTurtleLegacy extends ItemTurtleBase
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getOverlay( @Nonnull ItemStack stack ) { return null; }
|
||||
public ResourceLocation getOverlay( @Nonnull ItemStack stack )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFuelLevel( @Nonnull ItemStack stack )
|
||||
|
@@ -54,7 +54,7 @@ public class TurtleHoe extends TurtleTool
|
||||
{
|
||||
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 )
|
||||
{
|
||||
|
@@ -60,7 +60,7 @@ public class TurtleShovel extends TurtleTool
|
||||
{
|
||||
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 )
|
||||
{
|
||||
|
@@ -48,18 +48,18 @@ import java.util.function.Function;
|
||||
|
||||
public class TurtleTool extends AbstractTurtleUpgrade
|
||||
{
|
||||
protected ItemStack m_item;
|
||||
protected final ItemStack item;
|
||||
|
||||
public TurtleTool( ResourceLocation id, int legacyID, String adjective, Item item )
|
||||
{
|
||||
super( id, legacyID, TurtleUpgradeType.Tool, adjective, item );
|
||||
m_item = new ItemStack( item, 1, 0 );
|
||||
this.item = new ItemStack( item, 1, 0 );
|
||||
}
|
||||
|
||||
public TurtleTool( ResourceLocation id, int legacyID, Item item )
|
||||
{
|
||||
super( id, legacyID, TurtleUpgradeType.Tool, item );
|
||||
m_item = new ItemStack( item, 1, 0 );
|
||||
this.item = new ItemStack( item, 1, 0 );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@@ -76,7 +76,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
|
||||
);
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
return Pair.of(
|
||||
mc.getRenderItem().getItemModelMesher().getItemModel( m_item ),
|
||||
mc.getRenderItem().getItemModelMesher().getItemModel( item ),
|
||||
transform
|
||||
);
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
|
||||
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();
|
||||
@@ -202,7 +202,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
|
||||
IBlockState state = world.getBlockState( blockPosition );
|
||||
|
||||
TurtlePlayer turtlePlayer = TurtlePlaceCommand.createPlayer( turtle, turtlePosition, direction );
|
||||
turtlePlayer.loadInventory( m_item.copy() );
|
||||
turtlePlayer.loadInventory( item.copy() );
|
||||
|
||||
if( ComputerCraft.turtlesObeyBlockProtection )
|
||||
{
|
||||
@@ -246,7 +246,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
|
||||
boolean canHarvest = state.getBlock().canHarvestBlock( world, blockPosition, turtlePlayer );
|
||||
boolean canBreak = state.getBlock().removedByPlayer( state, world, blockPosition, turtlePlayer, canHarvest );
|
||||
if( canBreak ) state.getBlock().onPlayerDestroy( world, blockPosition, state );
|
||||
if( canHarvest )
|
||||
if( canHarvest && canBreak )
|
||||
{
|
||||
state.getBlock().harvestBlock( world, turtlePlayer, blockPosition, state, tile, turtlePlayer.getHeldItemMainhand() );
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ public final class ColourUtils
|
||||
"dyeBlack", "dyeRed", "dyeGreen", "dyeBrown",
|
||||
"dyeBlue", "dyePurple", "dyeCyan", "dyeLightGray",
|
||||
"dyeGray", "dyePink", "dyeLime", "dyeYellow",
|
||||
"dyeLightBlue", "dyeMagenta", "dyeOrange", "dyeWhite"
|
||||
"dyeLightBlue", "dyeMagenta", "dyeOrange", "dyeWhite",
|
||||
};
|
||||
|
||||
private static int[] ids;
|
||||
|
@@ -14,8 +14,6 @@ import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingDropsEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.EventPriority;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
@@ -35,7 +33,6 @@ public final class DropConsumer
|
||||
private static Function<ItemStack, ItemStack> dropConsumer;
|
||||
private static List<ItemStack> remainingDrops;
|
||||
private static WeakReference<World> dropWorld;
|
||||
private static BlockPos dropPos;
|
||||
private static AxisAlignedBB dropBounds;
|
||||
private static WeakReference<Entity> dropEntity;
|
||||
|
||||
@@ -45,7 +42,6 @@ public final class DropConsumer
|
||||
remainingDrops = new ArrayList<>();
|
||||
dropEntity = new WeakReference<>( entity );
|
||||
dropWorld = new WeakReference<>( entity.world );
|
||||
dropPos = null;
|
||||
dropBounds = new AxisAlignedBB( entity.getPosition() ).grow( 2, 2, 2 );
|
||||
|
||||
entity.captureDrops = true;
|
||||
@@ -54,10 +50,9 @@ public final class DropConsumer
|
||||
public static void set( World world, BlockPos pos, Function<ItemStack, ItemStack> consumer )
|
||||
{
|
||||
dropConsumer = consumer;
|
||||
remainingDrops = new ArrayList<>();
|
||||
remainingDrops = new ArrayList<>( 2 );
|
||||
dropEntity = null;
|
||||
dropWorld = new WeakReference<>( world );
|
||||
dropPos = pos;
|
||||
dropBounds = new AxisAlignedBB( pos ).grow( 2, 2, 2 );
|
||||
}
|
||||
|
||||
@@ -83,7 +78,6 @@ public final class DropConsumer
|
||||
remainingDrops = null;
|
||||
dropEntity = null;
|
||||
dropWorld = null;
|
||||
dropPos = null;
|
||||
dropBounds = null;
|
||||
|
||||
return remainingStacks;
|
||||
@@ -95,34 +89,7 @@ public final class DropConsumer
|
||||
if( !remaining.isEmpty() ) remainingDrops.add( remaining );
|
||||
}
|
||||
|
||||
@SubscribeEvent( priority = EventPriority.LOWEST )
|
||||
public static void onEntityLivingDrops( LivingDropsEvent event )
|
||||
{
|
||||
// Capture any mob drops for the current entity
|
||||
if( dropEntity != null && event.getEntity() == dropEntity.get() )
|
||||
{
|
||||
List<EntityItem> drops = event.getDrops();
|
||||
for( EntityItem entityItem : drops ) handleDrops( entityItem.getItem() );
|
||||
drops.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent( priority = EventPriority.LOWEST )
|
||||
public static void onHarvestDrops( BlockEvent.HarvestDropsEvent event )
|
||||
{
|
||||
// Capture block drops for the current entity
|
||||
if( dropWorld != null && dropWorld.get() == event.getWorld()
|
||||
&& dropPos != null && dropPos.equals( event.getPos() ) )
|
||||
{
|
||||
for( ItemStack item : event.getDrops() )
|
||||
{
|
||||
if( event.getWorld().rand.nextFloat() < event.getDropChance() ) handleDrops( item );
|
||||
}
|
||||
event.getDrops().clear();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent( priority = EventPriority.LOWEST )
|
||||
@SubscribeEvent( priority = EventPriority.HIGHEST )
|
||||
public static void onEntitySpawn( EntityJoinWorldEvent event )
|
||||
{
|
||||
// Capture any nearby item spawns
|
||||
|
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.shared.util;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Provides a delegate over inventories.
|
||||
*
|
||||
* This may be used both on {@link net.minecraft.tileentity.TileEntity}s to redirect the inventory to another tile,
|
||||
* and by other interfaces to have inventories which change their backing store.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface InventoryDelegate extends IInventory
|
||||
{
|
||||
IInventory getInventory();
|
||||
|
||||
@Override
|
||||
default int getSizeInventory()
|
||||
{
|
||||
return getInventory().getSizeInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isEmpty()
|
||||
{
|
||||
return getInventory().isEmpty();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
default ItemStack getStackInSlot( int slot )
|
||||
{
|
||||
return getInventory().getStackInSlot( slot );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
default ItemStack decrStackSize( int slot, int count )
|
||||
{
|
||||
return getInventory().decrStackSize( slot, count );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
default ItemStack removeStackFromSlot( int slot )
|
||||
{
|
||||
return getInventory().removeStackFromSlot( slot );
|
||||
}
|
||||
|
||||
@Override
|
||||
default void setInventorySlotContents( int slot, ItemStack stack )
|
||||
{
|
||||
getInventory().setInventorySlotContents( slot, stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getInventoryStackLimit()
|
||||
{
|
||||
return getInventory().getInventoryStackLimit();
|
||||
}
|
||||
|
||||
@Override
|
||||
default void markDirty()
|
||||
{
|
||||
getInventory().markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isUsableByPlayer( @Nonnull EntityPlayer player )
|
||||
{
|
||||
return getInventory().isUsableByPlayer( player );
|
||||
}
|
||||
|
||||
@Override
|
||||
default void openInventory( @Nonnull EntityPlayer player )
|
||||
{
|
||||
getInventory().openInventory( player );
|
||||
}
|
||||
|
||||
@Override
|
||||
default void closeInventory( @Nonnull EntityPlayer player )
|
||||
{
|
||||
getInventory().closeInventory( player );
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isItemValidForSlot( int slot, @Nonnull ItemStack stack )
|
||||
{
|
||||
return getInventory().isItemValidForSlot( slot, stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getField( int id )
|
||||
{
|
||||
return getInventory().getField( id );
|
||||
}
|
||||
|
||||
@Override
|
||||
default void setField( int id, int val )
|
||||
{
|
||||
getInventory().setField( id, val );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getFieldCount()
|
||||
{
|
||||
return getInventory().getFieldCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
default void clear()
|
||||
{
|
||||
getInventory().clear();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
default String getName()
|
||||
{
|
||||
return getInventory().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean hasCustomName()
|
||||
{
|
||||
return getInventory().hasCustomName();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
default ITextComponent getDisplayName()
|
||||
{
|
||||
return getInventory().getDisplayName();
|
||||
}
|
||||
}
|
@@ -69,12 +69,6 @@ public final class InventoryUtil
|
||||
return shareTagA.equals( shareTagB );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static ItemStack copyItem( @Nonnull ItemStack a )
|
||||
{
|
||||
return a.copy();
|
||||
}
|
||||
|
||||
// Methods for finding inventories:
|
||||
|
||||
public static IItemHandler getInventory( World world, BlockPos pos, EnumFacing side )
|
||||
|
@@ -72,12 +72,11 @@ public class Palette
|
||||
|
||||
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 )
|
||||
|
@@ -1,48 +1,19 @@
|
||||
local native_select, native_type = select, type
|
||||
|
||||
--- Expect an argument to have a specific type.
|
||||
-- Load in expect from the module path.
|
||||
--
|
||||
-- @tparam int index The 1-based argument index.
|
||||
-- @param value The argument's value.
|
||||
-- @tparam string ... The allowed types of the argument.
|
||||
-- @throws If the value is not one of the allowed types.
|
||||
local function expect(index, value, ...)
|
||||
local t = native_type(value)
|
||||
for i = 1, native_select("#", ...) do
|
||||
if t == native_select(i, ...) then return true end
|
||||
end
|
||||
-- Ideally we'd use require, but that is part of the shell, and so is not
|
||||
-- available to the BIOS or any APIs. All APIs load this using dofile, but that
|
||||
-- has not been defined at this point.
|
||||
local expect
|
||||
|
||||
local types = table.pack(...)
|
||||
for i = types.n, 1, -1 do
|
||||
if types[i] == "nil" then table.remove(types, i) end
|
||||
end
|
||||
do
|
||||
local h = fs.open("rom/modules/main/cc/expect.lua", "r")
|
||||
local f, err = loadstring(h.readAll(), "@expect.lua")
|
||||
h.close()
|
||||
|
||||
local type_names
|
||||
if #types <= 1 then
|
||||
type_names = tostring(...)
|
||||
else
|
||||
type_names = table.concat(types, ", ", 1, #types - 1) .. " or " .. types[#types]
|
||||
end
|
||||
|
||||
-- If we can determine the function name with a high level of confidence, try to include it.
|
||||
local name
|
||||
if native_type(debug) == "table" and native_type(debug.getinfo) == "function" then
|
||||
local ok, info = pcall(debug.getinfo, 3, "nS")
|
||||
if ok and info.name and #info.name ~= "" and info.what ~= "C" then name = info.name end
|
||||
end
|
||||
|
||||
if name then
|
||||
error( ("bad argument #%d to '%s' (expected %s, got %s)"):format(index, name, type_names, t), 3 )
|
||||
else
|
||||
error( ("bad argument #%d (expected %s, got %s)"):format(index, type_names, t), 3 )
|
||||
end
|
||||
if not f then error(err) end
|
||||
expect = f().expect
|
||||
end
|
||||
|
||||
-- We expose expect in the global table as APIs need to access it, but give it
|
||||
-- a non-identifier name - meaning it does not show up in auto-completion.
|
||||
-- expect is an internal function, and should not be used by users.
|
||||
_G["~expect"] = expect
|
||||
|
||||
if _VERSION == "Lua 5.1" then
|
||||
-- If we're on Lua 5.1, install parts of the Lua 5.2/5.3 API so that programs can be written against it
|
||||
local type = type
|
||||
@@ -568,23 +539,28 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
return sLine
|
||||
end
|
||||
|
||||
function loadfile( _sFile, _tEnv )
|
||||
expect(1, _sFile, "string")
|
||||
expect(2, _tEnv, "table", "nil")
|
||||
|
||||
local file = fs.open( _sFile, "r" )
|
||||
if file then
|
||||
local func, err = load( file.readAll(), "@" .. fs.getName( _sFile ), "t", _tEnv )
|
||||
file.close()
|
||||
return func, err
|
||||
function loadfile( filename, mode, env )
|
||||
-- Support the previous `loadfile(filename, env)` form instead.
|
||||
if type(mode) == "table" and env == nil then
|
||||
mode, env = nil, mode
|
||||
end
|
||||
return nil, "File not found"
|
||||
|
||||
expect(1, filename, "string")
|
||||
expect(2, mode, "string", "nil")
|
||||
expect(3, env, "table", "nil")
|
||||
|
||||
local file = fs.open( filename, "r" )
|
||||
if not file then return nil, "File not found" end
|
||||
|
||||
local func, err = load( file.readAll(), "@" .. fs.getName( filename ), mode, env )
|
||||
file.close()
|
||||
return func, err
|
||||
end
|
||||
|
||||
function dofile( _sFile )
|
||||
expect(1, _sFile, "string")
|
||||
|
||||
local fnFile, e = loadfile( _sFile, _G )
|
||||
local fnFile, e = loadfile( _sFile, nil, _G )
|
||||
if fnFile then
|
||||
return fnFile()
|
||||
else
|
||||
@@ -600,7 +576,7 @@ function os.run( _tEnv, _sPath, ... )
|
||||
local tArgs = table.pack( ... )
|
||||
local tEnv = _tEnv
|
||||
setmetatable( tEnv, { __index = _G } )
|
||||
local fnFile, err = loadfile( _sPath, tEnv )
|
||||
local fnFile, err = loadfile( _sPath, nil, tEnv )
|
||||
if fnFile then
|
||||
local ok, err = pcall( function()
|
||||
fnFile( table.unpack( tArgs, 1, tArgs.n ) )
|
||||
@@ -634,7 +610,7 @@ function os.loadAPI( _sPath )
|
||||
|
||||
local tEnv = {}
|
||||
setmetatable( tEnv, { __index = _G } )
|
||||
local fnAPI, err = loadfile( _sPath, tEnv )
|
||||
local fnAPI, err = loadfile( _sPath, nil, tEnv )
|
||||
if fnAPI then
|
||||
local ok, err = pcall( fnAPI )
|
||||
if not ok then
|
||||
|
@@ -1,4 +1,4 @@
|
||||
local expect = _G["~expect"]
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
-- Colors
|
||||
white = 1
|
||||
|
@@ -1,4 +1,4 @@
|
||||
local expect = _G["~expect"]
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
CHANNEL_GPS = 65534
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
local expect = _G["~expect"]
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local sPath = "/rom/help"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
-- Definition for the IO API
|
||||
|
||||
local expect, typeOf = _G["~expect"], _G.type
|
||||
local expect, typeOf = dofile("rom/modules/main/cc/expect.lua").expect, _G.type
|
||||
|
||||
--- If we return nil then close the file, as we've reached the end.
|
||||
-- We use this weird wrapper function as we wish to preserve the varargs
|
||||
|
@@ -1,7 +1,7 @@
|
||||
-- Minecraft key code bindings
|
||||
-- See http://www.minecraftwiki.net/wiki/Key_codes for more info
|
||||
|
||||
local expect = _G["~expect"]
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local tKeys = {
|
||||
nil, "one", "two", "three", "four", -- 1
|
||||
|
@@ -1,4 +1,4 @@
|
||||
local expect = _G["~expect"]
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local function drawPixelInternal( xPos, yPos )
|
||||
term.setCursorPos( xPos, yPos )
|
||||
|
@@ -1,4 +1,4 @@
|
||||
local expect = _G["~expect"]
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local native = peripheral
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
local expect = _G["~expect"]
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
CHANNEL_BROADCAST = 65535
|
||||
CHANNEL_REPEAT = 65533
|
||||
|
@@ -1,4 +1,4 @@
|
||||
local expect = _G["~expect"]
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local tSettings = {}
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
local expect = _G["~expect"]
|
||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||
|
||||
local native = (term.native and term.native()) or term
|
||||
local redirectTarget = native
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user