1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-09-07 12:57:55 +00:00

Merge pull request #54 from SquidDev-CC/feature/squid-breaks-everything

Squid breaks everything (not really lol)
This commit is contained in:
Merith
2021-06-09 09:21:14 -07:00
committed by GitHub
609 changed files with 26083 additions and 30210 deletions

View File

@@ -10,6 +10,3 @@ insert_final_newline = true
[*.md] [*.md]
trim_trailing_whitespace = false trim_trailing_whitespace = false
[*.properties]
insert_final_newline = false

View File

@@ -12,4 +12,5 @@ labels: bug
## Useful information to include: ## Useful information to include:
- Minecraft version - Minecraft version
- CC: Restitched version - CC: Restitched version
- Logs: These will be located in the `logs/` directory of your Minecraft instance. Please upload them as a gist or directly into this editor.
- Detailed reproduction steps: sometimes I can spot a bug pretty easily, but often it's much more obscure. The more information I have to help reproduce it, the quicker it'll get fixed. - Detailed reproduction steps: sometimes I can spot a bug pretty easily, but often it's much more obscure. The more information I have to help reproduce it, the quicker it'll get fixed.

View File

@@ -9,4 +9,4 @@ labels: peripheralShoutout
- Link to the mod - Link to the mod
- Mod Name - Mod Name
- Basic description of the mod - Basic description of the mod
- Link to CC:R Peripheral Documentation for the mod - Link to CC:R Peripheral Documentation for the mod

17
.github/matchers/checkstyle.json vendored Normal file
View File

@@ -0,0 +1,17 @@
{
"problemMatcher": [
{
"owner": "checkstyle",
"pattern": [
{
"regexp": "^([a-z]+) ([\\w./-]+):(\\d+):(\\d+): (.*)$",
"severity": 1,
"file": 2,
"line": 3,
"column": 4,
"message": 5
}
]
}
]
}

18
.github/matchers/illuaminate.json vendored Normal file
View File

@@ -0,0 +1,18 @@
{
"problemMatcher": [
{
"owner": "illuaminate",
"severity": "warning",
"pattern": [
{
"regexp": "^([\\w./-]+):\\[(\\d+):(\\d+)\\-(?:\\d+):(?:\\d+)\\]: (.*) \\[([a-z:-]+)\\]$",
"file": 1,
"line": 2,
"column": 3,
"message": 4,
"code": 5
}
]
}
]
}

15
.github/matchers/junit.json vendored Normal file
View File

@@ -0,0 +1,15 @@
{
"problemMatcher": [
{
"owner": "junit",
"pattern": [
{
"regexp": "^## ([\\w./-]+):(\\d+): (.*)$",
"file": 1,
"line": 2,
"message": 3
}
]
}
]
}

View File

@@ -3,33 +3,58 @@ name: Build
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
build: build:
name: Build name: Build
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Checkout submodules - name: Checkout submodules
run: git submodule update --init --recursive run: git submodule update --init --recursive
- name: Set up Java 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Cache gradle dependencies - name: Set up Java 8
uses: actions/cache@v2 uses: actions/setup-java@v1
with: with:
path: ~/.gradle/caches java-version: 8
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build with Gradle - name: Cache gradle dependencies
run: ./gradlew build --no-daemon || ./gradlew build --no-daemon uses: actions/cache@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Upload Jar - name: Disable Gradle daemon
uses: actions/upload-artifact@v1 run: |
with: mkdir -p ~/.gradle
name: cc-restiched echo "org.gradle.daemon=false" >> ~/.gradle/gradle.properties
path: build/libs
- name: Build with Gradle
run: |
./gradlew assemble || ./gradlew assemble
./gradlew build
- name: Upload Jar
uses: actions/upload-artifact@v2
with:
name: cc-restitched
path: build/libs
- name: Parse test reports
run: ./tools/parse-reports.py
if: ${{ failure() }}
- name: Cache pre-commit
uses: actions/cache@v2
with:
path: ~/.cache/pre-commit
key: ${{ runner.os }}-pre-commit-${{ hashFiles('config/pre-commit/config.yml') }}
restore-keys: |
${{ runner.os }}-pre-commit-
- name: Run linters
run: |
pip install pre-commit
pre-commit run --config config/pre-commit/config.yml --show-diff-on-failure --all --color=always

2
.gitignore vendored
View File

@@ -20,4 +20,4 @@
.idea .idea
.gradle .gradle
*.DS_Store *.DS_Store
.project .project

2
.gitpod.Dockerfile vendored
View File

@@ -16,4 +16,4 @@ RUN sudo apt-get -q update && \
sudo apt install -yq openjdk-8-jdk openjdk-16-jdk sudo apt install -yq openjdk-8-jdk openjdk-16-jdk
# This is so that you can use java 8 until such a time as you switch to java 16 # This is so that you can use java 8 until such a time as you switch to java 16
RUN sudo update-java-alternatives --set java-1.8.0-openjdk-amd64 RUN sudo update-java-alternatives --set java-1.8.0-openjdk-amd64

View File

@@ -15,4 +15,4 @@ vscode:
tasks: tasks:
- init: ./gradlew - init: ./gradlew

View File

@@ -9,7 +9,7 @@
// Custom Hidden Files // Custom Hidden Files
"**/.bin": true, "**/.bin": true,
"**/.editorconfig": true, "**/.editorconfig": true,
}, },
"java.configuration.updateBuildConfiguration": "automatic" "java.configuration.updateBuildConfiguration": "automatic"
} }

14
LICENSE
View File

@@ -19,14 +19,14 @@ Mod: The mod code designated by the present license, in source form, binary
form, as obtained standalone, as part of a wider distribution or resulting from form, as obtained standalone, as part of a wider distribution or resulting from
the compilation of the original or modified sources. the compilation of the original or modified sources.
Dependency: Code required for the mod to work properly. This includes Dependency: Code required for the mod to work properly. This includes
dependencies required to compile the code as well as any file or modification dependencies required to compile the code as well as any file or modification
that is explicitly or implicitly required for the mod to be working. that is explicitly or implicitly required for the mod to be working.
1. Scope 1. Scope
-------- --------
The present license is granted to any user of the mod. As a prerequisite, The present license is granted to any user of the mod. As a prerequisite,
a user must own a legally acquired copy of Minecraft a user must own a legally acquired copy of Minecraft
2. Liability 2. Liability
@@ -41,13 +41,13 @@ or misuse of this mod fall on the user.
3. Play rights 3. Play rights
-------------- --------------
The user is allowed to install this mod on a Minecraft client or server and to play The user is allowed to install this mod on a Minecraft client or server and to play
without restriction. without restriction.
4. Modification rights 4. Modification rights
---------------------- ----------------------
The user has the right to decompile the source code, look at either the The user has the right to decompile the source code, look at either the
decompiled version or the original source code, and to modify it. decompiled version or the original source code, and to modify it.
5. Distribution of original or modified copy rights 5. Distribution of original or modified copy rights
@@ -61,10 +61,10 @@ include:
- patch to its source or binary files - patch to its source or binary files
- any copy of a portion of its binary source files - any copy of a portion of its binary source files
The user is allowed to redistribute this mod partially, in totality, or The user is allowed to redistribute this mod partially, in totality, or
included in a distribution. included in a distribution.
When distributing binary files, the user must provide means to obtain its When distributing binary files, the user must provide means to obtain its
entire set of sources or modified sources at no cost. entire set of sources or modified sources at no cost.
All distributions of this mod must remain licensed under the CCPL. All distributions of this mod must remain licensed under the CCPL.
@@ -92,7 +92,7 @@ must be made available at no cost and remain licensed under the CCPL.
--------------- ---------------
If you choose to contribute code or assets to be included in this mod, you If you choose to contribute code or assets to be included in this mod, you
agree that, if added to to the main repository at agree that, if added to to the main repository at
https://github.com/dan200/ComputerCraft, your contributions will be covered by https://github.com/dan200/ComputerCraft, your contributions will be covered by
this license, and that Daniel Ratcliffe will retain the right to re-license the this license, and that Daniel Ratcliffe will retain the right to re-license the
mod, including your contributions, in part or in whole, under other licenses. mod, including your contributions, in part or in whole, under other licenses.

View File

@@ -30,7 +30,7 @@ Any contribution is welcome, be that using the mod, reporting bugs or contributi
> Comments, optional but useful if you had to do something differently than in CC:T outside of [Fabric](https://fabricmc.net/)/[Forge](https://mcforge.readthedocs.io/en/1.16.x/) differences > Comments, optional but useful if you had to do something differently than in CC:T outside of [Fabric](https://fabricmc.net/)/[Forge](https://mcforge.readthedocs.io/en/1.16.x/) differences
> >
> \`\`\` > \`\`\`
> >
>commitID >commitID
> >
> commit title > commit title
@@ -38,29 +38,29 @@ Any contribution is welcome, be that using the mod, reporting bugs or contributi
> commit desc > commit desc
> >
> \`\`\` > \`\`\`
2) Follow the [Fabric](https://fabricmc.net/) programming guidelines as close as possible. This means you have to use [`loom`](https://fabricmc.net/wiki/tutorial:mappings) mappings, 2) Follow the [Fabric](https://fabricmc.net/) programming guidelines as close as possible. This means you have to use [`loom`](https://fabricmc.net/wiki/tutorial:mappings) mappings,
3) You cannot intentionally implement bugs and security vulnerabilities 3) You cannot intentionally implement bugs and security vulnerabilities
4) Unless the commit is a ["patchwork"](https://github.com/Merith-TK/cc-restitched/blob/fabric/patchwork.md) compliant commit, (IE: taken from CC:T), the lua code is off limits 4) Unless the commit is a ["patchwork"](https://github.com/Merith-TK/cc-restitched/blob/fabric/patchwork.md) compliant commit, (IE: taken from CC:T), the lua code is off limits
## Bleeding Edge Builds ## Bleeding Edge Builds
Bleeding edge builds can be found [here](https://github.com/Merith-TK/cc-restitched/actions) at Github Actions. Bleeding edge builds can be found [here](https://github.com/Merith-TK/cc-restitched/actions) at Github Actions.
## Community ## Community
If you need help getting started with CC: Tweaked, want to show off your latest project, or just want to chat about ComputerCraft, here is the [Forum](https://forums.computercraft.cc/) and the [Discord](https://discord.gg/H2UyJXe) If you need help getting started with CC: Tweaked, want to show off your latest project, or just want to chat about ComputerCraft, here is the [Forum](https://forums.computercraft.cc/) and the [Discord](https://discord.gg/H2UyJXe)
## Known Issues ## Known Issues
Main Known issue Main Known issue
* Mods that add blocks that can be used as peripherals for CC:T On forge, don't work with CC:R. * Mods that add blocks that can be used as peripherals for CC:T On forge, don't work with CC:R.
* This is because of the differences between forge and fabric, and that mod devs, to my knowledge have not agreed upon a standard method in which to implement cross compatibility between mods, * This is because of the differences between forge and fabric, and that mod devs, to my knowledge have not agreed upon a standard method in which to implement cross compatibility between mods,
* [Fixed (d10f297c): please report if bug persists]</br> ~~Storage Peripherals throw a java "StackOverflowError" when using `pushItems()`,~~ * [Fixed (d10f297c): please report if bug persists]</br> ~~Storage Peripherals throw a java "StackOverflowError" when using `pushItems()`,~~
* ~~Work around, you are probably using `pushItems(chest, 1)` or similar. please use `pushItems(chest, 1, nil, 1)`.~~ * ~~Work around, you are probably using `pushItems(chest, 1)` or similar. please use `pushItems(chest, 1, nil, 1)`.~~
* Computers will not run built in commands, saying "File not found" * Computers will not run built in commands, saying "File not found"
* This is a know bug, dont know what causes it, but just restart the computer (`ctrl+r` for one second) and it will work again * This is a know bug, dont know what causes it, but just restart the computer (`ctrl+r` for one second) and it will work again
* Occurs when server runs `/reload` or a datapack is updated * Occurs when server runs `/reload` or a datapack is updated
## Perpherals ## Perpherals
Unfortunately, unlike the original CC:Tweaked project, CC:Restitched, does not have any actual peripheral mods, currently the only one we have is an example for mod devs to get started with making/adding the peripheral API to their mods! Unfortunately, unlike the original CC:Tweaked project, CC:Restitched, does not have any actual peripheral mods, currently the only one we have is an example for mod devs to get started with making/adding the peripheral API to their mods!
If your a mod dev made a mod with CC:R peripheral support, OR if your a player who found a mod with CC:R support, please open an [issue here](https://github.com/Merith-TK/cc-restitched/issues/new?assignees=&labels=peripheralShoutout&template=peripheral_shoutout.md) to let us know so we can add it to the list! If your a mod dev made a mod with CC:R peripheral support, OR if your a player who found a mod with CC:R support, please open an [issue here](https://github.com/Merith-TK/cc-restitched/issues/new?assignees=&labels=peripheralShoutout&template=peripheral_shoutout.md) to let us know so we can add it to the list!
* ![icon](https://raw.githubusercontent.com/Toad-Dev/cc-peripheral-test/master/src/main/resources/assets/cc_test/textures/block/test_peripheral.png) [CC Peripheral Test](https://github.com/Toad-Dev/cc-peripheral-test) * ![icon](https://raw.githubusercontent.com/Toad-Dev/cc-peripheral-test/master/src/main/resources/assets/cc_test/textures/block/test_peripheral.png) [CC Peripheral Test](https://github.com/Toad-Dev/cc-peripheral-test)
* This is an example mod for how to make peripherals that work as a block, or as a turtle upgrade! * This is an example mod for how to make peripherals that work as a block, or as a turtle upgrade!

View File

@@ -1,6 +1,8 @@
plugins { plugins {
id 'fabric-loom' version '0.6-SNAPSHOT' id 'fabric-loom' version '0.7-SNAPSHOT'
id 'maven-publish' id 'maven-publish'
id "checkstyle"
id "com.github.hierynomus.license" version "0.15.0"
} }
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_1_8
@@ -22,10 +24,12 @@ repositories {
} }
configurations { configurations {
compile.extendsFrom shade implementation.extendsFrom shade
} }
dependencies { dependencies {
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
minecraft "com.mojang:minecraft:${mc_version}" minecraft "com.mojang:minecraft:${mc_version}"
mappings "net.fabricmc:yarn:${mc_version}+build.${mappings_version}:v2" mappings "net.fabricmc:yarn:${mc_version}+build.${mappings_version}:v2"
modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}" modImplementation "net.fabricmc:fabric-loader:${fabric_loader_version}"
@@ -37,7 +41,7 @@ dependencies {
modImplementation "io.github.prospector:modmenu:${modmenu_version}" modImplementation "io.github.prospector:modmenu:${modmenu_version}"
modImplementation "me.shedaniel.cloth.api:cloth-utils-v1:${cloth_api_version}" modImplementation "me.shedaniel.cloth.api:cloth-utils-v1:${cloth_api_version}"
compile 'com.electronwill.night-config:toml:3.6.3' implementation 'com.electronwill.night-config:toml:3.6.3'
implementation 'com.google.code.findbugs:jsr305:3.0.2' implementation 'com.google.code.findbugs:jsr305:3.0.2'
shade 'org.squiddev:Cobalt:0.5.2-SNAPSHOT' shade 'org.squiddev:Cobalt:0.5.2-SNAPSHOT'
@@ -85,6 +89,49 @@ jar {
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) } from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
} }
import com.hierynomus.gradle.license.tasks.LicenseCheck
import com.hierynomus.gradle.license.tasks.LicenseFormat
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 file('config/license/main.txt')
}
}
[licenseTest, licenseFormatTest].forEach {
it.configure {
include("**/*.java")
header 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 file('config/license/api.txt')
}
}
// configure the maven publication // configure the maven publication
publishing { publishing {
publications { publications {

View File

@@ -2488,4 +2488,4 @@
</option> </option>
</inspection_tool> </inspection_tool>
</profile> </profile>
</component> </component>

View File

@@ -58,4 +58,4 @@
<option name="CONTINUATION_INDENT_SIZE" value="4" /> <option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions> </indentOptions>
</codeStyleSettings> </codeStyleSettings>
</code_scheme> </code_scheme>

View File

@@ -0,0 +1,164 @@
<?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_loc}/suppressions.xml" />
</module>
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="render_old"/>
</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" />
<module name="MemberName" />
<module name="MethodName" />
<module name="MethodTypeParameterName" />
<module name="PackageName">
<property name="format" value="^dan200\.computercraft(\.[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,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>

View 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" />
<!-- The commands API is documented in Lua. -->
<suppress checks="SummaryJavadocCheck" files=".*[\\/]CommandAPI.java" />
</suppressions>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,61 @@
<code_scheme name="Project" version="173">
<JSON>
<option name="OBJECT_WRAPPING" value="1" />
<option name="ARRAY_WRAPPING" value="1" />
</JSON>
<JavaCodeStyleSettings>
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="JD_P_AT_EMPTY_LINES" value="false" />
<option name="JD_PRESERVE_LINE_FEEDS" value="true" />
</JavaCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="BRACE_STYLE" value="2" />
<option name="CLASS_BRACE_STYLE" value="2" />
<option name="METHOD_BRACE_STYLE" value="2" />
<option name="LAMBDA_BRACE_STYLE" value="5" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="SPACE_WITHIN_METHOD_CALL_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_METHOD_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_IF_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_WHILE_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_FOR_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_TRY_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_CATCH_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_SWITCH_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_SYNCHRONIZED_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true" />
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_TRY_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SYNCHRONIZED_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="SPACE_WITHIN_ANNOTATION_PARENTHESES" value="true" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JSON">
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="SPACE_WITHIN_BRACKETS" value="true" />
<option name="SPACE_WITHIN_BRACES" value="true" />
<indentOptions>
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme>

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

@@ -0,0 +1,3 @@
This file is part of the public ComputerCraft API - http://www.computercraft.info
Copyright Daniel Ratcliffe, 2011-${year}. This API may be redistributed unmodified and in full only.
For help using the API, and posting your mods, visit the forums at computercraft.info.

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

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

View File

@@ -0,0 +1,49 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-merge-conflict
# Quick syntax checkers
- id: check-xml
- id: check-yaml
- id: check-toml
- id: check-json
exclude: "tsconfig\\.json$"
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
rev: 2.3.5
hooks:
- id: editorconfig-checker
args: ['-disable-indentation']
exclude: "^(.*\\.(bat)|LICENSE)$"
- repo: local
hooks:
- id: checkstyle
name: Check Java codestyle
files: ".*\\.java$"
language: system
entry: ./gradlew checkstyleMain checkstyleTest
pass_filenames: false
require_serial: true
- id: license
name: Check Java license headers
files: ".*\\.java$"
language: system
entry: ./gradlew licenseFormat
pass_filenames: false
require_serial: true
exclude: |
(?x)^(
src/generated|
src/test/resources/test-rom/data/json-parsing/|
src/test/server-files/|
config/idea/|
.vscode/
)

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env sh
set -e
test -d bin || mkdir bin
test -f bin/illuaminate || curl -s -obin/illuaminate https://squiddev.cc/illuaminate/linux-x86-64/illuaminate
chmod +x bin/illuaminate
if [ -n ${GITHUB_ACTIONS+x} ]; then
# Register a problem matcher (see https://github.com/actions/toolkit/blob/master/docs/problem-matchers.md)
# for illuaminate.
echo "::add-matcher::.github/matchers/illuaminate.json"
trap 'echo "::remove-matcher owner=illuaminate::"' EXIT
fi
./gradlew luaJavadoc
bin/illuaminate lint

Binary file not shown.

View File

@@ -1,6 +1,5 @@
#Tue Jul 07 13:15:43 EDT 2020
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

53
gradlew vendored
View File

@@ -1,5 +1,21 @@
#!/usr/bin/env sh #!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
############################################################################## ##############################################################################
## ##
## Gradle start up script for UN*X ## Gradle start up script for UN*X
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS="" DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD="maximum"
@@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi fi
# For Cygwin, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if $cygwin ; then if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"` JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
@@ -138,19 +156,19 @@ if $cygwin ; then
else else
eval `echo args$i`="\"$arg\"" eval `echo args$i`="\"$arg\""
fi fi
i=$((i+1)) i=`expr $i + 1`
done done
case $i in case $i in
(0) set -- ;; 0) set -- ;;
(1) set -- "$args0" ;; 1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;; 2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;; 3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;; 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac esac
fi fi
@@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " " echo " "
} }
APP_ARGS=$(save "$@") APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules # Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@" exec "$JAVACMD" "$@"

43
gradlew.bat vendored
View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS= set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell

View File

@@ -9,7 +9,7 @@ SubScript // Desc of commit
``` ```
If a edit that is present in CC:T is not needed, I will skip over it. If a edit that is present in CC:T is not needed, I will skip over it.
Any and all references to an issue number, are to be found on CC:T's repo. Any and all references to an issue number, are to be found on CC:T's repo.
Any commit that starts with `[Patchwork]` are purely edits made by my hand, and not based on other commits from CC:T, this is to help differentiate my changes from the official changes Any commit that starts with `[Patchwork]` are purely edits made by my hand, and not based on other commits from CC:T, this is to help differentiate my changes from the official changes
@@ -138,9 +138,9 @@ evidently need to lint examples too.
Add color table to docs (#553) Add color table to docs (#553)
``` ```
All API Documentation updates, All API Documentation updates,
`Not Needed` for this repo. `Not Needed` for this repo.
``` ```
93068402a2ffec00eedb8fe2d859ebdc005a1989 93068402a2ffec00eedb8fe2d859ebdc005a1989
Document remaining OS functions (#554) Document remaining OS functions (#554)
@@ -148,7 +148,7 @@ Document remaining OS functions (#554)
Update illuaminate CSS for deprecation (#556) Update illuaminate CSS for deprecation (#556)
``` ```
``` ```
Not Needed Not Needed
4766833cf2d041ed179529eecb9402ad09b2b79b 4766833cf2d041ed179529eecb9402ad09b2b79b
Bump JEI/crafttweaker versions Bump JEI/crafttweaker versions
@@ -156,12 +156,12 @@ Bump JEI/crafttweaker versions
In my defence, they weren't out when I started the 1.15 update. In my defence, they weren't out when I started the 1.15 update.
``` ```
``` ```
bf6053906dc6a3c7b0d40d5b097e745dce1f33bc bf6053906dc6a3c7b0d40d5b097e745dce1f33bc
Fix TBO norm issues on old GPUs Fix TBO norm issues on old GPUs
``` ```
``` ```
Not Needed Not Needed
113b560a201dbdea9de2a2ef536bcce1d6e51978 113b560a201dbdea9de2a2ef536bcce1d6e51978
Update configuration to match latest illuaminate Update configuration to match latest illuaminate
@@ -201,7 +201,7 @@ to expose this.
Closes #452 Closes #452
``` ```
``` ```
Not Needed Not Needed
6aae4e576621090840724e094aa25e51696530fc 6aae4e576621090840724e094aa25e51696530fc
Remove superfluous imports Remove superfluous imports
@@ -210,7 +210,7 @@ Hah, this is embarassing
``` ```
[TODO] [M3R1-01] Code has been applied, players still dont get achievments [TODO] [M3R1-01] Code has been applied, players still dont get achievments
``` ```
f6160bdc57b3d9850607c2c7c2ce9734b4963478 f6160bdc57b3d9850607c2c7c2ce9734b4963478
Fix players not getting advancements when they own turtles Fix players not getting advancements when they own turtles
@@ -228,7 +228,7 @@ resolve this properly.
Fixes #564 Fixes #564
``` ```
``` ```
17a932920711a5c0361a5048c9e0a5e7a58e6364 17a932920711a5c0361a5048c9e0a5e7a58e6364
Bump cct-javadoc version Bump cct-javadoc version
@@ -245,7 +245,7 @@ Tesselator, but this'll do for now.
Fixes Zundrel/cc-tweaked-fabric#20. Fixes Zundrel/cc-tweaked-fabric#20.
``` ```
``` ```
c58441b29c3715f092e7f3747bb3ec65ae5a3d29 c58441b29c3715f092e7f3747bb3ec65ae5a3d29
Various SNBT parsing improvements Various SNBT parsing improvements
@@ -257,7 +257,7 @@ Correctly handle:
Fixes #559 Fixes #559
``` ```
``` ```
e2a635b6e5f5942f999213434054e06833c5cb06 e2a635b6e5f5942f999213434054e06833c5cb06
Dont fail when codecov is being finicky Dont fail when codecov is being finicky
``` ```
@@ -270,13 +270,13 @@ Maybe I should run the whole test suite, not just the things I think
matter? Nah.... matter? Nah....
``` ```
``` ```
741adfa7bb2b950d2851c3f0072d6a4769f22773 741adfa7bb2b950d2851c3f0072d6a4769f22773
Use blit to draw boxes, add colors.toBlit (#570) Use blit to draw boxes, add colors.toBlit (#570)
``` ```
``` ```
d13bd2cce8d102ad7f61f557e707d6fe3731bc37 d13bd2cce8d102ad7f61f557e707d6fe3731bc37
use arg[0] in all usage printouts (#571) use arg[0] in all usage printouts (#571)
@@ -289,7 +289,7 @@ Bump to 1.94.0
``` ```
[TODO] [M3R1-02] Zero Clue how to reimplement this in fabric. [TODO] [M3R1-02] Zero Clue how to reimplement this in fabric.
``` ```
c8aeddedd4ed430f9cb6428676ebb4fa39834182 c8aeddedd4ed430f9cb6428676ebb4fa39834182
Auto-generate monitor models Auto-generate monitor models
@@ -399,7 +399,7 @@ Hopefully fixes #585. Hopefully.
``` ```
511eea39a11956c82e2c11a47b2e7cad27f9887e 511eea39a11956c82e2c11a47b2e7cad27f9887e
Remove <!-- -->s in usages Remove <!-- -->s in usages
``` ```
``` ```
@@ -426,7 +426,7 @@ Didn't port the lua tests over.
``` ```
737b3cb57696fb5517252e7db38bc88ce960b4d8 737b3cb57696fb5517252e7db38bc88ce960b4d8
Don't use capabilities for generic peripherals Don't use capabilities for generic peripherals
``` ```
Not ported, related to forges capability system which is not used in the port. Not ported, related to forges capability system which is not used in the port.

View File

@@ -6,15 +6,6 @@
package dan200.computercraft; package dan200.computercraft;
import static dan200.computercraft.shared.ComputerCraftRegistry.ModBlocks;
import static dan200.computercraft.shared.ComputerCraftRegistry.init;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.TimeUnit;
import dan200.computercraft.api.turtle.event.TurtleAction; import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.http.options.Action; import dan200.computercraft.core.apis.http.options.Action;
import dan200.computercraft.core.apis.http.options.AddressRule; import dan200.computercraft.core.apis.http.options.AddressRule;
@@ -32,22 +23,31 @@ import dan200.computercraft.shared.pocket.recipes.PocketComputerUpgradeRecipe;
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon; import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
import dan200.computercraft.shared.turtle.recipes.TurtleRecipe; import dan200.computercraft.shared.turtle.recipes.TurtleRecipe;
import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe; import dan200.computercraft.shared.turtle.recipes.TurtleUpgradeRecipe;
import dan200.computercraft.shared.util.*; import dan200.computercraft.shared.util.ImpostorRecipe;
import org.apache.logging.log4j.LogManager; import dan200.computercraft.shared.util.ImpostorShapelessRecipe;
import org.apache.logging.log4j.Logger;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder; import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.ResourcePackActivationType; import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public final class ComputerCraft implements ModInitializer { import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static dan200.computercraft.shared.ComputerCraftRegistry.ModBlocks;
import static dan200.computercraft.shared.ComputerCraftRegistry.init;
public final class ComputerCraft implements ModInitializer
{
public static final String MOD_ID = "computercraft"; public static final String MOD_ID = "computercraft";
// Configuration fields // Configuration fields
@@ -61,16 +61,15 @@ public final class ComputerCraft implements ModInitializer {
public static boolean commandRequireCreative = true; public static boolean commandRequireCreative = true;
public static int computerThreads = 1; public static int computerThreads = 1;
public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos(10); public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos( 10 );
public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos(5); public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos( 5 );
public static boolean httpEnabled = true; public static boolean httpEnabled = true;
public static boolean httpWebsocketEnabled = true; public static boolean httpWebsocketEnabled = true;
public static List<AddressRule> httpRules = Collections.unmodifiableList( Arrays.asList( public static List<AddressRule> httpRules = Collections.unmodifiableList( Arrays.asList(
AddressRule.parse( "$private", null, Action.DENY.toPartial() ), AddressRule.parse( "$private", null, Action.DENY.toPartial() ),
AddressRule.parse( "*", null, Action.ALLOW.toPartial() ) AddressRule.parse( "*", null, Action.ALLOW.toPartial() )
)); ) );
public static int httpMaxRequests = 16; public static int httpMaxRequests = 16;
public static int httpMaxWebsockets = 4; public static int httpMaxWebsockets = 4;
@@ -89,7 +88,7 @@ public final class ComputerCraft implements ModInitializer {
public static int advancedTurtleFuelLimit = 100000; public static int advancedTurtleFuelLimit = 100000;
public static boolean turtlesObeyBlockProtection = true; public static boolean turtlesObeyBlockProtection = true;
public static boolean turtlesCanPush = true; public static boolean turtlesCanPush = true;
public static EnumSet<TurtleAction> turtleDisabledActions = EnumSet.noneOf(TurtleAction.class); public static EnumSet<TurtleAction> turtleDisabledActions = EnumSet.noneOf( TurtleAction.class );
public static int computerTermWidth = 51; public static int computerTermWidth = 51;
public static int computerTermHeight = 19; public static int computerTermHeight = 19;
@@ -99,7 +98,6 @@ public final class ComputerCraft implements ModInitializer {
public static int pocketTermWidth = 26; public static int pocketTermWidth = 26;
public static int pocketTermHeight = 20; public static int pocketTermHeight = 20;
public static int monitorWidth = 8; public static int monitorWidth = 8;
public static int monitorHeight = 6; public static int monitorHeight = 6;
@@ -108,30 +106,32 @@ public final class ComputerCraft implements ModInitializer {
public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry(); public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();
// Logging // Logging
public static final Logger log = LogManager.getLogger(MOD_ID); public static final Logger log = LogManager.getLogger( MOD_ID );
public static ItemGroup MAIN_GROUP = FabricItemGroupBuilder.build(new Identifier(MOD_ID, "main"), () -> new ItemStack(ModBlocks.COMPUTER_NORMAL)); public static ItemGroup MAIN_GROUP = FabricItemGroupBuilder.build( new Identifier( MOD_ID, "main" ), () -> new ItemStack( ModBlocks.COMPUTER_NORMAL ) );
@Override @Override
public void onInitialize() { public void onInitialize()
{
ComputerCraftProxyCommon.init(); ComputerCraftProxyCommon.init();
Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "colour" ), ColourableRecipe.SERIALIZER );
Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "colour"), ColourableRecipe.SERIALIZER); Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "computer_upgrade" ), ComputerUpgradeRecipe.SERIALIZER );
Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "computer_upgrade"), ComputerUpgradeRecipe.SERIALIZER); Registry.register( Registry.RECIPE_SERIALIZER,
Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "pocket_computer_upgrade"), PocketComputerUpgradeRecipe.SERIALIZER); new Identifier( ComputerCraft.MOD_ID, "pocket_computer_upgrade" ),
Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "disk"), DiskRecipe.SERIALIZER); PocketComputerUpgradeRecipe.SERIALIZER );
Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "printout"), PrintoutRecipe.SERIALIZER); Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "disk" ), DiskRecipe.SERIALIZER );
Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "turtle"), TurtleRecipe.SERIALIZER); Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "printout" ), PrintoutRecipe.SERIALIZER );
Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "turtle_upgrade"), TurtleUpgradeRecipe.SERIALIZER); Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "turtle" ), TurtleRecipe.SERIALIZER );
Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "impostor_shaped"), ImpostorRecipe.SERIALIZER); Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "turtle_upgrade" ), TurtleUpgradeRecipe.SERIALIZER );
Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(ComputerCraft.MOD_ID, "impostor_shapeless"), ImpostorShapelessRecipe.SERIALIZER); Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "impostor_shaped" ), ImpostorRecipe.SERIALIZER );
Registry.register(Registry.LOOT_CONDITION_TYPE, new Identifier(ComputerCraft.MOD_ID, "block_named"), BlockNamedEntityLootCondition.TYPE); Registry.register( Registry.RECIPE_SERIALIZER, new Identifier( ComputerCraft.MOD_ID, "impostor_shapeless" ), ImpostorShapelessRecipe.SERIALIZER );
Registry.register(Registry.LOOT_CONDITION_TYPE, new Identifier(ComputerCraft.MOD_ID, "player_creative"), PlayerCreativeLootCondition.TYPE); Registry.register( Registry.LOOT_CONDITION_TYPE, new Identifier( ComputerCraft.MOD_ID, "block_named" ), BlockNamedEntityLootCondition.TYPE );
Registry.register(Registry.LOOT_CONDITION_TYPE, new Identifier(ComputerCraft.MOD_ID, "has_id"), HasComputerIdLootCondition.TYPE); Registry.register( Registry.LOOT_CONDITION_TYPE, new Identifier( ComputerCraft.MOD_ID, "player_creative" ), PlayerCreativeLootCondition.TYPE );
Registry.register( Registry.LOOT_CONDITION_TYPE, new Identifier( ComputerCraft.MOD_ID, "has_id" ), HasComputerIdLootCondition.TYPE );
init(); init();
FabricLoader.getInstance().getModContainer(MOD_ID).ifPresent(modContainer -> { FabricLoader.getInstance().getModContainer( MOD_ID ).ifPresent( modContainer -> {
ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MOD_ID, "classic"), modContainer, ResourcePackActivationType.NORMAL); ResourceManagerHelper.registerBuiltinResourcePack( new Identifier( MOD_ID, "classic" ), modContainer, ResourcePackActivationType.NORMAL );
ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MOD_ID, "overhaul"), modContainer, ResourcePackActivationType.NORMAL); ResourceManagerHelper.registerBuiltinResourcePack( new Identifier( MOD_ID, "overhaul" ), modContainer, ResourcePackActivationType.NORMAL );
}); } );
} }
} }

