1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-01 22:22:59 +00:00

Compare commits

...

51 Commits

Author SHA1 Message Date
Jonathan Coates
8c56b6a7be Merge branch 'mc-1.15.x' into mc-1.16.x 2021-03-12 09:26:15 +00:00
Jonathan Coates
66e42e0817 Bump version to 1.95.3 2021-03-12 09:19:16 +00:00
Jonathan Coates
0ee3d10fda Add User-Agent to Websockets
I think, haven't actually tested this :D:. Closes #730.
2021-03-12 09:14:52 +00:00
Jonathan Coates
ed0afc4068 Bump ForgeGradle version
Fixes #686
2021-03-12 08:59:31 +00:00
Wojbie
1f70ed6985 Make edit display errors/results of execution and handle require. (#723) 2021-02-23 20:50:19 +00:00
Weblate
8f3ea60c74 Translations for Portuguese (Brazil)
Co-authored-by: Matheus Medeiros Souza <mmedeiros.cbp@gmail.com>
2021-02-21 13:42:57 +00:00
Jonathan Coates
eb722a74cd Clarify the turtle.place docs a little
Closes #714
2021-02-20 20:19:22 +00:00
Jonathan Coates
1825f67eee Lazily load models in data generators
Fixes #701 (well, hopefully). Our BlockModelProvider is created when
running other mods' data generators (thought not run), which causes
issues as none of the models are considered as "existing files".
2021-02-13 13:02:24 +00:00
Jonathan Coates
975a994581 Fix missing method usages
Maybe one should do a full gradle build when doing major build c hanges
:D:.
2021-02-13 12:48:59 +00:00
Jonathan Coates
061514549d Bump Gradle/ForgeGradle version
This is definitely going to break the build (it shouldn't, but these
things always do). Anyway...

 - Use the new Java toolchain support, rather than requiring the user to
   install multiple Java versions.
 - Bump versions of several plugins.

We're sadly stuck on Gradle <7 for now, as they drop the old
maven-publish plugin, which drops SCP support.
2021-02-13 12:39:52 +00:00
Jonathan Coates
5e52429c23 Merge pull request #709 from SkyTheCodeMaster/patch-1
Fix `redstone.getBundledInput(side)` returning the output of said side.
2021-02-05 20:54:57 +00:00
SkyTheCodeMaster
396cf15a1f Fix redstone.getBundledInput(side) returning the output of said side. 2021-02-05 14:10:11 -05:00
Jonathan Coates
7514cf7320 Mark as compatible with 1.16.{4,5}
Closes #694
2021-01-24 21:23:29 +00:00
Jonathan Coates
1316d6a3c9 Migrate all examples to use tweaked.cc
Might as well, I've got the server capacity to spare. Hopefully.
2021-01-23 14:58:08 +00:00
Jonathan Coates
e1cbbe3628 Haven't been hoisted by this petard for a while
I really should move this to Gradle. Probably should just write my own
plugin at this point.
2021-01-19 21:33:05 +00:00
Jonathan Coates
6d367e08a3 ./gradlew checkstyleMain
Every time I forget to run this before pushing, I get very sad.
2021-01-19 21:15:18 +00:00
Jonathan Coates
eaa7359c8c Add a whole bunch of tests
Coverage graph goes woosh. Hopefully.

More importantly, all of these are historic regressions, so very much
worth tracking.
2021-01-19 20:02:45 +00:00
SquidDev
657ceda3af Switch back to reobfuscated name in RecordMedia
Fixes #688
2021-01-19 13:43:49 +00:00
JackMacWindows
a934e42219 Finish the rest of the event documentation (#683) 2021-01-19 09:20:52 +00:00
Jonathan Coates
1544749282 Defer sending monitor updates until tick end
We send monitor updates when a player starts watching a chunk. However,
the block/tile data has not been sent when this event is fired, and so
the packet is entirely ignored.

Instead, we now queue a "send this" task, which is then dispatched on
the next tick end.

I have memories of this working on 1.12, so either something changed in
an update or I'm a complete idiot. Both are possible.

Fixes #687
2021-01-18 22:20:48 +00:00
FensieRenaud
763bab80fa Serialise sparse arrays into JSON (#685) 2021-01-18 20:48:33 +00:00
FensieRenaud
417fda3019 Serialise sparse arrays into JSON (#685) 2021-01-18 16:44:39 +00:00
Jonathan Coates
444830cf2d Remove Grgit/jgit usage in build.gradle
The replacement is objectively worse. However, it supports Git
worktrees, which sadly jgit does not.

We really need to rewrite the build script to make it lazy so we're not
executing these commands every time.
2021-01-16 15:41:19 +00:00
Jonathan Coates
23bf33c454 Use mixins to construct the TestFunctionInfo class
There's some funky things going on here, but thankfully they're limited
to test code.
2021-01-16 12:40:00 +00:00
Jonathan Coates
0be030c497 Merge branch 'mc-1.15.x' into mc-1.16.x 2021-01-16 11:38:59 +00:00
Jonathan Coates
ee27d8f081 Bump version to 1.95.2 2021-01-16 11:18:59 +00:00
Jonathan Coates
a3a9684505 Widen version range to include 1.16.5
Building against 1.16.4 for now to ensure we don't break it. Hopefully
we can bump this too once most people have migrated.

Will push a release tomorrow - don't want to be sorting out merge
conflicts at 23:30.
2021-01-15 23:26:01 +00:00
Jonathan Coates
1381325813 Expand CONTRIBUTING a little
Explain our overly-complicated build system. Because of course we need
to.
2021-01-15 23:16:58 +00:00
Jonathan Coates
52b112fae6 Bump several action versions 2021-01-15 19:39:12 +00:00
Wojbie
c83eeb16a8 id.lua now handles more disk types (#677)
Co-authored-by: Lupus590 <lupussolitarius590@gmail.com>
2021-01-15 19:30:21 +00:00
Jonathan Coates
9d1ee6f61d Remove m_ (#658)
IT'S GONE!

Not looking forward to the merge conflicts on this one.
2021-01-15 16:35:49 +00:00
Jonathan Coates
b90611b4b4 Preserve registration order of upgrades
Makes them display in a more reasonable order within JEI. Closes #647
(note, the title is an entirley separate issue)!
2021-01-15 15:32:11 +00:00
Jonathan Coates
e1e7ef59c6 Measure code coverage from in-game tests
More importantly, `./gradlew check' actually runs the in-game tests,
which makes the CI steps look a little more sensible again.

Somewhat depressing that one of the longest files (15th) in CC:T is the
build script.
2021-01-15 09:54:38 +00:00
SquidDev
9ae0f4a993 Add some initial documentation for events
Credit to @BradyFromDiscord for writing these. See #640 and #565.

Co-authored-by: Brady <bradyakent@gmail.com
2021-01-14 18:37:20 +00:00
Jonathan Coates
fd262a7995 Clarify the cc.strings.wrap docs a little
Also make the example a bit more "useful". Hopefully this should clarify
that the function returns a table rather than a single string.

Closes #678.
2021-01-14 09:12:37 +00:00
Jonathan Coates
58054ad2d1 Reformat src/main/java
Removes several pointless imports. And, more importantly, fixes the
build.
2021-01-14 09:09:02 +00:00
Jonathan Coates
1255bd00fd Fix mounts being usable after a disk is ejected
This probably fails "responsible disclosure", but it's not an RCE and
frankly the whole bug is utterly hilarious so here we are...

It's possible to open a file on a disk drive and continue to read/write
to them after the disk has been removed:

    local disk = peripheral.find("drive")
    local input = fs.open(fs.combine(disk.getMountPath(), "stream"), "rb")
    local output = fs.open(fs.combine(disk.getMountPath(), "stream"), "wb")
    disk.ejectDisk()

    -- input/output can still be interacted with.

This is pretty amusing, as now it allows us to move the disk somewhere
else and repeat - we've now got a private tunnel which two computers can
use to communicate.

Fixing this is intuitively quite simple - just close any open files
belonging to this mount. However, this is where things get messy thanks
to the wonderful joy of how CC's streams are handled.

As things stand, the filesystem effectively does the following flow::
 - There is a function `open : String -> Channel' (file modes are
   irrelevant here).

 - Once a file is opened, we transform it into some <T extends
   Closeable>. This is, for instance, a BufferedReader.

 - We generate a "token" (i.e. FileSystemWrapper<T>), which we generate
   a week reference to and map it to a tuple of our Channel and T. If
   this token is ever garbage collected (someone forgot to call close()
   on a file), then we close our T and Channel.

 - This token and T are returned to the calling function, which then
   constructs a Lua object.

The problem here is that if we close the underlying Channel+T before the
Lua object calls .close(), then it won't know the underlying channel is
closed, and you get some pretty ugly errors (e.g. "Stream Closed"). So
we've moved the "is open" state into the FileSystemWrapper<T>.

The whole system is incredibly complex at this point, and I'd really
like to clean it up. Ideally we could treat the HandleGeneric as the
token instead - this way we could potentially also clean up
FileSystemWrapperMount.

BBut something to play with in the future, and not when it's 10:30pm.

---

All this wall of text, and this isn't the only bug I've found with disks
today :/.
2021-01-13 22:10:44 +00:00
Wojbie
1f84480a80 Make rightAlt only close menu, never open it. (#672)
Fixes #669
2021-01-11 21:59:29 +00:00
Jonathan Coates
b838efedd2 Retry the prepare step one time
Hopefully ensures failed assets assets don't entirely break the build.
2021-01-09 20:17:32 +00:00
Jonathan Coates
f78e24f9a0 Use UnsafeHacks to construct the test function info
This has been stripped (only in CI on 1.15, always in 1.16) so blows up
when we try to call it.
2021-01-09 20:12:13 +00:00
Jonathan Coates
88f5b20353 Fix checkstyle and licence checks
Of all the things to fail in this absurdy complex change >_>.
2021-01-09 20:00:15 +00:00
Jonathan Coates
331031be45 Run integration tests in-game
Name a more iconic duo than @SquidDev and over-engineered test
frameworks.

This uses Minecraft's test core[1] plus a home-grown framework to run
tests against computers in-world.

The general idea is:
 - Build a structure in game.
 - Save the structure to a file. This will be spawned in every time the
   test is run.
 - Write some code which asserts the structure behaves in a particular
   way. This is done in Kotlin (shock, horror), as coroutines give us a
   nice way to run asynchronous code while still running on the main
   thread.

As with all my testing efforts, I still haven't actually written any
tests!  It'd be good to go through some of the historic ones and write
some tests though. Turtle block placing and computer redstone
interactions are probably a good place to start.

[1]: https://www.youtube.com/watch?v=vXaWOJTCYNg
2021-01-09 19:50:27 +00:00
Jonathan Coates
c5694ea966 Merge branch 'mc-1.15.x' into mc-1.16.x 2021-01-09 19:25:33 +00:00
Jonathan Coates
34b5ede326 Switch to Mojang mappings
ForgeGradle (probably sensibly) yells at me about doing this. However:
 - There's a reasonable number of mods doing this, which establishes
   some optimistic precedent.
 - The licence update in Aug 2020 now allows you to use them for
   "development purposes". I guess source code counts??
 - I'm fairly sure this is also compatible with the CCPL - there's an
   exception for Minecraft code.

The main motivation for this is to make the Fabric port a little
easier. Hopefully folks (maybe me in the future, we'll see) will no
longer have to deal with mapping hell when merging - only mod loader
hell.
2021-01-09 19:22:58 +00:00
Jonathan Coates
7b476cb24b Remove usage of deprecated event constructor
This requires a Forge bump, but probably no harm in doing so anyway.
We're on an ancient (2nd Nov) version. Fixes #665.
2021-01-09 18:49:40 +00:00
Jonathan Coates
7ca261d763 Merge branch 'mc-1.15.x' into mc-1.16.x 2021-01-09 18:32:40 +00:00
Jonathan Coates
c864576619 Fix impostor recipes for disks
Well, this is embarrassing. See #652
2021-01-09 18:30:07 +00:00
Jonathan Coates
247c05305d Fix problem with RepeatArgumentType
The whole "flatten" thing can probably be dropped TBH. We don't use it
anywhere. Fixes #661
2021-01-08 17:50:26 +00:00
Jonathan Coates
2232f025b8 Make CC:T work as a non-root project 2021-01-08 17:50:25 +00:00
Wojbie
b2e5401486 Added Numpad Enter Support in rom lua programs. (#657) 2021-01-07 21:41:04 +00:00
Lupus590
41226371f3 Add isReadOnly to fs.attributes (#639) 2021-01-07 16:36:25 +00:00
325 changed files with 9787 additions and 3419 deletions

1
.gitattributes vendored
View File

@@ -1,2 +1,3 @@
# Ignore changes in generated files
src/generated/resources/data/** linguist-generated
src/test/server-files/structures linguist-generated

View File

@@ -16,7 +16,7 @@ jobs:
java-version: 8
- name: Cache gradle dependencies
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
@@ -24,10 +24,13 @@ jobs:
${{ runner.os }}-gradle-
- name: Build with Gradle
run: ./gradlew build --no-daemon || ./gradlew build --no-daemon
run: |
./gradlew assemble --no-daemon || ./gradlew assemble --no-daemon
./gradlew downloadAssets --no-daemon || ./gradlew downloadAssets --no-daemon
./gradlew build
- name: Upload Jar
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v2
with:
name: CC-Tweaked
path: build/libs

View File

@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Set up Java 8
uses: actions/setup-java@v1
@@ -19,7 +19,7 @@ jobs:
java-version: 8
- name: Cache gradle dependencies
uses: actions/cache@v1
uses: actions/cache@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}

View File

@@ -8,6 +8,10 @@ If you've any other questions, [just ask the community][community] or [open an i
If you have a bug, suggestion, or other feedback, the best thing to do is [file an issue][new-issue]. When doing so,
do use the issue templates - they provide a useful hint on what information to provide.
## Translations
Translations are managed through [Weblate], an online interface for managing language strings. This is synced
automatically with GitHub, so please don't submit PRs adding/changing translations!
## Developing
In order to develop CC: Tweaked, you'll need to download the source code and then run it. This is a pretty simple
process. When building on Windows, Use `gradlew.bat` instead of `./gradlew`.
@@ -20,6 +24,11 @@ If you want to run CC:T in a normal Minecraft instance, run `./gradlew build` an
These commands may take a few minutes to run the first time, as the environment is set up, but should be much faster
afterwards.
The following sections describe the more niche sections of CC: Tweaked's build system. Some bits of these are
quite-complex, and (dare I say) over-engineered, so you may wish to ignore them. Well tested/documented PRs are always
preferred (and I'd definitely recommend setting up the tooling if you're doing serious development work), but for
small changes it can be a lot.
### Code linters
CC: Tweaked uses a couple of "linters" on its source code, to enforce a consistent style across the project. While these
are run whenever you submit a PR, it's often useful to run this before committing.
@@ -27,15 +36,75 @@ are run whenever you submit a PR, it's often useful to run this before committin
- **[Checkstyle]:** Checks Java code to ensure it is consistently formatted. This can be run with `./gradlew build` or
`./gradle check`.
- **[illuaminate]:** Checks Lua code for semantic and styleistic issues. See [the usage section][illuaminate-usage] for
how to download and run it.
how to download and run it. You may need to generate the Java documentation stubs (see "Documentation" below) for all
lints to pass.
## Translations
Translations are managed through [Weblate], an online interface for managing language strings. This is synced
automatically with GitHub, so please don't submit PRs adding/changing translations!
### Documentation
When writing documentation for [CC: Tweaked's documentation website][docs], it may be useful to build the documentation
and preview it yourself before submitting a PR.
Building all documentation is, sadly, a multi-stage process (though this is largely hidden by Gradle). First we need to
convert Java doc-comments into Lua ones, we also generate some Javascript to embed. All of this is then finally fed into
illuaminate, which spits out our HTML.
#### Setting up the tooling
For various reasons, getting the environment set up to build documentation can be pretty complex. I'd quite like to
automate this via Docker and/or nix in the future, but this needs to be done manually for now.
This tooling is only needed if you need to build the whole website. If you just want to generate the Lua stubs, you can
skp this section.
- Install Node/npm and install our Node packages with `npm ci`.
- Install [illuaminate][illuaminate-usage] as described above.
#### Building documentation
Gradle should be your entrypoint to building most documentation. There's two tasks which are of interest:
- `./gradlew luaJavadoc` - Generate documentation stubs for Java methods.
- `./gradlew docWebsite` - Generate the whole website (including Javascript pages). The resulting HTML is stored at
`./build/docs/lua/`.
#### Writing documentation
illuaminate's documentation system is not currently documented (somewhat ironic), but is _largely_ the same as
[ldoc][ldoc]. Documentation comments are written in Markdown,
Our markdown engine does _not_ support GitHub flavoured markdown, and so does not support all the features one might
expect (such as tables). It is very much recommended that you build and preview the docs locally first.
### Testing
Thankfully running tests is much simpler than running the documentation generator! `./gradlew check` will run the
entire test suite (and some additional bits of verification).
Before we get into writing tests, it's worth mentioning the various test suites that CC: Tweaked has:
- "Core" Java (`./src/test/java`): These test core bits of the mod which don't require any Minecraft interaction.
This includes the `@LuaFunction` system, file system code, etc...
These tests are run by `./gradlew test`.
- CraftOS (`./src/test/resources/test-rom/`): These tests are written in Lua, and ensure the Lua environment, libraries
and programs work as expected. These are (generally) written to be able to be run on emulators too, to provide some
sort of compliance test.
These tests are run by the '"Core" Java' test suite, and so are also run with `./gradlew test`.
- In-game (`./src/test/java/dan200/computercraft/ingame/`): These tests are run on an actual Minecraft server, using
[the same system Mojang do][mc-test]. The aim of these is to test in-game behaviour of blocks and peripherals.
These are run by `./gradlew testInGame`.
## CraftOS tests
CraftOS's tests are written using a test system called "mcfly", heavily inspired by [busted] (and thus RSpec). Groups of
tests go inside `describe` blocks, and a single test goes inside `it`.
Assertions are generally written using `expect` (inspired by Hamcrest and the like). For instance, `expect(foo):eq("bar")`
asserts that your variable `foo` is equal to the expected value `"bar"`.
[new-issue]: https://github.com/SquidDev-CC/CC-Tweaked/issues/new/choose "Create a new issue"
[community]: README.md#Community "Get in touch with the community."
[checkstyle]: https://checkstyle.org/
[illuaminate]: https://github.com/SquidDev/illuaminate/
[illuaminate-usage]: https://github.com/SquidDev/illuaminate/blob/master/README.md#usage
[weblate]: https://i18n.tweaked.cc/projects/cc-tweaked/minecraft/
[illuaminate]: https://github.com/SquidDev/illuaminate/ "Illuaminate on GitHub"
[illuaminate-usage]: https://github.com/SquidDev/illuaminate/blob/master/README.md#usage "Installing Illuaminate"
[weblate]: https://i18n.tweaked.cc/projects/cc-tweaked/minecraft/ "CC: Tweaked weblate instance"
[docs]: https://tweaked.cc/ "CC: Tweaked documentation"
[ldoc]: http://stevedonovan.github.io/ldoc/ "ldoc, a Lua documentation generator."
[mc-test]: https://www.youtube.com/watch?v=vXaWOJTCYNg
[busted]: https://github.com/Olivine-Labs/busted "busted: Elegant Lua unit testing."

View File

@@ -6,12 +6,17 @@ buildscript {
name = "forge"
url = "https://files.minecraftforge.net/maven"
}
maven {
name = "Sponge (Mixin)"
url = "https://repo.spongepowered.org/repository/maven-public/"
content { includeGroup "org.spongepowered" }
}
}
dependencies {
classpath 'com.google.code.gson:gson:2.8.1'
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.190'
classpath 'net.minecraftforge.gradle:ForgeGradle:4.1.3'
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2'
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT'
}
}
@@ -19,12 +24,13 @@ plugins {
id "checkstyle"
id "jacoco"
id "com.github.hierynomus.license" version "0.15.0"
id "com.matthewprenger.cursegradle" version "1.3.0"
id "com.github.breadmoirai.github-release" version "2.2.4"
id "com.matthewprenger.cursegradle" version "1.4.0"
id "com.github.breadmoirai.github-release" version "2.2.12"
id "org.jetbrains.kotlin.jvm" version "1.3.72"
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.ajoberstar.grgit'
apply plugin: 'org.spongepowered.mixin'
apply plugin: 'maven-publish'
apply plugin: 'maven'
@@ -33,7 +39,11 @@ version = mod_version
group = "org.squiddev"
archivesBaseName = "cc-tweaked-${mc_version}"
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
}
minecraft {
runs {
@@ -50,9 +60,10 @@ minecraft {
}
server {
workingDirectory project.file("run/server-${mc_version}")
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
workingDirectory project.file("run/server")
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
arg "--nogui"
mods {
computercraft {
@@ -63,7 +74,7 @@ minecraft {
data {
workingDirectory project.file('run')
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP'
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
args '--mod', 'computercraft', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
@@ -73,13 +84,32 @@ minecraft {
}
}
}
testServer {
workingDirectory project.file('test-files/server')
parent runs.server
properties 'mixin.env.disableRefMap': 'true'
arg "-mixin.config=cctest.mixin.json"
arg "--nogui"
mods {
cctest {
source sourceSets.test
}
}
}
}
mappings channel: 'snapshot', version: "${mappings_version}".toString()
mappings channel: 'official', version: mc_version
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
}
mixin {
add sourceSets.test, "cctest.refmap.json"
}
sourceSets {
main.resources {
srcDir 'src/generated/resources'
@@ -120,6 +150,9 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72'
testImplementation 'org.jetbrains.kotlin:kotlin-reflect:1.3.72'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
@@ -142,11 +175,10 @@ task luaJavadoc(type: Javadoc) {
options.docletpath = configurations.cctJavadoc.files as List
options.doclet = "cc.tweaked.javadoc.LuaDoclet"
options.noTimestamp = false
// Attempt to run under Java 11 (any Java >= 9 will work though).
if(System.getProperty("java.version").startsWith("1.")
&& (System.getenv("JAVA_HOME_11_X64") != null || project.hasProperty("java11Home"))) {
executable = "${System.getenv("JAVA_HOME_11_X64") ?: project.property("java11Home")}/bin/javadoc"
javadocTool = javaToolchains.javadocToolFor {
languageVersion = JavaLanguageVersion.of(11)
}
}
@@ -184,7 +216,6 @@ import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import com.hierynomus.gradle.license.tasks.LicenseCheck
import com.hierynomus.gradle.license.tasks.LicenseFormat
import org.ajoberstar.grgit.Grgit
import proguard.gradle.ProGuardTask
task proguard(type: ProGuardTask, dependsOn: jar) {
@@ -237,16 +268,15 @@ processResources {
def hash = 'none'
Set<String> contributors = []
try {
def grgit = Grgit.open(dir: '.')
hash = grgit.head().id
hash = ["git", "-C", projectDir, "rev-parse", "HEAD"].execute().text.trim()
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
grgit.log().each {
if (!blacklist.contains(it.author.name)) contributors.add(it.author.name)
if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
["git", "-C", projectDir, "log", "--format=tformat:%an%n%cn"].execute().text.split('\n').each {
if (!blacklist.contains(it)) contributors.add(it)
}
} catch(Exception ignored) { }
} catch(Exception e) {
e.printStackTrace()
}
inputs.property "commithash", hash
from(sourceSets.main.resources.srcDirs) {
@@ -369,6 +399,7 @@ test {
}
jacocoTestReport {
dependsOn('test')
reports {
xml.enabled true
html.enabled true
@@ -388,14 +419,14 @@ license {
it.configure {
include("**/*.java")
exclude("dan200/computercraft/api/**")
header rootProject.file('config/license/main.txt')
header file('config/license/main.txt')
}
}
[licenseTest, licenseFormatTest].forEach {
it.configure {
include("**/*.java")
header rootProject.file('config/license/main.txt')
header file('config/license/main.txt')
}
}
@@ -412,10 +443,71 @@ task licenseFormatAPI(type: LicenseFormat);
it.configure {
source = sourceSets.main.java
include("dan200/computercraft/api/**")
header rootProject.file('config/license/api.txt')
header file('config/license/api.txt')
}
}
task setupServer(type: Copy) {
group "test server"
description "Sets up the environment for the test server."
from("src/test/server-files") {
include "eula.txt"
include "server.properties"
}
into "test-files/server"
}
tasks.register('testInGame', JavaExec.class).configure {
it.group('test server')
it.description("Runs tests on a temporary Minecraft server.")
it.dependsOn(setupServer, 'prepareRunTestServer')
// Copy from runTestServer. We do it in this slightly odd way as runTestServer
// isn't created until the task is configured (which is no good for us).
JavaExec exec = tasks.getByName('runTestServer')
it.setWorkingDir(exec.getWorkingDir())
it.setSystemProperties(exec.getSystemProperties())
it.setBootstrapClasspath(exec.getBootstrapClasspath())
it.setClasspath(exec.getClasspath())
it.setMain(exec.getMain())
it.setEnvironment(exec.getEnvironment())
it.setArgs(exec.getArgs())
it.setJvmArgs(exec.getJvmArgs())
it.systemProperty('forge.logging.console.level', 'info')
it.systemProperty('cctest.run', 'true')
// Jacoco and modlauncher don't play well together as the classes loaded in-game don't
// match up with those written to disk. We get Jacoco to dump all classes to disk, and
// use that when generating the report.
def coverageOut = new File(buildDir, 'jacocoClassDump/testInGame')
jacoco.applyTo(it)
it.jacoco.setIncludes(["dan200.computercraft.*"])
it.jacoco.setClassDumpDir(coverageOut)
it.outputs.dir(coverageOut)
// Older versions of modlauncher don't include a protection domain (and thus no code
// source). Jacoco skips such classes by default, so we need to explicitly include them.
it.jacoco.setIncludeNoLocationClasses(true)
}
tasks.register('jacocoTestInGameReport', JacocoReport.class).configure {
it.group('test server')
it.description('Generate coverage reports for in-game tests (testInGame)')
it.dependsOn('testInGame')
it.executionData(new File(buildDir, 'jacoco/testInGame.exec'))
it.sourceDirectories.from(sourceSets.main.allJava.srcDirs)
it.classDirectories.from(new File(buildDir, 'jacocoClassDump/testInGame'))
it.reports {
xml.enabled true
html.enabled true
}
}
check.dependsOn('jacocoTestInGameReport')
// Upload tasks
task checkRelease {
@@ -430,7 +522,7 @@ task checkRelease {
def ok = true
// Check we're targetting the current version
def whatsnew = new File("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt").readLines()
def whatsnew = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt").readLines()
if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
ok = false
project.logger.error("Expected `whatsnew.txt' to target $mod_version.")
@@ -447,7 +539,7 @@ task checkRelease {
// Check whatsnew and changelog match.
def versionChangelog = "# " + whatsnew.join("\n")
def changelog = new File("src/main/resources/data/computercraft/lua/rom/help/changelog.txt").getText()
def changelog = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/changelog.txt").getText()
if (!changelog.startsWith(versionChangelog)) {
ok = false
project.logger.error("whatsnew and changelog are not in sync")
@@ -468,6 +560,9 @@ curseforge {
relations {
incompatible "computercraft"
}
addGameVersion '1.16.4'
addGameVersion '1.16.5'
}
}
@@ -528,18 +623,23 @@ githubRelease {
token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
owner 'SquidDev-CC'
repo 'CC-Tweaked'
try {
targetCommitish = Grgit.open(dir: '.').branch.current().name
} catch(Exception ignored) { }
targetCommitish.set(project.provider({
try {
return ["git", "-C", projectDir, "rev-parse", "--abbrev-ref", "HEAD"].execute().text.trim()
} catch (Exception e) {
e.printStackTrace()
}
return "master"
}))
tagName "v${mc_version}-${mod_version}"
releaseName "[${mc_version}] ${mod_version}"
body {
"## " + new File("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
body.set(project.provider({
"## " + new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
.readLines()
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
.join("\n").trim()
}
}))
prerelease false
}

View File

@@ -7,7 +7,7 @@
<property name="charset" value="UTF-8" />
<module name="SuppressionFilter">
<property name="file" value="config/checkstyle/suppressions.xml" />
<property name="file" value="${config_loc}/suppressions.xml" />
</module>
<module name="BeforeExecutionExclusionFileFilter">
@@ -97,20 +97,11 @@
<module name="LambdaParameterName" />
<module name="LocalFinalVariableName" />
<module name="LocalVariableName" />
<!-- Allow an optional m_ on private members -->
<module name="MemberName">
<property name="applyToPrivate" value="false" />
<property name="applyToPackage" value="false" />
</module>
<module name="MemberName">
<property name="format" value="^(m_)?[a-z][a-zA-Z0-9]*$" />
<property name="applyToPrivate" value="true" />
<property name="applyToPackage" value="true" />
</module>
<module name="MemberName" />
<module name="MethodName" />
<module name="MethodTypeParameterName" />
<module name="PackageName">
<property name="format" value="^dan200\.computercraf(\.[a-z][a-z0-9]*)*" />
<property name="format" value="^dan200\.computercraft(\.[a-z][a-z0-9]*)*" />
</module>
<module name="ParameterName" />
<module name="StaticVariableName">

21
doc/events/alarm.md Normal file
View File

@@ -0,0 +1,21 @@
---
module: [kind=event] alarm
see: os.setAlarm To start an alarm.
---
The @{timer} event is fired when an alarm started with @{os.setAlarm} completes.
## Return Values
1. @{string}: The event name.
2. @{number}: The ID of the alarm that finished.
## Example
Starts a timer and then prints its ID:
```lua
local alarmID = os.setAlarm(os.time() + 0.05)
local event, id
repeat
event, id = os.pullEvent("alarm")
until id == alarmID
print("Alarm with ID " .. id .. " was fired")
```

24
doc/events/char.md Normal file
View File

@@ -0,0 +1,24 @@
---
module: [kind=event] char
see: key To listen to any key press.
---
The @{char} event is fired when a character is _typed_ on the keyboard.
The @{char} event is different to a key press. Sometimes multiple key presses may result in one character being
typed (for instance, on some European keyboards). Similarly, some keys (e.g. <kbd>Ctrl</kbd>) do not have any
corresponding character. The @{key} should be used if you want to listen to key presses themselves.
## Return values
1. @{string}: The event name.
2. @{string}: The string representing the character that was pressed.
## Example
Prints each character the user presses:
```lua
while true do
local event, character = os.pullEvent("char")
print(character .. " was pressed.")
end
```

View File

@@ -0,0 +1,18 @@
---
module: [kind=event] computer_command
---
The @{computer_command} event is fired when the `/computercraft queue` command is run for the current computer.
## Return Values
1. @{string}: The event name.
... @{string}: The arguments passed to the command.
## Example
Prints the contents of messages sent:
```lua
while true do
local event = {os.pullEvent("computer_command")}
print("Received message:", table.unpack(event, 2))
end
```

19
doc/events/disk.md Normal file
View File

@@ -0,0 +1,19 @@
---
module: [kind=event] disk
see: disk_eject For the event sent when a disk is removed.
---
The @{disk} event is fired when a disk is inserted into an adjacent or networked disk drive.
## Return Values
1. @{string}: The event name.
2. @{string}: The side of the disk drive that had a disk inserted.
## Example
Prints a message when a disk is inserted:
```lua
while true do
local event, side = os.pullEvent("disk")
print("Inserted a disk on side " .. side)
end
```

19
doc/events/disk_eject.md Normal file
View File

@@ -0,0 +1,19 @@
---
module: [kind=event] disk_eject
see: disk For the event sent when a disk is inserted.
---
The @{disk_eject} event is fired when a disk is removed from an adjacent or networked disk drive.
## Return Values
1. @{string}: The event name.
2. @{string}: The side of the disk drive that had a disk removed.
## Example
Prints a message when a disk is removed:
```lua
while true do
local event, side = os.pullEvent("disk_eject")
print("Removed a disk on side " .. side)
end
```

14
doc/events/http_check.md Normal file
View File

@@ -0,0 +1,14 @@
---
module: [kind=event] http_check
see: http.checkURLAsync To check a URL asynchronously.
---
The @{http_check} event is fired when a URL check finishes.
This event is normally handled inside @{http.checkURL}, but it can still be seen when using @{http.checkURLAsync}.
## Return Values
1. @{string}: The event name.
2. @{string}: The URL requested to be checked.
3. @{boolean}: Whether the check succeeded.
4. @{string|nil}: If the check failed, a reason explaining why the check failed.

View File

@@ -0,0 +1,39 @@
---
module: [kind=event] http_failure
see: http.request To send an HTTP request.
---
The @{http_failure} event is fired when an HTTP request fails.
This event is normally handled inside @{http.get} and @{http.post}, but it can still be seen when using @{http.request}.
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the site requested.
3. @{string}: An error describing the failure.
4. @{http.Response|nil}: A response handle if the connection succeeded, but the server's response indicated failure.
## Example
Prints an error why the website cannot be contacted:
```lua
local myURL = "https://does.not.exist.tweaked.cc"
http.request(myURL)
local event, url, err
repeat
event, url, err = os.pullEvent("http_failure")
until url == myURL
print("The URL " .. url .. " could not be reached: " .. err)
```
Prints the contents of a webpage that does not exist:
```lua
local myURL = "https://tweaked.cc/this/does/not/exist"
http.request(myURL)
local event, url, err, handle
repeat
event, url, err, handle = os.pullEvent("http_failure")
until url == myURL
print("The URL " .. url .. " could not be reached: " .. err)
print(handle.getResponseCode())
handle.close()
```

View File

@@ -0,0 +1,27 @@
---
module: [kind=event] http_success
see: http.request To make an HTTP request.
---
The @{http_success} event is fired when an HTTP request returns successfully.
This event is normally handled inside @{http.get} and @{http.post}, but it can still be seen when using @{http.request}.
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the site requested.
3. @{http.Response}: The handle for the response text.
## Example
Prints the content of a website (this may fail if the request fails):
```lua
local myURL = "https://tweaked.cc/"
http.request(myURL)
local event, url, handle
repeat
event, url, handle = os.pullEvent("http_success")
until url == myURL
print("Contents of " .. url .. ":")
print(handle.readAll())
handle.close()
```

26
doc/events/key.md Normal file
View File

@@ -0,0 +1,26 @@
---
module: [kind=event] key
---
This event is fired when any key is pressed while the terminal is focused.
This event returns a numerical "key code" (for instance, <kbd>F1</kbd> is 290). This value may vary between versions and
so it is recommended to use the constants in the @{keys} API rather than hard coding numeric values.
If the button pressed represented a printable character, then the @{key} event will be followed immediately by a @{char}
event. If you are consuming text input, use a @{char} event instead!
## Return values
1. @{string}: The event name.
2. @{number}: The numerical key value of the key pressed.
3. @{boolean}: Whether the key event was generated while holding the key (@{true}), rather than pressing it the first time (@{false}).
## Example
Prints each key when the user presses it, and if the key is being held.
```lua
while true do
local event, key, is_held = os.pullEvent("key")
print(("%s held=%s"):format(keys.getName(key), is_held))
end
```

24
doc/events/key_up.md Normal file
View File

@@ -0,0 +1,24 @@
---
module: [kind=event] key_up
see: keys For a lookup table of the given keys.
---
Fired whenever a key is released (or the terminal is closed while a key was being pressed).
This event returns a numerical "key code" (for instance, <kbd>F1</kbd> is 290). This value may vary between versions and
so it is recommended to use the constants in the @{keys} API rather than hard coding numeric values.
## Return values
1. @{string}: The event name.
2. @{number}: The numerical key value of the key pressed.
## Example
Prints each key released on the keyboard whenever a @{key_up} event is fired.
```lua
while true do
local event, key = os.pullEvent("key_up")
local name = keys.getName(key) or "unknown key"
print(name .. " was released.")
end
```

View File

@@ -0,0 +1,22 @@
---
module: [kind=event] modem_message
---
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.
2. @{string}: The side of the modem that received the message.
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 (decimal).
## Example
Prints a message when one is sent:
```lua
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)))
end
```

View File

@@ -0,0 +1,18 @@
---
module: [kind=event] monitor_resize
---
The @{monitor_resize} event is fired when an adjacent or networked monitor's size is changed.
## Return Values
1. @{string}: The event name.
2. @{string}: The side or network ID of the monitor that resized.
## Example
Prints a message when a monitor is resized:
```lua
while true do
local event, side = os.pullEvent("monitor_resize")
print("The monitor on side " .. side .. " was resized.")
end
```

View File

@@ -0,0 +1,20 @@
---
module: [kind=event] monitor_touch
---
The @{monitor_touch} event is fired when an adjacent or networked Advanced Monitor is right-clicked.
## Return Values
1. @{string}: The event name.
2. @{string}: The side or network ID of the monitor that was touched.
3. @{number}: The X coordinate of the touch, in characters.
4. @{number}: The Y coordinate of the touch, in characters.
## Example
Prints a message when a monitor is touched:
```lua
while true do
local event, side, x, y = os.pullEvent("monitor_touch")
print("The monitor on side " .. side .. " was touched at (" .. x .. ", " .. y .. ")")
end
```

34
doc/events/mouse_click.md Normal file
View File

@@ -0,0 +1,34 @@
---
module: [kind=event] mouse_click
---
This event is fired when the terminal is clicked with a mouse. This event is only fired on advanced computers (including
advanced turtles and pocket computers).
## Return values
1. @{string}: The event name.
2. @{number}: The mouse button that was clicked.
3. @{number}: The X-coordinate of the click.
4. @{number}: The Y-coordinate of the click.
## Mouse buttons
Several mouse events (@{mouse_click}, @{mouse_up}, @{mouse_scroll}) contain a "mouse button" code. This takes a
numerical value depending on which button on your mouse was last pressed when this event occurred.
<table class="pretty-table">
<!-- Our markdown parser doesn't work on tables!? Guess I'll have to roll my own soonish :/. -->
<tr><th>Button code</th><th>Mouse button</th></tr>
<tr><td align="right">1</td><td>Left button</td></tr>
<tr><td align="right">2</td><td>Middle button</td></tr>
<tr><td align="right">3</td><td>Right button</td></tr>
</table>
## Example
Print the button and the coordinates whenever the mouse is clicked.
```lua
while true do
local event, button, x, y = os.pullEvent("mouse_click")
print(("The mouse button %s was pressed at %d, %d"):format(button, x, y))
end
```

22
doc/events/mouse_drag.md Normal file
View File

@@ -0,0 +1,22 @@
---
module: [kind=event] mouse_drag
see: mouse_click For when a mouse button is initially pressed.
---
This event is fired every time the mouse is moved while a mouse button is being held.
## Return values
1. @{string}: The event name.
2. @{number}: The [mouse button](mouse_click.html#Mouse_buttons) that is being pressed.
3. @{number}: The X-coordinate of the mouse.
4. @{number}: The Y-coordinate of the mouse.
## Example
Print the button and the coordinates whenever the mouse is dragged.
```lua
while true do
local event, button, x, y = os.pullEvent("mouse_drag")
print(("The mouse button %s was dragged at %d, %d"):format(button, x, y))
end
```

View File

@@ -0,0 +1,21 @@
---
module: [kind=event] mouse_scroll
---
This event is fired when a mouse wheel is scrolled in the terminal.
## Return values
1. @{string}: The event name.
2. @{number}: The direction of the scroll. (-1 = up, 1 = down)
3. @{number}: The X-coordinate of the mouse when scrolling.
4. @{number}: The Y-coordinate of the mouse when scrolling.
## Example
Prints the direction of each scroll, and the position of the mouse at the time.
```lua
while true do
local event, dir, x, y = os.pullEvent("mouse_scroll")
print(("The mouse was scrolled in direction %s at %d, %d"):format(dir, x, y))
end
```

21
doc/events/mouse_up.md Normal file
View File

@@ -0,0 +1,21 @@
---
module: [kind=event] mouse_up
---
This event is fired when a mouse button is released or a held mouse leaves the computer's terminal.
## Return values
1. @{string}: The event name.
2. @{number}: The [mouse button](mouse_click.html#Mouse_buttons) that was released.
3. @{number}: The X-coordinate of the mouse.
4. @{number}: The Y-coordinate of the mouse.
## Example
Prints the coordinates and button number whenever the mouse is released.
```lua
while true do
local event, button, x, y = os.pullEvent("mouse_up")
print(("The mouse button %s was released at %d, %d"):format(button, x, y))
end
```

18
doc/events/paste.md Normal file
View File

@@ -0,0 +1,18 @@
---
module: [kind=event] paste
---
The @{paste} event is fired when text is pasted into the computer through Ctrl-V (or ⌘V on Mac).
## Return values
1. @{string}: The event name.
2. @{string} The text that was pasted.
## Example
Prints pasted text:
```lua
while true do
local event, text = os.pullEvent("paste")
print('"' .. text .. '" was pasted')
end
```

19
doc/events/peripheral.md Normal file
View File

@@ -0,0 +1,19 @@
---
module: [kind=event] peripheral
see: peripheral_detach For the event fired when a peripheral is detached.
---
The @{peripheral} event is fired when a peripheral is attached on a side or to a modem.
## Return Values
1. @{string}: The event name.
2. @{string}: The side the peripheral was attached to.
## Example
Prints a message when a peripheral is attached:
```lua
while true do
local event, side = os.pullEvent("peripheral")
print("A peripheral was attached on side " .. side)
end
```

View File

@@ -0,0 +1,19 @@
---
module: [kind=event] peripheral_detach
see: peripheral For the event fired when a peripheral is attached.
---
The @{peripheral_detach} event is fired when a peripheral is detached from a side or from a modem.
## Return Values
1. @{string}: The event name.
2. @{string}: The side the peripheral was detached from.
## Example
Prints a message when a peripheral is detached:
```lua
while true do
local event, side = os.pullEvent("peripheral_detach")
print("A peripheral was detached on side " .. side)
end
```

View File

@@ -0,0 +1,30 @@
---
module: [kind=event] rednet_message
see: modem_message For raw modem messages sent outside of Rednet.
see: rednet.receive To wait for a Rednet message with an optional timeout and protocol filter.
---
The @{rednet_message} event is fired when a message is sent over Rednet.
This event is usually handled by @{rednet.receive}, but it can also be pulled manually.
@{rednet_message} events are sent by @{rednet.run} in the top-level coroutine in response to @{modem_message} events. A @{rednet_message} event is always preceded by a @{modem_message} event. They are generated inside CraftOS rather than being sent by the ComputerCraft machine.
## Return Values
1. @{string}: The event name.
2. @{number}: The ID of the sending computer.
3. @{any}: The message sent.
4. @{string|nil}: The protocol of the message, if provided.
## Example
Prints a message when one is sent:
```lua
while true do
local event, sender, message, protocol = os.pullEvent("rednet_message")
if protocol ~= nil then
print("Received message from " .. sender .. " with protocol " .. protocol .. " and message " .. tostring(message))
else
print("Received message from " .. sender .. " with message " .. tostring(message))
end
end
```

14
doc/events/redstone.md Normal file
View File

@@ -0,0 +1,14 @@
---
module: [kind=event] redstone
---
The @{redstone} event is fired whenever any redstone inputs on the computer change.
## Example
Prints a message when a redstone input changes:
```lua
while true do
os.pullEvent("redstone")
print("A redstone input has changed!")
end
```

View File

@@ -0,0 +1,28 @@
---
module: [kind=event] task_complete
see: commands.execAsync To run a command which fires a task_complete event.
---
The @{task_complete} event is fired when an asynchronous task completes. This is usually handled inside the function call that queued the task; however, functions such as @{commands.execAsync} return immediately so the user can wait for completion.
## Return Values
1. @{string}: The event name.
2. @{number}: The ID of the task that completed.
3. @{boolean}: Whether the command succeeded.
4. @{string}: If the command failed, an error message explaining the failure. (This is not present if the command succeeded.)
...: Any parameters returned from the command.
## Example
Prints the results of an asynchronous command:
```lua
local taskID = commands.execAsync("say Hello")
local event
repeat
event = {os.pullEvent("task_complete")}
until event[2] == taskID
if event[3] == true then
print("Task " .. event[2] .. " succeeded:", table.unpack(event, 4))
else
print("Task " .. event[2] .. " failed: " .. event[4])
end
```

15
doc/events/term_resize.md Normal file
View File

@@ -0,0 +1,15 @@
---
module: [kind=event] term_resize
---
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 :
```lua
while true do
os.pullEvent("term_resize")
local w, h = term.getSize()
print("The term was resized to (" .. w .. ", " .. h .. ")")
end
```

25
doc/events/terminate.md Normal file
View File

@@ -0,0 +1,25 @@
---
module: [kind=event] terminate
---
The @{terminate} event is fired when <kbd>Ctrl-T</kbd> is held down.
This event is normally handled by @{os.pullEvent}, and will not be returned. However, @{os.pullEventRaw} will return this event when fired.
@{terminate} will be sent even when a filter is provided to @{os.pullEventRaw}. When using @{os.pullEventRaw} with a filter, make sure to check that the event is not @{terminate}.
## Example
Prints a message when Ctrl-T is held:
```lua
while true do
local event = os.pullEventRaw("terminate")
if event == "terminate" then print("Terminate requested!") end
end
```
Exits when Ctrl-T is held:
```lua
while true do
os.pullEvent()
end
```

21
doc/events/timer.md Normal file
View File

@@ -0,0 +1,21 @@
---
module: [kind=event] timer
see: os.startTimer To start a timer.
---
The @{timer} event is fired when a timer started with @{os.startTimer} completes.
## Return Values
1. @{string}: The event name.
2. @{number}: The ID of the timer that finished.
## Example
Starts a timer and then prints its ID:
```lua
local timerID = os.startTimer(2)
local event, id
repeat
event, id = os.pullEvent("timer")
until id == timerID
print("Timer with ID " .. id .. " was fired")
```

View File

@@ -0,0 +1,14 @@
---
module: [kind=event] turtle_inventory
---
The @{turtle_inventory} event is fired when a turtle's inventory is changed.
## Example
Prints a message when the inventory is changed:
```lua
while true do
os.pullEvent("turtle_inventory")
print("The inventory was changed.")
end
```

View File

@@ -0,0 +1,21 @@
---
module: [kind=event] websocket_closed
---
The @{websocket_closed} event is fired when an open WebSocket connection is closed.
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the WebSocket that was closed.
## Example
Prints a message when a WebSocket is closed (this may take a minute):
```lua
local myURL = "wss://example.tweaked.cc/echo"
local ws = http.websocket(myURL)
local event, url
repeat
event, url = os.pullEvent("websocket_closed")
until url == myURL
print("The WebSocket at " .. url .. " was closed.")
```

View File

@@ -0,0 +1,25 @@
---
module: [kind=event] websocket_failure
see: http.websocketAsync To send an HTTP request.
---
The @{websocket_failure} event is fired when a WebSocket connection request fails.
This event is normally handled inside @{http.websocket}, but it can still be seen when using @{http.websocketAsync}.
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the site requested.
3. @{string}: An error describing the failure.
## Example
Prints an error why the website cannot be contacted:
```lua
local myURL = "wss://example.tweaked.cc/not-a-websocket"
http.websocketAsync(myURL)
local event, url, err
repeat
event, url, err = os.pullEvent("websocket_failure")
until url == myURL
print("The URL " .. url .. " could not be reached: " .. err)
```

View File

@@ -0,0 +1,26 @@
---
module: [kind=event] websocket_message
---
The @{websocket_message} event is fired when a message is received on an open WebSocket connection.
This event is normally handled by @{http.Websocket.receive}, but it can also be pulled manually.
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the WebSocket.
3. @{string}: The contents of the message.
## Example
Prints a message sent by a WebSocket:
```lua
local myURL = "wss://example.tweaked.cc/echo"
local ws = http.websocket(myURL)
ws.send("Hello!")
local event, url, message
repeat
event, url, message = os.pullEvent("websocket_message")
until url == myURL
print("Received message from " .. url .. " with contents " .. message)
ws.close()
```

View File

@@ -0,0 +1,28 @@
---
module: [kind=event] websocket_success
see: http.websocketAsync To open a WebSocket asynchronously.
---
The @{websocket_success} event is fired when a WebSocket connection request returns successfully.
This event is normally handled inside @{http.websocket}, but it can still be seen when using @{http.websocketAsync}.
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the site.
3. @{http.Websocket}: The handle for the WebSocket.
## Example
Prints the content of a website (this may fail if the request fails):
```lua
local myURL = "wss://example.tweaked.cc/echo"
http.websocketAsync(myURL)
local event, url, handle
repeat
event, url, handle = os.pullEvent("websocket_success")
until url == myURL
print("Connected to " .. url)
handle.send("Hello!")
print(handle.receive())
handle.close()
```

View File

@@ -58,10 +58,10 @@ function request(...) end
-- @treturn string A message detailing why the request failed.
-- @treturn Response|nil The failing http response, if available.
--
-- @usage Make a request to [example.computercraft.cc](https://example.computercraft.cc),
-- @usage Make a request to [example.tweaked.cc](https://example.tweaked.cc),
-- and print the returned page.
-- ```lua
-- local request = http.get("https://example.computercraft.cc")
-- local request = http.get("https://example.tweaked.cc")
-- print(request.readAll())
-- -- => HTTP is working!
-- request.close()
@@ -123,7 +123,7 @@ function checkURLAsync(url) end
--
-- @usage
-- ```lua
-- print(http.checkURL("https://example.computercraft.cc/"))
-- print(http.checkURL("https://example.tweaked.cc/"))
-- -- => true
-- print(http.checkURL("http://localhost/"))
-- -- => false Domain not permitted

View File

@@ -1,7 +1,6 @@
# Mod properties
mod_version=1.95.1
mod_version=1.95.3
# Minecraft properties (update mods.toml when changing)
mc_version=1.16.4
forge_version=35.0.1
mappings_version=20201028-1.16.3
forge_version=35.1.16

Binary file not shown.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

53
gradlew vendored
View File

@@ -1,5 +1,21 @@
#!/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
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
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.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; 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\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
@@ -138,19 +156,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`
# 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"
# 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" "$@"

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
@rem ##########################################################################
@rem
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
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.
set DEFAULT_JVM_OPTS=
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
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_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
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
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@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
@rem End local scope for the variables with windows NT shell

View File

@@ -2,6 +2,7 @@
(sources
/doc/stub/
/doc/events/
/build/docs/luaJavadoc/
/src/main/resources/*/computercraft/lua/bios.lua
/src/main/resources/*/computercraft/lua/rom/
@@ -25,7 +26,8 @@
(module-kinds
(peripheral Peripherals)
(generic_peripheral "Generic Peripherals"))
(generic_peripheral "Generic Peripherals")
(event Events))
(library-path
/doc/stub/

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:1118481}"
"nbt": "{Color:1118481}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:15905484}"
"nbt": "{Color:15905484}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:8375321}"
"nbt": "{Color:8375321}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:14605932}"
"nbt": "{Color:14605932}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:10072818}"
"nbt": "{Color:10072818}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:15040472}"
"nbt": "{Color:15040472}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:15905331}"
"nbt": "{Color:15905331}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:15790320}"
"nbt": "{Color:15790320}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:13388876}"
"nbt": "{Color:13388876}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:5744206}"
"nbt": "{Color:5744206}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:8349260}"
"nbt": "{Color:8349260}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:3368652}"
"nbt": "{Color:3368652}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:11691749}"
"nbt": "{Color:11691749}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:5020082}"
"nbt": "{Color:5020082}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:10066329}"
"nbt": "{Color:10066329}"
}
}

View File

@@ -14,6 +14,6 @@
],
"result": {
"item": "computercraft:disk",
"nbt": "{color:5000268}"
"nbt": "{Color:5000268}"
}
}

View File

@@ -162,7 +162,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Override
public LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull Direction side )
{
TileEntity tile = world.getTileEntity( pos );
TileEntity tile = world.getBlockEntity( pos );
return tile == null ? LazyOptional.empty() : tile.getCapability( CAPABILITY_WIRED_ELEMENT, side );
}
}

View File

@@ -43,7 +43,7 @@ public final class TransformedModel
public static TransformedModel of( @Nonnull ItemStack item, @Nonnull TransformationMatrix transform )
{
IBakedModel model = Minecraft.getInstance().getItemRenderer().getItemModelMesher().getItemModel( item );
IBakedModel model = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getItemModel( item );
return new TransformedModel( model, transform );
}

View File

@@ -35,7 +35,7 @@ public abstract class AbstractPocketUpgrade implements IPocketUpgrade
protected AbstractPocketUpgrade( ResourceLocation id, NonNullSupplier<ItemStack> item )
{
this( id, Util.makeTranslationKey( "upgrade", id ) + ".adjective", item );
this( id, Util.makeDescriptionId( "upgrade", id ) + ".adjective", item );
}
protected AbstractPocketUpgrade( ResourceLocation id, String adjective, ItemStack stack )

View File

@@ -37,7 +37,7 @@ public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, NonNullSupplier<ItemStack> stack )
{
this( id, type, Util.makeTranslationKey( "upgrade", id ) + ".adjective", stack );
this( id, type, Util.makeDescriptionId( "upgrade", id ) + ".adjective", stack );
}
protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, String adjective, ItemStack stack )

View File

@@ -78,7 +78,7 @@ public final class ClientRegistry
@SubscribeEvent
public static void onTextureStitchEvent( TextureStitchEvent.Pre event )
{
if( !event.getMap().getTextureLocation().equals( PlayerContainer.LOCATION_BLOCKS_TEXTURE ) ) return;
if( !event.getMap().location().equals( PlayerContainer.BLOCK_ATLAS ) ) return;
for( String extra : EXTRA_TEXTURES )
{
@@ -96,10 +96,10 @@ public final class ClientRegistry
for( String modelName : EXTRA_MODELS )
{
ResourceLocation location = new ResourceLocation( ComputerCraft.MOD_ID, "item/" + modelName );
IUnbakedModel model = loader.getUnbakedModel( location );
model.getTextures( loader::getUnbakedModel, new HashSet<>() );
IUnbakedModel model = loader.getModel( location );
model.getMaterials( loader::getModel, new HashSet<>() );
IBakedModel baked = model.bakeModel( loader, ModelLoader.defaultTextureGetter(), SimpleModelTransform.IDENTITY, location );
IBakedModel baked = model.bake( loader, ModelLoader.defaultTextureGetter(), SimpleModelTransform.IDENTITY, location );
if( baked != null )
{
registry.put( new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, modelName ), "inventory" ), baked );

View File

@@ -27,7 +27,7 @@ public class ClientTableFormatter implements TableFormatter
private static FontRenderer renderer()
{
return Minecraft.getInstance().fontRenderer;
return Minecraft.getInstance().font;
}
@Override
@@ -39,7 +39,7 @@ public class ClientTableFormatter implements TableFormatter
FontRenderer renderer = renderer();
float spaceWidth = renderer.getStringWidth( " " );
float spaceWidth = renderer.width( " " );
int spaces = MathHelper.floor( extraWidth / spaceWidth );
int extra = extraWidth - (int) (spaces * spaceWidth);
@@ -55,33 +55,33 @@ public class ClientTableFormatter implements TableFormatter
@Override
public int getWidth( ITextComponent component )
{
return renderer().getStringPropertyWidth( component );
return renderer().width( component );
}
@Override
public void writeLine( int id, ITextComponent component )
{
Minecraft mc = Minecraft.getInstance();
NewChatGui chat = mc.ingameGUI.getChatGUI();
NewChatGui chat = mc.gui.getChat();
// TODO: Trim the text if it goes over the allowed length
// int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() );
// List<ITextProperties> list = RenderComponentsUtil.func_238505_a_( component, maxWidth, mc.fontRenderer );
// List<ITextProperties> list = RenderComponentsUtil.wrapComponents( component, maxWidth, mc.fontRenderer );
// if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id );
chat.printChatMessageWithOptionalDeletion( component, id );
chat.addMessage( component, id );
}
@Override
public int display( TableBuilder table )
{
NewChatGui chat = Minecraft.getInstance().ingameGUI.getChatGUI();
NewChatGui chat = Minecraft.getInstance().gui.getChat();
int lastHeight = lastHeights.get( table.getId() );
int height = TableFormatter.super.display( table );
lastHeights.put( table.getId(), height );
for( int i = height; i < lastHeight; i++ ) chat.deleteChatLine( i + table.getId() );
for( int i = height; i < lastHeight; i++ ) chat.removeById( i + table.getId() );
return height;
}
}

View File

@@ -66,22 +66,22 @@ public final class FixedWidthFontRenderer
int xStart = 1 + column * (FONT_WIDTH + 2);
int yStart = 1 + row * (FONT_HEIGHT + 2);
buffer.pos( transform, x, y, 0f ).color( r, g, b, 1.0f ).tex( xStart / WIDTH, yStart / WIDTH ).endVertex();
buffer.pos( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).tex( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
buffer.pos( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).tex( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).endVertex();
buffer.pos( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).tex( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).endVertex();
buffer.pos( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).tex( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
buffer.pos( transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).tex( (xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
buffer.vertex( transform, x, y, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, yStart / WIDTH ).endVertex();
buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
buffer.vertex( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).endVertex();
buffer.vertex( transform, x + FONT_WIDTH, y, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, yStart / WIDTH ).endVertex();
buffer.vertex( transform, x, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( xStart / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
buffer.vertex( transform, x + FONT_WIDTH, y + FONT_HEIGHT, 0f ).color( r, g, b, 1.0f ).uv( (xStart + FONT_WIDTH) / WIDTH, (yStart + FONT_HEIGHT) / WIDTH ).endVertex();
}
private static void drawQuad( Matrix4f transform, IVertexBuilder buffer, float x, float y, float width, float height, float r, float g, float b )
{
buffer.pos( transform, x, y, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_START, BACKGROUND_START ).endVertex();
buffer.pos( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_START, BACKGROUND_END ).endVertex();
buffer.pos( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_END, BACKGROUND_START ).endVertex();
buffer.pos( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_END, BACKGROUND_START ).endVertex();
buffer.pos( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_START, BACKGROUND_END ).endVertex();
buffer.pos( transform, x + width, y + height, 0 ).color( r, g, b, 1.0f ).tex( BACKGROUND_END, BACKGROUND_END ).endVertex();
buffer.vertex( transform, x, y, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_START ).endVertex();
buffer.vertex( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_END ).endVertex();
buffer.vertex( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_START ).endVertex();
buffer.vertex( transform, x + width, y, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_START ).endVertex();
buffer.vertex( transform, x, y + height, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_START, BACKGROUND_END ).endVertex();
buffer.vertex( transform, x + width, y + height, 0 ).color( r, g, b, 1.0f ).uv( BACKGROUND_END, BACKGROUND_END ).endVertex();
}
private static void drawQuad( Matrix4f transform, IVertexBuilder buffer, float x, float y, float width, float height, Palette palette, boolean greyscale, char colourIndex )
@@ -182,9 +182,9 @@ public final class FixedWidthFontRenderer
{
bindFont();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().renderBuffers().bufferSource();
drawString( IDENTITY, ((IRenderTypeBuffer) renderer).getBuffer( TYPE ), x, y, text, textColour, backgroundColour, palette, greyscale, leftMarginSize, rightMarginSize );
renderer.finish();
renderer.endBatch();
}
public static void drawTerminalWithoutCursor(
@@ -267,10 +267,10 @@ public final class FixedWidthFontRenderer
{
bindFont();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().renderBuffers().bufferSource();
IVertexBuilder buffer = renderer.getBuffer( TYPE );
drawTerminal( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize );
renderer.finish( TYPE );
renderer.endBatch( TYPE );
}
public static void drawTerminal(
@@ -291,9 +291,9 @@ public final class FixedWidthFontRenderer
{
bindFont();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().renderBuffers().bufferSource();
drawEmptyTerminal( transform, renderer, x, y, width, height );
renderer.finish();
renderer.endBatch();
}
public static void drawEmptyTerminal( float x, float y, float width, float height )
@@ -309,7 +309,7 @@ public final class FixedWidthFontRenderer
private static void bindFont()
{
Minecraft.getInstance().getTextureManager().bindTexture( FONT );
Minecraft.getInstance().getTextureManager().bind( FONT );
RenderSystem.texParameter( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
}
@@ -319,26 +319,26 @@ public final class FixedWidthFontRenderer
private static final VertexFormat FORMAT = DefaultVertexFormats.POSITION_COLOR_TEX;
static final RenderType MAIN = RenderType.makeType(
static final RenderType MAIN = RenderType.create(
"terminal_font", FORMAT, GL_MODE, 1024,
false, false, // useDelegate, needsSorting
RenderType.State.getBuilder()
.texture( new RenderState.TextureState( FONT, false, false ) ) // blur, minimap
.alpha( DEFAULT_ALPHA )
.lightmap( LIGHTMAP_DISABLED )
.writeMask( COLOR_WRITE )
.build( false )
RenderType.State.builder()
.setTextureState( new RenderState.TextureState( FONT, false, false ) ) // blur, minimap
.setAlphaState( DEFAULT_ALPHA )
.setLightmapState( NO_LIGHTMAP )
.setWriteMaskState( COLOR_WRITE )
.createCompositeState( false )
);
static final RenderType BLOCKER = RenderType.makeType(
static final RenderType BLOCKER = RenderType.create(
"terminal_blocker", FORMAT, GL_MODE, 256,
false, false, // useDelegate, needsSorting
RenderType.State.getBuilder()
.texture( new RenderState.TextureState( FONT, false, false ) ) // blur, minimap
.alpha( DEFAULT_ALPHA )
.writeMask( DEPTH_WRITE )
.lightmap( LIGHTMAP_DISABLED )
.build( false )
RenderType.State.builder()
.setTextureState( new RenderState.TextureState( FONT, false, false ) ) // blur, minimap
.setAlphaState( DEFAULT_ALPHA )
.setWriteMaskState( DEPTH_WRITE )
.setLightmapState( NO_LIGHTMAP )
.createCompositeState( false )
);
private Type( String name, Runnable setup, Runnable destroy )

View File

@@ -77,30 +77,30 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
@Override
protected void init()
{
minecraft.keyboardListener.enableRepeatEvents( true );
minecraft.keyboardHandler.setSendRepeatsToGui( true );
int termPxWidth = termWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
xSize = termPxWidth + MARGIN * 2 + BORDER * 2;
ySize = termPxHeight + MARGIN * 2 + BORDER * 2;
imageWidth = termPxWidth + MARGIN * 2 + BORDER * 2;
imageHeight = termPxHeight + MARGIN * 2 + BORDER * 2;
super.init();
terminal = new WidgetTerminal( minecraft, () -> computer, termWidth, termHeight, MARGIN, MARGIN, MARGIN, MARGIN );
terminalWrapper = new WidgetWrapper( terminal, MARGIN + BORDER + guiLeft, MARGIN + BORDER + guiTop, termPxWidth, termPxHeight );
terminalWrapper = new WidgetWrapper( terminal, MARGIN + BORDER + leftPos, MARGIN + BORDER + topPos, termPxWidth, termPxHeight );
children.add( terminalWrapper );
setListener( terminalWrapper );
setFocused( terminalWrapper );
}
@Override
public void onClose()
public void removed()
{
super.onClose();
super.removed();
children.remove( terminal );
terminal = null;
minecraft.keyboardListener.enableRepeatEvents( false );
minecraft.keyboardHandler.setSendRepeatsToGui( false );
}
@Override
@@ -114,23 +114,23 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
public boolean keyPressed( int key, int scancode, int modifiers )
{
// Forward the tab key to the terminal, rather than moving between controls.
if( key == GLFW.GLFW_KEY_TAB && getListener() != null && getListener() == terminalWrapper )
if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper )
{
return getListener().keyPressed( key, scancode, modifiers );
return getFocused().keyPressed( key, scancode, modifiers );
}
return super.keyPressed( key, scancode, modifiers );
}
@Override
public void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY )
public void renderBg( @Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY )
{
// Draw terminal
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
// Draw a border around the terminal
RenderSystem.color4f( 1, 1, 1, 1 );
minecraft.getTextureManager().bindTexture( ComputerBorderRenderer.getTexture( family ) );
minecraft.getTextureManager().bind( ComputerBorderRenderer.getTexture( family ) );
ComputerBorderRenderer.render(
terminalWrapper.getX() - MARGIN, terminalWrapper.getY() - MARGIN, getBlitOffset(),
terminalWrapper.getWidth() + MARGIN * 2, terminalWrapper.getHeight() + MARGIN * 2
@@ -141,18 +141,18 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks )
{
super.render( stack, mouseX, mouseY, partialTicks );
renderHoveredTooltip( stack, mouseX, mouseY );
renderTooltip( stack, mouseX, mouseY );
}
@Override
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
{
return (getListener() != null && getListener().mouseDragged( x, y, button, deltaX, deltaY ))
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|| super.mouseDragged( x, y, button, deltaX, deltaY );
}
@Override
protected void drawGuiContainerForegroundLayer( @Nonnull MatrixStack transform, int mouseX, int mouseY )
protected void renderLabels( @Nonnull MatrixStack transform, int mouseX, int mouseY )
{
// Skip rendering labels.
}

View File

@@ -25,11 +25,11 @@ public class GuiDiskDrive extends ContainerScreen<ContainerDiskDrive>
}
@Override
protected void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
protected void renderBg( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
{
RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( BACKGROUND );
blit( transform, guiLeft, guiTop, 0, 0, xSize, ySize );
minecraft.getTextureManager().bind( BACKGROUND );
blit( transform, leftPos, topPos, 0, 0, imageWidth, imageHeight );
}
@Override
@@ -37,6 +37,6 @@ public class GuiDiskDrive extends ContainerScreen<ContainerDiskDrive>
{
renderBackground( transform );
super.render( transform, mouseX, mouseY, partialTicks );
renderHoveredTooltip( transform, mouseX, mouseY );
renderTooltip( transform, mouseX, mouseY );
}
}

View File

@@ -33,13 +33,13 @@ public class GuiPrinter extends ContainerScreen<ContainerPrinter>
}*/
@Override
protected void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
protected void renderBg( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
{
RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( BACKGROUND );
blit( transform, guiLeft, guiTop, 0, 0, xSize, ySize );
minecraft.getTextureManager().bind( BACKGROUND );
blit( transform, leftPos, topPos, 0, 0, imageWidth, imageHeight );
if( getContainer().isPrinting() ) blit( transform, guiLeft + 34, guiTop + 21, 176, 0, 25, 45 );
if( getMenu().isPrinting() ) blit( transform, leftPos + 34, topPos + 21, 176, 0, 25, 45 );
}
@Override
@@ -47,6 +47,6 @@ public class GuiPrinter extends ContainerScreen<ContainerPrinter>
{
renderBackground( stack );
super.render( stack, mouseX, mouseY, partialTicks );
renderHoveredTooltip( stack, mouseX, mouseY );
renderTooltip( stack, mouseX, mouseY );
}
}

View File

@@ -24,29 +24,29 @@ import static dan200.computercraft.client.render.PrintoutRenderer.*;
public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
{
private final boolean m_book;
private final int m_pages;
private final TextBuffer[] m_text;
private final TextBuffer[] m_colours;
private int m_page;
private final boolean book;
private final int pages;
private final TextBuffer[] text;
private final TextBuffer[] colours;
private int page;
public GuiPrintout( ContainerHeldItem container, PlayerInventory player, ITextComponent title )
{
super( container, player, title );
ySize = Y_SIZE;
imageHeight = Y_SIZE;
String[] text = ItemPrintout.getText( container.getStack() );
m_text = new TextBuffer[text.length];
for( int i = 0; i < m_text.length; i++ ) m_text[i] = new TextBuffer( text[i] );
this.text = new TextBuffer[text.length];
for( int i = 0; i < this.text.length; i++ ) this.text[i] = new TextBuffer( text[i] );
String[] colours = ItemPrintout.getColours( container.getStack() );
m_colours = new TextBuffer[colours.length];
for( int i = 0; i < m_colours.length; i++ ) m_colours[i] = new TextBuffer( colours[i] );
this.colours = new TextBuffer[colours.length];
for( int i = 0; i < this.colours.length; i++ ) this.colours[i] = new TextBuffer( colours[i] );
m_page = 0;
m_pages = Math.max( m_text.length / ItemPrintout.LINES_PER_PAGE, 1 );
m_book = ((ItemPrintout) container.getStack().getItem()).getType() == ItemPrintout.Type.BOOK;
page = 0;
pages = Math.max( this.text.length / ItemPrintout.LINES_PER_PAGE, 1 );
book = ((ItemPrintout) container.getStack().getItem()).getType() == ItemPrintout.Type.BOOK;
}
@Override
@@ -56,13 +56,13 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
if( key == GLFW.GLFW_KEY_RIGHT )
{
if( m_page < m_pages - 1 ) m_page++;
if( page < pages - 1 ) page++;
return true;
}
if( key == GLFW.GLFW_KEY_LEFT )
{
if( m_page > 0 ) m_page--;
if( page > 0 ) page--;
return true;
}
@@ -76,14 +76,14 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
if( delta < 0 )
{
// Scroll up goes to the next page
if( m_page < m_pages - 1 ) m_page++;
if( page < pages - 1 ) page++;
return true;
}
if( delta > 0 )
{
// Scroll down goes to the previous page
if( m_page > 0 ) m_page--;
if( page > 0 ) page--;
return true;
}
@@ -91,17 +91,17 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
}
@Override
protected void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
protected void renderBg( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
{
// Draw the printout
RenderSystem.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
RenderSystem.enableDepthTest();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource();
Matrix4f matrix = transform.getLast().getMatrix();
drawBorder( matrix, renderer, guiLeft, guiTop, getBlitOffset(), m_page, m_pages, m_book );
drawText( matrix, renderer, guiLeft + X_TEXT_MARGIN, guiTop + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
renderer.finish();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().renderBuffers().bufferSource();
Matrix4f matrix = transform.last().pose();
drawBorder( matrix, renderer, leftPos, topPos, getBlitOffset(), page, pages, book );
drawText( matrix, renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * page, text, colours );
renderer.endBatch();
}
@Override
@@ -116,7 +116,7 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
}
@Override
protected void drawGuiContainerForegroundLayer( @Nonnull MatrixStack transform, int mouseX, int mouseY )
protected void renderLabels( @Nonnull MatrixStack transform, int mouseX, int mouseY )
{
// Skip rendering labels.
}

View File

@@ -23,13 +23,13 @@ import javax.annotation.Nonnull;
public class GuiTurtle extends ContainerScreen<ContainerTurtle>
{
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( "computercraft", "textures/gui/turtle_normal.png" );
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( "computercraft", "textures/gui/turtle_advanced.png" );
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/turtle_normal.png" );
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/turtle_advanced.png" );
private ContainerTurtle m_container;
private final ContainerTurtle container;
private final ComputerFamily m_family;
private final ClientComputer m_computer;
private final ComputerFamily family;
private final ClientComputer computer;
private WidgetTerminal terminal;
private WidgetWrapper terminalWrapper;
@@ -38,42 +38,42 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
{
super( container, player, title );
m_container = container;
m_family = container.getFamily();
m_computer = (ClientComputer) container.getComputer();
this.container = container;
family = container.getFamily();
computer = (ClientComputer) container.getComputer();
xSize = 254;
ySize = 217;
imageWidth = 254;
imageHeight = 217;
}
@Override
protected void init()
{
super.init();
minecraft.keyboardListener.enableRepeatEvents( true );
minecraft.keyboardHandler.setSendRepeatsToGui( true );
int termPxWidth = ComputerCraft.turtleTermWidth * FixedWidthFontRenderer.FONT_WIDTH;
int termPxHeight = ComputerCraft.turtleTermHeight * FixedWidthFontRenderer.FONT_HEIGHT;
terminal = new WidgetTerminal(
minecraft, () -> m_computer,
minecraft, () -> computer,
ComputerCraft.turtleTermWidth,
ComputerCraft.turtleTermHeight,
2, 2, 2, 2
);
terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + guiLeft, 2 + 8 + guiTop, termPxWidth, termPxHeight );
terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + leftPos, 2 + 8 + topPos, termPxWidth, termPxHeight );
children.add( terminalWrapper );
setListener( terminalWrapper );
setFocused( terminalWrapper );
}
@Override
public void onClose()
public void removed()
{
super.onClose();
super.removed();
children.remove( terminal );
terminal = null;
minecraft.keyboardListener.enableRepeatEvents( false );
minecraft.keyboardHandler.setSendRepeatsToGui( false );
}
@Override
@@ -87,35 +87,35 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
public boolean keyPressed( int key, int scancode, int modifiers )
{
// Forward the tab key to the terminal, rather than moving between controls.
if( key == GLFW.GLFW_KEY_TAB && getListener() != null && getListener() == terminalWrapper )
if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper )
{
return getListener().keyPressed( key, scancode, modifiers );
return getFocused().keyPressed( key, scancode, modifiers );
}
return super.keyPressed( key, scancode, modifiers );
}
@Override
protected void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
protected void renderBg( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
{
// Draw term
ResourceLocation texture = m_family == ComputerFamily.ADVANCED ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL;
ResourceLocation texture = family == ComputerFamily.ADVANCED ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL;
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
// Draw border/inventory
RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( texture );
blit( transform, guiLeft, guiTop, 0, 0, xSize, ySize );
minecraft.getTextureManager().bind( texture );
blit( transform, leftPos, topPos, 0, 0, imageWidth, imageHeight );
// Draw selection slot
int slot = m_container.getSelectedSlot();
int slot = container.getSelectedSlot();
if( slot >= 0 )
{
int slotX = slot % 4;
int slotY = slot / 4;
blit( transform,
guiLeft + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18,
guiTop + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18,
leftPos + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18,
topPos + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18,
0, 217, 24, 24
);
}
@@ -126,18 +126,18 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
{
renderBackground( stack );
super.render( stack, mouseX, mouseY, partialTicks );
renderHoveredTooltip( stack, mouseX, mouseY );
renderTooltip( stack, mouseX, mouseY );
}
@Override
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
{
return (getListener() != null && getListener().mouseDragged( x, y, button, deltaX, deltaY ))
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|| super.mouseDragged( x, y, button, deltaX, deltaY );
}
@Override
protected void drawGuiContainerForegroundLayer( @Nonnull MatrixStack transform, int mouseX, int mouseY )
protected void renderLabels( @Nonnull MatrixStack transform, int mouseX, int mouseY )
{
// Skip rendering labels.
}

View File

@@ -91,7 +91,7 @@ public class WidgetTerminal implements IGuiEventListener
case GLFW.GLFW_KEY_V:
// Ctrl+V for paste
String clipboard = client.keyboardListener.getClipboardString();
String clipboard = client.keyboardHandler.getClipboard();
if( clipboard != null )
{
// Clip to the first occurrence of \r or \n
@@ -111,7 +111,7 @@ public class WidgetTerminal implements IGuiEventListener
}
// Filter the string
clipboard = SharedConstants.filterAllowedCharacters( clipboard );
clipboard = SharedConstants.filterText( clipboard );
if( !clipboard.isEmpty() )
{
// Clip to 512 characters and queue the event

View File

@@ -43,12 +43,12 @@ public final class ComputerCraftProxyClient
registerContainers();
// While turtles themselves are not transparent, their upgrades may be.
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.TURTLE_NORMAL.get(), RenderType.getTranslucent() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.TURTLE_ADVANCED.get(), RenderType.getTranslucent() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.TURTLE_NORMAL.get(), RenderType.translucent() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.TURTLE_ADVANCED.get(), RenderType.translucent() );
// Monitors' textures have transparent fronts and so count as cutouts.
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.MONITOR_NORMAL.get(), RenderType.getCutout() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.MONITOR_ADVANCED.get(), RenderType.getCutout() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.MONITOR_NORMAL.get(), RenderType.cutout() );
RenderTypeLookup.setRenderLayer( Registry.ModBlocks.MONITOR_ADVANCED.get(), RenderType.cutout() );
// Setup TESRs
ClientRegistry.bindTileEntityRenderer( Registry.ModTiles.MONITOR_NORMAL.get(), TileEntityMonitorRenderer::new );
@@ -74,7 +74,7 @@ public final class ComputerCraftProxyClient
ResourceLocation id = new ResourceLocation( ComputerCraft.MOD_ID, name );
for( Supplier<? extends Item> item : items )
{
ItemModelsProperties.registerProperty( item.get(), id, getter );
ItemModelsProperties.register( item.get(), id, getter );
}
}
@@ -82,15 +82,15 @@ public final class ComputerCraftProxyClient
{
// My IDE doesn't think so, but we do actually need these generics.
ScreenManager.<ContainerComputer, GuiComputer<ContainerComputer>>registerFactory( Registry.ModContainers.COMPUTER.get(), GuiComputer::create );
ScreenManager.<ContainerPocketComputer, GuiComputer<ContainerPocketComputer>>registerFactory( Registry.ModContainers.POCKET_COMPUTER.get(), GuiComputer::createPocket );
ScreenManager.registerFactory( Registry.ModContainers.TURTLE.get(), GuiTurtle::new );
ScreenManager.<ContainerComputer, GuiComputer<ContainerComputer>>register( Registry.ModContainers.COMPUTER.get(), GuiComputer::create );
ScreenManager.<ContainerPocketComputer, GuiComputer<ContainerPocketComputer>>register( Registry.ModContainers.POCKET_COMPUTER.get(), GuiComputer::createPocket );
ScreenManager.register( Registry.ModContainers.TURTLE.get(), GuiTurtle::new );
ScreenManager.registerFactory( Registry.ModContainers.PRINTER.get(), GuiPrinter::new );
ScreenManager.registerFactory( Registry.ModContainers.DISK_DRIVE.get(), GuiDiskDrive::new );
ScreenManager.registerFactory( Registry.ModContainers.PRINTOUT.get(), GuiPrintout::new );
ScreenManager.register( Registry.ModContainers.PRINTER.get(), GuiPrinter::new );
ScreenManager.register( Registry.ModContainers.DISK_DRIVE.get(), GuiDiskDrive::new );
ScreenManager.register( Registry.ModContainers.PRINTOUT.get(), GuiPrintout::new );
ScreenManager.<ContainerViewComputer, GuiComputer<ContainerViewComputer>>registerFactory( Registry.ModContainers.VIEW_COMPUTER.get(), GuiComputer::createView );
ScreenManager.<ContainerViewComputer, GuiComputer<ContainerViewComputer>>register( Registry.ModContainers.VIEW_COMPUTER.get(), GuiComputer::createView );
}
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Dist.CLIENT )
@@ -99,7 +99,7 @@ public final class ComputerCraftProxyClient
@SubscribeEvent
public static void onWorldUnload( WorldEvent.Unload event )
{
if( event.getWorld().isRemote() )
if( event.getWorld().isClientSide() )
{
ClientMonitor.destroyAll();
}

View File

@@ -45,35 +45,35 @@ public final class CableHighlightRenderer
public static void drawHighlight( DrawHighlightEvent.HighlightBlock event )
{
BlockRayTraceResult hit = event.getTarget();
BlockPos pos = hit.getPos();
World world = event.getInfo().getRenderViewEntity().getEntityWorld();
BlockPos pos = hit.getBlockPos();
World world = event.getInfo().getEntity().getCommandSenderWorld();
ActiveRenderInfo info = event.getInfo();
BlockState state = world.getBlockState( pos );
// We only care about instances with both cable and modem.
if( state.getBlock() != Registry.ModBlocks.CABLE.get() || state.get( BlockCable.MODEM ).getFacing() == null || !state.get( BlockCable.CABLE ) )
if( state.getBlock() != Registry.ModBlocks.CABLE.get() || state.getValue( BlockCable.MODEM ).getFacing() == null || !state.getValue( BlockCable.CABLE ) )
{
return;
}
event.setCanceled( true );
VoxelShape shape = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.getHitVec().subtract( pos.getX(), pos.getY(), pos.getZ() ) )
VoxelShape shape = WorldUtil.isVecInside( CableShapes.getModemShape( state ), hit.getLocation().subtract( pos.getX(), pos.getY(), pos.getZ() ) )
? CableShapes.getModemShape( state )
: CableShapes.getCableShape( state );
Vector3d cameraPos = info.getProjectedView();
double xOffset = pos.getX() - cameraPos.getX();
double yOffset = pos.getY() - cameraPos.getY();
double zOffset = pos.getZ() - cameraPos.getZ();
Vector3d cameraPos = info.getPosition();
double xOffset = pos.getX() - cameraPos.x();
double yOffset = pos.getY() - cameraPos.y();
double zOffset = pos.getZ() - cameraPos.z();
IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.getLines() );
Matrix4f matrix4f = event.getMatrix().getLast().getMatrix();
shape.forEachEdge( ( x1, y1, z1, x2, y2, z2 ) -> {
buffer.pos( matrix4f, (float) (x1 + xOffset), (float) (y1 + yOffset), (float) (z1 + zOffset) )
IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.lines() );
Matrix4f matrix4f = event.getMatrix().last().pose();
shape.forAllEdges( ( x1, y1, z1, x2, y2, z2 ) -> {
buffer.vertex( matrix4f, (float) (x1 + xOffset), (float) (y1 + yOffset), (float) (z1 + zOffset) )
.color( 0, 0, 0, 0.4f ).endVertex();
buffer.pos( matrix4f, (float) (x2 + xOffset), (float) (y2 + yOffset), (float) (z2 + zOffset) )
buffer.vertex( matrix4f, (float) (x2 + xOffset), (float) (y2 + yOffset), (float) (z2 + zOffset) )
.color( 0, 0, 0, 0.4f ).endVertex();
} );
}

View File

@@ -85,13 +85,13 @@ public class ComputerBorderRenderer
public static void render( int x, int y, int z, int width, int height )
{
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEX );
render( IDENTITY, buffer, x, y, z, width, height );
RenderSystem.enableAlphaTest();
tessellator.draw();
tessellator.end();
}
public static void render( Matrix4f transform, IVertexBuilder buffer, int x, int y, int z, int width, int height )
@@ -166,9 +166,9 @@ public class ComputerBorderRenderer
private void renderTexture( int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight )
{
builder.pos( transform, x, y + height, z ).color( r, g, b, 1.0f ).tex( u * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).endVertex();
builder.pos( transform, x + width, y + height, z ).color( r, g, b, 1.0f ).tex( (u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).endVertex();
builder.pos( transform, x + width, y, z ).color( r, g, b, 1.0f ).tex( (u + textureWidth) * TEX_SCALE, v * TEX_SCALE ).endVertex();
builder.pos( transform, x, y, z ).color( r, g, b, 1.0f ).tex( u * TEX_SCALE, v * TEX_SCALE ).endVertex();
builder.vertex( transform, x, y + height, z ).color( r, g, b, 1.0f ).uv( u * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).endVertex();
builder.vertex( transform, x + width, y + height, z ).color( r, g, b, 1.0f ).uv( (u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE ).endVertex();
builder.vertex( transform, x + width, y, z ).color( r, g, b, 1.0f ).uv( (u + textureWidth) * TEX_SCALE, v * TEX_SCALE ).endVertex();
builder.vertex( transform, x, y, z ).color( r, g, b, 1.0f ).uv( u * TEX_SCALE, v * TEX_SCALE ).endVertex();
}
}

View File

@@ -33,8 +33,8 @@ public abstract class ItemMapLikeRenderer
{
PlayerEntity player = Minecraft.getInstance().player;
transform.push();
if( hand == Hand.MAIN_HAND && player.getHeldItemOffhand().isEmpty() )
transform.pushPose();
if( hand == Hand.MAIN_HAND && player.getOffhandItem().isEmpty() )
{
renderItemFirstPersonCenter( transform, render, lightTexture, pitch, equipProgress, swingProgress, stack );
}
@@ -42,11 +42,11 @@ public abstract class ItemMapLikeRenderer
{
renderItemFirstPersonSide(
transform, render, lightTexture,
hand == Hand.MAIN_HAND ? player.getPrimaryHand() : player.getPrimaryHand().opposite(),
hand == Hand.MAIN_HAND ? player.getMainArm() : player.getMainArm().getOpposite(),
equipProgress, swingProgress, stack
);
}
transform.pop();
transform.popPose();
}
/**
@@ -70,15 +70,15 @@ public abstract class ItemMapLikeRenderer
// If the player is not invisible then render a single arm
if( !minecraft.player.isInvisible() )
{
transform.push();
transform.rotate( Vector3f.ZP.rotationDegrees( offset * 10f ) );
minecraft.getFirstPersonRenderer().renderArmFirstPerson( transform, render, combinedLight, equipProgress, swingProgress, side );
transform.pop();
transform.pushPose();
transform.mulPose( Vector3f.ZP.rotationDegrees( offset * 10f ) );
minecraft.getItemInHandRenderer().renderPlayerArm( transform, render, combinedLight, equipProgress, swingProgress, side );
transform.popPose();
}
// Setup the appropriate transformations. This is just copied from the
// corresponding method in ItemRenderer.
transform.push();
transform.pushPose();
transform.translate( offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f );
float f1 = MathHelper.sqrt( swingProgress );
float f2 = MathHelper.sin( f1 * (float) Math.PI );
@@ -86,12 +86,12 @@ public abstract class ItemMapLikeRenderer
float f4 = 0.4f * MathHelper.sin( f1 * ((float) Math.PI * 2f) );
float f5 = -0.3f * MathHelper.sin( swingProgress * (float) Math.PI );
transform.translate( offset * f3, f4 - 0.3f * f2, f5 );
transform.rotate( Vector3f.XP.rotationDegrees( f2 * -45f ) );
transform.rotate( Vector3f.YP.rotationDegrees( offset * f2 * -30f ) );
transform.mulPose( Vector3f.XP.rotationDegrees( f2 * -45f ) );
transform.mulPose( Vector3f.YP.rotationDegrees( offset * f2 * -30f ) );
renderItem( transform, render, stack );
transform.pop();
transform.popPose();
}
/**
@@ -109,7 +109,7 @@ public abstract class ItemMapLikeRenderer
private void renderItemFirstPersonCenter( MatrixStack transform, IRenderTypeBuffer render, int combinedLight, float pitch, float equipProgress, float swingProgress, ItemStack stack )
{
Minecraft minecraft = Minecraft.getInstance();
FirstPersonRenderer renderer = minecraft.getFirstPersonRenderer();
FirstPersonRenderer renderer = minecraft.getItemInHandRenderer();
// Setup the appropriate transformations. This is just copied from the
// corresponding method in ItemRenderer.
@@ -118,20 +118,20 @@ public abstract class ItemMapLikeRenderer
float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI );
transform.translate( 0, -tX / 2, tZ );
float pitchAngle = renderer.getMapAngleFromPitch( pitch );
float pitchAngle = renderer.calculateMapTilt( pitch );
transform.translate( 0, 0.04F + equipProgress * -1.2f + pitchAngle * -0.5f, -0.72f );
transform.rotate( Vector3f.XP.rotationDegrees( pitchAngle * -85.0f ) );
transform.mulPose( Vector3f.XP.rotationDegrees( pitchAngle * -85.0f ) );
if( !minecraft.player.isInvisible() )
{
transform.push();
transform.rotate( Vector3f.YP.rotationDegrees( 90.0F ) );
renderer.renderArm( transform, render, combinedLight, HandSide.RIGHT );
renderer.renderArm( transform, render, combinedLight, HandSide.LEFT );
transform.pop();
transform.pushPose();
transform.mulPose( Vector3f.YP.rotationDegrees( 90.0F ) );
renderer.renderMapHand( transform, render, combinedLight, HandSide.RIGHT );
renderer.renderMapHand( transform, render, combinedLight, HandSide.LEFT );
transform.popPose();
}
float rX = MathHelper.sin( swingRt * (float) Math.PI );
transform.rotate( Vector3f.XP.rotationDegrees( rX * 20.0F ) );
transform.mulPose( Vector3f.XP.rotationDegrees( rX * 20.0F ) );
transform.scale( 2.0F, 2.0F, 2.0F );
renderItem( transform, render, stack );

View File

@@ -83,9 +83,9 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
// Setup various transformations. Note that these are partially adapted from the corresponding method
// in ItemRenderer
transform.push();
transform.rotate( Vector3f.YP.rotationDegrees( 180f ) );
transform.rotate( Vector3f.ZP.rotationDegrees( 180f ) );
transform.pushPose();
transform.mulPose( Vector3f.YP.rotationDegrees( 180f ) );
transform.mulPose( Vector3f.ZP.rotationDegrees( 180f ) );
transform.scale( 0.5f, 0.5f, 0.5f );
float scale = 0.75f / Math.max( width + BORDER * 2, height + BORDER * 2 + LIGHT_HEIGHT );
@@ -97,7 +97,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
ComputerFamily family = item.getFamily();
int frameColour = item.getColour( stack );
Matrix4f matrix = transform.getLast().getMatrix();
Matrix4f matrix = transform.last().pose();
renderFrame( matrix, family, frameColour, width, height );
// Render the light
@@ -114,26 +114,26 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
FixedWidthFontRenderer.drawEmptyTerminal( matrix, 0, 0, width, height );
}
transform.pop();
transform.popPose();
}
private static void renderFrame( Matrix4f transform, ComputerFamily family, int colour, int width, int height )
{
RenderSystem.enableBlend();
Minecraft.getInstance().getTextureManager()
.bindTexture( colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family ) );
.bind( colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family ) );
float r = ((colour >>> 16) & 0xFF) / 255.0f;
float g = ((colour >>> 8) & 0xFF) / 255.0f;
float b = (colour & 0xFF) / 255.0f;
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEX );
ComputerBorderRenderer.render( transform, buffer, 0, 0, 0, width, height, LIGHT_HEIGHT, r, g, b );
tessellator.draw();
tessellator.end();
}
private static void renderLight( Matrix4f transform, int colour, int width, int height )
@@ -145,14 +145,14 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
float b = (colour & 0xFF) / 255.0f;
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR );
buffer.pos( transform, width - LIGHT_HEIGHT * 2, height + LIGHT_HEIGHT + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.pos( transform, width, height + LIGHT_HEIGHT + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.pos( transform, width, height + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.pos( transform, width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.vertex( transform, width - LIGHT_HEIGHT * 2, height + LIGHT_HEIGHT + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.vertex( transform, width, height + LIGHT_HEIGHT + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.vertex( transform, width, height + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
buffer.vertex( transform, width - LIGHT_HEIGHT * 2, height + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
tessellator.draw();
tessellator.end();
RenderSystem.enableTexture();
}
}

View File

@@ -52,7 +52,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
@Override
protected void renderItem( MatrixStack transform, IRenderTypeBuffer render, ItemStack stack )
{
transform.rotate( Vector3f.XP.rotationDegrees( 180f ) );
transform.mulPose( Vector3f.XP.rotationDegrees( 180f ) );
transform.scale( 0.42f, 0.42f, -0.42f );
transform.translate( -0.5f, -0.48f, 0.0f );
@@ -70,7 +70,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
// Move a little bit forward to ensure we're not clipping with the frame
transform.translate( 0.0f, 0.0f, -0.001f );
transform.rotate( Vector3f.ZP.rotationDegrees( 180f ) );
transform.mulPose( Vector3f.ZP.rotationDegrees( 180f ) );
transform.scale( 0.95f, 0.95f, -0.95f );
transform.translate( -0.5f, -0.5f, 0.0f );
@@ -104,7 +104,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
transform.scale( scale, scale, scale );
transform.translate( (max - width) / 2.0, (max - height) / 2.0, 0.0 );
Matrix4f matrix = transform.getLast().getMatrix();
Matrix4f matrix = transform.last().pose();
drawBorder( matrix, render, 0, 0, -0.01f, 0, pages, book );
drawText( matrix, render,
X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, ItemPrintout.getText( stack ), ItemPrintout.getColours( stack )

View File

@@ -40,12 +40,12 @@ public final class MonitorHighlightRenderer
public static void drawHighlight( DrawHighlightEvent.HighlightBlock event )
{
// Preserve normal behaviour when crouching.
if( event.getInfo().getRenderViewEntity().isCrouching() ) return;
if( event.getInfo().getEntity().isCrouching() ) return;
World world = event.getInfo().getRenderViewEntity().getEntityWorld();
BlockPos pos = event.getTarget().getPos();
World world = event.getInfo().getEntity().getCommandSenderWorld();
BlockPos pos = event.getTarget().getBlockPos();
TileEntity tile = world.getTileEntity( pos );
TileEntity tile = world.getBlockEntity( pos );
if( !(tile instanceof TileMonitor) ) return;
TileMonitor monitor = (TileMonitor) tile;
@@ -61,13 +61,13 @@ public final class MonitorHighlightRenderer
if( monitor.getYIndex() != monitor.getHeight() - 1 ) faces.remove( monitor.getDown() );
MatrixStack transformStack = event.getMatrix();
Vector3d cameraPos = event.getInfo().getProjectedView();
transformStack.push();
transformStack.translate( pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ() );
Vector3d cameraPos = event.getInfo().getPosition();
transformStack.pushPose();
transformStack.translate( pos.getX() - cameraPos.x(), pos.getY() - cameraPos.y(), pos.getZ() - cameraPos.z() );
// I wish I could think of a better way to do this
IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.getLines() );
Matrix4f transform = transformStack.getLast().getMatrix();
IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.lines() );
Matrix4f transform = transformStack.last().pose();
if( faces.contains( NORTH ) || faces.contains( WEST ) ) line( buffer, transform, 0, 0, 0, UP );
if( faces.contains( SOUTH ) || faces.contains( WEST ) ) line( buffer, transform, 0, 0, 1, UP );
if( faces.contains( NORTH ) || faces.contains( EAST ) ) line( buffer, transform, 1, 0, 0, UP );
@@ -81,16 +81,16 @@ public final class MonitorHighlightRenderer
if( faces.contains( WEST ) || faces.contains( UP ) ) line( buffer, transform, 0, 1, 0, SOUTH );
if( faces.contains( EAST ) || faces.contains( UP ) ) line( buffer, transform, 1, 1, 0, SOUTH );
transformStack.pop();
transformStack.popPose();
}
private static void line( IVertexBuilder buffer, Matrix4f transform, float x, float y, float z, Direction direction )
{
buffer.pos( transform, x, y, z ).color( 0, 0, 0, 0.4f ).endVertex();
buffer.pos( transform,
x + direction.getXOffset(),
y + direction.getYOffset(),
z + direction.getZOffset()
buffer.vertex( transform, x, y, z ).color( 0, 0, 0, 0.4f ).endVertex();
buffer.vertex( transform,
x + direction.getStepX(),
y + direction.getStepY(),
z + direction.getStepZ()
).color( 0, 0, 0, 0.4f ).endVertex();
}
}

View File

@@ -42,7 +42,7 @@ class MonitorTextureBufferShader
static void setupUniform( Matrix4f transform, int width, int height, Palette palette, boolean greyscale )
{
MATRIX_BUFFER.rewind();
transform.write( MATRIX_BUFFER );
transform.store( MATRIX_BUFFER );
MATRIX_BUFFER.rewind();
RenderSystem.glUniformMatrix4( uniformMv, false, MATRIX_BUFFER );
@@ -71,7 +71,7 @@ class MonitorTextureBufferShader
{
if( initialised )
{
if( ok ) GlStateManager.useProgram( program );
if( ok ) GlStateManager._glUseProgram( program );
return ok;
}
@@ -94,14 +94,14 @@ class MonitorTextureBufferShader
int vertexShader = loadShader( GL20.GL_VERTEX_SHADER, "assets/computercraft/shaders/monitor.vert" );
int fragmentShader = loadShader( GL20.GL_FRAGMENT_SHADER, "assets/computercraft/shaders/monitor.frag" );
program = GlStateManager.createProgram();
GlStateManager.attachShader( program, vertexShader );
GlStateManager.attachShader( program, fragmentShader );
program = GlStateManager.glCreateProgram();
GlStateManager.glAttachShader( program, vertexShader );
GlStateManager.glAttachShader( program, fragmentShader );
GL20.glBindAttribLocation( program, 0, "v_pos" );
GlStateManager.linkProgram( program );
boolean ok = GlStateManager.getProgram( program, GL20.GL_LINK_STATUS ) != 0;
String log = GlStateManager.getProgramInfoLog( program, Short.MAX_VALUE ).trim();
GlStateManager.glLinkProgram( program );
boolean ok = GlStateManager.glGetProgrami( program, GL20.GL_LINK_STATUS ) != 0;
String log = GlStateManager.glGetProgramInfoLog( program, Short.MAX_VALUE ).trim();
if( !Strings.isNullOrEmpty( log ) )
{
ComputerCraft.log.warn( "Problems when linking monitor shader: {}", log );
@@ -109,8 +109,8 @@ class MonitorTextureBufferShader
GL20.glDetachShader( program, vertexShader );
GL20.glDetachShader( program, fragmentShader );
GlStateManager.deleteShader( vertexShader );
GlStateManager.deleteShader( fragmentShader );
GlStateManager.glDeleteShader( vertexShader );
GlStateManager.glDeleteShader( fragmentShader );
if( !ok ) return false;
@@ -137,13 +137,13 @@ class MonitorTextureBufferShader
if( stream == null ) throw new IllegalArgumentException( "Cannot find " + path );
String contents = TextureUtil.readResourceAsString( stream );
int shader = GlStateManager.createShader( kind );
int shader = GlStateManager.glCreateShader( kind );
GlStateManager.shaderSource( shader, contents );
GlStateManager.compileShader( shader );
GlStateManager.glShaderSource( shader, contents );
GlStateManager.glCompileShader( shader );
boolean ok = GlStateManager.getShader( shader, GL20.GL_COMPILE_STATUS ) != 0;
String log = GlStateManager.getShaderInfoLog( shader, Short.MAX_VALUE ).trim();
boolean ok = GlStateManager.glGetShaderi( shader, GL20.GL_COMPILE_STATUS ) != 0;
String log = GlStateManager.glGetShaderInfoLog( shader, Short.MAX_VALUE ).trim();
if( !Strings.isNullOrEmpty( log ) )
{
ComputerCraft.log.warn( "Problems when loading monitor shader {}: {}", path, log );
@@ -155,7 +155,7 @@ class MonitorTextureBufferShader
private static int getUniformLocation( int program, String name )
{
int uniform = GlStateManager.getUniformLocation( program, name );
int uniform = GlStateManager._glGetUniformLocation( program, name );
if( uniform == -1 ) throw new IllegalStateException( "Cannot find uniform " + name );
return uniform;
}

View File

@@ -146,18 +146,18 @@ public final class PrintoutRenderer
private static void drawTexture( Matrix4f matrix, IVertexBuilder buffer, float x, float y, float z, float u, float v, float width, float height )
{
buffer.pos( matrix, x, y + height, z ).tex( u / BG_SIZE, (v + height) / BG_SIZE ).endVertex();
buffer.pos( matrix, x + width, y + height, z ).tex( (u + width) / BG_SIZE, (v + height) / BG_SIZE ).endVertex();
buffer.pos( matrix, x + width, y, z ).tex( (u + width) / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.pos( matrix, x, y, z ).tex( u / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.vertex( matrix, x, y + height, z ).uv( u / BG_SIZE, (v + height) / BG_SIZE ).endVertex();
buffer.vertex( matrix, x + width, y + height, z ).uv( (u + width) / BG_SIZE, (v + height) / BG_SIZE ).endVertex();
buffer.vertex( matrix, x + width, y, z ).uv( (u + width) / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.vertex( matrix, x, y, z ).uv( u / BG_SIZE, v / BG_SIZE ).endVertex();
}
private static void drawTexture( Matrix4f matrix, IVertexBuilder buffer, float x, float y, float z, float width, float height, float u, float v, float tWidth, float tHeight )
{
buffer.pos( matrix, x, y + height, z ).tex( u / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex();
buffer.pos( matrix, x + width, y + height, z ).tex( (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex();
buffer.pos( matrix, x + width, y, z ).tex( (u + tWidth) / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.pos( matrix, x, y, z ).tex( u / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.vertex( matrix, x, y + height, z ).uv( u / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex();
buffer.vertex( matrix, x + width, y + height, z ).uv( (u + tWidth) / BG_SIZE, (v + tHeight) / BG_SIZE ).endVertex();
buffer.vertex( matrix, x + width, y, z ).uv( (u + tWidth) / BG_SIZE, v / BG_SIZE ).endVertex();
buffer.vertex( matrix, x, y, z ).uv( u / BG_SIZE, v / BG_SIZE ).endVertex();
}
public static float offsetAt( int page )
@@ -167,14 +167,14 @@ public final class PrintoutRenderer
private static final class Type extends RenderState
{
static final RenderType TYPE = RenderType.makeType(
static final RenderType TYPE = RenderType.create(
"printout_background", DefaultVertexFormats.POSITION_TEX, GL11.GL_QUADS, 1024,
false, false, // useDelegate, needsSorting
RenderType.State.getBuilder()
.texture( new RenderState.TextureState( BG, false, false ) ) // blur, minimap
.alpha( DEFAULT_ALPHA )
.lightmap( LIGHTMAP_DISABLED )
.build( false )
RenderType.State.builder()
.setTextureState( new RenderState.TextureState( BG, false, false ) ) // blur, minimap
.setAlphaState( DEFAULT_ALPHA )
.setLightmapState( NO_LIGHTMAP )
.createCompositeState( false )
);
private Type( String name, Runnable setup, Runnable destroy )

View File

@@ -61,7 +61,7 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
if( originTerminal == null ) return;
TileMonitor origin = originTerminal.getOrigin();
BlockPos monitorPos = monitor.getPos();
BlockPos monitorPos = monitor.getBlockPos();
// Ensure each monitor terminal is rendered only once. We allow rendering a specific tile
// multiple times in a single frame to ensure compatibility with shaders which may run a
@@ -75,24 +75,24 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
originTerminal.lastRenderFrame = renderFrame;
originTerminal.lastRenderPos = monitorPos;
BlockPos originPos = origin.getPos();
BlockPos originPos = origin.getBlockPos();
// Determine orientation
Direction dir = origin.getDirection();
Direction front = origin.getFront();
float yaw = dir.getHorizontalAngle();
float yaw = dir.toYRot();
float pitch = DirectionUtil.toPitchAngle( front );
// Setup initial transform
transform.push();
transform.pushPose();
transform.translate(
originPos.getX() - monitorPos.getX() + 0.5,
originPos.getY() - monitorPos.getY() + 0.5,
originPos.getZ() - monitorPos.getZ() + 0.5
);
transform.rotate( Vector3f.YN.rotationDegrees( yaw ) );
transform.rotate( Vector3f.XP.rotationDegrees( pitch ) );
transform.mulPose( Vector3f.YN.rotationDegrees( yaw ) );
transform.mulPose( Vector3f.XP.rotationDegrees( pitch ) );
transform.translate(
-0.5 + TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN,
origin.getHeight() - 0.5 - (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN) + 0,
@@ -110,10 +110,10 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT;
double xScale = xSize / pixelWidth;
double yScale = ySize / pixelHeight;
transform.push();
transform.pushPose();
transform.scale( (float) xScale, (float) -yScale, 1.0f );
Matrix4f matrix = transform.getLast().getMatrix();
Matrix4f matrix = transform.last().pose();
// Sneaky hack here: we get a buffer now in order to flush existing ones and set up the appropriate
// render state. I've no clue how well this'll work in future versions of Minecraft, but it does the trick
@@ -127,28 +127,28 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
// reasonable.
FixedWidthFontRenderer.drawCursor( matrix, buffer, 0, 0, terminal, !originTerminal.isColour() );
transform.pop();
transform.popPose();
}
else
{
FixedWidthFontRenderer.drawEmptyTerminal(
transform.getLast().getMatrix(), renderer,
transform.last().pose(), renderer,
-MARGIN, MARGIN,
(float) (xSize + 2 * MARGIN), (float) -(ySize + MARGIN * 2)
);
}
FixedWidthFontRenderer.drawBlocker(
transform.getLast().getMatrix(), renderer,
transform.last().pose(), renderer,
(float) -TileMonitor.RENDER_MARGIN, (float) TileMonitor.RENDER_MARGIN,
(float) (xSize + 2 * TileMonitor.RENDER_MARGIN), (float) -(ySize + TileMonitor.RENDER_MARGIN * 2)
);
// Force a flush of the blocker. WorldRenderer.updateCameraAndRender will "finish" all the built-in
// buffers before calling renderer.finish, which means the blocker isn't actually rendered at that point!
renderer.getBuffer( RenderType.getSolid() );
renderer.getBuffer( RenderType.solid() );
transform.pop();
transform.popPose();
}
private static void renderTerminal( Matrix4f matrix, ClientMonitor monitor, float xMargin, float yMargin )
@@ -173,7 +173,7 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
int size = width * height * 3;
if( tboContents == null || tboContents.capacity() < size )
{
tboContents = GLAllocation.createDirectByteBuffer( size );
tboContents = GLAllocation.createByteBuffer( size );
}
ByteBuffer monitorBuffer = tboContents;
@@ -190,28 +190,28 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
}
monitorBuffer.flip();
GlStateManager.bindBuffer( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer );
GlStateManager.bufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW );
GlStateManager.bindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer );
GlStateManager._glBufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW );
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
}
// Nobody knows what they're doing!
GlStateManager.activeTexture( MonitorTextureBufferShader.TEXTURE_INDEX );
GlStateManager._activeTexture( MonitorTextureBufferShader.TEXTURE_INDEX );
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, monitor.tboTexture );
GlStateManager.activeTexture( GL13.GL_TEXTURE0 );
GlStateManager._activeTexture( GL13.GL_TEXTURE0 );
MonitorTextureBufferShader.setupUniform( matrix, width, height, terminal.getPalette(), !monitor.isColour() );
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION );
buffer.pos( -xMargin, -yMargin, 0 ).endVertex();
buffer.pos( -xMargin, pixelHeight + yMargin, 0 ).endVertex();
buffer.pos( pixelWidth + xMargin, -yMargin, 0 ).endVertex();
buffer.pos( pixelWidth + xMargin, pixelHeight + yMargin, 0 ).endVertex();
tessellator.draw();
buffer.vertex( -xMargin, -yMargin, 0 ).endVertex();
buffer.vertex( -xMargin, pixelHeight + yMargin, 0 ).endVertex();
buffer.vertex( pixelWidth + xMargin, -yMargin, 0 ).endVertex();
buffer.vertex( pixelWidth + xMargin, pixelHeight + yMargin, 0 ).endVertex();
tessellator.end();
GlStateManager.useProgram( 0 );
GlStateManager._glUseProgram( 0 );
break;
}
@@ -221,22 +221,22 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
if( redraw )
{
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder builder = tessellator.getBuffer();
builder.begin( FixedWidthFontRenderer.TYPE.getDrawMode(), FixedWidthFontRenderer.TYPE.getVertexFormat() );
BufferBuilder builder = tessellator.getBuilder();
builder.begin( FixedWidthFontRenderer.TYPE.mode(), FixedWidthFontRenderer.TYPE.format() );
FixedWidthFontRenderer.drawTerminalWithoutCursor(
IDENTITY, builder, 0, 0,
terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin
);
builder.finishDrawing();
builder.end();
vbo.upload( builder );
}
vbo.bindBuffer();
FixedWidthFontRenderer.TYPE.getVertexFormat().setupBufferState( 0L );
vbo.draw( matrix, FixedWidthFontRenderer.TYPE.getDrawMode() );
VertexBuffer.unbindBuffer();
FixedWidthFontRenderer.TYPE.getVertexFormat().clearBufferState();
vbo.bind();
FixedWidthFontRenderer.TYPE.format().setupBufferState( 0L );
vbo.draw( matrix, FixedWidthFontRenderer.TYPE.mode() );
VertexBuffer.unbind();
FixedWidthFontRenderer.TYPE.format().clearBufferState();
break;
}
}

View File

@@ -72,31 +72,31 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
}
@Override
public void render( @Nonnull TileTurtle turtle, float partialTicks, @Nonnull MatrixStack transform, @Nonnull IRenderTypeBuffer renderer, int lightmapCoord, int overlayLight )
public void render( @Nonnull TileTurtle turtle, float partialTicks, @Nonnull MatrixStack transform, @Nonnull IRenderTypeBuffer buffers, int lightmapCoord, int overlayLight )
{
// Render the label
String label = turtle.createProxy().getLabel();
RayTraceResult hit = renderDispatcher.cameraHitResult;
if( label != null && hit.getType() == RayTraceResult.Type.BLOCK && turtle.getPos().equals( ((BlockRayTraceResult) hit).getPos() ) )
RayTraceResult hit = renderer.cameraHitResult;
if( label != null && hit.getType() == RayTraceResult.Type.BLOCK && turtle.getBlockPos().equals( ((BlockRayTraceResult) hit).getBlockPos() ) )
{
Minecraft mc = Minecraft.getInstance();
FontRenderer font = renderDispatcher.fontRenderer;
FontRenderer font = renderer.font;
transform.push();
transform.pushPose();
transform.translate( 0.5, 1.2, 0.5 );
transform.rotate( mc.getRenderManager().getCameraOrientation() );
transform.mulPose( mc.getEntityRenderDispatcher().cameraOrientation() );
transform.scale( -0.025f, -0.025f, 0.025f );
Matrix4f matrix = transform.getLast().getMatrix();
int opacity = (int) (mc.gameSettings.getTextBackgroundOpacity( 0.25f ) * 255) << 24;
float width = -font.getStringWidth( label ) / 2.0f;
font.renderString( label, width, (float) 0, 0x20ffffff, false, matrix, renderer, true, opacity, lightmapCoord );
font.renderString( label, width, (float) 0, 0xffffffff, false, matrix, renderer, false, 0, lightmapCoord );
Matrix4f matrix = transform.last().pose();
int opacity = (int) (mc.options.getBackgroundOpacity( 0.25f ) * 255) << 24;
float width = -font.width( label ) / 2.0f;
font.drawInBatch( label, width, (float) 0, 0x20ffffff, false, matrix, buffers, true, opacity, lightmapCoord );
font.drawInBatch( label, width, (float) 0, 0xffffffff, false, matrix, buffers, false, 0, lightmapCoord );
transform.pop();
transform.popPose();
}
transform.push();
transform.pushPose();
// Setup the transform.
Vector3d offset = turtle.getRenderOffset( partialTicks );
@@ -104,7 +104,7 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
transform.translate( offset.x, offset.y, offset.z );
transform.translate( 0.5f, 0.5f, 0.5f );
transform.rotate( Vector3f.YP.rotationDegrees( 180.0f - yaw ) );
transform.mulPose( Vector3f.YP.rotationDegrees( 180.0f - yaw ) );
if( label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" )) )
{
// Flip the model
@@ -117,7 +117,7 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
ComputerFamily family = turtle.getFamily();
ResourceLocation overlay = turtle.getOverlay();
IVertexBuilder buffer = renderer.getBuffer( Atlases.getTranslucentCullBlockType() );
IVertexBuilder buffer = buffers.getBuffer( Atlases.translucentCullBlockSheet() );
renderModel( transform, buffer, lightmapCoord, overlayLight, getTurtleModel( family, colour != -1 ), colour == -1 ? null : new int[] { colour } );
// Render the overlay
@@ -131,31 +131,31 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
renderUpgrade( transform, buffer, lightmapCoord, overlayLight, turtle, TurtleSide.LEFT, partialTicks );
renderUpgrade( transform, buffer, lightmapCoord, overlayLight, turtle, TurtleSide.RIGHT, partialTicks );
transform.pop();
transform.popPose();
}
private void renderUpgrade( @Nonnull MatrixStack transform, @Nonnull IVertexBuilder renderer, int lightmapCoord, int overlayLight, TileTurtle turtle, TurtleSide side, float f )
{
ITurtleUpgrade upgrade = turtle.getUpgrade( side );
if( upgrade == null ) return;
transform.push();
transform.pushPose();
float toolAngle = turtle.getToolRenderAngle( side, f );
transform.translate( 0.0f, 0.5f, 0.5f );
transform.rotate( Vector3f.XN.rotationDegrees( toolAngle ) );
transform.mulPose( Vector3f.XN.rotationDegrees( toolAngle ) );
transform.translate( 0.0f, -0.5f, -0.5f );
TransformedModel model = upgrade.getModel( turtle.getAccess(), side );
model.getMatrix().push( transform );
renderModel( transform, renderer, lightmapCoord, overlayLight, model.getModel(), null );
transform.pop();
transform.popPose();
transform.pop();
transform.popPose();
}
private void renderModel( @Nonnull MatrixStack transform, @Nonnull IVertexBuilder renderer, int lightmapCoord, int overlayLight, ModelResourceLocation modelLocation, int[] tints )
{
ModelManager modelManager = Minecraft.getInstance().getItemRenderer().getItemModelMesher().getModelManager();
ModelManager modelManager = Minecraft.getInstance().getItemRenderer().getItemModelShaper().getModelManager();
renderModel( transform, renderer, lightmapCoord, overlayLight, modelManager.getModel( modelLocation ), tints );
}
@@ -171,12 +171,12 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
private static void renderQuads( @Nonnull MatrixStack transform, @Nonnull IVertexBuilder buffer, int lightmapCoord, int overlayLight, List<BakedQuad> quads, int[] tints )
{
MatrixStack.Entry matrix = transform.getLast();
MatrixStack.Entry matrix = transform.last();
for( BakedQuad bakedquad : quads )
{
int tint = -1;
if( tints != null && bakedquad.hasTintIndex() )
if( tints != null && bakedquad.isTinted() )
{
int idx = bakedquad.getTintIndex();
if( idx >= 0 && idx < tints.length ) tint = tints[bakedquad.getTintIndex()];

View File

@@ -43,7 +43,7 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
@Override
public TurtleModel read( @Nonnull JsonDeserializationContext deserializationContext, @Nonnull JsonObject modelContents )
{
ResourceLocation model = new ResourceLocation( JSONUtils.getString( modelContents, "model" ) );
ResourceLocation model = new ResourceLocation( JSONUtils.getAsString( modelContents, "model" ) );
return new TurtleModel( model );
}
@@ -60,8 +60,8 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
public Collection<RenderMaterial> getTextures( IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors )
{
Set<RenderMaterial> materials = new HashSet<>();
materials.addAll( modelGetter.apply( family ).getTextures( modelGetter, missingTextureErrors ) );
materials.addAll( modelGetter.apply( COLOUR_TURTLE_MODEL ).getTextures( modelGetter, missingTextureErrors ) );
materials.addAll( modelGetter.apply( family ).getMaterials( modelGetter, missingTextureErrors ) );
materials.addAll( modelGetter.apply( COLOUR_TURTLE_MODEL ).getMaterials( modelGetter, missingTextureErrors ) );
return materials;
}

View File

@@ -23,22 +23,22 @@ import java.util.*;
public class TurtleMultiModel implements IBakedModel
{
private final IBakedModel m_baseModel;
private final IBakedModel m_overlayModel;
private final TransformationMatrix m_generalTransform;
private final TransformedModel m_leftUpgradeModel;
private final TransformedModel m_rightUpgradeModel;
private List<BakedQuad> m_generalQuads = null;
private Map<Direction, List<BakedQuad>> m_faceQuads = new EnumMap<>( Direction.class );
private final IBakedModel baseModel;
private final IBakedModel overlayModel;
private final TransformationMatrix generalTransform;
private final TransformedModel leftUpgradeModel;
private final TransformedModel rightUpgradeModel;
private List<BakedQuad> generalQuads = null;
private final Map<Direction, List<BakedQuad>> faceQuads = new EnumMap<>( Direction.class );
public TurtleMultiModel( IBakedModel baseModel, IBakedModel overlayModel, TransformationMatrix generalTransform, TransformedModel leftUpgradeModel, TransformedModel rightUpgradeModel )
{
// Get the models
m_baseModel = baseModel;
m_overlayModel = overlayModel;
m_leftUpgradeModel = leftUpgradeModel;
m_rightUpgradeModel = rightUpgradeModel;
m_generalTransform = generalTransform;
this.baseModel = baseModel;
this.overlayModel = overlayModel;
this.leftUpgradeModel = leftUpgradeModel;
this.rightUpgradeModel = rightUpgradeModel;
this.generalTransform = generalTransform;
}
@Nonnull
@@ -55,13 +55,13 @@ public class TurtleMultiModel implements IBakedModel
{
if( side != null )
{
if( !m_faceQuads.containsKey( side ) ) m_faceQuads.put( side, buildQuads( state, side, rand ) );
return m_faceQuads.get( side );
if( !faceQuads.containsKey( side ) ) faceQuads.put( side, buildQuads( state, side, rand ) );
return faceQuads.get( side );
}
else
{
if( m_generalQuads == null ) m_generalQuads = buildQuads( state, side, rand );
return m_generalQuads;
if( generalQuads == null ) generalQuads = buildQuads( state, side, rand );
return generalQuads;
}
}
@@ -70,63 +70,63 @@ public class TurtleMultiModel implements IBakedModel
ArrayList<BakedQuad> quads = new ArrayList<>();
transformQuadsTo( quads, m_baseModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), m_generalTransform );
if( m_overlayModel != null )
transformQuadsTo( quads, baseModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), generalTransform );
if( overlayModel != null )
{
transformQuadsTo( quads, m_overlayModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), m_generalTransform );
transformQuadsTo( quads, overlayModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), generalTransform );
}
if( m_leftUpgradeModel != null )
if( leftUpgradeModel != null )
{
TransformationMatrix upgradeTransform = m_generalTransform.compose( m_leftUpgradeModel.getMatrix() );
transformQuadsTo( quads, m_leftUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
TransformationMatrix upgradeTransform = generalTransform.compose( leftUpgradeModel.getMatrix() );
transformQuadsTo( quads, leftUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
}
if( m_rightUpgradeModel != null )
if( rightUpgradeModel != null )
{
TransformationMatrix upgradeTransform = m_generalTransform.compose( m_rightUpgradeModel.getMatrix() );
transformQuadsTo( quads, m_rightUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
TransformationMatrix upgradeTransform = generalTransform.compose( rightUpgradeModel.getMatrix() );
transformQuadsTo( quads, rightUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
}
quads.trimToSize();
return quads;
}
@Override
public boolean isAmbientOcclusion()
public boolean useAmbientOcclusion()
{
return m_baseModel.isAmbientOcclusion();
return baseModel.useAmbientOcclusion();
}
@Override
public boolean isGui3d()
{
return m_baseModel.isGui3d();
return baseModel.isGui3d();
}
@Override
public boolean isBuiltInRenderer()
public boolean isCustomRenderer()
{
return m_baseModel.isBuiltInRenderer();
return baseModel.isCustomRenderer();
}
@Override
public boolean isSideLit()
public boolean usesBlockLight()
{
return m_baseModel.isSideLit();
return baseModel.usesBlockLight();
}
@Nonnull
@Override
@Deprecated
public TextureAtlasSprite getParticleTexture()
public TextureAtlasSprite getParticleIcon()
{
return m_baseModel.getParticleTexture();
return baseModel.getParticleIcon();
}
@Nonnull
@Override
@Deprecated
public net.minecraft.client.renderer.model.ItemCameraTransforms getItemCameraTransforms()
public net.minecraft.client.renderer.model.ItemCameraTransforms getTransforms()
{
return m_baseModel.getItemCameraTransforms();
return baseModel.getTransforms();
}
@Nonnull

View File

@@ -23,7 +23,7 @@ public class TurtlePlayerRenderer extends EntityRenderer<TurtlePlayer>
@Nonnull
@Override
public ResourceLocation getEntityTexture( @Nonnull TurtlePlayer entity )
public ResourceLocation getTextureLocation( @Nonnull TurtlePlayer entity )
{
return ComputerBorderRenderer.BACKGROUND_NORMAL;
}

View File

@@ -42,26 +42,26 @@ public class TurtleSmartItemModel implements IBakedModel
stack.translate( 0, 0, 1 );
identity = TransformationMatrix.identity();
flip = new TransformationMatrix( stack.getLast().getMatrix() );
flip = new TransformationMatrix( stack.last().pose() );
}
private static class TurtleModelCombination
{
final boolean m_colour;
final ITurtleUpgrade m_leftUpgrade;
final ITurtleUpgrade m_rightUpgrade;
final ResourceLocation m_overlay;
final boolean m_christmas;
final boolean m_flip;
final boolean colour;
final ITurtleUpgrade leftUpgrade;
final ITurtleUpgrade rightUpgrade;
final ResourceLocation overlay;
final boolean christmas;
final boolean flip;
TurtleModelCombination( boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, ResourceLocation overlay, boolean christmas, boolean flip )
{
m_colour = colour;
m_leftUpgrade = leftUpgrade;
m_rightUpgrade = rightUpgrade;
m_overlay = overlay;
m_christmas = christmas;
m_flip = flip;
this.colour = colour;
this.leftUpgrade = leftUpgrade;
this.rightUpgrade = rightUpgrade;
this.overlay = overlay;
this.christmas = christmas;
this.flip = flip;
}
@Override
@@ -71,12 +71,12 @@ public class TurtleSmartItemModel implements IBakedModel
if( !(other instanceof TurtleModelCombination) ) return false;
TurtleModelCombination otherCombo = (TurtleModelCombination) other;
return otherCombo.m_colour == m_colour &&
otherCombo.m_leftUpgrade == m_leftUpgrade &&
otherCombo.m_rightUpgrade == m_rightUpgrade &&
Objects.equal( otherCombo.m_overlay, m_overlay ) &&
otherCombo.m_christmas == m_christmas &&
otherCombo.m_flip == m_flip;
return otherCombo.colour == colour &&
otherCombo.leftUpgrade == leftUpgrade &&
otherCombo.rightUpgrade == rightUpgrade &&
Objects.equal( otherCombo.overlay, overlay ) &&
otherCombo.christmas == christmas &&
otherCombo.flip == flip;
}
@Override
@@ -84,12 +84,12 @@ public class TurtleSmartItemModel implements IBakedModel
{
final int prime = 31;
int result = 0;
result = prime * result + (m_colour ? 1 : 0);
result = prime * result + (m_leftUpgrade != null ? m_leftUpgrade.hashCode() : 0);
result = prime * result + (m_rightUpgrade != null ? m_rightUpgrade.hashCode() : 0);
result = prime * result + (m_overlay != null ? m_overlay.hashCode() : 0);
result = prime * result + (m_christmas ? 1 : 0);
result = prime * result + (m_flip ? 1 : 0);
result = prime * result + (colour ? 1 : 0);
result = prime * result + (leftUpgrade != null ? leftUpgrade.hashCode() : 0);
result = prime * result + (rightUpgrade != null ? rightUpgrade.hashCode() : 0);
result = prime * result + (overlay != null ? overlay.hashCode() : 0);
result = prime * result + (christmas ? 1 : 0);
result = prime * result + (flip ? 1 : 0);
return result;
}
}
@@ -97,19 +97,19 @@ public class TurtleSmartItemModel implements IBakedModel
private final IBakedModel familyModel;
private final IBakedModel colourModel;
private final HashMap<TurtleModelCombination, IBakedModel> m_cachedModels = new HashMap<>();
private final ItemOverrideList m_overrides;
private final HashMap<TurtleModelCombination, IBakedModel> cachedModels = new HashMap<>();
private final ItemOverrideList overrides;
public TurtleSmartItemModel( IBakedModel familyModel, IBakedModel colourModel )
{
this.familyModel = familyModel;
this.colourModel = colourModel;
m_overrides = new ItemOverrideList()
overrides = new ItemOverrideList()
{
@Nonnull
@Override
public IBakedModel getOverrideModel( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable ClientWorld world, @Nullable LivingEntity entity )
public IBakedModel resolve( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable ClientWorld world, @Nullable LivingEntity entity )
{
ItemTurtle turtle = (ItemTurtle) stack.getItem();
int colour = turtle.getColour( stack );
@@ -121,8 +121,8 @@ public class TurtleSmartItemModel implements IBakedModel
boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" ));
TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip );
IBakedModel model = m_cachedModels.get( combo );
if( model == null ) m_cachedModels.put( combo, model = buildModel( combo ) );
IBakedModel model = cachedModels.get( combo );
if( model == null ) cachedModels.put( combo, model = buildModel( combo ) );
return model;
}
};
@@ -132,20 +132,20 @@ public class TurtleSmartItemModel implements IBakedModel
@Override
public ItemOverrideList getOverrides()
{
return m_overrides;
return overrides;
}
private IBakedModel buildModel( TurtleModelCombination combo )
{
Minecraft mc = Minecraft.getInstance();
ModelManager modelManager = mc.getItemRenderer().getItemModelMesher().getModelManager();
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_overlay, combo.m_christmas );
ModelManager modelManager = mc.getItemRenderer().getItemModelShaper().getModelManager();
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.overlay, combo.christmas );
IBakedModel baseModel = combo.m_colour ? colourModel : familyModel;
IBakedModel baseModel = combo.colour ? colourModel : familyModel;
IBakedModel overlayModel = overlayModelLocation != null ? modelManager.getModel( overlayModelLocation ) : null;
TransformationMatrix transform = combo.m_flip ? flip : identity;
TransformedModel leftModel = combo.m_leftUpgrade != null ? combo.m_leftUpgrade.getModel( null, TurtleSide.LEFT ) : null;
TransformedModel rightModel = combo.m_rightUpgrade != null ? combo.m_rightUpgrade.getModel( null, TurtleSide.RIGHT ) : null;
TransformationMatrix transform = combo.flip ? flip : identity;
TransformedModel leftModel = combo.leftUpgrade != null ? combo.leftUpgrade.getModel( null, TurtleSide.LEFT ) : null;
TransformedModel rightModel = combo.rightUpgrade != null ? combo.rightUpgrade.getModel( null, TurtleSide.RIGHT ) : null;
return new TurtleMultiModel( baseModel, overlayModel, transform, leftModel, rightModel );
}
@@ -166,9 +166,9 @@ public class TurtleSmartItemModel implements IBakedModel
}
@Override
public boolean isAmbientOcclusion()
public boolean useAmbientOcclusion()
{
return familyModel.isAmbientOcclusion();
return familyModel.useAmbientOcclusion();
}
@Override
@@ -178,31 +178,31 @@ public class TurtleSmartItemModel implements IBakedModel
}
@Override
public boolean isBuiltInRenderer()
public boolean isCustomRenderer()
{
return familyModel.isBuiltInRenderer();
return familyModel.isCustomRenderer();
}
@Override
public boolean isSideLit()
public boolean usesBlockLight()
{
return familyModel.isSideLit();
return familyModel.usesBlockLight();
}
@Nonnull
@Override
@Deprecated
public TextureAtlasSprite getParticleTexture()
public TextureAtlasSprite getParticleIcon()
{
return familyModel.getParticleTexture();
return familyModel.getParticleIcon();
}
@Nonnull
@Override
@Deprecated
public ItemCameraTransforms getItemCameraTransforms()
public ItemCameraTransforms getTransforms()
{
return familyModel.getItemCameraTransforms();
return familyModel.getTransforms();
}
}

View File

@@ -19,22 +19,22 @@ import java.util.Set;
public abstract class ComputerAccess implements IComputerAccess
{
private final IAPIEnvironment m_environment;
private final Set<String> m_mounts = new HashSet<>();
private final IAPIEnvironment environment;
private final Set<String> mounts = new HashSet<>();
protected ComputerAccess( IAPIEnvironment environment )
{
this.m_environment = environment;
this.environment = environment;
}
public void unmountAll()
{
FileSystem fileSystem = m_environment.getFileSystem();
for( String mount : m_mounts )
FileSystem fileSystem = environment.getFileSystem();
for( String mount : mounts )
{
fileSystem.unmount( mount );
}
m_mounts.clear();
mounts.clear();
}
@Override
@@ -46,7 +46,7 @@ public abstract class ComputerAccess implements IComputerAccess
// Mount the location
String location;
FileSystem fileSystem = m_environment.getFileSystem();
FileSystem fileSystem = environment.getFileSystem();
if( fileSystem == null ) throw new IllegalStateException( "File system has not been created" );
synchronized( fileSystem )
@@ -64,7 +64,7 @@ public abstract class ComputerAccess implements IComputerAccess
}
}
if( location != null ) m_mounts.add( location );
if( location != null ) mounts.add( location );
return location;
}
@@ -77,7 +77,7 @@ public abstract class ComputerAccess implements IComputerAccess
// Mount the location
String location;
FileSystem fileSystem = m_environment.getFileSystem();
FileSystem fileSystem = environment.getFileSystem();
if( fileSystem == null ) throw new IllegalStateException( "File system has not been created" );
synchronized( fileSystem )
@@ -95,7 +95,7 @@ public abstract class ComputerAccess implements IComputerAccess
}
}
if( location != null ) m_mounts.add( location );
if( location != null ) mounts.add( location );
return location;
}
@@ -103,37 +103,37 @@ public abstract class ComputerAccess implements IComputerAccess
public void unmount( String location )
{
if( location == null ) return;
if( !m_mounts.contains( location ) ) throw new IllegalStateException( "You didn't mount this location" );
if( !mounts.contains( location ) ) throw new IllegalStateException( "You didn't mount this location" );
m_environment.getFileSystem().unmount( location );
m_mounts.remove( location );
environment.getFileSystem().unmount( location );
mounts.remove( location );
}
@Override
public int getID()
{
return m_environment.getComputerID();
return environment.getComputerID();
}
@Override
public void queueEvent( @Nonnull String event, Object... arguments )
{
Objects.requireNonNull( event, "event cannot be null" );
m_environment.queueEvent( event, arguments );
environment.queueEvent( event, arguments );
}
@Nonnull
@Override
public IWorkMonitor getMainThreadMonitor()
{
return m_environment.getMainThreadMonitor();
return environment.getMainThreadMonitor();
}
private String findFreeLocation( String desiredLoc )
{
try
{
FileSystem fileSystem = m_environment.getFileSystem();
FileSystem fileSystem = environment.getFileSystem();
if( !fileSystem.exists( desiredLoc ) ) return desiredLoc;
// We used to check foo2, foo3, foo4, etc here but the disk drive does this itself now

View File

@@ -89,9 +89,9 @@ public class FSAPI implements ILuaAPI
*
* @param arguments The paths to combine.
* @return The new path, with separators added between parts as needed.
* @throws LuaException On argument errors.
* @cc.tparam string path The first part of the path. For example, a parent directory path.
* @cc.tparam string ... Additional parts of the path to combine.
* @throws LuaException On argument errors.
*/
@LuaFunction
public final String combine( IArguments arguments ) throws LuaException
@@ -471,8 +471,8 @@ public class FSAPI implements ILuaAPI
/**
* Get attributes about a specific file or folder.
*
* The returned attributes table contains information about the size of the file, whether it is a directory, and
* when it was created and last modified.
* The returned attributes table contains information about the size of the file, whether it is a directory,
* when it was created and last modified, and whether it is read only.
*
* The creation and modification times are given as the number of milliseconds since the UNIX epoch. This may be
* given to {@link OSAPI#date} in order to convert it to more usable form.
@@ -480,7 +480,7 @@ public class FSAPI implements ILuaAPI
* @param path The path to get attributes for.
* @return The resulting attributes.
* @throws LuaException If the path does not exist.
* @cc.treturn { size = number, isDir = boolean, created = number, modified = number } The resulting attributes.
* @cc.treturn { size = number, isDir = boolean, isReadOnly = boolean, created = number, modified = number } The resulting attributes.
* @see #getSize If you only care about the file's size.
* @see #isDir If you only care whether a path is a directory or not.
*/
@@ -496,6 +496,7 @@ public class FSAPI implements ILuaAPI
result.put( "created", getFileTime( attributes.creationTime() ) );
result.put( "size", attributes.isDirectory() ? 0 : attributes.size() );
result.put( "isDir", attributes.isDirectory() );
result.put( "isReadOnly", fileSystem.isReadOnly( path ) );
return result;
}
catch( FileSystemException e )

View File

@@ -14,6 +14,7 @@ import dan200.computercraft.core.apis.http.*;
import dan200.computercraft.core.apis.http.request.HttpRequest;
import dan200.computercraft.core.apis.http.websocket.Websocket;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
@@ -34,7 +35,7 @@ import static dan200.computercraft.core.apis.TableHelper.*;
*/
public class HTTPAPI implements ILuaAPI
{
private final IAPIEnvironment m_apiEnvironment;
private final IAPIEnvironment apiEnvironment;
private final ResourceGroup<CheckUrl> checkUrls = new ResourceGroup<>();
private final ResourceGroup<HttpRequest> requests = new ResourceQueue<>( () -> ComputerCraft.httpMaxRequests );
@@ -42,7 +43,7 @@ public class HTTPAPI implements ILuaAPI
public HTTPAPI( IAPIEnvironment environment )
{
m_apiEnvironment = environment;
apiEnvironment = environment;
}
@Override
@@ -123,7 +124,7 @@ public class HTTPAPI implements ILuaAPI
try
{
URI uri = HttpRequest.checkUri( address );
HttpRequest request = new HttpRequest( requests, m_apiEnvironment, address, postString, headers, binary, redirect );
HttpRequest request = new HttpRequest( requests, apiEnvironment, address, postString, headers, binary, redirect );
// Make the request
request.queue( r -> r.request( uri, httpMethod ) );
@@ -142,7 +143,7 @@ public class HTTPAPI implements ILuaAPI
try
{
URI uri = HttpRequest.checkUri( address );
new CheckUrl( checkUrls, m_apiEnvironment, address, uri ).queue( CheckUrl::run );
new CheckUrl( checkUrls, apiEnvironment, address, uri ).queue( CheckUrl::run );
return new Object[] { true };
}
@@ -165,7 +166,7 @@ public class HTTPAPI implements ILuaAPI
try
{
URI uri = Websocket.checkUri( address );
if( !new Websocket( websockets, m_apiEnvironment, uri, address, headers ).queue( Websocket::connect ) )
if( !new Websocket( websockets, apiEnvironment, uri, address, headers ).queue( Websocket::connect ) )
{
throw new LuaException( "Too many websockets already open" );
}
@@ -179,7 +180,7 @@ public class HTTPAPI implements ILuaAPI
}
@Nonnull
private static HttpHeaders getHeaders( @Nonnull Map<?, ?> headerTable ) throws LuaException
private HttpHeaders getHeaders( @Nonnull Map<?, ?> headerTable ) throws LuaException
{
HttpHeaders headers = new DefaultHttpHeaders();
for( Map.Entry<?, ?> entry : headerTable.entrySet() )
@@ -197,6 +198,11 @@ public class HTTPAPI implements ILuaAPI
}
}
}
if( !headers.contains( HttpHeaderNames.USER_AGENT ) )
{
headers.set( HttpHeaderNames.USER_AGENT, apiEnvironment.getComputerEnvironment().getUserAgent() );
}
return headers;
}
}

View File

@@ -32,29 +32,29 @@ public class OSAPI implements ILuaAPI
{
private final IAPIEnvironment apiEnvironment;
private final Int2ObjectMap<Alarm> m_alarms = new Int2ObjectOpenHashMap<>();
private int m_clock;
private double m_time;
private int m_day;
private final Int2ObjectMap<Alarm> alarms = new Int2ObjectOpenHashMap<>();
private int clock;
private double time;
private int day;
private int m_nextAlarmToken = 0;
private int nextAlarmToken = 0;
private static class Alarm implements Comparable<Alarm>
{
final double m_time;
final int m_day;
final double time;
final int day;
Alarm( double time, int day )
{
m_time = time;
m_day = day;
this.time = time;
this.day = day;
}
@Override
public int compareTo( @Nonnull Alarm o )
{
double t = m_day * 24.0 + m_time;
double ot = m_day * 24.0 + m_time;
double t = day * 24.0 + time;
double ot = day * 24.0 + time;
return Double.compare( t, ot );
}
}
@@ -73,38 +73,38 @@ public class OSAPI implements ILuaAPI
@Override
public void startup()
{
m_time = apiEnvironment.getComputerEnvironment().getTimeOfDay();
m_day = apiEnvironment.getComputerEnvironment().getDay();
m_clock = 0;
time = apiEnvironment.getComputerEnvironment().getTimeOfDay();
day = apiEnvironment.getComputerEnvironment().getDay();
clock = 0;
synchronized( m_alarms )
synchronized( alarms )
{
m_alarms.clear();
alarms.clear();
}
}
@Override
public void update()
{
m_clock++;
clock++;
// Wait for all of our alarms
synchronized( m_alarms )
synchronized( alarms )
{
double previousTime = m_time;
int previousDay = m_day;
double previousTime = time;
int previousDay = day;
double time = apiEnvironment.getComputerEnvironment().getTimeOfDay();
int day = apiEnvironment.getComputerEnvironment().getDay();
if( time > previousTime || day > previousDay )
{
double now = m_day * 24.0 + m_time;
Iterator<Int2ObjectMap.Entry<Alarm>> it = m_alarms.int2ObjectEntrySet().iterator();
double now = this.day * 24.0 + this.time;
Iterator<Int2ObjectMap.Entry<Alarm>> it = alarms.int2ObjectEntrySet().iterator();
while( it.hasNext() )
{
Int2ObjectMap.Entry<Alarm> entry = it.next();
Alarm alarm = entry.getValue();
double t = alarm.m_day * 24.0 + alarm.m_time;
double t = alarm.day * 24.0 + alarm.time;
if( now >= t )
{
apiEnvironment.queueEvent( "alarm", entry.getIntKey() );
@@ -113,17 +113,17 @@ public class OSAPI implements ILuaAPI
}
}
m_time = time;
m_day = day;
this.time = time;
this.day = day;
}
}
@Override
public void shutdown()
{
synchronized( m_alarms )
synchronized( alarms )
{
m_alarms.clear();
alarms.clear();
}
}
@@ -180,7 +180,7 @@ public class OSAPI implements ILuaAPI
*
* @param timer The number of seconds until the timer fires.
* @return The ID of the new timer. This can be used to filter the
* {@code timer} event, or {@link #cancelTimer cancel the timer}.
* {@code timer} event, or {@link #cancelTimer cancel the timer}.
* @throws LuaException If the time is below zero.
* @see #cancelTimer To cancel a timer.
*/
@@ -210,7 +210,7 @@ public class OSAPI implements ILuaAPI
*
* @param time The time at which to fire the alarm, in the range [0.0, 24.0).
* @return The ID of the new alarm. This can be used to filter the
* {@code alarm} event, or {@link #cancelAlarm cancel the alarm}.
* {@code alarm} event, or {@link #cancelAlarm cancel the alarm}.
* @throws LuaException If the time is out of range.
* @see #cancelAlarm To cancel an alarm.
*/
@@ -219,11 +219,11 @@ public class OSAPI implements ILuaAPI
{
checkFinite( 0, time );
if( time < 0.0 || time >= 24.0 ) throw new LuaException( "Number out of range" );
synchronized( m_alarms )
synchronized( alarms )
{
int day = time > m_time ? m_day : m_day + 1;
m_alarms.put( m_nextAlarmToken, new Alarm( time, day ) );
return m_nextAlarmToken++;
int day = time > this.time ? this.day : this.day + 1;
alarms.put( nextAlarmToken, new Alarm( time, day ) );
return nextAlarmToken++;
}
}
@@ -237,9 +237,9 @@ public class OSAPI implements ILuaAPI
@LuaFunction
public final void cancelAlarm( int token )
{
synchronized( m_alarms )
synchronized( alarms )
{
m_alarms.remove( token );
alarms.remove( token );
}
}
@@ -304,7 +304,7 @@ public class OSAPI implements ILuaAPI
@LuaFunction
public final double clock()
{
return m_clock * 0.05;
return clock * 0.05;
}
/**
@@ -341,7 +341,7 @@ public class OSAPI implements ILuaAPI
case "local": // Get Hour of day (local time)
return getTimeForCalendar( Calendar.getInstance() );
case "ingame": // Get in-game hour
return m_time;
return time;
default:
throw new LuaException( "Unsupported operation" );
}
@@ -371,7 +371,7 @@ public class OSAPI implements ILuaAPI
case "local": // Get numbers of days since 1970-01-01 (local time)
return getDayForCalendar( Calendar.getInstance() );
case "ingame":// Get game day
return m_day;
return day;
default:
throw new LuaException( "Unsupported operation" );
}
@@ -381,11 +381,11 @@ public class OSAPI implements ILuaAPI
* Returns the number of milliseconds since an epoch depending on the locale.
*
* * If called with {@code ingame}, returns the number of milliseconds since the
* world was created. This is the default.
* world was created. This is the default.
* * If called with {@code utc}, returns the number of milliseconds since 1
* January 1970 in the UTC timezone.
* January 1970 in the UTC timezone.
* * If called with {@code local}, returns the number of milliseconds since 1
* January 1970 in the server's local timezone.
* January 1970 in the server's local timezone.
*
* @param args The locale to get the milliseconds for. Defaults to {@code ingame} if not set.
* @return The milliseconds since the epoch depending on the selected locale.
@@ -410,9 +410,9 @@ public class OSAPI implements ILuaAPI
}
case "ingame":
// Get in-game epoch
synchronized( m_alarms )
synchronized( alarms )
{
return m_day * 86400000L + (long) (m_time * 3600000.0);
return day * 86400000L + (long) (time * 3600000.0);
}
default:
throw new LuaException( "Unsupported operation" );

View File

@@ -191,7 +191,7 @@ public class RedstoneAPI implements ILuaAPI
@LuaFunction
public final int getBundledInput( ComputerSide side )
{
return environment.getBundledOutput( side );
return environment.getBundledInput( side );
}
/**

View File

@@ -7,9 +7,9 @@ package dan200.computercraft.core.apis.handles;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
@@ -32,14 +32,14 @@ public class BinaryReadableHandle extends HandleGeneric
final SeekableByteChannel seekable;
private final ByteBuffer single = ByteBuffer.allocate( 1 );
BinaryReadableHandle( ReadableByteChannel reader, SeekableByteChannel seekable, Closeable closeable )
BinaryReadableHandle( ReadableByteChannel reader, SeekableByteChannel seekable, TrackingCloseable closeable )
{
super( closeable );
this.reader = reader;
this.seekable = seekable;
}
public static BinaryReadableHandle of( ReadableByteChannel channel, Closeable closeable )
public static BinaryReadableHandle of( ReadableByteChannel channel, TrackingCloseable closeable )
{
SeekableByteChannel seekable = asSeekable( channel );
return seekable == null ? new BinaryReadableHandle( channel, null, closeable ) : new Seekable( seekable, closeable );
@@ -47,7 +47,7 @@ public class BinaryReadableHandle extends HandleGeneric
public static BinaryReadableHandle of( ReadableByteChannel channel )
{
return of( channel, channel );
return of( channel, new TrackingCloseable.Impl( channel ) );
}
/**
@@ -237,7 +237,7 @@ public class BinaryReadableHandle extends HandleGeneric
public static class Seekable extends BinaryReadableHandle
{
Seekable( SeekableByteChannel seekable, Closeable closeable )
Seekable( SeekableByteChannel seekable, TrackingCloseable closeable )
{
super( seekable, seekable, closeable );
}

View File

@@ -9,8 +9,8 @@ import dan200.computercraft.api.lua.IArguments;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.lua.LuaValues;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
@@ -30,14 +30,14 @@ public class BinaryWritableHandle extends HandleGeneric
final SeekableByteChannel seekable;
private final ByteBuffer single = ByteBuffer.allocate( 1 );
protected BinaryWritableHandle( WritableByteChannel writer, SeekableByteChannel seekable, Closeable closeable )
protected BinaryWritableHandle( WritableByteChannel writer, SeekableByteChannel seekable, TrackingCloseable closeable )
{
super( closeable );
this.writer = writer;
this.seekable = seekable;
}
public static BinaryWritableHandle of( WritableByteChannel channel, Closeable closeable )
public static BinaryWritableHandle of( WritableByteChannel channel, TrackingCloseable closeable )
{
SeekableByteChannel seekable = asSeekable( channel );
return seekable == null ? new BinaryWritableHandle( channel, null, closeable ) : new Seekable( seekable, closeable );
@@ -45,7 +45,7 @@ public class BinaryWritableHandle extends HandleGeneric
public static BinaryWritableHandle of( WritableByteChannel channel )
{
return of( channel, channel );
return of( channel, new TrackingCloseable.Impl( channel ) );
}
/**
@@ -108,7 +108,7 @@ public class BinaryWritableHandle extends HandleGeneric
public static class Seekable extends BinaryWritableHandle
{
public Seekable( SeekableByteChannel seekable, Closeable closeable )
public Seekable( SeekableByteChannel seekable, TrackingCloseable closeable )
{
super( seekable, seekable, closeable );
}

View File

@@ -7,10 +7,10 @@ package dan200.computercraft.core.apis.handles;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import javax.annotation.Nonnull;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
@@ -32,7 +32,7 @@ public class EncodedReadableHandle extends HandleGeneric
private final BufferedReader reader;
public EncodedReadableHandle( @Nonnull BufferedReader reader, @Nonnull Closeable closable )
public EncodedReadableHandle( @Nonnull BufferedReader reader, @Nonnull TrackingCloseable closable )
{
super( closable );
this.reader = reader;
@@ -40,7 +40,7 @@ public class EncodedReadableHandle extends HandleGeneric
public EncodedReadableHandle( @Nonnull BufferedReader reader )
{
this( reader, reader );
this( reader, new TrackingCloseable.Impl( reader ) );
}
/**

View File

@@ -8,11 +8,11 @@ package dan200.computercraft.core.apis.handles;
import dan200.computercraft.api.lua.IArguments;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import dan200.computercraft.shared.util.StringUtil;
import javax.annotation.Nonnull;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
@@ -30,7 +30,7 @@ public class EncodedWritableHandle extends HandleGeneric
{
private final BufferedWriter writer;
public EncodedWritableHandle( @Nonnull BufferedWriter writer, @Nonnull Closeable closable )
public EncodedWritableHandle( @Nonnull BufferedWriter writer, @Nonnull TrackingCloseable closable )
{
super( closable );
this.writer = writer;

View File

@@ -7,10 +7,10 @@ package dan200.computercraft.core.apis.handles;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import dan200.computercraft.shared.util.IoUtil;
import javax.annotation.Nonnull;
import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.Channel;
import java.nio.channels.SeekableByteChannel;
@@ -18,25 +18,23 @@ import java.util.Optional;
public abstract class HandleGeneric
{
private Closeable closable;
private boolean open = true;
private TrackingCloseable closeable;
protected HandleGeneric( @Nonnull Closeable closable )
protected HandleGeneric( @Nonnull TrackingCloseable closeable )
{
this.closable = closable;
this.closeable = closeable;
}
protected void checkOpen() throws LuaException
{
if( !open ) throw new LuaException( "attempt to use a closed file" );
TrackingCloseable closeable = this.closeable;
if( closeable == null || !closeable.isOpen() ) throw new LuaException( "attempt to use a closed file" );
}
protected final void close()
{
open = false;
IoUtil.closeQuietly( closable );
closable = null;
IoUtil.closeQuietly( closeable );
closeable = null;
}
/**

View File

@@ -80,10 +80,6 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpOb
{
request.headers().set( HttpHeaderNames.ACCEPT_CHARSET, "UTF-8" );
}
if( !request.headers().contains( HttpHeaderNames.USER_AGENT ) )
{
request.headers().set( HttpHeaderNames.USER_AGENT, this.request.environment().getComputerEnvironment().getUserAgent() );
}
request.headers().set( HttpHeaderNames.HOST, uri.getPort() < 0 ? uri.getHost() : uri.getHost() + ":" + uri.getPort() );
request.headers().set( HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE );

View File

@@ -58,10 +58,10 @@ public class HttpResponseHandle implements ObjectSource
* If multiple headers are sent with the same name, they will be combined with a comma.
*
* @return The response's headers.
* @cc.usage Make a request to [example.computercraft.cc](https://example.computercraft.cc), and print the
* @cc.usage Make a request to [example.tweaked.cc](https://example.tweaked.cc), and print the
* returned headers.
* <pre>{@code
* local request = http.get("https://example.computercraft.cc")
* local request = http.get("https://example.tweaked.cc")
* print(textutils.serialize(request.getResponseHeaders()))
* -- => {
* -- [ "Content-Type" ] = "text/plain; charset=utf8",

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