This repository contains a fork of the MCHPRS Minecraft high-performance redstone server that adds an RCON-like protocol called RSC.
RSC is binary protocol running over TCP and enables extending redstone functionality without modifications to server software, by allowing fast and synchronized I/O(reading/writing/observing blocks etc.) with a Minecraft world from an external program.
The example scripts give some idea of what can be possible with this protocol:
The memory.lua
script implements external memory that can be connected to a redstone build,
so that a redstone build can use gigabytes of fast redstone-addressable memory.
The rawvideo.lua
script implements simple video streaming from a video source
to a display in Minecraft.
The rsc_api.lua
CGI script wraps the RSC API for the web, enabling extensions
to be written in JavaScript for the browser.
Note
This fork is not in any way officially associated with the official MCHPRS project.
Warning
Currently there are no permission checks on being able to listen to an arbitrary port! In it's current state it might not be suitable for public hosting.
Warning
Assume access to an RSC connection means full access to a MCHPRS plot! There is no authentication at the moment!
Some new chat commands have been added for this interface. All these commands apply to the current plot.
Chat command | Description |
---|---|
rsc_listen <bind address> |
Start the TCP listener thread and binds to the specified address:port |
rsc_chat |
Send a chat message that can be read by RSC clients |
freeze |
Freeze redstone ticks |
unfreeze |
Unfreeze redstone ticks |
binfo |
Show info about the block under the players feet |
pause_on_block |
Pauses the game when the block at position of the players feet changes |
(Pausing might interfere with the observing functionality of the RSC observe commands. Only a single block can be observed at a time.)
The RSC protocol is a very simple binary protocol.
A client can send one of 7 request packets, two of which(GetBlock and ObserveBlock) send a reply back.
The first byte in a package is always a packet ID. The other data types used in packets are signed and unsigned 32-bit little-endian integers.
Note
A request is not always immediately followed by a response for this particular request. For example, a ChatMessageResp can arrive while waiting for a GetBlockResp!
These requests can be sent to a RSC server from a RSC client.
Request type | Packet format | Server response | Additional details |
---|---|---|---|
GetBlock | <u8 0><i32 x><i32 y><i32 z> |
GetBlockResp | |
SetBlock | <u8 1><i32 x><i32 y><i32 z><u32 block_id> |
||
ObserveBlock | <u8 2><i32 x><i32 y><i32 z> |
ObserveBlockResp | |
UpdateBlock | <u8 3><i32 x><i32 y><i32 z> |
||
Freeze | <u8 4> |
||
Unfreeze | <u8 5> |
||
Step | <u8 6><i32 n> |
||
GetBlockRange | <u8 7><i32 x_min><i32 y_min><i32 z_min><i32 x_max><i32 y_max><i32 z_max> |
GetBlockRangeResp | |
SetBlockRange | <u8 8><i32 x_min><i32 y_min><i32 z_min><i32 x_max><i32 y_max><i32 z_max><u32 blockid><...> |
multiple block ids are in xyz-order | |
UpdateBlockRange | <u8 9><i32 x_min><i32 y_min><i32 z_min><i32 x_max><i32 y_max><i32 z_max> |
||
SendChatMessage | <u8 10><u8 ch><...> |
Zero-terminated | |
GetPlayers | <u8 11> |
GetPlayersResp | Get a list of players and player data |
Exit | <u8 255> |
These responses are sent by a RSC server to a RSC client in response to a request.
Response type | Packet format | Additional details |
---|---|---|
GetBlockResp | <u8 0><i32 x><i32 y><i32 z><u32 block_id> |
|
ObserveBlockResp | <u8 1><i32 x><i32 y><i32 z><u32 block_id> |
block_id is new block |
GetBlockRangeResp | <u8 2><i32 x_min><i32 y_min><i32 z_min><i32 x_max><i32 y_max><i32 z_max><u32 block_id><...> |
multiple block ids are in xyz-order |
ChatMessageResp | <u8 3><u8 ch><...> |
zero-terminated |
GetPlayersResp | <u8 4><u128 uuid><f64 x><f64 y><f64 z><f32 yaw><f32 pitch><u8 flying><u8 sprinting><u8 crouching><u8 on_ground><i32 pos1_x><i32 pos1_y><i32 pos1_z><i32 pos2_x><i32 pos2_y><i32 pos2_z><u8 username><...> |
Username is zero-terminated string |
A Lua client library for using RSC is available in the rsc_lib.lua
file.
It exports a single function, make_rsc_client(con)
, which takes a single
TCP connection argument and return a client handle.
Available client functions:
Function | Description |
---|---|
client.send_request.*(...) |
Send the specified request. Supported requests see above. |
client.receive_response() |
Return the next message from the server. First returned value is response type. Remaining return values are response arguments, see above. |
| client.wait_for_response(...)
| Wait for a specific server response specified in the arguments, ignoring and consuming all other responses. You can use "any"
to match any value for a specified argument. |
Using the client library a script runner is provided which makes writing RSC scripts even easier.
The rsc_run.lua <address> <port> <script> <args> <...>
script
will connect to the specified RSC server, and start to run the script
file.
If no script
is provided, an interactive shell is provided for the user to type commands.
Available functions in the script:
Function | Description |
---|---|
client.set_block(id, x,y,z) |
Set block at position |
id = client.get_block(x,y,z) |
Read block from position |
id = client.observe_block(x,y,z) |
Wait for block change on position |
client.update_block(x,y,z) |
Update (surrounding) blocks(typically after set) |
client.freeze() |
Disable redstone ticking |
client.unfreeze() |
Enable redstone ticking |
client.step(n) |
Run n redstone ticks |
Some example scripts are provided in the scripts/
directory. You can run them as:
# WARNING: This might set blocks in your plot! Make backups!
# play back a video file using ffmpeg
ffmpeg -re -i ~/video_file.webm -c:v rawvideo -r 10 -s 80x60 -f rawvideo -pix_fmt gray - | ./rsc_run.lua 127.0.0.1 25566 script/rawvideo.lua
# provided unlimited 0-tick read/writeable memory of any address and data size, read initial data from test.bin:
./rsc_run.lua 127.0.0.1 25566 script/memory.lua test.bin
# measure get_block latency(for testing)
./rsc_run.lua 127.0.0.1 25566 script/latency.lua
# example script(demonstrates every command)
./rsc_run.lua 127.0.0.1 25566 script/latency.lua
A CGI script has been implemented using the Lua client library.
Using this CGI script the entire API can be accessed using HTTP as well.
By default the CGI script will try to connect to 127.0.0.1:25566 for it's RSC connection.
If you want to change that, edit the address and port in the rsc_api.lua
script.
To run a simple test server, enter the www/
directory and run the busybox httpd server:
busybox httpd -v -f -p 8080
You can now send API requests to http://[your ip or localhost]:8080/cgi-bin/rsc_api.lua
, e.g.:
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=set_block&x=0&y=0&z=0&block_id=0"
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=get_block&x=0&y=0&z=0"
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=observe_block&x=0&y=0&z=0"
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=update_block&x=0&y=0&z=0"
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=freeze"
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=unfreeze"
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=step&n=1"
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=get_block_range&x_min=0&y_min=0&z_min=0&x_max=0&y_max=0&z_max=0"
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=set_block_range&x_min=0&y_min=0&z_min=0&x_max=2&y_max=2&z_max=2&blocks=0,0,0,0,0,0,0,0"
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=update_block_range&x_min=0&y_min=0&z_min=0&x_max=0&y_max=0&z_max=0"
curl "http://127.0.0.1:8080/cgi-bin/rsc_api.lua?command=send_chat_message&msg=hello+world"
A Minecraft 1.20.4 creative server built for redstone. Each 512x512 plot runs on a separate thread, allowing for less lag, more concurrency, and many awesome extra features!
MCHPRS is very different from traditional servers. Because this server is tailored to the use of computation redstone, many things that are a part of Vanilla Minecraft servers don't exist here. That being said, MCHPRS comes with many of its own unique features.
MCHPRS has made it possible to run programs such as a limited form of Minecraft on CPUs in Minecraft. To accomplish these speeds, we created Redpiler, the "Redstone Compiler".
If the Rust compiler is not already installed, you can find out how on their official website.
git clone https://github.com/MCHPR/MCHPRS.git
cd MCHPRS
cargo build --release
Once complete, the optimized executable will be located at ./target/release/mchprs
or ./target/release/mchprs.exe
depending on your operating system.
MCHPRS will generate a Config.toml
file in the current working directory when starting the server if it does not exist.
The following options are available at the toplevel (under no header):
Field | Description | Default |
---|---|---|
bind_address |
Bind address and port | 0.0.0.0:25565 |
motd |
Message of the day | "Minecraft High Performance Redstone Server" |
chat_format |
How to format chat message interpolating username and message with curly braces |
<{username}> {message} |
max_players |
Maximum number of simultaneous players | 99999 |
view_distance |
Maximal distance (in chunks) between players and loaded chunks | 8 |
whitelist |
Whether or not the whitelist (in whitelist.json ) should be enabled |
false |
schemati |
Mimic the verification and directory layout used by the Open Redstone Engineers Schemati plugin | false |
block_in_hitbox |
Allow placing blocks inside of players (hitbox logic is simplified) | true |
auto_redpiler |
Use redpiler automatically | false |
To change the plot size edit the constants defined in plot/mod.rs.
MCHPRS has no support for player authentication on its own, but supports Velocity modern ip-forwarding.
To use Velocity ip-forwarding, you must have a Velocity proxy set up and configured. Make sure player-info-forwarding-mode
is set to modern
in your Velocity config. Then, append this to your Config.toml
:
[velocity]
enabled = true
# This is the secret contained within `forwarding-secret-file` from your velocity config,
# NOT the path to the file.
secret = "<secret>"
MCHPRS has basic support for LuckPerms with MySQL or MariaDB remote database storage. This implementation has no commands or interface and would have to be manged through LuckPerms running on a proxy (/lpb
) or other server (/lp
)
To use LuckPerms, append this to your Config.toml
:
[luckperms]
# Define the address for the database.
host = "localhost"
# The name of the database the LuckPerms data is in.
db_name = "minecraft"
# Credentials for the database.
username = "minecraft"
password = "minecraft"
# The name of the server, used for server specific permissions.
# See: https://luckperms.net/wiki/Context
server_context = "global"
Command | Alias | Description |
---|---|---|
/rtps [rtps|unlimited] |
None | Set the redstone ticks per second in the plot to [rtps] . (There are two game ticks in a redstone tick) |
/radvance [ticks] |
/radv |
Advances the plot by [ticks] redstone ticks. |
/teleport [player] |
/tp |
Teleports you to [player] . |
/teleport [x] [y] [z] |
/tp |
Teleports you to [x] [y] [z] . Supports relative coordinates. Floats can be expressed as described here. |
/speed [speed] |
None | Sets your flyspeed. |
/gamemode [mode] |
/gmc , /gmsp |
Sets your gamemode. |
/container [type] [power] |
None | Gives you a container (e.g. barrel) which outputs a specified amount of power when used with a comparator. |
/toggleautorp |
None | Toggles automatic redpiler compilation. |
/stop |
None | Stops the server. |
The plot ownership system in MCHPRS is very incomplete. These are the commands that are currently implemented:
Command | Alias | Description |
---|---|---|
/plot info |
/p i |
Gets the owner of the plot you are in. |
/plot claim |
/p c |
Claims the plot you are in if it is not already claimed. |
/plot auto |
/p a |
Automatically finds an unclaimed plot and claims. |
/plot middle |
None | Teleports you to the center of the plot you are in. |
/plot visit [player] |
/p v |
Teleports you to a player's plot. |
/plot tp [x] [z] |
None | Teleports you to the plot at [x] [y] . Supports relative coordinates. |
/plot lock |
None | Locks the player into the plot so moving outside of the plot bounds does not transfer you to other plots. |
/plot unlock |
None | Reverses the locking done by /plot lock . |
/plot select |
/p sel |
Uses WorldEdit to select the entire plot. |
MCHPRS provides its own implementation of WorldEdit. Visit their documentation for more information. These are the commands that are currently implemented:
Command | Alias | Description |
---|---|---|
/up |
/u |
Go upwards some distance |
/ascend |
/asc |
Go up a floor |
/descend |
/desc |
Go down a floor |
//pos1 |
//1 |
Set position 1 |
//pos2 |
//2 |
Set position 2 |
//hpos1 |
//h1 |
Set position 1 to targeted block |
//hpos2 |
//h2 |
Set position 2 to targeted block |
//sel |
None | Clears your worldedit first and second positions. |
//set |
None | Sets all the blocks in the region |
//replace |
None | Replace all blocks in a selection with another |
//copy |
//c |
Copy the selection to the clipboard |
//cut |
//x |
Cut the selection to the clipboard |
//paste |
//v |
Paste the clipboard's contents (-a to ignore air, -u to also update) |
//undo |
None | Undoes the last action (from history) |
//redo |
None | Redoes the last action (from history) |
//rstack |
//rs |
Stack with more options, Refer to RedstoneTools |
//stack |
//s |
Repeat the contents of the selection |
//move |
None | Move the contents of the selection |
//count |
None | Counts the number of blocks matching a mask |
//load |
None | Loads a schematic from the ./schems/ folder. Make sure the schematic in the Sponge format if there are any issues. |
//save |
None | Save a schematic to the ./schems/ folder. |
//expand |
//e |
Expand the selection area |
//contract |
None | Contract the selection area |
//shift |
None | Shift the selection area |
//flip |
//f |
Flip the contents of the clipboard across the origin |
//rotate |
//r |
Rotate the contents of the clipboard |
//update |
None | Updates all blocks in the selection (-p to update the entire plot) |
//help |
None | Displays help for WorldEdit commands |
MCHPRS provides Redpiler, the redstone compiler. This allows redstone simulation much faster than otherwise possible. While redpiler is running, all redstone connections are pre-computed, thus interaction with the world is limited in this state. Placing or breaking blocks while redpiler is running will cause a reset and disable redpiler.
Command | Alias | Description |
---|---|---|
/redpiler compile |
/rp c |
Manually starts redpiler compilation. There are several flags available, described below. |
/redpiler reset |
/rp r |
Stops redpiler. |
Flag | Short | Description |
---|---|---|
--optimize |
-o |
Enable redpiler optimizations. WARNING: This can, and will, break the state of your build. Use backups when using this flag. |
--io-only |
-i |
Only send blocks updates of relevant input/output blocks. This includes trapdoors, lamps, note blocks, buttons, levers, and pressure plates. Using this flag can significantly reduce lag and improve simulation speed. |
--wire-dot-out |
-d |
Consider wires in the dot shape as an output block for -i . Useful for e.g. color displays. |
--update |
-u |
Update all blocks after redpiler resets. |
--export |
-e |
Export the compile graph using a binary format. This can be useful for developing out-of-tree uses of redpiler graphs. |
--export-dot |
None | Create a graphvis dot file of backend graph. Used for debugging/development. |
- @AL1L for his contributions to worldedit and other various features.
- @DavidGarland for a faster and overall better implementation of
get_entry
in the in-memory storage. This simple function runs 30% of the runtime for redstone.
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.