Commit graph

66 commits

Author SHA1 Message Date
sergystepanov
059e19d790 Remove com.Uid from the API 2025-12-24 21:23:19 +03:00
sergystepanov
94e13cb93b Clean api 2025-12-22 15:37:04 +03:00
sergystepanov
c800dd4bf9 Fix with go fix 2025-12-22 15:08:50 +03:00
sergystepanov
d45daeab7a Tweak room join/creation logic 2025-12-15 18:42:41 +03:00
sergystepanov
9191861cab Use iterators in the custom map implementation 2025-11-22 22:09:38 +03:00
sergystepanov
ddfc9249ec Fix some user slot race conditions
In cases where HasSlot() and Reserve() operations are delayed, multiple users may incorrectly be granted a slot due to race conditions.
2025-05-02 10:06:23 +03:00
Sergey Stepanov
954bb23bb8
Add Reset with 0 key 2024-12-03 00:38:15 +03:00
Sergey Stepanov
b2e275a6cd
Don't crash the app on http2 garbage 2024-11-28 23:24:35 +03:00
Sergey Stepanov
8686c4a6e5
Return workers by wids right away ;_; 2024-11-17 22:13:39 +03:00
Sergey Stepanov
2c50ae2290
Allow one game per a direct worker 2024-11-17 20:29:45 +03:00
Sergey Stepanov
f09500f289
Check slots for direct workers 2024-11-17 19:55:14 +03:00
Sergey Stepanov
1147aeda14 Track all worker saves to resume old games
Move library config to the top level
2024-11-17 12:59:43 +03:00
Sergey Stepanov
7b57f73b26 Send worker lib 2024-11-17 12:59:43 +03:00
Sergey Stepanov
45cc9e8245 Move library config to the top level 2024-11-17 12:59:43 +03:00
Sergey Stepanov
bdf3598367 Add game aliases
Allows different game names to be set in the alias.txt file [as name=alias] located in the games directory.
2024-08-31 22:29:31 +03:00
Sergey Stepanov
7ee98c1b03 Add keyboard and mouse support
Keyboard and mouse controls will now work if you use the kbMouseSupport parameter in the config for Libretro cores. Be aware that capturing mouse and keyboard controls properly is only possible in fullscreen mode.

Note: In the case of DOSBox, a virtual filesystem handler is not yet implemented, thus each game state will be shared between all rooms (DOS game instances) of CloudRetro.
2024-08-02 11:04:44 +03:00
Sergey Stepanov
99976dd560
Add frame-options option 2024-05-13 19:29:13 +03:00
Sergey Stepanov
2aaf37b766 Add Cache-Control for serving static files
Static files will be rechecked every 3 days instead of unlimited cache time. The Cache-Control header is mandatory in order to make browsers handle cache properly with Go's FileServer. The option can be modified in the server.CacheControl line of the config file.
2024-03-17 22:09:43 +03:00
Sergey Stepanov
91ace06f8b
Replace the hasMultitap option with a more general solution
The new hid option enables users to map a specific Libretro device (or multiple devices) to the input ports. For instance, this allows users to map a Multitap controller with the snes9x core.
2024-03-05 21:34:37 +03:00
Sergey Stepanov
4fbfa1d4e3
Fix possible NPEs 2023-11-26 22:39:46 +03:00
Sergey Stepanov
2e91feb861 Add initial automatic aspect ratio change
Depending on the configuration param coreAspectRatio, video streams may have automatic aspect ratio correction in the browser with the value provided by the cores themselves.
2023-11-03 01:12:22 +03:00
Sergey Stepanov
cb968d782a
Show rooms in the list 2023-10-21 02:37:44 +03:00
Sergey Stepanov
fb5d8c216b
Don't change players when there is no game 2023-10-18 21:46:33 +03:00
Sergey Stepanov
cddf081b8f
Use locks in router with rooms 2023-10-06 01:12:27 +03:00
Sergey Stepanov
196930281b Add the initial caged apps abstraction
In the current version of the application, we have strictly hardcoded the captured runtime application (FFI Libretro frontend) as well as the streaming transport (WebRTC). This commit makes it possible to choose these components at runtime.

In this commit, we no longer manage initially connected users separately from the rooms, and instead, we treat all users as abstract app sessions, rather than hardcoded WebRTC connections. These sessions may contain all the transport specifics, such as WebRTC and so on.

