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

Compare commits

..

747 Commits

Author SHA1 Message Date
Jonathan Coates
e81a2c72ce Merge branch 'mc-1.21.x' into mc-1.21.y 2025-07-12 21:46:28 +01:00
Jonathan Coates
01de6110c6 Re-enable JEI integration 2025-07-12 21:41:50 +01:00
Jonathan Coates
9cf0f85fcb Merge branch 'mc-1.20.x' into mc-1.21.x 2025-07-12 19:00:00 +01:00
Jonathan Coates
018ce7c8a5 Bump CC:T to 1.116.1 2025-07-12 18:57:05 +01:00
Jonathan Coates
44726827b4 Sync translations from Crowdin 2025-07-12 09:49:14 +01:00
Jonathan Coates
2bf0aba455 Don't use SpeakerPosition to get speaker's level
We use getLevel() specifically for reading the current registries
(and/or server). We don't need the exact position of the speaker to
query this, so add a dedicated method for it.

We actually had a similar method on 1.21.7 already for upgrades. This
just moves it to SpeakerPeripheral.

Fixes #2236.
2025-07-10 01:07:51 +01:00
Jonathan Coates
3cf914cb4c Fix NPE when loading mcfunctions
CommandSourceStack.getServer can be null, despite being marked as
non-nullable. Mojang!!! *shakes fist*

Fixes #2235.
2025-07-10 00:47:42 +01:00
Jonathan Coates
4868c4aa32 Small bits of cleanup
- Remove unused MonitorRenderer. I'm sure this had been deleted
   already, but apparently not!
 - Add missing items to the changelog.
 - Fix crash when clearing tests in a world.
 - Bump Iris deps, to help with debugging #2229.
2025-07-10 00:29:06 +01:00
Batári Balázs László
180156ff1c Add lang hu_hu (#2232) 2025-07-06 21:47:22 +00:00
Jonathan Coates
c6ba753568 Update allowed Minecraft versions 2025-07-06 22:34:43 +01:00
Jonathan Coates
9f45c91925 Update to latest TeaVM 2025-07-02 09:21:43 +01:00
Jonathan Coates
67412a2b72 Update to Minecraft 1.21.7 2025-06-30 22:55:55 +01:00
Jonathan Coates
5fa724ed24 Move Create integration setup to its proper place
Merge conflict gone wrong, I assume.
2025-06-30 22:53:15 +01:00
Jonathan Coates
76869593f0 Merge branch 'mc-1.21.x' into mc-1.21.y 2025-06-28 11:31:32 +01:00
Jonathan Coates
fbf994e803 Merge branch 'mc-1.20.x' into mc-1.21.x 2025-06-28 11:21:22 +01:00
Jonathan Coates
8344c0a5c2 Bump CC:T to 1.116.0 2025-06-28 11:03:52 +01:00
Jonathan Coates
a292d33830 Syntax highlighting for multiline tokens in edit
I don't love the implementation of this (see discussion in #2220), but
it's better than nothing. Wow, the editor really needs a bit of a
rewrite, the code is kinda messy.

Fixes #1396.
2025-06-25 22:50:23 +01:00
Jonathan Coates
341d1c7bc2 Move paint/edit menu bar into common module
I want to add a menu bar to the edit runner too, so let's make this code
a little more reusable first.
2025-06-25 22:14:09 +01:00
Jonathan Coates
846f9dff03 Update to latest NeoForge
Welllll, latest when I wrote the code, not at actual time of writing.
2025-06-24 22:59:44 +01:00
Jonathan Coates
64d10ad45b Data fixers for turtle owners 2025-06-24 22:58:04 +01:00
Jonathan Coates
531eacfac7 Merge pull request #2224 from matematikaadit/patch-1
Miniscule typo fix in the shell.path() doc comment
2025-06-21 16:59:01 +01:00
Adit Cahya Ramadhan
1f3da5205c Miniscule typo fix in the shell.path() doc comment
Noticed this when reading the shell API page in the wiki.
2025-06-21 22:29:04 +07:00
Jonathan Coates
e3fecb013a Update to Minecraft 1.26.1
Still one TODO left, but around data fixers, so fairly small.

 - GUI rendering got a big overhaul. I avoided the worst of it with
   9272e2efcd, but things like terminals
   and printouts still require some custom rendering.

 - Item models are now de-duplicated when rendering in the UI, so we
   need to keep track of their identity with
   (appendModelidentityElement). I'm not sure I've got this entirely
   right — whole thing feels unfortunately error-prone.

 - BE serialisation now goes through a Value{Input,Output} class, rather
   than using NBT directly. Fairly simple change, but has changed the
   format of the GameProfile used in turtle's owners. Need a DFU patch
   for this.
2025-06-18 21:19:04 +01:00
Jonathan Coates
798ceefafe Add test for crafting of disks
See #2221.
2025-06-18 21:00:32 +01:00
Jonathan Coates
7c0f79fc3c Move edit_runner into its own module
I've a few more features I'd like to add to it. Moving it out makes it
slightly easier to maintain.
2025-06-17 17:55:24 +01:00
Jonathan Coates
b35cefc5dd Switch from path to parentPath
I've been putting this off for a while, as I had issues in the past with
people using old Node versions (e.g. #1806), but it no long works on my
machine, so time to make the switch.

Also do a bit of a package update. Hit a rollup bug while doing this
(https://github.com/rollup/plugins/issues/1877), so holding that update
back for now.
2025-06-17 17:46:10 +01:00
Jonathan Coates
ec3dd328b3 Construct ByteBuffer manually in monitor renderer
In the 1.21.4 update (9277aa33e9), we
removed our DirectVertexBuffer class, and switched to vanilla's
VertexBuffer. This forced us to use MeshData and thus
ByteBufferBuilder instead of allocating the ByteBuffer ourselves.

One thing I'd missed with this is that Iris's text vertex sink API
requires us to allocate the whole buffer up-front and so the resulting
buffer has a limit of the *maximum* number of vertices rendered, not the
actual one.

This wasn't an issue on 1.21.4, as we didn't check this (I guess we just
silently rendered junk??), but for the 1.21.5 update
(a1df196673) we added some extra
assertions here, which now fail on Iris.

Typically, the whole original change was is now entirely redundant, as
Vanilla has removed VertexBuffer entirely, and so we can/should work in
terms of raw ByteBuffers again.

Fixes #2219.
2025-06-15 18:04:52 +01:00
Jonathan Coates
f3f43191ab Merge branch 'mc-1.21.x' into mc-1.21.y 2025-06-15 16:59:48 +01:00
Jonathan Coates
89dd521930 Merge branch 'mc-1.20.x' into mc-1.21.x 2025-06-15 16:31:51 +01:00
Jonathan Coates
9272e2efcd Use vanilla's nine-slice sprites for border rendering
- Move remaining sprites to the vanilla GUI atlas.

 - Convert our computer border/sidebar sprites to use vanilla's
   nine-sliced mcmeta files. I thought I'd have to do something custom
   here for the sidebar, as that has no right border, but vanilla
   supports that natively!

 - Use the normal GuiGraphics.blitSprite for rendering computer
   border/sidebar.

 - Obey nine-slice scaling within the pocket computer renderer.
2025-06-15 16:25:54 +01:00
Jonathan Coates
69353a4fcf Use lexer for edit's syntax highlighting
This is slightly more accurate for long strings and comments. Note that
we still work a line at a time (and in a non-incremental manner), so
doesn't actaully support multi-line strings (#1396).

We do now treat goto as a keyword (fixes #1653). We don't currently
support labels — those *technically* aren't a token (`:: foo --[[ a
comment ]] ::` is a valid label!), but maybe we could special-case the
short `::foo::` form.
2025-06-15 13:25:21 +01:00
Jonathan Coates
ff363dca5a Move sidebar_advanced.png down by one pixel
Apparently this has been broken since the file was created in
53546b9f57d9acaa4cdca14ae00eaf68ce8c50bd!? I'm sure I fixed this before,
but maybe that was a different but similar issue >_>.
2025-06-14 18:44:16 +01:00
LorneHyde
1c51282426 Fix syntax highlighting for strings ending in an escaped backslash (#2194) 2025-06-08 19:55:14 +00:00
Jonathan Coates
4a3a1c9275 Merge pull request #2214 from Wojbie/patch-1
Update motd path in startup.lua
2025-06-03 08:08:30 +01:00
Wojbie
2557dd0af9 Update motd path in startup.lua
Removes situations where shell resolution caused arbitrary program called `motd` at root get executed instead of expected /rom one.
2025-06-03 01:03:02 +02:00
Jonathan Coates
b5c0c6e104 Fix out-of-bounds when pasting too-long text
Used a `<=` instead of a `<`! How did I mess this up!?

Fixes #2209
2025-06-02 08:58:43 +01:00
SpartanSoftware
876fd8ddb8 Fix 0 being treated as a valid colour (#2211) 2025-05-31 07:46:03 +00:00
Jonathan Coates
ee3b1343b5 Handle keyboard layouts for our computer shortcuts
Convert GLFW's key codes back to their actual key, and then use that
when checking keyboard shortcuts. We *don't* do this for the paste key,
just to be consistent with vanilla's behaviour.

Fixes #2207.
2025-05-25 22:32:39 +01:00
JackMacWindows
b440b964b7 Add notes about minor changed file handle behavior in 1.109.0 (#2203) 2025-05-25 20:24:26 +00:00
Jonathan Coates
5dfc401b45 Update build plugin versions 2025-05-18 10:05:27 +01:00
Jonathan Coates
0790a8346a Merge branch 'mc-1.21.x' into mc-1.21.y 2025-05-16 18:38:21 +01:00
Jonathan Coates
418c9be7ac Allow changing terminal size with components
We add a new computercraft:term_size component that allows changing the
terminal size of computers and pocket computers.
2025-05-16 18:22:20 +01:00
Jonathan Coates
b491f6b11f Merge branch 'mc-1.20.x' into mc-1.21.x 2025-05-16 17:56:51 +01:00
Jonathan Coates
acafc06449 Make turtle upgrade models data driven
It's ItemModel, but for upgrades!
2025-05-11 09:17:54 +01:00
Jonathan Coates
598fd98a8b Load turtle overlays during model loading
Back in f10e401aea, we changed turtle
overlays to be loaded as a dynamic registry. This solved some of the
problems we had with upgrades (elf-compatibility), and seemed like a
good idea at the time.

However, because overlays are part of datapacks (not resource packs), we
also needed support for loading overlay models, which we did via an
"extra_models.json" file.

With the ItemModel changes, we can go for a different approach:
 - Turtle overlays are now stored on the item/BE as a simple
   ResourceLocation again.

 - The TurtleOverlay class is moved to the client, and loaded from
   resource packs, during model loading. They're now split into a baked
   form (holding a StandaloneModel) and an unbaked one (holding the
   ResourceLocation).

 - extra_model.json is no longer supported.
2025-05-10 23:30:39 +01:00
Jonathan Coates
e13e8ff92e Fix a couple of rendering issues
- Fix printouts in item frames being rendered too far foward.
 - Fix wired modems being flipped.
2025-05-10 17:52:12 +01:00
Jonathan Coates
0a0c80db41 Allow equipping pocket computers on the bottom
This allows equipping pocket computers on both the back (as before) and
bottom of a pocket computer. The asymmetry is a little unfortunate here,
but makes some sense with the crafting recipe (above goes behind, below
goes on the bottom).

 - Move some functionality from IPocketAccess into a PocketComputer
   interface (and PocketComputerInternal) interface, used by the pocket
   API.

   IPocketAccess preserves the same interface as before. Unlike
   ITurtleAccess, we /don't/ expose the PocketSide in the public API.

 - Several pocket-computer methods (e.g. setUpgradeData, setColour) are
   now required to be called on the main thread, and when the computer
   is being held. This allows us to write back changes to the item
   immediately, rather than the next time the item is ticked.

   Sadly this doesn't actually remove the need for onCraftedPostProcess
   as I'd originally hoped, but I think does make the code a little
   simpler.

 - Rename "computercraft:pocket_computer" component to
   "computercraft:back_pocket_computer".

 - And finally, support multiple upgrades on the pocket computer. This
   is actually quite an easy change, just tedious — there's lots of
   places to update!

Fixes #1406, and I think fixes #1148 — you can use a speaker to notify
you now.
2025-05-10 17:15:41 +01:00
Jonathan Coates
4344c3072f Add a test for turtle upgrade crafting
Every few years I get confused about which side turtle upgrades go on
when crafting. The fact that it's flipped always throws me! Let's add a
comment to the recipe, and add some tests to reassure myself.
2025-05-10 14:39:51 +01:00
Jonathan Coates
c20336286b Update to FAPI 0.122
- Use new tooltip component registry. This means we can move the
   tooltip appending magic to Neo only.

 - Use new chunk level change event. I'm not actually sure if we need
   this on recent versions (I can't reproduce the monitor update bug
   that we introduced this to fix), but I've no clue what's changed here.
2025-05-02 19:01:26 +01:00
Jonathan Coates
356366ede8 Undo dev changed to build script 2025-04-30 22:33:22 +01:00
Jonathan Coates
a1df196673 Update to Minecraft 1.21.5
0/10, would not recommend. Though increasingly feeling that about
modding as a whole — really not feeling as emotionally rewarding as it
once did.

Server-side changes are well, not simple, but relatively straightforward:

 - Block removal code is now called before the BE is removed, not after.

   - Monitors now need to track if they've being removed or not again.

   - Turtle drop consuming code no longer tries to insert items into
     the turtle immediately, instead waiting 'til the action is
     complete. Otherwise if the turtle gets destroyed mid-action
     (e.g. the block explodes), then it tries to insert its drops into
     itself!

     We previously guarded against this by checking if the turtle BE had
     been removed, but obviously this no longer works, so just easier to
     shift the insertion.

  - The interface for reading/writing NBT has been overhauled. It has
    native "getOr" and codec support (nice!) but also has been changed
    again in the latest snapshot (less nice!).

 - The dye item component no longer has a "hide tooltip" flag. We now
   hide the tooltip with a default component instead.

 - Related to the above, we can now do all the tooltip-related things we
   needed to do with vanilla's TooltipProvider. This did require
   splitting NonNegativeId into subclasses for disk/computer, but
   otherwise is quite nice.

 - Some changes to model datagen. Annoying, but boring.

 - Game tests got a complete overhaul. I'm keeping the interface the
   same for now (@GameTest), because I'm blowed if I'm datagenning test
   instances :p. If it's any consolation, both NF and Fabric are doing
   this too.

Client changes are a bit more involved though:

 - VertexBuffer has been entirely removed. We now construct the
   GpuBuffer directly.

 - BakedModel is gone! Oh this caused so much suffering for turtle
   models. I ended up rewriting the whole system in processes (which
   then involved PRs to NF and Fabric). Rather than returning a
   TransformedModel, turtle models are now responsible for rendering the
   model.

   This may see another rewrite in the future. I'd like to switch to
   JSON-based turtle models (like item models), but that's blocked on
   some changes to NF right now.

   Sorry to all add-on devs, I know this is a big change.
2025-04-30 22:31:30 +01:00
Jonathan Coates
947001104d Update Cobalt to 0.9.6
- Allow heterogenous __lt/__le.
2025-04-21 14:36:44 +01:00
Jonathan Coates
8711512769 Remove allocation tracking for computers
Reverts 76968f2f28. We'd originally added
this to gather some numbers for #1580, with the hope that it would also
be useful for server admins. Sadly, it's not as accurate as I originally
hoped — the number sometimes goes down for unclear reasons (something to
do with the TLAB maybe??).

Closes #1739.
2025-04-21 08:32:03 +01:00
Jonathan Coates
a939ad8b97 Merge branch 'mc-1.21.x' into mc-1.21.y 2025-03-25 08:45:03 +00:00
Jonathan Coates
fdae94b3c1 Merge branch 'mc-1.20.x' into mc-1.21.x 2025-03-25 08:44:27 +00:00
Jonathan Coates
9c0ce27ce6 Switch a few more places to use Java 17 features
New ErrorProne hint, and one which is actually pretty useful!
2025-03-22 09:39:47 +00:00
Jonathan Coates
c458360b18 Bump versions of build tooling
The main thing of note is Spotless, which also bumps the version of
Ktlint. I've been putting this off for a while[^1], as this changed a
bunch of formatting, and Spotless's (broken) caching was making it hard
to test. Ended up downloading ktlint and running it localy.

[^1]: 8204944b5f
2025-03-21 14:28:31 +00:00
Jonathan Coates
09ad6c1905 Add tags for disks and floppies
Fixes #2158
2025-03-20 19:16:16 +00:00
Jonathan Coates
0e1e8a72d3 Fix syncing of colour between PocketBrain and item
- Actually set colour when constructing the brain.
 - Sync it back after crafting, much like we do for upgrades (see
   dcc74e15c7) for more details.

We should take a proper look at this on 1.21.4 and make these methods
main-thread only, so we can sync immediately.

Fixes #2157
2025-03-20 18:54:06 +00:00
Jonathan Coates
995a6e7379 Merge branch 'mc-1.21.x' into mc-1.21.y 2025-03-18 09:29:35 +00:00
Jonathan Coates
ffa6eadc26 Register our BEs as entities
Fixes #2141. Hah, I wrote some tests for this in
b03546a158, but they pass because hoppers
still support vanilla inventories, but turtles don't.

Wish NeoForge registered a fallback for any inventory, like Fabric does,
but there we go.
2025-03-16 16:37:29 +00:00
Jonathan Coates
7c1e8e1951 Fix usages of javax's Nullable annotation 2025-03-16 16:29:19 +00:00
Jonathan Coates
b805a34c2d Merge branch 'mc-1.20.x' into mc-1.21.x 2025-03-16 16:28:53 +00:00
Jonathan Coates
b03546a158 Add game tests to check our blocks are inventories
See #2141
2025-03-16 15:59:43 +00:00
Jonathan Coates
582713467f Remove air blocks from test structures
This is a bit nasty, but makes the structure files *significtly* smaller
(1/4 the size), so feels worth doing.
2025-03-16 15:59:43 +00:00
Jonathan Coates
b6f41a0df5 Fix several issues with char/paste event validation
- Fix isValidClipboard always returning true.
 - Fix characters >=128 being rejected. We changed the signature from a
   byte to an int in 0f123b5efd, but
   didn't update all call sites.

   Valhalla cannot come soon enough. I would love to be able to have
   (cheap) wrapper classes for some of these types.

See Zeus-guy's comments in #860.
2025-03-16 14:07:15 +00:00
Jonathan Coates
594738a022 Standardised item details docs a little
Sort of closes #2125. I've really struggled to find a way to make it
clear that the information returned here is a snapshot of the current
item, and not a live view and/or proxy. Most wordings I've tried end up
feeling really clunky — given that this is a relatively rare
misunderstanding, let's not stress about this too much.
2025-03-16 10:25:57 +00:00
Jonathan Coates
27f2ab364c Clean up disk <-> drive right clicking
Oh dear. I'd originally set out to *remove* logic from DiskItem — we're
so close to being able to remove this item in 1.21! However, while
looking at this code, I realised I could remove the whole Forge-specific
doesSneakBypassUse.

We now remove the use hook on the block, and override useOn on the item.
Obvious in retrospect!
2025-03-15 12:28:29 +00:00
Jonathan Coates
5a43273757 docs: specify valid types for settings.define (#2140) 2025-03-13 07:10:30 +00:00
Drew Edwards
97e28516fb docs: specify valid types for settings.define 2025-03-13 01:40:08 +00:00
Jonathan Coates
676fb5fb53 Remove usages of onNeighborChange
Oh. This is from ye olde days (it's one of the first PRs to CC[^1]!). In
pre-1.13 days, furnaces changing their lit state would replace the block
(creating a new BE) and then set back the old BE. CC wouldn't pick up
the second event, and so would continue to use the peripheral from the
first.

We don't really need this any more, for a couple of reasons:
 a) Furnaces don't do this any more.

 b) Peripherals are now refreshed on the next tick rather than
    immediately.

 c) Forge's capabilities have an explicit invalidate() hook already. This
    technically only detects *removing* block entities, but I'm not sure
    there's any cases where you add a block entity without also
    triggering a block state change.

Ironically, the place we probably need this more is Fabric, where the
lookup API doesn't have a public invalidate hook (it's hidden away in
the BlockApiCache). I'm mostly relying on c) here, in that we just won't
see this happen in practice.

[^1]: https://github.com/dan200/ComputerCraft/pull/180
2025-03-09 15:22:49 +00:00
Jonathan Coates
08dc08b5a3 Replace appendHoverText with component-based tooltips
We have several items (e.g. ComputerItem), which only exist for their
custom tooltip implementation. We remove these, and replace them
vanilla-style component-based tooltips (TooltipProvider).

The implementation here is a little janky — as the vanilla list of
components is hard-coded, and neither mod loader offers a way to extend
it. For now we just use the generic mod-loader tooltip hook — this
probably would be easier with a mixin, but let's do things Properly.

It would be nice to fully remove DiskItem (we only keep this around for
doesSneakBypassUse), but that can be a future task.
2025-03-09 13:39:45 +00:00
Jonathan Coates
8f4d4038f6 Merge branch 'mc-1.20.x' into mc-1.21.x 2025-03-09 12:35:44 +00:00
Jonathan Coates
63ba3fe274 Fix printout crafting
Introduced by the previous commit — I'd made one of the checks too lax.
Add some tests for this, so it doesn't happen again, though this code
does get a complete rewrite in 1.21 anyway >_>.
2025-03-09 12:19:59 +00:00
Jonathan Coates
749b3df227 Remove PrintoutItem.getType
Kinda surprised this is still around! Not sure why I kept it post
the-flattening really, it's been redundant for a while.
2025-03-09 11:46:36 +00:00
Jonathan Coates
b97634b717 Flesh out LuaTable a bit
Add a whole buncha helper methods for parsing values, much like
IArguments. This allows us to remove TableHelper. Gosh, that dates back
to 2018!
2025-03-08 23:39:11 +00:00
Jonathan Coates
8ade1c38ac Send less computer BE data to the client
We only sent the id, label and lock code to the client for pick-block
interactions. Now that's handled on the server, we don't need this any
more!
2025-03-05 20:46:06 +00:00
Jonathan Coates
1b8344d0a3 Ignore shader loading errors
Another go at fixing #2127.

In a892739f8e we set the precision on the
Tbo uniform. However, this is stripped in the shader pre-processing
Pojav/gl4es does, and so has no effect. As a (terrible) workaround, we
now just ignore shader loading errors. This probably does leak memory
(we'll never clean up the program), but there's not much we can do about
that.
2025-03-05 19:01:32 +00:00
Jonathan Coates
b42bc0a01a Bump Loom and vanilla-extract versions 2025-03-05 18:49:03 +00:00
Jonathan Coates
70a7478529 Ignore some components when sending item to client
We send the item-form of the current computer in the computer menu data.
However, this leaks the current LockCode, as we include all components.
We now only gather a safe subset of components when constructing the
item.
2025-03-05 18:20:05 +00:00
Jonathan Coates
0cff73e2fc Add turtle.getEquipped{Left,Right}
These just return details about the currently equipped *item*. This
allows us to expose information about the currently equipped upgrade,
without having to invent a whole new format.

Docs are a bit consise, but didn't really know how to flesh them out any
further.

Fixes #964, fixes #1613, closes #1692.
2025-03-03 21:30:19 +00:00
Jonathan Coates
05163a4911 Store command computers in a separate folder
- Remove the /computercraft-computer-folder client command, and replace
   it with OPEN_FILE on NeoForge, or a /computercraft-open-folder
   command on Fabric (which now accepts a path, rather than an id).

 - Store command computer files in "computercraft/command_computer/<id>".

Fixes #1581.
2025-03-03 20:54:06 +00:00
Jonathan Coates
a892739f8e Specify precision in monitor fragment shader
Some people run Minecraft on OpenGL ES GPUs via the gl4es translation
bridge. This sets the default precision for floats and ints, but not
usamplerBuffer.

Using lowp should be fine here (we don't need to encode much info!), but
we use mediump just in case. Have run this through the Mali Offline
compiler, and it seems fine with it.

Fixes #2127.
2025-03-03 10:13:26 +00:00
Jonathan Coates
9277aa33e9 Update to 1.21.4
Please don't talk to me about this. The first couple of hours of this
update were quite enjoyable, and then the rest was one of the most
miserable times I've had modding.

This has been a real slog, partly due to some large MC changes (item
models are a great change, but a pain to adapt to), and partly due to
mental health reasons — honestly, I've opened up my IDE so many times,
and then just closed it because I've hated the thought of even working
on this.

I will publish this to my maven, so mod authors can depend on it, but I
have no plans to publish a 1.21.4 version. 1.21.5 is right around the
corner (again, with some cool, but no-doubt painful changes), and I
need some time to focus on some breaking changes.

This commit actually includes the 1.21.3 update — the git history got so
messy here, so I just clobbered the whole thing. Sorry.

== Rendering ==

 - Remove TBO monitor renderer: There was a big overhaul to how shaders
   are defined and loaded in 1.21.2. It might have been possible to
   update the monitor shader code to this version, it doesn't see much
   use nowadays, so let's just delete it.

   This is a real shame — the TBO renderer was one of my favourite
   projects I've worked on. Unfortunately, it just doesn't seem worth
   the ongoing maintenance burden. It lives on in the standalone
   emulator :D.

 - Similarly, the VBO rendering code got a bit of an overhaul. We no
   longer use a custom VBO subclass, and instead just hack vanilla's to
   support changing the number of vertices rendered.

   This does mean we need to construct a MeshData, rather than a raw
   ByteBuffer. This isn't too hard, but not sure how it'll play with
   Iris. Given recent vanilla performance improvements, maybe we can
   remove our Unsafe code and use a normal BufferBuilder now.

 - Remove our custom emissive model code, now that vanilla supports
   it. We should add emissive textures to some other models at some
   point.

 - Remove mod-loader specific model code, and replace it with vanilla's
   ItemModel. This does constrain the design of turtle upgrade modellers
   quite a bit — we now only accept an untransformed BakedModel or a
   transformed ItemStack model. We may relax this in the future,
   unclear.

   This change does mean that updsidedown turtles are broken. RIP :(.

 - Entity rendering now separates reading state from the entity from
   actual rendering. This means we need to pass some extra state around
   for item frames. Easy on Forge, but requires a mixin on Fabric.

== Recipes ==

There were several major changes to ingredients this update. The code
here hasn't been very well tested right now — might be nice to add some
game tests for this.

 - Ingredients can no longer be constructed directly from a tag key (it
   needs to be fetched from the current registries), so the recipe
   generation code needs a bit of a reshuffle.

 - DiskRecipe now accepts a custom list of ingredients, rather than
   being hard-coded (fixes #1755). Recipes can now return custom
   `RecipeDisplay`s used to show a recipe in the crafting book. We use
   this to replace the impostor recipes.

   I'm not entirely sure how well this'll play with other recipe
   mods. Here's hoping.

 - Similarly, our recipe mod integration has been updated to use
   RecipeDisplay. We had to do this as ingredients no longer accept
   arbitrary ItemStacks (only a specific item).

== Misc ==

 - Blocks/items now need to know their ID ahead of time (so they can
   compute their description). This requires some reshuffling to the
   registration code, but it's pretty minor.

 - updateShape and neighborChanged no longer take a direction (the
   Orientation is mostly null) and so invalidates all redstone and
   peripherals.

 - All the positions were lowered by one in game tests. It's a good
   change (they now match the positions in structures), but annoying to
   update for!
2025-03-02 21:34:47 +00:00
Jonathan Coates
f8785a092f Fix particle texture for turtle colour model
This is never actually used in practice, but let's avoid any missing
texture reference warnings! Embarrassing that I hadn't noticed this
before!
2025-03-02 21:14:27 +00:00
Jonathan Coates
598fc4aefd Merge branch 'mc-1.20.x' into mc-1.21.x 2025-03-01 22:49:56 +00:00
Jonathan Coates
dd7e8fcefc Bump CC:T to 1.115.1 2025-03-01 22:35:29 +00:00
Jonathan Coates
29c8f96912 Sync translations from CrowdIn
I remembered to do this *before* the update! 🎉
2025-03-01 22:34:45 +00:00
Jonathan Coates
b9267ecbfc Resize lectern pocket computer textures
This bumps them to be 48x48, which allows them to be downscaled to a
mipmap level of 4. We possibly should bump these to be 64x64 (actual
power of two), but I kinda want to avoid that, as it's so much wasted
space. If this does become a problem, we should probably put these on a
separate atlas instead.
2025-03-01 22:24:27 +00:00
Jonathan Coates
9d2c2db22b Fix speaker.playAudio not updating volume
Honestly, the whole design around volume and playSound/playAudio is a
little janky — it probably should be a separate setVolume method which
updates directly. But too late to change that now, so let's do what we
can.

See #2108
2025-03-01 20:28:37 +00:00
ellellie
6660966320 Update Create dependency to 6.0.0 (#2117) 2025-03-01 19:56:43 +00:00
Jonathan Coates
3acb231f01 Write some docs for migrating from MC 1.20 -> 1.21
Almost definitely too late (and not sure if anyone will read them
anyway), but we can but try.
2025-02-21 20:12:44 +00:00
Jonathan Coates
16324e1eac Flesh out detail provider/registry docs 2025-02-19 21:08:56 +00:00
Jonathan Coates
fa33949113 Merge AbstractComputerItem and ComputerItem
ComputerItem was just an empty subclass, so no sense keeping around. We
probably could get rid of CommandComputerItem too (just do an `instanceof
GameMasterBlock` in `getPlacementState`), but there's no rush.
2025-02-16 21:12:35 +00:00
Jonathan Coates
0c04d9de47 Merge branch 'mc-1.20.x' into mc-1.21.x 2025-02-16 21:04:28 +00:00
Jonathan Coates
32f5c38485 Remove IMedia implementations from our items
We now register these separately, rather than relying on the implicit
IMedia. This allows us to share a bit more logic between
PocketComputerItem and AbstractComputerItem. This doesn't make much
difference on 1.20.1, but does help a bit more on 1.21.1.
2025-02-16 20:32:01 +00:00
Jonathan Coates
01fe949b3e Use Fabric's Item Lookup for registering media providers
We'll switch to capabilities on the (Neo)Forge side for 1.21, when the
capability system is less painful, and then fully deprecate in 1.21.4.
2025-02-16 20:32:01 +00:00
Jonathan Coates
c03fce275e Add some abstractions for registering capabilities
This is pretty useless right now (not even going to try to use it for
Forge), but should be a bit more useful for 1.21.
2025-02-16 20:32:00 +00:00
Jonathan Coates
0998acaa82 Switch to JSpecify annotations
Now, hear me out, what if instead of having three @Nullable annotations,
we had *four*?

I've been wanting to switch away from javax.annoations for a while. The
library has been deprecated for ever and, unlike other @Nullable
annotations, the annotation is attached to the parameter/function
itself, rather than the type.

We use JSpecify rather than one of the alternatives (JetBrains,
CheckerFramework) mostly because it's what NullAway recommends. We keep
CheckerFramework around for @DefaultQualifier, and JB's for @Contract.

There are some ugly changes here — for instance, `@Nullable byte[]` is
replace by `byte @Nullable`, and `@Nullable ILuaMachine.Factory` is
`ILuaMachine.@Nullable Factory`. Ughr, I understand why, but it does not
spark joy :).
2025-02-16 18:09:15 +00:00
Jonathan Coates
12a44fed6f Sync translations from CrowdIn 2025-02-15 18:35:05 +00:00
Jonathan Coates
3f8c3b026a Merge branch 'mc-1.20.x' into mc-1.21.x 2025-02-14 20:44:39 +00:00
Jonathan Coates
0a8d505323 Bump CC:T to 1.115.0 2025-02-14 20:20:30 +00:00
Jonathan Coates
237a0ac3bb Expose printout contents to the API
Closes #2099
2025-02-14 18:13:20 +00:00
Jonathan Coates
b185d088b3 Suggest alternative table keys on nil errors (#2097)
We now suggest alternative table keys when code errors with "attempt
to index/call 'foo' (a nil value)". For example: "redstone.getinput()",
will now suggest "Did you mean: getInput".

This is a bit tricky to get right! In the above example, our code reads
like:

   1    GETTABUP 0 0 0 ; r0 := _ENV["redstone"]
   2    GETFIELD 0 0 1 ; r0 := r0["getinput"]
   3    CALL 0 1 1     ; r0()

Note, that when we get to the problematic line, we don't have access to
the original table that we attempted to index. In order to do this, we
borrow ideas from Lua's getobjname — we effectively write an evaluator
that walks back over the code and tries to reconstruct the expression
that resulted in nil.

For example, in the above case:
 - We know an instruction happened at pc=3, so we try to find the
   expression that computed r0.
 - We know this was set at pc=2, so we step back one. This is a GETFIELD
   instruction, so we check the key (it's a constant, so worth
   reporting), and then try to evaluate the table.
 - This version of r0 was set at pc=1, so we step back again. It's a
   GETTABUP instruction, so we can just evaluate that directly.

We then use this information (indexing _ENV.redstone with "getinput") to
find alternative keys (e.g. getInput, getOutput, etc...) and then pick
some likely suggestions with Damerau-Levenshtein/OSD.

I'm not entirely thrilled by the implementation here. The core
interpretation logic is implemented in Java. Which is *fine*, but a)
feels a little cheaty and b) means we're limited to what Lua bytecode
can provide (for instance, we can't inspect outer functions, or list all
available names in scope). We obviously can expand the bytecode if
needed, but something we'd want to be careful with.

The alternative approach would be to handle all the parsing in
Lua. Unfortunately, this is quite hard to get right — I think we'd need
some lazy parsing strategy to avoid constructing the whole AST, while
still retaining all the scope information we need.

I don't know. We really could make this as complex as we like, and I
don't know what the right balance is. It'd be cool to detect patterns
like the following, but is it *useful*?

    local monitor = peripheral.wrap("left")
    monitor.write("Hello")
        -- ^ monitor is nil. Is there a peripheral to the left of the
        -- computer?

For now, the current approach feels the easiest, and should allow us to
prototype things and see what does/doesn't work.
2025-02-13 21:57:29 +00:00
Jonathan Coates
051c70a731 Propagate exceptions from parallel where possible (#2095)
In the original implementation of our prettier runtime errors (#1320), we
wrapped the errors thrown within parallel functions into an exception
object. This means the call-stack is available to the catching-code, and
so is able to report a pretty exception message.

Unfortunately, this was a breaking change, and so we had to roll that
back. Some people were pcalling the parallel function, and matching on
the result of the error.

This is a second attempt at this, using a technique I've affectionately
dubbed "magic throws". The parallel API is now aware of whether it is
being pcalled or not, and thus able to decide whether to wrap the error
into an exception or not:

 - Add a new `cc.internal.tiny_require` module. This is a tiny
   reimplementation of require, for use in our global APIs.

 - Add a new (global, in the debug registry) `cc_try_barrier` function.
   This acts as a marker function, and is used to store additional
   information about the current coroutine.

   Currently this stores the parent coroutine (used to walk the full call
   stack) and a cache of whether any `pcall`-like function is on the
   stack.

   Both `parallel` and `cc.internal.exception.try` add this function to
   the root of the call stack.

 - When an error occurs within `parallel`, we walk up the call stack,
   using `cc_try_barrier` to traverse up the parent coroutine's stack
   too. If we do not find any `pcall`-like functions, then we know the
   error is never intercepted by user code, and so its safe to throw a
   full exception.
2025-02-13 17:38:57 +00:00
Jonathan Coates
2e2f308ff3 Support placing pocket computers on lecterns (#2098)
This allows shift+clicking a pocket computer on to a lectern. These
computers can be right clicked, opening the no-term computer GUI.
Terminal contents is rendered in-world, and broadcast to everyone in
range.

 - Add a new lectern PocketHolder.
 - Refactor some of the `PocketItemComputer` code to allow ticking pocket
   computers from a non-player/entity source.
 - Add a new model for pocket computers. This requires several new
   textures (somewhat mirroring the item ones), which is a little
   unfortunate, but looks much better than reusing the map renderer or
   item form.
2025-02-13 17:31:08 +00:00
Jonathan Coates
0f123b5efd Ignore unrepresentable characters when typing
In 94ad6dab0e, we changed it so typing
characters outside of CC's codepage were replaced with '?' rather than
ignored. This can be quite annoying for non-European users (where latin1
isn't very helpful!), so it makes sense to revert this change.

See discussion in #860 for more context.
2025-02-12 18:45:40 +00:00
Jonathan Coates
1278246cf7 Add back MoreRed support
I removed this in fc834cd97f, way back in
late 2024. Looks like it's been updating in the meantime and I hadn't
noticed, so add it back.

I've simplified the code a little bit, to make use of our NeoForge's new
capability system, but otherwise it's almost exactly the same :D.
2025-02-12 13:40:58 +00:00
Jonathan Coates
88cb03be6b Clean up the parallel API
- Store the filter alongside the coroutine rather than in a separate
   table (like we do in multishell).

 - Remove the redudant (I think!) second loop that checks for dead
   coroutines. We already check for dead coroutines in the main loop.

 - Rename some variables to be a bit more consistent. This makes this
   commit look noisier than it is. Sorry!
2025-02-09 16:53:59 +00:00
Jonathan Coates
1e25fa9bc3 Bump CC:T to 1.114.5 2025-02-09 10:16:45 +00:00
Jonathan Coates
74f707aaea Create a new CraftingInput for each craft
It's not actually safe to reuse this, as we need to recompute the
internal StackedContents each time the inventory changes, otherwise
ShapelessRecipe.matches will continue to return true, even if the actual
inventory doesn't include the required items.

Fixes #2094
2025-02-07 09:45:14 +00:00
Jonathan Coates
9bb62b047a Merge branch 'mc-1.20.x' into mc-1.21.x 2025-01-31 21:41:15 +00:00
Jonathan Coates
4360485880 Bump CC:T to 1.114.4 2025-01-31 21:09:57 +00:00
Jonathan Coates
b69a44a927 Redo turtle move checks
Oh, this is so broken, and really has been since the 1.13 update, if not
earlier.

 - Fix call to isUnobstructed using the bounding box of the
   *destination* block rather than the turtle. This is almost always
   air, so the box is empty.

 - Because the above check has been wrong for so many years, we now
   significantly relax the "can push" checks for entities. We now allow
   pushing entities in any direction.

   We also remove the "isUnobstructed" check for the destination entity
   pos. This causes problems (if two entities are standing on a turtle,
   they'll obstruct each other), and given pistons don't perform such a
   check, I don't think we need it.

 - Also do a bit of cleanup around air/liquid checks. We often ended up
   reading the block state multiple times, which is a little ugly.
2025-01-27 22:45:52 +00:00
Jonathan Coates
7d8f609c49 literally sobbing rn 2025-01-26 22:27:50 +00:00
Jonathan Coates
e7f56c4d25 Remove ComponentMap
I'd originally kept this around to prevent mods that use CC internals,
but fa2140d00b has probably broken those
anyway, so let's not worry too much.
2025-01-26 15:13:24 +00:00
Jonathan Coates
fa2140d00b Clean up container data interface
- Remove ContainerData.open.

 - Change PlatformHelper.openMenu to take a separate display name and
   MenuConstructor, rather than a MenuProvider. This makes the interface
   slightly easier to use in the common case, where we want to use
   lambdas instead.
2025-01-26 14:56:09 +00:00
Jonathan Coates
03388149b1 Fix command computers being exposed as peripherals
- Check whether the computer is a command computer before registering
   the capability.

 - Add tests to check what is/isn't a peripheral. See also #2020, where
   we forgot to register a peripheral on NeoForge 1.21.1.

Fixes #2070.
2025-01-26 11:13:52 +00:00
Jonathan Coates
f212861370 Mark command computers as onlyOpCanSetNbt
This isn't required in vanilla, as the command computer is a
GameMasterBlock, and so isn't placeable in the first place.

*However*, this is a problem with Create contraptions — with those it's
possible to "place" a command computer complete with NBT. We override
onlyOpCanSetNbt to prevent this [^1].

[^1]: 7a7993deb8/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java (L179)
2025-01-21 20:41:55 +00:00
Jonathan Coates
4f3663ccc9 Allow overriding computer/floppy capacity
This adds a new "computercraft:storage_capacity" component to items (and
"Capacity" NBT tag to BEs), that overrides the capacity for the given
item.

Fixes #1814
2025-01-21 10:04:46 +00:00
Jonathan Coates
53425c1e76 Merge branch 'mc-1.20.x' into mc-1.21.x 2025-01-20 22:22:09 +00:00
Jonathan Coates
55edced9de Move GUI sprites to the sprites/ folder
This is where vanilla will read the sprites from in future versions, so
means we have a consistent layout between versions.

Also move the turtle "selected slot" texture to a sprite sheet. It would
be good to do more of these in the future (e.g. printer progress, maybe
bits of printouts).

Sorry to resource pack artists for causing trouble again.
2025-01-20 20:21:22 +00:00
Jonathan Coates
dc969c5a78 Configure ServerComputer via a Properties builder
We currently need to pass a whole bunch of arguments to a ServerComputer
in order to construct it, and if we implement #1814, this will get a
whole lot worse. Instead, we now pass most parameters (computer id,
family, label, term size, components) via a separate Properties class,
much like Minecraft does for blocks and items.

I'm not wild about the design of the API here, but I think it's a step
in the right direction.
2025-01-20 19:47:18 +00:00
Jonathan Coates
94ad6dab0e Map Unicode to CC's charset for char/paste events
We now convert uncode characters from "char" and "paste" events to CC's
charset[^1], rather than just leaving them unconverted. This means you
can paste in special characters like "♠" or "🮙" and they will be
converted correctly. Characters outside that range will be replaced with
"?", as before.

It would be nice to make this a bi-directional mapping, and do this for
Lua methods too (e.g. os.setComputerLabel). However, that has much wider
ramifications (and more likelyhood of breaking something), so avoiding
that for now.

 - Remove the generic "queue event" client->server message, and replace
   it with separate char/terminate/paste messages. This allows us to
   delete a chunk of code (all the NBT<->Object conversion), and makes
   server-side validation of events possible.

 - Fix os.setComputerLabel accepting the section sign — this is treated
   as special by Minecraft's formatting code. Sorry, no fun allowed.

 - Convert paste/char codepoints to CC's charset. Sadly MC's char hook
   splits the codepoint into surrogate pairs, which we *don't* attempt
   to reconstruct, so you can't currently use unicode input for block
   characters — you can paste them though!

[^1]: I'm referring this to the "terminal charset" within the code. I've
flip-flopped between "CraftOS", "terminal", "ComputerCraft", but feel
especially great.
2025-01-19 11:07:29 +00:00
Jonathan Coates
938eb38ad5 Move computer events to a single point
This abstraction never made much sense on InputHandler, as we only leave
the default methods on ServerComputer.

We now add a new class (ComputerEvents), which has a series of *static*
methods, that can queue an event on a ComputerEvents.Receiver object.
This is a bit of an odd indirection (why not just make them instance
methods on Receiver?!), but I don't really want those methods leaking
everywhere.
2025-01-18 19:26:10 +00:00
Jonathan Coates
6739c4c6c0 Wait for computers to run each tick in gametests 2025-01-17 18:43:19 +00:00
Jonathan Coates
d6749f8461 Set issue type in the templates
We already have the label, so it's not quite clear if it's worth it, but
let make our issue board look even more like a tube of smarties.
2025-01-17 17:25:39 +00:00
Jonathan Coates
d697c47b80 Catch ModdedConfig.getFilePath errors
This occurs when syncing the server config to the client. Ideally we'd
not hit this code path in the first place, but unfortunately there's no
way to tell where the config file comes from.

Fixes #2065
2025-01-17 17:14:06 +00:00
Jonathan Coates
5ba7f99326 Add back inputs on processResources
I kinda thought that Gradle would be smart enough to know that these
were input (given they're passed to expand), but apparently not :/.
2025-01-14 21:26:31 +00:00
Jonathan Coates
4710ee5bcc Merge branch 'mc-1.20.x' into mc-1.21.x
As part of this, we also rewrite some of the turtle placing code, and
how it uses the turtle_can_use tag:

Minecraft 1.21 cleaned up the item/block clicking code a little bit,
splitting Block.use into Block.useItemOn and Block.useWithoutItem. The
first of these is pretty much exactly what we wanted in the first place,
so the tag was kinda redundant and we commented it out in the 1.21
update.

This was never meant to be a long-term fix, but time has gone by anyway.
We now check that tag, and call useWithoutItem() if present —
effectively restoring the previous behaviour.

Fixes #2011
2025-01-14 21:26:11 +00:00
Jonathan Coates
62c9e5b08f Add back missing translations
Lost in d3a3ab3c21, due to changes in
ea670cc358.
2025-01-14 18:14:51 +00:00
Jonathan Coates
2ca5850060 Bump CC:T to 1.114.3 2025-01-14 10:24:23 +00:00
Jonathan Coates
ed631b05e7 Fix TurtleTool using the wrong stack
When "placing" the item (e.g. hoeing soil), we were using the tool item,
rather than the passed stack. This was introduced in
9a914e75c4, so never made it into a
release.
2025-01-14 10:24:23 +00:00
Jonathan Coates
a2b9490d5c Some printer gametests
These are a little ugly, but do catch some issues we've seen in the
past. Fixes #1682 (for now), and on its birthday too!
2025-01-14 09:38:22 +00:00
Jonathan Coates
8204944b5f More Gradle cleanup
Mostly configuration cache support. And an aborted attempt at updating
spotless, which just resulted in a bunch of ktlint issues :/.
2025-01-14 08:48:48 +00:00
Jonathan Coates
ef0af67e96 Share some dependency exclusion code
- Disable Gradle module metadata for all Minecraft projects
 - Run dependency exclusion code for all projects

We need the former for MDG on 1.21, so might as well do some other
cleanup while we're here.
2025-01-13 00:02:54 +00:00
Jonathan Coates
9a914e75c4 Rethink PlatformHelper.useOn
useOn is now only responsible for firing the actual mod loader events,
and just returns the result of firing that event. The actual calling of
Block.use/Item.useOn now live in TurtlePlaceCommand.

This isn't especially useful for 1.20.1, but is more relevant on 1.21.1
when we look at #2011, as the shared code is much larger.
2025-01-12 22:01:43 +00:00
Jonathan Coates
4a532952d4 Merge branch 'mc-1.20.x' into mc-1.21.x 2025-01-12 20:48:49 +00:00
Jonathan Coates
546577041b More turtle game tests
See #1682. Mostly trying to capture some behaviour I know has changed in
1.21, so we can verify it more easily.
2025-01-12 20:29:37 +00:00
Jonathan Coates
f881c0ced0 A few more gametests, update to Gradle 8.12
Okay, listen. I started writing a few more gametests (see #1682), and
then thought I'd do a cheeky Gradle update. However, that broke
vanilla-extract[^1], and also triggered a load of deprecation warnings,
and at that point it was too late to separate the too.

[^1]: 8975ed5a7b
2025-01-12 18:26:51 +00:00
Jonathan Coates
0b389e04b0 Move Fabric datagen mixins to datagen module
This way they don't interfere with other mods doing datagen.

Also bump reuse version, to fix issues with globs.
2025-01-12 12:44:57 +00:00
Jonathan Coates
d3a3ab3c21 Sync translations from Crowdin
Closes #2044

Co-authored-by: Yaroslav Petryk <Yaroslav01@ukr.net>
2025-01-12 11:47:58 +00:00
Jonathan Coates
22e6c06e59 Don't store terminal snapshot as a ByteBuf
There's too many issues here around object pooling and reference
counting, that it's just not practical to correctly handle. We now just
use a plain old byte[] rather than a ByteBuf.

This does mean the array now lives on the Java heap rather than the
direct heap, but I *think* that's fine. It's something that is hard to
measure.

Fixes #2059
2025-01-12 10:37:27 +00:00
Jonathan Coates
7337b91692 Merge branch 'mc-1.20.x' into mc-1.21.x
Oh, I'm sure I missed something here. This was a nasty merge, has the
docs have changed so much in each version.
2025-01-11 17:54:15 +00:00
Jonathan Coates
3c46b8acd7 Clean up Javadocs a little
I've no motivation for modding right now, but always got time for build
system busywork!

CC:T (and CC before that) has always published its API docs. However,
they're not always the most helpful — they're useful if you know what
you're looking for, but aren't a good getting-started guide.

Part of the issue here is there's no examples, and everything is
described pretty abstractly. I have occasionally tried to improve this
(e.g. the peripheral docs in bdffabc08e),
but it's a long road.

This commit adds a new example mod, which registers peripherals, an API
and a turtle upgrade. While the mod itself isn't exported as part of the
docs, we reference blocks of it using Java's new {@snippet} tag.

 - Switch the Forge project to use NeoForge's new Legacy MDG plugin. We
   don't *need* to do this, but it means the build logic for Forge and
   NeoForge is more closely aligned.

 - Add a new SnippetTaglet, which is a partial backport of Java 18+'s
   {@snippet}.

 - Add an example mod. This is a working multi-loader mod, complete with
   datagen (albeit with no good multi-loader abstractions).

 - Move our existing <pre>{@code ...}</pre> blocks into the example mod,
   replacing them with {@snippet}s.

 - Add a new overview page to the docs, providing some getting-started
   information. We had this already in the dan200.computercraft.api
   package docs, but it's not especially visible there.
2025-01-09 20:47:51 +00:00
Jonathan Coates
d9fc1c3a80 Remove mention of submitting translations via PRs
Turns out it's possible, but a bit of a faff with CrowdIn. Why is all
translation software terrible!
2025-01-05 23:25:29 +00:00
Jonathan Coates
479aabdd09 Tweaks to CONTRIBUTING.md 2025-01-05 23:23:24 +00:00
Jonathan Coates
ad74893058 Remove redundant condition in io.read 2025-01-05 23:02:16 +00:00
Jonathan Coates
2ba6d5815b Fix fs.isDriveRoot for missing files
fs.getDrive returns nil for missing files, rather than the mount of the
parent file. This is a bit confusing — other mount-related functions
(e.g. getFreeSpace) find the nearest mount — but I think it's too late
to change this. Instead, we check if the file exists first.
2024-12-31 11:12:58 +00:00
tizu
7e2f490626 Show HTTP error in wget (#2037) 2024-12-22 16:45:04 +00:00
Jonathan Coates
4dc649d5e5 Merge pull request #2029 from MCJack123/patch-19
Add `turtle.getItemDetail` `detailed` flag introduction date
2024-12-12 09:18:44 +00:00
JackMacWindows
5bab415790 Add turtle.getItemDetail detailed flag introduction date 2024-12-12 00:44:25 -05:00
Jonathan Coates
f04c699df6 Merge branch 'mc-1.20.x' into mc-1.21.x 2024-12-05 12:19:16 +00:00
Jonathan Coates
9bbf3f3e1d Move datagen to its own source set
MC 1.21.4 means we have to move more data generation code into the
client source set. Given all this code movement, it probably makes sense
to put data generation in a separate source set instead.

1.21.4 also has split data generators for client and server, but neither
mod loader recommends this. This means we can/should merge DataProviders
and ClientDataProviders into a single class.

Data generators are no longer bundled with the jar, which does reduce
file size, but by a tiny amount (~70KiB).
2024-12-05 12:03:45 +00:00
Jonathan Coates
a3f8e653d4 Fix redstone relay not being registered as a peripheral
This was only present on the 1.21 NF version, hence not being noticed
before. Fixes #2020.

I pruned my Gradle cache recently, and I'm on some truly terrible hotel
wifi, so this is entirely untested. No beta, we die like men.
2024-12-03 07:31:25 +00:00
Jonathan Coates
7c02979c22 Upload jars in CI earlier
This means they're uploaded even if the linters or tests fail.
2024-11-30 12:07:55 +00:00
Jonathan Coates
fdb65c9368 Link to monitor events from the main monitor page 2024-11-28 10:31:36 +00:00
Jonathan Coates
ea670cc358 Try to unify our config files a bit
I've tried so many rewrites of the config system over the last few
months, in an attempt to get started on #1727. All of them stink, so
this is an attempt to apply some of the cleanup.

 - Move some of the common logic into ConfigFile. This means we now
   store more information ourselves for Forge, rather than reading it
   out of the ForgeConfigSpec.

 - Don't include the Range/Allowed keys in the translation key. This was
   mostly there because of how we read comments from Forge, but it never
   made much sense.

 - Remove our separate Trie structure, and just encode the tree as part
   of the children of a Group.
2024-11-24 21:53:04 +00:00
Jonathan Coates
b7396f3796 Merge branch 'mc-1.20.x' into mc-1.21.x 2024-11-23 09:36:50 +00:00
Jonathan Coates
1963e0160f Bump CC:T to 1.114.2
Ahhhh, I hate graphics code.
2024-11-23 09:34:03 +00:00
Jonathan Coates
9a06904634 Only skip cursor if it exists
If the cursor is not visible then we'd end up blinking the last
character on the screen. And if the screen was empty we'd spew the logs
with GL errors.
2024-11-23 09:31:04 +00:00
Jonathan Coates
5eb50ecb06 Merge branch 'mc-1.20.x' into mc-1.21.x 2024-11-23 09:16:48 +00:00
Jonathan Coates
5e24ad17d7 Bump CC:T to 1.114.1 2024-11-23 09:14:53 +00:00
Jonathan Coates
8b1cb09ddf Update translations 2024-11-23 09:10:50 +00:00
Jonathan Coates
7af2c14327 Move block entity component fixes to separate fixer
Some mods run their own datafixer chain, rather than piggybacking on top
of vanilla's. This is A BAD IDEA, but what can you do. If such a mod
tries to use ItemStackComponentizationFix in their own schema, then
CC:T's mixins will try to look up the turtle block entitie, and fail (as
they're not registered under the modded schema).

We now inject the block entity fix as a separate fixer, rather than
abusing ItemStackComponentizationFix.

See #2012
2024-11-23 08:53:54 +00:00
Jonathan Coates
d1a6b043c2 Clean up monitor cursor rendering
- Use the correct index count for the cursor quad. Monitors are now
   rendered as quads, rather than triangles.
 - *Skip* rendering the cursor vertex, rather than additionally
   rendering it.

I confess, I'm baffled how this code was ever written. From what I can
tell, this has been broken since it was first introduced in
4228011b84, and I'm sure I tested it then.

Fixes #2013. Probably.
2024-11-23 08:24:11 +00:00
Jonathan Coates
cddb8fec11 Fix crash when lectern has no item
This should never happen in practice, but might happen when using
/setblock or after world corruption, so let's be careful here.

Closes #2014
2024-11-19 21:35:00 +00:00
Jonathan Coates
1d7d8006d4 Stop publishing to CurseForge
Been dragging my feet over this for a while now, but increasingly
uncomfortable with Overwolf. I'm not going to delete the project (or any
existing versions), just not publish any new versions there.
2024-11-16 15:19:00 +00:00
Jonathan Coates
63bdc2537c Fix monitor events using the wrong computer set
Fixes #2010
2024-11-15 18:43:28 +00:00
Jonathan Coates
f776b17150 Fix argument order of math.atan in changelog 2024-11-15 15:32:40 +00:00
Jonathan Coates
0056709999 Merge branch 'mc-1.20.x' into mc-1.21.x 2024-11-15 09:25:46 +00:00
Jonathan Coates
31da2555cb Bump CC:T to 1.114.0 2024-11-15 08:22:05 +00:00
Jonathan Coates
9b19a93ab9 Sync translations from Crowdin
Ended up writing my own janky script to do this, rather than use the GH
integration. I'm not proud of this, but it works.
2024-11-15 08:14:06 +00:00
Jonathan Coates
0c8e757314 Several cleanup to turtle crafting upgrade
- Don't construct a fake player when crafting: vanilla now has its own
   automated crafting, so no longer requires the presence of a player.

 - Fix remainder stack not being set in some situations. Closes #2007.
2024-11-15 07:31:49 +00:00
Jonathan Coates
f39e86bb10 Bump NeoGradle version
This uses a shared asset directory (previously it was per-version), so
much more disk friendly.
2024-11-14 11:01:23 +00:00
Jonathan Coates
ad52117f0f Syntax highlight more docstrings
This is going to conflict horribly with MC 1.21 (where we started using
@snippet), but hopefully this still helps.
2024-11-13 11:00:46 +00:00
Jonathan Coates
bdffabc08e Clarify docs around registering peripherals 2024-11-13 10:19:10 +00:00
Jonathan Coates
87ce41f251 Update Cobalt to 0.9.5
- Fix several issues with large doubles
 - Fix metatable cache not being cleared
2024-11-12 21:11:22 +00:00
Jonathan Coates
e7c7919cad Add test for turtle crafting with remainders
See #2007. This isn't an issue on 1.20.1, so it doesn't fix the issue,
but good to have the test everywhere.
2024-11-12 09:17:03 +00:00
Jonathan Coates
4f66ac79d3 Add redstone relay block (#2002)
- Move redstone methods out of the IAPIEnvironment, and into a new
   RedstoneAccess. We similarly move the implementation from Environment
   into a new RedstoneState class.

   The interface is possibly a little redundant (interfaces with a
   single implementation are always a little suspect), but it's nice to
   keep the consumer/producer interfaces separate.

 - Abstract most redstone API methods into a separate shared class, that
   can be used by both the rs API and the new redstone relay.

 - Add the new redstone relay block.

The docs are probably a little lacking here, but I really struggled to
write anything which wasn't just "look, it's the same as the redstone
API".
2024-11-12 09:05:27 +00:00
Jonathan Coates
ba6da3bc6c Update item image exporter to work on 1.20.x 2024-11-12 08:11:09 +00:00
Jonathan Coates
b742745854 Cancel no-longer-needed timers
Several functions accept a "timeout" argument, which is implemented by
starting a timer, and then racing the desired output against the timer
event.

However, if the timer never wins, we weren't cancelling the timer, and
so it was still queued. This is especially problematic if dozens or
hundreds of rednet (or websocket) messages are received in quick
succession, as we could fill the entire event queue, and stall the
computer.

See #1995
2024-11-10 21:08:05 +00:00
Jonathan Coates
3293639adf Normalise language files 2024-11-05 10:00:08 +00:00
Jonathan Coates
064ff31830 Don't reset client pocket state when changing level
As part of the multi-loader work, we unified some of our event listening
code (0908acbe9b). This incorrectly caused
client pocket computer state to be reset when the player changes
dimension, rather than when the player (dis)connects.

The server code isn't aware of this behaviour, and so does not resend
pocket computer state when the player moves level. We could change this,
but just fixing when we clear the pocket computer state is a much nicer
fix!

Fixes #2004
2024-10-31 09:33:22 +00:00
Jonathan Coates
5d473725d5 Don't word-wrap in the bug report template
Oh, I wish GHFM handled soft-breaks as soft-breaks, rather than turning
them into hard ones :/.
2024-10-31 08:32:44 +00:00
Jonathan Coates
97a2f2dbdd A desperate plea to get people to include logs 2024-10-31 08:31:35 +00:00
Jonathan Coates
37c4789fa4 Fix Czech language mapping 2024-10-31 08:31:21 +00:00
Jonathan Coates
0aaeeeee24 Don't log HTTP errors
We don't do this for websockets, so maybe we can get away without this
for HTTP ones too? Closes #1975.
2024-10-27 16:07:17 +00:00
Jonathan Coates
2155ec3d63 Give up on codecov
v4 of the action seems to be much more restrictive in what can upload
coveage. I'll miss this (the historic view of coverage was nice!), but
not worth trying to get working again.

We also stop running client tests. These break so often, we only really
ran them for code coverage reasons.
2024-10-27 11:01:42 +00:00
NotSquidDev
0da906fc93 New Crowdin updates (#1954) 2024-10-27 10:18:26 +00:00
Jonathan Coates
9e5e6a1b60 Update npm packages and illuaminate 2024-10-27 10:01:29 +00:00
Jonathan Coates
dcc74e15c7 Fix pocket upgrades not applying after crafting
The most annoying thing about pocket computers is handling computer
state (label, upgrades, etc...). Unlike other computers, which are tied
to a specific block entity, pocket computers float untethered. We can't
hold a reference to a specific item stack (as the computer might be
moved between inventories, crafted, etc...), so instead we explicitly
sync data between the computer and *current* stack, whenever the holding
player/entity is ticked.

In ed0b156e05 I rewrote this syncing code
to always treat the computer as the source of truth. Upgrades would be
copied to the computer, but never the other way round. However, this
meant that upgrades obtained by crafting would never be detected,
requiring the computer to be destroyed and recreated.

A more long-term fix here is probably to rewrite IPocketAccess to only
allow updating upgrade data on the main thread, and when we have a valid
PocketHolder. This is a breaking API change though, and so will have to
wait for 1.21.3.

For now, we just add a hook that refreshes the upgrade after crafting.

Fixes #1957
2024-10-27 09:49:01 +00:00
Jonathan Coates
c271ed7c7f Fix wrong link in os.date docs
Should be os.time, not os.date! Fixes #1999
2024-10-24 14:03:06 +01:00
Karotte128
d6a246c122 Small german translation update (#1992) 2024-10-11 20:36:28 +02:00
Jonathan Coates
0bef3ee0d8 Install/run pre-commit directly
The update to Python 3.12 has broken the pre-commit action (as it
installs via pip rather than pipx). The maintainer seems unwilling to
fix it (to put it diplomatically), so let's just stop using the action
and imlement it ourselves.
2024-10-11 20:27:15 +02:00
Jonathan Coates
bb04df7086 Remove command translation keys
- <no pos> is no longer used, as positions cannot be nullable.
 - We don't really need the position one — we can just concatenate in
   Java.
2024-10-11 12:12:02 +02:00
RuyaSavascisi
a70baf0d74 Add Turkish translation 2024-09-28 15:03:33 +01:00
Jonathan Coates
86e2f92493 Add Turkish language mapping 2024-09-28 10:15:07 +01:00
Jonathan Coates
e9aceca1de Add a helper class for working with attached computers
One of the easiest things to mess up with writing a custom peripheral is
handling attached peripherals. IPeripheral.{attach,detach} are called
from multiple threads, so naive implementations that just store
computers in a set/list will at some point throw a CME.

Historically I've suggested using a concurrent collection (i.e.
ConcurrentHashMap). While this solves the problems of CMEs, it still has
some flaws. If a computer is detached while iterating over the
collection, the iterator will still yield the now-detached peripheral,
causing usages of that computer (e.g. queueEvent) to throw an exception.

The only fix here is to use a lock when updating and iterating over the
collection. This does come with some risks, but I think they are not too
serious:

 - Lock contention: Contention is relatively rare in general (as
   peripheral attach/detach is not especially frequent). If we do see
   contention, both iteration and update actions are cheap, so I would
   not expect the other thread to be blocked for a significant time.

 - Deadlocks: One could imagine an implementation if IComputerAccess
   that holds a lock both when detaching a peripheral and inside
   queueEvent.

   If we queue an event on one thread, and try to detach on the other,
   we could see a deadlock:

     Thread 1                         | Thread 2
    ----------------------------------------------------------
     AttachedComputerSet.queueEvent   | MyModem.detach
      (take lock #1)                  |  (take lock #2)

     -> MyModem.queueEvent            | AttachedComputerSet.remove
      (wait on lock #2)               |  (wait on lock #1)

   Such code would have been broken already (some peripherals already
   use locks), so I'm fairly sure we've fixed this in CC. But definitely
   something to watch out for.

Anyway, the long and short of it:
 - Add a new AttachedComputerSet that can be used to track the computers
   attached to a peripheral. We also mention this in the attach/detach
   docs, to hopefully make it a little more obvoius.

 - Update speakers and monitors to use this new class.
2024-09-22 13:51:11 +01:00
Jonathan Coates
3042950507 Update Cobalt to add math.atan(y, x) support 2024-09-22 13:13:07 +01:00
Jonathan Coates
63181e73a1 Unify Iris integrations
Iris now has built-in support for NeoForge, so we can use the same
integration on both.

We also re-enable Forge's client tests, and test Iris there too.

Fixes #1967
2024-09-11 20:10:38 +01:00
Jonathan Coates
4f3247a0e2 Merge branch 'mc-1.20.x' into mc-1.21.x 2024-09-11 19:28:13 +01:00
Jonathan Coates
f7a6aac657 Bump CC:T to 1.113.1 2024-09-11 18:27:13 +01:00
Jonathan Coates
782564e6ab Write colour channel as a single int
Should be a little more efficient than writing four bytes separately.
2024-09-11 18:27:13 +01:00
Jonathan Coates
6b8ba8b80b Shadow netty rather than jar-in-jaring
Under Forge, netty-codec lives on the BOOT layer. However, this means it
does not have access to our jzlib (which lives on the GAME layer). To
fix this, we now shadow netty-codec (and its dependents, like netty-http
and netty-proxy) rather than jar-in-jaring them.

This involves some horrible build logic, but means websocket compression
works on Forge.

Fixes #1958.
2024-09-11 18:00:12 +01:00
Jonathan Coates
52b76d8886 Some stability fixes to client tests
- Place the player above the test region before running tests. This
   guarantees the client has the chunks loaded (and rendered) before we
   start running tests.

 - Reset the time after running the monitor/printout tests.

 - Fix rotation of turtle item models.

This still isn't perfect - the first test still fails with Iris and
Sodium - but is an improvement. Probably will still fail in CI though
:D:.
2024-09-11 10:13:39 +01:00
Jonathan Coates
ba36c69583 Use ARGB32 to store palette colours
Previously we used an RGBA byte array. However, this comes with some
overhead (extra memory reads, bounds checks).

Minecraft 1.21+ uses ARGB32 colours for rendering (well, in the public
code — internaly it converts to ABGR), so it makes sense to match that
here.

We also add some helper functions for dealing with ARGB32 colours. These
can be removed in 1.21, as Minecraft will have these builtin.
2024-09-11 10:13:39 +01:00
Jonathan Coates
370e5f92a0 Wait until the turtle has gone in explosion tests
Rather than a fixed delay. This should help when turtle tasks are
running a little slow.
2024-09-11 08:52:42 +01:00
Jonathan Coates
36d05e4774 Some small optimisations to textutils.urlEncode
This probably isn't useful in practice — nobody is escaping 1MB of data.
Right. Right???? But no harm in doing it.

 - Cache globals as locals.
 - Remove redundant pattern capture.
 - Merge string.format calls into one.

Also remove the "if str then" check. I assume we accepted nil values a
long time ago, but that was broken when we added arg checks. Woops!
2024-08-30 10:15:24 +01:00
Jonathan Coates
89d1be17c9 Make common's CC:T dependencies api, not impl
While mods shouldn't be depending on common, sometimes it's unavoidable
(e.g. for cc-prometheus). In those cases, you want all the CC classes
available, not just the common ones.
2024-08-30 09:35:48 +01:00
Jonathan Coates
0069591af9 Fix overflow when converting recursive objects to Lua
In cdcd82679c, we rewrote the Lua
conversion function to update the "Java -> Lua" mapping after
conversion, rather than part way through.

This made the code a little cleaner (as we only updated the mapping in
one place), but is entirely incorrect — we need to store the object
first, in order to correctly handle recursive objects — otherwise we'll
just recurse infinitely (or until we overflow).

This partially reverts the above commit, while preserving the new
behaviour for singleton collections.

Fixes #1955.
2024-08-25 09:24:10 +01:00
Jonathan Coates
c36c8605bf Mention Crowdin in our documentation 2024-08-24 22:55:14 +01:00
Jonathan Coates
3c72a00d46 Write translations to the root 2024-08-24 18:46:22 +01:00
Jonathan Coates
58aefc8df8 Add Crowdin config
We may end up reverting this, but let's give it a go at least.
2024-08-24 18:29:17 +01:00
Konuma Takaki
97ddfc2794 Japanese translation update (#1950) 2024-08-22 09:43:55 +00:00
Jonathan Coates
4f15f4197b Fix turtle owning player not being set
Fixes #1948, fixes #1949
2024-08-21 18:01:58 +01:00
Jonathan Coates
6e4ec86586 Fix repeated words in DFPWM docs
Even more of these! I really need to stop getting bored half way through
writing sentences and then continue writing at the wrong place. Or,
y'know, get better at proof reading.
2024-08-20 09:22:04 +01:00
Jonathan Coates
0d8ac304c7 Merge branch 'mc-1.20.x' into mc-1.21.x 2024-08-19 20:54:14 +01:00
Jonathan Coates
fdd5f49369 Update JEI to fix crash with NF 2024-08-19 18:28:59 +01:00
Jonathan Coates
d24984c1d5 Bump CC:T to 1.113.0 2024-08-19 18:28:22 +01:00
Jonathan Coates
8080dcdd9e Fix pocket computers not being active in the off-hand
While Item.inventoryTick is passed a slot number, apparently that slot
corresponds to the offset within a particular inventory compartment
(such as the main inventory or armour)[^1], rather than the inventory as
a whole.

In the case of the off-hand, this means the pocket computer is set to be
in slot 0. When we next tick the computer (to send terminal updates), we
then assume the item has gone missing, and so skip sending updates.

Fixes #1945.

[^1]: A fun side effect of this is that the "selected" flag is true for
  the off-hand iff the player has slot 0 active. This whole thing feels
  like a vanilla bug, but who knows!
2024-08-19 17:34:39 +01:00
Jonathan Coates
d7cea55e2a Add recipes for pocket computers too
This is a little daft (recipes feel a little clumsy and tacked on), but
it's better than them being nowhere.
2024-08-19 08:10:50 +01:00
Jonathan Coates
9b2f974a81 Some tweaks to the turtle docs
- Mention only diamond tools can be used as upgrades, and be clearer
   that only the pickaxe and sword are actually useful. We probably
   could be more explicit here, but struggled to find a way to do that.

 - Expliitly list which peripherals can be equipped.

 - Add turtle recipes.
2024-08-19 08:06:00 +01:00
Jonathan Coates
43770fa9bd Remove usage of deprecated legacy Java Date API
I've been staring at this warning for years, and ignored it thinking it
would be a pain to fix. I'm a fool!
2024-08-18 12:56:36 +01:00
Jonathan Coates
80c7a54ad4 Test path manipulation methods sanitise correctly
There's some nuance here with pattern vs non-pattern characters, so
useful to test for that.
2024-08-18 12:49:33 +01:00
Jonathan Coates
e57b6fede2 Test behaviour of fs.getName/getDir with relative paths
It's not entirely clear what the correct behaviour of fs.getDir("..")
should be, and there's not much consensus between various languages.

I think the intended behaviour of this function is to move "up" one
directory level in the path, meaning it should return "../..".
2024-08-18 11:38:10 +01:00
Jonathan Coates
34a2fd039f Clarify behaviour of readAll at the end of a file
This should return an empty string, to match PUC Lua.
2024-08-18 11:03:17 +01:00
Jonathan Coates
3299d0e72a Search for items in the whole gametest structure
This fixes some flakiness where items get thrown outside a 1 block
radius.
2024-08-18 10:53:40 +01:00
Jonathan Coates
b89e2615db Don't add lore to item details when empty 2024-08-18 10:28:16 +01:00
Jonathan Coates
cdcd82679c Don't share singleton collections
CC tries to preserve sharing of objects when crossing the Lua/Java
boundary. For instance, if you queue (or send over a modem)
`{ tbl, tbl }`, then the returned table will have `x[1] == x[2]`.

However, this sharing causes issues with Java singletons. If some code
uses a singleton collection (such as List.of()) in multiple places, then
the same Lua table will be used in all those locations. It's incredibly
easy to accidentally, especially when using using Stream.toList.

For now, we special case these collections and don't de-duplicate them.
I'm not wild about this (it's a bit of a hack!), but I think it's
probably the easiest solution for now.

Fixes #1940
2024-08-18 10:20:54 +01:00
Jonathan Coates
cdfa866760 Fix several repeated words
Depressing how many of these there are. Some come from Dan though
(including one in the LICENSE!), so at least it's not just me!
2024-08-17 11:39:14 +01:00
Jonathan Coates
aa8078ddeb Allow placing printouts in lecterns
- Add a new custom lectern block, that is used to hold the printed
   pages. We have to roll quite a lot of custom logic, so this is much
   cleaner than trying to mixin to the existing lectern code.

 - Add a new (entity) model for printed pages and books placed on a
   lectern. I did originally think about just rendering the item (or the
   in-hand/map version), but I think this is a bit more consistent with
   vanilla.

   However, we do still need to sync the item to the client (mostly to
   get the current page count!). There is a risk of chunkbanning here,
   but I think it's much harder than vanilla, due to the significantly
   reduced page limit.
2024-08-15 21:19:13 +01:00
Jonathan Coates
7e53c19d74 Add a specialised menu for printouts
Rather than having a general "held-item" container, we now have a
specialised one for printouts. This now is a little more general,
supporting any container (not just the player inventory), and syncs the
current page via a data slot.

Currently this isn't especially useful, but should make it a little
easier to add lectern support in the future.
2024-08-15 20:58:09 +01:00
Jonathan Coates
b7a8432cfb Fix turtles capturing their own drops when broken
There's a whole load of gnarly issues that occur when a turtle is broken
mid-dig/attack (normally due to an explosion). We fixed most of these in
24af36743d, but not perfectly.

Part of the fix here was to not capture drops if the turtle BE has been
removed. However, on removal, turtles drop their items *before* removing
the BE. This meant that the drop consumer still triggered, and attempted
to insert items back into the turtle.

This bug only triggers if the turtle contains a stack larger than 10
(ish, I think) items, which is possibly why I'd never reproduced before.

We now drop items after removing the BE, which resolves the issue.

Fixes #1936.
2024-08-15 10:32:54 +01:00
Jonathan Coates
356c8e8aeb Fix disk drives not setting/clearing removed flag
This was originally noticed on 1.21, as it causes disk drives to not be
detected as peripherals. However, things will still be broken (albeit
more subtly) on 1.20, so worth fixing here.
2024-08-15 09:03:33 +01:00
Jonathan Coates
ed283155f7 Update to Gradle 8.10 2024-08-15 08:49:46 +01:00
Jonathan Coates
87dfad026e Add a test for exploding turtles
There's been a couple of bug reports in the past where the game would
crash if a turtle is destroyed while breaking a block (typically due to
the block exploding). This commit adds a test, to ensure that this is
handled gracefully.

I'm not entirely sure this is testing the right thing. Looking at the
issues in question, it doesn't look like I ever managed to reproduce the
bug. However, it's hopefully at least a quick sanity test to check we
never break this case.
2024-08-14 22:41:31 +01:00
Jonathan Coates
bb97c465d9 Fix computers/turtles not being dropped on explosion
Computer drops are currently[^1] implemented via a dynamic drop. To
support this, we need to inject the dynamic drop into the loot
parameters.

We currently do this by implementing our own drop logic in
playerWillDestroy[^2], manually creating the loot params and adding our
additional drop. However, if the item is dropped via some other method
(such as via explosions), we'll go through vanilla's drop logic and so
never add the dynamic drop!

The correct way to do this is to override getDrops to add the dynamic
drop instead. I don't know why we didn't always do this -- the code in
question was first written for MC 1.14[^3], when things were very
different.

[^1]: This is no longer the case on 1.21, where we can just copy
      capabilities.

[^2]: We need to override vanilla's drop behaviour to ensure items are
      dropped in creative mode.

[^3]: See 594bc4203c. Which probably means
      the bug has been around for 5 years :/.
2024-08-14 21:12:30 +01:00
Jonathan Coates
8bd4c3370e Update to Minecraft 1.21.1
I'm not sure we *need* to do this (the two versions are compatible), but
probably a good idea anyway.
2024-08-14 18:38:07 +01:00
Jonathan Coates
3eb84ffedd Fix several data fixer issues
Disk IDs and treasure disk colour were not being correctly converted.
This also adds several tests to ensure that these items are handled
correctly.

Closes #1934.
2024-08-14 09:24:07 +01:00
Jonathan Coates
9484315d37 Fix return type of Vector.dot
Closes #1932
2024-08-11 14:11:14 +01:00
Jonathan Coates
be59f1a875 Clarify some quicks of JSON serialisation
There's a mismatch between how Lua and JSON's values are defined, which
means that serialisation is a little confusing at times. This commit
attempts to document them a little better.

Closes #1885, closes #1920
2024-08-11 12:25:28 +01:00
Jonathan Coates
bfb28b4710 Log current block entity in TickScheduler
This check should be impossible (the BE has not been removed, but is no
longer present in the world), but we've had one instance where it has
happened (#1925). I don't have a good solution here, so at least let's
print both BEs for now.
2024-08-11 12:03:48 +01:00
JackMacWindows
216f0adb3c Fix a couple of typos in fluid method docs
Also mention ffmpeg can now encode/decode DFPWM.
2024-08-11 11:55:11 +01:00
Jonathan Coates
dad6874638 Add detail provider for data components
Historically we'd provide specific data based on the current item and
NBT (hence BasicItemDetailProvider). However, with components, it now
makes sense to provide details for all items with a specific component.

This commit adds a new "ComponentDetailProvider" class, that reads a
component from an item stack (or other component holder) and provides
details about it if present.
2024-08-11 11:53:16 +01:00
Jonathan Coates
77af4bc213 Fix a couple of typos in fluid method docs 2024-08-11 11:51:40 +01:00
Jonathan Coates
5abab982c7 Allow registering more generic detail providers
Allow registering details providers matching any super type, not just
the exact type. This is mostly useful for 1.21, where we can have
providers for any DataComponentHolder, not just item stacks.
2024-08-11 11:51:40 +01:00
Jonathan Coates
764e1aa332 Merge pull request #1924 from viluon/fix/get-next-version
Fix getNextVersion
2024-08-04 14:50:19 +01:00
Andrew Kvapil
c47718b09d Fix getNextVersion 2024-08-04 14:57:09 +02:00
Jonathan Coates
45cb597ecc Merge branch 'mc-1.20.x' into mc-1.21.x 2024-07-31 07:34:49 +01:00
Jonathan Coates
08d4f91c8b Bump CC:T to 1.112.0 2024-07-31 07:05:08 +01:00
Jonathan Coates
b9eac4e509 Computer components (#1915)
This adds a new mechanism for attaching additional objects to a
computer, allowing them to be queried by other mods. This is primarily
designed for mods which add external APIs, allowing them to add APIs
which depend on the computer's position or can interact with the turtle
inventory.

I will stress that the use-cases for custom APIs are few and far
between. Almost all the time a peripheral would be the better option,
and I am wary that this PR will encourage misuse of APIs. However, there
are some legitimate use-cases, and I think we should enable them.

 - Add a new "ComputerComponent" class, and several built-in components
   (for turtle, pocket and command computers).

 - Add a method to `IComputerSystem` to read a component from the
   computer. We also add methods to get the level and position of the
   computer.

 - Move all our existing APIs (built-in turtle, pocket, command) to use
   the public API.
2024-07-31 06:57:38 +01:00
Jonathan Coates
16577783d3 Fix incorrect offset in turtle crafting
This means we end up looking at the wrong slots, and thus fail to remove
items! Fixes #1918.
2024-07-31 06:40:37 +01:00
Jonathan Coates
c179da28f0 Make turtle colour opaque in BER
Fixes #1893
2024-07-31 06:30:43 +01:00
Jonathan Coates
dc3d8ea198 Move API factories to the common package
We don't actually use this functionality in other projects (e.g.
emulators). In fact the method to add new APIs only exists in the mod
itself!

We still need some mechanism to remove mounts when the computer is
shutdown. We add a new ApiLifecycle interface (with startup and
shutdown hooks), and use those in the ComputerSystem impl.
2024-07-29 19:46:25 +01:00
Jonathan Coates
cbe075b001 Expose level+position in IPocketAccess
This allows pocket upgrades (modems and speakers) to read the position
directly, rather than checking whether the entity is present.
2024-07-28 21:15:25 +01:00
Jonathan Coates
ed0b156e05 Attempt at splitting up pocket computer logic
Oh, I hate the pocket computer code so much. Minecraft was really not
designed to attach this sort of behaviour to computers. This commit is
an attempt of cleaning this up[^1].

Firstly, we move the the pocket computer state (upgrades, light) out of
PocketServerComputer and into a new PocketBrain class. This now acts as
the sole source-of-truth, with all state being synced back to the
original item stack on the entity tick.

This also adds a new PocketHolder interface, which generalises over the
various types that can hold a pocket computer (players and item
entities right now, possibly lecterns in the future).

[^1]: I'd say simplifying, but this would be a lie.
2024-07-28 21:13:07 +01:00
Jonathan Coates
2765abf971 Udpate to latest Neo, Fabric and Parchment
- Update to latest NeoForge, fixing issues with config API changes.
   Closes #1903.
 - Update to latest Fabric, switching to the ender pearl conventional
   tag, and new loot API.
2024-07-28 16:47:41 +01:00
Jonathan Coates
4dd0735066 Register modems as attached to their adjacent block
In c8eadf4011 we marked our various modems
as "brittle", which ensures they do not pop-off computers when the whole
structure moves.

However, this still requires the modem to be glued — if the modem is
outside the superglue range, it will still pop off. We can fix it by
registering a special "attached check" for the various modem blocks,
which says that the modem should be moved when the adjacent block does.

Fixes #1913
2024-07-26 18:28:13 +01:00
Jonathan Coates
38e516d7c7 Update to Reuse 4.0 2024-07-26 18:28:00 +01:00
Jonathan Coates
70a31855ac Only send pocket computer updates to players in range
Previously we sent it to all players in the current level. This updates
the check to only send it to players tracking the current chunk.
2024-07-26 10:07:26 +01:00
Jonathan Coates
6c8e64ffcd Add get/setUpgrade to IPocketAccess
We have similar methods in ITurtleAccess, so makes sense for them to be
here too.
2024-07-26 09:51:09 +01:00
Jonathan Coates
7285c32d58 Document that the speaker re-encoded audio samples 2024-07-25 20:32:08 +01:00
Jonathan Coates
99c60ac54b Remove IComputerBlockEntity
We only really made use of it in the has_computer_id loot condition, so
probably easier to remove it.
2024-07-25 09:28:00 +01:00
Jonathan Coates
63e40cf3cb Add a cc.strings.split method
This is largely copied from metis, with the documentation updated.
2024-07-24 22:18:50 +01:00
Jonathan Coates
1d45935a25 Update links to IRC
The EsperNet webchat has been decommissioned, with no plans to
replace. KiwiIRC is the recommended replacement, but I'm not comfortable
using it as a drop-in replacement[^1], so I've rephrased this section to
make it more clear.

[^1]: There seems to be ongoing issues with TLS certificates
  (https://github.com/kiwiirc/kiwiirc/issues/1870), which meant it
  wasn't usable when I first tried.
2024-07-24 21:38:14 +01:00
Jonathan Coates
f80373e7a2 Add bounds check to cc.strings.wrap
Fixes #1905, closes #1906.

Co-authored-by: Lupus590 <lupussolitarius590@gmail.com>
2024-07-24 19:40:10 +01:00
Jonathan Coates
63185629b7 Use "require" in textutils
This avoids us having to support requireless environments inside
cc.strings.

I do kinda wonder if os.loadAPI-loaded files should also have their own
shared "require", just so we're not loading 10 copies of cc.expect.
2024-07-24 19:40:10 +01:00
Jonathan Coates
4bfb9ac323 Fix/update language checker script
- Update location of the generated language file to point to common
   rather than Fabric.
 - Remove usage of OrderedDict, as dicts are ordered on recent versions
   of Python.
2024-07-24 19:40:09 +01:00
Jonathan Coates
5926b6c994 Update Gradle to 8.9
Fix several deprecation warnings, and specify the toolchain required to
launch the daemon.
2024-07-24 19:40:09 +01:00
Jonathan Coates
f5ed43584d Add tests for turtle equipping and crafting 2024-07-24 19:40:09 +01:00
Jonathan Coates
2c740bb904 Bump CC:T to 1.111.1 2024-07-04 19:08:06 +01:00
csqrb
d77f5f135f Preserve item data when upgrading pocket computers (#1888) 2024-07-03 07:21:02 +00:00
Jonathan Coates
0e4710a956 Update NF and NG
- Rename ToolActions to ItemAbilities. Closes #1881.
 - Remove our source set helper, as NG has built-in support for this
   now.
 - Remove our code to generate new JavaExec tasks from runs, as NG now
   generates JavaExec tasks normally.
2024-06-29 12:58:03 +01:00
Jonathan Coates
aca1d43550 Merge branch 'mc-1.20.x' into mc-1.21.x 2024-06-29 10:50:44 +01:00
Jonathan Coates
f10e401aea Load turtle overlays from a registry
- Add a new computercraft:turtle_overlay dynamic registry, which stores
   turtle overlays. Turtle overlays are just a model id and an
   (optional) boolean flag, which specifies whether this overlay is
   compatible with the elf/christmas model.

 - Change the computercraft:overlay component to accept a
   Holder<TurtleOverlay> (instead of just a model ID). This accepts both
   an overlay ID or an inline overlay object (e.g. you can do
   cc:turtle_normal[computercraft:overlay={model:"foo"}].

 - Update turtle model and BE rendering code to render both the overlay
   and elf (if compatible). Fixes #1663.

 - Ideally we'd automatically load all models listed in the overlay
   registry. However, resource loading happens separately to datapacks,
   so we can't link the two.

   Instead, we add a new assets/computercraft/extra_models.json file
   that lists any additional models that should be loaded and baked.

   This file includes all built-in overlay models, but external resource
   packs and/or mods can easily extend it.
2024-06-27 20:57:43 +01:00
Jonathan Coates
7744d2663b Fix heights of turtle flags
They were 0.5 squares too high, so the textures were a little stretched.
2024-06-27 20:41:42 +01:00
Jonathan Coates
4566cb8273 Add path-based error constructor to FileSystemException
This doesn't change any functionality, but means we only construct
"/{path}: {message}" strings in one location.
2024-06-26 21:12:44 +01:00
Jonathan Coates
052e7a7ae5 Make FileSystem.toLocal private
Use a custom to-local function in the various ArchiveMounts, which don't
faff around with sanitising paths.
2024-06-26 21:12:05 +01:00
Jonathan Coates
0895200681 Small bits of cleanup
Build system:
 - Switch to our new maven server. This has a cleaner separation between
   published packages and mirrored packages, to avoid leaking those into
   other people's builds.
 - Update Gradle and Loom versions.

Code:
 - Link to definitions instead in the breaking changes page.
 - Fix several unused variable warnings.

Other:
 - Remove unsupported Minecraft versions from the issue template.
2024-06-26 18:07:57 +01:00
Jonathan Coates
1a1623075f Fix turtle labels not rendering
The X scale factor should now be flipped. I'm not quite sure what in MC
has meant this should be changed, possibly the cameraOrientation matrix?

Fixes #1872
2024-06-26 18:06:48 +01:00
Jonathan Coates
54a95e07a4 Fix monitors not updating on NeoForge 2024-06-23 09:21:15 +01:00
Jonathan Coates
09d0f563b7 Add 1.21 to version list 2024-06-23 09:14:32 +01:00
Jonathan Coates
e188f1d3fa Link to os.time in os.setAlarm docs 2024-06-23 08:43:42 +01:00
Jonathan Coates
efd9a0f315 Fix JEI integration for MC 1.21
- Use the client side registry access (possible now that we've moved
   JEI to the client).

 - Generate unique ids for JEI recipes.
2024-06-22 22:48:37 +01:00
Jonathan Coates
28f75a0687 Merge branch 'mc-1.20.x' into mc-1.21.x 2024-06-22 22:33:18 +01:00
Jonathan Coates
819a4f7231 Hide a few ServerComputer internals 2024-06-22 18:48:31 +01:00
Jonathan Coates
898cb2a95d Remove CommandComputerBlockEntity
Due to the earlier commits, the only functionality this block entity
adds is to register the command API. This commit:

 - Add the command API when constructing the ServerComputer instead.
   This is not a good long-term solution (I think we need to make API
   factories more powerful), but is sufficient for now.

 - Replace usages of CommandComputerBlockEntity with a normal
   ComputerBlockEntity.
2024-06-22 18:19:00 +01:00
Jonathan Coates
03a8f83191 Unify command computer permission checks
- Move the command permisssion checks to a new
   ComputerFamily.checkUsable method (from
   CommandComputerBlockEntity and ViewComputerMenu). I don't feel great
   about putting new functionality in ComputerFamily (trying to move
   away from it), but I think this is fine for now.

 - Use this method from within the computer menu and computer block, to
   check whether computers can be interacted with.

 - Remove ViewComputerMenu, as it now no longer needs any special
   is-usable logic.
2024-06-22 18:08:04 +01:00
Jonathan Coates
aef92c8ebc Remove pocket computer GUI
Historically we used to have separate menu types for computers and
pocket computers, as the screen had to be initialised with the correct
terminal size.

However, as of c49547b962 (which was
admittedly two years ago now), we have the terminal available when
constructing the screen, and so the code for the two is identical.

This change actually merges the two screens, replacing usages of the
pocket computer UI with the computer one.
2024-06-22 17:41:49 +01:00
Jonathan Coates
571ea794a8 Decouple CommandAPI from the command computer BE
All we really need for its implementation is a level and position, which
we can get directly from the server block entity!
2024-06-22 17:18:21 +01:00
Jonathan Coates
4b102f16b3 Update to Minecraft 1.21
API Changes:

 - Minecraft had updated ModelResourceLocation to no longer inherit from
   ResourceLocation.

   To allow referencing both already baked models
   (ModelResourceLocation) and loading new models (via ResourceLocation)
   in turtle model loadders, we add a new "ModelLocation" class, that
   acts as a union between the two.

   I'm not entirely convinced by the design here, so might end up
   changing again before a stable release.o

 - Merge IMedia.getAudioTitle and IMedia.getAudio into a single
   IMedia.getAudio method, which now returns a JukeboxSong rather than a
   SoundEvent.

Other update notes:
 - Minecraft had rewritten how buffers are managed again. This is a
   fairly minor change for us (vertex -> addVertex, normal -> setNormal,
   etc...), with the exception that you can no longer use
   MultiBufferSource.immediate with the tesselator.

   I've replaced this with GuiGraphics.bufferSource, which appears to be
   fine, but worth keeping an eye on in case there's any odd render
   state issues.

 - Crafting now uses a CraftingInput (a list of items) rather than a
   CraftingContainer, which allows us to simplify turtle crafting code.
2024-06-22 16:19:59 +01:00
Jonathan Coates
e81af93043 Move JEI to client folder
I hadn't realised this, but plugins are only loaded on the client. This
is useful on 1.21, as we now have easy access to a holder lookup.
2024-06-22 13:23:03 +01:00
Jonathan Coates
bb933d0100 Merge branch 'mc-1.20.x' into mc-1.20.y 2024-06-21 08:36:18 +01:00
Jonathan Coates
25b8a65c5c Fix drive.getAudioTitle returning null for no disk
Historically (and according to the docs) getAudioTitle returned "false"
when the drive was empty (or had invalid media), and "null" when the
disk had no item. This was accidentally changed in a later refactor --
this change fixes that behaviour.
2024-06-21 07:54:18 +01:00
Jonathan Coates
e4236824d7 Revert "Changed Heart Character (-3 pixels)"
This reverts commit d9b0cc7075.

I'm not sure what happened here, but the font is just entirely offset.
This is on me for not noticing during review. 🤦
2024-06-20 19:03:17 +01:00
Jonathan Coates
cfd11ffa92 Support dark and light mode logos on the website
Requires an illuaminate bump to support <picture> tags.

Fixes #1861.
2024-06-20 18:32:01 +01:00
Jonathan Coates
ce133a5e66 Update Minecraft wiki link
We didn't update this at the same time as the other links, as it pointed
to an even older wiki URL!
2024-06-19 22:01:51 +01:00
Jonathan Coates
038fbc1ed1 Merge pull request #1823 from Bluerella/mc-1.20.x
Changed Heart Character (-3 pixels)
2024-06-19 21:41:55 +01:00
Weblate
c582fb521c Translations for German
Co-authored-by: Lord Duck <maximilian.schueller@hotmail.com>
2024-06-19 14:52:42 +00:00
Jonathan Coates
af21792844 Publish docs via an artifact instead
We'll deploy this via a webhook instead.
2024-06-19 09:57:56 +01:00
Jonathan Coates
9fbb1070ef Remove redundant helper method from datagen
Vanilla has had an equivalent method for a few years now!
2024-06-14 22:12:16 +01:00
Jonathan Coates
1944995c33 Update CCF links to my mirror 2024-06-11 20:27:06 +01:00
Jonathan Coates
ac851a795b Fix command.getBlockInfos indexing expression
And add an example, to make it all a little clearer
2024-06-06 20:04:32 +01:00
Weblate
334761788a Translations for Chinese (Simplified)
Co-authored-by: Kevin Z <zyxkad@gmail.com>
2024-06-05 18:24:44 +00:00
Jonathan Coates
5af3e15dd5 Nicer lexer error for "!" 2024-05-28 20:16:32 +01:00
Jonathan Coates
de078e3037 Merge branch 'mc-1.20.x' into mc-1.20.y 2024-05-28 18:46:19 +01:00
Jonathan Coates
209b1ddbf9 Bump CC:T to 1.111.0 2024-05-28 18:19:13 +01:00
Jonathan Coates
0c9f9a8652 Warn when Optifine is installed
We keep getting bug reports on 1.20.1 about an Optifine bug that causes
Forge's capabilities to not work (#1458). The cause of this bug is not
immediately visible to users, and can be very confusing when hit.

Optifine have not released a fix for this bug (despite it being reported
a year ago), and we continue to receive bug reports about it.

Nobody likes it when mods complain about other mods. So much Minecraft
drama can be traced back to this, and it's a slippery slope to go down.
I've tried to keep this as unobtrusive as possible — it's just a chat
message at world join, and it'll turn off if the bug is fixed.
2024-05-28 18:10:50 +01:00
Jonathan Coates
862d92785e Don't expose a menu provider for computers
We can't safely use this anyway (as custom data is not sent), so better
not to expose it at all. Fixes #1844.
2024-05-28 09:47:12 +01:00
Jonathan Coates
d48b85d50c Add r+/w+ support to io library 2024-05-26 10:16:33 +01:00
Jonathan Coates
4d619de357 Don't publish Gradle module metadata for common
Fixes #1842
2024-05-26 09:34:10 +01:00
Daniel Ratcliffe
57c289f173 Allow planks to be used for building in "adventure" 2024-05-25 10:04:45 +01:00
Jonathan Coates
f63f85921f Fix missing quotes in the settings example 2024-05-19 08:38:41 +01:00
Jonathan Coates
c7e49d1929 Use RecordItem.getDisplayName to get audio title
Rather than constructing the component manually. This should be more
compatible with mods that override getDisplayName.
2024-05-09 22:54:03 +01:00
Jonathan Coates
eb584aa94d Translate remaining item tags
These shouldn't appear in recipes, but just to stop Fabric complaining
:).
2024-05-09 18:47:28 +01:00
Jonathan Coates
ad70e2ad90 Make printout recipes a little more flexible
Rather than having one single hard-coded recipe, we now have separate
recipes for printed pages and printed books. These recipes are defined
in terms of

 - A list of ingredients (like shapeless recipes).
 - A result item.
 - An ingredient defining the acceptable page items (so printed page(s),
   but not books). This cannot overlap with any of the main ingredients.
 - The minimum number of printouts required.

We then override the shapeless recipe crafting logic to allow for
multiple printouts to appear.

It feels like it'd be nice to generalise this to a way of defining
shapeless recipes with variable-count ingredients (for instance, the
disk recipe could also be defined this way), but I don't think it's
worth it right now.

This solves some of the issues in #1755. Disk recipes have not been
changed yet.
2024-05-09 18:47:22 +01:00
Ella
d9b0cc7075 Changed Heart Character (-3 pixels) 2024-05-09 01:59:31 +05:30
Jonathan Coates
2c0d8263d3 Update to MC 1.20.6
- Update EMI and REI integration, and fix some issues with the upgrade
   crafting hooks.
 - Just use smooth stone for recipes, not #c:stone. We're mirroring
   redstone's crafting recipes here.
 - Some cleanup to printouts.
 - Remote upgrade data generators - these can be replaced with the
   standard registry data generators.
 - Remove the API's PlatformHelper - we no longer have any
   platform-specific code in the API.
2024-05-07 22:59:53 +01:00
Jonathan Coates
1e214f329e Build docs for all MC versions 2024-05-06 09:59:09 +01:00
Jonathan Coates
de930c8d09 Split up turtle textures (#1813)
Turtles currently read their textures from a single 128x128 sprite
sheet. Most of this texture is unused which means we end up wasting a
lot of the block texture atlas[^1].

This change splits up the turtle textures into individual 32x32
textures[^2], one for each side, and then an additional backpack
texture.

I'm very sorry to any resource pack artists out there. The
tools/update-resources.py script will update existing packs, but does
not (currently) handle non-standard resolutions.

[^1]: It used to be worse: https://github.com/dan200/ComputerCraft/issues/145

[^2]: Turtle textures are a bit weird, in that they mostly *look* 16x16,
  but have some detail in places.
2024-04-30 20:58:07 +00:00
Jonathan Coates
94c864759d Ignore enchantments/attributes on the original item
Turtle tools were not equippable, as we considered the stack enchanted
due to the item's base attribute modifiers. We now only check the
component patch for enchantments/attribute modifiers.

This also removes the craftItem property of tools - this hasn't worked
since we added support for enchanted tools!

Fixes #1810
2024-04-29 21:07:04 +01:00
Weblate
735e7ce09b Translations for Italian
Co-authored-by: Alessandro <ale.proto00@gmail.com>
2024-04-29 19:00:14 +00:00
Jonathan Coates
2226df7224 Small cleanup after testing
- Use TinyRemapper to remap mixins on Fabric. Mixins in the common
   project weren't being remapped correctly.

 - Update to latest NeoForge
   - Switch to the new tick events.
   - Call refreshDimensions() in the fake player constructor.
2024-04-28 22:02:12 +01:00
Jonathan Coates
959bdaeb61 Use a single upgrade type for modems
Replace turtle_modem_{normal,advanced} with a single turtle_modem
upgrade (and likewise for pocket upgrades). This is slightly more
complex (we now need a custom codec), but I think is more idiomatic.
2024-04-28 20:38:30 +01:00
Jonathan Coates
06ac373e83 Use components for upgrade adjectives
This makes quick-and-dirty datapacks a little easier, as you can now use
a hard-coded string rather than adding a language key.
2024-04-28 20:07:15 +01:00
Jonathan Coates
0aca6a4dc9 Remove several unused test files 2024-04-28 19:54:39 +01:00
Jonathan Coates
bf203bb1f3 Rewrite upgrades to use dynamic registries
Ever since 1.17, turtle and pocket upgrades have been loaded from
datpacks, rather than being hard-coded in Java. However, upgrades have
always been stored in our own registry-like structure, rather than using
vanilla's registries.

This has become a bit of a problem with the introduction of components.
The upgrade components now hold the upgrade object (rather than just its
id), which means we need the upgrades to be available much earlier (e.g.
when reading recipes).

The easiest fix here is to store upgrades in proper registries instead.
This means that upgrades can no longer be reloaded (it requires a world
restart), but otherwise is much nicer:

 - UpgradeData now stores a Holder<T> rather than a T.

 - UpgradeSerialiser has been renamed to UpgradeType. This now just
   provides a Codec<T>, rather than JSON and network reading/writing
   functions.

 - Upgrade classes no longer implement getUpgradeID(), but instead have
   a getType() function, which returns the associated UpgradeType.

 - Upgrades are now stored in turtle_upgrade (or pocket_upgrade) rather
   than turtle_upgrades (or pocket_upgrades). This will break existing
   datapacks, sorry!
2024-04-28 19:47:19 +01:00
Jonathan Coates
6e9799316a Update ErrorProne 2024-04-28 18:32:19 +01:00
Jonathan Coates
cd9840d1c1 Add workaround for inventory method test failure 2024-04-26 22:06:29 +01:00
Jonathan Coates
b9a002586c Update turtle reach limits to 1.20.5
We can replace our mixins with vanilla's built-in attributes.
2024-04-26 21:44:19 +01:00
Jonathan Coates
a3b07909b0 Replace some recipes with a more dynamic system
This adds a new "recipe function" system, that allows transforming the
result of a recipe according to some datapack-defined function.

Currently, we only provide one function: computercraft:copy_components,
which copies components from one of the ingredients to the result. This
allows us to replace several of our existing recipes:

 - Turtle overlay recipes are now defined as a normal shapeless recipe
   that copies all (non-overlay) components from the input turtle.

 - Computer conversion recipes (e.g. computer -> turtle, normal ->
   advanced) copy all components from the input computer to the result.

This is more complex (and thus more code), but also a little more
flexible, which hopefully is useful for someone :).
2024-04-26 21:44:18 +01:00
Jonathan Coates
d7786ee4b9 Merge branch 'mc-1.20.x' into mc-1.20.y 2024-04-26 18:38:15 +01:00
Jonathan Coates
4e90240922 Bump CC:T to 1.110.3 2024-04-26 18:22:06 +01:00
Jonathan Coates
1a87d1bf45 Move shared generated resources to common project
In 1.20.1, Forge and Fabric have different "common" tag conventions (for
instance, Forge uses forge:dusts/redstone, while Fabric uses
c:redstone_dusts). This means the generated recipes (and advancements)
will be different for the two loader projects. As such, we run data
generators for each loader, and store the results separately.

However, aside from some recipes and advancements, most resources /are/
the same between the two. This means we end up with a lot of duplicate
files, which make the diff even harder to read. This gets worse in
1.20.5, when NeoForge and Fabric have (largely) unified their tag names.

This commit now merges the generated resources of the two loaders,
moving shared files to the common project.

 - Add a new MergeTrees command, to handle the de-duplication of files.
 - Change the existing runData tasks to write to
   build/generatedResources.
 - Add a new :common:runData task, that reads from the
   build/generatedResources folder and writes to the per-project
   src/generated/resources.
2024-04-26 18:09:08 +01:00
Jonathan Coates
188806e8b0 Actually update NeoForge to 1.20.5
NF now loads mods from neoforge.mods.toml rather than mods.toml, so CC
wasn't actually being loaded. Tests all passed, because they didn't get
run in the first place!
2024-04-26 17:57:20 +01:00
Jonathan Coates
01407544c9 Update to 1.20.5 (#1793)
- Switch most network code to use StreamCodec
 - Turtle/pocket computer upgrades now use DataComponentPatch instead of
   raw NBT.
2024-04-25 20:32:48 +00:00
Jonathan Coates
bd2fd9d4c8 Merge branch 'mc-1.20.x' into mc-1.20.y 2024-04-25 18:23:04 +01:00
Jonathan Coates
00e2e2bd2d Switch to vanilla's stillValid implementation 2024-04-25 18:21:23 +01:00
Jonathan Coates
7c1f40031b Some cleanup to network messages
- Use enums for key and mouse actions, rather than integer ids.
 - Change TerminalState to always contain a terminal. We now make
   TerminalState nullable when we want to skip sending anything.
2024-04-25 18:19:34 +01:00
Jonathan Coates
929debd382 Don't build the webside on Windows/Mac
It seems to stall on Mac, and unlike Windows, I don't have access to a
machine to debug it :/.
2024-04-24 21:49:49 +01:00
Jonathan Coates
4980b7355d Don't share CharsetDecoders across threads
Fixes #1803
2024-04-24 21:19:30 +01:00
Jonathan Coates
5c457950d8 Merge branch 'mc-1.20.x' into mc-1.20.y 2024-04-24 20:30:59 +01:00
Jonathan Coates
925092add3 Fix build on Windows
- Force encoding to UTF-8
 - Fix npm not being found on the path
 - Test building common/web on OSX and Windows
2024-04-24 17:55:48 +01:00
Jonathan Coates
550296edc5 Fix typo in speaker docs
Closes #1799
2024-04-21 09:45:02 +01:00
Jonathan Coates
0771c4891b Various Gradle tweaks
- Update Gradle to 8.7
 - Configure IntelliJ to build internally, rather than delgating to
   Gradle. We've seen some weird issues with using delegated builds, so
   best avoided.
 - Remove gitpod config. This has been broken for a while (used Java 16
   rather than 17) and nobody noticed, so I suspect nobody uses this.
2024-04-19 18:14:51 +01:00
Jonathan Coates
776fa00b94 Update to latest TeaVM
- Add the core TeaVM jar to the runtime the classpath, to ensure
   various runtime classes are present.
 - Fix computer initialisation errors not being displayed on the screen.
   The terminal was set to the default 0x0 size when logging the error,
   and so never displayed anything!
2024-04-17 21:57:11 +01:00
Jonathan Coates
03bb279206 Move computer right click code to the block
Rather than handling right clicks within the block entity code, we now
handle it within the block. Turtles now handle the nametagging
behaviour themselves, rather than overriding canNameWithTag.
2024-04-17 15:01:50 +01:00
Weblate
fabd77132d Translations for Czech
Co-authored-by: Patriik <apatriik0@gmail.com>
2024-04-09 08:54:05 +00:00
Jonathan Coates
95be0a25bf Update Cobalt to 0.9.3
- Fix some errors missing source positions
 - Poll interrupted state when parsing Lua
2024-04-08 12:18:21 +01:00
Jonathan Coates
75f3ecce18 Render printout pages further forward in the UI
Rather than rendering the background further back. This was causing some
of the pages to not be rendered. I'm not quite sure why this is -- there
shouldn't be any z-fighting -- but this does work as a fix!

Fixes #1777
2024-04-08 12:07:53 +01:00
Jonathan Coates
688fdc40a6 Don't render background in the off-hand pocket UI
Fixes #1778
2024-04-08 12:02:25 +01:00
Jonathan Coates
22bd5309ba Merge branch 'mc-1.20.x' into mc-1.20.y 2024-04-07 22:06:49 +01:00
Jonathan Coates
ad49325376 Bump CC:T to 1.110.2 2024-04-07 21:20:56 +01:00
Jonathan Coates
825d45eb26 Fix NPE when rendering turtle's label
Minecraft.hitResult may /technically/ be null when rendering a turtle.
In vanilla, this doesn't appear to happen, but other mods (e.g.
Immersive Portals) may still take advantage of this.

This hitResult is then propagated to BlockEntityRenderDispatcher, where
the field was /not/ marked as nullable. This meant we didn't even notice
the potential of an NPE!

Closes #1775
2024-04-06 08:46:19 +01:00
Jonathan Coates
8b2516abb5 Update to latest NullAway
This fixes several issues with @Nullable fields not being checked. This
is great in principle, but a little annoying in practice as MC's
@Nullable annotations are sometimes a little overly strict -- we now
need to wrap a couple of things in assertNonNull checks.
2024-04-06 08:38:44 +01:00
Jonathan Coates
bce099ef32 Allow mounting folders in the standalone emulator
This theoretically allows you to use the emulator to run the test suite
(via  --mount-ro projects/core/src/test/resources/test-rom/:test-rom),
but not sure how useful this is in practice.
2024-04-03 21:27:18 +01:00
Jonathan Coates
6d14ce625f Use the correct modem in create:brittle
I tested this in-game, I swear! Just, typically, only with ender and
wired modems.
2024-04-03 09:29:31 +01:00
Jonathan Coates
c8eadf4011 Register CC's modems as brittle
This tells Create that modems will pop-off if their neighbour is moved,
and so changes the order that the block is moved in.

We possibly should use BlockMovementChecks.AttachedCheck instead, to
properly handle the direction modems are facing in. However, this
doesn't appear to be part of the public API, so probably best avoided.

Fixes #948
2024-04-03 08:44:30 +01:00
Jonathan Coates
0c1ab780bb Validate arguments in the vector API
This doesn't produce the best error messages (should "self" be argument
0 or 1?), but is better than throwing errors in vector's internals.
2024-04-01 22:25:08 +01:00
Jonathan Coates
0f623c2cca Move can-place modem logic to one place
This should make future changes easier. Closes #1769.
2024-04-01 13:55:44 +01:00
Matthew Wilbern
b9ba2534a4 speaker sound command (#1747) 2024-03-29 10:24:11 +00:00
Jonathan Coates
c764981a40 Merge pull request #1761 from cc-tweaked/feature/no-play-record
Prevent playing music discs with speaker.playSound
2024-03-29 07:55:31 +00:00
Jonathan Coates
6363164f2b Fix creating a zero-sized pocket terminal
When the terminal data is not present, width/height are set to 0, rather
than the terminal's width/height. This meant we'd create an empty
terminal, which then crashes when we try to render it.

We now make the terminal nullable and initialise it the first time we
receive the terminal data. To prevent future mistakes, we hide
width/height, and use TerminalState.create everywhere.

Fixes #1765
2024-03-26 21:59:41 +00:00
Jonathan Coates
63580b4acb Fallback to the current side when getting fluid cap
We did this for item caps in 9af1aa1ecf,
but makes sense to do this for fluid methods too.
2024-03-26 21:40:44 +00:00
Jonathan Coates
9af1aa1ecf Fallback to the current side when getting item cap
Fixes #1764
2024-03-25 08:59:08 +00:00
Jonathan Coates
ad0f551204 Merge pull request #1763 from cyberbit/patch-1
Fix cc.image.nft.draw signature
2024-03-24 15:18:44 +00:00
Jonathan Coates
0d3e00cc41 Small cleanup to OS API docs
- Mention the timer event in os.startTimer. Really we should have a
   similar example here too, but let's at least link the two for now.
 - Fix strftime link
2024-03-24 15:12:23 +00:00
cyberbit
836d6b939e Fix cc.image.nft.draw signature 2024-03-24 09:54:01 -05:00
Jonathan Coates
0e5248e5e6 Prevent playing music discs with speaker.playSound
I have mixed feelings about speaker.playSound. On one hand, it's pretty
useful to be able to play any sound. On the other, it sometimes feels
... maybe a little too magic?

One particular thing I don't like is that it allows you to play
arbitrary records, which sidesteps both a vanilla mechanic (finding
record discs) and existing CC functionality (disk.playAudio). We now
prevent playing record tracks from the speaker.
2024-03-24 12:53:57 +00:00
Jonathan Coates
e154b0db2a Fix speaker.playSound overwriting current sound
playSound should return false if we've already played a sound this tick,
rather than overwriting it.
2024-03-24 12:20:53 +00:00
Jonathan Coates
ae767eb5be Improve error when no path is passed to "speaker"
Co-authored-by: Matthew W <fatboychummy@gmail.com>
2024-03-24 11:10:36 +00:00
Jonathan Coates
c50d56d9fa Remove canClickRunClientCommand
This was added in 4675583e1c to handle
Forge on longer supporting RUN_COMMAND for client-side commands.
However, the mixins are still present on NF/1.20.4, so we don't need
this!
2024-03-23 15:38:18 +00:00
Jonathan Coates
777aa34bb0 Bump CC:T to 1.110.1 2024-03-23 11:09:42 +00:00
Jonathan Coates
286f969f94 Remove computers from both lookups when they timeout
In 5d8c46c7e6, we switched to using UUIDs
for looking up computers (rather than an integer ID). However, for
compatibility in some of the command code, we need to maintain the old
integer lookup map.

Most of the code was updated to handle this, *except* the code to remove
a computer from the registry. This meant that we'd fail to remove a
computer from the UUID lookup map, so computers ended up in a phantom
state where they were destroyed, but still accessible.

This is not an issue on 1.20.4, because the legacy int lookup map was
removed.

Fixes #1760
2024-03-23 10:59:47 +00:00
Jonathan Coates
7b9a156abc Register our block entities with DFU
This ensures that data fixers will be applied to items in these
inventories.
2024-03-22 21:47:11 +00:00
Jonathan Coates
0a9e5c78f3 Remove some deprecated code
Some of this is technically an API break, but 1.20.4 is pretty unstable.

 - Remove WiredNetwork from the public API
 - Remove legacy computer selectors
2024-03-22 21:36:52 +00:00
Jonathan Coates
da5885ef35 Merge branch 'mc-1.20.x' into mc-1.20.y 2024-03-22 21:23:49 +00:00
Jonathan Coates
57c72711bb Use a platform method to register item properties
The two mod loaders expose different methods for this (Forge's method
takes a ItemPropertyFunction, Fabric's a ClampedItemPropertyFunction).
This is fine in a Gradle build, as the methods are compatible. However,
when running from IntelliJ, we get crashes as the common code tries to
reference the wrong method.

We now pass in the method reference instead, ensuring we use the right
method on each loader.
2024-03-22 20:19:32 +00:00
Jonathan Coates
cbafbca86b Invalidate wired element when cable is added/removed
Otherwise we end up caching the old value of getWiredElement, which
might be absent if there is no cable!

Fixes #1759
2024-03-22 20:13:02 +00:00
Jonathan Coates
c9caffb10f Bump CC:T to 1.110.0
Tricky version number to type!
2024-03-21 21:57:05 +00:00
Jonathan Coates
4675583e1c STOP DOING MIXINS (on Forge)
BYTECODE WAS NOT SUPPOSED TO BE REWRITTEN

YEARS OF DEBUGGING REMAPPING FAILURES yet NO ACTUAL SOLUTION FOUND.

Wanted to use Mixins for anyway for a laugh? We had a tool for that: it
was called "FABRIC LOOM".

"Yes, please produce completely broken jars for no discernable reason"
Statements dreamed up by the utterly Deranged.

 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

This removes our two mixins used on Forge:

 - Breaking progress for cabled/wired modems.
 - Running client commands from chat click events. We now suggest the
   command on Forge instead.

Occasionally we get issues where the mixin annotation processor doesn't
write its tsrg file in time for the reobfJar/reobfJarJar task. I thought
we'd fixed that cb8e06af2a, but sometimes
we still produce missing jars - I have a feeling this might be to do
with incremental compilation.

We can maybe re-evaluate this on 1.20.4, where we don't need to worry
about remapping any more.
2024-03-21 21:45:17 +00:00
Jonathan Coates
afe16cc593 Clean up turtle inventory reading 2024-03-21 21:21:31 +00:00
Jonathan Coates
0abd107348 Load services with the service's classloader
We were seeing some strange issues in the Fabric test code where we
tried to load the implementation from a different classloader. This
ensures that the classloaders are consistent.
2024-03-21 20:50:31 +00:00
Jonathan Coates
cef4b4906b Bump Cobalt for tostring yield fix 2024-03-21 19:54:29 +00:00
Jonathan Coates
04900dc82f Skip main-thread tasks if peripheral is detached
Due to the asynchronous nature of main-thread tasks, it's possible for
them to be executed on peripherals which have been detached. This has
been known for a long time (#893 was opened back in 2021), but finding a
good solution here is tricky.

Most of the time the method will silently succeed, but if we try to
interact with an IComputerAccess (such as in inventory methods, as seen
in #1750), we throw a NotAttachedException exception and spam the logs!

This is an initial step towards fixing this - when calling a peripheral
method via peripheral.call/modem.callRemote, we now wrap any enqueued
main-thread tasks and silently skip them if the peripheral has been
detached since.

This means that peripheral methods may start to return nil when they
didn't before. I think this is *fine* (though not ideal for sure!) - we
return nil if the peripheral has been detached, so it's largely
equivalent to that.
2024-03-21 19:54:22 +00:00
Jonathan Coates
9b63cc81b1 Custom equality for Fabric's storage types
Double chests peripherals were getting reattached every time there was a
block update, as the inventories were not comparing equal (despite being
so!). We now check for a couple of common cases, which should be enough
for vanilla/vanilla-like inventories.

I actively Do Not Like This Code, but do not see a good alternative.
2024-03-21 19:54:22 +00:00
Jonathan Coates
9eead7a0ec Use shell.resolve in speaker.lua
Fixes #1753
2024-03-20 10:45:23 +00:00
Jonathan Coates
ad97b2922b Invalidate peripherals on updateShape
This fixes chests not being reattached when their size changes.
2024-03-20 10:07:29 +00:00
Jonathan Coates
52986f8d73 Drop modems as an item in updateShape
We were still handling this logic in neighborChanged, like this was
1.12. The horror!
2024-03-17 22:09:21 +00:00
Jonathan Coates
ab00580389 Simplify the previous patch a little
We can use BlockEntityType.getKey, rather than having to extend our
registry wrappers.
2024-03-17 16:21:56 +00:00
Jonathan Coates
128ac2f109 Better handling when a BE type isn't registered
This should never happen, but apparently it does!? We now log an error
(rather than crashing), and include the original BE (and associated
block), as the BE type isn't very useful.

See #1750. Technically this fixes it, but want to do some more poking
there first.
2024-03-17 16:13:33 +00:00
Jonathan Coates
5d8c46c7e6 Replace integer instance IDs with UUIDs
Here's a fun bug you can try at home:
 - Create a new world
 - Spawn in a pocket computer, turn it on, and place it in a chest.
 - Reload the world - the pocket computer in the chest should now be
   off.
 - Spawn in a new pocket computer, and turn it on. The computer in chest
   will also appear to be on!

This bug has been present since pocket computers were added (27th March,
2024).

When a pocket computer is added to a player's inventory, it is assigned
a unique *per-session* "instance id" , which is used to find the
associated computer. Note the "per-session" there - these ids will be
reused if you reload the world (or restart the server).

In the above bug, we see the following:

 - The first pocket computer is assigned an instance id of 0.
 - After reloading, the second pocket computer is assigned an instance
   id of 0.
 - If the first pocket computer was in our inventory, it'd be ticked and
   assigned a new instance id. However, because it's in an inventory, it
   keeps its old one.
 - Both computers look up their client-side computer state and get the
   same value, meaning the first pocket computer mirrors the second!

To fix this, we now ensure instance ids are entirely unique (not just
per-session). Rather than sequentially assigning an int, we now use a
random UUID (we probably could get away with a random long, but this
feels more idiomatic).

This has a couple of user-visible changes:

 - /computercraft no longer lists instance ids outside of dumping an
   individual computer.
 - The @c[instance=...] selector uses UUIDs. We still use int instance
   ids for the legacy selector, but that'll be removed in a later MC
   version.
 - Pocket computers now store a UUID rather than an int.

Related to this change (I made this change first, but then they got
kinda mixed up together), we now only create PocketComputerData when
receiving server data. This makes the code a little uglier in some
places (the data may now be null), but means we don't populate the
client-side pocket computer map with computers the server doesn't know
about.
2024-03-17 14:56:12 +00:00
Jonathan Coates
1a5dc92bd4 Some more cleanup to wired modems
- Remove "initial connections" flag, and just refresh connections +
   peripherals on the first tick.

 - Remove "peripheral attached" from NBT, and just read/write it from
   the block state. This might cause issues with #1010, but that's
   sufficiently old I hope it won't!
2024-03-17 00:18:27 +00:00
Jonathan Coates
98b2d3f310 Simplify WiredModemPeripheral interface a little 2024-03-16 23:24:55 +00:00
Jonathan Coates
e92c2d02f8 Fix turtle.suck reporting incorrect error
Our GatedPredicate hack was clever, but also fundamentally didn't work.
The predicate is called before extraction, so if extraction fails (for
instance, canTakeItemThroughFace returns false), then we still think an
item has been removed.

To fix that, we inline StorageUtil.move, specialising it for what we
need.
2024-03-16 21:27:21 +00:00
Jonathan Coates
f8ef40d378 Add a method for checking peripheral equality
This feels a little overkill, but nice to standardise how this code
looks.

There's a bit of me which wonders if we should remove
IPeripheral.equals, and just use Object.equals, but I do also kinda like
the explicitness of the current interface? IDK.
2024-03-16 14:01:22 +00:00
Jonathan Coates
61f9b1d0c6 Send entire DFPWM encoder state to the client
This ensures the client decoder is in sync with the server. Well, mostly
- we don't handle the anti-jerk, but that should correct itself within a
few samples.

Fixes #1748
2024-03-15 18:25:57 +00:00
Jonathan Coates
ffb62dfa02 Bump checkstyle, fix warnings from TeaVM upgrade 2024-03-13 21:52:09 +00:00
Jonathan Coates
6fb291112d Update TeaVM for ESM support
We still need our fork (file attributes, some Math/Int/Long methods),
but this simplifies things a wee bit.
2024-03-13 13:01:25 +00:00
Jonathan Coates
7ee821e9c9 Allow coroutine managers to integrate with error reporting
The original runtime error reporting PR[^1] added a "cc.exception"
module, which allowed coroutine managers (such as parallel) to throw
rich errors, detailing the original context where the error was thrown.

Unfortunately, the change to parallel broke some programs (>_>, don't do
string pattern matching on your errors!), and so had to be reverted,
along with the cc.exception module.

As a minimal replacement for this, we add support for user-thrown
exceptions within our internal code. If an error object "looks" like an
exception ("exception" __name, and a message and thread field), then we
use that as our error information instead.

This is currently undocumented (at least in user-facing documentation),
mostly because I couldn't figure out where to put it - the interface
should remain stable.

[^1]: https://github.com/cc-tweaked/CC-Tweaked/pull/1320
2024-03-12 20:55:30 +00:00
Jonathan Coates
b7df91349a Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.

Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.

This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
Jonathan Coates
cb8e06af2a Ensure mixin reobf configs run after compilation
Fixes #1744
2024-03-11 22:28:02 +00:00
Jonathan Coates
6478fca7a2 Update to latest illuaminate
This allows us to remove our image copying code
2024-03-11 21:36:46 +00:00
Jonathan Coates
3493159a05 Bump CC:T to 1.109.7 2024-03-10 19:10:09 +00:00
Jonathan Coates
eead67e314 Fix a couple of warnings 2024-03-10 12:04:40 +00:00
Jonathan Coates
3b8813cf8f Slightly more detailed negative allocation logging
Hopefully will help debug #1739. Maybe.
2024-03-10 11:26:36 +00:00
Jonathan Coates
a9191a4d4e Don't cache the client monitor
When rendering non-origin monitors, we would fetch the origin monitor,
read its client state, and then cache that on the current monitor to
avoid repeated lookups.

However, if the origin monitor is unloaded/removed on the client, and
then loaded agin, this cache will be not be invalidated, causing us to
render both the old and new monitor!

I think the correct thing to do here is cache the origin monitor. This
allows us to check when the origin monitor has been removed, and
invalidate the cache if needed.

However, I'm wary of any other edge cases here, so for now we do
something much simpler, and remove the cache entirely. This does mean
that monitors now need to perform extra block entity lookups, but the
performance cost doesn't appear to be too bad.

Fixes #1741
2024-03-10 10:57:56 +00:00
Jonathan Coates
451a2593ce Move WiredNode default methods to the impl 2024-03-10 10:00:52 +00:00
Jonathan Coates
d38b1da974 Don't propagate redstone when blink/label changes
Historically, computers tracked whether any world-visible state
(on/off/blinking, label and redstone outputs) had changed with a single
"has changed" flag. While this is simple to use, this has the curious
side effect of that term.setCursorBlink() or os.setComputerLabel() would
cause a block update!

This isn't really a problem in practice - it just means slightly more
block updates. However, the redstone propagation sometimes causes the
computer to invalidate/recheck peripherals, which masks several other
(yet unfixed) bugs.
2024-03-06 18:59:38 +00:00
Jonathan Coates
6e374579a4 Standardise on term colour parsing
- colors.toBlit now performs bounds checks on the passed value,
   preventing weird behaviour like color.toBlit(2 ^ 16) returning "10".

 - The window API now uses colors.toBlit (or rather a copy of it) for
   parsing colours, allowing doing silly things like
   term.setTextColour(colours.blue + 5).

 - Add some top-level documentation to the term API to explain some of
   the basics.

Closes #1736
2024-03-06 10:18:40 +00:00
Jonathan Coates
4daa2a2b6a Reschedule block entities when chunks are loaded
Minecraft sometimes keeps chunks in-memory, but not actively loaded. If
we schedule a block entity to be ticked and that chunk is is then
transitioned to this partially-loaded state, then the block entity is
never actually ticked.

This is most visible with monitors. When a monitor's contents changes,
if the monitor is not already marked as changed, we set it as changed
and schedule a tick (see ServerMonitor). However, if the tick is
dropped, we don't clear the changed flag, meaning subsequent changes
don't requeue the monitor to be ticked, and so the monitor is never
updated.

We fix this by maintaining a list of block entities whose tick was
dropped. If these block entities (or rather their owning chunk) is ever
re-loaded, then we reschedule them to be ticked.

An alternative approach here would be to add the scheduled tick directly
to the LevelChunk. However, getting hold of the LevelChunk for unloaded
blocks is quiet nasty, so I think best avoided.

Fixes #1146. Fixes #1560 - I believe the second one is a duplicate, and
I noticed too late :D.
2024-02-26 19:25:38 +00:00
Jonathan Coates
84b6edab82 More efficient removal of wired nodes from networks
When we remove a wired node from a network, we need to find connected
components in the rest of the graph. Typically, this requires a
traversal of the whole graph, taking O(|V| + |E|) time.

If we remove a lot of nodes at once (such as when unloading chunks),
this ends up being quadratic in the number of nodes. In some test
networks, this can take anywhere from a few seconds, to hanging the game
indefinitely.

This attempts to reduce the cases where this can happen, with a couple
of optimisations:

 - Instead of constructing a new hash set of reachable nodes (requiring
   multiple allocations and hash lookups), we store reachability as a
   temporary field on the WiredNode.

 - We abort our traversal of the graph if we can prove the graph remains
   connected after removing the node.

There's definitely future work to be done here in optimising large wired
networks, but this is a good first step.
2024-02-24 15:02:34 +00:00
Jonathan Coates
31aaf46d09 Deprecate WiredNetwork
We don't actually need this to be in the public API.
2024-02-24 14:55:22 +00:00
Jonathan Coates
2d11b51c62 Clean up the wired network tests
- Replace usages of WiredNetwork.connect/disconnect/remove with the
   WiredNode equivalents.

 - Convert "testLarge" into a proper JMH benchmark.

 - Don't put a peripheral on every node in the benchmarks. This isn't
   entirely representative, and means the peripheral juggling code ends
   up dominating the benchmark time.
2024-02-24 14:52:44 +00:00
Jonathan Coates
240528cce5 Update NF and NG
Trying to rebuild after this OOM killed all my windows. I hate NeoGradle
so much.
2024-02-18 19:02:23 +00:00
Jonathan Coates
83f1f86888 Merge branch 'mc-1.20.x' into mc-1.20.y 2024-02-18 18:45:20 +00:00
Jonathan Coates
a0f759527d Bump CC:T to 1.109.6 2024-02-18 18:33:42 +00:00
Jonathan Coates
385e4210fa Update Cobalt to 0.9.1 for weak table fixes 2024-02-18 18:23:43 +00:00
Jonathan Coates
d2896473f2 Update our parse errors to match latest illuaminate
We've been out-of-date for a while now, as we needed to update
lua_menhir to work with lrgrep 3.

 - Better handling of standalone names/expressions - we now correctly
   handle lists of names.

 - Handle missing commas in tables in a few more places.
2024-02-08 19:22:14 +00:00
Jonathan Coates
f14cb2a3d1 Fix MemoryMount using incorrect file lengths
- We checked the backing array when reading rather than the file's
   length, so could read beyond the end of the file.
 - We used the entry length when resizing, which effectively meant we
   doubled the size of the backing array on each write.
2024-02-07 21:36:17 +00:00
Jonathan Coates
8db5c6bc3a Allow ILuaAPIs to be exposed as a module
- cc.require now uses the internal _LOADED table to get the list of
   built-in globals. This fixes several globals not showing up on the
   list (e.g. utf8), and allows us to inject more modules from the Java
   side.

 - ILuaAPI now has a getModuleName() function. This is used to inject
   the API into the aforementioned _LOADED table, allowing it to be
   "require"d.
2024-02-05 18:53:24 +00:00
Jonathan Coates
9c202bd1c2 Fix incorrect cast for JEI 2024-02-05 18:52:20 +00:00
Jonathan Coates
fc834cd97f Update to 1.20.4 2024-01-31 20:55:14 +00:00
Jonathan Coates
f26e443e81 Bump CC:T to 1.109.5 2024-01-31 20:53:28 +00:00
Jonathan Coates
033378333f Standardise how we discard "char" events
One common issue we get when a program exits after handling a "key"
event is that it leaves the "char" event on the queue. This means that
the shell (or whatever program we switch in to) then receives the "char"
event, often displaying it to the screen.

Previously we've got around this by doing sleep(0) before exiting the
program. However, we also see this problem in edit's run handler script,
and I'm less comfortable doing the same hack there.

This adds a new internal discard_char function, which will either
wait one tick or return when seeing a char/key_up event.

Fixes #1705
2024-01-31 20:49:43 +00:00
Jonathan Coates
ebeaa757a9 Change how we put test libraries on the class path
- Mark our core test-fixtures jar as part of the "cctest", rather than
   a separate library. I'm fairly sure this was actually using the
   classpath version of CC rather than the legacyClasspath version!

 - Add a new "testMinecraftLibrary" configuration, instead of trying to
   infer it from the classpath. We have to jump through some hoops to
   avoid having multiple versions of a library on the classpath at once,
   but it's not too bad.

I'm working on a patch to bsl which might allow us to kill of
legacyClasspath instead. Please, anything is better than this.
2024-01-31 19:49:36 +00:00
Jonathan Coates
57b1a65db3 Fix using a tab instead of space
Annoying that pre-commit didn't catch this!
2024-01-30 22:01:57 +00:00
Jonathan Coates
27c72a4571 Use client-side commands for opening computer folders
Forge doesn't run client-side commands from sendUnsignedCommand, so we
still require a mixin there.

We do need to change the command name, as Fabric doesn't properly merge
the two command trees.
2024-01-30 22:00:36 +00:00
Jonathan Coates
f284328656 Regenerate Gradle wrapper 2024-01-29 22:14:48 +00:00
Jonathan Coates
6b83c63991 Switch to our own Gradle plugin for vanilla Minecraft
I didn't make a new years resolution to stop writing build tooling, but
maybe I should have.

This replaces our use of VanillaGradle with a new project,
VanillaExtract. This offers a couple of useful features for multi-loader
dev, including Parchment and Unpick support, both of which we now use in
CC:T.
2024-01-29 20:59:16 +00:00
Jonathan Coates
b27526bd21 Bump CC:T to 1.109.4 2024-01-27 10:26:56 +00:00
Jonathan Coates
cb25f6c08a Update Cobalt to 0.9.0
- Debug hooks are now correctly called for every function.
 - Fix several minor inconsistencies with debug.getinfo.
 - Fix Lua tables being sized incorrectly when created from varargs.
2024-01-27 10:04:34 +00:00
Jonathan Coates
d38b1d04e7 Update Gradle to 8.5
- Update FG to 6.0.20 - no major changes, but required for the Gradle
   update.
 - Update Loom to 1.5.x - this adds Vineflower support by default, so we
   can remove loom-vineflower.
2024-01-27 09:28:13 +00:00
Jonathan Coates
9ccee75a99 Fix the docs for ReadHandle.read's "count"
This was copied over from the old binary handle, and so states we
always return a single number if no count is given. This is only the
case when the file is opened in binary mode.
2024-01-23 22:39:49 +00:00
Jonathan Coates
359c8d6652 Reformat JSON by wrapping CachedOutput
Rather than mixing-in to CachedOutput, we just wrap our DataProviders to
use a custom CachedOutput which reformats the JSON before writing. This
allows us to drop mixins for common+non-client code.
2024-01-21 17:50:59 +00:00
Jonathan Coates
1788afacfc Remove note about disabling websocket limits
I suspect this was copied from the file limit, which can be turned off
by setting to 0.

Fixes #1691
2024-01-21 16:32:07 +00:00
Jonathan Coates
f695f22d8a Atomic update of disk drive item stacks
Disk drives have had a long-standing issue with mutating their contents
on the computer thread, potentially leading to all sorts of odd bugs.

We tried to fix this by moving setDiskLabel and the mounting code to run
on the main thread. Unfortunately, this means there is a slight delay to
mounts being attached, breaking disk startup.

This commit implements an alternative solution - we now do mounting on
the computer thread again. If the disk's stack is modified, we update it
in the peripheral-facing item, but not the actual inventory. The next
time the disk drive is ticked, we then sync the two items.

This does mean that there is a fraction of a tick where the two will be
out-of-sync. This isn't ideal - it would potentially be possible to
cycle through disk ids - but I don't really think that's avoidable
without significantly complicating the IMedia API.

Fixes #1649, fixes #1686.
2024-01-20 18:46:43 +00:00
Jonathan Coates
bc03090ca4 Merge pull request #1684 from cc-tweaked/hotfix/turtle-modellers-redo
Rewrite turtle upgrade modeller registration API
2024-01-17 19:45:48 +00:00
Jonathan Coates
a617d0d566 Rewrite turtle upgrade modeller registration API
Originally we exposed a single registerTurtleUpgradeModellermethod which
could be called from both Fabric (during a mod's client init) and Forge
(during FMLClientSetupEvent).

This was fine until we allowed upgrades to specify model dependencies,
which would then automatically loaded, as this means model loading now
depends on upgrade modellers being loaded. Unknown to me, this is not
guaranteed to be the case on Forge - mod setup happens at the same time
as resource reloading!

Unfortunately there's not really a salvageable way of fixing this with
the current API. Forge now uses a registration event-based system,
meaning we can guarantee all modellers are loaded before models are
baked.
2024-01-16 23:00:49 +00:00
Jonathan Coates
36599b321e Backport small changes from the 1.20.4 branch
- Add support for version overrides/exclusions in our dependency check.
   Sometimes mod loaders use different versions to vanilla, and we need
   some way to handle that.

 - Rescan wired network connections on the tick after invalidation,
   rather than when invalidated.

 - Convert some constant lambdas to static method references. Lambdas
   don't allocate if they don't capture variables, so this has the same
   performance and is a little less ugly.

 - Small code-style/formatting changes.
2024-01-16 21:42:25 +00:00
Jonathan Coates
1d6e3f4fc0 Change ComponentLookup to use ServerLevel
Makes this more consistent with the rest of the peripheral code, and our
changes in 1.20.4.
2024-01-15 08:28:59 +00:00
Jonathan Coates
30dc4cb38c Simplify our networking multi-platform code
Historically we used Forge's SimpleChannel methods (and
PacketDistributor) to send the packets to the client. However, we don't
need to do that - it is sufficient to convert it to a vanilla packet,
and send the packet ourselves.

Given we need to do this on Fabric, it makes sense to do this on Forge
as well. This allows us to unify (and thus simplify) a lot of how packet
sending works.

At the same time, we also remove the handling of speaker audio during
decoding. We originally did this to avoid the additional copy of audio
data. However, this doesn't work on 1.20.4 (as packets aren't
encoded/decoded on singleplayer), so it makes sense to do this
Correctly(TM).

This also allows us to get rid of ClientNetworkContext.get(). We do
still need to service load this class (as Forge's networking isn't split
up in the same way Fabric's is), but we'll be able to drop that in
1.20.4.

Finally, we move the record playing code from ClientNetworkContext to
ClientPlatformHelper. This means the network context no longer needs to
be platform-specific!
2024-01-14 22:53:36 +00:00
Jonathan Coates
be4512d1c3 Construct ComponentAccesses with the BE
After embarrassing, let's do some proper work.

Rather than passing the level and position each time we call
ComponentAccess.get(), we now pass them at construction time (in the
form of the BE). This makes the consuming code a little cleaner, and is
required for the NeoForge changes in 1.20.4.
2024-01-14 17:46:37 +00:00
Jonathan Coates
e6ee292850 Fix incorrect "Fix incorrect "incorrect incorrect"" 2024-01-14 16:27:55 +00:00
Jonathan Coates
9d36f72bad Fix incorrect "incorrect incorrect" 2024-01-14 16:12:52 +00:00
Jonathan Coates
b5923c4462 Flesh out the printer documentation slightly 2024-01-14 12:25:04 +00:00
Jonathan Coates
4d1e689719 Fix endPage() not updating the printer block state
This meant that we didn't show the bottom slot was full until other
items were moved in the inventory.
2024-01-14 12:23:55 +00:00
Marcus
9d4af07568 fix: breaking_changes flattening link incorrect (#1679) 2024-01-10 22:18:22 +00:00
lonevox
89294f4a22 Fix incorrect Lua list indexes in NBT tags (#1678) 2024-01-10 19:16:15 +00:00
Jonathan Coates
133b51b092 Don't warn when allocating 0 bytes
I was able to reproduce this by starting two computers, and then warming
up the JIT by running:

  while true do os.queueEvent("x") os.pullEvent("x") end

and then running the following on one computer, while typing on the
other:

  while true do end

I'm not quite sure why this happens. It's possible that once the JIT is
warm, we can resume computers without actually allocating anything,
though I'm a little unconvinced.

Fixes #1672
2024-01-08 21:52:30 +00:00
Jonathan Coates
272010e945 Require Minecraft 1.20.1
Closes #1671
2024-01-08 21:33:55 +00:00
Jonathan Coates
e0889c613a Mark "check valid item" test as required
This has passed for years now, no reason for it to be optional.
2024-01-07 13:35:38 +00:00
Jonathan Coates
f115d43d07 Fix some dependencies not appearing in the POM
Again! This time it was just the night-config ones.
2024-01-03 21:05:03 +00:00
Jonathan Coates
8be6b1b772 Bump CC:T to 1.109.3 2024-01-03 20:00:52 +00:00
Jonathan Coates
104d5e70de Update to Cobalt 0.8.2
- Fix error when using "goto" as the first statement in an if block.
 - Fix incorrect resizing of table's hash part when adding and removing
   keys.
2024-01-03 18:44:37 +00:00
Jonathan Coates
e3bda2f763 Add command computers to the operator blocks tab
Fixes #1666
2024-01-03 18:42:31 +00:00
Jonathan Coates
234f69e8e5 Add a MessageType for network messages
Everything old is new again!

CC's network message implementation has gone through several iterations:

 - Originally network messages were implemented with a single class,
   which held an packet id/type and and opaque blobs of data (as
   string/int/byte/NBT arrays), and a big switch statement to decode and
   process this data.

 - In 42d3901ee3, we split the messages
   into different classes all inheriting from NetworkMessage - this bit
   we've stuck with ever since.

   Each packet had a `getId(): int` method, which returned the
   discriminator for this packet.

 - However, getId() was only used when registering the packet, not when
   sending, and so in ce0685c31f we
   removed it, just passing in a constant integer at registration
   instead.

 - In 53abe5e56e, we made some relatively
   minor changes to make the code more multi-loader/split-source
   friendly. However, this meant when we finally came to add Fabric
   support (8152f19b6e), we had to
   re-implement a lot of Forge's network code.

In 1.20.4, Forge moves to a system much closer to Fabric's (and indeed,
Minecraft's own CustomPacketPayload), and so it makes sense to adapt to
that now. As such, we:

 - Add a new MessageType interface. This is implemented by the
   loader-specific modules, and holds whatever information is needed to
   register the packet (e.g. discriminator, reader function).

 - Each NetworkMessage now has a type(): MessageType<?> function. This
   is used by the Fabric networking code (and for NeoForge's on 1.20.4)
   instead of a class lookup.

 - NetworkMessages now creates/stores these MessageType<T>s (much like
   we'd do for registries), and provides getters for the
   clientbound/serverbound messages. Mod initialisers then call these
   getters to register packets.

 - For Forge, this is relatively unchanged. For Fabric, we now
   `FabricPacket`s.
2024-01-03 10:23:41 +00:00
Jonathan Coates
ed3a17f9b9 Fix trailing-comma errors on method calls
We were only matching `f(a, ` patterns, and not `x:f(a, `. We now just
match against any usages of call_args - hadn't quite realised we could
do that!
2023-12-28 17:07:39 +00:00
Jonathan Coates
0349c2b1f9 Allow local domains in the standalone emulator
- Clean up option parsing a bit, so it uses the Option, rather than its
   corresponding character code.
 - Add a new -L/--allow-local-domains flag to remove the $private rule
   from the HTTP rules.
2023-12-20 17:43:08 +00:00
Jonathan Coates
03f9e6bd6d Prevent sending too many websocket messages at once 2023-12-20 17:30:57 +00:00
Jonathan Coates
9d8c933a14 Remove several usages of ComputerFamily
While ComputerFamily is still useful, there's definitely some places
where it adds an extra layer of indirection. This commit attempts to
clean up some places where we no longer need it.

 - Remove ComputerFamily from AbstractComputerBlock. The only place this
   was needed is in TurtleBlock, and that can be replaced with normal
   Minecraft explosion resistence!

 - Pass in the fuel limit to the turtle block entity, rather than
   deriving it from current family.

 - The turtle BERs now derive their model from the turtle's item, rather
   than the turtle's family.

 - When creating upgrade/overlay recipes, use the item's name, rather
   than {pocket,turtle}_family. This means we can drop getFamily() from
   IComputerItem (it is still needed on to handle the UI).

 - We replace IComputerItem.withFamily with a method to change to a
   different item of the same type. ComputerUpgradeRecipe no longer
   takes a family, and instead just uses the result's item.

 - Computer blocks now use the normal Block.asItem() to find their
   corresponding item, rather than looking it up via family.

The above means we can remove all the family-based XyzItem.create(...)
methods, which have always felt a little ugly.

We still need ComputerFamily for a couple of things:
 - Permission checks for command computers.
 - Checks for mouse/colour support in ServerComputer.
 - UI textures.
2023-12-20 14:17:38 +00:00
Jonathan Coates
78bb3da58c Improve our version tooling
- Add a check to ensure declared dependencies in the :core project, and
   those inherited from Minecraft are the same.
 - Compute the next Cobalt version, rather than specifying it manually.
 - Add the gradle versions plugin (and version catalog update), and
   update some versions.
2023-12-19 18:12:21 +00:00
Jonathan Coates
39a5e40c92 Bump CC:T to 1.109.2
Take two!
2023-12-16 22:46:30 +00:00
Jonathan Coates
763ba51919 Update Cobalt to 0.8.1 2023-12-16 22:39:48 +00:00
Jonathan Coates
cf6ec8c28f Add a slightly cleaner system for excluding deps
Previously we prevented our published full jar depending on any of the
other projects by excluding the whole cc.tweaked jar. However, as Cobalt
also now lives in that group, this meant we were missing the Cobalt
dependency.

Rather than specifying a wildcard, we now exclude the dependencies when
adding them to the project.
2023-12-16 22:35:15 +00:00
Jonathan Coates
95d3b646b2 Bump CC:T to 1.109.1 2023-12-16 19:09:39 +00:00
Jonathan Coates
488f66eead Fix mouse_drag not firing for right/middle buttons
This is a bit of an odd combination of a few bugs:
 - When the terminal component is blurred, we fire a mouse_up event for
   the last-held button. However, we had an off-by-1 error here, so this
   only triggered for the right/middle buttons.

 - This was obsucuring the second bug, which is when we clicked within
   the terminal, this caused the terminal to be blurred (thus releasing
   the mouse) and then focused again.

   We fix this by only setting the focus if there's actually a change.

Fixes #1655
2023-12-10 12:01:34 +00:00
Jonathan Coates
1f7d245876 Specify charset when printing error messages 2023-12-08 09:52:17 +00:00
Jonathan Coates
af12b3a0ea Fix goto/:: tokens erroring in error reporting 2023-12-07 19:47:39 +00:00
Jonathan Coates
eb3e8ba677 Fix deadlock when adding/removing observers
When adding/removing observers, we locked on the observer, then
acquired the global lock. When a metric is observed, then we acquire the
global lock and then the observer lock.

If these happen at the same time, we can easily end up with a deadlock.
We simply avoid holding the observer lock for the entire add/remove
process (instead only locking when actually needed).

Closes #1639
2023-12-01 12:33:03 +00:00
Jonathan Coates
2043939531 Add compostors to the list of usable blocks
Fixes #1638
2023-11-22 18:24:59 +00:00
Jonathan Coates
84a799d27a Add abstract classes for our generic peripherals
This commit adds abstract classes to describe the interface for our
mod-loader-specific generic peripherals (inventories, fluid storage,
item storage).

This offers several advantages:
 - Javadoc to illuaminate conversion no longer needs the Forge project
   (just core and common).

 - Ensures we have a consistent interface between Forge and Fabric.

Note, this does /not/ implement fluid or energy storage for Fabric. We
probably could do fluid without issue, but not something worth doing
right now.
2023-11-22 18:20:15 +00:00
Jonathan Coates
fe826f5c9c Allow generic sources to have instance methods
Rather than assuming static methods are generic, and instance methods
are direct, the Generator now has separate entrypoints for handling
instance and generic methods.

As a result of this change, we've also relaxed some of the validation
code. As a result, we now allow calling private/protected methods
which are annotated with @LuaFunction.
2023-11-22 10:06:11 +00:00
Jonathan Coates
f8b7422294 Fix several issues with the web emulator
- Bump TeaVM version to fix issues with locales and our "export"
   generation.
 - Fix TComputerThread not requeuing correctly.
2023-11-15 13:12:31 +00:00
Jonathan Coates
b343c01216 Bump CC:T to 1.109.0 2023-11-15 09:39:52 +00:00
Jonathan Coates
76968f2f28 Track allocations while executing computers
This adds a new "java_allocation" metric, which tracks the number of
bytes allocated while executing the computer (as measured by Java). This
is not an 100% reliable number, but hopefully gives some insight into
what computers are doing.
2023-11-09 18:36:35 +00:00
Jonathan Coates
1d365f5a0b Add option to allow repetition in JSON serialiser
Closes #1588
2023-11-08 21:29:43 +00:00
Jonathan Coates
7b240cbf7e Merge pull request #1615 from cc-tweaked/feature/much-breakage-very-wow
Remove text mode, update Cobalt
2023-11-08 20:05:49 +00:00
Jonathan Coates
d272a327c7 Update CraftOS version to 1.9 2023-11-08 19:40:14 +00:00
Jonathan Coates
0c0556a5bc Always use raw bytes in file handles
Historically CC has supported two modes when working with file handles
(and HTTP requests):

 - Text mode, which reads/write using UTF-8.
 - Binary mode, which reads/writes the raw bytes.

However, this can be confusing at times. CC/Lua doesn't actually support
unicode, so any characters beyond the 0.255 range were replaced with
'?'. This meant that most of the time you were better off just using
binary mode.

This commit unifies text and binary mode - we now /always/ read the raw
bytes of the file, rather than converting to/from UTF-8. Binary mode now
only specifies whether handle.read() returns a number (and .write(123)
writes a byte rather than coercing to a string).

 - Refactor the entire handle hierarchy. We now have an AbstractMount
   base class, which has the concrete implementation of all methods. The
   public-facing classes then re-export these methods by annotating
   them with @LuaFunction.

   These implementations are based on the
   Binary{Readable,Writable}Handle classes. The Encoded{..}Handle
   versions are now entirely removed.

 - As we no longer need to use BufferedReader/BufferedWriter, we can
   remove quite a lot of logic in Filesystem to handle wrapping
   closeable objects.

 - Add a new WritableMount.openFile method, which generalises
   openForWrite/openForAppend to accept OpenOptions. This allows us to
   support update mode (r+, w+) in fs.open.

 - fs.open now uses the new handle types, and supports update (r+, w+)
   mode.

 - http.request now uses the new readable handle type. We no longer
   encode the request body to UTF-8, nor decode the response from UTF-8.

 - Websockets now return text frame's contents directly, rather than
   converting it from UTF-8. Sending text frames now attempts to treat
   the passed string as UTF-8, rather than treating it as latin1.
2023-11-08 19:40:14 +00:00
Jonathan Coates
87345c6b2e Add pasting support to the standalone emulator
- Move paste normalisation code to StringUtil, so it can be shared by
   emulators.
 - Add paste support to the emulator.
2023-11-08 19:40:14 +00:00
Jonathan Coates
784e623776 Update Cobalt to 0.8.0
- Update Cobalt to 0.8.0, switching our Lua version to 5.2(ish).

 - Remove our `load` wrapper, as we no longer need to inject _ENV into
   the enviroment table.

 - Update the parser to handle labels and goto. This doesn't check that
   gotos are well formed, but at least means the parser doesn't fall
   over on them.

 - Update our docs to reflect the changes to Cobalt.
2023-11-08 18:42:17 +00:00
Jonathan Coates
bcb3e9bd53 Bump CC:T to 1.108.4 2023-10-29 12:02:11 +00:00
Jonathan Coates
c30bffbd0f Add additional tests for filesystems/mounts
This tries to cover some holes in our existing coverage.

 - Port some of our Java readable handle tests to Lua (and also clean up
   the Java versions to stop using ObjectWrapper - that dates to
   pre-@LuaFunction!)

 - Test a couple of discrepancies between binary and text handles. This
   is mostly to do with the original number-based .read() and .write()
   interface for binary handles.

 - Fix a couple of edge cases in file-size accounting.
2023-10-29 12:01:26 +00:00
Jonathan Coates
91c41856c5 Add an "Incompatibilities between versions" page
This is largely based on our existing wiki page. I've pruned out a
couple of entries which I think are largely irrelevant (config file
splitting, Java API changes).

10/10 job by me of changing nothing since 1.13. Shame to break that
streak really.
2023-10-28 20:00:56 +01:00
Jonathan Coates
18c9723308 Add a standalone CC:T UI
Does it count as an emulator when it's official? I hope not, as this'd
make it my fourth or fifth emulator at this point.

 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

Developing/debugging CraftOS is a massive pain to do inside Minecraft,
as any change to resources requires a compile+hot swap cycle (and
sometimes a `/reload` in-game). As such, it's often more convenient to
spin up an emulator, pointing it to load the ROM from CC:T's sources.

However, this isn't practical when also making changes to the Java
classes. In this case, we either need to go in-game, or build a custom
version of CCEmuX.

This commit offers an alternative option: we now have our own emulator,
which allows us to hot swap both Lua and Java to our heart's content.

Most of the code here is based on our monitor TBO renderer. We probably
could share some more of this, but there's not really a good place for
it - feels a bit weird just to chuck it in :core.

This is *not* a general-purpose emulator. It's limited in a lot of
ways (won't launch on Mac[^1], no support for multiple computers) - just
stick to what's there already.

[^1]: We require OpenGL 4.5 due to our use of DSA.
2023-10-28 17:58:11 +01:00
Jonathan Coates
aee382ed70 Replace Fabric JUnit hacks with fabric-loader-junit
Also configure some of our common JUnit run configurations via Gradle -
I end up setting these up in every worktree anyway - so let's just do it
once.
2023-10-26 22:06:40 +01:00
Jonathan Coates
6656da5877 Remove disable_lua51_features config option
In practice, we're never going to change this to true by default. The
old Tekkit Legends pack enabled this[^1], and that caused a lot of
problems, though admittedly back in 2016 so things might be better now.

If people do want this functionality, it should be fairly easy to
replicate with a datapack, adding a file to rom/autorun.

[^1]: See https://www.computercraft.info/forums2/index.php?/topic/27663-

      Hate that I remember this, why is this still in my brain?
2023-10-25 08:59:55 +01:00
Jonathan Coates
09e521727f Make mount error messages a bit more consistent
- Move most error message constants to a new MountHelpers class.
 - Be a little more consistent in when we throw "No such file" vs "Not a
   file/directory" messages.
2023-10-22 13:13:07 +01:00
Jonathan Coates
cab66a2d6e Replace Collections methods with {List,Map,Set}.of
The two implementations aren't entirely compatible - the implementation
returned by .of will throw an NPE on .contains(null), whereas the
Collections implementations just return false. However, we try to avoid
passing null to collections methods, so this should be safe.

There's no strong reason to do this, but it helps make the code a little
more consistent
2023-10-21 10:37:43 +01:00
Jonathan Coates
8eabd4f303 Fix signs being empty when placed
As of 1.20, sign messages are immutable - we need to do
text = text.setMesssage(...) instead. Also do a tiny bit of cleanup to
this function while we're here.

Probably not the best use of my lunch break :D:.

Fixes #1611.
2023-10-20 13:32:38 +01:00
Jonathan Coates
e3ced84885 Merge branch 'feature/split-computer-thread' into mc-1.20.x 2023-10-19 22:54:56 +01:00
Jonathan Coates
0929ab577d Split ComputerThread/ComputerExecutor up a little
This is an attempt to enforce better separation between ComputerThread
and ComputerExecutor. Both of these classes are pretty complex in their
own right, and the way the two bleed into each other makes it all the
more confusing!

This effectively splits the ComputerExecutor into two separate classes:
 - ComputerScheduler.Executor (with the actual implementation inside
   ComputerThread): This holds all the ComputerThread-related logic
   which used to be in ComputerExecutor, including:

    - before/after work hooks
    - is-on-thread tracking
    - virtual runtime computation

 - ComputerScheduler.Worker: This encapsulates all the computer-related
   behaviour. The actual implementation remains in ComputerExecutor.

The boundaries are still a little fuzzy here, and it's all definitely
more coupled then I'd like, but still an improvement!

There are several additional changes at the same time:

 - TimeoutState has also been split up, to better define the boundary
   between consumers (such as ComputerExecutor and ILuaMachine) and
   controllers (ComputerThread).

   The getters still live in TimeoutState, but the core logic lives in
   ManagedTimeoutState.

 - We no longer track cumulative time in the TimeoutState. Instead, we
   allow varying the timeout of a computer. When a computer is paused,
   we store the remaining time, and restore it when resuming again.

   This also allows us give a longer timeout for computer
   startup/shutdown, hopefully avoiding some of those class-not-found
   issues we've seen.

 - We try to make the state machine of how ComputerExecutors live on the
   queue a little more explicit. This is very messy/confusing -
   something I want to property test in the future.

I'm sure there's more to be done here, especially in ComputerExecutor,
but hopefully this makes future changes a little less intimidating.
2023-10-19 22:50:11 +01:00
Jonathan Coates
2228733abc Move ComputerThread to its own package
This is entirely broken - we rely a lot on package locals right now -
but makes the next commit a little cleaner.
2023-10-19 18:31:02 +01:00
Jonathan Coates
e67c94d1bd Fix a couple of future deprecations in Gradle 2023-10-19 18:28:15 +01:00
Jonathan Coates
ae5a661a47 Add a discarding MetricsObserver
This is useful for test code where we don't care about the metrics
gathered.
2023-10-19 18:27:58 +01:00
Jonathan Coates
0ff58cdc3e Unify the generic peirpheral system a litte
Allows registering arbitrary block lookup functions instead of a
platform-specific capability. This is roughly what Fabric did before,
but generalised to also take an invalidation callback.

This callback is a little nasty - it needs to be a NonNullableConsumer
on Forge, but that class isn't available on Fabric. For now, we make the
lookup function (and thus the generic peripheral provider) generic on
some <T extends Runnable> type, then specialise that on the Forge side.
Hopefully we can clean this up when NeoForge reworks capabilities.
2023-10-17 21:59:16 +01:00
Jonathan Coates
1747c74770 Relicense some translations
One issue with Weblate is tracking down the provenance of who has
touched what file. I'm fairly sure this is accurate though.
2023-10-16 22:12:41 +01:00
Jonathan Coates
71669cf49c Replace ASM generation with MethodHandles
This is the second time I've rewritten our class generation in a little
over a month. Oh dear!

Back in d562a051c7 we started using method
handles inside our generated ASM, effectively replacing a direct call
with .invokeExact on a constant method handle.

This goes one step further and removes our ASM entirely, building up a
MethodHandle that checks arguments and then wraps the return value.
Rather than generating a class, we just return a new LuaFunction
instance that invokeExacts the method handle.

This is definitely slower than what we had before, but in the order of
8ns vs 12ns (in the worst case, sometimes they're much more comparable),
so I'm not too worried in practice.

However, generation of the actual method is now a bit faster. I've not
done any proper benchmarking, but it's about 20-30% faster.

This also gives us a bit more flexibility in the future, for instance
uisng bound MethodHandles in generation (e.g. for instance methods on
GenericSources). Not something I'm planning on doing right now, but is
an option.
2023-10-11 20:05:37 +01:00
Jonathan Coates
bd327e37eb Fix common jar not actually being published
Or rather, being published to the wrong place. The java-convention
plugin sets the group, but that was applied after the publishing one - I
was hoping it'd read that property lazy, but clearly not!
2023-10-11 19:15:36 +01:00
Jonathan Coates
bdce9a8170 Replace several Guava classes with Java stdlib
Wow, some of this is /old/. All the Maps.newHashMap stuff dates back to
Java 6, so must originally be CCTweaks code?!

We're unlikely to drop our Guava dependency (we use too much other
stuff), but we should make the most of the stdlib where possible.
2023-10-11 09:59:55 +01:00
Jonathan Coates
7e5598d084 Use ClassValue instead of LoadingCache
This should be significantly faster than LoadingCache (2.5x in my
benchmarks, but not sure they're representative). This isn't super
important - a lookup only takes 6us - but still worth using!
2023-10-11 09:30:29 +01:00
Jonathan Coates
440fca6535 Relicense a couple of more files
We've got in touch with Brady, so can now do the last of the docs \o/!

Also pick up a couple of stragglers that I'd missed from before.
2023-10-11 08:00:07 +01:00
Weblate
6635edd35c Translations for French
Translations for German

Translations for German

Co-authored-by: Sammy <SammyKoch@pm.me>
Co-authored-by: SquidDev <git@squiddev.cc>
2023-10-09 22:33:03 +00:00
Jonathan Coates
93ad40efbb Ensure the terminal exists when creating a monitor peripheral
Previously we had the invariant that if we had a server monitor, we also
had a terminal. When a monitor shrank into a place, we deleted the
monitor, and then recreated it when a peripheral was requested.

As of ab785a0906 this has changed
slightly, and we now just delete the terminal (keeping the ServerMonitor
around). However, we didn't adjust the peripheral code accordingly,
meaning we didn't recreate the /terminal/ when a peripheral was
requested.

The fix for this is very simple - most of the rest of this commit is
some additional code for ensuring monitor invariants hold, so we can
write tests with a little more confidence.

I'm not 100% sold on this approach. It's tricky having a double layer of
nullable state (ServerMonitor, and then the terminal). However, I think
this is reasonable - the ServerMonitor is a reference to the multiblock,
and the Terminal is part of the multiblock's state.

Even after all the refactors, monitor code is still nastier than I'd
like :/.

Fixes #1608
2023-10-09 22:09:01 +01:00
Jonathan Coates
27dc8b5b2c Pass follow_redirects flag to the CORS proxy
Currently redirects would be returned from the proxy, and then
immediately followed by XMLHTTPRequest. The proxy now follows requests
(when requested), so that should no longer happen.

We should probably switch over to fetch(...) here, to allow setting
follow_redirects to false, but that's a job for another day.

Haha, so many web emulator related commits of late. This'll die down
soon.
2023-10-08 20:12:47 +01:00
Jonathan Coates
3ebdf7ef5e Bump CC:T to 1.108.3 2023-10-08 15:25:45 +01:00
Jonathan Coates
905d4cb091 Fix crash when joining a dedicated server
We can't use FriendlyByte.readCollection to read to a
pre-allocated/array-backed NonNullList, as that doesn't implement
List.add. Instead, we just need to do a normal loop.

We add a couple of tests to round-trip our recipe specs. Unfortunately
we can't test the recipes themselves as our own registries aren't set
up, so this'll have to do for now.
2023-10-08 15:22:32 +01:00
Jonathan Coates
e7ab05d064 Bump CC:T to 1.108.2 2023-10-08 13:27:24 +01:00
Jonathan Coates
6ec34b42e5 Small cleanup to our web build scripts
- Update to Rollup 4.x
 - Replace terser and postcss with swc and lightningcss. This is
   definitely more code for us to write (maybe I should turn them into
   proper plugins we can depend on), but both speedier and fewer
   dependencies.
 - Drop dependency on glob - we can get away with fs.readdir for what we
   needed it for.
2023-10-08 13:14:02 +01:00
Jonathan Coates
ab785a0906 Fix monitors being warped after a resize
Oh, this was a really nasty bug to reproduce. I'm not sure why - it's
very simple - I guess I've only just seen screenshots of it, and never
sat down to try myself. Reminder to actually report your bugs folks!

In this case:

 1. Place down three down three monitors and then a computer.
 2. Display something on the monitor (monitor left paint a) is my go-to.
 3. Break the middle monitor.

We'd expect the left most monitor to be cleared, however it actually
preserves the monitor contents, resizing (and skewing it) to fit on its
new size!

This is because we clear the server monitor, but never sync that over to
the client, so the client monitor retains the old contents. To fix that,
instead of nulling out the server monitor, we null out the underlying
Terminal. This causes the change to be synced, fixing the bug.
2023-10-03 18:20:44 +01:00
Jonathan Coates
4541decd40 Fix canvas not always being redrawn on term resize
Paint implements its menu slightly differently to edit, in that it takes
control of the event loop until the menu is closed. This means that the
term_resize event is ignored, and so the canvas not redrawn when the
menu is open.
2023-10-03 18:18:33 +01:00
Spongecade
747a5a53b4 Update Minecraft wiki links to new domain (#1601) 2023-10-03 15:55:20 +00:00
Jonathan Coates
c0643fadca Build a web-based emulator for the documentation site (#1597)
Historically we've used copy-cat to provide a web-based emulator for
running example code on our documentation site. However, copy-cat is
often out-of-date with CC:T, which means example snippets fail when you
try to run them!

This commit vendors in copy-cat (or rather an updated version of it)
into CC:T itself, allowing us to ensure the emulator is always in sync
with the mod.

While the ARCHITECTURE.md documentation goes into a little bit more
detail here, the general implementation is as follows

 - In project/src/main we implement the core of the emulator. This
   includes a basic reimplementation of some of CC's classes to work on
   the web (mostly the HTTP API and ComputerThread), and some additional
   code to expose the computers to Javascript.

 - This is all then compiled to Javascript using [TeaVM][1] (we actually
   use a [personal fork of it][2] as there's a couple of changes I've
   not upstreamed yet).

 - The Javascript side then pulls in the these compiled classes (and
   the CC ROM) and hooks them up to [cc-web-term][3] to display the
   actual computer.

 - As we're no longer pulling in copy-cat, we can simplify our bundling
   system a little - we now just compile to ESM modules directly.

[1]: https://github.com/konsoletyper/teavm
[2]: https://github.com/SquidDev/teavm/tree/squid-patches
[3]: https://github.com/squiddev-cc/cc-web-term
2023-10-03 09:19:19 +01:00
Jonathan Coates
0a31de43c2 Run checkstyle on all source sets
Had an issue last week where testFixtures had a couple of issues which I
didn't pick up on, as the pre-commit hooks only check the main and test
source set.

We now add a per-project "checkstyle" task, which dependes on the
per-source-set checkstyle tasks.
2023-10-03 09:06:17 +01:00
Jonathan Coates
96b6947ef2 Flesh out MemoryMount into a writable mount
This moves MemoryMount to the main core module, and converts it to be a
"proper" WritableMount. It's still naively implemented - definitely
would be good to flesh out our tests in the future - but enough for what
we need it for.

We also do the following:
 - Remove the FileEntry.path variable, and instead pass the path around
   as a variable.
 - Clean up BinaryReadableHandle to use ByteBuffers in a more idiomatic
   way.
 - Add a couple more tests to our FS tests. These are in a bit of an odd
   place, where we want both Lua tests (for emulator compliance) and
   Java tests (for testing different implementations) - something to
   think about in the future.
2023-09-29 22:15:23 +01:00
Jonathan Coates
e7a1065bfc Move file transfer API to the code library
This is useful for emulators, which might want to emulate the event.
2023-09-29 21:09:23 +01:00
Jonathan Coates
663eecff0c Relocate our existing web code to subdirectories
- Move the frontend code into src/frontend
 - Move our custom element SSR system into src/htmlTransform.

This is mostly in prep for merging in copy-cat's core, as that's a whole
bunch of extra code.
2023-09-28 21:00:07 +01:00
Jonathan Coates
e6125bcf60 Try to make recipe serialisers more reusable
This attempts to reduce some duplication in recipe serialisation (and
deserialisation) by moving the structure of a recipe (group, category,
ingredients, result) into seprate types.

 - Add ShapedRecipeSpec and ShapelessRecipeSpec, which store the core
   properties of shaped and shapeless recipes. There's a couple of
   additional classes here for handling some of the other shared or
   complex logic.

 - These classes are now used by two new Custom{Shaped,Shapeless}Recipe
   classes, which are (mostly) equivalent to Minecraft's
   shaped/shapeless recipes, just with support for nbt in results.

 - All the other similar recipes now inherit from these base classes,
   which allows us to reuse a lot of this serialisation code. Alas, the
   total code size has still gone up - maybe there's too much
   abstraction here :).

 - Mostly unrelated, but fix the skull recipes using the wrong UUID
   format.

This allows us to remove our mixin for nbt in recipes (as we just use
our custom recipe now) and simplify serialisation a bit - hopefully
making the switch to codecs a little easier.
2023-09-23 18:24:02 +01:00
Jonathan Coates
0d6c6e7ae7 Hoist some ArchiveMount logic into a new superclass
- Add AbstractInMemoryMount, which contains all of ArchiveMount's file
   tree logic, but not the caching functionality.

 - Convert MemoryMount to inherit from AbstractInMemoryMount.

 - Add a helper method to add a file to an AbstractInMemoryMount, and
   use that within {Resource,Jar}Mount.

There's definitely more work to be done here - it might be nice to split
FileEntry into separate Directory and File interfaces, or at least make
them slightly more immutable, but that's definitely a future job.
2023-09-22 07:46:39 +01:00
Jonathan Coates
ae71eb3cae Reduce coupling in websocket code
- Add a new WebsocketClient interface, which WebsocketHandle uses for
   sending messages and closing. This reduces coupling between Websocket
   and WebsocketHandle, which is nice, though admitedly only use for
   copy-cat :).

 - WebsocketHandle now uses Websocket(Client).isClosed(), rather than
   tracking the closed state itself - this makes the class mostly a thin
   Lua wrapper over the client, which is nice.

 - Convert Options into a record.

 - Clarify the behaviour of ws.close() and the websocket_closed event.
   Our previous test was incorrect as it called WebsocketHandle.close
   (rather than WebsocketHandle.doClose), which had slightly different
   semantics in whether the event is queued.
2023-09-21 18:59:15 +01:00
Jonathan Coates
3188197447 Use Preact for static rendering of components
We already use preact for the copy-cat integration, so it makes sense to
use it during the static pass too. This allows us to drop a dependency
on react.
2023-09-20 22:09:58 +01:00
Jonathan Coates
6c8b391dab Some web tooling changes
- Switch to tsx from ts-node, fixing issues on Node 20
 - Update rehype
2023-09-18 17:15:03 +01:00
Jonathan Coates
b1248e4901 Add a tag for blocks wired modems should ignore
Includes wired modems (as before), but can be extended by other mods if
needed.
2023-09-11 21:29:17 +01:00
Jonathan Coates
56d97630e8 Bump CC:T to 1.108.1 2023-09-06 09:51:16 +01:00
Jonathan Coates
e660192f08 Make command computer permission checks stricter
- Placing a command computer requires the player to be in creative and
   opped.
 - Breaking a command computer now requires the player to be opped, as
   well as in creative.

As we've now got a dedicated item class for command comptuers, we move
the command-specific IMedia override to that class.

Fixes #1582.
2023-09-05 18:44:16 +01:00
Jonathan Coates
4e82bd352d Bump the priority of the computer thread
As this is responsible for interrupting computers, we should make sure
its priority is higher than the background threads. It spends most of
its time sleeping, so should be fine.
2023-09-05 18:39:55 +01:00
Jonathan Coates
07113c3e9b Move command actions to their own methods
Rather than having a mess of lambdas, we now move the bulk of the
implemetation to their own methods. The lambdas now just do argument
extraction - it's all stringly typed, so good to keep that with the
argument definition.

This also removes a couple of exception keys (and thus their translation
keys) as we no longer use them.
2023-09-05 18:37:10 +01:00
Jonathan Coates
d562a051c7 Use method handlees in our generated Lua methods (#1579)
When the target method is in a different class loader to CC, our
generated method fails, as it cannot find the target class. To get
around that, we create a MethodHandle to the target method, and then
inject that into the generated class (with Java's new dynamic constant
system). We can then invoke the MethodHandle in our generated code,
avoiding any references to the target class/method.
2023-09-03 16:12:37 +00:00
Jonathan Coates
6ac09742fc Fix errors from the typescript bump
Looks like ./gradlew docWebsite didn't rebuild here.
2023-08-31 20:49:53 +01:00
Jonathan Coates
5dd6b9a637 Generic dependency update
A couple of changes caused by checkstyle being a little more strict.
2023-08-31 19:14:37 +01:00
Jonathan Coates
8fb1dd346c Merge branch 'mc-1.19.x' into mc-1.20.x 2023-08-28 12:25:32 +01:00
Jonathan Coates
cdc8592aa3 Bump CC:T to 1.108.0 2023-08-28 12:24:35 +01:00
Jonathan Coates
0f6ea3deaf Add back MoreRed support
I removed this in aa0d544bba, way back in
late 2021. Looks like it's been updating in the meantime and I hadn't
noticed, so add it back.

I've simplified the code a little bit, to make use of our new capability
helpers, but otherwise it's almost exactly the same :D.
2023-08-28 00:04:46 +01:00
Jonathan Coates
13ed422bd5 Remove getBundledRedstoneConnectivity
Wow, this is old. It looks like it's a legacy of when this method was on
TileGeneric (and so returned false by default). As all implementations
now return true (turtle tools no longer block redstone), we don't really
need this any more.
2023-08-27 23:54:27 +01:00
Jonathan Coates
5b58271b92 Fix computer sidebar buttons being invisible 2023-08-27 19:25:04 +01:00
Jonathan Coates
4e42394f33 Merge branch 'mc-1.19.x' into mc-1.20.x 2023-08-27 19:08:59 +01:00
Jonathan Coates
53546b9f57 Split some textures into sprite sheets
- Split buttons.png into individual textures.
 - Split corners_xyz.png into the following:

   - borders_xyz.png: A nine-sliced texture of the computer borders.
   - pocket_bottom_xyz.png: A horizontally 3-sliced texture of the
     bottom part of a pocket computer.
   - sidebar_xyz.png: A vertically 3-sliced texture of the computer
     sidebar.

While not splitting the sliced textures into smaller ones may seem a
little odd, it's consistent with what vanilla does in 1.20.2, and I
think will make editing them easier than juggling 9 textures.

I do want to make this more data-driven in the future, but that will
have to wait until the changes in 1.20.2.

This also adds a tools/update-resources.py program, which performs this
transformation on a given resource pack.
2023-08-27 18:02:51 +01:00
Jonathan Coates
6dfdeb9321 Update Cobalt to 0.7.3
- Add support for Lua 5.2's %g.
 - Fix %p for the upper character ranges.
2023-08-27 15:35:55 +01:00
Jonathan Coates
500406f9eb Merge pull request #1569 from cc-tweaked/feature/no-compression
Remove compression from terminal/monitor packets
2023-08-27 14:15:56 +01:00
Jonathan Coates
b3738a7a63 Use permission APIs for the /computercraft command
- Add a generic PermissionRegistry interface. This behaves similarly to
   our ShaderMod interface, searching all providers until it finds a
   compatible one.

   We could just make this part of the platform code instead, but this
   allows us to support multiple systems on Fabric, where things are
   less standardised.

   This interface behaves like a registry, rather than a straight
   `getPermission(node, player)` method, as Forge requires us to list
   our nodes up-front.

 - Add Forge (using the built-in system) and Fabric (using
   fabric-permissions-api) implementations of the above interface.

 - Register permission nodes for our commands, and use those
   instead. This does mean that the permissions check for the root
   /computercraft command now requires enumerating all child
   commands (and so potential does 7 permission lookups), but hopefully
   this isn't too bad in practice.

 - Remove UserLevel.OWNER - we never used this anywhere, and I can't
   imagine we'll want to in the future.
2023-08-27 12:22:40 +01:00
Jonathan Coates
5f8b1dd67f Update Cobalt to 0.7.2
- Support printing and parsing hex float literals
 - Fix string.format "%q"'s handling of nan and inf (Kan18)
 - Fix string is-letter/is-digit patterns treating characters as
   unicode.
 - tostring(...) now uses __name.
2023-08-24 21:27:00 +01:00
Jonathan Coates
053751b190 Merge pull request #1570 from cc-tweaked/feature/new-md-syntax
Change the syntax of several markdown extensions
2023-08-24 16:26:41 +01:00
Jonathan Coates
52b78f92cd Use standard Markdown link syntax for references
References are now written using normal links: You now use [`print`] or
[print a string][`print`]) instead of @{print} or @{print|print a
string}.
2023-08-24 11:23:33 +01:00
Jonathan Coates
2055052a57 Switch to GitHub-style admonitions/alerts
As these are just a custom syntax on top of blockquotes, these work much
better with text editors.
2023-08-23 18:10:01 +01:00
Jonathan Coates
12ee47ff19 Bump illuaminate version
This has a new Markdown parser, so we need to remove our use of image
attributes.
2023-08-23 18:09:26 +01:00
Jonathan Coates
25776abf61 Fix address rules reading the wrong config key
Should be max_websocket_message, not just websocket_message.

Also add some additional validation to address rules, to check no
unrecognised keys are present.

Closes #1566.
2023-08-23 18:04:22 +01:00
Jonathan Coates
f7411b40a2 Remove compression from terminal/monitor packets 2023-08-23 10:06:15 +01:00
Jonathan Coates
8c8924f54e Fix CME in monitor's set of attached computers
We're very inconsistent with whether we use locks or concurrent maps
here. Something to sort out in the future, but for now add some missing
@GuardedBy annotations.
2023-08-23 10:05:56 +01:00
Jonathan Coates
c1628d077a Small improvements to packet reading/writing improvements
- Prefer {read,write}Nullable when possible.

 - Use SoundEvent.{writeTo,readFrom}Network, instead of sending the
   registry entries. This allows playing discs which don't register
   their SoundEvent on the server.

 - Add a couple of tests for round-tripping these packets.
2023-08-23 10:05:56 +01:00
Jonathan Coates
5b2fdec6ca Add some jqwik arbitraries for Minecraft types
This requires supporting registries in our platform test
code. Thankfully this is mostly the same as what we can do in Fabric -
the duplication is unfortunate - but it's easy enough.
2023-08-23 10:05:56 +01:00
Jonathan Coates
5a7259e4c9 Add a tiny library for checking structural equality
I want to write some tests to check that various packets round-trip
corretly. However, these packets don't (and shouldn't) implement
.equals, and so we need a more reflective(/hacky) way of comparing them.
2023-08-23 10:05:56 +01:00
Petr Karmashev
92b335f45f Fixed turtle.dropDown documentation (#1564) 2023-08-17 10:52:17 +00:00
Charlotte Herngreen
b93ea9c62e Fix function reference in cc.image.nft (#1559) 2023-08-15 16:59:41 +00:00
MineRobber___T
b9edd7c7f6 Add dark mode styling for recipes (#1558)
Exactly what it says on the tin.
2023-08-14 07:51:14 +01:00
Jonathan Coates
84a761ddd5 Bump pre-commit versions
Hopefully fixes pre-commit issues in CI.
2023-08-13 13:50:49 +01:00
Jonathan Coates
3371c4651c Merge branch 'mc-1.19.x' into mc-1.20.x 2023-08-13 08:38:13 +01:00
Jonathan Coates
2a04fb71fd Bump CC:T to 1.107.0 2023-08-13 08:34:45 +01:00
Srendi
df61389304 Fix some typos in CONTRIBUTING.md (#1549) 2023-08-05 21:30:19 +00:00
Jonathan Coates
e6bc1e4e27 Merge branch 'mc-1.19.x' into mc-1.20.x 2023-08-05 10:36:37 +01:00
Jonathan Coates
b6632c9ed9 Fix model hook nullability
Only an issue on the latest FAPI, so we also bump that.
2023-08-05 10:32:21 +01:00
Jonathan Coates
41b6711b38 Change button text in render rather than an override
This made more sense on 1.19.2 and before, but now that we have to do
this for tooltips, we might as well do it for messages as well.

Closes #1538, though hopefully will be resolved on the VO side too.
2023-07-27 19:12:27 +01:00
Virtio
02f0b7ec14 Fix typo in shell docs (#1537) 2023-07-25 16:27:23 +00:00
Jonathan Coates
a9d31cd3c6 Re-run datagen
- Remove some unused translation keys.
 - Run tools/language.py to sort the current translations and remove the
   aforementioned unused keys.
 - Update turtle tool impostor recipes - these now include the tool NBT!
2023-07-23 22:22:48 +01:00
Jonathan Coates
43744b0e85 Clean up ApiWrapper a little
We now wrap every Api with an ApiWrapper, rather than making it pretend
to be an ILuaApi.
2023-07-23 22:22:22 +01:00
Weblate
55510c42db Translations for Czech
Translations for Polish

Translations for French

Translations for Spanish

Translations for German

Co-authored-by: Patriik <apatriik0@gmail.com>
Co-authored-by: Sammy <SammyKoch@pm.me>
Co-authored-by: SquidDev <git@squiddev.cc>
2023-07-23 21:22:10 +00:00
Jonathan Coates
57a944fd90 Render enchanted upgrades with a glint (#1532) 2023-07-23 10:18:22 +00:00
Jonathan Coates
940f59b116 Automatically bake models from turtle modellers (#1531)
This avoids us having to list a bunch of model locations twice, and
hopefully makes things a little cleaner for add-on authors too
2023-07-22 19:51:50 +00:00
Jonathan Coates
dd08d1ec8e Fix client tests not running on Forge
This was introduced by the FG6 update - the cctest.client property
didn't get set, and so tests never started!
2023-07-22 19:40:50 +01:00
Jonathan Coates
90ed0b24e7 Send block updates to the computer when updating redstone
Fixes #1520
2023-07-22 13:50:13 +01:00
Jonathan Coates
0ad399a528 Rewrite turtle.dig tool actions
- Move the tool action before the "is block present" check, fixes
   #1527. This is where it was before, but we flipped it around in the
   tool rewrite.

 - Don't reuse as much turtle.place logic for tool actions. This fixes
   some instances where tools could till/level dirt through solid
   blocks.
2023-07-21 08:58:02 +01:00
Jonathan Coates
1b88213eca Make our registry wrapper implement IdMap
This allows us to use some of the byte-buffer helper methods directly
with our registries, rather than rolling our own helpers.
2023-07-19 20:20:38 +01:00
Erlend
eef05b9854 Add dark-mode compatible logo to README (#1521) 2023-07-18 19:26:45 +00:00
Jonathan Coates
24d74f5c80 Update to latest Fabric
- Overhaul model loading to work with the new API. This allows for
   using the emissive texture system in a more generic way, which is
   nice!

 - Convert some of our custom models to use Fabric's model hooks (i.e.
   emitItemQuads). We don't make use of this right now, but might be
   useful for rendering tools with enchantment glints.

   Note this does /not/ change any of the turtle block entity rendering
   code to use Fabric/Forge's model code. This will be a change we want
   to make in the future.

 - Some cleanup of our config API. This fixes us printing lots of
   warnings when creating a new config file on Fabric (same bug also
   occurs on Forge, but that's a loader problem).

 - Fix a few warnings
2023-07-18 19:27:27 +01:00
Jonathan Coates
ae50f900af Update library versions
Everything has updated to 1.20.1 now, so we can start depending on
things again :).
2023-07-10 20:50:32 +01:00
Jonathan Coates
48889ceb89 Merge branch 'mc-1.19.x' into mc-1.20.x 2023-07-10 20:38:25 +01:00
Jonathan Coates
c2988366d8 Add EMI compatibility
This just adds stack comparisons, so that upgrades are considered (much
like JEI and REI). No dynamic recipes, as EMI doesn't support those :(.
2023-07-10 20:31:06 +01:00
Jonathan Coates
ec0765ead1 Bump Cobalt to 0.7.1
- Fix numbers ending in "f" or "d" being lexed.
 - Fix string.pack's "z" causing out-of-bounds errors.
2023-07-10 20:17:54 +01:00
Weblate
b94e34f372 Translations for Italian
Co-authored-by: Alessandro <ale.proto00@gmail.com>
2023-07-10 15:03:03 +00:00
Jonathan Coates
af3263dec2 Allow disabling generic methods
Suddenly so easy as of the refactoring in 910a63214e395ecae6993d8e0487384c725b3dd3!

Closes #1382
2023-07-09 19:59:08 +01:00
Jonathan Coates
7f25c9a66b Only load client config on the client 2023-07-09 18:44:33 +01:00
Jonathan Coates
9ca3efff3c Add data generator support for required mods
We've supported resource conditions in the upgrade JSON for an age, but
don't expose it in our data generators at all.

Indeed, using these hooks is a bit of a pain to do in multi-loader
setups, as the JSON is different between the two loaders. We could
generate the JSON for all loaders at once, but it feels nicer to use
the per-loader APIs to add the conditions.

For now, we just support generating a single condition - whether a mod
is loaded not, via the requireMod(...) method.
2023-07-09 14:09:44 +01:00
Jonathan Coates
8f1bf4341c Merge branch 'mc-1.19.x' into mc-1.20.x 2023-07-08 09:38:17 +01:00
Jonathan Coates
aaf8c248a8 Bump CC:T to 1.106.1 2023-07-08 09:37:43 +01:00
Jonathan Coates
df26cd267a Fix conflicts with other mods replacing reach distance 2023-07-08 09:35:06 +01:00
Jonathan Coates
8914b78816 Also block the CGNAT range (100.64.0.0/10) 2023-07-08 09:27:09 +01:00
Jonathan Coates
9a48b53a83 Merge branch 'mc-1.19.x' into mc-1.20.x 2023-07-07 18:10:04 +01:00
Jonathan Coates
9519448e43 Don't render toast text with a shadow 2023-07-07 18:08:47 +01:00
Jonathan Coates
9ea7f45fa7 Fix class cast exception with ObjectSource
We were generating methods with the original object, rather than the
extra one.

Updated our tests to actually catch this. Unfortunately the only places
we use this interface is in HTTP responses and transferred files,
neither of which show up in the Lua-side tests.
2023-07-07 18:05:02 +01:00
Jonathan Coates
915b6f9d81 Switch away from Forge's loot modifiers
We switched to Forge's loot modifier system in the 1.20 update, as
LootTable.addPool had been removed. Turns out this was by accident, and
so we switch back to the previous implementation, as it's much simpler
and efficient.
2023-07-07 10:18:16 +01:00
Jonathan Coates
a98f3b2a4c Merge branch 'mc-1.19.x' into mc-1.20.x 2023-07-07 00:18:50 +01:00
Jonathan Coates
d351bc33c6 Bump CC:T to 1.106.0 2023-07-07 00:16:48 +01:00
Jonathan Coates
5d71770931 Several command permission fixes
- Attach permission checks to the first argument (so the literal
   command name) rather than the last argument. This fixes commands
   showing up when they shouldn't.

 - HelpingArgumentBuilder now inherits permissions of its leaf nodes.
   This only really impacts the "track" subcommand.

 - Don't autocomplete the computer selector for the "queue" subcommand.
   As everyone has permission for this command, it's possible to find
   all computer ids and labels in the world.

   I'm in mixed minds about this, but don't think this is an exploit -
   computer ids/labels are sent to in-range players so shouldn't be
   considered secret - but worth patching none-the-less.
2023-07-06 23:16:22 +01:00
Jonathan Coates
4bbde8c50c Tighten up the $private HTTP rule
- Block multicast and the fd00::/8 address ranges.
 - Block several cloud metadata providers which sit outside the standard
   address ranges.
2023-07-06 23:16:22 +01:00
Jonathan Coates
cc8c1f38e7 Small documentation improvements
- Document that settings.set doesn't persist values. I think this
   closes #1512 - haven't heard back from them.

 - Add missing close reasons to the websocket_closed event. Closes #1493.

 - Mention what values are preserved by os.queueEvent. This is just the
   same as modem.transmit. Closes #1490.
2023-07-06 23:03:22 +01:00
Jonathan Coates
cab9c9772a Add some tests for new turtle tool functionality
- Normalise upgrade keys, to be "allowEnchantments" and
   "consumeDurability". We were previously inconsistent with
   allow/allows and consumes.
 - Add tests for durability and enchantments of pickaxes.
 - Fix a couple of issues with the original upgrade NBT being modified.
 - Now store the item's tag under a separate key rather than on the
   root. This makes syncing the NBT between the two much nicer.
2023-07-06 22:28:56 +01:00
Jonathan Coates
e337a63712 Bump FG and Loom
Also split up CI steps a little, so that it's more clear what failed.
2023-07-05 20:58:15 +01:00
Weblate
efa92b741b Translations for Russian (ru_ru)
Translations for French

Co-authored-by: chesiren <chesiren63@gmail.com>
Co-authored-by: ego-rick <vsevidcev@gmail.com>
2023-07-04 23:03:03 +00:00
Jonathan Coates
a91ac6f214 Make turtle tools a little more flexible
Turtle tools now accept two additional JSON fields

 - allowEnchantments: Whether items with enchantments (or any
   non-standard NBT) can be equipped.
 - consumesDurability: Whether durability will be consumed. This can be
   "never" (the current and default behaviour), "always", and
   "when_enchanted".

Closes #1501.
2023-07-03 22:14:31 +01:00
PenguinEncounter
943a9406b1 Fix turtle.refuel example (#1510) 2023-07-02 17:19:09 +00:00
Jonathan Coates
0b2bb5e7b5 Use exclusiveContent for our maven
This is a little nasty as we need to include ForgeGradle's repo too, but
should still help a bit!
2023-07-02 12:21:03 +01:00
Jonathan Coates
8708048b6e Try to make turtle_test.peripheral_change more robust
Replace the arbitrary sleep with a thenWaitUntil.
2023-07-02 11:46:03 +01:00
Jonathan Coates
d138d9c4a5 Preserve item NBT for turtle tools
This is a pre-requisite for #1501, and some other refactorings I want to do.

Also fix items in the turtle upgrade slots vanishing. We now explicitly
invalidate the cache when setting the item.
2023-07-02 11:02:10 +01:00
Edvin
f54cb8a432 Allow upgrades to read/write upgrade data from ItemStacks (#1465) 2023-07-02 10:55:55 +01:00
Jonathan Coates
94f5ede75a Remove superflous Nonnull/Notnull annotations 2023-07-01 19:32:28 +01:00
Jonathan Coates
1977556da4 Deprecate IPocketAccess.getUpgrades
I think this left over from CCTweaks or Peripheral++. It doesn't really
make sense as an API - if/when we add multiple upgrades, we'll want a
different API for this.
2023-07-01 18:34:17 +01:00
Jonathan Coates
9eabb29999 Move the model cache inside TurtleModelParts
This removes a tiny bit of duplication (at the cost of mode code), but
makes the interface more intuitive, as there's no bouncing between
getCombination -> cache -> buildModel.
2023-07-01 18:27:36 +01:00
Jonathan Coates
ecf880ed82 Document HTTP rules a little better
It turns out we don't document the "port" option anywhere, so probably
worth doing a bit of an overhaul here.

 - Expand the top-level HTTP rules comment, clarifying how things are
   matched and describing each field.

 - Improve the comments on the default HTTP rule. We now also describe
   the $private rule and its motivation.

 - Don't drop/ignore invalid rules. This gets written back to the
   original config file, so is very annoying! Instead we now log an
   error and convert the rule into a "deny all" rule, which should make
   it obvious something is wrong.
2023-07-01 16:16:06 +01:00
Jonathan Coates
655d5aeca8 Improve REPL's handling of expressions
- Remove the "force_print" code. This is a relic of before we used
   table.pack, and so didn't know how many expressions had been
   returned.

 - Check the input string is a valid expression separately before
   wrapping it in an _echo(...). Fixes #1506.
2023-07-01 12:37:48 +01:00
Jonathan Coates
34f41c4039 Be lazier in configuring Forge runs 2023-06-29 22:31:49 +01:00
Jonathan Coates
f5b16261cc Update to Gradle 8.x
- Update to Loom 1.2 and FG 6.0. ForgeGradle has changed how it
   generates the runXyz tasks, which makes running our tests much
   harder. I've raised an issue upstream, but for now we do some nasty
   poking of internals.

 - Fix Sodium/Iris tests. Loom 1.1 changed how remapped configurations
   are generated - we create a dummy source set and associate the
   remapped configuration with that. All nasty stuff.

 - Publish the common library. I'm not a fan of this, but given how much
   internals I'm poking elsewhere, should probably get off my high
   horse.

 - Add renderdoc support to the client gametests, enabled with
   -Prenderdoc.
2023-06-29 20:10:17 +01:00
Jonathan Coates
7eb3b691da Fix misplaced calls to IArguments.escapes
- Fix mainThread=true methods calling IArguments.escapes too late. This
   should be done before scheduling on the main thread, not on the main
   thread itself!

 - Fix VarargsArguments.escapes not checking that the argument haven't
   been closed. This is slightly prone to race conditions, but I don't
   think it's worth the overhead of tracking the owning thread.

   Maybe when panama and its resource scopes are released.

Thanks Sara for pointing this out!

Slightly irked that none of our tests caught this. Alas.

Also fix a typo in AddressPredicate. Yes, no commit discipline.
2023-06-27 18:28:54 +01:00
Jonathan Coates
910a63214e Make Generic methods per-ComputerContext
- Move the class cache out of Generator into MethodSupplierImpl. This
   means we cache class generation globally (that's really expensive!),
   but the class -> method list lookup is local.

 - Move the global GenericSource/GenericMethod registry out of core,
   passing in the list of generic methods to the ComputerContext.

I'm not entirely thrilled by the slight overlap of MethodSupplierImpl and
Generator here, something to clean up in the future.
2023-06-26 21:46:55 +01:00
Jonathan Coates
591a7eca23 Clean up how we enumerate Lua/peripheral methods
- Move several interfaces out of `d00.computercraft.core.asm` into a
   new `aethods` package. It may make sense to expose this to the
   public API in a future commit (possibly part of #1462).

 - Add a new MethodSupplier<T> interface, which provides methods to
   iterate over all methods exported by an object (either directly, or
   including those from ObjectSources).

   This interface's concrete implementation (asm.MethodSupplierImpl),
   uses Generators and IntCaches as before - we can now make that all
   package-private though, which is nice!

 - Make the LuaMethod and PeripheralMethod MethodSupplier local to the
   ComputerContext. This currently has no effect (the underlying
   Generator is still global), but eventually we'll make GenericMethods
   non-global, which unlocks the door for #1382.

 - Update everything to use this new interface. This is mostly pretty
   sensible, but is a little uglier on the MC side (especially in
   generic peripherals), as we need to access the global ServerContext.
2023-06-26 19:42:42 +01:00
Jonathan Coates
a29a516a3f Small refactoring to generic peripherals
- Remove SidedGenericPeripheral (we never used this!), adding the
   functionality to GenericPeripheral directly. This is just used on the
   Fabric side for now, but might make sense with Forge too.

 - Move GenericPeripheralBuilder into the common project - this is
   identical between the two projects!

 - GenericPeripheralBuilder now generates a list of methods internally,
   rather than being passed the methods.

 - Add a tiny bit of documentation.
2023-06-26 19:11:59 +01:00
Jonathan Coates
4a5e03c11a Convert NamedMethod into a record 2023-06-26 18:51:14 +01:00
Jonathan Coates
50d460624f Make the list of API factories per-ComputerContext
The registry is still a singleton inside the Minecraft code, but this
makes the core a little cleaner.
2023-06-26 18:48:26 +01:00
Jonathan Coates
bc500df921 Use a builder for constructing ComputerContexts
We've got a few optional fields here, and more on their way, so this
ends up being a little nicer.
2023-06-26 18:42:19 +01:00
Jonathan Coates
4accda6b8e Some tiny optimisations to the window API
- Use integer indexes instead of strings (i.e. text, textColour). This
   is a tiny bit faster.
 - Avoid re-creating tables when clearing.

We're still mostly limited by the VM (slow) and string concatenation
(slow!). Short of having some low-level mutable buffer type, I don't
think we can improve this much :(.
2023-06-25 21:04:05 +01:00
Jonathan Coates
54ab98473f Be lazy in reporting errors in the lexer
Instead of reporting an error with `.report(f(...))`, we now do
`.report(f, ...)`. This allows consumers to ignore error messages when
not needed, such as when just doing syntax highlighting.
2023-06-25 15:48:57 +01:00
Jonathan Coates
7ffdbb2316 Publish docs for 1.20 as well 2023-06-25 09:47:56 +01:00
Jonathan Coates
672c2cf029 Limit turtle's reach distance in Item.use
When a turtle attempts to place a block, it does so by searching for
nearby blocks and attempting to place the item against that block.

This has slightly strange behaviour when working with "placable"
non-block items though (such as buckets or boats). In this case, we call
Item.use, which doesn't take in the position of the block we're placing
against. Instead these items do their own ray trace, using the default
reach distance.

If the block we're trying to place against is non-solid, the ray trace
will go straight through it and continue (up to the maximum of 5
blocks), allowing placing the item much further away.

Our fix here is to override the default reach distance of our fake
players, limiting it to 2. This is easy on Forge (it has built-in
support), and requires a mixin on Fabric.

Closes #1497.
2023-06-24 17:09:34 +01:00
Jonathan Coates
c3bdb0440e Merge pull request #1494 from Wojbie/lua.lua-require-fix
Update lua.lua require logic.
2023-06-20 23:38:22 +01:00
Wojbie
88f0c44152 Update lua.lua require logic.
This makes it more consistent in situations when someone requires with path starting with /.
2023-06-20 23:33:53 +02:00
Jonathan Coates
ebaf49508f Merge branch 'mc-1.19.x' into mc-1.20.x 2023-06-20 08:59:06 +01:00
JackMacWindows
c8523bf479 Add ability to serialize Unicode strings to JSON (#1489) 2023-06-18 21:42:28 +00:00
Jonathan Coates
953372b1b7 Fix quad order when rendering turtles upside down
- Reverse quads in our model transformer and when rendering as a block
   entity.
 - Correctly recompute normals when the quads have been inverted.

Closes #1283
2023-06-18 19:32:23 +01:00
Jonathan Coates
36b9f4ec55 Merge pull request #1485 from cc-tweaked/feature/turtle-upgrade-ui
Allow changing turtle upgrades from the GUI
2023-06-18 08:09:47 +01:00
Jonathan Coates
ccfed0059b Render the computer cursor as emissive
- Split the front face of the computer model into two layers - one for
   the main texture, and one for the cursor. This is actually a
   simplification of what we had before, which is nice.

 - Make the cursor layer render as an emissive quad, meaning it glows in
   the dark. This is very easy on Forge (just some model JSON) and very
   hard on Fabric (requires a custom model loader).
2023-06-17 18:02:05 +01:00
Jonathan Coates
c45fc94752 Remove support for clicking in off-hand pocket computers
This was broken/commented out already as part of the 1.20 update. I
don't think this is really going to be easy to add back without a lot of
reflection, so going to remove this feature instead.

Closes #1471.
2023-06-17 11:44:51 +01:00
Jonathan Coates
7b4ba11fb4 Allow changing turtle upgrades from the GUI
This adds two slots to the right of the turtle interface which contain
the left and right upgrades of a turtle.

 - Add turtle_upgrade_{left,right} indicators, which used as the
   background texture for the two upgrade slots. In order to use
   Slot.getNoItemIcon, we need to bake these into the block texture
   atlas.

   This is done with the new atlas JSON and a data generator - it's
   mostly pretty simple, but we do now need a client-side data
   generator, which is a little ugly to do.

 - Add a new UpgradeContainer/UpgradeSlot, which exposes a turtle's
   upgrades in an inventory-like way.

 - Update the turtle menu and screen to handle these new slots.
2023-06-17 10:48:44 +01:00
Jonathan Coates
8ccd5a560c Add support for codecs to our data generator system
This already exists in both upstream loaders, we just need to abstract
over it.
2023-06-17 10:37:19 +01:00
Weblate
0f866836a0 Translations for Russian (ru_ru)
Co-authored-by: Andrew71 <andrey.nikitin.vladimirovich@gmail.com>
2023-06-16 21:03:01 +00:00
Jonathan Coates
df591cd7c6 Allow extending UpgradeDataProvider
Closes #1477
2023-06-15 18:57:25 +01:00
Jonathan Coates
c7f3d4f45d Port fs.find to CraftOS
Also add support for "?" style wildcards.

Closes #1455.
2023-06-15 18:57:05 +01:00
Jonathan Coates
77ac04cb7a Fix changelog notes
Also exclude data generator cache from the Forge jar. Didn't have any
better place to put this 😳.
2023-06-15 18:32:30 +01:00
Jonathan Coates
fd1f6dda32 Allow using printed books in chiseled bookshelves 2023-06-14 20:42:58 +01:00
Jonathan Coates
5d6389dc50 Update to Minecraft 1.20.1 2023-06-13 18:07:07 +01:00
Jonathan Coates
201df7e987 Merge pull request #1481 from znepb/fix-flute-code
Fix missing curly brace in instrument list
2023-06-13 14:24:27 +01:00
Marcus
5722e51735 Fix missing curly brace in instrument list 2023-06-13 06:04:35 -04:00
Jonathan Coates
7a291619ab Merge pull request #1480 from MCJack123/patch-16
Fixed typo in cc.image.nft docs
2023-06-13 07:26:59 +01:00
JackMacWindows
4b9b19b02d Fixed typo in cc.image.nft docs 2023-06-12 19:49:45 -04:00
Jonathan Coates
1ece2aa23b Merge branch 'mc-1.19.x' into mc-1.20.x 2023-06-10 09:07:41 +01:00
Jonathan Coates
ec52f3e0e8 Bump CC:T to 1.104.0 2023-06-10 08:55:07 +01:00
Jonathan Coates
96847bb8c2 Make turtle placing consistent at all positions
Turtles used to place stairs upside-down when at y<0. Now we know why!
2023-06-08 20:52:32 +01:00
Jonathan Coates
68ef9f717b Deprecate itemGroups field
Since 1.19.3, this was only populated when the player opened the
creative menu, and so was useless in survival or multi-player
worlds.

Rather than removing the field entirely (🦑 backwards compatibility), we
replace it with the empty list. We also remove it from the docs, and add
a note explaining what the field used to do.

Closes #1285, albeit in the least satisfactory way possible.
2023-06-08 20:33:31 +01:00
Jonathan Coates
cba207d62d Use Minecraft's method for checking paste events
Fixes #1473.

There's an argument we should use Screen.hasControlDown() (which handles
Cmd vs Ctrl) instead of checking the modifiers, but we then need to
update all the translation strings, and I'm not convinced it's worth it
right now.
2023-06-08 18:48:50 +01:00
Jonathan Coates
e157978afc Deprecate ITurtleAccess.getVisual{Position,Yaw} 2023-06-08 18:32:00 +01:00
Jonathan Coates
ff1e5f6823 Update to 1.20
- Use GuiGraphics for rendering UI elements. Almost definitely some
   z-fighting issues slipped in here.

 - Use Forge's loot modifier system for handling treasure disks. I have
   mixed feelings about this - it's a nice system, but also is far less
   efficient than the previous approach.

 - Regenerate data. This is the brunt of the commit, but nothing
   especially interesting here.
2023-06-08 09:52:00 +01:00
Jonathan Coates
ef19988c37 Add translations for HTTP proxy config 2023-06-07 18:33:26 +01:00
Drew Edwards
c91bb5ac33 Add support for proxying HTTP requests (#1461) 2023-06-06 18:58:24 +00:00
Commandcracker
d45f2bfe80 Fix channel names in colors documentation (#1467) 2023-06-04 12:10:04 +00:00
Jonathan Coates
8fdef542c9 Update to latest JEI 2023-06-04 12:49:46 +01:00
Jonathan Coates
6e7cbf25e8 Clean up turtle/pocket computer item creation
- Remove ITurtleItem (and ITurtleBlockEntity): this was, AFAIK, mostly
   a relic of the pre-1.13 code where we had multiple turtle items.

   I do like the theory of abstracting everything out behind an
   interface, but given there's only one concrete implementation, I'm
   not convinced it's worth it right now.

 - Remove TurtleItemFactory/PocketComputerItemFactory: we now prefer
   calling the instance .create(...) method where we have the item
   available (for instance upgrade recipes).

   In the cases we don't (creating an item the first time round), we now
   move the static .create(...) method to the actual item class.
2023-06-04 11:25:30 +01:00
Jonathan Coates
b691430889 Clean up our thread creation code a little
- Provide a helper method for creating threads with a lower priority.

 - Use that in our network code (which already used this priority) and
   for the computer worker threads (which used the default priority
   before). I genuinely thought I did this years ago.
2023-06-03 20:51:21 +01:00
Jonathan Coates
f0abb83f6e Eagerly create upgrade registries for Fabric
Instead of creating the upgrade serialiser registries in mod
initialisation, we now do it when the API is created. This ensures the
registries are available for other mods, irrespective of mod load order.

This feels a little sad (we're doing side effects in the static
initialiser), but is /fine/ - it's pretty much what other mods do.
2023-06-03 19:04:02 +01:00
Jonathan Coates
4d064d1552 Document some of our client classes
This is mostly aiming to give an overview rather than be anything
comprehensive (there's another 230+ undocumented classes to go :p), but
it's a start.

Mostly just an excuse for me to procrastinate working on the nasty bugs
though!
2023-06-02 21:59:45 +01:00
Jonathan Coates
12ca8583f4 Add a couple of tests for HTTP 2023-06-02 20:57:45 +01:00
Jonathan Coates
9cca908bff Better logging in the term code 2023-06-01 20:32:04 +01:00
Jonathan Coates
5082b1677c Move MainThread config to its own class
This means the config is no longer stored as static fields, which is a
little cleaner. Would like to move everything else in the future, but
this is a good first step.
2023-05-31 22:21:17 +01:00
Jonathan Coates
590ef86c93 Show an error message when editing read-only files
See #1222
2023-05-31 19:32:35 +01:00
Jonathan Coates
b09200a270 Fix breaking computers having no particle or sound 2023-05-31 19:18:19 +01:00
Jonathan Coates
d3b39be9a8 Fix enums not being added to config files
The default validator allows for null (why???), and so accepts it not
being present at all.
2023-05-30 22:20:47 +01:00
Jonathan Coates
e153839a98 Detect playing HTML files in speaker
Goes someway towards preventing people playing YouTube or non-raw GitHub
files.
2023-05-26 10:19:42 +01:00
Jonathan Coates
842eb67e17 Normalise line endings in the SanitisedError test
We could use the system line ending when printing the message, but this
is fine too.
2023-05-25 09:49:40 +01:00
Jonathan Coates
ebed357f05 Truncate longer error messages
We could do this in a more concise manner by wrapping Throwable rather
than reimplementing printStackTrace. However, doing this way allows us
to handle nested exceptions too.
2023-05-25 09:10:03 +01:00
Jonathan Coates
9d16fda266 Fix image links in Modrinth description
Modrinth proxies images hosted on non-trusted domains through wsrv.nl,
for understandable reasons. However, wsrv.nl blocks tweaked.cc - I'm not
sure why. Instead we reference the image on GH directly, which works!

Also:
 - Fix the modrinthSyncBody task pointing to a missing file.
 - Update the licenses of a few files, post getting permission from
   people. <3 all.
2023-05-24 22:35:45 +01:00
Jonathan Coates
2ae14b4c08 Add support for HTTP timeouts (#1453)
- Add a `timeout` parameter to http request and websocket methods.
    - For requests, this sets the connection and read timeout.
    - For websockets, this sets the connection and handshake timeout.
 - Remove the timeout config option, as this is now specified by user
   code.
 - Use netty for handling websocket handshakes, meaning we no longer
   need to deal with pongs.
2023-05-23 22:32:16 +00:00
Jonathan Coates
55ed0dc3ef Use UTC formats for the 12am os.date tests
We could alternatively use os.time { ... } here, but this feels more
"correct"?

Fixes #1447
2023-05-21 11:08:01 +01:00
Jonathan Coates
3112f455ae Support arguments being coerced from strings
In this case, we use Lua's tostring(x) semantics (well, modulo
metamethods), instead of Java's Object.toString(x) call. This ensures
that values are formatted (mostly) consistently between Lua and Java
methods.

 - Add IArguments.getStringCoerced, which uses Lua's tostring semantics.

 - Add a Coerced<T> wrapper type, which says to use the .getXCoerced
   methods. I'm not thrilled about this interface - there's definitely
   an argument for using annotations - but this is probably more
   consistent for now.

 - Convert existing methods to use this call.

Closes #1445
2023-05-20 18:54:22 +01:00
Jonathan Coates
e0216f8792 Some core cleanup
- Move some ArgumentHelpers methods to the core project.
 - Remove static imports in CobaltLuaMachine, avoiding confusing calls
   to valueOf.
2023-05-18 19:20:27 +01:00
Jonathan Coates
03c794cd53 Remove packet distance restriction for wired modems
Given that the network (and peripheral access within the network) no
longer have distance limits, packets being limited makes less sense.

Closes #1434.
2023-05-18 19:01:09 +01:00
Jonathan Coates
b91bca8830 Merge pull request #1446 from Erb3/erb3-path-3
Add `colors.fromBlit`.
2023-05-17 22:47:28 +01:00
Jonathan Coates
90177c9f8b Convert to block comments
And remove empty line between block and definition
2023-05-17 22:21:38 +01:00
Erlend
952674a161 Improve argument validation in colors.fromBlit 2023-05-17 20:20:53 +02:00
Erlend
25ab7d0dcb Improve test for colors.fromBlit to show inverse 2023-05-17 20:16:47 +02:00
Erlend
98ee37719d Improve documentation for colors.fromBlit and colors.toBlit 2023-05-17 20:09:59 +02:00
khankul
e24b5f0888 Make maximum upload file size configurable (#1417) 2023-05-17 13:07:16 +00:00
Erlend
090d17c528 Add tests for colors.fromBlit 2023-05-17 14:43:08 +02:00
Jonathan Coates
470f2b098d Force LF for .kts files too 2023-05-17 13:28:03 +01:00
Erlend
722b870f98 fix #1367: Add colors.fromBlit 2023-05-17 14:02:21 +02:00
Jonathan Coates
3bf29695fb Fix a couple of wee bugs
- Fix monitor renderer debug text showing up even when debug overlay
   was not visible. This was a Forge-specific bug, which is why I'd not
   noticed it I guess??

 - Don't crash on alternative implementations of LoggerContext. Fixes
   #1431. I'm not 100% sure what is causing this - it doesn't happen
   with just CC:T at least - but at least we can bodge around it.
2023-05-07 10:15:03 +01:00
Weblate
99e8cd29a1 Translations for Ukrainian
Co-authored-by: Edvin <siredvin.dark@gmail.com>
2023-05-07 06:02:55 +00:00
Jonathan Coates
0e48ac1dfe Speed up JSON string parsing
We now use Lua patterns to find runs of characters. This makes string
parsing 3-4x faster. Ish - I've not run any exact benchmarks.

Closes #1408
2023-05-04 19:47:52 +01:00
Jonathan Coates
232c051526 Update to latest Fabric
- Use Fabric FakePlayer class
 - Remove redundant explosion accessor
2023-05-04 18:50:00 +01:00
Jonathan Coates
34928257c6 Merge pull request #1430 from Lupus590/patch-1
Fix typo in docs
2023-05-04 14:39:16 +01:00
Lupus590
5eb4a9033b Fix typo in docs
foreground and background *characters* -> foreground and background *colours*
2023-05-04 13:58:56 +01:00
Jonathan Coates
54b7366b2d Merge pull request #1421 from zyxkad/patch-1
Fixed `turtle.detectUp` & `turtle.detectDown` doc
2023-04-23 17:20:44 +01:00
Kevin Z
d6751b8e3d Update TurtleAPI.java
Fixed `turtle.detectUp` & `turtle.detectDown` doc
2023-04-23 09:58:29 -06:00
Jonathan Coates
5d7cbc8c64 Use Fabric's new SlottedStorage for inventory methods
This is a little more general than InventoryStorage and means we can get
rid of our nasty double chest hack.

The generic peripheral system doesn't currently support generics (hah),
and so we need to use a wrapper class for now.
2023-04-16 09:16:39 +01:00
Jonathan Coates
e8fd460935 Fix arrow keys not working in the printout UI
This is a Fabric-specific bug - vanilla always returns true from
keyPressed, but Forge patches it to not do that. Closes #1409.
2023-04-16 09:15:51 +01:00
Jonathan Coates
a0efe637d6 Merge pull request #1414 from Erb3/mc-1.19.x
Fix on/off translation being inverted
2023-04-16 09:13:47 +01:00
Erlend
f099b21f6f fix: on/off translation inverted 2023-04-15 16:21:53 +02:00
Jonathan Coates
3920ff08ab Some README cleanup
- Standardise our badges a little, adding a modrinth badge.
 - Mention Fabric and Forge support.
 - Don't include MC version in the Modrinth version number. I feel this
   was required at some point, but apparently not any more! This also
   allows us to use Modrinth for the Forge update JSON.
2023-04-06 18:18:40 +01:00
Jonathan Coates
ccd7f6326a Allow GPS hosts to be closer together
I'm not quite sure why I typed a 5 here. There we go.
2023-04-05 21:59:20 +01:00
Jonathan Coates
1f3815039f Bump CC:T to 1.104.0 2023-04-05 20:50:01 +01:00
Jonathan Coates
eef67a04a4 Handle duplicate pings received by gps.locate
Co-authored-by: Wojbie <Wojbie@gmail.com>
2023-04-05 20:18:38 +01:00
Jonathan Coates
8fe509ecb1 Properly scope IArguments to the current function call
This is a horrible commit: It's a breaking change in a pretty subtle
way, which means it won't be visible while updating. Fortunately I think
the only mod on 1.19.4 is Plethora, but other mods (Mek, Advanced
Peripherals) may be impacted when they update. Sorry!

For some motivation behind the original issue:

The default IArguments implementation (VarargArguments) lazily converts
Lua arguments to Java ones. This is mostly important when passing tables
to Java functions, as we can avoid the conversion entirely if the
function uses IArguments.getTableUnsafe.

However, this lazy conversion breaks down if IArguments is accessed on a
separate thread, as Lua values are not thread-safe. Thus we need to
perform this conversion before the cross-thread sharing occurs.

Now, ideally this would be an implementation detail and entirely
invisible to the user. One approach here would be to only perform this
lazy conversion for methods annotated with @LuaFunction(unsafe=true),
and have it be eager otherwise.

However, the peripheral API gets in the way here, as it means we can no
longer inspect the "actual" method being invoked. And so, alas, this
must leak into the public API.

TLDR: If you're getting weird errors about scope, add an
IArguments.escapes() call before sharing the arguments between threads.

Closes #1384
2023-04-01 11:09:03 +01:00
Jonathan Coates
cbb3e88d76 Relicense a couple more files
Again, not wild about .license files, but it's kinda the only option :/.

See #1339 for further details. <3 everyone!
2023-03-31 18:22:57 +01:00
Jonathan Coates
081953655c Turtle flags
- Add a new recipe type for turtle overlays, and recipe generator
   support for this recipe.
 - Add trans and rainbow flags.
 - Exclude .license files from the generated jar. I'm not thrilled on
   the whole .license file system, but it's kinda the easiest way.
 - Regenerate data. Yes, this is 90% of the commit :D.
2023-03-31 18:14:44 +01:00
Jonathan Coates
a9547d1d6f Further licensing work
- Fix several inaccuracies with several files not marking Dan's
   authorship. Most of these are new files, where the code was moved from
   somewhere else:
   - In the public API:  IDynamicLuaObject, ILuaAPI, TaskCallbakc,
     IDynamicPeripheral, UpgradeBase
   - In the ROM: fs, http, require

 - Do not mark Dan as an author for entirely new code. This affects
   DetailHelpers, DropConsumer, FluidData, InventoryMethods, ItemDetails,
   MonitorRenderState, NoTermComputerScreen, Palette, PlatformHelperImpl,
   UploadFileMessage, the Terminal tests, and any speaker-related files.

 - Relicence many files under the MPL where we have permission to do
   so. See #1339 for further details.

Thank you to everyone who has contributed so far! Cannot overstate how
appreciated it is <3.
2023-03-29 23:00:18 +01:00
Jonathan Coates
e876685f2a Put our bundled deps are on the classpath for gametests
We just need to make minecraftLibrary extend minecraftEmbed. I'd
genuinely forgotten that this isn't the case by default.
2023-03-29 23:00:18 +01:00
Jonathan Coates
dbd47be432 Detect common audio containers in "speaker"
Trying to play a non-DFPWM (or WAV) file will generate terrible noise,
which in turns generates confused users. Instead, fail to play the audio
file and redirect them to the docs.
2023-03-29 09:51:09 +01:00
Jonathan Coates
f93a33aa5e Bundle jzlib with our published jar
Netty requires this for handling compressed websockets with non-default
compression arguments.

Closes #1394
2023-03-29 09:32:06 +01:00
Jonathan Coates
e655c6d302 Prevent use of shell as a hashbang program
This doesn't do what you want (it'll infinite loop), so while special
casing it /is/ ugly, it's better than a confusing error.

Closes #1386.
2023-03-28 20:57:26 +01:00
Jonathan Coates
7535972a30 Fix pocket computers rendering as greyscale
When a client sided pocket computer was first seen via an item stack
(rather than the computer state being synced over the networK), it would
always be created in greyscale due to this incorrect instanceof check.

Closes #1347
2023-03-28 20:43:03 +01:00
Jonathan Coates
435aea18dc Some cleanup to argument checking
- Consult __name in native code too. Closes #1355. This has the added
   advantage that unconvertable values (i.e. functions) will now
   correctly be reported as their original type, not just nil.

 - Fix the error message in cc.expect, so it matches the rest of Lua.
   This has been bugging me for years, and I keep forgetting to change
   it.
2023-03-28 19:17:15 +01:00
Jonathan Coates
8a203e7454 Re-license several more files under MPL-2.0
- Several files where @MCJack123 is the exclusive contributor. He has
   signed over all contributions to "any OSI-approved license". Thank
   you!

 - Various the file handle classes: Looking at these again, I don't
   think they contain any of the original code.
2023-03-28 10:28:59 +01:00
Jonathan Coates
ca279d410a Support __name inside cc.expect
See #1355
2023-03-28 08:55:29 +01:00
Jonathan Coates
5bb2e8e8cd Update Cobalt to 0.7
- Timeouts are now driven by an interrupt system, rather than polling.
   While we do not impose memory limits, this should close #1333.

 - Update the table library to largely match Lua 5.4:
    - Add table.move
    - Table methods (with the exception of foreach/foreachi) now use
      metamethods (closes #1088).
   There's still some remaining quirks (for instance, table.insert
   accepts values out-of-bounds), but I think that's fine.

 - Cobalt's threaded-coroutine system is gone (load now supports
   yielding), so we no longer track coroutine metrics.

 - Type errors now use __name. See #1355, though this does not apply to
   CC methods (either on the Java or CraftOS side), so is not enough to
   resolve it.

See https://github.com/SquidDev/Cobalt/compare/v0.6.0...v0.7.0 for the
full delta.
2023-03-26 19:42:55 +01:00
Drew Edwards
0046b095b1 Sort compounds in NBT lists for hashing (#1391) 2023-03-26 16:49:52 +00:00
Jonathan Coates
82947a6e67 A couple of CSS tweaks
- Fix the "Run" button scrolling horizontally on small screens.
 - Make the "X" in the computer popup square.
 - Make the computer popup more fun.
2023-03-24 21:02:32 +00:00
Weblate
504567292b Translations for French
Co-authored-by: chesiren <chesiren63@gmail.com>
2023-03-19 11:02:50 +00:00
Jonathan Coates
1848d91646 Merge pull request #1378 from MCJack123/patch-15
Add more explanation on how `os.epoch("ingame")` works
2023-03-16 06:25:21 +00:00
JackMacWindows
06af3c7240 Add more explanation on how os.epoch("ingame") works 2023-03-16 01:28:12 -04:00
Jonathan Coates
266182996d Publish Fabric jars to CF/Modrinth
Like all publishing code, we'll only find out if it works when we run
it!
2023-03-15 23:20:13 +00:00
Jonathan Coates
986c65f56e Construct ILuaMachines in one go
This means creating an ILuaMachine is largely atomic - it either is
created or it fails.
2023-03-15 22:39:51 +00:00
Jonathan Coates
988219ffca Add back missing PlatformHelper
Add back file removed in merge of 895bc7721a.
2023-03-15 22:34:34 +00:00
Jonathan Coates
b9e2d0a936 Ignore metatables in textutils.serialize
Closes #1368
2023-03-15 21:53:47 +00:00
Jonathan Coates
895bc7721a License CC:T according to the REUSE specification (#1351)
This adds SPDX license headers to all source code files, following the
REUSE[1] specification. This does not include any asset files (such as
generated JSON files, or textures). While REUSE does support doing so
with ".license" files, for now we define these licences using the
.reuse/dep5 file.

[1]: https://reuse.software/
2023-03-15 21:52:13 +00:00
Jonathan Coates
3e6e3e70e5 Update to 1.19.4 (#1376) 2023-03-15 21:04:11 +00:00
Jonathan Coates
44f945c040 Correctly obey stack limits in OffsetStorage.extract/insert
Many thanks to Lem for managing to reproduce it. It was actually an easy
bug bug to spot on second look, but having a reliable way to verify was
super helpful.

Fixes #1338
2023-03-15 20:07:17 +00:00
Jonathan Coates
e96ac35d67 Replace Forge Config port with a NYI version
While it is a really nice library, it ends up being a bit overkill for
our needs - we don't need config syncing or anything. By NIHing our own,
we can drop one dependency and ease the updating burden a little.

Closes #1296
2023-03-14 22:47:34 +00:00
Jonathan Coates
a74089d8ae Bump dependency versions
Mostly in prep for 1.19.4.

 - Update to Loom 1.1.

   - Simplifies our handling of remapped configurations a little.
   - Removes the need for a fake fabric.mod.json in the API jar.

   For reasons I don't quite understand, this required us to bump the
   Fabric API version. Otherwise interfaces are not injected.

 - Update to Rollup 3.0.

 - Do NOT update NullAway: It now correctly checks @Nullable fields in
   inherited classes. This is good, but also a pain as Minecraft is a
   little over-eager in where it puts @Nullable.
2023-03-14 18:43:42 +00:00
Jonathan Coates
04fed62dad Fix NBT key name from the previous commit
I'd got it right originally, and then did a find-and-replace to fix the
gametests, forgetting that it'd touch here too. Woops.
2023-03-14 09:42:53 +00:00
Jonathan Coates
06322feb69 Fix typo in modem NBT key 2023-03-14 09:21:13 +00:00
Jonathan Coates
0ed0504a4c Add workaround for FG not picking up transitive deps 2023-03-14 09:03:45 +00:00
Weblate
e2cf43718f Translations for Norwegian Bokmål
Co-authored-by: Erlend <erlend.bergersen@sandnesskolen.no>
2023-03-08 10:56:04 +00:00
Jonathan Coates
118d04f018 Allow placing items against some blocks
We define a tag which allows specifying which blocks can be used. Right
now this is is just cauldrons and hives, as they have "placing into"
semantics.

Closes #1305. Many thanks to Lindsay-Needs-Sleep for their initial work
on this!

Fixes #1008. I believe also fixes #854.
2023-03-04 18:17:43 +00:00
Jonathan Coates
566315947b Try to ensure atomic writes to our ID file
- We now write to a "ids.json.new" file, then move that on top of the
   original ids.json file instead.

 - Use FileChannel.force to ensure the new file is properly flushed to
   disk. I can't really guarantee this'll work with the later
   Files.move, but it's better than not doing it!

Closes #1346.
2023-03-04 16:02:21 +00:00
Jonathan Coates
c9bb534799 Don't create a TrustManagerFactory
See the discussion in #1352 - Netty uses the system one by default,
so no sense creating our own.

Also make sure we through the HTTP error every time, not just on the
first failure. Otherwise we get cryptic connection dropped errors.
2023-03-04 11:21:06 +00:00
Jonathan Coates
1c120982a7 Distinguish between all parsers passing and failing
Given an input like f(x), which is both a valid statement and
expression, both parsers would accept the whole input. However, this was
treated the same as both parsers rejecting the input, resulting in a
crash when trying to print the error.

We now return immediately when any parser accepts the input.

Fixes #1354
2023-03-04 10:30:12 +00:00
Jonathan Coates
111f971ed0 Merge pull request #1349 from MCJack123/patch-14
Fix introduction dates of os.cancel[Alarm|Timer]
2023-02-28 06:36:36 +00:00
JackMacWindows
67c462f8b0 Fix introduction dates of os.cancel[Alarm|Timer] 2023-02-27 21:57:45 -05:00
Weblate
46ab2f5d5e Translations for Czech
Translations for Italian

Translations for French

Co-authored-by: Alessandro <ale.proto00@gmail.com>
Co-authored-by: RomanPlayer22 <romansulc13122006@gmail.com>
Co-authored-by: chesiren <chesiren63@gmail.com>
2023-02-20 14:55:58 +00:00
Jonathan Coates
4e909bc59e Improve several comma related parse errors
- Suggest adding a comma on { 2 3 }
 - Suggest removing a comma on f(1, )

Closes #1341.
2023-02-17 21:07:48 +00:00
Jonathan Coates
41c83988a1 Be more rigorous in checking for invalid values in settings.load
If someone had a recursive table (created with an IIFE), then we'd throw
an error inside reserialize. We now catch this error and silently drop
the value.

I'm not thrilled by this behaviour - there's an argument we should
return false instead - but it's consistent with what we currently do.

Closes #1337.
2023-02-17 09:08:29 +00:00
Jonathan Coates
a5bda7454a Use the VBO monitor renderer by default
Historically, the VBO was an order of magnitude slower than the TBO
renderer. However, as of fccca22d3f, the
difference is much smaller now. While TBOs /are/ still faster, this only
has a measurable impact in extreme stress tests, and so isn't worth the
occasional issues which occur.

I'm still keeping the code around for now: I'm incredibly fond of it,
even three years later. I may end up re-evaluating this the next time
Minecraft's rendering code changes :D.

This also adds a line to the debug screen showing the current monitor
renderer, though maybe less useful now that almost everyone will be
using VBOs!
2023-02-17 08:48:07 +00:00
Weblate
53619a64b5 Translations for Czech
Co-authored-by: RomanPlayer22 <romansulc13122006@gmail.com>
2023-02-14 19:55:55 +00:00
Jonathan Coates
77fc2e3af4 Bump illuaminate
- Fix search failing when something is missing a summary (i.e. the
   window API)

 - Correctly use ":" or "." for type members - previously it was
   incredibly inconsistent.
2023-02-14 08:44:19 +00:00
Jonathan Coates
33b6f38339 Hide the internal redirect methods in multishell
Previously it was possible to access all methods of the multishell
redirect by calling term.current(). This is definitely not intended, as
it leaks all sorts of internals to the user.

Also bump illuaminate - the new version is about twice as fast on my
machine.
2023-02-12 21:26:01 +00:00
Jonathan Coates
3a6c05688c Fix casing on Czech language file
Weblate is still buggy here, and I'm not sure why!
2023-02-12 20:48:51 +00:00
Weblate
efe924d068 Translations for Czech
Co-authored-by: RomanPlayer22 <romansulc13122006@gmail.com>
2023-02-11 17:53:16 +00:00
Jonathan Coates
e1ff1a8c6a Sync changelog and whatsnew
Every time I commit code on the train I end up regretting it and telling
myself I won't do it again. I should know better by now, and yet here we
are.
2023-02-10 21:32:54 +00:00
Weblate
131207057b Added translation for Czech
Co-authored-by: RomanPlayer22 <romansulc13122006@gmail.com>
2023-02-10 12:08:52 +00:00
Jonathan Coates
ab7af063c3 Remove wrapping from a couple of changelog items 2023-02-10 07:56:12 +00:00
2375 changed files with 58192 additions and 40810 deletions

View File

@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2017 The CC: Tweaked Developers
#
# SPDX-License-Identifier: CC0-1.0
root = true
[*]
@@ -14,11 +18,6 @@ ij_any_if_brace_force = if_multiline
ij_any_for_brace_force = if_multiline
ij_any_spaces_within_array_initializer_braces = true
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_method_parameters_wrap = off
ij_kotlin_call_parameters_wrap = off
[*.md]
trim_trailing_whitespace = false
@@ -27,3 +26,27 @@ indent_size = 2
[*.yml]
indent_size = 2
[*.{kt,kts}]
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
ij_kotlin_continuation_indent_size = 4
ij_kotlin_spaces_around_equality_operators = true
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
# Prefer to handle these manually
ij_kotlin_method_parameters_wrap = off
ij_kotlin_call_parameters_wrap = off
ij_kotlin_extends_list_wrap = off
ktlint_code_style = intellij_idea
ktlint_standard_class-naming = disabled
ktlint_standard_class-signature = disabled
ktlint_standard_function-naming = disabled
ktlint_standard_no-wildcard-imports = disabled
# FIXME: These two are disable right now as they're over-eager in putting things
# on the same line. We should set max_line_length and handle this properly.
ktlint_standard_function-signature = disabled
ktlint_standard_function-expression-body = disabled

View File

@@ -1,2 +1,6 @@
# SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
#
# SPDX-License-Identifier: CC0-1.0
# Reformat everything
f478c4ffc4fb9fc2200ec9b0bc751d047057ce81

5
.gitattributes vendored
View File

@@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2020 The CC: Tweaked Developers
#
# SPDX-License-Identifier: CC0-1.0
# Ignore changes in generated files
projects/*/src/generated/** linguist-generated
projects/common/src/testMod/resources/data/cctest/structures/* linguist-generated
@@ -7,6 +11,7 @@ projects/common/src/testMod/resources/data/cctest/structures/* linguist-generate
*.gradle eol=lf diff=java
*.java eol=lf diff=java
*.kt eol=lf diff=java
*.kts eol=lf diff=java
*.lua eol=lf
*.md eol=lf diff=markdown
*.txt eol=lf

View File

@@ -1,16 +1,18 @@
name: Bug report
description: Report some misbehaviour in the mod
labels: [ bug ]
type: bug
body:
- type: dropdown
id: mc-version
attributes:
label: Minecraft Version
description: What version of Minecraft are you using?
description: |
What version of Minecraft are you using? If your version is not listed, please try to reproduce on one of the supported versions.
options:
- 1.16.x
- 1.18.x
- 1.19.x
- 1.20.1
- 1.21.1
- 1.21.7
validations:
required: true
- type: input
@@ -27,8 +29,7 @@ body:
label: Details
description: |
Description of the bug. Please include the following:
- Logs: These will be located in the `logs/` directory of your Minecraft
instance. Please upload them as a gist or directly into this editor.
- Detailed reproduction steps: sometimes I can spot a bug pretty easily,
but often it's much more obscure. The more information I have to help
reproduce it, the quicker it'll get fixed.
- Logs: These will be located in the `logs/` directory of your Minecraft instance. This is always useful, even if it doesn't include errors, so please upload this!
- 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.
![A gif of burning text reading "Upload your logs!!!"](https://tweaked.cc/images/logs.gif)

View File

@@ -2,6 +2,7 @@
name: Feature request
about: Suggest an idea or improvement
labels: enhancement
type: feature
---
<!--

View File

@@ -8,17 +8,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v3
- name: 📥 Clone repository
uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v3
- name: 📥 Set up Java
uses: actions/setup-java@v4
with:
java-version: 17
java-version: 21
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: 📥 Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
cache-read-only: ${{ !startsWith(github.ref, 'refs/heads/mc-') }}
@@ -27,39 +27,45 @@ jobs:
mkdir -p ~/.gradle
echo "org.gradle.daemon=false" >> ~/.gradle/gradle.properties
- name: Build with Gradle
run: |
./gradlew assemble || ./gradlew assemble
./gradlew downloadAssets || ./gradlew downloadAssets
./gradlew build
- name: ⚒️ Build
run: ./gradlew assemble || ./gradlew assemble
- name: Run client tests
run: ./gradlew runGametestClient # Not checkClient, as no point running rendering tests.
# These are a little flaky on GH actions: its useful to run them, but don't break the build.
continue-on-error: true
- name: Prepare Jars
- name: 📦 Prepare Jars
run: |
# Find the main jar and append the git hash onto it.
mkdir -p jars
find projects/forge/build/libs projects/fabric/build/libs -type f -regex '.*[0-9.]+\(-SNAPSHOT\)?\.jar$' -exec bash -c 'cp {} "jars/$(basename {} .jar)-$(git rev-parse HEAD).jar"' \;
- name: Upload Jar
uses: actions/upload-artifact@v3
- name: 📤 Upload Jar
uses: actions/upload-artifact@v4
with:
name: CC-Tweaked
path: ./jars
- name: Upload coverage
uses: codecov/codecov-action@v3
- name: Cache pre-commit
uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit-3|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}
- name: Parse test reports
- name: 💡 Lint
run: |
pipx install pre-commit
pre-commit run --show-diff-on-failure --color=always
- name: 🧪 Run tests
run: ./gradlew test validateMixinNames checkChangelog
- name: 📥 Download assets for game tests
run: ./gradlew downloadAssets || ./gradlew downloadAssets
- name: 🧪 Run integration tests
run: ./gradlew runGametest
- name: 🧪 Parse test reports
run: ./tools/parse-reports.py
if: ${{ failure() }}
- name: Run linters
uses: pre-commit/action@v3.0.0
build-core:
strategy:
fail-fast: false
@@ -75,24 +81,28 @@ jobs:
runs-on: ${{ matrix.uses }}
steps:
- name: Clone repository
uses: actions/checkout@v3
- name: 📥 Clone repository
uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v3
- name: 📥 Set up Java
uses: actions/setup-java@v4
with:
java-version: 17
java-version: 21
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: 📥 Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
cache-read-only: ${{ !startsWith(github.ref, 'refs/heads/mc-') }}
- name: Run tests
- name: ⚒️ Build
run: |
./gradlew --configure-on-demand :core:assemble
- name: 🧪 Run tests
run: |
./gradlew --configure-on-demand :core:test
- name: Parse test reports
- name: 🧪 Parse test reports
run: python3 ./tools/parse-reports.py
if: ${{ failure() }}

View File

@@ -1,19 +0,0 @@
#!/usr/bin/env bash
set -eu
DEST="${GITHUB_REF#refs/*/}"
echo "Uploading docs to https://tweaked.cc/$DEST"
# Setup ssh key
mkdir -p "$HOME/.ssh/"
echo "$SSH_KEY" > "$HOME/.ssh/key"
chmod 600 "$HOME/.ssh/key"
# And upload
rsync -avc -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no -p $SSH_PORT" \
"$GITHUB_WORKSPACE/projects/web/build/site/" \
"$SSH_USER@$SSH_HOST:/$DEST"
rsync -avc -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no -p $SSH_PORT" \
"$GITHUB_WORKSPACE/projects/common-api/build/docs/javadoc/" \
"$SSH_USER@$SSH_HOST:/$DEST/javadoc"

View File

@@ -3,7 +3,7 @@ name: Build documentation
on:
push:
branches:
- mc-1.19.x
- mc-*
jobs:
make_doc:
@@ -11,30 +11,25 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v3
- name: 📥 Clone repository
uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v1
- name: 📥 Set up Java
uses: actions/setup-java@v4
with:
java-version: 17
java-version: 21
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: 📥 Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
cache-read-only: ${{ !startsWith(github.ref, 'refs/heads/mc-') }}
- name: Build with Gradle
run: ./gradlew compileJava --no-daemon || ./gradlew compileJava --no-daemon
- name: ⚒️ Generate documentation
run: ./gradlew docWebsite --no-daemon
- name: Generate documentation
run: ./gradlew docWebsite :common-api:javadoc --no-daemon
- name: Upload documentation
run: .github/workflows/make-doc.sh 2> /dev/null
env:
SSH_KEY: ${{ secrets.SSH_KEY }}
SSH_USER: ${{ secrets.SSH_USER }}
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_PORT: ${{ secrets.SSH_PORT }}
- name: 📤 Upload Jar
uses: actions/upload-artifact@v4
with:
name: Documentation
path: ./projects/web/build/site/

9
.gitignore vendored
View File

@@ -1,11 +1,19 @@
# SPDX-FileCopyrightText: 2017 The CC: Tweaked Developers
#
# SPDX-License-Identifier: CC0-1.0
# Build directories
/classes
/logs
/build
/projects/*/logs
/projects/fabric/fabricloader.log
/projects/*/build
/projects/*/src/test/generated_tests/
/buildSrc/build
/out
/buildSrc/out
/jars
/doc/out/
/node_modules
.jqwik-database
@@ -19,6 +27,7 @@
*.iml
.idea
.gradle
.kotlin
*.DS_Store
/.classpath

View File

@@ -1,22 +0,0 @@
image:
file: config/gitpod/Dockerfile
ports:
- port: 25565
onOpen: notify
vscode:
extensions:
- eamodio.gitlens
- github.vscode-pull-request-github
- ms-azuretools.vscode-docker
- redhat.java
- richardwillis.vscode-gradle
- vscjava.vscode-java-debug
- vscode.github
tasks:
- name: Setup pre-commit hool
init: pre-commit install --allow-missing-config
- name: Install npm packages
init: npm ci

View File

@@ -1,8 +1,12 @@
# SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
#
# SPDX-License-Identifier: CC0-1.0
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
@@ -16,12 +20,17 @@ repos:
exclude: "tsconfig\\.json$"
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
rev: 2.3.54
rev: 2.7.2
hooks:
- id: editorconfig-checker
args: ['-disable-indentation']
exclude: "^(.*\\.(bat)|LICENSE)$"
- repo: https://github.com/fsfe/reuse-tool
rev: v5.0.2
hooks:
- id: reuse
- repo: local
hooks:
- id: license
@@ -35,7 +44,7 @@ repos:
name: Check Java codestyle
files: ".*\\.java$"
language: system
entry: ./gradlew checkstyleMain checkstyleTest
entry: ./gradlew checkstyle
pass_filenames: false
require_serial: true
- id: illuaminate
@@ -49,6 +58,7 @@ repos:
exclude: |
(?x)^(
projects/[a-z]+/src/generated|
projects/[a-z]+/src/examples/generatedResources|
projects/core/src/test/resources/test-rom/data/json-parsing/|
.*\.dfpwm
)

View File

@@ -1,3 +1,8 @@
<!--
SPDX-FileCopyrightText: 2014 Coraline Ada Ehmke and contributors
SPDX-License-Identifier: CC-BY-4.0
-->
# Contributor Covenant Code of Conduct

View File

@@ -1,6 +1,12 @@
<!--
SPDX-FileCopyrightText: 2020 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
# Contributing to CC: Tweaked
As with many open source projects, CC: Tweaked thrives on contributions from other people! This document (hopefully)
provides an introduction as to how to get started in helping out.
provides an introduction as to how to get started with helping out.
If you've any other questions, [just ask the community][community] or [open an issue][new-issue].
@@ -16,16 +22,15 @@ If you have a bug, suggestion, or other feedback, the best thing to do is [file
use the issue templates - they provide a useful hint on what information to provide.
## Translations
Translations are managed through [Weblate], an online interface for managing language strings. This is synced
automatically with GitHub, so please don't submit PRs adding/changing translations!
Translations are managed through [CrowdIn], an online interface for managing language strings.
## Setting up a development environment
In order to develop CC: Tweaked, you'll need to download the source code and then run it.
- Make sure you've got the following software instealled:
- Java Development Kit (JDK) installed. This can be downloaded from [Adoptium].
- Make sure you've got the following software installed:
- Java Development Kit 21 (JDK). This can be downloaded from [Adoptium].
- [Git](https://git-scm.com/).
- If you want to work on documentation, [NodeJS][node].
- [NodeJS 20 or later][node].
- Download CC: Tweaked's source code:
```
@@ -43,12 +48,15 @@ If you want to run CC:T in a normal Minecraft instance, run `./gradlew assemble`
`projects/forge/build/libs` (for Forge) or `projects/fabric/build/libs` (for Fabric).
## Developing CC: Tweaked
Before making any major changes to CC: Tweaked, I'd recommend you have a read of the [the architecture
document][architecture] first. While it's not a comprehensive document, it gives a good hint of where you should start
looking to make your changes. As always, if you're not sure [do ask the community][community]!
Before making any major changes to CC: Tweaked, I'd recommend starting opening an issue or starting a discussion on
GitHub first. It's often helpful to discuss features before spending time developing them!
Once you're ready to start programming, have a read of the [the architecture document][architecture] first. While it's
not a comprehensive document, it gives a good hint of where you should start looking to make your changes. As always, if
you're not sure, [do ask the community][community]!
### Testing
When making larger changes, it's may be useful to write a test to make sure your code works as expected.
When making larger changes, it may be useful to write a test to make sure your code works as expected.
CC: Tweaked has several test suites, each designed to test something different:
@@ -80,26 +88,25 @@ You'll first need to [set up a development environment as above](#setting-up-a-d
Once this is set up, you can now run `./gradlew docWebsite`. This generates documentation from our Lua and Java code,
writing the resulting HTML into `./projects/web/build/site`, which can then be opened in a browser. When iterating on
documentation, you can instead run `./gradlew docWebsite -t`, which will rebuild documentation every time you change a
file.
documentation, you can instead run `./gradlew :web:assemble -x :web:compileTeaVM -t`, which will rebuild documentation
every time you change a file.
Documentation is built using [illuaminate] which, while not currently documented (somewhat ironic), is largely the same
as [ldoc][ldoc]. Documentation comments are written in Markdown, though note that we do not support many GitHub-specific
markdown features - if you can, do check what the documentation looks like locally!
markdown features. If you can, do check what the documentation looks like locally!
When writing long-form documentation (such as the guides in [doc/guides](doc/guides)), I find it useful to tell a
narrative. Think of what you want the user to learn or achieve, then start introducing a simple concept and then talk
about how you can build on that, until you've covered everything!
narrative. Think of what you want the user to learn or achieve, then start introducing a simple concept, and then talk
about how you can build on that until you've covered everything!
[new-issue]: https://github.com/cc-tweaked/CC-Tweaked/issues/new/choose "Create a new issue"
[community]: README.md#community "Get in touch with the community."
[Adoptium]: https://adoptium.net/temurin/releases?version=17 "Download OpenJDK 17"
[checkstyle]: https://checkstyle.org/
[illuaminate]: https://github.com/SquidDev/illuaminate/ "Illuaminate on GitHub"
[weblate]: https://i18n.tweaked.cc/projects/cc-tweaked/minecraft/ "CC: Tweaked weblate instance"
[docs]: https://tweaked.cc/ "CC: Tweaked documentation"
[ldoc]: http://stevedonovan.github.io/ldoc/ "ldoc, a Lua documentation generator."
[mc-test]: https://www.youtube.com/watch?v=vXaWOJTCYNg
[busted]: https://github.com/Olivine-Labs/busted "busted: Elegant Lua unit testing."
[node]: https://nodejs.org/en/ "Node.js"
[architecture]: projects/ARCHITECTURE.md
[Crowdin]: https://crowdin.com/project/cc-tweaked/

73
LICENSES/Apache-2.0.txt Normal file
View File

@@ -0,0 +1,73 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

93
LICENSES/CC-BY-3.0.txt Normal file
View File

@@ -0,0 +1,93 @@
Creative Commons Attribution 3.0 Unported
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
License
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
1. Definitions
a. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
b. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License.
c. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
d. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
e. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
f. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
g. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
h. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
i. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
a. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
b. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
c. to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
d. to Distribute and Publicly Perform Adaptations.
e. For the avoidance of doubt:
i. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
ii. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
iii. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
a. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested.
b. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
c. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
5. Representations, Warranties and Disclaimer
UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. Termination
a. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
b. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
8. Miscellaneous
a. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
b. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
c. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
d. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You.
e. This License may not be modified without the mutual written agreement of the Licensor and You.
f. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
Creative Commons Notice
Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor.
Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of this License.
Creative Commons may be contacted at http://creativecommons.org/.

156
LICENSES/CC-BY-4.0.txt Normal file
View File

@@ -0,0 +1,156 @@
Creative Commons Attribution 4.0 International
Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors.
Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensors permission is not necessary for any reasonfor example, because of any applicable exception or limitation to copyrightthen that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public.
Creative Commons Attribution 4.0 International Public License
By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
Section 1 Definitions.
a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
h. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
Section 2 Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
A. reproduce and Share the Licensed Material, in whole or in part; and
B. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
3. Term. The term of this Public License is specified in Section 6(a).
4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
5. Downstream recipients.
A. Offer from the Licensor Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
B. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this Public License.
3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties.
Section 3 License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified form), You must:
A. retain the following if it is supplied by the Licensor with the Licensed Material:
i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of warranties;
v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
Section 4 Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database;
b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
Section 5 Disclaimer of Warranties and Limitation of Liability.
a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
Section 6 Term and Termination.
a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
2. upon express reinstatement by the Licensor.
c. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
d. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
Section 7 Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
Section 8 Interpretation.
a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
Creative Commons may be contacted at creativecommons.org.

121
LICENSES/CC0-1.0.txt Normal file
View File

@@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

9
LICENSES/MIT.txt Normal file
View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) <year> <copyright holders>
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.

373
LICENSES/MPL-2.0.txt Normal file
View File

@@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@@ -1,11 +1,23 @@
# ![CC: Tweaked](doc/logo.png)
[![Current build status](https://github.com/cc-tweaked/CC-Tweaked/workflows/Build/badge.svg)](https://github.com/cc-tweaked/CC-Tweaked/actions "Current build status") [![Download CC: Tweaked on CurseForge](http://cf.way2muchnoise.eu/title/cc-tweaked.svg)][CurseForge]
<!--
SPDX-FileCopyrightText: 2017 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
<picture>
<source media="(prefers-color-scheme: dark)" srcset="./doc/logo-darkmode.png">
<source media="(prefers-color-scheme: light)" srcset="./doc/logo.png">
<img alt="CC: Tweaked" src="./doc/logo.png">
</picture>
[![Current build status](https://github.com/cc-tweaked/CC-Tweaked/workflows/Build/badge.svg)](https://github.com/cc-tweaked/CC-Tweaked/actions "Current build status")
[![Download CC: Tweaked on Modrinth](https://img.shields.io/static/v1?label=Download&color=00AF5C&logoColor=00AF5C&logo=Modrinth&message=CC:%20Tweaked)][Modrinth]
CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles and more to the game. A fork of the
much-beloved [ComputerCraft], it continues its legacy with better performance, stability, and a wealth of new features.
much-beloved [ComputerCraft], it continues its legacy with improved performance and stability, along with a wealth of
new features.
CC: Tweaked can be installed from [CurseForge] or [Modrinth]. It requires the [Minecraft Forge][forge] mod loader, but
[versions are available for Fabric][ccrestitched].
CC: Tweaked can be installed from [Modrinth]. It runs on both [Minecraft Forge] and [Fabric].
## Contributing
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. If you want to get started
@@ -13,8 +25,9 @@ developing the mod, [check out the instructions here](CONTRIBUTING.md#developing
## Community
If you need help getting started with CC: Tweaked, want to show off your latest project, or just want to chat about
ComputerCraft, do check out our [forum] and [GitHub discussions page][GitHub discussions]! There's also a fairly
populated, albeit quiet [IRC channel][irc], if that's more your cup of tea.
ComputerCraft, do check out our [GitHub discussions page][GitHub discussions]! There's also a fairly populated,
albeit quiet IRC channel on [EsperNet], if that's more your cup of tea. You can join `#computercraft` through your
desktop client, or online using [KiwiIRC].
We also host fairly comprehensive documentation at [tweaked.cc](https://tweaked.cc/ "The CC: Tweaked website").
@@ -26,22 +39,20 @@ on is present.
```groovy
repositories {
maven {
url "https://squiddev.cc/maven/"
url "https://maven.squiddev.cc"
content {
includeGroup("cc.tweaked")
includeModule("org.squiddev", "Cobalt")
includeModule("fuzs.forgeconfigapiport", "forgeconfigapiport-fabric")
}
}
}
dependencies {
// Vanilla (i.e. for multi-loader systems)
compileOnly("cc.tweaked:cc-tweaked-$mcVersion-common-api")
compileOnly("cc.tweaked:cc-tweaked-$mcVersion-common-api:$cctVersion")
// Forge Gradle
compileOnly(fg.deobf("cc.tweaked:cc-tweaked-$mcVersion-forge-api:$cctVersion"))
runtimeOnly(fg.deobf("cc.tweaked:cc-tweaked-$mcVersion-forge:$cctVersion"))
compileOnly("cc.tweaked:cc-tweaked-$mcVersion-forge-api:$cctVersion")
runtimeOnly("cc.tweaked:cc-tweaked-$mcVersion-forge:$cctVersion")
// Fabric Loom
modCompileOnly("cc.tweaked:cc-tweaked-$mcVersion-fabric-api:$cctVersion")
@@ -50,17 +61,16 @@ dependencies {
```
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.
subject to change at any point. If you depend on functionality outside the API (or need to mixin to CC:T), please file
an issue to let me know!
We bundle the API sources with the jar, so documentation should be easily viewable within your editor. Alternatively,
the generated documentation [can be browsed online](https://tweaked.cc/javadoc/).
[computercraft]: https://github.com/dan200/ComputerCraft "ComputerCraft on GitHub"
[curseforge]: https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked from CurseForge"
[modrinth]: https://modrinth.com/mod/gu7yAYhd "Download CC: Tweaked from Modrinth"
[forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
[ccrestitched]: https://www.curseforge.com/minecraft/mc-mods/cc-restitched "Download CC: Restitched from CurseForge"
[forum]: https://forums.computercraft.cc/
[Minecraft Forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
[Fabric]: https://fabricmc.net/use/installer/ "Download Fabric."
[GitHub Discussions]: https://github.com/cc-tweaked/CC-Tweaked/discussions
[IRC]: https://webchat.esper.net/?channels=computercraft "#computercraft on EsperNet"
[EsperNet]: https://www.esper.net/
[KiwiIRC]: https://kiwiirc.com/nextclient/#irc://irc.esper.net:+6697/#computercraft "#computercraft on EsperNet"

100
REUSE.toml Normal file
View File

@@ -0,0 +1,100 @@
# SPDX-FileCopyrightText: 2017 The CC: Tweaked Developers
#
# SPDX-License-Identifier: MPL-2.0
version = 1
SPDX-PackageName = "CC: Tweaked"
SPDX-PackageSupplier = "Jonathan Coates <git@squiddev.cc>"
SPDX-PackageDownloadLocation = "https://github.com/cc-tweaked/cc-tweaked"
[[annotations]]
SPDX-FileCopyrightText = "The CC: Tweaked Developers"
SPDX-License-Identifier = "CC0-1.0"
path = [
# Generated/data files are CC0.
"gradle/gradle-daemon-jvm.properties",
"projects/common/src/main/resources/assets/computercraft/sounds.json",
"projects/common/src/main/resources/assets/computercraft/sounds/empty.ogg",
"projects/common/src/testMod/resources/data/cctest/computercraft/turtle_upgrade/**",
"projects/common/src/testMod/resources/data/cctest/structures/**",
"projects/*/src/generated/**",
"projects/web/src/htmlTransform/export/index.json",
"projects/web/src/htmlTransform/export/items/minecraft/**",
# GitHub build scripts are CC0. While we could add a header to each file,
# it's unclear if it will break actions or issue templates in some way.
".github/**",
# Example mod is CC0.
"projects/*/src/examples/**"
]
[[annotations]]
# Several assets where it's inconvenient to create a .license file.
SPDX-FileCopyrightText = "The CC: Tweaked Developers"
SPDX-License-Identifier = "MPL-2.0"
path = [
"doc/images/**",
"package.json",
"package-lock.json",
"projects/*/src/*/resources/*.mixins.json",
"projects/fabric/src/*/resources/fabric.mod.json",
"projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.json",
"projects/common/src/testMod/resources/data/computercraft/loot_tables/treasure_disk.json",
"projects/common/src/testMod/resources/pack.mcmeta",
"projects/core/src/main/resources/data/computercraft/lua/rom/modules/command/.ignoreme",
"projects/core/src/main/resources/data/computercraft/lua/rom/modules/main/.ignoreme",
"projects/core/src/main/resources/data/computercraft/lua/rom/modules/turtle/.ignoreme",
"projects/core/src/main/resources/data/computercraft/lua/rom/motd.txt",
"projects/web/src/frontend/mount/.settings",
"projects/web/src/frontend/mount/example.nfp",
"projects/web/src/frontend/mount/example.nft",
"projects/web/src/frontend/mount/expr_template.lua",
"projects/web/tsconfig.json",
]
[[annotations]]
# Bulk-license original assets as CCPL.
SPDX-FileCopyrightText = "2011 Daniel Ratcliffe"
SPDX-License-Identifier = "LicenseRef-CCPL"
path = [
"doc/logo.png",
"doc/logo-darkmode.png",
"projects/common/src/main/resources/assets/computercraft/models/**",
"projects/common/src/main/resources/assets/computercraft/textures/**",
"projects/common/src/main/resources/pack.mcmeta",
"projects/common/src/main/resources/pack.png",
"projects/core/src/main/resources/assets/computercraft/textures/gui/term_font.png",
"projects/core/src/main/resources/data/computercraft/lua/rom/autorun/.ignoreme",
"projects/core/src/main/resources/data/computercraft/lua/rom/help/**",
"projects/core/src/main/resources/data/computercraft/lua/rom/programs/fun/advanced/levels/**",
"projects/web/src/htmlTransform/export/items/computercraft/**",
]
[[annotations]]
# Community-contributed language files
SPDX-FileCopyrightText = "2017 The CC: Tweaked Developers"
SPDX-License-Identifier = "LicenseRef-CCPL"
path = [
"projects/common/src/main/resources/assets/computercraft/lang/cs_cz.json",
"projects/common/src/main/resources/assets/computercraft/lang/ko_kr.json",
"projects/common/src/main/resources/assets/computercraft/lang/pl_pl.json",
"projects/common/src/main/resources/assets/computercraft/lang/pt_br.json",
"projects/common/src/main/resources/assets/computercraft/lang/ru_ru.json",
"projects/common/src/main/resources/assets/computercraft/lang/uk_ua.json",
"projects/common/src/main/resources/assets/computercraft/lang/zh_cn.json",
]
[[annotations]]
# Community-contributed language files
SPDX-FileCopyrightText = "2017 The CC: Tweaked Developers"
SPDX-License-Identifier = "MPL-2.0"
path = "projects/common/src/main/resources/assets/computercraft/lang/**"
[[annotations]]
path = ["gradle/wrapper/**"]
SPDX-FileCopyrightText = "Gradle Inc"
SPDX-License-Identifier = "Apache-2.0"
[[annotations]]
path = "projects/core/src/test/resources/test-rom/data/json-parsing/**"
SPDX-FileCopyrightText = "2016 Nicolas Seriot"
SPDX-License-Identifier = "MIT"

View File

@@ -1,10 +1,19 @@
import org.jetbrains.gradle.ext.compiler
import org.jetbrains.gradle.ext.settings
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
import cc.tweaked.gradle.JUnitExt
import net.fabricmc.loom.api.LoomGradleExtensionAPI
import net.fabricmc.loom.util.gradle.SourceSetHelper
import org.jetbrains.gradle.ext.*
import org.jetbrains.gradle.ext.Application
plugins {
publishing
alias(libs.plugins.taskTree)
alias(libs.plugins.githubRelease)
alias(libs.plugins.gradleVersions)
alias(libs.plugins.versionCatalogUpdate)
id("org.jetbrains.gradle.plugin.idea-ext")
id("cc-tweaked")
}
@@ -15,25 +24,80 @@ val mcVersion: String by extra
githubRelease {
token(findProperty("githubApiKey") as String? ?: "")
owner.set("cc-tweaked")
repo.set("CC-Tweaked")
targetCommitish.set(cct.gitBranch)
owner = "cc-tweaked"
repo = "CC-Tweaked"
targetCommitish = cct.gitBranch
tagName.set("v$mcVersion-$modVersion")
releaseName.set("[$mcVersion] $modVersion")
body.set(
provider {
"## " + project(":core").file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
.readLines()
.takeWhile { it != "Type \"help changelog\" to see the full version history." }
.joinToString("\n").trim()
},
)
prerelease.set(isUnstable)
tagName = "v$mcVersion-$modVersion"
releaseName = "[$mcVersion] $modVersion"
body = provider {
"## " + project(":core").file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
.readLines()
.takeWhile { it != "Type \"help changelog\" to see the full version history." }
.joinToString("\n").trim()
}
prerelease = isUnstable
}
tasks.publish { dependsOn(tasks.githubRelease) }
idea.project.settings.runConfigurations {
register<JUnitExt>("Core Tests") {
vmParameters = "-ea"
moduleName = "${idea.project.name}.core.test"
packageName = ""
}
register<JUnitExt>("CraftOS Tests") {
vmParameters = "-ea"
moduleName = "${idea.project.name}.core.test"
className = "dan200.computercraft.core.ComputerTestDelegate"
}
register<JUnitExt>("CraftOS Tests (Fast)") {
vmParameters = "-ea -Dcc.skip_keywords=slow"
moduleName = "${idea.project.name}.core.test"
className = "dan200.computercraft.core.ComputerTestDelegate"
}
register<JUnitExt>("Common Tests") {
vmParameters = "-ea"
moduleName = "${idea.project.name}.common.test"
packageName = ""
}
register<JUnitExt>("Fabric Tests") {
val fabricProject = evaluationDependsOn(":fabric")
val classPathGroup = fabricProject.extensions.getByType<LoomGradleExtensionAPI>().mods
.joinToString(File.pathSeparator + File.pathSeparator) { modSettings ->
SourceSetHelper.getClasspath(modSettings, project).joinToString(File.pathSeparator) { it.absolutePath }
}
vmParameters = "-ea -Dfabric.classPathGroups=$classPathGroup"
moduleName = "${idea.project.name}.fabric.test"
packageName = ""
}
register<JUnitExt>("Forge Tests") {
vmParameters = "-ea"
moduleName = "${idea.project.name}.forge.test"
packageName = ""
}
register<Application>("Standalone") {
moduleName = "${idea.project.name}.standalone.main"
mainClass = "cc.tweaked.standalone.Main"
programParameters = "--resources=projects/core/src/main/resources --term=80x30 --allow-local-domains"
}
}
// Build with the IntelliJ, rather than through Gradle. This may require setting the "Compiler Output" option in
// "Project Structure".
idea.project.settings.delegateActions {
delegateBuildRunToGradle = false
testRunner = ActionDelegationConfig.TestRunner.PLATFORM
}
idea.project.settings.compiler.javac {
// We want ErrorProne to be present when compiling via IntelliJ, as it offers some helpful warnings
// and errors. Loop through our source sets and find the appropriate flags.
@@ -50,3 +114,9 @@ idea.project.settings.compiler.javac {
}
.toMap()
}
versionCatalogUpdate {
sortByKey = false
pin { versions.addAll("fastutil", "guava", "netty", "slf4j") }
keep { keepUnusedLibraries = true }
}

View File

@@ -1,6 +1,12 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
plugins {
`java-gradle-plugin`
`kotlin-dsl`
alias(libs.plugins.gradleVersions)
alias(libs.plugins.versionCatalogUpdate)
}
// Duplicated in settings.gradle.kts
@@ -8,25 +14,10 @@ repositories {
mavenCentral()
gradlePluginPortal()
maven("https://maven.minecraftforge.net") {
name = "Forge"
maven("https://maven.neoforged.net") {
name = "NeoForge"
content {
includeGroup("net.minecraftforge")
includeGroup("net.minecraftforge.gradle")
}
}
maven("https://maven.parchmentmc.org") {
name = "Librarian"
content {
includeGroupByRegex("^org\\.parchmentmc.*")
}
}
maven("https://repo.spongepowered.org/repository/maven-public/") {
name = "Sponge"
content {
includeGroup("org.spongepowered")
includeGroup("net.neoforged")
}
}
@@ -36,6 +27,13 @@ repositories {
includeGroup("net.fabricmc")
}
}
maven("https://maven.squiddev.cc") {
name = "SquidDev"
content {
includeGroup("cc.tweaked.vanilla-extract")
}
}
}
dependencies {
@@ -44,10 +42,10 @@ dependencies {
implementation(libs.spotless)
implementation(libs.fabric.loom)
implementation(libs.forgeGradle)
implementation(libs.librarian)
implementation(libs.quiltflower)
implementation(libs.vanillaGradle)
implementation(libs.ideaExt)
implementation(libs.minotaur)
implementation(libs.modDevGradle)
implementation(libs.vanillaExtract)
}
gradlePlugin {
@@ -68,3 +66,9 @@ gradlePlugin {
}
}
}
versionCatalogUpdate {
sortByKey = false
keep { keepUnusedLibraries = true }
catalogFile = file("../gradle/libs.versions.toml")
}

View File

@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
dependencyResolutionManagement {
versionCatalogs {
create("libs") {

View File

@@ -1,14 +1,14 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
/** Default configuration for Fabric projects. */
import cc.tweaked.gradle.CCTweakedExtension
import cc.tweaked.gradle.CCTweakedPlugin
import cc.tweaked.gradle.IdeaRunConfigurations
import cc.tweaked.gradle.MinecraftConfigurations
import cc.tweaked.gradle.*
plugins {
`java-library`
id("fabric-loom")
id("io.github.juuxel.loom-quiltflower")
id("cc-tweaked.java-convention")
}
@@ -27,7 +27,7 @@ repositories {
loom {
splitEnvironmentSourceSets()
splitModDependencies.set(true)
splitModDependencies = true
}
MinecraftConfigurations.setup(project)
@@ -64,3 +64,9 @@ dependencies {
tasks.ideaSyncTask {
doLast { IdeaRunConfigurations(project).patch() }
}
tasks.named("checkDependencyConsistency", DependencyCheck::class.java) {
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
// Minecraft depends on asm, but Fabric forces it to a more recent version
override(libs.findLibrary("asm").get(), "9.8")
}

View File

@@ -1,25 +1,30 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
/** Default configuration for Forge projects. */
import cc.tweaked.gradle.CCTweakedExtension
import cc.tweaked.gradle.CCTweakedPlugin
import cc.tweaked.gradle.IdeaRunConfigurations
import cc.tweaked.gradle.MinecraftConfigurations
plugins {
id("cc-tweaked.java-convention")
id("net.minecraftforge.gradle")
id("org.parchmentmc.librarian.forgegradle")
id("net.neoforged.moddev")
}
plugins.apply(CCTweakedPlugin::class.java)
val mcVersion: String by extra
minecraft {
neoForge {
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
mappings("parchment", "${libs.findVersion("parchmentMc").get()}-${libs.findVersion("parchment").get()}-$mcVersion")
version = libs.findVersion("neoForge").get().toString()
accessTransformer(project(":forge").file("src/main/resources/META-INF/accesstransformer.cfg"))
parchment {
minecraftVersion = libs.findVersion("parchmentMc").get().toString()
mappingsVersion = libs.findVersion("parchment").get().toString()
}
}
MinecraftConfigurations.setup(project)
@@ -27,13 +32,3 @@ MinecraftConfigurations.setup(project)
extensions.configure(CCTweakedExtension::class.java) {
linters(minecraft = true, loader = "forge")
}
dependencies {
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
"minecraft"("net.minecraftforge:forge:$mcVersion-${libs.findVersion("forge").get()}")
}
tasks.configureEach {
// genIntellijRuns isn't registered until much later, so we need this silly hijinks.
if (name == "genIntellijRuns") doLast { IdeaRunConfigurations(project).patch() }
}

View File

@@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
import cc.tweaked.gradle.CCTweakedExtension
import cc.tweaked.gradle.CCTweakedPlugin
import cc.tweaked.gradle.LicenseHeader
import com.diffplug.gradle.spotless.FormatExtension
import com.diffplug.spotless.LineEnding
import net.ltgt.gradle.errorprone.CheckSeverity
@@ -26,7 +29,7 @@ base.archivesName.convention("cc-tweaked-$mcVersion-${project.name}")
java {
toolchain {
languageVersion.set(CCTweakedPlugin.JAVA_VERSION)
languageVersion = CCTweakedPlugin.JAVA_VERSION
}
withSourcesJar()
@@ -34,21 +37,26 @@ java {
repositories {
mavenCentral()
maven("https://squiddev.cc/maven") {
val mainMaven = maven("https://maven.squiddev.cc/mirror") {
name = "SquidDev"
content {
includeGroup("org.squiddev")
}
exclusiveContent {
forRepositories(mainMaven)
filter {
includeGroup("cc.tweaked")
// Things we mirror
includeGroup("com.simibubi.create")
includeGroup("net.commoble.morered")
includeGroup("dev.architectury")
includeGroup("dev.emi")
includeGroup("maven.modrinth")
includeGroup("me.shedaniel")
includeGroup("me.shedaniel.cloth")
includeGroup("me.shedaniel")
includeGroup("mezz.jei")
includeGroup("org.teavm")
includeModule("com.terraformersmc", "modmenu")
includeModule("fuzs.forgeconfigapiport", "forgeconfigapiport-fabric")
// Until https://github.com/SpongePowered/Mixin/pull/593 is merged
includeModule("org.spongepowered", "mixin")
}
}
}
@@ -57,6 +65,12 @@ dependencies {
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
checkstyle(libs.findLibrary("checkstyle").get())
constraints {
checkstyle("org.codehaus.plexus:plexus-container-default:2.1.1") {
because("2.1.0 depends on deprecated Google collections module")
}
}
errorprone(libs.findLibrary("errorProne-core").get())
errorprone(libs.findLibrary("nullAway").get())
}
@@ -64,27 +78,40 @@ dependencies {
// Configure default JavaCompile tasks with our arguments.
sourceSets.all {
tasks.named(compileJavaTaskName, JavaCompile::class.java) {
// Processing just gives us "No processor claimed any of these annotations", so skip that!
options.compilerArgs.addAll(listOf("-Xlint", "-Xlint:-processing"))
options.compilerArgs.addAll(
listOf(
"-Xlint",
// Processing just gives us "No processor claimed any of these annotations", so skip that!
"-Xlint:-processing",
// We violate this pattern too often for it to be a helpful warning. Something to improve one day!
"-Xlint:-this-escape",
),
)
options.errorprone {
check("InvalidBlockTag", CheckSeverity.OFF) // Broken by @cc.xyz
check("InvalidParam", CheckSeverity.OFF) // Broken by records.
check("InlineMeSuggester", CheckSeverity.OFF) // Minecraft uses @Deprecated liberally
// Too many false positives right now. Maybe we need an indirection for it later on.
check("AssignmentExpression", CheckSeverity.OFF) // I'm a bad person.
check("ReferenceEquality", CheckSeverity.OFF)
check("UnusedVariable", CheckSeverity.OFF) // Too many false positives with records.
check("EnumOrdinal", CheckSeverity.OFF) // For now. We could replace most of these with EnumMap.
check("OperatorPrecedence", CheckSeverity.OFF) // For now.
check("AlreadyChecked", CheckSeverity.OFF) // Seems to be broken?
check("NonOverridingEquals", CheckSeverity.OFF) // Peripheral.equals makes this hard to avoid
check("FutureReturnValueIgnored", CheckSeverity.OFF) // Too many false positives with Netty
check("InvalidInlineTag", CheckSeverity.OFF) // Triggered by @snippet. Can be removed on Java 21.
check("NullAway", CheckSeverity.ERROR)
option("NullAway:AnnotatedPackages", listOf("dan200.computercraft", "net.fabricmc.fabric.api").joinToString(","))
option(
"NullAway:AnnotatedPackages",
listOf("dan200.computercraft", "cc.tweaked", "net.fabricmc.fabric.api").joinToString(","),
)
option("NullAway:ExcludedFieldAnnotations", listOf("org.spongepowered.asm.mixin.Shadow").joinToString(","))
option("NullAway:CastToNonNullMethod", "dan200.computercraft.core.util.Nullability.assertNonNull")
option("NullAway:CheckOptionalEmptiness")
option("NullAway:AcknowledgeRestrictiveAnnotations")
excludedPaths = ".*/jmh_generated/.*"
}
}
}
@@ -95,16 +122,20 @@ tasks.compileTestJava {
}
}
tasks.withType(JavaCompile::class.java).configureEach {
options.encoding = "UTF-8"
}
tasks.processResources {
exclude("**/*.license")
exclude(".cache")
}
tasks.withType(AbstractArchiveTask::class.java).configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
dirMode = Integer.valueOf("755", 8)
fileMode = Integer.valueOf("664", 8)
filePermissions {}
dirPermissions {}
}
tasks.jar {
@@ -124,7 +155,7 @@ tasks.javadoc {
options {
val stdOptions = this as StandardJavadocDocletOptions
stdOptions.addBooleanOption("Xdoclint:all,-missing", true)
stdOptions.links("https://docs.oracle.com/en/java/javase/17/docs/api/")
stdOptions.links("https://docs.oracle.com/en/java/javase/21/docs/api/")
}
}
@@ -138,8 +169,8 @@ tasks.test {
}
tasks.withType(JacocoReport::class.java).configureEach {
reports.xml.required.set(true)
reports.html.required.set(true)
reports.xml.required = true
reports.html.required = true
}
project.plugins.withType(CCTweakedPlugin::class.java) {
@@ -150,6 +181,12 @@ project.plugins.withType(CCTweakedPlugin::class.java) {
}
}
tasks.register("checkstyle") {
description = "Run Checkstyle on all sources"
group = LifecycleBasePlugin.VERIFICATION_GROUP
dependsOn(tasks.withType(Checkstyle::class.java))
}
spotless {
encoding = StandardCharsets.UTF_8
lineEndings = LineEnding.UNIX
@@ -157,34 +194,23 @@ spotless {
fun FormatExtension.defaults() {
endWithNewline()
trimTrailingWhitespace()
indentWithSpaces(4)
leadingTabsToSpaces(4)
}
val licenser = LicenseHeader.create(
api = rootProject.file("config/license/api.txt"),
main = rootProject.file("config/license/main.txt"),
)
java {
defaults()
addStep(licenser)
importOrder("", "javax|java", "\\#")
removeUnusedImports()
}
val ktlintConfig = mapOf(
"disabled_rules" to "no-wildcard-imports",
"ij_kotlin_allow_trailing_comma" to "true",
"ij_kotlin_allow_trailing_comma_on_call_site" to "true",
)
kotlinGradle {
defaults()
ktlint().editorConfigOverride(ktlintConfig)
ktlint()
}
kotlin {
defaults()
ktlint().editorConfigOverride(ktlintConfig)
ktlint()
}
}
@@ -193,6 +219,5 @@ idea.module {
// Force Gradle to write to inherit the output directory from the parent, instead of writing to out/xxx/classes.
// This is required for Loom, and we patch Forge's run configurations to work there.
// TODO: Submit a patch to Forge to support ProjectRootManager.
inheritOutputDirs = true
}

View File

@@ -1,21 +0,0 @@
import cc.tweaked.gradle.CCTweakedPlugin
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm")
}
kotlin {
jvmToolchain {
languageVersion.set(CCTweakedPlugin.JAVA_VERSION)
}
}
tasks.withType(KotlinCompile::class.java).configureEach {
// So technically we shouldn't need to do this as the toolchain sets it above. However, the option only appears
// to be set when the task executes, so doesn't get picked up by IDEs.
kotlinOptions.jvmTarget = when {
CCTweakedPlugin.JAVA_VERSION.asInt() > 8 -> CCTweakedPlugin.JAVA_VERSION.toString()
else -> "1.${CCTweakedPlugin.JAVA_VERSION.asInt()}"
}
}

View File

@@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
import cc.tweaked.gradle.setProvider
plugins {
id("com.modrinth.minotaur")
id("cc-tweaked.publishing")
}
abstract class ModPublishingExtension {
abstract val output: Property<AbstractArchiveTask>
init {
output.finalizeValueOnRead()
}
}
val modPublishing = project.extensions.create("modPublishing", ModPublishingExtension::class.java)
val isUnstable = project.properties["isUnstable"] == "true"
val modVersion: String by extra
val mcVersion: String by extra
modrinth {
token = findProperty("modrinthApiKey") as String? ?: ""
projectId = "gu7yAYhd"
versionNumber = modVersion
versionName = modVersion
versionType = if (isUnstable) "alpha" else "release"
uploadFile.setProvider(modPublishing.output)
gameVersions.add(mcVersion)
changelog = "Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v$mcVersion-$modVersion)."
syncBodyFrom = provider { rootProject.file("doc/mod-page.md").readText() }
}
tasks.publish { dependsOn(tasks.modrinth) }

View File

@@ -1,5 +1,6 @@
import cc.tweaked.gradle.clientClasses
import cc.tweaked.gradle.commonClasses
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
/**
* Sets up the configurations for writing game tests.
@@ -7,35 +8,28 @@ import cc.tweaked.gradle.commonClasses
* See notes in [cc.tweaked.gradle.MinecraftConfigurations] for the general design behind these cursed ideas.
*/
import cc.tweaked.gradle.MinecraftConfigurations
import cc.tweaked.gradle.clientClasses
import cc.tweaked.gradle.commonClasses
plugins {
id("cc-tweaked.kotlin-convention")
kotlin("jvm")
id("cc-tweaked.java-convention")
}
val main = sourceSets["main"]
val client = sourceSets["client"]
// Both testMod and testFixtures inherit from the main and client classpath, just so we have access to Minecraft classes.
val testMod by sourceSets.creating {
compileClasspath += main.compileClasspath + client.compileClasspath
runtimeClasspath += main.runtimeClasspath + client.runtimeClasspath
}
MinecraftConfigurations.createDerivedConfiguration(project, MinecraftConfigurations.DATAGEN)
MinecraftConfigurations.createDerivedConfiguration(project, MinecraftConfigurations.EXAMPLES)
MinecraftConfigurations.createDerivedConfiguration(project, MinecraftConfigurations.TEST_MOD)
configurations {
named(testMod.compileClasspathConfigurationName) {
shouldResolveConsistentlyWith(compileClasspath.get())
}
// Set up generated resources
sourceSets.main { resources.srcDir("src/generated/resources") }
sourceSets.named("examples") { resources.srcDir("src/examples/generatedResources") }
named(testMod.runtimeClasspathConfigurationName) {
shouldResolveConsistentlyWith(runtimeClasspath.get())
}
}
// Like the main test configurations, we're safe to depend on source set outputs.
dependencies {
add(testMod.implementationConfigurationName, main.output)
add(testMod.implementationConfigurationName, client.output)
}
// Make sure our examples compile.
tasks.check { dependsOn(tasks.named("compileExamplesJava")) }
// Similar to java-test-fixtures, but tries to avoid putting the obfuscated jar on the classpath.

View File

@@ -1,4 +1,6 @@
import org.gradle.kotlin.dsl.`maven-publish`
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
plugins {
`java-library`
@@ -10,25 +12,26 @@ publishing {
register<MavenPublication>("maven") {
artifactId = base.archivesName.get()
from(components["java"])
suppressAllPomMetadataWarnings()
pom {
name.set("CC: Tweaked")
description.set("CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft.")
url.set("https://github.com/cc-tweaked/CC-Tweaked")
name = "CC: Tweaked"
description = "CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft."
url = "https://github.com/cc-tweaked/CC-Tweaked"
scm {
url.set("https://github.com/cc-tweaked/CC-Tweaked.git")
url = "https://github.com/cc-tweaked/CC-Tweaked.git"
}
issueManagement {
system.set("github")
url.set("https://github.com/cc-tweaked/CC-Tweaked/issues")
system = "github"
url = "https://github.com/cc-tweaked/CC-Tweaked/issues"
}
licenses {
license {
name.set("ComputerCraft Public License, Version 1.0")
url.set("https://github.com/cc-tweaked/CC-Tweaked/blob/HEAD/LICENSE")
name = "ComputerCraft Public License, Version 1.0"
url = "https://github.com/cc-tweaked/CC-Tweaked/blob/HEAD/LICENSE"
}
}
}
@@ -36,7 +39,7 @@ publishing {
}
repositories {
maven("https://squiddev.cc/maven") {
maven("https://maven.squiddev.cc") {
name = "SquidDev"
credentials(PasswordCredentials::class)

View File

@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
/** Default configuration for non-modloader-specific Minecraft projects. */
import cc.tweaked.gradle.CCTweakedExtension
@@ -6,25 +10,31 @@ import cc.tweaked.gradle.MinecraftConfigurations
plugins {
id("cc-tweaked.java-convention")
id("org.spongepowered.gradle.vanilla")
id("cc.tweaked.vanilla-extract")
}
plugins.apply(CCTweakedPlugin::class.java)
val mcVersion: String by extra
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
minecraft {
version(mcVersion)
mappings {
parchment(libs.findVersion("parchmentMc").get().toString(), libs.findVersion("parchment").get().toString())
}
unpick(libs.findLibrary("yarn").get())
}
dependencies {
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
// Depend on error prone annotations to silence a lot of compile warnings.
compileOnlyApi(libs.findLibrary("errorProne.annotations").get())
compileOnly(libs.findLibrary("errorProne.annotations").get())
}
MinecraftConfigurations.setup(project)
MinecraftConfigurations.setupBasic(project)
extensions.configure(CCTweakedExtension::class.java) {
linters(minecraft = true, loader = null)

View File

@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import net.ltgt.gradle.errorprone.CheckSeverity
@@ -6,21 +10,16 @@ import org.gradle.api.GradleException
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.attributes.TestSuiteType
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.provider.Provider
import org.gradle.api.provider.SetProperty
import org.gradle.api.reporting.ReportingExtension
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.configurationcache.extensions.capitalized
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.gradle.language.jvm.tasks.ProcessResources
import org.gradle.process.JavaForkOptions
import org.gradle.testing.jacoco.plugins.JacocoCoverageReport
import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
import org.gradle.testing.jacoco.plugins.JacocoTaskExtension
import org.gradle.testing.jacoco.tasks.JacocoReport
@@ -29,40 +28,31 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.File
import java.io.IOException
import java.net.URI
import java.net.URL
import java.util.regex.Pattern
abstract class CCTweakedExtension(
private val project: Project,
private val fs: FileSystemOperations,
) {
abstract class CCTweakedExtension(private val project: Project) {
/** Get the hash of the latest git commit. */
val gitHash: Provider<String> = gitProvider(project, "<no git hash>") {
ProcessHelpers.captureOut("git", "-C", project.rootProject.projectDir.absolutePath, "rev-parse", "HEAD").trim()
}
val gitHash: Provider<String> =
gitProvider("<no git commit>", listOf("rev-parse", "HEAD")) { it.trim() }
/** Get the current git branch. */
val gitBranch: Provider<String> = gitProvider(project, "<no git branch>") {
ProcessHelpers.captureOut("git", "-C", project.rootProject.projectDir.absolutePath, "rev-parse", "--abbrev-ref", "HEAD")
.trim()
}
val gitBranch: Provider<String> =
gitProvider("<no git branch>", listOf("rev-parse", "--abbrev-ref", "HEAD")) { it.trim() }
/** Get a list of all contributors to the project. */
val gitContributors: Provider<List<String>> = gitProvider(project, listOf()) {
ProcessHelpers.captureLines(
"git", "-C", project.rootProject.projectDir.absolutePath, "shortlog", "-ns",
"--group=author", "--group=trailer:co-authored-by", "HEAD",
)
.asSequence()
.map {
val matcher = COMMIT_COUNTS.matcher(it)
matcher.find()
matcher.group(1)
}
.filter { !IGNORED_USERS.contains(it) }
.toList()
.sortedWith(String.CASE_INSENSITIVE_ORDER)
}
val gitContributors: Provider<List<String>> =
gitProvider(listOf(), listOf("shortlog", "-ns", "--group=author", "--group=trailer:co-authored-by", "HEAD")) { input ->
input.lineSequence()
.filter { it.isNotEmpty() }
.map {
val matcher = COMMIT_COUNTS.matcher(it)
matcher.find()
matcher.group(1)
}
.filter { !IGNORED_USERS.contains(it) }
.toList()
.sortedWith(String.CASE_INSENSITIVE_ORDER)
}
/**
* References to other sources
@@ -99,14 +89,13 @@ abstract class CCTweakedExtension(
val otherJava = otherProject.extensions.getByType(JavaPluginExtension::class.java)
val main = otherJava.sourceSets.getByName("main")
val client = otherJava.sourceSets.getByName("client")
val testMod = otherJava.sourceSets.findByName("testMod")
val testFixtures = otherJava.sourceSets.findByName("testFixtures")
// Pull in sources from the other project.
extendSourceSet(otherProject, main)
extendSourceSet(otherProject, client)
if (testMod != null) extendSourceSet(otherProject, testMod)
if (testFixtures != null) extendSourceSet(otherProject, testFixtures)
for (sourceSet in listOf(MinecraftConfigurations.DATAGEN, MinecraftConfigurations.EXAMPLES, MinecraftConfigurations.TEST_MOD, "testFixtures")) {
otherJava.sourceSets.findByName(sourceSet)?.let { extendSourceSet(otherProject, it) }
}
// The extra source-processing tasks should include these files too.
project.tasks.named(main.javadocTaskName, Javadoc::class.java) { source(main.allJava, client.allJava) }
@@ -169,23 +158,19 @@ abstract class CCTweakedExtension(
}
fun <T> jacoco(task: NamedDomainObjectProvider<T>) where T : Task, T : JavaForkOptions {
val classDump = project.buildDir.resolve("jacocoClassDump/${task.name}")
val reportTaskName = "jacoco${task.name.capitalized()}Report"
val reportTaskName = "jacoco${task.name.capitalise()}Report"
val jacoco = project.extensions.getByType(JacocoPluginExtension::class.java)
task.configure {
finalizedBy(reportTaskName)
doFirst("Clean class dump directory") { fs.delete { delete(classDump) } }
jacoco.applyTo(this)
extensions.configure(JacocoTaskExtension::class.java) {
includes = listOf("dan200.computercraft.*")
classDumpDir = classDump
// Older versions of modlauncher don't include a protection domain (and thus no code
// source). Jacoco skips such classes by default, so we need to explicitly include them.
isIncludeNoLocationClasses = true
excludes = listOf(
"dan200.computercraft.mixin.*", // Exclude mixins, as they're not executed at runtime.
"dan200.computercraft.shared.Capabilities$*", // Exclude capability tokens, as Forge rewrites them.
)
}
}
@@ -194,15 +179,11 @@ abstract class CCTweakedExtension(
description = "Generates code coverage report for the ${task.name} task."
executionData(task.get())
classDirectories.from(classDump)
// Don't want to use sourceSets(...) here as we have a custom class directory.
for (ref in sourceSets.get()) sourceDirectories.from(ref.allSource.sourceDirectories)
}
project.extensions.configure(ReportingExtension::class.java) {
reports.register("${task.name}CodeCoverageReport", JacocoCoverageReport::class.java) {
testType.set(TestSuiteType.INTEGRATION_TEST)
// Don't want to use sourceSets(...) here as we don't use all class directories.
for (ref in this@CCTweakedExtension.sourceDirectories.get()) {
sourceDirectories.from(ref.sourceSet.allSource.sourceDirectories)
if (ref.classes) classDirectories.from(ref.sourceSet.output)
}
}
}
@@ -214,12 +195,12 @@ abstract class CCTweakedExtension(
* where possible.
*/
fun downloadFile(label: String, url: String): File {
val url = URL(url)
val path = File(url.path)
val uri = URI(url)
val path = File(uri.path)
project.repositories.ivy {
name = label
setUrl(URI(url.protocol, url.userInfo, url.host, url.port, path.parent, null, null))
setUrl(URI(uri.scheme, uri.userInfo, uri.host, uri.port, path.parent, null, null))
patternLayout {
artifact("[artifact].[ext]")
}
@@ -242,26 +223,31 @@ abstract class CCTweakedExtension(
).resolve().single()
}
private fun <T> gitProvider(default: T, command: List<String>, process: (String) -> T): Provider<T> {
val baseResult = project.providers.exec {
commandLine = listOf("git", "-C", project.rootDir.absolutePath) + command
}
return project.provider {
val res = try {
baseResult.standardOutput.asText.get()
} catch (e: IOException) {
project.logger.error("Cannot read Git repository: ${e.message}", e)
return@provider default
} catch (e: GradleException) {
project.logger.error("Cannot read Git repository: ${e.message}", e)
return@provider default
}
process(res)
}
}
companion object {
private val COMMIT_COUNTS = Pattern.compile("""^\s*[0-9]+\s+(.*)$""")
private val IGNORED_USERS = setOf(
"GitHub", "Daniel Ratcliffe", "Weblate",
"GitHub", "Daniel Ratcliffe", "NotSquidDev", "Weblate",
)
private fun <T> gitProvider(project: Project, default: T, supplier: () -> T): Provider<T> {
return project.provider {
try {
supplier()
} catch (e: IOException) {
project.logger.error("Cannot read Git repository: ${e.message}")
default
} catch (e: GradleException) {
project.logger.error("Cannot read Git repository: ${e.message}")
default
}
}
}
private val isIdeSync: Boolean
get() = java.lang.Boolean.parseBoolean(System.getProperty("idea.sync.active", "false"))
}

View File

@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.Plugin
@@ -5,6 +9,10 @@ import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.plugins.ide.idea.model.IdeaModel
import org.jetbrains.gradle.ext.IdeaExtPlugin
import org.jetbrains.gradle.ext.runConfigurations
import org.jetbrains.gradle.ext.settings
/**
* Configures projects to match a shared configuration.
@@ -17,9 +25,23 @@ class CCTweakedPlugin : Plugin<Project> {
val sourceSets = project.extensions.getByType(JavaPluginExtension::class.java).sourceSets
cct.sourceDirectories.add(SourceSetReference.internal(sourceSets.getByName("main")))
}
project.plugins.withType(IdeaExtPlugin::class.java) { extendIdea(project) }
}
/**
* Extend the [IdeaExtPlugin] plugin's `runConfiguration` container to also support [JUnitExt].
*/
private fun extendIdea(project: Project) {
val ideaModel = project.extensions.findByName("idea") as IdeaModel? ?: return
val ideaProject = ideaModel.project ?: return
ideaProject.settings.runConfigurations {
registerFactory(JUnitExt::class.java) { name -> project.objects.newInstance(JUnitExt::class.java, name) }
}
}
companion object {
val JAVA_VERSION = JavaLanguageVersion.of(17)
val JAVA_VERSION = JavaLanguageVersion.of(21)
}
}

View File

@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.DefaultTask

View File

@@ -1,72 +0,0 @@
package cc.tweaked.gradle
import com.diffplug.spotless.FormatterFunc
import com.diffplug.spotless.FormatterStep
import com.diffplug.spotless.generic.LicenseHeaderStep
import java.io.File
import java.io.Serializable
/**
* Similar to [LicenseHeaderStep], but supports multiple licenses.
*/
object LicenseHeader {
/**
* The current year to use in templates. Intentionally not dynamic to avoid failing the build.
*/
private const val YEAR = 2022
private val COMMENT = Regex("""^/\*(.*?)\*/\n?""", RegexOption.DOT_MATCHES_ALL)
fun create(api: File, main: File): FormatterStep = FormatterStep.createLazy(
"license",
{ Licenses(getTemplateText(api), getTemplateText(main)) },
{ state -> FormatterFunc.NeedsFile { contents, file -> formatFile(state, contents, file) } },
)
private fun getTemplateText(file: File): String =
file.readText().trim().replace("\${year}", "$YEAR")
private fun formatFile(licenses: Licenses, contents: String, file: File): String {
val license = getLicense(contents)
val expectedLicense = getExpectedLicense(licenses, file.parentFile)
return when {
license == null -> setLicense(expectedLicense, contents)
license.second != expectedLicense -> setLicense(expectedLicense, contents, license.first)
else -> contents
}
}
private fun getExpectedLicense(licenses: Licenses, root: File): String {
var file: File? = root
while (file != null) {
if (file.name == "api" && file.parentFile?.name == "computercraft") return licenses.api
file = file.parentFile
}
return licenses.main
}
private fun getLicense(contents: String): Pair<Int, String>? {
val match = COMMENT.find(contents) ?: return null
val license = match.groups[1]!!.value
.trim().lineSequence()
.map { it.trimStart(' ', '*') }
.joinToString("\n")
return Pair(match.range.last + 1, license)
}
private fun setLicense(license: String, contents: String, start: Int = 0): String {
val out = StringBuilder()
out.append("/*\n")
for (line in license.lineSequence()) out.append(" * ").append(line).append("\n")
out.append(" */\n")
out.append(contents, start, contents.length)
return out.toString()
}
private data class Licenses(val api: String, val main: String) : Serializable {
companion object {
private const val serialVersionUID: Long = 7741106448372435662L
}
}
}

View File

@@ -0,0 +1,98 @@
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.artifacts.component.ModuleComponentSelector
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.artifacts.result.DependencyResult
import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import org.gradle.language.base.plugins.LifecycleBasePlugin
abstract class DependencyCheck : DefaultTask() {
@get:Input
protected abstract val dependencies: ListProperty<DependencyResult>
/**
* A mapping of module coordinates (`group:module`) to versions, overriding the requested version.
*/
@get:Input
protected abstract val overrides: MapProperty<String, String>
init {
description = "Check :core's dependencies are consistent with Minecraft's."
group = LifecycleBasePlugin.VERIFICATION_GROUP
dependencies.finalizeValueOnRead()
overrides.finalizeValueOnRead()
}
/**
* Override a module with a different version.
*/
fun override(module: Provider<MinimalExternalModuleDependency>, version: String) {
overrides.putAll(project.provider { mutableMapOf(module.get().module.toString() to version) })
}
/**
* Add a configuration to check.
*/
fun configuration(configuration: Provider<Configuration>) {
// We can't store the Configuration in the cache, so store the resolved dependencies instead.
dependencies.addAll(configuration.map { it.incoming.resolutionResult.allDependencies })
}
@TaskAction
fun run() {
var ok = true
for (configuration in dependencies.get()) {
if (!check(configuration)) ok = false
}
if (!ok) {
throw GradleException("Mismatched versions in Minecraft dependencies. gradle/libs.versions.toml may need updating.")
}
}
private fun check(dependency: DependencyResult): Boolean {
if (dependency !is ResolvedDependencyResult) {
logger.warn("Found unexpected dependency result {}", dependency)
return false
}
// Skip dependencies on non-modules.
val requested = dependency.requested
if (requested !is ModuleComponentSelector) return true
// If this dependency is specified within some project (so is non-transitive), or is pulled in via Minecraft,
// then check for consistency.
// It would be nice to be smarter about transitive dependencies, but avoiding false positives is hard.
val from = dependency.from.id
if (
from is ProjectComponentIdentifier ||
from is ModuleComponentIdentifier && (from.group == "net.minecraft" || from.group == "io.netty")
) {
// If the version is different between the requested and selected version, report an error.
val selected = dependency.selected.moduleVersion!!.version
val requestedVersion = overrides.get()["${requested.group}:${requested.module}"] ?: requested.version
if (requestedVersion != selected) {
logger.error("Requested dependency {} (via {}) but got version {}", requested, from, selected)
return false
}
return true
}
return true
}
}

View File

@@ -1,11 +1,14 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.provider.Property
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.AbstractExecTask
import org.gradle.api.tasks.OutputDirectory
import java.io.File
abstract class ExecToDir : AbstractExecTask<ExecToDir>(ExecToDir::class.java) {
@get:OutputDirectory
abstract val output: Property<File>
abstract val output: DirectoryProperty
}

View File

@@ -1,7 +1,15 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.file.FileSystemLocation
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.JavaExec
import org.gradle.kotlin.dsl.getByName
import org.gradle.process.BaseExecSpec
import org.gradle.process.JavaExecSpec
import org.gradle.process.ProcessForkOptions
@@ -39,6 +47,21 @@ fun JavaExec.copyToFull(spec: JavaExec) {
copyToExec(spec)
}
/**
* Base this [JavaExec] task on an existing task.
*/
fun JavaExec.copyFromTask(task: JavaExec) {
for (dep in task.dependsOn) dependsOn(dep)
task.copyToFull(this)
}
/**
* Base this [JavaExec] task on an existing task.
*/
fun JavaExec.copyFromTask(task: String) {
copyFromTask(project.tasks.getByName<JavaExec>(task))
}
/**
* Copy additional [BaseExecSpec] options which aren't handled by [ProcessForkOptions.copyTo].
*/
@@ -115,3 +138,48 @@ class CloseScope : AutoCloseable {
}
}
}
/** Proxy method to avoid overload ambiguity. */
fun <T> Property<T>.setProvider(provider: Provider<out T>) = set(provider)
/** Short-cut method to get the absolute path of a [FileSystemLocation] provider. */
fun Provider<out FileSystemLocation>.getAbsolutePath(): String = get().asFile.absolutePath
/**
* Get the version immediately after the provided version.
*
* For example, given "1.2.3", this will return "1.2.4".
*/
fun getNextVersion(version: String): String {
// Split a version like x.y.z-SNAPSHOT into x.y.z and -SNAPSHOT
val dashIndex = version.indexOf('-')
val mainVersion = if (dashIndex < 0) version else version.substring(0, dashIndex)
// Find the last component in x.y.z and increment it.
val lastIndex = mainVersion.lastIndexOf('.')
if (lastIndex < 0) throw IllegalArgumentException("Cannot parse version format \"$version\"")
val lastVersion = try {
mainVersion.substring(lastIndex + 1).toInt()
} catch (e: NumberFormatException) {
throw IllegalArgumentException("Cannot parse version format \"$version\"", e)
}
// Then append all components together.
val out = StringBuilder()
out.append(version, 0, lastIndex + 1)
out.append(lastVersion + 1)
if (dashIndex >= 0) out.append(version, dashIndex, version.length)
return out.toString()
}
/**
* Capitalise the first letter of the string.
*
* This is a replacement for the now deprecated [String.capitalize].
*/
fun String.capitalise(): String {
if (isEmpty()) return this
val first = this[0]
val firstTitle = first.titlecaseChar()
return if (first == firstTitle) this else firstTitle + substring(1)
}

View File

@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.jetbrains.gradle.ext.JUnit
import javax.inject.Inject
/**
* A version of [JUnit] with a functional [className].
*
* See [#92](https://github.com/JetBrains/gradle-idea-ext-plugin/issues/92).
*/
open class JUnitExt @Inject constructor(nameParam: String) : JUnit(nameParam) {
override fun toMap(): MutableMap<String, *> {
val map = HashMap(super.toMap())
// Should be "class" instead of "className".
// See https://github.com/JetBrains/intellij-community/blob/9ba394021dc73a3926f13d6d6cdf434f9ee7046d/plugins/junit/src/com/intellij/execution/junit/JUnitRunConfigurationImporter.kt#L39
map["class"] = className
return map
}
}

View File

@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.Project
@@ -21,7 +25,6 @@ import javax.xml.xpath.XPathFactory
* Would be good to PR some (or all) of these changes upstream at some point.
*
* @see net.fabricmc.loom.configuration.ide.idea.IdeaSyncTask
* @see net.minecraftforge.gradle.common.util.runs.IntellijRunGenerator
*/
internal class IdeaRunConfigurations(project: Project) {
private val rootProject = project.rootProject
@@ -31,22 +34,6 @@ internal class IdeaRunConfigurations(project: Project) {
private val writer = TransformerFactory.newInstance().newTransformer()
private val ideaDir = rootProject.file(".idea/")
private val buildDir: Lazy<String?> = lazy {
val ideaMisc = ideaDir.resolve("misc.xml")
try {
val doc = Files.newBufferedReader(ideaMisc.toPath()).use {
documentBuilder.parse(InputSource(it))
}
val node =
xpath.evaluate("//component[@name=\"ProjectRootManager\"]/output", doc, XPathConstants.NODE) as Node
val attr = node.attributes.getNamedItem("url") as Attr
attr.value.removePrefix("file://")
} catch (e: Exception) {
LOGGER.error("Failed to find root directory", e)
null
}
}
fun patch() = synchronized(LOCK) {
val runConfigDir = ideaDir.resolve("runConfigurations")
@@ -54,10 +41,9 @@ internal class IdeaRunConfigurations(project: Project) {
Files.list(runConfigDir.toPath()).use {
for (configuration in it) {
val filename = configuration.fileName.toString();
val filename = configuration.fileName.toString()
when {
filename.endsWith("_fabric.xml") -> patchFabric(configuration)
filename.startsWith("forge_") && filename.endsWith(".xml") -> patchForge(configuration)
else -> {}
}
}
@@ -68,65 +54,6 @@ internal class IdeaRunConfigurations(project: Project) {
setXml("//configuration", "folderName") { "Fabric" }
}
private fun patchForge(path: Path) = withXml(path) {
val configId = path.fileName.toString().removePrefix("forge_").removeSuffix(".xml")
val sourceSet = forgeConfigs[configId]
if (sourceSet == null) {
LOGGER.error("[{}] Cannot map run configuration to a known source set", path)
return@withXml
}
setXml("//configuration", "folderName") { "Forge" }
setXml("//configuration/module", "name") { "${rootProject.name}.forge.$sourceSet" }
if (buildDir.value == null) return@withXml
setXml("//configuration/envs/env[@name=\"MOD_CLASSES\"]", "value") { classpath ->
val classes = classpath!!.split(':')
val newClasses = mutableListOf<String>()
fun appendUnique(x: String) {
if (!newClasses.contains(x)) newClasses.add(x)
}
for (entry in classes) {
if (!entry.contains("/out/")) {
appendUnique(entry)
continue
}
val match = CLASSPATH_ENTRY.matchEntire(entry)
if (match != null) {
val modId = match.groups["modId"]!!.value
val proj = match.groups["proj"]!!.value
var component = match.groups["component"]!!.value
if (component == "production") component = "main"
appendUnique(forgeModEntry(modId, proj, component))
} else {
LOGGER.warn("[{}] Unknown classpath entry {}", path, entry)
appendUnique(entry)
}
}
// Ensure common code is on the classpath
for (proj in listOf("common", "common-api")) {
for (component in listOf("main", "client")) {
appendUnique(forgeModEntry("computercraft", proj, component))
}
}
if (newClasses.any { it.startsWith("cctest%%") }) {
appendUnique(forgeModEntry("cctest", "core", "testFixtures"))
appendUnique(forgeModEntry("cctest", "common", "testFixtures"))
appendUnique(forgeModEntry("cctest", "common", "testMod"))
}
newClasses.joinToString(":")
}
}
private fun forgeModEntry(mod: String, project: String, component: String) =
"$mod%%${buildDir.value}/production/${rootProject.name}.$project.$component"
private fun LocatedDocument.setXml(xpath: String, attribute: String, value: (String?) -> String) {
val node = this@IdeaRunConfigurations.xpath.evaluate(xpath, document, XPathConstants.NODE) as Node?
if (node == null) {
@@ -155,16 +82,5 @@ internal class IdeaRunConfigurations(project: Project) {
companion object {
private val LOGGER = Logging.getLogger(IdeaRunConfigurations::class.java)
private val LOCK = Any()
private val CLASSPATH_ENTRY =
Regex("(?<modId>[a-z]+)%%\\\$PROJECT_DIR\\\$/projects/(?<proj>[a-z-]+)/out/(?<component>\\w+)/(?<type>[a-z]+)\$")
private val forgeConfigs = mapOf(
"runClient" to "client",
"runData" to "main",
"runGameTestServer" to "testMod",
"runServer" to "main",
"runTestClient" to "testMod",
)
}
}

View File

@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.DefaultTask
@@ -56,7 +60,7 @@ class IlluaminatePlugin : Plugin<Project> {
/** Define a dependency for illuaminate from a version number and the current operating system. */
private fun illuaminateArtifact(project: Project, version: String): Dependency {
val osName = System.getProperty("os.name").toLowerCase()
val osName = System.getProperty("os.name").lowercase()
val (os, suffix) = when {
osName.contains("windows") -> Pair("windows", ".exe")
osName.contains("mac os") || osName.contains("darwin") -> Pair("macos", "")
@@ -64,7 +68,7 @@ class IlluaminatePlugin : Plugin<Project> {
else -> error("Unsupported OS $osName for illuaminate")
}
val osArch = System.getProperty("os.arch").toLowerCase()
val osArch = System.getProperty("os.arch").lowercase()
val arch = when {
// On macOS the x86_64 binary will work for both ARM and Intel Macs through Rosetta.
os == "macos" -> "x86_64"

View File

@@ -1,62 +0,0 @@
package cc.tweaked.gradle
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.specs.Spec
/**
* A dependency in a POM file.
*/
data class MavenDependency(val groupId: String?, val artifactId: String?, val version: String?, val scope: String?)
/**
* A spec specifying which dependencies to include/exclude.
*/
class MavenDependencySpec {
private val excludeSpecs = mutableListOf<Spec<MavenDependency>>()
fun exclude(spec: Spec<MavenDependency>) {
excludeSpecs.add(spec)
}
fun exclude(dep: Dependency) {
exclude {
(dep.group.isNullOrEmpty() || dep.group == it.groupId) &&
(dep.name.isNullOrEmpty() || dep.name == it.artifactId) &&
(dep.version.isNullOrEmpty() || dep.version == it.version)
}
}
fun exclude(dep: MinimalExternalModuleDependency) {
exclude {
dep.module.group == it.groupId && dep.module.name == it.artifactId
}
}
fun isIncluded(dep: MavenDependency) = !excludeSpecs.any { it.isSatisfiedBy(dep) }
}
/**
* Configure dependencies present in this publication's POM file.
*
* While this approach is very ugly, it's the easiest way to handle it!
*/
fun MavenPublication.mavenDependencies(action: MavenDependencySpec.() -> Unit) {
val spec = MavenDependencySpec()
action(spec)
pom.withXml {
val dependencies = XmlUtil.findChild(asNode(), "dependencies") ?: return@withXml
dependencies.children().map { it as groovy.util.Node }.forEach {
val dep = MavenDependency(
groupId = XmlUtil.findChild(it, "groupId")?.text(),
artifactId = XmlUtil.findChild(it, "artifactId")?.text(),
version = XmlUtil.findChild(it, "version")?.text(),
scope = XmlUtil.findChild(it, "scope")?.text(),
)
if (!spec.isIncluded(dep)) it.parent().remove(it)
}
}
}

View File

@@ -0,0 +1,120 @@
// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import cc.tweaked.vanillaextract.core.util.MoreFiles
import org.gradle.api.Action
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.*
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.*
import javax.inject.Inject
/**
* Merge common files across multiple directories into one destination directory.
*
* This is intended for merging the generated resources from the Forge and Fabric projects. Files common between the two
* are written to the global [output] directory, while distinct files are written to the per-source
* [MergeTrees.Source.output] directory.
*/
abstract class MergeTrees : DefaultTask() {
/**
* A source directory to read from.
*/
interface Source {
/**
* The folder contianing all input files.
*/
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
val input: ConfigurableFileTree
fun input(configure: Action<ConfigurableFileTree>) {
configure.execute(input)
}
/**
* The folder to write files unique to this folder to.
*/
@get:OutputDirectory
val output: DirectoryProperty
}
/**
* The list of sources.
*/
@get:Nested
abstract val sources: ListProperty<Source>
/**
* Add and configure a new source.
*/
fun source(configure: Action<Source>) {
val instance = objectFactory.newInstance(Source::class.java)
configure.execute(instance)
instance.output.disallowChanges()
sources.add(instance)
}
/**
* The directory to write common files to.
*/
@get:OutputDirectory
abstract val output: DirectoryProperty
@get:Inject
protected abstract val objectFactory: ObjectFactory
@get:Inject
protected abstract val fsOperations: FileSystemOperations
@TaskAction
fun run() {
val sources = this.sources.get()
if (sources.isEmpty()) throw GradleException("Cannot have an empty list of sources")
val files = mutableMapOf<String, SharedFile>()
for (source in sources) {
source.input.visit(
object : FileVisitor {
override fun visitDir(dirDetails: FileVisitDetails) = Unit
override fun visitFile(fileDetails: FileVisitDetails) {
val path = fileDetails.file.toRelativeString(source.input.dir)
val hash = MoreFiles.computeSha1(fileDetails.file.toPath())
val existing = files[path]
if (existing == null) {
files[path] = SharedFile(hash, 1)
} else if (existing.hash == hash) {
existing.found++
}
}
},
)
}
val sharedFiles = files.entries.asSequence().filter { (_, v) -> v.found == sources.size }.map { (k, _) -> k }.toList()
// Copy shared files to the common directory
fsOperations.sync {
from(sources[0].input)
into(output)
include(sharedFiles)
}
// And all other files to their per-source directory
for (source in sources) {
fsOperations.sync {
from(source.input)
into(source.output)
exclude(sharedFiles)
}
}
}
class SharedFile(val hash: String, var found: Int)
}

View File

@@ -1,22 +1,20 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import cc.tweaked.vanillaextract.configurations.Capabilities
import cc.tweaked.vanillaextract.configurations.MinecraftSetup
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.attributes.Bundling
import org.gradle.api.attributes.Category
import org.gradle.api.attributes.LibraryElements
import org.gradle.api.attributes.Usage
import org.gradle.api.attributes.java.TargetJvmVersion
import org.gradle.api.capabilities.Capability
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.named
/**
* This sets up a separate client-only source set, and extends that and the main/common source set with additional
@@ -26,7 +24,6 @@ class MinecraftConfigurations private constructor(private val project: Project)
private val java = project.extensions.getByType(JavaPluginExtension::class.java)
private val sourceSets = java.sourceSets
private val configurations = project.configurations
private val objects = project.objects
private val main = sourceSets[SourceSet.MAIN_SOURCE_SET_NAME]
private val test = sourceSets[SourceSet.TEST_SOURCE_SET_NAME]
@@ -39,13 +36,7 @@ class MinecraftConfigurations private constructor(private val project: Project)
val client = sourceSets.maybeCreate("client")
// Ensure the client classpaths behave the same as the main ones.
configurations.named(client.compileClasspathConfigurationName) {
shouldResolveConsistentlyWith(configurations[main.compileClasspathConfigurationName])
}
configurations.named(client.runtimeClasspathConfigurationName) {
shouldResolveConsistentlyWith(configurations[main.runtimeClasspathConfigurationName])
}
consistentWithMain(client)
// Set up an API configuration for clients (to ensure it's consistent with the main source set).
val clientApi = configurations.maybeCreate(client.apiConfigurationName).apply {
@@ -55,31 +46,13 @@ class MinecraftConfigurations private constructor(private val project: Project)
}
configurations.named(client.implementationConfigurationName) { extendsFrom(clientApi) }
/*
Now add outgoing variants for the main and common source sets that we can consume downstream. This is possibly
the worst way to do things, but unfortunately the alternatives don't actually work very well:
- Just using source set outputs: This means dependencies don't propagate, which means when :fabric depends
on :fabric-api, we don't inherit the fake :common-api in IDEA.
- Having separate common/main jars: Nice in principle, but unfortunately Forge needs a separate deobf jar
task (as the original jar is obfuscated), and IDEA is not able to map its output back to a source set.
This works for now, but is incredibly brittle. It's part of the reason we can't use testFixtures inside our
MC projects, as that adds a project(self) -> test dependency, which would pull in the jar instead.
Note we register a fake client jar here. It's not actually needed, but is there to make sure IDEA has
a way to tell that client classes are needed at runtime.
I'm so sorry, deeply aware how cursed this is.
*/
setupOutgoing(main, "CommonOnly")
project.tasks.register(client.jarTaskName, Jar::class.java) {
description = "An empty jar standing in for the client classes."
group = BasePlugin.BUILD_GROUP
archiveClassifier.set("client")
}
setupOutgoing(client)
MinecraftSetup(project).setupOutgoingConfigurations()
// Reset the client classpath (Loom configures it slightly differently to this) and add a main -> client
// dependency. Here we /can/ use source set outputs as we add transitive deps by patching the classpath. Nasty,
@@ -102,88 +75,70 @@ class MinecraftConfigurations private constructor(private val project: Project)
project.tasks.named("jar", Jar::class.java) { from(client.output) }
project.tasks.named("sourcesJar", Jar::class.java) { from(client.allSource) }
setupBasic()
}
private fun consistentWithMain(sourceSet: SourceSet) {
configurations.named(sourceSet.compileClasspathConfigurationName) {
shouldResolveConsistentlyWith(configurations[main.compileClasspathConfigurationName])
}
configurations.named(sourceSet.runtimeClasspathConfigurationName) {
shouldResolveConsistentlyWith(configurations[main.runtimeClasspathConfigurationName])
}
}
private fun setupBasic() {
val client = sourceSets["client"]
project.extensions.configure(CCTweakedExtension::class.java) {
sourceDirectories.add(SourceSetReference.internal(client))
}
}
private fun setupOutgoing(sourceSet: SourceSet, suffix: String = "") {
setupOutgoing("${sourceSet.apiElementsConfigurationName}$suffix", sourceSet, objects.named(Usage.JAVA_API)) {
description = "API elements for ${sourceSet.name}"
extendsFrom(configurations[sourceSet.apiConfigurationName])
}
setupOutgoing("${sourceSet.runtimeElementsConfigurationName}$suffix", sourceSet, objects.named(Usage.JAVA_RUNTIME)) {
description = "Runtime elements for ${sourceSet.name}"
extendsFrom(configurations[sourceSet.implementationConfigurationName], configurations[sourceSet.runtimeOnlyConfigurationName])
}
// Register a task to check there are no conflicts with the core project.
val checkDependencyConsistency =
project.tasks.register("checkDependencyConsistency", DependencyCheck::class.java) {
// We need to check both the main and client classpath *configurations*, as the actual configuration
configuration(configurations.named(main.runtimeClasspathConfigurationName))
configuration(configurations.named(client.runtimeClasspathConfigurationName))
}
project.tasks.named("check") { dependsOn(checkDependencyConsistency) }
}
/**
* Set up an outgoing configuration for a specific source set. We set an additional "main" or "client" capability
* (depending on the source set name) which allows downstream projects to consume them separately (see
* [DependencyHandler.commonClasses] and [DependencyHandler.clientClasses]).
* Create a new configuration that pulls in the main and client classes from the mod.
*/
private fun setupOutgoing(name: String, sourceSet: SourceSet, usage: Usage, configure: Configuration.() -> Unit) {
configurations.register(name) {
isVisible = false
isCanBeConsumed = true
isCanBeResolved = false
configure(this)
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY))
attribute(Usage.USAGE_ATTRIBUTE, usage)
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
attributeProvider(
TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE,
java.toolchain.languageVersion.map { it.asInt() },
)
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR))
}
outgoing {
capability(BasicOutgoingCapability(project, sourceSet.name))
// We have two outgoing variants here: the original jar and the classes.
artifact(project.tasks.named(sourceSet.jarTaskName))
variants.create("classes") {
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.CLASSES))
sourceSet.output.classesDirs.forEach { artifact(it) { builtBy(sourceSet.output) } }
}
}
}
private fun createDerivedConfiguration(name: String) {
val client = sourceSets["client"]
val sourceSet = sourceSets.create(name)
sourceSet.compileClasspath += main.compileClasspath + client.compileClasspath
sourceSet.runtimeClasspath += main.runtimeClasspath + client.runtimeClasspath
consistentWithMain(sourceSet)
project.dependencies.add(sourceSet.implementationConfigurationName, main.output)
project.dependencies.add(sourceSet.implementationConfigurationName, client.output)
}
companion object {
const val DATAGEN = "datagen"
const val EXAMPLES = "examples"
const val TEST_MOD = "testMod"
fun setupBasic(project: Project) {
MinecraftConfigurations(project).setupBasic()
}
fun setup(project: Project) {
MinecraftConfigurations(project).setup()
}
fun createDerivedConfiguration(project: Project, name: String) {
MinecraftConfigurations(project).createDerivedConfiguration(name)
}
}
}
private class BasicIncomingCapability(private val module: ModuleDependency, private val name: String) : Capability {
override fun getGroup(): String = module.group!!
override fun getName(): String = "${module.name}-$name"
override fun getVersion(): String? = null
}
fun DependencyHandler.clientClasses(notation: Any): ModuleDependency =
Capabilities.clientClasses(create(notation) as ModuleDependency)
private class BasicOutgoingCapability(private val project: Project, private val name: String) : Capability {
override fun getGroup(): String = project.group.toString()
override fun getName(): String = "${project.name}-$name"
override fun getVersion(): String = project.version.toString()
}
fun DependencyHandler.clientClasses(notation: Any): ModuleDependency {
val dep = create(notation) as ModuleDependency
dep.capabilities { requireCapability(BasicIncomingCapability(dep, "client")) }
return dep
}
fun DependencyHandler.commonClasses(notation: Any): ModuleDependency {
val dep = create(notation) as ModuleDependency
dep.capabilities { requireCapability(BasicIncomingCapability(dep, "main")) }
return dep
}
fun DependencyHandler.commonClasses(notation: Any): ModuleDependency =
Capabilities.commonClasses(create(notation) as ModuleDependency)

View File

@@ -1,5 +1,10 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import net.neoforged.moddevgradle.internal.RunGameTask
import org.gradle.api.GradleException
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.invocation.Gradle
@@ -14,6 +19,7 @@ import java.nio.file.Files
import java.util.concurrent.TimeUnit
import java.util.function.Supplier
import javax.inject.Inject
import kotlin.collections.set
import kotlin.random.Random
/**
@@ -28,11 +34,14 @@ abstract class ClientJavaExec : JavaExec() {
usesService(clientRunner)
}
@get:Input
val renderdoc get() = project.hasProperty("renderdoc")
/**
* When [false], tests will not be run automatically, allowing the user to debug rendering.
*/
@get:Input
val clientDebug get() = project.hasProperty("clientDebug")
val clientDebug get() = renderdoc || project.hasProperty("clientDebug")
/**
* When [false], tests will not run under a framebuffer.
@@ -46,6 +55,33 @@ abstract class ClientJavaExec : JavaExec() {
@get:OutputFile
val testResults = project.layout.buildDirectory.file("test-results/$name.xml")
private fun setTestProperties() {
if (!clientDebug) systemProperty("cctest.client", "")
if (renderdoc) environment("LD_PRELOAD", "/usr/lib/librenderdoc.so")
systemProperty("cctest.gametest-report", testResults.get().asFile.absoluteFile)
workingDir(project.layout.buildDirectory.dir("gametest/$name"))
}
init {
setTestProperties()
}
fun copyFromForge(path: String) = copyFromForge(project.tasks.getByName(path, RunGameTask::class))
/**
* Set this task to run a given [RunGameTask].
*/
fun copyFromForge(task: RunGameTask) {
copyFrom(task)
// Eagerly evaluate the behaviour of RunGameTask.exec
environment.putAll(task.environmentProperty.get())
classpath(task.classpathProvider)
workingDir = task.gameDirectory.get().asFile
setTestProperties() // setRunConfig may clobber some properties, ensure everything is set.
}
/**
* Copy configuration from a task with the given name.
*/
@@ -57,10 +93,7 @@ abstract class ClientJavaExec : JavaExec() {
fun copyFrom(task: JavaExec) {
for (dep in task.dependsOn) dependsOn(dep)
task.copyToFull(this)
if (!clientDebug) systemProperty("cctest.client", "")
systemProperty("cctest.gametest-report", testResults.get().asFile.absoluteFile)
workingDir(project.buildDir.resolve("gametest").resolve(name))
setTestProperties() // copyToFull may clobber some properties, ensure everything is set.
}
/**
@@ -93,6 +126,23 @@ abstract class ClientJavaExec : JavaExec() {
}
}
/**
* Configure Iris to use Complementary Shaders.
*/
fun withComplementaryShaders() {
val cct = project.extensions.getByType(CCTweakedExtension::class.java)
withFileFrom(workingDir.resolve("shaderpacks/ComplementaryShaders_v4.6.zip")) {
cct.downloadFile("Complementary Shaders", "https://edge.forgecdn.net/files/3951/170/ComplementaryShaders_v4.6.zip")
}
withFileContents(workingDir.resolve("config/iris.properties")) {
"""
enableShaders=true
shaderPack=ComplementaryShaders_v4.6.zip
""".trimIndent()
}
}
@TaskAction
override fun exec() {
Files.createDirectories(workingDir.toPath())

View File

@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.DefaultTask
@@ -7,7 +11,9 @@ import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.process.ExecOperations
import java.io.File
import javax.inject.Inject
class NodePlugin : Plugin<Project> {
override fun apply(project: Project) {
@@ -39,10 +45,13 @@ abstract class NpmInstall : DefaultTask() {
@get:OutputDirectory
val nodeModules: Provider<Directory> = projectRoot.dir("node_modules")
@get:Inject
protected abstract val execOperations: ExecOperations
@TaskAction
fun install() {
project.exec {
commandLine("npm", "ci")
execOperations.exec {
commandLine(ProcessHelpers.getExecutable("npm"), "ci")
workingDir = projectRoot.get().asFile
}
}
@@ -55,6 +64,6 @@ abstract class NpmInstall : DefaultTask() {
abstract class NpxExecToDir : ExecToDir() {
init {
dependsOn(NpmInstall.TASK_NAME)
executable = "npx"
executable = ProcessHelpers.getExecutable("npx")
}
}

View File

@@ -1,47 +1,39 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.codehaus.groovy.runtime.ProcessGroovyMethods
import org.gradle.api.GradleException
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
internal object ProcessHelpers {
fun startProcess(vararg command: String): Process {
// Something randomly passes in "GIT_DIR=" as an environment variable which clobbers everything else. Don't
// inherit the environment array!
return ProcessBuilder()
.command(*command)
.redirectError(ProcessBuilder.Redirect.INHERIT)
.also { it.environment().clear() }
.start()
}
fun captureOut(vararg command: String): String {
val process = startProcess(*command)
process.outputStream.close()
val result = ProcessGroovyMethods.getText(process)
process.waitForOrThrow("Failed to run command")
return result
}
fun captureLines(vararg command: String): List<String> {
val process = startProcess(*command)
process.outputStream.close()
val out = BufferedReader(InputStreamReader(process.inputStream)).use { reader ->
reader.lines().filter { it.isNotEmpty() }.toList()
}
ProcessGroovyMethods.closeStreams(process)
process.waitForOrThrow("Failed to run command")
return out
}
fun onPath(name: String): Boolean {
val path = System.getenv("PATH") ?: return false
return path.splitToSequence(File.pathSeparator).any { File(it, name).exists() }
}
/**
* Search for an executable on the `PATH` if required.
*
* [Process]/[ProcessBuilder] does not handle all executable file extensions on Windows (such as `.com). When on
* Windows, this function searches `PATH` and `PATHEXT` for an executable matching [name].
*/
fun getExecutable(name: String): String {
if (!System.getProperty("os.name").lowercase().contains("windows")) return name
val path = (System.getenv("PATH") ?: return name).split(File.pathSeparator)
val pathExt = (System.getenv("PATHEXT") ?: return name).split(File.pathSeparator)
for (pathEntry in path) {
for (ext in pathExt) {
val resolved = File(pathEntry, name + ext)
if (resolved.exists()) return resolved.getAbsolutePath()
}
}
return name
}
}
internal fun Process.waitForOrThrow(message: String) {

View File

@@ -1,3 +1,7 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.tasks.SourceSet

View File

@@ -1,12 +0,0 @@
package cc.tweaked.gradle
import groovy.util.Node
import groovy.util.NodeList
object XmlUtil {
fun findChild(node: Node, name: String): Node? = when (val child = node.get(name)) {
is Node -> child
is NodeList -> child.singleOrNull() as Node?
else -> null
}
}

View File

@@ -1,4 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: 2019 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
@@ -6,8 +13,21 @@
<property name="tabWidth" value="4"/>
<property name="charset" value="UTF-8" />
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<module name="SuppressionFilter">
<property name="file" value="${config_loc}/suppressions.xml" />
<property name="file" value="${config_loc}/suppressions.xml" />
</module>
<!--
Checkstyle doesn't support @snippet (https://github.com/checkstyle/checkstyle/issues/11455),
so suppress warnings nearby
-->
<module name="SuppressWithNearbyTextFilter">
<property name="nearbyTextPattern" value="@snippet" />
<property name="lineRange" value="20" />
</module>
<module name="BeforeExecutionExclusionFileFilter">
@@ -81,7 +101,10 @@
<module name="InvalidJavadocPosition" />
<module name="JavadocBlockTagLocation" />
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocType">
<!-- Seems to complain about @hidden!? -->
<property name="allowUnknownTags" value="true" />
</module>
<module name="JavadocStyle">
<property name="checkHtml" value="false" />
</module>
@@ -105,17 +128,19 @@
<module name="LambdaParameterName" />
<module name="LocalFinalVariableName" />
<module name="LocalVariableName" />
<module name="MemberName" />
<module name="MemberName">
<property name="format" value="^(computercraft\$|\$)?[a-z][a-zA-Z0-9]*$" />
</module>
<module name="MethodName">
<property name="format" value="^(computercraft\$)?[a-z][a-zA-Z0-9]*$" />
</module>
<module name="MethodTypeParameterName" />
<module name="PackageName">
<property name="format" value="^(dan200\.computercraft|cc\.tweaked)(\.[a-z][a-z0-9]*)*" />
<property name="format" value="^(dan200\.computercraft|cc\.tweaked|com\.example\.examplemod)(\.[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="format" value="^[a-z][a-zA-Z0-9]*$" />
</module>
<module name="TypeName" />
@@ -130,7 +155,10 @@
<module name="NoWhitespaceAfter">
<property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP,METHOD_REF" />
</module>
<module name="NoWhitespaceBefore" />
<module name="NoWhitespaceBefore">
<!-- Allow whitespace before "..." for @Nullable annotations -->
<property name="tokens" value="COMMA,SEMI,POST_INC,POST_DEC,LABELED_STAT" />
</module>
<!-- TODO: Decide on an OperatorWrap style. -->
<module name="ParenPad" />
<module name="SeparatorWrap">

View File

@@ -1,4 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: 2019 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
<!DOCTYPE suppressions PUBLIC
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
@@ -9,4 +16,13 @@
<!-- The commands API is documented in Lua. -->
<suppress checks="SummaryJavadocCheck" files=".*[\\/]CommandAPI.java" />
<!-- Allow putting files in other packages if they look like our TeaVM stubs. -->
<suppress checks="PackageName" files=".*[\\/]T[A-Za-z]+.java" />
<!-- Allow underscores in our test classes. -->
<suppress checks="MethodName" files=".*(Contract|Test).java" />
<!-- Allow underscores in Mixin classes -->
<suppress checks="TypeName" files=".*[\\/]mixin[\\/].*.java" />
</suppressions>

View File

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

View File

@@ -1,3 +0,0 @@
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.

View File

@@ -1,3 +0,0 @@
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

29
crowdin.yml Normal file
View File

@@ -0,0 +1,29 @@
# SPDX-FileCopyrightText: 2017 The CC: Tweaked Developers
#
# SPDX-License-Identifier: MPL-2.0
files:
- source: projects/common/src/generated/resources/assets/computercraft/lang/en_us.json
translation: /projects/common/src/main/resources/assets/computercraft/lang/%locale_with_underscore%.json
languages_mapping:
locale_with_underscore:
cs: cs_cz # Czech
da: da_dk # Danish
de: de_de # German
es-ES: es_es # Spanish
fr: fr_fr # French
hu: hu_hu # Hungarian
it: it_it # Italian
ja: ja_jp # Japanese
ko: ko_kr # Korean
nb: nb_no # Norwegian Bokmal
nl: nl_nl # Dutch
pl: pl_pl # Polish
pt-BR: pt_br # Portuguese, Brazilian
ru: ru_ru # Russian
sv-SE: sv_se # Sweedish
tok: tok # Toki Pona
tr: tr_tr # Turkish
uk: uk_ua # Ukraine
vi: vi_vn # Vietnamese
zh-CN: zh_cn # Chinese Simplified

View File

@@ -3,11 +3,17 @@ module: [kind=event] alarm
see: os.setAlarm To start an alarm.
---
The @{alarm} event is fired when an alarm started with @{os.setAlarm} completes.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`alarm`] event is fired when an alarm started with [`os.setAlarm`] completes.
## Return Values
1. @{string}: The event name.
2. @{number}: The ID of the alarm that finished.
1. [`string`]: The event name.
2. [`number`]: The ID of the alarm that finished.
## Example
Starts a timer and then waits for it to complete.

View File

@@ -3,15 +3,21 @@ module: [kind=event] char
see: key To listen to any key press.
---
The @{char} event is fired when a character is typed on the keyboard.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
The @{char} event is different to a key press. Sometimes multiple key presses may result in one character being
SPDX-License-Identifier: MPL-2.0
-->
The [`char`] event is fired when a character is typed on the keyboard.
The [`char`] event is different to a key press. Sometimes multiple key presses may result in one character being
typed (for instance, on some European keyboards). Similarly, some keys (e.g. <kbd>Ctrl</kbd>) do not have any
corresponding character. The @{key} should be used if you want to listen to key presses themselves.
corresponding character. The [`key`] should be used if you want to listen to key presses themselves.
## Return values
1. @{string}: The event name.
2. @{string}: The string representing the character that was pressed.
1. [`string`]: The event name.
2. [`string`]: The string representing the character that was pressed.
## Example

View File

@@ -2,11 +2,17 @@
module: [kind=event] computer_command
---
The @{computer_command} event is fired when the `/computercraft queue` command is run for the current computer.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`computer_command`] event is fired when the `/computercraft queue` command is run for the current computer.
## Return Values
1. @{string}: The event name.
2. @{string}<abbr title="Variable number of arguments">&hellip;</abbr>: The arguments passed to the command.
1. [`string`]: The event name.
2. [`string`]<abbr title="Variable number of arguments">&hellip;</abbr>: The arguments passed to the command.
## Example
Prints the contents of messages sent:

View File

@@ -3,11 +3,17 @@ module: [kind=event] disk
see: disk_eject For the event sent when a disk is removed.
---
The @{disk} event is fired when a disk is inserted into an adjacent or networked disk drive.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`disk`] event is fired when a disk is inserted into an adjacent or networked disk drive.
## Return Values
1. @{string}: The event name.
2. @{string}: The side of the disk drive that had a disk inserted.
1. [`string`]: The event name.
2. [`string`]: The side of the disk drive that had a disk inserted.
## Example
Prints a message when a disk is inserted:

View File

@@ -3,11 +3,17 @@ module: [kind=event] disk_eject
see: disk For the event sent when a disk is inserted.
---
The @{disk_eject} event is fired when a disk is removed from an adjacent or networked disk drive.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`disk_eject`] event is fired when a disk is removed from an adjacent or networked disk drive.
## Return Values
1. @{string}: The event name.
2. @{string}: The side of the disk drive that had a disk removed.
1. [`string`]: The event name.
2. [`string`]: The side of the disk drive that had a disk removed.
## Example
Prints a message when a disk is removed:

View File

@@ -3,15 +3,21 @@ module: [kind=event] file_transfer
since: 1.101.0
---
The @{file_transfer} event is queued when a user drags-and-drops a file on an open computer.
<!--
SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
This event contains a single argument of type @{TransferredFiles}, which can be used to @{TransferredFiles.getFiles|get
the files to be transferred}. Each file returned is a @{fs.BinaryReadHandle|binary file handle} with an additional
@{TransferredFile.getName|getName} method.
SPDX-License-Identifier: MPL-2.0
-->
The [`file_transfer`] event is queued when a user drags-and-drops a file on an open computer.
This event contains a single argument of type [`TransferredFiles`], which can be used to [get the files to be
transferred][`TransferredFiles.getFiles`]. Each file returned is a [binary file handle][`fs.ReadHandle`] with an
additional [getName][`TransferredFile.getName`] method.
## Return values
1. @{string}: The event name
2. @{TransferredFiles}: The list of transferred files.
1. [`string`]: The event name
2. [`TransferredFiles`]: The list of transferred files.
## Example
Waits for a user to drop files on top of the computer, then prints the list of files and the size of each file.
@@ -23,7 +29,7 @@ for _, file in ipairs(files.getFiles()) do
local size = file.seek("end")
file.seek("set", 0)
print(file.getName() .. " " .. file.getSize())
print(file.getName() .. " " .. size)
end
```

View File

@@ -3,12 +3,18 @@ module: [kind=event] http_check
see: http.checkURLAsync To check a URL asynchronously.
---
The @{http_check} event is fired when a URL check finishes.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
This event is normally handled inside @{http.checkURL}, but it can still be seen when using @{http.checkURLAsync}.
SPDX-License-Identifier: MPL-2.0
-->
The [`http_check`] event is fired when a URL check finishes.
This event is normally handled inside [`http.checkURL`], but it can still be seen when using [`http.checkURLAsync`].
## Return Values
1. @{string}: The event name.
2. @{string}: The URL requested to be checked.
3. @{boolean}: Whether the check succeeded.
4. <span class="type">@{string}|@{nil}</span>: If the check failed, a reason explaining why the check failed.
1. [`string`]: The event name.
2. [`string`]: The URL requested to be checked.
3. [`boolean`]: Whether the check succeeded.
4. <span class="type">[`string`]|[`nil`]</span>: If the check failed, a reason explaining why the check failed.

View File

@@ -3,15 +3,21 @@ module: [kind=event] http_failure
see: http.request To send an HTTP request.
---
The @{http_failure} event is fired when an HTTP request fails.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
This event is normally handled inside @{http.get} and @{http.post}, but it can still be seen when using @{http.request}.
SPDX-License-Identifier: MPL-2.0
-->
The [`http_failure`] event is fired when an HTTP request fails.
This event is normally handled inside [`http.get`] and [`http.post`], but it can still be seen when using [`http.request`].
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the site requested.
3. @{string}: An error describing the failure.
4. <span class="type">@{http.Response}|@{nil}</span>: A response handle if the connection succeeded, but the server's
1. [`string`]: The event name.
2. [`string`]: The URL of the site requested.
3. [`string`]: An error describing the failure.
4. <span class="type">[`http.Response`]|[`nil`]</span>: A response handle if the connection succeeded, but the server's
response indicated failure.
## Example

View File

@@ -3,14 +3,20 @@ module: [kind=event] http_success
see: http.request To make an HTTP request.
---
The @{http_success} event is fired when an HTTP request returns successfully.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
This event is normally handled inside @{http.get} and @{http.post}, but it can still be seen when using @{http.request}.
SPDX-License-Identifier: MPL-2.0
-->
The [`http_success`] event is fired when an HTTP request returns successfully.
This event is normally handled inside [`http.get`] and [`http.post`], but it can still be seen when using [`http.request`].
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the site requested.
3. @{http.Response}: The successful HTTP response.
1. [`string`]: The event name.
2. [`string`]: The URL of the site requested.
3. [`http.Response`]: The successful HTTP response.
## Example
Prints the content of a website (this may fail if the request fails):

View File

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

View File

@@ -3,17 +3,23 @@ module: [kind=event] key_up
see: keys For a lookup table of the given keys.
---
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
Fired whenever a key is released (or the terminal is closed while a key was being pressed).
This event returns a numerical "key code" (for instance, <kbd>F1</kbd> is 290). This value may vary between versions and
so it is recommended to use the constants in the @{keys} API rather than hard coding numeric values.
so it is recommended to use the constants in the [`keys`] API rather than hard coding numeric values.
## Return values
1. @{string}: The event name.
2. @{number}: The numerical key value of the key pressed.
1. [`string`]: The event name.
2. [`number`]: The numerical key value of the key pressed.
## Example
Prints each key released on the keyboard whenever a @{key_up} event is fired.
Prints each key released on the keyboard whenever a [`key_up`] event is fired.
```lua
while true do

View File

@@ -2,18 +2,24 @@
module: [kind=event] modem_message
---
The @{modem_message} event is fired when a message is received on an open channel on any @{modem}.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`modem_message`] event is fired when a message is received on an open channel on any [`modem`].
## Return Values
1. @{string}: The event name.
2. @{string}: The side of the modem that received the message.
3. @{number}: The channel that the message was sent on.
4. @{number}: The reply channel set by the sender.
5. @{any}: The message as sent by the sender.
6. <span class="type">@{number}|@{nil}</span>: The distance between the sender and the receiver in blocks, or @{nil} if the message was sent between dimensions.
1. [`string`]: The event name.
2. [`string`]: The side of the modem that received the message.
3. [`number`]: The channel that the message was sent on.
4. [`number`]: The reply channel set by the sender.
5. [`any`]: The message as sent by the sender.
6. <span class="type">[`number`]|[`nil`]</span>: The distance between the sender and the receiver in blocks, or [`nil`] if the message was sent between dimensions.
## Example
Wraps a @{modem} peripheral, opens channel 0 for listening, and prints all received messages.
Wraps a [`modem`] peripheral, opens channel 0 for listening, and prints all received messages.
```lua
local modem = peripheral.find("modem") or error("No modem attached", 0)

View File

@@ -2,11 +2,17 @@
module: [kind=event] monitor_resize
---
The @{monitor_resize} event is fired when an adjacent or networked monitor's size is changed.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`monitor_resize`] event is fired when an adjacent or networked [monitor's][`monitor`] size is changed.
## Return Values
1. @{string}: The event name.
2. @{string}: The side or network ID of the monitor that was resized.
1. [`string`]: The event name.
2. [`string`]: The side or network ID of the monitor that was resized.
## Example
Prints a message when a monitor is resized:

View File

@@ -2,13 +2,19 @@
module: [kind=event] monitor_touch
---
The @{monitor_touch} event is fired when an adjacent or networked Advanced Monitor is right-clicked.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`monitor_touch`] event is fired when an adjacent or networked [Advanced Monitor][`monitor`] is right-clicked.
## Return Values
1. @{string}: The event name.
2. @{string}: The side or network ID of the monitor that was touched.
3. @{number}: The X coordinate of the touch, in characters.
4. @{number}: The Y coordinate of the touch, in characters.
1. [`string`]: The event name.
2. [`string`]: The side or network ID of the monitor that was touched.
3. [`number`]: The X coordinate of the touch, in characters.
4. [`number`]: The Y coordinate of the touch, in characters.
## Example
Prints a message when a monitor is touched:

View File

@@ -2,17 +2,23 @@
module: [kind=event] mouse_click
---
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
This event is fired when the terminal is clicked with a mouse. This event is only fired on advanced computers (including
advanced turtles and pocket computers).
## Return values
1. @{string}: The event name.
2. @{number}: The mouse button that was clicked.
3. @{number}: The X-coordinate of the click.
4. @{number}: The Y-coordinate of the click.
1. [`string`]: The event name.
2. [`number`]: The mouse button that was clicked.
3. [`number`]: The X-coordinate of the click.
4. [`number`]: The Y-coordinate of the click.
## Mouse buttons
Several mouse events (@{mouse_click}, @{mouse_up}, @{mouse_scroll}) contain a "mouse button" code. This takes a
Several mouse events ([`mouse_click`], [`mouse_up`], [`mouse_scroll`]) contain a "mouse button" code. This takes a
numerical value depending on which button on your mouse was last pressed when this event occurred.
| Button Code | Mouse Button |

View File

@@ -3,13 +3,19 @@ module: [kind=event] mouse_drag
see: mouse_click For when a mouse button is initially pressed.
---
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
This event is fired every time the mouse is moved while a mouse button is being held.
## Return values
1. @{string}: The event name.
2. @{number}: The [mouse button](mouse_click.html#Mouse_buttons) that is being pressed.
3. @{number}: The X-coordinate of the mouse.
4. @{number}: The Y-coordinate of the mouse.
1. [`string`]: The event name.
2. [`number`]: The [mouse button](mouse_click.html#Mouse_buttons) that is being pressed.
3. [`number`]: The X-coordinate of the mouse.
4. [`number`]: The Y-coordinate of the mouse.
## Example
Print the button and the coordinates whenever the mouse is dragged.

View File

@@ -2,13 +2,19 @@
module: [kind=event] mouse_scroll
---
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
This event is fired when a mouse wheel is scrolled in the terminal.
## Return values
1. @{string}: The event name.
2. @{number}: The direction of the scroll. (-1 = up, 1 = down)
3. @{number}: The X-coordinate of the mouse when scrolling.
4. @{number}: The Y-coordinate of the mouse when scrolling.
1. [`string`]: The event name.
2. [`number`]: The direction of the scroll. (-1 = up, 1 = down)
3. [`number`]: The X-coordinate of the mouse when scrolling.
4. [`number`]: The Y-coordinate of the mouse when scrolling.
## Example
Prints the direction of each scroll, and the position of the mouse at the time.

View File

@@ -2,13 +2,19 @@
module: [kind=event] mouse_up
---
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
This event is fired when a mouse button is released or a held mouse leaves the computer's terminal.
## Return values
1. @{string}: The event name.
2. @{number}: The [mouse button](mouse_click.html#Mouse_buttons) that was released.
3. @{number}: The X-coordinate of the mouse.
4. @{number}: The Y-coordinate of the mouse.
1. [`string`]: The event name.
2. [`number`]: The [mouse button](mouse_click.html#Mouse_buttons) that was released.
3. [`number`]: The X-coordinate of the mouse.
4. [`number`]: The Y-coordinate of the mouse.
## Example
Prints the coordinates and button number whenever the mouse is released.

View File

@@ -2,11 +2,17 @@
module: [kind=event] paste
---
The @{paste} event is fired when text is pasted into the computer through Ctrl-V (or ⌘V on Mac).
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`paste`] event is fired when text is pasted into the computer through Ctrl-V (or ⌘V on Mac).
## Return values
1. @{string}: The event name.
2. @{string} The text that was pasted.
1. [`string`]: The event name.
2. [`string`] The text that was pasted.
## Example
Prints pasted text:

View File

@@ -3,11 +3,17 @@ module: [kind=event] peripheral
see: peripheral_detach For the event fired when a peripheral is detached.
---
The @{peripheral} event is fired when a peripheral is attached on a side or to a modem.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`peripheral`] event is fired when a peripheral is attached on a side or to a modem.
## Return Values
1. @{string}: The event name.
2. @{string}: The side the peripheral was attached to.
1. [`string`]: The event name.
2. [`string`]: The side the peripheral was attached to.
## Example
Prints a message when a peripheral is attached:

View File

@@ -3,11 +3,17 @@ module: [kind=event] peripheral_detach
see: peripheral For the event fired when a peripheral is attached.
---
The @{peripheral_detach} event is fired when a peripheral is detached from a side or from a modem.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`peripheral_detach`] event is fired when a peripheral is detached from a side or from a modem.
## Return Values
1. @{string}: The event name.
2. @{string}: The side the peripheral was detached from.
1. [`string`]: The event name.
2. [`string`]: The side the peripheral was detached from.
## Example
Prints a message when a peripheral is detached:

View File

@@ -4,17 +4,23 @@ see: modem_message For raw modem messages sent outside of Rednet.
see: rednet.receive To wait for a Rednet message with an optional timeout and protocol filter.
---
The @{rednet_message} event is fired when a message is sent over Rednet.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
This event is usually handled by @{rednet.receive}, but it can also be pulled manually.
SPDX-License-Identifier: MPL-2.0
-->
@{rednet_message} events are sent by @{rednet.run} in the top-level coroutine in response to @{modem_message} events. A @{rednet_message} event is always preceded by a @{modem_message} event. They are generated inside CraftOS rather than being sent by the ComputerCraft machine.
The [`rednet_message`] event is fired when a message is sent over Rednet.
This event is usually handled by [`rednet.receive`], but it can also be pulled manually.
[`rednet_message`] events are sent by [`rednet.run`] in the top-level coroutine in response to [`modem_message`] events. A [`rednet_message`] event is always preceded by a [`modem_message`] event. They are generated inside CraftOS rather than being sent by the ComputerCraft machine.
## Return Values
1. @{string}: The event name.
2. @{number}: The ID of the sending computer.
3. @{any}: The message sent.
4. <span class="type">@{string}|@{nil}</span>: The protocol of the message, if provided.
1. [`string`]: The event name.
2. [`number`]: The ID of the sending computer.
3. [`any`]: The message sent.
4. <span class="type">[`string`]|[`nil`]</span>: The protocol of the message, if provided.
## Example
Prints a message when one is sent:

View File

@@ -2,10 +2,16 @@
module: [kind=event] redstone
---
The @{event!redstone} event is fired whenever any redstone inputs on the computer change.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`event!redstone`] event is fired whenever any redstone inputs on the computer or [relay][`redstone_relay`] change.
## Return values
1. @{string}: The event name.
1. [`string`]: The event name.
## Example
Prints a message when a redstone input changes:
@@ -15,3 +21,7 @@ while true do
print("A redstone input has changed!")
end
```
## See also
- [The `redstone` API on computers][`module!redstone`]
- [The `redstone_relay` peripheral][`redstone_relay`]

View File

@@ -3,14 +3,20 @@ module: [kind=event] speaker_audio_empty
see: speaker.playAudio To play audio using the speaker
---
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
## Return Values
1. @{string}: The event name.
2. @{string}: The name of the speaker which is available to play more audio.
1. [`string`]: The event name.
2. [`string`]: The name of the speaker which is available to play more audio.
## Example
This uses @{io.lines} to read audio data in blocks of 16KiB from "example_song.dfpwm", and then attempts to play it
using @{speaker.playAudio}. If the speaker's buffer is full, it waits for an event and tries again.
This uses [`io.lines`] to read audio data in blocks of 16KiB from "example_song.dfpwm", and then attempts to play it
using [`speaker.playAudio`]. If the speaker's buffer is full, it waits for an event and tries again.
```lua {data-peripheral=speaker}
local dfpwm = require("cc.audio.dfpwm")

View File

@@ -3,13 +3,19 @@ module: [kind=event] task_complete
see: commands.execAsync To run a command which fires a task_complete event.
---
The @{task_complete} event is fired when an asynchronous task completes. This is usually handled inside the function call that queued the task; however, functions such as @{commands.execAsync} return immediately so the user can wait for completion.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`task_complete`] event is fired when an asynchronous task completes. This is usually handled inside the function call that queued the task; however, functions such as [`commands.execAsync`] return immediately so the user can wait for completion.
## Return Values
1. @{string}: The event name.
2. @{number}: The ID of the task that completed.
3. @{boolean}: Whether the command succeeded.
4. @{string}: If the command failed, an error message explaining the failure. (This is not present if the command succeeded.)
1. [`string`]: The event name.
2. [`number`]: The ID of the task that completed.
3. [`boolean`]: Whether the command succeeded.
4. [`string`]: If the command failed, an error message explaining the failure. (This is not present if the command succeeded.)
5. <abbr title="Variable number of arguments">&hellip;</abbr>: Any parameters returned from the command.
## Example

View File

@@ -2,15 +2,21 @@
module: [kind=event] term_resize
---
The @{term_resize} event is fired when the main terminal is resized. For instance:
- When a the tab bar is shown or hidden in @{multishell}.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`term_resize`] event is fired when the main terminal is resized. For instance:
- When a the tab bar is shown or hidden in [`multishell`].
- When the terminal is redirected to a monitor via the "monitor" program and the monitor is resized.
When this event fires, some parts of the terminal may have been moved or deleted. Simple terminal programs (those
not using @{term.setCursorPos}) can ignore this event, but more complex GUI programs should redraw the entire screen.
not using [`term.setCursorPos`]) can ignore this event, but more complex GUI programs should redraw the entire screen.
## Return values
1. @{string}: The event name.
1. [`string`]: The event name.
## Example
Print a message each time the terminal is resized.

View File

@@ -2,14 +2,20 @@
module: [kind=event] terminate
---
The @{terminate} event is fired when <kbd>Ctrl-T</kbd> is held down.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
This event is normally handled by @{os.pullEvent}, and will not be returned. However, @{os.pullEventRaw} will return this event when fired.
SPDX-License-Identifier: MPL-2.0
-->
@{terminate} will be sent even when a filter is provided to @{os.pullEventRaw}. When using @{os.pullEventRaw} with a filter, make sure to check that the event is not @{terminate}.
The [`terminate`] event is fired when <kbd>Ctrl-T</kbd> is held down.
This event is normally handled by [`os.pullEvent`], and will not be returned. However, [`os.pullEventRaw`] will return this event when fired.
[`terminate`] will be sent even when a filter is provided to [`os.pullEventRaw`]. When using [`os.pullEventRaw`] with a filter, make sure to check that the event is not [`terminate`].
## Return values
1. @{string}: The event name.
1. [`string`]: The event name.
## Example
Prints a message when Ctrl-T is held:

View File

@@ -3,11 +3,17 @@ module: [kind=event] timer
see: os.startTimer To start a timer.
---
The @{timer} event is fired when a timer started with @{os.startTimer} completes.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`timer`] event is fired when a timer started with [`os.startTimer`] completes.
## Return Values
1. @{string}: The event name.
2. @{number}: The ID of the timer that finished.
1. [`string`]: The event name.
2. [`number`]: The ID of the timer that finished.
## Example
Start and wait for a timer to finish.

View File

@@ -2,10 +2,16 @@
module: [kind=event] turtle_inventory
---
The @{turtle_inventory} event is fired when a turtle's inventory is changed.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`turtle_inventory`] event is fired when a turtle's inventory is changed.
## Return values
1. @{string}: The event name.
1. [`string`]: The event name.
## Example
Prints a message when the inventory is changed:

View File

@@ -2,11 +2,26 @@
module: [kind=event] websocket_closed
---
The @{websocket_closed} event is fired when an open WebSocket connection is closed.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
The [`websocket_closed`] event is fired when an open WebSocket connection is closed.
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the WebSocket that was closed.
1. [`string`]: The event name.
2. [`string`]: The URL of the WebSocket that was closed.
3. <span class="type">[`string`]|[`nil`]</span>: The [server-provided reason][close_reason]
the websocket was closed. This will be [`nil`] if the connection was closed
abnormally.
4. <span class="type">[`number`]|[`nil`]</span>: The [connection close code][close_code],
indicating why the socket was closed. This will be [`nil`] if the connection
was closed abnormally.
[close_reason]: https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.6 "The WebSocket Connection Close Reason, RFC 6455"
[close_code]: https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.5 "The WebSocket Connection Close Code, RFC 6455"
## Example
Prints a message when a WebSocket is closed (this may take a minute):

View File

@@ -3,14 +3,20 @@ module: [kind=event] websocket_failure
see: http.websocketAsync To send an HTTP request.
---
The @{websocket_failure} event is fired when a WebSocket connection request fails.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
This event is normally handled inside @{http.websocket}, but it can still be seen when using @{http.websocketAsync}.
SPDX-License-Identifier: MPL-2.0
-->
The [`websocket_failure`] event is fired when a WebSocket connection request fails.
This event is normally handled inside [`http.websocket`], but it can still be seen when using [`http.websocketAsync`].
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the site requested.
3. @{string}: An error describing the failure.
1. [`string`]: The event name.
2. [`string`]: The URL of the site requested.
3. [`string`]: An error describing the failure.
## Example
Prints an error why the website cannot be contacted:

View File

@@ -2,15 +2,21 @@
module: [kind=event] websocket_message
---
The @{websocket_message} event is fired when a message is received on an open WebSocket connection.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
This event is normally handled by @{http.Websocket.receive}, but it can also be pulled manually.
SPDX-License-Identifier: MPL-2.0
-->
The [`websocket_message`] event is fired when a message is received on an open WebSocket connection.
This event is normally handled by [`http.Websocket.receive`], but it can also be pulled manually.
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the WebSocket.
3. @{string}: The contents of the message.
4. @{boolean}: Whether this is a binary message.
1. [`string`]: The event name.
2. [`string`]: The URL of the WebSocket.
3. [`string`]: The contents of the message.
4. [`boolean`]: Whether this is a binary message.
## Example
Prints a message sent by a WebSocket:

View File

@@ -3,14 +3,20 @@ module: [kind=event] websocket_success
see: http.websocketAsync To open a WebSocket asynchronously.
---
The @{websocket_success} event is fired when a WebSocket connection request returns successfully.
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
This event is normally handled inside @{http.websocket}, but it can still be seen when using @{http.websocketAsync}.
SPDX-License-Identifier: MPL-2.0
-->
The [`websocket_success`] event is fired when a WebSocket connection request returns successfully.
This event is normally handled inside [`http.websocket`], but it can still be seen when using [`http.websocketAsync`].
## Return Values
1. @{string}: The event name.
2. @{string}: The URL of the site.
3. @{http.Websocket}: The handle for the WebSocket.
1. [`string`]: The event name.
2. [`string`]: The URL of the site.
3. [`http.Websocket`]: The handle for the WebSocket.
## Example
Prints the content of a website (this may fail if the request fails):

View File

@@ -2,8 +2,14 @@
module: [kind=guide] gps_setup
---
<!--
SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
# Setting up GPS
The @{gps} API allows computers and turtles to find their current position using wireless modems.
The [`gps`] API allows computers and turtles to find their current position using wireless modems.
In order to use GPS, you'll need to set up multiple *GPS hosts*. These are computers running the special `gps host`
program, which tell other computers the host's position. Several hosts running together are known as a *GPS
@@ -13,22 +19,21 @@ In order to give the best results, a GPS constellation needs at least four compu
constellation is redundant, but it does not cause problems.
## Building a GPS constellation
![An example GPS constellation.](/images/gps-constellation-example.png){.big-image}
<img alt="An example GPS constellation." src="../images/gps-constellation-example.png" class="big-image" />
We are going to build our GPS constellation as shown in the image above. You will need 4 computers and either 4 wireless
modems or 4 ender modems. Try not to mix ender and wireless modems together as you might get some odd behavior when your
requesting computers are out of range.
:::tip Ender modems vs wireless modems
Ender modems have a very large range, which makes them very useful for setting up GPS hosts. If you do this then you
will likely only need one GPS constellation for the whole dimension (such as the Overworld or Nether).
If you do use wireless modems then you may find that you need multiple GPS constellations to cover your needs.
A computer needs a wireless or ender modem and to be in range of a GPS constellation that is in the same dimension as it
to use the GPS API. The reason for this is that ComputerCraft mimics real-life GPS by making use of the distance
parameter of @{modem_message|modem messages} and some maths.
:::
> [Ender modems vs wireless modems][!TIP]
> Ender modems have a very large range, which makes them very useful for setting up GPS hosts. If you do this then you
> will likely only need one GPS constellation for the whole dimension (such as the Overworld or Nether).
>
> If you do use wireless modems then you may find that you need multiple GPS constellations to cover your needs.
>
> A computer needs a wireless or ender modem and to be in range of a GPS constellation that is in the same dimension as
> it to use the GPS API. The reason for this is that ComputerCraft mimics real-life GPS by making use of the distance
> parameter of [modem messages][`modem_message`] and some maths.
Locate where you want to place your GPS constellation. You will need an area at least 6 blocks high, 6 blocks wide, and
6 blocks deep (6x6x6). If you are using wireless modems then you may want to build your constellation as high as you can
@@ -73,18 +78,16 @@ To hide Minecraft's debug screen, press <kbd>F3</kbd> again.
Create similar startup files for the other computers in your constellation, making sure to input the each computer's own
coordinates.
:::caution Modem messages come from the computer's position, not the modem's
Wireless modems transmit from the block that they are attached to *not* the block space that they occupy, the
coordinates that you input into your GPS host should be the position of the computer and not the position of the modem.
:::
> [Modem messages come from the computer's position, not the modem's][!WARNING]
> Wireless modems transmit from the block that they are attached to *not* the block space that they occupy, the
> coordinates that you input into your GPS host should be the position of the computer and not the position of the modem.
Congratulations, your constellation is now fully set up! You can test it by placing another computer close by, placing a
wireless modem on it, and running the `gps locate` program (or calling the @{gps.locate} function).
wireless modem on it, and running the `gps locate` program (or calling the [`gps.locate`] function).
:::info Why use Minecraft's coordinates?
CC doesn't care if you use Minecraft's coordinate system, so long as all of the GPS hosts with overlapping ranges use
the same reference point (requesting computers will get confused if hosts have different reference points). However,
using MC's coordinate system does provide a nice standard to adopt server-wide. It also is consistent with how command
computers get their location, they use MC's command system to get their block which returns that in MC's coordinate
system.
:::
> [Why use Minecraft's coordinates?][!INFO]
> CC doesn't care if you use Minecraft's coordinate system, so long as all of the GPS hosts with overlapping ranges use
> the same reference point (requesting computers will get confused if hosts have different reference points). However,
> using MC's coordinate system does provide a nice standard to adopt server-wide. It also is consistent with how command
> computers get their location, they use MC's command system to get their block which returns that in MC's coordinate
> system.

View File

@@ -2,6 +2,12 @@
module: [kind=guide] local_ips
---
<!--
SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
# Allowing access to local IPs
By default, ComputerCraft blocks access to local IP addresses for security. This means you can't normally access any
HTTP server running on your computer. However, this may be useful for testing programs without having a remote

View File

@@ -4,8 +4,14 @@ see: speaker.playAudio Play PCM audio using a speaker.
see: cc.audio.dfpwm Provides utilities for encoding and decoding DFPWM files.
---
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
# Playing audio with speakers
CC: Tweaked's speaker peripheral provides a powerful way to play any audio you like with the @{speaker.playAudio}
CC: Tweaked's speaker peripheral provides a powerful way to play any audio you like with the [`speaker.playAudio`]
method. However, for people unfamiliar with digital audio, it's not the most intuitive thing to use. This guide provides
an introduction to digital audio, demonstrates how to play music with CC: Tweaked's speakers, and then briefly discusses
the more complex topic of audio processing.
@@ -54,7 +60,7 @@ sine waves (and why wouldn't you?), you'd need a table with almost 3 _million_.
up very quickly, and these tables take up more and more memory.
Instead of building our entire song (well, sine wave) in one go, we can produce it in small batches, each of which get
passed off to @{speaker.playAudio} when the time is right. This allows us to build a _stream_ of audio, where we read
passed off to [`speaker.playAudio`] when the time is right. This allows us to build a _stream_ of audio, where we read
chunks of audio one at a time (either from a file or a tone generator like above), do some optional processing to each
one, and then play them.
@@ -78,15 +84,15 @@ end
```
It looks pretty similar to before, aside from we've wrapped the generation and playing code in a while loop, and added a
rather odd loop with @{speaker.playAudio} and @{os.pullEvent}.
rather odd loop with [`speaker.playAudio`] and [`os.pullEvent`].
Let's talk about this loop, why do we need to keep calling @{speaker.playAudio}? Remember that what we're trying to do
Let's talk about this loop, why do we need to keep calling [`speaker.playAudio`]? Remember that what we're trying to do
here is avoid keeping too much audio in memory at once. However, if we're generating audio quicker than the speakers can
play it, we're not helping at all - all this audio is still hanging around waiting to be played!
In order to avoid this, the speaker rejects any new chunks of audio if its backlog is too large. When this happens,
@{speaker.playAudio} returns false. Once enough audio has played, and the backlog has been reduced, a
@{speaker_audio_empty} event is queued, and we can try to play our chunk once more.
[`speaker.playAudio`] returns false. Once enough audio has played, and the backlog has been reduced, a
[`speaker_audio_empty`] event is queued, and we can try to play our chunk once more.
## Storing audio
PCM is a fantastic way of representing audio when we want to manipulate it, but it's not very efficient when we want to
@@ -100,7 +106,7 @@ computer. Instead, we need something much simpler.
DFPWM (Dynamic Filter Pulse Width Modulation) is the de facto standard audio format of the ComputerCraft (and
OpenComputers) world. Originally popularised by the addon mod [Computronics], CC:T now has built-in support for it with
the @{cc.audio.dfpwm} module. This allows you to read DFPWM files from disk, decode them to PCM, and then play them
the [`cc.audio.dfpwm`] module. This allows you to read DFPWM files from disk, decode them to PCM, and then play them
using the speaker.
Let's dive in with an example, and we'll explain things afterwards:
@@ -119,16 +125,16 @@ for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
end
```
Once again, we see the @{speaker.playAudio}/@{speaker_audio_empty} loop. However, the rest of the program is a little
Once again, we see the [`speaker.playAudio`]/[`speaker_audio_empty`] loop. However, the rest of the program is a little
different.
First, we require the dfpwm module and call @{cc.audio.dfpwm.make_decoder} to construct a new decoder. This decoder
First, we require the dfpwm module and call [`cc.audio.dfpwm.make_decoder`] to construct a new decoder. This decoder
accepts blocks of DFPWM data and converts it to a list of 8-bit amplitudes, which we can then play with our speaker.
As mentioned above, @{speaker.playAudio} accepts at most 128×1024 samples in one go. DFPMW uses a single bit for each
As mentioned above, [`speaker.playAudio`] accepts at most 128×1024 samples in one go. DFPWM uses a single bit for each
sample, which means we want to process our audio in chunks of 16×1024 bytes (16KiB). In order to do this, we use
@{io.lines}, which provides a nice way to loop over chunks of a file. You can of course just use @{fs.open} and
@{fs.BinaryReadHandle.read} if you prefer.
[`io.lines`], which provides a nice way to loop over chunks of a file. You can of course just use [`fs.open`] and
[`fs.ReadHandle.read`] if you prefer.
## Processing audio
As mentioned near the beginning of this guide, PCM audio is pretty easy to work with as it's just a list of amplitudes.
@@ -183,10 +189,9 @@ for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
end
```
:::note Confused?
Don't worry if you don't understand this example. It's quite advanced, and does use some ideas that this guide doesn't
cover. That said, don't be afraid to ask on [GitHub Discussions] or [IRC] either!
:::
> [Confused?][!NOTE]
> Don't worry if you don't understand this example. It's quite advanced, and does use some ideas that this guide doesn't
> cover. That said, don't be afraid to ask [the community for help][community].
It's worth noting that the examples of audio processing we've mentioned here are about manipulating the _amplitude_ of
the wave. If you wanted to modify the _frequency_ (for instance, shifting the pitch), things get rather more complex.
@@ -200,5 +205,4 @@ This is, I'm afraid, left as an exercise to the reader.
[PCM]: https://en.wikipedia.org/wiki/Pulse-code_modulation "Pulse-code Modulation - Wikipedia"
[Ring Buffer]: https://en.wikipedia.org/wiki/Circular_buffer "Circular buffer - Wikipedia"
[Sine Wave]: https://en.wikipedia.org/wiki/Sine_wave "Sine wave - Wikipedia"
[GitHub Discussions]: https://github.com/cc-tweaked/CC-Tweaked/discussions
[IRC]: https://webchat.esper.net/?channels=computercraft "#computercraft on EsperNet"
[Community]: /#community

View File

@@ -2,12 +2,18 @@
module: [kind=guide] using_require
---
<!--
SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
# Reusing code with require
A library is a collection of useful functions and other definitions which is stored separately to your main program. You
might want to create a library because you have some functions which are used in multiple programs, or just to split
your program into multiple more modular files.
Let's say we want to create a small library to make working with the @{term|terminal} a little easier. We'll provide two
Let's say we want to create a small library to make working with the [terminal][`term`] a little easier. We'll provide two
functions: `reset`, which clears the terminal and sets the cursor to (1, 1), and `write_center`, which prints some text
in the middle of the screen.
@@ -42,32 +48,32 @@ more_term.write_center("Hello, world!")
When run, this'll clear the screen and print some text in the middle of the first line.
## require in depth
While the previous section is a good introduction to how @{require} operates, there are a couple of remaining points
While the previous section is a good introduction to how [`require`] operates, there are a couple of remaining points
which are worth mentioning for more advanced usage.
### Libraries can return anything
In our above example, we return a table containing the functions we want to expose. However, it's worth pointing out
that you can return ''anything'' from your library - a table, a function or even just a string! @{require} treats them
that you can return ''anything'' from your library - a table, a function or even just a string! [`require`] treats them
all the same, and just returns whatever your library provides.
### Module resolution and the package path
In the above examples, we defined our library in a file, and @{require} read from it. While this is what you'll do most
of the time, it is possible to make @{require} look elsewhere for your library, such as downloading from a website or
In the above examples, we defined our library in a file, and [`require`] read from it. While this is what you'll do most
of the time, it is possible to make [`require`] look elsewhere for your library, such as downloading from a website or
loading from an in-memory library store.
As a result, the *module name* you pass to @{require} doesn't correspond to a file path. One common mistake is to load
As a result, the *module name* you pass to [`require`] doesn't correspond to a file path. One common mistake is to load
code from a sub-directory using `require("folder/library")` or even `require("folder/library.lua")`, neither of which
will do quite what you expect.
When loading libraries (also referred to as *modules*) from files, @{require} searches along the *@{package.path|module
path}*. By default, this looks something like:
When loading libraries (also referred to as *modules*) from files, [`require`] searches along the [*module
path*][`package.path`]. By default, this looks something like:
* `?.lua`
* `?/init.lua`
* `/rom/modules/main/?.lua`
* etc...
When you call `require("my_library")`, @{require} replaces the `?` in each element of the path with your module name, and
When you call `require("my_library")`, [`require`] replaces the `?` in each element of the path with your module name, and
checks if the file exists. In this case, we'd look for `my_library.lua`, `my_library/init.lua`,
`/rom/modules/main/my_library.lua` and so on. Note that this works *relative to the current program*, so if your
program is actually called `folder/program`, then we'll look for `folder/my_library.lua`, etc...
@@ -80,4 +86,4 @@ before we start looking for the library.
There are several external resources which go into require in a little more detail:
- The [Lua Module tutorial](http://lua-users.org/wiki/ModulesTutorial) on the Lua wiki.
- [Lua's manual section on @{require}](https://www.lua.org/manual/5.1/manual.html#pdf-require).
- [Lua's manual section on `require`](https://www.lua.org/manual/5.1/manual.html#pdf-require).

View File

@@ -1 +1,7 @@
<!--
SPDX-FileCopyrightText: 2020 The CC: Tweaked Developers
SPDX-License-Identifier: MPL-2.0
-->
<meta name="theme-color" content="#c8d87c">

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

View File

@@ -1,21 +1,34 @@
# ![CC: Tweaked](logo.png)
CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles and more to the game. A fork of the
much-beloved [ComputerCraft], it continues its legacy with better performance, stability, and a wealth of new features.
<!--
SPDX-FileCopyrightText: 2020 The CC: Tweaked Developers
CC: Tweaked can be installed from [CurseForge] or [Modrinth]. It requires the [Minecraft Forge][forge] mod loader, but
[versions are available for Fabric][ccrestitched].
SPDX-License-Identifier: MPL-2.0
-->
<h1>
<picture>
<source media="(prefers-color-scheme: dark)" srcset="logo-darkmode.png">
<source media="(prefers-color-scheme: light)" srcset="logo.png">
<img alt="CC: Tweaked" src="logo.png">
</picture>
</h1>
CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles and more to the game. A fork of the
much-beloved [ComputerCraft], it continues its legacy with improved performance and stability, along with a wealth of
new features.
CC: Tweaked can be installed from [Modrinth]. It runs on both [Minecraft Forge] and [Fabric].
## Features
Controlled using the [Lua programming language][lua], CC: Tweaked's computers provides all the tools you need to start
writing code and automating your Minecraft world.
![A ComputerCraft terminal open and ready to be programmed.](images/basic-terminal.png){.big-image}
<img alt="A ComputerCraft terminal open and ready to be programmed." src="images/basic-terminal.png" class="big-image" />
While computers are incredibly powerful, they're rather limited by their inability to move about. *Turtles* are the
solution here. They can move about the world, placing and breaking blocks, swinging a sword to protect you from zombies,
or whatever else you program them to!
![A turtle tunneling in Minecraft.](images/turtle.png){.big-image}
<img alt="A turtle tunneling in Minecraft." src="images/turtle.png" class="big-image" />
Not all problems can be solved with a pickaxe though, and so CC: Tweaked also provides a bunch of additional peripherals
for your computers. You can play a tune with speakers, display text or images on a monitor, connect all your
@@ -24,7 +37,7 @@ computers together with modems, and much more.
Computers can now also interact with inventories such as chests, allowing you to build complex inventory and item
management systems.
![A chest's contents being read by a computer and displayed on a monitor.](images/peripherals.png){.big-image}
<img alt="A chest's contents being read by a computer and displayed on a monitor." src="images/peripherals.png" class="big-image" />
## Getting Started
While ComputerCraft is lovely for both experienced programmers and for people who have never coded before, it can be a
@@ -32,12 +45,16 @@ little daunting getting started. Thankfully, there's several fantastic tutorials
- [Direwolf20's ComputerCraft tutorials](https://www.youtube.com/watch?v=wrUHUhfCY5A "ComputerCraft Tutorial Episode 1 - HELP! and Hello World")
- [Sethbling's ComputerCraft series](https://www.youtube.com/watch?v=DSsx4VSe-Uk "Programming Tutorial with Minecraft Turtles -- Ep. 1: Intro to Turtles and If-Then-Else_End")
- [Lyqyd's Computer Basics 1](http://www.computercraft.info/forums2/index.php?/topic/15033-computer-basics-i/ "Computer Basics I")
- [Lyqyd's Computer Basics 1](https://ccf.squiddev.cc/forums2/index.php?/topic/15033-computer-basics-i/ "Computer Basics I")
Once you're a little more familiar with the mod, the sidebar and links below provide more detailed documentation on the
various APIs and peripherals provided by the mod.
If you get stuck, do [ask a question on GitHub][GitHub Discussions] or pop in to the ComputerCraft's [IRC channel][IRC].
<h2 id="community">Community</h2>
If you need help getting started with CC: Tweaked, want to show off your latest project, or just want to chat about
ComputerCraft, do check out our [GitHub discussions page][GitHub discussions]! There's also a fairly populated,
albeit quiet IRC channel on [EsperNet], if that's more your cup of tea. You can join `#computercraft` through your
desktop client, or online using [KiwiIRC].
## Get Involved
CC: Tweaked lives on [GitHub]. If you've got any ideas, feedback or bugs please do [create an issue][bug].
@@ -45,10 +62,11 @@ CC: Tweaked lives on [GitHub]. If you've got any ideas, feedback or bugs please
[github]: https://github.com/cc-tweaked/CC-Tweaked/ "CC: Tweaked on GitHub"
[bug]: https://github.com/cc-tweaked/CC-Tweaked/issues/new/choose
[computercraft]: https://github.com/dan200/ComputerCraft "ComputerCraft on GitHub"
[curseforge]: https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked from CurseForge"
[modrinth]: https://modrinth.com/mod/gu7yAYhd "Download CC: Tweaked from Modrinth"
[forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
[ccrestitched]: https://www.curseforge.com/minecraft/mc-mods/cc-restitched "Download CC: Restitched from CurseForge"
[Minecraft Forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
[Fabric]: https://fabricmc.net/use/installer/ "Download Fabric."
[lua]: https://www.lua.org/ "Lua's main website"
[GitHub Discussions]: https://github.com/cc-tweaked/CC-Tweaked/discussions
[IRC]: https://webchat.esper.net/?channels=computercraft "#computercraft on EsperNet"
[EsperNet]: https://www.esper.net/
[KiwiIRC]: https://kiwiirc.com/nextclient/#irc://irc.esper.net:+6697/#computercraft "#computercraft on EsperNet"

BIN
doc/logo-darkmode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,7 +1,11 @@
# ![CC: Tweaked](https://tweaked.cc/logo.png)
CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles and more to the game. A fork of the much-beloved [ComputerCraft], it continues its legacy with better performance, stability, and a wealth of new features.
<!--
SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
**Fabric support is added by the [CC: Restitched][ccrestitched] project**
SPDX-License-Identifier: MPL-2.0
-->
# ![CC: Tweaked](https://tweaked.cc/logo.png)
CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles and more to the game. A fork of the much-beloved [ComputerCraft], it continues its legacy with improved performance and stability, along with a wealth of new features.
## Testimonials
@@ -18,13 +22,13 @@ CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles an
Controlled using the [Lua programming language][lua], CC: Tweaked's computers provides all the tools you need to start
writing code and automating your Minecraft world.
![A ComputerCraft terminal open and ready to be programmed.](https://tweaked.cc/images/basic-terminal.png)
![A ComputerCraft terminal open and ready to be programmed.](https://raw.githubusercontent.com/cc-tweaked/CC-Tweaked/HEAD/doc/images/basic-terminal.png)
While computers are incredibly powerful, they're rather limited by their inability to move about. *Turtles* are the
solution here. They can move about the world, placing and breaking blocks, swinging a sword to protect you from zombies,
or whatever else you program them to!
![A turtle tunneling in Minecraft.](https://tweaked.cc/images/turtle.png)
![A turtle tunneling in Minecraft.](https://raw.githubusercontent.com/cc-tweaked/CC-Tweaked/HEAD/doc/images/turtle.png)
Not all problems can be solved with a pickaxe though, and so CC: Tweaked also provides a bunch of additional peripherals
for your computers. You can play a tune with speakers, display text or images on a monitor, connect all your
@@ -33,7 +37,7 @@ computers together with modems, and much more.
Computers can now also interact with inventories such as chests, allowing you to build complex inventory and item
management systems.
![A chest's contents being read by a computer and displayed on a monitor.](https://tweaked.cc/images/peripherals.png)
![A chest's contents being read by a computer and displayed on a monitor.](https://raw.githubusercontent.com/cc-tweaked/CC-Tweaked/HEAD/doc/images/peripherals.png)
## Getting Started
While ComputerCraft is lovely for both experienced programmers and for people who have never coded before, it can be a
@@ -41,12 +45,16 @@ little daunting getting started. Thankfully, there's several fantastic tutorials
- [Direwolf20's ComputerCraft tutorials](https://www.youtube.com/watch?v=wrUHUhfCY5A "ComputerCraft Tutorial Episode 1 - HELP! and Hello World")
- [Sethbling's ComputerCraft series](https://www.youtube.com/watch?v=DSsx4VSe-Uk "Programming Tutorial with Minecraft Turtles -- Ep. 1: Intro to Turtles and If-Then-Else_End")
- [Lyqyd's Computer Basics 1](http://www.computercraft.info/forums2/index.php?/topic/15033-computer-basics-i/ "Computer Basics I")
- [Lyqyd's Computer Basics 1](https://ccf.squiddev.cc/forums2/index.php?/topic/15033-computer-basics-i/ "Computer Basics I")
Once you're a little more familiar with the mod, the [wiki](https://tweaked.cc/) provides more detailed documentation on the
various APIs and peripherals provided by the mod.
If you get stuck, do [ask a question on GitHub][GitHub Discussions] or pop in to the ComputerCraft's [IRC channel][IRC].
## Community
If you need help getting started with CC: Tweaked, want to show off your latest project, or just want to chat about
ComputerCraft, do check out our [GitHub discussions page][GitHub discussions]! There's also a fairly populated,
albeit quiet IRC channel on [EsperNet], if that's more your cup of tea. You can join `#computercraft` through your
desktop client, or online using [KiwiIRC].
## Get Involved
CC: Tweaked lives on [GitHub]. If you've got any ideas, feedback or bugs please do [create an issue][bug].
@@ -54,8 +62,7 @@ CC: Tweaked lives on [GitHub]. If you've got any ideas, feedback or bugs please
[github]: https://github.com/cc-tweaked/CC-Tweaked/ "CC: Tweaked on GitHub"
[bug]: https://github.com/cc-tweaked/CC-Tweaked/issues/new/choose
[computercraft]: https://github.com/dan200/ComputerCraft "ComputerCraft on GitHub"
[forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
[ccrestitched]: https://modrinth.com/mod/cc-restitched "Download CC: Restitched from Modrinth"
[lua]: https://www.lua.org/ "Lua's main website"
[GitHub Discussions]: https://github.com/cc-tweaked/CC-Tweaked/discussions
[IRC]: http://webchat.esper.net/?channels=computercraft "#computercraft on EsperNet"
[EsperNet]: https://www.esper.net/
[KiwiIRC]: https://kiwiirc.com/nextclient/#irc://irc.esper.net:+6697/#computercraft "#computercraft on EsperNet"

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