View File

@@ -6,13 +6,6 @@
package dan200.computercraft; package dan200.computercraft;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.api.ComputerCraftAPI.IComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI.IComputerCraftAPI;
import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount; import dan200.computercraft.api.filesystem.IWritableMount;
@@ -31,18 +24,14 @@ import dan200.computercraft.core.asm.GenericMethod;
import dan200.computercraft.core.filesystem.FileMount; import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.core.filesystem.ResourceMount; import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.fabric.mixin.MinecraftServerAccess; import dan200.computercraft.fabric.mixin.MinecraftServerAccess;
import dan200.computercraft.shared.BundledRedstone; import dan200.computercraft.shared.*;
import dan200.computercraft.shared.MediaProviders;
import dan200.computercraft.shared.Peripherals;
import dan200.computercraft.shared.PocketUpgrades;
import dan200.computercraft.shared.TurtleUpgrades;
import dan200.computercraft.shared.peripheral.modem.wired.TileCable; import dan200.computercraft.shared.peripheral.modem.wired.TileCable;
import dan200.computercraft.shared.peripheral.modem.wired.TileWiredModemFull; import dan200.computercraft.shared.peripheral.modem.wired.TileWiredModemFull;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork; import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.util.IDAssigner; import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.wired.WiredNode; import dan200.computercraft.shared.wired.WiredNode;
import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils; import me.shedaniel.cloth.api.utils.v1.GameInstanceUtils;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.resource.ReloadableResourceManager; import net.minecraft.resource.ReloadableResourceManager;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
@@ -52,24 +41,35 @@ import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.fabricmc.loader.api.FabricLoader; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public final class ComputerCraftAPIImpl implements IComputerCraftAPI { public final class ComputerCraftAPIImpl implements IComputerCraftAPI
{
public static final ComputerCraftAPIImpl INSTANCE = new ComputerCraftAPIImpl(); public static final ComputerCraftAPIImpl INSTANCE = new ComputerCraftAPIImpl();
private String version; private String version;
private ComputerCraftAPIImpl() { private ComputerCraftAPIImpl()
{
} }
public static InputStream getResourceFile(String domain, String subPath) { public static InputStream getResourceFile( String domain, String subPath )
{
MinecraftServer server = GameInstanceUtils.getServer(); MinecraftServer server = GameInstanceUtils.getServer();
if (server != null) { if( server != null )
ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServerAccess)server).getServerResourceManager().getResourceManager(); {
try { ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServerAccess) server).getServerResourceManager().getResourceManager();
return manager.getResource(new Identifier(domain, subPath)) try
.getInputStream(); {
} catch (IOException ignored) { return manager.getResource( new Identifier( domain, subPath ) )
.getInputStream();
}
catch( IOException ignored )
{
return null; return null;
} }
} }
@@ -78,71 +78,86 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI {
@Nonnull @Nonnull
@Override @Override
public String getInstalledVersion() { public String getInstalledVersion()
if (this.version != null) { {
if( this.version != null )
{
return this.version; return this.version;
} }
return this.version = FabricLoader.getInstance() return this.version = FabricLoader.getInstance()
.getModContainer(ComputerCraft.MOD_ID) .getModContainer( ComputerCraft.MOD_ID )
.map(x -> x.getMetadata() .map( x -> x.getMetadata()
.getVersion() .getVersion()
.toString()) .toString() )
.orElse("unknown"); .orElse( "unknown" );
} }
@Override @Override
public int createUniqueNumberedSaveDir(@Nonnull World world, @Nonnull String parentSubPath) { public int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath )
return IDAssigner.getNextId(parentSubPath); {
return IDAssigner.getNextId( parentSubPath );
} }
@Override @Override
public IWritableMount createSaveDirMount(@Nonnull World world, @Nonnull String subPath, long capacity) { public IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity )
try { {
return new FileMount(new File(IDAssigner.getDir(), subPath), capacity); try
} catch (Exception e) { {
return new FileMount( new File( IDAssigner.getDir(), subPath ), capacity );
}
catch( Exception e )
{
return null; return null;
} }
} }
@Override @Override
public IMount createResourceMount(@Nonnull String domain, @Nonnull String subPath) { public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
{
MinecraftServer server = GameInstanceUtils.getServer(); MinecraftServer server = GameInstanceUtils.getServer();
if (server != null) { if( server != null )
ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServerAccess)server).getServerResourceManager().getResourceManager(); {
ResourceMount mount = ResourceMount.get(domain, subPath, manager); ReloadableResourceManager manager = (ReloadableResourceManager) ((MinecraftServerAccess) server).getServerResourceManager().getResourceManager();
return mount.exists("") ? mount : null; ResourceMount mount = ResourceMount.get( domain, subPath, manager );
return mount.exists( "" ) ? mount : null;
} }
return null; return null;
} }
@Override @Override
public void registerPeripheralProvider(@Nonnull IPeripheralProvider provider) { public void registerPeripheralProvider( @Nonnull IPeripheralProvider provider )
Peripherals.register(provider); {
Peripherals.register( provider );
} }
@Override @Override
public void registerTurtleUpgrade(@Nonnull ITurtleUpgrade upgrade) { public void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade )
TurtleUpgrades.register(upgrade); {
TurtleUpgrades.register( upgrade );
} }
@Override @Override
public void registerBundledRedstoneProvider(@Nonnull IBundledRedstoneProvider provider) { public void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider )
BundledRedstone.register(provider); {
BundledRedstone.register( provider );
} }
@Override @Override
public int getBundledRedstoneOutput(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side) { public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
return BundledRedstone.getDefaultOutput(world, pos, side); {
return BundledRedstone.getDefaultOutput( world, pos, side );
} }
@Override @Override
public void registerMediaProvider(@Nonnull IMediaProvider provider) { public void registerMediaProvider( @Nonnull IMediaProvider provider )
MediaProviders.register(provider); {
MediaProviders.register( provider );
} }
@Override @Override
public void registerPocketUpgrade(@Nonnull IPocketUpgrade upgrade) { public void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade )
PocketUpgrades.register(upgrade); {
PocketUpgrades.register( upgrade );
} }
@Override @Override
@@ -153,28 +168,35 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI {
@Nonnull @Nonnull
@Override @Override
public IPacketNetwork getWirelessNetwork() { public IPacketNetwork getWirelessNetwork()
{
return WirelessNetwork.getUniversal(); return WirelessNetwork.getUniversal();
} }
@Override @Override
public void registerAPIFactory(@Nonnull ILuaAPIFactory factory) { public void registerAPIFactory( @Nonnull ILuaAPIFactory factory )
ApiFactories.register(factory); {
ApiFactories.register( factory );
} }
@Nonnull @Nonnull
@Override @Override
public IWiredNode createWiredNodeForElement(@Nonnull IWiredElement element) { public IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element )
return new WiredNode(element); {
return new WiredNode( element );
} }
@Nullable @Nullable
@Override @Override
public IWiredElement getWiredElementAt(@Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side) { public IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side )
BlockEntity tile = world.getBlockEntity(pos); {
if (tile instanceof TileCable) { BlockEntity tile = world.getBlockEntity( pos );
return ((TileCable) tile).getElement(side); if( tile instanceof TileCable )
} else if (tile instanceof TileWiredModemFull) { {
return ((TileCable) tile).getElement( side );
}
else if( tile instanceof TileWiredModemFull )
{
return ((TileWiredModemFull) tile).getElement(); return ((TileWiredModemFull) tile).getElement();
} }
return null; return null;

View File

@@ -6,9 +6,6 @@
package dan200.computercraft.api; package dan200.computercraft.api;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount; import dan200.computercraft.api.filesystem.IWritableMount;
import dan200.computercraft.api.lua.GenericSource; import dan200.computercraft.api.lua.GenericSource;
@@ -24,43 +21,53 @@ import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider; import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* The static entry point to the ComputerCraft API. * 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 { public final class ComputerCraftAPI
{
private static IComputerCraftAPI instance; private static IComputerCraftAPI instance;
@Nonnull @Nonnull
@Deprecated @Deprecated
public static String getAPIVersion() { public static String getAPIVersion()
{
return getInstalledVersion(); return getInstalledVersion();
} }
@Nonnull @Nonnull
public static String getInstalledVersion() { public static String getInstalledVersion()
{
return getInstance().getInstalledVersion(); return getInstance().getInstalledVersion();
} }
@Nonnull @Nonnull
private static IComputerCraftAPI getInstance() { private static IComputerCraftAPI getInstance()
if (instance != null) { {
if( instance != null )
{
return instance; return instance;
} }
try { try
return instance = (IComputerCraftAPI) Class.forName("dan200.computercraft.ComputerCraftAPIImpl") {
.getField("INSTANCE") return instance = (IComputerCraftAPI) Class.forName( "dan200.computercraft.ComputerCraftAPIImpl" )
.get(null); .getField( "INSTANCE" )
} catch (ReflectiveOperationException e) { .get( null );
throw new IllegalStateException("Cannot find ComputerCraft API", e); }
catch( ReflectiveOperationException e )
{
throw new IllegalStateException( "Cannot find ComputerCraft API", e );
} }
} }
@@ -69,15 +76,16 @@ public final class ComputerCraftAPI {
* *
* Use in conjunction with createSaveDirMount() to create a unique place for your peripherals or media items to store files. * Use in conjunction with createSaveDirMount() to create a unique place for your peripherals or media items to store files.
* *
* @param world The world for which the save dir should be created. This should be the server side world object. * @param world The world for which the save dir should be created. This should be the server side world object.
* @param parentSubPath The folder path within the save directory where the new directory should be created. eg: "computercraft/disk" * @param parentSubPath The folder path within the save directory where the new directory should be created. eg: "computercraft/disk"
* @return The numerical value of the name of the new folder, or -1 if the folder could not be created for some reason. * @return The numerical value of the name of the new folder, or -1 if the folder could not be created for some reason.
* *
* eg: if createUniqueNumberedSaveDir( world, "computer/disk" ) was called returns 42, then "computer/disk/42" is now available for writing. * eg: if createUniqueNumberedSaveDir( world, "computer/disk" ) was called returns 42, then "computer/disk/42" is now available for writing.
* @see #createSaveDirMount(World, String, long) * @see #createSaveDirMount(World, String, long)
*/ */
public static int createUniqueNumberedSaveDir(@Nonnull World world, @Nonnull String parentSubPath) { public static int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath )
return getInstance().createUniqueNumberedSaveDir(world, parentSubPath); {
return getInstance().createUniqueNumberedSaveDir( world, parentSubPath );
} }
/** /**
@@ -86,12 +94,12 @@ public final class ComputerCraftAPI {
* Use in conjunction with IComputerAccess.mount() or IComputerAccess.mountWritable() to mount a folder from the users save directory onto a computers * Use in conjunction with IComputerAccess.mount() or IComputerAccess.mountWritable() to mount a folder from the users save directory onto a computers
* file system. * file system.
* *
* @param world The world for which the save dir can be found. This should be the server side world object. * @param world The world for which the save dir can be found. This should be the server side world object.
* @param subPath The folder path within the save directory that the mount should map to. eg: "computer/disk/42". Use createUniqueNumberedSaveDir() * @param subPath The folder path within the save directory that the mount should map to. eg: "computer/disk/42". Use createUniqueNumberedSaveDir()
* to create a new numbered folder to use. * to create a new numbered folder to use.
* @param capacity The amount of data that can be stored in the directory before it fills up, in bytes. * @param capacity The amount of data that can be stored in the directory before it fills up, in bytes.
* @return The mount, or null if it could be created for some reason. Use IComputerAccess.mount() or IComputerAccess.mountWritable() to mount this on a * @return The mount, or null if it could be created for some reason. Use IComputerAccess.mount() or IComputerAccess.mountWritable() to mount this on a
* Computers' file system. * Computers' file system.
* @see #createUniqueNumberedSaveDir(World, String) * @see #createUniqueNumberedSaveDir(World, String)
* @see IComputerAccess#mount(String, IMount) * @see IComputerAccess#mount(String, IMount)
* @see IComputerAccess#mountWritable(String, IWritableMount) * @see IComputerAccess#mountWritable(String, IWritableMount)
@@ -99,8 +107,9 @@ public final class ComputerCraftAPI {
* @see IWritableMount * @see IWritableMount
*/ */
@Nullable @Nullable
public static IWritableMount createSaveDirMount(@Nonnull World world, @Nonnull String subPath, long capacity) { public static IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity )
return getInstance().createSaveDirMount(world, subPath, capacity); {
return getInstance().createSaveDirMount( world, subPath, capacity );
} }
/** /**
@@ -114,7 +123,7 @@ public final class ComputerCraftAPI {
* "/data/computercraft/lua/rom". We construct a mount for that with * "/data/computercraft/lua/rom". We construct a mount for that with
* {@code createResourceMount("computercraft", "lua/rom")}. * {@code createResourceMount("computercraft", "lua/rom")}.
* *
* @param domain The domain under which to look for resources. eg: "mymod". * @param domain The domain under which to look for resources. eg: "mymod".
* @param subPath The subPath under which to look for resources. eg: "lua/myfiles". * @param subPath The subPath under which to look for resources. eg: "lua/myfiles".
* @return The mount, or {@code null} if it could be created for some reason. * @return The mount, or {@code null} if it could be created for some reason.
* @see IComputerAccess#mount(String, IMount) * @see IComputerAccess#mount(String, IMount)
@@ -122,8 +131,9 @@ public final class ComputerCraftAPI {
* @see IMount * @see IMount
*/ */
@Nullable @Nullable
public static IMount createResourceMount(@Nonnull String domain, @Nonnull String subPath) { public static IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
return getInstance().createResourceMount(domain, subPath); {
return getInstance().createResourceMount( domain, subPath );
} }
/** /**
@@ -133,8 +143,9 @@ public final class ComputerCraftAPI {
* @see IPeripheral * @see IPeripheral
* @see IPeripheralProvider * @see IPeripheralProvider
*/ */
public static void registerPeripheralProvider(@Nonnull IPeripheralProvider provider) { public static void registerPeripheralProvider( @Nonnull IPeripheralProvider provider )
getInstance().registerPeripheralProvider(provider); {
getInstance().registerPeripheralProvider( provider );
} }
/** /**
@@ -155,8 +166,9 @@ public final class ComputerCraftAPI {
* @param upgrade The turtle upgrade to register. * @param upgrade The turtle upgrade to register.
* @see ITurtleUpgrade * @see ITurtleUpgrade
*/ */
public static void registerTurtleUpgrade(@Nonnull ITurtleUpgrade upgrade) { public static void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade )
getInstance().registerTurtleUpgrade(upgrade); {
getInstance().registerTurtleUpgrade( upgrade );
} }
/** /**
@@ -165,22 +177,24 @@ public final class ComputerCraftAPI {
* @param provider The bundled redstone provider to register. * @param provider The bundled redstone provider to register.
* @see IBundledRedstoneProvider * @see IBundledRedstoneProvider
*/ */
public static void registerBundledRedstoneProvider(@Nonnull IBundledRedstoneProvider provider) { public static void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider )
getInstance().registerBundledRedstoneProvider(provider); {
getInstance().registerBundledRedstoneProvider( provider );
} }
/** /**
* If there is a Computer or Turtle at a certain position in the world, get it's bundled redstone output. * If there is a Computer or Turtle at a certain position in the world, get it's bundled redstone output.
* *
* @param world The world this block is in. * @param world The world this block is in.
* @param pos The position this block is at. * @param pos The position this block is at.
* @param side The side to extract the bundled redstone output from. * @param side The side to extract the bundled redstone output from.
* @return If there is a block capable of emitting bundled redstone at the location, it's signal (0-65535) will be returned. If there is no block * @return If there is a block capable of emitting bundled redstone at the location, it's signal (0-65535) will be returned. If there is no block
* capable of emitting bundled redstone at the location, -1 will be returned. * capable of emitting bundled redstone at the location, -1 will be returned.
* @see IBundledRedstoneProvider * @see IBundledRedstoneProvider
*/ */
public static int getBundledRedstoneOutput(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side) { public static int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
return getInstance().getBundledRedstoneOutput(world, pos, side); {
return getInstance().getBundledRedstoneOutput( world, pos, side );
} }
/** /**
@@ -189,12 +203,14 @@ public final class ComputerCraftAPI {
* @param provider The media provider to register. * @param provider The media provider to register.
* @see IMediaProvider * @see IMediaProvider
*/ */
public static void registerMediaProvider(@Nonnull IMediaProvider provider) { public static void registerMediaProvider( @Nonnull IMediaProvider provider )
getInstance().registerMediaProvider(provider); {
getInstance().registerMediaProvider( provider );
} }
public static void registerPocketUpgrade(@Nonnull IPocketUpgrade upgrade) { public static void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade )
getInstance().registerPocketUpgrade(upgrade); {
getInstance().registerPocketUpgrade( upgrade );
} }
/** /**
@@ -202,12 +218,14 @@ public final class ComputerCraftAPI {
* *
* @return The global wireless network, or {@code null} if it could not be fetched. * @return The global wireless network, or {@code null} if it could not be fetched.
*/ */
public static IPacketNetwork getWirelessNetwork() { public static IPacketNetwork getWirelessNetwork()
{
return getInstance().getWirelessNetwork(); return getInstance().getWirelessNetwork();
} }
public static void registerAPIFactory(@Nonnull ILuaAPIFactory factory) { public static void registerAPIFactory( @Nonnull ILuaAPIFactory factory )
getInstance().registerAPIFactory(factory); {
getInstance().registerAPIFactory( factory );
} }
/** /**
@@ -218,59 +236,62 @@ public final class ComputerCraftAPI {
* @see IWiredElement#getNode() * @see IWiredElement#getNode()
*/ */
@Nonnull @Nonnull
public static IWiredNode createWiredNodeForElement(@Nonnull IWiredElement element) { public static IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element )
return getInstance().createWiredNodeForElement(element); {
return getInstance().createWiredNodeForElement( element );
} }
/** /**
* 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 world The world the block exists in
* @param pos The position the block exists in * @param pos The position the block exists in
* @param side The side to extract the network element from * @param side The side to extract the network element from
* @return The element's node * @return The element's node
* @see IWiredElement#getNode() * @see IWiredElement#getNode()
*/ */
@Nullable @Nullable
public static IWiredElement getWiredElementAt(@Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side) { public static IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side )
return getInstance().getWiredElementAt(world, pos, side); {
return getInstance().getWiredElementAt( world, pos, side );
} }
public interface IComputerCraftAPI { public interface IComputerCraftAPI
{
@Nonnull @Nonnull
String getInstalledVersion(); String getInstalledVersion();
int createUniqueNumberedSaveDir(@Nonnull World world, @Nonnull String parentSubPath); int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath );
@Nullable @Nullable
IWritableMount createSaveDirMount(@Nonnull World world, @Nonnull String subPath, long capacity); IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity );
@Nullable @Nullable
IMount createResourceMount(@Nonnull String domain, @Nonnull String subPath); IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath );
void registerPeripheralProvider(@Nonnull IPeripheralProvider provider); void registerPeripheralProvider( @Nonnull IPeripheralProvider provider );
void registerGenericSource( @Nonnull GenericSource source ); void registerGenericSource( @Nonnull GenericSource source );
void registerTurtleUpgrade(@Nonnull ITurtleUpgrade upgrade); void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade );
void registerBundledRedstoneProvider(@Nonnull IBundledRedstoneProvider provider); void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider );
int getBundledRedstoneOutput(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side); int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
void registerMediaProvider(@Nonnull IMediaProvider provider); void registerMediaProvider( @Nonnull IMediaProvider provider );
void registerPocketUpgrade(@Nonnull IPocketUpgrade upgrade); void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade );
@Nonnull @Nonnull
IPacketNetwork getWirelessNetwork(); IPacketNetwork getWirelessNetwork();
void registerAPIFactory(@Nonnull ILuaAPIFactory factory); void registerAPIFactory( @Nonnull ILuaAPIFactory factory );
@Nonnull @Nonnull
IWiredNode createWiredNodeForElement(@Nonnull IWiredElement element); IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element );
@Nullable @Nullable
IWiredElement getWiredElementAt(@Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side); IWiredElement getWiredElementAt( @Nonnull BlockView world, @Nonnull BlockPos pos, @Nonnull Direction side );
} }
} }

View File

@@ -6,12 +6,9 @@
package dan200.computercraft.api.client; package dan200.computercraft.api.client;
import java.util.Objects;
import javax.annotation.Nonnull;
import dan200.computercraft.fabric.mixin.AffineTransformationAccess; import dan200.computercraft.fabric.mixin.AffineTransformationAccess;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.BakedModelManager; import net.minecraft.client.render.model.BakedModelManager;
@@ -20,64 +17,78 @@ import net.minecraft.client.util.math.AffineTransformation;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.fabricmc.api.EnvType; import javax.annotation.Nonnull;
import net.fabricmc.api.Environment; import java.util.Objects;
/** /**
* A model to render, combined with a transformation matrix to apply. * A model to render, combined with a transformation matrix to apply.
*/ */
@Environment (EnvType.CLIENT) @Environment( EnvType.CLIENT )
public final class TransformedModel { public final class TransformedModel
{
private final BakedModel model; private final BakedModel model;
private final AffineTransformation matrix; private final AffineTransformation matrix;
public TransformedModel(@Nonnull BakedModel model, @Nonnull AffineTransformation matrix) { public TransformedModel( @Nonnull BakedModel model, @Nonnull AffineTransformation matrix )
this.model = Objects.requireNonNull(model); {
this.matrix = Objects.requireNonNull(matrix); this.model = Objects.requireNonNull( model );
this.matrix = Objects.requireNonNull( matrix );
} }
public TransformedModel(@Nonnull BakedModel model) { public TransformedModel( @Nonnull BakedModel model )
this.model = Objects.requireNonNull(model); {
this.model = Objects.requireNonNull( model );
this.matrix = AffineTransformation.identity(); this.matrix = AffineTransformation.identity();
} }
public static TransformedModel of(@Nonnull ModelIdentifier location) { public static TransformedModel of( @Nonnull ModelIdentifier location )
{
BakedModelManager modelManager = MinecraftClient.getInstance() BakedModelManager modelManager = MinecraftClient.getInstance()
.getBakedModelManager(); .getBakedModelManager();
return new TransformedModel(modelManager.getModel(location)); return new TransformedModel( modelManager.getModel( location ) );
} }
public static TransformedModel of(@Nonnull ItemStack item, @Nonnull AffineTransformation transform) { public static TransformedModel of( @Nonnull ItemStack item, @Nonnull AffineTransformation transform )
{
BakedModel model = MinecraftClient.getInstance() BakedModel model = MinecraftClient.getInstance()
.getItemRenderer() .getItemRenderer()
.getModels() .getModels()
.getModel(item); .getModel( item );
return new TransformedModel(model, transform); return new TransformedModel( model, transform );
} }
@Nonnull @Nonnull
public BakedModel getModel() { public BakedModel getModel()
{
return this.model; return this.model;
} }
@Nonnull @Nonnull
public AffineTransformation getMatrix() { public AffineTransformation getMatrix()
{
return this.matrix; return this.matrix;
} }
public void push(MatrixStack matrixStack) { public void push( MatrixStack matrixStack )
{
matrixStack.push(); matrixStack.push();
AffineTransformationAccess access = (AffineTransformationAccess) (Object) this.matrix; AffineTransformationAccess access = (AffineTransformationAccess) (Object) this.matrix;
if (access.getTranslation() != null) if( access.getTranslation() != null )
matrixStack.translate(access.getTranslation().getX(), access.getTranslation().getY(), access.getTranslation().getZ()); {
matrixStack.translate( access.getTranslation().getX(), access.getTranslation().getY(), access.getTranslation().getZ() );
}
matrixStack.multiply(this.matrix.getRotation2()); matrixStack.multiply( this.matrix.getRotation2() );
if (access.getScale() != null) if( access.getScale() != null )
matrixStack.scale(access.getScale().getX(), access.getScale().getY(), access.getScale().getZ()); {
matrixStack.scale( access.getScale().getX(), access.getScale().getY(), access.getScale().getZ() );
}
if (access.getRotation1() != null) if( access.getRotation1() != null )
matrixStack.multiply(access.getRotation1()); {
matrixStack.multiply( access.getRotation1() );
}
} }
} }

View File

@@ -13,59 +13,70 @@ import java.time.Instant;
/** /**
* A simple version of {@link BasicFileAttributes}, which provides what information a {@link IMount} already exposes. * A simple version of {@link BasicFileAttributes}, which provides what information a {@link IMount} already exposes.
*/ */
final class FileAttributes implements BasicFileAttributes { final class FileAttributes implements BasicFileAttributes
private static final FileTime EPOCH = FileTime.from(Instant.EPOCH); {
private static final FileTime EPOCH = FileTime.from( Instant.EPOCH );
private final boolean isDirectory; private final boolean isDirectory;
private final long size; private final long size;
FileAttributes(boolean isDirectory, long size) { FileAttributes( boolean isDirectory, long size )
{
this.isDirectory = isDirectory; this.isDirectory = isDirectory;
this.size = size; this.size = size;
} }
@Override @Override
public FileTime lastModifiedTime() { public FileTime lastModifiedTime()
{
return EPOCH; return EPOCH;
} }
@Override @Override
public FileTime lastAccessTime() { public FileTime lastAccessTime()
{
return EPOCH; return EPOCH;
} }
@Override @Override
public FileTime creationTime() { public FileTime creationTime()
{
return EPOCH; return EPOCH;
} }
@Override @Override
public boolean isRegularFile() { public boolean isRegularFile()
{
return !this.isDirectory; return !this.isDirectory;
} }
@Override @Override
public boolean isDirectory() { public boolean isDirectory()
{
return this.isDirectory; return this.isDirectory;
} }
@Override @Override
public boolean isSymbolicLink() { public boolean isSymbolicLink()
{
return false; return false;
} }
@Override @Override
public boolean isOther() { public boolean isOther()
{
return false; return false;
} }
@Override @Override
public long size() { public long size()
{
return this.size; return this.size;
} }
@Override @Override
public Object fileKey() { public Object fileKey()
{
return null; return null;
} }
} }

View File

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

View File

@@ -13,31 +13,32 @@ import java.io.IOException;
* *
* This exists for use by various APIs - one should not attempt to mount it. * This exists for use by various APIs - one should not attempt to mount it.
*/ */
public interface IFileSystem extends IWritableMount { public interface IFileSystem extends IWritableMount
{
/** /**
* Combine two paths together, reducing them into a normalised form. * Combine two paths together, reducing them into a normalised form.
* *
* @param path The main path. * @param path The main path.
* @param child The path to append. * @param child The path to append.
* @return The combined, normalised path. * @return The combined, normalised path.
*/ */
String combine(String path, String child); String combine( String path, String child );
/** /**
* Copy files from one location to another. * Copy files from one location to another.
* *
* @param from The location to copy from. * @param from The location to copy from.
* @param to The location to copy to. This should not exist. * @param to The location to copy to. This should not exist.
* @throws IOException If the copy failed. * @throws IOException If the copy failed.
*/ */
void copy(String from, String to) throws IOException; void copy( String from, String to ) throws IOException;
/** /**
* Move files from one location to another. * Move files from one location to another.
* *
* @param from The location to move from. * @param from The location to move from.
* @param to The location to move to. This should not exist. * @param to The location to move to. This should not exist.
* @throws IOException If the move failed. * @throws IOException If the move failed.
*/ */
void move(String from, String to) throws IOException; void move( String from, String to ) throws IOException;
} }

View File