Rooms, instead of having the hardcoded emulator app and WebRTC media encoders, now have these components decoupled. In theory, it is possible to add new transports (e.g., WebTransport) and streaming apps (e.g., wrapped into an ffmpeg desktop app).
2023-09-16 20:12:24 +03:00
Sergey Stepanov
49cb752b5c
Use implicit cast of app/game structs
That will make the code a bit tidier.
2023-08-01 22:27:21 +03:00
Sergey Stepanov
7fe3a893f6
Remove service package 2023-08-01 22:27:08 +03:00
Sergey Stepanov
d7e8ca5ace
Remove SSL from the monitoring routes 2023-07-07 15:28:50 +03:00
Sergey Stepanov
8fef57aa8d
Use TLS with the monitoring / profiling routes 2023-07-06 00:04:05 +03:00
Sergey Stepanov
2e1c837643 Show systems in the interface 2023-06-16 14:12:41 +03:00
Sergey Stepanov
860c8b9d45 Add system param into the library 2023-06-16 14:12:41 +03:00
Sergey Stepanov
5b4f74e2b7
Notify users when there are no gaming slots 2023-05-21 13:54:21 +03:00
Sergey Stepanov
3815e18027
Remove the hack involving the /static route 2023-05-03 11:11:08 +03:00
Sergey Stepanov
8893e1e5bf Update config manager 2023-04-22 17:05:28 +03:00
sergystepanov
3bb54fdad4
Clean API (#391)
Remove hard coupling between api (all the API data structures) and com (app clients communication protocol and logic).
2023-03-18 20:24:06 +03:00
Sergey Stepanov
cd056ee976
Bump to v3 2023-03-16 23:46:53 +03:00
Sergey Stepanov
04d9817b94
Set worker UID properly 2023-02-14 23:16:15 +03:00
Sergey Stepanov
207d514e8a
Move balancer into hub 2023-02-11 02:16:48 +03:00
sergystepanov
2b81c3fb87
Some optimizations (#387)
- Fixed broken image cache for the first stage RGBA frames. It was not a thread-safe one, which led to image tearing (parts of old images in multiple consecutive frames).
- 180 flip function for the OpenGL coordinate system has been moved into the rotation part.
- Optimized YUV converter.
- Optimized color converters:
  - Use __restrict pointers.
  - Draw image pixels with the faster bitwise operators and pointer arithmetic as 32/16bit LE numbers (may break on ARM devices like RPi). 
  - Pass uints for less num conversions.
  - Much faster XRGB -> RGBA conversion with Go's stdlib 32bit flip.
- Wrapped RGBA images into a custom struct in order to bypass opacity tests for the standard Go png functions, which needed for the PNG file export. Before that we set RGBx opacity byte explicitly during the pixel format conversions (much slower).
- Made Libretro core shutdown more deterministic. When we run a C core separately from the main Go process we have to make sure that the C core is not doing anything in its syscall while we stopping the emulator. Basically, a blocking call may be suspended on the Go's side while the other goroutines have no knowledge of that.
- Less info level logs.
- Added recording user label.
- Enabled RTCP sender reports by default, which may help with A/V sync.
- Check onMessage webrtc handler if it's set. May crash the program if not.
- Fixed some make dirs permissions.
- Enabled console colors (since MS has finally fixed their bloody Terminal).
- Disable log in some tests.
- Updated deps.
2023-01-31 22:22:03 +03:00
sergystepanov
3bd959b4ef
Refactored v3 (#350)
This PR contains refactored code.

**Changelog**
- Added new net code (the communication architecture was left intact).
- All network client IDs now have custom type `network.Uid` backed by github.com/rs/xid lib.
  ```
  The string representation of a UUID takes 32 bytes, and the new type will take just 16.
  Because of Golang JSON serialization problems with omitting zero-length empty slices (it can't) 
  and the need to use UID values as map keys (maps don't support slices as keys), 
  IDs are stored as strings (for now).
  ```
- A whole new WebSocket client/server implementation was added, as well as a new communication layer with synchronous and async call handlers.
  - WebSocket connections now support dedicated Ping/Pong frames as opposed to original ping text messages.
  - Used Gorilla WebSocket library doesn't allow concurrent (simultaneous) reads and writes, so this part was handled via send channel synchronization.
- New API structures can be found in the `pkg/api` folder.
- New communication protocol can be found in the `pkg/com/*` folder.
- Updated communication protocol is based on JSON-encoded messaging through WebSocket and has the following structure:
  ```
  Packet
    [id] string — a globally unique identification tag for the packet to track it trough a chain of requests.
    t uint8 — contains packet type information (i.e. INIT_PACKET, SDP_OFFER_PACKET, ...).
    [p] any — contains packet data (any type).

  Each packet is a text message in JSON-serialized form (WebSocket control frames obviously not).
  ```
  ```
  The main principle of this protocol and the duplex data exchange is:
  the one who initializes connection is called a client, and 
  the one who is being connected to is called a server. 
  With the current architecture, the coordinator is the server, the user browsers and workers are the clients.

            ____           ____
           ↓    ↑         ↑    ↓
     browser ⟶ coordinator ⟵ worker
       (c)          (s)         (c)

  One of the most crucial performance vise parts of these interactions is that 
  all the server-initiated calls to clients should be asynchronous!
  ```
  - In order to track synchronous calls (packets) with an asynchronous protocol, such as WebSocket, each packet may have an `id` that should be copied in all subsequent requests/responses.
  - The old `sessionID` param was replaced by `id` that should be stored inside the `p` (payload) part of the packet.
- It is possible to skip the default ping check for all connected workers on every user connection and just pick the first available with the new roundRobin param in the coordinator config file `coordinator.roundRobin: true/false`.
- Added a dedicated package for the system API (pkg/api/*).
- Added structured logging system (zerolog) for better logging and cloud services integration.
- Added a visual representation of the network message exchange in logs:
  ```
  ...
  01:00:01.1078 3f98 INF w → c Handshake ws://localhost:8000/wso
  01:00:01.1138  994 INF c ← w Handshake localhost:8000
  01:00:01.1148  994 INF c ← w Connect cid=cep.hrg
  01:00:01.1158  994 DBG c     connection id has been changed to cepl7obdrc3jv66kp2ug cid=cep.hrg
  01:00:01.1158 3f98 INF w → c Connect cid=cep.2ug
  01:00:01.1158  994 INF c     New worker / addr: localhost, ...
  01:00:01.1158 3f98 INF w     Connected to the coordinator localhost:8000 cid=cep.2ug
  01:00:02.5834  994 INF c ← u Handshake localhost:8000
  01:00:02.6175  994 INF c ← u Connect cid=cep.hs0
  01:00:02.6209  994 INF c     Search available workers cid=cep.hs0
  01:00:02.6214  994 INF c     Found next free worker cid=cep.hs0
  01:00:02.6220  994 INF c → u InitSession cid=cep.hs0
  01:00:02.6527  994 INF c ← u WebrtcInit cid=cep.hs0
  01:00:02.6527  994 INF c → w ᵇWebrtcInit cid=cep.hrg
  01:00:02.6537 3f98 INF w ← c WebrtcInit cid=cep.2ug
  01:00:02.6537 3f98 INF w     WebRTC start cid=cep.2ug
  ...
  ```
- Replaced a monstrous Prometheus metrics lib.
- Removed spflag dependency.
- Added new `version` config file param/constant for compatibility reasons.
- Bump the minimum required version for Go to 1.18 due to use of generics.
- Opus encoder now is cached and the default config is 96Kbps, complexity 5 (was 196Kbps, 8).
- Changed the default x264 quality parameters to `crf 23 / superfast / baseline` instead of `crf 17 / veryfast / main`.
- Added a separate WebRTC logging config param `webrtc.logLevel`.
- Worker now allocates much less memory.
- Optimized and fixed RGB to YUV converter.
- `--v=5` logging cmd flag was removed and replaced with the `debug` config parameter.


**Breaking changes (migration to v3)**
- Coordinator server API changes, see web/js/api/api.js.
- Coordinator client event API changes:
  - c `GAME_PLAYER_IDX_CHANGE` (string) -> `GAME_PLAYER_IDX` (number)
  - c `GAME_PLAYER_IDX` -> `GAME_PLAYER_IDX_SET`
  - c `MEDIA_STREAM_INITIALIZED` -> `WEBRTC_NEW_CONNECTION`
  - c `MEDIA_STREAM_SDP_AVAILABLE` -> `WEBRTC_SDP_OFFER`
  - c `MEDIA_STREAM_CANDIDATE_ADD` -> `WEBRTC_ICE_CANDIDATE_RECEIVED`
  - c `MEDIA_STREAM_CANDIDATE_FLUSH` -> `WEBRTC_ICE_CANDIDATES_FLUSH`
  - x `MEDIA_STREAM_READY` -> **removed**
  - c `CONNECTION_READY` -> `WEBRTC_CONNECTION_READY`
  - c `CONNECTION_CLOSED` -> `WEBRTC_CONNECTION_CLOSED`
  - c `GET_SERVER_LIST` -> `WORKER_LIST_FETCHED`
  - x `KEY_STATE_UPDATED` -> **removed**
  - n `WEBRTC_ICE_CANDIDATE_FOUND`
  - n `WEBRTC_SDP_ANSWER`
  - n `MESSAGE`
- `rtcp` module renamed to `webrtc`.
- Controller state equals Libretro controller state (changed order of bits), see: web/js/input/input.js.
- Added new `coordintaor.selector` config param that changes the selection algorithm for workers. By default it will select any free worker. Set this param to `ping` for the old behavior.
- Changed the name of the `webrtc.iceServers.url` config param to `webrtc.iceServers.urls`.
2023-01-09 23:20:22 +03:00
Sergey Stepanov
fac6cc4495
Generate xIds on the worker's side 2022-04-09 10:27:04 +03:00
Sergey Stepanov
c190177955
Show active workers in the debug mode 2022-04-08 20:11:28 +03:00
Sergey Stepanov
76c66339aa
Allow only available workers 2022-04-08 18:39:24 +03:00
sergystepanov
9ad3c98a7d
Rework worker selection feature (#365)
We add a new option for manual worker or machine (server with multiple workers) select, depending on the new coordinator option `coordinator.debug` which by default allows machine selection.
2022-04-07 21:04:30 +03:00
Sergey Stepanov
2a283e24db
Remove DebugHost and Environment config params 2021-12-30 11:06:35 +03:00
Sergey Stepanov
ad822a624d
Add optional Origin handling for Websockets 2021-12-15 17:58:49 +03:00
sergystepanov
1271aa8438
Game recording support (#356)
This feature adds the ability to record game sessions as raw a/v media files.
2021-12-04 14:20:38 +03:00
sergystepanov
47a9d70b74
Add the ability to set emulator ROM folder (#348)
Emulators now can load games with the same file extensions if you either place ROMs into the folder named as the emulator in the config file (libretro.core.list value) or any folder as you specify in the `libretro.core.list.{emulator}.folder` config param.
2021-08-30 19:50:35 +03:00
Sergey Stepanov
048617373a
Use empty auto cert http handler 2021-08-25 23:13:27 +03:00
sergystepanov
431d215eee
Update server HTTPS configuration (#337)
* Merge HTTP and HTTPS routes builder in coordinator

* Extract HTTP/S routes

* Rename config in coordinator

* Generalize child services

* Extract games library helper function

* Use string address instead of port for HTTP/S

* Use a dedicated port extractor function

* Add missing GA tag templating

* Rename shared server address and port params

* Introduce TLS config parameters

* Simplify HTTP/S server constructors

* Update server auto port roll

* Extract init function in worker

* Reorder return params of address type port fn

* Refactor config handler names

* Update TLS default config params

* Extract HTTP to HTTPS redirect function

* Use httpx in monitoring

* Don't log echo requests

* Remove error return from the abstract server

* Add WSS option to the worker-coordinator connection

* Change default worker config

* Make worker send its internal connection params

* Decouple gamelib from the coordinator

* Expose HTTP/S listener address

* Keep original HTTP/S addresses

* Remove no config handler in worker

* Use HTTP-HTTPS redirection

* Wrap net.Listener into a struct

* Clean http server creation fn

* Redirect to https with a generated address

* Use URL in the redirector

* Use zone address param in worker

* Make use of actual addr and port in the monitoring servers

* Use auto-justified monitoring addresses info

* Add the non-HTTPS worker to HTTPS coordinator connection warning

* Embed TLS struct

* Move connection API struct into cws package
2021-08-09 10:42:06 +03:00