1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-25 09:34:47 +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 # Ignore changes in generated files
src/generated/resources/data/** linguist-generated src/generated/resources/data/** linguist-generated
src/test/server-files/structures linguist-generated

View File

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

View File

@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2
- name: Set up Java 8 - name: Set up Java 8
uses: actions/setup-java@v1 uses: actions/setup-java@v1
@@ -19,7 +19,7 @@ jobs:
java-version: 8 java-version: 8
- name: Cache gradle dependencies - name: Cache gradle dependencies
uses: actions/cache@v1 uses: actions/cache@v2
with: with:
path: ~/.gradle/caches path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }} 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, 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. 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 ## Developing
In order to develop CC: Tweaked, you'll need to download the source code and then run it. This is a pretty simple 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`. 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 These commands may take a few minutes to run the first time, as the environment is set up, but should be much faster
afterwards. 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 ### Code linters
CC: Tweaked uses a couple of "linters" on its source code, to enforce a consistent style across the project. While these 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. 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 - **[Checkstyle]:** Checks Java code to ensure it is consistently formatted. This can be run with `./gradlew build` or
`./gradle check`. `./gradle check`.
- **[illuaminate]:** Checks Lua code for semantic and styleistic issues. See [the usage section][illuaminate-usage] for - **[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 ### Documentation
Translations are managed through [Weblate], an online interface for managing language strings. This is synced When writing documentation for [CC: Tweaked's documentation website][docs], it may be useful to build the documentation
automatically with GitHub, so please don't submit PRs adding/changing translations! 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" [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." [community]: README.md#Community "Get in touch with the community."
[checkstyle]: https://checkstyle.org/ [checkstyle]: https://checkstyle.org/
[illuaminate]: https://github.com/SquidDev/illuaminate/ [illuaminate]: https://github.com/SquidDev/illuaminate/ "Illuaminate on GitHub"
[illuaminate-usage]: https://github.com/SquidDev/illuaminate/blob/master/README.md#usage [illuaminate-usage]: https://github.com/SquidDev/illuaminate/blob/master/README.md#usage "Installing Illuaminate"
[weblate]: https://i18n.tweaked.cc/projects/cc-tweaked/minecraft/ [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" name = "forge"
url = "https://files.minecraftforge.net/maven" url = "https://files.minecraftforge.net/maven"
} }
maven {
name = "Sponge (Mixin)"
url = "https://repo.spongepowered.org/repository/maven-public/"
content { includeGroup "org.spongepowered" }
}
} }
dependencies { dependencies {
classpath 'com.google.code.gson:gson:2.8.1' 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 '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 "checkstyle"
id "jacoco" id "jacoco"
id "com.github.hierynomus.license" version "0.15.0" id "com.github.hierynomus.license" version "0.15.0"
id "com.matthewprenger.cursegradle" version "1.3.0" id "com.matthewprenger.cursegradle" version "1.4.0"
id "com.github.breadmoirai.github-release" version "2.2.4" 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: 'net.minecraftforge.gradle'
apply plugin: 'org.ajoberstar.grgit' apply plugin: 'org.spongepowered.mixin'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
apply plugin: 'maven' apply plugin: 'maven'
@@ -33,7 +39,11 @@ version = mod_version
group = "org.squiddev" group = "org.squiddev"
archivesBaseName = "cc-tweaked-${mc_version}" archivesBaseName = "cc-tweaked-${mc_version}"
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' java {
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
}
minecraft { minecraft {
runs { runs {
@@ -50,9 +60,10 @@ minecraft {
} }
server { server {
workingDirectory project.file("run/server-${mc_version}") workingDirectory project.file("run/server")
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP' property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug' property 'forge.logging.console.level', 'debug'
arg "--nogui"
mods { mods {
computercraft { computercraft {
@@ -63,7 +74,7 @@ minecraft {
data { data {
workingDirectory project.file('run') workingDirectory project.file('run')
property 'forge.logging.markers', 'REGISTRIES,REGISTRYDUMP' property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug' property 'forge.logging.console.level', 'debug'
args '--mod', 'computercraft', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') 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') accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
} }
mixin {
add sourceSets.test, "cctest.refmap.json"
}
sourceSets { sourceSets {
main.resources { main.resources {
srcDir 'src/generated/resources' srcDir 'src/generated/resources'
@@ -120,6 +150,9 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0' testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
testImplementation 'org.hamcrest:hamcrest:2.2' 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" 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.docletpath = configurations.cctJavadoc.files as List
options.doclet = "cc.tweaked.javadoc.LuaDoclet" options.doclet = "cc.tweaked.javadoc.LuaDoclet"
options.noTimestamp = false
// Attempt to run under Java 11 (any Java >= 9 will work though). javadocTool = javaToolchains.javadocToolFor {
if(System.getProperty("java.version").startsWith("1.") languageVersion = JavaLanguageVersion.of(11)
&& (System.getenv("JAVA_HOME_11_X64") != null || project.hasProperty("java11Home"))) {
executable = "${System.getenv("JAVA_HOME_11_X64") ?: project.property("java11Home")}/bin/javadoc"
} }
} }
@@ -184,7 +216,6 @@ import com.google.gson.GsonBuilder
import com.google.gson.JsonElement import com.google.gson.JsonElement
import com.hierynomus.gradle.license.tasks.LicenseCheck import com.hierynomus.gradle.license.tasks.LicenseCheck
import com.hierynomus.gradle.license.tasks.LicenseFormat import com.hierynomus.gradle.license.tasks.LicenseFormat
import org.ajoberstar.grgit.Grgit
import proguard.gradle.ProGuardTask import proguard.gradle.ProGuardTask
task proguard(type: ProGuardTask, dependsOn: jar) { task proguard(type: ProGuardTask, dependsOn: jar) {
@@ -237,16 +268,15 @@ processResources {
def hash = 'none' def hash = 'none'
Set<String> contributors = [] Set<String> contributors = []
try { try {
def grgit = Grgit.open(dir: '.') hash = ["git", "-C", projectDir, "rev-parse", "HEAD"].execute().text.trim()
hash = grgit.head().id
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe'] def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
grgit.log().each { ["git", "-C", projectDir, "log", "--format=tformat:%an%n%cn"].execute().text.split('\n').each {
if (!blacklist.contains(it.author.name)) contributors.add(it.author.name) if (!blacklist.contains(it)) contributors.add(it)
if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
} }
} catch(Exception ignored) { } } catch(Exception e) {
e.printStackTrace()
}
inputs.property "commithash", hash inputs.property "commithash", hash
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
@@ -369,6 +399,7 @@ test {
} }
jacocoTestReport { jacocoTestReport {
dependsOn('test')
reports { reports {
xml.enabled true xml.enabled true
html.enabled true html.enabled true
@@ -388,14 +419,14 @@ license {
it.configure { it.configure {
include("**/*.java") include("**/*.java")
exclude("dan200/computercraft/api/**") exclude("dan200/computercraft/api/**")
header rootProject.file('config/license/main.txt') header file('config/license/main.txt')
} }
} }
[licenseTest, licenseFormatTest].forEach { [licenseTest, licenseFormatTest].forEach {
it.configure { it.configure {
include("**/*.java") 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 { it.configure {
source = sourceSets.main.java source = sourceSets.main.java
include("dan200/computercraft/api/**") 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 // Upload tasks
task checkRelease { task checkRelease {
@@ -430,7 +522,7 @@ task checkRelease {
def ok = true def ok = true
// Check we're targetting the current version // 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") { if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
ok = false ok = false
project.logger.error("Expected `whatsnew.txt' to target $mod_version.") project.logger.error("Expected `whatsnew.txt' to target $mod_version.")
@@ -447,7 +539,7 @@ task checkRelease {
// Check whatsnew and changelog match. // Check whatsnew and changelog match.
def versionChangelog = "# " + whatsnew.join("\n") 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)) { if (!changelog.startsWith(versionChangelog)) {
ok = false ok = false
project.logger.error("whatsnew and changelog are not in sync") project.logger.error("whatsnew and changelog are not in sync")
@@ -468,6 +560,9 @@ curseforge {
relations { relations {
incompatible "computercraft" incompatible "computercraft"
} }
addGameVersion '1.16.4'
addGameVersion '1.16.5'
} }
} }
@@ -528,18 +623,23 @@ githubRelease {
token project.hasProperty('githubApiKey') ? project.githubApiKey : '' token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
owner 'SquidDev-CC' owner 'SquidDev-CC'
repo 'CC-Tweaked' repo 'CC-Tweaked'
try { targetCommitish.set(project.provider({
targetCommitish = Grgit.open(dir: '.').branch.current().name try {
} catch(Exception ignored) { } 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}" tagName "v${mc_version}-${mod_version}"
releaseName "[${mc_version}] ${mod_version}" releaseName "[${mc_version}] ${mod_version}"
body { body.set(project.provider({
"## " + new File("src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt") "## " + new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.txt")
.readLines() .readLines()
.takeWhile { it != 'Type "help changelog" to see the full version history.' } .takeWhile { it != 'Type "help changelog" to see the full version history.' }
.join("\n").trim() .join("\n").trim()
} }))
prerelease false prerelease false
} }

View File

@@ -7,7 +7,7 @@
<property name="charset" value="UTF-8" /> <property name="charset" value="UTF-8" />
<module name="SuppressionFilter"> <module name="SuppressionFilter">
<property name="file" value="config/checkstyle/suppressions.xml" /> <property name="file" value="${config_loc}/suppressions.xml" />
</module> </module>
<module name="BeforeExecutionExclusionFileFilter"> <module name="BeforeExecutionExclusionFileFilter">
@@ -97,20 +97,11 @@
<module name="LambdaParameterName" /> <module name="LambdaParameterName" />
<module name="LocalFinalVariableName" /> <module name="LocalFinalVariableName" />
<module name="LocalVariableName" /> <module name="LocalVariableName" />
<!-- Allow an optional m_ on private members --> <module name="MemberName" />
<module name="MemberName">
<property name="applyToPrivate" value="false" />
<property name="applyToPackage" value="false" />
</module>
<module name="MemberName">
<property name="format" value="^(m_)?[a-z][a-zA-Z0-9]*$" />
<property name="applyToPrivate" value="true" />
<property name="applyToPackage" value="true" />
</module>
<module name="MethodName" /> <module name="MethodName" />
<module name="MethodTypeParameterName" /> <module name="MethodTypeParameterName" />
<module name="PackageName"> <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>
<module name="ParameterName" /> <module name="ParameterName" />
<module name="StaticVariableName"> <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 string A message detailing why the request failed.
-- @treturn Response|nil The failing http response, if available. -- @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. -- and print the returned page.
-- ```lua -- ```lua
-- local request = http.get("https://example.computercraft.cc") -- local request = http.get("https://example.tweaked.cc")
-- print(request.readAll()) -- print(request.readAll())
-- -- => HTTP is working! -- -- => HTTP is working!
-- request.close() -- request.close()
@@ -123,7 +123,7 @@ function checkURLAsync(url) end
-- --
-- @usage -- @usage
-- ```lua -- ```lua
-- print(http.checkURL("https://example.computercraft.cc/")) -- print(http.checkURL("https://example.tweaked.cc/"))
-- -- => true -- -- => true
-- print(http.checkURL("http://localhost/")) -- print(http.checkURL("http://localhost/"))
-- -- => false Domain not permitted -- -- => false Domain not permitted

View File

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

Binary file not shown.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

53
gradlew vendored
View File

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

43
gradlew.bat vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -162,7 +162,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Override @Override
public LazyOptional<IWiredElement> getWiredElementAt( @Nonnull IBlockReader world, @Nonnull BlockPos pos, @Nonnull Direction side ) 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 ); 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 ) 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 ); return new TransformedModel( model, transform );
} }

