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.
- 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!
- 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.
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.
- 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.
- 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!
- 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
- 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.
- 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.
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.
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?
This means wired peripherals now correctly track their current mounts
and attached state, rather than inheriting from the origin wired modem.
Closes#890
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.
- 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
- 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.
This ensures inventory slots are synced while the container is open,
meaning the hotbar (which is visible underneath the GUI) correctly
updates.
Fixes#915
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!
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...
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.
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).
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.
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 :).!
- 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
- 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
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.
- 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.
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.
Plan here is to release 1.98 for 1.16.x and 1.17.x and 1.97.1 for
1.15.x. However, will let this sit for a few days while I sort out 1.98
and the 1.17 port just in case any more bugs pop up.
This uses Netty's global traffic shaping handlers to limit the rate at
which packets can be sent and received. If the bandwidth limit is hit,
we'll start dropping packets, which will mean remote servers send
traffic to us at a much slower pace.
This isn't perfect, as there is only a global limit, and not a
per-computer one. As a result, its possible for one computer to use
all/most bandwidth, and thus slow down other computers.
This would be something to improve on in the future. However, I've spent
a lot of time reading the netty source code and docs, and the
implementation for that is significantly more complex, and one I'm not
comfortable working on right now.
For the time being, this satisfies the issues in #33 and hopefully
alleviates server owner's concerns about the http API. Remaining
problems can either be solved by moderation (with help of the
//computercraft track` command) or future updates.
Closes#33
Also add a test for rednet message sending. Hopefully gives some of the
modem and networking code a little bit of coverage (which is clearly the
same as being right :p).
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
When exiting paint via the keyboard by typing "Ctrl" then "E"
separately, we consume the "key" event within paint, leaving the shell
to consume "read".
To avoid this, we run a sleep(0) to gobble any other left-over events.
Note, it's generally not enough to run a queueEvent/pullEvent here, as
the char event may not have ended up on the queue yet. Alas, as this
solution is pretty ugly.
- Move some shared Gui{Computer,Turtle} code into a new class. Using
entirely different naming conventions because of course (they are
consistent with MojMap, just not the rest of CC:T).
- Fix some mouse scaling issues in the terminal.
Speakers now play sounds using a custom set of packets.
- When playing a sound, we send the resource id, position, volume,
pitch and a UUID for the _speaker_ to all nearby clients.
- This UUID is then used when we need to update the sound. When the
speaker is moved or destroyed, we send a new packet to clients and
update accordingly.
This does have one side effect, that speakers can now only play one
sound at a time. I think this is accceptable - otherwise it's possible
to spam ward in a loop.
Notes still use the old networking code, and so will not be affected.
Closes#823
- Allow help files to use the ".md" suffix, and move changelog/whatsnew
to use them.
- When files end with ".md", the "help" program attempts to highlight
them. This involves:
- Colour code blocks with a lightGrey background.
- Replace lists to use bullet points instead of "-"/"*".
- Colours headings yellow.
The implementation of this is a bit janky because a) I wrote this and
b) we need to run this step before text wrapping, but preserve
colours and section positions over wrapping (thanks to Jack for
getting this working).
- Add section navigation to the help viewer, with left/right to move to
the next/previous section.
Closes#569
- Upgade to Gradle 7.0 and FG 5.0
- Allow running with any Java version - this now correctly compiles
Forge with the right version.
- Upload to Modrinth too. This is entirely untested, so may need some
tweaking.
Adds a sidebar to the computer and turtle GUI. This currently provides
- A power indicator, which turns on/shuts down a computer.
- Button to queue a "terminate" event
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
- Move registry code into the various *Registry classes.
I'm not sure this is any more sensible, but things being registered
in different places kinda irked me.
- Everything else (i.e. event listeners) goes in a {Client,Common}Hooks
class right now. It's not ideal, but I don't think we can split it up
much.
- Fix double updateOutput() call in TileComputerBase - I guess a
merge/rebase gone wrong in the past.
- Don't call updateBlock() when creating a server computer. This used
to be needed when we sent the computer to the client, but this is no
longer the case.
- Don't call updateBlock() on TileMonitors when updating from the
client. We don't need to do a redraw here, as this is all stored in
the block state now.
- Don't update the block when reading turtle upgrades. See #643 for
some background here.
See #658
- Return a more sensible string for empty treasure disks (i.e. those
given by /give). This should help identify packs which are giving
items in non-supported ways.
- Fix NPE when the treasure mount doesn't exist.
Fixes#801
- Simplify how the turtle's inventory is processed. We now copy all
items into the player inventory, attempt to place, and then copy the
items back.
This also fixes the problem where turtle.place() wouldn't (always)
update the item which was placed.
I'm also hoping this is more "correct" in how we process drops from
entities and whatnot. Though I've not had any reports of issues, so
it's probably fine.
- Replace the "error message" string array with an actual object. It'd
be nicer all these functions returned a TurtleCommandResult, but
merging error messages from that is a little harder.
Fun facts: the test suite was actually helpful here, and caught the fact
that hoeing was broken!
Implementation is a little awkward, as we can't send OPEN_FILE links
from the server, so we ensure the client runs a
/computercraft open-computer ID command instead. We then intercept this
on the client side and use that to open the folder.
- Add a basic problem matcher for illuaminate errors.
- Add a script (tools/parse-reports.py) which parses the XML reports
generated by checkstyle and junit, extracts source locations, and
emits them in a manner which can be consumed by another set of
matchers.
This should make it a little easier to see problems for folks who just
rely on CI to test things (though also, please don't do this if you can
help it).
using "optipng -o7 -strip all". I ran this a few years ago and had some
issues, but aren't seeing any problems now. I don't know if this is a
graphics card change, or just optipng fixed some bugs.
These are fairly minimal changes, but hopefully save a few bytes!
- Remove the service provider code and require people to explicitly
register these. This is definitely more ugly, but easier than people
pulling in AutoService or similar!
- Add an API for registering capabilities.
- Expand the doc comments a little. Not sure how useful they'll be, but
let's see!
There's still so much work to be done on this, but it's a "good enough"
first step.
This way we still get some differences between files and folders on
normal computers. I did try with just green, but I think the contrast is
too low.
Closes#656
Unlike short handles, we don't read these immediately, and so we can't
close it right away. Otherwise the file is considered empty!
FixesSquidDev-CC/treasure-programs#1
This uses pre-commit [1] to check patches are well formed and run
several linters on them. We currently do some boring things (check files
are syntactically valid) as well as some project-specific ones:
- Run illuaminate on the Lua files
- Run checkstyle on Java
[1]: https://pre-commit.com/
These are largely copied across from Cobalt's test suite, with some
minor tweaks. It actually exposed one bug in Cobalt, which is pretty
nice.
One interesting thing from the coroutine tests, is that Lua 5.4 (and
one assumes 5.2/5.3) doesn't allow yielding from within the error
handler of xpcall - I rather thought it might.
This doesn't add any of the PUC Lua tests yet - I got a little
distracted.
Also:
- Allow skipping "keyword" tests, in the style of busted. This is
implemented on the Java side for now.
- Fix a bug with os.date("%I", _) not being 2 characters wide.
- Don't treat turtles/pocket computers with no upgrades as an "any"
turtle. Otherwise getting the recipe of a crafty turtle shows the
recipe of a normal turtle too.
- Fix "get usage" of upgrade items not returning their recipes.
- Fix NPEs inside JEI (closes#719)
- Add remaining docs for the turtle API
- Add documentation for the fluid storage peripheral.
- Enforce undocumented warning for most modules (only io and window
remaining).
"Finish" in quotes, because these are clearly a long way from perfect.
I'm bad at writing docs, OK!
Fixes#701 (well, hopefully). Our BlockModelProvider is created when
running other mods' data generators (thought not run), which causes
issues as none of the models are considered as "existing files".
This is definitely going to break the build (it shouldn't, but these
things always do). Anyway...
- Use the new Java toolchain support, rather than requiring the user to
install multiple Java versions.
- Bump versions of several plugins.
We're sadly stuck on Gradle <7 for now, as they drop the old
maven-publish plugin, which drops SCP support.
We send monitor updates when a player starts watching a chunk. However,
the block/tile data has not been sent when this event is fired, and so
the packet is entirely ignored.
Instead, we now queue a "send this" task, which is then dispatched on
the next tick end.
I have memories of this working on 1.12, so either something changed in
an update or I'm a complete idiot. Both are possible.
Fixes#687
The replacement is objectively worse. However, it supports Git
worktrees, which sadly jgit does not.
We really need to rewrite the build script to make it lazy so we're not
executing these commands every time.
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.
More importantly, `./gradlew check' actually runs the in-game tests,
which makes the CI steps look a little more sensible again.
Somewhat depressing that one of the longest files (15th) in CC:T is the
build script.
This probably fails "responsible disclosure", but it's not an RCE and
frankly the whole bug is utterly hilarious so here we are...
It's possible to open a file on a disk drive and continue to read/write
to them after the disk has been removed:
local disk = peripheral.find("drive")
local input = fs.open(fs.combine(disk.getMountPath(), "stream"), "rb")
local output = fs.open(fs.combine(disk.getMountPath(), "stream"), "wb")
disk.ejectDisk()
-- input/output can still be interacted with.
This is pretty amusing, as now it allows us to move the disk somewhere
else and repeat - we've now got a private tunnel which two computers can
use to communicate.
Fixing this is intuitively quite simple - just close any open files
belonging to this mount. However, this is where things get messy thanks
to the wonderful joy of how CC's streams are handled.
As things stand, the filesystem effectively does the following flow::
- There is a function `open : String -> Channel' (file modes are
irrelevant here).
- Once a file is opened, we transform it into some <T extends
Closeable>. This is, for instance, a BufferedReader.
- We generate a "token" (i.e. FileSystemWrapper<T>), which we generate
a week reference to and map it to a tuple of our Channel and T. If
this token is ever garbage collected (someone forgot to call close()
on a file), then we close our T and Channel.
- This token and T are returned to the calling function, which then
constructs a Lua object.
The problem here is that if we close the underlying Channel+T before the
Lua object calls .close(), then it won't know the underlying channel is
closed, and you get some pretty ugly errors (e.g. "Stream Closed"). So
we've moved the "is open" state into the FileSystemWrapper<T>.
The whole system is incredibly complex at this point, and I'd really
like to clean it up. Ideally we could treat the HandleGeneric as the
token instead - this way we could potentially also clean up
FileSystemWrapperMount.
BBut something to play with in the future, and not when it's 10:30pm.
---
All this wall of text, and this isn't the only bug I've found with disks
today :/.
Name a more iconic duo than @SquidDev and over-engineered test
frameworks.
This uses Minecraft's test core[1] plus a home-grown framework to run
tests against computers in-world.
The general idea is:
- Build a structure in game.
- Save the structure to a file. This will be spawned in every time the
test is run.
- Write some code which asserts the structure behaves in a particular
way. This is done in Kotlin (shock, horror), as coroutines give us a
nice way to run asynchronous code while still running on the main
thread.
As with all my testing efforts, I still haven't actually written any
tests! It'd be good to go through some of the historic ones and write
some tests though. Turtle block placing and computer redstone
interactions are probably a good place to start.
[1]: https://www.youtube.com/watch?v=vXaWOJTCYNg
ForgeGradle (probably sensibly) yells at me about doing this. However:
- There's a reasonable number of mods doing this, which establishes
some optimistic precedent.
- The licence update in Aug 2020 now allows you to use them for
"development purposes". I guess source code counts??
- I'm fairly sure this is also compatible with the CCPL - there's an
exception for Minecraft code.
The main motivation for this is to make the Fabric port a little
easier. Hopefully folks (maybe me in the future, we'll see) will no
longer have to deal with mapping hell when merging - only mod loader
hell.
.getMethods() may throw if a method references classes which don't exist
(such as client-only classes on a server). This is an Error, and so is
unchecked - hence us not handling it before.
Fixes#645
- Fix doc library-path
- Only style <pre> code blocks as executable. Skip <code> ones.
- Document the default parameters in gps. Yes, we should do it
everywhere, but one has to start somewhere!
This has been broken for almost a year (28th Jan 2020), and I never
noticed. Good job me.
Fixes#641, closes#648 (basically the same, but targetting 1.15.x)
- Generate theme-color. Hopefully this time it works!
- Specify a site url. Technically this is wrong (we should use the
current git branch), but it's good enough for now.
- Move some options into a sub-category.
I knew I shouldn't do modding on things which aren't my main computer.
I actually did run checkstyleMain before committing, but entirely forgot
about this one. Go me.
- Move some common upgrade code to IUpgradeBase. 99% sure this this
preserves binary compatibility (on the JVM at least).
- Instead of requiring the share tag to match, allow upgrades to
specify their own predicate. IMO this is a little ugly, but required
to fix#614 as other mods chuck their own NBT on items.
- Remove incorrect impostor recipes for pocket computers. We were
generating them from the list of turtle upgrades instead!
- Fix JEI plugin not blocking impostor recipes as of the data-generator
rewrite.
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
Maybe the capability system was a mistake in retrospect, as we don't
store the peripheral outside, so there's no way to reuse it. That will
probably come in a later change.
As a smaller fix, we pass the invalidate listener directly. The lifetime
of this is the same as the computer, so we don't create a new one each
time.
There's still the potential to leak memory if people break/replace a
computer (as listeners aren't removed), but that's an unavoidable flaw
with capabilities.
Fixes#593
I'm getting quite addicted to this. Maybe less savings than monitors,
but still worth doing due to the number of files created.
Also fix our angle calculations for monitors. Thankfully we hadn't
shipped this yet :).
Means we can now do fs.combine("a", "b", "c"). Of course, one may just
write "a/b/c" in this case, but it's definitely useful elsewhere.
This is /technically/ a breaking change as fs.combine(a, b:gsub(...))
will no longer function (as gsub returns multiple arguments). However,
I've done a quick search through GH and my Pastebin archives and can't
find any programs which would break. Fingers crossed.
A little dubious, but apparently CC used to support it. This means we're
consistent with methods like io.write or string.len which accept strings
or numbers.
Fixes#591
Provides a basic interface for running examples on tweaked.cc. This is probably
janky as anything, but it works on my machine.
This is the culmination of 18 months of me building far too much infrastructure
(copy-cat, illuaminate), so that's nice I guess.
I should probably get out more.
I didn't think it was worth it, and then I found myself needing to
update a dozen of them. The code isn't especially pretty, but it works,
so that's fine.
Also fixes several issues with us using the wrong texture (closes#572).
I've put together a wiki page[1] which describes each texture in a
little more detail.
[1] https://github.com/SquidDev-CC/CC-Tweaked/wiki/Monitor-texture-reference
When we construct a new ServerPlayerEntity (and thus TurtlePlayer), we
get the current (global) advancement state and call .setPlayer() on it.
As grantCriterion blocks FakePlayers from getting advancements, this
means a player will no longer receive any advancements, as the "wrong"
player object is being consulted.
As a temporary work around, we attempt to restore the previous player to
the advancement store. I'll try to upstream something into Forge to
resolve this properly.
Fixes#564
This is a long way away from "feature complete" as it were. However,
it's definitely at a point where it's suitable for general usage - I'm
happy with the API, and don't think I'm going to be breaking things any
time soon.
That said, things aren't exposed yet for Java-side public consumption. I
was kinda waiting until working on Plethora to actually do that, but not
sure if/when that'll happen.
If someone else wants to work on an integration mod (or just adding
integrations for their own mod), do get in touch and I can work out how
to expose this.
Closes#452
Minecraft propagates "strong" redstone signals (such as those directly
from comparators or repeaters) through solid blocks. This includes
computers, which is a little annoying as it means one cannot feed
redstone wire from one side and a repeater from another.
This changes computers to not propagate strong redstone signals, in the
same way transparent blocks like glass do.
Closes#548.
The HTTP filtering system becomes even more complex! Though in this
case, it's pretty minimal, and definitely worth doing.
For instance, the following rule will allow connecting to localhost on
port :8080.
[[http.rules]]
host = "127.0.0.1"
port = 8080
action = "allow"
# Other rules as before.
Closes#540
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.
Doesn't fix#515 (arguably makes it worse in the sense that it's more
likely to throw). However it should provide better error reporting, and
make it more clear that it's not CC:T's fault.
It appears I had failed to update this when last bumping the Forge
version. Closes#521 - we're relying on a feature only added in Forge
31.1.16, and they're using 3.1.14.
Control characters become escaped as JSON requires
Non-ASCII characters get escaped as well for better interoperability
We assume here that lua strings represent only first 256 code points of unicode
We can just scrape them from the @AutoService annotation, which saves us
having to duplicate any work. Hopefully fixes#501, but I haven't tested
in a non-dev environment yet.
When dealing with invalid paths (for instance, ones which are too long
or malformed), Java may throw a FileSystemException. This contains the
absolute path (i.e. C:/Users/Moi/.../.minecraft/...), which is printed
to the user within CC - obviously not ideal!
We simply catch this exception within the MountWrapper and map it back
to the local path. The disadvantage of doing it here is that we can't
map the path in the exception back to the computer - we'd need to catch
it in FileMount for that - so we just assume it referrs to the original
path instead.
Doing it in FileMount ends up being a little uglier, as we already do
all the exception wrangling in FileWrapper, so this'll do for now.
Fixes#495
It's no longer possible to implement this on the tile, due to the
conflict in getType. Given this is a really bad idea, it's not a big
issue, but we should mention it in the documentation.
Fixes#496.
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.
This PR adds some documentation for APIs that did not have docs in the
source yet. This includes the:
* drive peripheral
* FS API
* OS PAI
* printer peripheral
* speaker peripheral
illuaminate does not handle Java files, for obvious reasons. In order to
get around that, we have a series of stub files within /doc/stub which
mirrored the Java ones. While this works, it has a few problems:
- The link to source code does not work - it just links to the stub
file.
- There's no guarantee that documentation remains consistent with the
Java code. This change found several methods which were incorrectly
documented beforehand.
We now replace this with a custom Java doclet[1], which extracts doc
comments from @LuaFunction annotated methods and generates stub-files
from them. These also contain a @source annotation, which allows us to
correctly link them back to the original Java code.
There's some issues with this which have yet to be fixed. However, I
don't think any of them are major blockers right now:
- The custom doclet relies on Java 9 - I think it's /technically/
possible to do this on Java 8, but the API is significantly uglier.
This means that we need to run javadoc on a separate JVM.
This is possible, and it works locally and on CI, but is definitely
not a nice approach.
- illuaminate now requires the doc stubs to be generated in order for
the linter to pass, which does make running the linter locally much
harder (especially given the above bullet point).
We could notionally include the generated stubs (or at least a cut
down version of them) in the repo, but I'm not 100% sure about that.
[1]: https://docs.oracle.com/javase/9/docs/api/jdk/javadoc/doclet/package-summary.html
- Refer to this as "data" rather than "metadata". I'm still not sure
where the meta came from - blame OpenPeripheral I guess.
- Likewise, use getItemDetail within inventory methods, rather than
getItemMeta.
- Refactor common data-getting code into one class. This means that
turtle.getItemDetail, turtle.inspect and commands.getBlockInfo all
use the same code.
- turtle.getItemDetail now accepts a second "detailed" parameter which
will include the full metadata (#471, #452).
- Tags are now only included in the detailed list. This is a breaking
change, however should only affect one version (1.89.x) and I'm not
convinced that the previous behaviour was safe.
This allows for configuring the size of computers and pocket computers,
as well as the max size of monitors.
There's several limitations with the current implementation, but it's
still "good enough" for an initial release:
- Turtles cannot be resized.
- GUIs do not scale themselves, so "large" sizes will not render within
the default resolution.
This exposes a basic peripheral for any tile entity which does not have methods
already registered. We currently provide the following methods:
- Inventories: size, list, getItemMeta, pushItems, pullItems.
- Energy storage: getEnergy, getEnergyCapacity
- Fluid tanks: tanks(), pushFluid, pullFluid.
These methods are currently experimental - it must be enabled through
`experimental.generic_peripherals`. While this is an initial step towards
implementing #452, but is by no means complete.
Well, mostly. We currently don't do recipe serializers as I'm a little
too lazy. For items, blocks and TE types this does make registration
nicer - we've some helper functions which help reduce duplication.
Some types (containers, TEs, etc..) are a little less nice, as we now
must define the registry object (i.e. the WhateverType<?>) in a separate
class to the class it constructs. However, it's probably a worthwhile
price to pay.
No clue how we're going to do this for the dynamic peripheral system
if/when that ships, but this is a good first stage.
Like the Java APIs, this relies on stub files, so we can't link to the
implementation which is a bit of a shame. However, it's a good first
step.
I'm really not very good at this modding lark am I? I've done a basic
search for other missing methods, and can't see anything, but goodness
knows.
Fixes#480
When calling .flip(), we limit the size of the buffer. However, this
limit is not reset when writing the next time, which means we get
out-of-bounds errors, even if the buffer is /technically/ big enough.
Clearing the buffer before drawing (rather than just resetting the
position) is enough to fix this.
Fixes#476 (and closes#477, which is a duplicate)
We never added back replacing of ${version} strings, which means that CC
was reporting incorrect version numbers in _HOST, the user agent and
network versions. This meant we would allow connections even on
mismatched versions (#464).
We shift all version handling into ComputerCraftAPI(Impl) - this now
relies on Forge code, so we don't want to run it in emulators.
- Strip any gui._.config options. These haven't been used since 1.12
and while they may return, it doesn't seem worth it right now.
- Fix a couple of typos in the English translations.
- Import from https://i18n.tweaked.cc. There's definitely some problems
with the import - empty translations are still included, so we write
a script to strip them.
This is simply exposed as a table from tag -> true. While this is less
natural than an array, it allows for easy esting of whether a tag is
present.
Closes#461
- Use texture over texture2D - the latter was deprecated in GLSL 1.30.
- Cache the tbo buffer - this saves an allocation when monitors update.
Closes#455. While the rest of the PR has some nice changes, it
performs signlificantly worse on my system.
This moves monitor networking into its own packet, rather than serialising
using NBT. This allows us to be more flexible with how monitors are
serialised.
We now compress terminal data using gzip. This reduces the packet size
of a max-sized-monitor from ~25kb to as little as 100b.
On my test set of images (what I would consider to be the extreme end of
the "reasonable" case), we have packets from 1.4kb bytes up to 12kb,
with a mean of 6kb. Even in the worst case, this is a 2x reduction in
packet size.
While this is a fantastic win for the common case, it is not abuse-proof.
One can create a terminal with high entropy (and so uncompressible). This
will still be close to the original packet size.
In order to prevent any other abuse, we also limit the amount of monitor
data a client can possibly receive to 1MB (configurable).
It should be release quality in all honesty[^1], but let's leave it a
few days to see if any issues trickle in.
[^1]: Well, aside from upsidedown turtles!
timetout, max_upload, max_download and max_websocket_message may now be
configured on a domain-by-domain basis. This uses the same system that
we use for the block/allow-list from before:
Example:
[[http.rules]]
host = "*"
action = "allow"
max_upload = 4194304
max_download = 16777216
timeout = 30000
This registers IPeripheral as a capability. As a result, all (Minecraft
facing) functionality operates using LazyOptional<_>s instead.
Peripheral providers should now return a LazyOptional<IPeripheral> too.
Hopefully this will allow custom peripherals to mark themselves as
invalid (say, because a dependency has changed).
While peripheral providers are somewhat redundant, they still have their
usages. If a peripheral is applied to a large number of blocks (for
instance, all inventories) then using capabilities does incur some
memory overhead.
We also make the following changes based on the above:
- Remove the default implementation for IWiredElement, migrating the
definition to a common "Capabilities" class.
- Remove IPeripheralTile - we'll exclusively use capabilities now.
Absurdly this is the most complex change, as all TEs needed to be
migrated too.
I'm not 100% sure of the correctness of this changes so far - I've
tested it pretty well, but blocks with more complex peripheral logic
(wired/wireless modems and turtles) are still a little messy.
- Remove the "command block" peripheral provider, attaching a
capability instead.
When creating a peripheral or custom Lua object, one must implement two
methods:
- getMethodNames(): String[] - Returns the name of the methods
- callMethod(int, ...): Object[] - Invokes the method using an index in
the above array.
This has a couple of problems:
- It's somewhat unwieldy to use - you need to keep track of array
indices, which leads to ugly code.
- Functions which yield (for instance, those which run on the main
thread) are blocking. This means we need to spawn new threads for
each CC-side yield.
We replace this system with a few changes:
- @LuaFunction annotation: One may annotate a public instance method
with this annotation. This then exposes a peripheral/lua object
method.
Furthermore, this method can accept and return a variety of types,
which often makes functions cleaner (e.g. can return an int rather
than an Object[], and specify and int argument rather than
Object[]).
- MethodResult: Instead of returning an Object[] and having blocking
yields, functions return a MethodResult. This either contains an
immediate return, or an instruction to yield with some continuation
to resume with.
MethodResult is then interpreted by the Lua runtime (i.e. Cobalt),
rather than our weird bodgey hacks before. This means we no longer
spawn new threads when yielding within CC.
- Methods accept IArguments instead of a raw Object array. This has a
few benefits:
- Consistent argument handling - people no longer need to use
ArgumentHelper (as it doesn't exist!), or even be aware of its
existence - you're rather forced into using it.
- More efficient code in some cases. We provide a Cobalt-specific
implementation of IArguments, which avoids the boxing/unboxing when
handling numbers and binary strings.
- cc.pretty.pretty now accepts two additional options:
- function_args: Show function arguments
- function_source: Show where functions are defined.
- Expose the two options as lua.* settings (defaulting function_args to
true, and function_source to false).
These are then used in the Lua REPL.
Closes#361
- Use jacoco for Java-side coverage. Our Java coverage is /terrible
(~10%), as we only really test the core libraries. Still a good thing
to track for regressions though.
- mcfly now tracks Lua side coverage. This works in several stages:
- Replace loadfile to include the whole path
- Add a debug hook which just tracks filename->(lines->count). This
is then submitted to the Java test runner.
- On test completion, we emit a luacov.report.out file.
As the debug hook is inserted by mcfly, this does not include any
computer startup (such as loading apis, or the root of bios.lua),
despite they're executed.
This would be possible to do (for instance, inject a custom header
into bios.lua). However, we're not actually testing any of the
behaviour of startup (aside from "does it not crash"), so I'm not
sure whether to include it or not. Something I'll most likely
re-evaluate.
`local varname = value` results in `varname` being inaccessible in
the next REPL input. This is often unintended and can lead to confusing
behaviour. We produce a warning when this occurs.
This uses the system described in #409, to render monitors in a more
efficient manner.
Each monitor is backed by a texture buffer object (TBO) which contains
a relatively compact encoding of the terminal state. This is then
rendered using a shader, which consumes the TBO and uses it to index
into main font texture.
As we're transmitting significantly less data to the GPU (only 3 bytes
per character), this effectively reduces any update lag to 0. FPS appears
to be up by a small fraction (10-15fps on my machine, to ~110), possibly
as we're now only drawing a single quad (though doing much more work in
the shader).
On my laptop, with its Intel integrated graphics card, I'm able to draw
120 full-sized monitors (with an effective resolution of 3972 x 2330) at
a consistent 60fps. Updates still cause a slight spike, but we always
remain above 30fps - a significant improvement over VBOs, where updates
would go off the chart.
Many thanks to @Lignum and @Lemmmy for devising this scheme, and helping
test and review it! ♥
Unknown blit colours, such as " " will be translated to black for the
background or white for the foreground. This restores the behaviour from
before #412.
- Write to a PacketBuffer instead of generating an NBT tag. This is
then converted to an NBT byte array when we send across the network.
- Pack background/foreground colours into a single byte.
This derives from some work I did back in 2017, and some of the changes
made/planned in #409. However, this patch does not change how terminals
are represented, it simply makes the transfer more compact.
This makes the patch incredibly small (100 lines!), but also limited in
what improvements it can make compared with #409. We send 26626 bytes
for a full-sized monitor. While a 2x improvement over the previous 58558
bytes, there's a lot of room for improvement.
This functions the same as shell.run, but does not tokenise the
arguments. This allows us to pass command line arguments through to
another program without having to re-quote them.
Closes#417
- Remove the parenthesis around the text (so it's now
"Computer ID: 12"), rather than "(Computer ID: 12").
- Show the tooltip if the computer has an ID and no label (as well as
when in advanced mode).
- Lint references to unknown fields of modules, excluding the keys and
colours modules. This caught several silly errors in our stub files,
but nothing else.
- Lint on using unknown globals. This highlighted a couple of really
silly mistakes. Fixes#427.
- Add documentation for fs.attributes, fs.getCapacity and pocket, as
they were not defined before.
Co-authored-by: JackMacWindows <jackmacwindowslinux@gmail.com>
- I'm excluding pocket computers, as they have such a tiny screen I'm
not sure the screen estate is worth it.
Pocket computers /generally/ aren't people's starter machine, so I
think this is fine.
- Prune the motd list, and try to make them a little shorter. I think
this list is more of the interesting ones. We can modify this list in
the future, as we get more feedback.[^1]
- Also fix paint/edit not adding an extension when they should. This
was caused by the settings rewrite, as the explicitly provided
default shadowed the one provided by bios.lua.
[^1]: ~5 months ago I asked for some feedback about enabling motds by
default. I only got something constructive back today >_>.
This replaces the allow/block lists with a series of rules. Each rule
takes the form
[[http.rules]]
host = "127.0.0.0/8"
action = "block"
This is pretty much the same as the previous config style, in that hosts
may be domains, wildcards or in CIDR notation. However, they may also be
mixed, so you could allow a specific IP, and then block all others.
- The store is now split into two sections:
- A list of possible options, with some metadata about them.
- A list of values which have been changed.
- settings.define can be used to register a new option. We have
migrated all existing options over to use it. This can be used to
define a default value, description, and a type the setting must have
(such as `string` or `boolean).
- settings.{set,unset,clear,load,store} operate using this value list.
This means that only values which have been changed are stored to
disk.
Furthermore, clearing/unsetting will reset to the /default/ value,
rather than removing entirely.
- The set program will now display descriptions.
- settings.{load,save} now default to `.settings` if no path is given.
This is a backport of 1.15's terminal rendering code with some further
improvements. This duplicates a fair bit of code, and is much more
efficient.
I expect the work done in #409 will supersede this, but that's unlikely
to make its way into the next release so it's worth getting this in for
now.
- Refactor a lot of common terminal code into
`FixedWithFontRenderer`. This shouldn't change any behaviour, but
makes a lot of our terminal renderers (printed pages, terminals,
monitors) a lot cleaner.
- Terminal rendering is done using a single mode/vertex format. Rather
than drawing an untextured quad for the background colours, we use an
entirely white piece of the terminal font. This allows us to batch
draws together more elegantly.
- Some minor optimisations:
- Skip rendering `"\0"` and `" "` characters. These characters occur
pretty often, especially on blank monitors and, as the font is empty
here, it is safe to skip them.
- Batch together adjacent background cells of the same colour. Again,
most terminals will have large runs of the same colour, so this is a
worthwhile optimisation.
These optimisations do mean that terminal performance is no longer
consistent as "noisy" terminals will have worse performance. This is
annoying, but still worthwhile.
- Switch monitor rendering over to use VBOs.
We also add a config option to switch between rendering backends. By
default we'll choose the best one compatible with your GPU, but there
is a config option to switch between VBOS (reasonable performance) and
display lists (bad).
When benchmarking 30 full-sized monitors rendering a static image, this
improves my FPS[^1] from 7 to 95. This is obviously an extreme case -
monitor updates are still slow, and so more frequently updating screens
will still be less than stellar.
[^1]: My graphics card is an Intel HD Graphics 520. Obviously numbers
will vary.
This would return true for any block with a fluid in it, including
waterlogged blocks. This resulted in much broken behaviour
- Turtles cannot place blocks when waterlogged (fixedd #385)
- Turtles could move into waterlogged blocks (such as fences),
replacing them.
This is relatively unoptimised right now, but should be efficient enough
for most practical applications.
- Add textutils.json_null. This will be serialized into a literal
`null`. When deserializing, and parse_null is true, this will be
returned instead of a nil.
- Add textutils.unserializeJSON (and textutils.unserializeJSON). This
is a standard compliant JSON parser (hopefully).
- Passing in nbt_style to textutils.unserializeJSON will handle
stringified NBT (no quotes around object keys, numeric suffices). We
don't currently support byte/long/int arrays - something to add in
a future commit.
- Remove stub for table.pack/table.unpack.
- Remove Lua 5.3 bitlib stub. We're not on 5.3, there's no
point emulating it.
- Change peripheral.call to correctly adjust the error level. This is a
terrible hack, but I believe the only good option.
It'd be good to remove load as well, but it's a little more complex due
to our injecting of _ENV.
Closes#363
It hasn't been http_enable for yonks - slightly worried I didn't notice
this earlier.
Also don't refer to ComputerCraft.cfg - the name has changed several
times across versions, so let's leave it ambiguous.
Hopefully provides a /little/ more information about the build process.
Hey, also means I only need to add a CoC to complete GH's community tab!
In all seriousness, there's probably a lot more I need to flesh out
here, such as some kind of vision and guides for issues/PRs. But this at
least documents the local development process. Somewhat.
- Return EPOCH if a zip entry's creation/modification/access time is
missing.
- If a BasicFileAttributes.*Time method returns null, use 0 as our
time. This shouldn't happen, but is a good sanity check.
Fixes#371
This adds documentation comments to many of CC's Lua APIs, and
a couple of the Java ones, through the use of stubs. We then
export these to HTML using illuaminate [1] and upload them to our
documentation site [2].
Uploads currently occur on pushes to master and any release/tag. The
site is entirely static - there is no way to switch between versions,
etc... but hopefully we can improve this in the future.
[1]: github.com/SquidDev/illuaminate/
[2]: https://tweaked.cc/
This means we are already provided with file attributes, which halfs[^1]
the time taken to scan folders.
[^1]: This dropped the fastest scan time from ~1.3s to ~0.6. It's by no
means a perfect benchmark, but this is still an obvious improvement.
- fs.getCapacity just returns the capacity of the current drive, if
available. This will be nil on rom mounts.
- fs.attributes returns an lfs like table of various file attributes.
Currently, this contains:
- access, modification, created: When this file was last accessed,
modified and created. Time is measured in milliseconds since the
epoch, same as os.epoch("utc") and what is accepted by os.date.
- size: Same as fs.getSize
- isDir: same as fs.isDir
Closes#262
- Move timer handling to IAPIEnvironment, rather than OSAPI. This means
the environment is reset on startup/shutdown, much like normal APIs.
- Websocket.receive now accepts an optional timetout (much like
rednet.receive). This starts a timer, and waits for it to complete.
Closes#201
- contains now performs a case-insensitive comparison. While this is a
little dubious, it's required for systems like Windows, where foo and
Foo are the same folder.
- Impose a depth limit on copyRecursive. If there are any other cases
where we may try to copy a folder into itself, this should prevent
the computer entirely crashing.
See #354
- Remove Lua script to generate recipes/advancements for coloured
disks, turtle upgrades and pocket upgrades. Replacing them with Lua
ones.
- Generate most block drops via the data generator system. Aside from
cables, they all follow one of two templates.
- Remove *Stream methods on IMount/IWritableMount, and make the channel
ones the primary.
- Fix location of AbstractTurtleUpgrade
- Make IComputerAccess.getAvailablePeripheral and .getMainThreadMonitor
mandatory.
- IComputerAccess throws a specialised NotAttachedException
Most of the port is pretty simple. The main problems are regarding
changes to Minecraft's rendering system.
- Remove several rendering tweaks until Forge's compatibility it
brought up-to-date
- Map rendering for pocket computers and printouts
- Item frame rendering for printouts
- Custom block outlines for monitors and cables/wired modems
- Custom breaking progress for cables/wired modems
- Turtle "Dinnerbone" rendering is currently broken, as normals are not
correctly transformed.
- Rewrite FixedWidthFontRenderer to to the buffer in a single sweep.
In order to do this, the term_font now also bundles a "background"
section, which is just a blank region of the screen.
- Render monitors using a VBO instead of a call list. I haven't
compared performance yet, but it manages to render a 6x5 array of
_static_ monitors at almost 60fps, which seems pretty reasonable.
- Add a cc.pretty module, which provides a Wadler style pretty printer [1].
- The cc.pretty.pretty function converts an arbitrary object into a
pretty-printed document. This can then be printed to the screen with
cc.pretty.{write, print} or converted to a string with cc.pretty.render.
- Convert the Lua REPL to use the pretty printer rather than
textutils.serialise.
[1]: http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf
GPS requests are now sent and received on CHANNEL_GPS by default
instead. This means it should not be possible to distinguish
computers (and thus locate them) via their GPS requests.
"exit" now has a custom __tostring method, which prints an explanation
message. This is very similar to how Python achives the same
functionality:
lua> exit
Call exit() to exit
lua> exit()
> Actually leaves the REPL
Unfortunately we can't apply the config changes due to backwards
compatibility. This'll be something we may need to PR into Forge.
CraftTweaker support still needs to be added.
It appears that WB opens containers manually, and thus all of our stubs
network stubs are entirely ignored. Thus the only solution here is to
stub out the whole network handler code.
Thankfully this is simple enough - we do the same for Plethora and 1.14.
Fixes#328
This provides the following methods:
- dan200.computercraft.turtle.removeUpgrade(id: String)
- dan200.computercraft.turtle.removeUpgrade(stack: IItemStack)
- dan200.computercraft.turtle.addTool(id: String, craftItem: IItemStack[, toolItem: IItemStack][, kind: string])
While it's pretty minimal, it should allow for a reasonable amount of
functionality.
Closes#327 and #97.
We now use illuaminate[1]'s linting facilities to check the rom and
bios.lua for a couple of common bugs and other problems.
Right now this doesn't detect any especially important bugs, though it
has caught lots of small things (unused variables, some noisy code). In
the future, the linter will grow in scope and features, which should
allow us to be stricter and catch most issues.
As a fun aside, we started off with ~150 bugs, and illuaminate was able
to fix all but 30 of them, which is pretty neat.
[1]: https://github.com/SquidDev/illuaminate
Before it would remain the same across world reloads, and thus would be
out-of-date after leaving the first world. This architecture technically
allows for running multiple servers at once, though that's not going to
matter that soon.
This fixes them not rendering particles when broken. Particle rendering
is a little janky right now, as it uses the whole texture - we should
probably split up the texture into smaller images. Fixes#315
This should fix several issues (see #304, etc...). I'll try to get round
to PRing this into Forge at some point, though on the other hand this is
/super/ ugly.
This shouldn't matter either way - we don't expose it in the creative
menu, and there's no recipes for it. This should shut up a log message
though. Fixes#305.
This fixes monitor rendering underwater (closes#314). By default,
isSolid returns true if the render layer is SOLID. As we use CUTOUT due
to our funky TE rendering, we need to override this to return true
anyway.
This will cause some side effects, as monitors now blocking light
propagation, but I don't think that's the end of the world.
This is sufficiently useful a class, that it's worthwhile exposing it.
Hopefully we can slowly encourage other mods to migrate to it (well, at
least in 1.14), and so make error messages more consistent.
Also:
- Add Javadoc for all public methods
- Clarify the method names a little (getNumber -> getDouble,
getReal -> getFiniteDouble).
- Make the *Table methods return a Map<?,?> instead of
Map<Object, Object>.
Previously we were just returning the current tile. However, if someone
was holding a reference to this inventory (such as a GUI), then it'd be
outdated and invalid once the turtle had moved.
This caused a couple of issues:
- turtle_inventory events would not be fired when moving items in the
turtle GUI.
- As of 75e2845c01, turtles would no
longer share their inventory state after moving. Thus, removing items
from a GUI using an invalid inventory would move them from an old
tile, duplicating the items.
Fixes#298, fixes#300
Not quite sure when this changed, but I'm fairly sure isMouseOver wasn't
a thing when I wrote this. Or I'm a plonker. Both are possible.
Also fixes mouse dragging not being handled in turtles.
Fixes#299
Closes#293. Doesn't really solve anything there aside from exposing the
number, but sadly there's not really anything obvious I can do on my end
- the command API just doesn't expose anything else.
- Adds cc.completions module, with a couple of helper functions for
working with the more general completion functionality (i.e. that
provided by read).
- Adds cc.shell.completions module, which provides shell-specific
completion functions.
- Add a "program completion builder", which allows you to write stuff
like this:
shell.setCompletionFunction( "rom/programs/redstone.lua",
completion.build(
{ completion.choice, { "probe", "set ", "pulse " } },
completion.side) )
Closes#232
It appears several mods inject their own drops on the LOWEST priority,
meaning that we capture the existing drops, and the other mod will clear
the (now empty) drop list and add its own, resulting in dupe bugs.
While I'd argue it's somewhat dubious doing this on the LOWEST priority,
it's not a battle I'm prepared to fight. For now, we just remove the
block/entity drop handlers, and handle all drop logic when entities are
spawned.
Fixes#288
This is the behaviour on 1.14 already, so it makes sense to backport to
1.12.
Any mod may now insert files into assets/computercraft/lua/rom, and
they'll be automatically added to the default ROM mount. This allows
other mods to easily register new programs or autorun files.
See #242
Lua 5.2+ uses loadfile(filename, mode, env), not loadfile(filename,
env). While this is a minor incompatibility, it'd be nice to be
consistent as much as possible.
We try to handle the incorrect case too, as obviously we don't want to
break existing programs.
This moves expect from the bios into a new craftos.expect module,
removing the internal _G["~expect"] definition. Apparently people were
using this irrespective of the "don't use this" comment, so we need to
find another solution.
While this does introduce some ugliness (having to load the module in
weird ways for programs, duplicating the expect function in memory), it
does allow people to use the function in a supported way, and removes
the global ugliness.
I'm not entirely sure how useful all of these will be yet - still
trying to work out what/when to test things, but hopefully this'll
be a useful datapoint.
This is equally an ugly hack, but means we're at least not constructing
entities with null worlds any more.
Ideally we could always use the turtle entity, but this will require a
bit more of a refactor.
Fixes#265
Mostly just rearranging. Bump JUnit version in an attempt to fix test
outputs, but it appears this is a mix of gradle/gradle#5975 and
gradle/gradle#4438.
- Add Forge's "name" field to the loot tables. This doesn't resolve all
our missing loot providers, but it's a start.
- Add back GUIs for pocket computers, printouts, view computer, etc...
Equivalent to `pastebin run`, but allows running arbitrary URLs
instead.
Is this a little questionable? Yes - people shouldn't be downloading
and running code from the internet. But hey, people do that already,
so we might as well make it convenient.
So very little works, but it compiles and runs.
Things to resolve over the next few days:
- Horrible mappings (should largely be resolved by tomorrow).
- Cannot send extra data over containers - we'll have to see what Forge
does here.
- Turtle models are broken
- No block drops yet - this will largely be cherry-picking whatever I
did on Fabric.
- Weird inventory desyncs (items don't show up initially when
interacting with a CC inventory).
- Probably lots of other things.
- Adds a CheckStyle configuration which is pretty similar to CC's
existing one.
- Add the Gradle license plugin.
- Ensure the existing source code is compatible with these additional
checks.
See #239
- Make mcfly's stubbing system a little more fault-tolerant.
- Add a small utility function which redirects print, printError and
write to capture their output, rather than printing to the terminal.
This can then be matched against in order to determine a program's
output.
It's a little flakey - you can't use it multiple times in an it
block, etc... but it's a nice feature.
- Add a small couple of tests to delete as a proof-of-concept.
- Convert existing changelog over to use Markdown. This mostly involves
wrapping code in backticks, and marking things as headers where
appropriate.
- Copy all of CC:T's release notes over to the changelog. This is
somewhat more verbose than Dan's notes, but keeping them in sync
seems reasonable (and allows for automation!).
As 'require' operates relative to the current program's directory,
rather than the current directory, it meant we were trying to load files
from /rom/programs.
This is never a good idea, so we add the current directory to the
package path, allowing you to use require as one'd expect.
- Define an expect(index, actual_value, types...) helper function which
takes an argument index, value and list of permissable types and
ensures the value is of one of those types.
If not, it will produce an error message with the expected and actual
type, as well as the argument number and (if available) the function
name.
- Expose expect in the global scope as _G["~expect"], hopefully making
it clear it is internal.
- Replace most manual type checks with this helper method.
- Write tests to ensure this argument validation works as expected
Also fix a couple of bugs exposed by this refactor and the subsequent
tests:
- Make rednet checks a little more strict - rednet.close(false) is no
longer valid.
- Error when attempting to redirect the terminal to itself
(term.redirect(term)).
- Add a link to discord and the forums. Oh goodness, I hope this
doesn't count as making things official.
I've had a couple of people email me with support requests, which is
/fine/, but there's better channels for it!
- Add a couple of PR templates
- Ask people to write tests for CraftOS changes. This is a standard
I'm trying to impose on myself, so seems reasonable to impose on
everyone. Sorry!
- Require same levels of explanation for PRs as we do for issues.
- Try to expand on the feature request "rationale" section a little.
Just trying to explan my process a little bit more.
This only renders the bounding box on non-screen edges of the monitor,
meaning you have an uninterrupted view of the screen when hovering
hover.
Closes#219
Rendering an item worked in principle, but had several caveats:
- The terminal did not fit well within the item's texture, so we had a
rather large border.
- The "correctness" of this was very tied to Minecraft's item rendering
code. This changed a little in 1.13, causing problems like #208.
Instead we effectively reuse the computer GUI rendering code, though
also handling coloured pocket computers and rendering the modem light.
This fixes#208, and hopefully fixes#212.
Actually, many *globs*. It additionally prints the glob if no files
matched it, since that's clearer.
Also move the ComputerTestDelegate's filesystem to be disk-based. This
is what actual computers use, and the MemoryMount is a little broken.
- os.time, when given a table, will act the same as PUC Lua - returning
the seconds since the epoch. We preserve the previous string/nil
behaviour though - os.epoch("local") is equivalent to PUC's
os.time().
- os.date will now act accept a string and (optional) time, returning
an appropriate table.
Somewhat resolves the madness which was dan200/ComputerCraft#183, and
hopefully (though probably not) makes @Vexatos happy.
This changes the previous behaviour a little, but hopefully is more
sane:
- Only require the socket to be open when first calling receive. This
means if it closes while receving, you won't get an error.
This behaviour is still not perfect - the socket could have closed,
but the event not reached the user yet, but it's better.
- Listen to websocket_close events while receiving, and return null
should it match ours.
See #201
We were using += instead of =, meaning the budget always grew,
rather than growing while there was still space. As a result, computers
were never correctly rate limited.
Further more, if a computer went into a deficit, we would continue to
increase the budget by a negative amount, exponentially decreasing until
overflowing!
Yes, this is a very embarrassing mistake. I'd been aware that rate
limiting wasn't working as expected for a while, I hadn't realised
the problem would be this stupid.
This uses the same behaviour that repeaters and comparators do for
determining their input, meaning that redstone directly connected to the
computer is read (as you would expect).
It's worth noting that this is a shift from previous behaviour.
Therefore, it runs the (small) risk of breaking existing builds.
However, I believe it is more consistent with the expected behaviour.
Originally introduced in 173ea72001, but
the underlying cause has been happening for much longer.
- Fix order of method name parameters. Looks like this has been broken
since 1.11. Woops.
- Catch RuntimeExceptions too, as Forge converts checked into unchecked
ones.
Fixes#179
I promise! The joys of using -SNAPSHOT I guess...
This will now correctly cause orphaned threads to be cleaned up,
reducing the risk of thread saturation.
If mod loading fails, we'll continue to load colour handlers. As
blocks/items have not been registered, then we'll throw an NPE.
See MinecraftForge/MinecraftForge#5682. Somewhat fixes#168.
Forge's config system will read the default values as integers, meaning
it fails to validate against the config spec. Ideally this'd be fixed in
forge, but this is a suitable work around.
Previously we just relied on magic int values, which was confusing and
potentially error-prone. We could use EnumFacing, but that's a)
dependent on MC and b) incorrect, as we're referring to local
coordinates.
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
- Languages are converted to JSON
- Rename most *(_advanced) blocks to *_{advanced,normal}. It's more
verbose, but means they're sorted together.
- A couple of changes to the ROM to work with some Java changes.
- Update recipes and advancements to not use damage values.
Are most of these changes small and petty? Yes. However, IMO they do
make the code more readable. Anyway, a summary of some of the more
interesting changes:
- Expose Abstract*Upgrade classes in the API
- Fix the spelling of Jonathan in the API docs (*shakes fist*)
- Fix bug with printout not working in the offhand.
- Rename any argments/variables accidentally named "m_*", and add an
inspection to prevent it happening again.
- Remove most of the Block*.Properties classes - just inline them in
the parent class.
- Return super.writeToNBT instead of reassigning at the top.
This makes use of the "sent" variable, which would otherwise go unused. It also makes rednet.send compliant to the behaviour specified in the Wiki: http://www.computercraft.info/wiki/Rednet.send
This is largely invisible (it's marked as a child of the main
"computercraft" mod), but allows other mods (such as Plethora) to add
hard/soft dependencies on CC:T in a user-friendly manner.
- Fire all the appropriate Forge hooks
- Crafting will now attempt to craft one item at a time in a loop,
instead of multiplying the resulting stack by the number of crafts.
This means we function as expected on recipes which consume
durability instead.
- Cache the recipe between crafting and getting the remainder (and each
craft loop). This should reduce any performance hit we would
otherwise get.
OK, so let's get this out of the way, there's some actual changes mixed
in here too. I'm really sorry:
- Turtles can now not be renamed with unnamed item tags (previously it
would clear the name, this seemed a little unideal).
- commands.getBlock(s)Data will also include NBT.
Now, onto the horror story which is these inspection changes:
- Make a lot of methods static
- Typo fixes
- Make utility classes final + private constructor
- Lots of reformatting (ifs -> ternary, invert control flow, etc...)
- ???
- Profit!
I'm so going to regret this - can pretty much guarantee this is going to
break something.
- Move container opening (and gui handling) into a separate class
- Move turtle/computer placement code onto the block
- GUIs now use gui{Left,Top} instead of calculating it manually.
- IPeripheralTile is now exposed in the API.
This uses a similar approach to ComputerThread: executors store how long
they've spent executing tasks. We then use that time to prioritise
executors.
One should note that we use the current runtime at the point of adding
to the queue - external tasks will not contribute towards it until a
later execution.
This effectively acts as a public interface to canExecuteExternal() and
consumeTime(). It's hopefully sufficiently general that we can mess
around with the backend as much as we like in the future.
One thing to note here is that this is based on a polling API, as it's
largely intended for people running work every tick. It would be
possible to adapt this with callbacks for when work is available,
etc..., but that was not needed immediately.
This also removes IComputerOwned, as Plethora no longer needs it.
Unlike ComputerThread, we do not have a single source of tasks, and so
need a smarter way to handle scheduling and rate limiting. This
introduces a cooldown system, which works on both a global and
per-computer level:
Each computer is allowed to do some work for 5ms. If they go over that
budget, then they are marked as "hot", and will not execute work on the
next tick, until they have cooled down. This ensures that _on average_
computers perform at most 5ms of work per tick.
Obviously this is a rather large time span, so we also apply a global
10ms to all computers. This uses the same cooldown principle, meaning we
keep to an average of 10ms, even if we go over budget.
We were not updating the property instances, so we never actually used
the new values. This changes the syncing method to just copy values from
the new config file, meaning comments and structure are preserved from
the old one.
Note, we cannot just call Config.load(File) again, as the defaults are
no longer accurate.
- We send special packets for key and mouse events, which are then
processed by the container's InputState.
- InputState keeps track of currently held keys and mouse buttons.
- When closing the container, we queue key_up/mouse_up events for any
pending buttons.
We attempted to simplify this 0bfb7049b0,
but that change now means that minimumVirtualRuntime is not updated. As
a result, new tasks will have a runtime of 0 when the queue is empty.
- Some performance improvements to JEI recipe resolver
- Use a shared map for upgrade items, meaning we only need one map
lookup.
- Cache the basic upgrade recipes.
- Use the MC version within project rather than version name.
Before IPocketAccess.getEntity would return the entity which last held
fthis computer, even if not holding it any more. As
ba823bae13 describes, this caused
pocket.equip/pocket.unequip to dupe items.
We move the validation from the PocketAPI into the main IPocketAccess
implementation, to ensure this issue does not occur elsewhere. Note, we
require a separate method, as this is no longer thread-safe.
We also now return ok, err instead of throwing an exception, in order to
be consistent with the turtle functions. See dan200/ComputerCraft#328.
This makes Pocket API not equip/unequip upgrades when the pocket
computer is outside of the player inventory (e.g. dragging,
dropped, placed in a chest).
Oh goodness, this is going to painful to update to 1.13.
We now translate:
- Computer/Disk ID tooltips
- /computercraft descriptions, synopsises and usages. The last of these
may not always be translated when in SMP, as it is sometimes done on
the server, but the alternative would be more complex than I'm happy
with.
- Tracking field names. Might be worth adding descriptions too in the
future.
Also cleanup a couple of other translation keys, so they're more
consistent with Minecraft.
Closes#141
- Turtle and pocket computers provide a "creator mod id" based on their
upgrade(s).
We track which mod was active when the upgrade was registered, and
use that to determine the owner. Technically we could use the
RegistryLocation ID, but this is not always correct (such as
Plethora's vanilla modules).
- We show all upgraded turtles/pocket computers in JEI now, rather than
just CC ones.
- We provide a custom IRecipeRegistryPlugin for upgrades, which
provides custom usage/recipes for any upgrade or upgraded item. We
also hide our generated turtle/pocket computer recipes in order to
prevent duplicates.
Previously we would register the recipes within our code, but the
advancements were written manually. This now generates JSON files for
both the advancement and recipe.
While this does mean we're shipping even more JSON, we'll need to do
this for 1.13 anyway, and means our advancements are guaranteed to be
consistent.
On a side note, a couple of other changes:
- Turtle upgrades are now mounted on the right in the creative
menu/fake recipes. This means the upgrade is now clearly visible in
the inventory.
- We no longer generate legacy turtle items at all: we'll always
construct turtle_expanded.
- Several peripheral items are no longer registered as having sub-types
(namely advanced and full-block modems).
- We only have one disk advancement now, which unlocks all 16 recipes.
- We have removed the disk conversion recipes - these can be
exposed through JEI if needed.
This allows wireless modems (advanced and normal) to be used in
multiparts. There's a very limited set of uses for this (mostly allows
using Chisel and Bits with them), but it's very simple to do.
I'd like to look into MCMP support for wired modems/cables in the
future, but this will be somewhat harder due to their pre-existing
multiblock structure.
Similarly, might be fun to look into CBMP compatibility.
- Share the ILuaContext across all method calls, as well as shifting it
into an anonymous class.
- Move the load/loadstring prefixing into bios.lua
- Be less militant in prefixing chunk names:
- load will no longer do any auto-prefixing.
- loadstring will not prefix when there no chunk name is supplied.
Before we would do `"=" .. supplied_program`, which made no sense.
For instance, `pastebin run https://pastebin.com/LYAxmSby` will now
extract the code and download appropriately. Also add an error message
when we received something which is not a valid pastebin code.
See #134.
This runs tests on CraftOS using a tiny test runner that I originally
knocked up for LuaDash. It can be run both from JUnit (so IDEA and
Gradle) and in-game in the shell, so is pretty accessible to work with.
I also add a very basic POC test for the io library. I'd like to flesh
this out soon enough to contain most of the things from the original io
test.
Before it was not actually selected until the task had yielded for the
first time. If a computer did not yield (or took a while to do so),
nothing would actually show up.
- CobaltLuaMachine/ComputerExecutor can now be paused - this suspends
the machine via a debug hook. When doing work again, we resume the
machine, rather than starting a new task.
- TimeoutState keeps track of how long the current execution of this task
has gone on for, when its deadline is, and the cumulative execution time of
this task.
- ComputerThread now uses a CFS based scheduler in order to determine which
computer to next run.
- Only update all runtimes and the minimum runtime when queuing new
exectors. We only need to update the current executor's runtime.
- Fix overflows when comparing times within TimeoutState.
System.nanotime() may (though probably won't) return negative values.
- Hopefully explain how the scheduler works a little bit.
- Runners would set their active executor before starting resetting the
time, meaning it would be judged as running and terminated.
- Similarly, the cumulative time start was reset to 0, meaning the
computer had been judged to run for an impossibly long time.
- If a computer hit the terminate threshold, but not the hard abort
one, then we'd print the stack trace of the terminated thread - we
now do it before interrupting.
There's still race conditions here when terminating a computer, but
hopefully these changes will mean they never occur under normal
operations (only when a computer has run for far too long).
- Fix the timeout error message displaying utter rot.
- Don't resize the runner array. We don't handle this correctly, so
we shouldn't handle it at all.
- Increment virtualRuntime after a task has executed.
- The computer queue is a priority queue sorted by "virtual runtime".
- Virtual runtime is based on the time this task has executed, divided
by the number of pending tasks.
- We try to execute every task within a given period. Each computer is
allocated a fair share of that period, depending how many tasks are
in the queue. Once a computer has used more than that period, the
computer is paused and the next one resumed.
TimeoutState now introduces a TIMESLICE, which is the maximum period of
time a computer can run before we will look into pausing it.
When we have executed a task for more than this period, and if there are
other computers waiting to execute work, then we will suspend the
machine.
Suspending the machine sets a flag on the ComputerExecutor, and pauses
the "cumulative" time - the time spent handling this particular event.
When resuming the machine, we restart our timer and resume the machine.
Oh goodness, when will it end?
- Computer errors are shown in red.
- Lua machine operations provide whether they succeeded, and an
optional error message (reason bios failed to load, timeout error,
another Lua error), which is then shown to the user.
- Clear the Cobalt "thrown soft abort" flag when resuming, rather than
every n instructions.
- Computers will clear their "should start" flag once the time has
expired, irrespective of whether it turned on or not. Before
computers would immediately restart after shutting down if the flag
had been set much earlier.
Errors within the Lua machine are displayed in a more friendly
When closing a BufferedWriter, we close the underlying writer. As we're
using channels, this is an instance of sun.nio.cs.StreamEncoder. This
will attempt to flush the pending character.
However, if throwing an exception within .write errors, the flush will
fail and so the underlying stream is not closed. This was causing us to
leak file descriptors.
We fix this by introducing ChannelWrappers - this holds the wrapper
object (say, a BufferedWriter) and underlying channel. When closed, we
dispose of the wrapper, and then the channel. You could think of this as
doing a nested try-with-resources, rather than a single one.
Note, this is not related to JDK-6378948 - this occurs in the underlying
stream encoder instead.
- TimeoutState uses nanoseconds rather than milliseconds. While this is
slightly less efficient on Windows, it's a) not the bottleneck of Lua
execution and b) we need a monotonic counter, otherwise we could
fail to terminate computers if the time changes.
- Add an exception handler to all threads.
- Document several classes a little better - I'm not sure how useful
all of these are, but _hopefully_ it'll make the internals a little
more accessible.
- Move state management (turnOn, shutdown, etc...) event handling and
the command queue into a ComputerExecutor
- This means the computer thread now just handles running "work" on
computer executors, rather than managing a separate command queue +
requeuing it.
- Instead of setting soft/hard timeouts on the ILuaMachine, we instead
provide it with a TimeoutState instance. This holds the current abort
flags, which can then be polled within debug hooks.
This means the Lua machine has to do less state management, but also
allows a more flexible implementation of aborts.
- Soft aborts are now handled by the TimeoutState - we track when the
task was started, and now only need to check we're more than 7s since
then.
Note, these timers work with millisecond granularity, rather than
nano, as this invokes substantially less overhead.
- Instead of having n runners being observed with n managers, we now
have n runners and 1 manager (or Monitor).
The runners are now responsible for pulling work from the queue. When
the start to execute a task, they set the time execution commenced.
The monitor then just checks each runner every 0.1s and handles hard
aborts (or killing the thread if need be).
- Rename unload -> close to be a little more consistent
- Make pollAndResetChanged be atomic, so we don't need to aquire a lock
- Get the computer queue from the task owner, rather than a separate
argument.
Ideally we'd add a couple more tests in the future, but this'll do for
now.
The bootstrap class is largely yoinked from CCTweaks-Lua, so is a tad
ugly. It works though.
We now generate a table and concatinate the elements together. This has
several benefits:
- We no longer emit emit trailing spaces, which caused issues on 1.13's
command system.
- We no longer need the error level variable, nor have the weird
recursion system - it's just easier to understand.
Prior to this change we would schedule a new task which attached
peripherals on the ComputerThread on the empty task queue. This had a
couple of issues:
- Slow running tasks on the computer thread could result in delays in
peripherals being attached (technically, though rarely seen in
practice).
- Now that the ComputerThread runs tasks at once, there was a race
condition in computers being turned on/off and peripherals being
attached/detached.
Note, while the documentation said that peripherals would only be
(at|de)tached on the computer thread, wired modems would attach on the
server thread, so this was not the case in practice.
One should be aware that peripherals are still detached on the
computer thread, most notably when turning a computer on/off.
This is almost definitely going to break some less well-behaved mods,
and possible some of the well behaved ones. I've tested this on SC, so
it definitely works fine with Computronics and Plethora.
- Restrict what items can be inserted into printers. They're now closer
to brewing stands or furnaces: nothing can go in the output slot,
only ink in the ink slot, and only paper in the paper slot.
- Fix build.gradle using the wrong version
- Trim the width of tables to fit when displaying on the client. Closes
#45. Note, our solution isn't perfect, as it will wordwrap too, but
it's adaquate for now.
- Reword elements of the README, mostly changing the elements about
vanilla ComputerCraft.
- Change versioning scheme: we'll now do 1.x.y, with 1.81.0 being the
next version.
- Include MC version in the file name
- Stop bundling javadoc with the jar. We'll look into hosting this on
squiddev.cc if really needed.
- Remove the LuaJ license from the root - we no longer bundle the
sources, so it's not needed here.
I realise this change looks a little dodgey on its own, so see #113 for
the full rationale.
When a turtle was unloaded but not actually disposed of, the
m_peripheral map hangs around. As a result, when creating a new
ServerComputer, the peripherals aren't considered changed and so they're
never attached.
Fixes#50.
Also fix that blumin' deprecated method which has been around for a wee
while now.
The Computer class currently has several resposiblities such as storing
id/label, managing redstone/peirpherals, handling management of the
computer (on/off/events) and updating the output.
In order to simplify this a little bit, we move our IAPIEnvironment
implementation into a separate file, and store all "world state"
(redstone + peripherals) in there. While we still need to have some
level of updating them within the main Computer instance, it's
substantially simpler.
- Fire close events instead of failure when open websockets error.
- Handle ping events. I thought I was doing this already, but this
requires a WebsocketProtocolHandler. Fixes#118
- Run optipng on all our images. This has very little effect on most of
them (as they're all so small anyway), but has resulted in a 50%
reduction in some cases.
- Run Proguard on our shadowed dependencies (Cobalt).
- Minify our JSON files, stripping all whitespace. This is mostly
useful for FML's annotation cache, as that's a massive file, but
still a semi-useful optimisation to make.
This has helped reduce the jar by about 110kb, which isn't much but
still feels somewhat worth it.
The latest version of Cobalt has several major changes, which I'm
looking forward to taking advantage of in the coming months:
- The Lua interpreter has been split up from the actual LuaClosure
instance. It now runs multiple functions within one loop, handling
pushing/popping and resuming method calls correctly.
This means we have a theoretically infinite call depth, as we're no
longer bounded by Java's stack size. In reality, this is limited to
32767 (Short.MAX_VALUE), as that's a mostly equivalent to the limits
PUC Lua exposes.
- The stack is no longer unwound in the event of errors. This both
simplifies error handling (not that CC:T needs to care about that)
but also means one can call debug.traceback on a now-dead coroutine
(which is more useful for debugging than using xpcall).
- Most significantly, coroutines are no longer each run on a dedicated
thread. Instead, yielding or resuming throws an exception to unwind
the Java stack and switches to a different coroutine.
In order to preserve compatability with CC's assumption about LuaJ's
threading model (namely that yielding blocks the thread), we also
provide a yieldBlock method (which CC:T consumes). This suspends the
current thread and switches execution to a new thread (see
SquidDev/Cobalt@b5ddf164f1 for more
details). While this does mean we need to use more than 1 thread,
it's still /substantially/ less than would otherwise be needed.
We've been running these changes on SwitchCraft for a few days now and
haven't seen any issues. One nice thing to observe is that the number of
CC thread has gone down from ~1.9k to ~100 (of those, ~70 are dedicated
to running coroutines). Similarly, the server has gone from generating
~15k threads over its lifetime, to ~3k. While this is still a lot, it's
a substantial improvement.
This is far more elegant than our weird method of baking things and
manually inserting them into the model map. Also means we no longer need
the whole turtle_dynamic thing.
We moved the direction call within the if block, but never actally
updated the condition! I'm on a roll of stupid bug fixes today, which
really isn't a good sign.
- Only have computers implement custom block drop logic: everything
else only drops in creative mode.
- Fix redstone inputs not being received correctly. Introduced in
8b86a954ee, yes I'm a silly billy.
- Only update the neighbour which changed.
- Convert terminals from a polling-based system to a more event-driven
one: they now accept an onChanged callback, which marks the parent as
dirty.
- Schedule ticks when monitors are marked as dirty.
- Add several missing @Overrides. This has nothing to do with the rest
of the changes, but I'm bad at good git practice.
- Merge BlockPeripheralBase and BlockPeripheral, as no other classes
extended the former.
- Make BlockPeripheral use ITilePeripheral instead of
TilePeripheralBase. This allows us to use other, non-ticking tiles
instead.
- Convert advanced and normal modems to extend from a generic
TileWirelessModemBase class, and thus neither now tick.
- Move getPeripheralType and getLabel from IPeripheralTile to
TilePeripheralBase. These were mostly constant on all other tiles, so
were rather redundant.
- Make TileAdvancedModem extend TileGeneric, and be non-ticking (using
similar logic to all other blocks).
- Move updateTick onto BlockGeneric/TileGeneric instead of the full
wired modem, as it is used by several tiles now.
- Make *Cable extend from *Generic, and schedule ticks instead of
running every tick.
We currently generate the crafting item once when the upgrade is first
created, and cache it for the duration of the game. As the item never
changes throughout the game, and constructing a stack is a little
expensive (we need to fire an event, etc...), the caching is worth
having.
However, some mods may register capabilities after we've constructed our
ItemStack. This means the capability will be present on other items but
not ours, meaning they are not considered equivalent, and thus the item
cannot be equipped.
In order to avoid this, we use compare items using their share-tag, like
Forge's IngredientNBT. This means the items must still be "mostly" the
same (same enchantements, etc...), but allow differing capabilities.
See NillerMedDild/Enigmatica2Expert#655 for the original bug report -
in this case, Astral Sourcery was registering the capability in init,
but we construct upgrades just before then.
- Move IDirectionalTile constraint from IPeripheralTile to
TilePeripheralBase.
- Make *WiredModemFull no longer inherit from *PeripheralBase. While
there is still some shared logic (namely in the syncing of "anim"),
it's largely fine as we don't store label or direction in NBT.
- Add a TickScheduler. This is a thread-safe version of
World.scheduleUpdate. We simply build a set of all TEs, and schedule
them to be updated the next tick.
- Make ModemState receive an "onChanged" listener, which is fired
whenever the modem changes.
- Make WiredModemFull no longer tick, instead scheduling updates when
it is first loaded and whenever the modem changes.
FileSystemMount was originally added to allow using ReadableByteChannels
instead of InputStreams. However, as zip files do not allow seeking,
there is no benefit of using them over the original JarMount (which we
need to preserve for backwards compatibility).
Instead of maintaining two near-identical mounts, we remove the
FileSystemMount and rewrite the JarMount implementation with several
improvements:
- Rewrite the jar scanning algorithm to be closer to 1.13+'s data pack
mount. This means we no longer require the jar file to have
directories before the file (though this was not a problem in
practice).
- Add all JarMounts to a ReferenceQueue, closing up the ZipFile when
they have been garbage collected (fixes#100).
- Cache the contents of all files for 60 seconds (with some constraints
on size). This allows us to seek on ROM files too (assuming they are
small), by reading the whole thing into memory.
The cache is shared across all mounts, and has a 64MiB limit, and
thus should not have an adverse impact on memory.
This is done in 1.13+ for items and blocks, so we might as well do it
for upgrades now. Note we can't do it for ender pocket modems, as the
upgrade ID is spelled incorrectly there.
- For those where placement is stored in the metadata (computers),
don't also set it in onBlockPlacedBy.
- Remove .getDefaultState(int, EnumFacing) override, as this means we
have more control over what is passed to us (namely, placer's
direction too).
"/computercraf" auto-completes to "/computercraft_copy" instead of
"/computercraft", which is rather annoying, as the former is not meant
to be used normally.
It's rather embarassing that it's been restructured _again_, but I think
this is a nice middle-ground. The previous implementation was written
mostly for Fabric, which doesn't always map perfectly to Forge.
- Move the message identifier into the registration phrase. It's not
really a property of the message itself, rather a property of the
registry, so better suited there.
- Move message handling into the message itself. Honestly, it was just
ending up being rather messy mixing the logic in two places.
This also means we can drop some proxy methods, as it's easier to
have conditionally loaded methods.
- Move network registry into a dedicated class, as that's what we're
doing for everything else.
This means we can avoid several rather ugly instances of getItemBlock
and a cast. We also derive the ItemBlock's registered name from the
block's name, which makes the register a little less ugly.
- Move the "world directory" getter out of the proxy - we can just use
Forge's code here.
- Remove the server proxies, as both were empty. We don't tend to
register any dedicated-server specific code, so I think we can leave
them out.
- All "named" entries (blocks, items, recipes, TEs and pocket/turtle
upgrades) are registeredin one place.
- Most client side models/textures are registered in ClientRegistry -
we can't do item colours or TEs for now, as these aren't event based.
- A little cleanup to how we handle ItemPocketComputer models.
This offers several advantages
- Less registration code: the subscribers are reigstered automatically,
and we don't need to worry about sided-proxies.
- We no longer have so many .instance() calls.
- Move SpeakerPeripheral's TileSpeaker functionality to a sub-class.
- Use Vec3d instead of BlockPos for speaker's positions.
- Use WorldUtil.dropItemStack to spawn in items.
- Remove redundant lock on ModemPeripheral.
- We now error if there are too many websockets, instead of queuing
them up. As these have a more explicit "lifetime", it could be
confusing if http.websocket just blocks indefinitely.
- Fix a CCME when cleaning up resources.
- Move all HTTP tasks to a unified "MonitoredResource" model. This
provides a uniform way of tracking object's lifetimes and disposing
of them when complete.
- Rewrite HTTP requests to use Netty instead of standard Java. This
offers several advantages:
- We have access to more HTTP verbs (mostly PATCH).
- We can now do http -> https redirects.
- We no longer need to spawn in a new thread for each HTTP request.
While we do need to run some tasks off-thread in order to resolve
IPs, it's generally a much shorter task, and so is less likely to
inflate the thread pool.
- Introduce several limits for the http API:
- There's a limit on how many HTTP requests and websockets may exist
at the same time. If the limit is reached, additional ones will be
queued up until pending requests have finished.
- HTTP requests may upload a maximum of 4Mib and download a maximum
of 16Mib (configurable).
- .getResponseCode now returns the status text, as well as the status
code.
While Plethora has been updated to no longer require these, it's
probably worth keeping them around a little longer, as people may not
upgrade them in sync.
We've had this on SC for most of a year now (and SC 1 for most of its
lifetime) and not seen any issues. I'm fairly confident that it does not
allow breaking the sandbox.
- Move configuration loading into a separate file, just so it doesn't
clutter up ComputerCraft.java.
- Normalise property names, so they're all snake_case.
- Split properties into separate categories (http, turtle, peripheral),
so the main one is less cluttered.
- Define an explicit ordering of each category.
- Provide whether a message was binary or text in websocket_message
and handle.receive(). (Fixes#96)
- Provide an optional reason and status code within the websocket_close
event.
Off topic, but also cleanup the file handles a little.
- Remove redundant constructors and super calls
- Standardise naming of texture fields
- Always use postfix notations for loops
- Cleanup several peripheral classes
Previously we would send computer state (labels, id, on/off) through the
ClientComputer rather than as part of the TE description. While this
mostly worked fine, it did end up making things more complex than they
needed to be.
We sync most data to the tile each tick, so there's little risk of
things getting out of date.
There's several reasons for this change:
- Try to make ComputerCraft.java less monolithic by moving
functionality into separate module-specific classes.
- Hopefully make the core class less Minecraft dependent, meaning
emulators are a little less dependent on anything outside of /core.
Note we still need /some/ methods in the main ComputerCraft class in
order to maintain backwards compatibility with Plethora and
Computronics.
Many bits of IInventory (open/close, fields, etc...) are not actually
needed most implementations, so we can clean things up a little with a
common interface.
Some methods act the same on both sides, and so can be in utility
classes. Others are only needed on one side, and so do not really need
to be part of the proxy.
- Remove TurtleVisionCamera. It would be possible to add this back in
the future, but for now it is unused and so should be removed.
- Move frame info (cursor blink, current render frame) into a
FrameInfo class.
- Move record methods (name, playing a record) into a RecordUtil class.
- getPickBlock is now implemented directly on computers and turtles,
rather than on the tile.
- Bounding boxes are handled on the block rather than tile. This ends
up being a little ugly in the case of BlockPeripheral, but it's not
the end of the world.
- Explosion resistance is only implemented for turtles now.
- Replace BlockCableCableVariant with a boolean, removing any custom
logic around it.
- Replace our previous cable Forge-blockstate with a vanilla one, which
handles cable connections in the model logic.
This ends up being slightly cleaner as we can rely on Minecraft's own
model dependency system. Also reduces reliance on Forge's APIs, which
_potentially_ makes porting a little easier.
- Remove the two redstone commands. These are not used (maybe only by
CCEdu), and so are somewhat redundant.
- Inline the select command, converting it to a lambda.
- Inline the attack/dig commands, as they did little more than wrap the
tool command.
As CCEdu has not been updated, and is unlikely to be updated as Dan does
not have the rights to open source it, we're removing explicit support
for now.
If an alternative arises in the future, it would be good to support, but
in a way which requires less workarounds in CC's core.
Most upgrades provides a couple of constant getters (upgrade ID,
adjective, crafting item). We move the getters into a parent class and
pass the values in via the constructor instead.
Also do a tiny bit of cleanup to the upgrades. Mostly just reducing
nesting, renaming fields, etc...
- Only generate resource pack mounts if the desired directory exists.
- Allow mounting files, as well as directories (fixes#90).
As always, also a wee bit of cleanup to some of the surrounding code.
I feel I should write a long winded commit message about the rationale
behind it, but honestly, it was just another folder in the directory
root we didn't need.
This allows us to block JEI processing key events such as "o", meaning
the GUI is not constantly toggled when interacting with a turtle.
Also clean up the widget code, as there's a lot of functionality here
which only is needed in CCEdu.
This is implemented in a rather ugly way: we register a client command
(/computercraft_copy) which updates the clipboard, and run that via a
click handler on the chat message.
This hopefully makes wired modems a little easier to use. We'll see.
I don't think anyone has actually ended up using this, so it's unlikely
to break anything (though do tell me if this is the case). On the flip
side, this allows us to queue events on multiple computers, and means
we can provide a little more documentation.
Using turtle.suck on an inventory filled with tools would fill the
entire chest with said item, rather than extracting a single item. In
order to avoid that, we clamp the extract limit to the max stack size
when first extracting an item.
This also inlines the makeSlotList logic, which means we can avoid
creating an array for each inventory operation. This probably won't
have any meaninful performance impact (even on large inventories), but
is a nice optimisation to make.
- Remove a redundant logger
- Provide a getter for the ComputerCraft thread group. This allows us
to monitor child threads within prometheus.
- Replace a deprecated call with a fastutils alternative.
Some mods (*cough* Computronics *cough*) directly access this class,
rather than using the API. We add this back to ensure they still behave
as expected.
Truth be told, I can't really complain, as Plethora also does dodgy
thing with CC internals.
- Keep track of the number of created and destroyed coroutines for each
computer.
- Run coroutines with a thread pool executor, which will keep stale
threads around for 60 seconds. This substantially reduces the
pressure from short-lived coroutines.
- Update to the latest Cobalt version.
- Introduce a ModemState, which shares the open channels across all
modem instances of a wired modem.
- Keep a set of computers for all modem peripherals.
- Keep a map of computers -> (string, peripheral) for wired modem
peripherals. We shouldn't need this one, as you cannot attach one
modem to another, but it's good to be consistent.
One major change here is that modems will continue to be "on", even if
no computers are attached. This would substantially increase
implementation complexity, so I think this is an acceptable compromise
for now.
Should fix#74
Java configured the charset decoders/encoders for streams to REPLACE
malformed characters rather than the default REPORT. It does not do the
same for channels, and so we were catching an IO exception and returning
null.
We'd somehow added spaces, which means they weren't registered under the
computercraft domain (rather, the "computercraft " one). We also create
a datafixer to ensure old worlds are handled correctly.
These were part of the original CC repo, but aren't really needed now
that everything important (LuaJ, bundling API docs+source), has been
moved to Gradle.
We also remove the LuaJ lib. It's sad to see it go, but it was rather
redundant. We're keeping the LuaJ sources for now, as I don't really
want a really large diff.
- Rename openStreamFor* methods to more accurate openChannelFor*
- Fix ArrayByteChannel having an incorrect .position() implementation
Cherry-picked from the PR against dan200/ComputerCraft
- Add an argument to send which controls whether it's a binary message
or not. This is a little ugly, but it's probably more effective than
anything else.
- Fix binary frames not correctly queueing the correct data in the
message event.
Closes#69
The method to register new SoundEvents is private, which means that few
(if any) mods actually register them. Consequently, one could not use
the speaker to play any modded sound, as they weren't registered on the
server side.
Using SPacketCustomSound does mean we can no longer determine if a sound
exists or not, but I think a price I'm willing to pay in order to allow
playing modded sounds.
This replaces the existing IMount openFor* method with openChannelFor*
ones, which return an appropriate byte channel instead.
As channels are not correctly closed when GCed, we introduce a
FileSystemWrapper. We store a weak reference to this, and when it is
GCed or the file closed, we will remove it from our "open file" set and
ensure any underlying buffers are closed.
While this change may seem a little odd, it does introduce some
benefits:
- We can replace JarMount with a more general FileSystemMount. This
does assume a read-only file system, but could technically be used
for other sources.
- Add support for seekable (binary) handles. We can now look for
instances of SeekableByteChannel and dynamically add it. This works
for all binary filesystem and HTTP streams.
- Rewrite the io library to more accurately emulate PUC Lua's
implementation. We do not correctly implement some elements (most
noticably "*n", but it's a definite improvement.
This crash can be triggered remotely by specially constructed rednet messages, making this a bit of a problem, as any repeaters can be remotely crashed.
A lot of these don't actually have any effect as they'll only be called
on the main thread or they are getters where the state is guaranteed to
be consistent whenever it is accessed.
Hopefully this'll reduce the chance of world updates being blocked by
waiting for peripheral locks to be released.
- Make window.reposition's argument validation a little more strict.
Previously it would accept `window.reposition(x, y, width)` (no
height argument), just not act upon it.
- Use select instead of table.unpack within `pastebin run`.
- Use `parallel.waitForAny` instead of `waitForAll` within the dance
program.
- Pipe the entire help file into `textutils.pagedPrint`, rather than
doing it line by line.
- Remove bytecode loading disabling from bios.lua. This never worked
correctly, and serves little purpose as LuaJ is not vulnerable to
such exploits.
- Bump MinecraftForge version so we don't crash on load. Oh boy, all
the deprecation warnings.
- Inject IBundledEmitter and IBundledReceiver capabilities onto all
TileGenerics.
- Register a IBundledRedstoneProvider instance for IBundledEmitter.
I'm not entirely a fan of massive templates, but there's
been a couple of lacklustre issues recently, so it's probably
good to formalise my guidelines.
This is a preliminary for updating to 1.13, as many of the name changes
apply to both. This will make it harder to remain consistent with
actual CC, though that will be less of a consideration when 1.13 hits.
When placing a sign against a tile entity (such as a turtle or chest),
we would consider that block the "placed" one instead, meaning the text
was never set. This solution isn't entirely ideal either, but short of
capturing block snapshots I'm not sure of a better solution.
Fixes#552
Effectively shift extracting the computer away from Plethora into CC:T.
Ideally we wouldn't need this at all, but Plethora does some funky
things with tick timings.
See SquidDev-CC/plethora#125
Player construction can get a little expensive, and this is exacerbated
by Sponge. We now cache a turtle's fake player (updating the position
every time it is requested) in order to reduce this overhead.
- The current page is always centred when rendering in a GUI, with
the turned pages moving from the sides.
- Pages are no longer evenly distributed from the centre - they follow
an exponential decay curve, so ones further out are closer together
(a bit like an open book).
- Render pages and books in item frames/in-hand (rather than just
single pages).
This currently does some very dirty things with z values in order to
prevent z-fighting. It would be nice to avoid that, though turning off
writing to the z buffer causes issues with the bounding box.
- Try to make drop capturing a little more generic. This now allows for
capturing a block's drop at a given position, as well as any drop
within a bounding box (for things which don't play nicely).
- Use as much of Minecraft's block breaking logic as possible,
hopefully simplifying things and making it more consistent with other
mods.
As we only send the terminal to players using the GUI, the map interface
was never updated. We now will also send the terminal state to whoever
has the computer in their inventory.
This also marks the terminal as dirty when a new player picks the pocket
computer up, hopefully preventing any desync issues which might occur
then.
Fixes#42.
- Fix text table only showing the first row (fixes#40)
- Do not emit alignment characters in monospace environments
- Reduce padding in monospace environments
Also make the output of dump consistent with that of the profiler: we
provide tp and view shortcuts for each computer.
- Slight airbrush effect for normal turtles. While this is only really
visible when upping the contrast, it's probably nice to fix.
- A few off-colour pixels for advanced turtles
- Include a list of features, pretty similar to that on the forum
thread or CurseForge page.
- Replace CC: Tweaked with CC:T. After all, who wants to type all of
that?
2018-05-15 12:27:04 +01:00
2364 changed files with 85136 additions and 94471 deletions
- Search for the suggestion here. It's possible someone's suggested it before!
-->
## Useful information to include:
- Explanation of how the feature/change should work.
- Some rationale/use case for a feature. My general approach to designing new features is to ask yourself "what issue are we trying to solve" and _then_ "is this the best way to solve this issue?".
- If there's a existing issue, please link to it. If not, provide fill out the same information you would in a normal issue - reproduction steps for bugs, rationale for use-case.
- If you're working on CraftOS, try to write a few test cases so we can ensure everything continues to work in the future. Tests live in `src/test/resources/test-rom/spec` and can be run with `./gradlew check`.
changelog="Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v${mc_version}-${mod_version})."
The @{modem_message} event is fired when a message is received on an open channel on any modem.
## Return Values
1. @{string}: The event name.
2. @{string}: The side of the modem that received the message.
3. @{number}: The channel that the message was sent on.
4. @{number}: The reply channel set by the sender.
5. @{any}: The message as sent by the sender.
6. @{number}: The distance between the sender and the receiver, in blocks (decimal).
## Example
Prints a message when one is sent:
```lua
while true do
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
print(("Message received on side %s on channel %d (reply to %d) from %f blocks away with message %s"):format(side, channel, replyChannel, distance, tostring(message)))
see: modem_message For raw modem messages sent outside of Rednet.
see: rednet.receive To wait for a Rednet message with an optional timeout and protocol filter.
---
The @{rednet_message} event is fired when a message is sent over Rednet.
This event is usually handled by @{rednet.receive}, but it can also be pulled manually.
@{rednet_message} events are sent by @{rednet.run} in the top-level coroutine in response to @{modem_message} events. A @{rednet_message} event is always preceded by a @{modem_message} event. They are generated inside CraftOS rather than being sent by the ComputerCraft machine.
## Return Values
1. @{string}: The event name.
2. @{number}: The ID of the sending computer.
3. @{any}: The message sent.
4. @{string|nil}: The protocol of the message, if provided.
## Example
Prints a message when one is sent:
```lua
while true do
local event, sender, message, protocol = os.pullEvent("rednet_message")
if protocol ~= nil then
print("Received message from " .. sender .. " with protocol " .. protocol .. " and message " .. tostring(message))
else
print("Received message from " .. sender .. " with message " .. tostring(message))
see: commands.execAsync To run a command which fires a task_complete event.
---
The @{task_complete} event is fired when an asynchronous task completes. This is usually handled inside the function call that queued the task; however, functions such as @{commands.execAsync} return immediately so the user can wait for completion.
## Return Values
1. @{string}: The event name.
2. @{number}: The ID of the task that completed.
3. @{boolean}: Whether the command succeeded.
4. @{string}: If the command failed, an error message explaining the failure. (This is not present if the command succeeded.)
The @{terminate} event is fired when <kbd>Ctrl-T</kbd> is held down.
This event is normally handled by @{os.pullEvent}, and will not be returned. However, @{os.pullEventRaw} will return this event when fired.
@{terminate} will be sent even when a filter is provided to @{os.pullEventRaw}. When using @{os.pullEventRaw} with a filter, make sure to check that the event is not @{terminate}.
## Example
Prints a message when Ctrl-T is held:
```lua
while true do
local event = os.pullEventRaw("terminate")
if event == "terminate" then print("Terminate requested!") end
The output <em>hello.java</em> is Java source, that implements the logic in hello.lua directly.
Once <em>hello.java</em> is compiled into <em>hello.class</em> it can be required and used in place of the original lua script, but with better performance.
There are no additional dependencies for compiling or running source-to-source compiled lua.
<p>
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-j</em></b> option when run in JDK 1.5 or higher:
Luaj can compile lua sources or binaries directly to java bytecode if the bcel library is on the class path. From the main distribution directory line type:
The output <em>hello.class</em> is Java bytecode, should run and produce the same result.
There is no runtime dependency on the bcel library,
but the compiled classes must be in the class path at runtime, unless runtime jit-compiling via luajc and bcel are desired (see later sections).
<p>
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path:
See a longer sample in <em>examples/lua/swingapp.lua</em> for details, including a simple animation loop, rendering graphics, mouse and key handling, and image loading.
In luaj 2.0.3 error reporting was turned on in the parser so line numbers are avaiable for most parse exceptions.
This example may be found in
<pre>
examples/jse/SampleParser.java
</pre>
<p>
See the <ahref="http://luaj.sourceforge.net/api/2.0/org/luaj/vm2/ast/package-summary.html">org.luaj.vm2.ast package</a> javadoc for the API relating to the syntax tree that is produced.
<h1>7 - <aname="7">Building and Testing</a></h1>
<h2>Building the jars</h2>
An ant file is included in the root directory which builds the libraries by default.
<p>
Other targets exist for creating distribution file an measuring code coverage of unit tests.
<h2>Unit tests</h2>
<p>
The main luaj JUnit tests are organized into a JUnit 3 suite:
<pre>
test/junit/org/luaj/vm2/AllTests.lua
</pre>
<p>
Unit test scripts can be found in these locations
<pre>
test/lua/*.lua
test/junit/org/luaj/vm2/compiler/lua5.1-tests.zip
test/junit/org/luaj/vm2/compiler/regressions.zip
test/junit/org/luaj/vm2/vm1/luajvm1-tests.zip
</pre>
<h2>Code coverage</h2>
<p>
A build script for running unit tests and producing code coverage statistics is in
<pre>
build-coverage.xml
</pre>
It relies on the cobertura code coverage library.
<h1>8 - <aname="8">Downloads</a></h1>
<h2>Downloads and Project Pages</h2>
Downloads for all version available on SourceForge or LuaForge.
Sources are hosted on SourceForge and available via sourceforge.net
<li>JSR-223 bindings change: non Java-primitives will now be passed as LuaValue </li>
<li>JSR-223 enhancement: allow both ".lua" and "lua" as extensions in getScriptEngine() </li>
<li>JSR-223 fix: use system class loader to support using luaj as JRE extension </li>
<li>Improve selection logic when binding to overloaded functions using luajava</li>
<li>Enhance javadoc, put it <ahref="docs/api/index.html">in distribution</a> and <ahref="http://luaj.sourceforge.net/api/2.0/index.html">on line</a></li>
<li>Major refactor of luajava type coercion logic, improve method selection.</li>
<li>Add lib/luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li>
publicintstrcmp(LuaStringrhs){typerror("attempt to compare number with string");return0;}
publicintcheckint(){
returnv;
}
publiclongchecklong(){
returnv;
}
publicdoublecheckdouble(){
returnv;
}
publicStringcheckjstring(){
returnString.valueOf(v);
}
publicLuaStringcheckstring(){
returnvalueOf(String.valueOf(v));
}
}
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.