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".
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
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)
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.
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