View File

@@ -35,7 +35,7 @@ public abstract class AbstractPocketUpgrade implements IPocketUpgrade
protected AbstractPocketUpgrade( ResourceLocation id, NonNullSupplier<ItemStack> item ) 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 ) 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 ) 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 ) protected AbstractTurtleUpgrade( ResourceLocation id, TurtleUpgradeType type, String adjective, ItemStack stack )

View File

@@ -78,7 +78,7 @@ public final class ClientRegistry
@SubscribeEvent @SubscribeEvent
public static void onTextureStitchEvent( TextureStitchEvent.Pre event ) 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 ) for( String extra : EXTRA_TEXTURES )
{ {
@@ -96,10 +96,10 @@ public final class ClientRegistry
for( String modelName : EXTRA_MODELS ) for( String modelName : EXTRA_MODELS )
{ {
ResourceLocation location = new ResourceLocation( ComputerCraft.MOD_ID, "item/" + modelName ); ResourceLocation location = new ResourceLocation( ComputerCraft.MOD_ID, "item/" + modelName );
IUnbakedModel model = loader.getUnbakedModel( location ); IUnbakedModel model = loader.getModel( location );
model.getTextures( loader::getUnbakedModel, new HashSet<>() ); 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 ) if( baked != null )
{ {
registry.put( new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, modelName ), "inventory" ), baked ); 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() private static FontRenderer renderer()
{ {
return Minecraft.getInstance().fontRenderer; return Minecraft.getInstance().font;
} }
@Override @Override
@@ -39,7 +39,7 @@ public class ClientTableFormatter implements TableFormatter
FontRenderer renderer = renderer(); FontRenderer renderer = renderer();
float spaceWidth = renderer.getStringWidth( " " ); float spaceWidth = renderer.width( " " );
int spaces = MathHelper.floor( extraWidth / spaceWidth ); int spaces = MathHelper.floor( extraWidth / spaceWidth );
int extra = extraWidth - (int) (spaces * spaceWidth); int extra = extraWidth - (int) (spaces * spaceWidth);
@@ -55,33 +55,33 @@ public class ClientTableFormatter implements TableFormatter
@Override @Override
public int getWidth( ITextComponent component ) public int getWidth( ITextComponent component )
{ {
return renderer().getStringPropertyWidth( component ); return renderer().width( component );
} }
@Override @Override
public void writeLine( int id, ITextComponent component ) public void writeLine( int id, ITextComponent component )
{ {
Minecraft mc = Minecraft.getInstance(); 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 // TODO: Trim the text if it goes over the allowed length
// int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() ); // int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getScale() );
// List<ITextProperties> list = RenderComponentsUtil.func_238505_a_( component, maxWidth, mc.fontRenderer ); // List<ITextProperties> list = RenderComponentsUtil.wrapComponents( component, maxWidth, mc.fontRenderer );
// if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id ); // if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id );
chat.printChatMessageWithOptionalDeletion( component, id ); chat.addMessage( component, id );
} }
@Override @Override
public int display( TableBuilder table ) public int display( TableBuilder table )
{ {
NewChatGui chat = Minecraft.getInstance().ingameGUI.getChatGUI(); NewChatGui chat = Minecraft.getInstance().gui.getChat();
int lastHeight = lastHeights.get( table.getId() ); int lastHeight = lastHeights.get( table.getId() );
int height = TableFormatter.super.display( table ); int height = TableFormatter.super.display( table );
lastHeights.put( table.getId(), height ); lastHeights.put( table.getId(), height );
for( int i = height; i < lastHeight; i++ ) chat.deleteChatLine( i + table.getId() ); for( int i = height; i < lastHeight; i++ ) chat.removeById( i + table.getId() );
return height; return height;
} }
} }

View File

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

View File

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

View File

@@ -25,11 +25,11 @@ public class GuiDiskDrive extends ContainerScreen<ContainerDiskDrive>
} }
@Override @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 ); RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( BACKGROUND ); minecraft.getTextureManager().bind( BACKGROUND );
blit( transform, guiLeft, guiTop, 0, 0, xSize, ySize ); blit( transform, leftPos, topPos, 0, 0, imageWidth, imageHeight );
} }
@Override @Override
@@ -37,6 +37,6 @@ public class GuiDiskDrive extends ContainerScreen<ContainerDiskDrive>
{ {
renderBackground( transform ); renderBackground( transform );
super.render( transform, mouseX, mouseY, partialTicks ); 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 @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 ); RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
minecraft.getTextureManager().bindTexture( BACKGROUND ); minecraft.getTextureManager().bind( BACKGROUND );
blit( transform, guiLeft, guiTop, 0, 0, xSize, ySize ); 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 @Override
@@ -47,6 +47,6 @@ public class GuiPrinter extends ContainerScreen<ContainerPrinter>
{ {
renderBackground( stack ); renderBackground( stack );
super.render( stack, mouseX, mouseY, partialTicks ); 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> public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
{ {
private final boolean m_book; private final boolean book;
private final int m_pages; private final int pages;
private final TextBuffer[] m_text; private final TextBuffer[] text;
private final TextBuffer[] m_colours; private final TextBuffer[] colours;
private int m_page; private int page;
public GuiPrintout( ContainerHeldItem container, PlayerInventory player, ITextComponent title ) public GuiPrintout( ContainerHeldItem container, PlayerInventory player, ITextComponent title )
{ {
super( container, player, title ); super( container, player, title );
ySize = Y_SIZE; imageHeight = Y_SIZE;
String[] text = ItemPrintout.getText( container.getStack() ); String[] text = ItemPrintout.getText( container.getStack() );
m_text = new TextBuffer[text.length]; this.text = new TextBuffer[text.length];
for( int i = 0; i < m_text.length; i++ ) m_text[i] = new TextBuffer( text[i] ); for( int i = 0; i < this.text.length; i++ ) this.text[i] = new TextBuffer( text[i] );
String[] colours = ItemPrintout.getColours( container.getStack() ); String[] colours = ItemPrintout.getColours( container.getStack() );
m_colours = new TextBuffer[colours.length]; this.colours = new TextBuffer[colours.length];
for( int i = 0; i < m_colours.length; i++ ) m_colours[i] = new TextBuffer( colours[i] ); for( int i = 0; i < this.colours.length; i++ ) this.colours[i] = new TextBuffer( colours[i] );
m_page = 0; page = 0;
m_pages = Math.max( m_text.length / ItemPrintout.LINES_PER_PAGE, 1 ); pages = Math.max( this.text.length / ItemPrintout.LINES_PER_PAGE, 1 );
m_book = ((ItemPrintout) container.getStack().getItem()).getType() == ItemPrintout.Type.BOOK; book = ((ItemPrintout) container.getStack().getItem()).getType() == ItemPrintout.Type.BOOK;
} }
@Override @Override
@@ -56,13 +56,13 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
if( key == GLFW.GLFW_KEY_RIGHT ) if( key == GLFW.GLFW_KEY_RIGHT )
{ {
if( m_page < m_pages - 1 ) m_page++; if( page < pages - 1 ) page++;
return true; return true;
} }
if( key == GLFW.GLFW_KEY_LEFT ) if( key == GLFW.GLFW_KEY_LEFT )
{ {
if( m_page > 0 ) m_page--; if( page > 0 ) page--;
return true; return true;
} }
@@ -76,14 +76,14 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
if( delta < 0 ) if( delta < 0 )
{ {
// Scroll up goes to the next page // Scroll up goes to the next page
if( m_page < m_pages - 1 ) m_page++; if( page < pages - 1 ) page++;
return true; return true;
} }
if( delta > 0 ) if( delta > 0 )
{ {
// Scroll down goes to the previous page // Scroll down goes to the previous page
if( m_page > 0 ) m_page--; if( page > 0 ) page--;
return true; return true;
} }
@@ -91,17 +91,17 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
} }
@Override @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 // Draw the printout
RenderSystem.color4f( 1.0f, 1.0f, 1.0f, 1.0f ); RenderSystem.color4f( 1.0f, 1.0f, 1.0f, 1.0f );
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().getRenderTypeBuffers().getBufferSource(); IRenderTypeBuffer.Impl renderer = Minecraft.getInstance().renderBuffers().bufferSource();
Matrix4f matrix = transform.getLast().getMatrix(); Matrix4f matrix = transform.last().pose();
drawBorder( matrix, renderer, guiLeft, guiTop, getBlitOffset(), m_page, m_pages, m_book ); drawBorder( matrix, renderer, leftPos, topPos, getBlitOffset(), page, pages, book );
drawText( matrix, renderer, guiLeft + X_TEXT_MARGIN, guiTop + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours ); drawText( matrix, renderer, leftPos + X_TEXT_MARGIN, topPos + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * page, text, colours );
renderer.finish(); renderer.endBatch();
} }
@Override @Override
@@ -116,7 +116,7 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
} }
@Override @Override
protected void drawGuiContainerForegroundLayer( @Nonnull MatrixStack transform, int mouseX, int mouseY ) protected void renderLabels( @Nonnull MatrixStack transform, int mouseX, int mouseY )
{ {
// Skip rendering labels. // Skip rendering labels.
} }

