mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-04 15:43:00 +00:00
Compare commits
80 Commits
v1.16.1-1.
...
v1.16.4-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83df64e520 | ||
|
|
74ac5bb3d1 | ||
|
|
d13bd2cce8 | ||
|
|
ab232bd689 | ||
|
|
cc96e41d3e | ||
|
|
741adfa7bb | ||
|
|
666e83cf4f | ||
|
|
e2a635b6e5 | ||
|
|
c58441b29c | ||
|
|
a6fcfb6af2 | ||
|
|
17a9329207 | ||
|
|
f6160bdc57 | ||
|
|
6aae4e5766 | ||
|
|
84a6bb1cf3 | ||
|
|
c334423d42 | ||
|
|
113b560a20 | ||
|
|
5bf367af9f | ||
|
|
61fb4caaad | ||
|
|
6734af6e4a | ||
|
|
bf6053906d | ||
|
|
4766833cf2 | ||
|
|
01d81cb91d | ||
|
|
93068402a2 | ||
|
|
34a2c835d4 | ||
|
|
30d35883b8 | ||
|
|
71563a52ff | ||
|
|
0c6e7b5db5 | ||
|
|
334ca65482 | ||
|
|
8472112fc1 | ||
|
|
84036d97d9 | ||
|
|
0832974725 | ||
|
|
6cee4efcd3 | ||
|
|
6f868849ab | ||
|
|
275ca58a82 | ||
|
|
87393e8aef | ||
|
|
86bf57e3cd | ||
|
|
72c1d451fe | ||
|
|
8b4a01df27 | ||
|
|
d0a973fa46 | ||
|
|
748ebbe66b | ||
|
|
59de21eae2 | ||
|
|
50473afea8 | ||
|
|
37f925de0a | ||
|
|
cefde3f003 | ||
|
|
ae6124d1f4 | ||
|
|
7e121ff72f | ||
|
|
5155e18de2 | ||
|
|
7365741088 | ||
|
|
d5368d0719 | ||
|
|
26c12ac1a9 | ||
|
|
2c67849b35 | ||
|
|
04509cefec | ||
|
|
74b9f5dcb0 | ||
|
|
7809a2eddd | ||
|
|
183b342071 | ||
|
|
0bb5515055 | ||
|
|
e8e9294fdf | ||
|
|
9acfc0316f | ||
|
|
29fb0baa09 | ||
|
|
d5de39ebd4 | ||
|
|
0faf76e4bd | ||
|
|
99581e1f40 | ||
|
|
e8e2ed9fe5 | ||
|
|
9f72448ecd | ||
|
|
3da3f16deb | ||
|
|
0e2ce3c634 | ||
|
|
fe00e00537 | ||
|
|
29646a7f61 | ||
|
|
50d2712581 | ||
|
|
3093f882d8 | ||
|
|
e5cf0d1c61 | ||
|
|
cd879b067f | ||
|
|
053cb1b53c | ||
|
|
6b102a8142 | ||
|
|
ac7979fb46 | ||
|
|
c8a6888a2f | ||
|
|
9ce33f8a3f | ||
|
|
d51851e763 | ||
|
|
fb70a1a998 | ||
|
|
a1dcd59d95 |
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -12,4 +12,5 @@ labels: bug
|
|||||||
## Useful information to include:
|
## Useful information to include:
|
||||||
- Minecraft version
|
- Minecraft version
|
||||||
- CC: Tweaked version
|
- CC: Tweaked version
|
||||||
|
- Logs: These will be located in the `logs/` directory of your Minecraft instance. Please upload them as a gist or directly into this editor.
|
||||||
- Detailed reproduction steps: sometimes I can spot a bug pretty easily, but often it's much more obscure. The more information I have to help reproduce it, the quicker it'll get fixed.
|
- Detailed reproduction steps: sometimes I can spot a bug pretty easily, but often it's much more obscure. The more information I have to help reproduce it, the quicker it'll get fixed.
|
||||||
|
|||||||
1
.github/workflows/main-ci.yml
vendored
1
.github/workflows/main-ci.yml
vendored
@@ -34,6 +34,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload Coverage
|
- name: Upload Coverage
|
||||||
run: bash <(curl -s https://codecov.io/bash)
|
run: bash <(curl -s https://codecov.io/bash)
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Generate Java documentation stubs
|
- name: Generate Java documentation stubs
|
||||||
run: ./gradlew luaJavadoc --no-daemon
|
run: ./gradlew luaJavadoc --no-daemon
|
||||||
|
|||||||
2
.github/workflows/make-doc.sh
vendored
2
.github/workflows/make-doc.sh
vendored
@@ -12,5 +12,5 @@ chmod 600 "$HOME/.ssh/key"
|
|||||||
|
|
||||||
# And upload
|
# And upload
|
||||||
rsync -avc -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no -p $SSH_PORT" \
|
rsync -avc -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no -p $SSH_PORT" \
|
||||||
"$GITHUB_WORKSPACE/doc/" \
|
"$GITHUB_WORKSPACE/doc/out/" \
|
||||||
"$SSH_USER@$SSH_HOST:/var/www/tweaked.cc/$DEST"
|
"$SSH_USER@$SSH_HOST:/var/www/tweaked.cc/$DEST"
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -3,9 +3,8 @@
|
|||||||
/logs
|
/logs
|
||||||
/build
|
/build
|
||||||
/out
|
/out
|
||||||
/doc/**/*.html
|
/doc/out/
|
||||||
/doc/javadoc/
|
/doc/javadoc/
|
||||||
/doc/index.json
|
|
||||||
|
|
||||||
# Runtime directories
|
# Runtime directories
|
||||||
/run
|
/run
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ do use the issue templates - they provide a useful hint on what information to p
|
|||||||
|
|
||||||
## 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.
|
process. When building on Windows, Use `gradlew.bat` instead of `./gradlew`.
|
||||||
|
|
||||||
- **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
|
- **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
|
||||||
- **Setup Forge:** `./gradlew build`
|
- **Setup Forge:** `./gradlew build`
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -1,4 +1,4 @@
|
|||||||
# 
|
# 
|
||||||
[](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
|
[](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
|
||||||
|
|
||||||
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
|
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
|
||||||
@@ -50,12 +50,12 @@ I'd generally recommend you don't contact me directly (email, DM, etc...) unless
|
|||||||
report exploits). You'll get a far quicker response if you ask the whole community!
|
report exploits). You'll get a far quicker response if you ask the whole community!
|
||||||
|
|
||||||
## Using
|
## Using
|
||||||
If you want to depend on CC: Tweaked, we have a maven repo. However, you should be wary that some functionality is only
|
CC: Tweaked is hosted on my maven repo, and so is relatively simple to depend on. You may wish to add a soft (or hard)
|
||||||
exposed by CC:T's API and not vanilla ComputerCraft. If you wish to support all variations of ComputerCraft, I recommend
|
dependency in your `mods.toml` file, with the appropriate version bounds, to ensure that API functionality you depend
|
||||||
using [cc.crzd.me's maven](https://cc.crzd.me/maven/) instead.
|
on is present.
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
dependencies {
|
repositories {
|
||||||
maven { url 'https://squiddev.cc/maven/' }
|
maven { url 'https://squiddev.cc/maven/' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
build.gradle
10
build.gradle
@@ -9,7 +9,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
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.179'
|
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.187'
|
||||||
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.ajoberstar.grgit:grgit-gradle:3.0.0'
|
||||||
}
|
}
|
||||||
@@ -106,10 +106,10 @@ dependencies {
|
|||||||
|
|
||||||
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
|
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
|
||||||
|
|
||||||
compileOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3:api")
|
compileOnly fg.deobf("mezz.jei:jei-1.16.3:7.6.0.49:api")
|
||||||
compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.15.2:6.0.0.9")
|
compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.16.3:7.0.0.48")
|
||||||
|
|
||||||
// runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3")
|
runtimeOnly fg.deobf("mezz.jei:jei-1.16.3:7.6.0.49")
|
||||||
|
|
||||||
compileOnly 'com.google.auto.service:auto-service:1.0-rc7'
|
compileOnly 'com.google.auto.service:auto-service:1.0-rc7'
|
||||||
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'
|
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'
|
||||||
@@ -122,7 +122,7 @@ dependencies {
|
|||||||
|
|
||||||
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
|
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
|
||||||
|
|
||||||
cctJavadoc 'cc.tweaked:cct-javadoc:1.1.0'
|
cctJavadoc 'cc.tweaked:cct-javadoc:1.2.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile tasks
|
// Compile tasks
|
||||||
|
|||||||
55
doc/stub/global.lua
Normal file
55
doc/stub/global.lua
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
--[[-
|
||||||
|
Global functions defined by `bios.lua`. This does not include standard Lua
|
||||||
|
functions.
|
||||||
|
|
||||||
|
@module _G
|
||||||
|
]]
|
||||||
|
|
||||||
|
--[[- Pauses execution for the specified number of seconds.
|
||||||
|
|
||||||
|
As it waits for a fixed amount of world ticks, `time` will automatically be
|
||||||
|
rounded up to the nearest multiple of 0.05 seconds. If you are using coroutines
|
||||||
|
or the @{parallel|parallel API}, it will only pause execution of the current
|
||||||
|
thread, not the whole program.
|
||||||
|
|
||||||
|
**Note** Because sleep internally uses timers, it is a function that yields.
|
||||||
|
This means that you can use it to prevent "Too long without yielding" errors,
|
||||||
|
however, as the minimum sleep time is 0.05 seconds, it will slow your program
|
||||||
|
down.
|
||||||
|
|
||||||
|
**Warning** Internally, this function queues and waits for a timer event (using
|
||||||
|
@{os.startTimer}), however it does not listen for any other events. This means
|
||||||
|
that any event that occurs while sleeping will be entirely discarded. If you
|
||||||
|
need to receive events while sleeping, consider using @{os.startTimer|timers},
|
||||||
|
or the @{parallel|parallel API}.
|
||||||
|
|
||||||
|
@tparam number time The number of seconds to sleep for, rounded up to the
|
||||||
|
nearest multiple of 0.05.
|
||||||
|
|
||||||
|
@see os.startTimer
|
||||||
|
]]
|
||||||
|
function sleep(time) end
|
||||||
|
|
||||||
|
function write(text) end
|
||||||
|
function print(...) end
|
||||||
|
function printError(...) end
|
||||||
|
|
||||||
|
function read(replaceChar, history, completeFn, default) end
|
||||||
|
|
||||||
|
--- The ComputerCraft and Minecraft version of the current computer environment.
|
||||||
|
--
|
||||||
|
-- For example, `ComputerCraft 1.93.0 (Minecraft 1.15.2)`.
|
||||||
|
_HOST = _HOST
|
||||||
|
|
||||||
|
--[[- The default computer settings as defined in the ComputerCraft
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
This is a comma-separated list of settings pairs defined by the mod
|
||||||
|
configuration or server owner. By default, it is empty.
|
||||||
|
|
||||||
|
An example value to disable autocompletion:
|
||||||
|
|
||||||
|
shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false
|
||||||
|
|
||||||
|
]]
|
||||||
|
_CC_DEFAULT_SETTINGS = _CC_DEFAULT_SETTINGS
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
--- The http library allows communicating with web servers, sending and
|
--- The http library allows communicating with web servers, sending and
|
||||||
-- receiving data from them.
|
-- receiving data from them.
|
||||||
--
|
--
|
||||||
-- #### `http_check` event
|
|
||||||
--
|
|
||||||
-- @module http
|
-- @module http
|
||||||
|
|
||||||
--- Asynchronously make a HTTP request to the given url.
|
--- Asynchronously make a HTTP request to the given url.
|
||||||
|
|||||||
115
doc/stub/os.lua
115
doc/stub/os.lua
@@ -1,6 +1,121 @@
|
|||||||
-- Defined in bios.lua
|
-- Defined in bios.lua
|
||||||
|
|
||||||
|
--[[- Loads the given API into the global environment.
|
||||||
|
|
||||||
|
**Warning** This function is deprecated. Use of this function will pollute the
|
||||||
|
global table, use @{require} instead.
|
||||||
|
|
||||||
|
This function loads and executes the file at the given path, and all global
|
||||||
|
variables and functions exported by it will by available through the use of
|
||||||
|
`myAPI.<function name>`, where `myAPI` is the base name of the API file.
|
||||||
|
|
||||||
|
@tparam string path The path of the API to load.
|
||||||
|
@treturn boolean Whether or not the API was successfully loaded.
|
||||||
|
|
||||||
|
@deprecated Use @{require}.
|
||||||
|
]]
|
||||||
function loadAPI(path) end
|
function loadAPI(path) end
|
||||||
|
|
||||||
|
--- Unloads an API which was loaded by @{os.loadAPI}.
|
||||||
|
--
|
||||||
|
-- This effectively removes the specified table from `_G`.
|
||||||
|
--
|
||||||
|
-- @tparam string name The name of the API to unload.
|
||||||
|
-- @deprecated Use @{require}.
|
||||||
|
function unloadAPI(name) end
|
||||||
|
|
||||||
|
--[[- Pause execution of the current thread and waits for any events matching
|
||||||
|
`filter`.
|
||||||
|
|
||||||
|
This function @{coroutine.yield|yields} the current process and waits for it
|
||||||
|
to be resumed with a vararg list where the first element matches `filter`.
|
||||||
|
If no `filter` is supplied, this will match all events.
|
||||||
|
|
||||||
|
Unlike @{os.pullEventRaw}, it will stop the application upon a "terminate"
|
||||||
|
event, printing the error "Terminated".
|
||||||
|
|
||||||
|
@tparam[opt] string filter Event to filter for.
|
||||||
|
@treturn string event The name of the event that fired.
|
||||||
|
@treturn any param... Optional additional parameters of the event.
|
||||||
|
@usage Listen for `mouse_click` events.
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local event, button, x, y = os.pullEvent("mouse_click")
|
||||||
|
print("Button", button, "was clicked at", x, ",", y)
|
||||||
|
end
|
||||||
|
|
||||||
|
@usage Listen for multiple events.
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local eventData = {os.pullEvent()}
|
||||||
|
local event = eventData[1]
|
||||||
|
|
||||||
|
if event == "mouse_click" then
|
||||||
|
print("Button", eventData[2], "was clicked at", eventData[3], ",", eventData[4])
|
||||||
|
elseif event == "key" then
|
||||||
|
print("Key code", eventData[2], "was pressed")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@see os.pullEventRaw To pull the terminate event.
|
||||||
|
]]
|
||||||
function pullEvent(filter) end
|
function pullEvent(filter) end
|
||||||
|
|
||||||
|
--[[- Pause execution of the current thread and waits for events, including the
|
||||||
|
`terminate` event.
|
||||||
|
|
||||||
|
This behaves almost the same as @{os.pullEvent}, except it allows you to handle
|
||||||
|
the `terminate` event yourself - the program will not stop execution when
|
||||||
|
<kbd>Ctrl+T</kbd> is pressed.
|
||||||
|
|
||||||
|
@tparam[opt] string filter Event to filter for.
|
||||||
|
@treturn string event The name of the event that fired.
|
||||||
|
@treturn any param... Optional additional parameters of the event.
|
||||||
|
@usage Listen for `terminate` events.
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local event = os.pullEventRaw()
|
||||||
|
if event == "terminate" then
|
||||||
|
print("Caught terminate event!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@see os.pullEvent To pull events normally.
|
||||||
|
]]
|
||||||
function pullEventRaw(filter) end
|
function pullEventRaw(filter) end
|
||||||
|
|
||||||
|
--- Pauses execution for the specified number of seconds, alias of @{_G.sleep}.
|
||||||
|
function sleep(time) end
|
||||||
|
|
||||||
|
--- Get the current CraftOS version (for example, `CraftOS 1.8`).
|
||||||
|
--
|
||||||
|
-- This is defined by `bios.lua`. For the current version of CC:Tweaked, this
|
||||||
|
-- should return `CraftOS 1.8`.
|
||||||
|
--
|
||||||
|
-- @treturn string The current CraftOS version.
|
||||||
function version() end
|
function version() end
|
||||||
|
|
||||||
|
--[[- Run the program at the given path with the specified environment and
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
This function does not resolve program names like the shell does. This means
|
||||||
|
that, for example, `os.run("edit")` will not work. As well as this, it does not
|
||||||
|
provide access to the @{shell} API in the environment. For this behaviour, use
|
||||||
|
@{shell.run} instead.
|
||||||
|
|
||||||
|
If the program cannot be found, or failed to run, it will print the error and
|
||||||
|
return `false`. If you want to handle this more gracefully, use an alternative
|
||||||
|
such as @{loadfile}.
|
||||||
|
|
||||||
|
@tparam table env The environment to run the program with.
|
||||||
|
@tparam string path The exact path of the program to run.
|
||||||
|
@param ... The arguments to pass to the program.
|
||||||
|
@treturn boolean Whether or not the program ran successfully.
|
||||||
|
@usage Run the default shell from within your program:
|
||||||
|
|
||||||
|
os.run({}, "/rom/programs/shell")
|
||||||
|
|
||||||
|
@see shell.run
|
||||||
|
@see loadfile
|
||||||
|
]]
|
||||||
function run(env, path, ...) end
|
function run(env, path, ...) end
|
||||||
|
|||||||
187
doc/styles.css
187
doc/styles.css
@@ -1,191 +1,14 @@
|
|||||||
/* Basic reset on elements */
|
/* Pretty tables, mostly inherited from table.definition-list */
|
||||||
h1, h2, h3, h4, p, table, div, body {
|
table.pretty-table {
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
font-size: 100%;
|
|
||||||
font: inherit;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
/* Make the page a little more airy */
|
|
||||||
body {
|
|
||||||
margin: 20px auto;
|
|
||||||
max-width: 1200px;
|
|
||||||
padding: 0 10px;
|
|
||||||
line-height: 1.6;
|
|
||||||
color: #222;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to use system default fonts. */
|
|
||||||
body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans",
|
|
||||||
"Droid Sans", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
||||||
}
|
|
||||||
|
|
||||||
code, pre, .parameter, .type, .definition-name, .reference-code {
|
|
||||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some definitions of basic tags */
|
|
||||||
code {
|
|
||||||
color: #c7254e;
|
|
||||||
background-color: #f9f2f4;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0.9em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 1.5em;
|
|
||||||
font-weight: lighter;
|
|
||||||
border-bottom: solid 1px #aaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2, h3, h4 { margin: 1.4em 0 0.3em;}
|
|
||||||
h2 { font-size: 1.25em; }
|
|
||||||
h3 { font-size: 1.15em; font-weight: bold; }
|
|
||||||
h4 { font-size: 1.06em; }
|
|
||||||
|
|
||||||
a, a:visited, a:active { font-weight: bold; color: #004080; text-decoration: none; }
|
|
||||||
a:hover { text-decoration: underline; }
|
|
||||||
|
|
||||||
blockquote {
|
|
||||||
padding: 0.3em;
|
|
||||||
margin: 1em 0;
|
|
||||||
background: #f0f0f0;
|
|
||||||
border-left: solid 0.5em #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stop sublists from having initial vertical space */
|
|
||||||
ul ul { margin-top: 0px; }
|
|
||||||
ol ul { margin-top: 0px; }
|
|
||||||
ol ol { margin-top: 0px; }
|
|
||||||
ul ol { margin-top: 0px; }
|
|
||||||
|
|
||||||
/* Make the target distinct; helps when we're navigating to a function */
|
|
||||||
a:target + * { background-color: #FFFF99; }
|
|
||||||
|
|
||||||
/* Allow linking to any subsection */
|
|
||||||
a[name]::before { content: "#"; }
|
|
||||||
|
|
||||||
/* Layout */
|
|
||||||
#main {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
justify-content: space-between;
|
|
||||||
min-height: calc(100vh - 100px);
|
|
||||||
}
|
|
||||||
|
|
||||||
#main > nav {
|
|
||||||
flex-basis: 30%;
|
|
||||||
min-width: 150px;
|
|
||||||
max-width: 250px;
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav h1, nav ul { padding: 0em 10px; }
|
|
||||||
|
|
||||||
nav h2 {
|
|
||||||
background-color:#e7e7e7;
|
|
||||||
font-size: 1.1em;
|
|
||||||
color:#000000;
|
|
||||||
padding: 5px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav ul {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content {
|
|
||||||
flex-shrink: 1;
|
|
||||||
flex-basis: 80%;
|
|
||||||
padding: 0px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
text-align: right;
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The definition lists at the top of each page */
|
|
||||||
table.definition-list {
|
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.definition-list td, table.definition-list th {
|
table.pretty-table td, table.pretty-table th {
|
||||||
border: 1px solid #cccccc;
|
border: 1px solid #cccccc;
|
||||||
padding: 5px;
|
padding: 2px 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.definition-list th {
|
table.pretty-table th {
|
||||||
background-color: #f0f0f0;
|
background-color: #f0f0f0;
|
||||||
min-width: 200px;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-align: right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table.definition-list td { width: 100%; }
|
|
||||||
|
|
||||||
dl.definition dt {
|
|
||||||
border-top: 1px solid #ccc;
|
|
||||||
padding-top: 1em;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl.definition dt .definition-name {
|
|
||||||
padding: 0 0.1em;
|
|
||||||
margin: 0 0.1em;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dl.definition dd {
|
|
||||||
padding-bottom: 1em;
|
|
||||||
margin: 10px 0 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
dl.definition h3 {
|
|
||||||
font-size: .95em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Links to source-code */
|
|
||||||
.source-link { font-size: 0.8em; }
|
|
||||||
.source-link::before { content: '[' }
|
|
||||||
.source-link::after { content: ']' }
|
|
||||||
a.source-link, a.source-link:visited, a.source-link:active { color: #505050; }
|
|
||||||
|
|
||||||
/* Method definitions */
|
|
||||||
span.parameter:after { content:":"; padding-left: 0.3em; }
|
|
||||||
.optional { text-decoration: underline dotted; }
|
|
||||||
|
|
||||||
/** Fancy colour display. */
|
|
||||||
.colour-ref {
|
|
||||||
display: inline-block;
|
|
||||||
width: 0.8em;
|
|
||||||
height: 0.8em;
|
|
||||||
margin: 0.1em 0.1em 0.3em 0.1em; /* Terrrible hack to force vertical alignment. */
|
|
||||||
border: solid 1px black;
|
|
||||||
box-sizing: border-box;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* styles for prettification of source */
|
|
||||||
.highlight .comment { color: #558817; }
|
|
||||||
.highlight .constant { color: #a8660d; }
|
|
||||||
.highlight .escape { color: #844631; }
|
|
||||||
.highlight .keyword { color: #aa5050; font-weight: bold; }
|
|
||||||
.highlight .library { color: #0e7c6b; }
|
|
||||||
.highlight .marker { color: #512b1e; background: #fedc56; font-weight: bold; }
|
|
||||||
.highlight .string { color: #8080ff; }
|
|
||||||
.highlight .literal-kw { color: #8080ff; }
|
|
||||||
.highlight .number { color: #f8660d; }
|
|
||||||
.highlight .operator { color: #2239a8; font-weight: bold; }
|
|
||||||
.highlight .preprocessor, pre .prepro { color: #a33243; }
|
|
||||||
.highlight .global { color: #800080; }
|
|
||||||
.highlight .user-keyword { color: #800080; }
|
|
||||||
.highlight .prompt { color: #558817; }
|
|
||||||
.highlight .url { color: #272fc2; text-decoration: underline; }
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Mod properties
|
# Mod properties
|
||||||
mod_version=1.90.0
|
mod_version=1.94.0
|
||||||
|
|
||||||
# Minecraft properties (update mods.toml when changing)
|
# Minecraft properties (update mods.toml when changing)
|
||||||
mc_version=1.16.1
|
mc_version=1.16.4
|
||||||
forge_version=32.0.63
|
forge_version=35.0.1
|
||||||
mappings_version=20200707-1.16.1
|
mappings_version=20201028-1.16.3
|
||||||
|
|||||||
@@ -10,7 +10,10 @@
|
|||||||
|
|
||||||
(doc
|
(doc
|
||||||
(title "CC: Tweaked")
|
(title "CC: Tweaked")
|
||||||
|
(destination doc/out)
|
||||||
|
(logo src/main/resources/pack.png)
|
||||||
(index doc/index.md)
|
(index doc/index.md)
|
||||||
|
(styles doc/styles.css)
|
||||||
(source-link https://github.com/SquidDev-CC/CC-Tweaked/blob/${commit}/${path}#L${line})
|
(source-link https://github.com/SquidDev-CC/CC-Tweaked/blob/${commit}/${path}#L${line})
|
||||||
|
|
||||||
(module-kinds
|
(module-kinds
|
||||||
@@ -50,7 +53,7 @@
|
|||||||
|
|
||||||
;; colours imports from colors, and we don't handle that right now.
|
;; colours imports from colors, and we don't handle that right now.
|
||||||
;; keys is entirely dynamic, so we skip it.
|
;; keys is entirely dynamic, so we skip it.
|
||||||
(dynamic-modules colours keys)
|
(dynamic-modules colours keys _G)
|
||||||
|
|
||||||
(globals
|
(globals
|
||||||
:max
|
:max
|
||||||
@@ -79,6 +82,7 @@
|
|||||||
/doc/stub/http.lua
|
/doc/stub/http.lua
|
||||||
/doc/stub/os.lua
|
/doc/stub/os.lua
|
||||||
/doc/stub/turtle.lua
|
/doc/stub/turtle.lua
|
||||||
|
/doc/stub/global.lua
|
||||||
; Java generated APIs
|
; Java generated APIs
|
||||||
/doc/javadoc/turtle.lua
|
/doc/javadoc/turtle.lua
|
||||||
; Peripherals
|
; Peripherals
|
||||||
@@ -100,7 +104,14 @@
|
|||||||
/doc/stub/fs.lua)
|
/doc/stub/fs.lua)
|
||||||
(linters -doc:unresolved-reference))
|
(linters -doc:unresolved-reference))
|
||||||
|
|
||||||
|
;; Suppress warnings for the BIOS using its own deprecated members for now.
|
||||||
|
(at /src/main/resources/*/computercraft/lua/bios.lua
|
||||||
|
(linters -var:deprecated))
|
||||||
|
|
||||||
(at /src/test/resources/test-rom
|
(at /src/test/resources/test-rom
|
||||||
|
; We should still be able to test deprecated members.
|
||||||
|
(linters -var:deprecated)
|
||||||
|
|
||||||
(lint
|
(lint
|
||||||
(globals
|
(globals
|
||||||
:max sleep write
|
:max sleep write
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package dan200.computercraft;
|
|||||||
import dan200.computercraft.api.turtle.event.TurtleAction;
|
import dan200.computercraft.api.turtle.event.TurtleAction;
|
||||||
import dan200.computercraft.core.apis.http.options.Action;
|
import dan200.computercraft.core.apis.http.options.Action;
|
||||||
import dan200.computercraft.core.apis.http.options.AddressRule;
|
import dan200.computercraft.core.apis.http.options.AddressRule;
|
||||||
|
import dan200.computercraft.core.asm.GenericSource;
|
||||||
import dan200.computercraft.shared.Config;
|
import dan200.computercraft.shared.Config;
|
||||||
import dan200.computercraft.shared.Registry;
|
import dan200.computercraft.shared.Registry;
|
||||||
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
|
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
|
||||||
@@ -16,6 +17,7 @@ import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
|||||||
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
|
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
|
||||||
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
|
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
|
||||||
import dan200.computercraft.shared.turtle.upgrades.*;
|
import dan200.computercraft.shared.turtle.upgrades.*;
|
||||||
|
import dan200.computercraft.shared.util.ServiceUtil;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@@ -37,6 +39,7 @@ public final class ComputerCraft
|
|||||||
public static final String[] DEFAULT_HTTP_ALLOW = new String[] { "*" };
|
public static final String[] DEFAULT_HTTP_ALLOW = new String[] { "*" };
|
||||||
public static final String[] DEFAULT_HTTP_DENY = new String[] {
|
public static final String[] DEFAULT_HTTP_DENY = new String[] {
|
||||||
"127.0.0.0/8",
|
"127.0.0.0/8",
|
||||||
|
"0.0.0.0/8",
|
||||||
"10.0.0.0/8",
|
"10.0.0.0/8",
|
||||||
"172.16.0.0/12",
|
"172.16.0.0/12",
|
||||||
"192.168.0.0/16",
|
"192.168.0.0/16",
|
||||||
@@ -60,10 +63,10 @@ public final class ComputerCraft
|
|||||||
public static boolean httpWebsocketEnabled = true;
|
public static boolean httpWebsocketEnabled = true;
|
||||||
public static List<AddressRule> httpRules = Collections.unmodifiableList( Stream.concat(
|
public static List<AddressRule> httpRules = Collections.unmodifiableList( Stream.concat(
|
||||||
Stream.of( DEFAULT_HTTP_DENY )
|
Stream.of( DEFAULT_HTTP_DENY )
|
||||||
.map( x -> AddressRule.parse( x, Action.DENY.toPartial() ) )
|
.map( x -> AddressRule.parse( x, null, Action.DENY.toPartial() ) )
|
||||||
.filter( Objects::nonNull ),
|
.filter( Objects::nonNull ),
|
||||||
Stream.of( DEFAULT_HTTP_ALLOW )
|
Stream.of( DEFAULT_HTTP_ALLOW )
|
||||||
.map( x -> AddressRule.parse( x, Action.ALLOW.toPartial() ) )
|
.map( x -> AddressRule.parse( x, null, Action.ALLOW.toPartial() ) )
|
||||||
.filter( Objects::nonNull )
|
.filter( Objects::nonNull )
|
||||||
).collect( Collectors.toList() ) );
|
).collect( Collectors.toList() ) );
|
||||||
|
|
||||||
@@ -87,8 +90,6 @@ public final class ComputerCraft
|
|||||||
public static boolean turtlesCanPush = true;
|
public static boolean turtlesCanPush = true;
|
||||||
public static EnumSet<TurtleAction> turtleDisabledActions = EnumSet.noneOf( TurtleAction.class );
|
public static EnumSet<TurtleAction> turtleDisabledActions = EnumSet.noneOf( TurtleAction.class );
|
||||||
|
|
||||||
public static boolean genericPeripheral = false;
|
|
||||||
|
|
||||||
public static int computerTermWidth = 51;
|
public static int computerTermWidth = 51;
|
||||||
public static int computerTermHeight = 19;
|
public static int computerTermHeight = 19;
|
||||||
|
|
||||||
@@ -133,5 +134,6 @@ public final class ComputerCraft
|
|||||||
{
|
{
|
||||||
Config.setup();
|
Config.setup();
|
||||||
Registry.setup();
|
Registry.setup();
|
||||||
|
GenericSource.setup( () -> ServiceUtil.loadServicesForge( GenericSource.class ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
|
|||||||
|
|
||||||
public static InputStream getResourceFile( String domain, String subPath )
|
public static InputStream getResourceFile( String domain, String subPath )
|
||||||
{
|
{
|
||||||
IReloadableResourceManager manager = (IReloadableResourceManager) ServerLifecycleHooks.getCurrentServer().getDataPackRegistries().func_240970_h_();
|
IReloadableResourceManager manager = (IReloadableResourceManager) ServerLifecycleHooks.getCurrentServer().getDataPackRegistries().getResourceManager();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return manager.getResource( new ResourceLocation( domain, subPath ) ).getInputStream();
|
return manager.getResource( new ResourceLocation( domain, subPath ) ).getInputStream();
|
||||||
@@ -97,7 +97,7 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
|
|||||||
@Override
|
@Override
|
||||||
public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
|
public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
|
||||||
{
|
{
|
||||||
IReloadableResourceManager manager = (IReloadableResourceManager) ServerLifecycleHooks.getCurrentServer().getDataPackRegistries().func_240970_h_();
|
IReloadableResourceManager manager = (IReloadableResourceManager) ServerLifecycleHooks.getCurrentServer().getDataPackRegistries().getResourceManager();
|
||||||
ResourceMount mount = ResourceMount.get( domain, subPath, manager );
|
ResourceMount mount = ResourceMount.get( domain, subPath, manager );
|
||||||
return mount.exists( "" ) ? mount : null;
|
return mount.exists( "" ) ? mount : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ public interface ITurtleAccess
|
|||||||
*
|
*
|
||||||
* @return This turtle's owner.
|
* @return This turtle's owner.
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nullable
|
||||||
GameProfile getOwningPlayer();
|
GameProfile getOwningPlayer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class ClientTableFormatter implements TableFormatter
|
|||||||
{
|
{
|
||||||
public static final ClientTableFormatter INSTANCE = new ClientTableFormatter();
|
public static final ClientTableFormatter INSTANCE = new ClientTableFormatter();
|
||||||
|
|
||||||
private static Int2IntOpenHashMap lastHeights = new Int2IntOpenHashMap();
|
private static final Int2IntOpenHashMap lastHeights = new Int2IntOpenHashMap();
|
||||||
|
|
||||||
private static FontRenderer renderer()
|
private static FontRenderer renderer()
|
||||||
{
|
{
|
||||||
@@ -55,7 +55,7 @@ public class ClientTableFormatter implements TableFormatter
|
|||||||
@Override
|
@Override
|
||||||
public int getWidth( ITextComponent component )
|
public int getWidth( ITextComponent component )
|
||||||
{
|
{
|
||||||
return renderer().func_238414_a_( component );
|
return renderer().getStringPropertyWidth( component );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -91,13 +91,13 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
|
|||||||
terminalWrapper = new WidgetWrapper( terminal, MARGIN + BORDER + guiLeft, MARGIN + BORDER + guiTop, termPxWidth, termPxHeight );
|
terminalWrapper = new WidgetWrapper( terminal, MARGIN + BORDER + guiLeft, MARGIN + BORDER + guiTop, termPxWidth, termPxHeight );
|
||||||
|
|
||||||
children.add( terminalWrapper );
|
children.add( terminalWrapper );
|
||||||
setFocused( terminalWrapper );
|
setListener( terminalWrapper );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed()
|
public void onClose()
|
||||||
{
|
{
|
||||||
super.removed();
|
super.onClose();
|
||||||
children.remove( terminal );
|
children.remove( terminal );
|
||||||
terminal = null;
|
terminal = null;
|
||||||
minecraft.keyboardListener.enableRepeatEvents( false );
|
minecraft.keyboardListener.enableRepeatEvents( false );
|
||||||
@@ -114,16 +114,16 @@ 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 && getFocused() != null && getFocused() == terminalWrapper )
|
if( key == GLFW.GLFW_KEY_TAB && getListener() != null && getListener() == terminalWrapper )
|
||||||
{
|
{
|
||||||
return getFocused().keyPressed( key, scancode, modifiers );
|
return getListener().keyPressed( key, scancode, modifiers );
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.keyPressed( key, scancode, modifiers );
|
return super.keyPressed( key, scancode, modifiers );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void func_230450_a_( @Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY )
|
public void drawGuiContainerBackgroundLayer( @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() );
|
||||||
@@ -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 );
|
||||||
func_230459_a_( stack, mouseX, mouseY );
|
renderHoveredTooltip( 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 (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|
return (getListener() != null && getListener().mouseDragged( x, y, button, deltaX, deltaY ))
|
||||||
|| super.mouseDragged( x, y, button, deltaX, deltaY );
|
|| super.mouseDragged( x, y, button, deltaX, deltaY );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void func_230451_b_( @Nonnull MatrixStack transform, int mouseX, int mouseY )
|
protected void drawGuiContainerForegroundLayer( @Nonnull MatrixStack transform, int mouseX, int mouseY )
|
||||||
{
|
{
|
||||||
// Skip rendering labels.
|
// Skip rendering labels.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public class GuiDiskDrive extends ContainerScreen<ContainerDiskDrive>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void func_230450_a_( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
|
protected void drawGuiContainerBackgroundLayer( @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().bindTexture( BACKGROUND );
|
||||||
@@ -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 );
|
||||||
func_230459_a_( transform, mouseX, mouseY );
|
renderHoveredTooltip( transform, mouseX, mouseY );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class GuiPrinter extends ContainerScreen<ContainerPrinter>
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void func_230450_a_( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
|
protected void drawGuiContainerBackgroundLayer( @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().bindTexture( BACKGROUND );
|
||||||
@@ -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 );
|
||||||
func_230459_a_( stack, mouseX, mouseY );
|
renderHoveredTooltip( stack, mouseX, mouseY );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import net.minecraft.client.gui.screen.inventory.ContainerScreen;
|
|||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
import net.minecraft.util.math.vector.TransformationMatrix;
|
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
@@ -25,8 +24,6 @@ import static dan200.computercraft.client.render.PrintoutRenderer.*;
|
|||||||
|
|
||||||
public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
|
public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
|
||||||
{
|
{
|
||||||
private static final Matrix4f IDENTITY = TransformationMatrix.identity().getMatrix();
|
|
||||||
|
|
||||||
private final boolean m_book;
|
private final boolean m_book;
|
||||||
private final int m_pages;
|
private final int m_pages;
|
||||||
private final TextBuffer[] m_text;
|
private final TextBuffer[] m_text;
|
||||||
@@ -94,7 +91,7 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void func_230450_a_( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
|
protected void drawGuiContainerBackgroundLayer( @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 );
|
||||||
@@ -116,11 +113,10 @@ public class GuiPrintout extends ContainerScreen<ContainerHeldItem>
|
|||||||
setBlitOffset( getBlitOffset() + 1 );
|
setBlitOffset( getBlitOffset() + 1 );
|
||||||
|
|
||||||
super.render( stack, mouseX, mouseY, partialTicks );
|
super.render( stack, mouseX, mouseY, partialTicks );
|
||||||
func_230459_a_( stack, mouseX, mouseY );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void func_230451_b_( @Nonnull MatrixStack transform, int mouseX, int mouseY )
|
protected void drawGuiContainerForegroundLayer( @Nonnull MatrixStack transform, int mouseX, int mouseY )
|
||||||
{
|
{
|
||||||
// Skip rendering labels.
|
// Skip rendering labels.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,13 +64,13 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
|
|||||||
terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + guiLeft, 2 + 8 + guiTop, termPxWidth, termPxHeight );
|
terminalWrapper = new WidgetWrapper( terminal, 2 + 8 + guiLeft, 2 + 8 + guiTop, termPxWidth, termPxHeight );
|
||||||
|
|
||||||
children.add( terminalWrapper );
|
children.add( terminalWrapper );
|
||||||
setFocused( terminalWrapper );
|
setListener( terminalWrapper );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removed()
|
public void onClose()
|
||||||
{
|
{
|
||||||
super.removed();
|
super.onClose();
|
||||||
children.remove( terminal );
|
children.remove( terminal );
|
||||||
terminal = null;
|
terminal = null;
|
||||||
minecraft.keyboardListener.enableRepeatEvents( false );
|
minecraft.keyboardListener.enableRepeatEvents( false );
|
||||||
@@ -87,41 +87,38 @@ 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 && getFocused() != null && getFocused() == terminalWrapper )
|
if( key == GLFW.GLFW_KEY_TAB && getListener() != null && getListener() == terminalWrapper )
|
||||||
{
|
{
|
||||||
return getFocused().keyPressed( key, scancode, modifiers );
|
return getListener().keyPressed( key, scancode, modifiers );
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.keyPressed( key, scancode, modifiers );
|
return super.keyPressed( key, scancode, modifiers );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawSelectionSlot( boolean advanced )
|
|
||||||
{
|
|
||||||
// Draw selection slot
|
|
||||||
int slot = m_container.getSelectedSlot();
|
|
||||||
if( slot >= 0 )
|
|
||||||
{
|
|
||||||
RenderSystem.color4f( 1.0F, 1.0F, 1.0F, 1.0F );
|
|
||||||
int slotX = slot % 4;
|
|
||||||
int slotY = slot / 4;
|
|
||||||
minecraft.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
|
|
||||||
// TODO: blit( guiLeft + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18, guiTop + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18, 0, 217, 24, 24 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void func_230450_a_( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
|
protected void drawGuiContainerBackgroundLayer( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
|
||||||
{
|
{
|
||||||
// Draw term
|
// Draw term
|
||||||
boolean advanced = m_family == ComputerFamily.ADVANCED;
|
ResourceLocation texture = m_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( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
|
minecraft.getTextureManager().bindTexture( texture );
|
||||||
blit( transform, guiLeft, guiTop, 0, 0, xSize, ySize );
|
blit( transform, guiLeft, guiTop, 0, 0, xSize, ySize );
|
||||||
|
|
||||||
drawSelectionSlot( advanced );
|
// Draw selection slot
|
||||||
|
int slot = m_container.getSelectedSlot();
|
||||||
|
if( slot >= 0 )
|
||||||
|
{
|
||||||
|
int slotX = slot % 4;
|
||||||
|
int slotY = slot / 4;
|
||||||
|
blit( transform,
|
||||||
|
guiLeft + ContainerTurtle.TURTLE_START_X - 2 + slotX * 18,
|
||||||
|
guiTop + ContainerTurtle.PLAYER_START_Y - 2 + slotY * 18,
|
||||||
|
0, 217, 24, 24
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -129,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 );
|
||||||
func_230459_a_( stack, mouseX, mouseY );
|
renderHoveredTooltip( 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 (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|
return (getListener() != null && getListener().mouseDragged( x, y, button, deltaX, deltaY ))
|
||||||
|| super.mouseDragged( x, y, button, deltaX, deltaY );
|
|| super.mouseDragged( x, y, button, deltaX, deltaY );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void func_230451_b_( @Nonnull MatrixStack transform, int mouseX, int mouseY )
|
protected void drawGuiContainerForegroundLayer( @Nonnull MatrixStack transform, int mouseX, int mouseY )
|
||||||
{
|
{
|
||||||
// Skip rendering labels.
|
// Skip rendering labels.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,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.func_239418_a_( item.get(), id, getter );
|
ItemModelsProperties.registerProperty( item.get(), id, getter );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
|
|||||||
|
|
||||||
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();
|
||||||
Minecraft.getInstance().getTextureManager()
|
Minecraft.getInstance().getTextureManager()
|
||||||
.bindTexture( colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family ) );
|
.bindTexture( colour != -1 ? ComputerBorderRenderer.BACKGROUND_COLOUR : ComputerBorderRenderer.getTexture( family ) );
|
||||||
|
|
||||||
@@ -137,7 +138,6 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
|
|||||||
|
|
||||||
private static void renderLight( Matrix4f transform, int colour, int width, int height )
|
private static void renderLight( Matrix4f transform, int colour, int width, int height )
|
||||||
{
|
{
|
||||||
RenderSystem.enableBlend();
|
|
||||||
RenderSystem.disableTexture();
|
RenderSystem.disableTexture();
|
||||||
|
|
||||||
float r = ((colour >>> 16) & 0xFF) / 255.0f;
|
float r = ((colour >>> 16) & 0xFF) / 255.0f;
|
||||||
|
|||||||
@@ -108,9 +108,9 @@ public class TurtleMultiModel implements IBakedModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean func_230044_c_()
|
public boolean isSideLit()
|
||||||
{
|
{
|
||||||
return m_baseModel.func_230044_c_();
|
return m_baseModel.isSideLit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class TurtleSmartItemModel implements IBakedModel
|
|||||||
{
|
{
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public IBakedModel func_239290_a_( @Nonnull IBakedModel originalModel, @Nonnull ItemStack stack, @Nullable ClientWorld world, @Nullable LivingEntity entity )
|
public IBakedModel getOverrideModel( @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 );
|
||||||
@@ -184,9 +184,9 @@ public class TurtleSmartItemModel implements IBakedModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean func_230044_c_()
|
public boolean isSideLit()
|
||||||
{
|
{
|
||||||
return familyModel.func_230044_c_();
|
return familyModel.isSideLit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
|||||||
@@ -479,6 +479,7 @@ public class FSAPI implements ILuaAPI
|
|||||||
BasicFileAttributes attributes = fileSystem.getAttributes( path );
|
BasicFileAttributes attributes = fileSystem.getAttributes( path );
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
result.put( "modification", getFileTime( attributes.lastModifiedTime() ) );
|
result.put( "modification", getFileTime( attributes.lastModifiedTime() ) );
|
||||||
|
result.put( "modified", getFileTime( attributes.lastModifiedTime() ) );
|
||||||
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() );
|
||||||
|
|||||||
@@ -171,12 +171,18 @@ public class OSAPI implements ILuaAPI
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a timer that will run for the specified number of seconds. Once
|
* Starts a timer that will run for the specified number of seconds. Once
|
||||||
* the timer fires, a timer event will be added to the queue with the ID
|
* the timer fires, a {@code timer} event will be added to the queue with
|
||||||
* returned from this function as the first parameter.
|
* the ID returned from this function as the first parameter.
|
||||||
|
*
|
||||||
|
* As with @{os.sleep|sleep}, {@code timer} will automatically be rounded up
|
||||||
|
* to the nearest multiple of 0.05 seconds, as it waits for a fixed amount
|
||||||
|
* of world ticks.
|
||||||
*
|
*
|
||||||
* @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.
|
* @return The ID of the new timer. This can be used to filter the
|
||||||
|
* {@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.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final int startTimer( double timer ) throws LuaException
|
public final int startTimer( double timer ) throws LuaException
|
||||||
@@ -199,11 +205,14 @@ public class OSAPI implements ILuaAPI
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an alarm that will fire at the specified world time. When it fires,
|
* Sets an alarm that will fire at the specified world time. When it fires,
|
||||||
* an alarm event will be added to the event queue.
|
* an {@code alarm} event will be added to the event queue with the ID
|
||||||
|
* returned from this function as the first parameter.
|
||||||
*
|
*
|
||||||
* @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 alarm that was set.
|
* @return The ID of the new alarm. This can be used to filter the
|
||||||
|
* {@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.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final int setAlarm( double time ) throws LuaException
|
public final int setAlarm( double time ) throws LuaException
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ public class CheckUrl extends Resource<CheckUrl>
|
|||||||
|
|
||||||
private final IAPIEnvironment environment;
|
private final IAPIEnvironment environment;
|
||||||
private final String address;
|
private final String address;
|
||||||
private final String host;
|
private final URI uri;
|
||||||
|
|
||||||
public CheckUrl( ResourceGroup<CheckUrl> limiter, IAPIEnvironment environment, String address, URI uri )
|
public CheckUrl( ResourceGroup<CheckUrl> limiter, IAPIEnvironment environment, String address, URI uri )
|
||||||
{
|
{
|
||||||
super( limiter );
|
super( limiter );
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
this.address = address;
|
this.address = address;
|
||||||
host = uri.getHost();
|
this.uri = uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run()
|
public void run()
|
||||||
@@ -47,8 +47,9 @@ public class CheckUrl extends Resource<CheckUrl>
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
InetSocketAddress netAddress = NetworkUtils.getAddress( host, 80, false );
|
boolean ssl = uri.getScheme().equalsIgnoreCase( "https" );
|
||||||
NetworkUtils.getOptions( host, netAddress );
|
InetSocketAddress netAddress = NetworkUtils.getAddress( uri, ssl );
|
||||||
|
NetworkUtils.getOptions( uri.getHost(), netAddress );
|
||||||
|
|
||||||
if( tryClose() ) environment.queueEvent( EVENT, address, true );
|
if( tryClose() ) environment.queueEvent( EVENT, address, true );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import io.netty.handler.ssl.SslContextBuilder;
|
|||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.SynchronousQueue;
|
import java.util.concurrent.SynchronousQueue;
|
||||||
@@ -99,6 +100,21 @@ public final class NetworkUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link InetSocketAddress} from a {@link java.net.URI}.
|
||||||
|
*
|
||||||
|
* Note, this may require a DNS lookup, and so should not be executed on the main CC thread.
|
||||||
|
*
|
||||||
|
* @param uri The URI to fetch.
|
||||||
|
* @param ssl Whether to connect with SSL. This is used to find the default port if not otherwise specified.
|
||||||
|
* @return The resolved address.
|
||||||
|
* @throws HTTPRequestException If the host is not malformed.
|
||||||
|
*/
|
||||||
|
public static InetSocketAddress getAddress( URI uri, boolean ssl ) throws HTTPRequestException
|
||||||
|
{
|
||||||
|
return getAddress( uri.getHost(), uri.getPort(), ssl );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link InetSocketAddress} from the resolved {@code host} and port.
|
* Create a {@link InetSocketAddress} from the resolved {@code host} and port.
|
||||||
*
|
*
|
||||||
@@ -128,7 +144,7 @@ public final class NetworkUtils
|
|||||||
*/
|
*/
|
||||||
public static Options getOptions( String host, InetSocketAddress address ) throws HTTPRequestException
|
public static Options getOptions( String host, InetSocketAddress address ) throws HTTPRequestException
|
||||||
{
|
{
|
||||||
Options options = AddressRule.apply( ComputerCraft.httpRules, host, address.getAddress() );
|
Options options = AddressRule.apply( ComputerCraft.httpRules, host, address );
|
||||||
if( options.action == Action.DENY ) throw new HTTPRequestException( "Domain not permitted" );
|
if( options.action == Action.DENY ) throw new HTTPRequestException( "Domain not permitted" );
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import javax.annotation.Nonnull;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.net.Inet6Address;
|
import java.net.Inet6Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,17 +53,23 @@ public final class AddressRule
|
|||||||
|
|
||||||
private final HostRange ip;
|
private final HostRange ip;
|
||||||
private final Pattern domainPattern;
|
private final Pattern domainPattern;
|
||||||
|
private final Integer port;
|
||||||
private final PartialOptions partial;
|
private final PartialOptions partial;
|
||||||
|
|
||||||
private AddressRule( @Nullable HostRange ip, @Nullable Pattern domainPattern, @Nonnull PartialOptions partial )
|
private AddressRule(
|
||||||
|
@Nullable HostRange ip,
|
||||||
|
@Nullable Pattern domainPattern,
|
||||||
|
@Nullable Integer port,
|
||||||
|
@Nonnull PartialOptions partial )
|
||||||
{
|
{
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
this.domainPattern = domainPattern;
|
this.domainPattern = domainPattern;
|
||||||
this.partial = partial;
|
this.partial = partial;
|
||||||
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static AddressRule parse( String filter, @Nonnull PartialOptions partial )
|
public static AddressRule parse( String filter, @Nullable Integer port, @Nonnull PartialOptions partial )
|
||||||
{
|
{
|
||||||
int cidr = filter.indexOf( '/' );
|
int cidr = filter.indexOf( '/' );
|
||||||
if( cidr >= 0 )
|
if( cidr >= 0 )
|
||||||
@@ -117,24 +124,27 @@ public final class AddressRule
|
|||||||
size -= 8;
|
size -= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AddressRule( new HostRange( minBytes, maxBytes ), null, partial );
|
return new AddressRule( new HostRange( minBytes, maxBytes ), null, port, partial );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Pattern pattern = Pattern.compile( "^\\Q" + filter.replaceAll( "\\*", "\\\\E.*\\\\Q" ) + "\\E$" );
|
Pattern pattern = Pattern.compile( "^\\Q" + filter.replaceAll( "\\*", "\\\\E.*\\\\Q" ) + "\\E$" );
|
||||||
return new AddressRule( null, pattern, partial );
|
return new AddressRule( null, pattern, port, partial );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given address matches a series of patterns.
|
* Determine whether the given address matches a series of patterns.
|
||||||
*
|
*
|
||||||
* @param domain The domain to match
|
* @param domain The domain to match
|
||||||
* @param address The address to check.
|
* @param socketAddress The address to check.
|
||||||
* @return Whether it matches any of these patterns.
|
* @return Whether it matches any of these patterns.
|
||||||
*/
|
*/
|
||||||
private boolean matches( String domain, InetAddress address )
|
private boolean matches( String domain, InetSocketAddress socketAddress )
|
||||||
{
|
{
|
||||||
|
InetAddress address = socketAddress.getAddress();
|
||||||
|
if( port != null && port != socketAddress.getPort() ) return false;
|
||||||
|
|
||||||
if( domainPattern != null )
|
if( domainPattern != null )
|
||||||
{
|
{
|
||||||
if( domainPattern.matcher( domain ).matches() ) return true;
|
if( domainPattern.matcher( domain ).matches() ) return true;
|
||||||
@@ -155,7 +165,7 @@ public final class AddressRule
|
|||||||
return ip != null && ip.contains( address );
|
return ip != null && ip.contains( address );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Options apply( Iterable<? extends AddressRule> rules, String domain, InetAddress address )
|
public static Options apply( Iterable<? extends AddressRule> rules, String domain, InetSocketAddress address )
|
||||||
{
|
{
|
||||||
PartialOptions options = null;
|
PartialOptions options = null;
|
||||||
boolean hasMany = false;
|
boolean hasMany = false;
|
||||||
|
|||||||
@@ -49,12 +49,14 @@ public class AddressRuleConfig
|
|||||||
public static boolean checkRule( UnmodifiableConfig builder )
|
public static boolean checkRule( UnmodifiableConfig builder )
|
||||||
{
|
{
|
||||||
String hostObj = get( builder, "host", String.class ).orElse( null );
|
String hostObj = get( builder, "host", String.class ).orElse( null );
|
||||||
|
Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
|
||||||
return hostObj != null && checkEnum( builder, "action", Action.class )
|
return hostObj != null && checkEnum( builder, "action", Action.class )
|
||||||
|
&& check( builder, "port", Number.class )
|
||||||
&& check( builder, "timeout", Number.class )
|
&& check( builder, "timeout", Number.class )
|
||||||
&& check( builder, "max_upload", Number.class )
|
&& check( builder, "max_upload", Number.class )
|
||||||
&& check( builder, "max_download", Number.class )
|
&& check( builder, "max_download", Number.class )
|
||||||
&& check( builder, "websocket_message", Number.class )
|
&& check( builder, "websocket_message", Number.class )
|
||||||
&& AddressRule.parse( hostObj, PartialOptions.DEFAULT ) != null;
|
&& AddressRule.parse( hostObj, port, PartialOptions.DEFAULT ) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -64,6 +66,7 @@ public class AddressRuleConfig
|
|||||||
if( hostObj == null ) return null;
|
if( hostObj == null ) return null;
|
||||||
|
|
||||||
Action action = getEnum( builder, "action", Action.class ).orElse( null );
|
Action action = getEnum( builder, "action", Action.class ).orElse( null );
|
||||||
|
Integer port = get( builder, "port", Number.class ).map( Number::intValue ).orElse( null );
|
||||||
Integer timeout = get( builder, "timeout", Number.class ).map( Number::intValue ).orElse( null );
|
Integer timeout = get( builder, "timeout", Number.class ).map( Number::intValue ).orElse( null );
|
||||||
Long maxUpload = get( builder, "max_upload", Number.class ).map( Number::longValue ).orElse( null );
|
Long maxUpload = get( builder, "max_upload", Number.class ).map( Number::longValue ).orElse( null );
|
||||||
Long maxDownload = get( builder, "max_download", Number.class ).map( Number::longValue ).orElse( null );
|
Long maxDownload = get( builder, "max_download", Number.class ).map( Number::longValue ).orElse( null );
|
||||||
@@ -77,7 +80,7 @@ public class AddressRuleConfig
|
|||||||
websocketMessage
|
websocketMessage
|
||||||
);
|
);
|
||||||
|
|
||||||
return AddressRule.parse( hostObj, options );
|
return AddressRule.parse( hostObj, port, options );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> boolean check( UnmodifiableConfig config, String field, Class<T> klass )
|
private static <T> boolean check( UnmodifiableConfig config, String field, Class<T> klass )
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ public class HttpRequest extends Resource<HttpRequest>
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
boolean ssl = uri.getScheme().equalsIgnoreCase( "https" );
|
boolean ssl = uri.getScheme().equalsIgnoreCase( "https" );
|
||||||
InetSocketAddress socketAddress = NetworkUtils.getAddress( uri.getHost(), uri.getPort(), ssl );
|
InetSocketAddress socketAddress = NetworkUtils.getAddress( uri, ssl );
|
||||||
Options options = NetworkUtils.getOptions( uri.getHost(), socketAddress );
|
Options options = NetworkUtils.getOptions( uri.getHost(), socketAddress );
|
||||||
SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;
|
SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;
|
||||||
|
|
||||||
|
|||||||
@@ -129,8 +129,7 @@ public class Websocket extends Resource<Websocket>
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
boolean ssl = uri.getScheme().equalsIgnoreCase( "wss" );
|
boolean ssl = uri.getScheme().equalsIgnoreCase( "wss" );
|
||||||
|
InetSocketAddress socketAddress = NetworkUtils.getAddress( uri, ssl );
|
||||||
InetSocketAddress socketAddress = NetworkUtils.getAddress( uri.getHost(), uri.getPort(), ssl );
|
|
||||||
Options options = NetworkUtils.getOptions( uri.getHost(), socketAddress );
|
Options options = NetworkUtils.getOptions( uri.getHost(), socketAddress );
|
||||||
SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;
|
SslContext sslContext = ssl ? NetworkUtils.getSslContext() : null;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ package dan200.computercraft.core.asm;
|
|||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.lua.LuaFunction;
|
import dan200.computercraft.api.lua.LuaFunction;
|
||||||
import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
|
import dan200.computercraft.shared.peripheral.generic.GenericPeripheralProvider;
|
||||||
|
import dan200.computercraft.shared.util.ServiceUtil;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@@ -16,11 +17,12 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.ServiceLoader;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic source of {@link LuaMethod} functions. This allows for injecting methods onto objects you do not own.
|
* A generic source of {@link LuaMethod} functions. This allows for injecting methods onto objects you do not own.
|
||||||
@@ -42,6 +44,18 @@ public interface GenericSource
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
ResourceLocation id();
|
ResourceLocation id();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a stream of generic sources.
|
||||||
|
*
|
||||||
|
* @param sources The source of generic methods.
|
||||||
|
* @see ServiceUtil For ways to load this. Sadly {@link java.util.ServiceLoader} is broken under Forge, but we don't
|
||||||
|
* want to add a hard-dep on Forge within core either.
|
||||||
|
*/
|
||||||
|
static void setup( Supplier<Stream<GenericSource>> sources )
|
||||||
|
{
|
||||||
|
GenericMethod.sources = sources;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A generic method is a method belonging to a {@link GenericSource} with a known target.
|
* A generic method is a method belonging to a {@link GenericSource} with a known target.
|
||||||
*/
|
*/
|
||||||
@@ -51,6 +65,7 @@ public interface GenericSource
|
|||||||
final LuaFunction annotation;
|
final LuaFunction annotation;
|
||||||
final Class<?> target;
|
final Class<?> target;
|
||||||
|
|
||||||
|
static Supplier<Stream<GenericSource>> sources;
|
||||||
private static List<GenericMethod> cache;
|
private static List<GenericMethod> cache;
|
||||||
|
|
||||||
GenericMethod( Method method, LuaFunction annotation, Class<?> target )
|
GenericMethod( Method method, LuaFunction annotation, Class<?> target )
|
||||||
@@ -68,10 +83,16 @@ public interface GenericSource
|
|||||||
static List<GenericMethod> all()
|
static List<GenericMethod> all()
|
||||||
{
|
{
|
||||||
if( cache != null ) return cache;
|
if( cache != null ) return cache;
|
||||||
return cache = StreamSupport
|
if( sources == null )
|
||||||
.stream( ServiceLoader.load( GenericSource.class, GenericSource.class.getClassLoader() ).spliterator(), false )
|
{
|
||||||
|
ComputerCraft.log.warn( "Getting GenericMethods without a provider" );
|
||||||
|
return cache = Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache = sources.get()
|
||||||
.flatMap( x -> Arrays.stream( x.getClass().getDeclaredMethods() ) )
|
.flatMap( x -> Arrays.stream( x.getClass().getDeclaredMethods() ) )
|
||||||
.map( method -> {
|
.map( method ->
|
||||||
|
{
|
||||||
LuaFunction annotation = method.getAnnotation( LuaFunction.class );
|
LuaFunction annotation = method.getAnnotation( LuaFunction.class );
|
||||||
if( annotation == null ) return null;
|
if( annotation == null ) return null;
|
||||||
|
|
||||||
|
|||||||
@@ -395,14 +395,7 @@ public final class ComputerThread
|
|||||||
executor.timeout.hardAbort();
|
executor.timeout.hardAbort();
|
||||||
executor.abort();
|
executor.abort();
|
||||||
|
|
||||||
if( afterHardAbort >= ABORT_TIMEOUT )
|
if( afterHardAbort >= ABORT_TIMEOUT * 2 )
|
||||||
{
|
|
||||||
// If we've hard aborted but we're still not dead, dump the stack trace and interrupt
|
|
||||||
// the task.
|
|
||||||
timeoutTask( executor, runner.owner, afterStart );
|
|
||||||
runner.owner.interrupt();
|
|
||||||
}
|
|
||||||
else if( afterHardAbort >= ABORT_TIMEOUT * 2 )
|
|
||||||
{
|
{
|
||||||
// If we've hard aborted and interrupted, and we're still not dead, then mark the runner
|
// If we've hard aborted and interrupted, and we're still not dead, then mark the runner
|
||||||
// as dead, finish off the task, and spawn a new runner.
|
// as dead, finish off the task, and spawn a new runner.
|
||||||
@@ -421,6 +414,13 @@ public final class ComputerThread
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( afterHardAbort >= ABORT_TIMEOUT )
|
||||||
|
{
|
||||||
|
// If we've hard aborted but we're still not dead, dump the stack trace and interrupt
|
||||||
|
// the task.
|
||||||
|
timeoutTask( executor, runner.owner, afterStart );
|
||||||
|
runner.owner.interrupt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ public class FileSystemWrapperMount implements IFileSystem
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return m_filesystem.exists( path );
|
return m_filesystem.isDir( path );
|
||||||
}
|
}
|
||||||
catch( FileSystemException e )
|
catch( FileSystemException e )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -83,9 +83,9 @@ class VarargArguments implements IArguments
|
|||||||
public ByteBuffer getBytes( int index ) throws LuaException
|
public ByteBuffer getBytes( int index ) throws LuaException
|
||||||
{
|
{
|
||||||
LuaValue value = varargs.arg( index + 1 );
|
LuaValue value = varargs.arg( index + 1 );
|
||||||
if( !(value instanceof LuaString) ) throw LuaValues.badArgument( index, "string", value.typeName() );
|
if( !(value instanceof LuaBaseString) ) throw LuaValues.badArgument( index, "string", value.typeName() );
|
||||||
|
|
||||||
LuaString str = (LuaString) value;
|
LuaString str = ((LuaBaseString) value).strvalue();
|
||||||
return ByteBuffer.wrap( str.bytes, str.offset, str.length ).asReadOnlyBuffer();
|
return ByteBuffer.wrap( str.bytes, str.offset, str.length ).asReadOnlyBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,9 +94,9 @@ class VarargArguments implements IArguments
|
|||||||
{
|
{
|
||||||
LuaValue value = varargs.arg( index + 1 );
|
LuaValue value = varargs.arg( index + 1 );
|
||||||
if( value.isNil() ) return Optional.empty();
|
if( value.isNil() ) return Optional.empty();
|
||||||
if( !(value instanceof LuaString) ) throw LuaValues.badArgument( index, "string", value.typeName() );
|
if( !(value instanceof LuaBaseString) ) throw LuaValues.badArgument( index, "string", value.typeName() );
|
||||||
|
|
||||||
LuaString str = (LuaString) value;
|
LuaString str = ((LuaBaseString) value).strvalue();
|
||||||
return Optional.of( ByteBuffer.wrap( str.bytes, str.offset, str.length ).asReadOnlyBuffer() );
|
return Optional.of( ByteBuffer.wrap( str.bytes, str.offset, str.length ).asReadOnlyBuffer() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
package dan200.computercraft.data;
|
package dan200.computercraft.data;
|
||||||
|
|
||||||
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
|
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
|
||||||
import net.minecraft.data.BlockTagsProvider;
|
|
||||||
import net.minecraft.data.DataGenerator;
|
import net.minecraft.data.DataGenerator;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
@@ -24,6 +23,6 @@ public class Generators
|
|||||||
DataGenerator generator = event.getGenerator();
|
DataGenerator generator = event.getGenerator();
|
||||||
generator.addProvider( new Recipes( generator ) );
|
generator.addProvider( new Recipes( generator ) );
|
||||||
generator.addProvider( new LootTables( generator ) );
|
generator.addProvider( new LootTables( generator ) );
|
||||||
generator.addProvider( new Tags( generator, new BlockTagsProvider( generator ) ) );
|
generator.addProvider( new Tags( generator, event.getExistingFileHelper() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public abstract class LootTableProvider implements IDataProvider
|
|||||||
tables.put( id, table );
|
tables.put( id, table );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
tables.forEach( ( key, value ) -> LootTableManager.func_227508_a_( validation, key, value ) );
|
tables.forEach( ( key, value ) -> LootTableManager.validateLootTable( validation, key, value ) );
|
||||||
|
|
||||||
Multimap<String, String> problems = validation.getProblems();
|
Multimap<String, String> problems = validation.getProblems();
|
||||||
if( !problems.isEmpty() )
|
if( !problems.isEmpty() )
|
||||||
|
|||||||
@@ -15,12 +15,13 @@ import net.minecraft.item.Item;
|
|||||||
import net.minecraft.tags.ITag;
|
import net.minecraft.tags.ITag;
|
||||||
import net.minecraft.tags.ItemTags;
|
import net.minecraft.tags.ItemTags;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
|
||||||
import static dan200.computercraft.data.Tags.CCTags.*;
|
import static dan200.computercraft.data.Tags.CCTags.*;
|
||||||
|
|
||||||
public class Tags extends ItemTagsProvider
|
public class Tags extends ItemTagsProvider
|
||||||
{
|
{
|
||||||
private static final ITag.INamedTag<Item> PIGLIN_LOVED = ItemTags.field_232903_N_;
|
private static final ITag.INamedTag<Item> PIGLIN_LOVED = ItemTags.PIGLIN_LOVED;
|
||||||
|
|
||||||
public static class CCTags
|
public static class CCTags
|
||||||
{
|
{
|
||||||
@@ -30,24 +31,24 @@ public class Tags extends ItemTagsProvider
|
|||||||
public static final ITag.INamedTag<Item> MONITOR = item( "monitor" );
|
public static final ITag.INamedTag<Item> MONITOR = item( "monitor" );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tags( DataGenerator generator, BlockTagsProvider tags )
|
public Tags( DataGenerator generator, ExistingFileHelper helper )
|
||||||
{
|
{
|
||||||
super( generator, tags );
|
super( generator, new BlockTagsProvider( generator, ComputerCraft.MOD_ID, helper ), ComputerCraft.MOD_ID, helper );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void registerTags()
|
protected void registerTags()
|
||||||
{
|
{
|
||||||
func_240522_a_( COMPUTER ).func_240534_a_(
|
getOrCreateBuilder( COMPUTER ).add(
|
||||||
Registry.ModItems.COMPUTER_NORMAL.get(),
|
Registry.ModItems.COMPUTER_NORMAL.get(),
|
||||||
Registry.ModItems.COMPUTER_ADVANCED.get(),
|
Registry.ModItems.COMPUTER_ADVANCED.get(),
|
||||||
Registry.ModItems.COMPUTER_COMMAND.get()
|
Registry.ModItems.COMPUTER_COMMAND.get()
|
||||||
);
|
);
|
||||||
func_240522_a_( TURTLE ).func_240534_a_( Registry.ModItems.TURTLE_NORMAL.get(), Registry.ModItems.TURTLE_ADVANCED.get() );
|
getOrCreateBuilder( TURTLE ).add( Registry.ModItems.TURTLE_NORMAL.get(), Registry.ModItems.TURTLE_ADVANCED.get() );
|
||||||
func_240522_a_( WIRED_MODEM ).func_240534_a_( Registry.ModItems.WIRED_MODEM.get(), Registry.ModItems.WIRED_MODEM_FULL.get() );
|
getOrCreateBuilder( WIRED_MODEM ).add( Registry.ModItems.WIRED_MODEM.get(), Registry.ModItems.WIRED_MODEM_FULL.get() );
|
||||||
func_240522_a_( MONITOR ).func_240534_a_( Registry.ModItems.MONITOR_NORMAL.get(), Registry.ModItems.MONITOR_ADVANCED.get() );
|
getOrCreateBuilder( MONITOR ).add( Registry.ModItems.MONITOR_NORMAL.get(), Registry.ModItems.MONITOR_ADVANCED.get() );
|
||||||
|
|
||||||
func_240522_a_( PIGLIN_LOVED ).func_240534_a_(
|
getOrCreateBuilder( PIGLIN_LOVED ).add(
|
||||||
Registry.ModItems.COMPUTER_ADVANCED.get(), Registry.ModItems.TURTLE_ADVANCED.get(),
|
Registry.ModItems.COMPUTER_ADVANCED.get(), Registry.ModItems.TURTLE_ADVANCED.get(),
|
||||||
Registry.ModItems.WIRELESS_MODEM_ADVANCED.get(), Registry.ModItems.POCKET_COMPUTER_ADVANCED.get(),
|
Registry.ModItems.WIRELESS_MODEM_ADVANCED.get(), Registry.ModItems.POCKET_COMPUTER_ADVANCED.get(),
|
||||||
Registry.ModItems.MONITOR_ADVANCED.get()
|
Registry.ModItems.MONITOR_ADVANCED.get()
|
||||||
|
|||||||
@@ -82,8 +82,6 @@ public final class Config
|
|||||||
private static final ConfigValue<Integer> monitorWidth;
|
private static final ConfigValue<Integer> monitorWidth;
|
||||||
private static final ConfigValue<Integer> monitorHeight;
|
private static final ConfigValue<Integer> monitorHeight;
|
||||||
|
|
||||||
private static final ConfigValue<Boolean> genericPeripheral;
|
|
||||||
|
|
||||||
private static final ConfigValue<MonitorRenderer> monitorRenderer;
|
private static final ConfigValue<MonitorRenderer> monitorRenderer;
|
||||||
private static final ConfigValue<Integer> monitorDistance;
|
private static final ConfigValue<Integer> monitorDistance;
|
||||||
|
|
||||||
@@ -294,17 +292,6 @@ public final class Config
|
|||||||
builder.pop();
|
builder.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
builder.comment( "Options for various experimental features. These are not guaranteed to be stable, and may change or be removed across versions." );
|
|
||||||
builder.push( "experimental" );
|
|
||||||
|
|
||||||
genericPeripheral = builder
|
|
||||||
.comment( "Attempt to make any existing block (or tile entity) a peripheral.\n" +
|
|
||||||
"This provides peripheral methods for any inventory, fluid tank or energy storage block. It will" +
|
|
||||||
"_not_ provide methods which have an existing peripheral provider." )
|
|
||||||
.define( "generic_peripherals", false );
|
|
||||||
}
|
|
||||||
|
|
||||||
serverSpec = builder.build();
|
serverSpec = builder.build();
|
||||||
|
|
||||||
Builder clientBuilder = new Builder();
|
Builder clientBuilder = new Builder();
|
||||||
@@ -379,9 +366,6 @@ public final class Config
|
|||||||
ComputerCraft.monitorWidth = monitorWidth.get();
|
ComputerCraft.monitorWidth = monitorWidth.get();
|
||||||
ComputerCraft.monitorHeight = monitorHeight.get();
|
ComputerCraft.monitorHeight = monitorHeight.get();
|
||||||
|
|
||||||
// Experimental
|
|
||||||
ComputerCraft.genericPeripheral = genericPeripheral.get();
|
|
||||||
|
|
||||||
// Client
|
// Client
|
||||||
ComputerCraft.monitorRenderer = monitorRenderer.get();
|
ComputerCraft.monitorRenderer = monitorRenderer.get();
|
||||||
ComputerCraft.monitorDistanceSq = monitorDistance.get() * monitorDistance.get();
|
ComputerCraft.monitorDistanceSq = monitorDistance.get() * monitorDistance.get();
|
||||||
|
|||||||
@@ -289,11 +289,11 @@ public final class CommandComputerCraft
|
|||||||
// Append the computer instance
|
// Append the computer instance
|
||||||
if( serverComputer == null )
|
if( serverComputer == null )
|
||||||
{
|
{
|
||||||
out.func_230529_a_( text( "?" ) );
|
out.append( text( "?" ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out.func_230529_a_( link(
|
out.append( link(
|
||||||
text( Integer.toString( serverComputer.getInstanceID() ) ),
|
text( Integer.toString( serverComputer.getInstanceID() ) ),
|
||||||
"/computercraft dump " + serverComputer.getInstanceID(),
|
"/computercraft dump " + serverComputer.getInstanceID(),
|
||||||
translate( "commands.computercraft.dump.action" )
|
translate( "commands.computercraft.dump.action" )
|
||||||
@@ -301,20 +301,20 @@ public final class CommandComputerCraft
|
|||||||
}
|
}
|
||||||
|
|
||||||
// And ID
|
// And ID
|
||||||
out.func_240702_b_( " (id " + computerId + ")" );
|
out.appendString( " (id " + computerId + ")" );
|
||||||
|
|
||||||
// And, if we're a player, some useful links
|
// And, if we're a player, some useful links
|
||||||
if( serverComputer != null && UserLevel.OP.test( source ) && isPlayer( source ) )
|
if( serverComputer != null && UserLevel.OP.test( source ) && isPlayer( source ) )
|
||||||
{
|
{
|
||||||
out
|
out
|
||||||
.func_240702_b_( " " )
|
.appendString( " " )
|
||||||
.func_230529_a_( link(
|
.append( link(
|
||||||
text( "\u261b" ),
|
text( "\u261b" ),
|
||||||
"/computercraft tp " + serverComputer.getInstanceID(),
|
"/computercraft tp " + serverComputer.getInstanceID(),
|
||||||
translate( "commands.computercraft.tp.action" )
|
translate( "commands.computercraft.tp.action" )
|
||||||
) )
|
) )
|
||||||
.func_240702_b_( " " )
|
.appendString( " " )
|
||||||
.func_230529_a_( link(
|
.append( link(
|
||||||
text( "\u20e2" ),
|
text( "\u20e2" ),
|
||||||
"/computercraft view " + serverComputer.getInstanceID(),
|
"/computercraft view " + serverComputer.getInstanceID(),
|
||||||
translate( "commands.computercraft.view.action" )
|
translate( "commands.computercraft.view.action" )
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import net.minecraft.client.Minecraft;
|
|||||||
import net.minecraft.command.CommandSource;
|
import net.minecraft.command.CommandSource;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
|
import net.minecraft.util.text.Style;
|
||||||
import net.minecraft.util.text.TranslationTextComponent;
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
import net.minecraft.util.text.event.ClickEvent;
|
import net.minecraft.util.text.event.ClickEvent;
|
||||||
import net.minecraft.util.text.event.HoverEvent;
|
import net.minecraft.util.text.event.HoverEvent;
|
||||||
@@ -57,10 +58,8 @@ public final class CommandCopy
|
|||||||
|
|
||||||
public static ITextComponent createCopyText( String text )
|
public static ITextComponent createCopyText( String text )
|
||||||
{
|
{
|
||||||
StringTextComponent name = new StringTextComponent( text );
|
return new StringTextComponent( text ).mergeStyle( Style.EMPTY
|
||||||
name.getStyle()
|
|
||||||
.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, PREFIX + text ) )
|
.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, PREFIX + text ) )
|
||||||
.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new TranslationTextComponent( "gui.computercraft.tooltip.copy" ) ) );
|
.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, new TranslationTextComponent( "gui.computercraft.tooltip.copy" ) ) ) );
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,11 +175,11 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
|
|||||||
String usage = dispatcher.getSmartUsage( temp, context.getSource() ).get( node ).substring( node.getName().length() );
|
String usage = dispatcher.getSmartUsage( temp, context.getSource() ).get( node ).substring( node.getName().length() );
|
||||||
|
|
||||||
IFormattableTextComponent output = new StringTextComponent( "" )
|
IFormattableTextComponent output = new StringTextComponent( "" )
|
||||||
.func_230529_a_( coloured( "/" + command + usage, HEADER ) )
|
.append( coloured( "/" + command + usage, HEADER ) )
|
||||||
.func_240702_b_( " " )
|
.appendString( " " )
|
||||||
.func_230529_a_( coloured( translate( "commands." + id + ".synopsis" ), SYNOPSIS ) )
|
.append( coloured( translate( "commands." + id + ".synopsis" ), SYNOPSIS ) )
|
||||||
.func_240702_b_( "\n" )
|
.appendString( "\n" )
|
||||||
.func_230529_a_( translate( "commands." + id + ".desc" ) );
|
.append( translate( "commands." + id + ".desc" ) );
|
||||||
|
|
||||||
for( CommandNode<CommandSource> child : node.getChildren() )
|
for( CommandNode<CommandSource> child : node.getChildren() )
|
||||||
{
|
{
|
||||||
@@ -188,16 +188,16 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
output.func_240702_b_( "\n" );
|
output.appendString( "\n" );
|
||||||
|
|
||||||
IFormattableTextComponent component = coloured( child.getName(), NAME );
|
IFormattableTextComponent component = coloured( child.getName(), NAME );
|
||||||
component.getStyle().setClickEvent( new ClickEvent(
|
component.getStyle().setClickEvent( new ClickEvent(
|
||||||
ClickEvent.Action.SUGGEST_COMMAND,
|
ClickEvent.Action.SUGGEST_COMMAND,
|
||||||
"/" + command + " " + child.getName()
|
"/" + command + " " + child.getName()
|
||||||
) );
|
) );
|
||||||
output.func_230529_a_( component );
|
output.append( component );
|
||||||
|
|
||||||
output.func_240702_b_( " - " ).func_230529_a_( translate( "commands." + id + "." + child.getName() + ".synopsis" ) );
|
output.appendString( " - " ).append( translate( "commands." + id + "." + child.getName() + ".synopsis" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|||||||
@@ -21,14 +21,12 @@ public final class ChatHelpers
|
|||||||
|
|
||||||
public static IFormattableTextComponent coloured( String text, TextFormatting colour )
|
public static IFormattableTextComponent coloured( String text, TextFormatting colour )
|
||||||
{
|
{
|
||||||
IFormattableTextComponent component = new StringTextComponent( text == null ? "" : text );
|
return new StringTextComponent( text == null ? "" : text ).mergeStyle( colour );
|
||||||
component.getStyle().setFormatting( colour );
|
|
||||||
return component;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends IFormattableTextComponent> T coloured( T component, TextFormatting colour )
|
public static <T extends IFormattableTextComponent> T coloured( T component, TextFormatting colour )
|
||||||
{
|
{
|
||||||
component.getStyle().setFormatting( colour );
|
component.mergeStyle( colour );
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +50,7 @@ public final class ChatHelpers
|
|||||||
IFormattableTextComponent component = new StringTextComponent( "" );
|
IFormattableTextComponent component = new StringTextComponent( "" );
|
||||||
for( ITextComponent child : children )
|
for( ITextComponent child : children )
|
||||||
{
|
{
|
||||||
component.func_230529_a_( child );
|
component.append( child );
|
||||||
}
|
}
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
@@ -74,11 +72,11 @@ public final class ChatHelpers
|
|||||||
{
|
{
|
||||||
Style style = component.getStyle();
|
Style style = component.getStyle();
|
||||||
|
|
||||||
if( style.getColor() == null ) style.setFormatting( TextFormatting.YELLOW );
|
if( style.getColor() == null ) style = style.setFormatting( TextFormatting.YELLOW );
|
||||||
style.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, command ) );
|
style = style.setClickEvent( new ClickEvent( ClickEvent.Action.RUN_COMMAND, command ) );
|
||||||
style.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, toolTip ) );
|
style = style.setHoverEvent( new HoverEvent( HoverEvent.Action.SHOW_TEXT, toolTip ) );
|
||||||
|
|
||||||
return component;
|
return component.setStyle( style );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IFormattableTextComponent header( String text )
|
public static IFormattableTextComponent header( String text )
|
||||||
|
|||||||
@@ -79,12 +79,12 @@ public interface TableFormatter
|
|||||||
StringTextComponent line = new StringTextComponent( "" );
|
StringTextComponent line = new StringTextComponent( "" );
|
||||||
for( int i = 0; i < columns - 1; i++ )
|
for( int i = 0; i < columns - 1; i++ )
|
||||||
{
|
{
|
||||||
line.func_230529_a_( headers[i] );
|
line.append( headers[i] );
|
||||||
ITextComponent padding = getPadding( headers[i], maxWidths[i] );
|
ITextComponent padding = getPadding( headers[i], maxWidths[i] );
|
||||||
if( padding != null ) line.func_230529_a_( padding );
|
if( padding != null ) line.append( padding );
|
||||||
line.func_230529_a_( SEPARATOR );
|
line.append( SEPARATOR );
|
||||||
}
|
}
|
||||||
line.func_230529_a_( headers[columns - 1] );
|
line.append( headers[columns - 1] );
|
||||||
|
|
||||||
writeLine( rowId++, line );
|
writeLine( rowId++, line );
|
||||||
|
|
||||||
@@ -100,12 +100,12 @@ public interface TableFormatter
|
|||||||
StringTextComponent line = new StringTextComponent( "" );
|
StringTextComponent line = new StringTextComponent( "" );
|
||||||
for( int i = 0; i < columns - 1; i++ )
|
for( int i = 0; i < columns - 1; i++ )
|
||||||
{
|
{
|
||||||
line.func_230529_a_( row[i] );
|
line.append( row[i] );
|
||||||
ITextComponent padding = getPadding( row[i], maxWidths[i] );
|
ITextComponent padding = getPadding( row[i], maxWidths[i] );
|
||||||
if( padding != null ) line.func_230529_a_( padding );
|
if( padding != null ) line.append( padding );
|
||||||
line.func_230529_a_( SEPARATOR );
|
line.append( SEPARATOR );
|
||||||
}
|
}
|
||||||
line.func_230529_a_( row[columns - 1] );
|
line.append( row[columns - 1] );
|
||||||
writeLine( rowId++, line );
|
writeLine( rowId++, line );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ public class CommandAPI implements ILuaAPI
|
|||||||
* @param command The command to execute.
|
* @param command The command to execute.
|
||||||
* @return The "task id". When this command has been executed, it will queue a `task_complete` event with a matching id.
|
* @return The "task id". When this command has been executed, it will queue a `task_complete` event with a matching id.
|
||||||
* @throws LuaException (hidden) If the task cannot be created.
|
* @throws LuaException (hidden) If the task cannot be created.
|
||||||
* @cc.tparam string command The command to execute.
|
|
||||||
* @cc.usage Asynchronously sets the block above the computer to stone.
|
* @cc.usage Asynchronously sets the block above the computer to stone.
|
||||||
* <pre>
|
* <pre>
|
||||||
* commands.execAsync("~ ~1 ~ minecraft:stone")
|
* commands.execAsync("~ ~1 ~ minecraft:stone")
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ import net.minecraft.util.Direction;
|
|||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
|
import net.minecraft.world.IWorldReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.server.ServerWorld;
|
import net.minecraft.world.server.ServerWorld;
|
||||||
import net.minecraftforge.fml.RegistryObject;
|
import net.minecraftforge.fml.RegistryObject;
|
||||||
@@ -138,6 +140,7 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
|
|||||||
public void onBlockHarvested( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull PlayerEntity player )
|
public void onBlockHarvested( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull PlayerEntity player )
|
||||||
{
|
{
|
||||||
if( !(world instanceof ServerWorld) ) return;
|
if( !(world instanceof ServerWorld) ) return;
|
||||||
|
ServerWorld serverWorld = (ServerWorld) world;
|
||||||
|
|
||||||
// We drop the item here instead of doing it in the harvest method, as we should
|
// We drop the item here instead of doing it in the harvest method, as we should
|
||||||
// drop computers for creative players too.
|
// drop computers for creative players too.
|
||||||
@@ -146,19 +149,19 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
|
|||||||
if( tile instanceof TileComputerBase )
|
if( tile instanceof TileComputerBase )
|
||||||
{
|
{
|
||||||
TileComputerBase computer = (TileComputerBase) tile;
|
TileComputerBase computer = (TileComputerBase) tile;
|
||||||
LootContext.Builder context = new LootContext.Builder( (ServerWorld) world )
|
LootContext.Builder context = new LootContext.Builder( serverWorld )
|
||||||
.withRandom( world.rand )
|
.withRandom( world.rand )
|
||||||
.withParameter( LootParameters.POSITION, pos )
|
.withParameter( LootParameters.field_237457_g_, Vector3d.copyCentered( pos ) )
|
||||||
.withParameter( LootParameters.TOOL, player.getHeldItemMainhand() )
|
.withParameter( LootParameters.TOOL, player.getHeldItemMainhand() )
|
||||||
.withParameter( LootParameters.THIS_ENTITY, player )
|
.withParameter( LootParameters.THIS_ENTITY, player )
|
||||||
.withNullableParameter( LootParameters.BLOCK_ENTITY, tile )
|
.withParameter( LootParameters.BLOCK_ENTITY, tile )
|
||||||
.withDynamicDrop( DROP, ( ctx, out ) -> out.accept( getItem( computer ) ) );
|
.withDynamicDrop( DROP, ( ctx, out ) -> out.accept( getItem( computer ) ) );
|
||||||
for( ItemStack item : state.getDrops( context ) )
|
for( ItemStack item : state.getDrops( context ) )
|
||||||
{
|
{
|
||||||
spawnAsEntity( world, pos, item );
|
spawnAsEntity( world, pos, item );
|
||||||
}
|
}
|
||||||
|
|
||||||
state.spawnAdditionalDrops( world, pos, player.getHeldItemMainhand() );
|
state.spawnAdditionalDrops( serverWorld, pos, player.getHeldItemMainhand() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,4 +183,10 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
|
|||||||
if( label != null ) computer.setLabel( label );
|
if( label != null ) computer.setLabel( label );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldCheckWeakPower( BlockState state, IWorldReader world, BlockPos pos, Direction side )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public abstract class ItemComputerBase extends BlockItem implements IComputerIte
|
|||||||
if( id >= 0 )
|
if( id >= 0 )
|
||||||
{
|
{
|
||||||
list.add( new TranslationTextComponent( "gui.computercraft.tooltip.computer_id", id )
|
list.add( new TranslationTextComponent( "gui.computercraft.tooltip.computer_id", id )
|
||||||
.func_240699_a_( TextFormatting.GRAY ) );
|
.mergeStyle( TextFormatting.GRAY ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,13 +29,13 @@ public final class ConstantLootConditionSerializer<T extends ILootCondition> imp
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void func_230424_a_( @Nonnull JsonObject json, @Nonnull T object, @Nonnull JsonSerializationContext context )
|
public void serialize( @Nonnull JsonObject json, @Nonnull T object, @Nonnull JsonSerializationContext context )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public T func_230423_a_( @Nonnull JsonObject json, @Nonnull JsonDeserializationContext context )
|
public T deserialize( @Nonnull JsonObject json, @Nonnull JsonDeserializationContext context )
|
||||||
{
|
{
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class ItemDisk extends Item implements IMedia, IColouredItem
|
|||||||
if( id >= 0 )
|
if( id >= 0 )
|
||||||
{
|
{
|
||||||
list.add( new TranslationTextComponent( "gui.computercraft.tooltip.disk_id", id )
|
list.add( new TranslationTextComponent( "gui.computercraft.tooltip.disk_id", id )
|
||||||
.func_240699_a_( TextFormatting.GRAY ) );
|
.mergeStyle( TextFormatting.GRAY ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public final class NetworkHandler
|
|||||||
|
|
||||||
public static void sendToAllAround( NetworkMessage packet, World world, Vector3d pos, double range )
|
public static void sendToAllAround( NetworkMessage packet, World world, Vector3d pos, double range )
|
||||||
{
|
{
|
||||||
PacketDistributor.TargetPoint target = new PacketDistributor.TargetPoint( pos.x, pos.y, pos.z, range, world.func_234923_W_() );
|
PacketDistributor.TargetPoint target = new PacketDistributor.TargetPoint( pos.x, pos.y, pos.z, range, world.getDimensionKey() );
|
||||||
network.send( PacketDistributor.NEAR.with( () -> target ), packet );
|
network.send( PacketDistributor.NEAR.with( () -> target ), packet );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,8 @@ import net.minecraft.util.text.StringTextComponent;
|
|||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent;
|
import net.minecraftforge.fml.network.NetworkEvent;
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts or stops a record on the client, depending on if {@link #soundEvent} is {@code null}.
|
* Starts or stops a record on the client, depending on if {@link #soundEvent} is {@code null}.
|
||||||
@@ -52,7 +50,7 @@ public class PlayRecordClientMessage implements NetworkMessage
|
|||||||
if( buf.readBoolean() )
|
if( buf.readBoolean() )
|
||||||
{
|
{
|
||||||
name = buf.readString( Short.MAX_VALUE );
|
name = buf.readString( Short.MAX_VALUE );
|
||||||
soundEvent = ForgeRegistries.SOUND_EVENTS.getValue( buf.readResourceLocation() );
|
soundEvent = buf.readRegistryIdSafe( SoundEvent.class );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -73,7 +71,7 @@ public class PlayRecordClientMessage implements NetworkMessage
|
|||||||
{
|
{
|
||||||
buf.writeBoolean( true );
|
buf.writeBoolean( true );
|
||||||
buf.writeString( name );
|
buf.writeString( name );
|
||||||
buf.writeResourceLocation( Objects.requireNonNull( soundEvent.getRegistryName(), "Sound is not registered" ) );
|
buf.writeRegistryId( soundEvent );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,8 @@ public class DiskDrivePeripheral implements IPeripheral
|
|||||||
/**
|
/**
|
||||||
* Returns the title of the inserted audio disk.
|
* Returns the title of the inserted audio disk.
|
||||||
*
|
*
|
||||||
* @return The title of the audio, or {@code nil} if no audio disk is inserted.
|
* @return The title of the audio, or {@code false} if no audio disk is inserted.
|
||||||
|
* @cc.treturn string|nil|false The title of the audio, {@code false} if no disk is inserted, or {@code nil} if the disk has no audio.
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
|||||||
public void read( @Nonnull BlockState state, @Nonnull CompoundNBT nbt )
|
public void read( @Nonnull BlockState state, @Nonnull CompoundNBT nbt )
|
||||||
{
|
{
|
||||||
super.read( state, nbt );
|
super.read( state, nbt );
|
||||||
customName = nbt.contains( NBT_NAME ) ? ITextComponent.Serializer.func_240643_a_( nbt.getString( NBT_NAME ) ) : null;
|
customName = nbt.contains( NBT_NAME ) ? ITextComponent.Serializer.getComponentFromJson( nbt.getString( NBT_NAME ) ) : null;
|
||||||
if( nbt.contains( NBT_ITEM ) )
|
if( nbt.contains( NBT_ITEM ) )
|
||||||
{
|
{
|
||||||
CompoundNBT item = nbt.getCompound( NBT_ITEM );
|
CompoundNBT item = nbt.getCompound( NBT_ITEM );
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.peripheral.generic;
|
package dan200.computercraft.shared.peripheral.generic;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.core.asm.NamedMethod;
|
import dan200.computercraft.core.asm.NamedMethod;
|
||||||
import dan200.computercraft.core.asm.PeripheralMethod;
|
import dan200.computercraft.core.asm.PeripheralMethod;
|
||||||
@@ -35,8 +34,6 @@ public class GenericPeripheralProvider
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
public static LazyOptional<IPeripheral> getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
|
public static LazyOptional<IPeripheral> getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
|
||||||
{
|
{
|
||||||
if( !ComputerCraft.genericPeripheral ) return LazyOptional.empty();
|
|
||||||
|
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile == null ) return LazyOptional.empty();
|
if( tile == null ) return LazyOptional.empty();
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
package dan200.computercraft.shared.peripheral.generic.data;
|
package dan200.computercraft.shared.peripheral.generic.data;
|
||||||
|
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
|
import dan200.computercraft.shared.util.NBTUtil;
|
||||||
import net.minecraft.enchantment.Enchantment;
|
import net.minecraft.enchantment.Enchantment;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.item.EnchantedBookItem;
|
import net.minecraft.item.EnchantedBookItem;
|
||||||
@@ -22,13 +23,26 @@ import javax.annotation.Nullable;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data providers for items.
|
||||||
|
*/
|
||||||
public class ItemData
|
public class ItemData
|
||||||
{
|
{
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static <T extends Map<? super String, Object>> T fillBasic( @Nonnull T data, @Nonnull ItemStack stack )
|
public static <T extends Map<? super String, Object>> T fillBasicSafe( @Nonnull T data, @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
data.put( "name", DataHelpers.getId( stack.getItem() ) );
|
data.put( "name", DataHelpers.getId( stack.getItem() ) );
|
||||||
data.put( "count", stack.getCount() );
|
data.put( "count", stack.getCount() );
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static <T extends Map<? super String, Object>> T fillBasic( @Nonnull T data, @Nonnull ItemStack stack )
|
||||||
|
{
|
||||||
|
fillBasicSafe( data, stack );
|
||||||
|
String hash = NBTUtil.getNBTHash( stack.getTag() );
|
||||||
|
if( hash != null ) data.put( "nbt", hash );
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +107,7 @@ public class ItemData
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return ITextComponent.Serializer.func_240643_a_( x.getString() );
|
return ITextComponent.Serializer.getComponentFromJson( x.getString() );
|
||||||
}
|
}
|
||||||
catch( JsonParseException e )
|
catch( JsonParseException e )
|
||||||
{
|
{
|
||||||
@@ -144,7 +158,7 @@ public class ItemData
|
|||||||
|
|
||||||
enchants.ensureCapacity( enchants.size() + rawEnchants.size() );
|
enchants.ensureCapacity( enchants.size() + rawEnchants.size() );
|
||||||
|
|
||||||
for( Map.Entry<Enchantment, Integer> entry : EnchantmentHelper.func_226652_a_( rawEnchants ).entrySet() )
|
for( Map.Entry<Enchantment, Integer> entry : EnchantmentHelper.deserializeEnchantments( rawEnchants ).entrySet() )
|
||||||
{
|
{
|
||||||
Enchantment enchantment = entry.getKey();
|
Enchantment enchantment = entry.getKey();
|
||||||
Integer level = entry.getValue();
|
Integer level = entry.getValue();
|
||||||
|
|||||||
@@ -207,9 +207,7 @@ public class BlockCable extends BlockGeneric implements IWaterLoggable
|
|||||||
Direction facing = state.get( MODEM ).getFacing();
|
Direction facing = state.get( MODEM ).getFacing();
|
||||||
if( facing == null ) return true;
|
if( facing == null ) return true;
|
||||||
|
|
||||||
BlockPos offsetPos = pos.offset( facing );
|
return hasEnoughSolidSide( world, pos.offset( facing ), facing.getOpposite() );
|
||||||
BlockState offsetState = world.getBlockState( offsetPos );
|
|
||||||
return hasSolidSide( offsetState, world, offsetPos, facing.getOpposite() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -217,8 +217,8 @@ public class TileWiredModemFull extends TileGeneric
|
|||||||
StringTextComponent base = new StringTextComponent( "" );
|
StringTextComponent base = new StringTextComponent( "" );
|
||||||
for( int i = 0; i < names.size(); i++ )
|
for( int i = 0; i < names.size(); i++ )
|
||||||
{
|
{
|
||||||
if( i > 0 ) base.func_240702_b_( ", " );
|
if( i > 0 ) base.appendString( ", " );
|
||||||
base.func_230529_a_( CommandCopy.createCopyText( names.get( i ) ) );
|
base.append( CommandCopy.createCopyText( names.get( i ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
player.sendStatusMessage( new TranslationTextComponent( kind, base ), false );
|
player.sendStatusMessage( new TranslationTextComponent( kind, base ), false );
|
||||||
|
|||||||
@@ -80,12 +80,10 @@ public class BlockWirelessModem extends BlockGeneric implements IWaterLoggable
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public boolean isValidPosition( BlockState state, IWorldReader world, BlockPos pos )
|
public boolean isValidPosition( BlockState state, @Nonnull IWorldReader world, BlockPos pos )
|
||||||
{
|
{
|
||||||
Direction facing = state.get( FACING );
|
Direction facing = state.get( FACING );
|
||||||
BlockPos offsetPos = pos.offset( facing );
|
return hasEnoughSolidSide( world, pos.offset( facing ), facing.getOpposite() );
|
||||||
BlockState offsetState = world.getBlockState( offsetPos );
|
|
||||||
return hasSolidSide( offsetState, world, offsetPos, facing.getOpposite() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public final class ClientMonitor extends ClientTerminal
|
|||||||
GL15.glBufferData( GL31.GL_TEXTURE_BUFFER, 0, GL15.GL_STATIC_DRAW );
|
GL15.glBufferData( GL31.GL_TEXTURE_BUFFER, 0, GL15.GL_STATIC_DRAW );
|
||||||
tboTexture = GlStateManager.genTexture();
|
tboTexture = GlStateManager.genTexture();
|
||||||
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, tboTexture );
|
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, tboTexture );
|
||||||
GL31.glTexBuffer( GL31.GL_TEXTURE_BUFFER, GL30.GL_R8, tboBuffer );
|
GL31.glTexBuffer( GL31.GL_TEXTURE_BUFFER, GL30.GL_R8UI, tboBuffer );
|
||||||
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, 0 );
|
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, 0 );
|
||||||
|
|
||||||
GlStateManager.bindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
|
GlStateManager.bindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import net.minecraft.inventory.IInventory;
|
|||||||
import net.minecraft.inventory.Inventory;
|
import net.minecraft.inventory.Inventory;
|
||||||
import net.minecraft.inventory.container.Container;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.inventory.container.Slot;
|
import net.minecraft.inventory.container.Slot;
|
||||||
import net.minecraft.item.DyeItem;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.IIntArray;
|
import net.minecraft.util.IIntArray;
|
||||||
import net.minecraft.util.IntArray;
|
import net.minecraft.util.IntArray;
|
||||||
@@ -95,7 +94,7 @@ public class ContainerPrinter extends Container
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Transfer from inventory to printer
|
// Transfer from inventory to printer
|
||||||
if( stack.getItem() instanceof DyeItem )
|
if( TilePrinter.isInk( stack ) )
|
||||||
{
|
{
|
||||||
if( !mergeItemStack( stack, 0, 1, false ) ) return ItemStack.EMPTY;
|
if( !mergeItemStack( stack, 0, 1, false ) ) return ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
|||||||
{
|
{
|
||||||
super.read( state, nbt );
|
super.read( state, nbt );
|
||||||
|
|
||||||
customName = nbt.contains( NBT_NAME ) ? ITextComponent.Serializer.func_240643_a_( nbt.getString( NBT_NAME ) ) : null;
|
customName = nbt.contains( NBT_NAME ) ? ITextComponent.Serializer.getComponentFromJson( nbt.getString( NBT_NAME ) ) : null;
|
||||||
|
|
||||||
// Read page
|
// Read page
|
||||||
synchronized( m_page )
|
synchronized( m_page )
|
||||||
@@ -300,9 +300,9 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isInk( @Nonnull ItemStack stack )
|
static boolean isInk( @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
return stack.getItem() instanceof DyeItem;
|
return ColourUtils.getStackColour( stack ) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPaper( @Nonnull ItemStack stack )
|
private static boolean isPaper( @Nonnull ItemStack stack )
|
||||||
@@ -321,7 +321,8 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
|||||||
private boolean inputPage()
|
private boolean inputPage()
|
||||||
{
|
{
|
||||||
ItemStack inkStack = m_inventory.get( 0 );
|
ItemStack inkStack = m_inventory.get( 0 );
|
||||||
if( !isInk( inkStack ) ) return false;
|
DyeColor dye = ColourUtils.getStackColour( inkStack );
|
||||||
|
if( dye == null ) return false;
|
||||||
|
|
||||||
for( int i = 1; i < 7; i++ )
|
for( int i = 1; i < 7; i++ )
|
||||||
{
|
{
|
||||||
@@ -329,8 +330,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
|||||||
if( paperStack.isEmpty() || !isPaper( paperStack ) ) continue;
|
if( paperStack.isEmpty() || !isPaper( paperStack ) ) continue;
|
||||||
|
|
||||||
// Setup the new page
|
// Setup the new page
|
||||||
DyeColor dye = ColourUtils.getStackColour( inkStack );
|
m_page.setTextColour( dye.getId() );
|
||||||
m_page.setTextColour( dye != null ? dye.getId() : 15 );
|
|
||||||
|
|
||||||
m_page.clear();
|
m_page.clear();
|
||||||
if( paperStack.getItem() instanceof ItemPrintout )
|
if( paperStack.getItem() instanceof ItemPrintout )
|
||||||
@@ -403,7 +403,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
|||||||
setInventorySlotContents( i, ItemStack.EMPTY );
|
setInventorySlotContents( i, ItemStack.EMPTY );
|
||||||
|
|
||||||
// Spawn the item in the world
|
// Spawn the item in the world
|
||||||
WorldUtil.dropItemStack( stack, getWorld(), Vector3d.func_237491_b_( getPos() ).add( 0.5, 0.75, 0.5 ) );
|
WorldUtil.dropItemStack( stack, getWorld(), Vector3d.copy( getPos() ).add( 0.5, 0.75, 0.5 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public abstract class SpeakerPeripheral implements IPeripheral
|
|||||||
|
|
||||||
float adjVolume = Math.min( volume, 3.0f );
|
float adjVolume = Math.min( volume, 3.0f );
|
||||||
server.getPlayerList().sendToAllNearExcept(
|
server.getPlayerList().sendToAllNearExcept(
|
||||||
null, pos.x, pos.y, pos.z, adjVolume > 1.0f ? 16 * adjVolume : 16.0, world.func_234923_W_(),
|
null, pos.x, pos.y, pos.z, adjVolume > 1.0f ? 16 * adjVolume : 16.0, world.getDimensionKey(),
|
||||||
new SPlaySoundPacket( name, SoundCategory.RECORDS, pos, adjVolume, pitch )
|
new SPlaySoundPacket( name, SoundCategory.RECORDS, pos, adjVolume, pitch )
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
|
|||||||
if( entity != null )
|
if( entity != null )
|
||||||
{
|
{
|
||||||
setWorld( entity.getEntityWorld() );
|
setWorld( entity.getEntityWorld() );
|
||||||
setPosition( entity.func_233580_cy_() );
|
setPosition( entity.getPosition() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a new entity has picked it up then rebroadcast the terminal to them
|
// If a new entity has picked it up then rebroadcast the terminal to them
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ public class ItemPocketComputer extends Item implements IComputerItem, IMedia, I
|
|||||||
if( id >= 0 )
|
if( id >= 0 )
|
||||||
{
|
{
|
||||||
list.add( new TranslationTextComponent( "gui.computercraft.tooltip.computer_id", id )
|
list.add( new TranslationTextComponent( "gui.computercraft.tooltip.computer_id", id )
|
||||||
.func_240699_a_( TextFormatting.GRAY ) );
|
.mergeStyle( TextFormatting.GRAY ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ import net.minecraft.util.ResourceLocation;
|
|||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
import net.minecraftforge.common.capabilities.CapabilityManager;
|
import net.minecraftforge.common.capabilities.CapabilityManager;
|
||||||
import net.minecraftforge.event.LootTableLoadEvent;
|
import net.minecraftforge.event.LootTableLoadEvent;
|
||||||
|
import net.minecraftforge.event.RegisterCommandsEvent;
|
||||||
import net.minecraftforge.event.TickEvent;
|
import net.minecraftforge.event.TickEvent;
|
||||||
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
|
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||||
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
|
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
|
||||||
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
|
||||||
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
|
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -71,7 +71,7 @@ public final class ComputerCraftProxyCommon
|
|||||||
|
|
||||||
private static void registerCondition( String name, LootConditionType serializer )
|
private static void registerCondition( String name, LootConditionType serializer )
|
||||||
{
|
{
|
||||||
Registry.register( Registry.field_239704_ba_, new ResourceLocation( ComputerCraft.MOD_ID, name ), serializer );
|
Registry.register( Registry.LOOT_CONDITION_TYPE, new ResourceLocation( ComputerCraft.MOD_ID, name ), serializer );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void registerProviders()
|
private static void registerProviders()
|
||||||
@@ -139,9 +139,9 @@ public final class ComputerCraftProxyCommon
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onServerStarting( FMLServerStartingEvent event )
|
public static void onRegisterCommand( RegisterCommandsEvent event )
|
||||||
{
|
{
|
||||||
CommandComputerCraft.register( event.getCommandDispatcher() );
|
CommandComputerCraft.register( event.getDispatcher() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|||||||
@@ -605,7 +605,7 @@ public class TurtleAPI implements ILuaAPI
|
|||||||
|
|
||||||
Map<String, Object> table = detailed
|
Map<String, Object> table = detailed
|
||||||
? ItemData.fill( new HashMap<>(), stack )
|
? ItemData.fill( new HashMap<>(), stack )
|
||||||
: ItemData.fillBasic( new HashMap<>(), stack );
|
: ItemData.fillBasicSafe( new HashMap<>(), stack );
|
||||||
|
|
||||||
TurtleActionEvent event = new TurtleInspectItemEvent( turtle, stack, table, detailed );
|
TurtleActionEvent event = new TurtleInspectItemEvent( turtle, stack, table, detailed );
|
||||||
if( MinecraftForge.EVENT_BUS.post( event ) ) return new Object[] { false, event.getFailureMessage() };
|
if( MinecraftForge.EVENT_BUS.post( event ) ) return new Object[] { false, event.getFailureMessage() };
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import net.minecraftforge.items.IItemHandlerModifiable;
|
|||||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@@ -598,7 +599,7 @@ public class TurtleBrain implements ITurtleAccess
|
|||||||
m_owningPlayer = profile;
|
m_owningPlayer = profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public GameProfile getOwningPlayer()
|
public GameProfile getOwningPlayer()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
|||||||
cancelResult = hitEntity.applyPlayerInteraction( turtlePlayer, hitPos, Hand.MAIN_HAND );
|
cancelResult = hitEntity.applyPlayerInteraction( turtlePlayer, hitPos, Hand.MAIN_HAND );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cancelResult == ActionResultType.SUCCESS )
|
if( cancelResult.isSuccessOrConsume() )
|
||||||
{
|
{
|
||||||
placed = true;
|
placed = true;
|
||||||
}
|
}
|
||||||
@@ -246,7 +246,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
|||||||
{
|
{
|
||||||
// See EntityPlayer.interactOn
|
// See EntityPlayer.interactOn
|
||||||
cancelResult = ForgeHooks.onInteractEntity( turtlePlayer, hitEntity, Hand.MAIN_HAND );
|
cancelResult = ForgeHooks.onInteractEntity( turtlePlayer, hitEntity, Hand.MAIN_HAND );
|
||||||
if( cancelResult == ActionResultType.SUCCESS )
|
if( cancelResult != null && cancelResult.isSuccessOrConsume() )
|
||||||
{
|
{
|
||||||
placed = true;
|
placed = true;
|
||||||
}
|
}
|
||||||
@@ -353,17 +353,15 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
|||||||
TileEntity existingTile = turtle.getWorld().getTileEntity( position );
|
TileEntity existingTile = turtle.getWorld().getTileEntity( position );
|
||||||
|
|
||||||
// See PlayerInteractionManager.processRightClickBlock
|
// See PlayerInteractionManager.processRightClickBlock
|
||||||
// TODO: ^ Check we're still consistent.
|
|
||||||
PlayerInteractEvent.RightClickBlock event = ForgeHooks.onRightClickBlock( turtlePlayer, Hand.MAIN_HAND, position, side );
|
PlayerInteractEvent.RightClickBlock event = ForgeHooks.onRightClickBlock( turtlePlayer, Hand.MAIN_HAND, position, side );
|
||||||
if( !event.isCanceled() )
|
if( !event.isCanceled() )
|
||||||
{
|
{
|
||||||
if( item.onItemUseFirst( stack, context ) == ActionResultType.SUCCESS )
|
if( item.onItemUseFirst( stack, context ).isSuccessOrConsume() )
|
||||||
{
|
{
|
||||||
placed = true;
|
placed = true;
|
||||||
turtlePlayer.loadInventory( stackCopy );
|
turtlePlayer.loadInventory( stackCopy );
|
||||||
}
|
}
|
||||||
else if( event.getUseItem() != Event.Result.DENY &&
|
else if( event.getUseItem() != Event.Result.DENY && stackCopy.onItemUse( context ).isSuccessOrConsume() )
|
||||||
stackCopy.onItemUse( context ) == ActionResultType.SUCCESS )
|
|
||||||
{
|
{
|
||||||
placed = true;
|
placed = true;
|
||||||
turtlePlayer.loadInventory( stackCopy );
|
turtlePlayer.loadInventory( stackCopy );
|
||||||
@@ -373,14 +371,14 @@ public class TurtlePlaceCommand implements ITurtleCommand
|
|||||||
if( !placed && (item instanceof BucketItem || item instanceof BoatItem || item instanceof LilyPadItem || item instanceof GlassBottleItem) )
|
if( !placed && (item instanceof BucketItem || item instanceof BoatItem || item instanceof LilyPadItem || item instanceof GlassBottleItem) )
|
||||||
{
|
{
|
||||||
ActionResultType actionResult = ForgeHooks.onItemRightClick( turtlePlayer, Hand.MAIN_HAND );
|
ActionResultType actionResult = ForgeHooks.onItemRightClick( turtlePlayer, Hand.MAIN_HAND );
|
||||||
if( actionResult == ActionResultType.SUCCESS )
|
if( actionResult != null && actionResult.isSuccessOrConsume() )
|
||||||
{
|
{
|
||||||
placed = true;
|
placed = true;
|
||||||
}
|
}
|
||||||
else if( actionResult == null )
|
else if( actionResult == null )
|
||||||
{
|
{
|
||||||
ActionResult<ItemStack> result = stackCopy.useItemRightClick( turtle.getWorld(), turtlePlayer, Hand.MAIN_HAND );
|
ActionResult<ItemStack> result = stackCopy.useItemRightClick( turtle.getWorld(), turtlePlayer, Hand.MAIN_HAND );
|
||||||
if( result.getType() == ActionResultType.SUCCESS && !ItemStack.areItemStacksEqual( stack, result.getResult() ) )
|
if( result.getType().isSuccessOrConsume() && !ItemStack.areItemStacksEqual( stack, result.getResult() ) )
|
||||||
{
|
{
|
||||||
placed = true;
|
placed = true;
|
||||||
turtlePlayer.loadInventory( result.getResult() );
|
turtlePlayer.loadInventory( result.getResult() );
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import net.minecraft.entity.EntitySize;
|
|||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.Pose;
|
import net.minecraft.entity.Pose;
|
||||||
import net.minecraft.entity.passive.horse.AbstractHorseEntity;
|
import net.minecraft.entity.passive.horse.AbstractHorseEntity;
|
||||||
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.inventory.IInventory;
|
import net.minecraft.inventory.IInventory;
|
||||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@@ -25,6 +26,7 @@ import net.minecraft.tileentity.SignTileEntity;
|
|||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraft.world.server.ServerWorld;
|
import net.minecraft.world.server.ServerWorld;
|
||||||
import net.minecraftforge.common.util.FakePlayer;
|
import net.minecraftforge.common.util.FakePlayer;
|
||||||
|
|
||||||
@@ -40,11 +42,30 @@ public final class TurtlePlayer extends FakePlayer
|
|||||||
"[ComputerCraft]"
|
"[ComputerCraft]"
|
||||||
);
|
);
|
||||||
|
|
||||||
private TurtlePlayer( ITurtleAccess turtle )
|
private TurtlePlayer( ServerWorld world, GameProfile name )
|
||||||
{
|
{
|
||||||
super( (ServerWorld) turtle.getWorld(), getProfile( turtle.getOwningPlayer() ) );
|
super( world, name );
|
||||||
this.connection = new FakeNetHandler( this );
|
}
|
||||||
setState( turtle );
|
|
||||||
|
private static TurtlePlayer create( ITurtleAccess turtle )
|
||||||
|
{
|
||||||
|
ServerWorld world = (ServerWorld) turtle.getWorld();
|
||||||
|
GameProfile profile = turtle.getOwningPlayer();
|
||||||
|
|
||||||
|
TurtlePlayer player = new TurtlePlayer( world, getProfile( profile ) );
|
||||||
|
player.connection = new FakeNetHandler( player );
|
||||||
|
player.setState( turtle );
|
||||||
|
|
||||||
|
if( profile != null && profile.getId() != null )
|
||||||
|
{
|
||||||
|
// Constructing a player overrides the "active player" variable in advancements. As fake players cannot
|
||||||
|
// get advancements, this prevents a normal player who has placed a turtle from getting advancements.
|
||||||
|
// We try to locate the "actual" player and restore them.
|
||||||
|
ServerPlayerEntity actualPlayer = world.getServer().getPlayerList().getPlayerByUUID( profile.getId() );
|
||||||
|
if( actualPlayer != null ) player.getAdvancements().setPlayer( actualPlayer );
|
||||||
|
}
|
||||||
|
|
||||||
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GameProfile getProfile( @Nullable GameProfile profile )
|
private static GameProfile getProfile( @Nullable GameProfile profile )
|
||||||
@@ -54,11 +75,10 @@ public final class TurtlePlayer extends FakePlayer
|
|||||||
|
|
||||||
private void setState( ITurtleAccess turtle )
|
private void setState( ITurtleAccess turtle )
|
||||||
{
|
{
|
||||||
if( openContainer != null )
|
if( openContainer != container )
|
||||||
{
|
{
|
||||||
ComputerCraft.log.warn( "Turtle has open container ({})", openContainer );
|
ComputerCraft.log.warn( "Turtle has open container ({})", openContainer );
|
||||||
openContainer.onContainerClosed( this );
|
closeContainer();
|
||||||
openContainer = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockPos position = turtle.getPosition();
|
BlockPos position = turtle.getPosition();
|
||||||
@@ -72,14 +92,14 @@ public final class TurtlePlayer extends FakePlayer
|
|||||||
|
|
||||||
public static TurtlePlayer get( ITurtleAccess access )
|
public static TurtlePlayer get( ITurtleAccess access )
|
||||||
{
|
{
|
||||||
if( !(access instanceof TurtleBrain) ) return new TurtlePlayer( access );
|
if( !(access instanceof TurtleBrain) ) return create( access );
|
||||||
|
|
||||||
TurtleBrain brain = (TurtleBrain) access;
|
TurtleBrain brain = (TurtleBrain) access;
|
||||||
TurtlePlayer player = brain.m_cachedPlayer;
|
TurtlePlayer player = brain.m_cachedPlayer;
|
||||||
if( player == null || player.getGameProfile() != getProfile( access.getOwningPlayer() )
|
if( player == null || player.getGameProfile() != getProfile( access.getOwningPlayer() )
|
||||||
|| player.getEntityWorld() != access.getWorld() )
|
|| player.getEntityWorld() != access.getWorld() )
|
||||||
{
|
{
|
||||||
player = brain.m_cachedPlayer = new TurtlePlayer( brain );
|
player = brain.m_cachedPlayer = create( brain );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -129,6 +149,12 @@ public final class TurtlePlayer extends FakePlayer
|
|||||||
return Registry.ModEntities.TURTLE_PLAYER.get();
|
return Registry.ModEntities.TURTLE_PLAYER.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3d getPositionVec()
|
||||||
|
{
|
||||||
|
return new Vector3d( getPosX(), getPosY(), getPosZ() );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getEyeHeight( @Nonnull Pose pose )
|
public float getEyeHeight( @Nonnull Pose pose )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
|
|||||||
protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player )
|
protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player )
|
||||||
{
|
{
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
return !state.isAir( world, pos )
|
return !state.isAir()
|
||||||
&& block != Blocks.BEDROCK
|
&& block != Blocks.BEDROCK
|
||||||
&& state.getPlayerRelativeBlockHardness( player, world, pos ) > 0
|
&& state.getPlayerRelativeBlockHardness( player, world, pos ) > 0
|
||||||
&& block.canEntityDestroy( state, world, pos, player );
|
&& block.canEntityDestroy( state, world, pos, player );
|
||||||
@@ -149,7 +149,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
|
|||||||
boolean attacked = false;
|
boolean attacked = false;
|
||||||
if( !hitEntity.hitByEntity( turtlePlayer ) )
|
if( !hitEntity.hitByEntity( turtlePlayer ) )
|
||||||
{
|
{
|
||||||
float damage = (float) turtlePlayer.func_233637_b_( Attributes.ATTACK_DAMAGE );
|
float damage = (float) turtlePlayer.getAttributeValue( Attributes.ATTACK_DAMAGE );
|
||||||
damage *= getDamageMultiplier();
|
damage *= getDamageMultiplier();
|
||||||
if( damage > 0.0f )
|
if( damage > 0.0f )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ public final class ColourUtils
|
|||||||
|
|
||||||
public static DyeColor getStackColour( ItemStack stack )
|
public static DyeColor getStackColour( ItemStack stack )
|
||||||
{
|
{
|
||||||
|
if( stack.isEmpty() ) return null;
|
||||||
|
|
||||||
for( int i = 0; i < DYES.length; i++ )
|
for( int i = 0; i < DYES.length; i++ )
|
||||||
{
|
{
|
||||||
ITag<Item> dye = DYES[i];
|
ITag<Item> dye = DYES[i];
|
||||||
|
|||||||
@@ -41,9 +41,7 @@ public final class DropConsumer
|
|||||||
remainingDrops = new ArrayList<>();
|
remainingDrops = new ArrayList<>();
|
||||||
dropEntity = entity;
|
dropEntity = entity;
|
||||||
dropWorld = entity.world;
|
dropWorld = entity.world;
|
||||||
dropBounds = new AxisAlignedBB( entity.func_233580_cy_() ).grow( 2, 2, 2 );
|
dropBounds = new AxisAlignedBB( entity.getPosition() ).grow( 2, 2, 2 );
|
||||||
|
|
||||||
entity.captureDrops( new ArrayList<>() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void set( World world, BlockPos pos, Function<ItemStack, ItemStack> consumer )
|
public static void set( World world, BlockPos pos, Function<ItemStack, ItemStack> consumer )
|
||||||
@@ -86,7 +84,7 @@ public final class DropConsumer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent( priority = EventPriority.LOW )
|
||||||
public static void onLivingDrops( LivingDropsEvent drops )
|
public static void onLivingDrops( LivingDropsEvent drops )
|
||||||
{
|
{
|
||||||
if( dropEntity == null || drops.getEntity() != dropEntity ) return;
|
if( dropEntity == null || drops.getEntity() != dropEntity ) return;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import net.minecraftforge.common.util.FakePlayer;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.crypto.SecretKey;
|
|
||||||
|
|
||||||
public class FakeNetHandler extends ServerPlayNetHandler
|
public class FakeNetHandler extends ServerPlayNetHandler
|
||||||
{
|
{
|
||||||
@@ -65,11 +64,6 @@ public class FakeNetHandler extends ServerPlayNetHandler
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleRecipeBookUpdate( @Nonnull CRecipeInfoPacket packet )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleSeenAdvancements( @Nonnull CSeenAdvancementsPacket packet )
|
public void handleSeenAdvancements( @Nonnull CSeenAdvancementsPacket packet )
|
||||||
{
|
{
|
||||||
@@ -327,11 +321,6 @@ public class FakeNetHandler extends ServerPlayNetHandler
|
|||||||
this.closeReason = message;
|
this.closeReason = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enableEncryption( @Nonnull SecretKey key )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public INetHandler getNetHandler()
|
public INetHandler getNetHandler()
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.google.gson.GsonBuilder;
|
|||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.world.storage.FolderName;
|
||||||
import net.minecraftforge.fml.server.ServerLifecycleHooks;
|
import net.minecraftforge.fml.server.ServerLifecycleHooks;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -25,6 +26,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
public final class IDAssigner
|
public final class IDAssigner
|
||||||
{
|
{
|
||||||
|
private static final FolderName FOLDER = new FolderName( ComputerCraft.MOD_ID );
|
||||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||||
private static final Type ID_TOKEN = new TypeToken<Map<String, Integer>>()
|
private static final Type ID_TOKEN = new TypeToken<Map<String, Integer>>()
|
||||||
{
|
{
|
||||||
@@ -40,9 +42,7 @@ public final class IDAssigner
|
|||||||
|
|
||||||
public static File getDir()
|
public static File getDir()
|
||||||
{
|
{
|
||||||
File root = ServerLifecycleHooks.getCurrentServer().getDataDirectory();
|
return ServerLifecycleHooks.getCurrentServer().func_240776_a_( FOLDER ).toFile();
|
||||||
// TODO: File worldDirectory = server.getWorld( World.field_234918_g_ ).getSaveHandler().getWorldDirectory();
|
|
||||||
return new File( root, ComputerCraft.MOD_ID );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MinecraftServer getCachedServer()
|
private static MinecraftServer getCachedServer()
|
||||||
|
|||||||
@@ -5,9 +5,19 @@
|
|||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.util;
|
package dan200.computercraft.shared.util;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
import net.minecraft.nbt.*;
|
import net.minecraft.nbt.*;
|
||||||
import net.minecraftforge.common.util.Constants;
|
import net.minecraftforge.common.util.Constants;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.DataOutput;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -159,4 +169,46 @@ public final class NBTUtil
|
|||||||
}
|
}
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static String getNBTHash( @Nullable CompoundNBT tag )
|
||||||
|
{
|
||||||
|
if( tag == null ) return null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MessageDigest digest = MessageDigest.getInstance( "MD5" );
|
||||||
|
DataOutput output = new DataOutputStream( new DigestOutputStream( digest ) );
|
||||||
|
CompressedStreamTools.write( tag, output );
|
||||||
|
byte[] hash = digest.digest();
|
||||||
|
return new String( Hex.encodeHex( hash ) );
|
||||||
|
}
|
||||||
|
catch( NoSuchAlgorithmException | IOException e )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.error( "Cannot hash NBT", e );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class DigestOutputStream extends OutputStream
|
||||||
|
{
|
||||||
|
private final MessageDigest digest;
|
||||||
|
|
||||||
|
DigestOutputStream( MessageDigest digest )
|
||||||
|
{
|
||||||
|
this.digest = digest;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write( @Nonnull byte[] b, int off, int len )
|
||||||
|
{
|
||||||
|
digest.update( b, off, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write( int b )
|
||||||
|
{
|
||||||
|
digest.update( (byte) b );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,6 @@ public final class RecordUtil
|
|||||||
public static void playRecord( SoundEvent record, String recordInfo, World world, BlockPos pos )
|
public static void playRecord( SoundEvent record, String recordInfo, World world, BlockPos pos )
|
||||||
{
|
{
|
||||||
NetworkMessage packet = record != null ? new PlayRecordClientMessage( pos, record, recordInfo ) : new PlayRecordClientMessage( pos );
|
NetworkMessage packet = record != null ? new PlayRecordClientMessage( pos, record, recordInfo ) : new PlayRecordClientMessage( pos );
|
||||||
NetworkHandler.sendToAllAround( packet, world, Vector3d.func_237489_a_( pos ), 64 );
|
NetworkHandler.sendToAllAround( packet, world, Vector3d.copyCentered( pos ), 64 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dan200.computercraft.shared.util;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.api.ComputerCraftAPI;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
public final class ServiceUtil
|
||||||
|
{
|
||||||
|
private static final Type AUTO_SERVICE = Type.getType( "Lcom/google/auto/service/AutoService;" );
|
||||||
|
|
||||||
|
private ServiceUtil()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Stream<T> loadServices( Class<T> target )
|
||||||
|
{
|
||||||
|
return StreamSupport.stream( ServiceLoader.load( target, ServiceUtil.class.getClassLoader() ).spliterator(), false );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Stream<T> loadServicesForge( Class<T> target )
|
||||||
|
{
|
||||||
|
Type type = Type.getType( target );
|
||||||
|
ClassLoader loader = ComputerCraftAPI.class.getClassLoader();
|
||||||
|
return ModList.get().getAllScanData().stream()
|
||||||
|
.flatMap( x -> x.getAnnotations().stream() )
|
||||||
|
.filter( x -> x.getAnnotationType().equals( AUTO_SERVICE ) )
|
||||||
|
.filter( x -> {
|
||||||
|
Object value = x.getAnnotationData().get( "value" );
|
||||||
|
return value instanceof List<?> && ((List<?>) value).contains( type );
|
||||||
|
} )
|
||||||
|
.flatMap( x -> {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class<?> klass = loader.loadClass( x.getClassType().getClassName() );
|
||||||
|
if( !target.isAssignableFrom( klass ) )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.error( "{} is not a subtype of {}", x.getClassType().getClassName(), target.getName() );
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<? extends T> casted = klass.asSubclass( target );
|
||||||
|
return Stream.of( casted.newInstance() );
|
||||||
|
}
|
||||||
|
catch( ReflectiveOperationException e )
|
||||||
|
{
|
||||||
|
ComputerCraft.log.error( "Cannot load {}", x.getClassType(), e );
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,3 +2,6 @@
|
|||||||
public net.minecraft.client.renderer.FirstPersonRenderer func_178100_c(F)F # getMapAngleFromPitch
|
public net.minecraft.client.renderer.FirstPersonRenderer func_178100_c(F)F # getMapAngleFromPitch
|
||||||
public net.minecraft.client.renderer.FirstPersonRenderer func_228401_a_(Lcom/mojang/blaze3d/matrix/MatrixStack;Lnet/minecraft/client/renderer/IRenderTypeBuffer;IFFLnet/minecraft/util/HandSide;)V # renderArmFirstPerson
|
public net.minecraft.client.renderer.FirstPersonRenderer func_228401_a_(Lcom/mojang/blaze3d/matrix/MatrixStack;Lnet/minecraft/client/renderer/IRenderTypeBuffer;IFFLnet/minecraft/util/HandSide;)V # renderArmFirstPerson
|
||||||
public net.minecraft.client.renderer.FirstPersonRenderer func_228403_a_(Lcom/mojang/blaze3d/matrix/MatrixStack;Lnet/minecraft/client/renderer/IRenderTypeBuffer;ILnet/minecraft/util/HandSide;)V # renderArm
|
public net.minecraft.client.renderer.FirstPersonRenderer func_228403_a_(Lcom/mojang/blaze3d/matrix/MatrixStack;Lnet/minecraft/client/renderer/IRenderTypeBuffer;ILnet/minecraft/util/HandSide;)V # renderArm
|
||||||
|
# ClientTableFormatter
|
||||||
|
public net.minecraft.client.gui.NewChatGui func_146234_a(Lnet/minecraft/util/text/ITextComponent;I)V # printChatMessageWithOptionalDeletion
|
||||||
|
public net.minecraft.client.gui.NewChatGui func_146242_c(I)V # deleteChatLine
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
modLoader="javafml"
|
modLoader="javafml"
|
||||||
loaderVersion="[32,33)"
|
loaderVersion="[35,36)"
|
||||||
|
|
||||||
issueTrackerURL="https://github.com/SquidDev-CC/CC-Tweaked/issues"
|
issueTrackerURL="https://github.com/SquidDev-CC/CC-Tweaked/issues"
|
||||||
displayURL="https://github.com/SquidDev-CC/CC-Tweaked"
|
displayURL="https://github.com/SquidDev-CC/CC-Tweaked"
|
||||||
@@ -7,6 +7,7 @@ logoFile="pack.png"
|
|||||||
|
|
||||||
credits="Created by Daniel Ratcliffe (@DanTwoHundred)"
|
credits="Created by Daniel Ratcliffe (@DanTwoHundred)"
|
||||||
authors="Daniel Ratcliffe, Aaron Mills, SquidDev"
|
authors="Daniel Ratcliffe, Aaron Mills, SquidDev"
|
||||||
|
license="ComputerCraft Public License (https://raw.githubusercontent.com/dan200/ComputerCraft/master/LICENSE)"
|
||||||
|
|
||||||
[[mods]]
|
[[mods]]
|
||||||
modId="computercraft"
|
modId="computercraft"
|
||||||
@@ -19,6 +20,6 @@ CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles a
|
|||||||
[[dependencies.computercraft]]
|
[[dependencies.computercraft]]
|
||||||
modId="forge"
|
modId="forge"
|
||||||
mandatory=true
|
mandatory=true
|
||||||
versionRange="[32.0.23,33)"
|
versionRange="[35.0.1,36)"
|
||||||
ordering="NONE"
|
ordering="NONE"
|
||||||
side="BOTH"
|
side="BOTH"
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"block.computercraft.computer_normal": "Dator",
|
"block.computercraft.computer_normal": "Dator",
|
||||||
"block.computercraft.computer_advanced": "Avancerad Dator",
|
"block.computercraft.computer_advanced": "Avancerad Dator",
|
||||||
"block.computercraft.computer_command": "Kommando Dator",
|
"block.computercraft.computer_command": "Kommandodator",
|
||||||
"block.computercraft.disk_drive": "Diskettläsare",
|
"block.computercraft.disk_drive": "Diskettläsare",
|
||||||
"block.computercraft.printer": "Skrivare",
|
"block.computercraft.printer": "Skrivare",
|
||||||
"block.computercraft.speaker": "Högtalare",
|
"block.computercraft.speaker": "Högtalare",
|
||||||
"block.computercraft.monitor_normal": "Skärm",
|
"block.computercraft.monitor_normal": "Skärm",
|
||||||
"block.computercraft.monitor_advanced": "Avancerad Skärm",
|
"block.computercraft.monitor_advanced": "Avancerad Skärm",
|
||||||
"block.computercraft.wireless_modem_normal": "Trådlöst Modem",
|
"block.computercraft.wireless_modem_normal": "Trådlöst Modem",
|
||||||
"block.computercraft.wireless_modem_advanced": "Ender Modem",
|
"block.computercraft.wireless_modem_advanced": "Endermodem",
|
||||||
"block.computercraft.wired_modem": "Trådat Modem",
|
"block.computercraft.wired_modem": "Trådat Modem",
|
||||||
"block.computercraft.cable": "Nätverkskabel",
|
"block.computercraft.cable": "Nätverkskabel",
|
||||||
"block.computercraft.wired_modem_full": "Trådat Modem",
|
"block.computercraft.wired_modem_full": "Trådat Modem",
|
||||||
@@ -38,5 +38,76 @@
|
|||||||
"upgrade.computercraft.speaker.adjective": "Högljudd",
|
"upgrade.computercraft.speaker.adjective": "Högljudd",
|
||||||
"chat.computercraft.wired_modem.peripheral_connected": "Kringutrustning \"%s\" är kopplad till nätverket",
|
"chat.computercraft.wired_modem.peripheral_connected": "Kringutrustning \"%s\" är kopplad till nätverket",
|
||||||
"chat.computercraft.wired_modem.peripheral_disconnected": "Kringutrustning \"%s\" är frånkopplad från nätverket",
|
"chat.computercraft.wired_modem.peripheral_disconnected": "Kringutrustning \"%s\" är frånkopplad från nätverket",
|
||||||
"gui.computercraft.tooltip.copy": "Kopiera till urklipp"
|
"gui.computercraft.tooltip.copy": "Kopiera till urklipp",
|
||||||
|
"gui.computercraft.tooltip.disk_id": "Diskett-ID: %s",
|
||||||
|
"gui.computercraft.tooltip.computer_id": "Dator-ID: %s",
|
||||||
|
"tracking_field.computercraft.coroutines_dead.name": "Coroutines borttagna",
|
||||||
|
"tracking_field.computercraft.coroutines_created.name": "Coroutines skapade",
|
||||||
|
"tracking_field.computercraft.websocket_outgoing.name": "Websocket utgående",
|
||||||
|
"tracking_field.computercraft.websocket_incoming.name": "Websocket ingående",
|
||||||
|
"tracking_field.computercraft.http_download.name": "HTTP-nedladdning",
|
||||||
|
"tracking_field.computercraft.http_upload.name": "HTTP-uppladdning",
|
||||||
|
"tracking_field.computercraft.http.name": "HTTP-förfrågningar",
|
||||||
|
"tracking_field.computercraft.turtle.name": "Turtle-operationer",
|
||||||
|
"tracking_field.computercraft.fs.name": "Filsystemoperationer",
|
||||||
|
"tracking_field.computercraft.peripheral.name": "Samtal till kringutrustning",
|
||||||
|
"tracking_field.computercraft.server_time.name": "Serveraktivitetstid",
|
||||||
|
"tracking_field.computercraft.server_count.name": "Antal serveruppgifter",
|
||||||
|
"tracking_field.computercraft.max.name": "Max tid",
|
||||||
|
"tracking_field.computercraft.average.name": "Genomsnittlig tid",
|
||||||
|
"tracking_field.computercraft.total.name": "Total tid",
|
||||||
|
"tracking_field.computercraft.tasks.name": "Uppgifter",
|
||||||
|
"argument.computercraft.argument_expected": "Argument förväntas",
|
||||||
|
"argument.computercraft.tracking_field.no_field": "Okänt fält '%s'",
|
||||||
|
"argument.computercraft.computer.many_matching": "Flera datorer matchar '%s' (%s träffar)",
|
||||||
|
"argument.computercraft.computer.no_matching": "Inga datorer matchar '%s'",
|
||||||
|
"commands.computercraft.generic.additional_rows": "%d ytterligare rader…",
|
||||||
|
"commands.computercraft.generic.exception": "Ohanterat felfall (%s)",
|
||||||
|
"commands.computercraft.generic.no": "N",
|
||||||
|
"commands.computercraft.generic.yes": "J",
|
||||||
|
"commands.computercraft.generic.position": "%s, %s, %s",
|
||||||
|
"commands.computercraft.generic.no_position": "<no pos>",
|
||||||
|
"commands.computercraft.queue.desc": "Skicka ett computer_command event till en kommandodator, skicka vidare ytterligare argument. Detta är mestadels utformat för kartmarkörer som fungerar som en mer datorvänlig version av /trigger. Alla spelare kan köra kommandot, vilket sannolikt skulle göras genom en textkomponents klick-event.",
|
||||||
|
"commands.computercraft.queue.synopsis": "Skicka ett computer_command event till en kommandodator",
|
||||||
|
"commands.computercraft.reload.done": "Konfiguration omladdad",
|
||||||
|
"commands.computercraft.reload.desc": "Ladda om ComputerCrafts konfigurationsfil",
|
||||||
|
"commands.computercraft.reload.synopsis": "Ladda om ComputerCrafts konfigurationsfil",
|
||||||
|
"commands.computercraft.track.dump.computer": "Dator",
|
||||||
|
"commands.computercraft.track.dump.no_timings": "Inga tidtagningar tillgängliga",
|
||||||
|
"commands.computercraft.track.dump.desc": "Dumpa de senaste resultaten av datorspårning.",
|
||||||
|
"commands.computercraft.track.dump.synopsis": "Dumpa de senaste spårningsresultaten",
|
||||||
|
"commands.computercraft.track.stop.not_enabled": "Spårar för tillfället inga datorer",
|
||||||
|
"commands.computercraft.track.stop.action": "Klicka för att stoppa spårning",
|
||||||
|
"commands.computercraft.track.stop.desc": "Stoppa spårning av alla datorers körtider och eventräkningar",
|
||||||
|
"commands.computercraft.track.stop.synopsis": "Stoppa spårning för alla datorer",
|
||||||
|
"commands.computercraft.track.start.stop": "Kör %s för att stoppa spårning och visa resultaten",
|
||||||
|
"commands.computercraft.track.start.desc": "Börja spåra alla dators körtider och eventräkningar. Detta kommer återställa resultaten från tidigare körningar.",
|
||||||
|
"commands.computercraft.track.start.synopsis": "Starta spårning för alla datorer",
|
||||||
|
"commands.computercraft.track.desc": "Spåra hur länge datorer exekverar, och även hur många event de hanterar. Detta presenterar information på liknande sätt som /forge track och kan vara användbart för att undersöka lagg.",
|
||||||
|
"commands.computercraft.track.synopsis": "Spåra körningstider för denna dator.",
|
||||||
|
"commands.computercraft.view.not_player": "Kan inte öppna terminalen för en ickespelare",
|
||||||
|
"commands.computercraft.view.action": "Titta på denna dator",
|
||||||
|
"commands.computercraft.view.desc": "Öppna datorns terminal för att möjligöra fjärrstyrning. Detta ger inte tillgång till turtlens inventory. Du kan ange en dators instans-id (t.ex. 123) eller dator-id (t.ex. #123).",
|
||||||
|
"commands.computercraft.view.synopsis": "Titta på datorns terminal.",
|
||||||
|
"commands.computercraft.tp.not_there": "Kan inte hitta datorn i världen",
|
||||||
|
"commands.computercraft.tp.not_player": "Kan inte öppna terminalen för en ickespelare",
|
||||||
|
"commands.computercraft.tp.action": "Teleportera till den här datorn",
|
||||||
|
"commands.computercraft.tp.desc": "Teleportera till datorns position. Du kan ange en dators instans-id (t.ex. 123), dator-id (t.ex. #123) eller etikett (t.ex. \"@Min dator\").",
|
||||||
|
"commands.computercraft.tp.synopsis": "Teleportera till en specifik dator.",
|
||||||
|
"commands.computercraft.turn_on.done": "Startade %s/%s datorer",
|
||||||
|
"commands.computercraft.turn_on.desc": "Starta de listade datorerna eller alla om ingen anges. Du kan ange en dators instans-id (t.ex. 123), dator-id (t.ex. #123) eller etikett (t.ex. \"@Min dator\").",
|
||||||
|
"commands.computercraft.turn_on.synopsis": "Starta på datorer på distans.",
|
||||||
|
"commands.computercraft.shutdown.done": "Stängde av %s/%s datorer",
|
||||||
|
"commands.computercraft.dump.desc": "Visa status för alla datorer eller specifik information för en dator. Du kan ange en dators instans-id (t.ex. 123), dator-id (t.ex. #123) eller etikett (t.ex. \"@Min dator\").",
|
||||||
|
"commands.computercraft.shutdown.desc": "Stäng av de listade datorerna eller alla om ingen anges. Du kan ange en dators instans-id (t.ex. 123), dator-id (t.ex. #123) eller etikett (t.ex. \"@Min dator\").",
|
||||||
|
"commands.computercraft.shutdown.synopsis": "Stäng av datorer på distans.",
|
||||||
|
"commands.computercraft.dump.action": "Visa mer information om den här datorn",
|
||||||
|
"commands.computercraft.dump.synopsis": "Visa status för datorer.",
|
||||||
|
"commands.computercraft.help.no_command": "Inget sådant kommando '%s'",
|
||||||
|
"commands.computercraft.help.no_children": "%s har inget underkommando",
|
||||||
|
"commands.computercraft.help.desc": "Visa detta hjälpmeddelande",
|
||||||
|
"commands.computercraft.help.synopsis": "Tillhandahåll hjälp för ett specifikt kommando",
|
||||||
|
"commands.computercraft.desc": "/computercraft kommandot tillhandahåller olika debugging- och administrationsverktyg för att kontrollera och interagera med datorer.",
|
||||||
|
"commands.computercraft.synopsis": "Olika kommandon för att kontrollera datorer.",
|
||||||
|
"itemGroup.computercraft": "ComputerCraft"
|
||||||
}
|
}
|
||||||
|
|||||||
48
src/main/resources/assets/computercraft/lang/vi.json
Normal file
48
src/main/resources/assets/computercraft/lang/vi.json
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"gui.computercraft.tooltip.disk_id": "ID của đĩa: %s",
|
||||||
|
"upgrade.computercraft.speaker.adjective": "Ồn ào",
|
||||||
|
"upgrade.computercraft.wireless_modem_advanced.adjective": "Ender",
|
||||||
|
"upgrade.computercraft.wireless_modem_normal.adjective": "Không dây",
|
||||||
|
"upgrade.minecraft.crafting_table.adjective": "Chế tạo",
|
||||||
|
"upgrade.minecraft.diamond_hoe.adjective": "Trồng trọt",
|
||||||
|
"upgrade.minecraft.diamond_axe.adjective": "Đốn",
|
||||||
|
"upgrade.minecraft.diamond_pickaxe.adjective": "Khai thác",
|
||||||
|
"upgrade.minecraft.diamond_shovel.adjective": "Đào",
|
||||||
|
"item.computercraft.pocket_computer_advanced.upgraded": "Máy tính bỏ túi tiên tiến %s",
|
||||||
|
"item.computercraft.pocket_computer_advanced": "Máy tính bỏ túi tiên tiến",
|
||||||
|
"item.computercraft.pocket_computer_normal.upgraded": "Máy tính bỏ túi %s",
|
||||||
|
"item.computercraft.pocket_computer_normal": "Máy tính bỏ túi",
|
||||||
|
"item.computercraft.printed_book": "Sách in",
|
||||||
|
"item.computercraft.printed_page": "Trang in",
|
||||||
|
"item.computercraft.treasure_disk": "Đĩa mềm",
|
||||||
|
"item.computercraft.disk": "Đĩa mềm",
|
||||||
|
"block.computercraft.turtle_advanced.upgraded_twice": "Rùa tiên tiến %s %s",
|
||||||
|
"block.computercraft.turtle_advanced.upgraded": "Rùa tiên tiến %s",
|
||||||
|
"block.computercraft.turtle_advanced": "Rùa tiên tiến",
|
||||||
|
"block.computercraft.turtle_normal.upgraded_twice": "Rùa %s %s",
|
||||||
|
"block.computercraft.turtle_normal.upgraded": "Rùa %s",
|
||||||
|
"block.computercraft.turtle_normal": "Rùa",
|
||||||
|
"block.computercraft.wired_modem_full": "Modem có dây",
|
||||||
|
"block.computercraft.cable": "Dây cáp mạng",
|
||||||
|
"block.computercraft.wired_modem": "Modem có dây",
|
||||||
|
"block.computercraft.wireless_modem_advanced": "Modem Ender",
|
||||||
|
"block.computercraft.wireless_modem_normal": "Modem không dây",
|
||||||
|
"block.computercraft.monitor_advanced": "Màn hình tiên tiếng",
|
||||||
|
"block.computercraft.monitor_normal": "Màn hình",
|
||||||
|
"block.computercraft.speaker": "Loa",
|
||||||
|
"block.computercraft.printer": "Máy in",
|
||||||
|
"block.computercraft.disk_drive": "Ỗ đĩa",
|
||||||
|
"block.computercraft.computer_command": "Máy tính điều khiển",
|
||||||
|
"block.computercraft.computer_normal": "Máy tính",
|
||||||
|
"itemGroup.computercraft": "ComputerCraft",
|
||||||
|
"block.computercraft.computer_advanced": "Máy tính tiên tiến",
|
||||||
|
"tracking_field.computercraft.websocket_incoming.name": "Websocket đến",
|
||||||
|
"tracking_field.computercraft.websocket_outgoing.name": "Websocket đi",
|
||||||
|
"gui.computercraft.tooltip.computer_id": "ID của máy tính: %s",
|
||||||
|
"tracking_field.computercraft.coroutines_dead.name": "Coroutine bỏ đi",
|
||||||
|
"tracking_field.computercraft.coroutines_created.name": "Coroutine đã tạo",
|
||||||
|
"tracking_field.computercraft.http_download.name": "HTTP tải xuống",
|
||||||
|
"tracking_field.computercraft.http_upload.name": "HTTP tải lên",
|
||||||
|
"tracking_field.computercraft.http.name": "Yêu cầu HTTP",
|
||||||
|
"gui.computercraft.tooltip.copy": "Sao chép vào clipboard"
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
uniform sampler2D u_font;
|
uniform sampler2D u_font;
|
||||||
uniform int u_width;
|
uniform int u_width;
|
||||||
uniform int u_height;
|
uniform int u_height;
|
||||||
uniform samplerBuffer u_tbo;
|
uniform usamplerBuffer u_tbo;
|
||||||
uniform vec3 u_palette[16];
|
uniform vec3 u_palette[16];
|
||||||
|
|
||||||
in vec2 f_pos;
|
in vec2 f_pos;
|
||||||
@@ -30,9 +30,9 @@ void main() {
|
|||||||
vec2 outside = step(vec2(0.0, 0.0), vec2(cell)) * step(vec2(cell), vec2(float(u_width) - 1.0, float(u_height) - 1.0));
|
vec2 outside = step(vec2(0.0, 0.0), vec2(cell)) * step(vec2(cell), vec2(float(u_width) - 1.0, float(u_height) - 1.0));
|
||||||
float mult = outside.x * outside.y;
|
float mult = outside.x * outside.y;
|
||||||
|
|
||||||
int character = int(texelFetch(u_tbo, index).r * 255.0);
|
int character = int(texelFetch(u_tbo, index).r);
|
||||||
int fg = int(texelFetch(u_tbo, index + 1).r * 255.0);
|
int fg = int(texelFetch(u_tbo, index + 1).r);
|
||||||
int bg = int(texelFetch(u_tbo, index + 2).r * 255.0);
|
int bg = int(texelFetch(u_tbo, index + 2).r);
|
||||||
|
|
||||||
vec2 pos = (term_pos - corner) * vec2(FONT_WIDTH, FONT_HEIGHT);
|
vec2 pos = (term_pos - corner) * vec2(FONT_WIDTH, FONT_HEIGHT);
|
||||||
vec4 img = texture(u_font, (texture_corner(character) + pos) / 256.0);
|
vec4 img = texture(u_font, (texture_corner(character) + pos) / 256.0);
|
||||||
|
|||||||
@@ -1,15 +1,137 @@
|
|||||||
--- The Colors API allows you to manipulate sets of colors.
|
--[[- The Colors API allows you to manipulate sets of colors.
|
||||||
--
|
|
||||||
-- This is useful in conjunction with Bundled Cables from the RedPower mod,
|
This is useful in conjunction with Bundled Cables from the RedPower mod, RedNet
|
||||||
-- RedNet Cables from the MineFactory Reloaded mod, and colors on Advanced
|
Cables from the MineFactory Reloaded mod, and colors on Advanced Computers and
|
||||||
-- Computers and Advanced Monitors.
|
Advanced Monitors.
|
||||||
--
|
|
||||||
-- For the non-American English version just replace @{colors} with @{colours}
|
For the non-American English version just replace @{colors} with @{colours} and
|
||||||
-- and it will use the other API, colours which is exactly the same, except in
|
it will use the other API, colours which is exactly the same, except in British
|
||||||
-- British English (e.g. @{colors.gray} is spelt @{colours.grey}).
|
English (e.g. @{colors.gray} is spelt @{colours.grey}).
|
||||||
--
|
|
||||||
-- @see colours
|
On basic terminals (such as the Computer and Monitor), all the colors are
|
||||||
-- @module colors
|
converted to grayscale. This means you can still use all 16 colors on the
|
||||||
|
screen, but they will appear as the nearest tint of gray. You can check if a
|
||||||
|
terminal supports color by using the function @{term.isColor}.
|
||||||
|
|
||||||
|
Grayscale colors are calculated by taking the average of the three components,
|
||||||
|
i.e. `(red + green + blue) / 3`.
|
||||||
|
|
||||||
|
<table class="pretty-table">
|
||||||
|
<thead>
|
||||||
|
<tr><th colspan="8" align="center">Default Colors</th></tr>
|
||||||
|
<tr>
|
||||||
|
<th rowspan="2" align="center">Color</th>
|
||||||
|
<th colspan="3" align="center">Value</th>
|
||||||
|
<th colspan="4" align="center">Default Palette Color</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Dec</th><th>Hex</th><th>Paint/Blit</th>
|
||||||
|
<th>Preview</th><th>Hex</th><th>RGB</th><th>Grayscale</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.white</code></td>
|
||||||
|
<td align="right">1</td><td align="right">0x1</td><td align="right">0</td>
|
||||||
|
<td style="background:#F0F0F0"></td><td>#F0F0F0</td><td>240, 240, 240</td>
|
||||||
|
<td style="background:#F0F0F0"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.orange</code></td>
|
||||||
|
<td align="right">2</td><td align="right">0x2</td><td align="right">1</td>
|
||||||
|
<td style="background:#F2B233"></td><td>#F2B233</td><td>242, 178, 51</td>
|
||||||
|
<td style="background:#9D9D9D"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.magenta</code></td>
|
||||||
|
<td align="right">4</td><td align="right">0x4</td><td align="right">2</td>
|
||||||
|
<td style="background:#E57FD8"></td><td>#E57FD8</td><td>229, 127, 216</td>
|
||||||
|
<td style="background:#BEBEBE"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.lightBlue</code></td>
|
||||||
|
<td align="right">8</td><td align="right">0x8</td><td align="right">3</td>
|
||||||
|
<td style="background:#99B2F2"></td><td>#99B2F2</td><td>153, 178, 242</td>
|
||||||
|
<td style="background:#BFBFBF"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.yellow</code></td>
|
||||||
|
<td align="right">16</td><td align="right">0x10</td><td align="right">4</td>
|
||||||
|
<td style="background:#DEDE6C"></td><td>#DEDE6C</td><td>222, 222, 108</td>
|
||||||
|
<td style="background:#B8B8B8"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.lime</code></td>
|
||||||
|
<td align="right">32</td><td align="right">0x20</td><td align="right">5</td>
|
||||||
|
<td style="background:#7FCC19"></td><td>#7FCC19</td><td>127, 204, 25</td>
|
||||||
|
<td style="background:#767676"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.pink</code></td>
|
||||||
|
<td align="right">64</td><td align="right">0x40</td><td align="right">6</td>
|
||||||
|
<td style="background:#F2B2CC"></td><td>#F2B2CC</td><td>242, 178, 204</td>
|
||||||
|
<td style="background:#D0D0D0"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.gray</code></td>
|
||||||
|
<td align="right">128</td><td align="right">0x80</td><td align="right">7</td>
|
||||||
|
<td style="background:#4C4C4C"></td><td>#4C4C4C</td><td>76, 76, 76</td>
|
||||||
|
<td style="background:#4C4C4C"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.lightGray</code></td>
|
||||||
|
<td align="right">256</td><td align="right">0x100</td><td align="right">8</td>
|
||||||
|
<td style="background:#999999"></td><td>#999999</td><td>153, 153, 153</td>
|
||||||
|
<td style="background:#999999"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.cyan</code></td>
|
||||||
|
<td align="right">512</td><td align="right">0x200</td><td align="right">9</td>
|
||||||
|
<td style="background:#4C99B2"></td><td>#4C99B2</td><td>76, 153, 178</td>
|
||||||
|
<td style="background:#878787"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.purple</code></td>
|
||||||
|
<td align="right">1024</td><td align="right">0x400</td><td align="right">a</td>
|
||||||
|
<td style="background:#B266E5"></td><td>#B266E5</td><td>178, 102, 229</td>
|
||||||
|
<td style="background:#A9A9A9"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.blue</code></td>
|
||||||
|
<td align="right">2048</td><td align="right">0x800</td><td align="right">b</td>
|
||||||
|
<td style="background:#3366CC"></td><td>#3366CC</td><td>51, 102, 204</td>
|
||||||
|
<td style="background:#777777"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.brown</code></td>
|
||||||
|
<td align="right">4096</td><td align="right">0x1000</td><td align="right">c</td>
|
||||||
|
<td style="background:#7F664C"></td><td>#7F664C</td><td>127, 102, 76</td>
|
||||||
|
<td style="background:#656565"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.green</code></td>
|
||||||
|
<td align="right">8192</td><td align="right">0x2000</td><td align="right">d</td>
|
||||||
|
<td style="background:#57A64E"></td><td>#57A64E</td><td>87, 166, 78</td>
|
||||||
|
<td style="background:#6E6E6E"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.red</code></td>
|
||||||
|
<td align="right">16384</td><td align="right">0x4000</td><td align="right">e</td>
|
||||||
|
<td style="background:#CC4C4C"></td><td>#CC4C4C</td><td>204, 76, 76</td>
|
||||||
|
<td style="background:#767676"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>colors.black</code></td>
|
||||||
|
<td align="right">32768</td><td align="right">0x8000</td><td align="right">f</td>
|
||||||
|
<td style="background:#111111"></td><td>#111111</td><td>17, 17, 17</td>
|
||||||
|
<td style="background:#111111"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
@see colours
|
||||||
|
@module colors
|
||||||
|
]]
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||||
|
|
||||||
@@ -37,7 +159,7 @@ yellow = 0x10
|
|||||||
-- terminal colour of #7FCC19.
|
-- terminal colour of #7FCC19.
|
||||||
lime = 0x20
|
lime = 0x20
|
||||||
|
|
||||||
--- Pink. Written as `6` in paint files and @{term.blit}, has a default
|
--- Pink: Written as `6` in paint files and @{term.blit}, has a default
|
||||||
-- terminal colour of #F2B2CC.
|
-- terminal colour of #F2B2CC.
|
||||||
pink = 0x40
|
pink = 0x40
|
||||||
|
|
||||||
@@ -74,10 +196,11 @@ green = 0x2000
|
|||||||
red = 0x4000
|
red = 0x4000
|
||||||
|
|
||||||
--- Black: Written as `f` in paint files and @{term.blit}, has a default
|
--- Black: Written as `f` in paint files and @{term.blit}, has a default
|
||||||
-- terminal colour of #191919.
|
-- terminal colour of #111111.
|
||||||
black = 0x8000
|
black = 0x8000
|
||||||
|
|
||||||
--- Combines a set of colors (or sets of colors) into a larger set.
|
--- Combines a set of colors (or sets of colors) into a larger set. Useful for
|
||||||
|
-- Bundled Cables.
|
||||||
--
|
--
|
||||||
-- @tparam number ... The colors to combine.
|
-- @tparam number ... The colors to combine.
|
||||||
-- @treturn number The union of the color sets given in `...`
|
-- @treturn number The union of the color sets given in `...`
|
||||||
@@ -96,7 +219,8 @@ function combine(...)
|
|||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Removes one or more colors (or sets of colors) from an initial set.
|
--- Removes one or more colors (or sets of colors) from an initial set. Useful
|
||||||
|
-- for Bundled Cables.
|
||||||
--
|
--
|
||||||
-- Each parameter beyond the first may be a single color or may be a set of
|
-- Each parameter beyond the first may be a single color or may be a set of
|
||||||
-- colors (in the latter case, all colors in the set are removed from the
|
-- colors (in the latter case, all colors in the set are removed from the
|
||||||
@@ -121,7 +245,8 @@ function subtract(colors, ...)
|
|||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Tests whether `color` is contained within `colors`.
|
--- Tests whether `color` is contained within `colors`. Useful for Bundled
|
||||||
|
-- Cables.
|
||||||
--
|
--
|
||||||
-- @tparam number colors A color, or color set
|
-- @tparam number colors A color, or color set
|
||||||
-- @tparam number color A color or set of colors that `colors` should contain.
|
-- @tparam number color A color or set of colors that `colors` should contain.
|
||||||
@@ -181,9 +306,6 @@ end
|
|||||||
--- Either calls @{colors.packRGB} or @{colors.unpackRGB}, depending on how many
|
--- Either calls @{colors.packRGB} or @{colors.unpackRGB}, depending on how many
|
||||||
-- arguments it receives.
|
-- arguments it receives.
|
||||||
--
|
--
|
||||||
-- **Note:** This function is deprecated, and it is recommended you use the
|
|
||||||
-- specific pack/unpack function directly.
|
|
||||||
--
|
|
||||||
-- @tparam[1] number r The red channel, as an argument to @{colors.packRGB}.
|
-- @tparam[1] number r The red channel, as an argument to @{colors.packRGB}.
|
||||||
-- @tparam[1] number g The green channel, as an argument to @{colors.packRGB}.
|
-- @tparam[1] number g The green channel, as an argument to @{colors.packRGB}.
|
||||||
-- @tparam[1] number b The blue channel, as an argument to @{colors.packRGB}.
|
-- @tparam[1] number b The blue channel, as an argument to @{colors.packRGB}.
|
||||||
@@ -192,6 +314,7 @@ end
|
|||||||
-- @treturn[2] number The red channel, as returned by @{colors.unpackRGB}
|
-- @treturn[2] number The red channel, as returned by @{colors.unpackRGB}
|
||||||
-- @treturn[2] number The green channel, as returned by @{colors.unpackRGB}
|
-- @treturn[2] number The green channel, as returned by @{colors.unpackRGB}
|
||||||
-- @treturn[2] number The blue channel, as returned by @{colors.unpackRGB}
|
-- @treturn[2] number The blue channel, as returned by @{colors.unpackRGB}
|
||||||
|
-- @deprecated Use @{packRGB} or @{unpackRGB} directly.
|
||||||
-- @usage
|
-- @usage
|
||||||
-- ```lua
|
-- ```lua
|
||||||
-- colors.rgb(0xb23399)
|
-- colors.rgb(0xb23399)
|
||||||
@@ -209,3 +332,21 @@ function rgb8(r, g, b)
|
|||||||
return packRGB(r, g, b)
|
return packRGB(r, g, b)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Colour to hex lookup table for toBlit
|
||||||
|
local color_hex_lookup = {}
|
||||||
|
for i = 0, 15 do
|
||||||
|
color_hex_lookup[2 ^ i] = string.format("%x", i)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Converts the given color to a paint/blit hex character (0-9a-f).
|
||||||
|
--
|
||||||
|
-- This is equivalent to converting floor(log_2(color)) to hexadecimal.
|
||||||
|
--
|
||||||
|
-- @tparam number color The color to convert.
|
||||||
|
-- @treturn string The blit hex code of the color.
|
||||||
|
function toBlit(color)
|
||||||
|
expect(1, color, "number")
|
||||||
|
return color_hex_lookup[color] or
|
||||||
|
string.format("%x", math.floor(math.log(color) / math.log(2)))
|
||||||
|
end
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ end
|
|||||||
-- The `mode` string can be any of the following:
|
-- The `mode` string can be any of the following:
|
||||||
-- - **"r"**: Read mode
|
-- - **"r"**: Read mode
|
||||||
-- - **"w"**: Write mode
|
-- - **"w"**: Write mode
|
||||||
-- - **"w"**: Append mode
|
-- - **"a"**: Append mode
|
||||||
--
|
--
|
||||||
-- The mode may also have a `b` at the end, which opens the file in "binary
|
-- The mode may also have a `b` at the end, which opens the file in "binary
|
||||||
-- mode". This allows you to read binary files, as well as seek within a file.
|
-- mode". This allows you to read binary files, as well as seek within a file.
|
||||||
|
|||||||
@@ -23,6 +23,25 @@ local function parseLine(tImageArg, sLine)
|
|||||||
table.insert(tImageArg, tLine)
|
table.insert(tImageArg, tLine)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Sorts pairs of startX/startY/endX/endY such that the start is always the min
|
||||||
|
local function sortCoords(startX, startY, endX, endY)
|
||||||
|
local minX, maxX, minY, maxY
|
||||||
|
|
||||||
|
if startX <= endX then
|
||||||
|
minX, maxX = startX, endX
|
||||||
|
else
|
||||||
|
minX, maxX = endX, startX
|
||||||
|
end
|
||||||
|
|
||||||
|
if startY <= endY then
|
||||||
|
minY, maxY = startY, endY
|
||||||
|
else
|
||||||
|
minY, maxY = endY, startY
|
||||||
|
end
|
||||||
|
|
||||||
|
return minX, maxX, minY, maxY
|
||||||
|
end
|
||||||
|
|
||||||
--- Parses an image from a multi-line string
|
--- Parses an image from a multi-line string
|
||||||
--
|
--
|
||||||
-- @tparam string image The string containing the raw-image data.
|
-- @tparam string image The string containing the raw-image data.
|
||||||
@@ -71,9 +90,6 @@ function drawPixel(xPos, yPos, colour)
|
|||||||
expect(2, yPos, "number")
|
expect(2, yPos, "number")
|
||||||
expect(3, colour, "number", "nil")
|
expect(3, colour, "number", "nil")
|
||||||
|
|
||||||
if type(xPos) ~= "number" then error("bad argument #1 (expected number, got " .. type(xPos) .. ")", 2) end
|
|
||||||
if type(yPos) ~= "number" then error("bad argument #2 (expected number, got " .. type(yPos) .. ")", 2) end
|
|
||||||
if colour ~= nil and type(colour) ~= "number" then error("bad argument #3 (expected number, got " .. type(colour) .. ")", 2) end
|
|
||||||
if colour then
|
if colour then
|
||||||
term.setBackgroundColor(colour)
|
term.setBackgroundColor(colour)
|
||||||
end
|
end
|
||||||
@@ -111,17 +127,7 @@ function drawLine(startX, startY, endX, endY, colour)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local minX = math.min(startX, endX)
|
local minX, maxX, minY, maxY = sortCoords(startX, startY, endX, endY)
|
||||||
local maxX, minY, maxY
|
|
||||||
if minX == startX then
|
|
||||||
minY = startY
|
|
||||||
maxX = endX
|
|
||||||
maxY = endY
|
|
||||||
else
|
|
||||||
minY = endY
|
|
||||||
maxX = startX
|
|
||||||
maxY = startY
|
|
||||||
end
|
|
||||||
|
|
||||||
-- TODO: clip to screen rectangle?
|
-- TODO: clip to screen rectangle?
|
||||||
|
|
||||||
@@ -177,37 +183,33 @@ function drawBox(startX, startY, endX, endY, nColour)
|
|||||||
endY = math.floor(endY)
|
endY = math.floor(endY)
|
||||||
|
|
||||||
if nColour then
|
if nColour then
|
||||||
term.setBackgroundColor(nColour)
|
term.setBackgroundColor(nColour) -- Maintain legacy behaviour
|
||||||
|
else
|
||||||
|
nColour = term.getBackgroundColour()
|
||||||
end
|
end
|
||||||
|
local colourHex = colours.toBlit(nColour)
|
||||||
|
|
||||||
if startX == endX and startY == endY then
|
if startX == endX and startY == endY then
|
||||||
drawPixelInternal(startX, startY)
|
drawPixelInternal(startX, startY)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local minX = math.min(startX, endX)
|
local minX, maxX, minY, maxY = sortCoords(startX, startY, endX, endY)
|
||||||
local maxX, minY, maxY
|
local width = maxX - minX + 1
|
||||||
if minX == startX then
|
|
||||||
minY = startY
|
|
||||||
maxX = endX
|
|
||||||
maxY = endY
|
|
||||||
else
|
|
||||||
minY = endY
|
|
||||||
maxX = startX
|
|
||||||
maxY = startY
|
|
||||||
end
|
|
||||||
|
|
||||||
for x = minX, maxX do
|
for y = minY, maxY do
|
||||||
drawPixelInternal(x, minY)
|
if y == minY or y == maxY then
|
||||||
drawPixelInternal(x, maxY)
|
term.setCursorPos(minX, y)
|
||||||
end
|
term.blit((" "):rep(width), colourHex:rep(width), colourHex:rep(width))
|
||||||
|
else
|
||||||
if maxY - minY >= 2 then
|
term.setCursorPos(minX, y)
|
||||||
for y = minY + 1, maxY - 1 do
|
term.blit(" ", colourHex, colourHex)
|
||||||
drawPixelInternal(minX, y)
|
term.setCursorPos(maxX, y)
|
||||||
drawPixelInternal(maxX, y)
|
term.blit(" ", colourHex, colourHex)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Draws a filled box on the current term from the specified start position to
|
--- Draws a filled box on the current term from the specified start position to
|
||||||
-- the specified end position.
|
-- the specified end position.
|
||||||
--
|
--
|
||||||
@@ -233,29 +235,23 @@ function drawFilledBox(startX, startY, endX, endY, nColour)
|
|||||||
endY = math.floor(endY)
|
endY = math.floor(endY)
|
||||||
|
|
||||||
if nColour then
|
if nColour then
|
||||||
term.setBackgroundColor(nColour)
|
term.setBackgroundColor(nColour) -- Maintain legacy behaviour
|
||||||
|
else
|
||||||
|
nColour = term.getBackgroundColour()
|
||||||
end
|
end
|
||||||
|
local colourHex = colours.toBlit(nColour)
|
||||||
|
|
||||||
if startX == endX and startY == endY then
|
if startX == endX and startY == endY then
|
||||||
drawPixelInternal(startX, startY)
|
drawPixelInternal(startX, startY)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local minX = math.min(startX, endX)
|
local minX, maxX, minY, maxY = sortCoords(startX, startY, endX, endY)
|
||||||
local maxX, minY, maxY
|
local width = maxX - minX + 1
|
||||||
if minX == startX then
|
|
||||||
minY = startY
|
|
||||||
maxX = endX
|
|
||||||
maxY = endY
|
|
||||||
else
|
|
||||||
minY = endY
|
|
||||||
maxX = startX
|
|
||||||
maxY = startY
|
|
||||||
end
|
|
||||||
|
|
||||||
for x = minX, maxX do
|
for y = minY, maxY do
|
||||||
for y = minY, maxY do
|
term.setCursorPos(minX, y)
|
||||||
drawPixelInternal(x, y)
|
term.blit((" "):rep(width), colourHex:rep(width), colourHex:rep(width))
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ function formatTime(nTime, bTwentyFourHour)
|
|||||||
local nHour = math.floor(nTime)
|
local nHour = math.floor(nTime)
|
||||||
local nMinute = math.floor((nTime - nHour) * 60)
|
local nMinute = math.floor((nTime - nHour) * 60)
|
||||||
if sTOD then
|
if sTOD then
|
||||||
return string.format("%d:%02d %s", nHour, nMinute, sTOD)
|
return string.format("%d:%02d %s", nHour == 0 and 12 or nHour, nMinute, sTOD)
|
||||||
else
|
else
|
||||||
return string.format("%d:%02d", nHour, nMinute)
|
return string.format("%d:%02d", nHour, nMinute)
|
||||||
end
|
end
|
||||||
@@ -335,6 +335,31 @@ empty_json_array = mk_tbl("[]", "empty_json_array")
|
|||||||
-- @see textutils.unserialiseJSON
|
-- @see textutils.unserialiseJSON
|
||||||
json_null = mk_tbl("null", "json_null")
|
json_null = mk_tbl("null", "json_null")
|
||||||
|
|
||||||
|
local serializeJSONString
|
||||||
|
do
|
||||||
|
local function hexify(c)
|
||||||
|
return ("\\u00%02X"):format(c:byte())
|
||||||
|
end
|
||||||
|
|
||||||
|
local map = {
|
||||||
|
["\""] = "\\\"",
|
||||||
|
["\\"] = "\\\\",
|
||||||
|
["\b"] = "\\b",
|
||||||
|
["\f"] = "\\f",
|
||||||
|
["\n"] = "\\n",
|
||||||
|
["\r"] = "\\r",
|
||||||
|
["\t"] = "\\t",
|
||||||
|
}
|
||||||
|
for i = 0, 0x1f do
|
||||||
|
local c = string.char(i)
|
||||||
|
if map[c] == nil then map[c] = hexify(c) end
|
||||||
|
end
|
||||||
|
|
||||||
|
serializeJSONString = function(s)
|
||||||
|
return ('"%s"'):format(s:gsub("[\0-\x1f\"\\]", map):gsub("[\x7f-\xff]", hexify))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function serializeJSONImpl(t, tTracking, bNBTStyle)
|
local function serializeJSONImpl(t, tTracking, bNBTStyle)
|
||||||
local sType = type(t)
|
local sType = type(t)
|
||||||
if t == empty_json_array then return "[]"
|
if t == empty_json_array then return "[]"
|
||||||
@@ -361,7 +386,7 @@ local function serializeJSONImpl(t, tTracking, bNBTStyle)
|
|||||||
if bNBTStyle then
|
if bNBTStyle then
|
||||||
sEntry = tostring(k) .. ":" .. serializeJSONImpl(v, tTracking, bNBTStyle)
|
sEntry = tostring(k) .. ":" .. serializeJSONImpl(v, tTracking, bNBTStyle)
|
||||||
else
|
else
|
||||||
sEntry = string.format("%q", k) .. ":" .. serializeJSONImpl(v, tTracking, bNBTStyle)
|
sEntry = serializeJSONString(k) .. ":" .. serializeJSONImpl(v, tTracking, bNBTStyle)
|
||||||
end
|
end
|
||||||
if nObjectSize == 0 then
|
if nObjectSize == 0 then
|
||||||
sObjectResult = sObjectResult .. sEntry
|
sObjectResult = sObjectResult .. sEntry
|
||||||
@@ -390,7 +415,7 @@ local function serializeJSONImpl(t, tTracking, bNBTStyle)
|
|||||||
end
|
end
|
||||||
|
|
||||||
elseif sType == "string" then
|
elseif sType == "string" then
|
||||||
return string.format("%q", t)
|
return serializeJSONString(t)
|
||||||
|
|
||||||
elseif sType == "number" or sType == "boolean" then
|
elseif sType == "number" or sType == "boolean" then
|
||||||
return tostring(t)
|
return tostring(t)
|
||||||
@@ -407,7 +432,7 @@ do
|
|||||||
|
|
||||||
--- Skip any whitespace
|
--- Skip any whitespace
|
||||||
local function skip(str, pos)
|
local function skip(str, pos)
|
||||||
local _, last = find(str, "^[ \n\r\v]+", pos)
|
local _, last = find(str, "^[ \n\r\t]+", pos)
|
||||||
if last then return last + 1 else return pos end
|
if last then return last + 1 else return pos end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -428,13 +453,13 @@ do
|
|||||||
error_at(pos, "Unexpected %s, expected %s.", actual, exp)
|
error_at(pos, "Unexpected %s, expected %s.", actual, exp)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function parse_string(str, pos)
|
local function parse_string(str, pos, terminate)
|
||||||
local buf, n = {}, 1
|
local buf, n = {}, 1
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
local c = sub(str, pos, pos)
|
local c = sub(str, pos, pos)
|
||||||
if c == "" then error_at(pos, "Unexpected end of input, expected '\"'.") end
|
if c == "" then error_at(pos, "Unexpected end of input, expected '\"'.") end
|
||||||
if c == '"' then break end
|
if c == terminate then break end
|
||||||
|
|
||||||
if c == '\\' then
|
if c == '\\' then
|
||||||
-- Handle the various escapes
|
-- Handle the various escapes
|
||||||
@@ -447,7 +472,7 @@ do
|
|||||||
buf[n], n, pos = utf8.char(tonumber(num_str, 16)), n + 1, pos + 6
|
buf[n], n, pos = utf8.char(tonumber(num_str, 16)), n + 1, pos + 6
|
||||||
else
|
else
|
||||||
local unesc = escapes[c]
|
local unesc = escapes[c]
|
||||||
if not unesc then error_at(pos + 1, "Unknown escape character %q.", unesc) end
|
if not unesc then error_at(pos + 1, "Unknown escape character %q.", c) end
|
||||||
buf[n], n, pos = unesc, n + 1, pos + 2
|
buf[n], n, pos = unesc, n + 1, pos + 2
|
||||||
end
|
end
|
||||||
elseif c >= '\x20' then
|
elseif c >= '\x20' then
|
||||||
@@ -460,13 +485,13 @@ do
|
|||||||
return concat(buf, "", 1, n - 1), pos + 1
|
return concat(buf, "", 1, n - 1), pos + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local valid = { b = true, B = true, s = true, S = true, l = true, L = true, f = true, F = true, d = true, D = true }
|
local num_types = { b = true, B = true, s = true, S = true, l = true, L = true, f = true, F = true, d = true, D = true }
|
||||||
local function parse_number(str, pos, opts)
|
local function parse_number(str, pos, opts)
|
||||||
local _, last, num_str = find(str, '^(-?%d+%.?%d*[eE]?[+-]?%d*)', pos)
|
local _, last, num_str = find(str, '^(-?%d+%.?%d*[eE]?[+-]?%d*)', pos)
|
||||||
local val = tonumber(num_str)
|
local val = tonumber(num_str)
|
||||||
if not val then error_at(pos, "Malformed number %q.", num_str) end
|
if not val then error_at(pos, "Malformed number %q.", num_str) end
|
||||||
|
|
||||||
if opts.nbt_style and valid[sub(str, pos + 1, pos + 1)] then return val, last + 2 end
|
if opts.nbt_style and num_types[sub(str, last + 1, last + 1)] then return val, last + 2 end
|
||||||
|
|
||||||
return val, last + 1
|
return val, last + 1
|
||||||
end
|
end
|
||||||
@@ -476,9 +501,11 @@ do
|
|||||||
return val, last + 1
|
return val, last + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local arr_types = { I = true, L = true, B = true }
|
||||||
local function decode_impl(str, pos, opts)
|
local function decode_impl(str, pos, opts)
|
||||||
local c = sub(str, pos, pos)
|
local c = sub(str, pos, pos)
|
||||||
if c == '"' then return parse_string(str, pos + 1)
|
if c == '"' then return parse_string(str, pos + 1, '"')
|
||||||
|
elseif c == "'" and opts.nbt_style then return parse_string(str, pos + 1, "\'")
|
||||||
elseif c == "-" or c >= "0" and c <= "9" then return parse_number(str, pos, opts)
|
elseif c == "-" or c >= "0" and c <= "9" then return parse_number(str, pos, opts)
|
||||||
elseif c == "t" then
|
elseif c == "t" then
|
||||||
if sub(str, pos + 1, pos + 3) == "rue" then return true, pos + 4 end
|
if sub(str, pos + 1, pos + 3) == "rue" then return true, pos + 4 end
|
||||||
@@ -503,7 +530,7 @@ do
|
|||||||
|
|
||||||
while true do
|
while true do
|
||||||
local key, value
|
local key, value
|
||||||
if c == "\"" then key, pos = parse_string(str, pos + 1)
|
if c == "\"" then key, pos = parse_string(str, pos + 1, "\"")
|
||||||
elseif opts.nbt_style then key, pos = parse_ident(str, pos)
|
elseif opts.nbt_style then key, pos = parse_ident(str, pos)
|
||||||
else return expected(pos, c, "object key")
|
else return expected(pos, c, "object key")
|
||||||
end
|
end
|
||||||
@@ -535,6 +562,11 @@ do
|
|||||||
pos = skip(str, pos + 1)
|
pos = skip(str, pos + 1)
|
||||||
c = sub(str, pos, pos)
|
c = sub(str, pos, pos)
|
||||||
|
|
||||||
|
if arr_types[c] and sub(str, pos + 1, pos + 1) == ";" and opts.nbt_style then
|
||||||
|
pos = skip(str, pos + 2)
|
||||||
|
c = sub(str, pos, pos)
|
||||||
|
end
|
||||||
|
|
||||||
if c == "" then return expected(pos, c, "']'") end
|
if c == "" then return expected(pos, c, "']'") end
|
||||||
if c == "]" then return empty_json_array, pos + 1 end
|
if c == "]" then return empty_json_array, pos + 1 end
|
||||||
|
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Get the buffered contents of a line in this window.
|
--- Get the buffered contents of a line in this window.
|
||||||
---
|
--
|
||||||
-- @tparam number y The y position of the line to get.
|
-- @tparam number y The y position of the line to get.
|
||||||
-- @treturn string The textual content of this line.
|
-- @treturn string The textual content of this line.
|
||||||
-- @treturn string The text colours of this line, suitable for use with @{term.blit}.
|
-- @treturn string The text colours of this line, suitable for use with @{term.blit}.
|
||||||
@@ -474,6 +474,14 @@ function create(parent, nX, nY, nWidth, nHeight, bStartVisible)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get whether this window is visible. Invisible windows will not be
|
||||||
|
-- drawn to the screen until they are made visible again.
|
||||||
|
--
|
||||||
|
-- @treturn boolean Whether this window is visible.
|
||||||
|
-- @see Window:setVisible
|
||||||
|
function window.isVisible()
|
||||||
|
return bVisible
|
||||||
|
end
|
||||||
--- Draw this window. This does nothing if the window is not visible.
|
--- Draw this window. This does nothing if the window is not visible.
|
||||||
--
|
--
|
||||||
-- @see Window:setVisible
|
-- @see Window:setVisible
|
||||||
|
|||||||
@@ -1,3 +1,74 @@
|
|||||||
|
# New features in CC: Tweaked 1.94.0
|
||||||
|
|
||||||
|
* Add getter for window visibility (devomaa)
|
||||||
|
* Generic peripherals are no longer experimental, and on by default.
|
||||||
|
* Use term.blit to draw boxes in paintutils (Lemmmy).
|
||||||
|
|
||||||
|
And several bug fixes:
|
||||||
|
* Fix turtles not getting advancements when turtles are on.
|
||||||
|
* Draw in-hand pocket computers with the correct transparent flags enabled.
|
||||||
|
* Several bug fixes to SNBT parsing.
|
||||||
|
* Fix several programs using their original name instead of aliases in usage hints (Lupus590).
|
||||||
|
|
||||||
|
# New features in CC: Tweaked 1.93.1
|
||||||
|
|
||||||
|
* Various documentation improvements (Lemmmy).
|
||||||
|
* Fix TBO monitor renderer on some older graphics cards (Lemmmy).
|
||||||
|
|
||||||
|
# New features in CC: Tweaked 1.93.0
|
||||||
|
|
||||||
|
* Update Swedish translations (Granddave).
|
||||||
|
* Printers use item tags to check dyes.
|
||||||
|
* HTTP rules may now be targetted for a specific port.
|
||||||
|
* Don't propagate adjacent redstone signals through computers.
|
||||||
|
|
||||||
|
And several bug fixes:
|
||||||
|
* Fix NPEs when turtles interact with containers.
|
||||||
|
|
||||||
|
# New features in CC: Tweaked 1.92.0
|
||||||
|
|
||||||
|
* Bump Cobalt version:
|
||||||
|
* Add support for the __pairs metamethod.
|
||||||
|
* string.format now uses the __tostring metamethod.
|
||||||
|
* Add date-specific MOTDs (MCJack123).
|
||||||
|
|
||||||
|
And several bug fixes:
|
||||||
|
* Correctly handle tabs within textutils.unserailizeJSON.
|
||||||
|
* Fix sheep not dropping items when sheared by turtles.
|
||||||
|
|
||||||
|
# New features in CC: Tweaked 1.91.1
|
||||||
|
|
||||||
|
* Fix crash when turtles interact with an entity.
|
||||||
|
|
||||||
|
# New features in CC: Tweaked 1.91.0
|
||||||
|
|
||||||
|
* [Generic peripherals] Expose NBT hashes of items to inventory methods.
|
||||||
|
* Bump Cobalt version
|
||||||
|
* Optimise handling of string concatenation.
|
||||||
|
* Add string.{pack,unpack,packsize} (MCJack123)
|
||||||
|
* Update to 1.16.2
|
||||||
|
|
||||||
|
And several bug fixes:
|
||||||
|
* Escape non-ASCII characters in JSON strings (neumond)
|
||||||
|
* Make field names in fs.attributes more consistent (abby)
|
||||||
|
* Fix textutils.formatTime correctly handle 12 AM (R93950X)
|
||||||
|
* Fix turtles placing buckets multiple times.
|
||||||
|
|
||||||
|
# New features in CC: Tweaked 1.90.3
|
||||||
|
|
||||||
|
* Fix the selected slot indicator missing from the turtle GUI.
|
||||||
|
* Ensure we load/save computer data from the world directory, rather than a global one.
|
||||||
|
|
||||||
|
# New features in CC: Tweaked 1.90.2
|
||||||
|
|
||||||
|
* Fix generic peripherals not being registered outside a dev environment.
|
||||||
|
* Fix `turtle.attack()` failing.
|
||||||
|
* Correctly set styles for the output of `/computercraft` commands.
|
||||||
|
|
||||||
|
# New features in CC: Tweaked 1.90.1
|
||||||
|
|
||||||
|
* Update to Forge 32.0.69
|
||||||
|
|
||||||
# New features in CC: Tweaked 1.90.0
|
# New features in CC: Tweaked 1.90.0
|
||||||
|
|
||||||
* Add cc.image.nft module, for working with nft files. (JakobDev)
|
* Add cc.image.nft module, for working with nft files. (JakobDev)
|
||||||
@@ -15,8 +86,6 @@ And several bug fixes:
|
|||||||
* Fix deadlock when mistakenly "watching" an unloaded chunk.
|
* Fix deadlock when mistakenly "watching" an unloaded chunk.
|
||||||
* Fix full path of files being leaked in some errors.
|
* Fix full path of files being leaked in some errors.
|
||||||
|
|
||||||
Type "help changelog" to see the full version history.
|
|
||||||
|
|
||||||
# New features in CC: Tweaked 1.89.1
|
# New features in CC: Tweaked 1.89.1
|
||||||
|
|
||||||
* Fix crashes when rendering monitors of varying sizes.
|
* Fix crashes when rendering monitors of varying sizes.
|
||||||
|
|||||||
@@ -1,18 +1,13 @@
|
|||||||
New features in CC: Tweaked 1.90.0
|
New features in CC: Tweaked 1.94.0
|
||||||
|
|
||||||
* Add cc.image.nft module, for working with nft files. (JakobDev)
|
* Add getter for window visibility (devomaa)
|
||||||
* [experimental] Provide a generic peripheral for any tile entity without an existing one. We currently provide methods for working with inventories, fluid tanks and energy storage. This is disabled by default, and must be turned on in the config.
|
* Generic peripherals are no longer experimental, and on by default.
|
||||||
* Add configuration to control the sizes of monitors and terminals.
|
* Use term.blit to draw boxes in paintutils (Lemmmy).
|
||||||
* Add configuration to control maximum render distance of monitors.
|
|
||||||
* Allow getting "detailed" information about an item, using `turtle.getItemDetail(slot, true)`. This will contain the same information that the generic peripheral supplies.
|
|
||||||
|
|
||||||
And several bug fixes:
|
And several bug fixes:
|
||||||
* Add back config for allowing interacting with command computers.
|
* Fix turtles not getting advancements when turtles are on.
|
||||||
* Fix write method missing from printers.
|
* Draw in-hand pocket computers with the correct transparent flags enabled.
|
||||||
* Fix dupe bug when killing an entity with a turtle.
|
* Several bug fixes to SNBT parsing.
|
||||||
* Correctly supply port in the Host header (neumond).
|
* Fix several programs using their original name instead of aliases in usage hints (Lupus590).
|
||||||
* Fix `turtle.craft` failing when missing an argument.
|
|
||||||
* Fix deadlock when mistakenly "watching" an unloaded chunk.
|
|
||||||
* Fix full path of files being leaked in some errors.
|
|
||||||
|
|
||||||
Type "help changelog" to see the full version history.
|
Type "help changelog" to see the full version history.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
-- @module cc.pretty
|
-- @module cc.pretty
|
||||||
-- @usage Print a table to the terminal
|
-- @usage Print a table to the terminal
|
||||||
-- local pretty = require "cc.pretty"
|
-- local pretty = require "cc.pretty"
|
||||||
-- pretty.write(pretty.dump({ 1, 2, 3 }))
|
-- pretty.write(pretty.pretty({ 1, 2, 3 }))
|
||||||
--
|
--
|
||||||
-- @usage Build a custom document and display it
|
-- @usage Build a custom document and display it
|
||||||
-- local pretty = require "cc.pretty"
|
-- local pretty = require "cc.pretty"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
local tArgs = { ... }
|
local tArgs = { ... }
|
||||||
if #tArgs > 2 then
|
if #tArgs > 2 then
|
||||||
print("Usage: alias <alias> <program>")
|
local programName = arg[0] or fs.getName(shell.getRunningProgram())
|
||||||
|
print("Usage: " .. programName .. " <alias> <program>")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
local tArgs = { ... }
|
local tArgs = { ... }
|
||||||
if #tArgs < 1 then
|
if #tArgs < 1 then
|
||||||
print("Usage: cd <path>")
|
local programName = arg[0] or fs.getName(shell.getRunningProgram())
|
||||||
|
print("Usage: " .. programName .. " <path>")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ if not commands then
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
if #tArgs == 0 then
|
if #tArgs == 0 then
|
||||||
printError("Usage: exec <command>")
|
local programName = arg[0] or fs.getName(shell.getRunningProgram())
|
||||||
|
printError("Usage: " .. programName .. " <command>")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
local tArgs = { ... }
|
local tArgs = { ... }
|
||||||
if #tArgs < 2 then
|
if #tArgs < 2 then
|
||||||
print("Usage: cp <source> <destination>")
|
local programName = arg[0] or fs.getName(shell.getRunningProgram())
|
||||||
|
print("Usage: " .. programName .. " <source> <destination>")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
local args = table.pack(...)
|
local args = table.pack(...)
|
||||||
|
|
||||||
if args.n < 1 then
|
if args.n < 1 then
|
||||||
print("Usage: rm <paths>")
|
local programName = arg[0] or fs.getName(shell.getRunningProgram())
|
||||||
|
print("Usage: " .. programName .. " <paths>")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
-- Get file to edit
|
-- Get file to edit
|
||||||
local tArgs = { ... }
|
local tArgs = { ... }
|
||||||
if #tArgs == 0 then
|
if #tArgs == 0 then
|
||||||
print("Usage: edit <path>")
|
local programName = arg[0] or fs.getName(shell.getRunningProgram())
|
||||||
|
print("Usage: " .. programName .. " <path>")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
-- Get arguments
|
-- Get arguments
|
||||||
local tArgs = { ... }
|
local tArgs = { ... }
|
||||||
if #tArgs == 0 then
|
if #tArgs == 0 then
|
||||||
print("Usage: eject <drive>")
|
local programName = arg[0] or fs.getName(shell.getRunningProgram())
|
||||||
|
print("Usage: " .. programName .. " <drive>")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user