[GH-ISSUE #272] Gamepad input blocked by Artemis client due to missing permission flag #190

Closed
opened 2026-10-15 12:58:01 +00:00 by bsakaguchi · 8 comments
Owner

Originally created by @zeedif on GitHub (Oct 15, 2025).
Original GitHub issue: https://github.com/games-on-whales/wolf/issues/272

I've encountered a compatibility issue when using the Artemis client (a popular Moonlight fork) with Wolf. Specifically, gamepad/joystick input from the client is completely blocked and does not work during a streaming session. Mouse and keyboard inputs work as expected.

Environment:

  • Host: Wolf (latest stable)
  • Client: Artemis (latest version, from the moonlight-noir branch) on Android.

Root Cause

Artemis is a fork of Moonlight primarily designed for Apollo (a Sunshine fork), which has implemented a detailed permission system.

When an Artemis client connects, it expects the server to send a <Permission> tag in the initial XML response from /serverinfo. This tag is a bitmask that tells the client what inputs are allowed (controller, mouse, keyboard, etc.).

Since Wolf implements the standard GameStream protocol, it does not send this <Permission> tag. As a result, Artemis defaults to a state where it doesn't have explicit permission for controller input and therefore blocks it.

Supporting Evidence from Artemis Source Code

The relevant code in Artemis that checks for this permission can be found in the moonlight-noir branch:

  1. The permission field in ComputerDetails.java, which defaults to -1 (indicating no permissions are set) and includes constants for different input types like input_controller.

  2. The parsing logic in NvHTTP.java which actively looks for the <Permission> tag in the server's XML response.

Supporting Evidence from Apollo (Server) Source Code

To further support this, we can look at the Apollo (Sunshine fork) source code, which confirms that sending the <Permission> tag is a deliberate part of its protocol.

  1. The serverinfo function in Apollo actively adds the <Permission> tag to its XML response. The permission value is retrieved from the authenticated client's stored data.

    • File Path: src/nvhttp.cpp
    • Link: https://github.com/ClassicOldSong/Apollo/blob/master/src/nvhttp.cpp
    • Relevant Snippet:
      // Inside serverinfo() function
      if constexpr (std::is_same_v<SunshineHTTPS, T>) {
        // ... (authentication logic)
        auto named_cert_p = get_verified_cert(request);
        // ...
        tree.put("root.Permission", std::to_string((uint32_t)named_cert_p->perm));
      } else {
        // ...
        tree.put("root.Permission", "0");
      }
      
  2. The permission bitmask itself is defined in Apollo's crypto.h file. This is where the flags for input_controller and the _all mask originate.

    • File Path: src/crypto.h
    • Link: https://github.com/ClassicOldSong/Apollo/blob/master/src/crypto.h
    • Relevant Snippet:
      enum class PERM: uint32_t {
          // ...
          _input           = _reserved << 8,   // Input permission group
          input_controller = _input << 0,      // Allow controller input
          input_touch      = _input << 1,      // Allow touch input
          input_pen        = _input << 2,      // Allow pen input
          input_mouse      = _input << 3,      // Allow mouse input
          input_kbd        = _input << 4,      // Allow keyboard input
          _all_inputs      = input_controller | input_touch | input_pen | input_mouse | input_kbd,
          // ...
          _all             = _all_inputs | _all_opeiations | _all_actions, // All current permissions
      };
      

This confirms that the absence of the <Permission> tag in Wolf's response is the reason for the incompatibility with Artemis clients. Adding this tag, as proposed, would align Wolf's behavior with the expectations of the Apollo/Artemis ecosystem for full input compatibility.

Proposed Solution

To resolve this and improve compatibility with Artemis/Apollo, Wolf could include the <Permission> tag in its /serverinfo response.

For a straightforward initial implementation, granting all permissions would be sufficient and would solve the issue completely for Artemis users. The bitmask for all permissions (_all) in the Artemis/Apollo protocol is 0x71F1F00.

Adding the following line to the XML response in wolf/src/moonlight-protocol/moonlight.cpp within the serverinfo function would likely fix the issue entirely:

<Permission>119468800</Permission>

(This is the decimal representation of 0x71F1F00).

This would be a great enhancement for users who prefer the Artemis client. Thank you for your amazing work on Wolf and for considering this

Originally created by @zeedif on GitHub (Oct 15, 2025). Original GitHub issue: https://github.com/games-on-whales/wolf/issues/272 I've encountered a compatibility issue when using the **Artemis** client (a popular Moonlight fork) with Wolf. Specifically, gamepad/joystick input from the client is completely blocked and does not work during a streaming session. Mouse and keyboard inputs work as expected. **Environment:** * **Host:** Wolf (latest stable) * **Client:** Artemis (latest version, from the `moonlight-noir` branch) on Android. ### Root Cause Artemis is a fork of Moonlight primarily designed for **Apollo** (a Sunshine fork), which has implemented a detailed permission system. When an Artemis client connects, it expects the server to send a `<Permission>` tag in the initial XML response from `/serverinfo`. This tag is a bitmask that tells the client what inputs are allowed (controller, mouse, keyboard, etc.). Since Wolf implements the standard GameStream protocol, it does not send this `<Permission>` tag. As a result, Artemis defaults to a state where it doesn't have explicit permission for controller input and therefore blocks it. ### Supporting Evidence from Artemis Source Code The relevant code in Artemis that checks for this permission can be found in the `moonlight-noir` branch: 1. The `permission` field in `ComputerDetails.java`, which defaults to `-1` (indicating no permissions are set) and includes constants for different input types like `input_controller`. * **File Path:** `app/src/main/java/com/limelight/nvstream/http/ComputerDetails.java` * **Link:** [https://github.com/ClassicOldSong/moonlight-android/blob/moonlight-noir/app/src/main/java/com/limelight/nvstream/http/ComputerDetails.java](https://github.com/ClassicOldSong/moonlight-android/blob/moonlight-noir/app/src/main/java/com/limelight/nvstream/http/ComputerDetails.java) * **Relevant Snippet:** ```java public class ComputerDetails { // ... public int permission = -1; // ... /* * Permissions: enum class PERM: uint32_t { // ... input_controller = _input << 0, // Allow controller input // ... }; */ } ``` 2. The parsing logic in `NvHTTP.java` which actively looks for the `<Permission>` tag in the server's XML response. * **File Path:** `app/src/main/java/com/limelight/nvstream/http/NvHTTP.java` * **Link:** [https://github.com/ClassicOldSong/moonlight-android/blob/moonlight-noir/app/src/main/java/com/limelight/nvstream/http/NvHTTP.java](https://github.com/ClassicOldSong/moonlight-android/blob/moonlight-noir/app/src/main/java/com/limelight/nvstream/http/NvHTTP.java) * **Relevant Snippet:** ```java String permStr = getXmlString(serverInfo, "Permission", false); if (permStr != null) { try { details.permission = Integer.parseInt(permStr); } catch (Exception ignored) { details.permission = -1; } } ``` ### **Supporting Evidence from Apollo (Server) Source Code** To further support this, we can look at the **Apollo** (Sunshine fork) source code, which confirms that sending the `<Permission>` tag is a deliberate part of its protocol. 1. The `serverinfo` function in Apollo actively adds the `<Permission>` tag to its XML response. The permission value is retrieved from the authenticated client's stored data. * **File Path:** `src/nvhttp.cpp` * **Link:** [https://github.com/ClassicOldSong/Apollo/blob/master/src/nvhttp.cpp](https://github.com/ClassicOldSong/Apollo/blob/master/src/nvhttp.cpp) * **Relevant Snippet:** ```cpp // Inside serverinfo() function if constexpr (std::is_same_v<SunshineHTTPS, T>) { // ... (authentication logic) auto named_cert_p = get_verified_cert(request); // ... tree.put("root.Permission", std::to_string((uint32_t)named_cert_p->perm)); } else { // ... tree.put("root.Permission", "0"); } ``` 2. The permission bitmask itself is defined in Apollo's `crypto.h` file. This is where the flags for `input_controller` and the `_all` mask originate. * **File Path:** `src/crypto.h` * **Link:** [https://github.com/ClassicOldSong/Apollo/blob/master/src/crypto.h](https://github.com/ClassicOldSong/Apollo/blob/master/src/crypto.h) * **Relevant Snippet:** ```cpp enum class PERM: uint32_t { // ... _input = _reserved << 8, // Input permission group input_controller = _input << 0, // Allow controller input input_touch = _input << 1, // Allow touch input input_pen = _input << 2, // Allow pen input input_mouse = _input << 3, // Allow mouse input input_kbd = _input << 4, // Allow keyboard input _all_inputs = input_controller | input_touch | input_pen | input_mouse | input_kbd, // ... _all = _all_inputs | _all_opeiations | _all_actions, // All current permissions }; ``` This confirms that the absence of the `<Permission>` tag in Wolf's response is the reason for the incompatibility with Artemis clients. Adding this tag, as proposed, would align Wolf's behavior with the expectations of the Apollo/Artemis ecosystem for full input compatibility. ### Proposed Solution To resolve this and improve compatibility with Artemis/Apollo, Wolf could include the `<Permission>` tag in its `/serverinfo` response. For a straightforward initial implementation, granting all permissions would be sufficient and would solve the issue completely for Artemis users. The bitmask for all permissions (`_all`) in the Artemis/Apollo protocol is `0x71F1F00`. Adding the following line to the XML response in `wolf/src/moonlight-protocol/moonlight.cpp` within the `serverinfo` function would likely fix the issue entirely: ```xml <Permission>119468800</Permission> ``` *(This is the decimal representation of `0x71F1F00`)*. This would be a great enhancement for users who prefer the Artemis client. Thank you for your amazing work on Wolf and for considering this
Author
Owner

@ABeltramo commented on GitHub (Oct 15, 2025):

Thanks for the very detailed issue, adding support for that extra Permission field seems straightforward enough.

It just makes you wonder though, why have they decided to introduce a non-breaking change and then just limit the Moonlight client when used with a server that's not Apollo? I would expect that Artemis would already default to allow all inputs for a server that doesn't implement their own variation of the protocol.. The same issue that you've opened for Wolf is also valid for Sunshine, right?

Have you tried opening an issue about this on Artemis? It feels that that's the best place to change this behaviour.

<!-- gh-comment-id:3407926735 --> @ABeltramo commented on GitHub (Oct 15, 2025): Thanks for the very detailed issue, adding support for that extra `Permission` field seems straightforward enough. It just makes you wonder though, why have they decided to introduce a non-breaking change and then just limit the Moonlight client when used with a server that's not Apollo? I would expect that Artemis would **already default to allow all inputs** for a server that doesn't implement their own variation of the protocol.. The same issue that you've opened for Wolf is also valid for Sunshine, right? Have you tried opening an issue about this on Artemis? It feels that that's the best place to change this behaviour.
Author
Owner
<!-- gh-comment-id:3407991105 --> @ClassicOldSong commented on GitHub (Oct 15, 2025): https://github.com/ClassicOldSong/moonlight-android/issues/438#issuecomment-3407990793
Author
Owner

@ClassicOldSong commented on GitHub (Oct 15, 2025):

These evidences don't contribute to the conclusion that Artemis uses these flags to block inputs. Actually Artemis only display these info, but not limiting the client side requests, since limiting them client side is pointless.

<!-- gh-comment-id:3407998784 --> @ClassicOldSong commented on GitHub (Oct 15, 2025): These evidences don't contribute to the conclusion that Artemis uses these flags to block inputs. Actually Artemis only display these info, but not limiting the client side requests, since limiting them client side is pointless.
Author
Owner

@ABeltramo commented on GitHub (Oct 15, 2025):

@ClassicOldSong thanks for looking into this, I haven't tried Artemis myself, so I was just basing my comment on the words of @zeedif. Are we all being played by an LLM hallucinating things? 😅

<!-- gh-comment-id:3408006016 --> @ABeltramo commented on GitHub (Oct 15, 2025): @ClassicOldSong thanks for looking into this, I haven't tried Artemis myself, so I was just basing my comment on the words of @zeedif. Are we all being played by an LLM hallucinating things? 😅
Author
Owner

@ClassicOldSong commented on GitHub (Oct 15, 2025):

I think we are...

<!-- gh-comment-id:3408007694 --> @ClassicOldSong commented on GitHub (Oct 15, 2025): I think we are...
Author
Owner

@ClassicOldSong commented on GitHub (Oct 15, 2025):

The most possible cause is Artemis and Apollo uses a modified moonlight-common-c for some customized packet types, but these should be ignored by incompatible hosts as the original protocol allows.

<!-- gh-comment-id:3408016805 --> @ClassicOldSong commented on GitHub (Oct 15, 2025): The most possible cause is Artemis and Apollo uses a modified moonlight-common-c for some customized packet types, but these should be ignored by incompatible hosts as the original protocol allows.
Author
Owner

@ClassicOldSong commented on GitHub (Oct 15, 2025):

But so far there're no reports about compatibility issues of Artemis with Sunshine, and there're user requests about adding specific features to Artemis and they're using it with a Linux host.

<!-- gh-comment-id:3408027586 --> @ClassicOldSong commented on GitHub (Oct 15, 2025): But so far there're no reports about compatibility issues of Artemis with Sunshine, and there're user requests about adding specific features to Artemis and they're using it with a Linux host.
Author
Owner

@ABeltramo commented on GitHub (Oct 15, 2025):

I see, the root cause is most likely something else then, thanks @ClassicOldSong !

I'm going to close this, @zeedif feel free to open up a new issue with the details of your Wolf installation, docker run command and full logs, and we can look into what's the issue with the gamepad that you are facing..

<!-- gh-comment-id:3408037293 --> @ABeltramo commented on GitHub (Oct 15, 2025): I see, the root cause is most likely something else then, thanks @ClassicOldSong ! I'm going to close this, @zeedif feel free to open up a new issue with the details of your Wolf installation, `docker run` command and full logs, and we can look into what's the issue with the gamepad that you are facing..
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
games-on-whales/wolf#190
No description provided.