Merge remote-tracking branch 'origin/master'
This commit is contained in:
14
.gitmodules
vendored
14
.gitmodules
vendored
@@ -4,7 +4,7 @@
|
||||
branch = master
|
||||
[submodule "packaging/linux/flatpak/deps/shared-modules"]
|
||||
path = packaging/linux/flatpak/deps/shared-modules
|
||||
url = https://github.com/flathub/shared-modules
|
||||
url = https://github.com/flathub/shared-modules.git
|
||||
branch = master
|
||||
[submodule "third-party/build-deps"]
|
||||
path = third-party/build-deps
|
||||
@@ -16,8 +16,8 @@
|
||||
branch = master
|
||||
[submodule "third-party/googletest"]
|
||||
path = third-party/googletest
|
||||
url = https://github.com/google/googletest/
|
||||
branch = v1.14.x
|
||||
url = https://github.com/google/googletest.git
|
||||
branch = main
|
||||
[submodule "third-party/inputtino"]
|
||||
path = third-party/inputtino
|
||||
url = https://github.com/games-on-whales/inputtino.git
|
||||
@@ -28,11 +28,11 @@
|
||||
branch = master
|
||||
[submodule "third-party/nv-codec-headers"]
|
||||
path = third-party/nv-codec-headers
|
||||
url = https://github.com/FFmpeg/nv-codec-headers
|
||||
url = https://github.com/FFmpeg/nv-codec-headers.git
|
||||
branch = sdk/12.0
|
||||
[submodule "third-party/nvapi-open-source-sdk"]
|
||||
path = third-party/nvapi-open-source-sdk
|
||||
url = https://github.com/LizardByte/nvapi-open-source-sdk
|
||||
url = https://github.com/LizardByte/nvapi-open-source-sdk.git
|
||||
branch = sdk
|
||||
[submodule "third-party/Simple-Web-Server"]
|
||||
path = third-party/Simple-Web-Server
|
||||
@@ -40,11 +40,11 @@
|
||||
branch = master
|
||||
[submodule "third-party/TPCircularBuffer"]
|
||||
path = third-party/TPCircularBuffer
|
||||
url = https://github.com/michaeltyson/TPCircularBuffer
|
||||
url = https://github.com/michaeltyson/TPCircularBuffer.git
|
||||
branch = master
|
||||
[submodule "third-party/tray"]
|
||||
path = third-party/tray
|
||||
url = https://github.com/LizardByte/tray
|
||||
url = https://github.com/LizardByte/tray.git
|
||||
branch = master
|
||||
[submodule "third-party/ViGEmClient"]
|
||||
path = third-party/ViGEmClient
|
||||
|
||||
@@ -67,6 +67,11 @@ if(${SUNSHINE_ENABLE_CUDA})
|
||||
|
||||
# message(STATUS "CUDA NVCC Flags: ${CUDA_NVCC_FLAGS}")
|
||||
message(STATUS "CUDA Architectures: ${CMAKE_CUDA_ARCHITECTURES}")
|
||||
elseif(${CUDA_FAIL_ON_MISSING})
|
||||
message(FATAL_ERROR
|
||||
"CUDA not found.
|
||||
If this is intentional, set '-DSUNSHINE_ENABLE_CUDA=OFF' or '-DCUDA_FAIL_ON_MISSING=OFF'"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
if(CUDA_FOUND)
|
||||
@@ -82,8 +87,8 @@ endif()
|
||||
|
||||
# drm
|
||||
if(${SUNSHINE_ENABLE_DRM})
|
||||
find_package(LIBDRM)
|
||||
find_package(LIBCAP)
|
||||
find_package(LIBDRM REQUIRED)
|
||||
find_package(LIBCAP REQUIRED)
|
||||
else()
|
||||
set(LIBDRM_FOUND OFF)
|
||||
set(LIBCAP_FOUND OFF)
|
||||
@@ -95,10 +100,6 @@ if(LIBDRM_FOUND AND LIBCAP_FOUND)
|
||||
list(APPEND PLATFORM_TARGET_FILES
|
||||
"${CMAKE_SOURCE_DIR}/src/platform/linux/kmsgrab.cpp")
|
||||
list(APPEND SUNSHINE_DEFINITIONS EGL_NO_X11=1)
|
||||
elseif(NOT LIBDRM_FOUND)
|
||||
message(WARNING "Missing libdrm")
|
||||
elseif(NOT LIBDRM_FOUND)
|
||||
message(WARNING "Missing libcap")
|
||||
endif()
|
||||
|
||||
# evdev
|
||||
@@ -106,7 +107,7 @@ include(dependencies/libevdev_Sunshine)
|
||||
|
||||
# vaapi
|
||||
if(${SUNSHINE_ENABLE_VAAPI})
|
||||
find_package(Libva)
|
||||
find_package(Libva REQUIRED)
|
||||
else()
|
||||
set(LIBVA_FOUND OFF)
|
||||
endif()
|
||||
@@ -121,7 +122,7 @@ endif()
|
||||
|
||||
# wayland
|
||||
if(${SUNSHINE_ENABLE_WAYLAND})
|
||||
find_package(Wayland)
|
||||
find_package(Wayland REQUIRED)
|
||||
else()
|
||||
set(WAYLAND_FOUND OFF)
|
||||
endif()
|
||||
@@ -153,7 +154,7 @@ endif()
|
||||
|
||||
# x11
|
||||
if(${SUNSHINE_ENABLE_X11})
|
||||
find_package(X11)
|
||||
find_package(X11 REQUIRED)
|
||||
else()
|
||||
set(X11_FOUND OFF)
|
||||
endif()
|
||||
@@ -187,10 +188,9 @@ if(${SUNSHINE_ENABLE_TRAY})
|
||||
endif()
|
||||
pkg_check_modules(LIBNOTIFY libnotify)
|
||||
if(NOT APPINDICATOR_FOUND OR NOT LIBNOTIFY_FOUND)
|
||||
set(SUNSHINE_TRAY 0)
|
||||
message(WARNING "Missing appindicator or libnotify, disabling tray icon")
|
||||
message(STATUS "APPINDICATOR_FOUND: ${APPINDICATOR_FOUND}")
|
||||
message(STATUS "LIBNOTIFY_FOUND: ${LIBNOTIFY_FOUND}")
|
||||
message(FATAL_ERROR "Couldn't find either appindicator or libnotify")
|
||||
else()
|
||||
include_directories(SYSTEM ${APPINDICATOR_INCLUDE_DIRS} ${LIBNOTIFY_INCLUDE_DIRS})
|
||||
link_directories(${APPINDICATOR_LIBRARY_DIRS} ${LIBNOTIFY_LIBRARY_DIRS})
|
||||
@@ -203,10 +203,6 @@ else()
|
||||
message(STATUS "Tray icon disabled")
|
||||
endif()
|
||||
|
||||
if(${SUNSHINE_ENABLE_TRAY} AND ${SUNSHINE_TRAY} EQUAL 0 AND SUNSHINE_REQUIRE_TRAY)
|
||||
message(FATAL_ERROR "Tray icon is required")
|
||||
endif()
|
||||
|
||||
if(${SUNSHINE_USE_LEGACY_INPUT}) # TODO: Remove this legacy option after the next stable release
|
||||
list(APPEND PLATFORM_TARGET_FILES "${CMAKE_SOURCE_DIR}/src/platform/linux/input/legacy_input.cpp")
|
||||
else()
|
||||
|
||||
@@ -27,7 +27,7 @@ if(NOT DEFINED FFMPEG_PREPARED_BINARIES)
|
||||
if(WIN32)
|
||||
set(FFMPEG_PLATFORM_LIBRARIES mfplat ole32 strmiids mfuuid vpl)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
set(FFMPEG_PLATFORM_LIBRARIES numa va va-drm va-x11 vdpau X11)
|
||||
set(FFMPEG_PLATFORM_LIBRARIES numa va va-drm va-x11 X11)
|
||||
endif()
|
||||
set(FFMPEG_PREPARED_BINARIES
|
||||
"${CMAKE_SOURCE_DIR}/third-party/build-deps/ffmpeg/${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
|
||||
@@ -51,7 +51,6 @@ set(CPACK_DEBIAN_PACKAGE_DEPENDS "\
|
||||
libpulse0, \
|
||||
libva2, \
|
||||
libva-drm2, \
|
||||
libvdpau1, \
|
||||
libwayland-client0, \
|
||||
libx11-6, \
|
||||
miniupnpc, \
|
||||
@@ -64,7 +63,6 @@ set(CPACK_RPM_PACKAGE_REQUIRES "\
|
||||
libevdev >= 1.5.6, \
|
||||
libopusenc >= 0.2.1, \
|
||||
libva >= 2.14.0, \
|
||||
libvdpau >= 1.5, \
|
||||
libwayland-client >= 1.20.0, \
|
||||
libX11 >= 1.7.3.1, \
|
||||
miniupnpc >= 2.2.4, \
|
||||
|
||||
@@ -22,7 +22,6 @@ option(BUILD_WERROR "Enable -Werror flag." OFF)
|
||||
option(SUNSHINE_CONFIGURE_ONLY "Configure special files only, then exit." OFF)
|
||||
|
||||
option(SUNSHINE_ENABLE_TRAY "Enable system tray icon. This option will be ignored on macOS." ON)
|
||||
option(SUNSHINE_REQUIRE_TRAY "Require system tray icon. Fail the build if tray requirements are not met." ON)
|
||||
|
||||
option(SUNSHINE_SYSTEM_WAYLAND_PROTOCOLS "Use system installation of wayland-protocols rather than the submodule." OFF)
|
||||
|
||||
@@ -32,6 +31,7 @@ else()
|
||||
option(BOOST_USE_STATIC "Use static boost libraries." ON)
|
||||
endif()
|
||||
|
||||
option(CUDA_FAIL_ON_MISSING "Fail the build if CUDA is not found." ON)
|
||||
option(CUDA_INHERIT_COMPILE_OPTIONS
|
||||
"When building CUDA code, inherit compile options from the the main project. You may want to disable this if
|
||||
your IDE throws errors about unknown flags after running cmake." ON)
|
||||
|
||||
@@ -46,7 +46,6 @@ apt-get install -y --no-install-recommends \
|
||||
libpulse-dev \
|
||||
libssl-dev \
|
||||
libva-dev \
|
||||
libvdpau-dev \
|
||||
libwayland-dev \
|
||||
libx11-dev \
|
||||
libxcb-shm0-dev \
|
||||
|
||||
@@ -238,6 +238,23 @@ This script is intended as a drop-in replacement with the same syntax. (It can b
|
||||
| Do | @code{}sh -c "kscreen-doctor output.HDMI-A-1.mode.${SUNSHINE_CLIENT_WIDTH}x${SUNSHINE_CLIENT_HEIGHT}@${SUNSHINE_CLIENT_FPS}"@endcode |
|
||||
| Undo | @code{}kscreen-doctor output.HDMI-A-1.mode.3840x2160@120@endcode |
|
||||
|
||||
@attention{The names of your displays will differ between X11 and Wayland.
|
||||
Be sure to use the correct name, depending on your session manager.
|
||||
e.g. On X11, the monitor may be called ``HDMI-A-0``, but on Wayland, it may be called ``HDMI-A-1``.
|
||||
}
|
||||
|
||||
@hint{Replace ``HDMI-A-1`` with the display name of the monitor you would like to use for Moonlight.
|
||||
You can list the monitors available to you with:
|
||||
```
|
||||
kscreen-doctor -o
|
||||
```
|
||||
|
||||
These will also give you the supported display properties for each monitor. You can select them either by
|
||||
hard-coding their corresponding number (e.g. ``kscreen-doctor output.HDMI-A1.mode.0``) or using the above
|
||||
``do`` command to fetch the resolution requested by your Moonlight client
|
||||
(which has a chance of not being supported by your monitor).
|
||||
}
|
||||
|
||||
###### NVIDIA
|
||||
|
||||
| Prep Step | Command |
|
||||
|
||||
@@ -224,7 +224,7 @@ flatpak run dev.lizardbyte.app.Sunshine
|
||||
|
||||
##### Run with KMS capture (Wayland & X11)
|
||||
```bash
|
||||
sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') flatpak run dev.lizardbyte.app.Sunshine
|
||||
sudo -i PULSE_SERVER=unix:/run/user/$(id -u $whoami)/pulse/native flatpak run dev.lizardbyte.app.Sunshine
|
||||
```
|
||||
|
||||
##### Uninstall
|
||||
|
||||
582
docs/guides.md
582
docs/guides.md
@@ -50,6 +50,10 @@ The virtual display is accelerated by the NVidia GPU using the TwinView configur
|
||||
I also only tested this on an Artix runit init system on LAN.
|
||||
I didn't have to do anything special with pulseaudio (pipewire untested).
|
||||
|
||||
Pipewire does not seem to work when Sunshine is started over an SSH session.
|
||||
A workaround to this problem is to kill the Sunshine instance started via SSH, and start a new one
|
||||
with the permissions of the desktop session. See [Autostart on boot without auto-login](#autostart-on-boot-without-auto-login)
|
||||
|
||||
Keep your monitors plugged in until the [Checkpoint](#checkpoint) step.}
|
||||
|
||||
@tip{Prior to editing any system configurations, you should make a copy of the original file.
|
||||
@@ -291,13 +295,25 @@ To enable root login over SSH edit your SSHD config, and add `PermitRootLogin ye
|
||||
sudo cp /etc/sudoers.d/${USER} /etc/sudoers.d/${USER}.backup
|
||||
```
|
||||
|
||||
2. `cd` to the parent dir of the `sunshine-setup.sh` script.
|
||||
3. Execute the following to update your sudoer config file.
|
||||
2. `cd` to the parent dir of the `sunshine-setup.sh` script and take note of the full filepath.
|
||||
3. Execute the following to edit your sudoer config file.
|
||||
|
||||
```bash
|
||||
echo "${USER} ALL=(ALL:ALL) ALL, NOPASSWD: $(pwd)/sunshine-setup.sh" \
|
||||
| sudo tee /etc/sudoers.d/${USER}
|
||||
```
|
||||
@danger{NEVER modify a file in ``sudoers.d`` directly. Always use the ``visudo`` command. This command checks your changes
|
||||
before saving the file, and if the resulting changes would break sudo on your system, it will prompt you to fix
|
||||
them. Modifying the file with nano or vim directly does not give you this sanity check and introduces the
|
||||
possibility of losing sudo access to your machine. Tread carefully, and make a backup.}
|
||||
|
||||
```bash
|
||||
sudo visudo /etc/sudoers.d/${USER}
|
||||
```
|
||||
|
||||
Copy the below configuration into the text editor. Change `${USER}` wherever it occurs to your username
|
||||
(e.g. if your username is `sunshineisaawesome` you should change `${USER}` to `sunshineisawesome`)
|
||||
or modify the path if you placed `sunshine-setup.sh` in a different area.
|
||||
|
||||
```
|
||||
${USER} ALL=(ALL:ALL) ALL, NOPASSWD: /home/${USER}/scripts/sunshine-setup.sh
|
||||
```
|
||||
|
||||
These changes allow the script to use sudo without being prompted with a password.
|
||||
|
||||
@@ -484,6 +500,560 @@ and refresh rate prior to connecting to an app. See
|
||||
[Changing Resolution and Refresh Rate](md_docs_2app__examples#changing-resolution-and-refresh-rate)
|
||||
for more information.}
|
||||
|
||||
### Autostart on boot without auto-login
|
||||
|
||||
| Author | [MidwesternRodent](https://github.com/midwesternrodent) |
|
||||
| ---------- | ------------------------------------------------------- |
|
||||
| Difficulty | Intermediate |
|
||||
|
||||
After following this guide you will be able to:
|
||||
1. Turn on the Sunshine host via Moonlight's Wake on LAN (WoL) feature.
|
||||
2. Have Sunshine initialize to the login screen ready for you to enter your credentials.
|
||||
3. Login to your desktop session remotely, and have your pipewire audio and Sunshine tray icon work appropriately.
|
||||
|
||||
#### Specifications
|
||||
This guide was created with the following software on the host:
|
||||
1. OpenSSH server and client (both on the host machine)
|
||||
2. Sunshine v2024.1003.1754422
|
||||
3. Debian 12 w/ KDE Plasma, SDDM, Wayland (also tested through xorg), and pipewire for audio.
|
||||
|
||||
The host hardware that was used in developing this guide:
|
||||
1. AMD 7900XTX
|
||||
2. AMD Ryzen 7 7800X3D
|
||||
3. 128GB DDR5 RAM
|
||||
4. 4 displays in total. 2 1080p displays, 1 3440x1440 display, and 1 4k Roku TV which is used as the always-on display
|
||||
for streaming. (could be subbed with a dummy plug).
|
||||
|
||||
If you have used this guide on any alternative hardware or software (including non-debian based distros)
|
||||
please, feel free to modify this guide and keep it growing!
|
||||
|
||||
#### Caveats
|
||||
1. When you login the machine will close your connection and you will have to reconnect. This is necessary due to an
|
||||
issue similar to why the [Uinput Permissions Workaround](#uinput-permissions-workaround) is needed since SSH
|
||||
connections are not treated the same as graphical logins. This causes weirdness like sound not working through
|
||||
pipewire, and the tray icon for Sunshine not appearing. To get around this, we need to close the SSH initiated Sunshine
|
||||
service, and start a new Sunshine service with the permissions of the graphical desktop. Unfortunately, this closes the
|
||||
connection and forces you to reconnect through Moonlight. There is no way around this to the best of my knowledge
|
||||
without enabling auto-login.
|
||||
3. This guide does not cover using virtual displays. If you are using Nvidia graphics,
|
||||
see [Remote SSH Headless Setup](#remote-ssh-headless-setup). If you are using AMD hardware, let me know
|
||||
if you find something or feel free to add it to this guide.
|
||||
4. I haven't (yet) found a way to disable sleep on the login screen, so if you wait too long after starting your PC,
|
||||
the display may go to sleep and Moonlight will have trouble connecting. Shutting down and using WoL works great
|
||||
though.
|
||||
|
||||
@attention{This is definitely safer than enabling auto-login directly, especially for a dual-use PC that is not only
|
||||
streamed via Moonlight, but is also used as a standard desktop. *However* I do not know the implications of having an
|
||||
always running SSH client to the localhost on the same machine. It may be possible for someone with significant
|
||||
knowledge and physical access to the machine to compromise your user account due to this always-running SSH session.
|
||||
However, that's better than just having the desktop always available, or opening up SSH even just your LAN since this
|
||||
guide specifically disables non-localhost connections, so I believe this is safer to use than auto-login for general
|
||||
users. As always, your [threat model](https://en.wikipedia.org/wiki/Threat_model) may vary.}
|
||||
|
||||
#### Prerequisites
|
||||
In [Remote SSH Headless Setup](#remote-ssh-headless-setup) complete the following sections.
|
||||
|
||||
1. [Static IP Setup](#static-ip-setup)
|
||||
2. [SSH Server Setup](#ssh-server-setup)
|
||||
3. [Virtual Display Setup](#virtual-display-setup)
|
||||
4. [Uinput Permissions Workaround](#uinput-permissions-workaround)
|
||||
5. [Stream Launcher Script](#stream-launcher-script)
|
||||
|
||||
@note{On a default Debian 12 install using KDE Plasma, you are using the Simple Desktop Display Manager (SDDM).
|
||||
Even if you are logging in to a Wayland session, SDDM by default starts with an xorg session, so this script
|
||||
does not need to be modified if you primarily use a Wayland session (the default) when you login.}
|
||||
|
||||
#### Instructions
|
||||
|
||||
##### Enable Wake on LAN
|
||||
|
||||
Wake on LAN (WoL) will allow you to send a magic packet to turn your PC on remotely. This is handled automatically by
|
||||
Moonlight's "send wake on lan" option in the app but you do need to enable it on your host machine first. The
|
||||
[instructions on the debian.org](https://wiki.debian.org/WakeOnLan#Enabling_WOL) site are a little hard to parse, so
|
||||
I've simplified them below.
|
||||
|
||||
@note{This may not work on all deb based distributions. If you know of a better way for POP OS, Ubuntu, or another
|
||||
debian based distro please feel free to edit the guide yourself, or let me know.}
|
||||
|
||||
First, find the name of your ethernet interface.
|
||||
|
||||
```bash
|
||||
ip link show
|
||||
```
|
||||
|
||||
When I run this command, these are the results I receive
|
||||
```
|
||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
|
||||
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
||||
2: enp117s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
|
||||
link/ether 9c:6b:00:59:33:c1 brd ff:ff:ff:ff:ff:ff
|
||||
```
|
||||
|
||||
We can ignore the loopback interface, and I can see my ethernet interface is called `enp117s0`. You might see
|
||||
wireless interfaces here as well but they can also be ignored.
|
||||
|
||||
@note{If your PC is only connected via Wi-Fi, it is still technically possible to get this working, but it is outside
|
||||
the scope of this guide and requires more networking knowledge and a Wi-Fi chip that supports WoL. If this is your
|
||||
first foray into linux, I'd recommend just getting a cable.}
|
||||
|
||||
Now I can install ethtool and modify my interface to allow Wake on LAN. For your use, replace `enp117s0` with whatever
|
||||
the name of your ethernet interface is from the command `ip link show`
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install ethtool
|
||||
sudo ethtool -s enp117s0 wol g
|
||||
```
|
||||
|
||||
##### SSH Client Setup
|
||||
To start, we need to install an SSH client (which is different from the *server* in [Remote SSH Headless Setup](#remote-ssh-headless-setup))
|
||||
on our machine if this not already done. Open a terminal and enter the following commands.
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install openssh-client
|
||||
```
|
||||
|
||||
Next we need to generate the keys we will use to connect to our SSH session. This is as simple as running the
|
||||
following in a terminal:
|
||||
|
||||
```bash
|
||||
ssh-keygen
|
||||
```
|
||||
|
||||
and simply pressing enter through the default options. This will place a file called `id_rsa` and `id_rsa.pub`
|
||||
in the hidden folder `~/.ssh/`. This is the default key used when this user initiates an SSH session.
|
||||
|
||||
Next, we'll copy that public key to the `~/.ssh/authorized_users` file. These are the public keys
|
||||
allowed to access this machine over SSH, and will allow us to establish an SSH connection with this user
|
||||
to the SSH server running on the localhost.
|
||||
|
||||
```bash
|
||||
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
|
||||
```
|
||||
|
||||
@tip{If you also want any other machines (e.g. a laptop or Steam Deck) to connect to your machine remotely over ssh,
|
||||
be sure to generate a pubkey on that machine and append it to the authorized_keys file like we did above.}
|
||||
|
||||
###### SSH Server Modifications
|
||||
|
||||
We'll want to make a few modification to the SSH server on the Sunshine host, both for convenience and security.
|
||||
|
||||
Modify `/etc/ssh/sshd_config` with the following changes:
|
||||
|
||||
@tabs{
|
||||
@tab{nano | ```bash
|
||||
sudo nano /etc/ssh/sshd_config
|
||||
```}
|
||||
@tab{vim | ```bash
|
||||
sudo vi /etc/ssh/sshd_config
|
||||
```}
|
||||
}
|
||||
|
||||
Find the line with `PasswordAuthentication` and make sure it is set to `no` (removed the `#` if present.
|
||||
Then find the line `PubkeyAuthentication` and make sure it is set to `yes` and remove the `#` from the beginning
|
||||
if present. When you're done you should have these two lines in your config somewhere.
|
||||
|
||||
```
|
||||
PubkeyAuthentication yes
|
||||
PasswordAuthentication no
|
||||
```
|
||||
|
||||
@tip{Using publickey encryption for SSH connections significantly increases your protection against brute force
|
||||
attacks, and protects you against a rogue machine pretending to be your SSH server and stealing your password.}
|
||||
|
||||
The next step is optional, but if you do not plan on connecting to your computer remotely via ssh and only have
|
||||
installed SSH for the purposes of using Sunshine, it's a good idea to disable listening for remote SSH connections.
|
||||
Do this by changing the following lines near the top of your ``sshd_config``:
|
||||
|
||||
```
|
||||
#ListenAddress 0.0.0.0
|
||||
#ListenAddress ::
|
||||
```
|
||||
|
||||
To the following:
|
||||
|
||||
```
|
||||
ListenAddress 127.0.0.1
|
||||
ListenAddress ::1
|
||||
```
|
||||
|
||||
This will only allow SSH connections coming from your computer itself.
|
||||
|
||||
@tip{on some distributions, the maintainers have added some files in ``/etc/ssh/sshd_config.d/`` which are pulled into
|
||||
your ``sshd_config``. These modifications can conflict with what we've just done. If you have any files in
|
||||
``/etc/ssh/sshd_config.d/``, make sure they do not include any of the changes we've just made or you will experience
|
||||
problems. If they do, you can comment out those lines by placing a ``#`` at their beginning, or delete the files safely
|
||||
if you don't plan to use SSH for anything other than Sunshine.}
|
||||
|
||||
###### Quick Test and Accept Host Authenticity.
|
||||
|
||||
Next, let's reboot the machine and try to connect! Accept any warnings about the unidentified host at this time,
|
||||
you'll never see those appear again unless something changes with your setup.
|
||||
|
||||
```bash
|
||||
ssh $(whoami)@localhost
|
||||
```
|
||||
|
||||
You should see a new login prompt for the machine you're already on, and when you type `exit` you should just see
|
||||
|
||||
```bash
|
||||
logout
|
||||
Connection to localhost closed.
|
||||
```
|
||||
|
||||
##### Run sunshine-setup on boot over SSH
|
||||
|
||||
Thanks to [this comment from Gavin Haynes on Unix Stack exchange](https://unix.stackexchange.com/questions/669389/how-do-i-get-an-ssh-command-to-run-on-boot/669476#669476),
|
||||
we can establish an SSH connection on boot to run the sunshine-setup script via a systemd service.
|
||||
|
||||
###### Disable default Sunshine services
|
||||
|
||||
These service files are sometimes overwritten when updating Sunshine with the .deb.
|
||||
So we'll be making new ones and disabling the included service files for our purposes.
|
||||
|
||||
```
|
||||
sudo sytstemctl disable sunshine
|
||||
systemctl --user disable sunshine
|
||||
```
|
||||
|
||||
@note{In order to disable the user service, you must be logged in to the graphical desktop environment and run the
|
||||
command from a GUI terminal. You'll also likely need to approve a polkit request (a graphical popup that asks
|
||||
for your password). Trying to disable the user service without being signed in to the graphical environment is a
|
||||
recipe for pain, and is why ``sudo`` is not invoked on the second line in the command above.}
|
||||
|
||||
###### Create the autossh-sunshine-start script
|
||||
|
||||
@tabs{
|
||||
@tab{nano | ```bash
|
||||
sudo nano /usr/local/bin/autossh-sunshine-start
|
||||
```}
|
||||
@tab{vim | ```bash
|
||||
sudo vi /usr/local/bin/autossh-sunshine-start
|
||||
```}
|
||||
}
|
||||
|
||||
Copy the below script to that location and replace `{USERNAME}` wherever it occurs with the username you created
|
||||
the SSH public key for in the previous section.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
ssh -i /home/{USERNAME}/.ssh/id_rsa {USERNAME}@localhost
|
||||
"/home/{USERNAME}/scripts/sunshine.sh"
|
||||
```
|
||||
|
||||
@attention{This script uses the location of the script in [Stream Launcher Script](#stream-launcher-script).
|
||||
Please complete that section before continuing.}
|
||||
|
||||
Once you've created the script, be sure to make it executable by running:
|
||||
|
||||
```bash
|
||||
sudo chmod +x /usr/local/bin/autossh-sunshine-start
|
||||
```
|
||||
|
||||
###### Create the autossh systemd service file
|
||||
|
||||
@tabs{
|
||||
@tab{nano | ```bash
|
||||
sudo nano /etc/systemd/system/autossh-sunshine.service
|
||||
```}
|
||||
@tab{vim | ```bash
|
||||
sudo vi /etc/systemd/system/autossh-sunshine.service
|
||||
```}
|
||||
}
|
||||
|
||||
Copy and paste the below systemd file and save it to the location in the commands above.
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description=Start sunshine over an localhost SSH connection on boot
|
||||
Requires=sshd.service
|
||||
After=sshd.service
|
||||
|
||||
[Service]
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/usr/local/bin/autossh-sunshine-start
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Make it executable, and enable the service when you're done.
|
||||
|
||||
```bash
|
||||
sudo chmod +x /etc/systemd/system/autossh-sunshine.service
|
||||
sudo systemctl start autossh-sunshine
|
||||
sudo systemctl enable autossh-sunshine
|
||||
```
|
||||
|
||||
This point is a good time for a sanity check, so restart your PC and try to sign in to your desktop via Moonlight.
|
||||
You should be able to access the login screen, enter your credentials, and control the user session. At this point
|
||||
you'll notice the reason for the next section as your audio will be non-functional and you won't see any tray icon
|
||||
for Sunshine. If you don't care about audio (and maybe a couple other bugs you might encounter from time to time due
|
||||
to the permissions difference between an SSH session and the desktop session), you can consider yourself finished at
|
||||
this point!
|
||||
|
||||
@note{You might also notice some issues if you have multiple monitors setup (including the dummy plug), like the mouse
|
||||
cursor not being on the right screen for you to login. We will address this in the last step of this guide. It requires
|
||||
messing with some configs for SDDM.}
|
||||
|
||||
##### Getting the audio working
|
||||
|
||||
To get the audio (and tray icon, etc...) working we will create a systemd user service, that will start on a graphical
|
||||
login, kill the autossh-sunshine system service, and start Sunshine just like the standard Sunshine service.
|
||||
This service will also need to call the autossh-sunshine system service before it is stopped as the user service will
|
||||
be killed when we log out of the graphical session, so we want to make sure we restart that SSH service so we don't
|
||||
lose the ability to log back in if we need to.
|
||||
|
||||
@tabs{
|
||||
@tab{nano | ```bash
|
||||
sudo nano /usr/lib/systemd/user/sunshine-after-login.service
|
||||
```}
|
||||
@tab{vim | ```bash
|
||||
sudo vi /usr/lib/systemd/user/sunshine-after-login.service
|
||||
```}
|
||||
}
|
||||
|
||||
Once again, copy the below service file into your text editor at the location above.
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description=Start Sunshine with the permissions of the graphical desktop session
|
||||
StartLimitIntervalSec=500
|
||||
StartLimitBurst=5
|
||||
|
||||
[Service]
|
||||
# Avoid starting Sunshine before the desktop is fully initialized.
|
||||
ExecStartPre=/usr/bin/pkill sunshine
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/usr/bin/sunshine
|
||||
ExecStopPost=/usr/bin/systemctl start autossh-sunshine
|
||||
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
[Install]
|
||||
WantedBy=xdg-desktop-autostart.target
|
||||
```
|
||||
|
||||
Make it executable, and enable it.
|
||||
|
||||
```bash
|
||||
sudo chmod +x /usr/lib/systemd/user/sunshine-after-login.service
|
||||
systemctl --user enable sunshine-after-login
|
||||
```
|
||||
|
||||
###### Polkit Rules for Sunshine User Service
|
||||
|
||||
Since this is being run with the permissions of the graphical session, we need to make a polkit modification to allow
|
||||
it to call the system service autossh-sunshine when this user service is stopped, without prompting us for a password.
|
||||
|
||||
@tabs{
|
||||
@tab{nano | ```bash
|
||||
sudo nano /etc/polkit-1/rules.d/sunshine.rules
|
||||
```}
|
||||
@tab{vim | ```bash
|
||||
sudo vi /etc/polkit-1/rules.d/sunshine.rules
|
||||
```}
|
||||
}
|
||||
|
||||
Once again, copy the below to the .rules file in your text editor.
|
||||
|
||||
```js
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "org.freedesktop.systemd1.manage-units" &&
|
||||
action.lookup("unit") == "autossh-sunshine.service")
|
||||
{
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
###### Modifications to sudoers.d files
|
||||
|
||||
Lastly, we need to make a few modifications to the sudoers file for our users. Replace {USERNAME} below with your
|
||||
username. You will be prompted to select either vi or nano for your editor if you've not used this command before,
|
||||
choose whichever you prefer.
|
||||
|
||||
```
|
||||
sudo visudo /etc/sudoers.d/{USERNAME}
|
||||
```
|
||||
|
||||
@danger{NEVER modify a file in ``sudoers.d`` directly. Always use the ``visudo`` command. This command checks your changes
|
||||
before saving the file, and if the resulting changes would break sudo on your system, it will prompt you to fix
|
||||
them. Modifying the file with nano or vim directly does not give you this sanity check and introduces the
|
||||
possibility of losing sudo access to your machine. Tread carefully, and make a backup.}
|
||||
|
||||
As always, copy and paste the below into your user's `sudoers.d` configuration. Replace {USERNAME} with your username,
|
||||
and {HOSTNAME} with the name of your computer.
|
||||
|
||||
```
|
||||
{USERNAME} {HOSTNAME} = (root) NOPASSWD: /home/{USERNAME}/scripts/sunshine-setup.sh
|
||||
{USERNAME} {HOSTNAME} = (root) NOPASSWD: /bin/sunshine
|
||||
{USERNAME} {HOSTNAME} = (root) NOPASSWD: /usr/bin/systemctl start autossh-sunshine
|
||||
{USERNAME} {HOSTNAME} = (root) NOPASSWD: /usr/bin/systemctl --user start sunshine-after-login
|
||||
# The below is optional, but will allow us to send trigger a shutdown with a sunshine prep command, if desired.
|
||||
{USERNAME} {HOSTNAME} = (root) NOPASSWD: /usr/sbin/shutdown
|
||||
```
|
||||
|
||||
Once again, restart your computer and do a quick test. Make sure you can connect to the PC to login and enter your
|
||||
credentials. You should be booted out of the system, and then can reconnect a few seconds later to the logged-in
|
||||
desktop session. You should see a tray icon for Sunshine, and the sound should be working (or you may need to manually
|
||||
select the sunshine-sink at least the first time).
|
||||
|
||||
If you don't have multiple monitors, at this point you can consider yourself done!
|
||||
|
||||
##### Configuring the login screen layout for multiple monitors
|
||||
|
||||
This is not Sunshine specific, but is a frequent problem I had setting up Sunshine and thought it pertinent to add to
|
||||
the guide. If you are using multiple monitors (even a single monitor with a dummy plug may have this problem) you
|
||||
might notice the streamed login screen has one or more of the following problems:
|
||||
|
||||
1. The text is way too small to see (caused by a too-high resolution)
|
||||
2. The mouse cursor is off on some other screen (caused by not mirroring the displays)
|
||||
3. There are multiple login screens overlapping each other (caused by differing resolutions, and trying to mirror
|
||||
the display).
|
||||
|
||||
###### Log in to an X11 Session
|
||||
|
||||
This can be fixed, by modifying some scripts called by SDDM on boot. To start though, we need to make sure we're
|
||||
logged into an x11 session, not Wayland or the terminal. As the Wayland session will give us incorrect information,
|
||||
and the terminal will give us no information since no graphical environment exists. SDDM initially starts an x11
|
||||
session to display the login screen so we need to use xorg commands to change the display configuration.
|
||||
|
||||
To do this, log out of your desktop session on the Sunshine host, and somewhere on the lower left of your screen
|
||||
(depending on your SDDM theme) there will be some text that on Debian 12 KDE Plasma defaults to saying
|
||||
`Session: Plasma (Wayland)`. Select this and choose `Plasma (X11)` from the drop down menu and sign in.
|
||||
|
||||
###### Find your monitor identifiers.
|
||||
|
||||
Open a terminal and run:
|
||||
|
||||
```bash
|
||||
xrandr | grep -w connected
|
||||
```
|
||||
|
||||
This will require some more sleuthing on your part. Different PC hardware, and different monitors / connectors,
|
||||
display the names differently. Some start at 0, some start 1. Some spell out "DisplayPort" some, say "DP". You will
|
||||
need to modify all of the commands from here on out based on the output of the above command. I will use the output I
|
||||
receive below as the example for the rest of this guide.
|
||||
|
||||
```bash
|
||||
DisplayPort-0 connected (normal left inverted right x axis y axis)
|
||||
DisplayPort-1 connected (normal left inverted right x axis y axis)
|
||||
DisplayPort-2 connected (normal left inverted right x axis y axis)
|
||||
HDMI-A-0 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 800mm x 450mm
|
||||
```
|
||||
|
||||
@note{If I instead run this command on Wayland, I get the following useless output. Hence the need to sign in to an
|
||||
x11 session.
|
||||
|
||||
```bash
|
||||
XWAYLAND0 connected 2592x1458+6031+0 (normal left inverted right x axis y axis) 600mm x 340mm
|
||||
XWAYLAND1 connected 2592x1458+0+0 (normal left inverted right x axis y axis) 480mm x 270mm
|
||||
XWAYLAND2 connected primary 3440x1440+2592+0 (normal left inverted right x axis y axis) 800mm x 330mm
|
||||
XWAYLAND3 connected 2592x1458+0+0 (normal left inverted right x axis y axis) 1440mm x 810mm
|
||||
|
||||
```
|
||||
}
|
||||
|
||||
|
||||
From this, you can see that my monitors are named the following under an x11 session.
|
||||
|
||||
DisplayPort-0
|
||||
DisplayPort-1
|
||||
DisplayPort-2
|
||||
HDMI-A-0
|
||||
|
||||
@tip{If you have a label maker, now would be a good time to unplug some cables, determine where they are on your
|
||||
system, and label the outputs on your graphics card to ease changing your setup in the future.}
|
||||
|
||||
In my setup, after moving some inputs I changed my system so that these cables correspond to the below monitors
|
||||
|
||||
| Display Name | Monitor |
|
||||
| ------------- | --------------------------- |
|
||||
| DisplayPort-0 | rightmost 1080p display |
|
||||
| DisplayPort-1 | leftmost 1080p display |
|
||||
| DisplayPort-2 | middle 3440x1440 display |
|
||||
| HDMI-A-0 | 4k Roku TV (and dummy plug) |
|
||||
|
||||
###### Modify the SDDM startup script
|
||||
|
||||
For my purposes, I would prefer to have the Roku TV (which doubles as my always-on dummy plug) to always display a
|
||||
1080p screen on login (this can be changed automatically after login). And I would like to retain the ability to use
|
||||
my leftmost monitor to login to my physical desktop, but I'd like to disable my primary and rightmost displays.
|
||||
|
||||
To do this, we need to modify the SDDM startup script to shut off DisplayPort-1 and DisplayPort-2, set HDMI-A-0 to
|
||||
1080p and mirror it with DisplayPort-1.
|
||||
|
||||
@tabs{
|
||||
@tab{nano | ```bash
|
||||
sudo nano /usr/share/sddm/scripts/Xsetup
|
||||
```}
|
||||
@tab{vim | ```bash
|
||||
sudo vi /usr/share/sddm/scripts/Xsetup
|
||||
```}
|
||||
}
|
||||
|
||||
Which will open a script that looks like this. We will not be removing these lines.
|
||||
|
||||
```bash
|
||||
#!/bin/sh
|
||||
# Xsetup - run as root before the login dialog appears
|
||||
|
||||
if [ -e /sbin/prime-offload ]; then
|
||||
echo running NVIDIA Prime setup /sbin/prime-offload
|
||||
/sbin/prime-offload
|
||||
fi
|
||||
```
|
||||
|
||||
At the bottom of this Xsetup script though, we can add some xrandr commands
|
||||
|
||||
To shut a display off, we can use: `xrandr --output {DISPLAYNAME} --off`.
|
||||
|
||||
To set a display as the primary and accept
|
||||
it's automatic (usually the maximum, but not always especially on TVs where the default refresh rate may be lower)
|
||||
resolution and refresh rate we can use: `xrandr --output {DISPLAYNAME} --auto --primary`.
|
||||
|
||||
To set a display to a specific resolution we can use: `xrandr --output {DISPLAYNAME} --mode {PIXELWIDTH}x{PIXELLENGTH}`.
|
||||
|
||||
And lastly, to mirror a display we can use: `xrandr --output {DISPLAYNAME} --same-as {ANOTHER-DISPLAY}`
|
||||
|
||||
So with my desire to mirror my TV and left displays, my Xsetup script now looks like this:
|
||||
|
||||
```bash
|
||||
#!/bin/sh
|
||||
# Xsetup - run as root before the login dialog appears
|
||||
|
||||
if [ -e /sbin/prime-offload ]; then
|
||||
echo running NVIDIA Prime setup /sbin/prime-offload
|
||||
/sbin/prime-offload
|
||||
fi
|
||||
|
||||
xrandr --output DisplayPort-0 --off
|
||||
xrandr --output DisplayPort-2 --off
|
||||
xrandr --output DisplayPort-1 --auto --primary
|
||||
xrandr --output HDMI-A-0 --mode 1920x1080
|
||||
xrandr --output HDMI-A-0 --same-as DisplayPort-1
|
||||
```
|
||||
|
||||
Save this file, reboot, and you should see your login screen now respects these settings. Make sure when you log
|
||||
back in, you select a Wayland session (if that is your preferred session manager).
|
||||
|
||||
#### Next Steps
|
||||
|
||||
Congratulations! You now have Sunshine starting on boot, you can login to your session remotely, you get all the
|
||||
benefits of the graphical session permissions, and you can safely shut down your PC with the confidence you can
|
||||
turn it back on when needed.
|
||||
|
||||
@seealso{As Eric Dong recommended, I'll also send you to automate changing your displays.
|
||||
You can add multiple commands, to turn off, or configure as many displays as you'd like with the sunshine prep
|
||||
commands. See [Changing Resolution and Refresh Rate](md_docs_2app__examples#changing-resolution-and-refresh-rate)
|
||||
for more information and remember that the display names for your prep commands, may be different than what you
|
||||
found for SDDM.}
|
||||
|
||||
|
||||
## macOS
|
||||
@todo{It's looking lonely here.}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@lizardbyte/shared-web": "2024.921.191855",
|
||||
"vue": "3.5.11",
|
||||
"vue": "3.5.12",
|
||||
"vue-i18n": "9.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -23,7 +23,6 @@ depends=(
|
||||
'libnotify'
|
||||
'libpulse'
|
||||
'libva'
|
||||
'libvdpau'
|
||||
'libx11'
|
||||
'libxcb'
|
||||
'libxfixes'
|
||||
|
||||
@@ -27,7 +27,6 @@ BuildRequires: libevdev-devel
|
||||
BuildRequires: libgudev
|
||||
BuildRequires: libnotify-devel
|
||||
BuildRequires: libva-devel
|
||||
BuildRequires: libvdpau-devel
|
||||
BuildRequires: libX11-devel
|
||||
BuildRequires: libxcb-devel
|
||||
BuildRequires: libXcursor-devel
|
||||
@@ -66,7 +65,6 @@ Requires: libdrm > 2.4.97
|
||||
Requires: libevdev >= 1.5.6
|
||||
Requires: libopusenc >= 0.2.1
|
||||
Requires: libva >= 2.14.0
|
||||
Requires: libvdpau >= 1.5
|
||||
Requires: libwayland-client >= 1.20.0
|
||||
Requires: libX11 >= 1.7.3.1
|
||||
Requires: miniupnpc >= 2.2.4
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<p>flatpak run --command=additional-install.sh @PROJECT_FQDN@</p>
|
||||
<p>NOTE: Sunshine uses a self-signed certificate. The web browser will report it as not secure, but it is safe.</p>
|
||||
<p>NOTE: KMS Grab (Optional)</p>
|
||||
<p>sudo -i PULSE_SERVER=unix:$(pactl info | awk '/Server String/{print$3}') flatpak run @PROJECT_FQDN@</p>
|
||||
<p>sudo -i PULSE_SERVER=unix:/run/user/$(id -u $whoami)/pulse/native flatpak run @PROJECT_FQDN@</p>
|
||||
</description>
|
||||
|
||||
<releases>
|
||||
|
||||
@@ -33,13 +33,13 @@ modules:
|
||||
- "modules/xvfb/xvfb.json"
|
||||
|
||||
# Runtime dependencies
|
||||
- shared-modules/libappindicator/libappindicator-gtk3-12.10.json
|
||||
- shared-modules/libayatana-appindicator/libayatana-appindicator-gtk3.json
|
||||
- "modules/avahi.json"
|
||||
- "modules/boost.json"
|
||||
- "modules/libevdev.json"
|
||||
- "modules/libnotify.json"
|
||||
- "modules/miniupnpc.json"
|
||||
- "modules/numactl.json" # TODO: is this still needed?
|
||||
- "modules/numactl.json"
|
||||
|
||||
# Caching is configured until here, not including CUDA, since it is too large for GitHub cache
|
||||
- "modules/cuda.json"
|
||||
|
||||
@@ -23,8 +23,8 @@ class @PROJECT_NAME@ < Formula
|
||||
end
|
||||
|
||||
option "with-docs", "Enable docs"
|
||||
option "with-dynamic-boost", "Dynamically link Boost libraries"
|
||||
option "without-dynamic-boost", "Statically link Boost libraries" # default option
|
||||
option "with-static-boost", "Enable static link of Boost libraries"
|
||||
option "without-static-boost", "Disable static link of Boost libraries" # default option
|
||||
|
||||
depends_on "cmake" => :build
|
||||
depends_on "doxygen" => :build
|
||||
@@ -35,6 +35,7 @@ class @PROJECT_NAME@ < Formula
|
||||
depends_on "miniupnpc"
|
||||
depends_on "openssl"
|
||||
depends_on "opus"
|
||||
depends_on "boost" => :recommended
|
||||
depends_on "icu4c" => :recommended
|
||||
|
||||
on_linux do
|
||||
@@ -43,7 +44,6 @@ class @PROJECT_NAME@ < Formula
|
||||
depends_on "libdrm"
|
||||
depends_on "libnotify"
|
||||
depends_on "libva"
|
||||
depends_on "libvdpau"
|
||||
depends_on "libx11"
|
||||
depends_on "libxcb"
|
||||
depends_on "libxcursor"
|
||||
@@ -84,14 +84,17 @@ class @PROJECT_NAME@ < Formula
|
||||
args << "-DBUILD_DOCS=OFF"
|
||||
end
|
||||
|
||||
if build.without? "dynamic-boost"
|
||||
if build.without? "static-boost"
|
||||
args << "-DBOOST_USE_STATIC=OFF"
|
||||
ohai "Disabled statically linking Boost libraries"
|
||||
else
|
||||
args << "-DBOOST_USE_STATIC=ON"
|
||||
ohai "Statically linking Boost libraries"
|
||||
ohai "Enabled statically linking Boost libraries"
|
||||
|
||||
unless Formula["icu4c"].any_version_installed?
|
||||
odie <<~EOS
|
||||
icu4c must be installed to link against static Boost libraries,
|
||||
either install icu4c or use brew install sunshine --with-dynamic-boost instead
|
||||
either install icu4c or use brew install sunshine --with-static-boost instead
|
||||
EOS
|
||||
end
|
||||
ENV.append "CXXFLAGS", "-I#{Formula["icu4c"].opt_include}"
|
||||
@@ -99,11 +102,10 @@ class @PROJECT_NAME@ < Formula
|
||||
ENV.append "LDFLAGS", "-L#{icu4c_lib_path}"
|
||||
ENV["LIBRARY_PATH"] = icu4c_lib_path
|
||||
ohai "Linking against ICU libraries at: #{icu4c_lib_path}"
|
||||
else
|
||||
args << "-DBOOST_USE_STATIC=OFF"
|
||||
ohai "Dynamically linking Boost libraries"
|
||||
end
|
||||
|
||||
args << "-DCUDA_FAIL_ON_MISSING=OFF" if OS.linux?
|
||||
|
||||
system "cmake", "-S", ".", "-B", "build", *std_cmake_args, *args
|
||||
|
||||
cd "build" do
|
||||
|
||||
@@ -106,7 +106,6 @@ function add_debain_based_deps() {
|
||||
"libopus-dev"
|
||||
"libpulse-dev"
|
||||
"libssl-dev"
|
||||
"libvdpau-dev"
|
||||
"libwayland-dev" # Wayland
|
||||
"libx11-dev" # X11
|
||||
"libxcb-shm0-dev" # X11
|
||||
@@ -162,7 +161,6 @@ function add_fedora_deps() {
|
||||
"libdrm-devel"
|
||||
"libevdev-devel"
|
||||
"libnotify-devel"
|
||||
"libvdpau-devel"
|
||||
"libX11-devel" # X11
|
||||
"libxcb-devel" # X11
|
||||
"libXcursor-devel" # X11
|
||||
|
||||
@@ -124,9 +124,8 @@ namespace {
|
||||
create_virtual_sink_waveformats() {
|
||||
if constexpr (channel_count == 2) {
|
||||
auto channel_mask = waveformat_mask_stereo;
|
||||
// only choose 24 or 16-bit formats to avoid clobbering existing Dolby/DTS spatial audio settings
|
||||
return {
|
||||
create_waveformat(sample_format_e::f32, channel_count, channel_mask),
|
||||
create_waveformat(sample_format_e::s32, channel_count, channel_mask),
|
||||
create_waveformat(sample_format_e::s24in32, channel_count, channel_mask),
|
||||
create_waveformat(sample_format_e::s24, channel_count, channel_mask),
|
||||
create_waveformat(sample_format_e::s16, channel_count, channel_mask),
|
||||
|
||||
@@ -1870,7 +1870,14 @@ namespace video {
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (shutdown_event->peek() || reinit_event.peek() || !images->running()) {
|
||||
// Break out of the encoding loop if any of the following are true:
|
||||
// a) The stream is ending
|
||||
// b) Sunshine is quitting
|
||||
// c) The capture side is waiting to reinit and we've encoded at least one frame
|
||||
//
|
||||
// If we have to reinit before we have received any captured frames, we will encode
|
||||
// the blank dummy frame just to let Moonlight know that we're alive.
|
||||
if (shutdown_event->peek() || !images->running() || (reinit_event.peek() && frame_nr > 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<nav class="navbar navbar-light navbar-expand-lg navbar-background header">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/" title="Apollo">
|
||||
<img src="/images/logo-apollo-45.png" height="45" alt="Apollo">
|
||||
<a class="navbar-brand" href="./" title="Apollo">
|
||||
<img src="./images/logo-apollo-45.png" height="45" alt="Apollo">
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
|
||||
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
@@ -11,22 +11,22 @@
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/"><i class="fas fa-fw fa-home"></i> {{ $t('navbar.home') }}</a>
|
||||
<a class="nav-link" href="./"><i class="fas fa-fw fa-home"></i> {{ $t('navbar.home') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/pin"><i class="fas fa-fw fa-unlock"></i> {{ $t('navbar.pin') }}</a>
|
||||
<a class="nav-link" href="./pin"><i class="fas fa-fw fa-unlock"></i> {{ $t('navbar.pin') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/apps"><i class="fas fa-fw fa-stream"></i> {{ $t('navbar.applications') }}</a>
|
||||
<a class="nav-link" href="./apps"><i class="fas fa-fw fa-stream"></i> {{ $t('navbar.applications') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/config"><i class="fas fa-fw fa-cog"></i> {{ $t('navbar.configuration') }}</a>
|
||||
<a class="nav-link" href="./config"><i class="fas fa-fw fa-cog"></i> {{ $t('navbar.configuration') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/password"><i class="fas fa-fw fa-user-shield"></i> {{ $t('navbar.password') }}</a>
|
||||
<a class="nav-link" href="./password"><i class="fas fa-fw fa-user-shield"></i> {{ $t('navbar.password') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/troubleshooting"><i class="fas fa-fw fa-info"></i> {{ $t('navbar.troubleshoot') }}</a>
|
||||
<a class="nav-link" href="./troubleshooting"><i class="fas fa-fw fa-info"></i> {{ $t('navbar.troubleshoot') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<ThemeToggle/>
|
||||
|
||||
@@ -436,7 +436,7 @@
|
||||
created() {
|
||||
this.loadApps();
|
||||
|
||||
fetch("/api/config", {
|
||||
fetch("./api/config", {
|
||||
credentials: 'include'
|
||||
})
|
||||
.then(r => r.json())
|
||||
@@ -444,7 +444,7 @@
|
||||
},
|
||||
methods: {
|
||||
loadApps() {
|
||||
fetch("/api/apps", {
|
||||
fetch("./api/apps", {
|
||||
credentials: 'include'
|
||||
})
|
||||
.then(r => r.json())
|
||||
@@ -459,7 +459,7 @@
|
||||
launchApp(app) {
|
||||
if (confirm(this.$t('apps.launch_warning'))) {
|
||||
app.launching = true;
|
||||
fetch("/api/apps/launch?uuid=" + app.uuid, {
|
||||
fetch("./api/apps/launch?uuid=" + app.uuid, {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
})
|
||||
@@ -483,7 +483,7 @@
|
||||
"Are you sure to delete " + app.name + "?"
|
||||
);
|
||||
if (resp) {
|
||||
fetch("/api/apps/delete?uuid=" + app.uuid, {
|
||||
fetch("./api/apps/delete?uuid=" + app.uuid, {
|
||||
credentials: 'include',
|
||||
method: "POST"
|
||||
}).then((r) => {
|
||||
@@ -584,7 +584,7 @@
|
||||
},
|
||||
useCover(cover) {
|
||||
this.coverFinderBusy = true;
|
||||
fetch("/api/covers/upload", {
|
||||
fetch("./api/covers/upload", {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
@@ -602,7 +602,7 @@
|
||||
this.editForm["image-path"] = this.editForm["image-path"].toString().replace(/"/g, '');
|
||||
delete this.editForm["launching"];
|
||||
delete this.editForm["id"];
|
||||
fetch("/api/apps", {
|
||||
fetch("./api/apps", {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
body: JSON.stringify(this.editForm),
|
||||
|
||||
@@ -291,7 +291,7 @@
|
||||
}
|
||||
},
|
||||
created() {
|
||||
fetch("/api/config", {
|
||||
fetch("./api/config", {
|
||||
credentials: 'include'
|
||||
})
|
||||
.then((r) => r.json())
|
||||
@@ -393,7 +393,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
return fetch("/api/config", {
|
||||
return fetch("./api/config", {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
body: JSON.stringify(config),
|
||||
@@ -417,7 +417,7 @@
|
||||
setTimeout(() => {
|
||||
this.saved = this.restarted = false;
|
||||
}, 5000);
|
||||
fetch("/api/restart", {
|
||||
fetch("./api/restart", {
|
||||
method: "POST"
|
||||
})
|
||||
.then((resp) => {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<ul>
|
||||
<li v-for="v in fancyLogs.filter(x => x.level === 'Fatal')">{{v.value}}</li>
|
||||
</ul>
|
||||
<a class="btn btn-danger" href="/troubleshooting/#logs">View Logs</a>
|
||||
<a class="btn btn-danger" href="./troubleshooting/#logs">View Logs</a>
|
||||
</div>
|
||||
<!-- Version -->
|
||||
<div class="card p-2 my-4">
|
||||
@@ -101,7 +101,7 @@
|
||||
},
|
||||
async created() {
|
||||
try {
|
||||
let config = await fetch("/api/config").then((r) => r.json());
|
||||
let config = await fetch("./api/config").then((r) => r.json());
|
||||
this.notifyPreReleases = config.notify_pre_releases;
|
||||
this.version = new ApolloVersion(null, config.version);
|
||||
console.log("Version: ", this.version.version)
|
||||
@@ -115,7 +115,7 @@
|
||||
console.error(e);
|
||||
}
|
||||
try {
|
||||
this.logs = (await fetch("/api/logs").then(r => r.text()))
|
||||
this.logs = (await fetch("./api/logs").then(r => r.text()))
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import {createI18n} from "vue-i18n";
|
||||
import en from './public/assets/locale/en.json'
|
||||
|
||||
export default async function() {
|
||||
let r = await (await fetch("/api/configLocale", { credentials: 'include' })).json();
|
||||
let r = await (await fetch("./api/configLocale", { credentials: 'include' })).json();
|
||||
let locale = r.locale ?? "en";
|
||||
document.querySelector('html').setAttribute('lang', locale);
|
||||
let messages = {
|
||||
@@ -12,7 +12,7 @@ export default async function() {
|
||||
};
|
||||
try {
|
||||
if (locale !== 'en') {
|
||||
let r = await (await fetch(`/assets/locale/${locale}.json`, { credentials: 'include' })).json();
|
||||
let r = await (await fetch(`./assets/locale/${locale}.json`, { credentials: 'include' })).json();
|
||||
messages[locale] = r;
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
return;
|
||||
};
|
||||
this.error = null;
|
||||
fetch("/api/password", {
|
||||
fetch("./api/password", {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
body: JSON.stringify(this.passwordData),
|
||||
|
||||
@@ -330,7 +330,7 @@
|
||||
let name = document.querySelector("#name-input").value;
|
||||
document.querySelector("#status").innerHTML = "";
|
||||
let b = JSON.stringify({pin: pin, name: name});
|
||||
fetch("/api/pin", {
|
||||
fetch("./api/pin", {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
body: b
|
||||
@@ -355,7 +355,7 @@
|
||||
requestOTP() {
|
||||
if (this.editingHost) return;
|
||||
|
||||
fetch(`/api/otp?passphrase=${this.passphrase}${this.deviceName && `&deviceName=${this.deviceName}` || ''}`, {
|
||||
fetch(`./api/otp?passphrase=${this.passphrase}${this.deviceName && `&deviceName=${this.deviceName}` || ''}`, {
|
||||
credentials: 'include'
|
||||
})
|
||||
.then(resp => resp.json())
|
||||
@@ -434,7 +434,7 @@
|
||||
name: client.editName,
|
||||
perm: client.editPerm & permissionMapping._all
|
||||
}
|
||||
fetch("/api/clients/update", {
|
||||
fetch("./api/clients/update", {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
body: JSON.stringify(editedClient)
|
||||
@@ -470,7 +470,7 @@
|
||||
client.editPerm ^= permissionMapping[permission];
|
||||
},
|
||||
disconnectClient(uuid) {
|
||||
fetch("/api/clients/disconnect", {
|
||||
fetch("./api/clients/disconnect", {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
body: JSON.stringify({ uuid })
|
||||
@@ -482,7 +482,7 @@
|
||||
},
|
||||
unpairAll() {
|
||||
this.unpairAllPressed = true;
|
||||
fetch("/api/clients/unpair-all", {
|
||||
fetch("./api/clients/unpair-all", {
|
||||
credentials: 'include',
|
||||
method: "POST"
|
||||
})
|
||||
@@ -497,7 +497,7 @@
|
||||
});
|
||||
},
|
||||
unpairSingle(uuid) {
|
||||
fetch("/api/clients/unpair", {
|
||||
fetch("./api/clients/unpair", {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
body: JSON.stringify({ uuid })
|
||||
@@ -510,7 +510,7 @@
|
||||
if (currentEditingClient) {
|
||||
this.cancelEdit(currentEditingClient);
|
||||
}
|
||||
fetch("/api/clients/list", { credentials: 'include' })
|
||||
fetch("./api/clients/list", { credentials: 'include' })
|
||||
.then((response) => response.json())
|
||||
.then((response) => {
|
||||
const clientList = document.querySelector("#client-list");
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"apps": {
|
||||
"actions": "Actions",
|
||||
"add_cmds": "Ajouter des commandes",
|
||||
"add_new": "Ajouter une autre",
|
||||
"add_new": "Ajouter une application",
|
||||
"app_name": "Nom de l'application",
|
||||
"app_name_desc": "Nom de l'application, affiché dans Moonlight",
|
||||
"applications_desc": "Les applications ne sont actualisées qu'au redémarrage du client",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Apollo</title>
|
||||
<link rel="icon" type="image/x-icon" href="/images/apollo.ico">
|
||||
<link rel="icon" type="image/x-icon" href="./images/apollo.ico">
|
||||
<link href="@fortawesome/fontawesome-free/css/all.min.css" rel="stylesheet">
|
||||
<link href="bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="/assets/css/apollo.css" rel="stylesheet" />
|
||||
<link href="./assets/css/apollo.css" rel="stylesheet" />
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
},
|
||||
methods: {
|
||||
refreshLogs() {
|
||||
fetch("/api/logs", { credentials: 'include' })
|
||||
fetch("./api/logs", { credentials: 'include' })
|
||||
.then((r) => r.text())
|
||||
.then((r) => {
|
||||
this.logs = r;
|
||||
@@ -162,7 +162,7 @@
|
||||
},
|
||||
closeApp() {
|
||||
this.closeAppPressed = true;
|
||||
fetch("/api/apps/close", {
|
||||
fetch("./api/apps/close", {
|
||||
credentials: 'include',
|
||||
method: "POST"
|
||||
})
|
||||
@@ -183,7 +183,7 @@
|
||||
setTimeout(() => {
|
||||
this.serverRestarting = false;
|
||||
}, 5000);
|
||||
fetch("/api/restart", {
|
||||
fetch("./api/restart", {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
})
|
||||
@@ -207,7 +207,7 @@
|
||||
quit() {
|
||||
if (window.confirm(this.i18n.t('troubleshooting.quit_apollo_confirm'))) {
|
||||
this.serverQuitting = true;
|
||||
fetch("/api/quit", {
|
||||
fetch("./api/quit", {
|
||||
credentials: 'include',
|
||||
method: "POST",
|
||||
})
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="card p-2">
|
||||
<header>
|
||||
<h1 class="mb-0">
|
||||
<img src="/images/logo-apollo-45.png" height="45" alt="">
|
||||
<img src="./images/logo-apollo-45.png" height="45" alt="">
|
||||
{{ $t('welcome.greeting') }}
|
||||
</h1>
|
||||
</header>
|
||||
@@ -80,7 +80,7 @@
|
||||
};
|
||||
this.error = null;
|
||||
this.loading = true;
|
||||
fetch("/api/password", {
|
||||
fetch("./api/password", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(this.passwordData),
|
||||
}).then((r) => {
|
||||
|
||||
@@ -76,4 +76,3 @@ if (WIN32)
|
||||
# this fixes libcurl linking errors when using non MSYS2 version of CMake
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_SEARCH_START_STATIC 1)
|
||||
endif ()
|
||||
|
||||
|
||||
2
third-party/moonlight-common-c
vendored
2
third-party/moonlight-common-c
vendored
Submodule third-party/moonlight-common-c updated: 84af637de7...40bec19cc1
@@ -39,6 +39,7 @@ export default defineConfig({
|
||||
vue: 'vue/dist/vue.esm-bundler.js'
|
||||
}
|
||||
},
|
||||
base: './',
|
||||
plugins: [vue(), ViteEjsPlugin({ header })],
|
||||
root: resolve(assetsSrcPath),
|
||||
build: {
|
||||
|
||||
Reference in New Issue
Block a user