View File

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

View File

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

View File

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

View File

@@ -45,35 +45,35 @@ public final class CableHighlightRenderer
public static void drawHighlight( DrawHighlightEvent.HighlightBlock event ) public static void drawHighlight( DrawHighlightEvent.HighlightBlock event )
{ {
BlockRayTraceResult hit = event.getTarget(); BlockRayTraceResult hit = event.getTarget();
BlockPos pos = hit.getPos(); BlockPos pos = hit.getBlockPos();
World world = event.getInfo().getRenderViewEntity().getEntityWorld(); World world = event.getInfo().getEntity().getCommandSenderWorld();
ActiveRenderInfo info = event.getInfo(); ActiveRenderInfo info = event.getInfo();
BlockState state = world.getBlockState( pos ); BlockState state = world.getBlockState( pos );
// We only care about instances with both cable and modem. // 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; return;
} }
event.setCanceled( true ); 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.getModemShape( state )
: CableShapes.getCableShape( state ); : CableShapes.getCableShape( state );
Vector3d cameraPos = info.getProjectedView(); Vector3d cameraPos = info.getPosition();
double xOffset = pos.getX() - cameraPos.getX(); double xOffset = pos.getX() - cameraPos.x();
double yOffset = pos.getY() - cameraPos.getY(); double yOffset = pos.getY() - cameraPos.y();
double zOffset = pos.getZ() - cameraPos.getZ(); double zOffset = pos.getZ() - cameraPos.z();
IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.getLines() ); IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.lines() );
Matrix4f matrix4f = event.getMatrix().getLast().getMatrix(); Matrix4f matrix4f = event.getMatrix().last().pose();
shape.forEachEdge( ( x1, y1, z1, x2, y2, z2 ) -> { shape.forAllEdges( ( x1, y1, z1, x2, y2, z2 ) -> {
buffer.pos( matrix4f, (float) (x1 + xOffset), (float) (y1 + yOffset), (float) (z1 + zOffset) ) buffer.vertex( matrix4f, (float) (x1 + xOffset), (float) (y1 + yOffset), (float) (z1 + zOffset) )
.color( 0, 0, 0, 0.4f ).endVertex(); .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(); .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 ) public static void render( int x, int y, int z, int width, int height )
{ {
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEX ); buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEX );
render( IDENTITY, buffer, x, y, z, width, height ); render( IDENTITY, buffer, x, y, z, width, height );
RenderSystem.enableAlphaTest(); RenderSystem.enableAlphaTest();
tessellator.draw(); tessellator.end();
} }
public static void render( Matrix4f transform, IVertexBuilder buffer, int x, int y, int z, int width, int height ) 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 ) 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.vertex( transform, x, y + height, z ).color( r, g, b, 1.0f ).uv( 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.vertex( transform, x + width, y + height, z ).color( r, g, b, 1.0f ).uv( (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.vertex( transform, x + width, y, z ).color( r, g, b, 1.0f ).uv( (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, 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; PlayerEntity player = Minecraft.getInstance().player;
transform.push(); transform.pushPose();
if( hand == Hand.MAIN_HAND && player.getHeldItemOffhand().isEmpty() ) if( hand == Hand.MAIN_HAND && player.getOffhandItem().isEmpty() )
{ {
renderItemFirstPersonCenter( transform, render, lightTexture, pitch, equipProgress, swingProgress, stack ); renderItemFirstPersonCenter( transform, render, lightTexture, pitch, equipProgress, swingProgress, stack );
} }
@@ -42,11 +42,11 @@ public abstract class ItemMapLikeRenderer
{ {
renderItemFirstPersonSide( renderItemFirstPersonSide(
transform, render, lightTexture, transform, render, lightTexture,
hand == Hand.MAIN_HAND ? player.getPrimaryHand() : player.getPrimaryHand().opposite(), hand == Hand.MAIN_HAND ? player.getMainArm() : player.getMainArm().getOpposite(),
equipProgress, swingProgress, stack 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 the player is not invisible then render a single arm
if( !minecraft.player.isInvisible() ) if( !minecraft.player.isInvisible() )
{ {
transform.push(); transform.pushPose();
transform.rotate( Vector3f.ZP.rotationDegrees( offset * 10f ) ); transform.mulPose( Vector3f.ZP.rotationDegrees( offset * 10f ) );
minecraft.getFirstPersonRenderer().renderArmFirstPerson( transform, render, combinedLight, equipProgress, swingProgress, side ); minecraft.getItemInHandRenderer().renderPlayerArm( transform, render, combinedLight, equipProgress, swingProgress, side );
transform.pop(); transform.popPose();
} }
// Setup the appropriate transformations. This is just copied from the // Setup the appropriate transformations. This is just copied from the
// corresponding method in ItemRenderer. // corresponding method in ItemRenderer.
transform.push(); transform.pushPose();
transform.translate( offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f ); transform.translate( offset * 0.51f, -0.08f + equipProgress * -1.2f, -0.75f );
float f1 = MathHelper.sqrt( swingProgress ); float f1 = MathHelper.sqrt( swingProgress );
float f2 = MathHelper.sin( f1 * (float) Math.PI ); 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 f4 = 0.4f * MathHelper.sin( f1 * ((float) Math.PI * 2f) );
float f5 = -0.3f * MathHelper.sin( swingProgress * (float) Math.PI ); float f5 = -0.3f * MathHelper.sin( swingProgress * (float) Math.PI );
transform.translate( offset * f3, f4 - 0.3f * f2, f5 ); transform.translate( offset * f3, f4 - 0.3f * f2, f5 );
transform.rotate( Vector3f.XP.rotationDegrees( f2 * -45f ) ); transform.mulPose( Vector3f.XP.rotationDegrees( f2 * -45f ) );
transform.rotate( Vector3f.YP.rotationDegrees( offset * f2 * -30f ) ); transform.mulPose( Vector3f.YP.rotationDegrees( offset * f2 * -30f ) );
renderItem( transform, render, stack ); 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 ) private void renderItemFirstPersonCenter( MatrixStack transform, IRenderTypeBuffer render, int combinedLight, float pitch, float equipProgress, float swingProgress, ItemStack stack )
{ {
Minecraft minecraft = Minecraft.getInstance(); Minecraft minecraft = Minecraft.getInstance();
FirstPersonRenderer renderer = minecraft.getFirstPersonRenderer(); FirstPersonRenderer renderer = minecraft.getItemInHandRenderer();
// Setup the appropriate transformations. This is just copied from the // Setup the appropriate transformations. This is just copied from the
// corresponding method in ItemRenderer. // corresponding method in ItemRenderer.
@@ -118,20 +118,20 @@ public abstract class ItemMapLikeRenderer
float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI ); float tZ = -0.4f * MathHelper.sin( swingRt * (float) Math.PI );
transform.translate( 0, -tX / 2, tZ ); 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.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() ) if( !minecraft.player.isInvisible() )
{ {
transform.push(); transform.pushPose();
transform.rotate( Vector3f.YP.rotationDegrees( 90.0F ) ); transform.mulPose( Vector3f.YP.rotationDegrees( 90.0F ) );
renderer.renderArm( transform, render, combinedLight, HandSide.RIGHT ); renderer.renderMapHand( transform, render, combinedLight, HandSide.RIGHT );
renderer.renderArm( transform, render, combinedLight, HandSide.LEFT ); renderer.renderMapHand( transform, render, combinedLight, HandSide.LEFT );
transform.pop(); transform.popPose();
} }
float rX = MathHelper.sin( swingRt * (float) Math.PI ); 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 ); transform.scale( 2.0F, 2.0F, 2.0F );
renderItem( transform, render, stack ); 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 // Setup various transformations. Note that these are partially adapted from the corresponding method
// in ItemRenderer // in ItemRenderer
transform.push(); transform.pushPose();
transform.rotate( Vector3f.YP.rotationDegrees( 180f ) ); transform.mulPose( Vector3f.YP.rotationDegrees( 180f ) );
transform.rotate( Vector3f.ZP.rotationDegrees( 180f ) ); transform.mulPose( Vector3f.ZP.rotationDegrees( 180f ) );
transform.scale( 0.5f, 0.5f, 0.5f ); transform.scale( 0.5f, 0.5f, 0.5f );
float scale = 0.75f / Math.max( width + BORDER * 2, height + BORDER * 2 + LIGHT_HEIGHT ); 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(); ComputerFamily family = item.getFamily();
int frameColour = item.getColour( stack ); int frameColour = item.getColour( stack );
Matrix4f matrix = transform.getLast().getMatrix(); Matrix4f matrix = transform.last().pose();
renderFrame( matrix, family, frameColour, width, height ); renderFrame( matrix, family, frameColour, width, height );
// Render the light // Render the light
@@ -114,26 +114,26 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
FixedWidthFontRenderer.drawEmptyTerminal( matrix, 0, 0, width, height ); 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 ) private static void renderFrame( Matrix4f transform, ComputerFamily family, int colour, int width, int height )
{ {
RenderSystem.enableBlend(); RenderSystem.enableBlend();
Minecraft.getInstance().getTextureManager() 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 r = ((colour >>> 16) & 0xFF) / 255.0f;
float g = ((colour >>> 8) & 0xFF) / 255.0f; float g = ((colour >>> 8) & 0xFF) / 255.0f;
float b = (colour & 0xFF) / 255.0f; float b = (colour & 0xFF) / 255.0f;
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEX ); buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEX );
ComputerBorderRenderer.render( transform, buffer, 0, 0, 0, width, height, LIGHT_HEIGHT, r, g, b ); 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 ) 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; float b = (colour & 0xFF) / 255.0f;
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR ); 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.vertex( 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.vertex( 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.vertex( 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 + BORDER / 2.0f, 0 ).color( r, g, b, 1.0f ).endVertex();
tessellator.draw(); tessellator.end();
RenderSystem.enableTexture(); RenderSystem.enableTexture();
} }
} }

View File

@@ -52,7 +52,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
@Override @Override
protected void renderItem( MatrixStack transform, IRenderTypeBuffer render, ItemStack stack ) 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.scale( 0.42f, 0.42f, -0.42f );
transform.translate( -0.5f, -0.48f, 0.0f ); 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 // Move a little bit forward to ensure we're not clipping with the frame
transform.translate( 0.0f, 0.0f, -0.001f ); 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.scale( 0.95f, 0.95f, -0.95f );
transform.translate( -0.5f, -0.5f, 0.0f ); transform.translate( -0.5f, -0.5f, 0.0f );
@@ -104,7 +104,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
transform.scale( scale, scale, scale ); transform.scale( scale, scale, scale );
transform.translate( (max - width) / 2.0, (max - height) / 2.0, 0.0 ); 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 ); drawBorder( matrix, render, 0, 0, -0.01f, 0, pages, book );
drawText( matrix, render, drawText( matrix, render,
X_TEXT_MARGIN, Y_TEXT_MARGIN, 0, ItemPrintout.getText( stack ), ItemPrintout.getColours( stack ) 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 ) public static void drawHighlight( DrawHighlightEvent.HighlightBlock event )
{ {
// Preserve normal behaviour when crouching. // Preserve normal behaviour when crouching.
if( event.getInfo().getRenderViewEntity().isCrouching() ) return; if( event.getInfo().getEntity().isCrouching() ) return;
World world = event.getInfo().getRenderViewEntity().getEntityWorld(); World world = event.getInfo().getEntity().getCommandSenderWorld();
BlockPos pos = event.getTarget().getPos(); BlockPos pos = event.getTarget().getBlockPos();
TileEntity tile = world.getTileEntity( pos ); TileEntity tile = world.getBlockEntity( pos );
if( !(tile instanceof TileMonitor) ) return; if( !(tile instanceof TileMonitor) ) return;
TileMonitor monitor = (TileMonitor) tile; TileMonitor monitor = (TileMonitor) tile;
@@ -61,13 +61,13 @@ public final class MonitorHighlightRenderer
if( monitor.getYIndex() != monitor.getHeight() - 1 ) faces.remove( monitor.getDown() ); if( monitor.getYIndex() != monitor.getHeight() - 1 ) faces.remove( monitor.getDown() );
MatrixStack transformStack = event.getMatrix(); MatrixStack transformStack = event.getMatrix();
Vector3d cameraPos = event.getInfo().getProjectedView(); Vector3d cameraPos = event.getInfo().getPosition();
transformStack.push(); transformStack.pushPose();
transformStack.translate( pos.getX() - cameraPos.getX(), pos.getY() - cameraPos.getY(), pos.getZ() - cameraPos.getZ() ); 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 // I wish I could think of a better way to do this
IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.getLines() ); IVertexBuilder buffer = event.getBuffers().getBuffer( RenderType.lines() );
Matrix4f transform = transformStack.getLast().getMatrix(); Matrix4f transform = transformStack.last().pose();
if( faces.contains( NORTH ) || faces.contains( WEST ) ) line( buffer, transform, 0, 0, 0, UP ); 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( 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 ); 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( 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 ); 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 ) 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.vertex( transform, x, y, z ).color( 0, 0, 0, 0.4f ).endVertex();
buffer.pos( transform, buffer.vertex( transform,
x + direction.getXOffset(), x + direction.getStepX(),
y + direction.getYOffset(), y + direction.getStepY(),
z + direction.getZOffset() z + direction.getStepZ()
).color( 0, 0, 0, 0.4f ).endVertex(); ).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 ) static void setupUniform( Matrix4f transform, int width, int height, Palette palette, boolean greyscale )
{ {
MATRIX_BUFFER.rewind(); MATRIX_BUFFER.rewind();
transform.write( MATRIX_BUFFER ); transform.store( MATRIX_BUFFER );
MATRIX_BUFFER.rewind(); MATRIX_BUFFER.rewind();
RenderSystem.glUniformMatrix4( uniformMv, false, MATRIX_BUFFER ); RenderSystem.glUniformMatrix4( uniformMv, false, MATRIX_BUFFER );
@@ -71,7 +71,7 @@ class MonitorTextureBufferShader
{ {
if( initialised ) if( initialised )
{ {
if( ok ) GlStateManager.useProgram( program ); if( ok ) GlStateManager._glUseProgram( program );
return ok; return ok;
} }
@@ -94,14 +94,14 @@ class MonitorTextureBufferShader
int vertexShader = loadShader( GL20.GL_VERTEX_SHADER, "assets/computercraft/shaders/monitor.vert" ); int vertexShader = loadShader( GL20.GL_VERTEX_SHADER, "assets/computercraft/shaders/monitor.vert" );
int fragmentShader = loadShader( GL20.GL_FRAGMENT_SHADER, "assets/computercraft/shaders/monitor.frag" ); int fragmentShader = loadShader( GL20.GL_FRAGMENT_SHADER, "assets/computercraft/shaders/monitor.frag" );
program = GlStateManager.createProgram(); program = GlStateManager.glCreateProgram();
GlStateManager.attachShader( program, vertexShader ); GlStateManager.glAttachShader( program, vertexShader );
GlStateManager.attachShader( program, fragmentShader ); GlStateManager.glAttachShader( program, fragmentShader );
GL20.glBindAttribLocation( program, 0, "v_pos" ); GL20.glBindAttribLocation( program, 0, "v_pos" );
GlStateManager.linkProgram( program ); GlStateManager.glLinkProgram( program );
boolean ok = GlStateManager.getProgram( program, GL20.GL_LINK_STATUS ) != 0; boolean ok = GlStateManager.glGetProgrami( program, GL20.GL_LINK_STATUS ) != 0;
String log = GlStateManager.getProgramInfoLog( program, Short.MAX_VALUE ).trim(); String log = GlStateManager.glGetProgramInfoLog( program, Short.MAX_VALUE ).trim();
if( !Strings.isNullOrEmpty( log ) ) if( !Strings.isNullOrEmpty( log ) )
{ {
ComputerCraft.log.warn( "Problems when linking monitor shader: {}", log ); ComputerCraft.log.warn( "Problems when linking monitor shader: {}", log );
@@ -109,8 +109,8 @@ class MonitorTextureBufferShader
GL20.glDetachShader( program, vertexShader ); GL20.glDetachShader( program, vertexShader );
GL20.glDetachShader( program, fragmentShader ); GL20.glDetachShader( program, fragmentShader );
GlStateManager.deleteShader( vertexShader ); GlStateManager.glDeleteShader( vertexShader );
GlStateManager.deleteShader( fragmentShader ); GlStateManager.glDeleteShader( fragmentShader );
if( !ok ) return false; if( !ok ) return false;
@@ -137,13 +137,13 @@ class MonitorTextureBufferShader
if( stream == null ) throw new IllegalArgumentException( "Cannot find " + path ); if( stream == null ) throw new IllegalArgumentException( "Cannot find " + path );
String contents = TextureUtil.readResourceAsString( stream ); String contents = TextureUtil.readResourceAsString( stream );
int shader = GlStateManager.createShader( kind ); int shader = GlStateManager.glCreateShader( kind );
GlStateManager.shaderSource( shader, contents ); GlStateManager.glShaderSource( shader, contents );
GlStateManager.compileShader( shader ); GlStateManager.glCompileShader( shader );
boolean ok = GlStateManager.getShader( shader, GL20.GL_COMPILE_STATUS ) != 0; boolean ok = GlStateManager.glGetShaderi( shader, GL20.GL_COMPILE_STATUS ) != 0;
String log = GlStateManager.getShaderInfoLog( shader, Short.MAX_VALUE ).trim(); String log = GlStateManager.glGetShaderInfoLog( shader, Short.MAX_VALUE ).trim();
if( !Strings.isNullOrEmpty( log ) ) if( !Strings.isNullOrEmpty( log ) )
{ {
ComputerCraft.log.warn( "Problems when loading monitor shader {}: {}", path, 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 ) 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 ); if( uniform == -1 ) throw new IllegalStateException( "Cannot find uniform " + name );
return uniform; 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 ) 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.vertex( matrix, x, y + height, z ).uv( 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.vertex( matrix, x + width, y + height, z ).uv( (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.vertex( matrix, x + width, y, z ).uv( (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, 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 ) 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.vertex( matrix, x, y + height, z ).uv( 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.vertex( matrix, x + width, y + height, z ).uv( (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.vertex( matrix, x + width, y, z ).uv( (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, z ).uv( u / BG_SIZE, v / BG_SIZE ).endVertex();
} }
public static float offsetAt( int page ) public static float offsetAt( int page )
@@ -167,14 +167,14 @@ public final class PrintoutRenderer
private static final class Type extends RenderState 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, "printout_background", DefaultVertexFormats.POSITION_TEX, GL11.GL_QUADS, 1024,
false, false, // useDelegate, needsSorting false, false, // useDelegate, needsSorting
RenderType.State.getBuilder() RenderType.State.builder()
.texture( new RenderState.TextureState( BG, false, false ) ) // blur, minimap .setTextureState( new RenderState.TextureState( BG, false, false ) ) // blur, minimap
.alpha( DEFAULT_ALPHA ) .setAlphaState( DEFAULT_ALPHA )
.lightmap( LIGHTMAP_DISABLED ) .setLightmapState( NO_LIGHTMAP )
.build( false ) .createCompositeState( false )
); );
private Type( String name, Runnable setup, Runnable destroy ) private Type( String name, Runnable setup, Runnable destroy )

View File

@@ -61,7 +61,7 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
if( originTerminal == null ) return; if( originTerminal == null ) return;
TileMonitor origin = originTerminal.getOrigin(); 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 // 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 // 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.lastRenderFrame = renderFrame;
originTerminal.lastRenderPos = monitorPos; originTerminal.lastRenderPos = monitorPos;
BlockPos originPos = origin.getPos(); BlockPos originPos = origin.getBlockPos();
// Determine orientation // Determine orientation
Direction dir = origin.getDirection(); Direction dir = origin.getDirection();
Direction front = origin.getFront(); Direction front = origin.getFront();
float yaw = dir.getHorizontalAngle(); float yaw = dir.toYRot();
float pitch = DirectionUtil.toPitchAngle( front ); float pitch = DirectionUtil.toPitchAngle( front );
// Setup initial transform // Setup initial transform
transform.push(); transform.pushPose();
transform.translate( transform.translate(
originPos.getX() - monitorPos.getX() + 0.5, originPos.getX() - monitorPos.getX() + 0.5,
originPos.getY() - monitorPos.getY() + 0.5, originPos.getY() - monitorPos.getY() + 0.5,
originPos.getZ() - monitorPos.getZ() + 0.5 originPos.getZ() - monitorPos.getZ() + 0.5
); );
transform.rotate( Vector3f.YN.rotationDegrees( yaw ) ); transform.mulPose( Vector3f.YN.rotationDegrees( yaw ) );
transform.rotate( Vector3f.XP.rotationDegrees( pitch ) ); transform.mulPose( Vector3f.XP.rotationDegrees( pitch ) );
transform.translate( transform.translate(
-0.5 + TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN, -0.5 + TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN,
origin.getHeight() - 0.5 - (TileMonitor.RENDER_BORDER + TileMonitor.RENDER_MARGIN) + 0, 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; int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT;
double xScale = xSize / pixelWidth; double xScale = xSize / pixelWidth;
double yScale = ySize / pixelHeight; double yScale = ySize / pixelHeight;
transform.push(); transform.pushPose();
transform.scale( (float) xScale, (float) -yScale, 1.0f ); 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 // 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 // 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. // reasonable.
FixedWidthFontRenderer.drawCursor( matrix, buffer, 0, 0, terminal, !originTerminal.isColour() ); FixedWidthFontRenderer.drawCursor( matrix, buffer, 0, 0, terminal, !originTerminal.isColour() );
transform.pop(); transform.popPose();
} }
else else
{ {
FixedWidthFontRenderer.drawEmptyTerminal( FixedWidthFontRenderer.drawEmptyTerminal(
transform.getLast().getMatrix(), renderer, transform.last().pose(), renderer,
-MARGIN, MARGIN, -MARGIN, MARGIN,
(float) (xSize + 2 * MARGIN), (float) -(ySize + MARGIN * 2) (float) (xSize + 2 * MARGIN), (float) -(ySize + MARGIN * 2)
); );
} }
FixedWidthFontRenderer.drawBlocker( FixedWidthFontRenderer.drawBlocker(
transform.getLast().getMatrix(), renderer, transform.last().pose(), renderer,
(float) -TileMonitor.RENDER_MARGIN, (float) TileMonitor.RENDER_MARGIN, (float) -TileMonitor.RENDER_MARGIN, (float) TileMonitor.RENDER_MARGIN,
(float) (xSize + 2 * TileMonitor.RENDER_MARGIN), (float) -(ySize + TileMonitor.RENDER_MARGIN * 2) (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 // 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! // 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 ) 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; int size = width * height * 3;
if( tboContents == null || tboContents.capacity() < size ) if( tboContents == null || tboContents.capacity() < size )
{ {
tboContents = GLAllocation.createDirectByteBuffer( size ); tboContents = GLAllocation.createByteBuffer( size );
} }
ByteBuffer monitorBuffer = tboContents; ByteBuffer monitorBuffer = tboContents;
@@ -190,28 +190,28 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
} }
monitorBuffer.flip(); monitorBuffer.flip();
GlStateManager.bindBuffer( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer ); GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer );
GlStateManager.bufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW ); GlStateManager._glBufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW );
GlStateManager.bindBuffer( GL31.GL_TEXTURE_BUFFER, 0 ); GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
} }
// Nobody knows what they're doing! // Nobody knows what they're doing!
GlStateManager.activeTexture( MonitorTextureBufferShader.TEXTURE_INDEX ); GlStateManager._activeTexture( MonitorTextureBufferShader.TEXTURE_INDEX );
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, monitor.tboTexture ); 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() ); MonitorTextureBufferShader.setupUniform( matrix, width, height, terminal.getPalette(), !monitor.isColour() );
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuilder();
buffer.begin( GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION ); buffer.begin( GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION );
buffer.pos( -xMargin, -yMargin, 0 ).endVertex(); buffer.vertex( -xMargin, -yMargin, 0 ).endVertex();
buffer.pos( -xMargin, pixelHeight + yMargin, 0 ).endVertex(); buffer.vertex( -xMargin, pixelHeight + yMargin, 0 ).endVertex();
buffer.pos( pixelWidth + xMargin, -yMargin, 0 ).endVertex(); buffer.vertex( pixelWidth + xMargin, -yMargin, 0 ).endVertex();
buffer.pos( pixelWidth + xMargin, pixelHeight + yMargin, 0 ).endVertex(); buffer.vertex( pixelWidth + xMargin, pixelHeight + yMargin, 0 ).endVertex();
tessellator.draw(); tessellator.end();
GlStateManager.useProgram( 0 ); GlStateManager._glUseProgram( 0 );
break; break;
} }
@@ -221,22 +221,22 @@ public class TileEntityMonitorRenderer extends TileEntityRenderer<TileMonitor>
if( redraw ) if( redraw )
{ {
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder builder = tessellator.getBuffer(); BufferBuilder builder = tessellator.getBuilder();
builder.begin( FixedWidthFontRenderer.TYPE.getDrawMode(), FixedWidthFontRenderer.TYPE.getVertexFormat() ); builder.begin( FixedWidthFontRenderer.TYPE.mode(), FixedWidthFontRenderer.TYPE.format() );
FixedWidthFontRenderer.drawTerminalWithoutCursor( FixedWidthFontRenderer.drawTerminalWithoutCursor(
IDENTITY, builder, 0, 0, IDENTITY, builder, 0, 0,
terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin terminal, !monitor.isColour(), yMargin, yMargin, xMargin, xMargin
); );
builder.finishDrawing(); builder.end();
vbo.upload( builder ); vbo.upload( builder );
} }
vbo.bindBuffer(); vbo.bind();
FixedWidthFontRenderer.TYPE.getVertexFormat().setupBufferState( 0L ); FixedWidthFontRenderer.TYPE.format().setupBufferState( 0L );
vbo.draw( matrix, FixedWidthFontRenderer.TYPE.getDrawMode() ); vbo.draw( matrix, FixedWidthFontRenderer.TYPE.mode() );
VertexBuffer.unbindBuffer(); VertexBuffer.unbind();
FixedWidthFontRenderer.TYPE.getVertexFormat().clearBufferState(); FixedWidthFontRenderer.TYPE.format().clearBufferState();
break; break;
} }
} }

