Skip to content

Commit

Permalink
Merge pull request #45 from PiterWeb/main
Browse files Browse the repository at this point in the history
New release trying wails build action
  • Loading branch information
PiterWeb authored Nov 22, 2024
2 parents 91e69b9 + 178b0d8 commit c83849f
Show file tree
Hide file tree
Showing 47 changed files with 4,853 additions and 5,928 deletions.
44 changes: 44 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Wails build

on:
push:
tags:
# Match any new tag
- '*'

env:
# Necessary for most environments as build failure can occur due to OOM issues
NODE_OPTIONS: "--max-old-space-size=4096"

jobs:
build:
strategy:
# Failure in one platform build won't impact the others
fail-fast: false
matrix:
build:
- name: 'RemoteControllerLinux'
platform: 'linux/amd64'
os: 'ubuntu-latest'
- name: 'RemoteControllerWindows'
platform: 'windows/amd64'
os: 'windows-latest'
- name: 'RemoteControllerDarwin'
platform: 'darwin/universal'
os: 'macos-latest'

runs-on: ${{ matrix.build.os }}
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive

- name: Build wails
uses: dAppServer/[email protected]
id: build
with:
build-name: ${{ matrix.build.name }}
build-platform: ${{ matrix.build.platform }}
package: false
go-version: '1.22'
62 changes: 38 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@

## Resources 📚

