1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-15 14:07:38 +00:00

Compare commits

...

265 Commits

Author SHA1 Message Date
SquidDev
8b1773dd60 Fix peripheral.getMethods returning {}
I don't even know how this snuck past.

Closes #346
2020-01-14 08:45:08 +00:00
SquidDev
018ecfbaa0 ▲ version 2020-01-13 13:43:38 +00:00
SquidDev
4c8fd4fc35 Allow returning collections and arrays from Java
Closes #344
2020-01-13 13:20:15 +00:00
Oliver Marks
35c1b10224 Anonymized GPS (#341)
GPS requests are now sent and received on CHANNEL_GPS by default
instead. This means it should not be possible to distinguish
computers (and thus locate them) via their GPS requests.
2020-01-08 17:07:01 +00:00
SquidDev
c1c01bef7c Fix argument index in expect call 2020-01-01 09:55:44 +00:00
SquidDev
a48c3d0ba8 A couple of io fixes
- Use expect within io.write before calling the handle's write
   function. Closes #338
 - Coerce to string in write before doing any writing. Fixes #339
2020-01-01 09:01:00 +00:00
SquidDev
93a9ebc4f6 Happy new year 2020-01-01 00:09:18 +00:00
JakobDev
7cc2bd43c6 Make builded Jar downloadable (#332) 2020-01-01 00:08:31 +00:00
Oliver Marks
393e628721 More MOTDs (#333) 2019-12-30 16:26:57 +00:00
Jonathan Coates
0bcd28e58c Fix incorrect module names 2019-12-29 19:47:52 +00:00
SquidDev
42f5389fb8 Make Lua's "exit" function a little prettier
"exit" now has a custom __tostring method, which prints an explanation
message. This is very similar to how Python achives the same
functionality:

    lua> exit
    Call exit() to exit
    lua> exit()
    > Actually leaves the REPL
2019-12-29 18:51:39 +00:00
Jacob
041cfe91b4 wilcards > wildcards (#331) 2019-12-29 06:12:55 +00:00
SquidDev
0dde859582 Bump version 2019-12-23 22:10:32 +00:00
SquidDev
e59c043fb6 Fix a couple of comments to use the new config names 2019-12-23 21:34:03 +00:00
SquidDev
ae928c4397 Make http domain configuration a little clearer 2019-12-23 18:59:36 +00:00
SquidDev
da41c65128 Update proguard configuration
- Remove redundant preservation of cobalt lib constructors. We use
   lambdas now, so this is no longer needed.
 - Fix Java crypto lib not being included.
2019-12-23 18:54:19 +00:00
SquidDev
4d18234714 Use a fake network handler too
It appears that WB opens containers manually, and thus all of our stubs
network stubs are entirely ignored. Thus the only solution here is to
stub out the whole network handler code.

Thankfully this is simple enough - we do the same for Plethora and 1.14.

Fixes #328
2019-12-23 17:17:32 +00:00
JakobDev
d254c6464b Add more MOTD messages again (#241) 2019-12-23 14:43:48 +00:00
Jonathan Coates
3a5d50e572 Basic Minetweaker support (#327)
This provides the following methods:

 - dan200.computercraft.turtle.removeUpgrade(id: String)
 - dan200.computercraft.turtle.removeUpgrade(stack: IItemStack)
 - dan200.computercraft.turtle.addTool(id: String, craftItem: IItemStack[, toolItem: IItemStack][, kind: string])

While it's pretty minimal, it should allow for a reasonable amount of
functionality.

Closes #327 and #97.
2019-12-18 15:29:24 +00:00
Jonathan Coates
03b6d2f1ab Replace string.len with # 2019-12-10 18:55:11 +00:00
Jared Allard
b0397ed3c5 Add support for HTTP PATCH and TRACE (#324) 2019-12-08 17:10:58 +00:00
Jonathan Coates
fa70ebcac2 Fix spacing on all of the rom (#323) 2019-12-07 10:33:47 +00:00
SquidDev
86e0330100 Lint bios and the rom (#321)
We now use illuaminate[1]'s linting facilities to check the rom and
bios.lua for a couple of common bugs and other problems.

Right now this doesn't detect any especially important bugs, though it
has caught lots of small things (unused variables, some noisy code). In
the future, the linter will grow in scope and features, which should
allow us to be stricter and catch most issues.

As a fun aside, we started off with ~150 bugs, and illuaminate was able
to fix all but 30 of them, which is pretty neat.

[1]: https://github.com/SquidDev/illuaminate
2019-12-03 23:26:13 +00:00
SquidDev
0ae70fed13 Correctly implement mouse movement within read
Note to self: if you're going to modify the rom, make sure you test on a
computer which doesn't overwrite the rom with something else.
2019-11-29 20:15:58 +00:00
SquidDev
121802a683 Bump version 2019-11-25 08:58:36 +00:00
SquidDev
08cf55e55f Correct implementation of clamp
That's what I get for inlining definitions.
2019-11-23 14:36:43 +00:00
SquidDev
3c8c0d78ef Use correct render type for turtles
This fixes them not rendering particles when broken. Particle rendering
is a little janky right now, as it uses the whole texture - we should
probably split up the texture into smaller images. Fixes #315
2019-11-23 13:24:36 +00:00
SquidDev
c4d18aa9ca Allow navigating read's input using the mouse 2019-11-23 13:21:07 +00:00
SquidDev
a8fadabaf1 Correct spelling in error message 2019-11-23 09:59:37 +00:00
SquidDev
38f9a015ca Wrap all remaining uses of Grgit
This allows you to build from a zip folder of CC:T. Fixes #307. Also fix
the build, woops.
2019-10-30 17:07:29 +00:00
SquidDev
c311cdc6f5 Make our Javadoc validation a little stricter
I'm not sure there's much utility in this, but still feels worth doing.
2019-10-27 15:16:47 +00:00
SquidDev
a93e0f3284 Expose ArgumentHelper in the public API
This is sufficiently useful a class, that it's worthwhile exposing it.
Hopefully we can slowly encourage other mods to migrate to it (well, at
least in 1.14), and so make error messages more consistent.

Also:
 - Add Javadoc for all public methods
 - Clarify the method names a little (getNumber -> getDouble,
   getReal -> getFiniteDouble).
 - Make the *Table methods return a Map<?,?> instead of
   Map<Object, Object>.
2019-10-27 14:29:07 +00:00
SquidDev
14b3065ba4 Check for trailing whitespace
I'd rather assumed one of the existing checkers did this already, but
apparently not.
2019-10-16 09:22:38 +01:00
SquidDev
c802290437 Bump version 2019-10-04 19:52:02 +01:00
SquidDev
418420523a Proxy the current turtle's inventory
Previously we were just returning the current tile. However, if someone
was holding a reference to this inventory (such as a GUI), then it'd be
outdated and invalid once the turtle had moved.

This caused a couple of issues:
 - turtle_inventory events would not be fired when moving items in the
   turtle GUI.
 - As of 75e2845c01, turtles would no
   longer share their inventory state after moving. Thus, removing items
   from a GUI using an invalid inventory would move them from an old
   tile, duplicating the items.

Fixes #298, fixes #300
2019-10-04 16:53:48 +01:00
Jonathan Coates
813e91073d Merge pull request #302 from Wendelstein7/master
Fixed turtle property category
2019-09-30 15:59:55 +01:00
Jonathan Coates
7250f22ff6 Update CI to also run on PRs 2019-09-30 15:37:52 +01:00
Wendelstein7
db31a53bba Fixed turtle property category
Likely was a leftover from copy pasting and a tired programmer.
2019-09-30 15:15:22 +02:00
SquidDev
3023f235a4 Goodbye Travis, I'm with GH Actions now 2019-09-27 08:56:53 +01:00
SquidDev
79cd8b4da5 Also return the number of affected entities
Closes #293. Doesn't really solve anything there aside from exposing the
number, but sadly there's not really anything obvious I can do on my end
- the command API just doesn't expose anything else.
2019-09-15 18:48:51 +01:00
Jonathan Coates
8e4d311cd9 Refactor shell completion into a separate module (#281)
- Adds cc.completions module, with a couple of helper functions for
   working with the more general completion functionality (i.e. that
   provided by read).
 - Adds cc.shell.completions module, which provides shell-specific
   completion functions.
 - Add a "program completion builder", which allows you to write stuff
   like this:

       shell.setCompletionFunction( "rom/programs/redstone.lua", 
         completion.build(
           { completion.choice, { "probe", "set ", "pulse " } },
           completion.side) )

Closes #232
2019-09-15 18:48:40 +01:00
SquidDev
9bd8c86a94 Change event priority to HIGHEST
See the comments in a802f25dd6 -
effectively we want to make sure we arrive before any other thing which
may capture items (some magnet mods, etc...).
2019-09-15 16:42:21 +01:00
Jonathan Coates
cbc0c1d0b6 A little experiment with GitHub actions
Let's give this a go.
2019-09-14 09:16:13 +01:00
SquidDev
49c37857d4 Window.reposition now allow changing the redirect buffer
See #270
2019-09-13 20:55:20 +01:00
SquidDev
a802f25dd6 Do not listen to block/entity drop events
It appears several mods inject their own drops on the LOWEST priority,
meaning that we capture the existing drops, and the other mod will clear
the (now empty) drop list and add its own, resulting in dupe bugs.

While I'd argue it's somewhat dubious doing this on the LOWEST priority,
it's not a battle I'm prepared to fight. For now, we just remove the
block/entity drop handlers, and handle all drop logic when entities are
spawned.

Fixes #288
2019-08-19 10:33:53 +01:00
Jonathan Coates
a80302c513 Merge pull request #287 from Lignum/patch-1
The pettiest of spelling fixes
2019-08-15 06:59:59 +01:00
Lignum
1c46949da7 Available 2019-08-15 07:37:02 +02:00
SquidDev
46d78af068 Fix changelog being out-of-sync 2019-08-04 11:05:44 +01:00
SquidDev
eb5cff1045 Alright, let's do this one last time 2019-08-04 09:27:48 +01:00
SquidDev
35c7792aa2 Limit the titles of printed pages
Just enforce the same restrictions as we do for computer/disk labels.
2019-08-04 08:59:44 +01:00
Jonathan Coates
521688d630 Merge pull request #183 from SquidDev-CC/feature/thread-safe-inventories 2019-08-01 14:30:32 +01:00
SquidDev
75e2845c01 Remove synchronized from turtle inventory code
These should never be called off the server thread, so this doesn't make
much difference.
2019-08-01 14:09:57 +01:00
SquidDev
2f96283286 Make disk drives thread-safe 2019-08-01 13:48:03 +01:00
SquidDev
cbe6e9b5f5 Make printers thread-safe 2019-08-01 13:48:03 +01:00
SquidDev
2ab79cf474 Version bumps 'n stuff 2019-07-30 15:48:05 +01:00
SquidDev
6ce34aba79 A quick attempt at fixing Travis
Oracle JDK 8 is EOL (I think at least).
2019-07-30 15:25:14 +01:00
SquidDev
5eeb320b60 Include all mods within a resource mount
This is the behaviour on 1.14 already, so it makes sense to backport to
1.12.

Any mod may now insert files into assets/computercraft/lua/rom, and
they'll be automatically added to the default ROM mount. This allows
other mods to easily register new programs or autorun files.

See #242
2019-07-30 15:20:08 +01:00
SquidDev
93310850d2 Use the "cc" module namespace instead of "craftos"
This is what we actually discussed in the issue, and I failed to
remember.
2019-07-27 11:34:59 +01:00
powerboat9
a2880b12ca Do not refuel beyond the turtle limit (#274) 2019-07-24 08:15:02 +01:00
powerboat9
303b57779a Fix turtles harvesting blocks when they shouldn't (#276)
harvestBlock should only be called when removedByPlayer and canHarvestBlock
return true, otherwise we run the risk of causing dupe bugs.

See #273.
2019-07-17 09:23:14 +01:00
SquidDev
6279816ecc Try using the HTTP one instead 2019-07-15 08:45:22 +01:00
SquidDev
4ae77261fa Petty changes because I'm petty 2019-07-13 08:29:28 +01:00
liquid
4b7d843b78 Removed term.getLine 2019-07-13 01:45:16 -05:00
liquid
1c28df65c3 Fixed style errors 2019-07-12 23:56:49 -05:00
liquid
85b740f484 Added term.getLine and window.getLine 2019-07-12 22:54:37 -05:00
SquidDev
f9929cb27d Fix the signature of loadfile
Lua 5.2+ uses loadfile(filename, mode, env), not loadfile(filename,
env). While this is a minor incompatibility, it'd be nice to be
consistent as much as possible.

We try to handle the incorrect case too, as obviously we don't want to
break existing programs.
2019-07-12 22:04:28 +01:00
SquidDev
bafab1ac07 Expose expect as a module (#267)
This moves expect from the bios into a new craftos.expect module,
removing the internal _G["~expect"] definition. Apparently people were
using this irrespective of the "don't use this" comment, so we need to
find another solution.

While this does introduce some ugliness (having to load the module in
weird ways for programs, duplicating the expect function in memory), it
does allow people to use the function in a supported way, and removes
the global ugliness.
2019-07-09 08:04:49 +01:00
JakobDev
e05c262468 Add more tests (#253)
I'm not entirely sure how useful all of these will be yet - still
trying to work out what/when to test things, but hopefully this'll
be a useful datapoint.
2019-07-08 09:24:05 +01:00
SquidDev
7a3f7d3bba I'm a muppet
Even worse, I enabled branch protection for some reason, and so can't
force push and pretend this never happened.
2019-06-29 15:49:14 +01:00
SquidDev
95aa48c456 Allow running expectations against stubbed functions
Co-authored-by: hydraz <urn@semi.works>
2019-06-29 15:37:41 +01:00
SquidDev
904a168d5c Fix incorrect explosion check
We should block explosions if the turtle is advanced /or/ if it's from
a fireball or entity, not if both.

Fixes #257
2019-06-21 18:53:28 +01:00
JakobDev
724441eddc Change URLs in build.gradle to https (#259) 2019-06-21 16:51:55 +01:00
SquidDev
f68ab3edd1 Minor tweaks to build script
Mostly just rearranging. Bump JUnit version in an attempt to fix test
outputs, but it appears this is a mix of gradle/gradle#5975 and
gradle/gradle#4438.
2019-06-15 11:05:45 +01:00
SquidDev
29dce26bf6 Clean up checkstyle warning
Fixes #251, closes #252
2019-06-14 20:55:32 +01:00
JakobDev
717ab69093 Add a few Checks (#248)
- Add some basic tests for several built-in programs.
 - Preserve the state of the shell between tests
2019-06-14 08:15:12 +01:00
SquidDev
138a2cf08f Merge branches 'copycheck' and 'renamefix' 2019-06-13 08:03:35 +01:00
JakobDev
81daf82647 Add Checks to copy.lua 2019-06-13 08:03:01 +01:00
JakobDev
f3798bfb63 Improve rename.lua's argument validation 2019-06-13 08:00:06 +01:00
SquidDev
bc07dfad2e Make sure all writeDescription methods are pure
We don't want to be firing block updates or anything from here! That
runs the ricks of causing CMEs and the like.

Fixes #245
2019-06-12 21:03:11 +01:00
JakobDev
309cbdb8be Add wget run (#218)
Equivalent to `pastebin run`, but allows running arbitrary URLs
instead.

Is this a little questionable? Yes - people shouldn't be downloading
and running code from the internet. But hey, people do that already,
so we might as well make it convenient.
2019-06-08 14:49:42 +01:00
SquidDev
a0e7c4a74c Add a little bit of source code checking to Gradle
- Adds a CheckStyle configuration which is pretty similar to CC's
   existing one.
 - Add the Gradle license plugin.
 - Ensure the existing source code is compatible with these additional
   checks.

See #239
2019-06-08 00:28:03 +01:00
Lignum
7d428030df Fix some warnings (#235)
Remove some unused code and fix a bunch of warnings
2019-06-07 14:35:17 +01:00
JakobDev
00c395f689 Add Check to delete.lua (#236) 2019-06-06 16:43:48 +01:00
SquidDev
d8e1c73d26 Ensure files cannot be closed multiple times
Also fix an NPE if we try to close them twice.

Fixes #230
2019-06-04 21:34:19 +01:00
SquidDev
ffa4cc241b Add a test utility for capturing program output
- Make mcfly's stubbing system a little more fault-tolerant.
 - Add a small utility function which redirects print, printError and
   write to capture their output, rather than printing to the terminal.
   This can then be matched against in order to determine a program's
   output.
   It's a little flakey - you can't use it multiple times in an it
   block, etc... but it's a nice feature.
 - Add a small couple of tests to delete as a proof-of-concept.
2019-06-03 20:33:09 +01:00
SquidDev
6f1b740c8f Un-localise paths in mount error messages
This is probably a little more complex than it needs to be, as we try to
handle the mounts as well (which generally don't error).

Fixes #229
2019-06-03 19:58:16 +01:00
SquidDev
3406ba3ebf Fix a build from a clean state failing 2019-06-02 18:48:36 +01:00
SquidDev
6b81bcf334 Bump version 2019-06-02 16:20:15 +01:00
SquidDev
acac70675d Add link to CF on the README
Not sure how useful this is - people are far more likely to come across
the CurseForge page than the GH one, but there's no harm I guess.

Closes #227
2019-06-01 15:15:39 +01:00
JakobDev
56434259c1 Add Checks for Turtle and Pocket programs (#226)
Error if turtle and pocket computers programs are not run on
their respective devices.
2019-06-01 12:48:33 +01:00
JakobDev
da7e4b9016 Add more MOTD messages. (#225) 2019-06-01 12:41:01 +01:00
SquidDev
d4b8650d21 Use select('#', ...) instead of ipairs on varargs
This means we don't discard any value after nil, meaning that
calls such as colors.combine(nil, 1, 2, 3) will error, rather
than returning 0.
2019-06-01 10:12:10 +01:00
SquidDev
17645a79f0 Fix type check on rednet.lookup
Fixes #224
2019-06-01 09:23:18 +01:00
SquidDev
ce1f14a010 Fix a couple of problems in the release buildscript
Otherwise that went pretty smoothly!
2019-05-31 13:56:48 +01:00
SquidDev
43050426de Bump version
First time using the new changelog tooling, let's see how this goes.
2019-05-31 13:53:15 +01:00
SquidDev
b05f60c98b Add small task to verify changelog is correct
Also use the changelog contents as the GH release notes
2019-05-31 10:19:24 +01:00
SquidDev
c44c560f96 Update changelog and whatsnew
- Convert existing changelog over to use Markdown. This mostly involves
   wrapping code in backticks, and marking things as headers where
   appropriate.
 - Copy all of CC:T's release notes over to the changelog. This is
   somewhat more verbose than Dan's notes, but keeping them in sync
   seems reasonable (and allows for automation!).
2019-05-31 09:35:45 +01:00
SquidDev
e839ef54af Forbid mutating empty_json_array
It's definitely still possible (rawset), but should prevent people
accidentally trying to modify it when they shouldn't.
2019-05-30 20:01:09 +01:00
SquidDev
0cb659d78c Ensure require is usable within the REPL
As 'require' operates relative to the current program's directory,
rather than the current directory, it meant we were trying to load files
from /rom/programs.

This is never a good idea, so we add the current directory to the
package path, allowing you to use require as one'd expect.
2019-05-30 19:52:55 +01:00
hydraz
9048deeb95 Add a function for type-checking arguments (#207)
- Define an expect(index, actual_value, types...) helper function which
   takes an argument index, value and list of permissable types and
   ensures the value is of one of those types.
   If not, it will produce an error message with the expected and actual
   type, as well as the argument number and (if available) the function
   name.
 - Expose expect in the global scope as _G["~expect"], hopefully making
   it clear it is internal.
 - Replace most manual type checks with this helper method.
 - Write tests to ensure this argument validation works as expected

Also fix a couple of bugs exposed by this refactor and the subsequent
tests:
 - Make rednet checks a little more strict - rednet.close(false) is no
   longer valid.
 - Error when attempting to redirect the terminal to itself 
   (term.redirect(term)).
2019-05-30 19:36:28 +01:00
SquidDev
5592ebae7d A small bit of housekeeping
- Add a link to discord and the forums. Oh goodness, I hope this
   doesn't count as making things official.
   I've had a couple of people email me with support requests, which is
   /fine/, but there's better channels for it!
 - Add a couple of PR templates
   - Ask people to write tests for CraftOS changes. This is a standard
     I'm trying to impose on myself, so seems reasonable to impose on
     everyone. Sorry!
   - Require same levels of explanation for PRs as we do for issues.
 - Try to expand on the feature request "rationale" section a little.
   Just trying to explan my process a little bit more.
2019-05-30 08:44:15 +01:00
SquidDev
b076c32fd1 Merge remote-tracking branch 'origin' 2019-05-30 07:57:30 +01:00
SquidDev
a48f1e310f Add a custom renderer for monitor block highlights (#220)
This only renders the bounding box on non-screen edges of the monitor,
meaning you have an uninterrupted view of the screen when hovering
hover.

Closes #219
2019-05-30 07:51:35 +01:00
SquidDev
19aca001d7 A couple of stability improvements to ComputerThread
- Be more generous in what errors we catch, handling some of the more
   "recoverable" ones.
 - Should a runner crash, attempt to restart it.
2019-05-29 09:03:31 +01:00
SquidDev
114f913bf8 Rework rendering of in-hand pocket computers (#215)
Rendering an item worked in principle, but had several caveats:
 - The terminal did not fit well within the item's texture, so we had a
   rather large border.
 - The "correctness" of this was very tied to Minecraft's item rendering
   code. This changed a little in 1.13, causing problems like #208.

Instead we effectively reuse the computer GUI rendering code, though
also handling coloured pocket computers and rendering the modem light.

This fixes #208, and hopefully fixes #212.
2019-05-26 15:24:37 +01:00
Daniel Ratcliffe
1c9810890a Merge pull request #577 from SquidDev-CC/feature/get-blink
Add .getCursorBlink to monitors and terminals
2019-05-26 00:14:02 +01:00
SquidDev
b11beb508b Convert mkdir motd note to plural
*shrug*
2019-05-25 19:17:10 +01:00
SquidDev
af8d4da594 Ensure the test name is ASCII
Gradle really doesn't like unicode apparently
2019-05-25 18:11:14 +01:00
JakobDev
a81db2cda6 Allow multiple arguments for mkdir (#216) 2019-05-25 18:04:56 +01:00
SquidDev
99bdff0f92 Automatically label issues created with templates 2019-05-25 14:53:48 +01:00
hydraz
5b0ce7410d Make delete delete many files (#210)
Actually, many *globs*. It additionally prints the glob if no files
matched it, since that's clearer.

Also move the ComputerTestDelegate's filesystem to be disk-based. This
is what actual computers use, and the MemoryMount is a little broken.
2019-05-25 09:02:42 +01:00
SquidDev
d5ea22d1a0 Jolly good job 2019-05-24 22:43:59 +01:00
SquidDev
210f3fa9e2 Add mostly standard compliant os.time/os.date
- os.time, when given a table, will act the same as PUC Lua - returning
   the seconds since the epoch. We preserve the previous string/nil
   behaviour though - os.epoch("local") is equivalent to PUC's
   os.time().

 - os.date will now act accept a string and (optional) time, returning
   an appropriate table.

Somewhat resolves the madness which was dan200/ComputerCraft#183, and
hopefully (though probably not) makes @Vexatos happy.
2019-05-24 22:33:56 +01:00
SquidDev
d661cfa88b Set the arg table within shell.run
This makes us a little more compatible with Lua
2019-05-24 18:42:19 +01:00
SquidDev
68bf3a71dc Lazilly instantiate the terminal packet
This means we don't create an NBT tag every tick if the screen is
updating, unless we actually need to.
2019-05-24 18:32:56 +01:00
SquidDev
3cdb12d293 Stop shipping jars with GH releases
The build appears to be a little bit broken, I haven't got willpower to
look into it, and it's not really used anyway.
2019-05-14 07:44:19 +01:00
Wilma456 (Jakob0815)
ad33acd7d1 Add MOTD (#175) 2019-05-13 16:54:19 +01:00
SquidDev
0ec3884e98 Handle websockets which close while receiving
This changes the previous behaviour a little, but hopefully is more
sane:

 - Only require the socket to be open when first calling receive. This
   means if it closes while receving, you won't get an error.

   This behaviour is still not perfect - the socket could have closed,
   but the event not reached the user yet, but it's better.

 - Listen to websocket_close events while receiving, and return null
   should it match ours.

See #201
2019-05-08 08:16:21 +01:00
SquidDev
7f2471d6b2 Fix list-like config options not reloading
Closes #199
2019-05-08 08:00:07 +01:00
SquidDev
8fafec4915 Fix budget growing too much
We were using += instead of =, meaning the budget always grew,
rather than growing while there was still space. As a result, computers
were never correctly rate limited.

Further more, if a computer went into a deficit, we would continue to
increase the budget by a negative amount, exponentially decreasing until
overflowing!

Yes, this is a very embarrassing mistake. I'd been aware that rate
limiting wasn't working as expected for a while, I hadn't realised
the problem would be this stupid.
2019-05-01 17:24:30 +01:00
SquidDev
b9fd690ecb Mark CC:T as incompatible with ComputerCraft
Just so people using the Twitch client don't try to use both.
2019-05-01 17:24:30 +01:00
xuyu0v0
2f2ada4416 Create zh_cn.lang (#186) 2019-04-24 15:41:13 +01:00
SquidDev
9c951c58d9 Revert "Switch over to Curse maven for now"
This reverts commit 4b4b47e231.

Didn't need it for that long. Woops.
2019-04-24 15:17:13 +01:00
SquidDev
4b4b47e231 Switch over to Curse maven for now
It stinks, but it's a suitable workaround.

Closes #184
2019-04-24 14:48:11 +01:00
SquidDev
978c28a686 Bump version 2019-04-24 09:48:28 +01:00
SquidDev
b867ada5e5 Merge pull request #182 from SquidDev-CC/hotfix/redstone-checks
Redstone behaviour tweaks
2019-04-24 09:45:28 +01:00
SquidDev
7071cc972b Make redstone behaviour consistent with repeaters
This uses the same behaviour that repeaters and comparators do for
determining their input, meaning that redstone directly connected to the
computer is read (as you would expect).

It's worth noting that this is a shift from previous behaviour.
Therefore, it runs the (small) risk of breaking existing builds.
However, I believe it is more consistent with the expected behaviour.
2019-04-22 11:52:53 +01:00
SquidDev
6898f932a0 Remove redstone blocked checks
This has been returning false for almost 2 years (since
8abff95441). At this point, it's probably
worth just dropping it entirely.
2019-04-22 11:40:19 +01:00
SquidDev
2e0ef6385d Fix TurtleCompareCommand throwing exceptions
Originally introduced in 173ea72001, but
the underlying cause has been happening for much longer.

 - Fix order of method name parameters. Looks like this has been broken
   since 1.11. Woops.
 - Catch RuntimeExceptions too, as Forge converts checked into unchecked
   ones.

Fixes #179
2019-04-19 18:57:12 +01:00
SquidDev
f93da7ea51 Bump Cobalt version
I promise! The joys of using -SNAPSHOT I guess...

This will now correctly cause orphaned threads to be cleaned up,
reducing the risk of thread saturation.
2019-04-18 09:49:52 +01:00
SquidDev
1210bb8a4d Fix Gradle dependencies
I'm not entirely sure why it didn't like the previous version, but there
we go.
2019-04-16 10:43:11 +01:00
SquidDev
48a71e96eb Bump version 2019-04-16 10:35:15 +01:00
SquidDev
3bf47b5290 Make refuelling a little more flexible
This removes the link between item size and refuel limit, meaning
working with other items (such as FE items) is a little easier.
2019-04-16 10:28:10 +01:00
SquidDev
9e9f199e55 Remove a couple of over-eager error logs 2019-04-16 10:08:12 +01:00
SquidDev
5a8a111857 You didn't see nothing 2019-04-15 18:33:59 +01:00
SquidDev
48ba247ab4 Create an IMultipartTile for all BlockPeripheral tiles
Fixes #176
2019-04-15 09:21:10 +01:00
SquidDev
b195cab6a7 Add a couple of colours unit tests 2019-04-09 10:35:23 +01:00
SquidDev
63dc0daa09 Convert computer sides to an enum
Previously we just relied on magic int values, which was confusing and
potentially error-prone. We could use EnumFacing, but that's a)
dependent on MC and b) incorrect, as we're referring to local
coordinates.
2019-04-09 10:02:54 +01:00
SquidDev
34602ec4be Move null checks from Preconditions to Objects 2019-04-08 14:54:57 +01:00
SquidDev
f3ce44042f Update all inputs if the block is not a neighbour
Fixes #172, and acts as a workaround for MrTJP/ProjectRed#1472.
2019-04-08 14:52:24 +01:00
SquidDev
4205f18f0c Publish jar files to GH too
I'm not sure if I'll keep this, as it's a little redundant. We're on an
older version of the plugin, as 2.2.7 seems to fail for me.

Closes #165.
2019-04-07 15:30:27 +01:00
SquidDev
6be330ae8d Expose Computer.getRootMount again
It's a little evil, but we need it for CCEmuX. There's other ways of
achieving this, but not with supporting CC and CC:T.
2019-04-07 14:58:25 +01:00
SquidDev
4569af2130 Bump version 2019-04-06 22:42:44 +01:00
SquidDev
765c31315a Make redstone updates identical to how MC does it
Also fixes rather embarassing bug with redstone not updating.
2019-04-06 22:42:03 +01:00
Wilma456 (Jakob0815)
0e191e42a0 Update de_de.lang (#166) 2019-04-03 14:58:04 +01:00
SquidDev
ca34b2a1b8 Update the dependency info a little 2019-04-02 21:37:19 +01:00
SquidDev
1fd0b40776 Fix printing not updating the output display state 2019-04-02 12:21:59 +01:00
SquidDev
2965fb666f Some further cleanup and 1.13 cherry-picks
Are most of these changes small and petty? Yes. However, IMO they do
make the code more readable. Anyway, a summary of some of the more
interesting changes:

 - Expose Abstract*Upgrade classes in the API
 - Fix the spelling of Jonathan in the API docs (*shakes fist*)
 - Fix bug with printout not working in the offhand.
 - Rename any argments/variables accidentally named "m_*", and add an
   inspection to prevent it happening again.
 - Remove most of the Block*.Properties classes - just inline them in
   the parent class.
 - Return super.writeToNBT instead of reassigning at the top.
2019-04-02 12:08:03 +01:00
Luca S
390575ab4d rednet.send now returns if the message was send (#164)
This makes use of the "sent" variable, which would otherwise go unused. It also makes rednet.send compliant to the behaviour specified in the Wiki: http://www.computercraft.info/wiki/Rednet.send
2019-04-01 19:31:21 +01:00
SquidDev
e4ef92ca2d Expose a stub "cctweaked" mod
This is largely invisible (it's marked as a child of the main
"computercraft" mod), but allows other mods (such as Plethora) to add
hard/soft dependencies on CC:T in a user-friendly manner.
2019-03-30 16:41:45 +00:00
SquidDev
9bf586b018 Make turtle crafting more consistent with vanilla
- Fire all the appropriate Forge hooks
 - Crafting will now attempt to craft one item at a time in a loop,
   instead of multiplying the resulting stack by the number of crafts.
   This means we function as expected on recipes which consume
   durability instead.
 - Cache the recipe between crafting and getting the remainder (and each
   craft loop). This should reduce any performance hit we would
   otherwise get.
2019-03-30 16:12:49 +00:00
SquidDev
173ea72001 Turn inspections up to 11
OK, so let's get this out of the way, there's some actual changes mixed
in here too. I'm really sorry:
 - Turtles can now not be renamed with unnamed item tags (previously it
   would clear the name, this seemed a little unideal).
 - commands.getBlock(s)Data will also include NBT.

Now, onto the horror story which is these inspection changes:
 - Make a lot of methods static
 - Typo fixes
 - Make utility classes final + private constructor
 - Lots of reformatting (ifs -> ternary, invert control flow, etc...)
 - ???
 - Profit!

I'm so going to regret this - can pretty much guarantee this is going to
break something.
2019-03-29 21:26:21 +00:00
SquidDev
1230cabcb0 Add an event for inspecting items too
We've had one for blocks for ever after all.
2019-03-27 20:58:14 +00:00
SquidDev
6ed03e1fcd Convert turtle refuelling into an event
This should allow us (or other mods) to register custom refuel handlers
should they so wish.
2019-03-27 20:38:39 +00:00
SquidDev
c4b371b124 Cherry pick several improvements from 1.13
- Move container opening (and gui handling) into a separate class
 - Move turtle/computer placement code onto the block
 - GUIs now use gui{Left,Top} instead of calculating it manually.
 - IPeripheralTile is now exposed in the API.
2019-03-27 19:20:59 +00:00
SquidDev
a600213b00 Merge pull request #153 from SquidDev-CC/feature/main-thread-limits 2019-03-26 11:28:35 +00:00
SquidDev
7799b8d4cb Convert MainThread into a priority queue
This uses a similar approach to ComputerThread: executors store how long
they've spent executing tasks. We then use that time to prioritise
executors.

One should note that we use the current runtime at the point of adding
to the queue - external tasks will not contribute towards it until a
later execution.
2019-03-26 11:21:40 +00:00
SquidDev
245bf26480 Expose max computer/global times as config options
These do have a direct impact on server performance, so are definitely
worthwhile exposing.
2019-03-26 11:21:40 +00:00
SquidDev
5d05205d69 Introduce IWorkMonitor into the public API
This effectively acts as a public interface to canExecuteExternal() and
consumeTime(). It's hopefully sufficiently general that we can mess
around with the backend as much as we like in the future.

One thing to note here is that this is based on a polling API, as it's
largely intended for people running work every tick. It would be
possible to adapt this with callbacks for when work is available,
etc..., but that was not needed immediately.

This also removes IComputerOwned, as Plethora no longer needs it.
2019-03-26 11:21:16 +00:00
SquidDev
853e2622a1 An initial prototype of main thread rate limiting
Unlike ComputerThread, we do not have a single source of tasks, and so
need a smarter way to handle scheduling and rate limiting. This
introduces a cooldown system, which works on both a global and
per-computer level:

Each computer is allowed to do some work for 5ms. If they go over that
budget, then they are marked as "hot", and will not execute work on the
next tick, until they have cooled down. This ensures that _on average_
computers perform at most 5ms of work per tick.

Obviously this is a rather large time span, so we also apply a global
10ms to all computers. This uses the same cooldown principle, meaning we
keep to an average of 10ms, even if we go over budget.
2019-03-26 11:21:16 +00:00
SquidDev
d0bf9e9cd7 Fix config reloading not working as expected
We were not updating the property instances, so we never actually used
the new values. This changes the syncing method to just copy values from
the new config file, meaning comments and structure are preserved from
the old one.

Note, we cannot just call Config.load(File) again, as the defaults are
no longer accurate.
2019-03-26 11:06:33 +00:00
SquidDev
7a7951ae68 Keep track of the current input state on the server
- We send special packets for key and mouse events, which are then
   processed by the container's InputState.
 - InputState keeps track of currently held keys and mouse buttons.
 - When closing the container, we queue key_up/mouse_up events for any
   pending buttons.
2019-03-24 21:58:13 +00:00
SquidDev
bd28955c8e Fix ComputerThread not updating the minimumVirtualRuntime
We attempted to simplify this 0bfb7049b0,
but that change now means that minimumVirtualRuntime is not updated. As
a result, new tasks will have a runtime of 0 when the queue is empty.
2019-03-24 18:13:00 +00:00
SquidDev
e46f09a939 Several recipe improvements
- Some performance improvements to JEI recipe resolver
   - Use a shared map for upgrade items, meaning we only need one map
     lookup.
   - Cache the basic upgrade recipes.
 - Use the MC version within project rather than version name.
2019-03-19 11:59:23 +00:00
daelvn
71b1f8138d Localize ComputerCraft for es_ES
Español de España (Castellano)
2019-03-19 09:50:21 +00:00
Wilma456 (Jakob0815)
1d82a1c98c Update German translation (#145) 2019-03-19 09:43:32 +00:00
Wilma456 (Jakob0815)
b5f60f3f11 Correct typo within en_us.lang (#144) 2019-03-16 17:00:26 +00:00
SquidDev
259665d9f1 Add a more strict form of IPocketAccess.getEntity
Before IPocketAccess.getEntity would return the entity which last held
fthis computer, even if not holding it any more. As
ba823bae13 describes, this caused
pocket.equip/pocket.unequip to dupe items.

We move the validation from the PocketAPI into the main IPocketAccess
implementation, to ensure this issue does not occur elsewhere. Note, we
require a separate method, as this is no longer thread-safe.

We also now return ok, err instead of throwing an exception, in order to
be consistent with the turtle functions. See dan200/ComputerCraft#328.
2019-03-16 11:18:03 +00:00
Iunius118
ba823bae13 Fix Pocket API working outside of player inventory
This makes Pocket API not equip/unequip upgrades when the pocket
computer is outside of the player inventory (e.g. dragging,
dropped, placed in a chest).
2019-03-16 11:08:44 +00:00
SquidDev
1290a4402c Add a tool to verify language files are well formed
I'm not going to pretend this is a beautiful script, but it's good
enough for basic validation of language files.
2019-03-16 11:04:37 +00:00
absolument
379076a5e2 Localize ComputerCraft for fr_fr
Following #488
Here is my translation in french fr_fr
2019-03-16 11:00:41 +00:00
SquidDev
d12bdf50d8 Remove most instances of non-translatable strings
Oh goodness, this is going to painful to update to 1.13.

We now translate:
 - Computer/Disk ID tooltips
 - /computercraft descriptions, synopsises and usages. The last of these
   may not always be translated when in SMP, as it is sometimes done on
   the server, but the alternative would be more complex than I'm happy
   with.
 - Tracking field names. Might be worth adding descriptions too in the
   future.

Also cleanup a couple of other translation keys, so they're more
consistent with Minecraft.

Closes #141
2019-03-16 10:26:40 +00:00
SquidDev
cbfd5aeeee Use Minecraft's "can use command blocks" check
Just means we're a little more consistent, and hopefully can remove
canPlayerUseCommands in the future, once Plethora stops using it.
2019-03-16 01:55:38 +00:00
SquidDev
41429bdc0b Improve our JEI integration a little bit
- Turtle and pocket computers provide a "creator mod id" based on their
   upgrade(s).
   We track which mod was active when the upgrade was registered, and
   use that to determine the owner. Technically we could use the
   RegistryLocation ID, but this is not always correct (such as
   Plethora's vanilla modules).
 - We show all upgraded turtles/pocket computers in JEI now, rather than
   just CC ones.
 - We provide a custom IRecipeRegistryPlugin for upgrades, which
   provides custom usage/recipes for any upgrade or upgraded item. We
   also hide our generated turtle/pocket computer recipes in order to
   prevent duplicates.
2019-03-16 01:51:12 +00:00
SquidDev
54b9966feb Make upgrade crafting even more lenient
This now allows items with empty tags to equal those with no tag.
2019-03-16 01:51:00 +00:00
SquidDev
105c66127c Automatically generate impostor recipes
Previously we would register the recipes within our code, but the
advancements were written manually. This now generates JSON files for
both the advancement and recipe.

While this does mean we're shipping even more JSON, we'll need to do
this for 1.13 anyway, and means our advancements are guaranteed to be
consistent.

On a side note, a couple of other changes:
 - Turtle upgrades are now mounted on the right in the creative
   menu/fake recipes. This means the upgrade is now clearly visible in
   the inventory.
 - We no longer generate legacy turtle items at all: we'll always
   construct turtle_expanded.
 - Several peripheral items are no longer registered as having sub-types
   (namely advanced and full-block modems).
 - We only have one disk advancement now, which unlocks all 16 recipes.
 - We have removed the disk conversion recipes - these can be
   exposed through JEI if needed.
2019-03-16 00:15:31 +00:00
SquidDev
765ad0bd3f Some basic integration with MCMP
This allows wireless modems (advanced and normal) to be used in
multiparts. There's a very limited set of uses for this (mostly allows
using Chisel and Bits with them), but it's very simple to do.

I'd like to look into MCMP support for wired modems/cables in the
future, but this will be somewhat harder due to their pre-existing
multiblock structure.

Similarly, might be fun to look into CBMP compatibility.
2019-03-14 22:14:47 +00:00
Linus Ramneborg
dd05478483 Localize for Swedish (#139) 2019-03-14 22:14:13 +00:00
hydraz
5d028dea39 Add pt_BR lang file 2019-03-14 17:15:34 +00:00
SquidDev
629c51d260 Fix language silliness 2019-03-14 17:15:05 +00:00
Alessandro
9ea57961af Added Italian language (#138) 2019-03-14 16:55:38 +00:00
Luca
07b9b1c9c7 os.time() and os.day() join the "Finally Case-Insensitive Party" 2019-03-13 15:42:39 +00:00
SquidDev
5b942ff9c1 Some changes to Lua machines and string loading
- Share the ILuaContext across all method calls, as well as shifting it
   into an anonymous class.
 - Move the load/loadstring prefixing into bios.lua
 - Be less militant in prefixing chunk names:
   - load will no longer do any auto-prefixing.
   - loadstring will not prefix when there no chunk name is supplied.
     Before we would do `"=" .. supplied_program`, which made no sense.
2019-03-10 12:24:55 +00:00
SquidDev
7b5a918941 Improve AddressPredicate error messages a little
See #134.
2019-03-10 11:22:11 +00:00
SquidDev
47721bf76b Allow running pastebin with the URL
For instance, `pastebin run https://pastebin.com/LYAxmSby` will now
extract the code and download appropriately. Also add an error message
when we received something which is not a valid pastebin code.

See #134.
2019-03-10 11:11:49 +00:00
SquidDev
35ce0974cd Fix NPE when checking URLs
If the host was null due to a malformed URL, we'd try to verify that it
was allowed, throwing an NPE.

Fixes #135
2019-03-10 10:45:30 +00:00
SquidDev
52e1906d42 Add a basic test framework for CraftOS
This runs tests on CraftOS using a tiny test runner that I originally
knocked up for LuaDash. It can be run both from JUnit (so IDEA and
Gradle) and in-game in the shell, so is pretty accessible to work with.

I also add a very basic POC test for the io library. I'd like to flesh
this out soon enough to contain most of the things from the original io
test.
2019-03-10 10:45:25 +00:00
SquidDev
eaf24a3ceb Update to JUnit 5
Also display test results within the Gradle build
2019-03-10 09:40:06 +00:00
SquidDev
62760e371e Add a section on how to depend on CC:T
It's not immediatly obvious where our maven repository is.
2019-03-04 22:59:38 +00:00
SquidDev
e154e11186 Select the initial multishell tab when starting up
Before it was not actually selected until the task had yielded for the
first time. If a computer did not yield (or took a while to do so),
nothing would actually show up.
2019-03-04 16:37:08 +00:00
SquidDev
72d079ef61 Merge pull request #119 from SquidDev-CC/feature/computer-thread-schedule
- CobaltLuaMachine/ComputerExecutor can now be paused - this suspends 
   the machine via a debug hook. When doing work again, we resume the 
   machine, rather than starting a new task.
 - TimeoutState keeps track of how long the current execution of this task
   has gone on for, when its deadline is, and the cumulative execution time of
   this task.
 - ComputerThread now uses a CFS based scheduler in order to determine which
   computer to next run.
2019-03-04 15:46:28 +00:00
SquidDev
0bfb7049b0 Document everything, and several further improvements
- Only update all runtimes and the minimum runtime when queuing new
   exectors. We only need to update the current executor's runtime.
 - Fix overflows when comparing times within TimeoutState.
   System.nanotime() may (though probably won't) return negative values.
 - Hopefully explain how the scheduler works a little bit.
2019-03-04 10:22:17 +00:00
SquidDev
f7cb526793 Attempt to fix race condition in ComputerThread
- Runners would set their active executor before starting resetting the
   time, meaning it would be judged as running and terminated.
 - Similarly, the cumulative time start was reset to 0, meaning the
   computer had been judged to run for an impossibly long time.
 - If a computer hit the terminate threshold, but not the hard abort
   one, then we'd print the stack trace of the terminated thread - we
   now do it before interrupting.

There's still race conditions here when terminating a computer, but
hopefully these changes will mean they never occur under normal
operations (only when a computer has run for far too long).
2019-03-04 09:22:14 +00:00
SquidDev
e34e833d3d Small changes to ComputerThread
- Fix the timeout error message displaying utter rot.
 - Don't resize the runner array. We don't handle this correctly, so
   we shouldn't handle it at all.
 - Increment virtualRuntime after a task has executed.
2019-03-02 09:16:25 +00:00
SquidDev
a125a19728 Implement a CFS based scheduler
- The computer queue is a priority queue sorted by "virtual runtime".
 - Virtual runtime is based on the time this task has executed, divided
   by the number of pending tasks.
 - We try to execute every task within a given period. Each computer is
   allocated a fair share of that period, depending how many tasks are
   in the queue. Once a computer has used more than that period, the
   computer is paused and the next one resumed.
2019-02-28 17:23:09 +00:00
SquidDev
b3e6a53868 Allow pausing Lua machines
TimeoutState now introduces a TIMESLICE, which is the maximum period of
time a computer can run before we will look into pausing it.

When we have executed a task for more than this period, and if there are
other computers waiting to execute work, then we will suspend the
machine.

Suspending the machine sets a flag on the ComputerExecutor, and pauses
the "cumulative" time - the time spent handling this particular event.
When resuming the machine, we restart our timer and resume the machine.
2019-02-28 16:49:06 +00:00
SquidDev
218f8e53bb Further improvements to computer execution
Oh goodness, when will it end?

 - Computer errors are shown in red.

 - Lua machine operations provide whether they succeeded, and an
   optional error message (reason bios failed to load, timeout error,
   another Lua error), which is then shown to the user.

 - Clear the Cobalt "thrown soft abort" flag when resuming, rather than
   every n instructions.

 - Computers will clear their "should start" flag once the time has
   expired, irrespective of whether it turned on or not. Before
   computers would immediately restart after shutting down if the flag
   had been set much earlier.

Errors within the Lua machine are displayed in a more friendly
2019-02-28 15:44:43 +00:00
SquidDev
d02575528b Fix leaking file descriptors when closing
When closing a BufferedWriter, we close the underlying writer. As we're
using channels, this is an instance of sun.nio.cs.StreamEncoder. This
will attempt to flush the pending character.

However, if throwing an exception within .write errors, the flush will
fail and so the underlying stream is not closed. This was causing us to
leak file descriptors.

We fix this by introducing ChannelWrappers - this holds the wrapper
object (say, a BufferedWriter) and underlying channel. When closed, we
dispose of the wrapper, and then the channel. You could think of this as
doing a nested try-with-resources, rather than a single one.

Note, this is not related to JDK-6378948 - this occurs in the underlying
stream encoder instead.
2019-02-28 11:24:12 +00:00
SquidDev
c78adb2cdc Several improvements to the computer thread rework
- TimeoutState uses nanoseconds rather than milliseconds. While this is
   slightly less efficient on Windows, it's a) not the bottleneck of Lua
   execution and b) we need a monotonic counter, otherwise we could
   fail to terminate computers if the time changes.
 - Add an exception handler to all threads.
 - Document several classes a little better - I'm not sure how useful
   all of these are, but _hopefully_ it'll make the internals a little
   more accessible.
2019-02-27 20:56:45 +00:00
SquidDev
3e28f79ce9 Shutdown computers in /computercraft shutdown
Unloading them now means they'll never be turned on again, which is a
little unideal.
2019-02-27 13:49:07 +00:00
SquidDev
67af7a698b Migrate the computer tasks into a separate thread
- Move state management (turnOn, shutdown, etc...) event handling and
   the command queue into a ComputerExecutor

 - This means the computer thread now just handles running "work" on
   computer executors, rather than managing a separate command queue +
   requeuing it.
2019-02-26 13:50:09 +00:00
SquidDev
06e76f9b15 Rewrite ComputerThread and the timeout system
- Instead of setting soft/hard timeouts on the ILuaMachine, we instead
   provide it with a TimeoutState instance. This holds the current abort
   flags, which can then be polled within debug hooks.

   This means the Lua machine has to do less state management, but also
   allows a more flexible implementation of aborts.

 - Soft aborts are now handled by the TimeoutState - we track when the
   task was started, and now only need to check we're more than 7s since
   then.

   Note, these timers work with millisecond granularity, rather than
   nano, as this invokes substantially less overhead.

 - Instead of having n runners being observed with n managers, we now
   have n runners and 1 manager (or Monitor).

   The runners are now responsible for pulling work from the queue. When
   the start to execute a task, they set the time execution commenced.
   The monitor then just checks each runner every 0.1s and handles hard
   aborts (or killing the thread if need be).
2019-02-26 13:46:10 +00:00
SquidDev
6d383d005c A couple of minor tweaks
- Rename unload -> close to be a little more consistent
 - Make pollAndResetChanged be atomic, so we don't need to aquire a lock
 - Get the computer queue from the task owner, rather than a separate
   argument.
2019-02-26 12:43:45 +00:00
SquidDev
c373583723 Add a test which boots a computer and runs forever
Ideally we'd add a couple more tests in the future, but this'll do for
now.

The bootstrap class is largely yoinked from CCTweaks-Lua, so is a tad
ugly. It works though.
2019-02-26 08:44:17 +00:00
SquidDev
f1d10809d5 Make commands.collapseArgs a little more sane
We now generate a table and concatinate the elements together. This has
several benefits:
 - We no longer emit emit trailing spaces, which caused issues on 1.13's
   command system.
 - We no longer need the error level variable, nor have the weird
   recursion system - it's just easier to understand.
2019-02-26 08:40:48 +00:00
SquidDev
474f571798 Attach peripherals directly rather than deferring
Prior to this change we would schedule a new task which attached
peripherals on the ComputerThread on the empty task queue. This had a
couple of issues:
 - Slow running tasks on the computer thread could result in delays in
   peripherals being attached (technically, though rarely seen in
   practice).
 - Now that the ComputerThread runs tasks at once, there was a race
   condition in computers being turned on/off and peripherals being
   attached/detached.

Note, while the documentation said that peripherals would only be
(at|de)tached on the computer thread, wired modems would attach on the
server thread, so this was not the case in practice.

One should be aware that peripherals are still detached on the
computer thread, most notably when turning a computer on/off.

This is almost definitely going to break some less well-behaved mods,
and possible some of the well behaved ones. I've tested this on SC, so
it definitely works fine with Computronics and Plethora.
2019-02-25 19:11:35 +00:00
SquidDev
fb9c125ab8 Update Cobalt version for latest bugfixes/changes
- Fix load not unwinding stack
 - Allow transferring control between coroutines when unwinding is
   disabled

Fixes #128
2019-02-25 14:18:45 +00:00
SquidDev
162fb37421 Handle Pastebin spam protection and add a cache buster (#127) 2019-02-24 20:06:02 +00:00
Drew Lemmy
d953f031f0 Remove debugging line 😬 2019-02-24 20:00:26 +00:00
Drew Lemmy
7fde89ad95 Use stderr for pastebin errors, and a prettier cache buster 2019-02-24 19:59:10 +00:00
Drew Lemmy
bd04a93ffb Handle pastebin spam protection and add a cache buster 2019-02-24 13:47:09 +00:00
SquidDev
e2bfaafe28 Bump version for colour fix 2019-02-24 08:20:22 +00:00
SquidDev
1fb3d16b89 Fix colours.*RGB methods working with 8 bit values
They should have been using 0-1s instead. I'm a moron for not noting
this earlier, and not testing this.
2019-02-23 23:20:46 +00:00
SquidDev
35645b3d93 Add back a couple of methods for CCEmuX compat 2019-02-23 12:46:09 +00:00
SquidDev
a4cd1fe77d Stop releasing betas by default
Things just got serious I guess??
2019-02-23 10:35:15 +00:00
Wilma456 (Jakob0815)
4145914024 Make Multishell Scrollable (#123)
You can now Scroll through the program list, if the list bigger than your
screen.
2019-02-21 16:00:13 +00:00
SquidDev
6bd11a5e4a Fix the other instance of the neighbour deprecation warning 2019-02-20 18:37:22 +00:00
SquidDev
46fa798797 Several minor improvements
- Restrict what items can be inserted into printers. They're now closer
   to brewing stands or furnaces: nothing can go in the output slot,
   only ink in the ink slot, and only paper in the paper slot.
 - Fix build.gradle using the wrong version
 - Trim the width of tables to fit when displaying on the client. Closes
   #45. Note, our solution isn't perfect, as it will wordwrap too, but
   it's adaquate for now.
2019-02-20 09:48:16 +00:00
SquidDev
70a226207e Update README and versioning (#121)
- Reword elements of the README, mostly changing the elements about
   vanilla ComputerCraft.
 - Change versioning scheme: we'll now do 1.x.y, with 1.81.0 being the
   next version.
 - Include MC version in the file name
 - Stop bundling javadoc with the jar. We'll look into hosting this on
   squiddev.cc if really needed.
 - Remove the LuaJ license from the root - we no longer bundle the
   sources, so it's not needed here.

I realise this change looks a little dodgey on its own, so see #113 for
the full rationale.
2019-02-19 14:49:13 +00:00
SquidDev
257a35f3ed Merge pull request #120 from SquidDev-CC/feature/palette-improvements
Minor palette improvements
2019-02-19 10:59:35 +00:00
Lignum
af01b9514b Split colours.rgb8 into colours.packRGB and colours.unpackRGB 2019-02-19 09:51:01 +00:00
Lignum
070fd1f2ff Add term.nativePaletteColo(u)r 2019-02-19 09:50:57 +00:00
SquidDev
fb59da2b06 Update GitHub templates, removing CC repo links
See #113
2019-02-18 23:35:50 +00:00
SquidDev
11e4d0de82 Fix turtle peripherals becoming desynced
When a turtle was unloaded but not actually disposed of, the
m_peripheral map hangs around. As a result, when creating a new
ServerComputer, the peripherals aren't considered changed and so they're
never attached.

Fixes #50.

Also fix that blumin' deprecated method which has been around for a wee
while now.
2019-02-18 23:28:51 +00:00
SquidDev
e46ab1e267 Revert some image optimisations 2019-02-18 22:58:39 +00:00
SquidDev
d6e0f368df Handle managing computer inputs/outputs separatly
The Computer class currently has several resposiblities such as storing
id/label, managing redstone/peirpherals, handling management of the
computer (on/off/events) and updating the output.

In order to simplify this a little bit, we move our IAPIEnvironment
implementation into a separate file, and store all "world state"
(redstone + peripherals) in there. While we still need to have some
level of updating them within the main Computer instance, it's
substantially simpler.
2019-02-17 19:48:52 +00:00
SquidDev
9f2884bc0f Several minor improvments to websockets
- Fire close events instead of failure when open websockets error.
 - Handle ping events. I thought I was doing this already, but this
   requires a WebsocketProtocolHandler. Fixes #118
2019-02-17 19:36:18 +00:00
SquidDev
18d468e887 Fix building from a fresh setup
We were attempting to resolve the Forge jars before they had been
generated, which meant the build failed.
2019-02-16 16:01:47 +00:00
SquidDev
63f6735bb8 Attempt to reduce jar size a little
- Run optipng on all our images. This has very little effect on most of
   them (as they're all so small anyway), but has resulted in a 50%
   reduction in some cases.
 - Run Proguard on our shadowed dependencies (Cobalt).
 - Minify our JSON files, stripping all whitespace. This is mostly
   useful for FML's annotation cache, as that's a massive file, but
   still a semi-useful optimisation to make.

This has helped reduce the jar by about 110kb, which isn't much but
still feels somewhat worth it.
2019-02-14 10:53:18 +00:00
SquidDev
ab6f0ccd16 Fix advanced modems not actually being advanced
We were constructing the peripheral before the advanced property had
been set, thus it was always false. Yay for Java.

Closes #111
2019-02-12 18:11:04 +00:00
SquidDev
ae0f093e73 Strip \r from .readLine on binary handles
Note, this is technically inconsistent with the spec. However, we'll use
this method for now in order to remain backwards compatible.

Fixes #109.
2019-02-11 16:58:43 +00:00
SquidDev
e5f988e3fe Fix missing advanced turtle model when rendering
I'm not even sure how I missed this when testing.
2019-02-11 16:38:33 +00:00
SquidDev
12e82afad2 Bump Cobalt version to enable single-threading
The latest version of Cobalt has several major changes, which I'm
looking forward to taking advantage of in the coming months:

 - The Lua interpreter has been split up from the actual LuaClosure
   instance. It now runs multiple functions within one loop, handling
   pushing/popping and resuming method calls correctly.

   This means we have a theoretically infinite call depth, as we're no
   longer bounded by Java's stack size. In reality, this is limited to
   32767 (Short.MAX_VALUE), as that's a mostly equivalent to the limits
   PUC Lua exposes.

 - The stack is no longer unwound in the event of errors. This both
   simplifies error handling (not that CC:T needs to care about that)
   but also means one can call debug.traceback on a now-dead coroutine
   (which is more useful for debugging than using xpcall).

 - Most significantly, coroutines are no longer each run on a dedicated
   thread. Instead, yielding or resuming throws an exception to unwind
   the Java stack and switches to a different coroutine.

   In order to preserve compatability with CC's assumption about LuaJ's
   threading model (namely that yielding blocks the thread), we also
   provide a yieldBlock method (which CC:T consumes). This suspends the
   current thread and switches execution to a new thread (see
   SquidDev/Cobalt@b5ddf164f1 for more
   details). While this does mean we need to use more than 1 thread,
   it's still /substantially/ less than would otherwise be needed.

We've been running these changes on SwitchCraft for a few days now and
haven't seen any issues. One nice thing to observe is that the number of
CC thread has gone down from ~1.9k to ~100 (of those, ~70 are dedicated
to running coroutines). Similarly, the server has gone from generating
~15k threads over its lifetime, to ~3k. While this is still a lot, it's
a substantial improvement.
2019-02-10 22:02:30 +00:00
SquidDev
6c2db93cbd Register item colour handlers on the event instead
Another step on my misguided quest to get rid of proxies
2019-02-10 09:55:06 +00:00
SquidDev
d5edbe700b Load turtle item models using a model loader
This is far more elegant than our weird method of baking things and
manually inserting them into the model map. Also means we no longer need
the whole turtle_dynamic thing.
2019-02-10 09:45:15 +00:00
SquidDev
86ad43c3ab Fix peripheral direction not being set
We moved the direction call within the if block, but never actally
updated the condition! I'm on a roll of stupid bug fixes today, which
really isn't a good sign.
2019-02-07 23:07:49 +00:00
SquidDev
f450c0156b Recomment out a global
It's actually rather worrying this was exposed, you could cause some
serious issues with it.
2019-02-07 20:22:00 +00:00
SquidDev
8abcfcb4ac Track turtle commands as server tasks
They're basically an alternative version of issueMainThreadTask anyway.
2019-01-30 20:43:08 +00:00
SquidDev
f3cace1d03 Allow building without a git repository
Closes #102
2019-01-28 14:05:53 +00:00
SquidDev
e1e5e898ab Make monitors use a concurrent map instead of a synchronized
We didn't lock when iterating on the main-thread, so it wasn't actually
thread-safe anyway!
2019-01-25 22:59:01 +00:00
SquidDev
3aa3852ff6 Some further improvements to BlockGeneric
- Only have computers implement custom block drop logic: everything
   else only drops in creative mode.
 - Fix redstone inputs not being received correctly. Introduced in
   8b86a954ee, yes I'm a silly billy.
 - Only update the neighbour which changed.
2019-01-25 22:03:44 +00:00
SquidDev
709a6329c7 Fix all wireless modem blocks being advanced 2019-01-25 00:12:49 +00:00
SquidDev
c9f05a2939 Make require a little more consistent with Lua 5.1
- Error messages are indented correctly
 - The module's name is passed as the first argument to modules
 - Make error messages match Lua's
2019-01-23 18:50:17 +00:00
Devilholk
e41377f862 Handle connection errors on websockets 2019-01-22 11:11:25 +00:00
SquidDev
d173787a94 Another backwards compat change
Plethora only implements getPos on older versions, so we need to stub
out both.
2019-01-21 17:36:25 +00:00
SquidDev
d5aea26f3a Bump version
It's pretty soon after the previous release (10 days!) but there's a
couple of important bug fixes and some nice improvements.
2019-01-21 11:02:29 +00:00
SquidDev
2681e578c4 Merge pull request #101 from SquidDev-CC/feature/no-ticking
Make several tile entities non-ticking, hopefully reducing
server load.
2019-01-21 08:29:42 +00:00
SquidDev
1f498dcc73 Backwards compat patch for Plethora
Ughghgghghr.
2019-01-20 16:16:02 +00:00
SquidDev
83b01d35eb Make monitors non-ticking
- Convert terminals from a polling-based system to a more event-driven
   one: they now accept an onChanged callback, which marks the parent as
   dirty.
 - Schedule ticks when monitors are marked as dirty.
 - Add several missing @Overrides. This has nothing to do with the rest
   of the changes, but I'm bad at good git practice.
2019-01-20 15:39:11 +00:00
SquidDev
8a7e651c99 Several miscellaneous changes
- Merge BlockPeripheralBase and BlockPeripheral, as no other classes
   extended the former.
 - Make BlockPeripheral use ITilePeripheral instead of
   TilePeripheralBase. This allows us to use other, non-ticking tiles
   instead.
 - Convert advanced and normal modems to extend from a generic
   TileWirelessModemBase class, and thus neither now tick.
2019-01-20 14:06:41 +00:00
SquidDev
80a5759bae Make advanced modems non-ticking
- Move getPeripheralType and getLabel from IPeripheralTile to
   TilePeripheralBase. These were mostly constant on all other tiles, so
   were rather redundant.
 - Make TileAdvancedModem extend TileGeneric, and be non-ticking (using
   similar logic to all other blocks).
2019-01-20 09:34:15 +00:00
SquidDev
e8a4fbb4e3 Make TileCable non-ticking
- Move updateTick onto BlockGeneric/TileGeneric instead of the full
   wired modem, as it is used by several tiles now.
 - Make *Cable extend from *Generic, and schedule ticks instead of
   running every tick.
2019-01-19 22:25:38 +00:00
SquidDev
0ce67afcc1 Be less strict in comparing upgrade crafting items
We currently generate the crafting item once when the upgrade is first
created, and cache it for the duration of the game. As the item never
changes throughout the game, and constructing a stack is a little
expensive (we need to fire an event, etc...), the caching is worth
having.

However, some mods may register capabilities after we've constructed our
ItemStack. This means the capability will be present on other items but
not ours, meaning they are not considered equivalent, and thus the item
cannot be equipped.

In order to avoid this, we use compare items using their share-tag, like
Forge's IngredientNBT. This means the items must still be "mostly" the
same (same enchantements, etc...), but allow differing capabilities.

See NillerMedDild/Enigmatica2Expert#655 for the original bug report -
in this case, Astral Sourcery was registering the capability in init,
but we construct upgrades just before then.
2019-01-19 21:57:21 +00:00
SquidDev
a8dad23fa3 Begin investigations into reducing ticking of TEs
- Move IDirectionalTile constraint from IPeripheralTile to
   TilePeripheralBase.
 - Make *WiredModemFull no longer inherit from *PeripheralBase. While
   there is still some shared logic (namely in the syncing of "anim"),
   it's largely fine as we don't store label or direction in NBT.
 - Add a TickScheduler. This is a thread-safe version of
   World.scheduleUpdate. We simply build a set of all TEs, and schedule
   them to be updated the next tick.
 - Make ModemState receive an "onChanged" listener, which is fired
   whenever the modem changes.
 - Make WiredModemFull no longer tick, instead scheduling updates when
   it is first loaded and whenever the modem changes.
2019-01-19 10:16:41 +00:00
SquidDev
443e0f8f76 Remove FileSystemMount and rewrite JarMount
FileSystemMount was originally added to allow using ReadableByteChannels
instead of InputStreams. However, as zip files do not allow seeking,
there is no benefit of using them over the original JarMount (which we
need to preserve for backwards compatibility).

Instead of maintaining two near-identical mounts, we remove the
FileSystemMount and rewrite the JarMount implementation with several
improvements:

 - Rewrite the jar scanning algorithm to be closer to 1.13+'s data pack
   mount. This means we no longer require the jar file to have
   directories before the file (though this was not a problem in
   practice).
 - Add all JarMounts to a ReferenceQueue, closing up the ZipFile when
   they have been garbage collected (fixes #100).
 - Cache the contents of all files for 60 seconds (with some constraints
   on size). This allows us to seek on ROM files too (assuming they are
   small), by reading the whole thing into memory.
   The cache is shared across all mounts, and has a 64MiB limit, and
   thus should not have an adverse impact on memory.
2019-01-16 17:25:46 +00:00
SquidDev
a838595e1e Derive upgrade adjectives from its ID
This is done in 1.13+ for items and blocks, so we might as well do it
for upgrades now. Note we can't do it for ender pocket modems, as the
upgrade ID is spelled incorrectly there.
2019-01-14 10:42:13 +00:00
SquidDev
61daab910e Simplify placement logic of various blocks
- For those where placement is stored in the metadata (computers),
   don't also set it in onBlockPlacedBy.
 - Remove .getDefaultState(int, EnumFacing) override, as this means we
   have more control over what is passed to us (namely, placer's
   direction too).
2019-01-14 10:27:19 +00:00
SquidDev
7fd19c43e9 Try to hide CommandCopy from most completions.
"/computercraf" auto-completes to "/computercraft_copy" instead of
"/computercraft", which is rather annoying, as the former is not meant
to be used normally.
2019-01-14 10:10:52 +00:00
SquidDev
ce0685c31f Move our message model to be closer to Forge's
It's rather embarassing that it's been restructured _again_, but I think
this is a nice middle-ground. The previous implementation was written
mostly for Fabric, which doesn't always map perfectly to Forge.

 - Move the message identifier into the registration phrase. It's not
   really a property of the message itself, rather a property of the
   registry, so better suited there.

 - Move message handling into the message itself. Honestly, it was just
   ending up being rather messy mixing the logic in two places.

   This also means we can drop some proxy methods, as it's easier to
   have conditionally loaded methods.

 - Move network registry into a dedicated class, as that's what we're
   doing for everything else.
2019-01-14 10:09:22 +00:00
SquidDev
e33f852baa Store references to the registered items
This means we can avoid several rather ugly instances of getItemBlock
and a cast. We also derive the ItemBlock's registered name from the
block's name, which makes the register a little less ugly.
2019-01-12 19:01:32 +00:00
SquidDev
227d5e9e69 Fix cables not rendering the breaking steps
The fact that it's taken this long for anyone to notice this didn't work
is rather embarassing.
2019-01-12 18:35:43 +00:00
SquidDev
1c648850ab Even more proxy pruning
- Move the "world directory" getter out of the proxy - we can just use
   Forge's code here.
 - Remove the server proxies, as both were empty. We don't tend to
   register any dedicated-server specific code, so I think we can leave
   them out.
2019-01-12 18:23:22 +00:00
SquidDev
63691707fc Move registration methods into a separate class
- All "named" entries (blocks, items, recipes, TEs and pocket/turtle
   upgrades) are registeredin one place.
 - Most client side models/textures are registered in ClientRegistry -
   we can't do item colours or TEs for now, as these aren't event based.
 - A little cleanup to how we handle ItemPocketComputer models.
2019-01-12 17:51:26 +00:00
SquidDev
5d97b9c8f3 Utilise @Mod.EventBusSubscriber a little more
This offers several advantages

 - Less registration code: the subscribers are reigstered automatically,
   and we don't need to worry about sided-proxies.
 - We no longer have so many .instance() calls.
2019-01-12 16:27:40 +00:00
SquidDev
77666d7399 Some more minor cleanups
- Move SpeakerPeripheral's TileSpeaker functionality to a sub-class.
 - Use Vec3d instead of BlockPos for speaker's positions.
 - Use WorldUtil.dropItemStack to spawn in items.
 - Remove redundant lock on ModemPeripheral.
2019-01-12 15:43:18 +00:00
750 changed files with 25083 additions and 14589 deletions

View File

@@ -11,5 +11,8 @@ insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[*.sexp]
indent_size = 2
[*.properties]
insert_final_newline = false

View File

@@ -1,16 +1,15 @@
---
name: Bug report
about: Report some misbehaviour in the mod
labels: bug
---
<!--
## Before reporting
- Search for the bug both here and [on the ComputerCraft issues page](https://github.com/dan200/ComputerCraft/issues?utf8=%E2%9C%93&q=is%3Aissue+)
- If possible, try to reproduce on vanilla ComputerCraft. If it still occurs, [report on the ComputerCraft repo](https://github.com/dan200/ComputerCraft/issues/new) instead.
- Search for the bug on the issue tracker. Make sure to look at closed issues too!
-->
## Useful information to include:
- Minecraft version
- CC: Tweaked version
- Detailed reproduction steps!** Sometimes I can spot a bug pretty easily, but often it's much more obscure. Anything you can give which will help reproduce it means it'll get fixed quicker.
- Detailed reproduction steps: sometimes I can spot a bug pretty easily, but often it's much more obscure. The more information I have to help reproduce it, the quicker it'll get fixed.

View File

@@ -1,15 +1,14 @@
---
name: Feature request
about: Suggest an idea or improvement
labels: enhancement
---
<!--
## Before reporting
- Search for the suggestion both here and [on the ComputerCraft issues page](https://github.com/dan200/ComputerCraft/issues?utf8=%E2%9C%93&q=is%3Aissue+). It's possible someone's suggested it before!
- Unless something is specific to CC:Tweaked, try to [suggest them on the ComputerCraft repo](https://github.com/dan200/ComputerCraft/issues/new). There's a lot more people watching it, so it allows the wider community to contribute.
- Search for the suggestion here. It's possible someone's suggested it before!
-->
## Useful information to include:
- Explanation of how the feature/change chould work.
- Some rationale/use case for a feature. I'd like to keep CC:T as minimal
- Explanation of how the feature/change should work.
- Some rationale/use case for a feature. My general approach to designing new features is to ask yourself "what issue are we trying to solve" and _then_ "is this the best way to solve this issue?".

View File

@@ -1,9 +1,3 @@
<!--
Unless this feature is specific to CC:Tweaked, try to [target the original ComputerCraft repo](https://github.com/dan200/ComputerCraft/) instead. There's a lot more people watching it, so it allows the wider community to contribute.
-->
## Useful information to include:
- Brief explanation of the changes you've made.
- Rationale of why this change has been made/reasoning behind it.
The more information you can provide, the easier it is to review something now _and_ to see why a change was made, when the code needs updating in the future.
## A quick checklist
- If there's a existing issue, please link to it. If not, provide fill out the same information you would in a normal issue - reproduction steps for bugs, rationale for use-case.
- If you're working on CraftOS, try to write a few test cases so we can ensure everything continues to work in the future. Tests live in `src/test/resources/test-rom/spec` and can be run with `./gradlew check`.

39
.github/workflows/main-ci.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Build
on: [push, pull_request]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Gradle
run: ./gradlew build --no-daemon
- name: Upload Jar
uses: actions/upload-artifact@v1
with:
name: CC-Tweaked
path: build/libs
lint-lua:
name: Lint Lua
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Lint Lua code
run: |
test -d bin || mkdir bin
test -f bin/illuaminate || wget -q -Obin/illuaminate https://squiddev.cc/illuaminate/bin/illuaminate
chmod +x bin/illuaminate
bin/illuaminate lint

6
.gitignore vendored
View File

@@ -15,3 +15,9 @@
.idea
.gradle
*.DS_Store
.classpath
.project
.settings/
bin/
*.launch

View File

@@ -1,34 +0,0 @@
std = "max"
ignore = {
-- Allow access to undefined globals or their fields. In the future we'll
-- define all of CC's globals within this file
'113', '143',
-- FIXME: Ignore unused arguments and loop variables
'212', '213',
-- Disable line is too long for now. It would be possible to clean
-- this up in the future.
'631',
}
-- Only run the linter on ROM and bios for now, as the treasure disks
-- are largely unsupported.
include_files = {
'src/main/resources/assets/computercraft/lua/rom',
'src/main/resources/assets/computercraft/lua/bios.lua'
}
files['src/main/resources/assets/computercraft/lua/bios.lua'] = {
-- Allow declaring and mutating globals
allow_defined_top = true,
ignore = { '112', '121', '122', '131', '142' },
}
files['src/main/resources/assets/computercraft/lua/rom/apis'] = {
-- APIs may define globals on the top level. We'll ignore unused globals,
-- as obviously they may be used outside that API.
allow_defined_top = true,
ignore = { '131' },
}

View File

@@ -1,14 +0,0 @@
language: java
script: ./gradlew build --no-daemon
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/s
jdk:
- oraclejdk8

View File

@@ -1,19 +0,0 @@
Copyright (c) 2007 LuaJ. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,35 +1,35 @@
# ![CC: Tweaked](logo.png)
[![Build Status](https://travis-ci.org/SquidDev-CC/CC-Tweaked.svg?branch=master)](https://travis-ci.org/SquidDev-CC/CC-Tweaked)
[![Current build status](https://github.com/SquidDev-CC/CC-Tweaked/workflows/Build/badge.svg)](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [![Download CC: Tweaked on CurseForge](http://cf.way2muchnoise.eu/title/cc-tweaked.svg)](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
CC: Tweaked is a fork of ComputerCraft which aims to provide earlier access to the more experimental and in-development
features of the mod. For a more stable experience, I recommend checking out the
[original mod](https://github.com/dan200/ComputerCraft).
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
turtles and more to Minecraft.
## What?
CC: Tweaked (or CC:T for short) does not aim to create a competing fork of ComputerCraft, nor am I planning to take it
in in a vastly different direction to the original mod. In fact, CC:T aims to be a nurturing ground for various
features, with a pull request against the original mod being the end goal.
ComputerCraft has always held a fond place in my heart: it's the mod which really got me into Minecraft, and it's the
mod which has kept me playing it for many years. However, development of the original mod has slowed, as the original
developers have had less time to work on the mod, and moved onto other projects and commitments.
CC:T also includes many pull requests from the community which have not yet been merged, offering a large number
of additional bug fixes and features over the original mod.
CC: Tweaked (or CC:T for short) is an attempt to continue ComputerCraft's legacy. It's not intended to be a competitor
to CC, nor do I want to take it in a vastly different direction to the original mod. Instead, CC:T focuses on making the
ComputerCraft experience as _solid_ as possible, ironing out any wrinkles that may have developed over time.
## Features
CC: Tweaked contains all the features of the latest alpha, as well as numerous fixes, performance improvements and
several additional features. I'd recommend checking out [the releases page](https://github.com/SquidDev-CC/CC-Tweaked/releases)
to see the full changes, but here's a couple of the more interesting changes:
CC: Tweaked contains all the features of the latest version of ComputerCraft, as well as numerous fixes, performance
improvements and several nifty additions. I'd recommend checking out [the releases page](https://github.com/SquidDev-CC/CC-Tweaked/releases)
to see the full set of changes, but here's a couple of the more interesting additions:
- Replace LuaJ with Cobalt.
- Allow running multiple computers at the same time.
- Websocket support in the HTTP library.
- Wired modems and cables act more like multiparts.
- Add map-like rendering for pocket computers and printed pages/books.
- Adds the `/computercraft` command, offering various diagnostic tools for server owners. This allows operators to
track which computers are hogging resources, turn on and shutdown multiple computers at once and interact with
computers remotely.
- Add full-block wired modems, allowing one to wrap non-solid peripherals (such as turtles, or chests if Plethora is
- Improvements to the `http` library, including websockets, support for other HTTP methods (`PUT`, `DELETE`, etc...)
and configurable limits on HTTP usage.
- Full-block wired modems, allowing one to wrap non-solid peripherals (such as turtles, or chests if Plethora is
installed).
- Extended binary file handles. They support file seeking, and reading new lines, allowing full (and accurate)
emulation of the standard Lua `io` library.
- Pocket computers can be held like maps, allowing you to view the screen without entering a GUI.
- Printed pages and books can be placed in item frames and held like maps.
- Several profiling and administration tools for server owners, via the `/computercraft` command. This allows operators
to track which computers are hogging resources, turn on and shutdown multiple computers at once and interact with
computers remotely.
- Closer emulation of standard Lua, adding the `debug` and `io` libraries. This also enables seeking within binary
files, meaning you don't need to read large files into memory.
- Allow running multiple computers on multiple threads, reducing latency on worlds with many computers.
## Relation to CCTweaks?
This mod has nothing to do with CCTweaks, though there is no denying the name is a throwback to it. That being said,
@@ -37,13 +37,39 @@ several features have been included, such as full block modems, the Cobalt runti
computers.
## Contributing
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. If you do wish to contribute
code, do consider submitting it to the ComputerCraft repository first.
That being said, in order to start helping develop CC:T, you'll need to follow these steps:
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. In order to start helping
develop CC:T, you'll need to follow these steps:
- **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
- **Setup Forge:** `./gradlew setupDecompWorkspace`
- **Test your changes:** `./gradlew runClient` (or run the `GradleStart` class from your IDE).
If you want to run CC:T in a normal Minecraft instance, run `./gradlew build` and copy the `.jar` from `build/libs`.
## Community
If you need help getting started with CC: Tweaked, want to show off your latest project, or just want to chat about
ComputerCraft we have a [forum](https://forums.computercraft.cc/) and [Discord guild](https://discord.gg/H2UyJXe)!
There's also a fairly populated, albeit quiet [IRC channel](http://webchat.esper.net/?channels=#computercraft), if
that's more your cup of tea.
I'd generally recommend you don't contact me directly (email, DM, etc...) unless absolutely necessary (i.e. in order to
report exploits). You'll get a far quicker response if you ask the whole community!
## Using
If you want to depend on CC: Tweaked, we have a maven repo. However, you should be wary that some functionality is only
exposed by CC:T's API and not vanilla ComputerCraft. If you wish to support all variations of ComputerCraft, I recommend
using [cc.crzd.me's maven](https://cc.crzd.me/maven/) instead.
```groovy
dependencies {
maven { url 'https://squiddev.cc/maven/' }
}
dependencies {
implementation "org.squiddev:cc-tweaked-${mc_version}:${cct_version}"
}
```
You should also be careful to only use classes within the `dan200.computercraft.api` package. Non-API classes are
subject to change at any point. If you depend on functionality outside the API, file an issue, and we can look into
exposing more features.

View File

@@ -5,17 +5,22 @@ buildscript {
jcenter()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
url = "https://files.minecraftforge.net/maven"
}
}
dependencies {
classpath 'com.google.code.gson:gson:2.8.1'
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'org.ajoberstar:gradle-git:1.6.0'
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta1'
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
}
}
plugins {
id 'com.matthewprenger.cursegradle' version '1.0.10'
id "checkstyle"
id "com.github.hierynomus.license" version "0.15.0"
id "com.matthewprenger.cursegradle" version "1.3.0"
id "com.github.breadmoirai.github-release" version "2.2.4"
}
apply plugin: 'net.minecraftforge.gradle.forge'
@@ -23,35 +28,41 @@ apply plugin: 'org.ajoberstar.grgit'
apply plugin: 'maven-publish'
apply plugin: 'maven'
version = "1.80pr1.13"
version = mod_version
group = "org.squiddev"
archivesBaseName = "cc-tweaked"
archivesBaseName = "cc-tweaked-${mc_version}"
minecraft {
version = "1.12.2-14.23.4.2749"
version = "${mc_version}-${forge_version}"
runDir = "run"
replace '${version}', project.version
replace '${version}', mod_version
// the mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD snapshot are built nightly.
// stable_# stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not allways work.
// simply re-run your setup task after changing the mappings to update your workspace.
mappings = "snapshot_20180724"
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
mappings = mappings_version
makeObfSourceJar = false
}
repositories {
maven {
name = "JEI"
url = "http://dvs1.progwml6.com/files/maven"
name "JEI"
url "https://dvs1.progwml6.com/files/maven"
}
maven {
name = "squiddev"
url = "https://dl.bintray.com/squiddev/maven"
name "SquidDev"
url "https://squiddev.cc/maven"
}
ivy {
name "Charset"
artifactPattern "https://asie.pl/files/mods/Charset/LibOnly/[module]-[revision](-[classifier]).[ext]"
}
maven {
name "Amadornes"
url "https://maven.amadornes.com/"
}
maven {
name "CraftTweaker"
url "https://maven.blamejared.com/"
}
ivy { artifactPattern "https://asie.pl/files/mods/Charset/LibOnly/[module]-[revision](-[classifier]).[ext]" }
}
configurations {
@@ -61,18 +72,25 @@ configurations {
}
dependencies {
deobfProvided "mezz.jei:jei_1.12.2:4.8.5.159:api"
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
deobfProvided "CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.554"
deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
deobfProvided "mezz.jei:jei_1.12.2:4.15.0.269:api"
deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
runtime "mezz.jei:jei_1.12.2:4.8.5.159"
runtime "mezz.jei:jei_1.12.2:4.15.0.269"
shade 'org.squiddev:Cobalt:0.4.0'
shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT'
testCompile 'junit:junit:4.11'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2'
deployerJars "org.apache.maven.wagon:wagon-ssh:3.0.0"
}
// Compile tasks
javadoc {
include "dan200/computercraft/api/**/*.java"
}
@@ -84,39 +102,99 @@ jar {
attributes('FMLAT': 'computercraft_at.cfg')
}
into("docs", { from (javadoc.destinationDir) })
into("api", { from (sourceSets.main.allSource) {
from (sourceSets.main.allSource) {
include "dan200/computercraft/api/**/*.java"
}})
}
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
}
[compileJava, compileTestJava].forEach {
it.configure {
options.compilerArgs << "-Xlint" << "-Xlint:-processing" << "-Werror"
}
}
import java.nio.charset.StandardCharsets
import java.nio.file.*
import java.util.zip.*
import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import com.hierynomus.gradle.license.tasks.LicenseCheck
import com.hierynomus.gradle.license.tasks.LicenseFormat
import org.ajoberstar.grgit.Grgit
import proguard.gradle.ProGuardTask
task proguard(type: ProGuardTask, dependsOn: jar) {
description "Removes unused shadowed classes from the jar"
group "compact"
injars jar.archivePath
outjars "${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar"
// Add the main runtime jar and all non-shadowed dependencies
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
libraryjars "${System.getProperty('java.home')}/lib/jce.jar"
doFirst {
sourceSets.main.compileClasspath
.filter { !it.name.contains("Cobalt") }
.each { libraryjars it }
}
// We want to avoid as much obfuscation as possible. We're only doing this to shrink code size.
dontobfuscate; dontoptimize; keepattributes; keepparameternames
// Proguard will remove directories by default, but that breaks JarMount.
keepdirectories 'assets/computercraft/lua**'
// Preserve ComputerCraft classes - we only want to strip shadowed files.
keep 'class dan200.computercraft.** { *; }'
}
task proguardMove(dependsOn: proguard) {
description "Replace the original jar with the minified version"
group "compact"
doLast {
Files.move(
file("${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar").toPath(),
file(jar.archivePath).toPath(),
StandardCopyOption.REPLACE_EXISTING
)
}
}
reobfJar.dependsOn proguardMove
processResources {
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
inputs.property "version", mod_version
inputs.property "mcversion", mc_version
def grgit = Grgit.open(dir: '.')
inputs.property "commithash", grgit.head().id
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
def hash = 'none'
Set<String> contributors = []
try {
def grgit = Grgit.open(dir: '.')
hash = grgit.head().id
grgit.log().each {
if (!blacklist.contains(it.author.name)) contributors.add(it.author.name)
if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
}
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
grgit.log().each {
if (!blacklist.contains(it.author.name)) contributors.add(it.author.name)
if (!blacklist.contains(it.committer.name)) contributors.add(it.committer.name)
}
} catch(Exception ignored) { }
inputs.property "commithash", hash
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
include 'assets/computercraft/lua/rom/help/credits.txt'
expand 'version':project.version,
'mcversion':project.minecraft.version,
'gitcontributors':contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
expand 'version': mod_version,
'mcversion': mc_version,
'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
}
from(sourceSets.main.resources.srcDirs) {
@@ -125,13 +203,149 @@ processResources {
}
}
task compressJson(dependsOn: extractAnnotationsJar) {
group "compact"
description "Minifies all JSON files, stripping whitespace"
def jarPath = file(jar.archivePath)
def tempPath = File.createTempFile("input", ".jar", temporaryDir)
tempPath.deleteOnExit()
def gson = new GsonBuilder().create()
doLast {
// Copy over all files in the current jar to the new one, running json files from GSON. As pretty printing
// is turned off, they should be minified.
new ZipFile(jarPath).withCloseable { inJar ->
tempPath.getParentFile().mkdirs()
new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tempPath))).withCloseable { outJar ->
inJar.entries().each { entry ->
if(entry.directory) {
outJar.putNextEntry(entry)
} else if(!entry.name.endsWith(".json")) {
outJar.putNextEntry(entry)
inJar.getInputStream(entry).withCloseable { outJar << it }
} else {
ZipEntry newEntry = new ZipEntry(entry.name)
newEntry.setTime(entry.time)
outJar.putNextEntry(newEntry)
def element = inJar.getInputStream(entry).withCloseable { gson.fromJson(it.newReader("UTF8"), JsonElement.class) }
outJar.write(gson.toJson(element).getBytes(StandardCharsets.UTF_8))
}
}
}
}
// And replace the original jar again
Files.move(tempPath.toPath(), jarPath.toPath(), StandardCopyOption.REPLACE_EXISTING)
}
}
assemble.dependsOn compressJson
// Check tasks
test {
useJUnitPlatform()
testLogging {
events "skipped", "failed"
}
}
license {
mapping("java", "SLASHSTAR_STYLE")
strictCheck true
ext.year = Calendar.getInstance().get(Calendar.YEAR)
}
[licenseMain, licenseFormatMain].forEach {
it.configure {
include("**/*.java")
exclude("dan200/computercraft/api/**")
header rootProject.file('config/license/main.txt')
}
}
[licenseTest, licenseFormatTest].forEach {
it.configure {
include("**/*.java")
header rootProject.file('config/license/main.txt')
}
}
gradle.projectsEvaluated {
tasks.withType(LicenseFormat) {
outputs.upToDateWhen { false }
}
}
task licenseAPI(type: LicenseCheck);
task licenseFormatAPI(type: LicenseFormat);
[licenseAPI, licenseFormatAPI].forEach {
it.configure {
source = sourceSets.main.java
include("dan200/computercraft/api/**")
header rootProject.file('config/license/api.txt')
}
}
// Upload tasks
task checkRelease {
group "upload"
description "Verifies that everything is ready for a release"
inputs.property "version", mod_version
inputs.file("src/main/resources/assets/computercraft/lua/rom/help/changelog.txt")
inputs.file("src/main/resources/assets/computercraft/lua/rom/help/whatsnew.txt")
doLast {
def ok = true
// Check we're targetting the current version
def whatsnew = new File("src/main/resources/assets/computercraft/lua/rom/help/whatsnew.txt").readLines()
if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
ok = false
project.logger.error("Expected `whatsnew.txt' to target $mod_version.")
}
// Check "read more" exists and trim it
def idx = whatsnew.findIndexOf { it == 'Type "help changelog" to see the full version history.' }
if (idx == -1) {
ok = false
project.logger.error("Must mention the changelog in whatsnew.txt")
} else {
whatsnew = whatsnew.getAt(0 ..< idx)
}
// Check whatsnew and changelog match.
def versionChangelog = "# " + whatsnew.join("\n")
def changelog = new File("src/main/resources/assets/computercraft/lua/rom/help/changelog.txt").getText()
if (!changelog.startsWith(versionChangelog)) {
ok = false
project.logger.error("whatsnew and changelog are not in sync")
}
if (!ok) throw new IllegalStateException("Could not check release")
}
}
check.dependsOn checkRelease
curseforge {
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
project {
id = '282001'
releaseType = 'beta'
changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${project.version})."
releaseType = 'release'
changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
relations {
incompatible "computercraft"
}
}
}
@@ -159,22 +373,22 @@ uploadArchives {
pom.project {
name 'CC: Tweaked'
packaging 'jar'
description 'A fork of ComputerCraft which aims to provide earlier access to the more experimental and in-development features of the mod.'
description 'CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft.'
url 'https://github.com/SquidDev-CC/CC-Tweaked'
scm {
url 'https://github.com/dan200/ComputerCraft.git'
url 'https://github.com/SquidDev-CC/CC-Tweaked.git'
}
issueManagement {
system 'github'
url 'https://github.com/dan200/ComputerCraft/issues'
url 'https://github.com/SquidDev-CC/CC-Tweaked/issues'
}
licenses {
license {
name 'ComputerCraft Public License, Version 1.0'
url 'https://github.com/dan200/ComputerCraft/blob/master/LICENSE'
url 'https://github.com/SquidDev-CC/CC-Tweaked/blob/master/LICENSE'
distribution 'repo'
}
}
@@ -188,10 +402,31 @@ uploadArchives {
}
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint"
githubRelease {
token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
owner 'SquidDev-CC'
repo 'CC-Tweaked'
try {
targetCommitish = Grgit.open(dir: '.').branch.current().name
} catch(Exception ignored) { }
tagName "v${mc_version}-${mod_version}"
releaseName "[${mc_version}] ${mod_version}"
body {
"## " + new File("src/main/resources/assets/computercraft/lua/rom/help/whatsnew.txt")
.readLines()
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
.join("\n").trim()
}
prerelease false
}
def uploadTasks = ["uploadArchives", "curseforge", "githubRelease"]
uploadTasks.forEach { tasks.getByName(it).dependsOn checkRelease }
task uploadAll(dependsOn: uploadTasks) {
group "upload"
description "Uploads to all repositories (Maven, Curse, GitHub release)"
}
runClient.outputs.upToDateWhen { false }

View File

@@ -0,0 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<property name="tabWidth" value="4"/>
<property name="charset" value="UTF-8" />
<module name="SuppressionFilter">
<property name="file" value="config/checkstyle/suppressions.xml" />
</module>
<module name="TreeWalker">
<!-- Annotations -->
<module name="AnnotationLocation" />
<module name="AnnotationUseStyle" />
<module name="MissingDeprecated" />
<module name="MissingOverride" />
<!-- Blocks -->
<module name="EmptyBlock" />
<module name="EmptyCatchBlock">
<property name="exceptionVariableName" value="ignored" />
</module>
<module name="LeftCurly">
<property name="option" value="nl" />
<!-- The defaults, minus lambdas. -->
<property name="tokens" value="ANNOTATION_DEF,CLASS_DEF,CTOR_DEF,ENUM_CONSTANT_DEF,ENUM_DEF,INTERFACE_DEF,LITERAL_CASE,LITERAL_CATCH,LITERAL_DEFAULT,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,METHOD_DEF,OBJBLOCK,STATIC_INIT" />
</module>
<module name="NeedBraces">
<property name="allowSingleLineStatement" value="true"/>
</module>
<module name="RightCurly">
<property name="option" value="alone" />
</module>
<!-- Class design. As if we've ever followed good practice here. -->
<module name="FinalClass" />
<module name="InterfaceIsType" />
<module name="MutableException" />
<module name="OneTopLevelClass" />
<!-- Coding -->
<module name="ArrayTrailingComma" />
<module name="EqualsHashCode" />
<!-- FallThrough does not handle unreachable code well -->
<module name="IllegalInstantiation" />
<module name="IllegalThrows" />
<module name="ModifiedControlVariable" />
<module name="NoClone" />
<module name="NoFinalizer" />
<module name="OneStatementPerLine" />
<module name="PackageDeclaration" />
<module name="SimplifyBooleanExpression" />
<module name="SimplifyBooleanReturn" />
<module name="StringLiteralEquality" />
<module name="UnnecessaryParentheses" />
<module name="UnnecessarySemicolonAfterTypeMemberDeclaration" />
<module name="UnnecessarySemicolonInTryWithResources" />
<module name="UnnecessarySemicolonInEnumeration" />
<!-- Imports -->
<module name="CustomImportOrder" />
<module name="IllegalImport" />
<module name="RedundantImport" />
<module name="UnusedImports" />
<!-- Javadoc -->
<!-- TODO: Missing* checks for the dan200.computercraft.api package? -->
<module name="AtclauseOrder" />
<module name="InvalidJavadocPosition" />
<module name="JavadocBlockTagLocation" />
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocStyle" />
<module name="NonEmptyAtclauseDescription" />
<module name="SingleLineJavadoc" />
<module name="SummaryJavadocCheck"/>
<!-- Misc -->
<module name="ArrayTypeStyle" />
<module name="CommentsIndentation" />
<module name="Indentation" />
<module name="OuterTypeFilename" />
<!-- Modifiers -->
<module name="ModifierOrder" />
<module name="RedundantModifier" />
<!-- Naming -->
<module name="ClassTypeParameterName" />
<module name="InterfaceTypeParameterName" />
<module name="LambdaParameterName" />
<module name="LocalFinalVariableName" />
<module name="LocalVariableName" />
<!-- Allow an optional m_ on private members -->
<module name="MemberName">
<property name="applyToPrivate" value="false" />
<property name="applyToPackage" value="false" />
</module>
<module name="MemberName">
<property name="format" value="^(m_)?[a-z][a-zA-Z0-9]*$" />
<property name="applyToPrivate" value="true" />
<property name="applyToPackage" value="true" />
</module>
<module name="MethodName" />
<module name="MethodTypeParameterName" />
<module name="PackageName">
<property name="format" value="^dan200\.computercraf(\.[a-z][a-z0-9]*)*" />
</module>
<module name="ParameterName" />
<module name="StaticVariableName">
<property name="format" value="^[a-z][a-zA-Z0-9]*|CAPABILITY(_[A-Z]+)?$" />
<property name="applyToPrivate" value="false" />
</module>
<module name="StaticVariableName">
<property name="format" value="^(s_)?[a-z][a-zA-Z0-9]*|CAPABILITY(_[A-Z]+)?$" />
<property name="applyToPrivate" value="true" />
</module>
<module name="TypeName" />
<!-- Whitespace -->
<module name="EmptyForInitializerPad"/>
<module name="EmptyForIteratorPad">
<property name="option" value="space"/>
</module>
<module name="GenericWhitespace" />
<module name="MethodParamPad" />
<module name="NoLineWrap" />
<module name="NoWhitespaceAfter">
<property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP" />
</module>
<module name="NoWhitespaceBefore" />
<!-- TODO: Decide on an OperatorWrap style. -->
<module name="ParenPad">
<property name="option" value="space" />
<property name="tokens" value="ANNOTATION,ANNOTATION_FIELD_DEF,CTOR_CALL,CTOR_DEF,ENUM_CONSTANT_DEF,LITERAL_CATCH,LITERAL_DO,LITERAL_FOR,LITERAL_IF,LITERAL_NEW,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_WHILE,METHOD_CALL,METHOD_DEF,RESOURCE_SPECIFICATION,SUPER_CTOR_CALL,LAMBDA" />
</module>
<module name="ParenPad">
<property name="option" value="nospace" />
<property name="tokens" value="DOT,EXPR,QUESTION" />
</module>
<module name="SeparatorWrap">
<property name="option" value="eol" />
<property name="tokens" value="COMMA,SEMI,ELLIPSIS,ARRAY_DECLARATOR,RBRACK,METHOD_REF" />
</module>
<module name="SeparatorWrap">
<property name="option" value="nl" />
<property name="tokens" value="DOT,AT" />
</module>
<module name="SingleSpaceSeparator" />
<module name="TypecastParenPad" />
<module name="WhitespaceAfter">
<property name="tokens" value="COMMA" />
</module>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true" />
<property name="ignoreEnhancedForColon" value="false" />
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,DO_WHILE,EQUAL,GE,GT,LAMBDA,LAND,LCURLY,LE,LITERAL_RETURN,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND" />
</module>
</module>
<module name="FileTabCharacter" />
<module name="NewlineAtEndOfFile" />
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="message" value="Trailing whitespace"/>
</module>
</module>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suppressions PUBLIC
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
<!-- All the config options and method fields. -->
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraft.java" />
<suppress checks="StaticVariableName" files=".*[\\/]ComputerCraftAPI.java" />
<!-- Do not check for missing package Javadoc. -->
<suppress checks="JavadocStyle" files=".*[\\/]package-info.java" />
</suppressions>

File diff suppressed because it is too large Load Diff

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

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

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

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

7
gradle.properties Normal file
View File

@@ -0,0 +1,7 @@
# Mod properties
mod_version=1.86.2
# Minecraft properties
mc_version=1.12.2
forge_version=14.23.4.2749
mappings_version=snapshot_20180724

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip

28
illuaminate.sexp Normal file
View File

@@ -0,0 +1,28 @@
; -*- mode: Lisp;-*-
(sources
/src/main/resources/assets/computercraft/lua/bios.lua
/src/main/resources/assets/computercraft/lua/rom/
/src/test/resources/test-rom)
(at /
(linters
;; It'd be nice to avoid this, but right now there's a lot of instances of
;; it.
-var:set-loop
;; It's useful to name arguments for documentation, so we allow this. It'd
;; be good to find a compromise in the future, but this works for now.
-var:unused-arg))
;; We disable the unused global linter in bios.lua and the APIs. In the future
;; hopefully we'll get illuaminate to handle this.
(at
(/src/main/resources/assets/computercraft/lua/bios.lua
/src/main/resources/assets/computercraft/lua/rom/apis/)
(linters -var:unused-global)
(lint
(allow-toplevel-global true)))
;; These warnings are broken right now
(at (bios.lua worm.lua) (linters -control:unreachable))

View File

@@ -1 +1 @@
rootProject.name = 'cc-tweaked'
rootProject.name = "cc-tweaked-${mc_version}"

View File

@@ -0,0 +1,29 @@
/*
* 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;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.network.NetworkCheckHandler;
import net.minecraftforge.fml.relauncher.Side;
import java.util.Map;
/**
* A stub mod for CC: Tweaked. This doesn't have any functionality (everything of note is done in
* {@link ComputerCraft}), but people may depend on this if they require CC: Tweaked functionality.
*/
@Mod(
modid = "cctweaked", name = ComputerCraft.NAME, version = ComputerCraft.VERSION,
acceptableRemoteVersions = "*"
)
public class CCTweaked
{
@NetworkCheckHandler
public boolean onNetworkConnect( Map<String, String> mods, Side side )
{
return true;
}
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft;
import dan200.computercraft.api.filesystem.IMount;
@@ -24,37 +23,38 @@ import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.AddressPredicate;
import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.apis.http.websocket.Websocket;
import dan200.computercraft.core.computer.MainThread;
import dan200.computercraft.core.filesystem.ComboMount;
import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.core.filesystem.FileSystemMount;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.filesystem.JarMount;
import dan200.computercraft.core.tracking.Tracking;
import dan200.computercraft.shared.*;
import dan200.computercraft.shared.computer.blocks.BlockCommandComputer;
import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.blocks.TileComputer;
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
import dan200.computercraft.shared.computer.items.ItemCommandComputer;
import dan200.computercraft.shared.computer.items.ItemComputer;
import dan200.computercraft.shared.media.items.ItemDiskExpanded;
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
import dan200.computercraft.shared.media.items.ItemPrintout;
import dan200.computercraft.shared.media.items.ItemTreasureDisk;
import dan200.computercraft.shared.peripheral.common.BlockPeripheral;
import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive;
import dan200.computercraft.shared.peripheral.common.ItemPeripheral;
import dan200.computercraft.shared.peripheral.modem.wired.BlockCable;
import dan200.computercraft.shared.peripheral.modem.wired.BlockWiredModemFull;
import dan200.computercraft.shared.peripheral.modem.wired.ItemCable;
import dan200.computercraft.shared.peripheral.modem.wireless.BlockAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.ItemAdvancedModem;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.peripheral.printer.TilePrinter;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.pocket.peripherals.PocketModem;
import dan200.computercraft.shared.pocket.peripherals.PocketSpeaker;
import dan200.computercraft.shared.proxy.ICCTurtleProxy;
import dan200.computercraft.shared.proxy.IComputerCraftProxy;
import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon;
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.items.ItemTurtleAdvanced;
import dan200.computercraft.shared.turtle.items.ItemTurtleLegacy;
import dan200.computercraft.shared.turtle.items.ItemTurtleNormal;
import dan200.computercraft.shared.turtle.upgrades.*;
import dan200.computercraft.shared.util.CreativeTabMain;
import dan200.computercraft.shared.util.IDAssigner;
@@ -62,22 +62,17 @@ import dan200.computercraft.shared.util.IoUtil;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import dan200.computercraft.shared.wired.WiredNode;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.common.*;
import net.minecraftforge.fml.common.event.*;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;
import org.apache.logging.log4j.Logger;
@@ -85,34 +80,21 @@ import java.io.*;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.ServiceConfigurationError;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@Mod(
modid = ComputerCraft.MOD_ID, name = "CC: Tweaked", version = "${version}",
modid = ComputerCraft.MOD_ID, name = ComputerCraft.NAME, version = ComputerCraft.VERSION,
guiFactory = "dan200.computercraft.client.gui.GuiConfigCC$Factory",
dependencies = "required:forge@[14.23.4.2746,)"
)
public class ComputerCraft
{
public static final String MOD_ID = "computercraft";
// GUI IDs
public static final int diskDriveGUIID = 100;
public static final int computerGUIID = 101;
public static final int printerGUIID = 102;
public static final int turtleGUIID = 103;
// ComputerCraftEdu uses ID 104
public static final int printoutGUIID = 105;
public static final int pocketComputerGUIID = 106;
public static final int viewComputerGUIID = 110;
static final String VERSION = "${version}";
static final String NAME = "CC: Tweaked";
// Configuration options
public static final String[] DEFAULT_HTTP_WHITELIST = new String[] { "*" };
@@ -130,9 +112,12 @@ public class ComputerCraft
public static boolean disable_lua51_features = false;
public static String default_computer_settings = "";
public static boolean debug_enable = true;
public static int computer_threads = 1;
public static boolean logPeripheralErrors = false;
public static int computer_threads = 1;
public static long maxMainGlobalTime = TimeUnit.MILLISECONDS.toNanos( 10 );
public static long maxMainComputerTime = TimeUnit.MILLISECONDS.toNanos( 5 );
public static boolean http_enable = true;
public static boolean http_websocket_enable = true;
public static AddressPredicate http_whitelist = new AddressPredicate( DEFAULT_HTTP_WHITELIST );
@@ -169,54 +154,77 @@ public class ComputerCraft
public static final int terminalHeight_pocketComputer = 20;
// Blocks and Items
public static class Blocks
public static final class Blocks
{
public static BlockComputer computer;
public static BlockPeripheral peripheral;
public static BlockCable cable;
public static BlockCommandComputer commandComputer;
public static BlockTurtle turtle;
public static BlockTurtle turtleExpanded;
public static BlockTurtle turtleAdvanced;
public static BlockCommandComputer commandComputer;
public static BlockPeripheral peripheral;
public static BlockCable cable;
public static BlockAdvancedModem advancedModem;
public static BlockWiredModemFull wiredModemFull;
}
public static class Items
public static final class Items
{
public static ItemComputer computer;
public static ItemCommandComputer commandComputer;
public static ItemTurtleLegacy turtle;
public static ItemTurtleNormal turtleExpanded;
public static ItemTurtleAdvanced turtleAdvanced;
public static ItemPocketComputer pocketComputer;
public static ItemDiskLegacy disk;
public static ItemDiskExpanded diskExpanded;
public static ItemPrintout printout;
public static ItemTreasureDisk treasureDisk;
public static ItemPocketComputer pocketComputer;
public static ItemPrintout printout;
public static ItemPeripheral peripheral;
public static ItemAdvancedModem advancedModem;
public static ItemCable cable;
public static ItemBlock wiredModemFull;
}
public static class Upgrades
public static final class TurtleUpgrades
{
public static TurtleModem wirelessModem;
public static TurtleModem advancedModem;
public static TurtleSpeaker speaker;
public static TurtleCraftingTable craftingTable;
public static TurtleSword diamondSword;
public static TurtleShovel diamondShovel;
public static TurtleTool diamondPickaxe;
public static TurtleAxe diamondAxe;
public static TurtleHoe diamondHoe;
public static TurtleModem advancedModem;
public static TurtleSpeaker turtleSpeaker;
}
public static class PocketUpgrades
public static final class PocketUpgrades
{
public static PocketModem wirelessModem;
public static PocketModem advancedModem;
public static PocketSpeaker speaker;
@Deprecated
public static PocketSpeaker pocketSpeaker;
}
// Registries
public static ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry();
public static ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();
@Deprecated
public static final class Upgrades
{
public static TurtleModem advancedModem;
}
// Networking
public static SimpleNetworkWrapper networkWrapper;
// Registries
public static final ClientComputerRegistry clientComputerRegistry = new ClientComputerRegistry();
public static final ServerComputerRegistry serverComputerRegistry = new ServerComputerRegistry();
// Creative
public static CreativeTabMain mainCreativeTab;
@@ -228,14 +236,14 @@ public class ComputerCraft
public static List<IPeripheralProvider> peripheralProviders = new ArrayList<>();
// Implementation
@Mod.Instance( value = ComputerCraft.MOD_ID )
@Mod.Instance( ComputerCraft.MOD_ID )
public static ComputerCraft instance;
@SidedProxy( clientSide = "dan200.computercraft.client.proxy.ComputerCraftProxyClient", serverSide = "dan200.computercraft.server.proxy.ComputerCraftProxyServer" )
public static IComputerCraftProxy proxy;
@SidedProxy( clientSide = "dan200.computercraft.client.proxy.CCTurtleProxyClient", serverSide = "dan200.computercraft.server.proxy.CCTurtleProxyServer" )
public static ICCTurtleProxy turtleProxy;
@SidedProxy(
clientSide = "dan200.computercraft.client.proxy.ComputerCraftProxyClient",
serverSide = "dan200.computercraft.shared.proxy.ComputerCraftProxyCommon"
)
private static ComputerCraftProxyCommon proxy;
@Mod.EventHandler
public void preInit( FMLPreInitializationEvent event )
@@ -245,24 +253,19 @@ public class ComputerCraft
// Load config
Config.load( event.getSuggestedConfigurationFile() );
// Setup network
networkWrapper = NetworkRegistry.INSTANCE.newSimpleChannel( ComputerCraft.MOD_ID );
proxy.preInit();
turtleProxy.preInit();
}
@Mod.EventHandler
public void init( FMLInitializationEvent event )
{
proxy.init();
turtleProxy.init();
}
@Mod.EventHandler
public void onServerStarting( FMLServerStartingEvent event )
{
proxy.initServer( event.getServer() );
ComputerCraftProxyCommon.initServer( event.getServer() );
}
@Mod.EventHandler
@@ -272,6 +275,7 @@ public class ComputerCraft
{
ComputerCraft.serverComputerRegistry.reset();
WirelessNetwork.resetNetworks();
MainThread.reset();
Tracking.reset();
}
}
@@ -283,65 +287,14 @@ public class ComputerCraft
{
ComputerCraft.serverComputerRegistry.reset();
WirelessNetwork.resetNetworks();
MainThread.reset();
Tracking.reset();
}
}
public static String getVersion()
{
return "${version}";
}
public static void openDiskDriveGUI( EntityPlayer player, TileDiskDrive drive )
{
BlockPos pos = drive.getPos();
player.openGui( ComputerCraft.instance, ComputerCraft.diskDriveGUIID, player.getEntityWorld(), pos.getX(), pos.getY(), pos.getZ() );
}
public static void openComputerGUI( EntityPlayer player, TileComputer computer )
{
BlockPos pos = computer.getPos();
player.openGui( ComputerCraft.instance, ComputerCraft.computerGUIID, player.getEntityWorld(), pos.getX(), pos.getY(), pos.getZ() );
}
public static void openPrinterGUI( EntityPlayer player, TilePrinter printer )
{
BlockPos pos = printer.getPos();
player.openGui( ComputerCraft.instance, ComputerCraft.printerGUIID, player.getEntityWorld(), pos.getX(), pos.getY(), pos.getZ() );
}
public static void openTurtleGUI( EntityPlayer player, TileTurtle turtle )
{
BlockPos pos = turtle.getPos();
player.openGui( instance, ComputerCraft.turtleGUIID, player.getEntityWorld(), pos.getX(), pos.getY(), pos.getZ() );
}
public static void openPrintoutGUI( EntityPlayer player, EnumHand hand )
{
player.openGui( ComputerCraft.instance, ComputerCraft.printoutGUIID, player.getEntityWorld(), hand.ordinal(), 0, 0 );
}
public static void openPocketComputerGUI( EntityPlayer player, EnumHand hand )
{
player.openGui( ComputerCraft.instance, ComputerCraft.pocketComputerGUIID, player.getEntityWorld(), hand.ordinal(), 0, 0 );
}
public static void openComputerGUI( EntityPlayer player, ServerComputer computer )
{
ComputerFamily family = computer.getFamily();
int width = 0, height = 0;
Terminal terminal = computer.getTerminal();
if( terminal != null )
{
width = terminal.getWidth();
height = terminal.getHeight();
}
// Pack useful terminal information into the various coordinate bits.
// These are extracted in ComputerCraftProxyCommon.getClientGuiElement
player.openGui( ComputerCraft.instance, ComputerCraft.viewComputerGUIID, player.getEntityWorld(),
computer.getInstanceID(), family.ordinal(), (width & 0xFFFF) << 16 | (height & 0xFFFF)
);
return VERSION;
}
private static File getBaseDir()
@@ -354,41 +307,6 @@ public class ComputerCraft
return new File( getBaseDir(), "resourcepacks" );
}
public static File getWorldDir( World world )
{
return proxy.getWorldDir( world );
}
public static void sendToPlayer( EntityPlayer player, IMessage packet )
{
networkWrapper.sendTo( packet, (EntityPlayerMP) player );
}
public static void sendToAllPlayers( IMessage packet )
{
networkWrapper.sendToAll( packet );
}
public static void sendToServer( IMessage packet )
{
networkWrapper.sendToServer( packet );
}
public static void sendToAllAround( IMessage packet, NetworkRegistry.TargetPoint point )
{
networkWrapper.sendToAllAround( packet, point );
}
public static boolean canPlayerUseCommands( EntityPlayer player )
{
MinecraftServer server = player.getServer();
if( server != null )
{
return server.getPlayerList().canSendCommands( player.getGameProfile() );
}
return false;
}
@Deprecated
public static void registerPermissionProvider( ITurtlePermissionProvider provider )
{
@@ -455,7 +373,7 @@ public class ComputerCraft
@Deprecated
public static int createUniqueNumberedSaveDir( World world, String parentSubPath )
{
return IDAssigner.getNextIDFromDirectory( new File( getWorldDir( world ), parentSubPath ) );
return IDAssigner.getNextIDFromDirectory( parentSubPath );
}
@Deprecated
@@ -463,7 +381,7 @@ public class ComputerCraft
{
try
{
return new FileMount( new File( getWorldDir( world ), subPath ), capacity );
return new FileMount( new File( getWorldDir(), subPath ), capacity );
}
catch( Exception e )
{
@@ -471,6 +389,27 @@ public class ComputerCraft
}
}
private static void loadFromFile( List<IMount> mounts, File file, String path, boolean allowMissing )
{
try
{
if( file.isFile() )
{
mounts.add( new JarMount( file, path ) );
}
else
{
File subResource = new File( file, path );
if( subResource.exists() ) mounts.add( new FileMount( subResource, 0 ) );
}
}
catch( IOException | RuntimeException e )
{
if( allowMissing && e instanceof FileNotFoundException ) return;
ComputerCraft.log.error( "Could not load mount '" + path + " 'from '" + file.getName() + "'", e );
}
}
@Deprecated
public static IMount createResourceMount( Class<?> modClass, String domain, String subPath )
{
@@ -490,20 +429,26 @@ public class ComputerCraft
}
}
// Mount from mod jar
// Mount from mod jars, preferring the specified one.
File modJar = getContainingJar( modClass );
Set<File> otherMods = new HashSet<>();
for( ModContainer container : Loader.instance().getActiveModList() )
{
File modFile = container.getSource();
if( modFile != null && !modFile.equals( modJar ) && modFile.exists() )
{
otherMods.add( container.getSource() );
}
}
for( File file : otherMods )
{
loadFromFile( mounts, file, subPath, true );
}
if( modJar != null )
{
try
{
FileSystem fs = FileSystems.newFileSystem( modJar.toPath(), ComputerCraft.class.getClassLoader() );
mounts.add( new FileSystemMount( fs, subPath ) );
}
catch( IOException | RuntimeException | ServiceConfigurationError e )
{
ComputerCraft.log.error( "Could not load mount from mod jar", e );
// Ignore
}
loadFromFile( mounts, modJar, subPath, false );
}
// Mount from resource packs
@@ -513,30 +458,8 @@ public class ComputerCraft
String[] resourcePacks = resourcePackDir.list();
for( String resourcePackName : resourcePacks )
{
try
{
File resourcePack = new File( resourcePackDir, resourcePackName );
if( !resourcePack.isDirectory() )
{
// Mount a resource pack from a jar
FileSystem fs = FileSystems.newFileSystem( resourcePack.toPath(), ComputerCraft.class.getClassLoader() );
if( Files.exists( fs.getPath( subPath ) ) ) mounts.add( new FileSystemMount( fs, subPath ) );
}
else
{
// Mount a resource pack from a folder
File subResource = new File( resourcePack, subPath );
if( subResource.exists() )
{
IMount resourcePackMount = new FileMount( subResource, 0 );
mounts.add( resourcePackMount );
}
}
}
catch( IOException | RuntimeException | ServiceConfigurationError e )
{
ComputerCraft.log.error( "Could not load resource pack '" + resourcePackName + "'", e );
}
File resourcePack = new File( resourcePackDir, resourcePackName );
loadFromFile( mounts, resourcePack, subPath, true );
}
}
@@ -642,7 +565,7 @@ public class ComputerCraft
private static File getContainingJar( Class<?> modClass )
{
String path = modClass.getProtectionDomain().getCodeSource().getLocation().getPath();
int bangIndex = path.indexOf( "!" );
int bangIndex = path.indexOf( '!' );
if( bangIndex >= 0 )
{
path = path.substring( 0, bangIndex );
@@ -673,17 +596,28 @@ public class ComputerCraft
private static File getDebugCodeDir( Class<?> modClass )
{
String path = modClass.getProtectionDomain().getCodeSource().getLocation().getPath();
int bangIndex = path.indexOf( "!" );
int bangIndex = path.indexOf( '!' );
return bangIndex >= 0 ? null : new File( new File( path ).getParentFile(), "../.." );
}
@Deprecated
public static void registerTurtleUpgrade( ITurtleUpgrade upgrade )
{
TurtleUpgrades.register( upgrade );
dan200.computercraft.shared.TurtleUpgrades.register( upgrade );
}
public static File getWorldDir()
{
return DimensionManager.getCurrentSaveRootDirectory();
}
//region Compatibility
@Deprecated
public static File getWorldDir( World world )
{
return DimensionManager.getCurrentSaveRootDirectory();
}
@Deprecated
public static IMedia getMedia( ItemStack stack )
{
@@ -699,7 +633,7 @@ public class ComputerCraft
@Deprecated
public static ITurtleUpgrade getTurtleUpgrade( ItemStack stack )
{
return TurtleUpgrades.get( stack );
return dan200.computercraft.shared.TurtleUpgrades.get( stack );
}
@Deprecated
@@ -711,7 +645,7 @@ public class ComputerCraft
@Deprecated
public static ITurtleUpgrade getTurtleUpgrade( String id )
{
return TurtleUpgrades.get( id );
return dan200.computercraft.shared.TurtleUpgrades.get( id );
}
@Deprecated
@@ -719,5 +653,12 @@ public class ComputerCraft
{
return Peripherals.getPeripheral( world, pos, side );
}
@Deprecated
public static boolean canPlayerUseCommands( EntityPlayer player )
{
MinecraftServer server = player.getServer();
return server != null && server.getPlayerList().canSendCommands( player.getGameProfile() );
}
//endregion
}

View File

@@ -1,10 +1,9 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.shared.turtle.upgrades;
package dan200.computercraft.api;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleUpgradeType;
@@ -15,6 +14,11 @@ import net.minecraft.util.ResourceLocation;
import javax.annotation.Nonnull;
/**
* A base class for {@link ITurtleUpgrade}s.
*
* One does not have to use this, but it does provide a convenient template.
*/
public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
{
private final ResourceLocation id;
@@ -23,7 +27,7 @@ public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
private final String adjective;
private final ItemStack stack;
public AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, String adjective, ItemStack stack )
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, String adjective, ItemStack stack )
{
this.id = id;
this.legacyId = legacyId;
@@ -32,16 +36,31 @@ public abstract class AbstractTurtleUpgrade implements ITurtleUpgrade
this.stack = stack;
}
public AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, String adjective, Item item )
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, String adjective, Item item )
{
this( id, legacyId, type, adjective, new ItemStack( item ) );
}
public AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, String adjective, Block block )
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, String adjective, Block block )
{
this( id, legacyId, type, adjective, new ItemStack( block ) );
}
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, ItemStack stack )
{
this( id, legacyId, type, "upgrade." + id + ".adjective", stack );
}
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, Item item )
{
this( id, legacyId, type, new ItemStack( item ) );
}
protected AbstractTurtleUpgrade( ResourceLocation id, int legacyId, TurtleUpgradeType type, Block block )
{
this( id, legacyId, type, new ItemStack( block ) );
}
@Nonnull
@Override
public final ResourceLocation getUpgradeID()

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api;
import dan200.computercraft.api.filesystem.IMount;
@@ -32,8 +31,9 @@ import java.lang.reflect.Method;
/**
* The static entry point to the ComputerCraft API.
* Members in this class must be called after mod_ComputerCraft has been initialised,
* but may be called before it is fully loaded.
*
* Members in this class must be called after mod_ComputerCraft has been initialised, but may be called before it is
* fully loaded.
*/
public final class ComputerCraftAPI
{
@@ -173,8 +173,8 @@ public final class ComputerCraftAPI
* Registers a peripheral provider to convert blocks into {@link IPeripheral} implementations.
*
* @param provider The peripheral provider to register.
* @see dan200.computercraft.api.peripheral.IPeripheral
* @see dan200.computercraft.api.peripheral.IPeripheralProvider
* @see IPeripheral
* @see IPeripheralProvider
*/
public static void registerPeripheralProvider( @Nonnull IPeripheralProvider provider )
{
@@ -198,7 +198,7 @@ public final class ComputerCraftAPI
* this during the load() method of your mod.
*
* @param upgrade The turtle upgrade to register.
* @see dan200.computercraft.api.turtle.ITurtleUpgrade
* @see ITurtleUpgrade
*/
public static void registerTurtleUpgrade( @Nonnull ITurtleUpgrade upgrade )
{
@@ -223,7 +223,7 @@ public final class ComputerCraftAPI
* Registers a bundled redstone provider to provide bundled redstone output for blocks.
*
* @param provider The bundled redstone provider to register.
* @see dan200.computercraft.api.redstone.IBundledRedstoneProvider
* @see IBundledRedstoneProvider
*/
public static void registerBundledRedstoneProvider( @Nonnull IBundledRedstoneProvider provider )
{
@@ -249,7 +249,7 @@ public final class ComputerCraftAPI
* @param side The side to extract the bundled redstone output from.
* @return If there is a block capable of emitting bundled redstone at the location, it's signal (0-65535) will be returned.
* If there is no block capable of emitting bundled redstone at the location, -1 will be returned.
* @see dan200.computercraft.api.redstone.IBundledRedstoneProvider
* @see IBundledRedstoneProvider
*/
public static int getBundledRedstoneOutput( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side )
{
@@ -269,10 +269,10 @@ public final class ComputerCraftAPI
}
/**
* Registers a media provider to provide {@link IMedia} implementations for Items
* Registers a media provider to provide {@link IMedia} implementations for Items.
*
* @param provider The media provider to register.
* @see dan200.computercraft.api.media.IMediaProvider
* @see IMediaProvider
*/
public static void registerMediaProvider( @Nonnull IMediaProvider provider )
{
@@ -294,7 +294,7 @@ public final class ComputerCraftAPI
* Registers a permission provider to restrict where turtles can move or build.
*
* @param provider The turtle permission provider to register.
* @see dan200.computercraft.api.permissions.ITurtlePermissionProvider
* @see ITurtlePermissionProvider
* @deprecated Prefer using {@link dan200.computercraft.api.turtle.event.TurtleBlockEvent} or the standard Forge events.
*/
@Deprecated
@@ -370,7 +370,7 @@ public final class ComputerCraftAPI
}
/**
* Construct a new wired node for a given wired element
* Construct a new wired node for a given wired element.
*
* @param element The element to construct it for
* @return The element's node
@@ -398,7 +398,7 @@ public final class ComputerCraftAPI
}
/**
* Get the wired network element for a block in world
* Get the wired network element for a block in world.
*
* @param world The world the block exists in
* @param pos The position the block exists in
@@ -438,50 +438,50 @@ public final class ComputerCraftAPI
computerCraft_getVersion = findCCMethod( "getVersion", new Class<?>[] {
} );
computerCraft_createUniqueNumberedSaveDir = findCCMethod( "createUniqueNumberedSaveDir", new Class<?>[] {
World.class, String.class
World.class, String.class,
} );
computerCraft_createSaveDirMount = findCCMethod( "createSaveDirMount", new Class<?>[] {
World.class, String.class, Long.TYPE
World.class, String.class, Long.TYPE,
} );
computerCraft_createResourceMount = findCCMethod( "createResourceMount", new Class<?>[] {
Class.class, String.class, String.class
Class.class, String.class, String.class,
} );
computerCraft_registerPeripheralProvider = findCCMethod( "registerPeripheralProvider", new Class<?>[] {
IPeripheralProvider.class
IPeripheralProvider.class,
} );
computerCraft_registerTurtleUpgrade = findCCMethod( "registerTurtleUpgrade", new Class<?>[] {
ITurtleUpgrade.class
ITurtleUpgrade.class,
} );
computerCraft_registerBundledRedstoneProvider = findCCMethod( "registerBundledRedstoneProvider", new Class<?>[] {
IBundledRedstoneProvider.class
IBundledRedstoneProvider.class,
} );
computerCraft_getDefaultBundledRedstoneOutput = findCCMethod( "getDefaultBundledRedstoneOutput", new Class<?>[] {
World.class, BlockPos.class, EnumFacing.class
World.class, BlockPos.class, EnumFacing.class,
} );
computerCraft_registerMediaProvider = findCCMethod( "registerMediaProvider", new Class<?>[] {
IMediaProvider.class
IMediaProvider.class,
} );
computerCraft_registerPermissionProvider = findCCMethod( "registerPermissionProvider", new Class<?>[] {
ITurtlePermissionProvider.class
ITurtlePermissionProvider.class,
} );
computerCraft_registerPocketUpgrade = findCCMethod( "registerPocketUpgrade", new Class<?>[] {
IPocketUpgrade.class
IPocketUpgrade.class,
} );
computerCraft_getWirelessNetwork = findCCMethod( "getWirelessNetwork", new Class<?>[] {
} );
computerCraft_registerAPIFactory = findCCMethod( "registerAPIFactory", new Class<?>[] {
ILuaAPIFactory.class
ILuaAPIFactory.class,
} );
computerCraft_createWiredNodeForElement = findCCMethod( "createWiredNodeForElement", new Class<?>[] {
IWiredElement.class
IWiredElement.class,
} );
computerCraft_getWiredElementAt = findCCMethod( "getWiredElementAt", new Class<?>[] {
IBlockAccess.class, BlockPos.class, EnumFacing.class
IBlockAccess.class, BlockPos.class, EnumFacing.class,
} );
}
catch( Exception e )
{
System.out.println( "ComputerCraftAPI: ComputerCraft not found." );
System.err.println( "ComputerCraftAPI: ComputerCraft not found." );
}
finally
{
@@ -498,7 +498,7 @@ public final class ComputerCraftAPI
}
catch( NoSuchMethodException e )
{
System.out.println( "ComputerCraftAPI: ComputerCraft method " + name + " not found." );
System.err.println( "ComputerCraftAPI: ComputerCraft method " + name + " not found." );
return null;
}
}

View File

@@ -0,0 +1,41 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.filesystem;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Objects;
/**
* An {@link IOException} which occurred on a specific file.
*
* This may be thrown from a {@link IMount} or {@link IWritableMount} to give more information about a failure.
*/
public class FileOperationException extends IOException
{
private static final long serialVersionUID = -8809108200853029849L;
private final String filename;
public FileOperationException( @Nullable String filename, @Nonnull String message )
{
super( Objects.requireNonNull( message, "message cannot be null" ) );
this.filename = filename;
}
public FileOperationException( String message )
{
super( Objects.requireNonNull( message, "message cannot be null" ) );
this.filename = null;
}
@Nullable
public String getFilename()
{
return filename;
}
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.filesystem;
import java.io.IOException;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.filesystem;
import dan200.computercraft.api.ComputerCraftAPI;
@@ -19,7 +18,7 @@ import java.util.List;
/**
* Represents a read only part of a virtual filesystem that can be mounted onto a computer using
* {@link IComputerAccess#mount(String, IMount)}
* {@link IComputerAccess#mount(String, IMount)}.
*
* Ready made implementations of this interface can be created using
* {@link ComputerCraftAPI#createSaveDirMount(World, String, long)} or
@@ -60,7 +59,7 @@ public interface IMount
void list( @Nonnull String path, @Nonnull List<String> contents ) throws IOException;
/**
* Returns the size of a file with a given path, in bytes
* Returns the size of a file with a given path, in bytes.
*
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
* @return The size of the file, in bytes.
@@ -90,7 +89,6 @@ public interface IMount
* @throws IOException If the file does not exist, or could not be opened.
*/
@Nonnull
@SuppressWarnings( "deprecation" )
default ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOException
{
return Channels.newChannel( openForRead( path ) );

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.filesystem;
import dan200.computercraft.api.ComputerCraftAPI;
@@ -67,7 +66,6 @@ public interface IWritableMount extends IMount
* @throws IOException If the file could not be opened for writing.
*/
@Nonnull
@SuppressWarnings( "deprecation" )
default WritableByteChannel openChannelForWrite( @Nonnull String path ) throws IOException
{
return Channels.newChannel( openForWrite( path ) );
@@ -94,7 +92,6 @@ public interface IWritableMount extends IMount
* @throws IOException If the file could not be opened for writing.
*/
@Nonnull
@SuppressWarnings( "deprecation" )
default WritableByteChannel openChannelForAppend( @Nonnull String path ) throws IOException
{
return Channels.newChannel( openForAppend( path ) );

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|FileSystem", apiVersion = "${version}" )
package dan200.computercraft.api.filesystem;

View File

@@ -0,0 +1,334 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
/**
* Provides methods for extracting values and validating Lua arguments, such as those provided to
* {@link ILuaObject#callMethod(ILuaContext, int, Object[])} or
* {@link IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}.
*
* This provides two sets of functions: the {@code get*} methods, which require an argument to be valid, and
* {@code opt*}, which accept a default value and return that if the argument was not present or was {@code null}.
* If the argument is of the wrong type, a suitable error message will be thrown, with a similar format to Lua's own
* error messages.
*
* <h2>Example usage:</h2>
* <pre>
* {@code
* int slot = getInt( args, 0 );
* int amount = optInt( args, 1, 64 );
* }
* </pre>
*/
public final class ArgumentHelper
{
private ArgumentHelper()
{
}
/**
* Get a string representation of the given value's type.
*
* @param value The value whose type we are trying to compute.
* @return A string representation of the given value's type, in a similar format to that provided by Lua's
* {@code type} function.
*/
@Nonnull
public static String getType( @Nullable Object value )
{
if( value == null ) return "nil";
if( value instanceof String ) return "string";
if( value instanceof Boolean ) return "boolean";
if( value instanceof Number ) return "number";
if( value instanceof Map ) return "table";
return "userdata";
}
/**
* Construct a "bad argument" exception, from an expected type and the actual value provided.
*
* @param index The argument number, starting from 0.
* @param expected The expected type for this argument.
* @param actual The actual value provided for this argument.
* @return The constructed exception, which should be thrown immediately.
*/
@Nonnull
public static LuaException badArgumentOf( int index, @Nonnull String expected, @Nullable Object actual )
{
return badArgument( index, expected, getType( actual ) );
}
/**
* Construct a "bad argument" exception, from an expected and actual type.
*
* @param index The argument number, starting from 0.
* @param expected The expected type for this argument.
* @param actual The provided type for this argument.
* @return The constructed exception, which should be thrown immediately.
*/
@Nonnull
public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual )
{
return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
}
/**
* Get an argument as a double.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a number.
* @see #getFiniteDouble(Object[], int) if you require this to be finite (i.e. not infinite or NaN).
*/
public static double getDouble( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return ((Number) value).doubleValue();
}
/**
* Get an argument as an integer.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not an integer.
*/
public static int getInt( @Nonnull Object[] args, int index ) throws LuaException
{
return (int) getLong( args, index );
}
/**
* Get an argument as a long.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a long.
*/
public static long getLong( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "number", "nil" );
Object value = args[index];
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return checkFinite( index, (Number) value ).longValue();
}
/**
* Get an argument as a finite number (not infinite or NaN).
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not finite.
*/
public static double getFiniteDouble( @Nonnull Object[] args, int index ) throws LuaException
{
return checkFinite( index, getDouble( args, index ) );
}
/**
* Get an argument as a boolean.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a boolean.
*/
public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "boolean", "nil" );
Object value = args[index];
if( !(value instanceof Boolean) ) throw badArgumentOf( index, "boolean", value );
return (Boolean) value;
}
/**
* Get an argument as a string.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a string.
*/
@Nonnull
public static String getString( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "string", "nil" );
Object value = args[index];
if( !(value instanceof String) ) throw badArgumentOf( index, "string", value );
return (String) value;
}
/**
* Get an argument as a table.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @return The argument's value.
* @throws LuaException If the value is not a table.
*/
@Nonnull
public static Map<?, ?> getTable( @Nonnull Object[] args, int index ) throws LuaException
{
if( index >= args.length ) throw badArgument( index, "table", "nil" );
Object value = args[index];
if( !(value instanceof Map) ) throw badArgumentOf( index, "table", value );
return (Map<?, ?>) value;
}
/**
* Get an argument as a double.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static double optDouble( @Nonnull Object[] args, int index, double def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return ((Number) value).doubleValue();
}
/**
* Get an argument as an int.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException
{
return (int) optLong( args, index, def );
}
/**
* Get an argument as a long.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a number.
*/
public static long optLong( @Nonnull Object[] args, int index, long def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Number) ) throw badArgumentOf( index, "number", value );
return checkFinite( index, (Number) value ).longValue();
}
/**
* Get an argument as a finite number (not infinite or NaN).
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not finite.
*/
public static double optFiniteDouble( @Nonnull Object[] args, int index, double def ) throws LuaException
{
return checkFinite( index, optDouble( args, index, def ) );
}
/**
* Get an argument as a boolean.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a boolean.
*/
public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Boolean) ) throw badArgumentOf( index, "boolean", value );
return (Boolean) value;
}
/**
* Get an argument as a string.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a string.
*/
public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof String) ) throw badArgumentOf( index, "string", value );
return (String) value;
}
/**
* Get an argument as a table.
*
* @param args The arguments to extract from.
* @param index The index into the argument array to read from.
* @param def The default value, if this argument is not given.
* @return The argument's value, or {@code def} if none was provided.
* @throws LuaException If the value is not a table.
*/
public static Map<?, ?> optTable( @Nonnull Object[] args, int index, Map<Object, Object> def ) throws LuaException
{
Object value = index < args.length ? args[index] : null;
if( value == null ) return def;
if( !(value instanceof Map) ) throw badArgumentOf( index, "table", value );
return (Map<?, ?>) value;
}
private static Number checkFinite( int index, Number value ) throws LuaException
{
checkFinite( index, value.doubleValue() );
return value;
}
private static double checkFinite( int index, double value ) throws LuaException
{
if( !Double.isFinite( value ) ) throw badArgument( index, "number", getNumericType( value ) );
return value;
}
/**
* Returns a more detailed representation of this number's type. If this is finite, it will just return "number",
* otherwise it returns whether it is infinite or NaN.
*
* @param value The value to extract the type for.
* @return This value's numeric type.
*/
@Nonnull
public static String getNumericType( double value )
{
if( Double.isNaN( value ) ) return "nan";
if( value == Double.POSITIVE_INFINITY ) return "inf";
if( value == Double.NEGATIVE_INFINITY ) return "-inf";
return "number";
}
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import dan200.computercraft.api.filesystem.IFileSystem;
@@ -26,7 +25,7 @@ public interface IComputerSystem extends IComputerAccess
IFileSystem getFileSystem();
/**
* Get the label for this computer
* Get the label for this computer.
*
* @return This computer's label, or {@code null} if it is not set.
*/

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import dan200.computercraft.api.ComputerCraftAPI;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import dan200.computercraft.api.ComputerCraftAPI;
@@ -17,6 +16,7 @@ import javax.annotation.Nullable;
* @see ILuaAPI
* @see ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory)
*/
@FunctionalInterface
public interface ILuaAPIFactory
{
/**

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import javax.annotation.Nonnull;
@@ -32,7 +31,12 @@ public interface ILuaContext
* intercepted, or the computer will leak memory and end up in a broken state.
*/
@Nonnull
Object[] pullEvent( @Nullable String filter ) throws LuaException, InterruptedException;
default Object[] pullEvent( @Nullable String filter ) throws LuaException, InterruptedException
{
Object[] results = pullEventRaw( filter );
if( results.length >= 1 && results[0].equals( "terminate" ) ) throw new LuaException( "Terminated", 0 );
return results;
}
/**
* The same as {@link #pullEvent(String)}, except "terminated" events are ignored. Only use this if you want to
@@ -47,7 +51,10 @@ public interface ILuaContext
* @see #pullEvent(String)
*/
@Nonnull
Object[] pullEventRaw( @Nullable String filter ) throws InterruptedException;
default Object[] pullEventRaw( @Nullable String filter ) throws InterruptedException
{
return yield( new Object[] { filter } );
}
/**
* Yield the current coroutine with some arguments until it is resumed. This method is exactly equivalent to

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import dan200.computercraft.api.peripheral.IComputerAccess;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import javax.annotation.Nullable;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import javax.annotation.Nullable;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Lua", apiVersion = "${version}" )
package dan200.computercraft.api.lua;

View File

@@ -1,12 +1,12 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.media;
import dan200.computercraft.api.filesystem.IMount;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.SoundEvent;
import net.minecraft.world.World;
@@ -16,7 +16,9 @@ import javax.annotation.Nullable;
/**
* Represents an item that can be placed in a disk drive and used by a Computer.
* Implement this interface on your Item class to allow it to be used in the drive.
*
* Implement this interface on your {@link Item} class to allow it to be used in the drive. Alternatively, register
* a {@link IMediaProvider}.
*/
public interface IMedia
{
@@ -43,7 +45,7 @@ public interface IMedia
/**
* If this disk represents an item with audio (like a record), get the readable name of the audio track. ie:
* "Jonathon Coulton - Still Alive"
* "Jonathan Coulton - Still Alive"
*
* @param stack The {@link ItemStack} to modify.
* @return The name, or null if this item does not represent an item with audio.
@@ -74,7 +76,7 @@ public interface IMedia
* @param world The world in which the item and disk drive reside.
* @return The mount, or null if this item does not represent an item with data. If the mount returned also
* implements {@link dan200.computercraft.api.filesystem.IWritableMount}, it will mounted using mountWritable()
* @see dan200.computercraft.api.filesystem.IMount
* @see IMount
* @see dan200.computercraft.api.filesystem.IWritableMount
* @see dan200.computercraft.api.ComputerCraftAPI#createSaveDirMount(World, String, long)
* @see dan200.computercraft.api.ComputerCraftAPI#createResourceMount(Class, String, String)

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.media;
import net.minecraft.item.ItemStack;
@@ -23,7 +22,7 @@ public interface IMediaProvider
* Produce an IMedia implementation from an ItemStack.
*
* @param stack The stack from which to extract the media information.
* @return An IMedia implementation, or null if the item is not something you wish to handle
* @return An {@link IMedia} implementation, or {@code null} if the item is not something you wish to handle
* @see dan200.computercraft.api.ComputerCraftAPI#registerMediaProvider(IMediaProvider)
*/
@Nullable

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Media", apiVersion = "${version}" )
package dan200.computercraft.api.media;

View File

@@ -1,6 +1,6 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.network;

View File

@@ -1,6 +1,6 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.network;

View File

@@ -1,6 +1,6 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.network;

View File

@@ -1,6 +1,6 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.network;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Network", apiVersion = "${version}" )
package dan200.computercraft.api.network;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.network.wired;
import dan200.computercraft.api.ComputerCraftAPI;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.network.wired;
import dan200.computercraft.api.peripheral.IPeripheral;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.network.wired;
import dan200.computercraft.api.peripheral.IPeripheral;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.network.wired;
import dan200.computercraft.api.network.IPacketNetwork;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.network.wired;
import dan200.computercraft.api.network.IPacketSender;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Network|Wired", apiVersion = "${version}" )
package dan200.computercraft.api.network.wired;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API", apiVersion = "${version}" )
package dan200.computercraft.api;

View File

@@ -1,14 +1,15 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.peripheral;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.ILuaTask;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
@@ -146,7 +147,7 @@ public interface IComputerAccess
*
* You may supply {@code null} to indicate that no arguments are to be supplied.
* @throws RuntimeException If the peripheral has been detached.
* @see dan200.computercraft.api.peripheral.IPeripheral#callMethod
* @see IPeripheral#callMethod
*/
void queueEvent( @Nonnull String event, @Nullable Object[] arguments );
@@ -179,8 +180,8 @@ public interface IComputerAccess
}
/**
* Get a reachable peripheral with the given attachement name. This is a equivalent to
* {@link #getAvailablePeripherals()}{@code .get(name)}, though may be more performant.
* Get a reachable peripheral with the given attachment name. This is a equivalent to
* {@link #getAvailablePeripherals()}{@code .get(name)}, though may be more efficient.
*
* @param name The peripheral's attached name
* @return The reachable peripheral, or {@code null} if none can be found.
@@ -191,4 +192,23 @@ public interface IComputerAccess
{
return null;
}
/**
* Get a {@link IWorkMonitor} for tasks your peripheral might execute on the main (server) thread.
*
* This should be used to ensure your peripheral integrates with ComputerCraft's monitoring and limiting of how much
* server time each computer consumes. You should not need to use this if you use
* {@link ILuaContext#issueMainThreadTask(ILuaTask)} - this is intended for mods with their own system for running
* work on the main thread.
*
* Please note that the returned implementation is <em>not</em> thread-safe, and should only be used from the main
* thread.
*
* @return The work monitor for the main thread, or {@code null} if this computer does not have one.
*/
@Nullable
default IWorkMonitor getMainThreadMonitor()
{
return null;
}
}

View File

@@ -1,11 +1,11 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.peripheral;
import dan200.computercraft.api.lua.ArgumentHelper;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
@@ -41,8 +41,8 @@ public interface IPeripheral
* This is called when a lua program on an attached computer calls {@code peripheral.call()} with
* one of the methods exposed by {@link #getMethodNames()}.
*
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
* when interacting with Minecraft objects.
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe when interacting
* with Minecraft objects.
*
* @param computer The interface to the computer that is making the call. Remember that multiple
* computers can be attached to a peripheral at once.
@@ -58,9 +58,11 @@ public interface IPeripheral
* Lua values of type "table" will be represented by Object type Map.<br>
* Lua values of any other type will be represented by a null object.<br>
* This array will be empty if no arguments are passed.
*
* It is recommended you use {@link ArgumentHelper} in order to validate and process arguments.
* @return An array of objects, representing values you wish to return to the lua program. Integers, Doubles, Floats,
* Strings, Booleans, Maps and ILuaObject and null be converted to their corresponding lua type. All other types
* will be converted to nil.
* Strings, Booleans, Maps, ILuaObject and null be converted to their corresponding lua type. All other types will
* be converted to nil.
*
* You may return null to indicate no values should be returned.
* @throws LuaException If you throw any exception from this function, a lua error will be raised with the
@@ -70,25 +72,27 @@ public interface IPeripheral
* InterruptedException will be thrown. This exception must not be caught or
* intercepted, or the computer will leak memory and end up in a broken state.
* @see #getMethodNames
* @see ArgumentHelper
*/
@Nullable
Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException;
/**
* Is called when canAttachToSide has returned true, and a computer is attaching to the peripheral.
* Is called when when a computer is attaching to the peripheral.
*
* This will occur when a peripheral is placed next to an active computer, when a computer is turned on next to a
* peripheral, or when a turtle travels into a square next to a peripheral.
* peripheral, when a turtle travels into a square next to a peripheral, or when a wired modem adjacent to this
* peripheral is does any of the above.
*
* Between calls to attach() and detach(), the attached computer can make method calls on the peripheral using
* Between calls to attach and {@link #detach}, the attached computer can make method calls on the peripheral using
* {@code peripheral.call()}. This method can be used to keep track of which computers are attached to the
* peripheral, or to take action when attachment occurs.
*
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
* when interacting with Minecraft objects.
* Be aware that will be called from both the server thread and ComputerCraft Lua thread, and so must be thread-safe
* and reentrant.
*
* @param computer The interface to the computer that is being attached. Remember that multiple
* computers can be attached to a peripheral at once.
* @param computer The interface to the computer that is being attached. Remember that multiple computers can be
* attached to a peripheral at once.
* @see #detach
*/
default void attach( @Nonnull IComputerAccess computer )
@@ -96,19 +100,21 @@ public interface IPeripheral
}
/**
* Is called when a computer is detaching from the peripheral.
* Called when a computer is detaching from the peripheral.
*
* This will occur when a computer shuts down, when the peripheral is removed while attached to computers,
* or when a turtle moves away from a square attached to a peripheral. This method can be used to keep track of
* which computers are attached to the peripheral, or to take action when detachment
* occurs.
* This will occur when a computer shuts down, when the peripheral is removed while attached to computers, when a
* turtle moves away from a block attached to a peripheral, or when a wired modem adjacent to this peripheral is
* detached.
*
* Be aware that this will be called from the ComputerCraft Lua thread, and must be thread-safe
* when interacting with Minecraft objects.
* This method can be used to keep track of which computers are attached to the peripheral, or to take action when
* detachment occurs.
*
* @param computer The interface to the computer that is being detached. Remember that multiple
* computers can be attached to a peripheral at once.
* @see #detach
* Be aware that this will be called from both the server and ComputerCraft Lua thread, and must be thread-safe
* and reentrant.
*
* @param computer The interface to the computer that is being detached. Remember that multiple computers can be
* attached to a peripheral at once.
* @see #attach
*/
default void detach( @Nonnull IComputerAccess computer )
{

View File

@@ -1,11 +1,11 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.peripheral;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -16,6 +16,8 @@ import javax.annotation.Nullable;
/**
* This interface is used to create peripheral implementations for blocks.
*
* If you have a {@link TileEntity} which acts as a peripheral, you may alternatively implement {@link IPeripheralTile}.
*
* @see dan200.computercraft.api.ComputerCraftAPI#registerPeripheralProvider(IPeripheralProvider)
*/
@FunctionalInterface

View File

@@ -0,0 +1,32 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.peripheral;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A {@link net.minecraft.tileentity.TileEntity} which may act as a peripheral.
*
* If you need more complex capabilities (such as handling TEs not belonging to your mod), you should use
* {@link IPeripheralProvider}.
*/
public interface IPeripheralTile
{
/**
* Get the peripheral on the given {@code side}.
*
* @param side The side to get the peripheral from.
* @return A peripheral, or {@code null} if there is not a peripheral here.
* @see IPeripheralProvider#getPeripheral(World, BlockPos, EnumFacing)
*/
@Nullable
IPeripheral getPeripheral( @Nonnull EnumFacing side );
}

View File

@@ -0,0 +1,77 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.peripheral;
import javax.annotation.Nonnull;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* Monitors "work" associated with a computer, keeping track of how much a computer has done, and ensuring every
* computer receives a fair share of any processing time.
*
* This is primarily intended for work done by peripherals on the main thread (such as on a tile entity's tick), but
* could be used for other purposes (such as complex computations done on another thread).
*
* Before running a task, one should call {@link #canWork()} to determine if the computer is currently allowed to
* execute work. If that returns true, you should execute the task and use {@link #trackWork(long, TimeUnit)} to inform
* the monitor how long that task took.
*
* Alternatively, use {@link #runWork(Runnable)} to run and keep track of work.
*
* @see IComputerAccess#getMainThreadMonitor()
*/
public interface IWorkMonitor
{
/**
* If the owning computer is currently allowed to execute work.
*
* @return If we can execute work right now.
*/
boolean canWork();
/**
* If the owning computer is currently allowed to execute work, and has ample time to do so.
*
* This is effectively a more restrictive form of {@link #canWork()}. One should use that in order to determine if
* you may do an initial piece of work, and shouldWork to determine if any additional task may be performed.
*
* @return If we should execute work right now.
*/
boolean shouldWork();
/**
* Inform the monitor how long some piece of work took to execute.
*
* @param time The time some task took to run
* @param unit The unit that {@code time} was measured in.
*/
void trackWork( long time, @Nonnull TimeUnit unit );
/**
* Run a task if possible, and inform the monitor of how long it took.
*
* @param runnable The task to run.
* @return If the task was actually run (namely, {@link #canWork()} returned {@code true}).
*/
default boolean runWork( @Nonnull Runnable runnable )
{
Objects.requireNonNull( runnable, "runnable should not be null" );
if( !canWork() ) return false;
long start = System.nanoTime();
try
{
runnable.run();
}
finally
{
trackWork( System.nanoTime() - start, TimeUnit.NANOSECONDS );
}
return true;
}
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Peripheral", apiVersion = "${version}" )
package dan200.computercraft.api.peripheral;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.permissions;
import net.minecraft.util.math.BlockPos;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Permissions", apiVersion = "${version}" )
package dan200.computercraft.api.permissions;

View File

@@ -1,17 +1,20 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.pocket;
package dan200.computercraft.shared.pocket.peripherals;
import dan200.computercraft.api.pocket.IPocketUpgrade;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import javax.annotation.Nonnull;
/**
* A base class for {@link IPocketUpgrade}s.
*
* One does not have to use this, but it does provide a convenient template.
*/
public abstract class AbstractPocketUpgrade implements IPocketUpgrade
{
private final ResourceLocation id;
@@ -25,6 +28,11 @@ public abstract class AbstractPocketUpgrade implements IPocketUpgrade
this.stack = stack;
}
protected AbstractPocketUpgrade( ResourceLocation id, ItemStack stack )
{
this( id, "upgrade." + id + ".adjective", stack );
}
@Nonnull
@Override
public final ResourceLocation getUpgradeID()

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.pocket;
import dan200.computercraft.api.peripheral.IPeripheral;
@@ -16,7 +15,7 @@ import javax.annotation.Nullable;
import java.util.Map;
/**
* Wrapper class for pocket computers
* Wrapper class for pocket computers.
*/
public interface IPocketAccess
{
@@ -24,10 +23,22 @@ public interface IPocketAccess
* Gets the entity holding this item.
*
* @return The holding entity. This may be {@code null}.
* @deprecated Use {@link #getValidEntity()} where possible.
*/
@Nullable
@Deprecated
Entity getEntity();
/**
* Gets the entity holding this item with additional safety checks.
*
* This must be called on the server thread.
*
* @return The holding entity, or {@code null} if none exists.
*/
@Nullable
Entity getValidEntity();
/**
* Get the colour of this pocket computer as a RGB number.
*

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.pocket;
import dan200.computercraft.api.ComputerCraftAPI;
@@ -19,7 +18,7 @@ import javax.annotation.Nullable;
/**
* Additional peripherals for pocket computers.
*
* This is similar to {@link dan200.computercraft.api.turtle.ITurtleUpgrade}.
* This is similar to {@link ITurtleUpgrade}.
*/
public interface IPocketUpgrade
{
@@ -54,6 +53,9 @@ public interface IPocketUpgrade
* pocket computer which holds this upgrade. This item stack is also used to determine the upgrade given by
* {@code pocket.equip()}/{@code pocket.unequip()}.
*
* Ideally this should be constant over a session. It is recommended that you cache
* the item too, in order to prevent constructing it every time the method is called.
*
* @return The item stack used for crafting. This can be {@link ItemStack#EMPTY} if crafting is disabled.
*/
@Nonnull

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.redstone;
import net.minecraft.util.EnumFacing;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Redstone", apiVersion = "${version}" )
package dan200.computercraft.api.redstone;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle;
import com.mojang.authlib.GameProfile;
@@ -145,7 +144,9 @@ public interface ITurtleAccess
GameProfile getOwningPlayer();
/**
* Get the inventory of this turtle
* Get the inventory of this turtle.
*
* Note: this inventory should only be accessed and modified on the server thread.
*
* @return This turtle's inventory
* @see #getItemHandler()
@@ -156,6 +157,8 @@ public interface ITurtleAccess
/**
* Get the inventory of this turtle as an {@link IItemHandlerModifiable}.
*
* Note: this inventory should only be accessed and modified on the server thread.
*
* @return This turtle's inventory
* @see #getInventory()
* @see IItemHandlerModifiable

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle;
import dan200.computercraft.api.lua.ILuaContext;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle;
import dan200.computercraft.api.ComputerCraftAPI;
@@ -79,6 +78,9 @@ public interface ITurtleUpgrade
* with to create a turtle which holds this upgrade. This item stack is also used
* to determine the upgrade given by {@code turtle.equip()}
*
* Ideally this should be constant over a session. It is recommended that you cache
* the item too, in order to prevent constructing it every time the method is called.
*
* @return The item stack to craft with, or {@link ItemStack#EMPTY} if it cannot be crafted.
*/
@Nonnull
@@ -106,8 +108,8 @@ public interface ITurtleUpgrade
* Will only be called for Tool turtle. Called when turtle.dig() or turtle.attack() is called
* by the turtle, and the tool is required to do some work.
*
* Conforming implementations should fire {@link BlockEvent.BreakEvent} and {@link TurtleBlockEvent.Dig}for digging,
* {@link AttackEntityEvent} and {@link TurtleAttackEvent} for attacking.
* Conforming implementations should fire {@link BlockEvent.BreakEvent} and {@link TurtleBlockEvent.Dig} for
* digging, {@link AttackEntityEvent} and {@link TurtleAttackEvent} for attacking.
*
* @param turtle Access to the turtle that the tool resides on.
* @param side Which side of the turtle (left or right) the tool resides on.

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle;
/**

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle;
import net.minecraft.util.EnumFacing;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle;
/**
@@ -12,12 +11,12 @@ package dan200.computercraft.api.turtle;
public enum TurtleSide
{
/**
* The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle)
* The turtle's left side (where the pickaxe usually is on a Wireless Mining Turtle).
*/
Left,
/**
* The turtle's right side (where the modem usually is on a Wireless Mining Turtle)
* The turtle's right side (where the modem usually is on a Wireless Mining Turtle).
*/
Right,
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle;
/**

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle;
import net.minecraft.util.EnumFacing;
@@ -18,12 +17,12 @@ import net.minecraft.util.EnumFacing;
public enum TurtleVerb
{
/**
* The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}
* The turtle called {@code turtle.dig()}, {@code turtle.digUp()} or {@code turtle.digDown()}.
*/
Dig,
/**
* The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()}
* The turtle called {@code turtle.attack()}, {@code turtle.attackUp()} or {@code turtle.attackDown()}.
*/
Attack,
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle.event;
/**
@@ -71,7 +70,7 @@ public enum TurtleAction
EQUIP,
/**
* Inspect a block in world
* Inspect a block in world.
*
* @see TurtleBlockEvent.Inspect
*/

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.lua.ILuaContext;
@@ -19,7 +18,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.eventhandler.Cancelable;
import javax.annotation.Nonnull;
import java.util.Map;
@@ -37,7 +35,6 @@ import java.util.Objects;
* Be aware that some events (such as {@link TurtleInventoryEvent}) do not necessarily interact
* with a block, simply objects within that block space.
*/
@Cancelable
public abstract class TurtleBlockEvent extends TurtlePlayerEvent
{
private final World world;
@@ -84,7 +81,6 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
*
* @see TurtleAction#DIG
*/
@Cancelable
public static class Dig extends TurtleBlockEvent
{
private final IBlockState block;
@@ -115,7 +111,7 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
}
/**
* Get the upgrade doing the digging
* Get the upgrade doing the digging.
*
* @return The upgrade doing the digging.
*/
@@ -142,7 +138,6 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
*
* @see TurtleAction#MOVE
*/
@Cancelable
public static class Move extends TurtleBlockEvent
{
public Move( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos )
@@ -156,7 +151,6 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
*
* @see TurtleAction#PLACE
*/
@Cancelable
public static class Place extends TurtleBlockEvent
{
private final ItemStack stack;
@@ -188,7 +182,6 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
*
* @see TurtleAction#INSPECT
*/
@Cancelable
public static class Inspect extends TurtleBlockEvent
{
private final IBlockState state;
@@ -229,7 +222,7 @@ public abstract class TurtleBlockEvent extends TurtlePlayerEvent
/**
* Add new information to the inspection result. Note this will override fields with the same name.
*
* @param newData The data to add. Note all values should be convertable to Lua (see
* @param newData The data to add. Note all values should be convertible to Lua (see
* {@link dan200.computercraft.api.peripheral.IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}).
*/
public void addData( @Nonnull Map<String, ?> newData )

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess;

View File

@@ -0,0 +1,73 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import java.util.Map;
import java.util.Objects;
/**
* Fired when a turtle gathers data on an item in its inventory.
*
* You may prevent items being inspected, or add additional information to the result. Be aware that this is fired on
* the computer thread, and so any operations on it must be thread safe.
*
* @see TurtleAction#INSPECT_ITEM
*/
public class TurtleInspectItemEvent extends TurtleActionEvent
{
private final ItemStack stack;
private final Map<String, Object> data;
public TurtleInspectItemEvent( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, @Nonnull Map<String, Object> data )
{
super( turtle, TurtleAction.INSPECT_ITEM );
Objects.requireNonNull( stack, "stack cannot be null" );
Objects.requireNonNull( data, "data cannot be null" );
this.stack = stack;
this.data = data;
}
/**
* The item which is currently being inspected.
*
* @return The item stack which is being inspected. This should <b>not</b> be modified.
*/
@Nonnull
public ItemStack getStack()
{
return stack;
}
/**
* Get the "inspection data" from this item, which will be returned to the user.
*
* @return This items's inspection data.
*/
@Nonnull
public Map<String, Object> getData()
{
return data;
}
/**
* Add new information to the inspection result. Note this will override fields with the same name.
*
* @param newData The data to add. Note all values should be convertible to Lua (see
* {@link dan200.computercraft.api.peripheral.IPeripheral#callMethod(IComputerAccess, ILuaContext, int, Object[])}).
*/
public void addData( @Nonnull Map<String, ?> newData )
{
Objects.requireNonNull( newData, "newData cannot be null" );
data.putAll( newData );
}
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess;
@@ -11,7 +10,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.fml.common.eventhandler.Cancelable;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nonnull;
@@ -21,7 +19,6 @@ import java.util.Objects;
/**
* Fired when a turtle attempts to interact with an inventory.
*/
@Cancelable
public abstract class TurtleInventoryEvent extends TurtleBlockEvent
{
private final IItemHandler handler;
@@ -33,7 +30,7 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
}
/**
* Get the inventory being interacted with
* Get the inventory being interacted with.
*
* @return The inventory being interacted with, {@code null} if the item will be dropped to/sucked from the world.
*/
@@ -48,7 +45,6 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
*
* @see TurtleAction#SUCK
*/
@Cancelable
public static class Suck extends TurtleInventoryEvent
{
public Suck( @Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull World world, @Nonnull BlockPos pos, @Nullable IItemHandler handler )
@@ -62,7 +58,6 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
*
* @see TurtleAction#DROP
*/
@Cancelable
public static class Drop extends TurtleInventoryEvent
{
private final ItemStack stack;
@@ -78,13 +73,12 @@ public abstract class TurtleInventoryEvent extends TurtleBlockEvent
/**
* The item which will be inserted into the inventory/dropped on the ground.
*
* Note that this is a copy of the original stack, and so should not be modified, as that will have no effect.
*
* @return The item stack which will be dropped.
* @return The item stack which will be dropped. This should <b>not</b> be modified.
*/
@Nonnull
public ItemStack getStack()
{
return stack.copy();
return stack;
}
}
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess;

View File

@@ -0,0 +1,90 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.turtle.event;
import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Objects;
/**
* Fired when a turtle attempts to refuel from an item.
*
* One may use {@link #setCanceled(boolean, String)} to prevent refueling from this specific item. Additionally, you
* may use {@link #setHandler(Handler)} to register a custom fuel provider.
*/
public class TurtleRefuelEvent extends TurtleActionEvent
{
private final ItemStack stack;
private Handler handler;
public TurtleRefuelEvent( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack )
{
super( turtle, TurtleAction.REFUEL );
Objects.requireNonNull( turtle, "turtle cannot be null" );
this.stack = stack;
}
/**
* Get the stack we are attempting to refuel from.
*
* Do not modify the returned stack - all modifications should be done within the {@link Handler}.
*
* @return The stack to refuel from.
*/
public ItemStack getStack()
{
return stack;
}
/**
* Get the refuel handler for this stack.
*
* @return The refuel handler, or {@code null} if none has currently been set.
* @see #setHandler(Handler)
*/
@Nullable
public Handler getHandler()
{
return handler;
}
/**
* Set the refuel handler for this stack.
*
* You should call this if you can actually refuel from this item, and ideally only if there are no existing
* handlers.
*
* @param handler The new refuel handler.
* @see #getHandler()
*/
public void setHandler( @Nullable Handler handler )
{
this.handler = handler;
}
/**
* Handles refuelling a turtle from a specific item.
*/
@FunctionalInterface
public interface Handler
{
/**
* Refuel a turtle using an item.
*
* @param turtle The turtle to refuel.
* @param stack The stack to refuel with.
* @param slot The slot the stack resides within. This may be used to modify the inventory afterwards.
* @param limit The maximum number of refuel operations to perform. This will often correspond to the number of
* items to consume.
* @return The amount of fuel gained.
*/
int refuel( @Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int slot, int limit );
}
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Turtle|Event", apiVersion = "${version}" )
package dan200.computercraft.api.turtle.event;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. This API may be redistributed unmodified and in full only.
* Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
@API( owner = "ComputerCraft", provides = "ComputerCraft|API|Turtle", apiVersion = "${version}" )
package dan200.computercraft.api.turtle;

View File

@@ -0,0 +1,184 @@
/*
* 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.client;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.render.TurtleModelLoader;
import dan200.computercraft.shared.media.items.ItemDiskLegacy;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
import dan200.computercraft.shared.turtle.items.ItemTurtleBase;
import dan200.computercraft.shared.util.Colour;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ColorHandlerEvent;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import javax.annotation.Nonnull;
/**
* Registers textures and models for items.
*/
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
public final class ClientRegistry
{
private static final String[] EXTRA_MODELS = new String[] {
"turtle_modem_off_left",
"turtle_modem_on_left",
"turtle_modem_off_right",
"turtle_modem_on_right",
"turtle_crafting_table_left",
"turtle_crafting_table_right",
"advanced_turtle_modem_off_left",
"advanced_turtle_modem_on_left",
"advanced_turtle_modem_off_right",
"advanced_turtle_modem_on_right",
"turtle_speaker_upgrade_left",
"turtle_speaker_upgrade_right",
"turtle_white",
"turtle_elf_overlay",
};
private ClientRegistry() {}
@SubscribeEvent
public static void registerModels( ModelRegistryEvent event )
{
ModelLoaderRegistry.registerLoader( TurtleModelLoader.INSTANCE );
// Register item models
registerUniversalItemModel( ComputerCraft.Items.computer, "computer" );
registerItemModel( ComputerCraft.Items.commandComputer, 0, "command_computer" );
registerItemModel( ComputerCraft.Items.pocketComputer, 0, "pocket_computer" );
registerItemModel( ComputerCraft.Items.pocketComputer, 1, "advanced_pocket_computer" );
registerItemModel( ComputerCraft.Items.peripheral, 0, "peripheral" );
registerItemModel( ComputerCraft.Items.peripheral, 1, "wireless_modem" );
registerItemModel( ComputerCraft.Items.peripheral, 2, "monitor" );
registerItemModel( ComputerCraft.Items.peripheral, 3, "printer" );
registerItemModel( ComputerCraft.Items.peripheral, 4, "advanced_monitor" );
registerItemModel( ComputerCraft.Items.cable, 0, "cable" );
registerItemModel( ComputerCraft.Items.cable, 1, "wired_modem" );
registerItemModel( ComputerCraft.Items.advancedModem, 0, "advanced_modem" );
registerItemModel( ComputerCraft.Items.peripheral, 5, "speaker" );
registerItemModel( ComputerCraft.Items.wiredModemFull, 0, "wired_modem_full" );
registerUniversalItemModel( ComputerCraft.Items.disk, "disk" );
registerItemModel( ComputerCraft.Items.diskExpanded, 0, "disk_expanded" );
registerItemModel( ComputerCraft.Items.treasureDisk, 0, "treasure_disk" );
registerItemModel( ComputerCraft.Items.printout, 0, "printout" );
registerItemModel( ComputerCraft.Items.printout, 1, "pages" );
registerItemModel( ComputerCraft.Items.printout, 2, "book" );
registerUniversalItemModel( ComputerCraft.Items.turtle, "turtle" );
registerUniversalItemModel( ComputerCraft.Items.turtleExpanded, "turtle" );
registerUniversalItemModel( ComputerCraft.Items.turtleAdvanced, "turtle_advanced" );
}
@SubscribeEvent
public static void onTextureStitchEvent( TextureStitchEvent.Pre event )
{
// Load all textures for the extra models
TextureMap map = event.getMap();
for( String upgrade : EXTRA_MODELS )
{
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( "computercraft", "block/" + upgrade ) );
for( ResourceLocation texture : model.getTextures() ) map.registerSprite( texture );
}
}
@SubscribeEvent
public static void onModelBakeEvent( ModelBakeEvent event )
{
// Load all extra models
for( String model : EXTRA_MODELS ) loadBlockModel( event, model );
}
@SubscribeEvent
public static void onItemColours( ColorHandlerEvent.Item event )
{
event.getItemColors().registerItemColorHandler(
( stack, layer ) -> layer == 1 ? ((ItemDiskLegacy) stack.getItem()).getColour( stack ) : 0xFFFFFF,
ComputerCraft.Items.disk, ComputerCraft.Items.diskExpanded
);
event.getItemColors().registerItemColorHandler( ( stack, layer ) -> {
switch( layer )
{
case 0:
default:
return 0xFFFFFF;
case 1: // Frame colour
return ComputerCraft.Items.pocketComputer.getColour( stack );
case 2: // Light colour
{
int light = ItemPocketComputer.getLightState( stack );
return light == -1 ? Colour.Black.getHex() : light;
}
}
}, ComputerCraft.Items.pocketComputer );
// Setup turtle colours
event.getItemColors().registerItemColorHandler(
( stack, tintIndex ) -> tintIndex == 0 ? ((ItemTurtleBase) stack.getItem()).getColour( stack ) : 0xFFFFFF,
ComputerCraft.Blocks.turtle, ComputerCraft.Blocks.turtleExpanded, ComputerCraft.Blocks.turtleAdvanced
);
}
private static void registerItemModel( Item item, int damage, String name )
{
ResourceLocation location = new ResourceLocation( ComputerCraft.MOD_ID, name );
final ModelResourceLocation res = new ModelResourceLocation( location, "inventory" );
ModelBakery.registerItemVariants( item, location );
ModelLoader.setCustomModelResourceLocation( item, damage, res );
}
private static void registerUniversalItemModel( Item item, String mainModel )
{
ResourceLocation mainLocation = new ResourceLocation( ComputerCraft.MOD_ID, mainModel );
ModelBakery.registerItemVariants( item, mainLocation );
final ModelResourceLocation mainModelLocation = new ModelResourceLocation( mainLocation, "inventory" );
ModelLoader.setCustomMeshDefinition( item, new ItemMeshDefinition()
{
@Nonnull
@Override
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
{
return mainModelLocation;
}
} );
}
private static void loadBlockModel( ModelBakeEvent event, String name )
{
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( ComputerCraft.MOD_ID, "block/" + name ) );
IBakedModel bakedModel = model.bake(
model.getDefaultState(), DefaultVertexFormats.ITEM,
location -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( location.toString() )
);
event.getModelRegistry().putObject( new ModelResourceLocation( ComputerCraft.MOD_ID + ":" + name, "inventory" ), bakedModel );
}
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client;
import dan200.computercraft.shared.command.text.ChatHelpers;
@@ -13,12 +12,14 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiNewChat;
import net.minecraft.client.gui.GuiUtilRenderComponents;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextFormatting;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nullable;
import java.util.List;
public class ClientTableFormatter implements TableFormatter
{
@@ -26,7 +27,7 @@ public class ClientTableFormatter implements TableFormatter
private static Int2IntOpenHashMap lastHeights = new Int2IntOpenHashMap();
private FontRenderer renderer()
private static FontRenderer renderer()
{
return Minecraft.getMinecraft().fontRenderer;
}
@@ -62,7 +63,13 @@ public class ClientTableFormatter implements TableFormatter
@Override
public void writeLine( int id, ITextComponent component )
{
Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion( component, id );
Minecraft mc = Minecraft.getMinecraft();
GuiNewChat chat = mc.ingameGUI.getChatGUI();
// Trim the text if it goes over the allowed length
int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getChatScale() );
List<ITextComponent> list = GuiUtilRenderComponents.splitText( component, maxWidth, mc.fontRenderer, false, false );
if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id );
}
@Override

View File

@@ -1,48 +1,44 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client;
import dan200.computercraft.ComputerCraft;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.relauncher.Side;
public class FrameInfo
@Mod.EventBusSubscriber( modid = ComputerCraft.MOD_ID, value = Side.CLIENT )
public final class FrameInfo
{
private static final FrameInfo instance = new FrameInfo();
public static FrameInfo instance()
{
return instance;
}
private int tick;
private long renderFrame;
private static int tick;
private static long renderFrame;
private FrameInfo()
{
}
public boolean getGlobalCursorBlink()
public static boolean getGlobalCursorBlink()
{
return (tick / 8) % 2 == 0;
}
public long getRenderFrame()
public static long getRenderFrame()
{
return renderFrame;
}
@SubscribeEvent
public void onTick( TickEvent.ClientTickEvent event )
public static void onTick( TickEvent.ClientTickEvent event )
{
if( event.phase == TickEvent.Phase.START ) tick++;
}
@SubscribeEvent
public void onRenderTick( TickEvent.RenderTickEvent event )
public static void onRenderTick( TickEvent.RenderTickEvent event )
{
if( event.phase == TickEvent.Phase.START ) renderFrame++;
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import dan200.computercraft.core.terminal.TextBuffer;
@@ -19,7 +18,7 @@ import org.lwjgl.opengl.GL11;
import java.util.Arrays;
public class FixedWidthFontRenderer
public final class FixedWidthFontRenderer
{
private static final ResourceLocation FONT = new ResourceLocation( "computercraft", "textures/gui/term_font.png" );
public static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/term_background.png" );
@@ -93,7 +92,7 @@ public class FixedWidthFontRenderer
private boolean isGreyScale( int colour )
{
return (colour == 0 || colour == 15 || colour == 7 || colour == 8);
return colour == 0 || colour == 15 || colour == 7 || colour == 8;
}
public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import dan200.computercraft.ComputerCraft;
@@ -24,9 +23,10 @@ import java.io.IOException;
public class GuiComputer extends GuiContainer
{
private static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/corners.png" );
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( "computercraft", "textures/gui/corners_advanced.png" );
private static final ResourceLocation BACKGROUND_COMMAND = new ResourceLocation( "computercraft", "textures/gui/corners_command.png" );
public static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners.png" );
public static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_advanced.png" );
public static final ResourceLocation BACKGROUND_COMMAND = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_command.png" );
public static final ResourceLocation BACKGROUND_COLOUR = new ResourceLocation( ComputerCraft.MOD_ID, "textures/gui/corners_colour.png" );
private final ComputerFamily m_family;
private final ClientComputer m_computer;
@@ -80,12 +80,6 @@ public class GuiComputer extends GuiContainer
Keyboard.enableRepeatEvents( false );
}
@Override
public boolean doesGuiPauseGame()
{
return false;
}
@Override
public void updateScreen()
{
@@ -144,7 +138,7 @@ public class GuiComputer extends GuiContainer
}
@Override
public void drawScreen( int mouseX, int mouseY, float f )
public void drawScreen( int mouseX, int mouseY, float partialTicks )
{
// Work out where to draw
int startX = (width - m_terminal.getWidth()) / 2;
@@ -156,7 +150,7 @@ public class GuiComputer extends GuiContainer
drawDefaultBackground();
// Draw terminal
m_terminal.draw( this.mc, startX, startY, mouseX, mouseY );
m_terminal.draw( mc, startX, startY, mouseX, mouseY );
// Draw a border around the terminal
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
@@ -164,29 +158,23 @@ public class GuiComputer extends GuiContainer
{
case Normal:
default:
{
this.mc.getTextureManager().bindTexture( BACKGROUND );
mc.getTextureManager().bindTexture( BACKGROUND_NORMAL );
break;
}
case Advanced:
{
this.mc.getTextureManager().bindTexture( BACKGROUND_ADVANCED );
mc.getTextureManager().bindTexture( BACKGROUND_ADVANCED );
break;
}
case Command:
{
this.mc.getTextureManager().bindTexture( BACKGROUND_COMMAND );
mc.getTextureManager().bindTexture( BACKGROUND_COMMAND );
break;
}
}
drawTexturedModalRect( startX - 12, startY - 12, 12, 28, 12, 12 );
drawTexturedModalRect( startX - 12, endY, 12, 40, 12, 16 );
drawTexturedModalRect( startX - 12, endY, 12, 40, 12, 12 );
drawTexturedModalRect( endX, startY - 12, 24, 28, 12, 12 );
drawTexturedModalRect( endX, endY, 24, 40, 12, 16 );
drawTexturedModalRect( endX, endY, 24, 40, 12, 12 );
drawTexturedModalRect( startX, startY - 12, 0, 0, endX - startX, 12 );
drawTexturedModalRect( startX, endY, 0, 12, endX - startX, 16 );
drawTexturedModalRect( startX, endY, 0, 12, endX - startX, 12 );
drawTexturedModalRect( startX - 12, startY, 0, 28, 12, endY - startY );
drawTexturedModalRect( endX, startY, 36, 28, 12, endY - startY );

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import dan200.computercraft.ComputerCraft;
@@ -22,10 +21,8 @@ public class GuiConfigCC extends GuiConfig
super( parentScreen, Config.getConfigElements(), ComputerCraft.MOD_ID, false, false, "CC: Tweaked" );
}
public static class Factory
implements IModGuiFactory
public static class Factory implements IModGuiFactory
{
@Override
public void initialize( Minecraft minecraft )
{

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
@@ -25,21 +24,19 @@ public class GuiDiskDrive extends GuiContainer
}
@Override
protected void drawGuiContainerForegroundLayer( int par1, int par2 )
protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY )
{
String title = m_container.getDiskDrive().getDisplayName().getUnformattedText();
fontRenderer.drawString( title, (xSize - fontRenderer.getStringWidth( title )) / 2, 6, 0x404040 );
fontRenderer.drawString( I18n.format( "container.inventory" ), 8, (ySize - 96) + 2, 0x404040 );
fontRenderer.drawString( I18n.format( "container.inventory" ), 8, ySize - 96 + 2, 0x404040 );
}
@Override
protected void drawGuiContainerBackgroundLayer( float f, int i, int j )
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
{
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
this.mc.getTextureManager().bindTexture( BACKGROUND );
int l = (width - xSize) / 2;
int i1 = (height - ySize) / 2;
drawTexturedModalRect( l, i1, 0, 0, xSize, ySize );
mc.getTextureManager().bindTexture( BACKGROUND );
drawTexturedModalRect( guiLeft, guiTop, 0, 0, xSize, ySize );
}
@Override

View File

@@ -1,13 +1,13 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
public class GuiPocketComputer extends GuiComputer
{
@@ -16,7 +16,7 @@ public class GuiPocketComputer extends GuiComputer
super(
container,
ComputerCraft.Items.pocketComputer.getFamily( container.getStack() ),
ComputerCraft.Items.pocketComputer.createClientComputer( container.getStack() ),
ItemPocketComputer.createClientComputer( container.getStack() ),
ComputerCraft.terminalWidth_pocketComputer,
ComputerCraft.terminalHeight_pocketComputer
);

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import dan200.computercraft.shared.peripheral.printer.ContainerPrinter;
@@ -16,36 +15,30 @@ public class GuiPrinter extends GuiContainer
{
private static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/printer.png" );
private final ContainerPrinter m_container;
private final ContainerPrinter container;
public GuiPrinter( ContainerPrinter container )
{
super( container );
m_container = container;
this.container = container;
}
@Override
protected void drawGuiContainerForegroundLayer( int par1, int par2 )
protected void drawGuiContainerForegroundLayer( int mouseX, int mouseY )
{
String title = m_container.getPrinter().getDisplayName().getUnformattedText();
String title = container.getPrinter().getDisplayName().getUnformattedText();
fontRenderer.drawString( title, (xSize - fontRenderer.getStringWidth( title )) / 2, 6, 0x404040 );
fontRenderer.drawString( I18n.format( "container.inventory" ), 8, (ySize - 96) + 2, 0x404040 );
fontRenderer.drawString( I18n.format( "container.inventory" ), 8, ySize - 96 + 2, 0x404040 );
}
@Override
protected void drawGuiContainerBackgroundLayer( float f, int i, int j )
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
{
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
this.mc.getTextureManager().bindTexture( BACKGROUND );
int startX = (width - xSize) / 2;
int startY = (height - ySize) / 2;
drawTexturedModalRect( startX, startY, 0, 0, xSize, ySize );
mc.getTextureManager().bindTexture( BACKGROUND );
drawTexturedModalRect( guiLeft, guiTop, 0, 0, xSize, ySize );
boolean printing = m_container.isPrinting();
if( printing )
{
drawTexturedModalRect( startX + 34, startY + 21, 176, 0, 25, 45 );
}
if( container.isPrinting() ) drawTexturedModalRect( guiLeft + 34, guiTop + 21, 176, 0, 25, 45 );
}
@Override

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import dan200.computercraft.core.terminal.TextBuffer;
@@ -29,6 +28,8 @@ public class GuiPrintout extends GuiContainer
{
super( container );
ySize = Y_SIZE;
String[] text = ItemPrintout.getText( container.getStack() );
m_text = new TextBuffer[text.length];
for( int i = 0; i < m_text.length; i++ ) m_text[i] = new TextBuffer( text[i] );
@@ -42,12 +43,6 @@ public class GuiPrintout extends GuiContainer
m_book = ItemPrintout.getType( container.getStack() ) == ItemPrintout.Type.Book;
}
@Override
public boolean doesGuiPauseGame()
{
return false;
}
@Override
protected void keyTyped( char c, int k ) throws IOException
{
@@ -73,41 +68,35 @@ public class GuiPrintout extends GuiContainer
int mouseWheelChange = Mouse.getEventDWheel();
if( mouseWheelChange < 0 )
{
// Up
// Scroll up goes to the next page
if( m_page < m_pages - 1 ) m_page++;
}
else if( mouseWheelChange > 0 )
{
// Down
// Scroll down goes to the previous page
if( m_page > 0 ) m_page--;
}
}
@Override
protected void drawGuiContainerForegroundLayer( int par1, int par2 )
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
{
}
@Override
protected void drawGuiContainerBackgroundLayer( float var1, int var2, int var3 )
{
}
@Override
public void drawScreen( int mouseX, int mouseY, float f )
{
// Draw background
zLevel = zLevel - 1;
drawDefaultBackground();
zLevel = zLevel + 1;
// Draw the printout
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
int startY = (height - Y_SIZE) / 2;
int startX = (width - X_SIZE) / 2;
drawBorder( guiLeft, guiTop, zLevel, m_page, m_pages, m_book );
drawText( guiLeft + X_TEXT_MARGIN, guiTop + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
}
drawBorder( startX, startY, zLevel, m_page, m_pages, m_book );
drawText( startX + X_TEXT_MARGIN, startY + Y_TEXT_MARGIN, ItemPrintout.LINES_PER_PAGE * m_page, m_text, m_colours );
@Override
public void drawScreen( int mouseX, int mouseY, float partialTicks )
{
// We must take the background further back in order to not overlap with our printed pages.
zLevel--;
drawDefaultBackground();
zLevel++;
super.drawScreen( mouseX, mouseY, partialTicks );
renderHoveredToolTip( mouseX, mouseY );
}
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui;
import dan200.computercraft.ComputerCraft;
@@ -23,7 +22,7 @@ import java.io.IOException;
public class GuiTurtle extends GuiContainer
{
private static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/turtle.png" );
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation( "computercraft", "textures/gui/turtle.png" );
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation( "computercraft", "textures/gui/turtle_advanced.png" );
private ContainerTurtle m_container;
@@ -50,8 +49,8 @@ public class GuiTurtle extends GuiContainer
super.initGui();
Keyboard.enableRepeatEvents( true );
m_terminalGui = new WidgetTerminal(
(width - xSize) / 2 + 8,
(height - ySize) / 2 + 8,
guiLeft + 8,
guiTop + 8,
ComputerCraft.terminalWidth_turtle,
ComputerCraft.terminalHeight_turtle,
() -> m_computer,
@@ -98,8 +97,8 @@ public class GuiTurtle extends GuiContainer
public void handleMouseInput() throws IOException
{
super.handleMouseInput();
int x = Mouse.getEventX() * this.width / mc.displayWidth;
int y = this.height - Mouse.getEventY() * this.height / mc.displayHeight - 1;
int x = Mouse.getEventX() * width / mc.displayWidth;
int y = height - Mouse.getEventY() * height / mc.displayHeight - 1;
m_terminalGui.handleMouseInput( x, y );
}
@@ -112,34 +111,29 @@ public class GuiTurtle extends GuiContainer
protected void drawSelectionSlot( boolean advanced )
{
int x = (width - xSize) / 2;
int y = (height - ySize) / 2;
// Draw selection slot
int slot = m_container.getSelectedSlot();
if( slot >= 0 )
{
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
int slotX = (slot % 4);
int slotY = (slot / 4);
this.mc.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND );
drawTexturedModalRect( x + m_container.m_turtleInvStartX - 2 + slotX * 18, y + m_container.m_playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24 );
int slotX = slot % 4;
int slotY = slot / 4;
mc.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
drawTexturedModalRect( guiLeft + m_container.turtleInvStartX - 2 + slotX * 18, guiTop + m_container.playerInvStartY - 2 + slotY * 18, 0, 217, 24, 24 );
}
}
@Override
protected void drawGuiContainerBackgroundLayer( float f, int mouseX, int mouseY )
protected void drawGuiContainerBackgroundLayer( float partialTicks, int mouseX, int mouseY )
{
// Draw term
boolean advanced = (m_family == ComputerFamily.Advanced);
boolean advanced = m_family == ComputerFamily.Advanced;
m_terminalGui.draw( Minecraft.getMinecraft(), 0, 0, mouseX, mouseY );
// Draw border/inventory
GlStateManager.color( 1.0F, 1.0F, 1.0F, 1.0F );
this.mc.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND );
int x = (width - xSize) / 2;
int y = (height - ySize) / 2;
drawTexturedModalRect( x, y, 0, 0, xSize, ySize );
mc.getTextureManager().bindTexture( advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
drawTexturedModalRect( guiLeft, guiTop, 0, 0, xSize, ySize );
drawSelectionSlot( advanced );
}

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui.widgets;
import net.minecraft.client.Minecraft;

View File

@@ -1,9 +1,8 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Copyright Daniel Ratcliffe, 2011-2020. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.gui.widgets;
import dan200.computercraft.client.FrameInfo;
@@ -31,23 +30,23 @@ public class WidgetTerminal extends Widget
private final IComputerContainer m_computer;
private float m_terminateTimer;
private float m_rebootTimer;
private float m_shutdownTimer;
private float m_terminateTimer = 0.0f;
private float m_rebootTimer = 0.0f;
private float m_shutdownTimer = 0.0f;
private int m_lastClickButton;
private int m_lastClickX;
private int m_lastClickY;
private int m_lastClickButton = -1;
private int m_lastClickX = -1;
private int m_lastClickY = -1;
private boolean m_focus;
private boolean m_allowFocusLoss;
private boolean m_focus = false;
private boolean m_allowFocusLoss = true;
private int m_leftMargin;
private int m_rightMargin;
private int m_topMargin;
private int m_bottomMargin;
private ArrayList<Integer> m_keysDown;
private final ArrayList<Integer> m_keysDown = new ArrayList<>();
public WidgetTerminal( int x, int y, int termWidth, int termHeight, IComputerContainer computer, int leftMargin, int rightMargin, int topMargin, int bottomMargin )
{
@@ -58,23 +57,11 @@ public class WidgetTerminal extends Widget
);
m_computer = computer;
m_terminateTimer = 0.0f;
m_rebootTimer = 0.0f;
m_shutdownTimer = 0.0f;
m_lastClickButton = -1;
m_lastClickX = -1;
m_lastClickY = -1;
m_focus = false;
m_allowFocusLoss = true;
m_leftMargin = leftMargin;
m_rightMargin = rightMargin;
m_topMargin = topMargin;
m_bottomMargin = bottomMargin;
m_keysDown = new ArrayList<>();
}
public void setAllowFocusLoss( boolean allowFocusLoss )
@@ -94,9 +81,9 @@ public class WidgetTerminal extends Widget
String clipboard = GuiScreen.getClipboardString();
if( clipboard != null )
{
// Clip to the first occurance of \r or \n
int newLineIndex1 = clipboard.indexOf( "\r" );
int newLineIndex2 = clipboard.indexOf( "\n" );
// Clip to the first occurrence of \r or \n
int newLineIndex1 = clipboard.indexOf( '\r' );
int newLineIndex2 = clipboard.indexOf( '\n' );
if( newLineIndex1 >= 0 && newLineIndex2 >= 0 )
{
clipboard = clipboard.substring( 0, Math.min( newLineIndex1, newLineIndex2 ) );
@@ -122,9 +109,7 @@ public class WidgetTerminal extends Widget
}
// Queue the "paste" event
queueEvent( "paste", new Object[] {
clipboard
} );
queueEvent( "paste", new Object[] { clipboard } );
}
}
return true;
@@ -143,18 +128,15 @@ public class WidgetTerminal extends Widget
}
// Queue the "key" event
queueEvent( "key", new Object[] {
key, repeat
} );
IComputer computer = m_computer.getComputer();
if( computer != null ) computer.keyDown( key, repeat );
handled = true;
}
if( (ch >= 32 && ch <= 126) || (ch >= 160 && ch <= 255) ) // printable chars in byte range
{
// Queue the "char" event
queueEvent( "char", new Object[] {
Character.toString( ch )
} );
queueEvent( "char", new Object[] { Character.toString( ch ) } );
handled = true;
}
@@ -189,9 +171,7 @@ public class WidgetTerminal extends Widget
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
computer.queueEvent( "mouse_click", new Object[] {
button + 1, charX + 1, charY + 1
} );
computer.mouseClick( button + 1, charX + 1, charY + 1 );
m_lastClickButton = button;
m_lastClickX = charX;
@@ -222,9 +202,8 @@ public class WidgetTerminal extends Widget
if( m_focus )
{
// Queue the "key_up" event
queueEvent( "key_up", new Object[] {
key
} );
IComputer computer = m_computer.getComputer();
if( computer != null ) computer.keyUp( key );
handled = true;
}
}
@@ -251,12 +230,7 @@ public class WidgetTerminal extends Widget
if( m_lastClickButton >= 0 && !Mouse.isButtonDown( m_lastClickButton ) )
{
if( m_focus )
{
computer.queueEvent( "mouse_up", new Object[] {
m_lastClickButton + 1, charX + 1, charY + 1
} );
}
if( m_focus ) computer.mouseUp( m_lastClickButton + 1, charX + 1, charY + 1 );
m_lastClickButton = -1;
}
@@ -270,22 +244,16 @@ public class WidgetTerminal extends Widget
{
if( wheelChange < 0 )
{
computer.queueEvent( "mouse_scroll", new Object[] {
1, charX + 1, charY + 1
} );
computer.mouseScroll( 1, charX + 1, charY + 1 );
}
else if( wheelChange > 0 )
{
computer.queueEvent( "mouse_scroll", new Object[] {
-1, charX + 1, charY + 1
} );
computer.mouseScroll( -1, charX + 1, charY + 1 );
}
if( m_lastClickButton >= 0 && (charX != m_lastClickX || charY != m_lastClickY) )
{
computer.queueEvent( "mouse_drag", new Object[] {
m_lastClickButton + 1, charX + 1, charY + 1
} );
computer.mouseDrag( m_lastClickButton + 1, charX + 1, charY + 1 );
m_lastClickX = charX;
m_lastClickY = charY;
}
@@ -305,11 +273,8 @@ public class WidgetTerminal extends Widget
{
if( m_terminateTimer < TERMINATE_TIME )
{
m_terminateTimer = m_terminateTimer + 0.05f;
if( m_terminateTimer >= TERMINATE_TIME )
{
queueEvent( "terminate" );
}
m_terminateTimer += 0.05f;
if( m_terminateTimer >= TERMINATE_TIME ) queueEvent( "terminate" );
}
}
else
@@ -322,14 +287,11 @@ public class WidgetTerminal extends Widget
{
if( m_rebootTimer < TERMINATE_TIME )
{
m_rebootTimer = m_rebootTimer + 0.05f;
m_rebootTimer += 0.05f;
if( m_rebootTimer >= TERMINATE_TIME )
{
IComputer computer = m_computer.getComputer();
if( computer != null )
{
computer.reboot();
}
if( computer != null ) computer.reboot();
}
}
}
@@ -343,14 +305,11 @@ public class WidgetTerminal extends Widget
{
if( m_shutdownTimer < TERMINATE_TIME )
{
m_shutdownTimer = m_shutdownTimer + 0.05f;
m_shutdownTimer += 0.05f;
if( m_shutdownTimer >= TERMINATE_TIME )
{
IComputer computer = m_computer.getComputer();
if( computer != null )
{
computer.shutdown();
}
if( computer != null ) computer.shutdown();
}
}
}
@@ -377,7 +336,7 @@ public class WidgetTerminal extends Widget
{
// Draw the screen contents
IComputer computer = m_computer.getComputer();
Terminal terminal = (computer != null) ? computer.getTerminal() : null;
Terminal terminal = computer != null ? computer.getTerminal() : null;
if( terminal != null )
{
// Draw the terminal
@@ -388,7 +347,7 @@ public class WidgetTerminal extends Widget
// Get the data from the terminal first
// Unfortunately we have to keep the lock for the whole of drawing, so the text doesn't change under us.
FixedWidthFontRenderer fontRenderer = FixedWidthFontRenderer.instance();
boolean tblink = m_focus && terminal.getCursorBlink() && FrameInfo.instance().getGlobalCursorBlink();
boolean tblink = m_focus && terminal.getCursorBlink() && FrameInfo.getGlobalCursorBlink();
int tw = terminal.getWidth();
int th = terminal.getHeight();
int tx = terminal.getCursorX();
@@ -455,18 +414,12 @@ public class WidgetTerminal extends Widget
private void queueEvent( String event )
{
IComputer computer = m_computer.getComputer();
if( computer != null )
{
computer.queueEvent( event );
}
if( computer != null ) computer.queueEvent( event );
}
private void queueEvent( String event, Object[] args )
{
IComputer computer = m_computer.getComputer();
if( computer != null )
{
computer.queueEvent( event, args );
}
if( computer != null ) computer.queueEvent( event, args );
}
}

View File

@@ -1,214 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.client.proxy;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.render.TileEntityTurtleRenderer;
import dan200.computercraft.client.render.TurtleSmartItemModel;
import dan200.computercraft.shared.proxy.CCTurtleProxyCommon;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.items.ItemTurtleBase;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.color.IItemColor;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.SimpleReloadableResourceManager;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nonnull;
public class CCTurtleProxyClient extends CCTurtleProxyCommon
{
// IComputerCraftProxy implementation
@Override
public void preInit()
{
super.preInit();
// Setup client forge handlers
registerForgeHandlers();
}
@SubscribeEvent
public void registerModels( ModelRegistryEvent event )
{
// Register item models
ItemMeshDefinition turtleMeshDefinition = new ItemMeshDefinition()
{
private ModelResourceLocation turtle_dynamic = new ModelResourceLocation( "computercraft:turtle_dynamic", "inventory" );
@Nonnull
@Override
public ModelResourceLocation getModelLocation( @Nonnull ItemStack stack )
{
return turtle_dynamic;
}
};
String[] turtleModelNames = new String[] {
"turtle_dynamic",
"turtle", "turtle_advanced",
"turtle_white",
"turtle_elf_overlay"
};
registerItemModel( ComputerCraft.Blocks.turtle, turtleMeshDefinition, turtleModelNames );
registerItemModel( ComputerCraft.Blocks.turtleExpanded, turtleMeshDefinition, turtleModelNames );
registerItemModel( ComputerCraft.Blocks.turtleAdvanced, turtleMeshDefinition, turtleModelNames );
}
@Override
public void init()
{
super.init();
// Setup turtle colours
Minecraft.getMinecraft().getItemColors().registerItemColorHandler(
new TurtleItemColour(),
ComputerCraft.Blocks.turtle, ComputerCraft.Blocks.turtleExpanded, ComputerCraft.Blocks.turtleAdvanced
);
// Setup renderers
ClientRegistry.bindTileEntitySpecialRenderer( TileTurtle.class, new TileEntityTurtleRenderer() );
}
private void registerItemModel( Block block, ItemMeshDefinition definition, String[] names )
{
registerItemModel( Item.getItemFromBlock( block ), definition, names );
}
private void registerItemModel( Item item, ItemMeshDefinition definition, String[] names )
{
ResourceLocation[] resources = new ResourceLocation[names.length];
for( int i = 0; i < names.length; i++ )
{
resources[i] = new ResourceLocation( "computercraft:" + names[i] );
}
ModelBakery.registerItemVariants( item, resources );
ModelLoader.setCustomMeshDefinition( item, definition );
}
private void registerForgeHandlers()
{
ForgeHandlers handlers = new ForgeHandlers();
MinecraftForge.EVENT_BUS.register( handlers );
}
public static class ForgeHandlers
{
private static final String[] TURTLE_UPGRADES = {
"turtle_modem_off_left",
"turtle_modem_on_left",
"turtle_modem_off_right",
"turtle_modem_on_right",
"turtle_crafting_table_left",
"turtle_crafting_table_right",
"advanced_turtle_modem_off_left",
"advanced_turtle_modem_on_left",
"advanced_turtle_modem_off_right",
"advanced_turtle_modem_on_right",
"turtle_speaker_upgrade_left",
"turtle_speaker_upgrade_right",
};
private TurtleSmartItemModel m_turtleSmartItemModel;
public ForgeHandlers()
{
m_turtleSmartItemModel = new TurtleSmartItemModel();
IResourceManager resourceManager = Minecraft.getMinecraft().getResourceManager();
if( resourceManager instanceof SimpleReloadableResourceManager )
{
SimpleReloadableResourceManager reloadableResourceManager = (SimpleReloadableResourceManager) resourceManager;
reloadableResourceManager.registerReloadListener( m_turtleSmartItemModel );
}
}
@SubscribeEvent
public void onTextureStitchEvent( TextureStitchEvent.Pre event )
{
// Load all textures for upgrades
TextureMap map = event.getMap();
for( String upgrade : TURTLE_UPGRADES )
{
IModel model = ModelLoaderRegistry.getModelOrMissing( new ResourceLocation( "computercraft", "block/" + upgrade ) );
for( ResourceLocation texture : model.getTextures() )
{
map.registerSprite( texture );
}
}
}
@SubscribeEvent
public void onModelBakeEvent( ModelBakeEvent event )
{
// Load all upgrade models
for( String upgrade : TURTLE_UPGRADES )
{
loadModel( event, upgrade );
}
loadSmartModel( event, "turtle_dynamic", m_turtleSmartItemModel );
}
private void loadModel( ModelBakeEvent event, String name )
{
IModel model = ModelLoaderRegistry.getModelOrMissing(
new ResourceLocation( "computercraft", "block/" + name )
);
IBakedModel bakedModel = model.bake(
model.getDefaultState(),
DefaultVertexFormats.ITEM,
location -> Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( location.toString() )
);
event.getModelRegistry().putObject(
new ModelResourceLocation( "computercraft:" + name, "inventory" ),
bakedModel
);
}
private void loadSmartModel( ModelBakeEvent event, String name, IBakedModel smartModel )
{
event.getModelRegistry().putObject(
new ModelResourceLocation( "computercraft:" + name, "inventory" ),
smartModel
);
}
}
private static class TurtleItemColour implements IItemColor
{
@Override
public int colorMultiplier( @Nonnull ItemStack stack, int tintIndex )
{
if( tintIndex == 0 )
{
ItemTurtleBase turtle = (ItemTurtleBase) stack.getItem();
int colour = turtle.getColour( stack );
if( colour != -1 ) return colour;
}
return 0xFFFFFF;
}
}
}

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