rojo-rbx / remodel

Scriptable Roblox multitool: Manipulate instances, model files, places, and assets on Roblox.com
MIT License
169 stars 38 forks source link

Provide an API for hashing Roblox files #60

Open grilme99 opened 3 years ago

grilme99 commented 3 years ago

I currently have a workflow for validating the authenticity of the production game on Roblox. Without going into major detail, this works by generating a hash of the final build file at publish-time and then periodically checking that against the live place automatically. The purpose of doing this is to make sure that the production game has always gone through the deployment pipeline and not published to directly (and by extension skipping all code review and unit tests).

I've tried different ways of accomplishing this. This first was a pure Lua implementation, but hashing algorithms written in Lua are slow and resource hungry. This doesn't work for large build files because I need to keep workflow times as low as possible. My current implementation is a mix of Lua and Node.js, with Lua (Remodel) handling the publishing/downloading of the game, and Node handling the actual hashing. This does work, but having to interface between Lua and Node (by invoking CLI commands from Node) is very clunky and error-prone.

Ideally, Remodel would provide an API to hash game files, utilizing the speed and efficiency of Rust to do it. This would vastly improve the speed (no need to download the Node runtime every time), efficiency, and readability of my workflow over my current implementation.

LPGhatguy commented 3 years ago

Similar to #45. Previously I wasn't very interested, but revisiting this now, I think I am onboard.

You might be able to install a LuaRocks package that has hash algorithms, but the experience of doing that isn't great.

What do you think this API should look like? Should we just accept a string? I've been thinking about introducing some new top-level globals instead of lumping everything into remodel. Something like:

remodel.hash("sha256", "something to hash")

-- or in its own global
crypto.hash("sha256", "something to hash")
grilme99 commented 3 years ago

I'm fully on board with crypto methods being their own global, and following that approach makes it easier to add more globals down the line for different purposes.

You might be able to install a LuaRocks package that has hash algorithms, but the experience of doing that isn't great.

Yeah, I'm not too familiar with the Lua ecosystem and how that would work, especially with Remodel specifically. This probably raises more concerns when it comes to CI/CD as well, rather than just running on your own PC? Ideally, this would have a few dependencies as possible, not to mention having to install LuaRocks packages is a huge barrier to entry.

What do you think this API should look like? Should we just accept a string?

I think the best approach should be taking a string so that it's not limited to just Roblox files specifically. Luckily this issue was closed recently so it should work for both file formats. Just to confirm, the best way to read the files as a string in Lua would be with the io.open method, right?

LPGhatguy commented 3 years ago

Just to confirm, the best way to read the files as a string in Lua would be with the io.open method, right?

You can do it with stock Lua like this:

local file = io.open(path, "rb")
local contents = file:read("*a")
file:close()

but we also have a Remodel API for this, given how wonky the Lua API is:

local contents = remodel.readFile(path)

Yeah, I'm not too familiar with the Lua ecosystem and how that would work, especially with Remodel specifically. This probably raises more concerns when it comes to CI/CD as well, rather than just running on your own PC? Ideally, this would have a few dependencies as possible, not to mention having to install LuaRocks packages is a huge barrier to entry.

It's actually much easier to set up LuaRocks on a CI/CD system than on a Windows developer machine. 😅

If you need this sorta thing in the mean time, check out how I set up Lua/LuaRocks in the Roact repository. Should just be a matter of picking the right version and using luarocks install sha2. There might be some funky stuff you'd need to set up with LUA_PATH to get things to work with Remodel.

Laying out everything that's required, I'm even more inclined to say that we should build this in.