1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-22 17:37:38 +00:00

Compare commits

..

36 Commits

Author SHA1 Message Date
Jonathan Coates
23c17075be save -> saveAdditional
Also add in a janky workabround for handleUpdateTag not being called.
Being an early porter is always fun :D:.
2021-12-02 09:20:06 +00:00
Jonathan Coates
87988a705b Exclude Jetbrains annotations from testModExtra
testModExtra must /strictly/ be the set of dependencies which are not
present in implementation - there can't be any duplicates.

Yes, it's stupid, but the whole lazyToken("minecraft_classpath") thing
wasn't really built with this in mind, so not much we can do :)
2021-12-01 20:40:46 +00:00
Jonathan Coates
179da1d8cf Update to MC 1.18
- Build fails right now due to module issues, so this won't be pushed
   to GitHub.
 - Monitors render transparently when loaded into the world. I don't
   think this is a 1.17 bug, so not sure what's going on here!
2021-11-30 22:48:38 +00:00
Jonathan Coates
92fd93c0e0 Merge branch 'mc-1.16.x' into mc-1.17.x 2021-11-30 22:37:07 +00:00
Jonathan Coates
af966179ce Merge branch 'mc-1.16.x' into mc-1.17.x 2021-11-29 19:40:05 +00:00
Jonathan Coates
2418cfb87b More instanceof pattern matching 2021-11-28 15:58:30 +00:00
Jonathan Coates
095101831c Pin to an older ForgeGradle
This .25 is still borked I think
2021-11-27 09:34:20 +00:00
Jonathan Coates
7b7527ec80 Rewrite turtle upgrade registration to be more data driven (#967)
The feature nobody asked for, but we're getting anyway.

Old way to register a turtle/pocket computer upgrade:

    ComputerCraftAPI.registerTurtleUpgrade(new MyUpgrade(new ResourceLocation("my_mod", "my_upgrade")));

New way to register a turtle/pocket computer upgrade:

First, define a serialiser for your turtle upgrade type:

    static final DeferredRegister<TurtleUpgradeSerialiser<?>> SERIALISERS = DeferredRegister.create( TurtleUpgradeSerialiser.TYPE, "my_mod" );
    public static final RegistryObject<TurtleUpgradeSerialiser<MyUpgrade>> MY_UPGRADE =
        SERIALISERS.register( "my_upgrade", () -> TurtleUpgradeSerialiser.simple( MyUpgrade::new ) );
    SERIALISERS.register(bus); // Call in your mod constructor.

Now either create a JSON string or use a data generator to register your upgrades:

    class TurtleDataGenerator extends TurtleUpgradeDataProvider {
        @Override
        protected void addUpgrades( @Nonnull Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> addUpgrade )
            simple(new ResourceLocation("my_mod", my_upgrade"), MY_UPGRADE.get()).add(addUpgrade);
        }
    }

See much better! In all seriousness, this does offer some benefits,
namely that it's now possible to overwrite or create upgrades via
datapacks.

Actual changes:
 - Remove ComputerCraftAPI.register{Turtle,Pocket}Upgrade functions.

 - Instead add {Turtle,Pocket}UpgradeSerialiser classes, which are used
   to load upgrades from JSON files in datapacks, and then read/write
   them to network packets (much like recipe serialisers).

 - The upgrade registries now subscribe to datapack reload events. They
   find all JSON files in the
   data/$mod_id/computercraft/{turtle,pocket}_upgrades directories,
   parse them, and then register them as upgrades.

   Once datapacks have fully reloaded, these upgrades are then sent over
   the network to the client.

 - Add data generators for turtle and pocket computer upgrades, to make
   the creation of JSON files a bit easier.

 - Port all of CC:T's upgrades over to use the new system.
2021-11-26 23:36:02 +00:00
Jonathan Coates
a4c5ecf8df Don't specify the version number in mods.toml 2021-11-25 14:54:32 +00:00
Jonathan Coates
99de00e16e Remove craft tweaker integration 2021-11-25 13:36:33 +00:00
Jonathan Coates
600227e481 Merge branch 'mc-1.16.x' into mc-1.17.x 2021-11-25 13:34:19 +00:00
Jonathan Coates
cf3f1d3d48 Add correct tool to CC computers
Also rerun data generators, forgot to do it as part of the previous
commit.

Fixes #953
2021-11-03 09:40:30 +00:00
Jonathan Coates
bca964629a Merge branch 'mc-1.16.x' into mc-1.17.x 2021-11-03 09:34:21 +00:00
Jonathan Coates
0e94355a85 Some post-1.17 cleanup
- Fix broken Javadoc references
 - Apply a couple of refactoring suggestions from IDEA
2021-10-13 17:46:29 +01:00
Jonathan Coates
0d35331b82 Default to Java 16 in the gitpod environment 2021-10-06 18:52:36 +01:00
Jonathan Coates
076b454c8f Also convert the turtle model key to a record 2021-10-06 18:40:33 +01:00
Jonathan Coates
36e0dcbad0 Change network packet to a record
Look at all that code we can delete!
2021-10-06 18:38:51 +01:00
Jonathan Coates
0b5fe990e5 Bump Forge version
- Clean up NBT constants, replace with built-in ones
 - Switch over to the new capability system
2021-10-06 18:28:28 +01:00
Jonathan Coates
29ece2a6e3 Don't run client tests on CI
Kinda sucks, but they're so inconsistent between platforms right now,
and I cannot be bothered to get CI working. It only needs to work on my
machine.
2021-10-06 18:23:38 +01:00
Jonathan Coates
eba26dedab Merge branch 'mc-1.16.x' into mc-1.17.x 2021-10-06 18:10:45 +01:00
Jonathan Coates
3eb601e554 Pass lightmap variables around various renderers
- Add lightmap parameters to the text, computer and printout renderers.

 - Printouts are always rendered using the current lightmap. When
   interacting with the GUI, we use the fullbright lightmap coordinate.

 - Pocket computers render their border using the lightmap. Terminal and
   light do not use the lightmap at all.

There's some funkiness going on here with render types - it appears the
"correct" position_color_tex_lightmap render type is actually one used
for text.

Fixes #919. This bug does occur on 1.16 too, but given how complex the
rendering changes are between 1.16 and 1.17 I do /not/ want to have to
implement this twice. Sorry.
2021-09-19 15:49:31 +01:00
Jonathan Coates
d0e79f310e Bump Forge version
Not much has changed, just some cleanup.
2021-09-19 11:57:37 +01:00
Jonathan Coates
0d6528aaf0 Merge branch 'mc-1.16.x' into mc-1.17.x 2021-09-19 11:38:25 +01:00
Jonathan Coates
b447b0e308 Increase memory limit of the gradle daemon
This has been standard in the mdk for a while, but never actually had to
do this before. IntelliJ finally started hitting this limit when
decompiling.
2021-09-18 12:42:36 +01:00
Jonathan Coates
b2273c9b29 Add back JEI integration 2021-08-29 22:20:06 +01:00
Jonathan Coates
bbf3e48763 Increase timeout of some more tests 2021-08-22 18:01:06 +01:00
Jonathan Coates
92fe1d4bc2 Merge branch 'mc-1.16.x' into mc-1.17.x 2021-08-22 17:50:33 +01:00
Jonathan Coates
4d591c600c Use clearRemoved rather than onLoad
Latter is broken on Forge right now.
2021-08-20 21:48:34 +01:00
Jonathan Coates
0a8e427c61 Merge branch 'mc-1.16.x' into mc-1.17.x 2021-08-20 21:47:55 +01:00
Jonathan Coates
0a537eaeee Rewrite some in-hand rendering code
- Fix missing shader for printout render type
 - Use current buffer provider for pocket computers rather than the
   tesselator. This requires us to use a non-depth-writing terminal +
   depth blocker, as otherwise one gets z-fighting.
 - Thus refactor some of the shaders to be terminal wide, not just for
   monitors.

Fixes #894
2021-08-17 13:00:52 +01:00
Jonathan Coates
aa857c1be3 Start using Java's instanceof pattern matching
Well, not really pattern matching, but it's still an improvement!
2021-08-08 12:45:30 +01:00
Jonathan Coates
e4ced551eb Remove most of the turtle events
I don't think anybody actually used these, and I'm not convinced they
had much value anyway.

It might be worth switching the refueling code to work as a registry
instead, though events are kinda nice.
2021-08-08 12:43:03 +01:00
Jonathan Coates
6eec9ba1a3 Merge branch 'mc-1.16.x' into mc-1.17.x 2021-08-08 12:40:00 +01:00
Jonathan Coates
a8f675c59d Make current branch detection more robust 2021-08-06 18:04:05 +01:00
Jonathan Coates
bb1ebaee4f Bump Forge and prepare for a release
I've been shown up[1]. Unacceptable!

[1]: https://twitter.com/SangarWasTaken/status/1423676992336060417
2021-08-06 17:25:34 +01:00
Jonathan Coates
bb1183d274 Update to Minecraft 1.17.1
- Remap everything to use MojMap class names too. This is what Forge
   uses, so \o/.

   This does NOT currently rename any classes to use suffix notation or
   BlockEntity. That will come in a later change. We do however rename
   references of "World" to "Level".

 - Move the test mod into a separate "cctest" source set. As Forge now
   works using Jigsaw we cannot have multiple mods defining the same
   package, which causes problems with our JUnit test classes.

 - Remove our custom test framework and replace it with vanilla's (this
   is no longer stripped from the jar). RIP kotlin coroutines.

   It's still worth using Kotlin here though, just for extension
   methods.

 - Other 1.17-related changes:
    - Use separate tile/block entity tick methods for server and client
      side, often avoiding ticking at all on the client.

    - Switch much of the monitor rendering code to use vanilla's
      built-in shader system. It's still an incredibly ugly hack, so not
      really expecting this to work with any rendering mods, but we'll
      cross that bridge when we come to it.
2021-08-06 17:18:09 +01:00
692 changed files with 10012 additions and 24663 deletions

1
.gitattributes vendored
View File

@@ -13,4 +13,3 @@ src/testMod/server-files/structures linguist-generated
*.png binary
*.jar binary
*.dfpwm binary

View File

@@ -8,9 +8,9 @@ body:
label: Minecraft Version
description: What version of Minecraft are you using?
options:
- 1.15.x
- 1.16.x
- 1.17.x
- 1.18.x
validations:
required: true
- type: input

View File

@@ -6,7 +6,6 @@ buildscript {
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:5.1.+'
classpath "org.spongepowered:mixingradle:0.7.+"
classpath 'org.parchmentmc:librarian:1.+'
}
}
@@ -23,7 +22,6 @@ plugins {
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: "org.spongepowered.mixin"
apply plugin: 'org.parchmentmc.librarian.forgegradle'
version = mod_version
@@ -31,7 +29,7 @@ version = mod_version
group = "org.squiddev"
archivesBaseName = "cc-tweaked-${mc_version}"
def javaVersion = JavaLanguageVersion.of(8)
def javaVersion = JavaLanguageVersion.of(17)
java {
toolchain {
languageVersion = javaVersion
@@ -48,6 +46,10 @@ tasks.withType(JavaExec).configureEach {
}
sourceSets {
main.java {
exclude 'dan200/computercraft/shared/integration/jei/**'
exclude 'dan200/computercraft/shared/integration/morered/**'
}
main.resources {
srcDir 'src/generated/resources'
}
@@ -58,6 +60,10 @@ sourceSets {
minecraft {
runs {
all {
lazyToken('minecraft_classpath') {
configurations.shade.copyRecursive().resolve().collect { it.absolutePath }.join(File.pathSeparator)
}
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
@@ -66,8 +72,6 @@ minecraft {
source sourceSets.main
}
}
arg "-mixin.config=computercraft.mixins.json"
}
client {
@@ -93,6 +97,12 @@ minecraft {
source sourceSets.testMod
}
}
lazyToken('minecraft_classpath') {
(configurations.shade.copyRecursive().resolve() + configurations.testModExtra.copyRecursive().resolve())
.collect { it.absolutePath }
.join(File.pathSeparator)
}
}
testServer {
@@ -104,19 +114,21 @@ minecraft {
source sourceSets.testMod
}
}
lazyToken('minecraft_classpath') {
(configurations.shade.copyRecursive().resolve() + configurations.testModExtra.copyRecursive().resolve())
.collect { it.absolutePath }
.join(File.pathSeparator)
}
}
}
mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
// mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
mappings channel: 'official', version: mc_version
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')
}
mixin {
add sourceSets.main, 'computercraft.mixins.refmap.json'
}
repositories {
mavenCentral()
maven {
@@ -128,23 +140,21 @@ repositories {
configurations {
shade
implementation.extendsFrom shade
cctJavadoc
testModExtra
testModImplementation.extendsFrom(testModExtra)
testModImplementation.extendsFrom(implementation)
testModImplementation.extendsFrom(testImplementation)
}
dependencies {
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
checkstyle "com.puppycrawl.tools:checkstyle:8.45"
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
annotationProcessor 'org.spongepowered:mixin:0.8.4:processor'
compileOnly fg.deobf("mezz.jei:jei-1.16.5:7.7.0.104:api")
compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.16.5:7.1.0.313")
compileOnly fg.deobf("commoble.morered:morered-1.16.5:2.1.1.0")
runtimeOnly fg.deobf("mezz.jei:jei-1.16.5:7.7.0.104")
// compileOnly fg.deobf("mezz.jei:jei-1.17.1:8.0.0.14:api")
// runtimeOnly fg.deobf("mezz.jei:jei-1.17.1:8.0.0.14")
shade 'org.squiddev:Cobalt:0.5.2-SNAPSHOT'
@@ -153,12 +163,14 @@ dependencies {
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.0'
testImplementation 'org.jetbrains.kotlin:kotlin-reflect:1.6.0'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
testModImplementation sourceSets.main.output
testModExtra('org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.0') {
exclude group: "org.jetbrains", module: "annotations"
}
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.5'
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.2'
}
// Compile tasks
@@ -184,7 +196,7 @@ task luaJavadoc(type: Javadoc) {
options.noTimestamp = false
javadocTool = javaToolchains.javadocToolFor {
languageVersion = JavaLanguageVersion.of(11)
languageVersion = javaVersion
}
}
@@ -197,14 +209,15 @@ jar {
"Implementation-Title" : "CC: Tweaked",
"Implementation-Version" : "${mod_version}",
"Implementation-Vendor" : "SquidDev",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
"MixinConfigs" : "computercraft.mixins.json",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
])
}
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
}
jar.finalizedBy('reobfJar')
[compileJava, compileTestJava, compileTestModJava].forEach {
it.configure {
options.compilerArgs << "-Xlint" << "-Xlint:-processing"
@@ -212,9 +225,6 @@ jar {
}
processResources {
inputs.property "version", mod_version
inputs.property "mcversion", mc_version
def hash = 'none'
Set<String> contributors = []
try {
@@ -231,16 +241,14 @@ processResources {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
from(sourceSets.main.resources.srcDirs) {
include 'META-INF/mods.toml'
include 'data/computercraft/lua/rom/help/credits.txt'
expand 'version': mod_version,
'mcversion': mc_version,
'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
expand(
'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
)
}
from(sourceSets.main.resources.srcDirs) {
exclude 'META-INF/mods.toml'
exclude 'data/computercraft/lua/rom/help/credits.txt'
}
}
@@ -254,6 +262,7 @@ sourcesJar {
import com.hierynomus.gradle.license.tasks.LicenseCheck
import com.hierynomus.gradle.license.tasks.LicenseFormat
import com.modrinth.minotaur.TaskModrinthUpload
import org.apache.tools.ant.taskdefs.condition.Os
List<String> mkCommand(String command) {
@@ -273,7 +282,18 @@ task rollup(type: Exec) {
commandLine mkCommand('"node_modules/.bin/rollup" --config rollup.config.js')
}
task illuaminateDocs(type: Exec, dependsOn: [rollup, luaJavadoc]) {
task minifyWeb(type: Exec, dependsOn: rollup) {
group = "build"
description = "Bundles JS into rollup"
inputs.file("$buildDir/rollup/index.js").withPropertyName("sources")
inputs.file("package-lock.json").withPropertyName("package-lock.json")
outputs.file("$buildDir/rollup/index.min.js").withPropertyName("output")
commandLine mkCommand('"node_modules/.bin/terser"' + " -o '$buildDir/rollup/index.min.js' '$buildDir/rollup/index.js'")
}
task illuaminateDocs(type: Exec, dependsOn: [minifyWeb, luaJavadoc]) {
group = "build"
description = "Bundles JS into rollup"
@@ -281,7 +301,7 @@ task illuaminateDocs(type: Exec, dependsOn: [rollup, luaJavadoc]) {
inputs.files(fileTree("src/main/resources/data/computercraft/lua/rom")).withPropertyName("lua rom")
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
inputs.dir("$buildDir/docs/luaJavadoc")
inputs.file("$buildDir/rollup/index.js").withPropertyName("scripts")
inputs.file("$buildDir/rollup/index.min.js").withPropertyName("scripts")
inputs.file("src/web/styles.css").withPropertyName("styles")
outputs.dir("$buildDir/docs/lua")
@@ -289,13 +309,9 @@ task illuaminateDocs(type: Exec, dependsOn: [rollup, luaJavadoc]) {
}
task docWebsite(type: Copy, dependsOn: [illuaminateDocs]) {
from('doc') {
include 'logo.png'
include 'images/**'
}
from("$buildDir/rollup") {
exclude 'index.js'
}
from 'doc'
include 'logo.png'
include 'images/**'
into "${project.docsDir}/lua"
}
@@ -463,18 +479,19 @@ task checkRelease {
}
check.dependsOn checkRelease
def isStable = false
curseforge {
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
project {
id = '282001'
releaseType = 'release'
releaseType = isStable ? 'release' : 'alpha'
changelog = "Release notes can be found on the GitHub repository (https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
addGameVersion "${mc_version}"
}
}
import com.modrinth.minotaur.TaskModrinthUpload
tasks.register('publishModrinth', TaskModrinthUpload.class).configure {
dependsOn('assemble', 'reobfJar')
onlyIf {
@@ -485,6 +502,7 @@ tasks.register('publishModrinth', TaskModrinthUpload.class).configure {
projectId = 'gu7yAYhd'
versionNumber = "${project.mc_version}-${project.mod_version}"
uploadFile = jar
versionType = isStable ? 'RELEASE' : 'ALPHA'
addGameVersion(project.mc_version)
changelog = "Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
addLoader('forge')
@@ -545,12 +563,17 @@ githubRelease {
owner 'cc-tweaked'
repo 'CC-Tweaked'
targetCommitish.set(project.provider({
try {
return ["git", "-C", projectDir, "rev-parse", "--abbrev-ref", "HEAD"].execute().text.trim()
} catch (Exception e) {
e.printStackTrace()
def cmd = ["git", "rev-parse", "--abbrev-ref", "HEAD"]
println(cmd)
def proc = cmd.execute([], projectDir)
if (proc.waitFor() != 0) {
println(proc.err.text.trim())
throw new IllegalStateException("Executed with a non-0 exit code (${proc.exitValue()}).")
}
return "master"
def branch = proc.text.trim()
if (branch == "") throw new IllegalStateException("Cannot determine branch")
return branch
}))
tagName "v${mc_version}-${mod_version}"
@@ -561,7 +584,7 @@ githubRelease {
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
.join("\n").trim()
}))
prerelease false
prerelease isStable
}
def uploadTasks = ["publish", "curseforge", "publishModrinth", "githubRelease"]

View File

@@ -58,13 +58,20 @@
<module name="SimplifyBooleanExpression" />
<module name="SimplifyBooleanReturn" />
<module name="StringLiteralEquality" />
<module name="UnnecessaryParentheses" />
<module name="UnnecessaryParentheses">
<!-- Default minus LAND. -->
<property name="tokens" value="EXPR,IDENT,NUM_DOUBLE,NUM_FLOAT,NUM_INT,NUM_LONG,STRING_LITERAL,LITERAL_NULL,LITERAL_FALSE,LITERAL_TRUE,ASSIGN,BAND_ASSIGN,BOR_ASSIGN,BSR_ASSIGN,BXOR_ASSIGN,DIV_ASSIGN,MINUS_ASSIGN,MOD_ASSIGN,PLUS_ASSIGN,SL_ASSIGN,SR_ASSIGN,STAR_ASSIGN,LAMBDA,TEXT_BLOCK_LITERAL_BEGIN,LITERAL_INSTANCEOF,GT,LT,GE,LE,EQUAL,NOT_EQUAL,UNARY_MINUS,UNARY_PLUS,INC,DEC,LNOT,BNOT,POST_INC,POST_DEC" />
</module>
<module name="UnnecessarySemicolonAfterTypeMemberDeclaration" />
<module name="UnnecessarySemicolonInTryWithResources" />
<module name="UnnecessarySemicolonInEnumeration" />
<!-- Imports -->
<module name="CustomImportOrder" />
<module name="CustomImportOrder">
<property name="customImportOrderRules"
value="THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE###STATIC"
/>
</module>
<module name="IllegalImport" />
<module name="RedundantImport" />
<module name="UnusedImports" />
@@ -154,6 +161,7 @@
<property name="allowEmptyLambdas" value="true" />
<property name="allowEmptyMethods" value="true" />
<property name="allowEmptyConstructors" value="true" />
<property name="allowEmptyTypes" value="true" />
<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>

View File

@@ -3,6 +3,6 @@ FROM gitpod/workspace-base
USER gitpod
RUN sudo apt-get -q update \
&& sudo apt-get install -yq openjdk-8-jdk openjdk-16-jdk python3-pip npm \
&& sudo apt-get install -yq openjdk-16-jdk python3-pip npm \
&& sudo pip3 install pre-commit \
&& sudo update-java-alternatives --set java-1.8.0-openjdk-amd64
&& sudo update-java-alternatives --set java-1.16.0-openjdk-amd64

View File

@@ -51,6 +51,5 @@ exclude: |
src/generated|
src/test/resources/test-rom/data/json-parsing/|
src/testMod/server-files/|
config/idea/|
.*\.dfpwm
config/idea/
)

View File

@@ -2,7 +2,7 @@
module: [kind=event] modem_message
---
The @{modem_message} event is fired when a message is received on an open channel on any @{modem}.
The @{modem_message} event is fired when a message is received on an open channel on any modem.
## Return Values
1. @{string}: The event name.
@@ -10,15 +10,11 @@ The @{modem_message} event is fired when a message is received on an open channe
3. @{number}: The channel that the message was sent on.
4. @{number}: The reply channel set by the sender.
5. @{any}: The message as sent by the sender.
6. @{number}: The distance between the sender and the receiver, in blocks.
6. @{number}: The distance between the sender and the receiver, in blocks (decimal).
## Example
Wraps a @{modem} peripheral, opens channel 0 for listening, and prints all received messages.
Prints a message when one is sent:
```lua
local modem = peripheral.find("modem") or error("No modem attached", 0)
modem.open(0)
while true do
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
print(("Message received on side %s on channel %d (reply to %d) from %f blocks away with message %s"):format(side, channel, replyChannel, distance, tostring(message)))

View File

@@ -1,27 +0,0 @@
---
module: [kind=event] speaker_audio_empty
see: speaker.playAudio To play audio using the speaker
---
## Return Values
1. @{string}: The event name.
2. @{string}: The name of the speaker which is available to play more audio.
## Example
This uses @{io.lines} to read audio data in blocks of 16KiB from "example_song.dfpwm", and then attempts to play it
using @{speaker.playAudio}. If the speaker's buffer is full, it waits for an event and tries again.
```lua {data-peripheral=speaker}
local dfpwm = require("cc.audio.dfpwm")
local speaker = peripheral.find("speaker")
local decoder = dfpwm.make_decoder()
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
local buffer = decoder(chunk)
while not speaker.playAudio(buffer) do
os.pullEvent("speaker_audio_empty")
end
end
```

View File

@@ -2,12 +2,7 @@
module: [kind=event] term_resize
---
The @{term_resize} event is fired when the main terminal is resized. For instance:
- When a the tab bar is shown or hidden in @{multishell}.
- When the terminal is redirected to a monitor via the "monitor" program and the monitor is resized.
When this event fires, some parts of the terminal may have been moved or deleted. Simple terminal programs (those
not using @{term.setCursorPos}) can ignore this event, but more complex GUI programs should redraw the entire screen.
The @{term_resize} event is fired when the main terminal is resized, mainly when a new tab is opened or closed in @{multishell}.
## Example
Prints :

View File

@@ -1,200 +0,0 @@
---
module: [kind=guide] speaker_audio
see: speaker.playAudio Play PCM audio using a speaker.
see: cc.audio.dfpwm Provides utilities for encoding and decoding DFPWM files.
---
# Playing audio with speakers
CC: Tweaked's speaker peripheral provides a powerful way to play any audio you like with the @{speaker.playAudio}
method. However, for people unfamiliar with digital audio, it's not the most intuitive thing to use. This guide provides
an introduction to digital audio, demonstrates how to play music with CC: Tweaked's speakers, and then briefly discusses
the more complex topic of audio processing.
## A short introduction to digital audio
When sound is recorded it is captured as an analogue signal, effectively the electrical version of a sound
wave. However, this signal is continuous, and so can't be used directly by a computer. Instead, we measure (or *sample*)
the amplitude of the wave many times a second and then *quantise* that amplitude, rounding it to the nearest
representable value.
This representation of sound - a long, uniformally sampled list of amplitudes is referred to as [Pulse-code
Modulation][PCM] (PCM). PCM can be thought of as the "standard" audio format, as it's incredibly easy to work with. For
instance, to mix two pieces of audio together, you can just add samples from the two tracks together and take the average.
CC: Tweaked's speakers also work with PCM audio. It plays back 48,000 samples a second, where each sample is an integer
between -128 and 127. This is more commonly referred to as 48kHz and an 8-bit resolution.
Let's now look at a quick example. We're going to generate a [Sine Wave] at 220Hz, which sounds like a low monotonous
hum. First we wrap our speaker peripheral, and then we fill a table (also referred to as a *buffer*) with 128×1024
samples - this is the maximum number of samples a speaker can accept in one go.
In order to fill this buffer, we need to do a little maths. We want to play 220 sine waves each second, where each sine
wave completes a full oscillation in 2π "units". This means one seconds worth of audio is 2×π×220 "units" long. We then
need to split this into 48k samples, basically meaning for each sample we move 2×π×220/48k "along" the sine curve.
```lua {data-peripheral=speaker}
local speaker = peripheral.find("speaker")
local buffer = {}
local t, dt = 0, 2 * math.pi * 220 / 48000
for i = 1, 128 * 1024 do
buffer[i] = math.floor(math.sin(t) * 127)
t = (t + dt) % (math.pi * 2)
end
speaker.playAudio(buffer)
```
## Streaming audio
You might notice that the above snippet only generates a short bit of audio - 2.7s seconds to be precise. While we could
try increasing the number of loop iterations, we'll get an error when we try to play it through the speaker: the sound
buffer is too large for it to handle.
Our 2.7 seconds of audio is stored in a table with over 130 _thousand_ elements. If we wanted to play a full minute of
sine waves (and why wouldn't you?), you'd need a table with almost 3 _million_. Suddenly you find these numbers adding
up very quickly, and these tables take up more and more memory.
Instead of building our entire song (well, sine wave) in one go, we can produce it in small batches, each of which get
passed off to @{speaker.playAudio} when the time is right. This allows us to build a _stream_ of audio, where we read
chunks of audio one at a time (either from a file or a tone generator like above), do some optional processing to each
one, and then play them.
Let's adapt our example from above to do that instead.
```lua {data-peripheral=speaker}
local speaker = peripheral.find("speaker")
local t, dt = 0, 2 * math.pi * 220 / 48000
while true do
local buffer = {}
for i = 1, 16 * 1024 * 8 do
buffer[i] = math.floor(math.sin(t) * 127)
t = (t + dt) % (math.pi * 2)
end
while not speaker.playAudio(buffer) do
os.pullEvent("speaker_audio_empty")
end
end
```
It looks pretty similar to before, aside from we've wrapped the generation and playing code in a while loop, and added a
rather odd loop with @{speaker.playAudio} and @{os.pullEvent}.
Let's talk about this loop, why do we need to keep calling @{speaker.playAudio}? Remember that what we're trying to do
here is avoid keeping too much audio in memory at once. However, if we're generating audio quicker than the speakers can
play it, we're not helping at all - all this audio is still hanging around waiting to be played!
In order to avoid this, the speaker rejects any new chunks of audio if its backlog is too large. When this happens,
@{speaker.playAudio} returns false. Once enough audio has played, and the backlog has been reduced, a
@{speaker_audio_empty} event is queued, and we can try to play our chunk once more.
## Storing audio
PCM is a fantastic way of representing audio when we want to manipulate it, but it's not very efficient when we want to
store it to disk. Compare the size of a WAV file (which uses PCM) to an equivalent MP3, it's often 5 times the size.
Instead, we store audio in special formats (or *codecs*) and then convert them to PCM when we need to do processing on
them.
Modern audio codecs use some incredibly impressive techniques to compress the audio as much as possible while preserving
sound quality. However, due to CC: Tweaked's limited processing power, it's not really possible to use these from your
computer. Instead, we need something much simpler.
DFPWM (Dynamic Filter Pulse Width Modulation) is the de facto standard audio format of the ComputerCraft (and
OpenComputers) world. Originally popularised by the addon mod [Computronics], CC:T now has built-in support for it with
the @{cc.audio.dfpwm} module. This allows you to read DFPWM files from disk, decode them to PCM, and then play them
using the speaker.
Let's dive in with an example, and we'll explain things afterwards:
```lua {data-peripheral=speaker}
local dfpwm = require("cc.audio.dfpwm")
local speaker = peripheral.find("speaker")
local decoder = dfpwm.make_decoder()
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
local buffer = decoder(chunk)
while not speaker.playAudio(buffer) do
os.pullEvent("speaker_audio_empty")
end
end
```
Once again, we see the @{speaker.playAudio}/@{speaker_audio_empty} loop. However, the rest of the program is a little
different.
First, we require the dfpwm module and call @{cc.audio.dfpwm.make_decoder} to construct a new decoder. This decoder
accepts blocks of DFPWM data and converts it to a list of 8-bit amplitudes, which we can then play with our speaker.
As mentioned to above, @{speaker.playAudio} accepts at most 128×1024 samples in one go. DFPMW uses a single bit for each
sample, which means we want to process our audio in chunks of 16×1024 bytes (16KiB). In order to do this, we use
@{io.lines}, which provides a nice way to loop over chunks of a file. You can of course just use @{fs.open} and
@{fs.BinaryReadHandle.read} if you prefer.
## Processing audio
As mentioned near the beginning of this guide, PCM audio is pretty easy to work with as it's just a list of amplitudes.
You can mix together samples from different streams by adding their amplitudes, change the rate of playback by removing
samples, etc...
Let's put together a small demonstration here. We're going to add a small delay effect to the song above, so that you
hear a faint echo about a second later.
In order to do this, we'll follow a format similar to the previous example, decoding the audio and then playing it.
However, we'll also add some new logic between those two steps, which loops over every sample in our chunk of audio, and
adds the sample from one second ago to it.
For this, we'll need to keep track of the last 48k samples - exactly one seconds worth of audio. We can do this using a
[Ring Buffer], which helps makes things a little more efficient.
```lua {data-peripheral=speaker}
local dfpwm = require("cc.audio.dfpwm")
local speaker = peripheral.find("speaker")
-- Speakers play at 48kHz, so one second is 48k samples. We first fill our buffer
-- with 0s, as there's nothing to echo at the start of the track!
local samples_i, samples_n = 1, 48000
local samples = {}
for i = 1, samples_n do samples[i] = 0 end
local decoder = dfpwm.make_decoder()
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
local buffer = decoder(chunk)
for i = 1, #buffer do
local original_value = buffer[i]
-- Replace this sample with its current amplitude plus the amplitude from one second ago.
-- We scale both to ensure the resulting value is still between -128 and 127.
buffer[i] = original_value * 0.6 + samples[samples_i] * 0.4
-- Now store the current sample, and move the "head" of our ring buffer forward one place.
samples[samples_i] = original_value
samples_i = samples_i + 1
if samples_i > samples_n then samples_i = 1 end
end
while not speaker.playAudio(buffer) do
os.pullEvent("speaker_audio_empty")
end
end
```
:::note Confused?
Don't worry if you don't understand this example. It's quite advanced, and does use some ideas that this guide doesn't
cover. That said, don't be afraid to ask on [Discord] or [IRC] either!
:::
It's worth noting that the examples of audio processing we've mentioned here are about manipulating the _amplitude_ of
the wave. If you wanted to modify the _frequency_ (for instance, shifting the pitch), things get rather more complex.
For this, you'd need to use the [Fast Fourier transform][FFT] to convert the stream of amplitudes to frequencies,
process those, and then convert them back to amplitudes.
This is, I'm afraid, left as an exercise to the reader.
[Computronics]: https://github.com/Vexatos/Computronics/ "Computronics on GitHub"
[FFT]: https://en.wikipedia.org/wiki/Fast_Fourier_transform "Fast Fourier transform - Wikipedia"
[PCM]: https://en.wikipedia.org/wiki/Pulse-code_modulation "Pulse-code Modulation - Wikipedia"
[Ring Buffer]: https://en.wikipedia.org/wiki/Circular_buffer "Circular buffer - Wikipedia"
[Sine Wave]: https://en.wikipedia.org/wiki/Sine_wave "Sine wave - Wikipedia"
[Discord]: https://discord.computercraft.cc "The Minecraft Computer Mods Discord"
[IRC]: http://webchat.esper.net/?channels=computercraft "IRC webchat on EsperNet"

View File

@@ -1,83 +0,0 @@
---
module: [kind=guide] using_require
---
# Reusing code with require
A library is a collection of useful functions and other definitions which is stored separately to your main program. You
might want to create a library because you have some functions which are used in multiple programs, or just to split
your program into multiple more modular files.
Let's say we want to create a small library to make working with the @{term|terminal} a little easier. We'll provide two
functions: `reset`, which clears the terminal and sets the cursor to (1, 1), and `write_center`, which prints some text
in the middle of the screen.
Start off by creating a file called `more_term.lua`:
```lua {data-snippet=more_term}
local function reset()
term.clear()
term.setCursorPos(1, 1)
end
local function write_center(text)
local x, y = term.getCursorPos()
local width, height = term.getSize()
term.setCursorPos(math.floor((width - #text) / 2) + 1, y)
term.write(text)
end
return { reset = reset, write_center = write_center }
```
Now, what's going on here? We define our two functions as one might expect, and then at the bottom return a table with
the two functions. When we require this library, this table is what is returned. With that, we can then call the
original functions. Now create a new file, with the following:
```lua {data-mount=more_term:more_term.lua}
local more_term = require("more_term")
more_term.reset()
more_term.write_center("Hello, world!")
```
When run, this'll clear the screen and print some text in the middle of the first line.
## require in depth
While the previous section is a good introduction to how @{require} operates, there are a couple of remaining points
which are worth mentioning for more advanced usage.
### Libraries can return anything
In our above example, we return a table containing the functions we want to expose. However, it's worth pointing out
that you can return ''anything'' from your library - a table, a function or even just a string! @{require} treats them
all the same, and just returns whatever your library provides.
### Module resolution and the package path
In the above examples, we defined our library in a file, and @{require} read from it. While this is what you'll do most
of the time, it is possible to make @{require} look elsewhere for your library, such as downloading from a website or
loading from an in-memory library store.
As a result, the *module name* you pass to @{require} doesn't correspond to a file path. One common mistake is to load
code from a sub-directory using `require("folder/library")` or even `require("folder/library.lua")`, neither of which
will do quite what you expect.
When loading libraries (also referred to as *modules*) from files, @{require} searches along the *@{package.path|module
path}*. By default, this looks something like:
* `?.lua`
* `?/init.lua`
* `/rom/modules/main/?.lua`
* etc...
When you call `require("my_library")`, @{require} replaces the `?` in each element of the path with your module name, and
checks if the file exists. In this case, we'd look for `my_library.lua`, `my_library/init.lua`,
`/rom/modules/main/my_library.lua` and so on. Note that this works *relative to the current program*, so if your
program is actually called `folder/program`, then we'll look for `folder/my_library.lua`, etc...
One other caveat is loading libraries from sub-directories. For instance, say we have a file
`my/fancy/library.lua`. This can be loaded by using `require("my.fancy.library")` - the '.'s are replaced with '/'
before we start looking for the library.
## External links
There are several external resources which go into require in a little more detail:
- The [Lua Module tutorial](http://lua-users.org/wiki/ModulesTutorial) on the Lua wiki.
- [Lua's manual section on @{require}](https://www.lua.org/manual/5.1/manual.html#pdf-require).

View File

@@ -12,19 +12,16 @@ rounded up to the nearest multiple of 0.05 seconds. If you are using coroutines
or the @{parallel|parallel API}, it will only pause execution of the current
thread, not the whole program.
:::tip
Because sleep internally uses timers, it is a function that yields. This means
that you can use it to prevent "Too long without yielding" errors, however, as
the minimum sleep time is 0.05 seconds, it will slow your program down.
:::
**Note** Because sleep internally uses timers, it is a function that yields.
This means that you can use it to prevent "Too long without yielding" errors,
however, as the minimum sleep time is 0.05 seconds, it will slow your program
down.
:::caution
Internally, this function queues and waits for a timer event (using
**Warning** Internally, this function queues and waits for a timer event (using
@{os.startTimer}), however it does not listen for any other events. This means
that any event that occurs while sleeping will be entirely discarded. If you
need to receive events while sleeping, consider using @{os.startTimer|timers},
or the @{parallel|parallel API}.
:::
@tparam number time The number of seconds to sleep for, rounded up to the
nearest multiple of 0.05.

View File

@@ -1,8 +1,10 @@
org.gradle.jvmargs=-Xmx3G
# Mod properties
mod_version=1.100.2
mod_version=1.99.0
# Minecraft properties (update mods.toml when changing)
mc_version=1.16.5
mapping_version=2021.08.08
forge_version=36.2.20
mc_version=1.18
mapping_version=2021.09.05
forge_version=38.0.0
# NO SERIOUSLY, UPDATE mods.toml WHEN CHANGING

View File

@@ -1,9 +1,8 @@
; -*- mode: Lisp;-*-
(sources
/doc/events/
/doc/guides/
/doc/stub/
/doc/events/
/build/docs/luaJavadoc/
/src/main/resources/*/computercraft/lua/bios.lua
/src/main/resources/*/computercraft/lua/rom/
@@ -28,8 +27,7 @@
(module-kinds
(peripheral Peripherals)
(generic_peripheral "Generic Peripherals")
(event Events)
(guide Guides))
(event Events))
(library-path
/doc/stub/

86
package-lock.json generated
View File

@@ -14,7 +14,6 @@
},
"devDependencies": {
"@rollup/plugin-typescript": "^8.2.5",
"@rollup/plugin-url": "^6.1.0",
"requirejs": "^2.3.6",
"rollup": "^2.33.1",
"rollup-plugin-terser": "^7.0.2",
@@ -74,23 +73,6 @@
"typescript": ">=3.7.0"
}
},
"node_modules/@rollup/plugin-url": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-url/-/plugin-url-6.1.0.tgz",
"integrity": "sha512-FJNWBnBB7nLzbcaGmu1no+U/LlRR67TtgfRFP+VEKSrWlDTE6n9jMns/N4Q/VL6l4x6kTHQX4HQfwTcldaAfHQ==",
"dev": true,
"dependencies": {
"@rollup/pluginutils": "^3.1.0",
"make-dir": "^3.1.0",
"mime": "^2.4.6"
},
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0"
}
},
"node_modules/@rollup/pluginutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
@@ -282,39 +264,12 @@
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"dependencies": {
"semver": "^6.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
"node_modules/mime": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
"dev": true,
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@@ -427,15 +382,6 @@
}
]
},
"node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/serialize-javascript": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
@@ -566,17 +512,6 @@
"resolve": "^1.17.0"
}
},
"@rollup/plugin-url": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-url/-/plugin-url-6.1.0.tgz",
"integrity": "sha512-FJNWBnBB7nLzbcaGmu1no+U/LlRR67TtgfRFP+VEKSrWlDTE6n9jMns/N4Q/VL6l4x6kTHQX4HQfwTcldaAfHQ==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.1.0",
"make-dir": "^3.1.0",
"mime": "^2.4.6"
}
},
"@rollup/pluginutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
@@ -730,27 +665,12 @@
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
"dev": true,
"requires": {
"semver": "^6.0.0"
}
},
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
"mime": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
"dev": true
},
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@@ -820,12 +740,6 @@
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"serialize-javascript": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",

View File

@@ -10,7 +10,6 @@
},
"devDependencies": {
"@rollup/plugin-typescript": "^8.2.5",
"@rollup/plugin-url": "^6.1.0",
"requirejs": "^2.3.6",
"rollup": "^2.33.1",
"rollup-plugin-terser": "^7.0.2",

View File

@@ -1,8 +1,7 @@
import { readFileSync } from "fs";
import { readFileSync } from "fs";
import path from "path";
import typescript from "@rollup/plugin-typescript";
import url from '@rollup/plugin-url';
import { terser } from "rollup-plugin-terser";
const input = "src/web";
@@ -11,7 +10,7 @@ const requirejs = readFileSync("node_modules/requirejs/require.js");
export default {
input: [`${input}/index.tsx`],
output: {
dir: "build/rollup/",
file: "build/rollup/index.js",
// We bundle requirejs (and config) into the header. It's rather gross
// but also works reasonably well.
// Also suffix a ?v=${date} onto the end in the event we need to require a specific copy-cat version.
@@ -19,7 +18,7 @@ export default {
${requirejs}
require.config({
paths: { copycat: "https://copy-cat.squiddev.cc" },
urlArgs: function(id) { return id == "copycat/embed" ? "?v=20211221" : ""; }
urlArgs: function(id) { return id == "copycat/embed" ? "?v=20211127" : ""; }
});
`,
format: "amd",
@@ -34,18 +33,12 @@ export default {
plugins: [
typescript(),
url({
include: "**/*.dfpwm",
fileName: "[name]-[hash][extname]",
publicPath: "/",
}),
{
name: "cc-tweaked",
async transform(code, file) {
// Allow loading files in /mount.
const ext = path.extname(file);
return ext != '.dfpwm' && path.dirname(file) === path.resolve(`${input}/mount`)
return ext != '.tsx' && ext != '.ts' && path.dirname(file) === path.resolve(`${input}/mount`)
? `export default ${JSON.stringify(code)};\n`
: null;
},

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "minecraft:redstone"
"items": [
"minecraft:redstone"
]
},
{
"item": "minecraft:gold_ingot"
"items": [
"minecraft:gold_ingot"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "minecraft:command_block"
"items": [
"minecraft:command_block"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:disk_drive"
"items": [
"computercraft:disk_drive"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:pocket_computer_advanced"
"items": [
"computercraft:pocket_computer_advanced"
]
},
{
"item": "computercraft:speaker"
"items": [
"computercraft:speaker"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:pocket_computer_advanced"
"items": [
"computercraft:pocket_computer_advanced"
]
},
{
"item": "computercraft:wireless_modem_advanced"
"items": [
"computercraft:wireless_modem_advanced"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:pocket_computer_advanced"
"items": [
"computercraft:pocket_computer_advanced"
]
},
{
"item": "computercraft:wireless_modem_normal"
"items": [
"computercraft:wireless_modem_normal"
]
}
]
}

View File

@@ -21,7 +21,9 @@
"conditions": {
"items": [
{
"item": "minecraft:golden_apple"
"items": [
"minecraft:golden_apple"
]
}
]
}

View File

@@ -21,7 +21,9 @@
"conditions": {
"items": [
{
"item": "minecraft:golden_apple"
"items": [
"minecraft:golden_apple"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:pocket_computer_normal"
"items": [
"computercraft:pocket_computer_normal"
]
},
{
"item": "computercraft:speaker"
"items": [
"computercraft:speaker"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:pocket_computer_normal"
"items": [
"computercraft:pocket_computer_normal"
]
},
{
"item": "computercraft:wireless_modem_advanced"
"items": [
"computercraft:wireless_modem_advanced"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:pocket_computer_normal"
"items": [
"computercraft:pocket_computer_normal"
]
},
{
"item": "computercraft:wireless_modem_normal"
"items": [
"computercraft:wireless_modem_normal"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:printer"
"items": [
"computercraft:printer"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:printer"
"items": [
"computercraft:printer"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_advanced"
"items": [
"computercraft:turtle_advanced"
]
},
{
"item": "computercraft:speaker"
"items": [
"computercraft:speaker"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_advanced"
"items": [
"computercraft:turtle_advanced"
]
},
{
"item": "computercraft:wireless_modem_advanced"
"items": [
"computercraft:wireless_modem_advanced"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_advanced"
"items": [
"computercraft:turtle_advanced"
]
},
{
"item": "computercraft:wireless_modem_normal"
"items": [
"computercraft:wireless_modem_normal"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_advanced"
"items": [
"computercraft:turtle_advanced"
]
},
{
"item": "minecraft:crafting_table"
"items": [
"minecraft:crafting_table"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_advanced"
"items": [
"computercraft:turtle_advanced"
]
},
{
"item": "minecraft:diamond_axe"
"items": [
"minecraft:diamond_axe"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_advanced"
"items": [
"computercraft:turtle_advanced"
]
},
{
"item": "minecraft:diamond_hoe"
"items": [
"minecraft:diamond_hoe"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_advanced"
"items": [
"computercraft:turtle_advanced"
]
},
{
"item": "minecraft:diamond_pickaxe"
"items": [
"minecraft:diamond_pickaxe"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_advanced"
"items": [
"computercraft:turtle_advanced"
]
},
{
"item": "minecraft:diamond_shovel"
"items": [
"minecraft:diamond_shovel"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_advanced"
"items": [
"computercraft:turtle_advanced"
]
},
{
"item": "minecraft:diamond_sword"
"items": [
"minecraft:diamond_sword"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_normal"
"items": [
"computercraft:turtle_normal"
]
},
{
"item": "computercraft:speaker"
"items": [
"computercraft:speaker"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_normal"
"items": [
"computercraft:turtle_normal"
]
},
{
"item": "computercraft:wireless_modem_advanced"
"items": [
"computercraft:wireless_modem_advanced"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_normal"
"items": [
"computercraft:turtle_normal"
]
},
{
"item": "computercraft:wireless_modem_normal"
"items": [
"computercraft:wireless_modem_normal"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_normal"
"items": [
"computercraft:turtle_normal"
]
},
{
"item": "minecraft:crafting_table"
"items": [
"minecraft:crafting_table"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_normal"
"items": [
"computercraft:turtle_normal"
]
},
{
"item": "minecraft:diamond_axe"
"items": [
"minecraft:diamond_axe"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_normal"
"items": [
"computercraft:turtle_normal"
]
},
{
"item": "minecraft:diamond_hoe"
"items": [
"minecraft:diamond_hoe"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_normal"
"items": [
"computercraft:turtle_normal"
]
},
{
"item": "minecraft:diamond_pickaxe"
"items": [
"minecraft:diamond_pickaxe"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_normal"
"items": [
"computercraft:turtle_normal"
]
},
{
"item": "minecraft:diamond_shovel"
"items": [
"minecraft:diamond_shovel"
]
}
]
}

View File

@@ -11,10 +11,14 @@
"conditions": {
"items": [
{
"item": "computercraft:turtle_normal"
"items": [
"computercraft:turtle_normal"
]
},
{
"item": "minecraft:diamond_sword"
"items": [
"minecraft:diamond_sword"
]
}
]
}

View File

@@ -21,7 +21,9 @@
"conditions": {
"items": [
{
"item": "computercraft:cable"
"items": [
"computercraft:cable"
]
}
]
}

View File

@@ -21,7 +21,9 @@
"conditions": {
"items": [
{
"item": "computercraft:wireless_modem_normal"
"items": [
"computercraft:wireless_modem_normal"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:monitor_normal"
"items": [
"computercraft:monitor_normal"
]
}
]
}

View File

@@ -11,7 +11,9 @@
"conditions": {
"items": [
{
"item": "computercraft:computer_advanced"
"items": [
"computercraft:computer_advanced"
]
}
]
}

View File

@@ -0,0 +1,4 @@
{
"type": "computercraft:speaker",
"item": "computercraft:speaker"
}

View File

@@ -0,0 +1,4 @@
{
"type": "computercraft:wireless_modem_advanced",
"item": "computercraft:wireless_modem_advanced"
}

View File

@@ -0,0 +1,4 @@
{
"type": "computercraft:wireless_modem_normal",
"item": "computercraft:wireless_modem_normal"
}

View File

@@ -0,0 +1,4 @@
{
"type": "computercraft:speaker",
"item": "computercraft:speaker"
}

View File

@@ -0,0 +1,4 @@
{
"type": "computercraft:wireless_modem_advanced",
"item": "computercraft:wireless_modem_advanced"
}

View File

@@ -0,0 +1,4 @@
{
"type": "computercraft:wireless_modem_normal",
"item": "computercraft:wireless_modem_normal"
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "cable",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
@@ -21,11 +22,13 @@
"cable": "true"
}
}
]
],
"functions": []
},
{
"name": "wired_modem",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
@@ -46,7 +49,8 @@
}
}
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:dynamic",
@@ -28,7 +29,8 @@
}
]
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:dynamic",
@@ -28,7 +29,8 @@
}
]
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:dynamic",
@@ -28,7 +29,8 @@
}
]
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
@@ -14,7 +15,8 @@
{
"condition": "minecraft:survives_explosion"
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
@@ -14,7 +15,8 @@
{
"condition": "minecraft:survives_explosion"
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
@@ -14,7 +15,8 @@
{
"condition": "minecraft:survives_explosion"
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
@@ -14,7 +15,8 @@
{
"condition": "minecraft:survives_explosion"
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
@@ -14,7 +15,8 @@
{
"condition": "minecraft:survives_explosion"
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:dynamic",
@@ -28,7 +29,8 @@
}
]
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:dynamic",
@@ -28,7 +29,8 @@
}
]
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
@@ -14,7 +15,8 @@
{
"condition": "minecraft:survives_explosion"
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
@@ -14,7 +15,8 @@
{
"condition": "minecraft:survives_explosion"
}
]
],
"functions": []
}
]
}

View File

@@ -3,7 +3,8 @@
"pools": [
{
"name": "main",
"rolls": 1,
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
@@ -14,7 +15,8 @@
{
"condition": "minecraft:survives_explosion"
}
]
],
"functions": []
}
]
}

View File

@@ -2,6 +2,7 @@
"replace": false,
"values": [
"#minecraft:crops",
"#minecraft:mineable/hoe",
"minecraft:cactus",
"minecraft:melon",
"minecraft:pumpkin",

View File

@@ -1,6 +1,7 @@
{
"replace": false,
"values": [
"#minecraft:mineable/shovel",
"minecraft:melon",
"minecraft:pumpkin",
"minecraft:carved_pumpkin",

View File

@@ -0,0 +1,4 @@
{
"type": "computercraft:workbench",
"item": "minecraft:crafting_table"
}

View File

@@ -0,0 +1,5 @@
{
"type": "computercraft:tool",
"item": "minecraft:diamond_axe",
"damageMultiplier": 6.0
}

View File

@@ -0,0 +1,5 @@
{
"type": "computercraft:tool",
"item": "minecraft:diamond_hoe",
"breakable": "computercraft:turtle_hoe_harvestable"
}

View File

@@ -0,0 +1,4 @@
{
"type": "computercraft:tool",
"item": "minecraft:diamond_pickaxe"
}

View File

@@ -0,0 +1,5 @@
{
"type": "computercraft:tool",
"item": "minecraft:diamond_shovel",
"breakable": "computercraft:turtle_shovel_harvestable"
}

View File

@@ -0,0 +1,6 @@
{
"type": "computercraft:tool",
"item": "minecraft:diamond_sword",
"damageMultiplier": 9.0,
"breakable": "computercraft:turtle_sword_harvestable"
}

View File

@@ -0,0 +1,18 @@
{
"replace": false,
"values": [
"computercraft:computer_normal",
"computercraft:computer_advanced",
"computercraft:turtle_normal",
"computercraft:turtle_advanced",
"computercraft:speaker",
"computercraft:disk_drive",
"computercraft:printer",
"computercraft:monitor_normal",
"computercraft:monitor_advanced",
"computercraft:wireless_modem_normal",
"computercraft:wireless_modem_advanced",
"computercraft:wired_modem_full",
"computercraft:cable"
]
}

View File

@@ -1,11 +1,10 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft;
import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.http.options.Action;
import dan200.computercraft.core.apis.http.options.AddressRule;
import dan200.computercraft.shared.Config;
@@ -13,16 +12,10 @@ import dan200.computercraft.shared.Registry;
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
import dan200.computercraft.shared.turtle.upgrades.*;
import net.minecraftforge.fml.common.Mod;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -45,10 +38,10 @@ public final class ComputerCraft
public static boolean httpEnabled = true;
public static boolean httpWebsocketEnabled = true;
public static List<AddressRule> httpRules = Collections.unmodifiableList( Arrays.asList(
public static List<AddressRule> httpRules = List.of(
AddressRule.parse( "$private", null, Action.DENY.toPartial() ),
AddressRule.parse( "*", null, Action.ALLOW.toPartial() )
) );
);
public static int httpMaxRequests = 16;
public static int httpMaxWebsockets = 4;
@@ -62,7 +55,7 @@ public final class ComputerCraft
public static int modemHighAltitudeRangeDuringStorm = 384;
public static int maxNotesPerTick = 8;
public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST;
public static double monitorDistanceSq = 4096;
public static int monitorDistance = 65;
public static long monitorBandwidth = 1_000_000;
public static boolean turtlesNeedFuel = true;
@@ -70,7 +63,6 @@ public final class ComputerCraft
public static int advancedTurtleFuelLimit = 100000;
public static boolean turtlesObeyBlockProtection = true;
public static boolean turtlesCanPush = true;
public static EnumSet<TurtleAction> turtleDisabledActions = EnumSet.noneOf( TurtleAction.class );
public static int computerTermWidth = 51;
public static int computerTermHeight = 19;
@@ -84,27 +76,6 @@ public final class ComputerCraft
public static int monitorWidth = 8;
public static int monitorHeight = 6;
public static final class TurtleUpgrades
{
public static TurtleModem wirelessModemNormal;
public static TurtleModem wirelessModemAdvanced;
public static TurtleSpeaker speaker;
public static TurtleCraftingTable craftingTable;
public static TurtleSword diamondSword;
public static TurtleShovel diamondShovel;
public static TurtleTool diamondPickaxe;
public static TurtleAxe diamondAxe;
public static TurtleHoe diamondHoe;
}
public static final class PocketUpgrades
{
public static PocketModem wirelessModemNormal;
public static PocketModem wirelessModemAdvanced;
public static PocketSpeaker speaker;
}
// Registries
public static final ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry();
public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();

View File

@@ -1,6 +1,6 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft;
@@ -15,30 +15,30 @@ import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.asm.GenericMethod;
import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.*;
import dan200.computercraft.shared.BundledRedstone;
import dan200.computercraft.shared.MediaProviders;
import dan200.computercraft.shared.Peripherals;
import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.wired.WiredNode;
import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.resources.IResourceManager;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ReloadableResourceManager;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import net.minecraftforge.server.ServerLifecycleHooks;
import javax.annotation.Nonnull;
import java.io.File;
@@ -59,7 +59,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
public static InputStream getResourceFile( String domain, String subPath )
{
IReloadableResourceManager manager = (IReloadableResourceManager) ServerLifecycleHooks.getCurrentServer().getDataPackRegistries().getResourceManager();
ReloadableResourceManager manager = (ReloadableResourceManager) ServerLifecycleHooks.getCurrentServer().getResourceManager();
try
{
return manager.getResource( new ResourceLocation( domain, subPath ) ).getInputStream();
@@ -81,13 +81,13 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
}
@Override
public int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath )
public int createUniqueNumberedSaveDir( @Nonnull Level world, @Nonnull String parentSubPath )
{
return IDAssigner.getNextId( parentSubPath );
}
@Override
public IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity )
public IWritableMount createSaveDirMount( @Nonnull Level world, @Nonnull String subPath, long capacity )
{
try
{
@@ -102,7 +102,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Override
public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
{
IResourceManager manager = ServerLifecycleHooks.getCurrentServer().getDataPackRegistries().getResourceManager();
ResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
ResourceMount mount = ResourceMount.get( domain, subPath, manager );
return mount.exists( "" ) ? mount : null;
}
@@ -125,12 +125,6 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
GenericPeripheralProvider.addCapability( capability );
}
@Override
public void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade )
{
TurtleUpgrades.register( upgrade );
}
@Override
public void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider )
{
@@ -138,7 +132,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
}
@Override
public int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
public int getBundledRedstoneOutput( @Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
return BundledRedstone.getDefaultOutput( world, pos, side );
}
@@ -149,12 +143,6 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
MediaProviders.register( provider );
}
@Override
public void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade )
{
PocketUpgrades.register( upgrade );
}
@Nonnull
@Override
public IPacketNetwork getWirelessNetwork()
@@ -177,9 +165,9 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Nonnull
@Override
public LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull Direction side )
public LazyOptional<IWiredElement> getWiredElementAt( @Nonnull BlockGetter world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
TileEntity tile = world.getBlockEntity( pos );
BlockEntity tile = world.getBlockEntity( pos );
return tile == null ? LazyOptional.empty() : tile.getCapability( CAPABILITY_WIRED_ELEMENT, side );
}
}

View File

@@ -1,6 +1,6 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. 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.
*/
package dan200.computercraft.api;
@@ -17,13 +17,11 @@ import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
@@ -38,19 +36,14 @@ import javax.annotation.Nullable;
*/
public final class ComputerCraftAPI
{
public static final String MOD_ID = "computercraft";
@Nonnull
public static String getInstalledVersion()
{
return getInstance().getInstalledVersion();
}
@Nonnull
@Deprecated
public static String getAPIVersion()
{
return getInstalledVersion();
}
/**
* Creates a numbered directory in a subfolder of the save directory for a given world, and returns that number.
*
@@ -62,9 +55,9 @@ public final class ComputerCraftAPI
*
* 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(Level, String, long)
*/
public static int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath )
public static int createUniqueNumberedSaveDir( @Nonnull Level world, @Nonnull String parentSubPath )
{
return getInstance().createUniqueNumberedSaveDir( world, parentSubPath );
}
@@ -81,14 +74,14 @@ public final class ComputerCraftAPI
* @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 Computers' file system.
* @see #createUniqueNumberedSaveDir(World, String)
* @see #createUniqueNumberedSaveDir(Level, String)
* @see IComputerAccess#mount(String, IMount)
* @see IComputerAccess#mountWritable(String, IWritableMount)
* @see IMount
* @see IWritableMount
*/
@Nullable
public static IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity )
public static IWritableMount createSaveDirMount( @Nonnull Level world, @Nonnull String subPath, long capacity )
{
return getInstance().createSaveDirMount( world, subPath, capacity );
}
@@ -151,19 +144,6 @@ public final class ComputerCraftAPI
getInstance().registerGenericCapability( capability );
}
/**
* Registers a new turtle turtle for use in ComputerCraft. After calling this,
* users should be able to craft Turtles with your new turtle. It is recommended to call
* this during the load() method of your mod.
*
* @param upgrade The turtle upgrade to register.
* @see ITurtleUpgrade
*/
public static void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade )
{
getInstance().registerTurtleUpgrade( upgrade );
}
/**
* Registers a bundled redstone provider to provide bundled redstone output for blocks.
*
@@ -185,7 +165,7 @@ public final class ComputerCraftAPI
* If there is no block capable of emitting bundled redstone at the location, -1 will be returned.
* @see IBundledRedstoneProvider
*/
public static int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
public static int getBundledRedstoneOutput( @Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
return getInstance().getBundledRedstoneOutput( world, pos, side );
}
@@ -201,11 +181,6 @@ public final class ComputerCraftAPI
getInstance().registerMediaProvider( provider );
}
public static void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade )
{
getInstance().registerPocketUpgrade( upgrade );
}
/**
* Attempt to get the game-wide wireless network.
*
@@ -244,7 +219,7 @@ public final class ComputerCraftAPI
* @see IWiredElement#getNode()
*/
@Nonnull
public static LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull Direction side )
public static LazyOptional<IWiredElement> getWiredElementAt( @Nonnull BlockGetter world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
return getInstance().getWiredElementAt( world, pos, side );
}
@@ -272,10 +247,10 @@ public final class ComputerCraftAPI
@Nonnull
String getInstalledVersion();
int createUniqueNumberedSaveDir( @Nonnull World world, @Nonnull String parentSubPath );
int createUniqueNumberedSaveDir( @Nonnull Level world, @Nonnull String parentSubPath );
@Nullable
IWritableMount createSaveDirMount( @Nonnull World world, @Nonnull String subPath, long capacity );
IWritableMount createSaveDirMount( @Nonnull Level world, @Nonnull String subPath, long capacity );
@Nullable
IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath );
@@ -286,16 +261,12 @@ public final class ComputerCraftAPI
void registerGenericCapability( @Nonnull Capability<?> capability );
void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade );
void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider );
int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side );
int getBundledRedstoneOutput( @Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction side );
void registerMediaProvider( @Nonnull IMediaProvider provider );
void registerPocketUpgrade( @Nonnull IPocketUpgrade upgrade );
@Nonnull
IPacketNetwork getWirelessNetwork();
@@ -305,6 +276,6 @@ public final class ComputerCraftAPI
IWiredNode createWiredNodeForElement( @Nonnull IWiredElement element );
@Nonnull
LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull Direction side );
LazyOptional<IWiredElement> getWiredElementAt( @Nonnull BlockGetter world, @Nonnull BlockPos pos, @Nonnull Direction side );
}
}

View File

@@ -0,0 +1,66 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* 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.
*/
package dan200.computercraft.api;
import dan200.computercraft.ComputerCraft;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.ItemTags;
import net.minecraft.tags.Tag;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
/**
* Tags provided by ComputerCraft.
*/
public class ComputerCraftTags
{
public static class Items
{
public static final Tag.Named<Item> COMPUTER = make( "computer" );
public static final Tag.Named<Item> TURTLE = make( "turtle" );
public static final Tag.Named<Item> WIRED_MODEM = make( "wired_modem" );
public static final Tag.Named<Item> MONITOR = make( "monitor" );
private static Tag.Named<Item> make( String name )
{
return ItemTags.bind( new ResourceLocation( ComputerCraft.MOD_ID, name ).toString() );
}
}
public static class Blocks
{
public static final Tag.Named<Block> COMPUTER = make( "computer" );
public static final Tag.Named<Block> TURTLE = make( "turtle" );
public static final Tag.Named<Block> WIRED_MODEM = make( "wired_modem" );
public static final Tag.Named<Block> MONITOR = make( "monitor" );
/**
* Blocks which can be broken by any turtle tool.
*/
public static final Tag.Named<Block> TURTLE_ALWAYS_BREAKABLE = make( "turtle_always_breakable" );
/**
* Blocks which can be broken by the default shovel tool.
*/
public static final Tag.Named<Block> TURTLE_SHOVEL_BREAKABLE = make( "turtle_shovel_harvestable" );
/**
* Blocks which can be broken with the default sword tool.
*/
public static final Tag.Named<Block> TURTLE_SWORD_BREAKABLE = make( "turtle_sword_harvestable" );
/**
* Blocks which can be broken with the default hoe tool.
*/
public static final Tag.Named<Block> TURTLE_HOE_BREAKABLE = make( "turtle_hoe_harvestable" );
private static Tag.Named<Block> make( String name )
{
return BlockTags.bind( new ResourceLocation( ComputerCraft.MOD_ID, name ).toString() );
}
}
}

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