Neos-Metaverse / NeosPublic

A public issue/wiki only repository for the NeosVR project
197 stars 9 forks source link

Headless client API #3693

Open glitchfur opened 2 years ago

glitchfur commented 2 years ago

Is your feature request related to a problem? Please describe.

Interacting with the headless client programmatically can be a difficult task. Currently, the only way of controlling the headless client is through its console. The only solution I've seen so far to work with this in software is to write a "wrapper" around the headless client which takes hold of its stdin and stdout pipes to issue commands and capture the output. It works okay, but it is not a 100% perfect solution due to the intricacies of passing data back and forth in this way. It also prevents the console from being used by the end user, because the software controlling the headless client has to stay attached to those pipes the entire time. If those connections break somehow, the headless client essentially becomes a drone with no pilot.

Additionally, parsing the output of commands can be a pain as it is formatted for human eyes. Splitting lines based on their tabulation or using regex are solutions to this problem, but again it is not 100% perfect. Special care needs to be taken for multi-line world names or descriptions, world names with XML tags that change the color, and occasional log messages being printed to the console arbitrarily which can throw everything off. This method is also very prone to breakage. Depending on how strict the parsing is done, the Neos team fixing a single typo in a string or adding another space to a line can be enough to break data parsing entirely without extensive testing for each and every release.

Finally, this solution does not scale well. Commands can only be issued one at a time, and waiting on the output of the previous command is required before the next one even initiates. In sessions with lots of users online, this can become a major problem, as I have experienced slower execution times of commands the more people pile into a session.

tl;dr: Relying on the console for programmatic control of a headless client is inefficient and can be unreliable.

Relevant issues

No response

Describe the solution you'd like

My suggestion is that an API is added to the headless client for easy control via software. This would eliminate the need for third-party "wrapper" based APIs and would make building software around Neos' headless client significantly easier and less error prone.

This could take several forms, but my implementation idea is a local REST API: When the headless client starts up, it would start a tiny web server on localhost using a specific port number. Issuing commands would be done by GETing URL endpoints (such as /status or /worlds). URL parameters would be used to provide arguments to these commands if required (ex. /invite?friend=GlitchFur). Responses would be returned in machine-friendly JSON format. When the headless client is stopped, the web server goes down with it.

I think it would be best for security purposes to have such an API off by default and only toggled on when an argument is passed to the headless client (such as --api) and/or by adding an option to the configuration file.

REST APIs are well understood and language agnostic and JSON libraries are basically standard, so any developer would be able to quickly start building applications to interact with the headless client in whatever language they're most comfortable with, without the need for downloading/installing any new software or libraries.

Describe alternatives you've considered

Alternative implementation ideas:

Additional context

No response

Frozenreflex commented 2 years ago

Since Neos is written in C#, you could reference the FrooxEngine dll or the headless executable in the csproj and make it do whatever you need to do through that

  <PropertyGroup>
    <NeosPath>$(MSBuildThisFileDirectory)NeosVR</NeosPath>
    <NeosPath Condition="Exists('C:\Program Files (x86)\Steam\steamapps\common\NeosVR\')">C:\Program Files (x86)\Steam\steamapps\common\NeosVR\</NeosPath>
    <NeosPath Condition="Exists('$(HOME)/.steam/steam/steamapps/common/NeosVR/')">$(HOME)/.steam/steam/steamapps/common/NeosVR/</NeosPath>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="FrooxEngine">
      <HintPath>$(NeosPath)Neos_Data/Managed/FrooxEngine.dll</HintPath>
    </Reference>
  </ItemGroup>
glitchfur commented 2 years ago

Thanks for that suggestion, but I'm suggesting a language-agnostic RPC type interface for controlling the headless client.

shadowpanther commented 2 years ago

There's an earlier issue #2035, though your explanation is better