@@ -6,18 +6,16 @@
package dan200.computercraft.api.filesystem; package dan200.computercraft.api.filesystem;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IComputerAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IComputerAccess;
import net.minecraft.world.World;
/** /**
* Represents a read only part of a virtual filesystem that can be mounted onto a computer using {@link IComputerAccess#mount(String, IMount)}. * Represents a read only part of a virtual filesystem that can be mounted onto a computer using {@link IComputerAccess#mount(String, IMount)}.
* *
@@ -29,26 +27,27 @@ import net.minecraft.world.World;
* @see IComputerAccess#mount(String, IMount) * @see IComputerAccess#mount(String, IMount)
* @see IWritableMount * @see IWritableMount
*/ */
public interface IMount { public interface IMount
{
/** /**
* Returns the file names of all the files in a directory. * Returns the file names of all the files in a directory.
* *
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms". * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms".
* @param contents A list of strings. Add all the file names to this list. * @param contents A list of strings. Add all the file names to this list.
* @throws IOException If the file was not a directory, or could not be listed. * @throws IOException If the file was not a directory, or could not be listed.
*/ */
void list(@Nonnull String path, @Nonnull List<String> contents) throws IOException; void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException;
/** /**
* Opens a file with a given path, and returns an {@link ReadableByteChannel} representing its contents. * Opens a file with a given path, and returns an {@link ReadableByteChannel} representing its contents.
* *
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram". * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
* @return A channel representing the contents of the file. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one will be able to * @return A channel representing the contents of the file. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one will be able to
* seek to arbitrary positions when using binary mode. * seek to arbitrary positions when using binary mode.
* @throws IOException If the file does not exist, or could not be opened. * @throws IOException If the file does not exist, or could not be opened.
*/ */
@Nonnull @Nonnull
ReadableByteChannel openForRead(@Nonnull String path) throws IOException; ReadableByteChannel openForRead( @Nonnull String path ) throws IOException;
/** /**
* Get attributes about the given file. * Get attributes about the given file.
@@ -58,11 +57,13 @@ public interface IMount {
* @throws IOException If the file does not exist, or attributes could not be fetched. * @throws IOException If the file does not exist, or attributes could not be fetched.
*/ */
@Nonnull @Nonnull
default BasicFileAttributes getAttributes(@Nonnull String path) throws IOException { default BasicFileAttributes getAttributes( @Nonnull String path ) throws IOException
if (!this.exists(path)) { {
throw new FileOperationException(path, "No such file"); if( !this.exists( path ) )
{
throw new FileOperationException( path, "No such file" );
} }
return new FileAttributes(this.isDirectory(path), this.getSize(path)); return new FileAttributes( this.isDirectory( path ), this.getSize( path ) );
} }
/** /**
@@ -72,7 +73,7 @@ public interface IMount {
* @return If the file exists. * @return If the file exists.
* @throws IOException If an error occurs when checking the existence of the file. * @throws IOException If an error occurs when checking the existence of the file.
*/ */
boolean exists(@Nonnull String path) throws IOException; boolean exists( @Nonnull String path ) throws IOException;
/** /**
* Returns whether a file with a given path is a directory or not. * Returns whether a file with a given path is a directory or not.
@@ -81,7 +82,7 @@ public interface IMount {
* @return If the file exists and is a directory * @return If the file exists and is a directory
* @throws IOException If an error occurs when checking whether the file is a directory. * @throws IOException If an error occurs when checking whether the file is a directory.
*/ */
boolean isDirectory(@Nonnull String path) throws IOException; boolean isDirectory( @Nonnull String path ) 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.
@@ -90,5 +91,5 @@ public interface IMount {
* @return The size of the file, in bytes. * @return The size of the file, in bytes.
* @throws IOException If the file does not exist, or its size could not be determined. * @throws IOException If the file does not exist, or its size could not be determined.
*/ */
long getSize(@Nonnull String path) throws IOException; long getSize( @Nonnull String path ) throws IOException;
} }

View File

@@ -6,18 +6,16 @@
package dan200.computercraft.api.filesystem; package dan200.computercraft.api.filesystem;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IComputerAccess;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import java.util.OptionalLong; import java.util.OptionalLong;
import javax.annotation.Nonnull;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IComputerAccess;
import net.minecraft.world.World;
/** /**
* Represents a part of a virtual filesystem that can be mounted onto a computer using {@link IComputerAccess#mount(String, IMount)} or {@link * Represents a part of a virtual filesystem that can be mounted onto a computer using {@link IComputerAccess#mount(String, IMount)} or {@link
* IComputerAccess#mountWritable(String, IWritableMount)}, that can also be written to. * IComputerAccess#mountWritable(String, IWritableMount)}, that can also be written to.
@@ -30,14 +28,15 @@ import net.minecraft.world.World;
* @see IComputerAccess#mountWritable(String, IWritableMount) * @see IComputerAccess#mountWritable(String, IWritableMount)
* @see IMount * @see IMount
*/ */
public interface IWritableMount extends IMount { public interface IWritableMount extends IMount
{
/** /**
* Creates a directory at a given path inside the virtual file system. * Creates a directory at a given path inside the virtual file system.
* *
* @param path A file path in normalised format, relative to the mount location. ie: "programs/mynewprograms". * @param path A file path in normalised format, relative to the mount location. ie: "programs/mynewprograms".
* @throws IOException If the directory already exists or could not be created. * @throws IOException If the directory already exists or could not be created.
*/ */
void makeDirectory(@Nonnull String path) throws IOException; void makeDirectory( @Nonnull String path ) throws IOException;
/** /**
* Deletes a directory at a given path inside the virtual file system. * Deletes a directory at a given path inside the virtual file system.
@@ -45,29 +44,29 @@ public interface IWritableMount extends IMount {
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myoldprograms". * @param path A file path in normalised format, relative to the mount location. ie: "programs/myoldprograms".
* @throws IOException If the file does not exist or could not be deleted. * @throws IOException If the file does not exist or could not be deleted.
*/ */
void delete(@Nonnull String path) throws IOException; void delete( @Nonnull String path ) throws IOException;
/** /**
* Opens a file with a given path, and returns an {@link OutputStream} for writing to it. * Opens a file with a given path, and returns an {@link OutputStream} for writing to it.
* *
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram". * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
* @return A stream for writing to. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one will be able to seek to arbitrary * @return A stream for writing to. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one will be able to seek to arbitrary
* positions when using binary mode. * positions when using binary mode.
* @throws IOException If the file could not be opened for writing. * @throws IOException If the file could not be opened for writing.
*/ */
@Nonnull @Nonnull
WritableByteChannel openForWrite(@Nonnull String path) throws IOException; WritableByteChannel openForWrite( @Nonnull String path ) throws IOException;
/** /**
* Opens a file with a given path, and returns an {@link OutputStream} for appending to it. * Opens a file with a given path, and returns an {@link OutputStream} for appending to it.
* *
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram". * @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
* @return A stream for writing to. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one will be able to seek to arbitrary * @return A stream for writing to. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one will be able to seek to arbitrary
* positions when using binary mode. * positions when using binary mode.
* @throws IOException If the file could not be opened for writing. * @throws IOException If the file could not be opened for writing.
*/ */
@Nonnull @Nonnull
WritableByteChannel openForAppend(@Nonnull String path) throws IOException; WritableByteChannel openForAppend( @Nonnull String path ) throws IOException;
/** /**
* Get the amount of free space on the mount, in bytes. You should decrease this value as the user writes to the mount, and write operations should fail * Get the amount of free space on the mount, in bytes. You should decrease this value as the user writes to the mount, and write operations should fail
@@ -84,7 +83,8 @@ public interface IWritableMount extends IMount {
* @return The capacity of this mount, in bytes. * @return The capacity of this mount, in bytes.
*/ */
@Nonnull @Nonnull
default OptionalLong getCapacity() { default OptionalLong getCapacity()
{
return OptionalLong.empty(); return OptionalLong.empty();
} }
} }

View File

@@ -6,19 +6,19 @@
package dan200.computercraft.api.lua; package dan200.computercraft.api.lua;
import static dan200.computercraft.api.lua.LuaValues.checkFinite; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nonnull; import static dan200.computercraft.api.lua.LuaValues.checkFinite;
import javax.annotation.Nullable;
/** /**
* The arguments passed to a function. * The arguments passed to a function.
*/ */
public interface IArguments { public interface IArguments
{
/** /**
* Drop a number of arguments. The returned arguments instance will access arguments at position {@code i + count}, rather than {@code i}. However, * Drop a number of arguments. The returned arguments instance will access arguments at position {@code i + count}, rather than {@code i}. However,
* errors will still use the given argument index. * errors will still use the given argument index.
@@ -26,12 +26,14 @@ public interface IArguments {
* @param count The number of arguments to drop. * @param count The number of arguments to drop.
* @return The new {@link IArguments} instance. * @return The new {@link IArguments} instance.
*/ */
IArguments drop(int count); IArguments drop( int count );
default Object[] getAll() { default Object[] getAll()
{
Object[] result = new Object[this.count()]; Object[] result = new Object[this.count()];
for (int i = 0; i < result.length; i++) { for( int i = 0; i < result.length; i++ )
result[i] = this.get(i); {
result[i] = this.get( i );
} }
return result; return result;
} }
@@ -58,7 +60,7 @@ public interface IArguments {
* @return The argument's value, or {@code null} if not present. * @return The argument's value, or {@code null} if not present.
*/ */
@Nullable @Nullable
Object get(int index); Object get( int index );
/** /**
* Get an argument as an integer. * Get an argument as an integer.
@@ -67,8 +69,9 @@ public interface IArguments {
* @return The argument's value. * @return The argument's value.
* @throws LuaException If the value is not an integer. * @throws LuaException If the value is not an integer.
*/ */
default int getInt(int index) throws LuaException { default int getInt( int index ) throws LuaException
return (int) this.getLong(index); {
return (int) this.getLong( index );
} }
/** /**
@@ -78,13 +81,15 @@ public interface IArguments {
* @return The argument's value. * @return The argument's value.
* @throws LuaException If the value is not a long. * @throws LuaException If the value is not a long.
*/ */
default long getLong(int index) throws LuaException { default long getLong( int index ) throws LuaException
Object value = this.get(index); {
if (!(value instanceof Number)) { Object value = this.get( index );
throw LuaValues.badArgumentOf(index, "number", value); if( !(value instanceof Number) )
{
throw LuaValues.badArgumentOf( index, "number", value );
} }
return LuaValues.checkFiniteNum(index, (Number) value) return LuaValues.checkFiniteNum( index, (Number) value )
.longValue(); .longValue();
} }
/** /**
@@ -94,8 +99,9 @@ public interface IArguments {
* @return The argument's value. * @return The argument's value.
* @throws LuaException If the value is not finite. * @throws LuaException If the value is not finite.
*/ */
default double getFiniteDouble(int index) throws LuaException { default double getFiniteDouble( int index ) throws LuaException
return checkFinite(index, this.getDouble(index)); {
return checkFinite( index, this.getDouble( index ) );
} }
/** /**
@@ -106,10 +112,12 @@ public interface IArguments {
* @throws LuaException If the value is not a number. * @throws LuaException If the value is not a number.
* @see #getFiniteDouble(int) if you require this to be finite (i.e. not infinite or NaN). * @see #getFiniteDouble(int) if you require this to be finite (i.e. not infinite or NaN).
*/ */
default double getDouble(int index) throws LuaException { default double getDouble( int index ) throws LuaException
Object value = this.get(index); {
if (!(value instanceof Number)) { Object value = this.get( index );
throw LuaValues.badArgumentOf(index, "number", value); if( !(value instanceof Number) )
{
throw LuaValues.badArgumentOf( index, "number", value );
} }
return ((Number) value).doubleValue(); return ((Number) value).doubleValue();
} }
@@ -121,10 +129,12 @@ public interface IArguments {
* @return The argument's value. * @return The argument's value.
* @throws LuaException If the value is not a boolean. * @throws LuaException If the value is not a boolean.
*/ */
default boolean getBoolean(int index) throws LuaException { default boolean getBoolean( int index ) throws LuaException
Object value = this.get(index); {
if (!(value instanceof Boolean)) { Object value = this.get( index );
throw LuaValues.badArgumentOf(index, "boolean", value); if( !(value instanceof Boolean) )
{
throw LuaValues.badArgumentOf( index, "boolean", value );
} }
return (Boolean) value; return (Boolean) value;
} }
@@ -137,8 +147,9 @@ public interface IArguments {
* @throws LuaException If the value is not a string. * @throws LuaException If the value is not a string.
*/ */
@Nonnull @Nonnull
default ByteBuffer getBytes(int index) throws LuaException { default ByteBuffer getBytes( int index ) throws LuaException
return LuaValues.encode(this.getString(index)); {
return LuaValues.encode( this.getString( index ) );
} }
/** /**
@@ -149,10 +160,12 @@ public interface IArguments {
* @throws LuaException If the value is not a string. * @throws LuaException If the value is not a string.
*/ */
@Nonnull @Nonnull
default String getString(int index) throws LuaException { default String getString( int index ) throws LuaException
Object value = this.get(index); {
if (!(value instanceof String)) { Object value = this.get( index );
throw LuaValues.badArgumentOf(index, "string", value); if( !(value instanceof String) )
{
throw LuaValues.badArgumentOf( index, "string", value );
} }
return (String) value; return (String) value;
} }
@@ -162,13 +175,14 @@ public interface IArguments {
* *
* @param index The argument number. * @param index The argument number.
* @param klass The type of enum to parse. * @param klass The type of enum to parse.
* @param <T> The type of enum to parse. * @param <T> The type of enum to parse.
* @return The argument's value. * @return The argument's value.
* @throws LuaException If the value is not a string or not a valid option for this enum. * @throws LuaException If the value is not a string or not a valid option for this enum.
*/ */
@Nonnull @Nonnull
default <T extends Enum<T>> T getEnum(int index, Class<T> klass) throws LuaException { default <T extends Enum<T>> T getEnum( int index, Class<T> klass ) throws LuaException
return LuaValues.checkEnum(index, klass, this.getString(index)); {
return LuaValues.checkEnum( index, klass, this.getString( index ) );
} }
/** /**
@@ -179,10 +193,12 @@ public interface IArguments {
* @throws LuaException If the value is not a table. * @throws LuaException If the value is not a table.
*/ */
@Nonnull @Nonnull
default Map<?, ?> getTable(int index) throws LuaException { default Map<?, ?> getTable( int index ) throws LuaException
Object value = this.get(index); {
if (!(value instanceof Map)) { Object value = this.get( index );
throw LuaValues.badArgumentOf(index, "table", value); if( !(value instanceof Map) )
{
throw LuaValues.badArgumentOf( index, "table", value );
} }
return (Map<?, ?>) value; return (Map<?, ?>) value;
} }
@@ -194,8 +210,9 @@ public interface IArguments {
* @return The argument's value, or {@link Optional#empty()} if not present. This is a <em>read only</em> buffer. * @return The argument's value, or {@link Optional#empty()} if not present. This is a <em>read only</em> buffer.
* @throws LuaException If the value is not a string. * @throws LuaException If the value is not a string.
*/ */
default Optional<ByteBuffer> optBytes(int index) throws LuaException { default Optional<ByteBuffer> optBytes( int index ) throws LuaException
return this.optString(index).map(LuaValues::encode); {
return this.optString( index ).map( LuaValues::encode );
} }
/** /**
@@ -205,15 +222,18 @@ public interface IArguments {
* @return The argument's value, or {@link Optional#empty()} if not present. * @return The argument's value, or {@link Optional#empty()} if not present.
* @throws LuaException If the value is not a string. * @throws LuaException If the value is not a string.
*/ */
default Optional<String> optString(int index) throws LuaException { default Optional<String> optString( int index ) throws LuaException
Object value = this.get(index); {
if (value == null) { Object value = this.get( index );
if( value == null )
{
return Optional.empty(); return Optional.empty();
} }
if (!(value instanceof String)) { if( !(value instanceof String) )
throw LuaValues.badArgumentOf(index, "string", value); {
throw LuaValues.badArgumentOf( index, "string", value );
} }
return Optional.of((String) value); return Optional.of( (String) value );
} }
/** /**
@@ -221,26 +241,28 @@ public interface IArguments {
* *
* @param index The argument number. * @param index The argument number.
* @param klass The type of enum to parse. * @param klass The type of enum to parse.
* @param <T> The type of enum to parse. * @param <T> The type of enum to parse.
* @return The argument's value. * @return The argument's value.
* @throws LuaException If the value is not a string or not a valid option for this enum. * @throws LuaException If the value is not a string or not a valid option for this enum.
*/ */
@Nonnull @Nonnull
default <T extends Enum<T>> Optional<T> optEnum(int index, Class<T> klass) throws LuaException { default <T extends Enum<T>> Optional<T> optEnum( int index, Class<T> klass ) throws LuaException
Optional<String> str = this.optString(index); {
return str.isPresent() ? Optional.of(LuaValues.checkEnum(index, klass, str.get())) : Optional.empty(); Optional<String> str = this.optString( index );
return str.isPresent() ? Optional.of( LuaValues.checkEnum( index, klass, str.get() ) ) : Optional.empty();
} }
/** /**
* Get an argument as a double. * Get an argument as a double.
* *
* @param index The argument number. * @param index The argument number.
* @param def The default value, if this argument is not given. * @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided. * @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number. * @throws LuaException If the value is not a number.
*/ */
default double optDouble(int index, double def) throws LuaException { default double optDouble( int index, double def ) throws LuaException
return this.optDouble(index).orElse(def); {
return this.optDouble( index ).orElse( def );
} }
/** /**
@@ -251,27 +273,31 @@ public interface IArguments {
* @throws LuaException If the value is not a number. * @throws LuaException If the value is not a number.
*/ */
@Nonnull @Nonnull
default Optional<Double> optDouble(int index) throws LuaException { default Optional<Double> optDouble( int index ) throws LuaException
Object value = this.get(index); {
if (value == null) { Object value = this.get( index );
if( value == null )
{
return Optional.empty(); return Optional.empty();
} }
if (!(value instanceof Number)) { if( !(value instanceof Number) )
throw LuaValues.badArgumentOf(index, "number", value); {
throw LuaValues.badArgumentOf( index, "number", value );
} }
return Optional.of(((Number) value).doubleValue()); return Optional.of( ((Number) value).doubleValue() );
} }
/** /**
* Get an argument as an int. * Get an argument as an int.
* *
* @param index The argument number. * @param index The argument number.
* @param def The default value, if this argument is not given. * @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided. * @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number. * @throws LuaException If the value is not a number.
*/ */
default int optInt(int index, int def) throws LuaException { default int optInt( int index, int def ) throws LuaException
return this.optInt(index).orElse(def); {
return this.optInt( index ).orElse( def );
} }
/** /**
@@ -282,8 +308,9 @@ public interface IArguments {
* @throws LuaException If the value is not a number. * @throws LuaException If the value is not a number.
*/ */
@Nonnull @Nonnull
default Optional<Integer> optInt(int index) throws LuaException { default Optional<Integer> optInt( int index ) throws LuaException
return this.optLong(index).map(Long::intValue); {
return this.optLong( index ).map( Long::intValue );
} }
/** /**
@@ -293,40 +320,45 @@ public interface IArguments {
* @return The argument's value, or {@link Optional#empty()} if not present. * @return The argument's value, or {@link Optional#empty()} if not present.
* @throws LuaException If the value is not a number. * @throws LuaException If the value is not a number.
*/ */
default Optional<Long> optLong(int index) throws LuaException { default Optional<Long> optLong( int index ) throws LuaException
Object value = this.get(index); {
if (value == null) { Object value = this.get( index );
if( value == null )
{
return Optional.empty(); return Optional.empty();
} }
if (!(value instanceof Number)) { if( !(value instanceof Number) )
throw LuaValues.badArgumentOf(index, "number", value); {
throw LuaValues.badArgumentOf( index, "number", value );
} }
return Optional.of(LuaValues.checkFiniteNum(index, (Number) value) return Optional.of( LuaValues.checkFiniteNum( index, (Number) value )
.longValue()); .longValue() );
} }
/** /**
* Get an argument as a long. * Get an argument as a long.
* *
* @param index The argument number. * @param index The argument number.
* @param def The default value, if this argument is not given. * @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided. * @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number. * @throws LuaException If the value is not a number.
*/ */
default long optLong(int index, long def) throws LuaException { default long optLong( int index, long def ) throws LuaException
return this.optLong(index).orElse(def); {
return this.optLong( index ).orElse( def );
} }
/** /**
* Get an argument as a finite number (not infinite or NaN). * Get an argument as a finite number (not infinite or NaN).
* *
* @param index The argument number. * @param index The argument number.
* @param def The default value, if this argument is not given. * @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided. * @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not finite. * @throws LuaException If the value is not finite.
*/ */
default double optFiniteDouble(int index, double def) throws LuaException { default double optFiniteDouble( int index, double def ) throws LuaException
return this.optFiniteDouble(index).orElse(def); {
return this.optFiniteDouble( index ).orElse( def );
} }
/** /**
@@ -336,10 +368,12 @@ public interface IArguments {
* @return The argument's value, or {@link Optional#empty()} if not present. * @return The argument's value, or {@link Optional#empty()} if not present.
* @throws LuaException If the value is not finite. * @throws LuaException If the value is not finite.
*/ */
default Optional<Double> optFiniteDouble(int index) throws LuaException { default Optional<Double> optFiniteDouble( int index ) throws LuaException
Optional<Double> value = this.optDouble(index); {
if (value.isPresent()) { Optional<Double> value = this.optDouble( index );
LuaValues.checkFiniteNum(index, value.get()); if( value.isPresent() )
{
LuaValues.checkFiniteNum( index, value.get() );
} }
return value; return value;
} }
@@ -348,12 +382,13 @@ public interface IArguments {
* Get an argument as a boolean. * Get an argument as a boolean.
* *
* @param index The argument number. * @param index The argument number.
* @param def The default value, if this argument is not given. * @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided. * @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a boolean. * @throws LuaException If the value is not a boolean.
*/ */
default boolean optBoolean(int index, boolean def) throws LuaException { default boolean optBoolean( int index, boolean def ) throws LuaException
return this.optBoolean(index).orElse(def); {
return this.optBoolean( index ).orElse( def );
} }
/** /**
@@ -363,39 +398,44 @@ public interface IArguments {
* @return The argument's value, or {@link Optional#empty()} if not present. * @return The argument's value, or {@link Optional#empty()} if not present.
* @throws LuaException If the value is not a boolean. * @throws LuaException If the value is not a boolean.
*/ */
default Optional<Boolean> optBoolean(int index) throws LuaException { default Optional<Boolean> optBoolean( int index ) throws LuaException
Object value = this.get(index); {
if (value == null) { Object value = this.get( index );
if( value == null )
{
return Optional.empty(); return Optional.empty();
} }
if (!(value instanceof Boolean)) { if( !(value instanceof Boolean) )
throw LuaValues.badArgumentOf(index, "boolean", value); {
throw LuaValues.badArgumentOf( index, "boolean", value );
} }
return Optional.of((Boolean) value); return Optional.of( (Boolean) value );
} }
/** /**
* Get an argument as a string. * Get an argument as a string.
* *
* @param index The argument number. * @param index The argument number.
* @param def The default value, if this argument is not given. * @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided. * @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a string. * @throws LuaException If the value is not a string.
*/ */
default String optString(int index, String def) throws LuaException { default String optString( int index, String def ) throws LuaException
return this.optString(index).orElse(def); {
return this.optString( index ).orElse( def );
} }
/** /**
* Get an argument as a table. * Get an argument as a table.
* *
* @param index The argument number. * @param index The argument number.
* @param def The default value, if this argument is not given. * @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided. * @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a table. * @throws LuaException If the value is not a table.
*/ */
default Map<?, ?> optTable(int index, Map<Object, Object> def) throws LuaException { default Map<?, ?> optTable( int index, Map<Object, Object> def ) throws LuaException
return this.optTable(index).orElse(def); {
return this.optTable( index ).orElse( def );
} }
/** /**
@@ -405,14 +445,17 @@ public interface IArguments {
* @return The argument's value, or {@link Optional#empty()} if not present. * @return The argument's value, or {@link Optional#empty()} if not present.
* @throws LuaException If the value is not a table. * @throws LuaException If the value is not a table.
*/ */
default Optional<Map<?, ?>> optTable(int index) throws LuaException { default Optional<Map<?, ?>> optTable( int index ) throws LuaException
Object value = this.get(index); {
if (value == null) { Object value = this.get( index );
if( value == null )
{
return Optional.empty(); return Optional.empty();
} }
if (!(value instanceof Map)) { if( !(value instanceof Map) )
throw LuaValues.badArgumentOf(index, "map", value); {
throw LuaValues.badArgumentOf( index, "map", value );
} }
return Optional.of((Map<?, ?>) value); return Optional.of( (Map<?, ?>) value );
} }
} }

View File

@@ -6,15 +6,16 @@
package dan200.computercraft.api.lua; package dan200.computercraft.api.lua;
import javax.annotation.Nullable;
import dan200.computercraft.api.filesystem.IFileSystem; import dan200.computercraft.api.filesystem.IFileSystem;
import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IComputerAccess;
import javax.annotation.Nullable;
/** /**
* An interface passed to {@link ILuaAPIFactory} in order to provide additional information about a computer. * An interface passed to {@link ILuaAPIFactory} in order to provide additional information about a computer.
*/ */
public interface IComputerSystem extends IComputerAccess { public interface IComputerSystem extends IComputerAccess
{
/** /**
* Get the file system for this computer. * Get the file system for this computer.
* *

View File

@@ -6,17 +6,18 @@
package dan200.computercraft.api.lua; package dan200.computercraft.api.lua;
import javax.annotation.Nonnull;
import dan200.computercraft.api.peripheral.IDynamicPeripheral; import dan200.computercraft.api.peripheral.IDynamicPeripheral;
import javax.annotation.Nonnull;
/** /**
* An interface for representing custom objects returned by peripherals or other Lua objects. * An interface for representing custom objects returned by peripherals or other Lua objects.
* *
* Generally, one does not need to implement this type - it is sufficient to return an object with some methods annotated with {@link LuaFunction}. {@link * Generally, one does not need to implement this type - it is sufficient to return an object with some methods annotated with {@link LuaFunction}. {@link
* IDynamicLuaObject} is useful when you wish your available methods to change at runtime. * IDynamicLuaObject} is useful when you wish your available methods to change at runtime.
*/ */
public interface IDynamicLuaObject { public interface IDynamicLuaObject
{
/** /**
* Get the names of the methods that this object implements. This should not change over the course of the object's lifetime. * Get the names of the methods that this object implements. This should not change over the course of the object's lifetime.
* *
@@ -29,12 +30,12 @@ public interface IDynamicLuaObject {
/** /**
* Called when a user calls one of the methods that this object implements. * Called when a user calls one of the methods that this object implements.
* *
* @param context The context of the currently running lua thread. This can be used to wait for events or otherwise yield. * @param context The context of the currently running lua thread. This can be used to wait for events or otherwise yield.
* @param method An integer identifying which method index from {@link #getMethodNames()} the computer wishes to call. * @param method An integer identifying which method index from {@link #getMethodNames()} the computer wishes to call.
* @param arguments The arguments for this method. * @param arguments The arguments for this method.
* @return The result of this function. Either an immediate value ({@link MethodResult#of(Object...)} or an instruction to yield. * @return The result of this function. Either an immediate value ({@link MethodResult#of(Object...)} or an instruction to yield.
* @throws LuaException If the function threw an exception. * @throws LuaException If the function threw an exception.
*/ */
@Nonnull @Nonnull
MethodResult callMethod(@Nonnull ILuaContext context, int method, @Nonnull IArguments arguments) throws LuaException; MethodResult callMethod( @Nonnull ILuaContext context, int method, @Nonnull IArguments arguments ) throws LuaException;
} }

View File

@@ -18,7 +18,8 @@ import dan200.computercraft.api.ComputerCraftAPI;
* @see ILuaAPIFactory * @see ILuaAPIFactory
* @see ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory) * @see ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory)
*/ */
public interface ILuaAPI { public interface ILuaAPI
{
/** /**
* Get the globals this API will be assigned to. This will override any other global, so you should * Get the globals this API will be assigned to. This will override any other global, so you should
* *
@@ -31,13 +32,15 @@ public interface ILuaAPI {
* *
* One should only interact with the file system. * One should only interact with the file system.
*/ */
default void startup() { default void startup()
{
} }
/** /**
* Called every time the computer is ticked. This can be used to process various. * Called every time the computer is ticked. This can be used to process various.
*/ */
default void update() { default void update()
{
} }
/** /**
@@ -45,6 +48,7 @@ public interface ILuaAPI {
* *
* This should reset the state of the object, disposing any remaining file handles, or other resources. * This should reset the state of the object, disposing any remaining file handles, or other resources.
*/ */
default void shutdown() { default void shutdown()
{
} }
} }

View File

@@ -6,11 +6,11 @@
package dan200.computercraft.api.lua; package dan200.computercraft.api.lua;
import dan200.computercraft.api.ComputerCraftAPI;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import dan200.computercraft.api.ComputerCraftAPI;
/** /**
* Construct an {@link ILuaAPI} for a specific computer. * Construct an {@link ILuaAPI} for a specific computer.
* *
@@ -18,7 +18,8 @@ import dan200.computercraft.api.ComputerCraftAPI;
* @see ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory) * @see ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory)
*/ */
@FunctionalInterface @FunctionalInterface
public interface ILuaAPIFactory { public interface ILuaAPIFactory
{
/** /**
* Create a new API instance for a given computer. * Create a new API instance for a given computer.
* *
@@ -26,5 +27,5 @@ public interface ILuaAPIFactory {
* @return The created API, or {@code null} if one should not be injected. * @return The created API, or {@code null} if one should not be injected.
*/ */
@Nullable @Nullable
ILuaAPI create(@Nonnull IComputerSystem computer); ILuaAPI create( @Nonnull IComputerSystem computer );
} }

View File

@@ -13,7 +13,8 @@ import javax.annotation.Nonnull;
* *
* @see MethodResult#yield(Object[], ILuaCallback) * @see MethodResult#yield(Object[], ILuaCallback)
*/ */
public interface ILuaCallback { public interface ILuaCallback
{
/** /**
* Resume this coroutine. * Resume this coroutine.
* *
@@ -22,5 +23,5 @@ public interface ILuaCallback {
* @throws LuaException On an error. * @throws LuaException On an error.
*/ */
@Nonnull @Nonnull
MethodResult resume(Object[] args) throws LuaException; MethodResult resume( Object[] args ) throws LuaException;
} }

View File

@@ -12,7 +12,8 @@ import javax.annotation.Nonnull;
* An interface passed to peripherals and {@link IDynamicLuaObject}s by computers or turtles, providing methods that allow the peripheral call to interface * An interface passed to peripherals and {@link IDynamicLuaObject}s by computers or turtles, providing methods that allow the peripheral call to interface
* with the computer. * with the computer.
*/ */
public interface ILuaContext { public interface ILuaContext
{
/** /**
* Queue a task to be executed on the main server thread at the beginning of next tick, but do not wait for it to complete. This should be used when you * Queue a task to be executed on the main server thread at the beginning of next tick, but do not wait for it to complete. This should be used when you
* need to interact with the world in a thread-safe manner but do not care about the result or you wish to run asynchronously. * need to interact with the world in a thread-safe manner but do not care about the result or you wish to run asynchronously.
@@ -25,5 +26,5 @@ public interface ILuaContext {
* @throws LuaException If the task could not be queued. * @throws LuaException If the task could not be queued.
* @see LuaFunction#mainThread() To run functions on the main thread and return their results synchronously. * @see LuaFunction#mainThread() To run functions on the main thread and return their results synchronously.
*/ */
long issueMainThreadTask(@Nonnull ILuaTask task) throws LuaException; long issueMainThreadTask( @Nonnull ILuaTask task ) throws LuaException;
} }

View File

@@ -15,7 +15,8 @@ import javax.annotation.Nonnull;
* @see MethodResult#of(Object) * @see MethodResult#of(Object)
*/ */
@FunctionalInterface @FunctionalInterface
public interface ILuaFunction { public interface ILuaFunction
{
/** /**
* Call this function with a series of arguments. Note, this will <em>always</em> be called on the computer thread, and so its implementation must be * Call this function with a series of arguments. Note, this will <em>always</em> be called on the computer thread, and so its implementation must be
* thread-safe. * thread-safe.
@@ -25,5 +26,5 @@ public interface ILuaFunction {
* @throws LuaException Upon Lua errors. * @throws LuaException Upon Lua errors.
*/ */
@Nonnull @Nonnull
MethodResult call(@Nonnull IArguments arguments) throws LuaException; MethodResult call( @Nonnull IArguments arguments ) throws LuaException;
} }

View File

@@ -1,18 +1,18 @@
/* /*
* This file is part of the public ComputerCraft API - http://www.computercraft.info * 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. * Copyright Daniel Ratcliffe, 2011-2021. 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. * For help using the API, and posting your mods, visit the forums at computercraft.info.
*/ */
package dan200.computercraft.api.lua; package dan200.computercraft.api.lua;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public interface ILuaObject { public interface ILuaObject
{
@Nonnull @Nonnull
String[] getMethodNames(); String[] getMethodNames();
@Nullable @Nullable
Object[] callMethod(@Nonnull ILuaContext context, int method, @Nonnull Object[] arguments) throws LuaException, InterruptedException; Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException;
} }

View File

@@ -15,13 +15,14 @@ import javax.annotation.Nullable;
* @see ILuaContext#issueMainThreadTask(ILuaTask) * @see ILuaContext#issueMainThreadTask(ILuaTask)
*/ */
@FunctionalInterface @FunctionalInterface
public interface ILuaTask { public interface ILuaTask
{
/** /**
* Execute this task. * Execute this task.
* *
* @return The arguments to add to the {@code task_completed} event. * @return The arguments to add to the {@code task_completed} event.
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the same message as your exception. Use this * @throws LuaException If you throw any exception from this function, a lua error will be raised with the same message as your exception. Use this
* to throw appropriate errors if the wrong arguments are supplied to your method. * to throw appropriate errors if the wrong arguments are supplied to your method.
*/ */
@Nullable @Nullable
Object[] execute() throws LuaException; Object[] execute() throws LuaException;

View File

@@ -11,19 +11,22 @@ import javax.annotation.Nullable;
/** /**
* An exception representing an error in Lua, like that raised by the {@code error()} function. * An exception representing an error in Lua, like that raised by the {@code error()} function.
*/ */
public class LuaException extends Exception { public class LuaException extends Exception
{
private static final long serialVersionUID = -6136063076818512651L; private static final long serialVersionUID = -6136063076818512651L;
private final boolean hasLevel; private final boolean hasLevel;
private final int level; private final int level;
public LuaException(@Nullable String message) { public LuaException( @Nullable String message )
super(message); {
super( message );
this.hasLevel = false; this.hasLevel = false;
this.level = 1; this.level = 1;
} }
public LuaException(@Nullable String message, int level) { public LuaException( @Nullable String message, int level )
super(message); {
super( message );
this.hasLevel = true; this.hasLevel = true;
this.level = level; this.level = level;
} }
@@ -33,7 +36,8 @@ public class LuaException extends Exception {
* *
* @return Whether this has an explicit level. * @return Whether this has an explicit level.
*/ */
public boolean hasLevel() { public boolean hasLevel()
{
return this.hasLevel; return this.hasLevel;
} }
@@ -42,7 +46,8 @@ public class LuaException extends Exception {
* *
* @return The level to raise the error at. * @return The level to raise the error at.
*/ */
public int getLevel() { public int getLevel()
{
return this.level; return this.level;
} }
} }

View File

@@ -6,17 +6,13 @@
package dan200.computercraft.api.lua; package dan200.computercraft.api.lua;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Map;
import java.util.Optional;
import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import java.lang.annotation.*;
import java.util.Map;
import java.util.Optional;
/** /**
* Used to mark a Java function which is callable from Lua. * Used to mark a Java function which is callable from Lua.
* *
@@ -41,9 +37,10 @@ import dan200.computercraft.api.peripheral.IPeripheral;
* {@link MethodResult#of(Object...)}. * {@link MethodResult#of(Object...)}.
*/ */
@Documented @Documented
@Retention (RetentionPolicy.RUNTIME) @Retention( RetentionPolicy.RUNTIME )
@Target (ElementType.METHOD) @Target( ElementType.METHOD )
public @interface LuaFunction { public @interface LuaFunction
{
/** /**
* Explicitly specify the method names of this function. If not given, it uses the name of the annotated method. * Explicitly specify the method names of this function. If not given, it uses the name of the annotated method.
* *

View File

@@ -6,19 +6,20 @@
package dan200.computercraft.api.lua; package dan200.computercraft.api.lua;
import java.nio.ByteBuffer;
import java.util.Map;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.nio.ByteBuffer;
import java.util.Map;
/** /**
* Various utility functions for operating with Lua values. * Various utility functions for operating with Lua values.
* *
* @see IArguments * @see IArguments
*/ */
public final class LuaValues { public final class LuaValues
private LuaValues() { {
private LuaValues()
{
} }
/** /**
@@ -28,41 +29,45 @@ public final class LuaValues {
* @return The encoded string. * @return The encoded string.
*/ */
@Nonnull @Nonnull
public static ByteBuffer encode(@Nonnull String string) { public static ByteBuffer encode( @Nonnull String string )
{
byte[] chars = new byte[string.length()]; byte[] chars = new byte[string.length()];
for (int i = 0; i < chars.length; i++) { for( int i = 0; i < chars.length; i++ )
char c = string.charAt(i); {
char c = string.charAt( i );
chars[i] = c < 256 ? (byte) c : 63; chars[i] = c < 256 ? (byte) c : 63;
} }
return ByteBuffer.wrap(chars) return ByteBuffer.wrap( chars )
.asReadOnlyBuffer(); .asReadOnlyBuffer();
} }
/** /**
* Construct a "bad argument" exception, from an expected type and the actual value provided. * Construct a "bad argument" exception, from an expected type and the actual value provided.
* *
* @param index The argument number, starting from 0. * @param index The argument number, starting from 0.
* @param expected The expected type for this argument. * @param expected The expected type for this argument.
* @param actual The actual value provided for this argument. * @param actual The actual value provided for this argument.
* @return The constructed exception, which should be thrown immediately. * @return The constructed exception, which should be thrown immediately.
*/ */
@Nonnull @Nonnull
public static LuaException badArgumentOf(int index, @Nonnull String expected, @Nullable Object actual) { public static LuaException badArgumentOf( int index, @Nonnull String expected, @Nullable Object actual )
return badArgument(index, expected, getType(actual)); {
return badArgument( index, expected, getType( actual ) );
} }
/** /**
* Construct a "bad argument" exception, from an expected and actual type. * Construct a "bad argument" exception, from an expected and actual type.
* *
* @param index The argument number, starting from 0. * @param index The argument number, starting from 0.
* @param expected The expected type for this argument. * @param expected The expected type for this argument.
* @param actual The provided type for this argument. * @param actual The provided type for this argument.
* @return The constructed exception, which should be thrown immediately. * @return The constructed exception, which should be thrown immediately.
*/ */
@Nonnull @Nonnull
public static LuaException badArgument(int index, @Nonnull String expected, @Nonnull String actual) { public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
return new LuaException("bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")"); {
return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
} }
/** /**
@@ -72,20 +77,26 @@ public final class LuaValues {
* @return A string representation of the given value's type, in a similar format to that provided by Lua's {@code type} function. * @return A string representation of the given value's type, in a similar format to that provided by Lua's {@code type} function.
*/ */
@Nonnull @Nonnull
public static String getType(@Nullable Object value) { public static String getType( @Nullable Object value )
if (value == null) { {
if( value == null )
{
return "nil"; return "nil";
} }
if (value instanceof String) { if( value instanceof String )
{
return "string"; return "string";
} }
if (value instanceof Boolean) { if( value instanceof Boolean )
{
return "boolean"; return "boolean";
} }
if (value instanceof Number) { if( value instanceof Number )
{
return "number"; return "number";
} }
if (value instanceof Map) { if( value instanceof Map )
{
return "table"; return "table";
} }
return "userdata"; return "userdata";
@@ -99,8 +110,9 @@ public final class LuaValues {
* @return The input {@code value}. * @return The input {@code value}.
* @throws LuaException If this is not a finite number. * @throws LuaException If this is not a finite number.
*/ */
public static Number checkFiniteNum(int index, Number value) throws LuaException { public static Number checkFiniteNum( int index, Number value ) throws LuaException
checkFinite(index, value.doubleValue()); {
checkFinite( index, value.doubleValue() );
return value; return value;
} }
@@ -112,9 +124,11 @@ public final class LuaValues {
* @return The input {@code value}. * @return The input {@code value}.
* @throws LuaException If this is not a finite number. * @throws LuaException If this is not a finite number.
*/ */
public static double checkFinite(int index, double value) throws LuaException { public static double checkFinite( int index, double value ) throws LuaException
if (!Double.isFinite(value)) { {
throw badArgument(index, "number", getNumericType(value)); if( !Double.isFinite( value ) )
{
throw badArgument( index, "number", getNumericType( value ) );
} }
return value; return value;
} }
@@ -127,14 +141,18 @@ public final class LuaValues {
* @return This value's numeric type. * @return This value's numeric type.
*/ */
@Nonnull @Nonnull
public static String getNumericType(double value) { public static String getNumericType( double value )
if (Double.isNaN(value)) { {
if( Double.isNaN( value ) )
{
return "nan"; return "nan";
} }
if (value == Double.POSITIVE_INFINITY) { if( value == Double.POSITIVE_INFINITY )
{
return "inf"; return "inf";
} }
if (value == Double.NEGATIVE_INFINITY) { if( value == Double.NEGATIVE_INFINITY )
{
return "-inf"; return "-inf";
} }
return "number"; return "number";
@@ -146,18 +164,21 @@ public final class LuaValues {
* @param index The argument index to check. * @param index The argument index to check.
* @param klass The class of the enum instance. * @param klass The class of the enum instance.
* @param value The value to extract. * @param value The value to extract.
* @param <T> The type of enum we are extracting. * @param <T> The type of enum we are extracting.
* @return The parsed enum value. * @return The parsed enum value.
* @throws LuaException If this is not a known enum value. * @throws LuaException If this is not a known enum value.
*/ */
public static <T extends Enum<T>> T checkEnum(int index, Class<T> klass, String value) throws LuaException { public static <T extends Enum<T>> T checkEnum( int index, Class<T> klass, String value ) throws LuaException
for (T possibility : klass.getEnumConstants()) { {
if (possibility.name() for( T possibility : klass.getEnumConstants() )
.equalsIgnoreCase(value)) { {
if( possibility.name()
.equalsIgnoreCase( value ) )
{
return possibility; return possibility;
} }
} }
throw new LuaException("bad argument #" + (index + 1) + " (unknown option " + value + ")"); throw new LuaException( "bad argument #" + (index + 1) + " (unknown option " + value + ")" );
} }
} }

View File

@@ -6,36 +6,38 @@
package dan200.computercraft.api.lua; package dan200.computercraft.api.lua;
import dan200.computercraft.api.peripheral.IComputerAccess;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.api.peripheral.IComputerAccess;
/** /**
* The result of invoking a Lua method. * The result of invoking a Lua method.
* *
* Method results either return a value immediately ({@link #of(Object...)} or yield control to the parent coroutine. When the current coroutine is resumed, * Method results either return a value immediately ({@link #of(Object...)} or yield control to the parent coroutine. When the current coroutine is resumed,
* we invoke the provided {@link ILuaCallback#resume(Object[])} callback. * we invoke the provided {@link ILuaCallback#resume(Object[])} callback.
*/ */
public final class MethodResult { public final class MethodResult
private static final MethodResult empty = new MethodResult(null, null); {
private static final MethodResult empty = new MethodResult( null, null );
private final Object[] result; private final Object[] result;
private final ILuaCallback callback; private final ILuaCallback callback;
private final int adjust; private final int adjust;
private MethodResult(Object[] arguments, ILuaCallback callback) { private MethodResult( Object[] arguments, ILuaCallback callback )
{
this.result = arguments; this.result = arguments;
this.callback = callback; this.callback = callback;
this.adjust = 0; this.adjust = 0;
} }
private MethodResult(Object[] arguments, ILuaCallback callback, int adjust) { private MethodResult( Object[] arguments, ILuaCallback callback, int adjust )
{
this.result = arguments; this.result = arguments;
this.callback = callback; this.callback = callback;
this.adjust = adjust; this.adjust = adjust;
@@ -47,7 +49,8 @@ public final class MethodResult {
* @return A method result which returns immediately with no values. * @return A method result which returns immediately with no values.
*/ */
@Nonnull @Nonnull
public static MethodResult of() { public static MethodResult of()
{
return empty; return empty;
} }
@@ -64,8 +67,9 @@ public final class MethodResult {
* @return A method result which returns immediately with the given value. * @return A method result which returns immediately with the given value.
*/ */
@Nonnull @Nonnull
public static MethodResult of(@Nullable Object value) { public static MethodResult of( @Nullable Object value )
return new MethodResult(new Object[] {value}, null); {
return new MethodResult( new Object[] { value }, null );
} }
/** /**
@@ -75,43 +79,47 @@ public final class MethodResult {
* @return A method result which returns immediately with the given values. * @return A method result which returns immediately with the given values.
*/ */
@Nonnull @Nonnull
public static MethodResult of(@Nullable Object... values) { public static MethodResult of( @Nullable Object... values )
return values == null || values.length == 0 ? empty : new MethodResult(values, null); {
return values == null || values.length == 0 ? empty : new MethodResult( values, null );
} }
/** /**
* Wait for an event to occur on the computer, suspending the thread until it arises. This method is exactly equivalent to {@code os.pullEvent()} in * Wait for an event to occur on the computer, suspending the thread until it arises. This method is exactly equivalent to {@code os.pullEvent()} in
* lua. * lua.
* *
* @param filter A specific event to wait for, or null to wait for any event. * @param filter A specific event to wait for, or null to wait for any event.
* @param callback The callback to resume with the name of the event that occurred, and any event parameters. * @param callback The callback to resume with the name of the event that occurred, and any event parameters.
* @return The method result which represents this yield. * @return The method result which represents this yield.
* @see IComputerAccess#queueEvent(String, Object[]) * @see IComputerAccess#queueEvent(String, Object[])
*/ */
@Nonnull @Nonnull
public static MethodResult pullEvent(@Nullable String filter, @Nonnull ILuaCallback callback) { public static MethodResult pullEvent( @Nullable String filter, @Nonnull ILuaCallback callback )
Objects.requireNonNull(callback, "callback cannot be null"); {
return new MethodResult(new Object[] {filter}, results -> { Objects.requireNonNull( callback, "callback cannot be null" );
if (results.length >= 1 && results[0].equals("terminate")) { return new MethodResult( new Object[] { filter }, results -> {
throw new LuaException("Terminated", 0); if( results.length >= 1 && results[0].equals( "terminate" ) )
{
throw new LuaException( "Terminated", 0 );
} }
return callback.resume(results); return callback.resume( results );
}); } );
} }
/** /**
* The same as {@link #pullEvent(String, ILuaCallback)}, except "terminated" events are ignored. Only use this if you want to prevent program * The same as {@link #pullEvent(String, ILuaCallback)}, except "terminated" events are ignored. Only use this if you want to prevent program
* termination, which is not recommended. This method is exactly equivalent to {@code os.pullEventRaw()} in Lua. * termination, which is not recommended. This method is exactly equivalent to {@code os.pullEventRaw()} in Lua.
* *
* @param filter A specific event to wait for, or null to wait for any event. * @param filter A specific event to wait for, or null to wait for any event.
* @param callback The callback to resume with the name of the event that occurred, and any event parameters. * @param callback The callback to resume with the name of the event that occurred, and any event parameters.
* @return The method result which represents this yield. * @return The method result which represents this yield.
* @see #pullEvent(String, ILuaCallback) * @see #pullEvent(String, ILuaCallback)
*/ */
@Nonnull @Nonnull
public static MethodResult pullEventRaw(@Nullable String filter, @Nonnull ILuaCallback callback) { public static MethodResult pullEventRaw( @Nullable String filter, @Nonnull ILuaCallback callback )
Objects.requireNonNull(callback, "callback cannot be null"); {
return new MethodResult(new Object[] {filter}, callback); Objects.requireNonNull( callback, "callback cannot be null" );
return new MethodResult( new Object[] { filter }, callback );
} }
/** /**
@@ -119,27 +127,31 @@ public final class MethodResult {
* {@code pullEvent()} if you wish to wait for events. * {@code pullEvent()} if you wish to wait for events.
* *
* @param arguments An object array containing the arguments to pass to coroutine.yield() * @param arguments An object array containing the arguments to pass to coroutine.yield()
* @param callback The callback to resume with an array containing the return values from coroutine.yield() * @param callback The callback to resume with an array containing the return values from coroutine.yield()
* @return The method result which represents this yield. * @return The method result which represents this yield.
* @see #pullEvent(String, ILuaCallback) * @see #pullEvent(String, ILuaCallback)
*/ */
@Nonnull @Nonnull
public static MethodResult yield(@Nullable Object[] arguments, @Nonnull ILuaCallback callback) { public static MethodResult yield( @Nullable Object[] arguments, @Nonnull ILuaCallback callback )
Objects.requireNonNull(callback, "callback cannot be null"); {
return new MethodResult(arguments, callback); Objects.requireNonNull( callback, "callback cannot be null" );
return new MethodResult( arguments, callback );
} }
@Nullable @Nullable
public Object[] getResult() { public Object[] getResult()
{
return this.result; return this.result;
} }
@Nullable @Nullable
public ILuaCallback getCallback() { public ILuaCallback getCallback()
{
return this.callback; return this.callback;
} }
public int getErrorAdjust() { public int getErrorAdjust()
{
return this.adjust; return this.adjust;
} }
@@ -150,13 +162,16 @@ public final class MethodResult {
* @return The new {@link MethodResult} with an adjusted error. This has no effect on immediate results. * @return The new {@link MethodResult} with an adjusted error. This has no effect on immediate results.
*/ */
@Nonnull @Nonnull
public MethodResult adjustError(int adjust) { public MethodResult adjustError( int adjust )
if (adjust < 0) { {
throw new IllegalArgumentException("cannot adjust by a negative amount"); if( adjust < 0 )
{
throw new IllegalArgumentException( "cannot adjust by a negative amount" );
} }
if (adjust == 0 || this.callback == null) { if( adjust == 0 || this.callback == null )
{
return this; return this;
} }
return new MethodResult(this.result, this.callback, this.adjust + adjust); return new MethodResult( this.result, this.callback, this.adjust + adjust );
} }
} }

View File

@@ -6,61 +6,71 @@
package dan200.computercraft.api.lua; package dan200.computercraft.api.lua;
import javax.annotation.Nullable;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import javax.annotation.Nullable;
/** /**
* An implementation of {@link IArguments} which wraps an array of {@link Object}. * An implementation of {@link IArguments} which wraps an array of {@link Object}.
*/ */
public final class ObjectArguments implements IArguments { public final class ObjectArguments implements IArguments
{
private static final IArguments EMPTY = new ObjectArguments(); private static final IArguments EMPTY = new ObjectArguments();
private final List<Object> args; private final List<Object> args;
@Deprecated @Deprecated
@SuppressWarnings ("unused") @SuppressWarnings( "unused" )
public ObjectArguments(IArguments arguments) { public ObjectArguments( IArguments arguments )
{
throw new IllegalStateException(); throw new IllegalStateException();
} }
public ObjectArguments(Object... args) { public ObjectArguments( Object... args )
this.args = Arrays.asList(args); {
this.args = Arrays.asList( args );
} }
public ObjectArguments(List<Object> args) { public ObjectArguments( List<Object> args )
this.args = Objects.requireNonNull(args); {
this.args = Objects.requireNonNull( args );
} }
@Override @Override
public IArguments drop(int count) { public IArguments drop( int count )
if (count < 0) { {
throw new IllegalStateException("count cannot be negative"); if( count < 0 )
{
throw new IllegalStateException( "count cannot be negative" );
} }
if (count == 0) { if( count == 0 )
{
return this; return this;
} }
if (count >= this.args.size()) { if( count >= this.args.size() )
{
return EMPTY; return EMPTY;
} }
return new ObjectArguments(this.args.subList(count, this.args.size())); return new ObjectArguments( this.args.subList( count, this.args.size() ) );
} }
@Override @Override
public Object[] getAll() { public Object[] getAll()
{
return this.args.toArray(); return this.args.toArray();
} }
@Override @Override
public int count() { public int count()
{
return this.args.size(); return this.args.size();
} }
@Nullable @Nullable
@Override @Override
public Object get(int index) { public Object get( int index )
return index >= this.args.size() ? null : this.args.get(index); {
return index >= this.args.size() ? null : this.args.get( index );
} }
} }

View File

@@ -6,22 +6,22 @@
package dan200.computercraft.api.media; package dan200.computercraft.api.media;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IMount;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* Represents an item that can be placed in a disk drive and used by a Computer. * Represents an item that can be placed in a disk drive and used by a Computer.
* *
* Implement this interface on your {@link Item} class to allow it to be used in the drive. Alternatively, register a {@link IMediaProvider}. * Implement this interface on your {@link Item} class to allow it to be used in the drive. Alternatively, register a {@link IMediaProvider}.
*/ */
public interface IMedia { public interface IMedia
{
/** /**
* Get a string representing the label of this item. Will be called via {@code disk.getLabel()} in lua. * Get a string representing the label of this item. Will be called via {@code disk.getLabel()} in lua.
* *
@@ -29,7 +29,7 @@ public interface IMedia {
* @return The label. ie: "Dan's Programs". * @return The label. ie: "Dan's Programs".
*/ */
@Nullable @Nullable
String getLabel(@Nonnull ItemStack stack); String getLabel( @Nonnull ItemStack stack );
/** /**
* Set a string representing the label of this item. Will be called vi {@code disk.setLabel()} in lua. * Set a string representing the label of this item. Will be called vi {@code disk.setLabel()} in lua.
@@ -38,7 +38,8 @@ public interface IMedia {
* @param label The string to set the label to. * @param label The string to set the label to.
* @return true if the label was updated, false if the label may not be modified. * @return true if the label was updated, false if the label may not be modified.
*/ */
default boolean setLabel(@Nonnull ItemStack stack, @Nullable String label) { default boolean setLabel( @Nonnull ItemStack stack, @Nullable String label )
{
return false; return false;
} }
@@ -49,7 +50,8 @@ public interface IMedia {
* @return The name, or null if this item does not represent an item with audio. * @return The name, or null if this item does not represent an item with audio.
*/ */
@Nullable @Nullable
default String getAudioTitle(@Nonnull ItemStack stack) { default String getAudioTitle( @Nonnull ItemStack stack )
{
return null; return null;
} }
@@ -60,7 +62,8 @@ public interface IMedia {
* @return The name, or null if this item does not represent an item with audio. * @return The name, or null if this item does not represent an item with audio.
*/ */
@Nullable @Nullable
default SoundEvent getAudio(@Nonnull ItemStack stack) { default SoundEvent getAudio( @Nonnull ItemStack stack )
{
return null; return null;
} }
@@ -71,14 +74,15 @@ public interface IMedia {
* @param stack The {@link ItemStack} to modify. * @param stack The {@link ItemStack} to modify.
* @param world The world in which the item and disk drive reside. * @param world The world in which the item and disk drive reside.
* @return The mount, or null if this item does not represent an item with data. If the mount returned also implements {@link * @return The mount, or null if this item does not represent an item with data. If the mount returned also implements {@link
* dan200.computercraft.api.filesystem.IWritableMount}, it will mounted using mountWritable() * dan200.computercraft.api.filesystem.IWritableMount}, it will mounted using mountWritable()
* @see IMount * @see IMount
* @see dan200.computercraft.api.filesystem.IWritableMount * @see dan200.computercraft.api.filesystem.IWritableMount
* @see dan200.computercraft.api.ComputerCraftAPI#createSaveDirMount(World, String, long) * @see dan200.computercraft.api.ComputerCraftAPI#createSaveDirMount(World, String, long)
* @see dan200.computercraft.api.ComputerCraftAPI#createResourceMount(String, String) * @see dan200.computercraft.api.ComputerCraftAPI#createResourceMount(String, String)
*/ */
@Nullable @Nullable
default IMount createDataMount(@Nonnull ItemStack stack, @Nonnull World world) { default IMount createDataMount( @Nonnull ItemStack stack, @Nonnull World world )
{
return null; return null;
} }
} }

View File

@@ -6,18 +6,19 @@
package dan200.computercraft.api.media; package dan200.computercraft.api.media;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import net.minecraft.item.ItemStack;
/** /**
* This interface is used to provide {@link IMedia} implementations for {@link ItemStack}. * This interface is used to provide {@link IMedia} implementations for {@link ItemStack}.
* *
* @see dan200.computercraft.api.ComputerCraftAPI#registerMediaProvider(IMediaProvider) * @see dan200.computercraft.api.ComputerCraftAPI#registerMediaProvider(IMediaProvider)
*/ */
@FunctionalInterface @FunctionalInterface
public interface IMediaProvider { public interface IMediaProvider
{
/** /**
* Produce an IMedia implementation from an ItemStack. * Produce an IMedia implementation from an ItemStack.
* *
@@ -26,5 +27,5 @@ public interface IMediaProvider {
* @see dan200.computercraft.api.ComputerCraftAPI#registerMediaProvider(IMediaProvider) * @see dan200.computercraft.api.ComputerCraftAPI#registerMediaProvider(IMediaProvider)
*/ */
@Nullable @Nullable
IMedia getMedia(@Nonnull ItemStack stack); IMedia getMedia( @Nonnull ItemStack stack );
} }

View File

@@ -14,20 +14,21 @@ import javax.annotation.Nonnull;
* @see Packet * @see Packet
* @see IPacketReceiver * @see IPacketReceiver
*/ */
public interface IPacketNetwork { public interface IPacketNetwork
{
/** /**
* Add a receiver to the network. * Add a receiver to the network.
* *
* @param receiver The receiver to register to the network. * @param receiver The receiver to register to the network.
*/ */
void addReceiver(@Nonnull IPacketReceiver receiver); void addReceiver( @Nonnull IPacketReceiver receiver );
/** /**
* Remove a receiver from the network. * Remove a receiver from the network.
* *
* @param receiver The device to remove from the network. * @param receiver The device to remove from the network.
*/ */
void removeReceiver(@Nonnull IPacketReceiver receiver); void removeReceiver( @Nonnull IPacketReceiver receiver );
/** /**
* Determine whether this network is wireless. * Determine whether this network is wireless.
@@ -41,11 +42,11 @@ public interface IPacketNetwork {
* interdimensional ones). * interdimensional ones).
* *
* @param packet The packet to send. * @param packet The packet to send.
* @param range The maximum distance this packet will be sent. * @param range The maximum distance this packet will be sent.
* @see #transmitInterdimensional(Packet) * @see #transmitInterdimensional(Packet)
* @see IPacketReceiver#receiveSameDimension(Packet, double) * @see IPacketReceiver#receiveSameDimension(Packet, double)
*/ */
void transmitSameDimension(@Nonnull Packet packet, double range); void transmitSameDimension( @Nonnull Packet packet, double range );
/** /**
* Submit a packet for transmitting across the network. This will route the packet through the network, sending it to all receivers across all * Submit a packet for transmitting across the network. This will route the packet through the network, sending it to all receivers across all
@@ -55,5 +56,5 @@ public interface IPacketNetwork {
* @see #transmitSameDimension(Packet, double) * @see #transmitSameDimension(Packet, double)
* @see IPacketReceiver#receiveDifferentDimension(Packet) * @see IPacketReceiver#receiveDifferentDimension(Packet)
*/ */
void transmitInterdimensional(@Nonnull Packet packet); void transmitInterdimensional( @Nonnull Packet packet );
} }

View File

@@ -6,15 +6,16 @@
package dan200.computercraft.api.network; package dan200.computercraft.api.network;
import javax.annotation.Nonnull;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
/** /**
* An object on an {@link IPacketNetwork}, capable of receiving packets. * An object on an {@link IPacketNetwork}, capable of receiving packets.
*/ */
public interface IPacketReceiver { public interface IPacketReceiver
{
/** /**
* Get the world in which this packet receiver exists. * Get the world in which this packet receiver exists.
* *
@@ -59,25 +60,25 @@ public interface IPacketReceiver {
/** /**
* Receive a network packet from the same dimension. * Receive a network packet from the same dimension.
* *
* @param packet The packet to receive. Generally you should check that you are listening on the given channel and, if so, queue the appropriate * @param packet The packet to receive. Generally you should check that you are listening on the given channel and, if so, queue the appropriate
* modem event. * modem event.
* @param distance The distance this packet has travelled from the source. * @param distance The distance this packet has travelled from the source.
* @see Packet * @see Packet
* @see #getRange() * @see #getRange()
* @see IPacketNetwork#transmitSameDimension(Packet, double) * @see IPacketNetwork#transmitSameDimension(Packet, double)
* @see IPacketNetwork#transmitInterdimensional(Packet) * @see IPacketNetwork#transmitInterdimensional(Packet)
*/ */
void receiveSameDimension(@Nonnull Packet packet, double distance); void receiveSameDimension( @Nonnull Packet packet, double distance );
/** /**
* Receive a network packet from a different dimension. * Receive a network packet from a different dimension.
* *
* @param packet The packet to receive. Generally you should check that you are listening on the given channel and, if so, queue the appropriate * @param packet The packet to receive. Generally you should check that you are listening on the given channel and, if so, queue the appropriate
* modem event. * modem event.
* @see Packet * @see Packet
* @see IPacketNetwork#transmitInterdimensional(Packet) * @see IPacketNetwork#transmitInterdimensional(Packet)
* @see IPacketNetwork#transmitSameDimension(Packet, double) * @see IPacketNetwork#transmitSameDimension(Packet, double)
* @see #isInterdimensional() * @see #isInterdimensional()
*/ */
void receiveDifferentDimension(@Nonnull Packet packet); void receiveDifferentDimension( @Nonnull Packet packet );
} }

View File

@@ -6,15 +6,16 @@
package dan200.computercraft.api.network; package dan200.computercraft.api.network;
import javax.annotation.Nonnull;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
/** /**
* An object on a {@link IPacketNetwork}, capable of sending packets. * An object on a {@link IPacketNetwork}, capable of sending packets.
*/ */
public interface IPacketSender { public interface IPacketSender
{
/** /**
* Get the world in which this packet sender exists. * Get the world in which this packet sender exists.
* *

View File

@@ -6,10 +6,9 @@
package dan200.computercraft.api.network; package dan200.computercraft.api.network;
import java.util.Objects;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Objects;
/** /**
* Represents a packet which may be sent across a {@link IPacketNetwork}. * Represents a packet which may be sent across a {@link IPacketNetwork}.
@@ -20,7 +19,8 @@ import javax.annotation.Nullable;
* @see IPacketReceiver#receiveDifferentDimension(Packet) * @see IPacketReceiver#receiveDifferentDimension(Packet)
* @see IPacketReceiver#receiveSameDimension(Packet, double) * @see IPacketReceiver#receiveSameDimension(Packet, double)
*/ */
public class Packet { public class Packet
{
private final int channel; private final int channel;
private final int replyChannel; private final int replyChannel;
private final Object payload; private final Object payload;
@@ -30,14 +30,15 @@ public class Packet {
/** /**
* Create a new packet, ready for transmitting across the network. * Create a new packet, ready for transmitting across the network.
* *
* @param channel The channel to send the packet along. Receiving devices should only process packets from on channels they are listening to. * @param channel The channel to send the packet along. Receiving devices should only process packets from on channels they are listening to.
* @param replyChannel The channel to reply on. * @param replyChannel The channel to reply on.
* @param payload The contents of this packet. This should be a "valid" Lua object, safe for queuing as an event or returning from a peripheral * @param payload The contents of this packet. This should be a "valid" Lua object, safe for queuing as an event or returning from a peripheral
* call. * call.
* @param sender The object which sent this packet. * @param sender The object which sent this packet.
*/ */
public Packet(int channel, int replyChannel, @Nullable Object payload, @Nonnull IPacketSender sender) { public Packet( int channel, int replyChannel, @Nullable Object payload, @Nonnull IPacketSender sender )
Objects.requireNonNull(sender, "sender cannot be null"); {
Objects.requireNonNull( sender, "sender cannot be null" );
this.channel = channel; this.channel = channel;
this.replyChannel = replyChannel; this.replyChannel = replyChannel;
@@ -50,7 +51,8 @@ public class Packet {
* *
* @return This packet's channel. * @return This packet's channel.
*/ */
public int getChannel() { public int getChannel()
{
return this.channel; return this.channel;
} }
@@ -59,7 +61,8 @@ public class Packet {
* *
* @return This channel to reply on. * @return This channel to reply on.
*/ */
public int getReplyChannel() { public int getReplyChannel()
{
return this.replyChannel; return this.replyChannel;
} }
@@ -69,7 +72,8 @@ public class Packet {
* @return The packet's payload * @return The packet's payload
*/ */
@Nullable @Nullable
public Object getPayload() { public Object getPayload()
{
return this.payload; return this.payload;
} }
@@ -79,12 +83,14 @@ public class Packet {
* @return The sending object. * @return The sending object.
*/ */
@Nonnull @Nonnull
public IPacketSender getSender() { public IPacketSender getSender()
{
return this.sender; return this.sender;
} }
@Override @Override
public int hashCode() { public int hashCode()
{
int result; int result;
result = this.channel; result = this.channel;
result = 31 * result + this.replyChannel; result = 31 * result + this.replyChannel;
@@ -94,25 +100,31 @@ public class Packet {
} }
@Override @Override
public boolean equals(Object o) { public boolean equals( Object o )
if (this == o) { {
if( this == o )
{
return true; return true;
} }
if (o == null || this.getClass() != o.getClass()) { if( o == null || this.getClass() != o.getClass() )
{
return false; return false;
} }
Packet packet = (Packet) o; Packet packet = (Packet) o;
if (this.channel != packet.channel) { if( this.channel != packet.channel )
{
return false; return false;
} }
if (this.replyChannel != packet.replyChannel) { if( this.replyChannel != packet.replyChannel )
{
return false; return false;
} }
if (!Objects.equals(this.payload, packet.payload)) { if( !Objects.equals( this.payload, packet.payload ) )
{
return false; return false;
} }
return this.sender.equals(packet.sender); return this.sender.equals( packet.sender );
} }
} }

View File

@@ -6,10 +6,10 @@
package dan200.computercraft.api.network.wired; package dan200.computercraft.api.network.wired;
import javax.annotation.Nonnull;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import javax.annotation.Nonnull;
/** /**
* An object which may be part of a wired network. * An object which may be part of a wired network.
* *
@@ -19,13 +19,15 @@ import dan200.computercraft.api.ComputerCraftAPI;
* Elements are generally tied to a block or tile entity in world. In such as case, one should provide the {@link IWiredElement} capability for the * Elements are generally tied to a block or tile entity in world. In such as case, one should provide the {@link IWiredElement} capability for the
* appropriate sides. * appropriate sides.
*/ */
public interface IWiredElement extends IWiredSender { public interface IWiredElement extends IWiredSender
{
/** /**
* Called when objects on the network change. This may occur when network nodes are added or removed, or when peripherals change. * Called when objects on the network change. This may occur when network nodes are added or removed, or when peripherals change.
* *
* @param change The change which occurred. * @param change The change which occurred.
* @see IWiredNetworkChange * @see IWiredNetworkChange
*/ */
default void networkChanged(@Nonnull IWiredNetworkChange change) { default void networkChanged( @Nonnull IWiredNetworkChange change )
{
} }
} }

View File

@@ -6,11 +6,10 @@
package dan200.computercraft.api.network.wired; package dan200.computercraft.api.network.wired;
import java.util.Map; import dan200.computercraft.api.peripheral.IPeripheral;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Map;
import dan200.computercraft.api.peripheral.IPeripheral;
/** /**
* A wired network is composed of one of more {@link IWiredNode}s, a set of connections between them, and a series of peripherals. * A wired network is composed of one of more {@link IWiredNode}s, a set of connections between them, and a series of peripherals.
@@ -24,28 +23,29 @@ import dan200.computercraft.api.peripheral.IPeripheral;
* *
* @see IWiredNode#getNetwork() * @see IWiredNode#getNetwork()
*/ */
public interface IWiredNetwork { public interface IWiredNetwork
{
/** /**
* Create a connection between two nodes. * Create a connection between two nodes.
* *
* This should only be used on the server thread. * This should only be used on the server thread.
* *
* @param left The first node to connect * @param left The first node to connect
* @param right The second node to connect * @param right The second node to connect
* @return {@code true} if a connection was created or {@code false} if the connection already exists. * @return {@code true} if a connection was created or {@code false} if the connection already exists.
* @throws IllegalStateException If neither node is on the network. * @throws IllegalStateException If neither node is on the network.
* @throws IllegalArgumentException If {@code left} and {@code right} are equal. * @throws IllegalArgumentException If {@code left} and {@code right} are equal.
* @see IWiredNode#connectTo(IWiredNode) * @see IWiredNode#connectTo(IWiredNode)
* @see IWiredNetwork#connect(IWiredNode, IWiredNode) * @see IWiredNetwork#connect(IWiredNode, IWiredNode)
*/ */
boolean connect(@Nonnull IWiredNode left, @Nonnull IWiredNode right); boolean connect( @Nonnull IWiredNode left, @Nonnull IWiredNode right );
/** /**
* Destroy a connection between this node and another. * Destroy a connection between this node and another.
* *
* This should only be used on the server thread. * This should only be used on the server thread.
* *
* @param left The first node in the connection. * @param left The first node in the connection.
* @param right The second node in the connection. * @param right The second node in the connection.
* @return {@code true} if a connection was destroyed or {@code false} if no connection exists. * @return {@code true} if a connection was destroyed or {@code false} if no connection exists.
* @throws IllegalArgumentException If either node is not on the network. * @throws IllegalArgumentException If either node is not on the network.
@@ -53,7 +53,7 @@ public interface IWiredNetwork {
* @see IWiredNode#disconnectFrom(IWiredNode) * @see IWiredNode#disconnectFrom(IWiredNode)
* @see IWiredNetwork#connect(IWiredNode, IWiredNode) * @see IWiredNetwork#connect(IWiredNode, IWiredNode)
*/ */
boolean disconnect(@Nonnull IWiredNode left, @Nonnull IWiredNode right); boolean disconnect( @Nonnull IWiredNode left, @Nonnull IWiredNode right );
/** /**
* Sever all connections this node has, removing it from this network. * Sever all connections this node has, removing it from this network.
@@ -65,17 +65,17 @@ public interface IWiredNetwork {
* @throws IllegalArgumentException If the node is not in the network. * @throws IllegalArgumentException If the node is not in the network.
* @see IWiredNode#remove() * @see IWiredNode#remove()
*/ */
boolean remove(@Nonnull IWiredNode node); boolean remove( @Nonnull IWiredNode node );
/** /**
* Update the peripherals a node provides. * Update the peripherals a node provides.
* *
* This should only be used on the server thread. You should only call this on nodes that your network element owns. * This should only be used on the server thread. You should only call this on nodes that your network element owns.
* *
* @param node The node to attach peripherals for. * @param node The node to attach peripherals for.
* @param peripherals The new peripherals for this node. * @param peripherals The new peripherals for this node.
* @throws IllegalArgumentException If the node is not in the network. * @throws IllegalArgumentException If the node is not in the network.
* @see IWiredNode#updatePeripherals(Map) * @see IWiredNode#updatePeripherals(Map)
*/ */
void updatePeripherals(@Nonnull IWiredNode node, @Nonnull Map<String, IPeripheral> peripherals); void updatePeripherals( @Nonnull IWiredNode node, @Nonnull Map<String, IPeripheral> peripherals );
} }

View File

@@ -6,18 +6,18 @@
package dan200.computercraft.api.network.wired; package dan200.computercraft.api.network.wired;
import java.util.Map; import dan200.computercraft.api.peripheral.IPeripheral;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Map;
import dan200.computercraft.api.peripheral.IPeripheral;
/** /**
* Represents a change to the objects on a wired network. * Represents a change to the objects on a wired network.
* *
* @see IWiredElement#networkChanged(IWiredNetworkChange) * @see IWiredElement#networkChanged(IWiredNetworkChange)
*/ */
public interface IWiredNetworkChange { public interface IWiredNetworkChange
{
/** /**
* A set of peripherals which have been removed. Note that there may be entries with the same name in the added and removed set, but with a different * A set of peripherals which have been removed. Note that there may be entries with the same name in the added and removed set, but with a different
* peripheral. * peripheral.

View File

@@ -6,13 +6,12 @@
package dan200.computercraft.api.network.wired; package dan200.computercraft.api.network.wired;
import java.util.Map;
import javax.annotation.Nonnull;
import dan200.computercraft.api.network.IPacketNetwork; import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import javax.annotation.Nonnull;
import java.util.Map;
/** /**
* Wired nodes act as a layer between {@link IWiredElement}s and {@link IWiredNetwork}s. * Wired nodes act as a layer between {@link IWiredElement}s and {@link IWiredNetwork}s.
* *
@@ -25,7 +24,8 @@ import dan200.computercraft.api.peripheral.IPeripheral;
* *
* Wired nodes also provide several convenience methods for interacting with a wired network. These should only ever be used on the main server thread. * Wired nodes also provide several convenience methods for interacting with a wired network. These should only ever be used on the main server thread.
*/ */
public interface IWiredNode extends IPacketNetwork { public interface IWiredNode extends IPacketNetwork
{
/** /**
* The associated element for this network node. * The associated element for this network node.
* *
@@ -44,8 +44,9 @@ public interface IWiredNode extends IPacketNetwork {
* @see IWiredNetwork#connect(IWiredNode, IWiredNode) * @see IWiredNetwork#connect(IWiredNode, IWiredNode)
* @see IWiredNode#disconnectFrom(IWiredNode) * @see IWiredNode#disconnectFrom(IWiredNode)
*/ */
default boolean connectTo(@Nonnull IWiredNode node) { default boolean connectTo( @Nonnull IWiredNode node )
return this.getNetwork().connect(this, node); {
return this.getNetwork().connect( this, node );
} }
/** /**
@@ -69,8 +70,9 @@ public interface IWiredNode extends IPacketNetwork {
* @see IWiredNetwork#disconnect(IWiredNode, IWiredNode) * @see IWiredNetwork#disconnect(IWiredNode, IWiredNode)
* @see IWiredNode#connectTo(IWiredNode) * @see IWiredNode#connectTo(IWiredNode)
*/ */
default boolean disconnectFrom(@Nonnull IWiredNode node) { default boolean disconnectFrom( @Nonnull IWiredNode node )
return this.getNetwork().disconnect(this, node); {
return this.getNetwork().disconnect( this, node );
} }
/** /**
@@ -82,8 +84,9 @@ public interface IWiredNode extends IPacketNetwork {
* @throws IllegalArgumentException If the node is not in the network. * @throws IllegalArgumentException If the node is not in the network.
* @see IWiredNetwork#remove(IWiredNode) * @see IWiredNetwork#remove(IWiredNode)
*/ */
default boolean remove() { default boolean remove()
return this.getNetwork().remove(this); {
return this.getNetwork().remove( this );
} }
/** /**
@@ -94,7 +97,8 @@ public interface IWiredNode extends IPacketNetwork {
* @param peripherals The new peripherals for this node. * @param peripherals The new peripherals for this node.
* @see IWiredNetwork#updatePeripherals(IWiredNode, Map) * @see IWiredNetwork#updatePeripherals(IWiredNode, Map)
*/ */
default void updatePeripherals(@Nonnull Map<String, IPeripheral> peripherals) { default void updatePeripherals( @Nonnull Map<String, IPeripheral> peripherals )
this.getNetwork().updatePeripherals(this, peripherals); {
this.getNetwork().updatePeripherals( this, peripherals );
} }
} }

View File

@@ -6,16 +6,17 @@
package dan200.computercraft.api.network.wired; package dan200.computercraft.api.network.wired;
import javax.annotation.Nonnull;
import dan200.computercraft.api.network.IPacketSender; import dan200.computercraft.api.network.IPacketSender;
import javax.annotation.Nonnull;
/** /**
* An object on a {@link IWiredNetwork} capable of sending packets. * An object on a {@link IWiredNetwork} capable of sending packets.
* *
* Unlike a regular {@link IPacketSender}, this must be associated with the node you are attempting to to send the packet from. * Unlike a regular {@link IPacketSender}, this must be associated with the node you are attempting to to send the packet from.
*/ */
public interface IWiredSender extends IPacketSender { public interface IWiredSender extends IPacketSender
{
/** /**
* The node in the network representing this object. * The node in the network representing this object.
* *

View File

@@ -6,11 +6,6 @@
package dan200.computercraft.api.peripheral; package dan200.computercraft.api.peripheral;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount; import dan200.computercraft.api.filesystem.IWritableMount;
@@ -18,21 +13,25 @@ import dan200.computercraft.api.lua.ILuaCallback;
import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.ILuaTask; import dan200.computercraft.api.lua.ILuaTask;
import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.lua.MethodResult;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
/** /**
* The interface passed to peripherals by computers or turtles, providing methods that they can call. This should not be implemented by your classes. Do not * The interface passed to peripherals by computers or turtles, providing methods that they can call. This should not be implemented by your classes. Do not
* interact with computers except via this interface. * interact with computers except via this interface.
*/ */
public interface IComputerAccess { public interface IComputerAccess
{
/** /**
* Mount a mount onto the computer's file system in a read only mode. * Mount a mount onto the computer's file system in a read only mode.
* *
* @param desiredLocation The location on the computer's file system where you would like the mount to be mounted. * @param desiredLocation The location on the computer's file system where you would like the mount to be mounted.
* @param mount The mount object to mount on the computer. * @param mount The mount object to mount on the computer.
* @return The location on the computer's file system where you the mount mounted, or {@code null} if there was already a file in the desired location. * @return The location on the computer's file system where you the mount mounted, or {@code null} if there was already a file in the desired location.
* Store this value if you wish to unmount the mount later. * Store this value if you wish to unmount the mount later.
* @throws NotAttachedException If the peripheral has been detached. * @throws NotAttachedException If the peripheral has been detached.
* @see ComputerCraftAPI#createSaveDirMount(World, String, long) * @see ComputerCraftAPI#createSaveDirMount(World, String, long)
* @see ComputerCraftAPI#createResourceMount(String, String) * @see ComputerCraftAPI#createResourceMount(String, String)
@@ -42,18 +41,19 @@ public interface IComputerAccess {
* @see IMount * @see IMount
*/ */
@Nullable @Nullable
default String mount(@Nonnull String desiredLocation, @Nonnull IMount mount) { default String mount( @Nonnull String desiredLocation, @Nonnull IMount mount )
return this.mount(desiredLocation, mount, this.getAttachmentName()); {
return this.mount( desiredLocation, mount, this.getAttachmentName() );
} }
/** /**
* Mount a mount onto the computer's file system in a read only mode. * Mount a mount onto the computer's file system in a read only mode.
* *
* @param desiredLocation The location on the computer's file system where you would like the mount to be mounted. * @param desiredLocation The location on the computer's file system where you would like the mount to be mounted.
* @param mount The mount object to mount on the computer. * @param mount The mount object to mount on the computer.
* @param driveName A custom name to give for this mount location, as returned by {@code fs.getDrive()}. * @param driveName A custom name to give for this mount location, as returned by {@code fs.getDrive()}.
* @return The location on the computer's file system where you the mount mounted, or {@code null} if there was already a file in the desired location. * @return The location on the computer's file system where you the mount mounted, or {@code null} if there was already a file in the desired location.
* Store this value if you wish to unmount the mount later. * Store this value if you wish to unmount the mount later.
* @throws NotAttachedException If the peripheral has been detached. * @throws NotAttachedException If the peripheral has been detached.
* @see ComputerCraftAPI#createSaveDirMount(World, String, long) * @see ComputerCraftAPI#createSaveDirMount(World, String, long)
* @see ComputerCraftAPI#createResourceMount(String, String) * @see ComputerCraftAPI#createResourceMount(String, String)
@@ -63,7 +63,7 @@ public interface IComputerAccess {
* @see IMount * @see IMount
*/ */
@Nullable @Nullable
String mount(@Nonnull String desiredLocation, @Nonnull IMount mount, @Nonnull String driveName); String mount( @Nonnull String desiredLocation, @Nonnull IMount mount, @Nonnull String driveName );
/** /**
* Get a string, unique to the computer, by which the computer refers to this peripheral. For directly attached peripherals this will be * Get a string, unique to the computer, by which the computer refers to this peripheral. For directly attached peripherals this will be
@@ -80,9 +80,9 @@ public interface IComputerAccess {
* Mount a mount onto the computer's file system in a writable mode. * Mount a mount onto the computer's file system in a writable mode.
* *
* @param desiredLocation The location on the computer's file system where you would like the mount to be mounted. * @param desiredLocation The location on the computer's file system where you would like the mount to be mounted.
* @param mount The mount object to mount on the computer. * @param mount The mount object to mount on the computer.
* @return The location on the computer's file system where you the mount mounted, or null if there was already a file in the desired location. Store * @return The location on the computer's file system where you the mount mounted, or null if there was already a file in the desired location. Store
* this value if you wish to unmount the mount later. * this value if you wish to unmount the mount later.
* @throws NotAttachedException If the peripheral has been detached. * @throws NotAttachedException If the peripheral has been detached.
* @see ComputerCraftAPI#createSaveDirMount(World, String, long) * @see ComputerCraftAPI#createSaveDirMount(World, String, long)
* @see ComputerCraftAPI#createResourceMount(String, String) * @see ComputerCraftAPI#createResourceMount(String, String)
@@ -91,18 +91,19 @@ public interface IComputerAccess {
* @see IMount * @see IMount
*/ */
@Nullable @Nullable
default String mountWritable(@Nonnull String desiredLocation, @Nonnull IWritableMount mount) { default String mountWritable( @Nonnull String desiredLocation, @Nonnull IWritableMount mount )
return this.mountWritable(desiredLocation, mount, this.getAttachmentName()); {
return this.mountWritable( desiredLocation, mount, this.getAttachmentName() );
} }
/** /**
* Mount a mount onto the computer's file system in a writable mode. * Mount a mount onto the computer's file system in a writable mode.
* *
* @param desiredLocation The location on the computer's file system where you would like the mount to be mounted. * @param desiredLocation The location on the computer's file system where you would like the mount to be mounted.
* @param mount The mount object to mount on the computer. * @param mount The mount object to mount on the computer.
* @param driveName A custom name to give for this mount location, as returned by {@code fs.getDrive()}. * @param driveName A custom name to give for this mount location, as returned by {@code fs.getDrive()}.
* @return The location on the computer's file system where you the mount mounted, or null if there was already a file in the desired location. Store * @return The location on the computer's file system where you the mount mounted, or null if there was already a file in the desired location. Store
* this value if you wish to unmount the mount later. * this value if you wish to unmount the mount later.
* @throws NotAttachedException If the peripheral has been detached. * @throws NotAttachedException If the peripheral has been detached.
* @see ComputerCraftAPI#createSaveDirMount(World, String, long) * @see ComputerCraftAPI#createSaveDirMount(World, String, long)
* @see ComputerCraftAPI#createResourceMount(String, String) * @see ComputerCraftAPI#createResourceMount(String, String)
@@ -110,7 +111,7 @@ public interface IComputerAccess {
* @see #unmount(String) * @see #unmount(String)
* @see IMount * @see IMount
*/ */
String mountWritable(@Nonnull String desiredLocation, @Nonnull IWritableMount mount, @Nonnull String driveName); String mountWritable( @Nonnull String desiredLocation, @Nonnull IWritableMount mount, @Nonnull String driveName );
/** /**
* Unmounts a directory previously mounted onto the computers file system by {@link #mount(String, IMount)} or {@link #mountWritable(String, * Unmounts a directory previously mounted onto the computers file system by {@link #mount(String, IMount)} or {@link #mountWritable(String,
@@ -122,13 +123,13 @@ public interface IComputerAccess {
* Note that you cannot unmount another peripheral's mounts. * Note that you cannot unmount another peripheral's mounts.
* *
* @param location The desired location in the computers file system of the directory to unmount. This must be the location of a directory * @param location The desired location in the computers file system of the directory to unmount. This must be the location of a directory
* previously mounted by {@link #mount(String, IMount)} or {@link #mountWritable(String, IWritableMount)}, as indicated by their return value. * previously mounted by {@link #mount(String, IMount)} or {@link #mountWritable(String, IWritableMount)}, as indicated by their return value.
* @throws NotAttachedException If the peripheral has been detached. * @throws NotAttachedException If the peripheral has been detached.
* @throws IllegalStateException If the mount does not exist, or was mounted by another peripheral. * @throws IllegalStateException If the mount does not exist, or was mounted by another peripheral.
* @see #mount(String, IMount) * @see #mount(String, IMount)
* @see #mountWritable(String, IWritableMount) * @see #mountWritable(String, IWritableMount)
*/ */
void unmount(@Nullable String location); void unmount( @Nullable String location );
/** /**
* Returns the numerical ID of this computer. * Returns the numerical ID of this computer.
@@ -144,17 +145,17 @@ public interface IComputerAccess {
* Causes an event to be raised on this computer, which the computer can respond to by calling {@code os.pullEvent()}. This can be used to notify the * Causes an event to be raised on this computer, which the computer can respond to by calling {@code os.pullEvent()}. This can be used to notify the
* computer when things happen in the world or to this peripheral. * computer when things happen in the world or to this peripheral.
* *
* @param event A string identifying the type of event that has occurred, this will be returned as the first value from {@code os.pullEvent()}. It * @param event A string identifying the type of event that has occurred, this will be returned as the first value from {@code os.pullEvent()}. It
* is recommended that you you choose a name that is unique, and recognisable as originating from your peripheral. eg: If your peripheral type is * is recommended that you you choose a name that is unique, and recognisable as originating from your peripheral. eg: If your peripheral type is
* "button", a suitable event would be "button_pressed". * "button", a suitable event would be "button_pressed".
* @param arguments In addition to a name, you may pass an array of extra arguments to the event, that will be supplied as extra return values to * @param arguments In addition to a name, you may pass an array of extra arguments to the event, that will be supplied as extra return values to
* os.pullEvent(). Objects in the array will be converted to lua data types in the same fashion as the return values of IPeripheral.callMethod(). * os.pullEvent(). Objects in the array will be converted to lua data types in the same fashion as the return values of IPeripheral.callMethod().
* *
* You may supply {@code null} to indicate that no arguments are to be supplied. * You may supply {@code null} to indicate that no arguments are to be supplied.
* @throws NotAttachedException If the peripheral has been detached. * @throws NotAttachedException If the peripheral has been detached.
* @see MethodResult#pullEvent(String, ILuaCallback) * @see MethodResult#pullEvent(String, ILuaCallback)
*/ */
void queueEvent(@Nonnull String event, @Nullable Object... arguments); void queueEvent( @Nonnull String event, @Nullable Object... arguments );
/** /**
* Get a set of peripherals that this computer access can "see", along with their attachment name. * Get a set of peripherals that this computer access can "see", along with their attachment name.
@@ -178,7 +179,7 @@ public interface IComputerAccess {
* @see #getAvailablePeripherals() * @see #getAvailablePeripherals()
*/ */
@Nullable @Nullable
IPeripheral getAvailablePeripheral(@Nonnull String name); IPeripheral getAvailablePeripheral( @Nonnull String name );
/** /**
* Get a {@link IWorkMonitor} for tasks your peripheral might execute on the main (server) thread. * Get a {@link IWorkMonitor} for tasks your peripheral might execute on the main (server) thread.

View File

@@ -6,14 +6,9 @@
package dan200.computercraft.api.peripheral; package dan200.computercraft.api.peripheral;
import javax.annotation.Nonnull; import dan200.computercraft.api.lua.*;
import dan200.computercraft.api.lua.IArguments; import javax.annotation.Nonnull;
import dan200.computercraft.api.lua.IDynamicLuaObject;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.lua.MethodResult;
/** /**
* A peripheral whose methods are not known at runtime. * A peripheral whose methods are not known at runtime.
@@ -21,7 +16,8 @@ import dan200.computercraft.api.lua.MethodResult;
* This behaves similarly to {@link IDynamicLuaObject}, though also accepting the current {@link IComputerAccess}. Generally one may use {@link LuaFunction} * This behaves similarly to {@link IDynamicLuaObject}, though also accepting the current {@link IComputerAccess}. Generally one may use {@link LuaFunction}
* instead of implementing this interface. * instead of implementing this interface.
*/ */
public interface IDynamicPeripheral extends IPeripheral { public interface IDynamicPeripheral extends IPeripheral
{
/** /**
* Should return an array of strings that identify the methods that this peripheral exposes to Lua. This will be called once before each attachment, and * Should return an array of strings that identify the methods that this peripheral exposes to Lua. This will be called once before each attachment, and
* should not change when called multiple times. * should not change when called multiple times.
@@ -38,16 +34,16 @@ public interface IDynamicPeripheral extends IPeripheral {
* *
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe when interacting with Minecraft objects. * Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe when interacting with Minecraft objects.
* *
* @param computer The interface to the computer that is making the call. Remember that multiple computers can be attached to a peripheral at once. * @param computer The interface to the computer that is making the call. Remember that multiple computers can be attached to a peripheral at once.
* @param context The context of the currently running lua thread. This can be used to wait for events or otherwise yield. * @param context The context of the currently running lua thread. This can be used to wait for events or otherwise yield.
* @param method An integer identifying which of the methods from getMethodNames() the computercraft wishes to call. The integer indicates the index * @param method An integer identifying which of the methods from getMethodNames() the computercraft wishes to call. The integer indicates the index
* into the getMethodNames() table that corresponds to the string passed into peripheral.call() * into the getMethodNames() table that corresponds to the string passed into peripheral.call()
* @param arguments The arguments for this method. * @param arguments The arguments for this method.
* @return A {@link MethodResult} containing the values to return or the action to perform. * @return A {@link MethodResult} containing the values to return or the action to perform.
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the same message as your exception. Use this * @throws LuaException If you throw any exception from this function, a lua error will be raised with the same message as your exception. Use this
* to throw appropriate errors if the wrong arguments are supplied to your method. * to throw appropriate errors if the wrong arguments are supplied to your method.
* @see #getMethodNames() * @see #getMethodNames()
*/ */
@Nonnull @Nonnull
MethodResult callMethod(@Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull IArguments arguments) throws LuaException; MethodResult callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull IArguments arguments ) throws LuaException;
} }

View File

@@ -6,11 +6,11 @@
package dan200.computercraft.api.peripheral; package dan200.computercraft.api.peripheral;
import dan200.computercraft.api.lua.LuaFunction;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import dan200.computercraft.api.lua.LuaFunction;
/** /**
* The interface that defines a peripheral. * The interface that defines a peripheral.
* *
@@ -19,7 +19,8 @@ import dan200.computercraft.api.lua.LuaFunction;
* *
* Peripherals should provide a series of methods to the user, either using {@link LuaFunction} or by implementing {@link IDynamicPeripheral}. * Peripherals should provide a series of methods to the user, either using {@link LuaFunction} or by implementing {@link IDynamicPeripheral}.
*/ */
public interface IPeripheral { public interface IPeripheral
{
/** /**
* Should return a string that uniquely identifies this type of peripheral. This can be queried from lua by calling {@code peripheral.getType()} * Should return a string that uniquely identifies this type of peripheral. This can be queried from lua by calling {@code peripheral.getType()}
* *
@@ -42,7 +43,8 @@ public interface IPeripheral {
* @param computer The interface to the computer that is being attached. Remember that multiple computers can be attached to a peripheral at once. * @param computer The interface to the computer that is being attached. Remember that multiple computers can be attached to a peripheral at once.
* @see #detach * @see #detach
*/ */
default void attach(@Nonnull IComputerAccess computer) { default void attach( @Nonnull IComputerAccess computer )
{
} }
/** /**
@@ -58,7 +60,8 @@ public interface IPeripheral {
* @param computer The interface to the computer that is being detached. Remember that multiple computers can be attached to a peripheral at once. * @param computer The interface to the computer that is being detached. Remember that multiple computers can be attached to a peripheral at once.
* @see #attach * @see #attach
*/ */
default void detach(@Nonnull IComputerAccess computer) { default void detach( @Nonnull IComputerAccess computer )
{
} }
/** /**
@@ -67,7 +70,8 @@ public interface IPeripheral {
* @return The object this peripheral targets * @return The object this peripheral targets
*/ */
@Nullable @Nullable
default Object getTarget() { default Object getTarget()
{
return null; return null;
} }
@@ -80,5 +84,5 @@ public interface IPeripheral {
* @param other The peripheral to compare against. This may be {@code null}. * @param other The peripheral to compare against. This may be {@code null}.
* @return Whether these peripherals are equivalent. * @return Whether these peripherals are equivalent.
*/ */
boolean equals(@Nullable IPeripheral other); boolean equals( @Nullable IPeripheral other );
} }

View File

@@ -6,15 +6,14 @@
package dan200.computercraft.api.peripheral; package dan200.computercraft.api.peripheral;
import java.util.Optional;
import javax.annotation.Nonnull;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.Optional;
/** /**
* This interface is used to create peripheral implementations for blocks. * This interface is used to create peripheral implementations for blocks.
* *
@@ -23,16 +22,17 @@ import net.minecraft.world.World;
* @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider) * @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
*/ */
@FunctionalInterface @FunctionalInterface
public interface IPeripheralProvider { public interface IPeripheralProvider
{
/** /**
* Produce an peripheral implementation from a block location. * Produce an peripheral implementation from a block location.
* *
* @param world The world the block is in. * @param world The world the block is in.
* @param pos The position the block is at. * @param pos The position the block is at.
* @param side The side to get the peripheral from. * @param side The side to get the peripheral from.
* @return A peripheral, or {@link Optional#empty()} if there is not a peripheral here you'd like to handle. * @return A peripheral, or {@link Optional#empty()} if there is not a peripheral here you'd like to handle.
* @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider) * @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
*/ */
@Nonnull @Nonnull
IPeripheral getPeripheral(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side); IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
} }

View File

@@ -1,24 +1,24 @@
/* /*
* This file is part of the public ComputerCraft API - http://www.computercraft.info * 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. * Copyright Daniel Ratcliffe, 2011-2021. 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. * For help using the API, and posting your mods, visit the forums at computercraft.info.
*/ */
package dan200.computercraft.api.peripheral; package dan200.computercraft.api.peripheral;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* A {@link net.minecraft.block.entity.BlockEntity} which may act as a peripheral. * A {@link net.minecraft.block.entity.BlockEntity} which may act as a peripheral.
* *
* If you need more complex capabilities (such as handling TEs not belonging to your mod), you should use {@link IPeripheralProvider}. * If you need more complex capabilities (such as handling TEs not belonging to your mod), you should use {@link IPeripheralProvider}.
*/ */
public interface IPeripheralTile { public interface IPeripheralTile
{
/** /**
* Get the peripheral on the given {@code side}. * Get the peripheral on the given {@code side}.
* *
@@ -27,5 +27,5 @@ public interface IPeripheralTile {
* @see IPeripheralProvider#getPeripheral(World, BlockPos, Direction) * @see IPeripheralProvider#getPeripheral(World, BlockPos, Direction)
*/ */
@Nullable @Nullable
IPeripheral getPeripheral(@Nonnull Direction side); IPeripheral getPeripheral( @Nonnull Direction side );
} }

View File

@@ -6,11 +6,10 @@
package dan200.computercraft.api.peripheral; package dan200.computercraft.api.peripheral;
import javax.annotation.Nonnull;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
/** /**
* Monitors "work" associated with a computer, keeping track of how much a computer has done, and ensuring every computer receives a fair share of any * Monitors "work" associated with a computer, keeping track of how much a computer has done, and ensuring every computer receives a fair share of any
* processing time. * processing time.
@@ -25,7 +24,8 @@ import javax.annotation.Nonnull;
* *
* @see IComputerAccess#getMainThreadMonitor() * @see IComputerAccess#getMainThreadMonitor()
*/ */
public interface IWorkMonitor { public interface IWorkMonitor
{
/** /**
* If the owning computer is currently allowed to execute work, and has ample time to do so. * If the owning computer is currently allowed to execute work, and has ample time to do so.
* *
@@ -42,17 +42,22 @@ public interface IWorkMonitor {
* @param runnable The task to run. * @param runnable The task to run.
* @return If the task was actually run (namely, {@link #canWork()} returned {@code true}). * @return If the task was actually run (namely, {@link #canWork()} returned {@code true}).
*/ */
default boolean runWork(@Nonnull Runnable runnable) { default boolean runWork( @Nonnull Runnable runnable )
Objects.requireNonNull(runnable, "runnable should not be null"); {
if (!this.canWork()) { Objects.requireNonNull( runnable, "runnable should not be null" );
if( !this.canWork() )
{
return false; return false;
} }
long start = System.nanoTime(); long start = System.nanoTime();
try { try
{
runnable.run(); runnable.run();
} finally { }
this.trackWork(System.nanoTime() - start, TimeUnit.NANOSECONDS); finally
{
this.trackWork( System.nanoTime() - start, TimeUnit.NANOSECONDS );
} }
return true; return true;
@@ -71,5 +76,5 @@ public interface IWorkMonitor {
* @param time The time some task took to run * @param time The time some task took to run
* @param unit The unit that {@code time} was measured in. * @param unit The unit that {@code time} was measured in.
*/ */
void trackWork(long time, @Nonnull TimeUnit unit); void trackWork( long time, @Nonnull TimeUnit unit );
} }

View File

@@ -9,14 +9,17 @@ package dan200.computercraft.api.peripheral;
/** /**
* Thrown when performing operations on {@link IComputerAccess} when the current peripheral is no longer attached to the computer. * Thrown when performing operations on {@link IComputerAccess} when the current peripheral is no longer attached to the computer.
*/ */
public class NotAttachedException extends IllegalStateException { public class NotAttachedException extends IllegalStateException
{
private static final long serialVersionUID = 1221244785535553536L; private static final long serialVersionUID = 1221244785535553536L;
public NotAttachedException() { public NotAttachedException()
super("You are not attached to this computer"); {
super( "You are not attached to this computer" );
} }
public NotAttachedException(String s) { public NotAttachedException( String s )
super(s); {
super( s );
} }
} }

View File

@@ -6,34 +6,38 @@
package dan200.computercraft.api.pocket; package dan200.computercraft.api.pocket;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemConvertible;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import javax.annotation.Nonnull;
/** /**
* A base class for {@link IPocketUpgrade}s. * A base class for {@link IPocketUpgrade}s.
* *
* One does not have to use this, but it does provide a convenient template. * One does not have to use this, but it does provide a convenient template.
*/ */
public abstract class AbstractPocketUpgrade implements IPocketUpgrade { public abstract class AbstractPocketUpgrade implements IPocketUpgrade
{
private final Identifier id; private final Identifier id;
private final String adjective; private final String adjective;
private final ItemStack stack; private final ItemStack stack;
protected AbstractPocketUpgrade(Identifier id, ItemConvertible item) { protected AbstractPocketUpgrade( Identifier id, ItemConvertible item )
this(id, Util.createTranslationKey("upgrade", id) + ".adjective", item); {
this( id, Util.createTranslationKey( "upgrade", id ) + ".adjective", item );
} }
protected AbstractPocketUpgrade(Identifier id, String adjective, ItemConvertible item) { protected AbstractPocketUpgrade( Identifier id, String adjective, ItemConvertible item )
{
this.id = id; this.id = id;
this.adjective = adjective; this.adjective = adjective;
this.stack = new ItemStack(item); this.stack = new ItemStack( item );
} }
protected AbstractPocketUpgrade(Identifier id, String adjective, ItemStack stack) { protected AbstractPocketUpgrade( Identifier id, String adjective, ItemStack stack )
{
this.id = id; this.id = id;
this.adjective = adjective; this.adjective = adjective;
this.stack = stack; this.stack = stack;
@@ -42,19 +46,22 @@ public abstract class AbstractPocketUpgrade implements IPocketUpgrade {
@Nonnull @Nonnull
@Override @Override
public final Identifier getUpgradeID() { public final Identifier getUpgradeID()
{
return this.id; return this.id;
} }
@Nonnull @Nonnull
@Override @Override
public final String getUnlocalisedAdjective() { public final String getUnlocalisedAdjective()
{
return this.adjective; return this.adjective;
} }
@Nonnull @Nonnull
@Override @Override
public final ItemStack getCraftingItem() { public final ItemStack getCraftingItem()
{
return this.stack; return this.stack;
} }
} }

View File

@@ -6,21 +6,20 @@
package dan200.computercraft.api.pocket; package dan200.computercraft.api.pocket;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
/** /**
* Wrapper class for pocket computers. * Wrapper class for pocket computers.
*/ */
public interface IPocketAccess { public interface IPocketAccess
{
/** /**
* Gets the entity holding this item. * Gets the entity holding this item.
* *
@@ -43,10 +42,10 @@ public interface IPocketAccess {
* Set the colour of the pocket computer to a RGB number. * Set the colour of the pocket computer to a RGB number.
* *
* @param colour The colour this pocket computer should be changed to. This should be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or * @param colour The colour this pocket computer should be changed to. This should be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or
* -1 to reset to the default colour. * -1 to reset to the default colour.
* @see #getColour() * @see #getColour()
*/ */
void setColour(int colour); void setColour( int colour );
/** /**
* Get the colour of this pocket computer's light as a RGB number. * Get the colour of this pocket computer's light as a RGB number.
@@ -60,10 +59,10 @@ public interface IPocketAccess {
* Set the colour of the pocket computer's light to a RGB number. * Set the colour of the pocket computer's light to a RGB number.
* *
* @param colour The colour this modem's light will be changed to. This should be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or -1 * @param colour The colour this modem's light will be changed to. This should be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or -1
* to reset to the default colour. * to reset to the default colour.
* @see #getLight() * @see #getLight()
*/ */
void setLight(int colour); void setLight( int colour );
/** /**
* Get the upgrade-specific NBT. * Get the upgrade-specific NBT.

View File

@@ -6,15 +6,14 @@
package dan200.computercraft.api.pocket; package dan200.computercraft.api.pocket;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.IUpgradeBase; import dan200.computercraft.api.IUpgradeBase;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* Additional peripherals for pocket computers. * Additional peripherals for pocket computers.
* *
@@ -33,29 +32,31 @@ public interface IPocketUpgrade extends IUpgradeBase
* @see #update(IPocketAccess, IPeripheral) * @see #update(IPocketAccess, IPeripheral)
*/ */
@Nullable @Nullable
IPeripheral createPeripheral(@Nonnull IPocketAccess access); IPeripheral createPeripheral( @Nonnull IPocketAccess access );
/** /**
* Called when the pocket computer item stack updates. * Called when the pocket computer item stack updates.
* *
* @param access The access object for the pocket item stack. * @param access The access object for the pocket item stack.
* @param peripheral The peripheral for this upgrade. * @param peripheral The peripheral for this upgrade.
* @see #createPeripheral(IPocketAccess) * @see #createPeripheral(IPocketAccess)
*/ */
default void update(@Nonnull IPocketAccess access, @Nullable IPeripheral peripheral) { default void update( @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral )
{
} }
/** /**
* Called when the pocket computer is right clicked. * Called when the pocket computer is right clicked.
* *
* @param world The world the computer is in. * @param world The world the computer is in.
* @param access The access object for the pocket item stack. * @param access The access object for the pocket item stack.
* @param peripheral The peripheral for this upgrade. * @param peripheral The peripheral for this upgrade.
* @return {@code true} to stop the GUI from opening, otherwise false. You should always provide some code path which returns {@code false}, such as * @return {@code true} to stop the GUI from opening, otherwise false. You should always provide some code path which returns {@code false}, such as
* requiring the player to be sneaking - otherwise they will be unable to access the GUI. * requiring the player to be sneaking - otherwise they will be unable to access the GUI.
* @see #createPeripheral(IPocketAccess) * @see #createPeripheral(IPocketAccess)
*/ */
default boolean onRightClick(@Nonnull World world, @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral) { default boolean onRightClick( @Nonnull World world, @Nonnull IPocketAccess access, @Nullable IPeripheral peripheral )
{
return false; return false;
} }
} }

View File

@@ -6,27 +6,28 @@
package dan200.computercraft.api.redstone; package dan200.computercraft.api.redstone;
import javax.annotation.Nonnull;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
/** /**
* This interface is used to provide bundled redstone output for blocks. * This interface is used to provide bundled redstone output for blocks.
* *
* @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider) * @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider)
*/ */
@FunctionalInterface @FunctionalInterface
public interface IBundledRedstoneProvider { public interface IBundledRedstoneProvider
{
/** /**
* Produce an bundled redstone output from a block location. * Produce an bundled redstone output from a block location.
* *
* @param world The world this block is in. * @param world The world this block is in.
* @param pos The position this block is at. * @param pos The position this block is at.
* @param side The side to extract the bundled redstone output from. * @param side The side to extract the bundled redstone output from.
* @return A number in the range 0-65535 to indicate this block is providing output, or -1 if you do not wish to handle this block. * @return A number in the range 0-65535 to indicate this block is providing output, or -1 if you do not wish to handle this block.
* @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider) * @see dan200.computercraft.api.ComputerCraftAPI#registerBundledRedstoneProvider(IBundledRedstoneProvider)
*/ */
int getBundledRedstoneOutput(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side); int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
} }

View File

@@ -6,65 +6,74 @@
package dan200.computercraft.api.turtle; package dan200.computercraft.api.turtle;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemConvertible;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import javax.annotation.Nonnull;
/** /**
* A base class for {@link ITurtleUpgrade}s. * A base class for {@link ITurtleUpgrade}s.
* *
* One does not have to use this, but it does provide a convenient template. * One does not have to use this, but it does provide a convenient template.
*/ */
public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade { public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
{
private final Identifier id; private final Identifier id;
private final TurtleUpgradeType type; private final TurtleUpgradeType type;
private final String adjective; private final String adjective;
private final ItemStack stack; private final ItemStack stack;
protected AbstractTurtleUpgrade(Identifier id, TurtleUpgradeType type, String adjective, ItemConvertible item) { protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, String adjective, ItemConvertible item )
this(id, type, adjective, new ItemStack(item)); {
this( id, type, adjective, new ItemStack( item ) );
} }
protected AbstractTurtleUpgrade(Identifier id, TurtleUpgradeType type, String adjective, ItemStack stack) { protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, String adjective, ItemStack stack )
{
this.id = id; this.id = id;
this.type = type; this.type = type;
this.adjective = adjective; this.adjective = adjective;
this.stack = stack; this.stack = stack;
} }
protected AbstractTurtleUpgrade(Identifier id, TurtleUpgradeType type, ItemConvertible item) { protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, ItemConvertible item )
this(id, type, new ItemStack(item)); {
this( id, type, new ItemStack( item ) );
} }
protected AbstractTurtleUpgrade(Identifier id, TurtleUpgradeType type, ItemStack stack) { protected AbstractTurtleUpgrade( Identifier id, TurtleUpgradeType type, ItemStack stack )
this(id, type, Util.createTranslationKey("upgrade", id) + ".adjective", stack); {
this( id, type, Util.createTranslationKey( "upgrade", id ) + ".adjective", stack );
} }
@Nonnull @Nonnull
@Override @Override
public final Identifier getUpgradeID() { public final Identifier getUpgradeID()
{
return this.id; return this.id;
} }
@Nonnull @Nonnull
@Override @Override
public final String getUnlocalisedAdjective() { public final String getUnlocalisedAdjective()
{
return this.adjective; return this.adjective;
} }
@Nonnull @Nonnull
@Override @Override
public final TurtleUpgradeType getType() { public final TurtleUpgradeType getType()
{
return this.type; return this.type;
} }
@Nonnull @Nonnull
@Override @Override
public final ItemStack getCraftingItem() { public final ItemStack getCraftingItem()
{
return this.stack; return this.stack;
} }
} }

View File

@@ -1,23 +1,14 @@
/* /*
* This file is part of ComputerCraft - http://www.computercraft.info * This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission. * Copyright Daniel Ratcliffe, 2011-2021. This API may be redistributed unmodified and in full only.
* Send enquiries to dratcliffe@gmail.com * For help using the API, and posting your mods, visit the forums at computercraft.info.
*/ */
package dan200.computercraft.api.turtle; package dan200.computercraft.api.turtle;
import java.util.Collection;
import java.util.OptionalInt;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.crypto.Cipher;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.block.entity.CommandBlockBlockEntity; import net.minecraft.block.entity.CommandBlockBlockEntity;
import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.block.entity.SignBlockEntity;
import net.minecraft.command.argument.EntityAnchorArgumentType; import net.minecraft.command.argument.EntityAnchorArgumentType;
@@ -27,11 +18,7 @@ import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.passive.HorseBaseEntity; import net.minecraft.entity.passive.HorseBaseEntity;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.ClientConnection; import net.minecraft.network.*;
import net.minecraft.network.MessageType;
import net.minecraft.network.NetworkSide;
import net.minecraft.network.NetworkState;
import net.minecraft.network.Packet;
import net.minecraft.network.packet.c2s.play.RequestCommandCompletionsC2SPacket; import net.minecraft.network.packet.c2s.play.RequestCommandCompletionsC2SPacket;
import net.minecraft.network.packet.c2s.play.VehicleMoveC2SPacket; import net.minecraft.network.packet.c2s.play.VehicleMoveC2SPacket;
import net.minecraft.recipe.Recipe; import net.minecraft.recipe.Recipe;
@@ -51,217 +38,319 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.village.TradeOfferList; import net.minecraft.village.TradeOfferList;
import net.minecraft.world.GameMode; import net.minecraft.world.GameMode;
import javax.annotation.Nullable;
import javax.crypto.Cipher;
import java.util.Collection;
import java.util.OptionalInt;
import java.util.UUID;
/** /**
* A wrapper for {@link ServerPlayerEntity} which denotes a "fake" player. * A wrapper for {@link ServerPlayerEntity} which denotes a "fake" player.
* *
* Please note that this does not implement any of the traditional fake player behaviour. It simply exists to prevent me passing in normal players. * Please note that this does not implement any of the traditional fake player behaviour. It simply exists to prevent me passing in normal players.
*/ */
public class FakePlayer extends ServerPlayerEntity { public class FakePlayer extends ServerPlayerEntity
public FakePlayer(ServerWorld world, GameProfile gameProfile) { {
super(world.getServer(), world, gameProfile, new ServerPlayerInteractionManager(world)); public FakePlayer( ServerWorld world, GameProfile gameProfile )
this.networkHandler = new FakeNetHandler(this); {
super( world.getServer(), world, gameProfile, new ServerPlayerInteractionManager( world ) );
this.networkHandler = new FakeNetHandler( this );
} }
// region Direct networkHandler access // region Direct networkHandler access
@Override @Override
public void enterCombat() { } public void enterCombat()
{
}
@Override @Override
public void endCombat() { } public void endCombat()
{
}
@Override @Override
public void tick() { } public void tick()
{
}
@Override @Override
public void playerTick() { } public void playerTick()
{
}
@Override @Override
public void onDeath(DamageSource damage) { } public void onDeath( DamageSource damage )
{
}
@Override @Override
public Entity moveToWorld(ServerWorld destination) { public Entity moveToWorld( ServerWorld destination )
{
return this; return this;
} }
@Override @Override
public void wakeUp(boolean bl, boolean updateSleepingPlayers) { public void wakeUp( boolean bl, boolean updateSleepingPlayers )
{
} }
@Override @Override
public boolean startRiding(Entity entity, boolean flag) { public boolean startRiding( Entity entity, boolean flag )
{
return false; return false;
} }
@Override @Override
public void stopRiding() { } public void stopRiding()
{
}
@Override @Override
public void openEditSignScreen(SignBlockEntity tile) { } public void openEditSignScreen( SignBlockEntity tile )
{
}
@Override @Override
public OptionalInt openHandledScreen(@Nullable NamedScreenHandlerFactory container) { public OptionalInt openHandledScreen( @Nullable NamedScreenHandlerFactory container )
{
return OptionalInt.empty(); return OptionalInt.empty();
} }
@Override @Override
public void sendTradeOffers(int id, TradeOfferList list, int level, int experience, boolean levelled, boolean refreshable) { } public void sendTradeOffers( int id, TradeOfferList list, int level, int experience, boolean levelled, boolean refreshable )
{
}
@Override @Override
public void openHorseInventory(HorseBaseEntity horse, Inventory inventory) { } public void openHorseInventory( HorseBaseEntity horse, Inventory inventory )
{
}
@Override @Override
public void openEditBookScreen(ItemStack stack, Hand hand) { } public void openEditBookScreen( ItemStack stack, Hand hand )
{
}
@Override @Override
public void openCommandBlockScreen(CommandBlockBlockEntity block) { } public void openCommandBlockScreen( CommandBlockBlockEntity block )
{
}
@Override @Override
public void onSlotUpdate(ScreenHandler container, int slot, ItemStack stack) { } public void onSlotUpdate( ScreenHandler container, int slot, ItemStack stack )
{
}
@Override @Override
public void onHandlerRegistered(ScreenHandler container, DefaultedList<ItemStack> defaultedList) { } public void onHandlerRegistered( ScreenHandler container, DefaultedList<ItemStack> defaultedList )
{
}
@Override @Override
public void onPropertyUpdate(ScreenHandler container, int key, int value) { } public void onPropertyUpdate( ScreenHandler container, int key, int value )
{
}
@Override @Override
public void closeHandledScreen() { } public void closeHandledScreen()
{
}
@Override @Override
public void updateCursorStack() { } public void updateCursorStack()
{
}
@Override @Override
public int unlockRecipes(Collection<Recipe<?>> recipes) { public int unlockRecipes( Collection<Recipe<?>> recipes )
{
return 0; return 0;
} }
// Indirect // Indirect
@Override @Override
public int lockRecipes(Collection<Recipe<?>> recipes) { public int lockRecipes( Collection<Recipe<?>> recipes )
{
return 0; return 0;
} }
@Override @Override
public void sendMessage(Text textComponent, boolean status) { } public void sendMessage( Text textComponent, boolean status )
{
}
@Override @Override
protected void consumeItem() { } protected void consumeItem()
{
}
@Override @Override
public void lookAt(EntityAnchorArgumentType.EntityAnchor anchor, Vec3d vec3d) {} public void lookAt( EntityAnchorArgumentType.EntityAnchor anchor, Vec3d vec3d )
{
}
@Override @Override
public void method_14222(EntityAnchorArgumentType.EntityAnchor self, Entity entity, EntityAnchorArgumentType.EntityAnchor target) { } public void method_14222( EntityAnchorArgumentType.EntityAnchor self, Entity entity, EntityAnchorArgumentType.EntityAnchor target )
{
}
@Override @Override
protected void onStatusEffectApplied(StatusEffectInstance statusEffectInstance) { } protected void onStatusEffectApplied( StatusEffectInstance statusEffectInstance )
{
}
@Override @Override
protected void onStatusEffectUpgraded(StatusEffectInstance statusEffectInstance, boolean particles) { } protected void onStatusEffectUpgraded( StatusEffectInstance statusEffectInstance, boolean particles )
{
}
@Override @Override
protected void onStatusEffectRemoved(StatusEffectInstance statusEffectInstance) { } protected void onStatusEffectRemoved( StatusEffectInstance statusEffectInstance )
{
}
@Override @Override
public void requestTeleport(double x, double y, double z) { } public void requestTeleport( double x, double y, double z )
{
}
@Override @Override
public void setGameMode(GameMode gameMode) { } public void setGameMode( GameMode gameMode )
{
}
@Override @Override
public void sendMessage(Text message, MessageType type, UUID senderUuid) { public void sendMessage( Text message, MessageType type, UUID senderUuid )
{
} }
@Override @Override
public String getIp() { public String getIp()
{
return "[Fake Player]"; return "[Fake Player]";
} }
@Override @Override
public void sendResourcePackUrl(String url, String hash) { } public void sendResourcePackUrl( String url, String hash )
{
@Override
public void onStoppedTracking(Entity entity) { }
@Override
public void setCameraEntity(Entity entity) { }
@Override
public void teleport(ServerWorld serverWorld, double x, double y, double z, float pitch, float yaw) { }
@Override
public void sendInitialChunkPackets(ChunkPos chunkPos, Packet<?> packet, Packet<?> packet2) { }
@Override
public void sendUnloadChunkPacket(ChunkPos chunkPos) { }
@Override
public void playSound(SoundEvent soundEvent, SoundCategory soundCategory, float volume, float pitch) { }
private static class FakeNetHandler extends ServerPlayNetworkHandler {
FakeNetHandler(ServerPlayerEntity player) {
super(player.server, new FakeConnection(), player);
}
@Override
public void disconnect(Text message) { }
@Override
public void onVehicleMove(VehicleMoveC2SPacket move) { }
@Override
public void onRequestCommandCompletions(RequestCommandCompletionsC2SPacket packet) { }
@Override
public void sendPacket(Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> listener) { }
} }
private static class FakeConnection extends ClientConnection { @Override
FakeConnection() { public void onStoppedTracking( Entity entity )
super(NetworkSide.CLIENTBOUND); {
}
@Override
public void setCameraEntity( Entity entity )
{
}
@Override
public void teleport( ServerWorld serverWorld, double x, double y, double z, float pitch, float yaw )
{
}
@Override
public void sendInitialChunkPackets( ChunkPos chunkPos, Packet<?> packet, Packet<?> packet2 )
{
}
@Override
public void sendUnloadChunkPacket( ChunkPos chunkPos )
{
}
@Override
public void playSound( SoundEvent soundEvent, SoundCategory soundCategory, float volume, float pitch )
{
}
private static class FakeNetHandler extends ServerPlayNetworkHandler
{
FakeNetHandler( ServerPlayerEntity player )
{
super( player.server, new FakeConnection(), player );
} }
@Override @Override
public void channelActive(ChannelHandlerContext active) { public void disconnect( Text message )
{
} }
@Override @Override
public void setState(NetworkState state) { public void onVehicleMove( VehicleMoveC2SPacket move )
{
} }
@Override @Override
public void exceptionCaught(ChannelHandlerContext context, Throwable err) { public void onRequestCommandCompletions( RequestCommandCompletionsC2SPacket packet )
{
} }
@Override @Override
protected void channelRead0(ChannelHandlerContext context, Packet<?> packet) { public void sendPacket( Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> listener )
{
}
}
private static class FakeConnection extends ClientConnection
{
FakeConnection()
{
super( NetworkSide.CLIENTBOUND );
} }
@Override @Override
public void send(Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> listener) { public void channelActive( ChannelHandlerContext active )
{
} }
@Override @Override
public void tick() { public void setState( NetworkState state )
{
} }
@Override @Override
public void disconnect(Text message) { public void exceptionCaught( ChannelHandlerContext context, Throwable err )
{
} }
@Override @Override
public void setupEncryption(Cipher cipher, Cipher cipher2) { protected void channelRead0( ChannelHandlerContext context, Packet<?> packet )
super.setupEncryption(cipher, cipher2); {
} }
@Override @Override
public void disableAutoRead() { public void send( Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> listener )
{
} }
@Override @Override
public void setCompressionThreshold(int size) { public void tick()
{
}
@Override
public void disconnect( Text message )
{
}
@Override
public void setupEncryption( Cipher cipher, Cipher cipher2 )
{
super.setupEncryption( cipher, cipher2 );
}
@Override
public void disableAutoRead()
{
}
@Override
public void setCompressionThreshold( int size )
{
} }
} }
} }

View File

@@ -6,15 +6,11 @@
package dan200.computercraft.api.turtle; package dan200.computercraft.api.turtle;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import dan200.computercraft.api.lua.ILuaCallback; import dan200.computercraft.api.lua.ILuaCallback;
import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.lua.MethodResult;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.util.ItemStorage; import dan200.computercraft.shared.util.ItemStorage;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -22,12 +18,16 @@ import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* The interface passed to turtle by turtles, providing methods that they can call. * The interface passed to turtle by turtles, providing methods that they can call.
* *
* This should not be implemented by your classes. Do not interact with turtles except via this interface and {@link ITurtleUpgrade}. * This should not be implemented by your classes. Do not interact with turtles except via this interface and {@link ITurtleUpgrade}.
*/ */
public interface ITurtleAccess { public interface ITurtleAccess
{
/** /**
* Returns the world in which the turtle resides. * Returns the world in which the turtle resides.
* *
@@ -51,11 +51,11 @@ public interface ITurtleAccess {
* using {@link #playAnimation(TurtleAnimation)}. * using {@link #playAnimation(TurtleAnimation)}.
* *
* @param world The new world to move it to * @param world The new world to move it to
* @param pos The new position to move it to. * @param pos The new position to move it to.
* @return Whether the movement was successful. It may fail if the block was not loaded or the block placement was cancelled. * @return Whether the movement was successful. It may fail if the block was not loaded or the block placement was cancelled.
* @throws UnsupportedOperationException When attempting to teleport on the client side. * @throws UnsupportedOperationException When attempting to teleport on the client side.
*/ */
boolean teleportTo(@Nonnull World world, @Nonnull BlockPos pos); boolean teleportTo( @Nonnull World world, @Nonnull BlockPos pos );
/** /**
* Returns a vector containing the floating point co-ordinates at which the turtle is rendered. This will shift when the turtle is moving. * Returns a vector containing the floating point co-ordinates at which the turtle is rendered. This will shift when the turtle is moving.
@@ -65,7 +65,7 @@ public interface ITurtleAccess {
* @see #getVisualYaw(float) * @see #getVisualYaw(float)
*/ */
@Nonnull @Nonnull
Vec3d getVisualPosition(float f); Vec3d getVisualPosition( float f );
/** /**
* Returns the yaw the turtle is facing when it is rendered. * Returns the yaw the turtle is facing when it is rendered.
@@ -74,7 +74,7 @@ public interface ITurtleAccess {
* @return The yaw the turtle is facing. * @return The yaw the turtle is facing.
* @see #getVisualPosition(float) * @see #getVisualPosition(float)
*/ */
float getVisualYaw(float f); float getVisualYaw( float f );
/** /**
* Returns the world direction the turtle is currently facing. * Returns the world direction the turtle is currently facing.
@@ -92,7 +92,7 @@ public interface ITurtleAccess {
* @param dir The new direction to set. This should be on either the x or z axis (so north, south, east or west). * @param dir The new direction to set. This should be on either the x or z axis (so north, south, east or west).
* @see #getDirection() * @see #getDirection()
*/ */
void setDirection(@Nonnull Direction dir); void setDirection( @Nonnull Direction dir );
/** /**
* Get the currently selected slot in the turtle's inventory. * Get the currently selected slot in the turtle's inventory.
@@ -111,7 +111,7 @@ public interface ITurtleAccess {
* @see #getInventory() * @see #getInventory()
* @see #getSelectedSlot() * @see #getSelectedSlot()
*/ */
void setSelectedSlot(int slot); void setSelectedSlot( int slot );
/** /**
* Get the colour of this turtle as a RGB number. * Get the colour of this turtle as a RGB number.
@@ -125,10 +125,10 @@ public interface ITurtleAccess {
* Set the colour of the turtle to a RGB number. * Set the colour of the turtle to a RGB number.
* *
* @param colour The colour this turtle should be changed to. This should be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or -1 to * @param colour The colour this turtle should be changed to. This should be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or -1 to
* reset to the default colour. * reset to the default colour.
* @see #getColour() * @see #getColour()
*/ */
void setColour(int colour); void setColour( int colour );
/** /**
* Get the player who owns this turtle, namely whoever placed it. * Get the player who owns this turtle, namely whoever placed it.
@@ -165,7 +165,7 @@ public interface ITurtleAccess {
* @see #addFuel(int) * @see #addFuel(int)
* @see #consumeFuel(int) * @see #consumeFuel(int)
*/ */
void setFuelLevel(int fuel); void setFuelLevel( int fuel );
/** /**
* Get the maximum amount of fuel a turtle can hold. * Get the maximum amount of fuel a turtle can hold.
@@ -179,10 +179,10 @@ public interface ITurtleAccess {
* *
* @param fuel The amount of fuel to consume. * @param fuel The amount of fuel to consume.
* @return Whether the turtle was able to consume the amount of fuel specified. Will return false if you supply a number greater than the current fuel * @return Whether the turtle was able to consume the amount of fuel specified. Will return false if you supply a number greater than the current fuel
* level of the turtle. No fuel will be consumed if {@code false} is returned. * level of the turtle. No fuel will be consumed if {@code false} is returned.
* @throws UnsupportedOperationException When attempting to consume fuel on the client side. * @throws UnsupportedOperationException When attempting to consume fuel on the client side.
*/ */
boolean consumeFuel(int fuel); boolean consumeFuel( int fuel );
/** /**
* Increase the turtle's fuel level by the given amount. * Increase the turtle's fuel level by the given amount.
@@ -190,7 +190,7 @@ public interface ITurtleAccess {
* @param fuel The amount to refuel with. * @param fuel The amount to refuel with.
* @throws UnsupportedOperationException When attempting to refuel on the client side. * @throws UnsupportedOperationException When attempting to refuel on the client side.
*/ */
void addFuel(int fuel); void addFuel( int fuel );
/** /**
* Adds a custom command to the turtles command queue. Unlike peripheral methods, these custom commands will be executed on the main thread, so are * Adds a custom command to the turtles command queue. Unlike peripheral methods, these custom commands will be executed on the main thread, so are
@@ -205,7 +205,7 @@ public interface ITurtleAccess {
* @see MethodResult#pullEvent(String, ILuaCallback) * @see MethodResult#pullEvent(String, ILuaCallback)
*/ */
@Nonnull @Nonnull
MethodResult executeCommand(@Nonnull ITurtleCommand command); MethodResult executeCommand( @Nonnull ITurtleCommand command );
/** /**
* Start playing a specific animation. This will prevent other turtle commands from executing until it is finished. * Start playing a specific animation. This will prevent other turtle commands from executing until it is finished.
@@ -214,7 +214,7 @@ public interface ITurtleAccess {
* @throws UnsupportedOperationException When attempting to execute play an animation on the client side. * @throws UnsupportedOperationException When attempting to execute play an animation on the client side.
* @see TurtleAnimation * @see TurtleAnimation
*/ */
void playAnimation(@Nonnull TurtleAnimation animation); void playAnimation( @Nonnull TurtleAnimation animation );
/** /**
* Returns the turtle on the specified side of the turtle, if there is one. * Returns the turtle on the specified side of the turtle, if there is one.
@@ -224,16 +224,16 @@ public interface ITurtleAccess {
* @see #setUpgrade(TurtleSide, ITurtleUpgrade) * @see #setUpgrade(TurtleSide, ITurtleUpgrade)
*/ */
@Nullable @Nullable
ITurtleUpgrade getUpgrade(@Nonnull TurtleSide side); ITurtleUpgrade getUpgrade( @Nonnull TurtleSide side );
/** /**
* Set the upgrade for a given side, resetting peripherals and clearing upgrade specific data. * Set the upgrade for a given side, resetting peripherals and clearing upgrade specific data.
* *
* @param side The side to set the upgrade on. * @param side The side to set the upgrade on.
* @param upgrade The upgrade to set, may be {@code null} to clear. * @param upgrade The upgrade to set, may be {@code null} to clear.
* @see #getUpgrade(TurtleSide) * @see #getUpgrade(TurtleSide)
*/ */
void setUpgrade(@Nonnull TurtleSide side, @Nullable ITurtleUpgrade upgrade); void setUpgrade( @Nonnull TurtleSide side, @Nullable ITurtleUpgrade upgrade );
/** /**
* Returns the peripheral created by the upgrade on the specified side of the turtle, if there is one. * Returns the peripheral created by the upgrade on the specified side of the turtle, if there is one.
@@ -242,7 +242,7 @@ public interface ITurtleAccess {
* @return The peripheral created by the upgrade on the specified side of the turtle, {@code null} if none exists. * @return The peripheral created by the upgrade on the specified side of the turtle, {@code null} if none exists.
*/ */
@Nullable @Nullable
IPeripheral getPeripheral(@Nonnull TurtleSide side); IPeripheral getPeripheral( @Nonnull TurtleSide side );
/** /**
* Get an upgrade-specific NBT compound, which can be used to store arbitrary data. * Get an upgrade-specific NBT compound, which can be used to store arbitrary data.
@@ -255,7 +255,7 @@ public interface ITurtleAccess {
* @see #updateUpgradeNBTData(TurtleSide) * @see #updateUpgradeNBTData(TurtleSide)
*/ */
@Nonnull @Nonnull
CompoundTag getUpgradeNBTData(@Nullable TurtleSide side); CompoundTag getUpgradeNBTData( @Nullable TurtleSide side );
/** /**
* Mark the upgrade-specific data as dirty on a specific side. This is required for the data to be synced to the client and persisted. * Mark the upgrade-specific data as dirty on a specific side. This is required for the data to be synced to the client and persisted.
@@ -263,10 +263,11 @@ public interface ITurtleAccess {
* @param side The side to mark dirty. * @param side The side to mark dirty.
* @see #updateUpgradeNBTData(TurtleSide) * @see #updateUpgradeNBTData(TurtleSide)
*/ */
void updateUpgradeNBTData(@Nonnull TurtleSide side); void updateUpgradeNBTData( @Nonnull TurtleSide side );
default ItemStorage getItemHandler() { default ItemStorage getItemHandler()
return ItemStorage.wrap(this.getInventory()); {
return ItemStorage.wrap( this.getInventory() );
} }
/** /**

View File

@@ -14,7 +14,8 @@ import javax.annotation.Nonnull;
* @see ITurtleAccess#executeCommand(ITurtleCommand) * @see ITurtleAccess#executeCommand(ITurtleCommand)
*/ */
@FunctionalInterface @FunctionalInterface
public interface ITurtleCommand { public interface ITurtleCommand
{
/** /**
* Will be called by the turtle on the main thread when it is time to execute the custom command. * Will be called by the turtle on the main thread when it is time to execute the custom command.
* *
@@ -29,5 +30,5 @@ public interface ITurtleCommand {
* @see TurtleCommandResult * @see TurtleCommandResult
*/ */
@Nonnull @Nonnull
TurtleCommandResult execute(@Nonnull ITurtleAccess turtle); TurtleCommandResult execute( @Nonnull ITurtleAccess turtle );
} }

View File

@@ -6,18 +6,16 @@
package dan200.computercraft.api.turtle; package dan200.computercraft.api.turtle;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.IUpgradeBase; import dan200.computercraft.api.IUpgradeBase;
import dan200.computercraft.api.client.TransformedModel; import dan200.computercraft.api.client.TransformedModel;
import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraft.util.math.Direction;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.util.math.Direction;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* The primary interface for defining an update for Turtles. A turtle update can either be a new tool, or a new peripheral. * The primary interface for defining an update for Turtles. A turtle update can either be a new tool, or a new peripheral.
@@ -42,28 +40,30 @@ public interface ITurtleUpgrade extends IUpgradeBase
* TurtleSide)}. It will be attached, detached and have methods called in the same manner as a Computer peripheral. * TurtleSide)}. It will be attached, detached and have methods called in the same manner as a Computer peripheral.
* *
* @param turtle Access to the turtle that the peripheral is being created for. * @param turtle Access to the turtle that the peripheral is being created for.
* @param side Which side of the turtle (left or right) that the upgrade resides on. * @param side Which side of the turtle (left or right) that the upgrade resides on.
* @return The newly created peripheral. You may return {@code null} if this upgrade is a Tool and this method is not expected to be called. * @return The newly created peripheral. You may return {@code null} if this upgrade is a Tool and this method is not expected to be called.
*/ */
@Nullable @Nullable
default IPeripheral createPeripheral(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side) { default IPeripheral createPeripheral( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side )
{
return null; return null;
} }
/** /**
* 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. * 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.
* *
* @param turtle Access to the turtle that the tool resides on. * @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. * @param side Which side of the turtle (left or right) the tool resides on.
* @param verb Which action (dig or attack) the turtle is being called on to perform. * @param verb Which action (dig or attack) the turtle is being called on to perform.
* @param direction Which world direction the action should be performed in, relative to the turtles position. This will either be up, down, or the * @param direction Which world direction the action should be performed in, relative to the turtles position. This will either be up, down, or the
* direction the turtle is facing, depending on whether dig, digUp or digDown was called. * direction the turtle is facing, depending on whether dig, digUp or digDown was called.
* @return Whether the turtle was able to perform the action, and hence whether the {@code turtle.dig()} or {@code turtle.attack()} lua method should * @return Whether the turtle was able to perform the action, and hence whether the {@code turtle.dig()} or {@code turtle.attack()} lua method should
* return true. If true is returned, the tool will perform a swinging animation. You may return {@code null} if this turtle is a Peripheral and * return true. If true is returned, the tool will perform a swinging animation. You may return {@code null} if this turtle is a Peripheral and
* this method is not expected to be called. * this method is not expected to be called.
*/ */
@Nonnull @Nonnull
default TurtleCommandResult useTool(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction) { default TurtleCommandResult useTool( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nonnull TurtleVerb verb, @Nonnull Direction direction )
{
return TurtleCommandResult.failure(); return TurtleCommandResult.failure();
} }
@@ -71,19 +71,20 @@ public interface ITurtleUpgrade extends IUpgradeBase
* Called to obtain the model to be used when rendering a turtle peripheral. * Called to obtain the model to be used when rendering a turtle peripheral.
* *
* @param turtle Access to the turtle that the upgrade resides on. This will be null when getting item models! * @param turtle Access to the turtle that the upgrade resides on. This will be null when getting item models!
* @param side Which side of the turtle (left or right) the upgrade resides on. * @param side Which side of the turtle (left or right) the upgrade resides on.
* @return The model that you wish to be used to render your upgrade. * @return The model that you wish to be used to render your upgrade.
*/ */
@Nonnull @Nonnull
@Environment (EnvType.CLIENT) @Environment( EnvType.CLIENT )
TransformedModel getModel(@Nullable ITurtleAccess turtle, @Nonnull TurtleSide side); TransformedModel getModel( @Nullable ITurtleAccess turtle, @Nonnull TurtleSide side );
/** /**
* Called once per tick for each turtle which has the upgrade equipped. * Called once per tick for each turtle which has the upgrade equipped.
* *
* @param turtle Access to the turtle that the upgrade resides on. * @param turtle Access to the turtle that the upgrade resides on.
* @param side Which side of the turtle (left or right) the upgrade resides on. * @param side Which side of the turtle (left or right) the upgrade resides on.
*/ */
default void update(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side) { default void update( @Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side )
{
} }
} }

View File

@@ -13,7 +13,8 @@ package dan200.computercraft.api.turtle;
* *
* @see ITurtleAccess#playAnimation(TurtleAnimation) * @see ITurtleAccess#playAnimation(TurtleAnimation)
*/ */
public enum TurtleAnimation { public enum TurtleAnimation
{
/** /**
* An animation which does nothing. This takes no time to complete. * An animation which does nothing. This takes no time to complete.
* *

View File

@@ -15,14 +15,16 @@ import javax.annotation.Nullable;
* @see ITurtleCommand#execute(ITurtleAccess) * @see ITurtleCommand#execute(ITurtleAccess)
* @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction) * @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction)
*/ */
public final class TurtleCommandResult { public final class TurtleCommandResult
private static final TurtleCommandResult EMPTY_SUCCESS = new TurtleCommandResult(true, null, null); {
private static final TurtleCommandResult EMPTY_FAILURE = new TurtleCommandResult(false, null, null); private static final TurtleCommandResult EMPTY_SUCCESS = new TurtleCommandResult( true, null, null );
private static final TurtleCommandResult EMPTY_FAILURE = new TurtleCommandResult( false, null, null );
private final boolean success; private final boolean success;
private final String errorMessage; private final String errorMessage;
private final Object[] results; private final Object[] results;
private TurtleCommandResult(boolean success, String errorMessage, Object[] results) { private TurtleCommandResult( boolean success, String errorMessage, Object[] results )
{
this.success = success; this.success = success;
this.errorMessage = errorMessage; this.errorMessage = errorMessage;
this.results = results; this.results = results;
@@ -34,7 +36,8 @@ public final class TurtleCommandResult {
* @return A successful command result with no values. * @return A successful command result with no values.
*/ */
@Nonnull @Nonnull
public static TurtleCommandResult success() { public static TurtleCommandResult success()
{
return EMPTY_SUCCESS; return EMPTY_SUCCESS;
} }
@@ -45,11 +48,13 @@ public final class TurtleCommandResult {
* @return A successful command result with the given values. * @return A successful command result with the given values.
*/ */
@Nonnull @Nonnull
public static TurtleCommandResult success(@Nullable Object[] results) { public static TurtleCommandResult success( @Nullable Object[] results )
if (results == null || results.length == 0) { {
if( results == null || results.length == 0 )
{
return EMPTY_SUCCESS; return EMPTY_SUCCESS;
} }
return new TurtleCommandResult(true, null, results); return new TurtleCommandResult( true, null, results );
} }
/** /**
@@ -58,7 +63,8 @@ public final class TurtleCommandResult {
* @return A failed command result with no message. * @return A failed command result with no message.
*/ */
@Nonnull @Nonnull
public static TurtleCommandResult failure() { public static TurtleCommandResult failure()
{
return EMPTY_FAILURE; return EMPTY_FAILURE;
} }
@@ -69,11 +75,13 @@ public final class TurtleCommandResult {
* @return A failed command result with a message. * @return A failed command result with a message.
*/ */
@Nonnull @Nonnull
public static TurtleCommandResult failure(@Nullable String errorMessage) { public static TurtleCommandResult failure( @Nullable String errorMessage )
if (errorMessage == null) { {
if( errorMessage == null )
{
return EMPTY_FAILURE; return EMPTY_FAILURE;
} }
return new TurtleCommandResult(false, errorMessage, null); return new TurtleCommandResult( false, errorMessage, null );
} }
/** /**
@@ -81,7 +89,8 @@ public final class TurtleCommandResult {
* *
* @return If the command was successful. * @return If the command was successful.
*/ */
public boolean isSuccess() { public boolean isSuccess()
{
return this.success; return this.success;
} }
@@ -91,7 +100,8 @@ public final class TurtleCommandResult {
* @return The command's error message, or {@code null} if it was a success. * @return The command's error message, or {@code null} if it was a success.
*/ */
@Nullable @Nullable
public String getErrorMessage() { public String getErrorMessage()
{
return this.errorMessage; return this.errorMessage;
} }
@@ -101,7 +111,8 @@ public final class TurtleCommandResult {
* @return The command's result, or {@code null} if it was a failure. * @return The command's result, or {@code null} if it was a failure.
*/ */
@Nullable @Nullable
public Object[] getResults() { public Object[] getResults()
{
return this.results; return this.results;
} }
} }

View File

@@ -9,7 +9,8 @@ package dan200.computercraft.api.turtle;
/** /**
* An enum representing the two sides of the turtle that a turtle turtle might reside. * An enum representing the two sides of the turtle that a turtle turtle might reside.
*/ */
public enum TurtleSide { 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).
*/ */

View File

@@ -11,7 +11,8 @@ package dan200.computercraft.api.turtle;
* *
* @see ITurtleUpgrade#getType() * @see ITurtleUpgrade#getType()
*/ */
public enum TurtleUpgradeType { public enum TurtleUpgradeType
{
/** /**
* A tool is rendered as an item on the side of the turtle, and responds to the {@code turtle.dig()} and {@code turtle.attack()} methods (Such as * A tool is rendered as an item on the side of the turtle, and responds to the {@code turtle.dig()} and {@code turtle.attack()} methods (Such as
* pickaxe or sword on Mining and Melee turtles). * pickaxe or sword on Mining and Melee turtles).
@@ -30,11 +31,13 @@ public enum TurtleUpgradeType {
*/ */
BOTH; BOTH;
public boolean isTool() { public boolean isTool()
{
return this == TOOL || this == BOTH; return this == TOOL || this == BOTH;
} }
public boolean isPeripheral() { public boolean isPeripheral()
{
return this == PERIPHERAL || this == BOTH; return this == PERIPHERAL || this == BOTH;
} }
} }

View File

@@ -12,7 +12,8 @@ package dan200.computercraft.api.turtle;
* @see ITurtleUpgrade#getType() * @see ITurtleUpgrade#getType()
* @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction) * @see ITurtleUpgrade#useTool(ITurtleAccess, TurtleSide, TurtleVerb, Direction)
*/ */
public enum TurtleVerb { 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()}.
*/ */

View File

@@ -11,7 +11,8 @@ package dan200.computercraft.api.turtle.event;
* *
* @see TurtleActionEvent * @see TurtleActionEvent
*/ */
public enum TurtleAction { public enum TurtleAction
{
/** /**
* A turtle moves to a new position. * A turtle moves to a new position.
* *

View File

@@ -6,30 +6,32 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import java.util.Objects; import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleCommandResult;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Objects;
import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleCommandResult;
/** /**
* An event fired when a turtle is performing a known action. * An event fired when a turtle is performing a known action.
*/ */
public class TurtleActionEvent extends TurtleEvent { public class TurtleActionEvent extends TurtleEvent
{
private final TurtleAction action; private final TurtleAction action;
private String failureMessage; private String failureMessage;
private boolean cancelled = false; private boolean cancelled = false;
public TurtleActionEvent(@Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action) { public TurtleActionEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action )
super(turtle); {
super( turtle );
Objects.requireNonNull(action, "action cannot be null"); Objects.requireNonNull( action, "action cannot be null" );
this.action = action; this.action = action;
} }
public TurtleAction getAction() { public TurtleAction getAction()
{
return this.action; return this.action;
} }
@@ -43,8 +45,9 @@ public class TurtleActionEvent extends TurtleEvent {
* @deprecated Use {@link #setCanceled(boolean, String)} instead. * @deprecated Use {@link #setCanceled(boolean, String)} instead.
*/ */
@Deprecated @Deprecated
public void setCanceled(boolean cancel) { public void setCanceled( boolean cancel )
this.setCanceled(cancel, null); {
this.setCanceled( cancel, null );
} }
/** /**
@@ -52,11 +55,12 @@ public class TurtleActionEvent extends TurtleEvent {
* *
* If {@code cancel} is {@code true}, this action will not be carried out. * If {@code cancel} is {@code true}, this action will not be carried out.
* *
* @param cancel The new canceled value. * @param cancel The new canceled value.
* @param failureMessage The message to return to the user explaining the failure. * @param failureMessage The message to return to the user explaining the failure.
* @see TurtleCommandResult#failure(String) * @see TurtleCommandResult#failure(String)
*/ */
public void setCanceled(boolean cancel, @Nullable String failureMessage) { public void setCanceled( boolean cancel, @Nullable String failureMessage )
{
this.cancelled = true; this.cancelled = true;
this.failureMessage = cancel ? failureMessage : null; this.failureMessage = cancel ? failureMessage : null;
} }
@@ -69,11 +73,13 @@ public class TurtleActionEvent extends TurtleEvent {
* @see #setCanceled(boolean, String) * @see #setCanceled(boolean, String)
*/ */
@Nullable @Nullable
public String getFailureMessage() { public String getFailureMessage()
{
return this.failureMessage; return this.failureMessage;
} }
public boolean isCancelled() { public boolean isCancelled()
{
return this.cancelled; return this.cancelled;
} }
} }

View File

@@ -6,33 +6,33 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import java.util.Objects;
import javax.annotation.Nonnull;
import dan200.computercraft.api.turtle.FakePlayer; import dan200.computercraft.api.turtle.FakePlayer;
import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleSide;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import javax.annotation.Nonnull;
import java.util.Objects;
/** /**
* Fired when a turtle attempts to attack an entity. * Fired when a turtle attempts to attack an entity.
* *
* @see TurtleAction#ATTACK * @see TurtleAction#ATTACK
*/ */
public class TurtleAttackEvent extends TurtlePlayerEvent { public class TurtleAttackEvent extends TurtlePlayerEvent
{
private final Entity target; private final Entity target;
private final ITurtleUpgrade upgrade; private final ITurtleUpgrade upgrade;
private final TurtleSide side; private final TurtleSide side;
public TurtleAttackEvent(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull Entity target, @Nonnull ITurtleUpgrade upgrade, public TurtleAttackEvent( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull Entity target, @Nonnull ITurtleUpgrade upgrade,
@Nonnull TurtleSide side) { @Nonnull TurtleSide side )
super(turtle, TurtleAction.ATTACK, player); {
Objects.requireNonNull(target, "target cannot be null"); super( turtle, TurtleAction.ATTACK, player );
Objects.requireNonNull(upgrade, "upgrade cannot be null"); Objects.requireNonNull( target, "target cannot be null" );
Objects.requireNonNull(side, "side cannot be null"); Objects.requireNonNull( upgrade, "upgrade cannot be null" );
Objects.requireNonNull( side, "side cannot be null" );
this.target = target; this.target = target;
this.upgrade = upgrade; this.upgrade = upgrade;
this.side = side; this.side = side;
@@ -44,7 +44,8 @@ public class TurtleAttackEvent extends TurtlePlayerEvent {
* @return The entity being attacked. * @return The entity being attacked.
*/ */
@Nonnull @Nonnull
public Entity getTarget() { public Entity getTarget()
{
return this.target; return this.target;
} }
@@ -54,7 +55,8 @@ public class TurtleAttackEvent extends TurtlePlayerEvent {
* @return The upgrade responsible for attacking. * @return The upgrade responsible for attacking.
*/ */
@Nonnull @Nonnull
public ITurtleUpgrade getUpgrade() { public ITurtleUpgrade getUpgrade()
{
return this.upgrade; return this.upgrade;
} }
@@ -64,7 +66,8 @@ public class TurtleAttackEvent extends TurtlePlayerEvent {
* @return The upgrade's side. * @return The upgrade's side.
*/ */
@Nonnull @Nonnull
public TurtleSide getSide() { public TurtleSide getSide()
{
return this.side; return this.side;
} }
} }

View File

@@ -6,22 +6,20 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nonnull;
import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.lua.MethodResult;
import dan200.computercraft.api.turtle.FakePlayer; import dan200.computercraft.api.turtle.FakePlayer;
import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.turtle.TurtleSide;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.Map;
import java.util.Objects;
/** /**
* A general event for when a turtle interacts with a block or region. * A general event for when a turtle interacts with a block or region.
* *
@@ -31,16 +29,18 @@ import net.minecraft.world.World;
* *
* Be aware that some events (such as {@link TurtleInventoryEvent}) do not necessarily interact with a block, simply objects within that block space. * Be aware that some events (such as {@link TurtleInventoryEvent}) do not necessarily interact with a block, simply objects within that block space.
*/ */
public abstract class TurtleBlockEvent extends TurtlePlayerEvent { public abstract class TurtleBlockEvent extends TurtlePlayerEvent
{
private final World world; private final World world;
private final BlockPos pos; private final BlockPos pos;
protected TurtleBlockEvent(@Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world, protected TurtleBlockEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world,
@Nonnull BlockPos pos) { @Nonnull BlockPos pos )
super(turtle, action, player); {
super( turtle, action, player );
Objects.requireNonNull(world, "world cannot be null"); Objects.requireNonNull( world, "world cannot be null" );
Objects.requireNonNull(pos, "pos cannot be null"); Objects.requireNonNull( pos, "pos cannot be null" );
this.world = world; this.world = world;
this.pos = pos; this.pos = pos;
} }
@@ -50,7 +50,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* *
* @return The world the turtle is interacting in. * @return The world the turtle is interacting in.
*/ */
public World getWorld() { public World getWorld()
{
return this.world; return this.world;
} }
@@ -59,7 +60,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* *
* @return The position the turtle is interacting with. * @return The position the turtle is interacting with.
*/ */
public BlockPos getPos() { public BlockPos getPos()
{
return this.pos; return this.pos;
} }
@@ -68,18 +70,20 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* *
* @see TurtleAction#DIG * @see TurtleAction#DIG
*/ */
public static class Dig extends TurtleBlockEvent { public static class Dig extends TurtleBlockEvent
{
private final BlockState block; private final BlockState block;
private final ITurtleUpgrade upgrade; private final ITurtleUpgrade upgrade;
private final TurtleSide side; private final TurtleSide side;
public Dig(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState block, public Dig( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState block,
@Nonnull ITurtleUpgrade upgrade, @Nonnull TurtleSide side) { @Nonnull ITurtleUpgrade upgrade, @Nonnull TurtleSide side )
super(turtle, TurtleAction.DIG, player, world, pos); {
super( turtle, TurtleAction.DIG, player, world, pos );
Objects.requireNonNull(block, "block cannot be null"); Objects.requireNonNull( block, "block cannot be null" );
Objects.requireNonNull(upgrade, "upgrade cannot be null"); Objects.requireNonNull( upgrade, "upgrade cannot be null" );
Objects.requireNonNull(side, "side cannot be null"); Objects.requireNonNull( side, "side cannot be null" );
this.block = block; this.block = block;
this.upgrade = upgrade; this.upgrade = upgrade;
this.side = side; this.side = side;
@@ -91,7 +95,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* @return The block which is going to be broken. * @return The block which is going to be broken.
*/ */
@Nonnull @Nonnull
public BlockState getBlock() { public BlockState getBlock()
{
return this.block; return this.block;
} }
@@ -101,7 +106,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* @return The upgrade doing the digging. * @return The upgrade doing the digging.
*/ */
@Nonnull @Nonnull
public ITurtleUpgrade getUpgrade() { public ITurtleUpgrade getUpgrade()
{
return this.upgrade; return this.upgrade;
} }
@@ -111,7 +117,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* @return The upgrade's side. * @return The upgrade's side.
*/ */
@Nonnull @Nonnull
public TurtleSide getSide() { public TurtleSide getSide()
{
return this.side; return this.side;
} }
} }
@@ -121,9 +128,11 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* *
* @see TurtleAction#MOVE * @see TurtleAction#MOVE
*/ */
public static class Move extends TurtleBlockEvent { public static class Move extends TurtleBlockEvent
public Move(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos) { {
super(turtle, TurtleAction.MOVE, player, world, pos); public Move( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos )
{
super( turtle, TurtleAction.MOVE, player, world, pos );
} }
} }
@@ -132,13 +141,15 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* *
* @see TurtleAction#PLACE * @see TurtleAction#PLACE
*/ */
public static class Place extends TurtleBlockEvent { public static class Place extends TurtleBlockEvent
{
private final ItemStack stack; private final ItemStack stack;
public Place(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull ItemStack stack) { public Place( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull ItemStack stack )
super(turtle, TurtleAction.PLACE, player, world, pos); {
super( turtle, TurtleAction.PLACE, player, world, pos );
Objects.requireNonNull(stack, "stack cannot be null"); Objects.requireNonNull( stack, "stack cannot be null" );
this.stack = stack; this.stack = stack;
} }
@@ -148,7 +159,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* @return The item stack to be placed. * @return The item stack to be placed.
*/ */
@Nonnull @Nonnull
public ItemStack getStack() { public ItemStack getStack()
{
return this.stack; return this.stack;
} }
} }
@@ -160,16 +172,18 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* *
* @see TurtleAction#INSPECT * @see TurtleAction#INSPECT
*/ */
public static class Inspect extends TurtleBlockEvent { public static class Inspect extends TurtleBlockEvent
{
private final BlockState state; private final BlockState state;
private final Map<String, Object> data; private final Map<String, Object> data;
public Inspect(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, public Inspect( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state,
@Nonnull Map<String, Object> data) { @Nonnull Map<String, Object> data )
super(turtle, TurtleAction.INSPECT, player, world, pos); {
super( turtle, TurtleAction.INSPECT, player, world, pos );
Objects.requireNonNull(state, "state cannot be null"); Objects.requireNonNull( state, "state cannot be null" );
Objects.requireNonNull(data, "data cannot be null"); Objects.requireNonNull( data, "data cannot be null" );
this.data = data; this.data = data;
this.state = state; this.state = state;
} }
@@ -180,7 +194,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* @return The inspected block state. * @return The inspected block state.
*/ */
@Nonnull @Nonnull
public BlockState getState() { public BlockState getState()
{
return this.state; return this.state;
} }
@@ -190,7 +205,8 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* @return This block's inspection data. * @return This block's inspection data.
*/ */
@Nonnull @Nonnull
public Map<String, Object> getData() { public Map<String, Object> getData()
{
return this.data; return this.data;
} }
@@ -199,9 +215,10 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent {
* *
* @param newData The data to add. Note all values should be convertible to Lua (see {@link MethodResult#of(Object)}). * @param newData The data to add. Note all values should be convertible to Lua (see {@link MethodResult#of(Object)}).
*/ */
public void addData(@Nonnull Map<String, ?> newData) { public void addData( @Nonnull Map<String, ?> newData )
Objects.requireNonNull(newData, "newData cannot be null"); {
this.data.putAll(newData); Objects.requireNonNull( newData, "newData cannot be null" );
this.data.putAll( newData );
} }
} }
} }

View File

@@ -6,13 +6,12 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import java.util.Objects;
import javax.annotation.Nonnull;
import com.google.common.eventbus.EventBus; import com.google.common.eventbus.EventBus;
import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleAccess;
import javax.annotation.Nonnull;
import java.util.Objects;
/** /**
* A base class for all events concerning a turtle. This will only ever constructed and fired on the server side, so sever specific methods on {@link * A base class for all events concerning a turtle. This will only ever constructed and fired on the server side, so sever specific methods on {@link
* ITurtleAccess} are safe to use. * ITurtleAccess} are safe to use.
@@ -21,18 +20,21 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
* *
* @see TurtleActionEvent * @see TurtleActionEvent
*/ */
public abstract class TurtleEvent { public abstract class TurtleEvent
{
public static final EventBus EVENT_BUS = new EventBus(); public static final EventBus EVENT_BUS = new EventBus();
private final ITurtleAccess turtle; private final ITurtleAccess turtle;
protected TurtleEvent(@Nonnull ITurtleAccess turtle) { protected TurtleEvent( @Nonnull ITurtleAccess turtle )
Objects.requireNonNull(turtle, "turtle cannot be null"); {
Objects.requireNonNull( turtle, "turtle cannot be null" );
this.turtle = turtle; this.turtle = turtle;
} }
public static boolean post(TurtleActionEvent event) { public static boolean post( TurtleActionEvent event )
EVENT_BUS.post(event); {
EVENT_BUS.post( event );
return event.isCancelled(); return event.isCancelled();
} }
@@ -42,7 +44,8 @@ public abstract class TurtleEvent {
* @return The access for this turtle. * @return The access for this turtle.
*/ */
@Nonnull @Nonnull
public ITurtleAccess getTurtle() { public ITurtleAccess getTurtle()
{
return this.turtle; return this.turtle;
} }

View File

@@ -6,16 +6,14 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nonnull;
import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.lua.MethodResult;
import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import java.util.Map;
import java.util.Objects;
/** /**
* Fired when a turtle gathers data on an item in its inventory. * Fired when a turtle gathers data on an item in its inventory.
* *
@@ -24,21 +22,24 @@ import net.minecraft.item.ItemStack;
* *
* @see TurtleAction#INSPECT_ITEM * @see TurtleAction#INSPECT_ITEM
*/ */
public class TurtleInspectItemEvent extends TurtleActionEvent { public class TurtleInspectItemEvent extends TurtleActionEvent
{
private final ItemStack stack; private final ItemStack stack;
private final Map<String, Object> data; private final Map<String, Object> data;
private final boolean mainThread; private final boolean mainThread;
@Deprecated @Deprecated
public TurtleInspectItemEvent(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, @Nonnull Map<String, Object> data) { public TurtleInspectItemEvent( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, @Nonnull Map<String, Object> data )
this(turtle, stack, data, false); {
this( turtle, stack, data, false );
} }
public TurtleInspectItemEvent(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, @Nonnull Map<String, Object> data, boolean mainThread) { public TurtleInspectItemEvent( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, @Nonnull Map<String, Object> data, boolean mainThread )
super(turtle, TurtleAction.INSPECT_ITEM); {
super( turtle, TurtleAction.INSPECT_ITEM );
Objects.requireNonNull(stack, "stack cannot be null"); Objects.requireNonNull( stack, "stack cannot be null" );
Objects.requireNonNull(data, "data cannot be null"); Objects.requireNonNull( data, "data cannot be null" );
this.stack = stack; this.stack = stack;
this.data = data; this.data = data;
this.mainThread = mainThread; this.mainThread = mainThread;
@@ -50,7 +51,8 @@ public class TurtleInspectItemEvent extends TurtleActionEvent {
* @return The item stack which is being inspected. This should <b>not</b> be modified. * @return The item stack which is being inspected. This should <b>not</b> be modified.
*/ */
@Nonnull @Nonnull
public ItemStack getStack() { public ItemStack getStack()
{
return this.stack; return this.stack;
} }
@@ -60,7 +62,8 @@ public class TurtleInspectItemEvent extends TurtleActionEvent {
* @return This items's inspection data. * @return This items's inspection data.
*/ */
@Nonnull @Nonnull
public Map<String, Object> getData() { public Map<String, Object> getData()
{
return this.data; return this.data;
} }
@@ -69,7 +72,8 @@ public class TurtleInspectItemEvent extends TurtleActionEvent {
* *
* @return If this is run on the main thread. * @return If this is run on the main thread.
*/ */
public boolean onMainThread() { public boolean onMainThread()
{
return this.mainThread; return this.mainThread;
} }
@@ -78,8 +82,9 @@ public class TurtleInspectItemEvent extends TurtleActionEvent {
* *
* @param newData The data to add. Note all values should be convertible to Lua (see {@link MethodResult#of(Object)}). * @param newData The data to add. Note all values should be convertible to Lua (see {@link MethodResult#of(Object)}).
*/ */
public void addData(@Nonnull Map<String, ?> newData) { public void addData( @Nonnull Map<String, ?> newData )
Objects.requireNonNull(newData, "newData cannot be null"); {
this.data.putAll(newData); Objects.requireNonNull( newData, "newData cannot be null" );
this.data.putAll( newData );
} }
} }

View File

@@ -6,28 +6,28 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import dan200.computercraft.api.turtle.FakePlayer; import dan200.computercraft.api.turtle.FakePlayer;
import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Objects;
/** /**
* Fired when a turtle attempts to interact with an inventory. * Fired when a turtle attempts to interact with an inventory.
*/ */
public abstract class TurtleInventoryEvent extends TurtleBlockEvent { public abstract class TurtleInventoryEvent extends TurtleBlockEvent
{
private final Inventory handler; private final Inventory handler;
protected TurtleInventoryEvent(@Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world, protected TurtleInventoryEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player, @Nonnull World world,
@Nonnull BlockPos pos, @Nullable Inventory handler) { @Nonnull BlockPos pos, @Nullable Inventory handler )
super(turtle, action, player, world, pos); {
super( turtle, action, player, world, pos );
this.handler = handler; this.handler = handler;
} }
@@ -37,7 +37,8 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent {
* @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world. * @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world.
*/ */
@Nullable @Nullable
public Inventory getItemHandler() { public Inventory getItemHandler()
{
return this.handler; return this.handler;
} }
@@ -46,9 +47,11 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent {
* *
* @see TurtleAction#SUCK * @see TurtleAction#SUCK
*/ */
public static class Suck extends TurtleInventoryEvent { public static class Suck extends TurtleInventoryEvent
public Suck(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler) { {
super(turtle, TurtleAction.SUCK, player, world, pos, handler); public Suck( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler )
{
super( turtle, TurtleAction.SUCK, player, world, pos, handler );
} }
} }
@@ -57,14 +60,16 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent {
* *
* @see TurtleAction#DROP * @see TurtleAction#DROP
*/ */
public static class Drop extends TurtleInventoryEvent { public static class Drop extends TurtleInventoryEvent
{
private final ItemStack stack; private final ItemStack stack;
public Drop(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler, public Drop( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable Inventory handler,
@Nonnull ItemStack stack) { @Nonnull ItemStack stack )
super(turtle, TurtleAction.DROP, player, world, pos, handler); {
super( turtle, TurtleAction.DROP, player, world, pos, handler );
Objects.requireNonNull(stack, "stack cannot be null"); Objects.requireNonNull( stack, "stack cannot be null" );
this.stack = stack; this.stack = stack;
} }
@@ -74,7 +79,8 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent {
* @return The item stack which will be dropped. This should <b>not</b> be modified. * @return The item stack which will be dropped. This should <b>not</b> be modified.
*/ */
@Nonnull @Nonnull
public ItemStack getStack() { public ItemStack getStack()
{
return this.stack; return this.stack;
} }
} }

View File

@@ -6,25 +6,26 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import java.util.Objects;
import javax.annotation.Nonnull;
import dan200.computercraft.api.turtle.FakePlayer; import dan200.computercraft.api.turtle.FakePlayer;
import dan200.computercraft.api.turtle.ITurtleAccess; import dan200.computercraft.api.turtle.ITurtleAccess;
import javax.annotation.Nonnull;
import java.util.Objects;
/** /**
* An action done by a turtle which is normally done by a player. * An action done by a turtle which is normally done by a player.
* *
* {@link #getPlayer()} may be used to modify the player's attributes or perform permission checks. * {@link #getPlayer()} may be used to modify the player's attributes or perform permission checks.
*/ */
public abstract class TurtlePlayerEvent extends TurtleActionEvent { public abstract class TurtlePlayerEvent extends TurtleActionEvent
{
private final FakePlayer player; private final FakePlayer player;
protected TurtlePlayerEvent(@Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player) { protected TurtlePlayerEvent( @Nonnull ITurtleAccess turtle, @Nonnull TurtleAction action, @Nonnull FakePlayer player )
super(turtle, action); {
super( turtle, action );
Objects.requireNonNull(player, "player cannot be null"); Objects.requireNonNull( player, "player cannot be null" );
this.player = player; this.player = player;
} }
@@ -36,7 +37,8 @@ public abstract class TurtlePlayerEvent extends TurtleActionEvent {
* @return A {@link FakePlayer} representing this turtle. * @return A {@link FakePlayer} representing this turtle.
*/ */
@Nonnull @Nonnull
public FakePlayer getPlayer() { public FakePlayer getPlayer()
{
return this.player; return this.player;
} }
} }

View File

@@ -6,14 +6,12 @@
package dan200.computercraft.api.turtle.event; package dan200.computercraft.api.turtle.event;
import java.util.Objects; import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Objects;
import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraft.item.ItemStack;
/** /**
* Fired when a turtle attempts to refuel from an item. * Fired when a turtle attempts to refuel from an item.
@@ -21,14 +19,16 @@ import net.minecraft.item.ItemStack;
* One may use {@link #setCanceled(boolean, String)} to prevent refueling from this specific item. Additionally, you may use {@link #setHandler(Handler)} to * One may use {@link #setCanceled(boolean, String)} to prevent refueling from this specific item. Additionally, you may use {@link #setHandler(Handler)} to
* register a custom fuel provider. * register a custom fuel provider.
*/ */
public class TurtleRefuelEvent extends TurtleActionEvent { public class TurtleRefuelEvent extends TurtleActionEvent
{
private final ItemStack stack; private final ItemStack stack;
private Handler handler; private Handler handler;
public TurtleRefuelEvent(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack) { public TurtleRefuelEvent( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack )
super(turtle, TurtleAction.REFUEL); {
super( turtle, TurtleAction.REFUEL );
Objects.requireNonNull(turtle, "turtle cannot be null"); Objects.requireNonNull( turtle, "turtle cannot be null" );
this.stack = stack; this.stack = stack;
} }
@@ -39,7 +39,8 @@ public class TurtleRefuelEvent extends TurtleActionEvent {
* *
* @return The stack to refuel from. * @return The stack to refuel from.
*/ */
public ItemStack getStack() { public ItemStack getStack()
{
return this.stack; return this.stack;
} }
@@ -50,7 +51,8 @@ public class TurtleRefuelEvent extends TurtleActionEvent {
* @see #setHandler(Handler) * @see #setHandler(Handler)
*/ */
@Nullable @Nullable
public Handler getHandler() { public Handler getHandler()
{
return this.handler; return this.handler;
} }
@@ -62,7 +64,8 @@ public class TurtleRefuelEvent extends TurtleActionEvent {
* @param handler The new refuel handler. * @param handler The new refuel handler.
* @see #getHandler() * @see #getHandler()
*/ */
public void setHandler(@Nullable Handler handler) { public void setHandler( @Nullable Handler handler )
{
this.handler = handler; this.handler = handler;
} }
@@ -70,16 +73,17 @@ public class TurtleRefuelEvent extends TurtleActionEvent {
* Handles refuelling a turtle from a specific item. * Handles refuelling a turtle from a specific item.
*/ */
@FunctionalInterface @FunctionalInterface
public interface Handler { public interface Handler
{
/** /**
* Refuel a turtle using an item. * Refuel a turtle using an item.
* *
* @param turtle The turtle to refuel. * @param turtle The turtle to refuel.
* @param stack The stack to refuel with. * @param stack The stack to refuel with.
* @param slot The slot the stack resides within. This may be used to modify the inventory afterwards. * @param slot The slot the stack resides within. This may be used to modify the inventory afterwards.
* @param limit The maximum number of refuel operations to perform. This will often correspond to the number of items to consume. * @param limit The maximum number of refuel operations to perform. This will often correspond to the number of items to consume.
* @return The amount of fuel gained. * @return The amount of fuel gained.
*/ */
int refuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int slot, int limit); int refuel( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int slot, int limit );
} }
} }

View File

@@ -6,9 +6,6 @@
package dan200.computercraft.client; package dan200.computercraft.client;
import java.util.HashSet;
import java.util.function.Consumer;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.ComputerCraftRegistry; import dan200.computercraft.shared.ComputerCraftRegistry;
import dan200.computercraft.shared.common.IColouredItem; import dan200.computercraft.shared.common.IColouredItem;
@@ -16,7 +13,8 @@ import dan200.computercraft.shared.media.items.ItemDisk;
import dan200.computercraft.shared.media.items.ItemTreasureDisk; import dan200.computercraft.shared.media.items.ItemTreasureDisk;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Colour;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.ModelLoader; import net.minecraft.client.render.model.ModelLoader;
@@ -27,17 +25,18 @@ import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.resource.ResourceManager; import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; import java.util.HashSet;
import net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback; import java.util.function.Consumer;
/** /**
* Registers textures and models for items. * Registers textures and models for items.
*/ */
@SuppressWarnings ({ @SuppressWarnings( {
"MethodCallSideOnly", "MethodCallSideOnly",
"LocalVariableDeclarationSideOnly" "LocalVariableDeclarationSideOnly"
}) } )
public final class ClientRegistry { public final class ClientRegistry
{
private static final String[] EXTRA_MODELS = new String[] { private static final String[] EXTRA_MODELS = new String[] {
"turtle_modem_normal_off_left", "turtle_modem_normal_off_left",
"turtle_modem_normal_on_left", "turtle_modem_normal_on_left",
@@ -56,7 +55,7 @@ public final class ClientRegistry {
"turtle_colour", "turtle_colour",
"turtle_elf_overlay", "turtle_elf_overlay",
}; };
private static final String[] EXTRA_TEXTURES = new String[] { private static final String[] EXTRA_TEXTURES = new String[] {
// TODO: Gather these automatically from the model. Sadly the model loader isn't available // TODO: Gather these automatically from the model. Sadly the model loader isn't available
@@ -65,59 +64,66 @@ public final class ClientRegistry {
"block/turtle_elf_overlay", "block/turtle_elf_overlay",
"block/turtle_crafty_face", "block/turtle_crafty_face",
"block/turtle_speaker_face", "block/turtle_speaker_face",
}; };
private ClientRegistry() {} private ClientRegistry() {}
public static void onTextureStitchEvent(SpriteAtlasTexture atlasTexture, ClientSpriteRegistryCallback.Registry registry) { public static void onTextureStitchEvent( SpriteAtlasTexture atlasTexture, ClientSpriteRegistryCallback.Registry registry )
for (String extra : EXTRA_TEXTURES) { {
registry.register(new Identifier(ComputerCraft.MOD_ID, extra)); for( String extra : EXTRA_TEXTURES )
{
registry.register( new Identifier( ComputerCraft.MOD_ID, extra ) );
} }
} }
@SuppressWarnings ("NewExpressionSideOnly") @SuppressWarnings( "NewExpressionSideOnly" )
public static void onModelBakeEvent(ResourceManager manager, Consumer<ModelIdentifier> out) { public static void onModelBakeEvent( ResourceManager manager, Consumer<ModelIdentifier> out )
for (String model : EXTRA_MODELS) { {
out.accept(new ModelIdentifier(new Identifier(ComputerCraft.MOD_ID, model), "inventory")); for( String model : EXTRA_MODELS )
{
out.accept( new ModelIdentifier( new Identifier( ComputerCraft.MOD_ID, model ), "inventory" ) );
} }
} }
public static void onItemColours() { public static void onItemColours()
ColorProviderRegistry.ITEM.register((stack, layer) -> { {
return layer == 1 ? ((ItemDisk) stack.getItem()).getColour(stack) : 0xFFFFFF; ColorProviderRegistry.ITEM.register( ( stack, layer ) -> {
}, ComputerCraftRegistry.ModItems.DISK); return layer == 1 ? ((ItemDisk) stack.getItem()).getColour( stack ) : 0xFFFFFF;
}, ComputerCraftRegistry.ModItems.DISK );
ColorProviderRegistry.ITEM.register((stack, layer) -> layer == 1 ? ItemTreasureDisk.getColour(stack) : 0xFFFFFF, ColorProviderRegistry.ITEM.register( ( stack, layer ) -> layer == 1 ? ItemTreasureDisk.getColour( stack ) : 0xFFFFFF,
ComputerCraftRegistry.ModItems.TREASURE_DISK); ComputerCraftRegistry.ModItems.TREASURE_DISK );
ColorProviderRegistry.ITEM.register((stack, layer) -> { ColorProviderRegistry.ITEM.register( ( stack, layer ) -> {
switch (layer) { switch( layer )
case 0:
default:
return 0xFFFFFF;
case 1: // Frame colour
return IColouredItem.getColourBasic(stack);
case 2: // Light colour
{ {
int light = ItemPocketComputer.getLightState(stack); case 0:
return light == -1 ? Colour.BLACK.getHex() : light; default:
return 0xFFFFFF;
case 1: // Frame colour
return IColouredItem.getColourBasic( stack );
case 2: // Light colour
{
int light = ItemPocketComputer.getLightState( stack );
return light == -1 ? Colour.BLACK.getHex() : light;
}
} }
} }, ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL, ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED );
}, ComputerCraftRegistry.ModItems.POCKET_COMPUTER_NORMAL, ComputerCraftRegistry.ModItems.POCKET_COMPUTER_ADVANCED);
// Setup turtle colours // Setup turtle colours
ColorProviderRegistry.ITEM.register((stack, tintIndex) -> tintIndex == 0 ? ((IColouredItem) stack.getItem()).getColour(stack) : 0xFFFFFF, ColorProviderRegistry.ITEM.register( ( stack, tintIndex ) -> tintIndex == 0 ? ((IColouredItem) stack.getItem()).getColour( stack ) : 0xFFFFFF,
ComputerCraftRegistry.ModBlocks.TURTLE_NORMAL, ComputerCraftRegistry.ModBlocks.TURTLE_NORMAL,
ComputerCraftRegistry.ModBlocks.TURTLE_ADVANCED); ComputerCraftRegistry.ModBlocks.TURTLE_ADVANCED );
} }
private static BakedModel bake(ModelLoader loader, UnbakedModel model, Identifier identifier) { private static BakedModel bake( ModelLoader loader, UnbakedModel model, Identifier identifier )
model.getTextureDependencies(loader::getOrLoadModel, new HashSet<>()); {
return model.bake(loader, model.getTextureDependencies( loader::getOrLoadModel, new HashSet<>() );
spriteIdentifier -> MinecraftClient.getInstance() return model.bake( loader,
.getSpriteAtlas(spriteIdentifier.getAtlasId()) spriteIdentifier -> MinecraftClient.getInstance()
.apply(spriteIdentifier.getTextureId()), .getSpriteAtlas( spriteIdentifier.getAtlasId() )
ModelRotation.X0_Y0, .apply( spriteIdentifier.getTextureId() ),
identifier); ModelRotation.X0_Y0,
identifier );
} }
} }

View File

@@ -6,64 +6,70 @@
package dan200.computercraft.client; package dan200.computercraft.client;
import javax.annotation.Nullable;
import dan200.computercraft.fabric.mixin.ChatHudAccess; import dan200.computercraft.fabric.mixin.ChatHudAccess;
import dan200.computercraft.shared.command.text.ChatHelpers; import dan200.computercraft.shared.command.text.ChatHelpers;
import dan200.computercraft.shared.command.text.TableBuilder; import dan200.computercraft.shared.command.text.TableBuilder;
import dan200.computercraft.shared.command.text.TableFormatter; import dan200.computercraft.shared.command.text.TableFormatter;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.apache.commons.lang3.StringUtils;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.hud.ChatHud; import net.minecraft.client.gui.hud.ChatHud;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import org.apache.commons.lang3.StringUtils;
@SuppressWarnings ({ import javax.annotation.Nullable;
@SuppressWarnings( {
"MethodCallSideOnly", "MethodCallSideOnly",
"LocalVariableDeclarationSideOnly" "LocalVariableDeclarationSideOnly"
}) } )
public class ClientTableFormatter implements TableFormatter { public class ClientTableFormatter implements TableFormatter
{
public static final ClientTableFormatter INSTANCE = new ClientTableFormatter(); public static final ClientTableFormatter INSTANCE = new ClientTableFormatter();
private static Int2IntOpenHashMap lastHeights = new Int2IntOpenHashMap(); private static Int2IntOpenHashMap lastHeights = new Int2IntOpenHashMap();
@Override @Override
@Nullable @Nullable
public Text getPadding(Text component, int width) { public Text getPadding( Text component, int width )
int extraWidth = width - this.getWidth(component); {
if (extraWidth <= 0) { int extraWidth = width - this.getWidth( component );
if( extraWidth <= 0 )
{
return null; return null;
} }
TextRenderer renderer = renderer(); TextRenderer renderer = renderer();
float spaceWidth = renderer.getWidth(" "); float spaceWidth = renderer.getWidth( " " );
int spaces = MathHelper.floor(extraWidth / spaceWidth); int spaces = MathHelper.floor( extraWidth / spaceWidth );
int extra = extraWidth - (int) (spaces * spaceWidth); int extra = extraWidth - (int) (spaces * spaceWidth);
return ChatHelpers.coloured(StringUtils.repeat(' ', spaces) + StringUtils.repeat((char) 712, extra), Formatting.GRAY); return ChatHelpers.coloured( StringUtils.repeat( ' ', spaces ) + StringUtils.repeat( (char) 712, extra ), Formatting.GRAY );
} }
private static TextRenderer renderer() { private static TextRenderer renderer()
{
return MinecraftClient.getInstance().textRenderer; return MinecraftClient.getInstance().textRenderer;
} }
@Override @Override
public int getColumnPadding() { public int getColumnPadding()
{
return 3; return 3;
} }
@Override @Override
public int getWidth(Text component) { public int getWidth( Text component )
return renderer().getWidth(component); {
return renderer().getWidth( component );
} }
@Override @Override
public void writeLine(int id, Text component) { public void writeLine( int id, Text component )
{
MinecraftClient mc = MinecraftClient.getInstance(); MinecraftClient mc = MinecraftClient.getInstance();
ChatHud chat = mc.inGameHud.getChatHud(); ChatHud chat = mc.inGameHud.getChatHud();
@@ -71,20 +77,22 @@ public class ClientTableFormatter implements TableFormatter {
// int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() ); // int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() );
// List<ITextProperties> list = RenderComponentsUtil.func_238505_a_( component, maxWidth, mc.fontRenderer ); // List<ITextProperties> list = RenderComponentsUtil.func_238505_a_( component, maxWidth, mc.fontRenderer );
// if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id ); // if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id );
((ChatHudAccess)chat).callAddMessage(component, id); ((ChatHudAccess) chat).callAddMessage( component, id );
} }
@Override @Override
public int display(TableBuilder table) { public int display( TableBuilder table )
{
ChatHud chat = MinecraftClient.getInstance().inGameHud.getChatHud(); ChatHud chat = MinecraftClient.getInstance().inGameHud.getChatHud();
int lastHeight = lastHeights.get(table.getId()); int lastHeight = lastHeights.get( table.getId() );
int height = TableFormatter.super.display(table); int height = TableFormatter.super.display( table );
lastHeights.put(table.getId(), height); lastHeights.put( table.getId(), height );
for (int i = height; i < lastHeight; i++) { for( int i = height; i < lastHeight; i++ )
((ChatHudAccess)chat).callRemoveMessage(i + table.getId()); {
((ChatHudAccess) chat).callRemoveMessage( i + table.getId() );
} }
return height; return height;
} }

View File

@@ -8,38 +8,41 @@ package dan200.computercraft.client;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
public final class FrameInfo { public final class FrameInfo
{
private static int tick; private static int tick;
private static long renderFrame; private static long renderFrame;
static { private FrameInfo()
{
} }
private FrameInfo() { public static void init()
} {
ClientTickEvents.START_CLIENT_TICK.register( m -> {
public static void init() {
ClientTickEvents.START_CLIENT_TICK.register(m -> {
tick++; tick++;
}); } );
} }
public static boolean getGlobalCursorBlink() { public static boolean getGlobalCursorBlink()
{
return (tick / 8) % 2 == 0; return (tick / 8) % 2 == 0;
} }
public static long getRenderFrame() { public static long getRenderFrame()
{
return renderFrame; return renderFrame;
} }
// TODO Call this in a callback // TODO Call this in a callback
public static void onTick() { public static void onTick()
{
tick++; tick++;
} }
// TODO Call this in a callback // TODO Call this in a callback
public static void onRenderFrame() { public static void onRenderFrame()
{
renderFrame++; renderFrame++;
} }
} }

View File

@@ -6,159 +6,175 @@
package dan200.computercraft.client.gui; package dan200.computercraft.client.gui;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import dan200.computercraft.client.FrameInfo; import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.terminal.TextBuffer; import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.util.Colour; import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Palette; import dan200.computercraft.shared.util.Palette;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.*;
import net.minecraft.client.render.RenderPhase;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.AffineTransformation; import net.minecraft.client.util.math.AffineTransformation;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Matrix4f;
import org.lwjgl.opengl.GL11;
public final class FixedWidthFontRenderer { import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public final class FixedWidthFontRenderer
{
public static final int FONT_HEIGHT = 9; public static final int FONT_HEIGHT = 9;
public static final int FONT_WIDTH = 6; public static final int FONT_WIDTH = 6;
public static final float WIDTH = 256.0f; public static final float WIDTH = 256.0f;
public static final float BACKGROUND_START = (WIDTH - 6.0f) / WIDTH; public static final float BACKGROUND_START = (WIDTH - 6.0f) / WIDTH;
public static final float BACKGROUND_END = (WIDTH - 4.0f) / WIDTH; public static final float BACKGROUND_END = (WIDTH - 4.0f) / WIDTH;
private static final Matrix4f IDENTITY = AffineTransformation.identity() private static final Matrix4f IDENTITY = AffineTransformation.identity()
.getMatrix(); .getMatrix();
private static final Identifier FONT = new Identifier("computercraft", "textures/gui/term_font.png"); private static final Identifier FONT = new Identifier( "computercraft", "textures/gui/term_font.png" );
public static final RenderLayer TYPE = Type.MAIN; public static final RenderLayer TYPE = Type.MAIN;
private FixedWidthFontRenderer() { private FixedWidthFontRenderer()
{
} }
public static void drawString(float x, float y, @Nonnull TextBuffer text, @Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, public static void drawString( float x, float y, @Nonnull TextBuffer text, @Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour,
@Nonnull Palette palette, boolean greyscale, float leftMarginSize, float rightMarginSize) { @Nonnull Palette palette, boolean greyscale, float leftMarginSize, float rightMarginSize )
{
bindFont(); bindFont();
VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance() VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance()
.getBufferBuilders() .getBufferBuilders()
.getEntityVertexConsumers(); .getEntityVertexConsumers();
drawString(IDENTITY, drawString( IDENTITY,
((VertexConsumerProvider) renderer).getBuffer(TYPE), ((VertexConsumerProvider) renderer).getBuffer( TYPE ),
x, x,
y, y,
text, text,
textColour, textColour,
backgroundColour, backgroundColour,
palette, palette,
greyscale, greyscale,
leftMarginSize, leftMarginSize,
rightMarginSize); rightMarginSize );
renderer.draw(); renderer.draw();
} }
private static void bindFont() { private static void bindFont()
{
MinecraftClient.getInstance() MinecraftClient.getInstance()
.getTextureManager() .getTextureManager()
.bindTexture(FONT); .bindTexture( FONT );
RenderSystem.texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP); RenderSystem.texParameter( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
} }
public static void drawString(@Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, @Nonnull TextBuffer text, public static void drawString( @Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, @Nonnull TextBuffer text,
@Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale, @Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale,
float leftMarginSize, float rightMarginSize) { float leftMarginSize, float rightMarginSize )
if (backgroundColour != null) { {
drawBackground(transform, renderer, x, y, backgroundColour, palette, greyscale, leftMarginSize, rightMarginSize, FONT_HEIGHT); if( backgroundColour != null )
{
drawBackground( transform, renderer, x, y, backgroundColour, palette, greyscale, leftMarginSize, rightMarginSize, FONT_HEIGHT );
} }
for (int i = 0; i < text.length(); i++) { for( int i = 0; i < text.length(); i++ )
double[] colour = palette.getColour(getColour(textColour.charAt(i), Colour.BLACK)); {
double[] colour = palette.getColour( getColour( textColour.charAt( i ), Colour.BLACK ) );
float r, g, b; float r, g, b;
if (greyscale) { if( greyscale )
r = g = b = toGreyscale(colour); {
} else { r = g = b = toGreyscale( colour );
}
else
{
r = (float) colour[0]; r = (float) colour[0];
g = (float) colour[1]; g = (float) colour[1];
b = (float) colour[2]; b = (float) colour[2];
} }
// Draw char // Draw char
int index = text.charAt(i); int index = text.charAt( i );
if (index > 255) { if( index > 255 )
{
index = '?'; index = '?';
} }
drawChar(transform, renderer, x + i * FONT_WIDTH, y, index, r, g, b); drawChar( transform, renderer, x + i * FONT_WIDTH, y, index, r, g, b );
} }
} }
private static void drawBackground(@Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, private static void drawBackground( @Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y,
@Nonnull TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale, float leftMarginSize, @Nonnull TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale, float leftMarginSize,
float rightMarginSize, float height) { float rightMarginSize, float height )
if (leftMarginSize > 0) { {
drawQuad(transform, renderer, x - leftMarginSize, y, leftMarginSize, height, palette, greyscale, backgroundColour.charAt(0)); if( leftMarginSize > 0 )
{
drawQuad( transform, renderer, x - leftMarginSize, y, leftMarginSize, height, palette, greyscale, backgroundColour.charAt( 0 ) );
} }
if (rightMarginSize > 0) { if( rightMarginSize > 0 )
drawQuad(transform, {
renderer, drawQuad( transform,
x + backgroundColour.length() * FONT_WIDTH, renderer,
y, x + backgroundColour.length() * FONT_WIDTH,
rightMarginSize, y,
height, rightMarginSize,
palette, height,
greyscale, palette,
backgroundColour.charAt(backgroundColour.length() - 1)); greyscale,
backgroundColour.charAt( backgroundColour.length() - 1 ) );
} }
// Batch together runs of identical background cells. // Batch together runs of identical background cells.
int blockStart = 0; int blockStart = 0;
char blockColour = '\0'; char blockColour = '\0';
for (int i = 0; i < backgroundColour.length(); i++) { for( int i = 0; i < backgroundColour.length(); i++ )
char colourIndex = backgroundColour.charAt(i); {
if (colourIndex == blockColour) { char colourIndex = backgroundColour.charAt( i );
if( colourIndex == blockColour )
{
continue; continue;
} }
if (blockColour != '\0') { if( blockColour != '\0' )
drawQuad(transform, renderer, x + blockStart * FONT_WIDTH, y, FONT_WIDTH * (i - blockStart), height, palette, greyscale, blockColour); {
drawQuad( transform, renderer, x + blockStart * FONT_WIDTH, y, FONT_WIDTH * (i - blockStart), height, palette, greyscale, blockColour );
} }
blockColour = colourIndex; blockColour = colourIndex;
blockStart = i; blockStart = i;
} }
if (blockColour != '\0') { if( blockColour != '\0' )
drawQuad(transform, {
renderer, drawQuad( transform,
x + blockStart * FONT_WIDTH, renderer,
y, x + blockStart * FONT_WIDTH,
FONT_WIDTH * (backgroundColour.length() - blockStart), y,
height, FONT_WIDTH * (backgroundColour.length() - blockStart),
palette, height,
greyscale, palette,
blockColour); greyscale,
blockColour );
} }
} }
public static int getColour(char c, Colour def) { public static int getColour( char c, Colour def )
return 15 - Terminal.getColour(c, def); {
return 15 - Terminal.getColour( c, def );
} }
public static float toGreyscale(double[] rgb) { public static float toGreyscale( double[] rgb )
{
return (float) ((rgb[0] + rgb[1] + rgb[2]) / 3); return (float) ((rgb[0] + rgb[1] + rgb[2]) / 3);
} }
private static void drawChar(Matrix4f transform, VertexConsumer buffer, float x, float y, int index, float r, float g, float b) { private static void drawChar( Matrix4f transform, VertexConsumer buffer, float x, float y, int index, float r, float g, float b )
{
// Short circuit to avoid the common case - the texture should be blank here after all. // Short circuit to avoid the common case - the texture should be blank here after all.
if (index == '\0' || index == ' ') { if( index == '\0' || index == ' ' )
{
return; return;
} }
@@ -168,217 +184,238 @@ public final class FixedWidthFontRenderer {
int xStart = 1 + column * (FONT_WIDTH + 2); int xStart = 1 + column * (FONT_WIDTH + 2);
int yStart = 1 + row * (FONT_HEIGHT + 2); int yStart = 1 + row * (FONT_HEIGHT + 2);
buffer.vertex(transform, x, y, 0f) buffer.vertex( transform, x, y, 0f )
.color(r, g, b, 1.0f) .color( r, g, b, 1.0f )
.texture(xStart / WIDTH, yStart / WIDTH) .texture( xStart / WIDTH, yStart / WIDTH )
.next(); .next();
buffer.vertex(transform, x, y + FONT_HEIGHT, 0f) buffer.vertex( transform, x, y + FONT_HEIGHT, 0f )
.color(r, g, b, 1.0f) .color( r, g, b, 1.0f )
.texture(xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH) .texture( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH )
.next(); .next();
buffer.vertex(transform, x + FONT_WIDTH, y, 0f) buffer.vertex( transform, x + FONT_WIDTH, y, 0f )
.color(r, g, b, 1.0f) .color( r, g, b, 1.0f )
.texture((xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH) .texture( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH )
.next(); .next();
buffer.vertex(transform, x + FONT_WIDTH, y, 0f) buffer.vertex( transform, x + FONT_WIDTH, y, 0f )
.color(r, g, b, 1.0f) .color( r, g, b, 1.0f )
.texture((xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH) .texture( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH )
.next(); .next();
buffer.vertex(transform, x, y + FONT_HEIGHT, 0f) buffer.vertex( transform, x, y + FONT_HEIGHT, 0f )
.color(r, g, b, 1.0f) .color( r, g, b, 1.0f )
.texture(xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH) .texture( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH )
.next(); .next();
buffer.vertex(transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f) buffer.vertex( transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f )
.color(r, g, b, 1.0f) .color( r, g, b, 1.0f )
.texture((xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH) .texture( (xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH )
.next(); .next();
} }
private static void drawQuad(Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, Palette palette, private static void drawQuad( Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, Palette palette,
boolean greyscale, char colourIndex) { boolean greyscale, char colourIndex )
double[] colour = palette.getColour(getColour(colourIndex, Colour.BLACK)); {
double[] colour = palette.getColour( getColour( colourIndex, Colour.BLACK ) );
float r, g, b; float r, g, b;
if (greyscale) { if( greyscale )
r = g = b = toGreyscale(colour); {
} else { r = g = b = toGreyscale( colour );
}
else
{
r = (float) colour[0]; r = (float) colour[0];
g = (float) colour[1]; g = (float) colour[1];
b = (float) colour[2]; b = (float) colour[2];
} }
drawQuad(transform, buffer, x, y, width, height, r, g, b); drawQuad( transform, buffer, x, y, width, height, r, g, b );
} }
private static void drawQuad(Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, float r, float g, float b) { private static void drawQuad( Matrix4f transform, VertexConsumer buffer, float x, float y, float width, float height, float r, float g, float b )
buffer.vertex(transform, x, y, 0) {
.color(r, g, b, 1.0f) buffer.vertex( transform, x, y, 0 )
.texture(BACKGROUND_START, BACKGROUND_START) .color( r, g, b, 1.0f )
.next(); .texture( BACKGROUND_START, BACKGROUND_START )
buffer.vertex(transform, x, y + height, 0) .next();
.color(r, g, b, 1.0f) buffer.vertex( transform, x, y + height, 0 )
.texture(BACKGROUND_START, BACKGROUND_END) .color( r, g, b, 1.0f )
.next(); .texture( BACKGROUND_START, BACKGROUND_END )
buffer.vertex(transform, x + width, y, 0) .next();
.color(r, g, b, 1.0f) buffer.vertex( transform, x + width, y, 0 )
.texture(BACKGROUND_END, BACKGROUND_START) .color( r, g, b, 1.0f )
.next(); .texture( BACKGROUND_END, BACKGROUND_START )
buffer.vertex(transform, x + width, y, 0) .next();
.color(r, g, b, 1.0f) buffer.vertex( transform, x + width, y, 0 )
.texture(BACKGROUND_END, BACKGROUND_START) .color( r, g, b, 1.0f )
.next(); .texture( BACKGROUND_END, BACKGROUND_START )
buffer.vertex(transform, x, y + height, 0) .next();
.color(r, g, b, 1.0f) buffer.vertex( transform, x, y + height, 0 )
.texture(BACKGROUND_START, BACKGROUND_END) .color( r, g, b, 1.0f )
.next(); .texture( BACKGROUND_START, BACKGROUND_END )
buffer.vertex(transform, x + width, y + height, 0) .next();
.color(r, g, b, 1.0f) buffer.vertex( transform, x + width, y + height, 0 )
.texture(BACKGROUND_END, BACKGROUND_END) .color( r, g, b, 1.0f )
.next(); .texture( BACKGROUND_END, BACKGROUND_END )
.next();
} }
public static void drawTerminalWithoutCursor(@Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, public static void drawTerminalWithoutCursor( @Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y,
@Nonnull Terminal terminal, boolean greyscale, float topMarginSize, float bottomMarginSize, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, float bottomMarginSize,
float leftMarginSize, float rightMarginSize) { float leftMarginSize, float rightMarginSize )
{
Palette palette = terminal.getPalette(); Palette palette = terminal.getPalette();
int height = terminal.getHeight(); int height = terminal.getHeight();
// Top and bottom margins // Top and bottom margins
drawBackground(transform, drawBackground( transform,
buffer, buffer,
x, x,
y - topMarginSize, y - topMarginSize,
terminal.getBackgroundColourLine(0), terminal.getBackgroundColourLine( 0 ),
palette, palette,
greyscale, greyscale,
leftMarginSize, leftMarginSize,
rightMarginSize, rightMarginSize,
topMarginSize); topMarginSize );
drawBackground(transform, drawBackground( transform,
buffer, buffer,
x, x,
y + height * FONT_HEIGHT, y + height * FONT_HEIGHT,
terminal.getBackgroundColourLine(height - 1), terminal.getBackgroundColourLine( height - 1 ),
palette, palette,
greyscale, greyscale,
leftMarginSize, leftMarginSize,
rightMarginSize, rightMarginSize,
bottomMarginSize); bottomMarginSize );
// The main text // The main text
for (int i = 0; i < height; i++) { for( int i = 0; i < height; i++ )
drawString(transform, {
buffer, drawString( transform,
x, buffer,
y + FixedWidthFontRenderer.FONT_HEIGHT * i, x,
terminal.getLine(i), y + FixedWidthFontRenderer.FONT_HEIGHT * i,
terminal.getTextColourLine(i), terminal.getLine( i ),
terminal.getBackgroundColourLine(i), terminal.getTextColourLine( i ),
palette, terminal.getBackgroundColourLine( i ),
greyscale, palette,
leftMarginSize, greyscale,
rightMarginSize); leftMarginSize,
rightMarginSize );
} }
} }
public static void drawCursor(@Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal, public static void drawCursor( @Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal,
boolean greyscale) { boolean greyscale )
{
Palette palette = terminal.getPalette(); Palette palette = terminal.getPalette();
int width = terminal.getWidth(); int width = terminal.getWidth();
int height = terminal.getHeight(); int height = terminal.getHeight();
int cursorX = terminal.getCursorX(); int cursorX = terminal.getCursorX();
int cursorY = terminal.getCursorY(); int cursorY = terminal.getCursorY();
if (terminal.getCursorBlink() && cursorX >= 0 && cursorX < width && cursorY >= 0 && cursorY < height && FrameInfo.getGlobalCursorBlink()) { if( terminal.getCursorBlink() && cursorX >= 0 && cursorX < width && cursorY >= 0 && cursorY < height && FrameInfo.getGlobalCursorBlink() )
double[] colour = palette.getColour(15 - terminal.getTextColour()); {
double[] colour = palette.getColour( 15 - terminal.getTextColour() );
float r, g, b; float r, g, b;
if (greyscale) { if( greyscale )
r = g = b = toGreyscale(colour); {
} else { r = g = b = toGreyscale( colour );
}
else
{
r = (float) colour[0]; r = (float) colour[0];
g = (float) colour[1]; g = (float) colour[1];
b = (float) colour[2]; b = (float) colour[2];
} }
drawChar(transform, buffer, x + cursorX * FONT_WIDTH, y + cursorY * FONT_HEIGHT, '_', r, g, b); drawChar( transform, buffer, x + cursorX * FONT_WIDTH, y + cursorY * FONT_HEIGHT, '_', r, g, b );
} }
} }
public static void drawTerminal(@Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal, public static void drawTerminal( @Nonnull Matrix4f transform, @Nonnull VertexConsumer buffer, float x, float y, @Nonnull Terminal terminal,
boolean greyscale, float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize) { boolean greyscale, float topMarginSize, float bottomMarginSize, float leftMarginSize, float rightMarginSize )
drawTerminalWithoutCursor(transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize); {
drawCursor(transform, buffer, x, y, terminal, greyscale); drawTerminalWithoutCursor( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize );
drawCursor( transform, buffer, x, y, terminal, greyscale );
} }
public static void drawTerminal(@Nonnull Matrix4f transform, float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, public static void drawTerminal( @Nonnull Matrix4f transform, float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize,
float bottomMarginSize, float leftMarginSize, float rightMarginSize) { float bottomMarginSize, float leftMarginSize, float rightMarginSize )
{
bindFont(); bindFont();
VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance() VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance()
.getBufferBuilders() .getBufferBuilders()
.getEntityVertexConsumers(); .getEntityVertexConsumers();
VertexConsumer buffer = renderer.getBuffer(TYPE); VertexConsumer buffer = renderer.getBuffer( TYPE );
drawTerminal(transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize); drawTerminal( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize );
renderer.draw(TYPE); renderer.draw( TYPE );
} }
public static void drawTerminal(float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, float bottomMarginSize, public static void drawTerminal( float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize, float bottomMarginSize,
float leftMarginSize, float rightMarginSize) { float leftMarginSize, float rightMarginSize )
drawTerminal(IDENTITY, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize); {
drawTerminal( IDENTITY, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize );
} }
public static void drawEmptyTerminal(float x, float y, float width, float height) { public static void drawEmptyTerminal( float x, float y, float width, float height )
drawEmptyTerminal(IDENTITY, x, y, width, height); {
drawEmptyTerminal( IDENTITY, x, y, width, height );
} }
public static void drawEmptyTerminal(@Nonnull Matrix4f transform, float x, float y, float width, float height) { public static void drawEmptyTerminal( @Nonnull Matrix4f transform, float x, float y, float width, float height )
{
bindFont(); bindFont();
VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance() VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance()
.getBufferBuilders() .getBufferBuilders()
.getEntityVertexConsumers(); .getEntityVertexConsumers();
drawEmptyTerminal(transform, renderer, x, y, width, height); drawEmptyTerminal( transform, renderer, x, y, width, height );
renderer.draw(); renderer.draw();
} }
public static void drawEmptyTerminal(@Nonnull Matrix4f transform, @Nonnull VertexConsumerProvider renderer, float x, float y, float width, public static void drawEmptyTerminal( @Nonnull Matrix4f transform, @Nonnull VertexConsumerProvider renderer, float x, float y, float width,
float height) { float height )
{
Colour colour = Colour.BLACK; Colour colour = Colour.BLACK;
drawQuad(transform, renderer.getBuffer(TYPE), x, y, width, height, colour.getR(), colour.getG(), colour.getB()); drawQuad( transform, renderer.getBuffer( TYPE ), x, y, width, height, colour.getR(), colour.getG(), colour.getB() );
} }
public static void drawBlocker(@Nonnull Matrix4f transform, @Nonnull VertexConsumerProvider renderer, float x, float y, float width, float height) { public static void drawBlocker( @Nonnull Matrix4f transform, @Nonnull VertexConsumerProvider renderer, float x, float y, float width, float height )
{
Colour colour = Colour.BLACK; Colour colour = Colour.BLACK;
drawQuad(transform, renderer.getBuffer(Type.BLOCKER), x, y, width, height, colour.getR(), colour.getG(), colour.getB()); drawQuad( transform, renderer.getBuffer( Type.BLOCKER ), x, y, width, height, colour.getR(), colour.getG(), colour.getB() );
} }
private static final class Type extends RenderPhase { private static final class Type extends RenderPhase
{
private static final int GL_MODE = GL11.GL_TRIANGLES; private static final int GL_MODE = GL11.GL_TRIANGLES;
private static final VertexFormat FORMAT = VertexFormats.POSITION_COLOR_TEXTURE; private static final VertexFormat FORMAT = VertexFormats.POSITION_COLOR_TEXTURE;
static final RenderLayer MAIN = RenderLayer.of("terminal_font", FORMAT, GL_MODE, 1024, false, false, // useDelegate, needsSorting static final RenderLayer MAIN = RenderLayer.of( "terminal_font", FORMAT, GL_MODE, 1024, false, false, // useDelegate, needsSorting
RenderLayer.MultiPhaseParameters.builder() RenderLayer.MultiPhaseParameters.builder()
.texture(new RenderPhase.Texture(FONT, .texture( new RenderPhase.Texture( FONT,
false, false,
false)) // blur, minimap false ) ) // blur, minimap
.alpha(ONE_TENTH_ALPHA) .alpha( ONE_TENTH_ALPHA )
.lightmap(DISABLE_LIGHTMAP) .lightmap( DISABLE_LIGHTMAP )
.writeMaskState(COLOR_MASK) .writeMaskState( COLOR_MASK )
.build(false)); .build( false ) );
static final RenderLayer BLOCKER = RenderLayer.of("terminal_blocker", FORMAT, GL_MODE, 256, false, false, // useDelegate, needsSorting static final RenderLayer BLOCKER = RenderLayer.of( "terminal_blocker", FORMAT, GL_MODE, 256, false, false, // useDelegate, needsSorting
RenderLayer.MultiPhaseParameters.builder() RenderLayer.MultiPhaseParameters.builder()
.texture(new RenderPhase.Texture(FONT, .texture( new RenderPhase.Texture( FONT,
false, false,
false)) // blur, minimap false ) ) // blur, minimap
.alpha(ONE_TENTH_ALPHA) .alpha( ONE_TENTH_ALPHA )
.writeMaskState(DEPTH_MASK) .writeMaskState( DEPTH_MASK )
.lightmap(DISABLE_LIGHTMAP) .lightmap( DISABLE_LIGHTMAP )
.build(false)); .build( false ) );
private Type(String name, Runnable setup, Runnable destroy) { private Type( String name, Runnable setup, Runnable destroy )
super(name, setup, destroy); {
super( name, setup, destroy );
} }
} }
} }

View File

@@ -6,11 +6,6 @@
package dan200.computercraft.client.gui; package dan200.computercraft.client.gui;
import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER;
import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
import javax.annotation.Nonnull;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import dan200.computercraft.ComputerCraft; import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.widgets.WidgetTerminal; import dan200.computercraft.client.gui.widgets.WidgetTerminal;
@@ -22,14 +17,19 @@ import dan200.computercraft.shared.computer.inventory.ContainerComputer;
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase; import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer; import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer; import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer;
import org.lwjgl.glfw.GLFW;
import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW;
public final class GuiComputer<T extends ContainerComputerBase> extends HandledScreen<T> { import javax.annotation.Nonnull;
import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER;
import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
public final class GuiComputer<T extends ContainerComputerBase> extends HandledScreen<T>
{
private final ComputerFamily family; private final ComputerFamily family;
private final ClientComputer computer; private final ClientComputer computer;
private final int termWidth; private final int termWidth;
@@ -38,8 +38,9 @@ public final class GuiComputer<T extends ContainerComputerBase> extends HandledS
private WidgetTerminal terminal; private WidgetTerminal terminal;
private WidgetWrapper terminalWrapper; private WidgetWrapper terminalWrapper;
private GuiComputer(T container, PlayerInventory player, Text title, int termWidth, int termHeight) { private GuiComputer( T container, PlayerInventory player, Text title, int termWidth, int termHeight )
super(container, player, title); {
super( container, player, title );
this.family = container.getFamily(); this.family = container.getFamily();
this.computer = (ClientComputer) container.getComputer(); this.computer = (ClientComputer) container.getComputer();
this.termWidth = termWidth; this.termWidth = termWidth;
@@ -47,22 +48,26 @@ public final class GuiComputer<T extends ContainerComputerBase> extends HandledS
this.terminal = null; this.terminal = null;
} }
public static GuiComputer<ContainerComputer> create(ContainerComputer container, PlayerInventory inventory, Text component) { public static GuiComputer<ContainerComputer> create( ContainerComputer container, PlayerInventory inventory, Text component )
return new GuiComputer<>(container, inventory, component, ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight); {
return new GuiComputer<>( container, inventory, component, ComputerCraft.computerTermWidth, ComputerCraft.computerTermHeight );
} }
public static GuiComputer<ContainerPocketComputer> createPocket(ContainerPocketComputer container, PlayerInventory inventory, Text component) { public static GuiComputer<ContainerPocketComputer> createPocket( ContainerPocketComputer container, PlayerInventory inventory, Text component )
return new GuiComputer<>(container, inventory, component, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight); {
return new GuiComputer<>( container, inventory, component, ComputerCraft.pocketTermWidth, ComputerCraft.pocketTermHeight );
} }
public static GuiComputer<ContainerViewComputer> createView(ContainerViewComputer container, PlayerInventory inventory, Text component) { public static GuiComputer<ContainerViewComputer> createView( ContainerViewComputer container, PlayerInventory inventory, Text component )
return new GuiComputer<>(container, inventory, component, container.getWidth(), container.getHeight()); {
return new GuiComputer<>( container, inventory, component, container.getWidth(), container.getHeight() );
} }
@Override @Override
protected void init() { protected void init()
this.client.keyboard.setRepeatEvents(true); {
this.client.keyboard.setRepeatEvents( true );
int termPxWidth = this.termWidth * FixedWidthFontRenderer.FONT_WIDTH; int termPxWidth = this.termWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = this.termHeight * FixedWidthFontRenderer.FONT_HEIGHT; int termPxHeight = this.termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
@@ -72,67 +77,76 @@ public final class GuiComputer<T extends ContainerComputerBase> extends HandledS
super.init(); super.init();
this.terminal = new WidgetTerminal(this.client, () -> this.computer, this.termWidth, this.termHeight, MARGIN, MARGIN, MARGIN, MARGIN); this.terminal = new WidgetTerminal( this.client, () -> this.computer, this.termWidth, this.termHeight, MARGIN, MARGIN, MARGIN, MARGIN );
this.terminalWrapper = new WidgetWrapper(this.terminal, MARGIN + BORDER + this.x, MARGIN + BORDER + this.y, termPxWidth, termPxHeight); this.terminalWrapper = new WidgetWrapper( this.terminal, MARGIN + BORDER + this.x, MARGIN + BORDER + this.y, termPxWidth, termPxHeight );
this.children.add(this.terminalWrapper); this.children.add( this.terminalWrapper );
this.setFocused(this.terminalWrapper); this.setFocused( this.terminalWrapper );
} }
@Override @Override
public void render(@Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks) { public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks )
super.render(stack, mouseX, mouseY, partialTicks); {
this.drawMouseoverTooltip(stack, mouseX, mouseY); super.render( stack, mouseX, mouseY, partialTicks );
this.drawMouseoverTooltip( stack, mouseX, mouseY );
} }
@Override @Override
protected void drawForeground(@Nonnull MatrixStack transform, int mouseX, int mouseY) { protected void drawForeground( @Nonnull MatrixStack transform, int mouseX, int mouseY )
{
// Skip rendering labels. // Skip rendering labels.
} }
@Override @Override
public void drawBackground(@Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY) { public void drawBackground( @Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY )
{
// Draw terminal // Draw terminal
this.terminal.draw(this.terminalWrapper.getX(), this.terminalWrapper.getY()); this.terminal.draw( this.terminalWrapper.getX(), this.terminalWrapper.getY() );
// Draw a border around the terminal // Draw a border around the terminal
RenderSystem.color4f(1, 1, 1, 1); RenderSystem.color4f( 1, 1, 1, 1 );
this.client.getTextureManager() this.client.getTextureManager()
.bindTexture(ComputerBorderRenderer.getTexture(this.family)); .bindTexture( ComputerBorderRenderer.getTexture( this.family ) );
ComputerBorderRenderer.render(this.terminalWrapper.getX() - MARGIN, this.terminalWrapper.getY() - MARGIN, ComputerBorderRenderer.render( this.terminalWrapper.getX() - MARGIN, this.terminalWrapper.getY() - MARGIN,
this.getZOffset(), this.terminalWrapper.getWidth() + MARGIN * 2, this.terminalWrapper.getHeight() + MARGIN * 2); this.getZOffset(), this.terminalWrapper.getWidth() + MARGIN * 2, this.terminalWrapper.getHeight() + MARGIN * 2 );
} }
@Override @Override
public boolean mouseDragged(double x, double y, int button, double deltaX, double deltaY) { public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
return (this.getFocused() != null && this.getFocused().mouseDragged(x, y, button, deltaX, deltaY)) || super.mouseDragged(x, y, button, deltaX, deltaY); {
return (this.getFocused() != null && this.getFocused().mouseDragged( x, y, button, deltaX, deltaY )) || super.mouseDragged( x, y, button, deltaX, deltaY );
} }
@Override @Override
public boolean mouseReleased(double mouseX, double mouseY, int button) { public boolean mouseReleased( double mouseX, double mouseY, int button )
return (this.getFocused() != null && this.getFocused().mouseReleased(mouseX, mouseY, button)) || super.mouseReleased(x, y, button); {
} return (this.getFocused() != null && this.getFocused().mouseReleased( mouseX, mouseY, button )) || super.mouseReleased( x, y, button );
}
@Override @Override
public boolean keyPressed(int key, int scancode, int modifiers) { public boolean keyPressed( int key, int scancode, int modifiers )
{
// Forward the tab key to the terminal, rather than moving between controls. // Forward the tab key to the terminal, rather than moving between controls.
if (key == GLFW.GLFW_KEY_TAB && this.getFocused() != null && this.getFocused() == this.terminalWrapper) { if( key == GLFW.GLFW_KEY_TAB && this.getFocused() != null && this.getFocused() == this.terminalWrapper )
return this.getFocused().keyPressed(key, scancode, modifiers); {
return this.getFocused().keyPressed( key, scancode, modifiers );
} }
return super.keyPressed(key, scancode, modifiers); return super.keyPressed( key, scancode, modifiers );
} }
@Override @Override
public void removed() { public void removed()
{
super.removed(); super.removed();
this.children.remove(this.terminal); this.children.remove( this.terminal );
this.terminal = null; this.terminal = null;
this.client.keyboard.setRepeatEvents(false); this.client.keyboard.setRepeatEvents( false );
} }
@Override @Override
public void tick() { public void tick()
{
super.tick(); super.tick();
this.terminal.update(); this.terminal.update();
} }

View File

@@ -6,36 +6,39 @@
package dan200.computercraft.client.gui; package dan200.computercraft.client.gui;
import javax.annotation.Nonnull;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive; import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class GuiDiskDrive extends HandledScreen<ContainerDiskDrive> { import javax.annotation.Nonnull;
private static final Identifier BACKGROUND = new Identifier("computercraft", "textures/gui/disk_drive.png");
public GuiDiskDrive(ContainerDiskDrive container, PlayerInventory player, Text title) { public class GuiDiskDrive extends HandledScreen<ContainerDiskDrive>
super(container, player, title); {
private static final Identifier BACKGROUND = new Identifier( "computercraft", "textures/gui/disk_drive.png" );
public GuiDiskDrive( ContainerDiskDrive container, PlayerInventory player, Text title )
{
super( container, player, title );
} }
@Override @Override
public void render(@Nonnull MatrixStack transform, int mouseX, int mouseY, float partialTicks) { public void render( @Nonnull MatrixStack transform, int mouseX, int mouseY, float partialTicks )
this.renderBackground(transform); {
super.render(transform, mouseX, mouseY, partialTicks); this.renderBackground( transform );
this.drawMouseoverTooltip(transform, mouseX, mouseY); super.render( transform, mouseX, mouseY, partialTicks );
this.drawMouseoverTooltip( transform, mouseX, mouseY );
} }
@Override @Override
protected void drawBackground(@Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY) { protected void drawBackground( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); {
RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
this.client.getTextureManager() this.client.getTextureManager()
.bindTexture(BACKGROUND); .bindTexture( BACKGROUND );
this.drawTexture(transform, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight); this.drawTexture( transform, this.x, this.y, 0, 0, this.backgroundWidth, this.backgroundHeight );
} }
} }

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