View File

@@ -72,31 +72,31 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
} }
@Override @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 // Render the label
String label = turtle.createProxy().getLabel(); String label = turtle.createProxy().getLabel();
RayTraceResult hit = renderDispatcher.cameraHitResult; RayTraceResult hit = renderer.cameraHitResult;
if( label != null && hit.getType() == RayTraceResult.Type.BLOCK && turtle.getPos().equals( ((BlockRayTraceResult) hit).getPos() ) ) if( label != null && hit.getType() == RayTraceResult.Type.BLOCK && turtle.getBlockPos().equals( ((BlockRayTraceResult) hit).getBlockPos() ) )
{ {
Minecraft mc = Minecraft.getInstance(); 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.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 ); transform.scale( -0.025f, -0.025f, 0.025f );
Matrix4f matrix = transform.getLast().getMatrix(); Matrix4f matrix = transform.last().pose();
int opacity = (int) (mc.gameSettings.getTextBackgroundOpacity( 0.25f ) * 255) << 24; int opacity = (int) (mc.options.getBackgroundOpacity( 0.25f ) * 255) << 24;
float width = -font.getStringWidth( label ) / 2.0f; float width = -font.width( label ) / 2.0f;
font.renderString( label, width, (float) 0, 0x20ffffff, false, matrix, renderer, true, opacity, lightmapCoord ); font.drawInBatch( label, width, (float) 0, 0x20ffffff, false, matrix, buffers, true, opacity, lightmapCoord );
font.renderString( label, width, (float) 0, 0xffffffff, false, matrix, renderer, false, 0, 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. // Setup the transform.
Vector3d offset = turtle.getRenderOffset( partialTicks ); 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( offset.x, offset.y, offset.z );
transform.translate( 0.5f, 0.5f, 0.5f ); 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" )) ) if( label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" )) )
{ {
// Flip the model // Flip the model
@@ -117,7 +117,7 @@ public class TileEntityTurtleRenderer extends TileEntityRenderer<TileTurtle>
ComputerFamily family = turtle.getFamily(); ComputerFamily family = turtle.getFamily();
ResourceLocation overlay = turtle.getOverlay(); 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 } ); renderModel( transform, buffer, lightmapCoord, overlayLight, getTurtleModel( family, colour != -1 ), colour == -1 ? null : new int[] { colour } );
// Render the overlay // 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.LEFT, partialTicks );
renderUpgrade( transform, buffer, lightmapCoord, overlayLight, turtle, TurtleSide.RIGHT, 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 ) private void renderUpgrade( @Nonnull MatrixStack transform, @Nonnull IVertexBuilder renderer, int lightmapCoord, int overlayLight, TileTurtle turtle, TurtleSide side, float f )
{ {
ITurtleUpgrade upgrade = turtle.getUpgrade( side ); ITurtleUpgrade upgrade = turtle.getUpgrade( side );
if( upgrade == null ) return; if( upgrade == null ) return;
transform.push(); transform.pushPose();
float toolAngle = turtle.getToolRenderAngle( side, f ); float toolAngle = turtle.getToolRenderAngle( side, f );
transform.translate( 0.0f, 0.5f, 0.5f ); 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 ); transform.translate( 0.0f, -0.5f, -0.5f );
TransformedModel model = upgrade.getModel( turtle.getAccess(), side ); TransformedModel model = upgrade.getModel( turtle.getAccess(), side );
model.getMatrix().push( transform ); model.getMatrix().push( transform );
renderModel( transform, renderer, lightmapCoord, overlayLight, model.getModel(), null ); 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 ) 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 ); 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 ) 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 ) for( BakedQuad bakedquad : quads )
{ {
int tint = -1; int tint = -1;
if( tints != null && bakedquad.hasTintIndex() ) if( tints != null && bakedquad.isTinted() )
{ {
int idx = bakedquad.getTintIndex(); int idx = bakedquad.getTintIndex();
if( idx >= 0 && idx < tints.length ) tint = tints[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 @Override
public TurtleModel read( @Nonnull JsonDeserializationContext deserializationContext, @Nonnull JsonObject modelContents ) 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 ); 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 ) public Collection<RenderMaterial> getTextures( IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors )
{ {
Set<RenderMaterial> materials = new HashSet<>(); Set<RenderMaterial> materials = new HashSet<>();
materials.addAll( modelGetter.apply( family ).getTextures( modelGetter, missingTextureErrors ) ); materials.addAll( modelGetter.apply( family ).getMaterials( modelGetter, missingTextureErrors ) );
materials.addAll( modelGetter.apply( COLOUR_TURTLE_MODEL ).getTextures( modelGetter, missingTextureErrors ) ); materials.addAll( modelGetter.apply( COLOUR_TURTLE_MODEL ).getMaterials( modelGetter, missingTextureErrors ) );
return materials; return materials;
} }

View File

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

View File

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

View File

@@ -42,26 +42,26 @@ public class TurtleSmartItemModel implements IBakedModel
stack.translate( 0, 0, 1 ); stack.translate( 0, 0, 1 );
identity = TransformationMatrix.identity(); identity = TransformationMatrix.identity();
flip = new TransformationMatrix( stack.getLast().getMatrix() ); flip = new TransformationMatrix( stack.last().pose() );
} }
private static class TurtleModelCombination private static class TurtleModelCombination
{ {
final boolean m_colour; final boolean colour;
final ITurtleUpgrade m_leftUpgrade; final ITurtleUpgrade leftUpgrade;
final ITurtleUpgrade m_rightUpgrade; final ITurtleUpgrade rightUpgrade;
final ResourceLocation m_overlay; final ResourceLocation overlay;
final boolean m_christmas; final boolean christmas;
final boolean m_flip; final boolean flip;
TurtleModelCombination( boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, ResourceLocation overlay, boolean christmas, boolean flip ) TurtleModelCombination( boolean colour, ITurtleUpgrade leftUpgrade, ITurtleUpgrade rightUpgrade, ResourceLocation overlay, boolean christmas, boolean flip )
{ {
m_colour = colour; this.colour = colour;
m_leftUpgrade = leftUpgrade; this.leftUpgrade = leftUpgrade;
m_rightUpgrade = rightUpgrade; this.rightUpgrade = rightUpgrade;
m_overlay = overlay; this.overlay = overlay;
m_christmas = christmas; this.christmas = christmas;
m_flip = flip; this.flip = flip;
} }
@Override @Override
@@ -71,12 +71,12 @@ public class TurtleSmartItemModel implements IBakedModel
if( !(other instanceof TurtleModelCombination) ) return false; if( !(other instanceof TurtleModelCombination) ) return false;
TurtleModelCombination otherCombo = (TurtleModelCombination) other; TurtleModelCombination otherCombo = (TurtleModelCombination) other;
return otherCombo.m_colour == m_colour && return otherCombo.colour == colour &&
otherCombo.m_leftUpgrade == m_leftUpgrade && otherCombo.leftUpgrade == leftUpgrade &&
otherCombo.m_rightUpgrade == m_rightUpgrade && otherCombo.rightUpgrade == rightUpgrade &&
Objects.equal( otherCombo.m_overlay, m_overlay ) && Objects.equal( otherCombo.overlay, overlay ) &&
otherCombo.m_christmas == m_christmas && otherCombo.christmas == christmas &&
otherCombo.m_flip == m_flip; otherCombo.flip == flip;
} }
@Override @Override
@@ -84,12 +84,12 @@ public class TurtleSmartItemModel implements IBakedModel
{ {
final int prime = 31; final int prime = 31;
int result = 0; int result = 0;
result = prime * result + (m_colour ? 1 : 0); result = prime * result + (colour ? 1 : 0);
result = prime * result + (m_leftUpgrade != null ? m_leftUpgrade.hashCode() : 0); result = prime * result + (leftUpgrade != null ? leftUpgrade.hashCode() : 0);
result = prime * result + (m_rightUpgrade != null ? m_rightUpgrade.hashCode() : 0); result = prime * result + (rightUpgrade != null ? rightUpgrade.hashCode() : 0);
result = prime * result + (m_overlay != null ? m_overlay.hashCode() : 0); result = prime * result + (overlay != null ? overlay.hashCode() : 0);
result = prime * result + (m_christmas ? 1 : 0); result = prime * result + (christmas ? 1 : 0);
result = prime * result + (m_flip ? 1 : 0); result = prime * result + (flip ? 1 : 0);
return result; return result;
} }
} }
@@ -97,19 +97,19 @@ public class TurtleSmartItemModel implements IBakedModel
private final IBakedModel familyModel; private final IBakedModel familyModel;
private final IBakedModel colourModel; private final IBakedModel colourModel;
private final HashMap<TurtleModelCombination, IBakedModel> m_cachedModels = new HashMap<>(); private final HashMap<TurtleModelCombination, IBakedModel> cachedModels = new HashMap<>();
private final ItemOverrideList m_overrides; private final ItemOverrideList overrides;
public TurtleSmartItemModel( IBakedModel familyModel, IBakedModel colourModel ) public TurtleSmartItemModel( IBakedModel familyModel, IBakedModel colourModel )
{ {
this.familyModel = familyModel; this.familyModel = familyModel;
this.colourModel = colourModel; this.colourModel = colourModel;
m_overrides = new ItemOverrideList() overrides = new ItemOverrideList()
{ {
@Nonnull @Nonnull
@Override @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(); ItemTurtle turtle = (ItemTurtle) stack.getItem();
int colour = turtle.getColour( stack ); int colour = turtle.getColour( stack );
@@ -121,8 +121,8 @@ public class TurtleSmartItemModel implements IBakedModel
boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" )); boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" ));
TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip ); TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip );
IBakedModel model = m_cachedModels.get( combo ); IBakedModel model = cachedModels.get( combo );
if( model == null ) m_cachedModels.put( combo, model = buildModel( combo ) ); if( model == null ) cachedModels.put( combo, model = buildModel( combo ) );
return model; return model;
} }
}; };
@@ -132,20 +132,20 @@ public class TurtleSmartItemModel implements IBakedModel
@Override @Override
public ItemOverrideList getOverrides() public ItemOverrideList getOverrides()
{ {
return m_overrides; return overrides;
} }
private IBakedModel buildModel( TurtleModelCombination combo ) private IBakedModel buildModel( TurtleModelCombination combo )
{ {
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
ModelManager modelManager = mc.getItemRenderer().getItemModelMesher().getModelManager(); ModelManager modelManager = mc.getItemRenderer().getItemModelShaper().getModelManager();
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.m_overlay, combo.m_christmas ); 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; IBakedModel overlayModel = overlayModelLocation != null ? modelManager.getModel( overlayModelLocation ) : null;
TransformationMatrix transform = combo.m_flip ? flip : identity; TransformationMatrix transform = combo.flip ? flip : identity;
TransformedModel leftModel = combo.m_leftUpgrade != null ? combo.m_leftUpgrade.getModel( null, TurtleSide.LEFT ) : null; TransformedModel leftModel = combo.leftUpgrade != null ? combo.leftUpgrade.getModel( null, TurtleSide.LEFT ) : null;
TransformedModel rightModel = combo.m_rightUpgrade != null ? combo.m_rightUpgrade.getModel( null, TurtleSide.RIGHT ) : null; TransformedModel rightModel = combo.rightUpgrade != null ? combo.rightUpgrade.getModel( null, TurtleSide.RIGHT ) : null;
return new TurtleMultiModel( baseModel, overlayModel, transform, leftModel, rightModel ); return new TurtleMultiModel( baseModel, overlayModel, transform, leftModel, rightModel );
} }
@@ -166,9 +166,9 @@ public class TurtleSmartItemModel implements IBakedModel
} }
@Override @Override
public boolean isAmbientOcclusion() public boolean useAmbientOcclusion()
{ {
return familyModel.isAmbientOcclusion(); return familyModel.useAmbientOcclusion();
} }
@Override @Override
@@ -178,31 +178,31 @@ public class TurtleSmartItemModel implements IBakedModel
} }
@Override @Override
public boolean isBuiltInRenderer() public boolean isCustomRenderer()
{ {
return familyModel.isBuiltInRenderer(); return familyModel.isCustomRenderer();
} }
@Override @Override
public boolean isSideLit() public boolean usesBlockLight()
{ {
return familyModel.isSideLit(); return familyModel.usesBlockLight();
} }
@Nonnull @Nonnull
@Override @Override
@Deprecated @Deprecated
public TextureAtlasSprite getParticleTexture() public TextureAtlasSprite getParticleIcon()
{ {
return familyModel.getParticleTexture(); return familyModel.getParticleIcon();
} }
@Nonnull @Nonnull
@Override @Override
@Deprecated @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 public abstract class ComputerAccess implements IComputerAccess
{ {
private final IAPIEnvironment m_environment; private final IAPIEnvironment environment;
private final Set<String> m_mounts = new HashSet<>(); private final Set<String> mounts = new HashSet<>();
protected ComputerAccess( IAPIEnvironment environment ) protected ComputerAccess( IAPIEnvironment environment )
{ {
this.m_environment = environment; this.environment = environment;
} }
public void unmountAll() public void unmountAll()
{ {
FileSystem fileSystem = m_environment.getFileSystem(); FileSystem fileSystem = environment.getFileSystem();
for( String mount : m_mounts ) for( String mount : mounts )
{ {
fileSystem.unmount( mount ); fileSystem.unmount( mount );
} }
m_mounts.clear(); mounts.clear();
} }
@Override @Override
@@ -46,7 +46,7 @@ public abstract class ComputerAccess implements IComputerAccess
// Mount the location // Mount the location
String location; String location;
FileSystem fileSystem = m_environment.getFileSystem(); FileSystem fileSystem = environment.getFileSystem();
if( fileSystem == null ) throw new IllegalStateException( "File system has not been created" ); if( fileSystem == null ) throw new IllegalStateException( "File system has not been created" );
synchronized( fileSystem ) 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; return location;
} }
@@ -77,7 +77,7 @@ public abstract class ComputerAccess implements IComputerAccess
// Mount the location // Mount the location
String location; String location;
FileSystem fileSystem = m_environment.getFileSystem(); FileSystem fileSystem = environment.getFileSystem();
if( fileSystem == null ) throw new IllegalStateException( "File system has not been created" ); if( fileSystem == null ) throw new IllegalStateException( "File system has not been created" );
synchronized( fileSystem ) 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; return location;
} }
@@ -103,37 +103,37 @@ public abstract class ComputerAccess implements IComputerAccess
public void unmount( String location ) public void unmount( String location )
{ {
if( location == null ) return; 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 ); environment.getFileSystem().unmount( location );
m_mounts.remove( location ); mounts.remove( location );
} }
@Override @Override
public int getID() public int getID()
{ {
return m_environment.getComputerID(); return environment.getComputerID();
} }
@Override @Override
public void queueEvent( @Nonnull String event, Object... arguments ) public void queueEvent( @Nonnull String event, Object... arguments )
{ {
Objects.requireNonNull( event, "event cannot be null" ); Objects.requireNonNull( event, "event cannot be null" );
m_environment.queueEvent( event, arguments ); environment.queueEvent( event, arguments );
} }
@Nonnull @Nonnull
@Override @Override
public IWorkMonitor getMainThreadMonitor() public IWorkMonitor getMainThreadMonitor()
{ {
return m_environment.getMainThreadMonitor(); return environment.getMainThreadMonitor();
} }
private String findFreeLocation( String desiredLoc ) private String findFreeLocation( String desiredLoc )
{ {
try try
{ {
FileSystem fileSystem = m_environment.getFileSystem(); FileSystem fileSystem = environment.getFileSystem();
if( !fileSystem.exists( desiredLoc ) ) return desiredLoc; if( !fileSystem.exists( desiredLoc ) ) return desiredLoc;
// We used to check foo2, foo3, foo4, etc here but the disk drive does this itself now // 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. * @param arguments The paths to combine.
* @return The new path, with separators added between parts as needed. * @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 path The first part of the path. For example, a parent directory path.
* @cc.tparam string ... Additional parts of the path to combine. * @cc.tparam string ... Additional parts of the path to combine.
* @throws LuaException On argument errors.
*/ */
@LuaFunction @LuaFunction
public final String combine( IArguments arguments ) throws LuaException 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. * 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 * The returned attributes table contains information about the size of the file, whether it is a directory,
* when it was created and last modified. * 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 * 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. * 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. * @param path The path to get attributes for.
* @return The resulting attributes. * @return The resulting attributes.
* @throws LuaException If the path does not exist. * @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 #getSize If you only care about the file's size.
* @see #isDir If you only care whether a path is a directory or not. * @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( "created", getFileTime( attributes.creationTime() ) );
result.put( "size", attributes.isDirectory() ? 0 : attributes.size() ); result.put( "size", attributes.isDirectory() ? 0 : attributes.size() );
result.put( "isDir", attributes.isDirectory() ); result.put( "isDir", attributes.isDirectory() );
result.put( "isReadOnly", fileSystem.isReadOnly( path ) );
return result; return result;
} }
catch( FileSystemException e ) 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.request.HttpRequest;
import dan200.computercraft.core.apis.http.websocket.Websocket; import dan200.computercraft.core.apis.http.websocket.Websocket;
import io.netty.handler.codec.http.DefaultHttpHeaders; 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.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpMethod;
@@ -34,7 +35,7 @@ import static dan200.computercraft.core.apis.TableHelper.*;
*/ */
public class HTTPAPI implements ILuaAPI public class HTTPAPI implements ILuaAPI
{ {
private final IAPIEnvironment m_apiEnvironment; private final IAPIEnvironment apiEnvironment;
private final ResourceGroup<CheckUrl> checkUrls = new ResourceGroup<>(); private final ResourceGroup<CheckUrl> checkUrls = new ResourceGroup<>();
private final ResourceGroup<HttpRequest> requests = new ResourceQueue<>( () -> ComputerCraft.httpMaxRequests ); private final ResourceGroup<HttpRequest> requests = new ResourceQueue<>( () -> ComputerCraft.httpMaxRequests );
@@ -42,7 +43,7 @@ public class HTTPAPI implements ILuaAPI
public HTTPAPI( IAPIEnvironment environment ) public HTTPAPI( IAPIEnvironment environment )
{ {
m_apiEnvironment = environment; apiEnvironment = environment;
} }
@Override @Override
@@ -123,7 +124,7 @@ public class HTTPAPI implements ILuaAPI
try try
{ {
URI uri = HttpRequest.checkUri( address ); 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 // Make the request
request.queue( r -> r.request( uri, httpMethod ) ); request.queue( r -> r.request( uri, httpMethod ) );
@@ -142,7 +143,7 @@ public class HTTPAPI implements ILuaAPI
try try
{ {
URI uri = HttpRequest.checkUri( address ); 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 }; return new Object[] { true };
} }
@@ -165,7 +166,7 @@ public class HTTPAPI implements ILuaAPI
try try
{ {
URI uri = Websocket.checkUri( address ); 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" ); throw new LuaException( "Too many websockets already open" );
} }
@@ -179,7 +180,7 @@ public class HTTPAPI implements ILuaAPI
} }
@Nonnull @Nonnull
private static HttpHeaders getHeaders( @Nonnull Map<?, ?> headerTable ) throws LuaException private HttpHeaders getHeaders( @Nonnull Map<?, ?> headerTable ) throws LuaException
{ {
HttpHeaders headers = new DefaultHttpHeaders(); HttpHeaders headers = new DefaultHttpHeaders();
for( Map.Entry<?, ?> entry : headerTable.entrySet() ) 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; return headers;
} }
} }

View File

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

View File

@@ -191,7 +191,7 @@ public class RedstoneAPI implements ILuaAPI
@LuaFunction @LuaFunction
public final int getBundledInput( ComputerSide side ) 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.LuaException;
import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
@@ -32,14 +32,14 @@ public class BinaryReadableHandle extends HandleGeneric
final SeekableByteChannel seekable; final SeekableByteChannel seekable;
private final ByteBuffer single = ByteBuffer.allocate( 1 ); private final ByteBuffer single = ByteBuffer.allocate( 1 );
BinaryReadableHandle( ReadableByteChannel reader, SeekableByteChannel seekable, Closeable closeable ) BinaryReadableHandle( ReadableByteChannel reader, SeekableByteChannel seekable, TrackingCloseable closeable )
{ {
super( closeable ); super( closeable );
this.reader = reader; this.reader = reader;
this.seekable = seekable; this.seekable = seekable;
} }
public static BinaryReadableHandle of( ReadableByteChannel channel, Closeable closeable ) public static BinaryReadableHandle of( ReadableByteChannel channel, TrackingCloseable closeable )
{ {
SeekableByteChannel seekable = asSeekable( channel ); SeekableByteChannel seekable = asSeekable( channel );
return seekable == null ? new BinaryReadableHandle( channel, null, closeable ) : new Seekable( seekable, closeable ); 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 ) 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 public static class Seekable extends BinaryReadableHandle
{ {
Seekable( SeekableByteChannel seekable, Closeable closeable ) Seekable( SeekableByteChannel seekable, TrackingCloseable closeable )
{ {
super( seekable, seekable, 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.LuaException;
import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.lua.LuaValues; import dan200.computercraft.api.lua.LuaValues;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
@@ -30,14 +30,14 @@ public class BinaryWritableHandle extends HandleGeneric
final SeekableByteChannel seekable; final SeekableByteChannel seekable;
private final ByteBuffer single = ByteBuffer.allocate( 1 ); 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 ); super( closeable );
this.writer = writer; this.writer = writer;
this.seekable = seekable; this.seekable = seekable;
} }
public static BinaryWritableHandle of( WritableByteChannel channel, Closeable closeable ) public static BinaryWritableHandle of( WritableByteChannel channel, TrackingCloseable closeable )
{ {
SeekableByteChannel seekable = asSeekable( channel ); SeekableByteChannel seekable = asSeekable( channel );
return seekable == null ? new BinaryWritableHandle( channel, null, closeable ) : new Seekable( seekable, closeable ); 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 ) 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 static class Seekable extends BinaryWritableHandle
{ {
public Seekable( SeekableByteChannel seekable, Closeable closeable ) public Seekable( SeekableByteChannel seekable, TrackingCloseable closeable )
{ {
super( seekable, seekable, 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.LuaException;
import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
@@ -32,7 +32,7 @@ public class EncodedReadableHandle extends HandleGeneric
private final BufferedReader reader; private final BufferedReader reader;
public EncodedReadableHandle( @Nonnull BufferedReader reader, @Nonnull Closeable closable ) public EncodedReadableHandle( @Nonnull BufferedReader reader, @Nonnull TrackingCloseable closable )
{ {
super( closable ); super( closable );
this.reader = reader; this.reader = reader;
@@ -40,7 +40,7 @@ public class EncodedReadableHandle extends HandleGeneric
public EncodedReadableHandle( @Nonnull BufferedReader reader ) 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.IArguments;
import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import dan200.computercraft.shared.util.StringUtil; import dan200.computercraft.shared.util.StringUtil;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
@@ -30,7 +30,7 @@ public class EncodedWritableHandle extends HandleGeneric
{ {
private final BufferedWriter writer; private final BufferedWriter writer;
public EncodedWritableHandle( @Nonnull BufferedWriter writer, @Nonnull Closeable closable ) public EncodedWritableHandle( @Nonnull BufferedWriter writer, @Nonnull TrackingCloseable closable )
{ {
super( closable ); super( closable );
this.writer = writer; 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.LuaException;
import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.core.filesystem.TrackingCloseable;
import dan200.computercraft.shared.util.IoUtil; import dan200.computercraft.shared.util.IoUtil;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.Channel; import java.nio.channels.Channel;
import java.nio.channels.SeekableByteChannel; import java.nio.channels.SeekableByteChannel;
@@ -18,25 +18,23 @@ import java.util.Optional;
public abstract class HandleGeneric public abstract class HandleGeneric
{ {
private Closeable closable; private TrackingCloseable closeable;
private boolean open = true;
protected HandleGeneric( @Nonnull Closeable closable ) protected HandleGeneric( @Nonnull TrackingCloseable closeable )
{ {
this.closable = closable; this.closeable = closeable;
} }
protected void checkOpen() throws LuaException 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() protected final void close()
{ {
open = false; IoUtil.closeQuietly( closeable );
closeable = null;
IoUtil.closeQuietly( closable );
closable = null;
} }
/** /**

View File

@@ -80,10 +80,6 @@ public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpOb
{ {
request.headers().set( HttpHeaderNames.ACCEPT_CHARSET, "UTF-8" ); 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.HOST, uri.getPort() < 0 ? uri.getHost() : uri.getHost() + ":" + uri.getPort() );
request.headers().set( HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE ); 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. * If multiple headers are sent with the same name, they will be combined with a comma.
* *
* @return The response's headers. * @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. * returned headers.
* <pre>{@code * <pre>{@code
* local request = http.get("https://example.computercraft.cc") * local request = http.get("https://example.tweaked.cc")
* print(textutils.serialize(request.getResponseHeaders())) * print(textutils.serialize(request.getResponseHeaders()))
* -- => { * -- => {
* -- [ "Content-Type" ] = "text/plain; charset=utf8", * -- [ "Content-Type" ] = "text/plain; charset=utf8",

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