Named Pipe Demo
Back
The Goal
This is still an experimental feature.
It is for version 1.01.30.
A named pipe allows the Fractal Block World program to communicate to
other programs on your computer.
Once you give Fractal Block World permission, it can create
a named pipe on your computer
(which it can read from and write to).
Then, other programs on your computer can read from or write to
that same named pipe.
It is up to you to run those other programs:
Fractal Block World will never launch a program on your computer.
Why would you ever want to do such a thing?
You could make an experimental mod which allows players to see
the position of their friends also playing the game.
It could show an icon on the HUD showing the direction
and distance to their friends.
This could be implemented by the Fractal Block World program
communicating to a 3rd party program X on the user's computer
(via a named pipe).
That 3rd party program could then communicate to some kind of
server program Y on another computer.
Disclaimer
Use this feature at your own risk.
The concern is you should never download untrusted
programs onto your computer and run them.
Fractal Block World is not liable for anything detrimental
that happens by you downloading software
from the internet (or any other source) and running it.
Note that Fractal Block World is also not liable
for anything bad that happens as a result of using the
Fractal Block World game.
This feature is not really intended for the general public.
It is more intended for modders making experimental mods.
It would make sense to have a policy that 3rd party programs
that communicate with Fractal Block World on a user's machine
have to be written in a language like Python.
That way the community can see exactly what the code is doing.
Allow the Xar Package to Create Named Pipes
If you play the xar package, then in order for it to create named pipes,
the user first needs to give permission for this.
Note that once permission is given to the xar package,
mods that are loaded along with the xar package also have this permission.
Go to
Options → Mods → Permissions
and select the xar package.
Then click the yes button to allow the xar package permission to create named pipes.
This Demo Mod and How it Works
Here is the mod that we will discuss.
Install this mod in the Input/Packages directory. This is a mod for the xar package.
Open Fractal Block World and make sure you have given the xar package
permission to create named pipes.
Then, go to
Options → Mods → Select Mods
and select the xar package and add this mod
(demo_named_pipe_mod) as a mod.
Now here is the interesting part.
Install the python programming language on your computer.
You will need to open the terminal of your computer and
install a certain python package by running the following command:
pip install pywin32
Read the file
Input/Packages/demo_named_pip_mod/Misc/pipe_client.py
and you can see that it is not doing anything suspicious.
Then open the terminal of your computer, cd
into the directory
Input/Packages/demo_named_pip_mod/Misc/,
and run the following command:
./pipe_client.py
Now the pipe client is running.
Every second, it should print a message to the terminal
saying that the client is running and waiting for a certain named
piped to be created.
While the pipe client is running, open up the Fractal Block World program.
Start a new game or load an existing game that uses the xar package.
Because you have selected the demo_named_pipe_mod mod
as a mod for the xar package,
as soon as you load the game,
it will create a certain named pipe.
If you now look at your computer's terminal, the python pipe client
will say that it "got a handle to a pipe".
Now in Fractal Block World, open the game's terminal and run the command
"chat carrot".
This will send the message "carrot" to the named pipe.
If you go back to your computer's terminal, the python pipe client
will show that it received the message "carrot".
As soon as the python pipe client received a message from the pipe,
it sends the message "potato" back.
Look at the Fractal Block World terminal to see that is got the message.
How the Mod Works
There is really only one interesting file in the mod
we are talking about, and it is the file
Game/Commands/game_cmd_chat.lua
Let us look at the file:
--File: Game/Commands/game_cmd_chat.lua
--This is called by the engine when the game is loaded.
--It has the effect of registering the "chat" command
--to the command system. Note that the command system
--is part of the xar package.
function p.__load_game()
local cmd_name = "chat"
game_command_system.add_command(cmd_name, p.handler)
game_command_system.add_help(cmd_name, p.get_help_str())
--
--Global variables that start with "temp"
--are not saved when we save the game.
ga_init_i("temp.chat_named_pipe_handle", -1)
local handle = ga_open_named_pipe("FBW_example_pipe")
ga_set_i("temp.chat_named_pipe_handle", handle)
end
function p.handler(str)
local handle = ga_get_i("temp.chat_named_pipe_handle")
ga_write(handle, str)
end
function p.__update_passive()
p.update_common()
end
function p.__update()
p.update_common()
end
function p.update_common()
local handle = ga_get_i("temp.chat_named_pipe_handle")
local msg = ga_read(handle)
if( msg ~= "" ) then
ga_console_print("Msg from named pipe: " .. msg)
end
end
function p.get_help_str()
return
"Usage: chat str\n\n"
.. "Sends the given string to a certain \"named pipe\". "
end
So the __load_game function is called when the package loads.
It registers a new command called "chat" with the xar package
command system.
That is, the file game_command_system is part of the xar package.
The __load_game function then does something non-trivial:
It opens a named pipe with the name "FBW_example_pipe".
The full operating system name for the named pipe is slightly
different (see the python pipe client).
There is an extra rule: the name of the pipe must start with
"FBW_".
The function ga_open_named_pipe returns an integer "handle"
to the named pipe that was created.
If it was not successful, it will return -1
and to the console will be printed a message saying that the xar
package does not have permissions to create named pipes.
Here we store the integer handle for the pipe
in the variable "temp.chat_named_pipe_handle".
Note that variables that start with "temp" are not saved
when we save the game.
Then, when the player opens the console and runs the command
"chat carrot", then the function game_cmd_chat.handler
will be called with the string argument "carrot".
This will result in the function ga_write being called,
given "carrot" as its string parameter.
This is it for the Fractal Block World part of the mod!
The Python Pipe Client
We have included the python pipe client
as the file demo_named_pipe_mod/Misc/pipe_client.py.
This is a python program
(so you need to have python installed on your computer to run it).
Here is the code of this python program:
#!python
#This was partially taken from the following link:
#https://stackoverflow.com/questions/48542644/python-and-windows-named-pipes
import time
import sys
import win32pipe, win32file, pywintypes
print("FBW Named pipe client demo")
while True:
try:
pipe_name = r'\\.\\pipe\\FBW_example_pipe'
handle = win32file.CreateFile(
pipe_name,
win32file.GENERIC_READ | win32file.GENERIC_WRITE,
0,
None,
win32file.OPEN_EXISTING,
0,
None
)
print("Got a handle to a pipe!!! Waiting for data from the pipe.")
while True:
buffer_size = 4096
(hr, byte_data) = win32file.ReadFile(handle, buffer_size)
print("Got data!")
str_data = byte_data.decode("utf-8")
print("Received data: " + str_data)
#
print("Writing the following message back to the pipe: potato")
return_msg = "potato"
return_bytes = return_msg.encode("utf-8")
win32file.WriteFile(handle, return_bytes)
except pywintypes.error as e:
if e.args[0] == 2:
print("No pipe, trying again in a sec")
time.sleep(1)
elif e.args[0] == 109:
print("Broken pipe")