- [FAQ](https://remote-controller.vercel.app/info/resources/faq/)
- [Security](https://remote-controller.vercel.app/info/resources/security/)
- [Docs](./docs/) 📘
- [FAQ](https://remote-controller.vercel.app/info/resources/faq/) 💬
- [Security](https://remote-controller.vercel.app/info/resources/security/) 🔐

- https://github.com/user-attachments/assets/f4a412fa-f403-4429-85fb-9c1e74bff458

Expand All @@ -49,19 +50,19 @@

| Windows | Linux | MacOS | Browser (Only Client) |
|--------- |------- |------- |--------- |
|| (Only keyboard)⌛ Looking for contributions for Gamepad | | ✔ (Known Issues with Safari) |
|| (Only keyboard)⌛ Looking for contributions for Gamepad | (In theory keyboard works)⌛ Looking for contributions for Gamepad | ✔ (Known Issues with Safari) |

### Gamepad Support 🎮
### Native Gamepad Support 🎮

| PC Controller (XInput/DirectInput) | Xbox Controller (XInput) | PlayStation Controler
|--------- |------- |------- |
||||
|||(You can achieve emulating a Xbox Controller) |

### Translations 🔠

| English | Spanish | Galician | Russian |Other languages |
|--------- |------- |------- | ------- | ------- |
| 100% ✔ | 100% ✔ | 100% ✔ | 29.5% |⌛ Looking for contributions
| English | Spanish | Galician | Russian | French |Other languages |
|--------- |------- |------- | ------- | ------- | ------- |
| 100% ✔ | 100% ✔ | 100% ✔ | 100% ✔ | 100% ✔ (@Zorkyx22) |⌛ Looking for contributions

## Self Hosting ☁

Expand All @@ -71,37 +72,50 @@ There is no way to self-host the infrastructure of RemoteController because it h

- Also you can host the Web version (but it is only frontend) to make like a network of Remote Controller web clients

## Build
## Run Dev

### Prerequisites

You must have Wails CLI, NodeJS, npm and Golang installed.
You must have Task CLI, Wails CLI, NodeJS, pnpm and Golang installed.

### How to

First go to the frontend folder and run
Go to the root project folder and run

`$ pnpm install`<br>
`$ pnpm run build`
- Full App :

Now run the following command on the root directory of the main project:
`$ task dev-all`

`$ wails build`
- Frontend:

finally go to the build/bin folder and your executable will be there.
`$ task dev-front`

> [!Note]
> Please note the supported platforms in the table
## Build

### Prerequisites

You must have Task CLI, Wails CLI, NodeJS, pnpm and Golang installed.

### How to

Go to the root project folder and run

- For general builds:

`$ task build`

## How it works 👷‍♂️
- For Windows builds:

This desktop APP is based on the WebRTC 🎞 standard and it uses the power of Go to communicate 🗣 with the Gamepad emulation libraries.
In Windows uses the ViGEm Bus Driver with the ViGEm Client DLL
`$ task build-win`

For the low level actions uses Go.
On the other hand the UI works with Web technologies (WASM, Sveltekit, Tailwind, DaisyUI & Typescript)
- For Linux builds:

You can learn more about [how it works](./docs/README.md) under the hood all the project
`$ task build-linux`

finally go to the build/bin folder and your executables will be there.

> [!Note]
> Please note the supported platforms in the table
## Contributting 🤝

Expand Down
5 changes: 3 additions & 2 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ tasks:
- pnpm run dev
desc: Run the frontend in development mode
test:
desc: Run E2E tests
dir: frontend
deps: [dev-all]
cmds:
- pnpm run test
desc: Run the frontend tests
- pnpm run test
80 changes: 78 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Docs 📘

## Frontend (UI Logic)
## Frontend (Browser)

Source code location : [/frontend/](../frontend)

WebRTC code: [/frontend/src/lib/webrtc/](../frontend/src/lib/webrtc)

### [Frontend Docs](./FRONTEND.md)

Expand All @@ -15,6 +19,10 @@

## Backend (Dekstop APP Logic)

Source code location: [/main.go](../main.go) + [/src/](../src)

WebRTC code: [/src/net/](../src/net) + [/src/streaming_signal/](../src/streaming_signal/)

### [Backend Docs](./BACKEND.md)

### Stack:
Expand All @@ -32,4 +40,72 @@ WebRTC is totally supported by all main desktop/mobile browsers and is also avai

The purpose of WebRTC is to make a P2P connection between Host and Client devices to send Gamepad Input using data channels and also captured Video/Audio with media channels.

DisplayMedia is for capturing video/audio from desktop/aplications and them stream it through WebRTC media channel.
DisplayMedia is for capturing video/audio from desktop/aplications and them stream it through WebRTC media channel.

### Wails

This project is using Wails so it might be important to know how wails works.

Wails is like Electron but for Go, and instead of embed a Chromium Browser you will use the existent browser of you OS (webview2, gtkwebview, ...).

You will have two parts:
- "Browser":
This is what runs HTML, CSS, JS, TS, WASM (provides the UI)
- "Desktop APP":
This is what runs Go code

#### Bindings

Wails can generate bindings in JS for Go generated functions. <br>

In the project all bindings are located in [/src/desktop/](../src/desktop/)

Real example:

This function located in [/src/desktop/app.go](../src/desktop/app.go)

```go
func (a *App) GetCurrentOS() string {
return strings.ToUpper(runtime.GOOS)
}
```
will appear as

```js
export function GetCurrentOS() {
return window['go']['desktop']['App']['GetCurrentOS']();
}
```

in the path [/frontend/src/lib/wailsjs/go/desktop/App.js](../frontend/src/lib/wailsjs/go/desktop/App.js)

#### Events

Wails have listeners and event dispatchers to send data between JS <-> GO in a bidirectional flow (this are contained in the wails runtime pkg)

## Roles

First make sure to read the Wails section above.

We are going to start with ¿ How the two roles communicate ?.

To not enter in WebRTC matery we are going to say that each peer needs to need some information from the other after the connection begins so we need to pass that information.<br><br>
To do that we share codes, this codes are simply the data needed by WebRTC but encoded and compressed to be the most portable it can, to not require the use of a signaling server. This way you will not have to self-host any serice.

Note: all the "codes" encoding & compression is done in Go or Wasm (generated from the Go code).

### Client

Client code is only located on the "Browser" (JS/TS).

The logic is very simple. The client creates a WebRTC connection with the host and through the Gamepad API of the "Browser" gets the gamepad data, later we copy the structure and send using a WebRTC Datachannel.
If there is an available Screen + Audio stream we can connect to it creating a new WebRTC connection and using the previous as signaling server. The render of the stream is all done using Web APIs.

### Host

Host is the most complex role cause part of the logic of webrtc code is on the "Browser" and other in "Desktop APP".

This division of logic is because we need:
- Go: A WebRTC connection that goes directly to the ViGEm driver (which is loaded as a DLL in Go) to insert the gamepad data or a similar situation with keyboard.

- JS/TS: We need to send the Screen + Audio stream to the client. To do that we need the WebRTC stream in the "Browser", one way of achieve this could have been doing a rtp stream proxy and use the Go WebRTC connection but that would have add latency and use of more resources. Because of that it is created a new WebRTC connection only for the stream on the "Browser", this connection is auto created and uses as signaling service the normal WebRTC connection used for Gamepad data.
9 changes: 9 additions & 0 deletions frontend/cypress/e2e/config/basic_conn.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
describe("Basic connection", () => {

it("load", () => {
cy.visit('http://localhost:34115/');
cy.wait(1000)
cy.log("hello")
})

})
5 changes: 0 additions & 5 deletions frontend/cypress/e2e/config/languages.cy.ts

This file was deleted.

35 changes: 35 additions & 0 deletions frontend/cypress/e2e/config/tutorial.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
describe('Tutorial flow', () => {
it('Load main page ', () => {
cy.visit('http://localhost:34115/');
});

it('tutorial', () => {

cy.visit('http://localhost:34115/');
cy.get('button.btn').click();
cy.get('button.driver-popover-next-btn').click();
cy.location('pathname').should('equal', '/mode/config');
cy.wait(1000);
cy.get('.grid > :nth-child(5) > .btn').click();
cy.get(':nth-child(3) > .btn').click();
cy.get(':nth-child(4) > .btn').click();
cy.get('.grid > :nth-child(1) > .btn').click();
cy.get('.grid > :nth-child(2) > .btn').click();
cy.get('button.driver-popover-next-btn').click();
cy.wait(1000);
cy.get('button.driver-popover-next-btn').click();
cy.location('pathname').should('equal', '/mode/config/advanced/stun');
cy.wait(1000);
cy.get('button.driver-popover-next-btn').click();
cy.wait(1000);
cy.get('button.driver-popover-next-btn').click();
cy.wait(1000);
cy.location('pathname').should('equal', '/mode/config');
cy.get('button.driver-popover-next-btn').click();
cy.wait(1000);
cy.get('button.driver-popover-next-btn').click();
cy.wait(1000);
cy.get('button.driver-popover-next-btn').click();
cy.location('pathname').should('equal', '/');
});
});
12 changes: 6 additions & 6 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c83849f

Please sign in to comment.