mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-11-04 07:32:59 +00:00 
			
		
		
		
	Compare commits
	
		
			64 Commits
		
	
	
		
			v1.91.2
			...
			v1.12.2-1.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					0ae70fed13 | ||
| 
						 | 
					121802a683 | ||
| 
						 | 
					08cf55e55f | ||
| 
						 | 
					3c8c0d78ef | ||
| 
						 | 
					c4d18aa9ca | ||
| 
						 | 
					a8fadabaf1 | ||
| 
						 | 
					38f9a015ca | ||
| 
						 | 
					c311cdc6f5 | ||
| 
						 | 
					a93e0f3284 | ||
| 
						 | 
					14b3065ba4 | ||
| 
						 | 
					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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										98
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								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.25"
 | 
			
		||||
 | 
			
		||||
    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"
 | 
			
		||||
@@ -264,7 +331,7 @@ task checkRelease {
 | 
			
		||||
        if (!ok) throw new IllegalStateException("Could not check release")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
check.dependsOn checkRelease
 | 
			
		||||
 | 
			
		||||
curseforge {
 | 
			
		||||
    apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
 | 
			
		||||
@@ -336,7 +403,9 @@ githubRelease {
 | 
			
		||||
    token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
 | 
			
		||||
    owner 'SquidDev-CC'
 | 
			
		||||
    repo 'CC-Tweaked'
 | 
			
		||||
    targetCommitish { Grgit.open(dir: '.').branch.current().name }
 | 
			
		||||
    try {
 | 
			
		||||
        targetCommitish = Grgit.open(dir: '.').branch.current().name
 | 
			
		||||
    } catch(Exception ignored) { }
 | 
			
		||||
 | 
			
		||||
    tagName "v${mc_version}-${mod_version}"
 | 
			
		||||
    releaseName "[${mc_version}] ${mod_version}"
 | 
			
		||||
@@ -357,18 +426,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 }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										169
									
								
								config/checkstyle/checkstyle.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								config/checkstyle/checkstyle.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
			
		||||
<?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" />
 | 
			
		||||
        <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" />
 | 
			
		||||
        <module name="UnnecessarySemicolonAfterTypeMemberDeclaration" />
 | 
			
		||||
        <module name="UnnecessarySemicolonInTryWithResources" />
 | 
			
		||||
        <module name="UnnecessarySemicolonInEnumeration" />
 | 
			
		||||
 | 
			
		||||
        <!-- Imports -->
 | 
			
		||||
        <module name="CustomImportOrder" />
 | 
			
		||||
        <module name="IllegalImport" />
 | 
			
		||||
        <module name="RedundantImport" />
 | 
			
		||||
        <module name="UnusedImports" />
 | 
			
		||||
 | 
			
		||||
        <!-- Javadoc -->
 | 
			
		||||
        <!-- TODO: Missing* checks for the dan200.computercraft.api package? -->
 | 
			
		||||
        <module name="AtclauseOrder" />
 | 
			
		||||
        <module name="InvalidJavadocPosition" />
 | 
			
		||||
        <module name="JavadocBlockTagLocation" />
 | 
			
		||||
        <module name="JavadocMethod"/>
 | 
			
		||||
        <module name="JavadocType"/>
 | 
			
		||||
        <module name="JavadocStyle" />
 | 
			
		||||
        <module name="NonEmptyAtclauseDescription" />
 | 
			
		||||
        <module name="SingleLineJavadoc" />
 | 
			
		||||
        <module name="SummaryJavadocCheck"/>
 | 
			
		||||
 | 
			
		||||
        <!-- Misc -->
 | 
			
		||||
        <module name="ArrayTypeStyle" />
 | 
			
		||||
        <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 name="RegexpSingleline">
 | 
			
		||||
        <property name="format" value="\s+$"/>
 | 
			
		||||
        <property name="message" value="Trailing whitespace"/>
 | 
			
		||||
    </module>
 | 
			
		||||
</module>
 | 
			
		||||
							
								
								
									
										12
									
								
								config/checkstyle/suppressions.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								config/checkstyle/suppressions.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
<?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" />
 | 
			
		||||
 | 
			
		||||
    <!-- Do not check for missing package Javadoc. -->
 | 
			
		||||
    <suppress checks="JavadocStyle" files=".*[\\/]package-info.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.2
 | 
			
		||||
 | 
			
		||||
# 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;
 | 
			
		||||
 
 | 
			
		||||
@@ -32,8 +32,9 @@ import java.lang.reflect.Method;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The static entry point to the ComputerCraft API.
 | 
			
		||||
 * Members in this class must be called after mod_ComputerCraft has been initialised,
 | 
			
		||||
 * but may be called before it is fully loaded.
 | 
			
		||||
 *
 | 
			
		||||
 * Members in this class must be called after mod_ComputerCraft has been initialised, but may be called before it is
 | 
			
		||||
 * fully loaded.
 | 
			
		||||
 */
 | 
			
		||||
public final class ComputerCraftAPI
 | 
			
		||||
{
 | 
			
		||||
@@ -269,7 +270,7 @@ public final class ComputerCraftAPI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Registers a media provider to provide {@link IMedia} implementations for Items
 | 
			
		||||
     * Registers a media provider to provide {@link IMedia} implementations for Items.
 | 
			
		||||
     *
 | 
			
		||||
     * @param provider The media provider to register.
 | 
			
		||||
     * @see IMediaProvider
 | 
			
		||||
@@ -370,7 +371,7 @@ public final class ComputerCraftAPI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a new wired node for a given wired element
 | 
			
		||||
     * Construct a new wired node for a given wired element.
 | 
			
		||||
     *
 | 
			
		||||
     * @param element The element to construct it for
 | 
			
		||||
     * @return The element's node
 | 
			
		||||
@@ -398,7 +399,7 @@ public final class ComputerCraftAPI
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the wired network element for a block in world
 | 
			
		||||
     * Get the wired network element for a block in world.
 | 
			
		||||
     *
 | 
			
		||||
     * @param world The world the block exists in
 | 
			
		||||
     * @param pos   The position the block exists in
 | 
			
		||||
@@ -438,45 +439,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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -19,7 +19,7 @@ import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents a read only part of a virtual filesystem that can be mounted onto a computer using
 | 
			
		||||
 * {@link IComputerAccess#mount(String, IMount)}
 | 
			
		||||
 * {@link IComputerAccess#mount(String, IMount)}.
 | 
			
		||||
 *
 | 
			
		||||
 * Ready made implementations of this interface can be created using
 | 
			
		||||
 * {@link ComputerCraftAPI#createSaveDirMount(World, String, long)} or
 | 
			
		||||
@@ -60,7 +60,7 @@ public interface IMount
 | 
			
		||||
    void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the size of a file with a given path, in bytes
 | 
			
		||||
     * Returns the size of a file with a given path, in bytes.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
 | 
			
		||||
     * @return The size of the file, in bytes.
 | 
			
		||||
@@ -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 ) );
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										335
									
								
								src/main/java/dan200/computercraft/api/lua/ArgumentHelper.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										335
									
								
								src/main/java/dan200/computercraft/api/lua/ArgumentHelper.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,335 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of the public ComputerCraft API - http://www.computercraft.info
 | 
			
		||||
 * Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
 | 
			
		||||
 * For help using the API, and posting your mods, visit the forums at computercraft.info.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package dan200.computercraft.api.lua;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.api.peripheral.IComputerAccess;
 | 
			
		||||
import dan200.computercraft.api.peripheral.IPeripheral;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Provides methods for extracting values and validating Lua arguments, such as those provided to
 | 
			
		||||
 * {@link ILuaObject#callMethod(ILuaContext, int, Object[])} or
 | 
			
		||||
 * {@link IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}.
 | 
			
		||||
 *
 | 
			
		||||
 * This provides two sets of functions: the {@code get*} methods, which require an argument to be valid, and
 | 
			
		||||
 * {@code opt*}, which accept a default value and return that if the argument was not present or was {@code null}.
 | 
			
		||||
 * If the argument is of the wrong type, a suitable error message will be thrown, with a similar format to Lua's own
 | 
			
		||||
 * error messages.
 | 
			
		||||
 *
 | 
			
		||||
 * <h2>Example usage:</h2>
 | 
			
		||||
 * <pre>
 | 
			
		||||
 * {@code
 | 
			
		||||
 * int slot = getInt( args, 0 );
 | 
			
		||||
 * int amount = optInt( args, 1, 64 );
 | 
			
		||||
 * }
 | 
			
		||||
 * </pre>
 | 
			
		||||
 */
 | 
			
		||||
public final class ArgumentHelper
 | 
			
		||||
{
 | 
			
		||||
    private ArgumentHelper()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a string representation of the given value's type.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value The value whose type we are trying to compute.
 | 
			
		||||
     * @return A string representation of the given value's type, in a similar format to that provided by Lua's
 | 
			
		||||
     * {@code type} function.
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static String getType( @Nullable Object value )
 | 
			
		||||
    {
 | 
			
		||||
        if( value == null ) return "nil";
 | 
			
		||||
        if( value instanceof String ) return "string";
 | 
			
		||||
        if( value instanceof Boolean ) return "boolean";
 | 
			
		||||
        if( value instanceof Number ) return "number";
 | 
			
		||||
        if( value instanceof Map ) return "table";
 | 
			
		||||
        return "userdata";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a "bad argument" exception, from an expected type and the actual value provided.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index    The argument number, starting from 0.
 | 
			
		||||
     * @param expected The expected type for this argument.
 | 
			
		||||
     * @param actual   The actual value provided for this argument.
 | 
			
		||||
     * @return The constructed exception, which should be thrown immediately.
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static LuaException badArgumentOf( int index, @Nonnull String expected, @Nullable Object actual )
 | 
			
		||||
    {
 | 
			
		||||
        return badArgument( index, expected, getType( actual ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Construct a "bad argument" exception, from an expected and actual type.
 | 
			
		||||
     *
 | 
			
		||||
     * @param index    The argument number, starting from 0.
 | 
			
		||||
     * @param expected The expected type for this argument.
 | 
			
		||||
     * @param actual   The provided type for this argument.
 | 
			
		||||
     * @return The constructed exception, which should be thrown immediately.
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
 | 
			
		||||
    {
 | 
			
		||||
        return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a double.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @return The argument's value.
 | 
			
		||||
     * @throws LuaException If the value is not a number.
 | 
			
		||||
     * @see #getFiniteDouble(Object[], int) if you require this to be finite (i.e. not infinite or NaN).
 | 
			
		||||
     */
 | 
			
		||||
    public static double getDouble( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( index >= args.length ) throw badArgument( index, "number", "nil" );
 | 
			
		||||
        Object value = args[index];
 | 
			
		||||
        if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
 | 
			
		||||
        return ((Number) value).doubleValue();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as an integer.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @return The argument's value.
 | 
			
		||||
     * @throws LuaException If the value is not an integer.
 | 
			
		||||
     */
 | 
			
		||||
    public static int getInt( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        return (int) getLong( args, index );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a long.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @return The argument's value.
 | 
			
		||||
     * @throws LuaException If the value is not a long.
 | 
			
		||||
     */
 | 
			
		||||
    public static long getLong( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( index >= args.length ) throw badArgument( index, "number", "nil" );
 | 
			
		||||
        Object value = args[index];
 | 
			
		||||
        if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
 | 
			
		||||
        return checkFinite( index, (Number) value ).longValue();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a finite number (not infinite or NaN).
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @return The argument's value.
 | 
			
		||||
     * @throws LuaException If the value is not finite.
 | 
			
		||||
     */
 | 
			
		||||
    public static double getFiniteDouble( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        return checkFinite( index, getDouble( args, index ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a boolean.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @return The argument's value.
 | 
			
		||||
     * @throws LuaException If the value is not a boolean.
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( index >= args.length ) throw badArgument( index, "boolean", "nil" );
 | 
			
		||||
        Object value = args[index];
 | 
			
		||||
        if( !(value instanceof Boolean) ) throw badArgumentOf( index, "boolean", value );
 | 
			
		||||
        return (Boolean) value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a string.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @return The argument's value.
 | 
			
		||||
     * @throws LuaException If the value is not a string.
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static String getString( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( index >= args.length ) throw badArgument( index, "string", "nil" );
 | 
			
		||||
        Object value = args[index];
 | 
			
		||||
        if( !(value instanceof String) ) throw badArgumentOf( index, "string", value );
 | 
			
		||||
        return (String) value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a table.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @return The argument's value.
 | 
			
		||||
     * @throws LuaException If the value is not a table.
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static Map<?, ?> getTable( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( index >= args.length ) throw badArgument( index, "table", "nil" );
 | 
			
		||||
        Object value = args[index];
 | 
			
		||||
        if( !(value instanceof Map) ) throw badArgumentOf( index, "table", value );
 | 
			
		||||
        return (Map<?, ?>) value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a double.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @param def   The default value, if this argument is not given.
 | 
			
		||||
     * @return The argument's value, or {@code def} if none was provided.
 | 
			
		||||
     * @throws LuaException If the value is not a number.
 | 
			
		||||
     */
 | 
			
		||||
    public static double optDouble( @Nonnull Object[] args, int index, double def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        Object value = index < args.length ? args[index] : null;
 | 
			
		||||
        if( value == null ) return def;
 | 
			
		||||
        if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
 | 
			
		||||
        return ((Number) value).doubleValue();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as an int.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @param def   The default value, if this argument is not given.
 | 
			
		||||
     * @return The argument's value, or {@code def} if none was provided.
 | 
			
		||||
     * @throws LuaException If the value is not a number.
 | 
			
		||||
     */
 | 
			
		||||
    public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        return (int) optLong( args, index, def );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a long.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @param def   The default value, if this argument is not given.
 | 
			
		||||
     * @return The argument's value, or {@code def} if none was provided.
 | 
			
		||||
     * @throws LuaException If the value is not a number.
 | 
			
		||||
     */
 | 
			
		||||
    public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        Object value = index < args.length ? args[index] : null;
 | 
			
		||||
        if( value == null ) return def;
 | 
			
		||||
        if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
 | 
			
		||||
        return checkFinite( index, (Number) value ).longValue();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a finite number (not infinite or NaN).
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @param def   The default value, if this argument is not given.
 | 
			
		||||
     * @return The argument's value, or {@code def} if none was provided.
 | 
			
		||||
     * @throws LuaException If the value is not finite.
 | 
			
		||||
     */
 | 
			
		||||
    public static double optFiniteDouble( @Nonnull Object[] args, int index, double def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        return checkFinite( index, optDouble( args, index, def ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a boolean.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @param def   The default value, if this argument is not given.
 | 
			
		||||
     * @return The argument's value, or {@code def} if none was provided.
 | 
			
		||||
     * @throws LuaException If the value is not a boolean.
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        Object value = index < args.length ? args[index] : null;
 | 
			
		||||
        if( value == null ) return def;
 | 
			
		||||
        if( !(value instanceof Boolean) ) throw badArgumentOf( index, "boolean", value );
 | 
			
		||||
        return (Boolean) value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a string.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @param def   The default value, if this argument is not given.
 | 
			
		||||
     * @return The argument's value, or {@code def} if none was provided.
 | 
			
		||||
     * @throws LuaException If the value is not a string.
 | 
			
		||||
     */
 | 
			
		||||
    public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        Object value = index < args.length ? args[index] : null;
 | 
			
		||||
        if( value == null ) return def;
 | 
			
		||||
        if( !(value instanceof String) ) throw badArgumentOf( index, "string", value );
 | 
			
		||||
        return (String) value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an argument as a table.
 | 
			
		||||
     *
 | 
			
		||||
     * @param args  The arguments to extract from.
 | 
			
		||||
     * @param index The index into the argument array to read from.
 | 
			
		||||
     * @param def   The default value, if this argument is not given.
 | 
			
		||||
     * @return The argument's value, or {@code def} if none was provided.
 | 
			
		||||
     * @throws LuaException If the value is not a table.
 | 
			
		||||
     */
 | 
			
		||||
    public static Map<?, ?> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        Object value = index < args.length ? args[index] : null;
 | 
			
		||||
        if( value == null ) return def;
 | 
			
		||||
        if( !(value instanceof Map) ) throw badArgumentOf( index, "table", value );
 | 
			
		||||
        return (Map<?, ?>) value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Number checkFinite( int index, Number value ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        checkFinite( index, value.doubleValue() );
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static double checkFinite( int index, double value ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( !Double.isFinite( value ) ) throw badArgument( index, "number", getNumericType( value ) );
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns a more detailed representation of this number's type. If this is finite, it will just return "number",
 | 
			
		||||
     * otherwise it returns whether it is infinite or NaN.
 | 
			
		||||
     *
 | 
			
		||||
     * @param value The value to extract the type for.
 | 
			
		||||
     * @return This value's numeric type.
 | 
			
		||||
     */
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static String getNumericType( double value )
 | 
			
		||||
    {
 | 
			
		||||
        if( Double.isNaN( value ) ) return "nan";
 | 
			
		||||
        if( value == Double.POSITIVE_INFINITY ) return "inf";
 | 
			
		||||
        if( value == Double.NEGATIVE_INFINITY ) return "-inf";
 | 
			
		||||
        return "number";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -26,7 +26,7 @@ public interface IComputerSystem extends IComputerAccess
 | 
			
		||||
    IFileSystem getFileSystem();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the label for this computer
 | 
			
		||||
     * Get the label for this computer.
 | 
			
		||||
     *
 | 
			
		||||
     * @return This computer's label, or {@code null} if it is not set.
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@
 | 
			
		||||
 | 
			
		||||
package dan200.computercraft.api.peripheral;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.api.lua.ArgumentHelper;
 | 
			
		||||
import dan200.computercraft.api.lua.ILuaContext;
 | 
			
		||||
import dan200.computercraft.api.lua.LuaException;
 | 
			
		||||
 | 
			
		||||
@@ -58,9 +59,11 @@ public interface IPeripheral
 | 
			
		||||
     *                  Lua values of type "table" will be represented by Object type Map.<br>
 | 
			
		||||
     *                  Lua values of any other type will be represented by a null object.<br>
 | 
			
		||||
     *                  This array will be empty if no arguments are passed.
 | 
			
		||||
     *
 | 
			
		||||
     *                  It is recommended you use {@link ArgumentHelper} in order to validate and process arguments.
 | 
			
		||||
     * @return An array of objects, representing values you wish to return to the lua program. Integers, Doubles, Floats,
 | 
			
		||||
     * Strings, Booleans, Maps and ILuaObject and null be converted to their corresponding lua type. All other types
 | 
			
		||||
     * will be converted to nil.
 | 
			
		||||
     * Strings, Booleans, Maps, ILuaObject and null be converted to their corresponding lua type. All other types will
 | 
			
		||||
     * be converted to nil.
 | 
			
		||||
     *
 | 
			
		||||
     * You may return null to indicate no values should be returned.
 | 
			
		||||
     * @throws LuaException         If you throw any exception from this function, a lua error will be raised with the
 | 
			
		||||
@@ -70,6 +73,7 @@ public interface IPeripheral
 | 
			
		||||
     *                              InterruptedException will be thrown. This exception must not be caught or
 | 
			
		||||
     *                              intercepted, or the computer will leak memory and end up in a broken state.
 | 
			
		||||
     * @see #getMethodNames
 | 
			
		||||
     * @see ArgumentHelper
 | 
			
		||||
     */
 | 
			
		||||
    @Nullable
 | 
			
		||||
    Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException;
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ import javax.annotation.Nullable;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Wrapper class for pocket computers
 | 
			
		||||
 * Wrapper class for pocket computers.
 | 
			
		||||
 */
 | 
			
		||||
public interface IPocketAccess
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
@@ -12,12 +12,12 @@ package dan200.computercraft.api.turtle;
 | 
			
		||||
public enum TurtleSide
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle)
 | 
			
		||||
     * The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle).
 | 
			
		||||
     */
 | 
			
		||||
    Left,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The turtle's right side (where the modem usually is on a Wireless Mining Turtle)
 | 
			
		||||
     * The turtle's right side (where the modem usually is on a Wireless Mining Turtle).
 | 
			
		||||
     */
 | 
			
		||||
    Right,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,12 +18,12 @@ import net.minecraft.util.EnumFacing;
 | 
			
		||||
public enum TurtleVerb
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}
 | 
			
		||||
     * The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}.
 | 
			
		||||
     */
 | 
			
		||||
    Dig,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()}
 | 
			
		||||
     * The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()}.
 | 
			
		||||
     */
 | 
			
		||||
    Attack,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ public enum TurtleAction
 | 
			
		||||
    EQUIP,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Inspect a block in world
 | 
			
		||||
     * Inspect a block in world.
 | 
			
		||||
     *
 | 
			
		||||
     * @see TurtleBlockEvent.Inspect
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -112,7 +112,7 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Get the upgrade doing the digging
 | 
			
		||||
         * Get the upgrade doing the digging.
 | 
			
		||||
         *
 | 
			
		||||
         * @return The upgrade doing the digging.
 | 
			
		||||
         */
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the inventory being interacted with
 | 
			
		||||
     * Get the inventory being interacted with.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world.
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -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 );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ import net.minecraft.util.math.MathHelper;
 | 
			
		||||
public abstract class ItemMapLikeRenderer
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The main rendering method for the item
 | 
			
		||||
     * The main rendering method for the item.
 | 
			
		||||
     *
 | 
			
		||||
     * @param stack The stack to render
 | 
			
		||||
     * @see ItemRenderer#renderMapFirstPerson(ItemStack)
 | 
			
		||||
@@ -87,7 +87,7 @@ public abstract class ItemMapLikeRenderer
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Render an item in the middle of the screen
 | 
			
		||||
     * Render an item in the middle of the screen.
 | 
			
		||||
     *
 | 
			
		||||
     * @param pitch         The pitch of the player
 | 
			
		||||
     * @param equipProgress The equip progress of this item
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*;
 | 
			
		||||
import static dan200.computercraft.client.gui.GuiComputer.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Emulates map rendering for pocket computers
 | 
			
		||||
 * Emulates map rendering for pocket computers.
 | 
			
		||||
 */
 | 
			
		||||
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
 | 
			
		||||
public final class ItemPocketRenderer extends ItemMapLikeRenderer
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ import static dan200.computercraft.shared.media.items.ItemPrintout.LINES_PER_PAG
 | 
			
		||||
import static dan200.computercraft.shared.media.items.ItemPrintout.LINE_MAX_LENGTH;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Emulates map and item-frame rendering for printouts
 | 
			
		||||
 * Emulates map and item-frame rendering for printouts.
 | 
			
		||||
 */
 | 
			
		||||
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
 | 
			
		||||
public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -28,32 +28,32 @@ public final class PrintoutRenderer
 | 
			
		||||
    private static final double BG_SIZE = 256.0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Width of a page
 | 
			
		||||
     * Width of a page.
 | 
			
		||||
     */
 | 
			
		||||
    public static final int X_SIZE = 172;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Height of a page
 | 
			
		||||
     * Height of a page.
 | 
			
		||||
     */
 | 
			
		||||
    public static final int Y_SIZE = 209;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Padding between the left and right of a page and the text
 | 
			
		||||
     * Padding between the left and right of a page and the text.
 | 
			
		||||
     */
 | 
			
		||||
    public static final int X_TEXT_MARGIN = 13;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Padding between the top and bottom of a page and the text
 | 
			
		||||
     * Padding between the top and bottom of a page and the text.
 | 
			
		||||
     */
 | 
			
		||||
    public static final int Y_TEXT_MARGIN = 11;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Width of the extra page texture
 | 
			
		||||
     * Width of the extra page texture.
 | 
			
		||||
     */
 | 
			
		||||
    private static final int X_FOLD_SIZE = 12;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Size of the leather cover
 | 
			
		||||
     * Size of the leather cover.
 | 
			
		||||
     */
 | 
			
		||||
    public static final int COVER_SIZE = 12;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -97,6 +97,8 @@ public class TileEntityCableRenderer extends TileEntitySpecialRenderer<TileCable
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set up the state for rendering block-breaking progress.
 | 
			
		||||
     *
 | 
			
		||||
     * @see RenderGlobal#preRenderDamagedBlocks()
 | 
			
		||||
     */
 | 
			
		||||
    private void preRenderDamagedBlocks()
 | 
			
		||||
@@ -115,6 +117,8 @@ public class TileEntityCableRenderer extends TileEntitySpecialRenderer<TileCable
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Tear down the state for rendering block-breaking progress.
 | 
			
		||||
     *
 | 
			
		||||
     * @see RenderGlobal#postRenderDamagedBlocks()
 | 
			
		||||
     */
 | 
			
		||||
    private void postRenderDamagedBlocks()
 | 
			
		||||
 
 | 
			
		||||
@@ -154,7 +154,7 @@ public class AddressPredicate
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine whether the given address matches a series of patterns
 | 
			
		||||
     * Determine whether the given address matches a series of patterns.
 | 
			
		||||
     *
 | 
			
		||||
     * @param address The address to check.
 | 
			
		||||
     * @return Whether it matches any of these patterns.
 | 
			
		||||
 
 | 
			
		||||
@@ -13,256 +13,106 @@ import javax.annotation.Nullable;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Various helpers for arguments
 | 
			
		||||
 * A stub for any mods which depended on this version of the argument helper.
 | 
			
		||||
 *
 | 
			
		||||
 * @deprecated Use {@link dan200.computercraft.api.lua.ArgumentHelper}.
 | 
			
		||||
 */
 | 
			
		||||
@Deprecated
 | 
			
		||||
public final class ArgumentHelper
 | 
			
		||||
{
 | 
			
		||||
    private ArgumentHelper()
 | 
			
		||||
    {
 | 
			
		||||
        throw new IllegalStateException( "Cannot instantiate singleton " + getClass().getName() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static String getType( @Nullable Object type )
 | 
			
		||||
    {
 | 
			
		||||
        if( type == null ) return "nil";
 | 
			
		||||
        if( type instanceof String ) return "string";
 | 
			
		||||
        if( type instanceof Boolean ) return "boolean";
 | 
			
		||||
        if( type instanceof Number ) return "number";
 | 
			
		||||
        if( type instanceof Map ) return "table";
 | 
			
		||||
 | 
			
		||||
        Class<?> klass = type.getClass();
 | 
			
		||||
        if( klass.isArray() )
 | 
			
		||||
        {
 | 
			
		||||
            StringBuilder name = new StringBuilder();
 | 
			
		||||
            while( klass.isArray() )
 | 
			
		||||
            {
 | 
			
		||||
                name.append( "[]" );
 | 
			
		||||
                klass = klass.getComponentType();
 | 
			
		||||
            }
 | 
			
		||||
            name.insert( 0, klass.getName() );
 | 
			
		||||
            return name.toString();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return klass.getName();
 | 
			
		||||
        }
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.getType( type );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static LuaException badArgument( int index, @Nonnull String expected, @Nullable Object actual )
 | 
			
		||||
    {
 | 
			
		||||
        return badArgument( index, expected, getType( actual ) );
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.badArgumentOf( index, expected, actual );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
 | 
			
		||||
    {
 | 
			
		||||
        return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.badArgument( index, expected, actual );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static double getNumber( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( index >= args.length ) throw badArgument( index, "number", "nil" );
 | 
			
		||||
        Object value = args[index];
 | 
			
		||||
        if( value instanceof Number )
 | 
			
		||||
        {
 | 
			
		||||
            return ((Number) value).doubleValue();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "number", value );
 | 
			
		||||
        }
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.getDouble( args, index );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int getInt( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        return (int) getLong( args, index );
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.getInt( args, index );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static long getLong( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( index >= args.length ) throw badArgument( index, "number", "nil" );
 | 
			
		||||
        Object value = args[index];
 | 
			
		||||
        if( value instanceof Number )
 | 
			
		||||
        {
 | 
			
		||||
            return checkReal( index, (Number) value ).longValue();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "number", value );
 | 
			
		||||
        }
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.getLong( args, index );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static double getReal( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        return checkReal( index, getNumber( args, index ) );
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.getFiniteDouble( args, index );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( index >= args.length ) throw badArgument( index, "boolean", "nil" );
 | 
			
		||||
        Object value = args[index];
 | 
			
		||||
        if( value instanceof Boolean )
 | 
			
		||||
        {
 | 
			
		||||
            return (Boolean) value;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "boolean", value );
 | 
			
		||||
        }
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.getBoolean( args, index );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    public static String getString( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( index >= args.length ) throw badArgument( index, "string", "nil" );
 | 
			
		||||
        Object value = args[index];
 | 
			
		||||
        if( value instanceof String )
 | 
			
		||||
        {
 | 
			
		||||
            return (String) value;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "string", value );
 | 
			
		||||
        }
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.getString( args, index );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings( "unchecked" )
 | 
			
		||||
    @Nonnull
 | 
			
		||||
    @SuppressWarnings( "unchecked" )
 | 
			
		||||
    public static Map<Object, Object> getTable( @Nonnull Object[] args, int index ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( index >= args.length ) throw badArgument( index, "table", "nil" );
 | 
			
		||||
        Object value = args[index];
 | 
			
		||||
        if( value instanceof Map )
 | 
			
		||||
        {
 | 
			
		||||
            return (Map<Object, Object>) value;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "table", value );
 | 
			
		||||
        }
 | 
			
		||||
        return (Map<Object, Object>) dan200.computercraft.api.lua.ArgumentHelper.getTable( args, index );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static double optNumber( @Nonnull Object[] args, int index, double def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        Object value = index < args.length ? args[index] : null;
 | 
			
		||||
        if( value == null )
 | 
			
		||||
        {
 | 
			
		||||
            return def;
 | 
			
		||||
        }
 | 
			
		||||
        else if( value instanceof Number )
 | 
			
		||||
        {
 | 
			
		||||
            return ((Number) value).doubleValue();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "number", value );
 | 
			
		||||
        }
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.optDouble( args, index, def );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        return (int) optLong( args, index, def );
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.optInt( args, index, def );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        Object value = index < args.length ? args[index] : null;
 | 
			
		||||
        if( value == null )
 | 
			
		||||
        {
 | 
			
		||||
            return def;
 | 
			
		||||
        }
 | 
			
		||||
        else if( value instanceof Number )
 | 
			
		||||
        {
 | 
			
		||||
            return checkReal( index, (Number) value ).longValue();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "number", value );
 | 
			
		||||
        }
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.optLong( args, index, def );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static double optReal( @Nonnull Object[] args, int index, double def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        return checkReal( index, optNumber( args, index, def ) );
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.optFiniteDouble( args, index, def );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        Object value = index < args.length ? args[index] : null;
 | 
			
		||||
        if( value == null )
 | 
			
		||||
        {
 | 
			
		||||
            return def;
 | 
			
		||||
        }
 | 
			
		||||
        else if( value instanceof Boolean )
 | 
			
		||||
        {
 | 
			
		||||
            return (Boolean) value;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "boolean", value );
 | 
			
		||||
        }
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.optBoolean( args, index, def );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        Object value = index < args.length ? args[index] : null;
 | 
			
		||||
        if( value == null )
 | 
			
		||||
        {
 | 
			
		||||
            return def;
 | 
			
		||||
        }
 | 
			
		||||
        else if( value instanceof String )
 | 
			
		||||
        {
 | 
			
		||||
            return (String) value;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "string", value );
 | 
			
		||||
        }
 | 
			
		||||
        return dan200.computercraft.api.lua.ArgumentHelper.optString( args, index, def );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings( "unchecked" )
 | 
			
		||||
    public static Map<Object, Object> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        Object value = index < args.length ? args[index] : null;
 | 
			
		||||
        if( value == null )
 | 
			
		||||
        {
 | 
			
		||||
            return def;
 | 
			
		||||
        }
 | 
			
		||||
        else if( value instanceof Map )
 | 
			
		||||
        {
 | 
			
		||||
            return (Map<Object, Object>) value;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "table", value );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Number checkReal( int index, Number value ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        checkReal( index, value.doubleValue() );
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static double checkReal( int index, double value ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( Double.isNaN( value ) )
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "number", "nan" );
 | 
			
		||||
        }
 | 
			
		||||
        else if( value == Double.POSITIVE_INFINITY )
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "number", "inf" );
 | 
			
		||||
        }
 | 
			
		||||
        else if( value == Double.NEGATIVE_INFINITY )
 | 
			
		||||
        {
 | 
			
		||||
            throw badArgument( index, "number", "-inf" );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return value;
 | 
			
		||||
        }
 | 
			
		||||
        return (Map<Object, Object>) dan200.computercraft.api.lua.ArgumentHelper.optTable( args, index, def );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
 | 
			
		||||
 | 
			
		||||
public class FSAPI implements ILuaAPI
 | 
			
		||||
{
 | 
			
		||||
@@ -43,9 +43,7 @@ public class FSAPI implements ILuaAPI
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] getNames()
 | 
			
		||||
    {
 | 
			
		||||
        return new String[] {
 | 
			
		||||
            "fs"
 | 
			
		||||
        };
 | 
			
		||||
        return new String[] { "fs" };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ import java.util.Collections;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.*;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.*;
 | 
			
		||||
import static dan200.computercraft.core.apis.TableHelper.*;
 | 
			
		||||
 | 
			
		||||
public class HTTPAPI implements ILuaAPI
 | 
			
		||||
@@ -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 )
 | 
			
		||||
@@ -90,12 +89,12 @@ public class HTTPAPI implements ILuaAPI
 | 
			
		||||
            case 0: // request
 | 
			
		||||
            {
 | 
			
		||||
                String address, postString, requestMethod;
 | 
			
		||||
                Map<Object, Object> headerTable;
 | 
			
		||||
                Map<?, ?> headerTable;
 | 
			
		||||
                boolean binary, redirect;
 | 
			
		||||
 | 
			
		||||
                if( args.length >= 1 && args[0] instanceof Map )
 | 
			
		||||
                {
 | 
			
		||||
                    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 );
 | 
			
		||||
@@ -174,7 +172,7 @@ public class HTTPAPI implements ILuaAPI
 | 
			
		||||
            case 2: // websocket
 | 
			
		||||
            {
 | 
			
		||||
                String address = getString( args, 0 );
 | 
			
		||||
                Map<Object, Object> headerTbl = optTable( args, 1, Collections.emptyMap() );
 | 
			
		||||
                Map<?, ?> headerTbl = optTable( args, 1, Collections.emptyMap() );
 | 
			
		||||
 | 
			
		||||
                if( !ComputerCraft.http_websocket_enable )
 | 
			
		||||
                {
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ import java.time.ZonedDateTime;
 | 
			
		||||
import java.time.format.DateTimeFormatterBuilder;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.*;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.*;
 | 
			
		||||
 | 
			
		||||
public class OSAPI implements ILuaAPI
 | 
			
		||||
{
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -231,7 +229,7 @@ public class OSAPI implements ILuaAPI
 | 
			
		||||
            case 1:
 | 
			
		||||
            {
 | 
			
		||||
                // startTimer
 | 
			
		||||
                double timer = getReal( args, 0 );
 | 
			
		||||
                double timer = getFiniteDouble( args, 0 );
 | 
			
		||||
                synchronized( m_timers )
 | 
			
		||||
                {
 | 
			
		||||
                    m_timers.put( m_nextTimerToken, new Timer( (int) Math.round( timer / 0.05 ) ) );
 | 
			
		||||
@@ -241,7 +239,7 @@ public class OSAPI implements ILuaAPI
 | 
			
		||||
            case 2:
 | 
			
		||||
            {
 | 
			
		||||
                // setAlarm
 | 
			
		||||
                double time = getReal( args, 0 );
 | 
			
		||||
                double time = getFiniteDouble( args, 0 );
 | 
			
		||||
                if( time < 0.0 || time >= 24.0 )
 | 
			
		||||
                {
 | 
			
		||||
                    throw new LuaException( "Number out of range" );
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
 | 
			
		||||
 | 
			
		||||
public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChangeListener
 | 
			
		||||
{
 | 
			
		||||
@@ -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()];
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ import javax.annotation.Nonnull;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.*;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.*;
 | 
			
		||||
 | 
			
		||||
public class RedstoneAPI implements ILuaAPI
 | 
			
		||||
{
 | 
			
		||||
@@ -29,9 +29,7 @@ public class RedstoneAPI implements ILuaAPI
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] getNames()
 | 
			
		||||
    {
 | 
			
		||||
        return new String[] {
 | 
			
		||||
            "rs", "redstone"
 | 
			
		||||
        };
 | 
			
		||||
        return new String[] { "rs", "redstone" };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nonnull
 | 
			
		||||
 
 | 
			
		||||
@@ -6,14 +6,17 @@
 | 
			
		||||
 | 
			
		||||
package dan200.computercraft.core.apis;
 | 
			
		||||
 | 
			
		||||
import dan200.computercraft.api.lua.ArgumentHelper;
 | 
			
		||||
import dan200.computercraft.api.lua.LuaException;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
import javax.annotation.Nullable;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.getNumericType;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Various helpers for tables
 | 
			
		||||
 * Various helpers for tables.
 | 
			
		||||
 */
 | 
			
		||||
public final class TableHelper
 | 
			
		||||
{
 | 
			
		||||
@@ -200,21 +203,7 @@ public final class TableHelper
 | 
			
		||||
 | 
			
		||||
    private static double checkReal( @Nonnull String key, double value ) throws LuaException
 | 
			
		||||
    {
 | 
			
		||||
        if( Double.isNaN( value ) )
 | 
			
		||||
        {
 | 
			
		||||
            throw badKey( key, "number", "nan" );
 | 
			
		||||
        }
 | 
			
		||||
        else if( value == Double.POSITIVE_INFINITY )
 | 
			
		||||
        {
 | 
			
		||||
            throw badKey( key, "number", "inf" );
 | 
			
		||||
        }
 | 
			
		||||
        else if( value == Double.NEGATIVE_INFINITY )
 | 
			
		||||
        {
 | 
			
		||||
            throw badKey( key, "number", "-inf" );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return value;
 | 
			
		||||
        }
 | 
			
		||||
        if( !Double.isFinite( value ) ) throw badKey( key, "number", getNumericType( value ) );
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ import org.apache.commons.lang3.ArrayUtils;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.*;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.*;
 | 
			
		||||
 | 
			
		||||
public class TermAPI implements ILuaAPI
 | 
			
		||||
{
 | 
			
		||||
@@ -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 )
 | 
			
		||||
@@ -246,9 +242,9 @@ public class TermAPI implements ILuaAPI
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    double r = getReal( args, 1 );
 | 
			
		||||
                    double g = getReal( args, 2 );
 | 
			
		||||
                    double b = getReal( args, 3 );
 | 
			
		||||
                    double r = getFiniteDouble( args, 1 );
 | 
			
		||||
                    double g = getFiniteDouble( args, 2 );
 | 
			
		||||
                    double b = getFiniteDouble( args, 3 );
 | 
			
		||||
                    setColour( m_terminal, colour, r, g, b );
 | 
			
		||||
                }
 | 
			
		||||
                return null;
 | 
			
		||||
 
 | 
			
		||||
@@ -21,8 +21,8 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
 | 
			
		||||
 | 
			
		||||
public class BinaryReadableHandle extends HandleGeneric
 | 
			
		||||
{
 | 
			
		||||
@@ -212,6 +212,7 @@ public class BinaryReadableHandle extends HandleGeneric
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            case 3: // close
 | 
			
		||||
                checkOpen();
 | 
			
		||||
                close();
 | 
			
		||||
                return null;
 | 
			
		||||
            case 4: // seek
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,9 @@
 | 
			
		||||
package dan200.computercraft.core.apis.handles;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.ObjectArrays;
 | 
			
		||||
import dan200.computercraft.api.lua.ArgumentHelper;
 | 
			
		||||
import dan200.computercraft.api.lua.ILuaContext;
 | 
			
		||||
import dan200.computercraft.api.lua.LuaException;
 | 
			
		||||
import dan200.computercraft.core.apis.ArgumentHelper;
 | 
			
		||||
import dan200.computercraft.shared.util.StringUtil;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
@@ -73,7 +73,7 @@ public class BinaryWritableHandle extends HandleGeneric
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        throw ArgumentHelper.badArgument( 0, "string or number", args.length > 0 ? args[0] : null );
 | 
			
		||||
                        throw ArgumentHelper.badArgumentOf( 0, "string or number", args.length > 0 ? args[0] : null );
 | 
			
		||||
                    }
 | 
			
		||||
                    return null;
 | 
			
		||||
                }
 | 
			
		||||
@@ -95,6 +95,7 @@ public class BinaryWritableHandle extends HandleGeneric
 | 
			
		||||
                    return null;
 | 
			
		||||
                }
 | 
			
		||||
            case 2: // close
 | 
			
		||||
                checkOpen();
 | 
			
		||||
                close();
 | 
			
		||||
                return null;
 | 
			
		||||
            case 3: // seek
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,8 @@ import java.nio.charset.CharsetDecoder;
 | 
			
		||||
import java.nio.charset.CodingErrorAction;
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean;
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.optInt;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.optInt;
 | 
			
		||||
 | 
			
		||||
public class EncodedReadableHandle extends HandleGeneric
 | 
			
		||||
{
 | 
			
		||||
@@ -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:
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,8 @@ import java.io.IOException;
 | 
			
		||||
import java.nio.channels.Channel;
 | 
			
		||||
import java.nio.channels.SeekableByteChannel;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.optLong;
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.optString;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.optLong;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.optString;
 | 
			
		||||
 | 
			
		||||
public abstract class HandleGeneric implements ILuaObject
 | 
			
		||||
{
 | 
			
		||||
@@ -37,12 +37,17 @@ 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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Shared implementation for various file handle types
 | 
			
		||||
     * Shared implementation for various file handle types.
 | 
			
		||||
     *
 | 
			
		||||
     * @param channel The channel to seek in
 | 
			
		||||
     * @param args    The Lua arguments to process, like Lua's {@code file:seek}.
 | 
			
		||||
 
 | 
			
		||||
@@ -99,7 +99,7 @@ public final class NetworkUtils
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks a host is allowed
 | 
			
		||||
     * Checks a host is allowed.
 | 
			
		||||
     *
 | 
			
		||||
     * @param host The domain to check against
 | 
			
		||||
     * @throws HTTPRequestException If the host is not permitted.
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,8 @@ import java.util.function.Consumer;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A holder for one or more resources, with a lifetime.
 | 
			
		||||
 *
 | 
			
		||||
 * @param <T> The type of this resource. Should be the class extending from {@link Resource}.
 | 
			
		||||
 */
 | 
			
		||||
public abstract class Resource<T extends Resource<T>> implements Closeable
 | 
			
		||||
{
 | 
			
		||||
@@ -42,8 +44,9 @@ public abstract class Resource<T extends Resource<T>> implements Closeable
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if this has been cancelled. If so, it'll clean up any
 | 
			
		||||
     * existing resources and cancel any pending futures.
 | 
			
		||||
     * Checks if this has been cancelled. If so, it'll clean up any existing resources and cancel any pending futures.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Whether this resource has been closed.
 | 
			
		||||
     */
 | 
			
		||||
    public final boolean checkClosed()
 | 
			
		||||
    {
 | 
			
		||||
@@ -72,13 +75,15 @@ 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 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create a {@link WeakReference} which will close {@code this} when collected.
 | 
			
		||||
     *
 | 
			
		||||
     * @param <R>    The object we are wrapping in a reference.
 | 
			
		||||
     * @param object The object to reference to
 | 
			
		||||
     * @return The weak reference.
 | 
			
		||||
     */
 | 
			
		||||
@@ -95,7 +100,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 ) );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,8 @@ import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A collection of {@link Resource}s, with an upper bound on capacity.
 | 
			
		||||
 *
 | 
			
		||||
 * @param <T> The type of the resource this group manages.
 | 
			
		||||
 */
 | 
			
		||||
public class ResourceGroup<T extends Resource<T>>
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,8 @@ import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A {@link ResourceGroup} which will queue items when the group at capacity.
 | 
			
		||||
 *
 | 
			
		||||
 * @param <T> The type of the resource this queue manages.
 | 
			
		||||
 */
 | 
			
		||||
public class ResourceQueue<T extends Resource<T>> extends ResourceGroup<T>
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ import java.util.concurrent.TimeUnit;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicInteger;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents one or more
 | 
			
		||||
 * Represents an in-progress HTTP request.
 | 
			
		||||
 */
 | 
			
		||||
public class HttpRequest extends Resource<HttpRequest>
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -226,7 +226,11 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpOb
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine the redirect from this response
 | 
			
		||||
     * Determine the redirect from this response.
 | 
			
		||||
     *
 | 
			
		||||
     * @param status  The status of the HTTP response.
 | 
			
		||||
     * @param headers The headers of the HTTP response.
 | 
			
		||||
     * @return The URI to redirect to, or {@code null} if no redirect should occur.
 | 
			
		||||
     */
 | 
			
		||||
    private URI getRedirect( HttpResponseStatus status, HttpHeaders headers )
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ import javax.annotation.Nullable;
 | 
			
		||||
import java.io.Closeable;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.optBoolean;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.optBoolean;
 | 
			
		||||
import static dan200.computercraft.core.apis.http.websocket.Websocket.CLOSE_EVENT;
 | 
			
		||||
import static dan200.computercraft.core.apis.http.websocket.Websocket.MESSAGE_EVENT;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -239,7 +239,6 @@ public class Computer
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    @SuppressWarnings( "unused" )
 | 
			
		||||
    public void advance( double dt )
 | 
			
		||||
    {
 | 
			
		||||
        tick();
 | 
			
		||||
 
 | 
			
		||||
@@ -268,7 +268,7 @@ final class ComputerExecutor
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Queue an event if the computer is on
 | 
			
		||||
     * Queue an event if the computer is on.
 | 
			
		||||
     *
 | 
			
		||||
     * @param event The event's name
 | 
			
		||||
     * @param args  The event's arguments
 | 
			
		||||
 
 | 
			
		||||
@@ -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 )
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@ import static dan200.computercraft.core.computer.TimeoutState.TIMEOUT;
 | 
			
		||||
public final class ComputerThread
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * How often the computer thread monitor should run, in milliseconds
 | 
			
		||||
     * How often the computer thread monitor should run, in milliseconds.
 | 
			
		||||
     *
 | 
			
		||||
     * @see Monitor
 | 
			
		||||
     */
 | 
			
		||||
@@ -83,7 +83,7 @@ public final class ComputerThread
 | 
			
		||||
    private static final Object threadLock = new Object();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether the computer thread system is currently running
 | 
			
		||||
     * Whether the computer thread system is currently running.
 | 
			
		||||
     */
 | 
			
		||||
    private static volatile boolean running = false;
 | 
			
		||||
 | 
			
		||||
@@ -105,7 +105,7 @@ public final class ComputerThread
 | 
			
		||||
    private static final Condition hasWork = computerLock.newCondition();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Active queues to execute
 | 
			
		||||
     * Active queues to execute.
 | 
			
		||||
     */
 | 
			
		||||
    private static final TreeSet<ComputerExecutor> computerQueue = new TreeSet<>( ( a, b ) -> {
 | 
			
		||||
        if( a == b ) return 0; // Should never happen, but let's be consistent here
 | 
			
		||||
@@ -126,7 +126,7 @@ public final class ComputerThread
 | 
			
		||||
    private ComputerThread() {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Start the computer thread
 | 
			
		||||
     * Start the computer thread.
 | 
			
		||||
     */
 | 
			
		||||
    static void start()
 | 
			
		||||
    {
 | 
			
		||||
@@ -194,7 +194,7 @@ public final class ComputerThread
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Mark a computer as having work, enqueuing it on the thread
 | 
			
		||||
     * Mark a computer as having work, enqueuing it on the thread.
 | 
			
		||||
     *
 | 
			
		||||
     * You must be holding {@link ComputerExecutor}'s {@code queueLock} when calling this method - it should only
 | 
			
		||||
     * be called from {@code enqueue}.
 | 
			
		||||
@@ -244,6 +244,8 @@ public final class ComputerThread
 | 
			
		||||
     * {@link #minimumVirtualRuntime} based on the current tasks.
 | 
			
		||||
     *
 | 
			
		||||
     * This is called before queueing tasks, to ensure that {@link #minimumVirtualRuntime} is up-to-date.
 | 
			
		||||
     *
 | 
			
		||||
     * @param current The machine which we updating runtimes from.
 | 
			
		||||
     */
 | 
			
		||||
    private static void updateRuntimes( @Nullable ComputerExecutor current )
 | 
			
		||||
    {
 | 
			
		||||
@@ -321,7 +323,7 @@ public final class ComputerThread
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The scaled period for a single task
 | 
			
		||||
     * The scaled period for a single task.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The scaled period for the task
 | 
			
		||||
     * @see #DEFAULT_LATENCY
 | 
			
		||||
@@ -336,7 +338,7 @@ public final class ComputerThread
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine if the thread has computers queued up
 | 
			
		||||
     * Determine if the thread has computers queued up.
 | 
			
		||||
     *
 | 
			
		||||
     * @return If we have work queued up.
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -36,12 +36,12 @@ import java.util.concurrent.TimeUnit;
 | 
			
		||||
public final class TimeoutState
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The total time a task is allowed to run before aborting in nanoseconds
 | 
			
		||||
     * The total time a task is allowed to run before aborting in nanoseconds.
 | 
			
		||||
     */
 | 
			
		||||
    static final long TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 7000 );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The time the task is allowed to run after each abort in nanoseconds
 | 
			
		||||
     * The time the task is allowed to run after each abort in nanoseconds.
 | 
			
		||||
     */
 | 
			
		||||
    static final long ABORT_TIMEOUT = TimeUnit.MILLISECONDS.toNanos( 1500 );
 | 
			
		||||
 | 
			
		||||
@@ -111,6 +111,8 @@ public final class TimeoutState
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * If the machine should be passively aborted.
 | 
			
		||||
     *
 | 
			
		||||
     * @return {@code true} if we should throw a timeout error.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isSoftAborted()
 | 
			
		||||
    {
 | 
			
		||||
@@ -118,7 +120,9 @@ public final class TimeoutState
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * If the machine should be forcibly aborted.
 | 
			
		||||
     * Determine if the machine should be forcibly aborted.
 | 
			
		||||
     *
 | 
			
		||||
     * @return {@code true} if the machine should be forcibly shut down.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isHardAborted()
 | 
			
		||||
    {
 | 
			
		||||
@@ -146,7 +150,7 @@ public final class TimeoutState
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pauses the cumulative time, to be resumed by {@link #startTimer()}
 | 
			
		||||
     * Pauses the cumulative time, to be resumed by {@link #startTimer()}.
 | 
			
		||||
     *
 | 
			
		||||
     * @see #nanoCumulative()
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
                    } );
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ public final class MachineResult
 | 
			
		||||
    public static final MachineResult TIMEOUT = new MachineResult( true, false, TimeoutState.ABORT_MESSAGE );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * An error with no user-friendly error message
 | 
			
		||||
     * An error with no user-friendly error message.
 | 
			
		||||
     */
 | 
			
		||||
    public static final MachineResult GENERIC_ERROR = new MachineResult( true, false, null );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -314,6 +314,9 @@ public class Terminal
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine whether this terminal has changed.
 | 
			
		||||
     *
 | 
			
		||||
     * @return If this terminal is dirty.
 | 
			
		||||
     * @deprecated All {@code *Changed()} methods are deprecated: one should pass in a callback
 | 
			
		||||
     * instead.
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -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 );
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A command which delegates to a series of sub commands
 | 
			
		||||
 * A command which delegates to a series of sub commands.
 | 
			
		||||
 */
 | 
			
		||||
public class CommandRoot implements ISubCommand
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ import java.util.List;
 | 
			
		||||
public interface ISubCommand
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the name of this command
 | 
			
		||||
     * Get the name of this command.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The name of this command
 | 
			
		||||
     * @see ICommand#getName()
 | 
			
		||||
@@ -40,7 +40,7 @@ public interface ISubCommand
 | 
			
		||||
    String getFullName();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the usage of this command
 | 
			
		||||
     * Get the usage of this command.
 | 
			
		||||
     *
 | 
			
		||||
     * @param context The context this command is executed in
 | 
			
		||||
     * @return The usage of this command
 | 
			
		||||
@@ -62,16 +62,17 @@ public interface ISubCommand
 | 
			
		||||
    boolean checkPermission( @Nonnull CommandContext context );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Execute this command
 | 
			
		||||
     * Execute this command.
 | 
			
		||||
     *
 | 
			
		||||
     * @param context   The current command context.
 | 
			
		||||
     * @param arguments The arguments passed  @throws CommandException When an error occurs
 | 
			
		||||
     * @param arguments The arguments passed
 | 
			
		||||
     * @throws CommandException When an error occurs
 | 
			
		||||
     * @see ICommand#execute(MinecraftServer, ICommandSender, String[])
 | 
			
		||||
     */
 | 
			
		||||
    void execute( @Nonnull CommandContext context, @Nonnull List<String> arguments ) throws CommandException;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a list of possible completions
 | 
			
		||||
     * Get a list of possible completions.
 | 
			
		||||
     *
 | 
			
		||||
     * @param context   The current command context.
 | 
			
		||||
     * @param arguments The arguments passed. You should complete the last one.
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ import net.minecraft.util.text.event.ClickEvent;
 | 
			
		||||
import net.minecraft.util.text.event.HoverEvent;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Various helpers for building chat messages
 | 
			
		||||
 * Various helpers for building chat messages.
 | 
			
		||||
 */
 | 
			
		||||
public final class ChatHelpers
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,7 @@ public class TableBuilder
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Trim this table to a given height
 | 
			
		||||
     * Trim this table to a given height.
 | 
			
		||||
     *
 | 
			
		||||
     * @param height The desired height.
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ public interface TableFormatter
 | 
			
		||||
    ITextComponent HEADER = coloured( "=", TextFormatting.GRAY );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get additional padding for the component
 | 
			
		||||
     * Get additional padding for the component.
 | 
			
		||||
     *
 | 
			
		||||
     * @param component The component to pad
 | 
			
		||||
     * @param width     The desired width for the component
 | 
			
		||||
@@ -32,7 +32,7 @@ public interface TableFormatter
 | 
			
		||||
    ITextComponent getPadding( ITextComponent component, int width );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the minimum padding between each column
 | 
			
		||||
     * Get the minimum padding between each column.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The minimum padding.
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
 
 | 
			
		||||
@@ -30,8 +30,8 @@ import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
 | 
			
		||||
 | 
			
		||||
public class CommandAPI implements ILuaAPI
 | 
			
		||||
{
 | 
			
		||||
@@ -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 )
 | 
			
		||||
        {
 | 
			
		||||
@@ -206,7 +204,7 @@ public class CommandAPI implements ILuaAPI
 | 
			
		||||
                    );
 | 
			
		||||
                    if( !world.isValid( min ) || !world.isValid( max ) )
 | 
			
		||||
                    {
 | 
			
		||||
                        throw new LuaException( "Co-ordinates out or range" );
 | 
			
		||||
                        throw new LuaException( "Co-ordinates out of range" );
 | 
			
		||||
                    }
 | 
			
		||||
                    if( (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1) > 4096 )
 | 
			
		||||
                    {
 | 
			
		||||
@@ -245,7 +243,7 @@ public class CommandAPI implements ILuaAPI
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        throw new LuaException( "co-ordinates out or range" );
 | 
			
		||||
                        throw new LuaException( "Co-ordinates out of range" );
 | 
			
		||||
                    }
 | 
			
		||||
                } );
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -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" );
 | 
			
		||||
@@ -280,7 +280,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the redstone input for an adjacent block
 | 
			
		||||
     * Gets the redstone input for an adjacent block.
 | 
			
		||||
     *
 | 
			
		||||
     * @param world The world we exist in
 | 
			
		||||
     * @param pos   The position of the neighbour
 | 
			
		||||
@@ -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 ) )
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
package dan200.computercraft.shared.computer.core;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Receives some input and forwards it to a computer
 | 
			
		||||
 * Receives some input and forwards it to a computer.
 | 
			
		||||
 *
 | 
			
		||||
 * @see InputState
 | 
			
		||||
 * @see IComputer
 | 
			
		||||
 
 | 
			
		||||
@@ -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 )
 | 
			
		||||
        {
 | 
			
		||||
@@ -107,7 +108,7 @@ public class JEIComputerCraft implements IModPlugin
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Distinguishes turtles by upgrades and family
 | 
			
		||||
     * Distinguishes turtles by upgrades and family.
 | 
			
		||||
     */
 | 
			
		||||
    private static final ISubtypeInterpreter turtleSubtype = stack -> {
 | 
			
		||||
        Item item = stack.getItem();
 | 
			
		||||
@@ -131,7 +132,7 @@ public class JEIComputerCraft implements IModPlugin
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Distinguishes pocket computers by upgrade and family
 | 
			
		||||
     * Distinguishes pocket computers by upgrade and family.
 | 
			
		||||
     */
 | 
			
		||||
    private static final ISubtypeInterpreter pocketSubtype = stack -> {
 | 
			
		||||
        Item item = stack.getItem();
 | 
			
		||||
@@ -151,7 +152,7 @@ public class JEIComputerCraft implements IModPlugin
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Distinguishes disks by colour
 | 
			
		||||
     * Distinguishes disks by colour.
 | 
			
		||||
     */
 | 
			
		||||
    private static final ISubtypeInterpreter diskSubtype = stack -> {
 | 
			
		||||
        Item item = stack.getItem();
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ import net.minecraft.util.SoundEvent;
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An implementation of IMedia for ItemRecord's
 | 
			
		||||
 * An implementation of IMedia for ItemRecords.
 | 
			
		||||
 */
 | 
			
		||||
public final class RecordMedia implements IMedia
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -72,6 +72,7 @@ public final class NetworkHandler
 | 
			
		||||
     * /**
 | 
			
		||||
     * Register packet, and a thread-unsafe handler for it.
 | 
			
		||||
     *
 | 
			
		||||
     * @param <T>     The type of the packet to send.
 | 
			
		||||
     * @param id      The identifier for this packet type
 | 
			
		||||
     * @param side    The side to register this packet handler under
 | 
			
		||||
     * @param factory The factory for this type of packet.
 | 
			
		||||
 
 | 
			
		||||
@@ -39,5 +39,8 @@ public enum PeripheralType implements IStringSerializable
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() { return name; }
 | 
			
		||||
    public String toString()
 | 
			
		||||
    {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ import net.minecraft.tileentity.TileEntityCommandBlock;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.Nonnull;
 | 
			
		||||
 | 
			
		||||
import static dan200.computercraft.core.apis.ArgumentHelper.getString;
 | 
			
		||||
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
 | 
			
		||||
 | 
			
		||||
public class CommandBlockPeripheral implements IPeripheral
 | 
			
		||||
{
 | 
			
		||||
@@ -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:
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user