1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-09-20 19:29:44 +00:00

Compare commits

...

1017 Commits

Author SHA1 Message Date
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
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
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
Jonathan Coates
6a116aadb8
Bump CC:T to 1.103.1
Woops!

 - Fix the REPL not printing values, as exception.try didn't return
   values. It did originally, and then I tried to simplify it >_>

 - Change repl_exprs to run an expression and program parser in
   parallel, rather than handling the parallelism on the grammar side -
   that has a few shift/reduce conflicts which result in bad parse
   errors.
2023-02-09 21:45:20 +00:00
Jonathan Coates
9e6e0c8b88
Bump CC:T to 1.103.0 2023-02-09 21:02:09 +00:00
Jonathan Coates
5502412181
Improve display of runtime errors (#1320)
- Bump Cobalt to 0.6.0. We now track both line and column numbers of
   each bytecode instruction, allowing us to map an error to a concrete
   position.

 - `loadfile` (and similar functions) now use the full path, rather than
   the file name. Cobalt truncates this to 30 characters (rather than
   the previous 60) so this should be less noisy.

 - The shell, edit and Lua REPL now display the corresponding source
   code alongside an error.

   Note this is incredibly limited right now - it won't cope with errors
   which cross coroutine boundaries. Supporting this is on the roadmap,
   but requires some careful API design.
2023-02-09 20:53:50 +00:00
Jonathan Coates
62e3c5f9aa
Queue key presses for a short period after pressing a computer shortcut
Fixes #1326
2023-02-09 20:10:20 +00:00
Jonathan Coates
7e54a40fa9
Add a couple of missing version annotations 2023-02-09 20:09:57 +00:00
Jonathan Coates
8ac42566ec
Be a little more robust in turtle item rendering
See #1328. Also some holiday cleanup, because my commit discipline is
terrible.
2023-02-09 20:07:55 +00:00
Jonathan Coates
66b20d2bdb
Don't dye/undye turtles when right clicked
While it's a nice immersive interaction, it's far too easy to trigger by
accident. Dying/undying can now only be done via crafting and the
cauldron.

Closes #1321
2023-02-08 20:14:07 +00:00
Jonathan Coates
81dad421d5
Allow undying items using a sponge
It's much less aggressive than dunking it in a cauldron, so won't damage
any of your precious electronics.

I had this idea back in 2017 (dan200/ComputerCraft#230). Can't believe
it took me almost 6 years to implement.
2023-02-08 20:13:58 +00:00
Jonathan Coates
3075d3cea8
Fxi teh spolling of handshakder 2023-02-07 20:59:45 +00:00
Jonathan Coates
cdab8f429e
Clarify Minecraft' shift+right click behaviour
Closes #1323
2023-02-07 08:45:17 +00:00
Jonathan Coates
2e5cd29e12
Use tags to what items turtle.place() can .use()
In older versions we just used a hard-coded list of items and
superclasses. This was somewhat ugly, and so in 1.19.3 I tried to make
this code more generic.

However, this has a lot of unintended consequences - for instance
turtles can now throw ender pearls, which is definitely not intended!

By using a tag, we can emulate the old behaviour, while still allowing
modders and pack devs to add additional items if needed.
2023-02-04 18:14:18 +00:00
Jonathan Coates
22cadd6730
Various improvements to our Lua parser
- Encode the DFA as a virtual machine (identical to lrgrep) rather than
   compiling it to a series of Lua functions. While this is a little
   slower and uglier, it's much more space efficient, shaving off 16Kb.

 - Minimise the DFA properly. This only shaves off a few states, but
   every little helps.

 - Run the error handling code from a non-reduced parser stack. This was
   incredibly nasty to get right (and positions are still not correctly
   handled), but it fixes several broken error messages.
2023-02-04 12:46:51 +00:00
Jonathan Coates
366052ec48
Merge pull request #1316 from LelouBil/patch-1
Fix word error in rednet documentation
2023-02-03 19:39:13 +00:00
Jonathan Coates
3224e0bf8b
Fix a few typos in the documentation
- Move modem recipes out of the usage section.
 - Add missing argument names to BinaryWriableHandle.write. Illuaminate
   really should catch this, but for now I did a grep and couldn't find
   any more instances of this.
2023-02-03 19:29:16 +00:00
Weblate
fb4b097a66 Translations for Toki Pona
Co-authored-by: wackbyte <wackbyte@protonmail.com>
2023-02-03 04:55:48 +00:00
Bilel MEDIMEGH
67f3d91850
Fix word error in rednet documentation
Replaced "The name this protocol exposes for the given protocol" into "The name this **computer** exposes for the given protocol"
2023-01-30 18:19:06 +01:00
Jonathan Coates
1e3a930543
Copy pocket upgrades items before dropping them
We were modifying the stack, meaning the crafting item would end up
empty!
2023-01-26 22:40:03 +00:00
Jonathan Coates
b21e2f4e63
Update Cobalt to fix yielding inside __len
Closes #1307
2023-01-26 09:43:10 +00:00
Jonathan Coates
a12b405acf
Custom parse errors for Lua (#1298)
- Add several (internal) modules for lexing and parsing Lua code. These
   allow us to provide (hopefully) higher quality error messages than
   Lua's built-in messages.

 - `shell.run`, `edit` and `lua` now use this parser when fed invalid
   code. This allows us to provide better syntax errors, while not
   having any impact on the happy path.

   Note this does not affect any other mechanism for loading code 
   (`load`, `require`, `dofile`).

There's still a lot of work to do here in improving error message
quality, but hopefully this provides a good starting point.
2023-01-25 20:35:43 +00:00
Jonathan Coates
e076818b29
Bump Cobalt for even more verbose VM logging
See #1307
2023-01-25 18:47:27 +00:00
Jonathan Coates
1554c7b397
Always expose nbt from turtle.getItemDetail
- Document the thread safety of DetailRegistry a little better.

 - Turtles now duplicate their inventory to the "previous
   inventory" (now called inventorySnapshot) immediately, rather than
   when the block is ticked.

   This is slightly more resource intensive, but I don't think it's so
   bad we need to worry.

 - As this snapshot is now always up-to-date, we can read it from the
   computer thread. Given the item is immutable, it's safe to read NBT
   from it.

   _Technically_ this is not safe under the Java memory model, but in
   practice I don't think we'll observe the wrong value.

Closes #1306
2023-01-25 18:37:14 +00:00
Jonathan Coates
6cd32a6368
Fix a few typos
Just ran[^1] over the codebase. Turns out we'd duplicated one of the
changelog entries entirely - I suspect due to a version merge gone
wrong!

[^1]: https://github.com/crate-ci/typos/
2023-01-24 18:47:29 +00:00
Jonathan Coates
7335a892b5
Expose test methods to required libraries
This allows us to use stub everywhere, rather than having to pass it
around as an argument.
2023-01-24 18:27:30 +00:00
Weblate
83eddc6636 Translations for Toki Pona
Translations for Italian

Co-authored-by: Alessandro <ale.proto00@gmail.com>
Co-authored-by: wackbyte <wackbyte@protonmail.com>
2023-01-24 05:55:48 +00:00
Jonathan Coates
d066d175bf
Attach a speaker peripheral inside its docs
This required a version bump to cct-javadoc to allow using attributes
inside <pre> blocks.
2023-01-22 12:24:36 +00:00
Jonathan Coates
9873ccfa0d
Send the original rednet message to the current computer
We were incorrectly enquing the modem payload, not the underlying rednet
message.

Closes #1308.
2023-01-21 08:23:00 +00:00
Weblate
da7a50368d Added translation for Toki Pona
Co-authored-by: wackbyte <wackbyte@protonmail.com>
2023-01-18 14:59:35 +00:00
Jonathan Coates
8cfbfe7ceb
Make errors messages in edit more obvious
See #1222.
2023-01-17 21:43:26 +00:00
ouroborus
67244b17af
Update event docs (#1304) 2023-01-17 21:17:47 +00:00
Jonathan Coates
9e1de23f4a
Log internal Cobalt VM errors
See #1307
2023-01-17 20:37:16 +00:00
Jonathan Coates
86b60855d6
Enforce version bounds for the Kotlin stdlib
We were pulling in an ancient version of the jdk8 stdlib via
kotlinx.coroutines, hence the conflict in versions.
2023-01-17 20:28:31 +00:00
Jonathan Coates
db6b6fd173
Bump Kotlin version to 1.8 2023-01-17 19:33:49 +00:00
Jonathan Coates
2014e9527e
Some event typo fixes 2023-01-16 22:53:58 +00:00
Emma
f43b839056
Add support for shebangs (#1273) 2023-01-14 22:12:04 +00:00
Jonathan Coates
f561572509
Bump CC:T to 1.102.2 2023-01-14 20:07:01 +00:00
Jonathan Coates
edb21f33be
Mount drives on the main thread
When the peripheral is attached, we add the computer to the map and
queue the actual disk to be mounted next tick. This avoids the
thread-safety issues with mutating the item (and creating disk ids) that
might be caused by doing it on the computer thread.

The mount is now also managed separately to the MediaStack, as that was
meant to be an immutable snapshot of the item!

Fixes #1282
2023-01-14 17:51:49 +00:00
Jonathan Coates
02b68b259e
Correctly track coverage for startup.lua too 2023-01-12 22:26:39 +00:00
Jonathan Coates
28a55349a9
Move coverage to the Java side
While slightly irritating (requires Cobalt magic), it's much, much
faster.
2023-01-12 21:02:33 +00:00
Jonathan Coates
2457a31728
Fix printouts crashing in item frames 2023-01-09 18:28:44 +00:00
Jonathan Coates
cdc91a8e5d
Fix stack overflow in logging code 2023-01-08 18:29:36 +00:00
Jonathan Coates
8024017f53
Bump CC:T to 1.102.1
There's still some remaining bugs (#1282), but I think worth getting the
fixes for the worst issues out first.
2023-01-08 18:21:10 +00:00
Jonathan Coates
592ff84aea
Read computer threads directly from the config object (#1295)
This gives us slightly better guarantees that the config has actually
been loaded. This, along with a FCAP bump, fixes this config option
not doing anything on Fabric.
2023-01-07 22:16:06 +00:00
Jonathan Coates
4360458416
Attempt to reduce test flakiness
I'm really not sure why the modem one fails. I can't reproduce outside
of CI, so quite hard to debug :/.
2023-01-07 15:05:21 +00:00
Jonathan Coates
717e096b94
Include the licences of our dependencies in the credits
I feel like we should have been doing this from the beginning. Love to
uncompliant for 11 years :/.
2023-01-06 09:34:07 +00:00
Jonathan Coates
34a31abd9c
Move our internal module into the main package path
I originally put cc.import in a separate directory from the main
modules. This means that programs must extend the package path in order
to import these modules.

However, this ends up being a mixed blessing: while it makes it much
harder for users to accidentally require user code, it also means we
can't expose a public interface which wraps a private module.

Instead, cc.import now lives on the main package path, but lives under
the cc.internal namespace and is not documented anywhere. Hopefully this
should be enough of a clue that one shouldn't use it :p.
2023-01-05 21:55:08 +00:00
Jonathan Coates
bdecb88cca
Support resource conditions in upgrade JSON 2023-01-02 15:56:01 +00:00
Weblate
af15030fa4 Translations for Italian
Co-authored-by: Trenord <luca.ilari@gmail.com>
2023-01-01 20:55:45 +00:00
Jonathan Coates
3a883db49e
Test that wired modems form networks
See #1278
2023-01-01 17:57:53 +00:00
Jonathan Coates
8ea5b64f64
Improve our CI artifacts
- Publish Forge and Fabric
 - Include version hash in the download
2023-01-01 15:04:25 +00:00
Jonathan Coates
7b6caf76e4
Increase the distance from which we drop items
I was having issues where dropped items would clip into blocks when
dropped, and then phase upwards through the turtle instead. This makes
things a little more consistent with dispenser behaviour.
2023-01-01 14:51:47 +00:00
Jonathan Coates
230c7ee904
Clamp speaker volume again
Looks like this was removed in b048b6666d.
2023-01-01 08:51:07 +00:00
Jonathan Coates
aa203802c6
Fix search tab showing up in itemGroups 2022-12-31 16:24:19 +00:00
Jonathan Coates
1259e29f21
Fix full-block wired modems not connecting
Closes #1278.
2022-12-29 22:30:09 +00:00
Jonathan Coates
77f62dac94
Fix mouse_up not being fired on Fabric 2022-12-29 22:16:36 +00:00
Jonathan Coates
7f34aff6bb
Correctly handle double chests on Fabric
Closes #1279. The perils of ignoring the transfer API :(.
2022-12-29 21:48:59 +00:00
Jonathan Coates
3047e3cdf4
Simplify cable/modem block breaking code
Instead of taking control of the breaking logic in all cases, we now
only do so when we have both a cable and modem. This allows us to fall
back to default vanilla behaviour and so correctly drop the modem/cable
item.
2022-12-29 12:21:10 +00:00
Emma
7a83a403f0
Fix OOB when item insertion wraps around (#1277)
Co-authored-by: Jonathan Coates <git@squiddev.cc>
2022-12-29 11:26:25 +00:00
Jonathan Coates
a1d5c76d00
Test for moving into a rotated container
Similar to the test in #1277. The duplication here is a little
irritating, but don't think we can avoid that.
2022-12-29 11:11:26 +00:00
Emma
bcdfa7c5ff
Fix bug where turtle drops inventory when moving (#1276) 2022-12-29 09:02:02 +00:00
Jonathan Coates
2c59b9122b
Set location when creating a pocket modem
We now call getLevel() when attaching the peripheral, so need the
position to be available immediately. Fixes #1274.

I /think/ the entity should always be present, as peripherals are
only created on startup or when calling pocket.equipBack, both of which
require a player.[^1]

I suspect this was a little broken before (the level wouldn't be
available if a modem received a message before the position had
been set), but that would be much rarer.

I'm not 100% convinced about the thread-safety of this code (the writes
to level may not be immediately visible on other threads), so may need
to think about that.

[^1]: Note that when peripherals come to be /attached/ they may no
longer have a player (as there's a gap between turning a computer on and
it actually starting). However, the level/position will have been
initialised by then, so this isn't a problem.
2022-12-29 08:52:28 +00:00
Emma
d2c7b944ab
Fix crash on Fabric when attempting to use a non-fuel item as fuel. (#1275)
Co-authored-by: Jonathan Coates <git@squiddev.cc>
2022-12-29 08:22:09 +00:00
Jonathan Coates
e241575329
Prepare for 1.102.0
This is a stupid tradition.
2022-12-24 10:51:54 +00:00
Jonathan Coates
86c4c7483d
Bump Cobalt and ForgeConfigAPI versions
Fixes #1248, fixes #1249
2022-12-21 15:58:51 +00:00
Jonathan Coates
9010219b9c
Merge pull request #1262 from emmachase/mc-1.19.x
Fix duplicated swing animations on high-ping servers
2022-12-20 10:26:54 +00:00
emmachase
172d1824fc Fix duplicated swing animations on high-ping servers
Use `InteractionResult.sidedSuccess` / `.CONSUME` where applicable instead of `.SUCCESS`. This prevents the server from sending an additional swing animation packet to the client. Normally this isn't a problem, since the client will de-duplicate swing packets if they are within the animation duration of the currently playing swing; however, when connected to a server with a high ping the packet is sent after the animation is already finished on the client, resulting in a duplicate animation.
2022-12-19 19:53:41 -08:00
Jonathan Coates
9d394f44d3
Merge pull request #1255 from toad-dev/patch/illuaminate-support-arm-macs
Deliver x86_64 Illuaminate binaries to all Macs
2022-12-18 00:00:22 +00:00
David Queneau
6e5b7243f4 Deliver x86_64 Illuaminate binaries to all Macs
The Intel native binaries run just fine on Apple-silicon Macs through
Rosetta.
2022-12-17 14:57:30 -08:00
Jonathan Coates
27b732f835
Make the turtle label move with the turtle
We now perform movement translations before rendering the label, rather
than afterwards. This means the label moves smoothly(ish), rather than
jumping from block to block.
2022-12-15 22:25:14 +00:00
Jonathan Coates
4fa7f50534
Time fs and peripheral operations 2022-12-15 22:12:53 +00:00
Jonathan Coates
eeac86b07c
Satiate the demons of checkstyle
I was sure I'd run pre-commit, but clearly not!
2022-12-15 21:42:18 +00:00
Jonathan Coates
36ce490566
Use RenderSystem for setting polygon offsets 2022-12-15 21:24:38 +00:00
Jonathan Coates
e7fe22d4f8
Don't round trip values in executeMainThreadTask
I've been meaning to fix this for over 6 years, and just kept
forgetting.

Previously ILuaContext.executeMainThreadTask worked by running
ILuaContext.issueMainThreadTask, pulling task_complete events, and then
returning the results.

While this makes the implementation simple, it means that the task's
results were converted into Lua values (in order to queue the event) and
then back into Java ones (when the event was pulled), before eventually
being converted into Lua once more.

Not only is this inefficient, as roundtripping isn't lossless, you
couldn't return functions or rich objects from main thread functions
(see https://github.com/dan200/ComputerCraft/issues/125).

We now store the return value on the Java side and then return that when
the receiving the task_complete event - the event no longer carries the
result. Note this does not affect methods using issueMainThreadTask!
2022-12-15 20:19:28 +00:00
Jonathan Coates
2b237332ce
Update to latest Forge
This fixes the issue with DeferredRegister crashing on non-wrapped
registries.
2022-12-15 17:53:50 +00:00
Jonathan Coates
1276478deb
Use the correct import path in import.lua
Think this is worth backporting to 1.16.5. Ughr.
2022-12-14 21:29:38 +00:00
Jonathan Coates
551f6ba60c
Fix out-of-bounds read in ByteBufferChannel
Introduced in fa122a56cf by the looks of
it, so shouldn't have ever made it into a release.
2022-12-14 21:21:47 +00:00
Jonathan Coates
99a2b26fc5
Fix some typos in ARCHITECTURE.md
Mostly just relics of the old multi-loader branch.
2022-12-14 18:49:06 +00:00
Jonathan Coates
0787e17ebe
Use git shortlog for gathering contributors 2022-12-13 20:31:59 +00:00
Jonathan Coates
06163e4f25
Fix a couple of packaging issues
- Fix client classes not being included in Forge.
 - Only remap Nettty's HTTP classes, not all of them. This feels a
   little more error prone - maybe we should jar-in-jar this in the
   future.
 - Use the correct refmaps on Forge.
 - Prevent the Fabric jar pulling in some other mods.

Closes #1247
2022-12-12 20:28:18 +00:00
Jonathan Coates
18fbd96c10
Some further improvemnets to mount error handling
- Correctly handle FileOperationExceptions for the root mount.
 - Remove some checks from MountWrapper: Mount/WritableMount should do
   these already!
 - Normalise file paths, always using a '/'.
2022-12-10 12:54:49 +00:00
Jonathan Coates
367773e173
Some refactoring of mounts
- Separate FileMount into separate FileMount and WritableFileMount
   classes. This separates the (relatively simple) read-only code from
   the (soon to be even more complex) read/write code.

   It also allows you to create read-only mounts which don't bother with
   filesystem accounting, which is nice.

 - Make openForWrite/openForAppend always return a SeekableFileHandle.
   Appendable files still cannot be seeked within, but that check is now
   done on the FS side.

 - Refactor the various mount tests to live in test contract interfaces,
   allowing us to reuse them between mounts.

 - Clean up our error handling a little better. (Most) file-specific code
   has been moved to FileMount, and ArchiveMount-derived classes now
   throw correct path-localised exceptions.
2022-12-09 22:02:31 +00:00
Jonathan Coates
8007a30849
Actually update README with the new maven coordinates
Also bump REI to 1.19.3
2022-12-09 18:05:35 +00:00
Jonathan Coates
df38f3e887
Update README with the new maven coordinates
Currently published under 1.102.0-SNAPSHOT if anybody wants/needs to
poke. I'm going to break Mount/WritableMount, but everything else should
be stable!
2022-12-08 21:52:34 +00:00
Jonathan Coates
c3fe9f00d4
Update to Minecraft 1.19.3
Lots of minor changes, but nothing too nasty - just tedious.

Known bugs/issues:
 - REI and JEI haven't been updated at the time of writing, so our usage
   of their APIs may be incompatible.

 - Crash when opening the config UI in Fabric, as forgeconfigapi-port
   hasn't been updated yet.

Will hold off on doing a release until those mods have updated.
2022-12-08 19:45:02 +00:00
Jonathan Coates
3b42f22a4f
A couple of fixes to the HTTP API
- Flip http.websocket and http.websocketAsync docs (fixes #1244)

 - Fix http.request queuing a http_failure event with no URL when
   passing a malformed URL

 - Fix http.websocketAsync not queuing websocket_failure events on
   immediate failure.
2022-12-07 21:14:33 +00:00
Jonathan Coates
9962ce1a5c
Finish a sentence
Folks have been waiting 2 years for this, it's time to end the suspense.
2022-12-07 09:53:16 +00:00
Jonathan Coates
9f48395596
Correctly format 12AM/PM with %I
Fixes #1243
2022-12-06 21:50:28 +00:00
Jonathan Coates
020c5cd2d3
Support renaming files directly without copying/deleting
In classic squid tradition: 20% code, and 80% test logic.

Closes #962. Alas, whoever reported this has deleted their account, so
they can't even be happy about it :(.
2022-12-04 21:59:30 +00:00
Jonathan Coates
a9c0b02e3c
Run core tests on Windows/OSX too
We've a couple of Windows-specific tests here which I've not actually
run on Windows for years. It feels worth doing properly.
2022-12-04 18:41:19 +00:00
Jonathan Coates
fc5f296eeb
Make Mount.openForRead always return a SeekableByteChannel
I want to make some further changes to Mount here, but this helps
simplify BinaryReadableHandle a little.
2022-12-03 18:20:50 +00:00
Jonathan Coates
c96172e78d
Refactor common {Jar,Resource}Mount code into a parent class 2022-12-03 18:02:12 +00:00
Jonathan Coates
fa122a56cf
Resolve a few TODOs
- Update ForgeConfigAPI to the latest version, to fix the race
   condition.
 - Move WirelessNetwork lifecycle management to ServerContext.
 - Some doc fixes.
2022-12-03 15:55:48 +00:00
Jonathan Coates
87c6d3aef6
Initial pass of the API breaking changes for 1.19.3 (#1232)
- Remove deprecated API members in prep for 1.19.3. This allows us to
   remove the mc-stubs and forge-stubs projects.

 - Make several methods take a MinecraftServer instead of a Level (or
   nothing at all).

 - Remove I prefixes from a whole bunch of interfaces, making things a
   little more consistent with Java conventions.

   This avoids touching the "main" interfaces people consume for now. I
   want to do that another Minecraft version, to avoid making the update
   too painful.

 - Remove IFileSystem and associated getters. This has never worked very
   well and I don't think has got much (any?) usage.
2022-12-03 15:02:00 +00:00
Jonathan Coates
95c57e843d
Pass project root to cct-javadoc
Fixes #1238
2022-12-02 22:00:00 +00:00
Jonathan Coates
b13998dd96
Allow client tests to fail
I give this commit a 50% chance of failing for other GH Actions related
reasons. Nobody ever gets CI commits right on the first try.
2022-11-25 20:45:43 +00:00
Drew Edwards
47816805fb
Check the filesystem for isReadOnly (#1226) 2022-11-25 20:40:40 +00:00
Jonathan Coates
b8fce1eecc
Trim spaces from filesystem paths
I kinda hate this, but not sure what else to do. It might be worth
rewriting sanitizePath in the future to loop through the string once,
but I think this is good enough for now.
2022-11-25 20:12:10 +00:00
Jonathan Coates
ee2670d53b
Move some functions out of bios into their own APIs
This removes the patching of fs and http, and replaces them with their
own standard Lua APIs. This makes the bios a little simpler, and means
we can move the documentation in line.
2022-11-21 22:47:07 +00:00
Jonathan Coates
3a96aea894
Add a couple of tests for pocket computers
- Ensure they're correctly synced to the client. This definitely isn't
   comprehensive, but doing anything further probably involves multiple
   players, which is tricky.

 - Quick rendering test for in-hand computers.
2022-11-21 21:34:35 +00:00
Jonathan Coates
0fc78acd49
Fix computer upgrade recipes 2022-11-21 19:08:23 +00:00
Jonathan Coates
737d8a2585
Add a couple of tests for inventory transfer
For now this is just a couple of regression tests for a couple of CC:R
bugs.
2022-11-20 19:41:36 +00:00
Jonathan Coates
e2447bb0fd
Fix path to Fabric mod icon
Forge requires the file to be in the root of the jar, hence doing it
this way round. The icon is read using ModContainer.findPath, so this
shouldn't conflict with other mods.
2022-11-20 17:31:14 +00:00
Jonathan Coates
2255d49d16
Update to latest Fabric
Love being on the bleedin' edge. More importantly, this fixes a couple
of issues:
 - Translations are loaded on the server, meaning .getItemDetail
   correctly translates modded items.
 - Shulker boxes cannot be moved inside other shulker boxes using the
   transfer API.
 - Start using Fab API's ItemStack.getRecipeRemainder().
2022-11-20 16:05:28 +00:00
Weblate
3fa39b5f98 Translations for Russian (ru_ru)
Translations for Swedish

Translations for French

Co-authored-by: Naheulf <newheulf@gmail.com>
Co-authored-by: SquidDev <git@squiddev.cc>
Co-authored-by: Алексей <handbrake.mine@gmail.com>
2022-11-20 13:16:06 +00:00
Jonathan Coates
08df68dcc0
Generate en_us.json via datagen
I was originally pretty sceptical about this, but it actually ends up
being useful for the same reason any other form of datagen is: we can
ensure that names are well formed, and that every string is actually
translated.

There's some future work here to go through all the custom translation
keys and move them into constants (maybe also do something with the
/computercraft command?), but that's a separate chunk of work.

The main motivation for this is to add translation keys to our config:
the Fabric version of Forge Config API provides a config UI, so it's
useful to provide user-friendly strings. Our generator also
automatically copies comments over, turning them into tooltips.

This also updates all of the other language files to match en_us.json
again: it's a very noisy diff as the file is now sorted alphabetically.
Hopefully this won't affect weblate though

[^1]: Amusing really that the Fabric port actually is more useful than
the original.
2022-11-20 13:00:43 +00:00
Jonathan Coates
8f92417a2f
Add a system for client-side tests (#1219)
- Add a new ClientJavaExec Gradle task, which is used for client-side
   tests. This:

   - Copies the exec spec from another JavaExec task.
   - Sets some additional system properties to configure on gametest framework.
   - Runs Java inside an X framebuffer (when available), meaning we
     don't need to spin up a new window.

   We also configure this task so that only one instance can run at
   once, meaning we don't spawn multiple MC windows at once!

 - Port our 1.16 client test framework to 1.19. This is mostly the same
   as before, but screenshots no longer do a golden test: they /just/
   write to a folder. Screenshots are compared manually afterwards.

   This is still pretty brittle, and there's a lot of sleeps scattered
   around in the code. It's not clear how well this will play on CI.

 - Roll our own game test loader, rather than relying on the mod loader
   to do it for us. This ensures that loading is consistent between
   platforms (we already had to do some hacks for Forge) and makes it
   easier to provide custom logic for loading client-only tests.

 - Run several client tests (namely those involving monitor rendering)
   against Sodium and Iris too. There's some nastiness here to set up
   new Loom run configurations and automatically configure Iris to use
   Complementary Shaders, but it's not too bad. These tests /don't/ run
   on CI, so it doesn't need to be as reliable.
2022-11-18 23:57:25 +00:00
Jonathan Coates
b58b9b7df3
Fix several issues with the Fabric API jar
- Bundle the core API inside the Fabric API jar for now, to ensure
   that ResourceLocation is remapped.

 - Add a dummy fabric.mod.json file to the API. We'll remove this once
   https://github.com/FabricMC/fabric-loom/pull/749 is released.
2022-11-18 23:21:05 +00:00
Jonathan Coates
8d2e150f05
Various improvements to packaging
This fixes several issues I had with consuming multi-loader CC:T in
various upstream mods.

 - Include /all/ sources in the Forge/Fabric jar. Before it was just the
   common classes, and not the core or API.

 - Use some Gradle magic to remove superfluous dependencies from the POM
   file. Also make sure Cobalt and Netty are present as dependencies.

 - Start using minimize() in our shadow jar config again.
2022-11-17 09:26:57 +00:00
Jonathan Coates
8152f19b6e
Fabric lol
- Add support for Fabric. This is mostly pretty simple, though does
   require a lot more mixins than Forge.

   Half this diff is due to data generators: we run them separately as
   some aspects (recipes mostly) are different between the loaders.

 - Add integration with Iris (same as our Oculus support) and REI
   (mostly the same as our JEI support).

 - Generic peripherals only support inventories (or rather
   InventoryStorage) right now. Supporting more of the Fabric storage
   API is going to be tricky due to the slotted nature of the API: maybe
   something to revisit after Transfer API V3 (V4?, I've lost track).

Note, this does /not/ mean I will be publishing a Fabric version of
CC:T. My plan is to rebase CC:R on top of this, hopefully simplifying
the maintenance work on their end and making the two mods a little more
consistent.
2022-11-10 19:42:34 +00:00
Jonathan Coates
b2b58892e3
Minor fixes and cleanup
My working tree is a mess, so this is not a good commit. I'm making a
bit of a habit of this.

 - Fix UserLevel.OWNER check failing on single player servers.
 - Correctly handle the "open folder" fake command.
 - Some reshuffling of Forge-specific methods to make Fabric slightly
   easier.
2022-11-10 17:15:12 +00:00
Jonathan Coates
8360e8234d
Post multi-loader cleanup
This commit got away from me, okay? No, I'm not proud of it either.

 - Remove our overrides of handleUpdate tag: we now try to detect
   whether we're on the client or server inside BlockEntity.load. Alas,
   this is needed for Fabric.

 - Remove BlockGeneric/TileGeneric entirely: we've slowly whittled this
   down over the years, and nowadays we can get away with putting most
   of its functionality into subclasses.

   This allows us to do some nice things with overriding HorizontalBlock
   (or our new HorizontalContainerBlock class), rather than
   reimplementing functionality in each class. Though it would be nice
   if Java had some sort of trait system :D:

 - Simplify a lot of our container class so it's just defined in terms
   of a NonNullList<ItemStack>. This also includes a total rewrite of
   the disk drive which I'm not ... thrilled about. It ended up being
   easier to copy the code from the mc-next branch :D:.

 - Try to test some of the gnarly bits of this. Still a /lot/ more to be
   done with testing this.

Closes #658
2022-11-10 15:55:34 +00:00
Jonathan Coates
77624fc6fd
Update project paths in our utility build scripts 2022-11-10 09:12:28 +00:00
Jonathan Coates
1d335f7290
Add a couple of errorprone plugins
- Check that common code does not reference client-only classes.
 - Check that @ForgeOverride really overrides a method in Forge
   projects.
2022-11-10 08:54:09 +00:00
Jonathan Coates
f04acdc199
Split CC:T into common and forge projects
After several weeks of carefully arranging ribbons, we pull the string
and end up with, ... a bit of a messy bow. There were still some things
I'd missed.

 - Split the mod into a common (vanilla-only) project and Forge-specific
   project. This gives us room to add Fabric support later on.

 - Split the project into main/client source sets. This is not currently
   statically checked: we'll do that soon.

 - Rename block/item/tile entities to use suffixes rather than prefixes.
2022-11-10 08:54:09 +00:00
Jonathan Coates
bdf590fa30
Clean up data generators a little 2022-11-09 22:02:47 +00:00
Jonathan Coates
0c4fd2b29e
Make the shader mod system a little more flexible
Mostly for multi-loader support, but also /technically/ makes it easier
to support multiple loaders in the future.
2022-11-09 21:05:27 +00:00
Jonathan Coates
8a7156785d
Refactor turtle actions for easier multi-loader support
- TurtlePlayer now returns a fake player, rather than extending from
   Forge's implementation.

 - Remove "turtle obeys block protection" config option.

 - Put some of the more complex turtle actions behind the
   PlatformHelper.
2022-11-09 20:50:43 +00:00
Jonathan Coates
4d50b48ea6
Remove all references to the ComputerCraft class
Another ugly commit, not thrilled about it:
 - Move all config values to a separate Config class.
 - Replace ComputerCraft.log with class-specific loggers.
 - Replace ComputerCraft.MOD_ID with ComputerCraftAPI.MOD_ID
2022-11-09 20:10:24 +00:00
Jonathan Coates
48285404b9
Move the rendering monitor code to the client side
It's kinda funny looking at all the pre-CC:T proxy code, how much this
has come full circle. I think this design is nicer than what 1.12 did,
but it's still slighly embarassing.
2022-11-09 19:55:42 +00:00
Jonathan Coates
b36b96e0bc
Make the main mod non-null by default
This was actually much more work than I thought it would be. Tests pass,
but I'm sure there's some regressions in here.
2022-11-09 18:59:51 +00:00
Jonathan Coates
34c7fcf750
Refactor the turtle model code a little
Should make it easier to use in a multi-loader setting. This probably
still needs a bit more work: Dinnerbone turtles are still very broken.
2022-11-09 17:21:29 +00:00
Jonathan Coates
cc73fcd85d
Move many Forge-specific methods behind PlatformHelper
There's still a lot of work to be done on turtles (TurtlePlayer, all the
turtle tool stuff), but we're a good way along now.
2022-11-09 14:41:46 +00:00
Jonathan Coates
22729f6f16
Abstract our our use of Forge's tags 2022-11-09 10:59:05 +00:00
Jonathan Coates
55494b7671
Rewrite how we do inventory transfers
- Add a new ContainerTransfer class to handle moving items between
   containers. This is now used for turtle.drop/turtle.suck as well as
   inventory methods.

 - Any other usages of IItemHandler (which are mostly on turtle
   inventories) now use Container and a couple of helper methods.
2022-11-08 21:31:24 +00:00
Jonathan Coates
7d47b219c5
Access capabilities using PlatformHelper
We provide a new abstraction: ComponentAccess, which is a view of
capabilities (or block lookups for Fabric) for adjacent blocks.
2022-11-08 17:44:06 +00:00
Jonathan Coates
320007dbc6
Improve packaging of published jars
- Publish javadoc again: for now this is just the common-api

 - Remove all dependencies from the published Forge jar. This is
   technically not needed (fg.deobf does this anyway), but seems
   sensible.
2022-11-08 16:43:27 +00:00
Jonathan Coates
0908acbe9b
Move all event handlers to a common class
While this does now involve a little more indirection, by having a
single location for all hooks it's much easier to keep event listeners
consistent between loaders.

The diff is pretty noisy (I've inlined some classes, and ClientRegistry
got a big restructure), but functionality should be the same.
2022-11-08 10:48:22 +00:00
Jonathan Coates
e8f9cdd221
Attach capabilities to our BlockEntities externally
Previously we overrode getCapability on our BlockEntity implementations.
While this is the Proper way to do things, it's obviously impossible to
do in a multi-loader environment.

We now subscribe to the AttachCapabilitiesEvent and add our caps that
way. This does require[^1] some nasty invalidation of caps in a couple
of places, which I'm not wild about.

[^1]: I'm not actually sure it does: we invalidate peripherals and wired
elements when neighbours change, so the explicit invalidation probably
isn't useful.
2022-11-06 22:26:07 +00:00
Jonathan Coates
53abe5e56e
Make net code more multi-loader friendly
NetworkMessage follows vanilla's Packet much more closely now: the
handler takes a context argument, which varies between the client and
server.

 - The server handler just returns the ServerPlayer who sent the
   message.
 - The client context provides handleXyz(...) methods for each
   clientbound packet. Our packet subclasses call the appropriate
   method - the implementation of which contains the actual
   implementation.

Doing this allows us to move a whole bunch of client-specific code into
the main client package, dropping several @OnlyIn annotations and
generally reducing the risk of accidentally loading client classes on
the server.

We also abstract out some packet sending and general networking code to
make it easier to use in a multi-loader context.
2022-11-06 20:13:04 +00:00
Jonathan Coates
564752c8dd
Flesh out our registry abstraction layer
- Replace our usages of DeferredRegistry with a custom
   RegistrationHelper. This effectively behaves the same, just without
   any references to Forge code!

 - Replace any references to ForgeRegistries with a home-grown
   Registries class. This just fetches the underlying registry and
   proxies the method calls.

 - Change recipe serialisers and loot item conditions to be registered
   the same way as other entries.

 - Move any Forge specific registration code off to the main
   ComputerCraft class.
2022-11-06 18:37:00 +00:00
Jonathan Coates
6d665ad841
Rename Registry to ModRegistry
Avoids the conflict with Minecraft's built-in registry class
2022-11-06 18:37:00 +00:00
Jonathan Coates
9cd728fea9
Update parse-reports to handle new paths 2022-11-06 18:37:00 +00:00
Oliver Caha
1c890e5a5c
Fix typo in speaker documentation (#1209) 2022-11-06 18:33:46 +00:00
Jonathan Coates
955b9c7d28
Default Forge/Common API to non-null 2022-11-06 15:50:24 +00:00
Jonathan Coates
76710eec9d
Move our public API into separate modules
This adds two new modules: common-api and forge-api, which contain the
common and Forge-specific interfaces for CC's Minecraft-specific API.

We add a new PlatformHelper interface, which abstracts over some of the
loader-specific functionality, such as reading registries[^1] or calling
Forge-specific methods. This interface is then implemented in the main
mod, and loaded via ServiceLoaders.

Some other notes on this:

 - We now split shared and client-specific source code into separate
   modules. This is to make it harder to reference client code on the
   server, thus crashing the game.

   Eventually we'll split the main mod up too into separate source sets
   - this is, of course, a much bigger problem!

 - There's currently some nastiness here due to wanting to preserve
   binary compatibility of the API. We'll hopefully be able to remove
   this when 1.19.3 releases.

 - In order to build a separate Forge-specific API jar, we compile the
   common sources twice: once for the common jar and once for the Forge
   jar.

   Getting this to play nicely with IDEs is a little tricky and so we
   provide a cct.inlineProject(...) helper to handle everything.

[^1]: We /can/ do this with vanilla's APIs, but it gives a lot of
deprecation warnings. It just ends up being nicer to abstract over it.
2022-11-06 15:07:13 +00:00
Jonathan Coates
d8e2161f15
Move website source/build logic to projects/web
Mostly useful as it moves some of our build logic out of the main
project, as that's already pretty noisy!
2022-11-06 13:37:07 +00:00
Jonathan Coates
c82f37d3bf
Switch the core library to be non-null by default
See comments in c8c128d335 for further
details. This requires /relatively/ few changes - mostly cases we were
missing @Nullable annotations.
2022-11-06 11:55:26 +00:00
Jonathan Coates
c8c128d335
Switch the core-api to be non-null by default
We'll do this everywhere eventually, but much easier to do it
incrementally:

 - Use checker framework to default all field/methods/parameters to
   @Nonnull.

 - Start using ErrorProne[1] and NullAway[2] to check for possible null
   pointer issues. I did look into using CheckerFramework, but it's much
   stricter (i.e. it's actually Correct). This is technically good, but
   is a much steeper migration path, which I'm not sure we're prepared
   for yet!

[1]: https://github.com/google/error-prone
[2]: https://github.com/uber/NullAway
2022-11-06 10:28:49 +00:00
Jonathan Coates
acc254a1ef
Move dan200.computercraft.core into a separate module
This is a very big diff in changed files, but very small in actual
changes.
2022-11-06 10:02:14 +00:00
Jonathan Coates
a17b001950
Move the core API into a separate module
It should be possible to consume the ComputerCraft's core (i.e.
non-Minecraft code) in other projects, such as emulators.  While this
has been possible for years, it's somewhat tricky from a maintenance
perspective - it's very easy to accidentally add an MC dependency
somewhere!

By publishing a separate "core" jar, we can better distinguish the
boundaries between our Lua runtime and the Minecraft-specific code.

Ideally we could have one core project (rather than separate core and
core-api modules), and publish a separate "api" jar, like we do for the
main mod. However, this isn't really possible to express using Maven
dependencies, and so we must resort to this system.

Of course, this is kinda what the Java module system is meant to solve,
but unfortunately getting that working with Minecraft is infeasible.
2022-11-04 21:41:59 +00:00
Jonathan Coates
e4e528e5bf
Prepare dan200.computercraft.core for splitting off
- Move core-specific config options to a separate CoreConfig class.
 - Use class-specific loggers, instead of a global one.
 - Use log markers instead of a logComputerErrors option.
2022-11-04 19:58:57 +00:00
Jonathan Coates
6cc86b0ae5
Exclude the previous commit from git blame
This can be added by running the following command:

    git config --global blame.ignoreRevsFile .git-blame-ignore-revs
2022-11-04 13:42:00 +00:00
Jonathan Coates
f478c4ffc4
Reformat everything
- Switch to a fairly standard code format. This is largely based on
   IntelliJ defaults, with some minor tweaks applied via editor config.
   Should mean people don't need to import a config!

 - Use "var" everywhere instead of explicit types. Type inference is a
   joy, and I intend to use it to its fullest.

 - Start using switch expressions: we couldn't use them before because
   IntelliJ does silly things with our previous brace style, but now we
   have the luxury of them!
2022-11-04 13:41:38 +00:00
Jonathan Coates
7df0412c2d
Bump CC:T to 1.101.1
Our last palendrome for a while!
2022-11-03 20:41:47 +00:00
Jonathan Coates
998efcc950
Move our test thread scheduler into the main jar
While useless in-game, both CCEmuX and eval.tweaked.cc ended up
reimplementing it, so might as well expose it!
2022-11-03 20:41:47 +00:00
Jonathan Coates
45c5de73bb
Correctly register turtle refuel handlers
And actually test them! Along with a whole load of other turtle tests.

Fixes #1202
2022-11-03 20:41:46 +00:00
Alessandro Proto
c919011a7e
Check for valid nSender field on RedNet message receive (#1200) 2022-11-03 08:40:37 +00:00
Jonathan Coates
0f1f5247ca
Merge branch 'mc-1.18.x' into mc-1.19.x 2022-11-02 09:55:10 +00:00
Jonathan Coates
0db32bd0fe
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-11-02 09:55:10 +00:00
Jonathan Coates
1d3ecb551d
Improvee changelog 2022-11-02 07:58:31 +00:00
Jonathan Coates
aefda6a381
Fix a couple of issues with the release process
Only way to test these is in prod, alas :D:
2022-11-01 21:53:05 +00:00
Jonathan Coates
c1bf9f0b24
Prepare the public API for multi-loader support
Well, sort of. For now, we just mark a whole bunch of stuff as
@Deprecated.
2022-11-01 21:05:24 +00:00
Jonathan Coates
629abb65e3
Merge branch 'mc-1.18.x' into mc-1.19.x 2022-11-01 20:11:36 +00:00
Jonathan Coates
11ac865877
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-11-01 20:07:15 +00:00
Jonathan Coates
6b93fafc46
Bump CC:T to 1.101.0
These version numbers are very hard to type correctly.
2022-11-01 20:01:21 +00:00
Jonathan Coates
1acb8441ec
Add a couple of tests for file autocompletion 2022-11-01 19:22:07 +00:00
Ivo Leal
4b0988768d
Add include_hidden option to fs.complete (#1194) 2022-11-01 14:50:15 +00:00
Jonathan Coates
f528046535
Add a whole bunch of missing @since annotations 2022-10-31 20:09:47 +00:00
Jonathan Coates
93f747fb54
Fix incorrect reboot tooltip
This tooltip was a) using the wrong text and b) incorrect anyway!
Rebooting an off computer does nothing, rather than turning it on.
2022-10-31 20:08:50 +00:00
Jonathan Coates
5d4c34fbac
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-10-31 18:03:39 +00:00
Jonathan Coates
4c5b3a6ee5
Clear Origin header on websockets
Technically this removes Sec-Websocket-Origin, as that's what the
current version of Netty uses. We'll need to change this on 1.18+.

Closes ##1197.
2022-10-31 17:46:02 +00:00
Jonathan Coates
7701b343fb
Make PartialOptions immutable
- Switch to using OptionalInt/OptionalLong instead of @Nullable
   Long/Integers. I know IntelliJ complains, but it avoids the risk of
   implicit unboxing.

 - Instead of mutating PartialOptions, we now define a merge() function
   which returns the new options. This simplifies the logic in
   AddressRule a whole bunch.
2022-10-31 09:13:40 +00:00
Jonathan Coates
14cb97cba1
Sort NBT when writing
This should fix the worst cases of #1196.
2022-10-30 16:47:26 +00:00
Jonathan Coates
1490ca8624
Bump Cobalt version
Adds debug.getregistry() support
2022-10-30 16:39:25 +00:00
Jonathan Coates
f5b89982de
Don't unnecessarily scroll in edit run wrapper (#1195) 2022-10-30 15:17:33 +00:00
Jonathan Coates
1a87175ae7
Be a little more rigorous in KotlinLuaMachine's threading 2022-10-30 11:44:01 +00:00
Jonathan Coates
c4184a33bc
Rewrite our gametest system
This is a noisier diff than I'd like as this is just a direct copy from
the multi-loader branch.

 - Rename "ingame" package to "gametest"

 - Don't chain GameTestSequence methods - it's actually much cleaner if
   we just use Kotlin's implicit this syntax.

 - Use our work in 71f81e1201 to write
   computer tests using Kotlin instead of Lua. This means all the logic
   is in one place, which is nice!

 - Add a couple more tests for some of the more error-prone bits of
   functionality.
2022-10-30 10:50:16 +00:00
Jonathan Coates
b3702fed78
Remove all Minecraft references from the core package
This is an initial step before refactoring this into a separate module.
It's definitely not complete - there's a lot of work needed to remove
referneces to the main ComputerCraft class for instance - but is a
useful first step.
2022-10-30 09:20:26 +00:00
Jonathan Coates
b5056fc3b8
Merge branch 'mc-1.18.x' into mc-1.19.x 2022-10-30 09:06:40 +00:00
Jonathan Coates
38b2c944f3
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-10-30 08:49:52 +00:00
Jonathan Coates
5ee5b11995
Fix month and day names under Java 17
I still don't really understand why the ROOT locale is wrong here, but
there we go. We'll need to remember to uncomment the tests on the 1.18
branch!

Also add some code to map tests back to their definition side. Alas,
this only links to the file right now, not the correct line :/.
2022-10-29 23:54:35 +01:00
Jonathan Coates
b2d2153258
Add several missing version annotations
I probably need to add this to the pre-release checklist. Don't think
there's a good way to automate this :(
2022-10-29 22:49:45 +01:00
Jonathan Coates
3d6ef0cf96
Fix peripheral API using the wrong methods 2022-10-29 22:47:57 +01:00
Jonathan Coates
71f81e1201
Move some test support code into testFixtues
This offers very few advantages now, but helps support the following in
the future:

 - Reuse test support code across multiple projects (useful for
   multi-loader).
 - Allow using test fixture code in testMod. We've got a version of our
   gametest which use Kotlin instead of Lua for asserting computer
   behaviour.

We can't use java-test-fixtures here for Forge reasons, so have to roll
our own version. Alas.

 - Add an ILuaMachine implementation which runs Kotlin coroutines
   instead. We can use this for testing asynchronous APIs. This also
   replaces the FakeComputerManager.

 - Move most things in the .support module to .test.core. We need to use
   a separate package in order to cope with Java 9 modules (again,
   thanks Forge).
2022-10-29 18:17:02 +01:00
Jonathan Coates
1e88d37004
Add peripheral_hub type for wired-modem-like peripherals (#1193)
This allows other mods to create wired-modem alike blocks, which expose
peripherals on the wired network, without having to reimplement the main
modem interface.

This is not currently documented, but a peripheral_hub should provide
the following methods:

 - isPresentRemote
 - getTypeRemote
 - hasTypeRemote
 - getMethodsRemote
 - callRemote
2022-10-29 16:03:05 +01:00
Jonathan Coates
97387556fe
Handle file transfers inside CraftOS (#1190)
- Add a new file_transfer event. This has the signature
   "file_transfer", TransferredFiles.

   TransferredFiles has a single method getFiles(), which returns a list
   of all transferred files.

 - Add a new "import" program which waits for a file_transfer event and
   writes files to the current directory.

 - If a file_transfer event is not handled (i.e. its getFiles() method
   is not called) within 5 seconds on the client, we display a toast
   informing the user on how to upload a file.
2022-10-29 12:01:23 +01:00
Jonathan Coates
1f910ee2ba
Use a separate object for tracking TickScheduler state
This allows us to use non-TileGeneric block entities. This is a clever
trick which will help us later!
2022-10-28 23:40:55 +01:00
Jonathan Coates
a9ef874174
Regenerate assets using our new JSON printer
Haha. Hahahaah. I've gone mad with power.
2022-10-26 18:38:20 +01:00
Jonathan Coates
a2911038c5
Merge branch 'mc-1.18.x' into mc-1.19.x 2022-10-26 09:53:32 +01:00
Jonathan Coates
158850be09
Some Java-17ification
I might just stick on 1.18 for the rest of these refactors. Porting
across the mojmap boundary is painful.
2022-10-25 22:58:31 +01:00
Jonathan Coates
be827a21db
Merge branch 'mc-1.16.x' into mc-1.18.x
I dare say there's going to be some bugs with this. I was as careful as
I could be, but yikes it was nasty.
2022-10-25 22:38:26 +01:00
Jonathan Coates
562f224c01
Refactor out our JEI plugin into reusable components
Pretty useless right now, but either useful for CC:R or our eventual
multi-loader support.
2022-10-25 19:26:44 +01:00
Jonathan Coates
f45614175a
Some improvements to Javadoc publishing
- Use <p> everywhere. This is uglier, but also technically more
   correct. This requires a version bump to cct-javadoc, and will give
   me a massive headache when merging.

 - Link against the existing OpenJDK docs.
2022-10-25 19:17:55 +01:00
Jonathan Coates
af7af615c7
Correctly shut down computer threads
We now wait for workers to terminate when closing the computer thread.

I'll be honest, I'm not happy with this code. Multi-threading is really
hard to get right, and I can't say I'm convinced this is especially well
behaved. I did look at trying to model this in TLA+, but in the end
decided it wasn't worth it.

In the future we probably want to split ComputerExecutor into two
objects, where one is our entry in the ComputerThread queue (and so
holds timing information) while the other is responsible for actual
execution.
2022-10-25 09:32:32 +01:00
Jonathan Coates
8171578e80
Some minor build system improvements
- Correctly handle Git commands failing. We need an actual default
   value, not just null!

 - Use run/ and build/tmp/ for temporary test locations, not
   /test-files.
2022-10-24 19:21:09 +01:00
Jonathan Coates
f4e542b4db
Use our global logger instead of per-class ones
No slf4j available for 1.16.5, and I'll forget if I depend on
log4j.
2022-10-23 16:13:08 +01:00
Jonathan Coates
3e3bc8d4b1
Fix a whole bunch of GH action issues
- Switch over to the Gradle GH action. Not expecting massive changes,
   but might provide some better caching.

 - Bump some GH action versions.

 - Fix a Java 8 compatability issue in our build scripts.
2022-10-22 21:36:52 +01:00
Jonathan Coates
b48f590b92
Merge branch 'feature/gradle-vice' into mc-1.16.x
The hills are alive with the sound of build scripts!
2022-10-22 21:13:50 +01:00
Jonathan Coates
6ab90dc30d
Convert build script to Kotlin
- Add a new Node plugin. This automatically installs npm dependencies
   and provides a "NpxExecToDir" to dir task. This allows us to make the
   doc website task dependencies a little nicer, by simply chaining
   tasks together, rather than doing dependsOn + `input.files(the other
   task output)`.

 - Switch over to CurseForgeGradle from CurseGradle. The latter is
   super clunky to use in non-Groovy languages.

 - Copy our Modrinth description body to our repo, and add support for
   syncing it. We'll still have to do CF manually I think.
2022-10-22 21:09:08 +01:00
Jonathan Coates
0cfdd7b5e9
Move some more build logic to buildSrc
Look, I don't enjoy having 600 LOC long build.gradle files, it's just
very easy to do! This at least moves some of the complexity elsewhere,
so the build script is a little more declarative.
2022-10-22 20:47:47 +01:00
Jonathan Coates
af5d816798
Use spotless for enforcing licenses
It's more verbose as the default license plugin doesn't support multiple
license headers. However, it also gives us some other goodies (namely
formatting Kotlin and removing unused imports), so worth doing.
2022-10-22 18:19:51 +01:00
Jonathan Coates
57cf6084e2
Manage ComputerThread's lifecycle in ComputerContext
This converts ComputerThread from a singleton into a proper object,
which is setup when starting a computer, and tore down when the
ComputerContext is closed.

While this is mostly for conceptual elegance, it does offer some
concrete benefits:
 - You can now adjust the thread count without restarting the whole
   game (just leaving and rentering the world). Though, alas, no effect
   on servers.
 - We can run multiple ComputerThreads in parallel, which makes it much
   easier to run tests in parallel. This allows us to remove our rather
   silly IsolatedRunner test helper.
2022-10-22 14:36:25 +01:00
Jonathan Coates
e9cde9e1bf
Refactor out main thread tasks into an interface
Computers now use a MainThreadScheduler to construct a
MainThreadScheduler.Executor, which is used to submit tasks. Our
previous (singleton) MainThread and MainThreadExecutor now implement
these interfaces.

The main purpose of this is to better manage the lifetime of the server
thread tasks. We've had at least one bug caused by us failing to reset
its state, so good to avoid those! This also allows us to use a fake
implementation in tests where we don't expect main thread tasks to run.

As we're now passing a bunch of arguments into our Computer, we bundle
the "global" ones into ComputerContext (which now also includes the Lua
machine factory!). This definitely isn't the nicest API, so we might
want to rethink this one day.
2022-10-22 14:13:06 +01:00
Jonathan Coates
68da044ff2
Merge branch 'feature/new-metrics' into mc-1.16.x 2022-10-22 12:21:41 +01:00
Jonathan Coates
18d9993fa7
Merge branch 'feature/more-datagen' into mc-1.16.x 2022-10-22 12:04:07 +01:00
Jonathan Coates
0c3de1087e
Switch to vanilla's model data generators
In some ways this isn't as nice as the Forge version (requires ATs,
doesn't check texture/model existence). However, it's more multi-loader
friendly and in some cases has much less boilerplate.

Blockstate JSON files are incredibly verbose, so we add a custom JSON
pretty printer which writes things in a slightly more compact manner.

This also changes how turtle upgrades are loaded - we now support
standard ResourceLocations (so computercraft:blocks/some_turtle_upgrade)
as well as ModelResourceLocations (computercraft:items/some_turtle_upgrade#inventory).
I don't think any resource packs need to touch our upgrades, but
apologies if this breaks anything.
2022-10-22 11:55:30 +01:00
Jonathan Coates
ff89e5feeb
Some datagen improvements
- Convert remaining recipes over to datagen.

 - Switch loot tables to use vanilla's loot table generator. It's
   honestly not too different, just the earlier system confused me too
   much :).

Alas, a positive diff because the JSON is so verbose. I've got a really
nice patch which makes the JSON more compact, but alas the Mixin doesn't
apply on 1.16 :(.
2022-10-22 10:50:10 +01:00
Jonathan Coates
0b26ab366d
Rewrite the metrics system
- Remove TrackingField and replace it with a Metric abstract class.
   This has two concrete subclasses - Counter and Event. Events carry an
   additional piece of data each time it is observed, such as HTTP
   response size.

 - Computers now accept a MetricsObserver, which tracks metrics for this
   particular computer. This allows us to decouple Computer classes and
   metrics information. The concrete MetricsObserver class we use within
   Minecraft exposes the ServerComputer directly, so we no longer need to
   do the awkward mapping and lookups!

 - The /computercraft command can now do aggregates (count, avg, max)
   over all Event metrics. This removes the need for special handling of
   computer and server time.

There's also a small number of changes in removing the coupling between
Computer and some of its dependencies (ILuaMachine, MainThreadExecutor).
This makes some future refactorings easier, I promise!
2022-10-22 01:35:13 +01:00
Jonathan Coates
cb9731306c
Give up on ComputerThreadTest being accurate
It's just too timing dependent right now. I'd like to fix this in the
future, but doing so is hard.
2022-10-22 00:42:21 +01:00
Jonathan Coates
5d833ac634
Expose getters for the detail registry too (#1188) 2022-10-22 00:42:07 +01:00
Jonathan Coates
9db3e6d2a0
Load the CC API with services loaders
This is a little odd (it's more complex for one!), but means we can
reuse the internal API interface in other classes, which is useful for
the data provider refactor I'm about to do.

This is much nicer in Java 17 :D (records, ServiceLoader.stream()),
but such is the perils of still targetting 1.16.
2022-10-21 23:50:44 +01:00
Jonathan Coates
1e703f1b07
Fix several off-by-one issues in UploadFileMessage
We now fuzz UploadFileMessage, generating random files and checking they
round-trip correctly.

The joy of having a long-lasting refactor branch with an absolutely
massive diff, is that you end up spotting bugs, and then it's a massive
pain to merge the fix back into trunk!
2022-10-21 23:10:18 +01:00
Jonathan Coates
b663028f42
Start work on curtailing our global state
The last 4 or 5 commits have simplified things. I can now have some
unnecessary complexity as a treat!

This is some initial work on better tying the lifecycle of
computers (and ComputerCraft) related state to the lifecycle of the
current Minecraft server.

 - Move server-wide methods in IComputerEnvironment (such as creating
   resource mounts) into a separate interface.
 - Add a new ServerContext class, which now holds the ID Assigner,
   server computer registry, and some other tiny bits and bobs. This can
   only be accessed by ServerContect.get(MinecraftServer), forcing
   slightly better discipline for how we use these globals.

This does allow us to nuke some of the ugliest bits in IDAssigner. Even
if it makes things much longer!
2022-10-21 21:02:24 +01:00
Jonathan Coates
cee60cdb5b
Require computers to have a fixed ID
Moves ID assigning out of the Computer class and into wherever we
construct the ServerComputer (so in computer blocks and pocket computer
items).

This is definitely not perfect - it'd be nice to make ServerComputers
more responsible for managing the lifecycle of computers (so assigning
ids, handling auto-starting, etc...), but I've not found a good way to
handle this yet!
2022-10-21 19:51:41 +01:00
Jonathan Coates
695ef0542a
Don't store a mutable array in Colour
It's kinda bad form, and we no longer need it anyway!
2022-10-21 19:07:58 +01:00
Jonathan Coates
c0d20b72c9
Remove ClientTerminal/ServerTerminal
They bring very little to the table now that computers do their own
thing! This also helps simplify the code in ServerMonitor a bit - turns
out we had two "dirty" flags in the implementation!
2022-10-21 19:00:29 +01:00
Jonathan Coates
cf05ab1db1
Store colour support in the Terminal
Previously we stored it alongside the terminal. While this makes sense -
it's not a property of the terminal itself, it ends up duplicating code
in a bunch of places.

We now track the colour flag on the terminal itself. This allows us to
simplify a couple of things:

 - The palette now also knows whether it supports colours or not, and so
   performs greyscale conversion. This means we no longer need to thread
   a "greyscale" flag throughout terminal rendering.

 - Remove isColour() getters from a whole load of
   places (TerminalMethods, ServerTerminal, IComputerEnvironment).
2022-10-21 18:26:57 +01:00
Jonathan Coates
c49547b962
Remove ClientComputer
Historically CC has maintained two computer registries; one on the
server (which runs the actual computer) and one on the client (which
stores the terminal and some small bits of additional data).

This means when a user opens the computer UI, we send the terminal
contents and store it in the client computer registry. We then send the
instance id alongside the "open container" packet, which is used to look
up the client computer (and thus terminal) in our client-side registry.

This patch makes the computer menu syncing behaviour more consistent
with vanilla. The initial terminal contents is sent alongside the "open
container" packet, and subsequent terminal changes apply /just/ to the
open container. Computer on/off state is synced via a vanilla
ContainerData/IIntArray.

Likewise, sending user input to the server now targets the open
container, rather than an arbitrary instance id.

The one remaining usage of ClientComputer is for pocket computers. For
these, we still need to sync the current on/off/blinking state and the
pocket computer light.

We don't need the full ClientComputer interface for this case (after
all, you can't send input to a pocket computer someone else is
holding!). This means we can tear out ClientComputer and
ClientComputerRegistry, replacing it with a much simpler
ClientPocketComputers store.

This in turn allows the following changes:

 - Remove IComputer, as we no longer need to abstract over client and
   server computers.

 - Likewise, we can merge ComputerRegistry into the server
   registry. This commit also cleans up the handling of instance IDs a
   little bit: ServerComputers are now responsible for generating their
   ID and adding/removing themselves from the registry.

 - As the client-side terminal will never be null, we can remove a whole
   bunch of null checks throughout the codebase.

 - As the terminal is available immediately, we don't need to explicitly
   pass in terminal sizes to the computer GUIs. This means we're no
   longer reliant on those config values on the client side!

 - Remove the "request computer state" packet. Pocket computers now
   store which players need to know the computer state, automatically
   sending data when a new player starts tracking the computer.
2022-10-21 18:17:43 +01:00
Jonathan Coates
c8e15f201c
Correctly bind VBOs before drawing them
Caused by 4228011b84. While correct on
1.18, this isn't correct on 1.19 - I clearly messed up the merge here.

Fixes #1183, possibly #1184 - haven't been able to reproduce.
2022-10-16 09:50:17 +01:00
Jonathan Coates
bc79100a2f
Merge branch 'mc-1.18.x' into mc-1.19.x 2022-10-14 22:09:13 +01:00
Jonathan Coates
9ed5ebb868
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-10-12 08:32:03 +01:00
Jonathan Coates
a9b74dc979
Make IRC links https 2022-10-09 11:22:24 +01:00
Jonathan Coates
12b8a0393f
Dump Cobalt's internal state on timeouts
Closes #1180
2022-10-09 11:22:16 +01:00
Jonathan Coates
cbfd83c2ba
Merge pull request #1182 from Quezler/patch-2
Add all but 3 of the missing dutch translations
2022-10-08 20:54:34 +01:00
Patrick 'Quezler' Mounier
8564c1e54b
Add all but 3 of the missing dutch translations 2022-10-08 21:00:58 +02:00
Jonathan Coates
66dff1523b
Merge branch 'mc-1.18.x' into mc-1.19.x 2022-10-01 12:37:10 +01:00
Jonathan Coates
08895cdecc
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-10-01 12:36:09 +01:00
Jonathan Coates
5be290a1e2
Bump version to 1.100.10
One more version and then it's a palendrome! Sort of.
2022-10-01 12:33:06 +01:00
Jonathan Coates
371f931140
Always add HTTP programs to the path (#1172) 2022-09-30 09:00:07 +00:00
Jonathan Coates
da5956e943
Make the sidebar a little wider
I was going to do something productive tonight, but then this happened.

Whatever, I'm retired, I'm allowed to make my entire existence just
adding 50px to things. Heck, maybe I'll do the same tomorrow too.
2022-09-29 22:21:38 +01:00
Jonathan Coates
e7533f2353
Improve community links a little 2022-09-29 22:01:51 +01:00
roland-a
0b7fbcde53
Send block updates to client when the turtle moves #1167 (#1170)
Fixes #1167
2022-09-29 17:49:02 +00:00
Jonathan Coates
76f8dd2d14
Properly bump to 1.19.2
We support 1.19.2 already (well, hopefully!), this just drops 1.19.1
support.
2022-09-21 18:11:50 +01:00
Jonathan Coates
c3b7302108
Remove some unused arguments in LuaDateTime
See comments in #1157
2022-09-11 15:03:09 +01:00
Jonathan Coates
61ac48c99f
Mention audio formats in speaker help
Closes #1133. I'm not super happy about any of the versions proposed
there, but I think this is better than nothing.

Co-authored-by: JackMacWindows <jackmacwindowslinux@gmail.com>
2022-09-11 14:57:45 +01:00
Jonathan Coates
d22e138413
Fix numerous off-by-one errors in help program
We clamped various values to the height of the screen, rather than the
height of the content box (height-1). We didn't notice this most of the
time as the last line of a file is empty - it only really mattered when
a file was the same height as the computer's screen.

We now do the following:
 - Strip the trailing new line from a file when reading.
 - Replace most usages of height with height-1.
2022-09-11 14:57:34 +01:00
Jonathan Coates
ba64e06ca7
Use a Gradle plugin to download illuaminate
Previously illumainate required manual users to manually download it and
place it in ./bin/. This is both inconvenient for the user, and makes it
hard to ensure people are running the "right" version.

We now provide a small Gradle plugin which registers illuaminate as a
ependency, downloading the appropriate (now versioned!) file. This also
theoretically supports Macs, though I don't have access to one to test
this.

This enables the following changes:

 - The Lua lint script has been converted to a Gradle task (./gradle
   lintLua).

 - illuaminateDocs now uses a task definition with an explicit output
   directory. We can now consume this output as an input to another
   task, and get a task dependency implicitly.

 - Move the pre-commit config into the root of the tree. We can now use
   the default GitHub action to run our hooks.

 - Simplify CONTRIBUTING.md a little bit. Hopefully it's less
   intimidating now.
2022-09-11 14:11:33 +01:00
Jonathan Coates
db8c979a06
Merge pull request #1156 from IvoLeal72/patch-1
Fixed usage example of textuils.pagedTabulate
2022-08-28 16:41:40 +01:00
Ivo Leal
9d18487dc5
Fixed usage example of textuils.pagedTabulate 2022-08-28 15:24:47 +01:00
Jonathan Coates
34a2e87735
Merge branch 'mc-1.18.x' into mc-1.19.x 2022-07-30 18:46:31 +01:00
Jonathan Coates
feb7681c9c
Add some missing test timeouts 2022-07-30 18:14:43 +01:00
Jonathan Coates
ad4a2aa68d
Mirror Oculus with our maven
In some ways it's probably less reliable than modrinth, but let's be
consistent here.
2022-07-30 17:56:56 +01:00
Jonathan Coates
4228011b84
Support Occulus shaders
This is mostly copied from the work Toad and I did for CC:R.

Instead of not writing to the depth buffer when rendering terminals, we
now render terminal forgrounds with a small glPolygonOffset (or an
emulation of it where not possible). This removes the need for custom
render types, while still avoiding z-fighting between the terminal
foreground and background.

The VBO monitors backend now uses Iris's TextVertexSink API when
available: Iris overwrites the vertex format for RenderType.text, and so
we need to use this API to avoid rendering garbage.

Performance is maybe a little worse than before (<3ms) and definitely
worse than CC:R. Unfortunately we can't do our upload batching as that
conflicts with Optifine's patches - instead we need to maintain two
separate VBOs. This is a bit slower, but not so bad it's unworkable.
2022-07-30 12:15:04 +01:00
Jonathan Coates
c43d851e63
Register turtle upgrade models separately
ITurtleUpgrade.getModel has always been rather error-prone to use, due
to its client-only nature. As ModelResourceLocation is now client-only
again in Forge 1.19.1, no seems a good time to fix this.

The getter for models is now a separate interface inside a new
dan200.computercraft.api.client package. These are registered
per-TurtleUpgradeSerialiser (as those should correspond to class
anyway). It's a little ugly, and we may rename the XxxSerialiser classes
to something more general in a future update.

I'm not wild about the interface here either - happy to change it in
future versions too.

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

Also clean up the generic arguments to IUpgradeBase/UpgradeSerialiser a
little bit. It's not great (wish Java had HKTs), but it's better.
2022-07-28 19:02:38 +01:00
Jonathan Coates
50fe7935a3
Merge branch 'mc-1.18.x' into mc-1.19.x 2022-07-28 09:49:25 +01:00
Jonathan Coates
bd19fdf350
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-07-28 09:43:06 +01:00
Jonathan Coates
c3615d9c5b
Update to 1.19.1 2022-07-28 08:52:03 +01:00
Jonathan Coates
e2041f7438
Bump version to 1.100.9 2022-07-27 08:25:31 +01:00
Jonathan Coates
d61202e2b8
Fix location of language file 2022-07-27 07:52:05 +01:00
Weblate
6ce88a7dcf Translations for Norwegian Bokmål
Co-authored-by: Erlend <erlend.bergersen@sandnesskolen.no>
2022-07-26 13:17:57 +00:00
Weblate
5d65b3e654 Added translation for Norwegian Bokmål
Co-authored-by: Erlend <erlend.bergersen@sandnesskolen.no>
2022-07-24 15:45:46 +00:00
Erlend
abf857f864
Clearify GPS documentation note (#1139) 2022-07-22 20:27:27 +00:00
Jonathan Coates
ebef3117f2
Update npm packages 2022-07-21 20:38:44 +01:00
Jonathan Coates
25a44bea6e
Correctly set VertexBuffer.format
Fixes #1137. Maybe.
2022-07-21 09:50:33 +01:00
Jonathan Coates
b28c1ac8e0
Test various time locales exist
Not clear if we can really test their behaviour too much.

See 69b211b4fb.
2022-07-21 09:44:40 +01:00
Jonathan Coates
69b211b4fb
Fix name of "ingame" time locale
This has been here since 1.17 :D. Class rename gone wrong!
2022-07-21 09:44:36 +01:00
Jonathan Coates
48147fa61c
Don't use MultiBufferSource for monitors
We're doing lots of weird OpenGL shenangins anyway, so it doesn't make
sense to use it. Instead just draw directly using the Tesselator
BufferBuilder.

This might improve compatiability with Sodium/Rubidium. Please don't let
me know if it doesn't though - I really don't want to have to deal with
it any more.
2022-07-16 22:07:23 +01:00
Jonathan Coates
ba976f9a16
Fix monitor depth blocker being too small
This allowed you to see transparent blocks through the bottom/right
margins of the monitor when using the VBO renderer.
2022-07-16 22:07:15 +01:00
Luiz Krüger
969feb4a1c
ItemGroup info on getItemDetail (#1127) 2022-07-16 20:30:20 +00:00
Jonathan Coates
4a273ae8e5
Update to latest Forge
- Lots of refactoring/cleanup to Forge's events and client APIs.
   - Render types/layers for blocks are now set on the model rather than
     in code.

   - Models now can work with multiple render types. As this would
     massively complicate the implementation of the turtle item model, we
     now implement a much simpler version, which makes use of Forge's
     BakedModel.getRenderPasses to return a separate model for the core
     turtle and each upgrade.

 - Send monitor contents to players immediately when they start watching
   the chunk. ChunkWatchEvent.Watch is now fired from a more sensible
   location, so this is much easier to implement!
2022-07-16 19:08:11 +01:00
JackMacWindows
bd5de11ad5
Add WAV support to speaker program (#1112) 2022-07-09 08:59:35 +01:00
Jonathan Coates
5366fcb9c8
Point people towards the http.rules config option
Rather than blanket disabling http with http.enabled. I think it's still
useful to keep the option around, but hopefully make it clearer what the
ramifications are.
2022-07-08 22:13:39 +01:00
Jonathan Coates
6335e77da6
Add a code of conduct
Been meaning to do this for years, woops.
2022-07-08 22:08:50 +01:00
heap-underflow
4cfd0a2d1c
Fix off-by-1 error in generic inventory's getItemLimit() (#1131) 2022-07-08 07:44:13 +00:00
Jonathan Coates
be3a960273
Check for duplicate ids when registering channels
Should prevent #1130 occurring again. Possibly worth submitting a PR to
Forge for this too.
2022-07-08 08:27:37 +01:00
Jonathan Coates
f25a73b8f2
Fix packet ID conflict
Merge gone wrong I suspect. I should probably add a check for this.

Fixes #1130. Slightly embarassing that this has been around for 7
months.
2022-07-07 21:45:05 +01:00
Jonathan Coates
954254e7e4
Update Minecraft versions 2022-07-07 21:06:32 +01:00
Jonathan Coates
e906f3ebc3
Remove IArguments.releaseImmediate
Was deprecated pre-1.19, just forgot to remove it as part of the update.
2022-07-02 17:00:14 +01:00
Jonathan Coates
56f0e0674f
Fix term.blit failing on substrings
Hahah. Serves me right for trying to optimise too much. Fixes #1123.
2022-07-02 16:47:43 +01:00
Jonathan Coates
4e438df9ad
Update cct-javadoc
No longer warns about empty comments. Closes #1107.
2022-07-02 11:51:58 +01:00
Toad-Dev
51c3a9d8af
Fix z-fighting on bold printout borders.
- Changed page background to render as one quad, instead of two halves.
- Set page background to a z-offset that is between zeroth (potentially
  bold border) and subsequent background pages. Bold borders were at the
  same z-offset before.
2022-07-02 11:24:40 +01:00
Jonathan Coates
d967730085
Run the JSX transformer without type checking
Makes it run about twice as fast. Still irritatingly slow, though really
want to avoid making it incremental or anything.
2022-07-02 10:12:47 +01:00
Lupus590
d6afee8deb
Document setting up a gps constellation (#1070) 2022-07-02 10:09:38 +01:00
Jonathan Coates
41bddcab9f
Use shorter mod version when publishing to Modrinth
i.e. 1.100.8 rather than 1.19-1.100.8.
2022-07-02 09:10:45 +01:00
Jonathan Coates
b8d7695392
Merge pull request #1126 from JohnnyIrvin/mc-1.16.x
Spelling error Turtle API
2022-07-01 21:13:18 +01:00
Johnny Irvin
b7fa4102df
Fix spell err Turtle API Doc
* `throug` -> `through`
2022-07-01 09:19:11 -04:00
Jonathan Coates
92c613a7a2
Merge branch 'mc-1.18.x' into mc-1.19.x 2022-06-23 22:41:49 +01:00
Jonathan Coates
d2f94f2653
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-06-23 22:26:09 +01:00
Jonathan Coates
718111787c
Also propogate the Java launcher when copying tasks
We removed the config which ran all JavaExec tasks with the given
launcher, so need to override this again.

A little abusrd that this isn't done by Gradle, but there we go.
2022-06-23 22:24:53 +01:00
Jonathan Coates
bb0e449560
Switch over to using SLF4J
No bearing on MC, but allows us to drop the depenedency in other
projects (CCEmuX, eval.tweaked.cc, etc...)

I'd quite like to spin the core into a separate project which doesn't
depend on MC at all, but not worth doing right now.
2022-06-23 20:57:24 +01:00
Jonathan Coates
ee495b3359
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-06-23 20:53:37 +01:00
Jonathan Coates
d1e952770d
Bump version to 1.100.8 2022-06-23 20:44:14 +01:00
Jonathan Coates
2d30208631
Avoid early creation of tasks
Notionally speeds up the build a little, though not really noticable in
practice.
2022-06-23 20:44:14 +01:00
Jonathan Coates
03f50f9298
_Actually_ publish an API jar 2022-06-21 07:28:15 +01:00
Jonathan Coates
8fc7820a12
Sync each config type separately
Forge checks for early access now which is sensible, but given we
sidestep Forge's ConfigValue system anyway, not very useful for us :D:.

Fixes #1117
2022-06-20 19:58:10 +01:00
Jonathan Coates
1a0e3fc2fa
Use the Gradle shadow plugin to shade deps
Just saves us from having to worry about conflicts with other mods which
bundle Cobalt. This might make the transition to Jar-in-Jar easier too -
not sure yet!

Also produce an API jar - fixes #1060.
2022-06-20 19:54:35 +01:00
Jonathan Coates
6d5b13dbbc
Revert "Switch over to using SLF4J"
This reverts commit b7f698d6f7.

Apparently slf4j is on the classpath in dev but not in live. Will apply
this on 1.18 and later instead.
2022-06-20 19:52:23 +01:00
Jonathan Coates
f9f8233ef4
Some "improvements" to our Gradle script
- Switch to plugins { ... } imports for Forge (FG finally supports it!)

 - Use FG's new fg.component to clean up our Maven metadata instead. We
   also mark JEI as optional (using Gradle's registerFeature), which
   means we've no stray deps inside our POM any more.
2022-06-19 11:21:42 +01:00
Jonathan Coates
a2e3d9d9bd
Update JEI to 1.19
Fixes #1116
2022-06-19 11:17:31 +01:00
Jonathan Coates
b7f698d6f7
Switch over to using SLF4J
No bearing on MC, but allows us to drop the depenedency in other
projects (CCEmuX, eval.tweaked.cc, etc...)

I'd quite like to spin the core into a separate project which doesn't
depend on MC at all, but not worth doing right now.
2022-06-19 11:10:53 +01:00
Jonathan Coates
93f3cd4a53
Fix lock code being null for newly placed blocks
This causes an NPE when serialising or opening printers and disk drives.
Fixes #1109
2022-06-16 07:56:54 +01:00
Jonathan Coates
755f8eff93
Mark 1.19 as alpha-quality
I knew I had an option for this, I just forgot to flip it!
2022-06-12 16:46:43 +01:00
Jonathan Coates
a879efc3d0
Don't shade all of Netty in the CC:T jar
Fixes #1108. Let this be a lesson to all of us: don't update mods at
midnight after a 20h day while half-delirious.
2022-06-12 16:39:57 +01:00
Jonathan Coates
a913232e62
Merge branch 'mc-1.18.x' into mc-1.19.x 2022-06-10 00:04:35 +01:00
Jonathan Coates
557765d8f0
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-06-10 00:00:19 +01:00
Jonathan Coates
1e044aed68
Bump version to 1.100.6 2022-06-09 23:41:43 +01:00
Jonathan Coates
5382d34d29
Bump Forge version
Nothing major has changed, just at this point it's best to be on latest.
2022-06-09 23:34:46 +01:00
Jonathan Coates
cbbb34cdd4
Normalise language files again
Weblate keeps making things uppercase >_>
2022-06-09 08:43:19 +01:00
Jonathan Coates
8f7719a8dc
Update to Minecraft 1.19
Oh my, a same day release! Well, if we use the AoE timezone.

Entirely untested (well, aside from automated tests), I haven't even
launched a client. In my defence, its just past midnight and I've been
up since 4am.
2022-06-08 00:10:55 +01:00
Weblate
ca58e39707 Translations for Ukrainian
Co-authored-by: RobloMinerYT <svatoslatus2005@gmail.com>
2022-06-07 04:23:27 +00:00
Weblate
0aac966239 Added translation for Ukrainian
Co-authored-by: RobloMinerYT <svatoslatus2005@gmail.com>
2022-06-06 11:55:10 +00:00
Jonathan Coates
0e1e8dfa8c
Add recipes to more pages
Might be better if we had pages for each block, but this'll do for now.
2022-06-05 12:20:07 +01:00
Jonathan Coates
a1cbc1d803
Fix turtles not preserving their lock when moving 2022-06-04 15:30:42 +01:00
Jonathan Coates
0b6dc25607
Fix command quoting for Windows
Thanks Lupus for finding this. I really need to redo how some of these
commands are run - maybe use npm scripts instead.
2022-06-01 14:33:23 +01:00
Jonathan Coates
b91809bfc7
Move some eldritch horrors to another directory
Also fix make-doc.sh uploading the wrong file.
2022-06-01 01:02:26 +01:00
Jonathan Coates
178126725e
Add more eldritch horrors to the build system
- Add a basic data exporter to the test mod, run via a /ccexport
   command. This dumps all of CC's recipes, and the item icons needed to
   display those recipes.

 - Post-process our illuaminate HTML, applying several transforms:
    - Apply syntax highlighting to code blocks. We previously did this
      at runtime, so this shaves some bytes off the bundle.

    - Convert a mc-recipe custom element into a recipe grid using
      react/react-dom.

 - Add a recipe to the speaker page. I'll probably clean this up in the
   future (though someone else is free to too!), but it's a nice
   start and proof-of-concept.

I tried so hard here to use next.js and MDX instead of rolling our own
solution again, but it's so hard to make it play well with "normal"
Markdown, which isn't explicitly written for MDX.
2022-06-01 00:48:36 +01:00
Jonathan Coates
cd76425877
Tiny bits and bobs
Oh my, what good commit discipline!

 - Remove unused method in NetworkHandler.
 - Correctly pass the transformation to ComputerBorderRenderer.
2022-05-30 17:42:33 +01:00
Jonathan Coates
4411756b06
Use a queue rather than a set in TickScheduler
We now track whether a tile is enqueued or not via an atomic boolean on
the block entity itself, rather than using a hash set. This is
significantly faster (>10x).

This is mostly intended for monitors, as they're the only peripheral
likely to call TickScheduler.schedule lots of times (rather than modems,
which just invoke it when opening/closing a channel[^1])[^2]. This
change is enough to allow me to update 120 monitors each tick without
any major tearing.

[^1]: GPS does do this on each gps.locate call, so it will help there,
but modems are typically limited by other computers sending messages,
not peripheral calls themselves.

[^2]: Note that montitors implement their own change tracking, so still
only call this once per tick. But it's enough to introduce some latency!
2022-05-30 14:25:51 +01:00
Jonathan Coates
1fd57a874f
Send terminal text and colours separately
This gives us slightly better compression, as backgrounds will often be
a single run of colours while the foreground won't be.

In practice, this is rarely an issue, as most terminals are small, but
worth doing anyway.
2022-05-30 13:44:11 +01:00
Jonathan Coates
3f0704624e
Fix location of DFPWM test 2022-05-30 13:36:36 +01:00
Jonathan Coates
3b6cd783cb
Don't allow modems to be used in adventure mode
This (along with computer locking) should be Good Enough for BlanketCon.
2022-05-28 09:23:23 +01:00
Jonathan Coates
a07bba4ece
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-05-27 22:28:55 +01:00
Jonathan Coates
ab22726883
Preserve on-state of pocket computers
This is far less robust than block-based computers, but I don't think it
needs to be. Fixes #1097 Or closes? Unclear - I'm counting this as a
bug.
2022-05-27 22:23:04 +01:00
Jonathan Coates
2efad38f53
Allow computers and inventories to be locked
Just like vanilla locking, this isn't accessible in survival.

> "im retired! im retired!!", i continue to insist as i slowly shrink
> and transform into a corn cob.
2022-05-27 22:22:54 +01:00
Jonathan Coates
83a1af6526
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-05-27 18:55:51 +01:00
Drew Edwards
8b89d88d04
Allow other mods to provide extra item/block details (#1101) 2022-05-24 22:21:18 +01:00
Jonathan Coates
36635662f1
Merge pull request #1100 from Lemmmy/lemmmy/extendable-computer-screen
Make ComputerScreenBase methods extendable
2022-05-23 18:04:30 +01:00
Drew Edwards
bbc0afa111 Make ComputerScreenBase methods extendable 2022-05-23 17:13:17 +01:00
Drew Edwards
34dc915d57
Add validation to printer slots (#1099) 2022-05-23 16:02:12 +00:00
Jonathan Coates
24ed0ca723
Try to remove some flakiness in tests
- Make assertions a little more relaxed
 - Increase timeouts of computer tests (again :D:).
 - Log where we're up to in computer tests, to make tracking stalls a
   little easier
2022-05-23 10:26:18 +01:00
Jonathan Coates
5052718428
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-05-22 15:03:01 +01:00
Jonathan Coates
431e4c9419
Some reformatting to config comments
- Rewrap everything at 80 columns. To make this tolerable I'm using
   IDEA's language fragment support - hence the absurd line lengths.

 - Add full stops to all comments.

 - Clarify that HTTP rules are applied in-order.
2022-05-22 14:34:31 +01:00
Jonathan Coates
2639b84eb2
Deprecate IArguments.releaseImmediate
This is only ever defined (and called) within the ILuaMachine-specific
code. Not sure why I ever made this public.
2022-05-22 14:05:04 +01:00
Jonathan Coates
d631111610
Improvements to contribution generation
- Parse Co-authored-by lines too. There's several contributors (mostly
   via weblate, but a few GH ones too) who weren't credited otherwise.

 - Add support for git mailmap, remapping some emails to a canonnical
   username. This allows us to remove some duplicates - nobody needs
   both SquidDev and "Jonathan Coates."

   I'm not making this file public, as it contains email addresses. This
   does mean that CI builds will still contain the full list with
   duplicates.
2022-05-19 14:09:08 +01:00
Jonathan Coates
c981c75b7c
Merge pull request #1096 from FayneAldan/patch-1
Fix typo in documentation
2022-05-13 21:05:01 +01:00
Fayne Aldan
f05a539443
Fix typo in documentation 2022-05-13 13:41:52 -06:00
Jonathan Coates
d8a7ab540a
Merge pull request #1095 from Wojbie/mc-1.16.x
Add important leading /
2022-05-10 21:42:40 +01:00
Wojbie
a7536ea4fa Add important leading /
Fixes #1094
2022-05-10 22:30:10 +02:00
Chick Chicky
d9e75d7c47
Added parse_empty_array to textutils.unserialiseJSON (#1092)
Fixes #1089.
2022-05-08 09:53:02 +00:00
Jonathan Coates
78334c4cb1
Fix counts in /computercraft {turn-on,shutdown}
We were using the size of the selectors (which is normally 1) rather
than the number of computers.
2022-05-07 20:17:44 +01:00
JackMacWindows
f5f0c7990a
Add note about special JSON values in docs for textutils.unserializeJSON (#1058) 2022-05-07 10:10:25 +00:00
Jonathan Coates
87a1c1a525
Some minor documentation fixes
- Add a TOC to the Local IPs page.
 - Increase the echo delay in our speaker audio page to 1.5s. This
   sounds much better and is less clashy than 1s. Also add a
   sleep(0) (eww, I know) to fix timeouts on some browsers/computers.
 - Move Lua feature compat to a new "reference" section. Still haven't
   figured out how to structure these docs - open to any ideas really.
 - Mention FFmpeg as an option for converting to DFPWM (closes #1075).
 - Allow data-mount to override built-in files. See my comment in #1069.
2022-05-05 13:27:33 +01:00
Jonathan Coates
be45b718b3
Correctly mark reify as CLIENT 2022-05-05 00:23:38 +01:00
Jonathan Coates
ad2d1d6a05
Merge branch 'feature/optimise-timeouts' into mc-1.16.x 2022-05-04 18:29:08 +01:00
Jonathan Coates
65a7370db1
Rethink how computer timeouts are handled
Previously we would compute the current timeout flags every 128
instructions of the Lua machine. While computing these flags is
_relatively_ cheap (just get the current time), it still all adds up.

Instead we now set the timeout flags from the computer monitor/watchdog
thread. This does mean that the monitor thread needs to wake up more
often[^1] _if the queue is full_, otherwise we can sleep for 100ms as
before.

This does mean that pausing is a little less accurate (can technically
take up 2*period instead). This isn't great, but in practice it seems
fine - I've not noticed any playability issues.

This offers a small (but measurable!) boost to computer performance.

[^1]: We currently sleep for scaledPeriod, but we could choose to do less.
2022-05-04 12:33:14 +01:00
Jonathan Coates
03b0244084
Minor improvements to resetting code
- Reset state while the server is starting rather than once it has
   started. Hopefully fixes a weird issue where wireless modems wouldn't
   be "connected" on server startup.

 - Correctly reset the MainThread metrics on server start/stop.
2022-05-04 11:31:59 +01:00
Jonathan Coates
6322e72110
Add a test harness for ComputerThread
Geesh, this is nasty. Because ComputerThread is incredibly stateful, and
we want to run tests in isolation, we run each test inside its own
isolated ClassLoader (and thus ComputerThread instance).

Everything else is less nasty, though still a bit ... yuck. We also
define a custom ILuaMachine which just runs lambdas[^1], and some
utilities for starting those.

This is then tied together for four very basic tests. This is sufficient
for the changes I want to make, but might be nice to test some more
comprehensive stuff later on (e.g. timeouts after pausing).

[^1]: Which also means the ILuaMachine implementation can be changed by
other mods[^2], if someone wants to have another stab at LuaJIT :p.

[^2]: In theory. I doubt its possible in practice because so much is
package private.
2022-05-03 22:58:28 +01:00
Jonathan Coates
7ad6132494
Move VarargArguments factory to VarargArguments itself 2022-05-03 18:51:34 +01:00
Jonathan Coates
e2189535b8
Fix several thread-unsafe client registrations
Also remove deprecated usage of DeferredWorkQueue. Oh goodness, some of
this code is so old now.

Fixes #1084
2022-05-03 18:48:08 +01:00
Jonathan Coates
79467499e6
Use ByteBuffers in term.blit
This is about 5-6x faster than using a String as we don't need to
allocate and copy multiple times. In the grand scheme of things, still
vastly overshadowed by the Lua interpreter, but worth doing.
2022-05-03 12:47:34 +01:00
Jonathan Coates
074793090d
Fix Optifine detection
I really should have tested this. And not expected Optifine to be
normal.
2022-05-03 11:57:35 +01:00
Jonathan Coates
cbbab26bf3
Some minor documentation improvements
- Start making the summary lines for modules a little better. Just say
   what the module does, rather than "The X API does Y" or "Provides Y".
   There's still a lot of work to be done here.

 - Bundle prism.js on the page, so we can highlight non-Lua code.

 - Copy our local_ips wiki page to the main docs.
2022-05-02 17:49:32 +01:00
Jonathan Coates
9cb7091ce7
Fix several deprecated warnings 2022-05-02 16:21:56 +01:00
Sr_endi
e909e11e05
[1.16] Make blocks rotatable for structures (#1083) 2022-05-01 12:09:38 +01:00
JackMacWindows
6239dbe9ca
Add documentation on full list of 5.2/5.3 features (#1071) 2022-05-01 08:29:43 +01:00
Jonathan Coates
49601f0b7c
Bump Cobalt version
Oh deary me.
2022-04-29 22:35:41 +01:00
Jonathan Coates
caa412b7d2
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-04-28 20:27:48 +01:00
Jonathan Coates
9cb7a5bec7
Track owning entity when sending sounds
This allows us to sync the position to the entity immediately, rather
than the sound jumping about.

Someone has set up rick-rolling pocket computers (<3 to whoever did
this), and the lag on them irritates me enough to fix this.

Fixes #1074
2022-04-28 19:59:31 +01:00
Cloud Chagnon
118b89ea41
Fix off by one error in printout renderer
Fixes printouts being drawn slightly offset to the left in all cases,
noticeable mainly when in item frames.
2022-04-28 17:42:04 +01:00
Jonathan Coates
f2474bbfa2
Remove redundant class 2022-04-28 17:41:07 +01:00
Jonathan Coates
159f90896e
Merge branch 'mc-1.16.x' into mc-1.18.x 2022-04-27 13:52:11 +01:00
Jonathan Coates
f108ba93af
Bump version to 1.100.5
> Modulo any game-breaking bugs [...] this will be the last CC: Tweaked
> release.

Terrible performance is game-breaking right? Or am I just petty?
2022-04-27 13:46:55 +01:00
Jonathan Coates
2a4f75ba15
Use Forge's new sound stream API
- Bump Forge version to latest RB.
 - Generate an 8-bit audio stream again, as we no longer need to be
   compatible with MC's existing streams.

No functionality changes, just mildly less hacky.
2022-04-27 10:59:28 +01:00
Jonathan Coates
ad228e94a3
Merge remote-tracking branch 'origin/mc-1.16.x' into mc-1.16.x
I hate doing this, but I have too many merges in progress to rebase.
2022-04-26 22:43:22 +01:00
Jonathan Coates
42b98bce28
Reset the BufferUploader state on Linux
GlStateManager.glDeleteBuffers clears a buffer before deleting it on
Linux - I assume otherwise there's memory leaks on some drivers? - which
clobbers BufferUploader's cache. Roll our own version which resets the
cache when needed.

Also always reset the cache when deleting/creating a DirectVertexBuffer.
2022-04-26 22:39:34 +01:00
Jonathan Coates
59e3608d2a
Merge branch 'mc-1.16.x' into mc-1.18.x
I was right: I did not enjoy this.
2022-04-26 22:17:42 +01:00
Jonathan Coates
fccca22d3f
Merge branch 'feature/font-rendering-optimise' into mc-1.16.x
This /significantly/ improves performance of the VBO renderer (3fps to
80fps with 120 constantly changing monitors) and offers some minor FPS
improvements to the TBO renderer.

This also makes the 1.16 rendering code a little more consistent with
the 1.18 code, cleaning it up a little in the process.

Closes #1065 - this is a backport of those changes for 1.16. I will
merge these changes into 1.18, as with everything else (oh boy, that'll
be fun).

Please note this is only tested on my machine right now - any help
testing on other CPU/GPU configurations is much appreciated.
2022-04-26 21:43:53 +01:00
Jonathan Coates
4bfdb65989
Use VBO renderer when Optifine is installed
Historically I've been reluctant to do this as people might be running
Optifine for performance rather than shaders, and the VBO renderer was
significantly slower when monitors were changing.

With the recent performance optimisations, the difference isn't as bad.
Given how many people ask/complain about the TBO renderer and shaders, I
think it's worth doing this, even if it's not as granular as I'd like.

Also changes how we do the monitor backend check. We now only check for
compatibility if BEST is selected - if there's an override, we assume
the user knows what they're doing (a bold assumption, if I may say so
myself).
2022-04-26 21:43:21 +01:00
Jonathan Coates
22e8b9b587
Don't render cursors separately
- For TBOs, we now pass cursor position, colour and blink state as
   variables to the shader, and use them to overlay the cursor texture
   in the right place.

   As we no longer need to render the cursor, we can skip the depth
   buffer, meaning we have to do one fewer upload+draw cycle.

 - For VBOs, we bake the cursor into the main VBO, and switch between
   rendering n and n+1 quads. We still need the depth blocker, but can
   save one upload+draw cycle when the cursor is visible.

This saves significant time on the TBO renderer - somewhere between 4
and 7ms/frame, which bumps us up from 35 to 47fps on my test world (480
full-sized monitors, changing every tick). [Taken on 1.18, but should be
similar on 1.16]
2022-04-26 21:43:21 +01:00
Jonathan Coates
77a00b14ae
Use UBOs for the TBO renderer
Like #455, this sets our uniforms via a UBO rather than having separate
ones for each value. There are a couple of small differences:

 - Have a UBO for each monitor, rather than sharing one and rewriting it
   every monitor. This means we only need to update the buffer when the
   monitor changes.

 - Use std140 rather than the default layout. This means we don't have
   to care about location/stride in the buffer.

Also like #455, this doesn't actually seem to result in any performance
improvements for me. However, it does make it a bit easier to handle a
large number of uniforms.

Also cleans up the generation of the main monitor texture buffer:

 - Move buffer generation into a separate method - just ensures that it
   shows up separately in profilers.
 - Explicitly pass the position when setting bytes, rather than
   incrementing the internal one. This saves some memory reads/writes (I
   thought Java optimised them out, evidently not!). Saves a few fps
   when updating.
 - Use DSA when possible. Unclear if it helps at all, but nice to do :).
2022-04-26 21:43:21 +01:00
Jonathan Coates
78aa757549
Memorize getRenderBoundingBox
This takes a non-trivial amount of time on the render thread[^1], so
worth doing.

I don't actually think the allocation is the heavy thing here -
VisualVM says it's toWorldPos being slow. I'm not sure why - possibly
just all the block property lookups? [^2]

[^1]: To be clear, this is with 120 monitors and no other block entities
with custom renderers. so not really representative.

[^2]: I wish I could provide a narrower range, but it varies so much
between me restarting the game. Makes it impossible to benchmark
anything!
2022-04-26 21:43:21 +01:00
Jonathan Coates
1196568a7c
Use Ű̶̹̚n̵̦̂́s̷̭̲͐a̶̞͔̔f̸̠́̀e̵͔̋̀ to upload the monitor's contents
The VBO renderer needs to generate a buffer with two quads for each
cell, and then transfer it to the GPU. For large monitors, generating
this buffer can get quite slow. Most of the issues come from
IVertexBuilder (VertexConsumer under MojMap) having a lot of overhead.

By emitting a ByteBuffer directly (and doing so with Unsafe to avoid
bounds checks), we can improve performance 10 fold, going from
3fps/300ms for 120 monitors to 111fps/9ms.

See 41fa95bce4 and #1065 for some more
context and other exploratory work. The key thing to note is we _need_ a
separate version of FWFR for emitting to a ByteBuffer, as introducing
polymorphism to it comes with a significant performance hit.
2022-04-26 21:43:21 +01:00
Jonathan Coates
48c4f397f9
Backport some text rendering code from 1.18
- Move all RenderType instances into a common class.

Cherry-picked from 41fa95bce4:
 - Render GL_QUADS instead of GL_TRIANGLES.

 - Remove any "immediate mode" methods from FWFR. Most use-cases can be
   replaced with the global MultiBufferSource and a proper RenderType
   (which we weren't using correctly before!).

   Only the GUI code (WidgetTerminal) needs to use the immediate mode.

 - Pre-convert palette colours to bytes, storing both the coloured and
   greyscale versions as a byte array.

Cherry-picked from 3eb601e554:
 - Pass lightmap variables around the various renderers. Fixes #919 for
   1.16!
2022-04-26 17:56:43 +01:00
Jonathan Coates
8871f40ced
Move FWFR into a separate package
Just a precursor to doing any work on it.
2022-04-26 16:27:49 +01:00
Jonathan Coates
aa62c1f206
Remove redundant CSS in src/web/styles.css
Moved to illuaminate itself
2022-04-26 16:20:04 +01:00
Jonathan Coates
fd32b06d6f
Merge pull request #1078 from Hasaabitt/patch-1
Fixed typo
2022-04-24 22:51:21 +01:00
Hasaabitt
739d6813c0
Fixed typo
"Instead, it is a standard program, which its API into the programs that it launches."
becomes
"Instead, it is a standard program, which injects its API into the programs that it launches."
2022-04-24 16:56:31 -04:00
Jonathan Coates
daf81b897a
Use vector helpers to convert BlockPos to Vector3d
A little shorter and more explicit than constructing the Vector3d
manually. Fixes an issue where sounds were centered on the bottom left
of speakers, not the middle (see cc-tweaked/cc-restitched#85).
2022-04-22 09:30:04 +01:00
Jonathan Coates
e865d96f7b
Fix some typos in the colors API
Closes #1072
2022-04-16 21:14:43 +01:00
Jonathan Coates
79b1872cab
Fall back to the given side if the internal one isn't provided
See #1061, closes #1064.

Nobody ever seems to implement this correctly (though it's better than
1.12, at least we've not seen any crashes), and this isn't a fight I
care enough about fighting any more.
2022-04-08 10:12:41 +01:00
Jonathan Coates
41fa95bce4
Cleanup and optimise terminal rendering (#1057)
- Remove the POSITION_COLOR render type. Instead we just render a
   background terminal quad as the pocket computer light - it's a little
   (lot?) more cheaty, but saves having to create a render type.

 - Use the existing position_color_tex shader instead of our copy. I
   looked at using RenderType.text, but had a bunch of problems with GUI
   terminals. Its possible we can fix it, but didn't want to spend too
   much time on it.

 - Remove some methods from FixedWidthFontRenderer, inlining them into
   the call site.

 - Switch back to using GL_QUADS rather than GL_TRIANGLES. I know Lig
   will shout at me for this, but the rest of MC uses QUADS, so I don't
   think best practice really matters here.

 - Fix the TBO backend monitor not rendering monitors with fog.
 
   Unfortunately we can't easily do this to the VBO one without writing
   a custom shader (which defeats the whole point of the VBO backend!),
   as the distance calculation of most render types expect an
   already-transformed position (camera-relative I think!) while we pass
   a world-relative one.

 - When rendering to a VBO we push vertices to a ByteBuffer directly,
   rather than going through MC's VertexConsumer system. This removes
   the overhead which comes with VertexConsumer, significantly improving
   performance.

 - Pre-convert palette colours to bytes, storing both the coloured and
   greyscale versions as a byte array. This allows us to remove the
   multiple casts and conversions (double -> float -> (greyscale) ->
   byte), offering noticeable performance improvements (multiple ms per
   frame).

   We're using a byte[] here rather than a record of three bytes as
   notionally it provides better performance when writing to a
   ByteBuffer directly compared to calling .put() four times. [^1]

 - Memorize getRenderBoundingBox. This was taking about 5% of the total
   time on the render thread[^2], so worth doing.

   I don't actually think the allocation is the heavy thing here -
   VisualVM says it's toWorldPos being slow. I'm not sure why - possibly
   just all the block property lookups? [^2]

Note that none of these changes improve compatibility with Optifine.
Right now there's some serious issues where monitors are writing _over_
blocks in front of them. To fix this, we probably need to remove the
depth blocker and just render characters with a z offset. Will do that
in a separate commit, as I need to evaluate how well that change will
work first.

The main advantage of this commit is the improved performance. In my 
stress test with 120 monitors updating every tick, I'm getting 10-20fps
[^3] (still much worse than TBOs, which manages a solid 60-100).

In practice, we'll actually be much better than this. Our network
bandwidth limits means only 40 change in a single tick - and so FPS is
much more reasonable (+60fps).

[^1]: In general, put(byte[]) is faster than put(byte) multiple times.
Just not clear if this is true when dealing with a small (and loop
unrolled) number of bytes.

[^2]: To be clear, this is with 120 monitors and no other block entities
with custom renderers. so not really representative.

[^3]: I wish I could provide a narrower range, but it varies so much
between me restarting the game. Makes it impossible to benchmark
anything!
2022-04-02 10:54:03 +01:00
Jonathan Coates
2a92794da3
Merge pull request #1055 from bclindner/mc-1.16.x
Documentation fix for rednet.broadcast
2022-03-27 17:40:33 +01:00
Brian C. Lindner
b3e009cca5
doc fix 2022-03-27 16:12:42 +00:00
Jonathan Coates
ba7598c689
Merge branch 'mc-1.17.x' into mc-1.18.x 2022-03-23 08:40:25 +00:00
Jonathan Coates
70c5cbafec
Merge branch 'mc-1.16.x' into mc-1.17.x 2022-03-23 08:39:39 +00:00
Jonathan Coates
2c64186965
Bump version to 1.100.4 2022-03-23 08:36:09 +00:00
Jonathan Coates
7731759c77
Bump Forge version one more time 2022-03-23 08:34:57 +00:00
Jonathan Coates
e6339b2847
Update to Forge's latest registry API
Forge 4.0.18 deprecated a lot of methods and moved where
RegistryEvent.NewRegistry lives, so we needed to update. This does break
the CC API a little bit (sorry!) though given Forge 1.18.2 is still in
flux, that's probably inevitable.
2022-03-19 08:45:14 +00:00
Jonathan Coates
31ba17d085
Don't wait for the chunk to be loaded when checking for monitors
There's a couple of alternative ways to solve this. Ideally we'd send
our network messages at the same time as MC does
(ChunkManager.playerLoadedChunk), but this'd require a mixin.

Instead we just rely on the fact that if the chunk isn't loaded,
monitors won't have done anything and so we don't need to send their
contents!

Fixes #1047, probably doesn't cause any regressions. I've not seen any
issues on 1.16, but I also hadn't before so ¯\_(ツ)_/¯.
2022-03-18 19:59:02 +00:00
Jonathan Coates
6353e8d930
Merge branch 'mc-1.16.x' into mc-1.17.x 2022-03-03 10:45:25 +00:00
Jonathan Coates
78cce4981a
Merge branch 'mc-1.17.x' into mc-1.18.x 2022-03-03 10:45:25 +00:00
Jonathan Coates
97c953a9be
Fix not running the test server during a build 2022-03-03 10:11:17 +00:00
Jonathan Coates
52df7cb8a4
Switch to Forge's game test system
It's now impossible to run the client tests (tests are still there, but
none of the other infrastructure is). We've not run these for months now
due to their severe flakiness :(.
2022-03-03 09:57:36 +00:00
Jonathan Coates
6735cfd12e
Update to 1.18.2
Did not enjoy, would not recommend.
2022-03-03 09:17:40 +00:00
Jonathan Coates
bcc7dd6991
Fix typo in Javadoc 2022-03-02 12:54:59 +00:00
Jonathan Coates
f994696161
Merge branch 'mc-1.17.x' into mc-1.18.x 2022-02-28 16:26:16 +00:00
Jonathan Coates
4a4e8bb4b6
Merge branch 'mc-1.16.x' into mc-1.17.x 2022-02-28 16:25:33 +00:00
Jonathan Coates
bd36185662
Bump version
Holding off until Forge releases for 1.18.2
2022-02-28 15:35:16 +00:00
Jonathan Coates
045c4fc88c
Merge pull request #1027 from Toad-Dev/issue-1026
Fix large file uploads producing oversized packets.
2022-02-28 11:06:59 +00:00
Jonathan Coates
e0fcc425c6
Prevent id map being null when file is empty
Fixes #1030
2022-02-28 11:01:04 +00:00
Jonathan Coates
e01895d719
Remove turtle_player EntityType
This was added in the 1.13 update and I'm still not sure why. Other mods
seem to get away without it, so I think it's fine to remove.

Also remove the fake net manager, as that's part of Forge nowadays.

Fixes #1044.
2022-02-28 10:34:41 +00:00
Jonathan Coates
87b38f4249
Fix incorrect recipe name in turtle advancement 2022-02-28 10:32:33 +00:00
Toad-Dev
60d1d1bb18 Fix large file uploads producing oversized packets.
- Fixes #1026
- The remaining bytes counter wasn't being decremented, so the code that
  splits off smaller packets was unreachable. Thus all file slices were
  being put into a single UploadFileMessage packet.
2022-01-23 22:31:27 -08:00
Jonathan Coates
cdf8b77ffd
Merge pull request #1017 from Possseidon/patch-1
Fix table with mouse button codes in documentation.
2022-01-20 12:40:09 +00:00
Possseidon
e2ce52fe81
Fix table with mouse button codes.
Codes for right and middle mouse buttons were swapped.
2022-01-19 17:39:19 +01:00
Jonathan Coates
9edce36efd
Merge branch 'mc-1.17.x' into mc-1.18.x 2022-01-14 23:01:12 +00:00
Jonathan Coates
e05588c662
Merge branch 'mc-1.16.x' into mc-1.17.x 2022-01-14 23:00:17 +00:00
Jonathan Coates
9cf70b10ef
Bump version 2022-01-14 22:58:19 +00:00
Jonathan Coates
9ac8f3aeea
Fix wired modems having incorrect blockstate
Fixes #1010
2022-01-14 15:37:49 +00:00
Jonathan Coates
e191b08eb5
Use Guava instead of commons-codec for hex encoding
The latter was removed in 1.18 on the server side.

Fixes #1011.
2022-01-14 15:35:58 +00:00
Jonathan Coates
a1221b99e1
Remove debugging log line
Fixes #1014
2022-01-14 14:45:55 +00:00
Jonathan Coates
85bced6b1d
Merge pull request #1015 from Paspartout/patch-1
speaker_audio.md: Fix missing add/sum typo
2022-01-14 10:55:08 +00:00
Paspartout
fc4569e0cc
speaker_audio.md: Fix missing add/sum typo 2022-01-13 17:36:26 +01:00
Weblate
e7f08313d9 Translations for Danish
Co-authored-by: Christian L.W <christianlw@hotmail.dk>
Co-authored-by: Christian L.W. <christianlw@hotmail.dk>
2022-01-02 23:29:24 +00:00
Jonathan Coates
79366bf2f5
Merge branch 'mc-1.17.x' into mc-1.18.x 2022-01-01 15:41:24 +00:00
Jonathan Coates
413fa5bcc8
Merge branch 'mc-1.16.x' into mc-1.17.x 2022-01-01 15:41:05 +00:00
Jonathan Coates
79fc8237b6
Bump version to 1.100.1
My new years resolution is to make no more CC:T commits.
2022-01-01 15:36:03 +00:00
Jonathan Coates
9d50d6414c
Happy new year
Should be the last time I'll have to do this!
2022-01-01 00:09:34 +00:00
Jonathan Coates
16df86224b
Fix pocket speakers incorrectly detaching computers
- Fix UpgradeSpeakerPeripheral not calling super.detach (so old
   computers were never cleaned up)
 - Correctly lock computer accesses inside SpeakerPeripheral

Fixes #1003.

Fingers crossed this is the last bug. Then I can bump the year and push
a new release tomorrow.
2021-12-31 18:24:54 +00:00
Jonathan Coates
a9519f68a1
Clarify term_resize event
Closes #1000, fixes #999.

Co-authored-by: Wojbie <Wojbie@gmail.com>
2021-12-31 18:16:36 +00:00
Jonathan Coates
f1a08a3362
Merge pull request #1002 from Toad-Dev/issue-1001
Fix hasTypeRemote not working with additional types. (#1001)
2021-12-31 18:14:14 +00:00
Toad-Dev
802949d888 Fix hasTypeRemote not working with additional peripheral types.
Fixes #1001. Looks like the culprit was a simple typo.
2021-12-26 21:18:40 -08:00
Jonathan Coates
2b901f2d5e
Merge branch 'mc-1.17.x' into mc-1.18.x 2021-12-25 08:05:25 +00:00
Jonathan Coates
62f2cd5cb2
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-12-25 08:05:25 +00:00
Jonathan Coates
e558b31b2b
Fix some typos in a dfpwm example 2021-12-21 22:25:16 +00:00
Jonathan Coates
afd82fbf1f
Add speaker support to the documentation website
Happy to pick a different piece of audio, but this seemed like a fun one
to me.
2021-12-21 22:20:57 +00:00
Jonathan Coates
901d8d4c3b
Merge branch 'mc-1.17.x' into mc-1.18.x 2021-12-21 15:15:53 +00:00
Jonathan Coates
f794ce42ab
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-12-21 15:10:19 +00:00
Jonathan Coates
f470478a0f
Bump CC:T version to 1.100
We're still a few days away from release, but don't think anything else
is going to change. And I /really/ don't want to have to write this
changelog (and then merge into later versions) on the 25th.
2021-12-21 14:55:01 +00:00
Jonathan Coates
aa009df740
Improve fs API introduction
Again, not perfect, but better than a single sentence.
2021-12-21 14:39:08 +00:00
Jonathan Coates
0c6c0badde
Move turtle docs into the Java code instead
Yeah, should have seen that coming
2021-12-21 12:00:13 +00:00
Jonathan Coates
bed2e0b658
Write an introduction to the turtle API
It's better at least, I just don't know if it's good.
2021-12-21 11:53:46 +00:00
Jonathan Coates
0f9ddac83c
Copy and paste the wiki guide on require
I wrote the original, so I don't need to feel guilty :)

Closes #565.
2021-12-21 00:55:16 +00:00
Jonathan Coates
932b77d7ee
Rewrite several doc introductions
Mostly focussing on rednet and modem here. Not sure if I made them any
better, we'll see!
2021-12-21 00:27:07 +00:00
Jonathan Coates
5eedea1bbb
Don't push non-pushable entities
Fixes #949
2021-12-20 17:58:39 +00:00
Jonathan Coates
114261944a
Tick pocket computers in item entity form
See #995. And no, just because I'm adding this doesn't mean it's not a
terrible issue.
2021-12-20 17:37:42 +00:00
Jonathan Coates
4d10639efb
Use correct Java annotations package 2021-12-20 12:19:52 +00:00
Jonathan Coates
aa36b49c50
Enqueue audio when receiving it
While Minecraft will automatically push a new buffer when one is
exhausted, this doesn't help if there's only a single buffer in the
queue, and you end up with stutter.

By enquing a buffer when receiving sound we ensure there's always
something queued. I'm not 100% happy with this solution, but it does
alleviate some of the concerns in #993.

Also reduce the size of the client buffer to 0.5s from 1.5s. This is
still enough to ensure seamless audio when the server is running slow (I
tested at 13 tps, but should be able to go much worse).
2021-12-19 19:50:43 +00:00
Jonathan Coates
8a1067940d
Account for the game being paused when tracking sound progress
When the game is paused in SSP world, speakers are not ticked. However,
System.nanoTime() continues to increase, which means the next tick
speakers believe there has been a big jump and so schedule a bunch of
extra audio.

To avoid this, we keep track of how long the game has been paused offset
nanoTime by that amount.

Fixes #994
2021-12-19 16:29:06 +00:00
Jonathan Coates
2562642664
Re-add JEI integration 2021-12-18 11:42:22 +00:00
Jonathan Coates
632db1cfa5
Merge branch 'mc-1.17.x' into mc-1.18.x 2021-12-18 11:38:48 +00:00
Jonathan Coates
aa0d544bba
Remove MoreRed integration
It's not been updated to 1.17/1.18, nor touched since July. Can easily
be added back in if this changes.
2021-12-18 11:35:52 +00:00
Jonathan Coates
2f6ad00764
Use Java 16 ByteBuffer methods where possible 2021-12-18 11:34:44 +00:00
Jonathan Coates
05da4dd362
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-12-18 11:25:28 +00:00
Jonathan Coates
0477b2742c
Use duplicate() instead of rewind()
It's just more confusing having to keep track of where the ByteBuffer is
at. In this case, I think we were forgetting to rewind after computing
the digest.

Hopefully we'll be able to drop some of these in 1.17 as Java 16 has
a few more ByteBuffer methods

Fixes #992
2021-12-18 11:23:12 +00:00
Jonathan Coates
fe3c42ce22
Mark 1.17 (and 1.18) as stable 2021-12-17 16:44:29 +00:00
Jonathan Coates
f6fcba7a39
Merge branch 'mc-1.17.x' into mc-1.18.x 2021-12-14 20:13:53 +00:00
Jonathan Coates
82a7edee12
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-12-14 20:07:48 +00:00
Jonathan Coates
b048b6666d
Add arbitrary audio support to speakers (#982)
Speakers can now play arbitrary PCM audio, sampled at 48kHz and with a
resolution of 8 bits. Programs can build up buffers of audio locally,
play it using `speaker.playAudio`, where it is encoded to DFPWM, sent
across the network, decoded, and played on the client.

`speaker.playAudio` may return false when a chunk of audio has been
submitted but not yet sent to the client. In this case, the program
should wait for a speaker_audio_empty event and try again, repeating
until it works.

While the API is a little odd, this gives us fantastic flexibility (we
can play arbitrary streams of audio) while still being resilient in the
presence of server lag (either TPS or on the computer thread).

Some other notes:
 - There is a significant buffer on both the client and server, which
   means that sound take several seconds to finish after playing has
   started. One can force it to be stopped playing with the new
  `speaker.stop` call.

 - This also adds a `cc.audio.dfpwm` module, which allows encoding and
   decoding DFPWM1a audio files.

 - I spent so long writing the documentation for this. Who knows if it'll
   be helpful!
2021-12-13 22:56:59 +00:00
Jonathan Coates
e16f66e128
Some bits of rednet cleanup
- Remove all the hungrarian notation in variables. Currently leaving
   the format of rednet messages for now, while I work out whether this
   counts as part of the public API or not.

 - Fix the "repeat" program failing with broadcast packets. This was
   introduced in #900, but I don't think anybody noticed. Will be more
   relevant when #955 is implemented though.
2021-12-13 14:30:13 +00:00
Jonathan Coates
1cfad31a0d
Separate breaking progress for wired modems
This means that if the current player is breaking a cable/wired modem,
only the part they're looking at has breaking progress. Closes #355.

A mixin is definitely not the cleanest way to do this. There's a couple
of alternatives:

 - CodeChickenLib's approach of overriding the BlockRendererDispatcher
   instance with a delegating subclasss. One mod doing this is fine,
   several is Not Great.o

 - Adding a PR to Forge: I started this, and it's definitely the ideal
   solution, but any event for this would have a ton of fields and just
   ended up looking super ugly.
2021-12-13 13:30:43 +00:00
Jonathan Coates
7c373c6e06
Merge branch 'mc-1.17.x' into mc-1.18.x 2021-12-11 07:50:18 +00:00
Jonathan Coates
6196aae488
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-12-11 07:49:33 +00:00
Jonathan Coates
92a0ef2b75
Bump CC:T version 2021-12-11 07:37:10 +00:00
Jonathan Coates
57c5d19f95
Update to Forge 1.18.1 2021-12-11 07:31:41 +00:00
Jonathan Coates
1f6e0f287d
Ensure the origin monitor is valid too
Blurh, still not sure if this is Correct or anything, but have no clue
what's causing this. Fixes #985. Hopefully.
2021-12-10 13:13:31 +00:00
Jonathan Coates
0e4b7a5a75
Prevent terminal buttons stealing focus
I have shutdown my computer by accident far too many times now.
2021-12-08 23:16:53 +00:00
Jonathan Coates
47ad7a35dc
Fix NPE when pulling an event with no type
I assume people have broken coroutine dispatchers - I didn't think it
was possible to queue an actual event with no type.

See cc-tweaked/cc-restitched#31. Will fix it too once merged downstream!
2021-12-08 22:47:21 +00:00
Jonathan Coates
3eab2a9b57
Add support for a zero-copy Lua table
The API is entirely designed for the needs of the speaker right now, so
doesn't do much else.
2021-12-07 18:27:29 +00:00
Jonathan Coates
c4024a4c4c
Use an admonition instead 2021-12-02 22:41:58 +00:00
Jonathan Coates
f5fb82cd7d
Merge pull request #977 from MCJack123/patch-9
Add package.searchpath
2021-12-02 12:34:07 +00:00
Jonathan Coates
23c17075be
save -> saveAdditional
Also add in a janky workabround for handleUpdateTag not being called.
Being an early porter is always fun :D:.
2021-12-02 09:20:06 +00:00
MCJack123
e18ba8a2c2
Add package.searchpath 2021-12-01 18:55:24 -05:00
Jonathan Coates
87988a705b
Exclude Jetbrains annotations from testModExtra
testModExtra must /strictly/ be the set of dependencies which are not
present in implementation - there can't be any duplicates.

Yes, it's stupid, but the whole lazyToken("minecraft_classpath") thing
wasn't really built with this in mind, so not much we can do :)
2021-12-01 20:40:46 +00:00
Jonathan Coates
422bfdb60d
Add 1.18 and remove 1.15 from the issue template
No, we're not pushing it to Curse yet, but while I remember.
2021-12-01 20:24:37 +00:00
Jonathan Coates
1851ed31cd
Release keys when opening the offhand pocket computer screen
Opening a screen KeyBinding.releaseAll(), which forces all inputs to be
considered released. However, our init() function then calls
grabMouse(), which calls Keybinding.setAll(), undoing this work.

The fix we're going for here is to call releaseAll() one more time[^1]
after grabbing the mouse. I think if this becomes any more of a problem,
we should roll our own grabMouse which _doesn't_ implement any specific
behaviour.

Fixes #975

[^1]: Obvious problem here is that we do minecraft.screen=xyz rather
      than setScreen. We need to - otherwise we'd just hit a stack
      overflow - but it's not great.
2021-12-01 20:09:38 +00:00
Jonathan Coates
179da1d8cf
Update to MC 1.18
- Build fails right now due to module issues, so this won't be pushed
   to GitHub.
 - Monitors render transparently when loaded into the world. I don't
   think this is a 1.17 bug, so not sure what's going on here!
2021-11-30 22:48:38 +00:00
Jonathan Coates
92fd93c0e0
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-11-30 22:37:07 +00:00
Jonathan Coates
3929dba4a5
Only send update packets on the TEs which need it
More bits of #658
2021-11-30 22:01:09 +00:00
Jonathan Coates
af966179ce
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-11-29 19:40:05 +00:00
Jonathan Coates
5927e9bb10
Bump CC:T version 2021-11-29 18:54:54 +00:00
Jonathan Coates
53811f8169
Allow peripherals to have multiple types (#963)
Peripherals can now have multiple types:
 - A single primary type. This is the same as the current idea of a
   type - some identifier which (mostly) uniquely identifies this kind
   of peripheral. For instance, "speaker" or "minecraft:chest".

 - 0 or more "additional" types. These are more like traits, and
   describe what other behaviour the peripheral has - is it an
   inventory? Does it supply additional peripherals (like a wired
   modem)?.

This is mostly intended for the generic peripheral system, but it might
prove useful elsewhere too - we'll have to see!

 - peripheral.getType (and modem.getTypeRemote) now returns 1 or more
   values, rather than exactly one.
 - Add a new peripheral.hasType (and modem.hasTypeRemote) function which
   determines if a peripheral has the given type (primary or
   additional).
 - Change peripheral.find and all internal peripheral methods to use
   peripheral.hasType instead.
 - Update the peripherals program to show all types

This effectively allows you to do things like
`peripheral.find("inventory")` to find all inventories.

This also rewrites the introduction to the peripheral API, hopefully
making it a little more useful.
2021-11-29 17:37:30 +00:00
Jonathan Coates
298f339376
Invalidate peripherals during the computer's tick instead
- Capability invalidation and tile/block entity changes set a dirty bit
   instead of refetching the peripheral immediately.
 - Then on the block's tick we recompute the peripheral if the dirty bit
   is set.

Fixes #696 and probably fixes #882. Some way towards #893, but not
everything yet.

This is probably going to break things horribly. Let's find out!
2021-11-28 20:03:27 +00:00
Jonathan Coates
2418cfb87b
More instanceof pattern matching 2021-11-28 15:58:30 +00:00
Jonathan Coates
9d44f1ca66
Make capability invalidation callbacks less strict
Forge!! *shakes fist*.
2021-11-28 12:47:08 +00:00
Jonathan Coates
306e06a79a
Do not allow transferring into removed blocks
See #893.
2021-11-28 12:32:31 +00:00
Jonathan Coates
4f11549112
Remove space in fs API 2021-11-27 16:35:44 +00:00
Jonathan Coates
7f3490591d
Some fixes to the web-based emulator
- Bump copy-cat version to have support for initial files in
   directories and the blit fixes.
 - Add an example nft image and move example nfp into a data/ directory.
 - Fix nft parser not resetting colours on the start of each line.
2021-11-27 12:27:40 +00:00
Jonathan Coates
095101831c
Pin to an older ForgeGradle
This .25 is still borked I think
2021-11-27 09:34:20 +00:00
Jonathan Coates
7b7527ec80
Rewrite turtle upgrade registration to be more data driven (#967)
The feature nobody asked for, but we're getting anyway.

Old way to register a turtle/pocket computer upgrade:

    ComputerCraftAPI.registerTurtleUpgrade(new MyUpgrade(new ResourceLocation("my_mod", "my_upgrade")));

New way to register a turtle/pocket computer upgrade:

First, define a serialiser for your turtle upgrade type:

    static final DeferredRegister<TurtleUpgradeSerialiser<?>> SERIALISERS = DeferredRegister.create( TurtleUpgradeSerialiser.TYPE, "my_mod" );
    public static final RegistryObject<TurtleUpgradeSerialiser<MyUpgrade>> MY_UPGRADE =
        SERIALISERS.register( "my_upgrade", () -> TurtleUpgradeSerialiser.simple( MyUpgrade::new ) );
    SERIALISERS.register(bus); // Call in your mod constructor.

Now either create a JSON string or use a data generator to register your upgrades:

    class TurtleDataGenerator extends TurtleUpgradeDataProvider {
        @Override
        protected void addUpgrades( @Nonnull Consumer<Upgrade<TurtleUpgradeSerialiser<?>>> addUpgrade )
            simple(new ResourceLocation("my_mod", my_upgrade"), MY_UPGRADE.get()).add(addUpgrade);
        }
    }

See much better! In all seriousness, this does offer some benefits,
namely that it's now possible to overwrite or create upgrades via
datapacks.

Actual changes:
 - Remove ComputerCraftAPI.register{Turtle,Pocket}Upgrade functions.

 - Instead add {Turtle,Pocket}UpgradeSerialiser classes, which are used
   to load upgrades from JSON files in datapacks, and then read/write
   them to network packets (much like recipe serialisers).

 - The upgrade registries now subscribe to datapack reload events. They
   find all JSON files in the
   data/$mod_id/computercraft/{turtle,pocket}_upgrades directories,
   parse them, and then register them as upgrades.

   Once datapacks have fully reloaded, these upgrades are then sent over
   the network to the client.

 - Add data generators for turtle and pocket computer upgrades, to make
   the creation of JSON files a bit easier.

 - Port all of CC:T's upgrades over to use the new system.
2021-11-26 23:36:02 +00:00
Lupus590
8ffd45c66e
"cc.pretty".pretty_print shortcut function (#965) 2021-11-26 21:13:15 +00:00
Jonathan Coates
e247bd823e
Bump Gradle and Kotlin versions
I think we need this for 1.18
2021-11-26 21:12:20 +00:00
Jonathan Coates
276956eed8
Fix command block config not being read 2021-11-26 20:58:58 +00:00
Jonathan Coates
a4c5ecf8df
Don't specify the version number in mods.toml 2021-11-25 14:54:32 +00:00
Jonathan Coates
99de00e16e
Remove craft tweaker integration 2021-11-25 13:36:33 +00:00
Jonathan Coates
600227e481
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-11-25 13:34:19 +00:00
Jonathan Coates
18d66bd727
Add dimension parameter to commands.getBlockInfo{,s}
Closes #130. Worth noting it doesn't add an additional argument to
getBlockPosition - want to leave that off for now.
2021-11-24 19:31:54 +00:00
Jonathan Coates
d3563a3854
Cleanup resource mount reloading
- Subscribe to the "on add reload listener" event, otherwise we don't
   get reloads beyond the first one! This means we no longer need to
   cast the resource manager to a reloadable one.
 - Change the mount cache so it's keyed on path, rather than "path ✕
   manager".
 - Update the reload listener just to use the mount cache, rather than
   having its own separate list. I really don't understand what I was
   thinking before.
2021-11-24 19:07:12 +00:00
Jonathan Coates
c2dc8bf675
Rewrite monitor resizing
- Some improvements to validation of monitors. This rejects monitors
   with invalid dimensions, specifically those with a width or height
   of 0. Should fix #922.

 - Simplify monitor collapsing a little. This now just attempts to
   resize the four "corner" monitors (where present) and then expands
   them if needed. Fixes #913.

 - Rewrite monitor expansion so that it's no longer recursive. Instead
   we track the "origin" monitor and replace it whenever we resize to
   the left or upwards.

   Also add a upper bound on the loop count, which should prevent things
   like #922 happening again. Though as mentioned above, validation
   should prevent this anyway.

 - Some small bits of cleanup to general monitor code.

I have absolutely no confidence that this code is any better behaved
than the previous version. Let's find out I guess!
2021-11-24 13:35:57 +00:00
Jonathan Coates
603119e1e6
Replace magic values with Forge constants
Gonna have to replace these in 1.17 as Minecraft exposes these by
default!
2021-11-23 21:17:34 +00:00
Jonathan Coates
d9b3f17b52
Add a debug overlay for monitors and turtles
Monitors is probably the more useful thing here (well, for me at
least). It is a _debug_ overlay after all :p.
2021-11-23 21:14:06 +00:00
Jonathan Coates
993bccc51f
Resort language files
Slightly annoying that weblate keeps getting this wrong. I don't think
any of the addons allow me to enforce an ordering either.
2021-11-23 19:48:47 +00:00
Weblate
96d3b27064 Translations for Korean
Co-authored-by: E. Kim <mindy15963@naver.com>
2021-11-23 19:43:15 +00:00
Jonathan Coates
f33f57ea35
Allow generic peripherals to specify a custom source
- Add a new GenericPeripheral interface. We don't strictly speaking
   need this - could put this on GenericSource - but the separation
   seems cleaner.

 - GenericPeripheral.getType() returns a new PeripheralType class, which
   can either be untyped() or specify a type name. This is a little
   over-engineered (could just be a nullable string), but I'm planning
   to allow multiple types in the future, so want some level of
   future-proofing.

 - Thread this PeripheralType through the method gathering code and
   expose it to the GenericPeripheralProvider, which then chooses an
   appropriate name.

   This is a little ugly (we're leaking information about peripherals
   everywhere), but I think is fine for now. It's all private internals
   after all!

Closes #830
2021-11-22 18:05:13 +00:00
Jonathan Coates
070479d901
Make executeMainThreadTask a default method
- Move TaskCallback into the API and make it package private. This
   effectively means it's not an API class, just exists there for
   convenience reasons.
 - Replace any usage of TaskCallback.make with
   ILuaContext.executeMainThreadTask.
 - Some minor formatting/checkstyle changes to bring us inline with
   IntelliJ config.
2021-11-21 11:19:02 +00:00
Jonathan Coates
2fe40f669d
Don't send packets when the server is stopping
Fixes #956
2021-11-20 23:20:27 +00:00
Jonathan Coates
1b39c9f470
Bump various package versions 2021-11-20 23:20:12 +00:00
Weblate
814d5cbcd1 Translations for Italian
Co-authored-by: Alessandro <ale.proto00@gmail.com>
2021-11-17 14:24:23 +00:00
Anavrins
4d8862c78e
Optimize peripheral calls in rednet.run (#954) 2021-11-14 06:57:47 +00:00
Weblate
6cc2f035db Translations for Japanese (ja_jp)
Co-authored-by: MORIMORI0317 <morimori.0317@outlook.jp>
2021-11-13 06:24:20 +00:00
Jonathan Coates
cf3f1d3d48
Add correct tool to CC computers
Also rerun data generators, forgot to do it as part of the previous
commit.

Fixes #953
2021-11-03 09:40:30 +00:00
Jonathan Coates
bca964629a
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-11-03 09:34:21 +00:00
Jonathan Coates
ea7a218f4a
Make turtle breaking a little more data driven
- Allow any tool to break an "instabreak" block (saplings, plants,
   TNT). Oddly this doesn't include bamboo or bamboo sapings (they're
   marked as instabreak, only to have their strength overridden again!),
   so we also provide a tag for additional blocks to allow.

 - Hoes and shovels now allow breaking any block for which this tool is
   effective.

 - Use block tags to drive any other block breaking capabilities. For
   instance, hoes can break pumpkins and cactuses despite not being
   effective.

This should get a little nicer in 1.17, as we can just use block tags
for everything.
2021-10-27 19:32:58 +01:00
Jonathan Coates
544bcaa599
Clear the entity drop list as well as cancelling
Fixes #940
2021-10-24 19:11:21 +01:00
Jonathan Coates
ab6b861cd6
Move repo to cc-tweaked org
Let's see how this goes.
 - Update references to the new repo
 - Use rrsync on the server, meaning make-doc.sh uploads relative to the
   website root.
 - Bump Gradle wrapper to 7.2. Not related to this change, but possibly
   fixes running under Java 16. Possibly.
2021-10-17 18:14:32 +01:00
Jonathan Coates
72e8fc03d3
Fix upload bandwidth limit not being set
Lol, woops.
2021-10-13 17:56:12 +01:00
Jonathan Coates
0e94355a85
Some post-1.17 cleanup
- Fix broken Javadoc references
 - Apply a couple of refactoring suggestions from IDEA
2021-10-13 17:46:29 +01:00
Jonathan Coates
482ae0d22e
Fix recipe book upgrade recipes
- Flip turtle/pocket and upgrade item.
 - Correctly set NBT on pocket upgrade recipe output.
2021-10-11 12:17:45 +01:00
Jonathan Coates
6dd33f7099
Play sounds using ResourceLocation rather than SoundEvent
The latter is not registered when sounds are added via resource packs.

Fixes #938. Probably.
2021-10-10 22:35:45 +01:00
Jonathan Coates
045472577a
Improve motd a hundred fold
Yes, I know this is a terrible feature. But it's been a long week and
I'm so tired.

Also fix the ordering in motd_spec. Who thought putting the month first
was reasonable?
2021-10-08 20:49:37 +01:00
JackMacWindows
9f539dbd59
Add about program for easier version identification (#936) 2021-10-08 11:29:52 +01:00
Jonathan Coates
ca367e7cc7
Don't run client tests on CI
Kinda sucks, but they're so inconsistent between platforms right now,
and I cannot be bothered to get CI working. It only needs to work on my
machine.
2021-10-07 11:51:18 +01:00
Weblate
f6fd0ad172 Translations for Russian (ru_ru)
Translations for French

Translations for English

Co-authored-by: SquidDev <git@squiddev.cc>
2021-10-07 10:25:23 +00:00
Jonathan Coates
0d35331b82
Default to Java 16 in the gitpod environment 2021-10-06 18:52:36 +01:00
Jonathan Coates
076b454c8f
Also convert the turtle model key to a record 2021-10-06 18:40:33 +01:00
Jonathan Coates
36e0dcbad0
Change network packet to a record
Look at all that code we can delete!
2021-10-06 18:38:51 +01:00
Jonathan Coates
0b5fe990e5
Bump Forge version
- Clean up NBT constants, replace with built-in ones
 - Switch over to the new capability system
2021-10-06 18:28:28 +01:00
Jonathan Coates
29ece2a6e3
Don't run client tests on CI
Kinda sucks, but they're so inconsistent between platforms right now,
and I cannot be bothered to get CI working. It only needs to work on my
machine.
2021-10-06 18:23:38 +01:00
Jonathan Coates
eba26dedab
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-10-06 18:10:45 +01:00
Weblate
13779d6ad3 Translations for French
Translations for German

Co-authored-by: SquidDev <bonzoweb@hotmail.co.uk>
2021-10-06 16:09:38 +00:00
Jonathan Coates
d700f1f500
Bump the image comparison threshold again
Not sure what the right long-term solution is here. An alternative image
comparison? Take multiple screenshots?
2021-10-03 11:21:37 +01:00
i develop things
06bf84f151
Make color arguments to term.blit case-insensitive (#929) 2021-10-03 11:11:31 +01:00
Jonathan Coates
8ba20985d7
Store additional state in WiredModemPeripheral
This means wired peripherals now correctly track their current mounts
and attached state, rather than inheriting from the origin wired modem.

Closes #890
2021-09-27 22:18:32 +01:00
JackMacWindows
7bb7b5e638
Make Rednet deduplication more efficient (#925) 2021-09-26 21:15:37 +01:00
Alessandro
297426419b
Fix computer IDs greater than 65535 crashing Rednet (#900) 2021-09-26 17:13:26 +01:00
Jonathan Coates
eb61c5c5d7
Add a overly-complex test harness for rednet
Allows us to run multiple "computers" in parallel and send messages
betwene them. I don't think this counts as another test framework, but
it's sure silly.
2021-09-26 16:45:23 +01:00
Jonathan Coates
cf2bc667c1
Add more tests for monitor and printout rendering 2021-09-26 11:10:41 +01:00
Jonathan Coates
c8449086ee
Optimise CC:T logo 2021-09-26 10:26:42 +01:00
Jonathan Coates
662bead8be
Several fixes and improvements for client tests
- Fix broken /cctest marker
 - Correctly wait for the screenshot to be taken before continuing.
 - Filter out client tests in a different place, meaning we can remove
   the /cctest runall command
 - Bump kotlin version
2021-09-26 09:48:58 +01:00
Jonathan Coates
acaa61a720
Make the monitor depth blocker slightly larger 2021-09-25 16:46:37 +01:00
Jonathan Coates
5facbca2b3
Merge pull request #927 from MCJack123/patch-8
Added binary flag to websocket_message docs
2021-09-23 20:34:21 +01:00
JackMacWindows
6c6b2c2ff3
Added binary flag to websocket_message docs 2021-09-23 15:20:19 -04:00
Jonathan Coates
3eb601e554
Pass lightmap variables around various renderers
- Add lightmap parameters to the text, computer and printout renderers.

 - Printouts are always rendered using the current lightmap. When
   interacting with the GUI, we use the fullbright lightmap coordinate.

 - Pocket computers render their border using the lightmap. Terminal and
   light do not use the lightmap at all.

There's some funkiness going on here with render types - it appears the
"correct" position_color_tex_lightmap render type is actually one used
for text.

Fixes #919. This bug does occur on 1.16 too, but given how complex the
rendering changes are between 1.16 and 1.17 I do /not/ want to have to
implement this twice. Sorry.
2021-09-19 15:49:31 +01:00
Jonathan Coates
d0e79f310e
Bump Forge version
Not much has changed, just some cleanup.
2021-09-19 11:57:37 +01:00
Jonathan Coates
0d6528aaf0
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-09-19 11:38:25 +01:00
MAGGen-hub
647902c019
Allow using mouse in off-hand pocket computer screen (#918) 2021-09-19 11:24:55 +01:00
Jonathan Coates
2aa70b49c1
Add invisible slots to computer GUIs
This ensures inventory slots are synced while the container is open,
meaning the hotbar (which is visible underneath the GUI) correctly
updates.

Fixes #915
2021-09-19 11:18:24 +01:00
Jonathan Coates
b17ab16e05
Allow the user to opt in to client tests 2021-09-19 10:43:55 +01:00
Jonathan Coates
b447b0e308
Increase memory limit of the gradle daemon
This has been standard in the mdk for a while, but never actually had to
do this before. IntelliJ finally started hitting this limit when
decompiling.
2021-09-18 12:42:36 +01:00
Wojbie
94ad106272
Several improvements to textutils.serialise (#920)
- Handle nan and infinity, by emitting them as 0/0 and 0/1.
- Differentiate between repeated and recursive tables in the
  error message.
2021-09-17 10:30:23 +01:00
xXTurner
dc9edf26ec
Fixed typo in the javadoc of CommandsAPI class (#924) 2021-09-15 19:35:32 +01:00
Jonathan Coates
048c7bda23
Allow opening pocket computers without rendering a terminal
When placed in the off hand, pocket computers now render a different
screen when opened in the off-hand, just rendering text at the top of
the screen rather than "opening" the whole computer.

This means you can view the world and computer in your hand at the
same time, effectively allowing you to emulate the
Plethora/MoarPeripherals keyboard (and much more).

This currently requires you to move the pocket computer to the other
hand to open it normally. I did look into allowing for shift+right click
to open normally, but this is awkward when you're looking at a something
like a monitor - you need to shift as otherwise you'd click the block!

Plethora hooks into onItemUseFirst instead, and this might be an option
in the future - meaning that right click would always open some computer
GUI and never the blocks. This may be something we change in the future
- let's get some feedback first!

Closes #861. Apologies for this essay, but if you got this far you were
probably interested!
2021-08-30 18:52:02 +01:00
Jonathan Coates
c9397460a4
Optimise maven repository usage
Geesh, we get a lot of 404s against this.
2021-08-29 22:23:58 +01:00
Jonathan Coates
b2273c9b29
Add back JEI integration 2021-08-29 22:20:06 +01:00
Jonathan Coates
9e82209aab
Split uploaded files across multiple packets
Still not 100% sure of the correctness here, but it appears to work.
Closes #887.
2021-08-29 16:58:02 +01:00
JackMacWindows
340ade170f
Add the rest of the feature introduction versions to the docs (#908) 2021-08-26 08:02:58 +01:00
ralphgod3
7cac8401e8
Uncomment remaining keys (#907) 2021-08-25 22:45:10 +01:00
Jonathan Coates
0f899357c2
Some documentation bits and bobs
More #853, closes #858
2021-08-25 22:33:55 +01:00
Jonathan Coates
3396fe2871
Make UserLevel.OWNER a little more strict
Closes #904
2021-08-25 22:09:24 +01:00
Jonathan Coates
bbf3e48763
Increase timeout of some more tests 2021-08-22 18:01:06 +01:00
Jonathan Coates
92fe1d4bc2
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-08-22 17:50:33 +01:00
Jonathan Coates
9fbcbae5b3
Bump version to 1.98.2 2021-08-22 17:39:32 +01:00
Jonathan Coates
36a779dc18
Use data generators in a few more places
As always, a massive diff which is largely just moving files between
projects. This does fix a couple of issues with advancements, but
otherwise should behave the same.

Speaking of which, should probably go and test some of these recipes...
2021-08-21 15:50:01 +01:00
Jonathan Coates
cd8b8bbc74
Bump codecov action version
This'll be deprecated next year. We've plenty of time, but worth fixing
while I'm looking at this stuff.
2021-08-20 22:33:09 +01:00
Jonathan Coates
d8319bb35c
Fix coverage not being generated for in-game tests 2021-08-20 22:13:21 +01:00
Jonathan Coates
afd6adbffa
npm update
The worst ecosystem
2021-08-20 21:54:44 +01:00
Jonathan Coates
4d591c600c
Use clearRemoved rather than onLoad
Latter is broken on Forge right now.
2021-08-20 21:48:34 +01:00
Jonathan Coates
0a8e427c61
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-08-20 21:47:55 +01:00
Jonathan Coates
d3a5d1e314
Add tests for transmitting via wired modems
It crashes on 1.17 right now, so worth checking!
2021-08-20 18:35:00 +01:00
Jonathan Coates
56010382fb
Rethink how computers run tests in game
Instead of using ids for each computer each computer is spawned with id
0 but has a label which matches up to its test name. This has several
advantages:

 - No more confusing IDs: the test code now just does thenComputerOk()
   and that's it - the computer to track is inferred from the test name.
 - All files are stored on one computer, which means we can write code
   which is shared between tests.
2021-08-20 17:05:27 +01:00
Jonathan Coates
0ff6b0ca70
Client-side tests
This spins up a Minecraft instance (much like we do for the server) and
instructs the client to take screenshots at particular times. We then
compare those screenshots and assert they match (modulo some small
delta).
2021-08-20 17:05:13 +01:00
Jonathan Coates
4b33306940
Refactor the test code to be closer to 1.17
Basically mimic the actual API that Minecraft would expose if the
methods hadn't been stripped. Lots of ATs and unsafe hacks to get this
working, but thankfully the API we can expose to the user is pretty
nice. Yay for Kotlin?

Anyway, will cause some immediate pain (yay merge conflicts) but should
make keeping the two in sync much easier.
2021-08-20 17:05:13 +01:00
Jonathan Coates
4dea3dff36
Move some Forge hooks into a separate class 2021-08-20 17:05:13 +01:00
Jonathan Coates
3e8c741170
Update test mod "generated" tags 2021-08-18 13:03:53 +01:00
Jonathan Coates
62baa72457
Add some tests for wired modems 2021-08-18 12:55:58 +01:00
Jonathan Coates
5eb711da87
Relocate test mod to testMod source set
This'll be fun to rebase 1.17 on to :).
2021-08-18 12:55:58 +01:00
Jonathan Coates
79c5df1d92
Fix weblate exporting the wrong language
Ughghgr.
2021-08-18 12:53:19 +01:00
Jonathan Coates
991ea6e829
Switch mappings over to Parchment
These are still equivalent to the official mappings but also include
method names and javadoc. Yay!

A bit weird to be on versioned mappings after 8 months of MojMap :).!
2021-08-18 12:49:50 +01:00
Weblate
1d160641a4 Translations for Japanese
Co-authored-by: MORIMORI0317 <morimori.0317@outlook.jp>
2021-08-18 10:53:58 +00:00
Weblate
c2b3d914f7 Added translation for Japanese
Co-authored-by: MORIMORI0317 <morimori.0317@outlook.jp>
2021-08-18 10:22:58 +00:00
Jonathan Coates
0a537eaeee
Rewrite some in-hand rendering code
- Fix missing shader for printout render type
 - Use current buffer provider for pocket computers rather than the
   tesselator. This requires us to use a non-depth-writing terminal +
   depth blocker, as otherwise one gets z-fighting.
 - Thus refactor some of the shaders to be terminal wide, not just for
   monitors.

Fixes #894
2021-08-17 13:00:52 +01:00
Jonathan Coates
143b2bdbcd
🦀 ComputerCraft is dead 🦀 2021-08-15 22:25:31 +01:00
Jonathan Coates
8cb21ed4d1
Woops
I had this as assume-unchanged for some reason
2021-08-13 22:45:42 +01:00
Jonathan Coates
8aa7695fdd
Some doc updates
- Fix some spacing in code blocks
 - Rewrite the index page
 - You can't see it, but update illuaminate.
2021-08-13 22:35:08 +01:00
Jonathan Coates
fa78818069
Several fixes to speaker volume
- Use linear attenuation.
 - Fix speakers being 16 times as loud as they should be. They correctly
   cut off at the right distance, but didn't fade out as one might
   expect.
 - Clamp volume at 0, not 1. Fixes #892
2021-08-12 18:19:53 +01:00
Jonathan Coates
aa857c1be3
Start using Java's instanceof pattern matching
Well, not really pattern matching, but it's still an improvement!
2021-08-08 12:45:30 +01:00
Jonathan Coates
e4ced551eb
Remove most of the turtle events
I don't think anybody actually used these, and I'm not convinced they
had much value anyway.

It might be worth switching the refueling code to work as a registry
instead, though events are kinda nice.
2021-08-08 12:43:03 +01:00
Jonathan Coates
6eec9ba1a3
Merge branch 'mc-1.16.x' into mc-1.17.x 2021-08-08 12:40:00 +01:00
Jonathan Coates
62172c6049
Fix depending on a client-only class
I checked matrix but not transformationmatrix >_>.
2021-08-08 12:38:06 +01:00
Jonathan Coates
39f3cf8cbe
Cache the tool's transformation matrix 2021-08-08 12:28:25 +01:00
Jonathan Coates
5082947331
Add 1.17 to the issue template 2021-08-08 12:23:02 +01:00
Jonathan Coates
a8f675c59d
Make current branch detection more robust 2021-08-06 18:04:05 +01:00
Jonathan Coates
bb1ebaee4f
Bump Forge and prepare for a release
I've been shown up[1]. Unacceptable!

[1]: https://twitter.com/SangarWasTaken/status/1423676992336060417
2021-08-06 17:25:34 +01:00
Jonathan Coates
bb1183d274
Update to Minecraft 1.17.1
- Remap everything to use MojMap class names too. This is what Forge
   uses, so \o/.

   This does NOT currently rename any classes to use suffix notation or
   BlockEntity. That will come in a later change. We do however rename
   references of "World" to "Level".

 - Move the test mod into a separate "cctest" source set. As Forge now
   works using Jigsaw we cannot have multiple mods defining the same
   package, which causes problems with our JUnit test classes.

 - Remove our custom test framework and replace it with vanilla's (this
   is no longer stripped from the jar). RIP kotlin coroutines.

   It's still worth using Kotlin here though, just for extension
   methods.

 - Other 1.17-related changes:
    - Use separate tile/block entity tick methods for server and client
      side, often avoiding ticking at all on the client.

    - Switch much of the monitor rendering code to use vanilla's
      built-in shader system. It's still an incredibly ugly hack, so not
      really expecting this to work with any rendering mods, but we'll
      cross that bridge when we come to it.
2021-08-06 17:18:09 +01:00
Jonathan Coates
01ddb2b4e4
A couple of documentation improvements
- Add some missing to the turtle API docs
 - Version history for peripheral and redstone. I /think/ this is
   complete.
2021-08-05 19:25:10 +01:00
Jonathan Coates
bdd38fb061
Update changelog and whatsnew for release 2021-08-02 20:15:32 +01:00
DrHesperus
06f35e4997
Update and rename 2021-08-02 19:49:50 +01:00
Jonathan Coates
2d95c32892
Reformat language files 2021-08-02 19:48:16 +01:00
Jonathan Coates
6f4d4540b2
Update location of several langauge files
Looks like weblate was misconfigured here. These should be picked up -
fingers crossed!
2021-08-02 19:05:10 +01:00
Jonathan Coates
96316cddaa
Fix monitor resize checks being entirely wrong
Fixes #879
2021-08-02 18:46:00 +01:00
Jonathan Coates
e84ddef877
Bump version to 1.98.0 2021-08-01 09:02:05 +01:00
Jonathan Coates
11b40bb6d5
Identify unknown upgrades as ComputerCraft instead
When the mod id is null, the namespace is given as "minecraft". This is
not what we want, so use CC there instead.
2021-08-01 08:48:02 +01:00
Jonathan Coates
686c6a4c44
Use cc.strings.wrap inside slowWrite
Means we don't end up re-wrapping text and producing incorrect results.
Fixes #865
2021-08-01 08:43:37 +01:00
Jonathan Coates
a1821035d3
Add a bit of version information to the bios
It's probably the lowest traffic module :p.

Also (somewhat) improve the deprecated messages in os.loadAPI. We really
need a proper article on require and converting from os.loadAPI.
2021-07-30 22:45:51 +01:00
Jonathan Coates
7b8650bbc8 Fix fs.getCapacity docs
Slightly embarassing the state this was in
2021-07-29 09:59:21 +00:00
Jonathan Coates
0285260e97
Merge branch 'mc-1.15.x' into mc-1.16.x 2021-07-28 16:18:27 +01:00
Jonathan Coates
7012ac7163
Merge branch 'mc-1.15.x' into mc-1.16.x 2021-07-25 16:42:22 +01:00
Jonathan Coates
5b57f7509d
Add back executeMainThreadTask
Closes #868
2021-07-24 12:04:21 +01:00
Jonathan Coates
7bcc16bb40 Some examples for rednet 2021-07-23 10:52:44 +00:00
Jonathan Coates
31e6746bdf
Reword community links a bit 2021-07-21 23:20:27 +01:00
Jonathan Coates
c39bf3eb4d
Hopefully block people creating blank issues 2021-07-21 23:18:32 +01:00
JackMacWindows
8b952e7e1e
Fix parallel.* hanging when called with no args (#863) 2021-07-19 11:20:35 +01:00
SkyTheCodeMaster
04e97f7b86
Fix & enhance some docs (#857) 2021-07-18 17:36:09 +01:00
Jonathan Coates
74752c561c
Correctly extract parse errors from build reports 2021-07-18 16:17:11 +01:00
Jonathan Coates
ee96458b56
Merge pull request #862 from Angalexik/typo
Fix typo in paintutils documentation
2021-07-18 12:16:19 +01:00
Angalexik
333410e4cd
Fixed typo in paintutils documentation 2021-07-18 12:37:16 +02:00
Jonathan Coates
999a39a3e6
Merge branch 'mc-1.15.x' into mc-1.16.x 2021-07-15 13:05:31 +01:00
Jonathan Coates
347affcc5c
Merge pull request #859 from emiliskiskis/patch-1
Fix typo in turtle.craft documentation
2021-07-12 14:31:28 +01:00
Emilis Kiškis
8ebe34b8da
Fix typo in turtle.craft documentation
Description wrote "to craft sticks, slots should contain sticks", whereas it should say "planks" in the second part.
2021-07-11 11:03:41 +03:00
Jonathan Coates
7086cb8a02
Merge pull request #848 from SkyTheCodeMaster/patch-3
Turn a nil to a string
2021-07-05 06:16:05 +01:00
SkyTheCodeMaster
8dbc930c2f
Turn a nil to a string
Makes a `nil` a string inside of an expect in `define`, allowing `nil` to be passed.
2021-07-04 20:54:55 -04:00
Jonathan Coates
61eb67849d
Some fs examples
See #566
2021-07-03 14:05:41 +01:00
Jonathan Coates
0d22270f8b
Publish docs from 1.16 instead 2021-07-02 21:49:19 +01:00
Jonathan Coates
abb9c14256
Bump Forge Gradle version 2021-07-02 21:48:28 +01:00
Jonathan Coates
815e534dc6
Merge branch 'mc-1.15.x' into mc-1.16.x 2021-07-02 21:03:39 +01:00
Jonathan Coates
efa2be2821
Update changelog for 1.16.x-only features 2021-06-28 22:58:13 +01:00
Jonathan Coates
670db97fc7
Merge branch 'mc-1.15.x' into mc-1.16.x 2021-06-28 22:52:05 +01:00
Jonathan Coates
a5bca3f0df
File uploading (#840) 2021-06-28 22:49:45 +01:00
Jonathan Coates
5ef8d52c13
Merge branch 'mc-1.15.x' into mc-1.16.x 2021-06-28 18:37:24 +01:00
Jonathan Coates
3ab3213290 Try the new issue template system 2021-06-24 08:31:41 +00:00
Jonathan Coates
9bd662d8dc
Fix CraftTweaker actions being applied twice
By default CT applies them on the client and server. In a single player
world, this means we try to create two upgrades, which obviously fails!

Fixes #721
2021-06-22 19:39:46 +01:00
Jonathan Coates
df7a40354e
Merge branch 'mc-1.15.x' into mc-1.16.x 2021-06-19 15:18:12 +01:00
Jonathan Coates
2d3e88ef59
Replace mixin with access transformers
Hadn't realised I could use these to touch final modifiers! More
importantly, Mixin doesn't work with FG 5.0, so we needed an alternative
:).
2021-06-19 12:52:07 +01:00
Jonathan Coates
0bfe960cbd
Merge branch 'mc-1.15.x' into mc-1.16.x 2021-06-19 12:41:30 +01:00
Jonathan Coates
db2cde4a4c
Add MoreRed support
I've written three or four integrations with bundled cables now over the
various versions, and I'm still not convinced this one is right. It
appears to work though, so we'll see.

We need depend on the main jar here (rather than the API jar), as
otherwise our javadoc tools fails - the API references some internal
classes which aren't on our classpath.

It might be nice to write tests for this (and CT) in the future -
goodness knows these features are fragile - but that'll require some
more gradle work which I don't want to do right now.

Closes #772
2021-06-05 14:48:38 +01:00
Jonathan Coates
5eec7d9172
Bump to 1.16.5
I don't think anyone still uses 1.16.4, so no point worrying about it.

Closes #808
2021-06-05 12:32:40 +01:00
Jonathan Coates
8b9735d72e
Fix background not rendering on (pocket) computers 2021-06-05 11:46:10 +01:00
Jonathan Coates
1866916cb8
Fix coloured pocket computers using the wrong texture 2021-06-05 11:36:36 +01:00
Jonathan Coates
f38a6a9d43
Merge branch 'mc-1.15.x' into mc-1.16.x 2021-06-05 11:36:30 +01:00
Jonathan Coates
7f9b86a78e
Add basic JMX monitoring on dedicated servers
Closes #482
2021-05-27 21:36:56 +01:00
Jonathan Coates
f0ba1108d5 Merge branch 'mc-1.15.x' into mc-1.16.x 2021-05-20 19:03:56 +01:00
Jonathan Coates
8b8692ba53 Merge branch 'mc-1.15.x' into mc-1.16.x 2021-05-20 18:30:10 +01:00
Jonathan Coates
f387730b88 Merge branch 'mc-1.15.x' into mc-1.16.x 2021-04-24 11:50:23 +01:00
Jonathan Coates
8c56b6a7be Merge branch 'mc-1.15.x' into mc-1.16.x 2021-03-12 09:26:15 +00:00
Jonathan Coates
7514cf7320 Mark as compatible with 1.16.{4,5}
Closes #694
2021-01-24 21:23:29 +00:00
FensieRenaud
417fda3019
Serialise sparse arrays into JSON (#685) 2021-01-18 16:44:39 +00:00
Jonathan Coates
23bf33c454 Use mixins to construct the TestFunctionInfo class
There's some funky things going on here, but thankfully they're limited
to test code.
2021-01-16 12:40:00 +00:00
Jonathan Coates
0be030c497 Merge branch 'mc-1.15.x' into mc-1.16.x 2021-01-16 11:38:59 +00:00
Jonathan Coates
a3a9684505 Widen version range to include 1.16.5
Building against 1.16.4 for now to ensure we don't break it. Hopefully
we can bump this too once most people have migrated.

Will push a release tomorrow - don't want to be sorting out merge
conflicts at 23:30.
2021-01-15 23:26:01 +00:00
Jonathan Coates
c5694ea966 Merge branch 'mc-1.15.x' into mc-1.16.x 2021-01-09 19:25:33 +00:00
Jonathan Coates
7b476cb24b Remove usage of deprecated event constructor
This requires a Forge bump, but probably no harm in doing so anyway.
We're on an ancient (2nd Nov) version. Fixes #665.
2021-01-09 18:49:40 +00:00
Jonathan Coates
7ca261d763 Merge branch 'mc-1.15.x' into mc-1.16.x 2021-01-09 18:32:40 +00:00
Jonathan Coates
1edb7288b9 Merge branch 'mc-1.15.x' into mc-1.16.x 2021-01-06 22:39:54 +00:00
Jonathan Coates
4af5bcc0b0 Fix serveral 1.15 -> 1.16 issues
Well, strictly speaking some mapping changes.
2020-12-25 16:59:09 +00:00
Jonathan Coates
96c577482d Merge branch 'mc-1.15.x' into mc-1.16.x 2020-12-25 16:43:32 +00:00
SquidDev
61f8e97f6b Force the monitor depth blocker to be flushed
As explained in the comment, "built-in" rendering types are now manually
rendered ("finish"ed) before calling finish() on the main renderer. This
means our depth blocker hasn't actually been drawn (if a monitor is the
last TE to be rendered), and so blocks pass the depth test when they
shouldn't.

Fixes #599
2020-12-11 13:09:16 +00:00
SquidDev
c92f06cfd9 Bump deps to 1.16.4 2020-12-11 13:08:24 +00:00
Stephen Gibson
c9f3d315c0
Fix epoch documentation to use milliseconds (#580) 2020-11-13 14:32:49 +00:00
SquidDev
83df64e520 Merge branch 'mc-1.15.x' into mc-1.16.x 2020-11-07 12:46:10 +00:00
SquidDev
ab232bd689 Update to MC 1.16.4
Just some mapping changes really
2020-11-03 15:33:10 +00:00
SquidDev
5bf367af9f Merge branch 'mc-1.15.x' into mc-1.16.x 2020-10-23 17:45:11 +01:00
SquidDev
4766833cf2 Bump JEI/crafttweaker versions
In my defence, they weren't out when I started the 1.15 update.
2020-10-20 17:38:59 +01:00
SquidDev
71563a52ff Let's make this a proper release 2020-10-04 11:31:06 +01:00
SquidDev
0c6e7b5db5 Merge branch 'mc-1.15.x' into mc-1.16.x 2020-10-04 11:24:42 +01:00
SquidDev
72c1d451fe Mark the release as beta-quality 2020-09-12 10:47:19 +01:00
SquidDev
8b4a01df27 Update to Minecraft 1.16.3
I hope the Fabric folks now realise this is gonna be a race of who can
update first :p. Either way, this was a very easy update - only changes
were due to unrelated Forge changes.
2020-09-12 10:45:59 +01:00
SquidDev
d0a973fa46 Merge branch 'mc-1.15.x' into mc-1.16.x 2020-09-12 09:29:21 +01:00
SquidDev
26c12ac1a9 Bump version to 1.91.1 2020-09-04 17:29:35 +01:00
SquidDev
2c67849b35 Fix NPE when turtles interact with an entity
Closes #531
2020-08-27 17:17:03 +01:00
SquidDev
7809a2eddd Merge branch 'mc-1.15.x' into mc-1.16.x 2020-08-23 15:46:17 +01:00
SquidDev
e8e9294fdf Correctly check for success or consume
No, I don't really know what the difference is either :). Closes #518.
2020-08-22 19:28:02 +01:00
SquidDev
99581e1f40 Initial update to 1.16.2
Seems to load fine, but not done any proper testing.
2020-08-14 22:00:03 +01:00
SquidDev
29646a7f61 Bump version to 1.90.3 2020-07-27 19:07:06 +01:00
SquidDev
50d2712581 Resolve CC's save location to the world dir
Fixes #509
2020-07-27 19:04:57 +01:00
SquidDev
3093f882d8 Fix selected slot now showing in the turtle GUI 2020-07-27 18:37:07 +01:00
SquidDev
e5cf0d1c61 Update mappings 2020-07-27 18:26:42 +01:00
SquidDev
6b102a8142 Merge branch 'mc-1.15.x' into mc-1.16.x 2020-07-25 12:08:33 +01:00
SquidDev
c8a6888a2f Fix styles not being saved
Styles have been changed to be immutable, meaning that we were never
updating them! Fixes #499.
2020-07-25 11:19:04 +01:00
SquidDev
9ce33f8a3f Add back missing override of getPositionVec
This was removed in the initial update (46595e73df)
because I got terribly confused over mappings and I forgot to add it
back.

Fixes #505
2020-07-25 10:56:50 +01:00
SquidDev
a1dcd59d95 Update to latest Forge
Fixes #498
2020-07-18 15:11:57 +01:00
SquidDev
2a17585702 Merge branch 'mc-1.15.x' into mc-1.16.x 2020-07-18 12:24:49 +01:00
SquidDev
087c305b0d Fix non-inventory GUIs rendering labels 2020-07-18 12:17:02 +01:00
SquidDev
31764f6d65 Register various gold items as piglin_loved 2020-07-18 11:14:55 +01:00
SquidDev
4efde2b294 Merge branch 'mc-1.15.x' into mc-1.16.x 2020-07-18 10:34:29 +01:00
SquidDev
46595e73df Initial update to Minecraft 1.16.1
A lot is broken, but at least we can get in game:
 - GUIs render a whole bunch of additional "inventory" text, which we
   really don't want.
 - Computers load from the wrong location.
 - There's some issues with using Forge's tags from outside of JSON
   recipes. We need to work out why.
2020-07-11 20:36:10 +01:00
3477 changed files with 133718 additions and 87620 deletions

View File

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2017 The CC: Tweaked Developers
#
# SPDX-License-Identifier: CC0-1.0
root = true
[*]
@ -8,6 +12,17 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
ij_continuation_indent_size = 4
ij_any_do_while_brace_force = if_multiline
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

6
.git-blame-ignore-revs Normal file
View File

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

10
.gitattributes vendored
View File

@ -1,15 +1,21 @@
# SPDX-FileCopyrightText: 2020 The CC: Tweaked Developers
#
# SPDX-License-Identifier: CC0-1.0
# Ignore changes in generated files
src/generated/resources/data/** linguist-generated
src/test/server-files/structures linguist-generated
projects/*/src/generated/** linguist-generated
projects/common/src/testMod/resources/data/cctest/structures/* linguist-generated
* text=auto
*.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
*.png binary
*.jar binary
*.dfpwm binary

View File

@ -8,8 +8,10 @@ body:
label: Minecraft Version
description: What version of Minecraft are you using?
options:
- 1.15.x
- 1.16.x
- 1.18.x
- 1.19.x
- 1.20.x
validations:
required: true
- type: input

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: GitHub Discussions
url: https://github.com/cc-tweaked/CC-Tweaked/discussions
about: Ask questions on GitHub Discussions.

View File

@ -0,0 +1,4 @@
---
name: Something else
about: An issue about something else.
---

View File

@ -8,54 +8,97 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: 📥 Clone repository
uses: actions/checkout@v3
- name: Set up Java 8
uses: actions/setup-java@v1
- name: 📥 Set up Java
uses: actions/setup-java@v3
with:
java-version: 8
java-version: 17
distribution: 'temurin'
- name: Cache gradle dependencies
uses: actions/cache@v2
- name: 📥 Setup Gradle
uses: gradle/gradle-build-action@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
cache-read-only: ${{ !startsWith(github.ref, 'refs/heads/mc-') }}
- name: Disable Gradle daemon
run: |
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: Upload Jar
uses: actions/upload-artifact@v2
with:
name: CC-Tweaked
path: build/libs
- name: 💡 Lint
uses: pre-commit/action@v3.0.0
- name: Upload Coverage
uses: codecov/codecov-action@v1
- name: 🧪 Run tests
run: ./gradlew test validateMixinNames checkChangelog
- name: Parse test reports
- name: 📥 Download assets for game tests
run: ./gradlew downloadAssets || ./gradlew downloadAssets
- name: 🧪 Run integration tests
run: ./gradlew runGametest
- 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: 🧪 Parse test reports
run: ./tools/parse-reports.py
if: ${{ failure() }}
- name: Cache pre-commit
uses: actions/cache@v2
with:
path: ~/.cache/pre-commit
key: ${{ runner.os }}-pre-commit-${{ hashFiles('config/pre-commit/config.yml') }}
restore-keys: |
${{ runner.os }}-pre-commit-
- name: Run linters
- name: 📦 Prepare Jars
run: |
pip install pre-commit
pre-commit run --config config/pre-commit/config.yml --show-diff-on-failure --all --color=always
# 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
with:
name: CC-Tweaked
path: ./jars
- name: 📤 Upload coverage
uses: codecov/codecov-action@v3
build-core:
strategy:
fail-fast: false
matrix:
include:
- name: Windows
uses: windows-latest
- name: macOS
uses: macos-latest
name: Test on ${{ matrix.name }}
runs-on: ${{ matrix.uses }}
steps:
- name: Clone repository
uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: 17
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
cache-read-only: ${{ !startsWith(github.ref, 'refs/heads/mc-') }}
- name: Run tests
run: |
./gradlew --configure-on-demand :core:test
- name: Parse test reports
run: python3 ./tools/parse-reports.py
if: ${{ failure() }}

View File

@ -12,8 +12,8 @@ chmod 600 "$HOME/.ssh/key"
# And upload
rsync -avc -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no -p $SSH_PORT" \
"$GITHUB_WORKSPACE/build/docs/lua/" \
"$SSH_USER@$SSH_HOST:/var/www/tweaked.cc/$DEST"
"$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/build/docs/javadoc/" \
"$SSH_USER@$SSH_HOST:/var/www/tweaked.cc/$DEST/javadoc"
"$GITHUB_WORKSPACE/projects/common-api/build/docs/javadoc/" \
"$SSH_USER@$SSH_HOST:/$DEST/javadoc"

View File

@ -3,7 +3,8 @@ name: Build documentation
on:
push:
branches:
- mc-1.16.x
- mc-1.19.x
- mc-1.20.x
jobs:
make_doc:
@ -11,35 +12,25 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Clone repository
uses: actions/checkout@v3
- name: Set up Java 8
- name: Set up Java
uses: actions/setup-java@v1
with:
java-version: 8
java-version: 17
distribution: 'temurin'
- name: Cache gradle dependencies
uses: actions/cache@v2
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('gradle.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Setup illuaminate
run: |
test -d bin || mkdir bin
test -f bin/illuaminate || wget -q -Obin/illuaminate https://squiddev.cc/illuaminate/linux-x86-64/illuaminate
chmod +x bin/illuaminate
- name: Setup node
run: npm ci
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 javadoc --no-daemon
run: ./gradlew docWebsite :common-api:javadoc --no-daemon
- name: Upload documentation
run: .github/workflows/make-doc.sh 2> /dev/null

19
.gitignore vendored
View File

@ -1,15 +1,26 @@
# 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
# Runtime directories
/run
/run-*
/test-files
/projects/*/run
*.ipr
*.iws
@ -22,8 +33,6 @@
/.project
/.settings
/.vscode
bin/
*.launch
/src/generated/resources/.cache
/src/web/mount/*.d.ts
/projects/*/src/generated/resources/.cache

View File

@ -1,3 +1,7 @@
# SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
#
# SPDX-License-Identifier: MPL-2.0
image:
file: config/gitpod/Dockerfile
@ -17,6 +21,6 @@ vscode:
tasks:
- name: Setup pre-commit hool
init: pre-commit install --config config/pre-commit/config.yml --allow-missing-config
init: pre-commit install --allow-missing-config
- name: Install npm packages
init: npm ci

63
.pre-commit-config.yaml Normal file
View File

@ -0,0 +1,63 @@
# 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.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-merge-conflict
# Quick syntax checkers
- id: check-xml
- id: check-yaml
- id: check-toml
- id: check-json
exclude: "tsconfig\\.json$"
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
rev: 2.7.2
hooks:
- id: editorconfig-checker
args: ['-disable-indentation']
exclude: "^(.*\\.(bat)|LICENSE)$"
- repo: https://github.com/fsfe/reuse-tool
rev: v2.1.0
hooks:
- id: reuse
- repo: local
hooks:
- id: license
name: Spotless
files: ".*\\.(java|kt|kts)$"
language: system
entry: ./gradlew spotlessApply
pass_filenames: false
require_serial: true
- id: checkstyle
name: Check Java codestyle
files: ".*\\.java$"
language: system
entry: ./gradlew checkstyle
pass_filenames: false
require_serial: true
- id: illuaminate
name: Check Lua code
files: ".*\\.(lua|java|md)"
language: system
entry: ./gradlew lintLua
pass_filenames: false
require_serial: true
exclude: |
(?x)^(
projects/[a-z]+/src/generated|
projects/core/src/test/resources/test-rom/data/json-parsing/|
.*\.dfpwm
)

100
.reuse/dep5 Normal file
View File

@ -0,0 +1,100 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://github.com/cc-tweaked/cc-tweaked
Upstream-Name: CC: Tweaked
Upstream-Contact: Jonathan Coates <git@squiddev.cc>
Files:
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_upgrades/*
projects/common/src/testMod/resources/data/cctest/structures/*
projects/fabric/src/generated/*
projects/forge/src/generated/*
projects/web/src/htmlTransform/export/index.json
projects/web/src/htmlTransform/export/items/minecraft/*
Comment: Generated/data files are CC0.
Copyright: The CC: Tweaked Developers
License: CC0-1.0
Files:
doc/images/*
package.json
package-lock.json
projects/common/src/client/resources/computercraft-client.mixins.json
projects/common/src/main/resources/assets/minecraft/shaders/core/computercraft/monitor_tbo.json
projects/common/src/main/resources/computercraft.mixins.json
projects/common/src/testMod/resources/computercraft-gametest.mixins.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/fabric-api/src/main/modJson/fabric.mod.json
projects/fabric/src/client/resources/computercraft-client.fabric.mixins.json
projects/fabric/src/main/resources/computercraft.fabric.mixins.json
projects/fabric/src/main/resources/fabric.mod.json
projects/fabric/src/testMod/resources/computercraft-gametest.fabric.mixins.json
projects/fabric/src/testMod/resources/fabric.mod.json
projects/forge/src/client/resources/computercraft-client.forge.mixins.json
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
Comment: Several assets where it's inconvenient to create a .license file.
Copyright: The CC: Tweaked Developers
License: MPL-2.0
Files:
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/*
Comment: Bulk-license original assets as CCPL.
Copyright: 2011 Daniel Ratcliffe
License: LicenseRef-CCPL
Files:
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
Comment: Community-contributed license files
Copyright: 2017 The CC: Tweaked Developers
License: LicenseRef-CCPL
Files:
projects/common/src/main/resources/assets/computercraft/lang/*
Comment: Community-contributed license files
Copyright: 2017 The CC: Tweaked Developers
License: MPL-2.0
Files:
.github/*
Comment:
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.
Copyright: Jonathan Coates <git@squiddev.cc>
License: CC0-1.0
Files:
gradle/wrapper/*
gradlew
gradlew.bat
Copyright: Gradle Inc
License: Apache-2.0
Files: projects/core/src/test/resources/test-rom/data/json-parsing/*
Copyright: 2016 Nicolas Seriot
License: MIT

138
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,138 @@
<!--
SPDX-FileCopyrightText: 2014 Coraline Ada Ehmke and contributors
SPDX-License-Identifier: CC-BY-4.0
-->
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
"conduct AT squiddev DOT cc". All complaints will be reviewed and investigated
promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

View File

@ -1,114 +1,110 @@
<!--
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].
## Table of Contents
- [Reporting issues](#reporting-issues)
- [Translations](#translations)
- [Setting up a development environment](#setting-up-a-development-environment)
- [Developing CC: Tweaked](#developing-cc-tweaked)
- [Writing documentation](#writing-documentation)
## Reporting issues
If you have a bug, suggestion, or other feedback, the best thing to do is [file an issue][new-issue]. When doing so,
do use the issue templates - they provide a useful hint on what information to provide.
If you have a bug, suggestion, or other feedback, the best thing to do is [file an issue][new-issue]. When doing so, do
use the issue templates - they provide a useful hint on what information to provide.
## Translations
Translations are managed through [Weblate], an online interface for managing language strings. This is synced
automatically with GitHub, so please don't submit PRs adding/changing translations!
## Developing
In order to develop CC: Tweaked, you'll need to download the source code and then run it. This is a pretty simple
process. When building on Windows, Use `gradlew.bat` instead of `./gradlew`.
## Setting up a development environment
In order to develop CC: Tweaked, you'll need to download the source code and then run it.
- **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
- **Setup Forge:** `./gradlew build`
- **Run Minecraft:** `./gradlew runClient` (or run the `GradleStart` class from your IDE).
- **Optionally:** For small PRs (especially those only touching Lua code), it may be easier to use GitPod, which
provides a pre-configured environment: [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-2b2b2b?logo=gitpod)](https://gitpod.io/#https://github.com/SquidDev-CC/CC-Tweaked/)
- Make sure you've got the following software installed:
- Java Development Kit (JDK) installed. This can be downloaded from [Adoptium].
- [Git](https://git-scm.com/).
- If you want to work on documentation, [NodeJS][node].
Do note you will need to download the mod after compiling to test.
- Download CC: Tweaked's source code:
```
git clone https://github.com/cc-tweaked/CC-Tweaked.git
cd CC-Tweaked
```
If you want to run CC:T in a normal Minecraft instance, run `./gradlew build` and copy the `.jar` from `build/libs`.
These commands may take a few minutes to run the first time, as the environment is set up, but should be much faster
afterwards.
- Build CC: Tweaked with `./gradlew build`. This will be very slow the first time it runs, as it needs to download a
lot of dependencies (and decompile Minecraft several times). Subsequent runs should be much faster!
The following sections describe the more niche sections of CC: Tweaked's build system. Some bits of these are
quite-complex, and (dare I say) over-engineered, so you may wish to ignore them. Well tested/documented PRs are always
preferred (and I'd definitely recommend setting up the tooling if you're doing serious development work), but for
small changes it can be a lot.
- You're now ready to start developing CC: Tweaked. Running `./gradlew :forge:runClient` or
`./gradle :fabric:runClient` will start Minecraft under Forge and Fabric respectively.
### Code linters
CC: Tweaked uses a couple of "linters" on its source code, to enforce a consistent style across the project. While these
are run whenever you submit a PR, it's often useful to run this before committing.
If you want to run CC:T in a normal Minecraft instance, run `./gradlew assemble` and copy the `.jar` from
`projects/forge/build/libs` (for Forge) or `projects/fabric/build/libs` (for Fabric).
- **[Checkstyle]:** Checks Java code to ensure it is consistently formatted. This can be run with `./gradlew build` or
`./gradle check`.
- **[illuaminate]:** Checks Lua code for semantic and styleistic issues. See [the usage section][illuaminate-usage] for
how to download and run it. You may need to generate the Java documentation stubs (see "Documentation" below) for all
lints to pass.
## 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]!
### Documentation
### Testing
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:
- In order to test CraftOS and its builtin APIs, we have a test suite written in Lua located at
`projects/core/src/test/resources/test-rom/`. These don't rely on any Minecraft code, which means they can run on
emulators, acting as a sort of compliance test.
These tests are written using a test system called "mcfly", heavily inspired by [busted]. Groups of tests go inside
`describe` blocks, and a single test goes inside `it`. Assertions are generally written using `expect` (inspired by
Hamcrest and the like). For instance, `expect(foo):eq("bar")` asserts that your variable `foo` is equal to the
expected value `"bar"`.
These tests can be run with `./gradlew :core:test`.
- In-game functionality, such as the behaviour of blocks and items, is tested using [Minecraft's gametest
system][mc-test] (`projects/common/src/testMod`). These tests spin up a server, spawn a structure for each test, and
then run some code on the blocks defined in that structure.
These tests can be run with `./gradlew runGametest` (or `./gradle :forge:runGametest`/`./gradlew :fabric:runGametest`
for a single loader).
For more information, [see the architecture document][architecture].
## Writing documentation
When writing documentation for [CC: Tweaked's documentation website][docs], it may be useful to build the documentation
and preview it yourself before submitting a PR.
Building all documentation is, sadly, a multi-stage process (though this is largely hidden by Gradle). First we need to
convert Java doc-comments into Lua ones, we also generate some Javascript to embed. All of this is then finally fed into
illuaminate, which spits out our HTML.
You'll first need to [set up a development environment as above](#setting-up-a-development-environment).
#### Setting up the tooling
For various reasons, getting the environment set up to build documentation can be pretty complex. I'd quite like to
automate this via Docker and/or nix in the future, but this needs to be done manually for now.
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.
This tooling is only needed if you need to build the whole website. If you just want to generate the Lua stubs, you can
skp this section.
- Install Node/npm and install our Node packages with `npm ci`.
- Install [illuaminate][illuaminate-usage] as described above.
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!
#### Building documentation
Gradle should be your entrypoint to building most documentation. There's two tasks which are of interest:
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!
- `./gradlew luaJavadoc` - Generate documentation stubs for Java methods.
- `./gradlew docWebsite` - Generate the whole website (including Javascript pages). The resulting HTML is stored at
`./build/docs/lua/`.
#### Writing documentation
illuaminate's documentation system is not currently documented (somewhat ironic), but is _largely_ the same as
[ldoc][ldoc]. Documentation comments are written in Markdown,
Our markdown engine does _not_ support GitHub flavoured markdown, and so does not support all the features one might
expect (such as tables). It is very much recommended that you build and preview the docs locally first.
### Testing
Thankfully running tests is much simpler than running the documentation generator! `./gradlew check` will run the
entire test suite (and some additional bits of verification).
Before we get into writing tests, it's worth mentioning the various test suites that CC: Tweaked has:
- "Core" Java (`./src/test/java`): These test core bits of the mod which don't require any Minecraft interaction.
This includes the `@LuaFunction` system, file system code, etc...
These tests are run by `./gradlew test`.
- CraftOS (`./src/test/resources/test-rom/`): These tests are written in Lua, and ensure the Lua environment, libraries
and programs work as expected. These are (generally) written to be able to be run on emulators too, to provide some
sort of compliance test.
These tests are run by the '"Core" Java' test suite, and so are also run with `./gradlew test`.
- In-game (`./src/test/java/dan200/computercraft/ingame/`): These tests are run on an actual Minecraft server, using
[the same system Mojang do][mc-test]. The aim of these is to test in-game behaviour of blocks and peripherals.
These are run by `./gradlew testInGame`.
## CraftOS tests
CraftOS's tests are written using a test system called "mcfly", heavily inspired by [busted] (and thus RSpec). Groups of
tests go inside `describe` blocks, and a single test goes inside `it`.
Assertions are generally written using `expect` (inspired by Hamcrest and the like). For instance, `expect(foo):eq("bar")`
asserts that your variable `foo` is equal to the expected value `"bar"`.
[new-issue]: https://github.com/SquidDev-CC/CC-Tweaked/issues/new/choose "Create a new issue"
[community]: README.md#Community "Get in touch with the community."
[checkstyle]: https://checkstyle.org/
[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"
[illuaminate]: https://github.com/SquidDev/illuaminate/ "Illuaminate on GitHub"
[illuaminate-usage]: https://github.com/SquidDev/illuaminate/blob/master/README.md#usage "Installing Illuaminate"
[weblate]: https://i18n.tweaked.cc/projects/cc-tweaked/minecraft/ "CC: Tweaked weblate instance"
[docs]: https://tweaked.cc/ "CC: Tweaked documentation"
[ldoc]: http://stevedonovan.github.io/ldoc/ "ldoc, a Lua documentation generator."
[mc-test]: https://www.youtube.com/watch?v=vXaWOJTCYNg
[busted]: https://github.com/Olivine-Labs/busted "busted: Elegant Lua unit testing."
[node]: https://nodejs.org/en/ "Node.js"
[architecture]: projects/ARCHITECTURE.md

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.

101
README.md
View File

@ -1,40 +1,24 @@
# ![CC: Tweaked](doc/logo.png)
[![Current build status](https://github.com/SquidDev-CC/CC-Tweaked/workflows/Build/badge.svg)](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [![Download CC: Tweaked on CurseForge](http://cf.way2muchnoise.eu/title/cc-tweaked.svg)](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
<!--
SPDX-FileCopyrightText: 2017 The CC: Tweaked Developers
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
turtles and more to Minecraft.
SPDX-License-Identifier: MPL-2.0
-->
## What?
ComputerCraft has always held a fond place in my heart: it's the mod which really got me into Minecraft, and it's the
mod which has kept me playing it for many years. However, development of the original mod has slowed, as the original
developers have had less time to work on the mod, and moved onto other projects and commitments.
<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>
CC: Tweaked (or CC:T for short) is an attempt to continue ComputerCraft's legacy. It's not intended to be a competitor
to CC, nor do I want to take it in a vastly different direction to the original mod. Instead, CC:T focuses on making the
ComputerCraft experience as _solid_ as possible, ironing out any wrinkles that may have developed over time.
[![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](https://img.shields.io/static/v1?label=Download&message=CC:%20Tweaked&color=E04E14&logoColor=E04E14&logo=CurseForge)][CurseForge]
[![Download CC: Tweaked on Modrinth](https://img.shields.io/static/v1?label=Download&color=00AF5C&logoColor=00AF5C&logo=Modrinth&message=CC:%20Tweaked)][Modrinth]
## Features
CC: Tweaked contains all the features of the latest version of ComputerCraft, as well as numerous fixes, performance
improvements and several nifty additions. I'd recommend checking out [the releases page](https://github.com/SquidDev-CC/CC-Tweaked/releases)
to see the full set of changes, but here's a couple of the more interesting additions:
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.
- Improvements to the `http` library, including websockets, support for other HTTP methods (`PUT`, `DELETE`, etc...)
and configurable limits on HTTP usage.
- Full-block wired modems, allowing one to wrap non-solid peripherals (such as turtles, or chests if Plethora is
installed).
- Pocket computers can be held like maps, allowing you to view the screen without entering a GUI.
- Printed pages and books can be placed in item frames and held like maps.
- Several profiling and administration tools for server owners, via the `/computercraft` command. This allows operators
to track which computers are hogging resources, turn on and shutdown multiple computers at once and interact with
computers remotely.
- Closer emulation of standard Lua, adding the `debug` and `io` libraries. This also enables seeking within binary
files, meaning you don't need to read large files into memory.
- Allow running multiple computers on multiple threads, reducing latency on worlds with many computers.
## Relation to CCTweaks?
This mod has nothing to do with CCTweaks, though there is no denying the name is a throwback to it. That being said,
several features have been included, such as full block modems, the Cobalt runtime and map-like rendering for pocket
computers.
CC: Tweaked can be installed from [CurseForge] or [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
@ -42,12 +26,10 @@ 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 we have a [forum](https://forums.computercraft.cc/) and [Discord guild](https://discord.computercraft.cc)!
There's also a fairly populated, albeit quiet [IRC channel](http://webchat.esper.net/?channels=computercraft), if that's
more your cup of tea.
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.
I'd generally recommend you don't contact me directly (email, DM, etc...) unless absolutely necessary (i.e. in order to
report exploits). You'll get a far quicker response if you ask the whole community!
We also host fairly comprehensive documentation at [tweaked.cc](https://tweaked.cc/ "The CC: Tweaked website").
## Using
CC: Tweaked is hosted on my maven repo, and so is relatively simple to depend on. You may wish to add a soft (or hard)
@ -56,17 +38,54 @@ on is present.
```groovy
repositories {
maven { url 'https://squiddev.cc/maven/' }
maven {
url "https://squiddev.cc/maven/"
content {
includeGroup("cc.tweaked")
}
}
}
dependencies {
implementation fg.deobf("org.squiddev:cc-tweaked-${mc_version}:${cct_version}")
// Vanilla (i.e. for multi-loader systems)
compileOnly("cc.tweaked:cc-tweaked-$mcVersion-common-api:$cctVersion")
// Forge Gradle
compileOnly("cc.tweaked:cc-tweaked-$mcVersion-core-api:$cctVersion")
compileOnly(fg.deobf("cc.tweaked:cc-tweaked-$mcVersion-forge-api:$cctVersion"))
runtimeOnly(fg.deobf("cc.tweaked:cc-tweaked-$mcVersion-forge:$cctVersion"))
// Fabric Loom
modCompileOnly("cc.tweaked:cc-tweaked-$mcVersion-fabric-api:$cctVersion")
modRuntimeOnly("cc.tweaked:cc-tweaked-$mcVersion-fabric:$cctVersion")
}
```
When using ForgeGradle, you may also need to add the following:
```groovy
minecraft {
runs {
configureEach {
property 'mixin.env.remapRefMap', 'true'
property 'mixin.env.refMapRemappingFile', "${buildDir}/createSrgToMcp/output.srg"
}
}
}
```
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"
[Minecraft Forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
[Fabric]: https://fabricmc.net/use/installer/ "Download Fabric."
[forum]: https://forums.computercraft.cc/
[GitHub Discussions]: https://github.com/cc-tweaked/CC-Tweaked/discussions
[IRC]: https://webchat.esper.net/?channels=computercraft "#computercraft on EsperNet"

View File

@ -1,564 +0,0 @@
buildscript {
repositories {
mavenCentral()
maven {
name = "forge"
url = "https://maven.minecraftforge.net"
}
}
dependencies {
classpath 'com.google.code.gson:gson:2.8.1'
classpath 'net.minecraftforge.gradle:ForgeGradle:5.0.6'
}
}
plugins {
id "checkstyle"
id "jacoco"
id "maven-publish"
id "com.github.hierynomus.license" version "0.16.1"
id "com.matthewprenger.cursegradle" version "1.4.0"
id "com.github.breadmoirai.github-release" version "2.2.12"
id "org.jetbrains.kotlin.jvm" version "1.3.72"
id "com.modrinth.minotaur" version "1.2.1"
}
apply plugin: 'net.minecraftforge.gradle'
version = mod_version
group = "org.squiddev"
archivesBaseName = "cc-tweaked-${mc_version}"
def javaVersion = JavaLanguageVersion.of(8)
java {
toolchain {
languageVersion = javaVersion
}
withSourcesJar()
withJavadocJar()
}
// Tragically java.toolchain.languageVersion doesn't apply to ForgeGradle's
// tasks, so we force all launchers to use the right Java version.
tasks.withType(JavaCompile).configureEach {
javaCompiler = javaToolchains.compilerFor {
languageVersion = javaVersion
}
}
tasks.withType(JavaExec).configureEach {
javaLauncher = javaToolchains.launcherFor {
languageVersion = javaVersion
}
}
minecraft {
runs {
client {
workingDirectory project.file('run')
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
mods {
computercraft {
source sourceSets.main
}
}
}
server {
workingDirectory project.file("run/server")
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
arg "--nogui"
mods {
computercraft {
source sourceSets.main
}
}
}
data {
workingDirectory project.file('run')
property 'forge.logging.markers', 'REGISTRIES'
property 'forge.logging.console.level', 'debug'
args '--mod', 'computercraft', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
mods {
computercraft {
source sourceSets.main
}
}
}
testServer {
workingDirectory project.file('test-files/server')
parent runs.server
mods {
cctest {
source sourceSets.test
}
}
}
}
mappings channel: 'official', version: project.mc_version
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
}
sourceSets {
main.resources {
srcDir 'src/generated/resources'
}
}
repositories {
mavenCentral()
maven {
name "SquidDev"
url "https://squiddev.cc/maven"
}
}
configurations {
shade
compile.extendsFrom shade
cctJavadoc
}
dependencies {
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
compileOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3:api")
compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.15.2:6.0.0.9")
runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.3")
shade 'org.squiddev:Cobalt:0.5.2-SNAPSHOT'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72'
testImplementation 'org.jetbrains.kotlin:kotlin-reflect:1.3.72'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.0'
}
// Compile tasks
javadoc {
include "dan200/computercraft/api/**/*.java"
}
task luaJavadoc(type: Javadoc) {
description "Generates documentation for Java-side Lua functions."
group "documentation"
source = sourceSets.main.allJava
destinationDir = file("${project.docsDir}/luaJavadoc")
classpath = sourceSets.main.compileClasspath
options.docletpath = configurations.cctJavadoc.files as List
options.doclet = "cc.tweaked.javadoc.LuaDoclet"
options.noTimestamp = false
javadocTool = javaToolchains.javadocToolFor {
languageVersion = JavaLanguageVersion.of(11)
}
}
jar {
manifest {
attributes(["Specification-Title": "computercraft",
"Specification-Vendor": "SquidDev",
"Specification-Version": "1",
"Implementation-Title": "CC: Tweaked",
"Implementation-Version": "${mod_version}",
"Implementation-Vendor" :"SquidDev",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")])
}
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
}
[compileJava, compileTestJava].forEach {
it.configure {
options.compilerArgs << "-Xlint" << "-Xlint:-processing"
}
}
processResources {
inputs.property "version", mod_version
inputs.property "mcversion", mc_version
def hash = 'none'
Set<String> contributors = []
try {
hash = ["git", "-C", projectDir, "rev-parse", "HEAD"].execute().text.trim()
def blacklist = ['GitHub', 'dan200', 'Daniel Ratcliffe']
["git", "-C", projectDir, "log", "--format=tformat:%an%n%cn"].execute().text.split('\n').each {
if (!blacklist.contains(it)) contributors.add(it)
}
} catch(Exception e) {
e.printStackTrace()
}
inputs.property "commithash", hash
duplicatesStrategy = DuplicatesStrategy.INCLUDE
from(sourceSets.main.resources.srcDirs) {
include 'META-INF/mods.toml'
include 'data/computercraft/lua/rom/help/credits.txt'
expand 'version': mod_version,
'mcversion': mc_version,
'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
}
from(sourceSets.main.resources.srcDirs) {
exclude 'META-INF/mods.toml'
exclude 'data/computercraft/lua/rom/help/credits.txt'
}
}
sourcesJar {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
// Web tasks
import org.apache.tools.ant.taskdefs.condition.Os
List<String> mkCommand(String command) {
return Os.isFamily(Os.FAMILY_WINDOWS) ? ["cmd", "/c", command] : ["sh", "-c", command]
}
task rollup(type: Exec) {
group = "build"
description = "Bundles JS into rollup"
inputs.files(fileTree("src/web")).withPropertyName("sources")
inputs.file("package-lock.json").withPropertyName("package-lock.json")
inputs.file("tsconfig.json").withPropertyName("Typescript config")
inputs.file("rollup.config.js").withPropertyName("Rollup config")
outputs.file("$buildDir/rollup/index.js").withPropertyName("output")
commandLine mkCommand('"node_modules/.bin/rollup" --config rollup.config.js')
}
task minifyWeb(type: Exec, dependsOn: rollup) {
group = "build"
description = "Bundles JS into rollup"
inputs.file("$buildDir/rollup/index.js").withPropertyName("sources")
inputs.file("package-lock.json").withPropertyName("package-lock.json")
outputs.file("$buildDir/rollup/index.min.js").withPropertyName("output")
commandLine mkCommand('"node_modules/.bin/terser"' + " -o '$buildDir/rollup/index.min.js' '$buildDir/rollup/index.js'")
}
task illuaminateDocs(type: Exec, dependsOn: [minifyWeb, luaJavadoc]) {
group = "build"
description = "Bundles JS into rollup"
inputs.files(fileTree("doc")).withPropertyName("docs")
inputs.files(fileTree("src/main/resources/data/computercraft/lua/rom")).withPropertyName("lua rom")
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
inputs.dir("$buildDir/docs/luaJavadoc")
inputs.file("$buildDir/rollup/index.min.js").withPropertyName("scripts")
inputs.file("src/web/styles.css").withPropertyName("styles")
outputs.dir("$buildDir/docs/lua")
commandLine mkCommand('"bin/illuaminate" doc-gen')
}
task docWebsite(type: Copy, dependsOn: [illuaminateDocs]) {
from 'doc/logo.png'
into "${project.docsDir}/lua"
}
// Check tasks
test {
useJUnitPlatform()
testLogging {
events "skipped", "failed"
}
}
jacocoTestReport {
dependsOn('test')
reports {
xml.enabled true
html.enabled true
}
}
check.dependsOn jacocoTestReport
import com.hierynomus.gradle.license.tasks.LicenseCheck
import com.hierynomus.gradle.license.tasks.LicenseFormat
license {
mapping("java", "SLASHSTAR_STYLE")
strictCheck true
ext.year = Calendar.getInstance().get(Calendar.YEAR)
}
[licenseMain, licenseFormatMain].forEach {
it.configure {
include("**/*.java")
exclude("dan200/computercraft/api/**")
header file('config/license/main.txt')
}
}
[licenseTest, licenseFormatTest].forEach {
it.configure {
include("**/*.java")
header file('config/license/main.txt')
}
}
gradle.projectsEvaluated {
tasks.withType(LicenseFormat) {
outputs.upToDateWhen { false }
}
}
task licenseAPI(type: LicenseCheck);
task licenseFormatAPI(type: LicenseFormat);
[licenseAPI, licenseFormatAPI].forEach {
it.configure {
source = sourceSets.main.java
include("dan200/computercraft/api/**")
header file('config/license/api.txt')
}
}
task setupServer(type: Copy) {
group "test server"
description "Sets up the environment for the test server."
from("src/test/server-files") {
include "eula.txt"
include "server.properties"
}
into "test-files/server"
}
tasks.register('testInGame', JavaExec.class).configure {
it.group('test server')
it.description("Runs tests on a temporary Minecraft server.")
it.dependsOn(setupServer, 'prepareRunTestServer', 'cleanTestInGame')
// Copy from runTestServer. We do it in this slightly odd way as runTestServer
// isn't created until the task is configured (which is no good for us).
JavaExec exec = tasks.getByName('runTestServer')
it.setWorkingDir(exec.getWorkingDir())
it.setSystemProperties(exec.getSystemProperties())
it.setBootstrapClasspath(exec.getBootstrapClasspath())
it.setClasspath(exec.getClasspath())
it.setMain(exec.getMain())
it.setEnvironment(exec.getEnvironment())
it.setArgs(exec.getArgs())
it.setJvmArgs(exec.getJvmArgs())
it.systemProperty('forge.logging.console.level', 'info')
it.systemProperty('cctest.run', 'true')
// Jacoco and modlauncher don't play well together as the classes loaded in-game don't
// match up with those written to disk. We get Jacoco to dump all classes to disk, and
// use that when generating the report.
def coverageOut = new File(buildDir, 'jacocoClassDump/testInGame')
jacoco.applyTo(it)
it.jacoco.setIncludes(["dan200.computercraft.*"])
it.jacoco.setClassDumpDir(coverageOut)
it.outputs.dir(coverageOut)
// Older versions of modlauncher don't include a protection domain (and thus no code
// source). Jacoco skips such classes by default, so we need to explicitly include them.
it.jacoco.setIncludeNoLocationClasses(true)
}
tasks.register('jacocoTestInGameReport', JacocoReport.class).configure {
it.group('test server')
it.description('Generate coverage reports for in-game tests (testInGame)')
it.dependsOn('testInGame')
it.executionData(new File(buildDir, 'jacoco/testInGame.exec'))
it.sourceDirectories.from(sourceSets.main.allJava.srcDirs)
it.classDirectories.from(new File(buildDir, 'jacocoClassDump/testInGame'))
it.reports {
xml.enabled true
html.enabled true
}
}
check.dependsOn('jacocoTestInGameReport')
// Upload tasks
task checkRelease {
group "upload"
description "Verifies that everything is ready for a release"
inputs.property "version", mod_version
inputs.file("src/main/resources/data/computercraft/lua/rom/help/changelog.md")
inputs.file("src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
doLast {
def ok = true
// Check we're targetting the current version
def whatsnew = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.md").readLines()
if (whatsnew[0] != "New features in CC: Tweaked $mod_version") {
ok = false
project.logger.error("Expected `whatsnew.md' to target $mod_version.")
}
// Check "read more" exists and trim it
def idx = whatsnew.findIndexOf { it == 'Type "help changelog" to see the full version history.' }
if (idx == -1) {
ok = false
project.logger.error("Must mention the changelog in whatsnew.md")
} else {
whatsnew = whatsnew.getAt(0 ..< idx)
}
// Check whatsnew and changelog match.
def versionChangelog = "# " + whatsnew.join("\n")
def changelog = new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/changelog.md").getText()
if (!changelog.startsWith(versionChangelog)) {
ok = false
project.logger.error("whatsnew and changelog are not in sync")
}
if (!ok) throw new IllegalStateException("Could not check release")
}
}
check.dependsOn checkRelease
curseforge {
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
project {
id = '282001'
releaseType = 'release'
changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
relations {
incompatible "computercraft"
}
}
}
import com.modrinth.minotaur.TaskModrinthUpload
tasks.register('publishModrinth', TaskModrinthUpload.class).configure {
dependsOn('assemble', 'reobfJar')
onlyIf {
project.hasProperty('modrinthApiKey')
}
token = project.hasProperty('modrinthApiKey') ? project.getProperty('modrinthApiKey') : ''
projectId = 'gu7yAYhd'
versionNumber = "${project.mc_version}-${project.mod_version}"
uploadFile = jar
addGameVersion(project.mc_version)
changelog = "Release notes can be found on the [GitHub repository](https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
addLoader('forge')
}
tasks.withType(GenerateModuleMetadata) {
// We can't generate metadata as that includes Forge as a dependency.
enabled = false
}
publishing {
publications {
maven(MavenPublication) {
from components.java
pom {
name = 'CC: Tweaked'
description = 'CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles and more to Minecraft.'
url = 'https://github.com/SquidDev-CC/CC-Tweaked'
scm {
url = 'https://github.com/SquidDev-CC/CC-Tweaked.git'
}
issueManagement {
system = 'github'
url = 'https://github.com/SquidDev-CC/CC-Tweaked/issues'
}
licenses {
license {
name = 'ComputerCraft Public License, Version 1.0'
url = 'https://github.com/SquidDev-CC/CC-Tweaked/blob/mc-1.15.x/LICENSE'
}
}
withXml { asNode().remove(asNode().get("dependencies")) }
}
}
}
repositories {
if (project.hasProperty("mavenUser")) {
maven {
name = "SquidDev"
url = "https://squiddev.cc/maven"
credentials {
username = project.property("mavenUser") as String
password = project.property("mavenPass") as String
}
}
}
}
}
githubRelease {
token project.hasProperty('githubApiKey') ? project.githubApiKey : ''
owner 'SquidDev-CC'
repo 'CC-Tweaked'
targetCommitish.set(project.provider({
try {
return ["git", "-C", projectDir, "rev-parse", "--abbrev-ref", "HEAD"].execute().text.trim()
} catch (Exception e) {
e.printStackTrace()
}
return "master"
}))
tagName "v${mc_version}-${mod_version}"
releaseName "[${mc_version}] ${mod_version}"
body.set(project.provider({
"## " + new File(projectDir, "src/main/resources/data/computercraft/lua/rom/help/whatsnew.md")
.readLines()
.takeWhile { it != 'Type "help changelog" to see the full version history.' }
.join("\n").trim()
}))
prerelease false
}
def uploadTasks = ["publish", "curseforge", "publishModrinth", "githubRelease"]
uploadTasks.forEach { tasks.getByName(it).dependsOn checkRelease }
task uploadAll(dependsOn: uploadTasks) {
group "upload"
description "Uploads to all repositories (Maven, Curse, Modrinth, GitHub release)"
}

112
build.gradle.kts Normal file
View File

@ -0,0 +1,112 @@
// 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.compiler
import org.jetbrains.gradle.ext.runConfigurations
import org.jetbrains.gradle.ext.settings
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")
}
val isUnstable = project.properties["isUnstable"] == "true"
val modVersion: String by extra
val mcVersion: String by extra
githubRelease {
token(findProperty("githubApiKey") as String? ?: "")
owner.set("cc-tweaked")
repo.set("CC-Tweaked")
targetCommitish.set(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)
}
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 = ""
}
}
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.
moduleJavacAdditionalOptions = subprojects
.asSequence()
.map { evaluationDependsOn(it.path) }
.flatMap { project ->
val sourceSets = project.extensions.findByType(SourceSetContainer::class) ?: return@flatMap sequenceOf()
sourceSets.asSequence().map { sourceSet ->
val name = "${idea.project.name}.${project.name}.${sourceSet.name}"
val compile = project.tasks.named(sourceSet.compileJavaTaskName, JavaCompile::class).get()
name to compile.options.allCompilerArgs.joinToString(" ") { if (it.contains(" ")) "\"$it\"" else it }
}
}
.toMap()
}
versionCatalogUpdate {
sortByKey.set(false)
pin { versions.addAll("fastutil", "guava", "netty", "slf4j") }
keep { keepUnusedLibraries.set(true) }
}

84
buildSrc/build.gradle.kts Normal file
View File

@ -0,0 +1,84 @@
// 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
repositories {
mavenCentral()
gradlePluginPortal()
maven("https://maven.minecraftforge.net") {
name = "Forge"
content {
includeGroup("net.minecraftforge")
includeGroup("net.minecraftforge.gradle")
}
}
maven("https://maven.parchmentmc.org") {
name = "Librarian"
content {
includeGroupByRegex("^org\\.parchmentmc.*")
}
}
maven("https://maven.fabricmc.net/") {
name = "Fabric"
content {
includeGroup("net.fabricmc")
}
}
maven("https://squiddev.cc/maven") {
name = "SquidDev"
content {
includeGroup("cc.tweaked.vanilla-extract")
}
}
}
dependencies {
implementation(libs.errorProne.plugin)
implementation(libs.kotlin.plugin)
implementation(libs.spotless)
implementation(libs.curseForgeGradle)
implementation(libs.fabric.loom)
implementation(libs.forgeGradle)
implementation(libs.ideaExt)
implementation(libs.librarian)
implementation(libs.minotaur)
implementation(libs.vanillaExtract)
}
gradlePlugin {
plugins {
register("cc-tweaked") {
id = "cc-tweaked"
implementationClass = "cc.tweaked.gradle.CCTweakedPlugin"
}
register("cc-tweaked.illuaminate") {
id = "cc-tweaked.illuaminate"
implementationClass = "cc.tweaked.gradle.IlluaminatePlugin"
}
register("cc-tweaked.node") {
id = "cc-tweaked.node"
implementationClass = "cc.tweaked.gradle.NodePlugin"
}
}
}
versionCatalogUpdate {
sortByKey.set(false)
keep { keepUnusedLibraries.set(true) }
catalogFile.set(file("../gradle/libs.versions.toml"))
}

View File

@ -0,0 +1,11 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}

View File

@ -0,0 +1,69 @@
// 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
plugins {
`java-library`
id("fabric-loom")
id("cc-tweaked.java-convention")
}
plugins.apply(CCTweakedPlugin::class.java)
val mcVersion: String by extra
repositories {
maven("https://maven.parchmentmc.org/") {
name = "Parchment"
content {
includeGroup("org.parchmentmc.data")
}
}
}
loom {
splitEnvironmentSourceSets()
splitModDependencies.set(true)
}
MinecraftConfigurations.setup(project)
extensions.configure(CCTweakedExtension::class.java) {
linters(minecraft = true, loader = "fabric")
}
dependencies {
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
minecraft("com.mojang:minecraft:$mcVersion")
mappings(
loom.layered {
officialMojangMappings()
parchment(
project.dependencies.create(
group = "org.parchmentmc.data",
name = "parchment-${libs.findVersion("parchmentMc").get()}",
version = libs.findVersion("parchment").get().toString(),
ext = "zip",
),
)
},
)
modImplementation(libs.findLibrary("fabric-loader").get())
modImplementation(libs.findLibrary("fabric-api").get())
// Depend on error prone annotations to silence a lot of compile warnings.
compileOnlyApi(libs.findLibrary("errorProne.annotations").get())
}
tasks.ideaSyncTask {
doLast { IdeaRunConfigurations(project).patch() }
}

View File

@ -0,0 +1,44 @@
// 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("net.minecraftforge.gradle")
// We must apply java-convention after Forge, as we need the fg extension to be present.
id("cc-tweaked.java-convention")
id("org.parchmentmc.librarian.forgegradle")
}
plugins.apply(CCTweakedPlugin::class.java)
val mcVersion: String by extra
minecraft {
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
mappings("parchment", "${libs.findVersion("parchmentMc").get()}-${libs.findVersion("parchment").get()}-$mcVersion")
accessTransformer(project(":forge").file("src/main/resources/META-INF/accesstransformer.cfg"))
}
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

@ -0,0 +1,64 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
import cc.tweaked.gradle.clientClasses
import cc.tweaked.gradle.commonClasses
/**
* Sets up the configurations for writing game tests.
*
* See notes in [cc.tweaked.gradle.MinecraftConfigurations] for the general design behind these cursed ideas.
*/
plugins {
id("cc-tweaked.kotlin-convention")
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
}
configurations {
named(testMod.compileClasspathConfigurationName) {
shouldResolveConsistentlyWith(compileClasspath.get())
}
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)
}
// Similar to java-test-fixtures, but tries to avoid putting the obfuscated jar on the classpath.
val testFixtures by sourceSets.creating {
compileClasspath += main.compileClasspath + client.compileClasspath
}
java.registerFeature("testFixtures") {
usingSourceSet(testFixtures)
disablePublication()
}
dependencies {
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
add(testFixtures.apiConfigurationName, libs.findBundle("test").get())
// Consumers of this project already have the common and client classes on the classpath, so it's fine for these
// to be compile-only.
add(testFixtures.compileOnlyApiConfigurationName, commonClasses(project))
add(testFixtures.compileOnlyApiConfigurationName, clientClasses(project))
testImplementation(testFixtures(project))
}

View File

@ -0,0 +1,231 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
import cc.tweaked.gradle.CCTweakedExtension
import cc.tweaked.gradle.CCTweakedPlugin
import com.diffplug.gradle.spotless.FormatExtension
import com.diffplug.spotless.LineEnding
import net.ltgt.gradle.errorprone.CheckSeverity
import net.ltgt.gradle.errorprone.errorprone
import java.nio.charset.StandardCharsets
plugins {
`java-library`
idea
jacoco
checkstyle
id("com.diffplug.spotless")
id("net.ltgt.errorprone")
}
val modVersion: String by extra
val mcVersion: String by extra
group = "cc.tweaked"
version = modVersion
base.archivesName.convention("cc-tweaked-$mcVersion-${project.name}")
java {
toolchain {
languageVersion.set(CCTweakedPlugin.JAVA_VERSION)
}
withSourcesJar()
}
repositories {
mavenCentral()
val mainMaven = maven("https://squiddev.cc/maven") {
name = "SquidDev"
}
exclusiveContent {
forRepositories(mainMaven)
// Include the ForgeGradle repository if present. This requires that ForgeGradle is already present, which we
// enforce in our Forge overlay.
val fg =
project.extensions.findByType(net.minecraftforge.gradle.userdev.DependencyManagementExtension::class.java)
if (fg != null) forRepositories(fg.repository)
filter {
includeGroup("cc.tweaked")
// Things we mirror
includeGroup("commoble.morered")
includeGroup("dev.architectury")
includeGroup("dev.emi")
includeGroup("maven.modrinth")
includeGroup("me.shedaniel.cloth")
includeGroup("me.shedaniel")
includeGroup("mezz.jei")
includeGroup("org.teavm")
includeModule("com.terraformersmc", "modmenu")
includeModule("me.lucko", "fabric-permissions-api")
}
}
}
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())
}
// 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.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("ReferenceEquality", CheckSeverity.OFF)
check("UnusedVariable", CheckSeverity.OFF) // Too many false positives with records.
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("NullAway", CheckSeverity.ERROR)
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/.*"
}
}
}
tasks.compileTestJava {
options.errorprone {
check("NullAway", CheckSeverity.OFF)
}
}
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)
}
tasks.jar {
manifest {
attributes(
"Specification-Title" to "computercraft",
"Specification-Vendor" to "SquidDev",
"Specification-Version" to "1",
"Implementation-Title" to "cctweaked-${project.name}",
"Implementation-Version" to modVersion,
"Implementation-Vendor" to "SquidDev",
)
}
}
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/")
}
}
tasks.test {
finalizedBy("jacocoTestReport")
useJUnitPlatform()
testLogging {
events("skipped", "failed")
}
}
tasks.withType(JacocoReport::class.java).configureEach {
reports.xml.required.set(true)
reports.html.required.set(true)
}
project.plugins.withType(CCTweakedPlugin::class.java) {
// Set up jacoco to read from /all/ our source directories.
val cct = project.extensions.getByType<CCTweakedExtension>()
project.tasks.named("jacocoTestReport", JacocoReport::class.java) {
for (ref in cct.sourceSets.get()) sourceDirectories.from(ref.allSource.sourceDirectories)
}
}
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
fun FormatExtension.defaults() {
endWithNewline()
trimTrailingWhitespace()
indentWithSpaces(4)
}
java {
defaults()
removeUnusedImports()
}
val ktlintConfig = mapOf(
"ktlint_standard_no-wildcard-imports" to "disabled",
"ktlint_standard_class-naming" to "disabled",
"ktlint_standard_function-naming" to "disabled",
"ij_kotlin_allow_trailing_comma" to "true",
"ij_kotlin_allow_trailing_comma_on_call_site" to "true",
)
kotlinGradle {
defaults()
ktlint().editorConfigOverride(ktlintConfig)
}
kotlin {
defaults()
ktlint().editorConfigOverride(ktlintConfig)
}
}
idea.module {
excludeDirs.addAll(project.files("run", "out", "logs").files)
// 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

@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.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,58 @@
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
import net.darkhax.curseforgegradle.TaskPublishCurseForge
import cc.tweaked.gradle.setProvider
plugins {
id("net.darkhax.curseforgegradle")
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
val publishCurseForge by tasks.registering(TaskPublishCurseForge::class) {
group = PublishingPlugin.PUBLISH_TASK_GROUP
description = "Upload artifacts to CurseForge"
apiToken = findProperty("curseForgeApiKey") ?: ""
enabled = apiToken != ""
val mainFile = upload("282001", modPublishing.output)
mainFile.changelog =
"Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v$mcVersion-$modVersion)."
mainFile.changelogType = "markdown"
mainFile.releaseType = if (isUnstable) "alpha" else "release"
mainFile.gameVersions.add(mcVersion)
}
tasks.publish { dependsOn(publishCurseForge) }
modrinth {
token.set(findProperty("modrinthApiKey") as String? ?: "")
projectId.set("gu7yAYhd")
versionNumber.set(modVersion)
versionName.set(modVersion)
versionType.set(if (isUnstable) "alpha" else "release")
uploadFile.setProvider(modPublishing.output)
gameVersions.add(mcVersion)
changelog.set("Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v$mcVersion-$modVersion).")
syncBodyFrom.set(provider { rootProject.file("doc/mod-page.md").readText() })
}
tasks.publish { dependsOn(tasks.modrinth) }

View File

@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
plugins {
`java-library`
`maven-publish`
}
publishing {
publications {
register<MavenPublication>("maven") {
artifactId = base.archivesName.get()
from(components["java"])
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")
scm {
url.set("https://github.com/cc-tweaked/CC-Tweaked.git")
}
issueManagement {
system.set("github")
url.set("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")
}
}
}
}
}
repositories {
maven("https://squiddev.cc/maven") {
name = "SquidDev"
credentials(PasswordCredentials::class)
}
}
}

View File

@ -0,0 +1,41 @@
// 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
import cc.tweaked.gradle.CCTweakedPlugin
import cc.tweaked.gradle.MinecraftConfigurations
plugins {
id("cc-tweaked.java-convention")
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 {
// Depend on error prone annotations to silence a lot of compile warnings.
compileOnly(libs.findLibrary("errorProne.annotations").get())
}
MinecraftConfigurations.setupBasic(project)
extensions.configure(CCTweakedExtension::class.java) {
linters(minecraft = true, loader = null)
}

View File

@ -0,0 +1,294 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import net.ltgt.gradle.errorprone.CheckSeverity
import net.ltgt.gradle.errorprone.errorprone
import org.gradle.api.GradleException
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Dependency
import org.gradle.api.attributes.TestSuiteType
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.provider.ListProperty
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
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
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,
) {
/** 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()
}
/** 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()
}
/** 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)
}
/**
* References to other sources
*/
val sourceDirectories: SetProperty<SourceSetReference> = project.objects.setProperty(SourceSetReference::class.java)
/**
* Dependencies excluded from published artifacts.
*/
private val excludedDeps: ListProperty<Dependency> = project.objects.listProperty(Dependency::class.java)
/** All source sets referenced by this project. */
val sourceSets = sourceDirectories.map { x -> x.map { it.sourceSet } }
init {
sourceDirectories.finalizeValueOnRead()
excludedDeps.finalizeValueOnRead()
project.afterEvaluate { sourceDirectories.disallowChanges() }
}
/**
* Mark this project as consuming another project. Its [sourceDirectories] are added, allowing easier configuration
* of run configurations and other tasks which consume sources/classes.
*/
fun externalSources(project: Project) {
val otherCct = project.extensions.getByType(CCTweakedExtension::class.java)
for (sourceSet in otherCct.sourceDirectories.get()) {
sourceDirectories.add(SourceSetReference(sourceSet.sourceSet, classes = sourceSet.classes, external = true))
}
}
/**
* Add a dependency on another project such that its sources and compiles are processed with this one.
*
* This is used when importing a common library into a loader-specific one, as we want to compile sources using
* the loader-specific sources.
*/
fun inlineProject(path: String) {
val otherProject = project.evaluationDependsOn(path)
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)
// The extra source-processing tasks should include these files too.
project.tasks.named(main.javadocTaskName, Javadoc::class.java) { source(main.allJava, client.allJava) }
project.tasks.named(main.sourcesJarTaskName, Jar::class.java) { from(main.allSource, client.allSource) }
sourceDirectories.addAll(SourceSetReference.inline(main), SourceSetReference.inline(client))
}
/**
* Extend a source set with files from another project.
*
* This actually extends the original compile tasks, as extending the source sets does not play well with IDEs.
*/
private fun extendSourceSet(otherProject: Project, sourceSet: SourceSet) {
project.tasks.named(sourceSet.compileJavaTaskName, JavaCompile::class.java) {
dependsOn(otherProject.tasks.named(sourceSet.compileJavaTaskName)) // Avoid duplicate compile errors
source(sourceSet.allJava)
}
project.tasks.named(sourceSet.processResourcesTaskName, ProcessResources::class.java) {
from(sourceSet.resources)
}
// Also try to depend on Kotlin if it exists
val kotlin = otherProject.extensions.findByType(KotlinProjectExtension::class.java)
if (kotlin != null) {
val compileKotlin = sourceSet.getCompileTaskName("kotlin")
project.tasks.named(compileKotlin, KotlinCompile::class.java) {
dependsOn(otherProject.tasks.named(compileKotlin))
source(kotlin.sourceSets.getByName(sourceSet.name).kotlin)
}
}
// If we're doing an IDE sync, add a fake dependency to ensure it's on the classpath.
if (isIdeSync) project.dependencies.add(sourceSet.apiConfigurationName, sourceSet.output)
}
fun linters(@Suppress("UNUSED_PARAMETER") vararg unused: UseNamedArgs, minecraft: Boolean, loader: String?) {
val java = project.extensions.getByType(JavaPluginExtension::class.java)
val sourceSets = java.sourceSets
project.dependencies.run { add("errorprone", project(mapOf("path" to ":lints"))) }
sourceSets.all {
val name = name
project.tasks.named(compileJavaTaskName, JavaCompile::class.java) {
options.errorprone {
// Only the main source set should run the side checker
check("SideChecker", if (minecraft && name == "main") CheckSeverity.DEFAULT else CheckSeverity.OFF)
// The MissingLoaderOverride check superseeds the MissingOverride one, so disable that.
if (loader != null) {
check("MissingOverride", CheckSeverity.OFF)
option("ModLoader", loader)
} else {
check("LoaderOverride", CheckSeverity.OFF)
check("MissingLoaderOverride", CheckSeverity.OFF)
}
}
}
}
}
fun <T> jacoco(task: NamedDomainObjectProvider<T>) where T : Task, T : JavaForkOptions {
val classDump = project.layout.buildDirectory.dir("jacocoClassDump/${task.name}")
val reportTaskName = "jacoco${task.name.capitalized()}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.get().asFile
// 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
}
}
project.tasks.register(reportTaskName, JacocoReport::class.java) {
group = LifecycleBasePlugin.VERIFICATION_GROUP
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)
}
}
}
/**
* Download a file by creating a dummy Ivy repository.
*
* This should only be used for one-off downloads. Using a more conventional Ivy or Maven repository is preferred
* where possible.
*/
fun downloadFile(label: String, url: String): File {
val url = URL(url)
val path = File(url.path)
project.repositories.ivy {
name = label
setUrl(URI(url.protocol, url.userInfo, url.host, url.port, path.parent, null, null))
patternLayout {
artifact("[artifact].[ext]")
}
metadataSources {
artifact()
}
content {
includeModule("cc.tweaked.internal", path.nameWithoutExtension)
}
}
return project.configurations.detachedConfiguration(
project.dependencies.create(
mapOf(
"group" to "cc.tweaked.internal",
"name" to path.nameWithoutExtension,
"ext" to path.extension,
),
),
).resolve().single()
}
/**
* Exclude a dependency from being published in Maven.
*/
fun exclude(dep: Dependency) {
excludedDeps.add(dep)
}
/**
* Configure a [MavenDependencySpec].
*/
fun configureExcludes(spec: MavenDependencySpec) {
for (dep in excludedDeps.get()) spec.exclude(dep)
}
companion object {
private val COMMIT_COUNTS = Pattern.compile("""^\s*[0-9]+\s+(.*)$""")
private val IGNORED_USERS = setOf(
"GitHub", "Daniel Ratcliffe", "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

@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.Plugin
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.
*/
class CCTweakedPlugin : Plugin<Project> {
override fun apply(project: Project) {
val cct = project.extensions.create("cct", CCTweakedExtension::class.java)
project.plugins.withType(JavaPlugin::class.java) {
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)
}
}

View File

@ -0,0 +1,68 @@
// SPDX-FileCopyrightText: 2022 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.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
import org.gradle.language.base.plugins.LifecycleBasePlugin
/**
* Checks the `changelog.md` and `whatsnew.md` files are well-formed.
*/
@CacheableTask
abstract class CheckChangelog : DefaultTask() {
init {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Verifies the changelog and whatsnew file are consistent."
}
@get:Input
abstract val version: Property<String>
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val changelog: RegularFileProperty
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val whatsNew: RegularFileProperty
@TaskAction
fun check() {
val version = version.get()
var ok = true
// Check we're targeting the current version
var whatsNew = whatsNew.get().asFile.readLines()
if (whatsNew[0] != "New features in CC: Tweaked $version") {
ok = false
logger.error("Expected `whatsnew.md' to target $version.")
}
// Check "read more" exists and trim it
val idx = whatsNew.indexOfFirst { it == "Type \"help changelog\" to see the full version history." }
if (idx == -1) {
ok = false
logger.error("Must mention the changelog in whatsnew.md")
} else {
whatsNew = whatsNew.slice(0 until idx)
}
// Check whatsnew and changelog match.
val expectedChangelog = sequenceOf("# ${whatsNew[0]}") + whatsNew.slice(1 until whatsNew.size).asSequence()
val changelog = changelog.get().asFile.readLines()
val mismatch = expectedChangelog.zip(changelog.asSequence()).filter { (a, b) -> a != b }.firstOrNull()
if (mismatch != null) {
ok = false
logger.error("whatsnew and changelog are not in sync")
}
if (!ok) throw GradleException("Could not check release")
}
}

View File

@ -0,0 +1,92 @@
// 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
abstract val configuration: ListProperty<Configuration>
/**
* A mapping of module coordinates (`group:module`) to versions, overriding the requested version.
*/
@get:Input
abstract val overrides: MapProperty<String, String>
init {
description = "Check :core's dependencies are consistent with Minecraft's."
group = LifecycleBasePlugin.VERIFICATION_GROUP
configuration.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) })
}
@TaskAction
fun run() {
var ok = true
for (configuration in configuration.get()) {
configuration.incoming.resolutionResult.allDependencies {
if (!check(this@allDependencies)) 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

@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
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: DirectoryProperty
}

View File

@ -0,0 +1,157 @@
// 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.process.BaseExecSpec
import org.gradle.process.JavaExecSpec
import org.gradle.process.ProcessForkOptions
/**
* Add an annotation processor to all source sets.
*/
fun DependencyHandler.annotationProcessorEverywhere(dep: Any) {
add("compileOnly", dep)
add("annotationProcessor", dep)
add("clientCompileOnly", dep)
add("clientAnnotationProcessor", dep)
add("testCompileOnly", dep)
add("testAnnotationProcessor", dep)
}
/**
* A version of [JavaExecSpec.copyTo] which copies *all* properties.
*/
fun JavaExec.copyToFull(spec: JavaExec) {
copyTo(spec)
// Additional Java options
spec.jvmArgs = jvmArgs // Fabric overrides getJvmArgs so copyTo doesn't do the right thing.
spec.args = args
spec.argumentProviders.addAll(argumentProviders)
spec.mainClass.set(mainClass)
spec.classpath = classpath
spec.javaLauncher.set(javaLauncher)
if (executable != null) spec.setExecutable(executable!!)
// Additional ExecSpec options
copyToExec(spec)
}
/**
* Copy additional [BaseExecSpec] options which aren't handled by [ProcessForkOptions.copyTo].
*/
fun BaseExecSpec.copyToExec(spec: BaseExecSpec) {
spec.isIgnoreExitValue = isIgnoreExitValue
if (standardInput != null) spec.standardInput = standardInput
if (standardOutput != null) spec.standardOutput = standardOutput
if (errorOutput != null) spec.errorOutput = errorOutput
}
/**
* An alternative to [Nothing] with a more descriptive name. Use to enforce calling a function with named arguments:
*
* ```kotlin
* fun f(vararg unused: UseNamedArgs, arg1: Int, arg2: Int) {
* // ...
* }
* ```
*/
class UseNamedArgs private constructor()
/**
* An [AutoCloseable] implementation which can be used to combine other [AutoCloseable] instances.
*
* Values which implement [AutoCloseable] can be dynamically registered with [CloseScope.add]. When the scope is closed,
* each value is closed in the opposite order.
*
* This is largely intended for cases where it's not appropriate to nest [AutoCloseable.use], for instance when nested
* would be too deep.
*/
class CloseScope : AutoCloseable {
private val toClose = ArrayDeque<AutoCloseable>()
/**
* Add a value to be closed when this scope is closed.
*/
public fun add(value: AutoCloseable) {
toClose.addLast(value)
}
override fun close() {
close(null)
}
@PublishedApi
internal fun close(baseException: Throwable?) {
var exception = baseException
while (true) {
var toClose = toClose.removeLastOrNull() ?: break
try {
toClose.close()
} catch (e: Throwable) {
if (exception == null) {
exception = e
} else {
exception.addSuppressed(e)
}
}
}
if (exception != null) throw exception
}
inline fun <R> use(block: (CloseScope) -> R): R {
var exception: Throwable? = null
try {
return block(this)
} catch (e: Throwable) {
exception = e
throw e
} finally {
close(exception)
}
}
}
/** 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 {
version.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()
}

View File

@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import net.minecraftforge.gradle.common.util.RunConfig
import net.minecraftforge.gradle.common.util.runs.setRunConfigInternal
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.JavaExec
import org.gradle.jvm.toolchain.JavaToolchainService
import java.nio.file.Files
/**
* Set [JavaExec] task to run a given [RunConfig].
*/
fun JavaExec.setRunConfig(config: RunConfig) {
dependsOn("prepareRuns")
setRunConfigInternal(project, this, config)
doFirst("Create working directory") { Files.createDirectories(workingDir.toPath()) }
javaLauncher.set(
project.extensions.getByType(JavaToolchainService::class.java)
.launcherFor(project.extensions.getByType(JavaPluginExtension::class.java).toolchain),
)
}

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

@ -0,0 +1,174 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.Project
import org.gradle.api.logging.Logging
import org.w3c.dom.Attr
import org.w3c.dom.Document
import org.w3c.dom.Node
import org.xml.sax.InputSource
import java.nio.file.Files
import java.nio.file.Path
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
import javax.xml.xpath.XPathConstants
import javax.xml.xpath.XPathFactory
/**
* Patches up run configurations from ForgeGradle and Loom.
*
* 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
private val documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
private val xpath = XPathFactory.newInstance().newXPath()
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")
if (!runConfigDir.isDirectory) return
Files.list(runConfigDir.toPath()).use {
for (configuration in it) {
val filename = configuration.fileName.toString();
when {
filename.endsWith("_fabric.xml") -> patchFabric(configuration)
filename.startsWith("forge_") && filename.endsWith(".xml") -> patchForge(configuration)
else -> {}
}
}
}
}
private fun patchFabric(path: Path) = withXml(path) {
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) {
LOGGER.error("[{}] Cannot find {}", path.fileName, xpath)
return
}
val attr = node.attributes.getNamedItem(attribute) as Attr? ?: document.createAttribute(attribute)
val oldValue = attr.value
attr.value = value(attr.value)
node.attributes.setNamedItem(attr)
if (oldValue != attr.value) {
LOGGER.info("[{}] Setting {}@{}:\n Old: {}\n New: {}", path.fileName, xpath, attribute, oldValue, attr.value)
}
}
private fun withXml(path: Path, run: LocatedDocument.() -> Unit) {
val doc = Files.newBufferedReader(path).use { documentBuilder.parse(InputSource(it)) }
run(LocatedDocument(path, doc))
Files.newBufferedWriter(path).use { writer.transform(DOMSource(doc), StreamResult(it)) }
}
private class LocatedDocument(val path: Path, val document: Document)
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

@ -0,0 +1,127 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Dependency
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.AbstractExecTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import java.io.File
abstract class IlluaminateExtension {
/** The version of illuaminate to use. */
abstract val version: Property<String>
/** The path to illuaminate. If not given, illuaminate will be downloaded automatically. */
abstract val file: Property<File>
}
class IlluaminatePlugin : Plugin<Project> {
override fun apply(project: Project) {
val extension = project.extensions.create("illuaminate", IlluaminateExtension::class.java)
extension.file.convention(setupDependency(project, extension.version))
project.tasks.register(SetupIlluaminate.NAME, SetupIlluaminate::class.java) {
file.set(extension.file.map { it.absolutePath })
}
}
/** Set up a repository for illuaminate and download our binary from it. */
private fun setupDependency(project: Project, version: Provider<String>): Provider<File> {
project.repositories.ivy {
name = "Illuaminate"
setUrl("https://squiddev.cc/illuaminate/bin/")
patternLayout {
artifact("[revision]/[artifact]-[ext]")
}
metadataSources {
artifact()
}
content {
includeModule("cc.squiddev", "illuaminate")
}
}
return version.map {
val dep = illuaminateArtifact(project, it)
val configuration = project.configurations.detachedConfiguration(dep)
configuration.isTransitive = false
configuration.resolve().single()
}
}
/** 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").lowercase()
val (os, suffix) = when {
osName.contains("windows") -> Pair("windows", ".exe")
osName.contains("mac os") || osName.contains("darwin") -> Pair("macos", "")
osName.contains("linux") -> Pair("linux", "")
else -> error("Unsupported OS $osName for illuaminate")
}
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"
osArch == "arm" || osArch.startsWith("aarch") -> error("Unsupported architecture '$osArch' for illuaminate")
osArch.contains("64") -> "x86_64"
else -> error("Unsupported architecture '$osArch' for illuaminate")
}
return project.dependencies.create(
mapOf(
"group" to "cc.squiddev",
"name" to "illuaminate",
"version" to version,
"ext" to "$os-$arch$suffix",
),
)
}
}
private val Task.illuaminatePath: String? // "?" needed to avoid overload ambiguity in setExecutable below.
get() = project.extensions.getByType(IlluaminateExtension::class.java).file.get().absolutePath
/** Prepares illuaminate for being run. This simply requests the dependency and then marks it as executable. */
abstract class SetupIlluaminate : DefaultTask() {
@get:Input
abstract val file: Property<String>
@TaskAction
fun setExecutable() {
val file = File(this.file.get())
if (file.canExecute()) {
didWork = false
return
}
file.setExecutable(true)
}
companion object {
const val NAME: String = "setupIlluaminate"
}
}
abstract class IlluaminateExec : AbstractExecTask<IlluaminateExec>(IlluaminateExec::class.java) {
init {
dependsOn(SetupIlluaminate.NAME)
executable = illuaminatePath
}
}
abstract class IlluaminateExecToDir : ExecToDir() {
init {
dependsOn(SetupIlluaminate.NAME)
executable = illuaminatePath
}
}

View File

@ -0,0 +1,73 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.plugins.BasePluginExtension
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 {
// We have to cheat a little for project dependencies, as the project name doesn't match the artifact group.
val name = when (dep) {
is ProjectDependency -> dep.dependencyProject.extensions.getByType(BasePluginExtension::class.java).archivesName.get()
else -> dep.name
}
(dep.group.isNullOrEmpty() || dep.group == it.groupId) &&
(name.isNullOrEmpty() || 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: 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.ModuleDependency
import org.gradle.api.artifacts.dsl.DependencyHandler
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
/**
* This sets up a separate client-only source set, and extends that and the main/common source set with additional
* metadata, to make it easier to consume jars downstream.
*/
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]
/**
* Performs the initial setup of our configurations.
*/
private fun setup() {
// Define a client source set.
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])
}
// Set up an API configuration for clients (to ensure it's consistent with the main source set).
val clientApi = configurations.maybeCreate(client.apiConfigurationName).apply {
isVisible = false
isCanBeConsumed = false
isCanBeResolved = false
}
configurations.named(client.implementationConfigurationName) { extendsFrom(clientApi) }
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")
}
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,
// but avoids accidentally pulling in Forge's obfuscated jar.
client.compileClasspath = client.compileClasspath + main.compileClasspath
client.runtimeClasspath = client.runtimeClasspath + main.runtimeClasspath
project.dependencies.add(client.apiConfigurationName, main.output)
// Also add client classes to the test classpath. We do the same nasty tricks as needed for main -> client.
test.compileClasspath += client.compileClasspath
test.runtimeClasspath += client.runtimeClasspath
project.dependencies.add(test.implementationConfigurationName, client.output)
// Configure some tasks to include our additional files.
project.tasks.named("javadoc", Javadoc::class.java) {
source(client.allJava)
classpath = main.compileClasspath + main.output + client.compileClasspath + client.output
}
// This are already done by Fabric, but we need it for Forge and vanilla. It shouldn't conflict at all.
project.tasks.named("jar", Jar::class.java) { from(client.output) }
project.tasks.named("sourcesJar", Jar::class.java) { from(client.allSource) }
setupBasic()
}
private fun setupBasic() {
val client = sourceSets["client"]
project.extensions.configure(CCTweakedExtension::class.java) {
sourceDirectories.add(SourceSetReference.internal(client))
}
// 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.add(configurations.named(main.runtimeClasspathConfigurationName))
configuration.add(configurations.named(client.runtimeClasspathConfigurationName))
}
project.tasks.named("check") { dependsOn(checkDependencyConsistency) }
}
companion object {
fun setupBasic(project: Project) {
MinecraftConfigurations(project).setupBasic()
}
fun setup(project: Project) {
MinecraftConfigurations(project).setup()
}
}
}
fun DependencyHandler.clientClasses(notation: Any): ModuleDependency =
Capabilities.clientClasses(create(notation) as ModuleDependency)
fun DependencyHandler.commonClasses(notation: Any): ModuleDependency =
Capabilities.commonClasses(create(notation) as ModuleDependency)

View File

@ -0,0 +1,215 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import net.minecraftforge.gradle.common.util.RunConfig
import org.gradle.api.GradleException
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.invocation.Gradle
import org.gradle.api.provider.Provider
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
import org.gradle.api.tasks.*
import org.gradle.kotlin.dsl.getByName
import org.gradle.language.base.plugins.LifecycleBasePlugin
import java.io.File
import java.nio.file.Files
import java.util.concurrent.TimeUnit
import java.util.function.Supplier
import javax.inject.Inject
import kotlin.random.Random
/**
* A [JavaExec] task for client-tests. This sets some common setup, and uses [MinecraftRunnerService] to ensure only one
* test runs at once.
*/
abstract class ClientJavaExec : JavaExec() {
private val clientRunner: Provider<MinecraftRunnerService> = MinecraftRunnerService.get(project.gradle)
init {
group = LifecycleBasePlugin.VERIFICATION_GROUP
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() = renderdoc || project.hasProperty("clientDebug")
/**
* When [false], tests will not run under a framebuffer.
*/
@get:Input
val useFramebuffer get() = !clientDebug && !project.hasProperty("clientNoFramebuffer")
/**
* The path test results are written to.
*/
@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()
}
/**
* Set this task to run a given [RunConfig].
*/
fun setRunConfig(config: RunConfig) {
(this as JavaExec).setRunConfig(config)
setTestProperties() // setRunConfig may clobber some properties, ensure everything is set.
}
/**
* Copy configuration from a task with the given name.
*/
fun copyFrom(path: String) = copyFrom(project.tasks.getByName(path, JavaExec::class))
/**
* Copy configuration from an existing [JavaExec] task.
*/
fun copyFrom(task: JavaExec) {
for (dep in task.dependsOn) dependsOn(dep)
task.copyToFull(this)
setTestProperties() // copyToFull may clobber some properties, ensure everything is set.
}
/**
* Only run tests with the given tags.
*/
fun tags(vararg tags: String) {
systemProperty("cctest.tags", tags.joinToString(","))
}
/**
* Write a file with the given contents before starting Minecraft. This may be useful for writing config files.
*/
fun withFileContents(path: Any, contents: Supplier<String>) {
val file = project.file(path).toPath()
doFirst {
Files.createDirectories(file.parent)
Files.writeString(file, contents.get())
}
}
/**
* Copy a file to the provided path before starting Minecraft. This copy only occurs if the file does not already
* exist.
*/
fun withFileFrom(path: Any, source: Supplier<File>) {
val file = project.file(path).toPath()
doFirst {
Files.createDirectories(file.parent)
if (!Files.exists(file)) Files.copy(source.get().toPath(), file)
}
}
@TaskAction
override fun exec() {
Files.createDirectories(workingDir.toPath())
fsOperations.delete { delete(workingDir.resolve("screenshots")) }
if (useFramebuffer) {
clientRunner.get().wrapClient(this) { super.exec() }
} else {
super.exec()
}
}
@get:Inject
protected abstract val fsOperations: FileSystemOperations
}
/**
* A service for [JavaExec] tasks which start Minecraft.
*
* Tasks may run `usesService(MinecraftRunnerService.get(gradle))` to ensure that only one Minecraft-related task runs
* at once.
*/
abstract class MinecraftRunnerService : BuildService<BuildServiceParameters.None> {
private val hasXvfb = lazy {
System.getProperty("os.name", "").equals("linux", ignoreCase = true) && ProcessHelpers.onPath("xvfb-run")
}
internal fun wrapClient(exec: JavaExec, run: () -> Unit) = when {
hasXvfb.value -> runXvfb(exec, run)
else -> run()
}
/**
* Run a program under Xvfb, preventing it spawning a window.
*/
private fun runXvfb(exec: JavaExec, run: () -> Unit) {
fun ProcessBuilder.startVerbose(): Process {
exec.logger.info("Running ${this.command()}")
return start()
}
CloseScope().use { scope ->
val dir = Files.createTempDirectory("cctweaked").toAbsolutePath()
scope.add { fsOperations.delete { delete(dir) } }
val authFile = Files.createTempFile(dir, "Xauthority", "").toAbsolutePath()
val cookie = StringBuilder().also {
for (i in 0..31) it.append("0123456789abcdef"[Random.nextInt(16)])
}.toString()
val xvfb =
ProcessBuilder("Xvfb", "-displayfd", "1", "-screen", "0", "640x480x24", "-nolisten", "tcp").also {
it.inheritIO()
it.environment()["XAUTHORITY"] = authFile.toString()
it.redirectOutput(ProcessBuilder.Redirect.PIPE)
}.startVerbose()
scope.add { xvfb.destroyForcibly().waitFor() }
val server = xvfb.inputReader().use { it.readLine().trim() }
exec.logger.info("Running at :$server (XAUTHORITY=$authFile.toA")
ProcessBuilder("xauth", "add", ":$server", ".", cookie).also {
it.inheritIO()
it.environment()["XAUTHORITY"] = authFile.toString()
}.startVerbose().waitForOrThrow("Failed to setup XAuthority file")
scope.add {
ProcessBuilder("xauth", "remove", ":$server").also {
it.inheritIO()
it.environment()["XAUTHORITY"] = authFile.toString()
}.startVerbose().waitFor()
}
// Wait a few seconds for Xvfb to start. Ugly, but identical to xvfb-run.
if (xvfb.waitFor(3, TimeUnit.SECONDS)) {
throw GradleException("Xvfb unexpectedly exited (with status code ${xvfb.exitValue()})")
}
exec.environment("XAUTHORITY", authFile.toString())
exec.environment("DISPLAY", ":$server")
run()
}
}
@get:Inject
protected abstract val fsOperations: FileSystemOperations
companion object {
fun get(gradle: Gradle): Provider<MinecraftRunnerService> =
gradle.sharedServices.registerIfAbsent("cc.tweaked.gradle.ClientJavaExec", MinecraftRunnerService::class.java) {
maxParallelUsages.set(1)
}
}
}

View File

@ -0,0 +1,64 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import java.io.File
class NodePlugin : Plugin<Project> {
override fun apply(project: Project) {
val extension = project.extensions.create("node", NodeExtension::class.java)
project.tasks.register(NpmInstall.TASK_NAME, NpmInstall::class.java) {
projectRoot.convention(extension.projectRoot)
}
}
}
abstract class NodeExtension(project: Project) {
/** The directory containing `package-lock.json` and `node_modules/`. */
abstract val projectRoot: DirectoryProperty
init {
projectRoot.convention(project.layout.projectDirectory)
}
}
/** Installs node modules as dependencies. */
abstract class NpmInstall : DefaultTask() {
@get:Internal
abstract val projectRoot: DirectoryProperty
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
val packageLock: Provider<File> = projectRoot.file("package-lock.json").map { it.asFile }
@get:OutputDirectory
val nodeModules: Provider<Directory> = projectRoot.dir("node_modules")
@TaskAction
fun install() {
project.exec {
commandLine("npm", "ci")
workingDir = projectRoot.get().asFile
}
}
companion object {
internal const val TASK_NAME: String = "npmInstall"
}
}
abstract class NpxExecToDir : ExecToDir() {
init {
dependsOn(NpmInstall.TASK_NAME)
executable = "npx"
}
}

View File

@ -0,0 +1,54 @@
// 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() }
}
}
internal fun Process.waitForOrThrow(message: String) {
val ret = waitFor()
if (ret != 0) throw GradleException("$message (exited with $ret)")
}

View File

@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.tasks.SourceSet
data class SourceSetReference(
val sourceSet: SourceSet,
val classes: Boolean,
val external: Boolean,
) {
companion object {
/** A source set in the current project. */
fun internal(sourceSet: SourceSet) = SourceSetReference(sourceSet, classes = true, external = false)
/** A source set from another project. */
fun external(sourceSet: SourceSet) = SourceSetReference(sourceSet, classes = true, external = true)
/** A source set which is inlined into the current project. */
fun inline(sourceSet: SourceSet) = SourceSetReference(sourceSet, classes = false, external = false)
}
}

View File

@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.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

@ -0,0 +1,51 @@
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package net.minecraftforge.gradle.common.util.runs
import net.minecraftforge.gradle.common.util.RunConfig
import org.gradle.api.Project
import org.gradle.process.CommandLineArgumentProvider
import org.gradle.process.JavaExecSpec
import java.io.File
import java.util.function.Supplier
import java.util.stream.Collectors
import java.util.stream.Stream
/**
* Set up a [JavaExecSpec] to execute a [RunConfig].
*
* [MinecraftRunTask] sets up all its properties when the task is executed, rather than when configured. As such, it's
* not possible to use [cc.tweaked.gradle.copyToFull] like we do for Fabric. Instead, we set up the task manually.
*
* Unfortunately most of the functionality we need is package-private, and so we have to put our code into the package.
*/
internal fun setRunConfigInternal(project: Project, spec: JavaExecSpec, config: RunConfig) {
spec.workingDir = File(config.workingDirectory)
spec.mainClass.set(config.main)
for (source in config.allSources) spec.classpath(source.runtimeClasspath)
val originalTask = project.tasks.named(config.taskName, MinecraftRunTask::class.java)
// Add argument and JVM argument via providers, to be as lazy as possible with fetching artifacts.
val lazyTokens = RunConfigGenerator.configureTokensLazy(
project, config, RunConfigGenerator.mapModClassesToGradle(project, config),
originalTask.get().minecraftArtifacts,
originalTask.get().runtimeClasspathArtifacts,
)
spec.argumentProviders.add(
CommandLineArgumentProvider {
RunConfigGenerator.getArgsStream(config, lazyTokens, false).toList()
},
)
spec.jvmArgumentProviders.add(
CommandLineArgumentProvider {
(if (config.isClient) config.jvmArgs + originalTask.get().additionalClientArgs.get() else config.jvmArgs).map { config.replace(lazyTokens, it) } +
config.properties.map { (k, v) -> "-D${k}=${config.replace(lazyTokens, v)}" }
},
)
for ((key, value) in config.environment) spec.environment(key, config.replace(lazyTokens, value))
}

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,12 @@
<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>
<module name="BeforeExecutionExclusionFileFilter">
@ -17,7 +28,10 @@
<module name="TreeWalker">
<!-- Annotations -->
<module name="AnnotationLocation" />
<module name="AnnotationUseStyle" />
<module name="AnnotationUseStyle">
<!-- We want trailing commas on multiline arrays. -->
<property name="trailingArrayComma" value="ignore" />
</module>
<module name="MissingDeprecated" />
<module name="MissingOverride" />
@ -26,17 +40,11 @@
<module name="EmptyCatchBlock">
<property name="exceptionVariableName" value="ignored" />
</module>
<module name="LeftCurly">
<property name="option" value="nl" />
<!-- The defaults, minus lambdas. -->
<property name="tokens" value="ANNOTATION_DEF,CLASS_DEF,CTOR_DEF,ENUM_CONSTANT_DEF,ENUM_DEF,INTERFACE_DEF,LITERAL_CASE,LITERAL_CATCH,LITERAL_DEFAULT,LITERAL_DO,LITERAL_ELSE,LITERAL_FINALLY,LITERAL_FOR,LITERAL_IF,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_TRY,LITERAL_WHILE,METHOD_DEF,OBJBLOCK,STATIC_INIT" />
</module>
<module name="LeftCurly" />
<module name="NeedBraces">
<property name="allowSingleLineStatement" value="true"/>
</module>
<module name="RightCurly">
<property name="option" value="alone" />
</module>
<module name="RightCurly" />
<!-- Class design. As if we've ever followed good practice here. -->
<module name="FinalClass" />
@ -58,25 +66,36 @@
<module name="SimplifyBooleanExpression" />
<module name="SimplifyBooleanReturn" />
<module name="StringLiteralEquality" />
<module name="UnnecessaryParentheses" />
<module name="UnnecessaryParentheses">
<!-- Default minus LAND. -->
<property name="tokens" value="EXPR,IDENT,NUM_DOUBLE,NUM_FLOAT,NUM_INT,NUM_LONG,STRING_LITERAL,LITERAL_NULL,LITERAL_FALSE,LITERAL_TRUE,ASSIGN,BAND_ASSIGN,BOR_ASSIGN,BSR_ASSIGN,BXOR_ASSIGN,DIV_ASSIGN,MINUS_ASSIGN,MOD_ASSIGN,PLUS_ASSIGN,SL_ASSIGN,SR_ASSIGN,STAR_ASSIGN,LAMBDA,TEXT_BLOCK_LITERAL_BEGIN,LITERAL_INSTANCEOF,GT,LT,GE,LE,EQUAL,NOT_EQUAL,UNARY_MINUS,UNARY_PLUS,INC,DEC,LNOT,BNOT,POST_INC,POST_DEC" />
</module>
<module name="UnnecessarySemicolonAfterTypeMemberDeclaration" />
<module name="UnnecessarySemicolonInTryWithResources" />
<module name="UnnecessarySemicolonInEnumeration" />
<!-- Imports -->
<module name="CustomImportOrder" />
<module name="CustomImportOrder">
<property name="customImportOrderRules"
value="THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE###STATIC"
/>
</module>
<module name="IllegalImport" />
<module name="RedundantImport" />
<module name="UnusedImports" />
<!-- Javadoc -->
<!-- TODO: Missing* checks for the dan200.computercraft.api package? -->
<module name="AtclauseOrder" />
<module name="AtclauseOrder">
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
</module>
<module name="InvalidJavadocPosition" />
<module name="JavadocBlockTagLocation" />
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocStyle" />
<module name="JavadocStyle">
<property name="checkHtml" value="false" />
</module>
<module name="NonEmptyAtclauseDescription" />
<module name="SingleLineJavadoc" />
<module name="SummaryJavadocCheck"/>
@ -97,20 +116,19 @@
<module name="LambdaParameterName" />
<module name="LocalFinalVariableName" />
<module name="LocalVariableName" />
<module name="MemberName" />
<module name="MethodName" />
<module name="MemberName">
<property name="format" value="^\$?[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(\.[a-z][a-z0-9]*)*" />
<property name="format" value="^(dan200\.computercraft|cc\.tweaked)(\.[a-z][a-z0-9]*)*" />
</module>
<module name="ParameterName" />
<module name="StaticVariableName">
<property name="format" value="^[a-z][a-zA-Z0-9]*|CAPABILITY(_[A-Z_]+)?$" />
<property name="applyToPrivate" value="false" />
</module>
<module name="StaticVariableName">
<property name="format" value="^(s_)?[a-z][a-zA-Z0-9]*|CAPABILITY(_[A-Z_]+)?$" />
<property name="applyToPrivate" value="true" />
<property name="format" value="^[a-z][a-zA-Z0-9]*$" />
</module>
<module name="TypeName" />
@ -123,18 +141,11 @@
<module name="MethodParamPad" />
<module name="NoLineWrap" />
<module name="NoWhitespaceAfter">
<property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP" />
<property name="tokens" value="AT,INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT,ARRAY_DECLARATOR,INDEX_OP,METHOD_REF" />
</module>
<module name="NoWhitespaceBefore" />
<!-- TODO: Decide on an OperatorWrap style. -->
<module name="ParenPad">
<property name="option" value="space" />
<property name="tokens" value="ANNOTATION,ANNOTATION_FIELD_DEF,CTOR_CALL,CTOR_DEF,ENUM_CONSTANT_DEF,LITERAL_CATCH,LITERAL_DO,LITERAL_FOR,LITERAL_IF,LITERAL_NEW,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_WHILE,METHOD_CALL,METHOD_DEF,RESOURCE_SPECIFICATION,SUPER_CTOR_CALL,LAMBDA" />
</module>
<module name="ParenPad">
<property name="option" value="nospace" />
<property name="tokens" value="DOT,EXPR,QUESTION" />
</module>
<module name="ParenPad" />
<module name="SeparatorWrap">
<property name="option" value="eol" />
<property name="tokens" value="COMMA,SEMI,ELLIPSIS,ARRAY_DECLARATOR,RBRACK,METHOD_REF" />
@ -149,8 +160,13 @@
<property name="tokens" value="COMMA" />
</module>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true" />
<property name="ignoreEnhancedForColon" value="false" />
<!-- Allow empty functions -->
<property name="allowEmptyLambdas" value="true" />
<property name="allowEmptyMethods" value="true" />
<property name="allowEmptyConstructors" value="true" />
<property name="allowEmptyTypes" value="true" />
<property name="tokens" value="ASSIGN,BAND,BAND_ASSIGN,BOR,BOR_ASSIGN,BSR,BSR_ASSIGN,BXOR,BXOR_ASSIGN,COLON,DIV,DIV_ASSIGN,EQUAL,GE,GT,LAMBDA,LAND,LCURLY,LE,LITERAL_RETURN,LOR,LT,MINUS,MINUS_ASSIGN,MOD,MOD_ASSIGN,NOT_EQUAL,PLUS,PLUS_ASSIGN,QUESTION,RCURLY,SL,SLIST,SL_ASSIGN,SR,SR_ASSIGN,STAR,STAR_ASSIGN,LITERAL_ASSERT,TYPE_EXTENSION_AND" />
</module>
</module>

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,10 @@
<!-- 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" />
</suppressions>

View File

@ -1,8 +1,12 @@
# SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
#
# SPDX-License-Identifier: MPL-2.0
FROM gitpod/workspace-base
USER gitpod
RUN sudo apt-get -q update \
&& sudo apt-get install -yq openjdk-8-jdk openjdk-16-jdk python3-pip npm \
&& sudo apt-get install -yq openjdk-16-jdk python3-pip npm \
&& sudo pip3 install pre-commit \
&& sudo update-java-alternatives --set java-1.8.0-openjdk-amd64
&& sudo update-java-alternatives --set java-1.16.0-openjdk-amd64

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
<code_scheme name="Project" version="173">
<JSON>
<option name="OBJECT_WRAPPING" value="1" />
<option name="ARRAY_WRAPPING" value="1" />
</JSON>
<JavaCodeStyleSettings>
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="JD_P_AT_EMPTY_LINES" value="false" />
<option name="JD_PRESERVE_LINE_FEEDS" value="true" />
</JavaCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="BRACE_STYLE" value="2" />
<option name="CLASS_BRACE_STYLE" value="2" />
<option name="METHOD_BRACE_STYLE" value="2" />
<option name="LAMBDA_BRACE_STYLE" value="5" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
<option name="FINALLY_ON_NEW_LINE" value="true" />
<option name="SPACE_WITHIN_METHOD_CALL_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_METHOD_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_IF_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_WHILE_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_FOR_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_TRY_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_CATCH_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_SWITCH_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_SYNCHRONIZED_PARENTHESES" value="true" />
<option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true" />
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_TRY_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SYNCHRONIZED_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
<option name="IF_BRACE_FORCE" value="1" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="SPACE_WITHIN_ANNOTATION_PARENTHESES" value="true" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JSON">
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="SPACE_WITHIN_BRACKETS" value="true" />
<option name="SPACE_WITHIN_BRACES" value="true" />
<indentOptions>
<option name="INDENT_SIZE" value="4" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings>
</code_scheme>

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

View File

@ -1,55 +0,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: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-merge-conflict
# Quick syntax checkers
- id: check-xml
- id: check-yaml
- id: check-toml
- id: check-json
exclude: "tsconfig\\.json$"
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
rev: 2.3.5
hooks:
- id: editorconfig-checker
args: ['-disable-indentation']
exclude: "^(.*\\.(bat)|LICENSE)$"
- repo: local
hooks:
- id: checkstyle
name: Check Java codestyle
files: ".*\\.java$"
language: system
entry: ./gradlew checkstyleMain checkstyleTest
pass_filenames: false
require_serial: true
- id: license
name: Check Java license headers
files: ".*\\.java$"
language: system
entry: ./gradlew licenseFormat
pass_filenames: false
require_serial: true
- id: illuaminate
name: Check Lua code
files: ".*\\.(lua|java|md)"
language: script
entry: config/pre-commit/illuaminate-lint.sh
pass_filenames: false
require_serial: true
exclude: |
(?x)^(
src/generated|
src/test/resources/test-rom/data/json-parsing/|
src/test/server-files/|
config/idea/
)

View File

@ -1,16 +0,0 @@
#!/usr/bin/env sh
set -e
test -d bin || mkdir bin
test -f bin/illuaminate || curl -s -obin/illuaminate https://squiddev.cc/illuaminate/linux-x86-64/illuaminate
chmod +x bin/illuaminate
if [ -n ${GITHUB_ACTIONS+x} ]; then
# Register a problem matcher (see https://github.com/actions/toolkit/blob/master/docs/problem-matchers.md)
# for illuaminate.
echo "::add-matcher::.github/matchers/illuaminate.json"
trap 'echo "::remove-matcher owner=illuaminate::"' EXIT
fi
./gradlew luaJavadoc
bin/illuaminate lint

View File

@ -3,19 +3,26 @@ module: [kind=event] alarm
see: os.setAlarm To start an alarm.
---
The @{timer} 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 prints its ID:
Starts a timer and then waits for it to complete.
```lua
local alarmID = os.setAlarm(os.time() + 0.05)
local alarm_id = os.setAlarm(os.time() + 0.05)
local event, id
repeat
event, id = os.pullEvent("alarm")
until id == alarmID
until id == alarm_id
print("Alarm with ID " .. id .. " was fired")
```

View File

@ -3,22 +3,29 @@ 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
Prints each character the user presses:
```lua
while true do
local event, character = os.pullEvent("char")
print(character .. " was pressed.")
local event, character = os.pullEvent("char")
print(character .. " was pressed.")
end
```

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.
... @{string}: 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

@ -0,0 +1,48 @@
---
module: [kind=event] file_transfer
since: 1.101.0
---
<!--
SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
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.
## 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.
```lua
local _, files = os.pullEvent("file_transfer")
for _, file in ipairs(files.getFiles()) do
-- Seek to the end of the file to get its size, then go back to the beginning.
local size = file.seek("end")
file.seek("set", 0)
print(file.getName() .. " " .. size)
end
```
## Example
Save each transferred file to the computer's storage.
```lua
local _, files = os.pullEvent("file_transfer")
for _, file in ipairs(files.getFiles()) do
local handle = fs.open(file.getName(), "wb")
handle.write(file.readAll())
handle.close()
file.close()
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. @{string|nil}: 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,22 @@ 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. @{http.Response|nil}: A response handle if the connection succeeded, but the server's response indicated failure.
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
Prints an error why the website cannot be contacted:

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 handle for the response text.
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,21 +2,33 @@
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. @{number}: The distance between the sender and the receiver, in blocks (decimal).
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
Prints a message when one is sent:
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)
modem.open(0)
while true do
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
print(("Message received on side %s on channel %d (reply to %d) from %f blocks away with message %s"):format(side, channel, replyChannel, distance, tostring(message)))
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
print(("Message received on side %s on channel %d (reply to %d) from %f blocks away with message %s"):format(
side, channel, replyChannel, distance, tostring(message)
))
end
```

View File

@ -2,14 +2,21 @@
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 size is changed.
## Return Values
1. @{string}: The event name.
2. @{string}: The side or network ID of the monitor that 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:
```lua
while true do
local event, side = os.pullEvent("monitor_resize")

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 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,26 +2,30 @@
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.
<table class="pretty-table">
<!-- Our markdown parser doesn't work on tables!? Guess I'll have to roll my own soonish :/. -->
<tr><th>Button code</th><th>Mouse button</th></tr>
<tr><td align="right">1</td><td>Left button</td></tr>
<tr><td align="right">2</td><td>Middle button</td></tr>
<tr><td align="right">3</td><td>Right button</td></tr>
</table>
| Button Code | Mouse Button |
|------------:|---------------|
| 1 | Left button |
| 2 | Right button |
| 3 | Middle button |
## Example
Print the button and the coordinates whenever the mouse is clicked.

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. @{string|nil}: 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,7 +2,16 @@
module: [kind=event] redstone
---
The @{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 change.
## Return values
1. [`string`]: The event name.
## Example
Prints a message when a redstone input changes:

View File

@ -0,0 +1,33 @@
---
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.
## 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.
```lua {data-peripheral=speaker}
local dfpwm = require("cc.audio.dfpwm")
local speaker = peripheral.find("speaker")
local decoder = dfpwm.make_decoder()
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
local buffer = decoder(chunk)
while not speaker.playAudio(buffer) do
os.pullEvent("speaker_audio_empty")
end
end
```

View File

@ -3,14 +3,20 @@ 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.)
...: Any parameters returned from the command.
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
Prints the results of an asynchronous command:

View File

@ -2,10 +2,25 @@
module: [kind=event] term_resize
---
The @{term_resize} event is fired when the main terminal is resized, mainly when a new tab is opened or closed in @{multishell}.
<!--
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.
## Return values
1. [`string`]: The event name.
## Example
Prints :
Print a message each time the terminal is resized.
```lua
while true do
os.pullEvent("term_resize")

View File

@ -2,11 +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.
## Example
Prints a message when Ctrl-T is held:

View File

@ -3,19 +3,25 @@ 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
Starts a timer and then prints its ID:
Start and wait for a timer to finish.
```lua
local timerID = os.startTimer(2)
local timer_id = os.startTimer(2)
local event, id
repeat
event, id = os.pullEvent("timer")
until id == timerID
until id == timer_id
print("Timer with ID " .. id .. " was fired")
```

View File

@ -2,7 +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.
## 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,14 +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.
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):

93
doc/guides/gps_setup.md Normal file
View File

@ -0,0 +1,93 @@
---
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.
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
constellation*.
In order to give the best results, a GPS constellation needs at least four computers. More than four GPS hosts per
constellation is redundant, but it does not cause problems.
## Building a GPS constellation
<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.
> [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
because high altitude boosts modem message range and thus the radius that your constellation covers.
The GPS constellation will only work when it is in a loaded chunk. If you want your constellation to always be
accessible, you may want to permanently load the chunk using a vanilla or modded chunk loader. Make sure that your 6x6x6
area fits in a single chunk to reduce the number of chunks that need to be kept loaded.
Let's get started building the constellation! Place your first computer in one of the corners of your 6x6x6. Remember
which computer this is as other computers need to be placed relative to it. Place the second computer 4 blocks above the
first. Go back to your first computer and place your third computer 5 blocks in front of your first computer, leaving 4
blocks of air between them. Finally for the fourth computer, go back to your first computer and place it 5 blocks right
of your first computer, leaving 4 blocks of air between them.
With all four computers placed within the 6x6x6, place one modem on top of each computer. You should have 4 modems and 4
computers all within your 6x6x6 where each modem is attached to a computer and each computer has a modem.
Currently your GPS constellation will not work, that's because each host is not aware that it's a GPS host. We will fix
this in the next section.
## Configuring the constellation
Now that the structure of your constellation is built, we need to configure each host in it.
Go back to the first computer that you placed and create a startup file, by running `edit startup`.
Type the following code into the file:
```lua
shell.run("gps", "host", x, y, z)
```
Escape from the computer GUI and then press <kbd>F3</kbd> to open Minecraft's debug screen and then look at the computer
(without opening the GUI). On the right of the screen about halfway down you should see an entry labeled `Targeted
Block`, the numbers correspond to the position of the block that you are looking at. Replace `x` with the first number,
`y` with the second number, and `z` with the third number.
For example, if I had a computer at x = 59, y = 5, z = -150, then my <kbd>F3</kbd> debug screen entry would be `Target
Block: 59, 5, -150` and I would change my startup file to this `shell.run("gps", "host", 59, 5, -150)`.
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.
> [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).
> [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.

105
doc/guides/local_ips.md Normal file
View File

@ -0,0 +1,105 @@
---
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
server. You can unblock these IPs in the ComputerCraft config.
- [Minecraft 1.13 and later, CC:T 1.87.0 and later](#cc-1.87.0)
- [Minecraft 1.13 and later, CC:T 1.86.2 and earlier](#cc-1.86.2)
- [Minecraft 1.12.2 and earlier](#mc-1.12)
## Minecraft 1.13 and later, CC:T 1.87.0 and later {#cc-1.87.0}
The configuration file can be located at `serverconfig/computercraft-server.toml` inside the world folder on either
single-player or multiplayer. Look for lines that look like this:
```toml
#A list of rules which control behaviour of the "http" API for specific domains or IPs.
#Each rule is an item with a 'host' to match against, and a series of properties. The host may be a domain name ("pastebin.com"),
#wildcard ("*.pastebin.com") or CIDR notation ("127.0.0.0/8"). If no rules, the domain is blocked.
[[http.rules]]
host = "$private"
action = "deny"
```
On 1.95.0 and later, this will be a single entry with `host = "$private"`. On earlier versions, this will be a number of
`[[http.rules]]` with various IP addresses. You will want to remove all of the `[[http.rules]]` entries that have
`action = "deny"`. Then save the file and relaunch Minecraft (Server).
Here's what it should look like after removing:
```toml
#A list of rules which control behaviour of the "http" API for specific domains or IPs.
#Each rule is an item with a 'host' to match against, and a series of properties. The host may be a domain name ("pastebin.com"),
#wildcard ("*.pastebin.com") or CIDR notation ("127.0.0.0/8"). If no rules, the domain is blocked.
[[http.rules]]
#The maximum size (in bytes) that a computer can send or receive in one websocket packet.
max_websocket_message = 131072
host = "*"
#The maximum size (in bytes) that a computer can upload in a single request. This includes headers and POST text.
max_upload = 4194304
action = "allow"
#The maximum size (in bytes) that a computer can download in a single request. Note that responses may receive more data than allowed, but this data will not be returned to the client.
max_download = 16777216
#The period of time (in milliseconds) to wait before a HTTP request times out. Set to 0 for unlimited.
timeout = 30000
```
## Minecraft 1.13 and later, CC:T 1.86.2 and earlier {#cc-1.86.2}
The configuration file for singleplayer is at `.minecraft/config/computercraft-common.toml`. Look for lines that look
like this:
```toml
#A list of wildcards for domains or IP ranges that cannot be accessed through the "http" API on Computers.
#If this is empty then all whitelisted domains will be accessible. Example: "*.github.com" will block access to all subdomains of github.com.
#You can use domain names ("pastebin.com"), wildcards ("*.pastebin.com") or CIDR notation ("127.0.0.0/8").
blacklist = ["127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fd00::/8"]
```
Remove everything inside the array, leaving the last line as `blacklist = []`. Then save the file and relaunch Minecraft.
Here's what it should look like after removing:
```toml
#A list of wildcards for domains or IP ranges that cannot be accessed through the "http" API on Computers.
#If this is empty then all whitelisted domains will be accessible. Example: "*.github.com" will block access to all subdomains of github.com.
#You can use domain names ("pastebin.com"), wildcards ("*.pastebin.com") or CIDR notation ("127.0.0.0/8").
blacklist = []
```
## Minecraft 1.12.2 and earlier {#mc-1.12}
On singleplayer, the configuration file is located at `.minecraft\config\ComputerCraft.cfg`. On multiplayer, the
configuration file is located at `<server folder>\config\ComputerCraft.cfg`. Look for lines that look like this:
```ini
# A list of wildcards for domains or IP ranges that cannot be accessed through the "http" API on Computers.
# If this is empty then all explicitly allowed domains will be accessible. Example: "*.github.com" will block access to all subdomains of github.com.
# You can use domain names ("pastebin.com"), wildcards ("*.pastebin.com") or CIDR notation ("127.0.0.0/8").
S:blocked_domains <
127.0.0.0/8
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
fd00::/8
>
```
Delete everything between the `<>`, leaving the last line as `S:blocked_domains = <>`. Then save the file and relaunch
Minecraft (Server).
Here's what it should look like after removing:
```ini
# A list of wildcards for domains or IP ranges that cannot be accessed through the "http" API on Computers.
# If this is empty then all explicitly allowed domains will be accessible. Example: "*.github.com" will block access to all subdomains of github.com.
# You can use domain names ("pastebin.com"), wildcards ("*.pastebin.com") or CIDR notation ("127.0.0.0/8").
S:blocked_domains <>
```

209
doc/guides/speaker_audio.md Normal file
View File

@ -0,0 +1,209 @@
---
module: [kind=guide] speaker_audio
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`]
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.
## A short introduction to digital audio
When sound is recorded it is captured as an analogue signal, effectively the electrical version of a sound
wave. However, this signal is continuous, and so can't be used directly by a computer. Instead, we measure (or *sample*)
the amplitude of the wave many times a second and then *quantise* that amplitude, rounding it to the nearest
representable value.
This representation of sound - a long, uniformally sampled list of amplitudes is referred to as [Pulse-code
Modulation][PCM] (PCM). PCM can be thought of as the "standard" audio format, as it's incredibly easy to work with. For
instance, to mix two pieces of audio together, you can just add samples from the two tracks together and take the average.
CC: Tweaked's speakers also work with PCM audio. It plays back 48,000 samples a second, where each sample is an integer
between -128 and 127. This is more commonly referred to as 48kHz and an 8-bit resolution.
Let's now look at a quick example. We're going to generate a [Sine Wave] at 220Hz, which sounds like a low monotonous
hum. First we wrap our speaker peripheral, and then we fill a table (also referred to as a *buffer*) with 128×1024
samples - this is the maximum number of samples a speaker can accept in one go.
In order to fill this buffer, we need to do a little maths. We want to play 220 sine waves each second, where each sine
wave completes a full oscillation in 2π "units". This means one seconds worth of audio is 2×π×220 "units" long. We then
need to split this into 48k samples, basically meaning for each sample we move 2×π×220/48k "along" the sine curve.
```lua {data-peripheral=speaker}
local speaker = peripheral.find("speaker")
local buffer = {}
local t, dt = 0, 2 * math.pi * 220 / 48000
for i = 1, 128 * 1024 do
buffer[i] = math.floor(math.sin(t) * 127)
t = (t + dt) % (math.pi * 2)
end
speaker.playAudio(buffer)
```
## Streaming audio
You might notice that the above snippet only generates a short bit of audio - 2.7s seconds to be precise. While we could
try increasing the number of loop iterations, we'll get an error when we try to play it through the speaker: the sound
buffer is too large for it to handle.
Our 2.7 seconds of audio is stored in a table with over 130 _thousand_ elements. If we wanted to play a full minute of
sine waves (and why wouldn't you?), you'd need a table with almost 3 _million_. Suddenly you find these numbers adding
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
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.
Let's adapt our example from above to do that instead.
```lua {data-peripheral=speaker}
local speaker = peripheral.find("speaker")
local t, dt = 0, 2 * math.pi * 220 / 48000
while true do
local buffer = {}
for i = 1, 16 * 1024 * 8 do
buffer[i] = math.floor(math.sin(t) * 127)
t = (t + dt) % (math.pi * 2)
end
while not speaker.playAudio(buffer) do
os.pullEvent("speaker_audio_empty")
end
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`].
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.
## 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
store it to disk. Compare the size of a WAV file (which uses PCM) to an equivalent MP3, it's often 5 times the size.
Instead, we store audio in special formats (or *codecs*) and then convert them to PCM when we need to do processing on
them.
Modern audio codecs use some incredibly impressive techniques to compress the audio as much as possible while preserving
sound quality. However, due to CC: Tweaked's limited processing power, it's not really possible to use these from your
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
using the speaker.
Let's dive in with an example, and we'll explain things afterwards:
```lua {data-peripheral=speaker}
local dfpwm = require("cc.audio.dfpwm")
local speaker = peripheral.find("speaker")
local decoder = dfpwm.make_decoder()
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
local buffer = decoder(chunk)
while not speaker.playAudio(buffer) do
os.pullEvent("speaker_audio_empty")
end
end
```
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
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
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.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.
You can mix together samples from different streams by adding their amplitudes, change the rate of playback by removing
samples, etc...
Let's put together a small demonstration here. We're going to add a small delay effect to the song above, so that you
hear a faint echo a second and a half later.
In order to do this, we'll follow a format similar to the previous example, decoding the audio and then playing it.
However, we'll also add some new logic between those two steps, which loops over every sample in our chunk of audio, and
adds the sample from 1.5 seconds ago to it.
For this, we'll need to keep track of the last 72k samples - exactly 1.5 seconds worth of audio. We can do this using a
[Ring Buffer], which helps makes things a little more efficient.
```lua {data-peripheral=speaker}
local dfpwm = require("cc.audio.dfpwm")
local speaker = peripheral.find("speaker")
-- Speakers play at 48kHz, so 1.5 seconds is 72k samples. We first fill our buffer
-- with 0s, as there's nothing to echo at the start of the track!
local samples_i, samples_n = 1, 48000 * 1.5
local samples = {}
for i = 1, samples_n do samples[i] = 0 end
local decoder = dfpwm.make_decoder()
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
local buffer = decoder(chunk)
for i = 1, #buffer do
local original_value = buffer[i]
-- Replace this sample with its current amplitude plus the amplitude from 1.5 seconds ago.
-- We scale both to ensure the resulting value is still between -128 and 127.
buffer[i] = original_value * 0.6 + samples[samples_i] * 0.4
-- Now store the current sample, and move the "head" of our ring buffer forward one place.
samples[samples_i] = original_value
samples_i = samples_i + 1
if samples_i > samples_n then samples_i = 1 end
end
while not speaker.playAudio(buffer) do
os.pullEvent("speaker_audio_empty")
end
-- The audio processing above can be quite slow and preparing the first batch of audio
-- may timeout the computer. We sleep to avoid this.
-- There's definitely better ways of handling this - this is just an example!
sleep(0.05)
end
```
> [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 on [GitHub Discussions] or [IRC] either!
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.
For this, you'd need to use the [Fast Fourier transform][FFT] to convert the stream of amplitudes to frequencies,
process those, and then convert them back to amplitudes.
This is, I'm afraid, left as an exercise to the reader.
[Computronics]: https://github.com/Vexatos/Computronics/ "Computronics on GitHub"
[FFT]: https://en.wikipedia.org/wiki/Fast_Fourier_transform "Fast Fourier transform - Wikipedia"
[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"

View File

@ -0,0 +1,89 @@
---
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 [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.
Start off by creating a file called `more_term.lua`:
```lua {data-snippet=more_term}
local function reset()
term.clear()
term.setCursorPos(1, 1)
end
local function write_center(text)
local x, y = term.getCursorPos()
local width, height = term.getSize()
term.setCursorPos(math.floor((width - #text) / 2) + 1, y)
term.write(text)
end
return { reset = reset, write_center = write_center }
```
Now, what's going on here? We define our two functions as one might expect, and then at the bottom return a table with
the two functions. When we require this library, this table is what is returned. With that, we can then call the
original functions. Now create a new file, with the following:
```lua {data-mount=more_term:more_term.lua}
local more_term = require("more_term")
more_term.reset()
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
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
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
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
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 [*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
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...
One other caveat is loading libraries from sub-directories. For instance, say we have a file
`my/fancy/library.lua`. This can be loaded by using `require("my.fancy.library")` - the '.'s are replaced with '/'
before we start looking for the library.
## External links
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).

View File

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

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