Starting a local headless client - glitchfur/NeosVR-Headless-API GitHub Wiki
Make sure your shell is in the correct directory and that your virtual environment is active (source venv/bin/activate
if you haven't done it already), then import LocalHeadlessClient
.
from neosvr_headless_api import LocalHeadlessClient
You can create a new headless client by calling LocalHeadlessClient
with the path to your headless client, meaning the folder that Neos.exe
is in:
hc = LocalHeadlessClient(
"/home/glitch/.local/share/Steam/steamapps/common/NeosVR/"
)
hc.wait_for_ready()
Creating this object will immediately launch the headless client in the background. Adjust the path above to point to where your headless client is located. Neos will use the default configuration file relative to itself at Config/Config.json
if one is not specified. You can provide the path to a different configuration file using the config
keyword argument:
hc = LocalHeadlessClient("...", config="/path/to/config.json")
The .wait_for_ready()
method will block until the headless client has finished starting up. This ensures that we don't try to run any commands until the headless client is ready, otherwise they will throw an exception. In code, you should always call this function and wait for it to return immediately after starting the headless client to ensure you don't run any commands too early.
At this point the headless client is fully started and we can call some methods. Lets try .status()
.
In [1]: hc.status()
Out[1]:
{'name': "Glitch's World",
'session_id': 'S-1462cabf-9ac4-46b7-80b4-3921455093e1',
'current_users': 1,
'present_users': 0,
'max_users': 8,
'uptime': '00:00:18.9775300',
'access_level': 'Anyone',
'hidden_from_listing': False,
'mobile_friendly': False,
'description': 'This is where a cat knocks a bunch of stuff over.',
'tags': ["computer", "cat", "code", "coffee", "chaos"],
'users': ['GlitchHost']}
This will execute the status
command in the headless client. Almost all of the commands that you can execute in the headless client are available as methods, such as .worlds()
or .users()
. For commands that contain multiple words, the words are separated with underscores instead of being camel case. For example: The method for the command hideFromListing
is actually .hide_from_listing()
.
You'll also notice that this isn't traditional headless client output. This is actually a dict
, with each line of information being its own key. Numbers like max_users
are automatically converted to int
. NeosVR-Headless-API does the heavy lifting for you of parsing command output and turning it into the appropriate Python data types. It will also make a best effort at handling sessions with complex data such as multi-line world names and descriptions. This means developers can get straight to coding without having to deal with substrings, splits, and regex to work with the data.
Each command has a different return type, so check the documentation to see what methods are available.
If you'd like to know how to control headless clients remotely, head over to Starting a remote headless client.
These examples don't have any logical rhyme or reason, they just show how to use the library.
Silence all unsilenced users in a session, and vice versa
hc = LocalHeadlessClient(...)
hc.wait_for_ready()
for user in hc.users()[1:]: # The [1:] skips the headless user
if user["silenced"]:
hc.unsilence(user["name"])
else:
hc.silence(user["name"])
These examples assume the host user is friends with all users in the session.
Invite everyone in one session to a new session
old_world_users = hc.users()[1:]
hc.focus(1)
for user in old_world_users:
hc.invite(user["name"])
Send a message to all users in all sessions, wait, then shut down
from time import sleep
# Keep track of the world we're currently in
start_world = hc.status()["session_id"]
for index, world in enumerate(hc.worlds()):
hc.focus(index)
for user in hc.users()[1:]:
hc.message(
user["name"],
"Heads up! The headless is going down in 60 seconds."
)
# Switch back to where we were before
hc.focus(start_world)
sleep(60)
hc.shutdown()