commit c2b9c50c8d8a3d6e13a42494ba0bc3b726b5d133 Author: ascpixi <44982772+ascpixi@users.noreply.github.com> Date: Mon Mar 4 23:17:27 2024 +0100 Clone from "yuzu-emu/yuzu-multiplayer-dedicated" diff --git a/.ci/build.sh b/.ci/build.sh new file mode 100644 index 0000000..d5a0bde --- /dev/null +++ b/.ci/build.sh @@ -0,0 +1,33 @@ +#!/bin/bash -ex + +TOPDIR="$(dirname "$0")" + +git config user.name "github-actions" +git config user.email "github-actions[bot]@users.noreply.github.com" +git am "$TOPDIR"/../patches/*.patch + +CFLAGS="-ftree-vectorize -flto" +if [[ "$(uname -m)" == "aarch64" ]]; then + CFLAGS="$CFLAGS -march=armv8-a+crc+crypto" +elif [[ "$(uname -m)" == "x86_64" ]]; then + # those three of you still using Prescott should just compile this yourselves + CFLAGS="$CFLAGS -march=core2 -mtune=intel" +fi +if [[ "$USE_CCACHE" != '0' ]]; then + echo '[+] Enabled ccache' + ccache -s + export CC='/usr/lib/ccache/gcc' + export CXX='/usr/lib/ccache/g++' +fi + +export CFLAGS +export CXXFLAGS="$CFLAGS" +export LDFLAGS="-flto -fuse-linker-plugin -fuse-ld=gold" + +# build and install dependencies +"$TOPDIR"/deps.sh + +mkdir -p build && cd build +cmake .. -GNinja -DYUZU_USE_BUNDLED_FFMPEG=ON -DYUZU_TESTS=OFF -DENABLE_LIBUSB=OFF -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF -DENABLE_QT=OFF -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=OFF -DUSE_DISCORD_PRESENCE=OFF +ninja yuzu-room +strip ./bin/yuzu-room diff --git a/.ci/deps.sh b/.ci/deps.sh new file mode 100644 index 0000000..007f2b8 --- /dev/null +++ b/.ci/deps.sh @@ -0,0 +1,71 @@ +#!/bin/bash -e + +FMT_VERSION="10.2.1" +JSON_VERSION="3.11.3" +ZLIB_VERSION="1.3" +ZSTD_VERSION="1.5.5" +LZ4_VERSION="1.9.4" +BOOST_VERSION="1.84.0" + +cmake_install() { + cmake . -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON "$@" + ninja install +} + +# $1: url $2: dir name $3: sha256sum +download_extract() { + local filename + filename="$(basename "$1")" + wget "$1" -O "$filename" + echo "$3 $filename" > "$filename".sha256sum + sha256sum -c "$filename".sha256sum + bsdtar xf "$filename" + pushd "$2" +} + +info() { + echo -e "\e[1m--> Downloading and building $1...\e[0m" +} + +info "fmt ${FMT_VERSION}" +download_extract "https://github.com/fmtlib/fmt/releases/download/${FMT_VERSION}/fmt-${FMT_VERSION}.zip" "fmt-${FMT_VERSION}" 312151a2d13c8327f5c9c586ac6cf7cddc1658e8f53edae0ec56509c8fa516c9 +cmake_install -DFMT_DOC=OFF -DFMT_TEST=OFF +popd + +info "nlohmann_json ${JSON_VERSION}" +download_extract "https://github.com/nlohmann/json/releases/download/v${JSON_VERSION}/json.tar.xz" json d6c65aca6b1ed68e7a182f4757257b107ae403032760ed6ef121c9d55e81757d +cmake_install -DJSON_BuildTests=OFF +popd + +info "zlib ${ZLIB_VERSION}" +download_extract "https://github.com/madler/zlib/releases/download/v${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.xz" "zlib-${ZLIB_VERSION}" 8a9ba2898e1d0d774eca6ba5b4627a11e5588ba85c8851336eb38de4683050a7 +cmake_install -DCMAKE_POLICY_DEFAULT_CMP0069=NEW +# delete shared libraies as we can't use them in the final image +rm -v /usr/local/lib/libz.so* +popd + +info "zstd ${ZSTD_VERSION}" +download_extract "https://github.com/facebook/zstd/releases/download/v${ZSTD_VERSION}/zstd-${ZSTD_VERSION}.tar.gz" "zstd-${ZSTD_VERSION}"/build/cmake 9c4396cc829cfae319a6e2615202e82aad41372073482fce286fac78646d3ee4 +cmake_install -DZSTD_BUILD_PROGRAMS=OFF -DBUILD_TESTING=OFF -GNinja -DZSTD_BUILD_STATIC=ON -DZSTD_BUILD_SHARED=OFF +popd + +info "lz4 ${LZ4_VERSION}" +download_extract "https://github.com/lz4/lz4/archive/refs/tags/v${LZ4_VERSION}.tar.gz" "lz4-${LZ4_VERSION}/build/cmake" 0b0e3aa07c8c063ddf40b082bdf7e37a1562bda40a0ff5272957f3e987e0e54b +cmake_install -DLZ4_BUILD_CLI=OFF -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DLZ4_BUILD_LEGACY_LZ4C=OFF +# we need to adjust the exported name of the static library +cat << EOF >> /usr/local/lib/cmake/lz4/lz4Targets.cmake +# Injected commands by yuzu-room builder script +add_library(lz4::lz4 ALIAS LZ4::lz4_static) +EOF +popd + +info "boost ${BOOST_VERSION}" +download_extract "https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.xz" "boost-${BOOST_VERSION}" 2e64e5d79a738d0fa6fb546c6e5c2bd28f88d268a2a080546f74e5ff98f29d0e +# Boost use its own ad-hoc build system +# we only enable what yuzu needs +./bootstrap.sh --with-libraries=context,container,system,headers +./b2 -j "$(nproc)" install --prefix=/usr/local +popd + +# fake xbyak for non-amd64 (workaround a CMakeLists bug in yuzu) +echo '!' > /usr/local/lib/libxbyak.a diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b9fe9e6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,97 @@ +name: "Yuzu Rooms Docker Image CI" + +on: + push: + branches: ["*"] + tags: ["*"] + pull_request: + branches: [master] + workflow_dispatch: + inputs: {} + schedule: + - cron: "0 7 * * 0" + +env: + REGISTRY_IMAGE: yuzuemu/yuzu-multiplayer-dedicated + +jobs: + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + platform: + - linux/amd64 + - linux/arm64 + steps: + - uses: actions/checkout@v4 + - name: Create Docker Image Label + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_IMAGE }} + tags: type=raw,value=latest,enable={{is_default_branch}} + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker BuildX + uses: docker/setup-buildx-action@v3 + - name: Login to DockerHub + uses: docker/login-action@v3 + if: (github.ref == 'refs/heads/master') && (github.repository == 'yuzu-emu/yuzu-multiplayer-dedicated') + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build Image + id: build + uses: docker/build-push-action@v5 + with: + platforms: ${{ matrix.platform }} + push: ${{ (github.ref == 'refs/heads/master') && (github.repository == 'yuzu-emu/yuzu-multiplayer-dedicated') }} + outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true + - name: Export digest + run: | + mkdir -p /tmp/digests + digest="${{ steps.build.outputs.digest }}" + cache_name="digests-${{ matrix.platform }}" + echo "CACHE_NAME=${cache_name/\//-}" >> $GITHUB_ENV + touch "/tmp/digests/${digest#sha256:}" + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: ${{ env.CACHE_NAME }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + upload: + runs-on: ubuntu-latest + if: (github.ref == 'refs/heads/master') && (github.repository == 'yuzu-emu/yuzu-multiplayer-dedicated') + needs: + - build + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + pattern: digests-* + path: /tmp/digests + merge-multiple: true + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Create Docker Image Label + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY_IMAGE }} + tags: type=raw,value=latest,enable={{is_default_branch}} + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d838493 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,66 @@ +# syntax=docker/dockerfile:1.3 +ARG UBUNTU_RELEASE=23.10 +ARG USER=ubuntu UID=101 GROUP=ubuntu GID=101 + +### BOILERPLATE BEGIN ### + +FROM golang:1.20 AS chisel +ARG UBUNTU_RELEASE +RUN git clone -b ubuntu-${UBUNTU_RELEASE} https://github.com/canonical/chisel-releases /opt/chisel-releases \ + && git clone --depth 1 -b main https://github.com/canonical/chisel /opt/chisel +WORKDIR /opt/chisel +RUN go generate internal/deb/version.go \ + && go build ./cmd/chisel + +FROM ubuntu:$UBUNTU_RELEASE AS builder +SHELL ["/bin/bash", "-oeux", "pipefail", "-c"] +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates \ + && apt-get clean -y \ + && rm -rf /var/lib/apt/lists/* +COPY --from=chisel /opt/chisel/chisel /usr/bin/ + +FROM builder AS rootfs-prep +ARG USER UID GROUP GID +RUN mkdir -p /rootfs/etc \ + && echo "$GROUP:x:$GID:" >/rootfs/etc/group \ + && echo "$USER:x:$UID:$GID::/nohome:/noshell" >/rootfs/etc/passwd + +FROM scratch AS image-prep +ARG UID GID +USER $UID:$GID + +### BOILERPLATE END ### + +FROM ubuntu:$UBUNTU_RELEASE AS build +ENV DEBIAN_FRONTEND=noninteractive +ARG USE_CCACHE +RUN apt-get update && apt-get -y full-upgrade && \ + apt-get install -y build-essential wget git ccache ninja-build libssl-dev pkg-config libarchive-tools \ + cmake cmake-data +COPY . /root/build-files + +RUN --mount=type=cache,id=ccache,target=/root/.ccache \ + git clone --depth 1000 -j4 --recursive https://github.com/yuzu-emu/yuzu-mainline.git /root/yuzu-mainline && \ + cd /root/yuzu-mainline && /root/build-files/.ci/build.sh + +FROM rootfs-prep AS sliced-deps +COPY --from=chisel /opt/chisel-releases /opt/chisel-releases +RUN chisel cut --release /opt/chisel-releases --root /rootfs \ + base-files_base \ + base-files_release-info \ + ca-certificates_data \ + libgcc-s1_libs \ + libc6_libs \ + libssl3_libs \ + libstdc++6_libs \ + openssl_config \ + openssl_data + +FROM image-prep AS final +COPY --from=sliced-deps /rootfs / +LABEL maintainer="yuzuemu" +# Create app directory +WORKDIR /usr/src/app +COPY --from=build /root/yuzu-mainline/build/bin/yuzu-room /usr/src/app +ENTRYPOINT [ "/usr/src/app/yuzu-room" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..50aeecb --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# yuzu Multiplayer Dedicated Lobby + +Quickly stand up new dedicated multiplayer lobbies that will be broadcasted on yuzu. + +## Usage +``` +sudo docker run -d \ + --publish 5000:5000/udp \ + yuzuemu/yuzu-multiplayer-dedicated \ + --room-name "(COUNTRY) (REGION) - GAME TITLE" \ + --preferred-game "GAME TITLE" \ + --preferred-game-id "TITLE ID" \ + --port 5000 \ + --max_members 4 \ + --token "YUZU ACCOUNT TOKEN" \ + --enable-yuzu-mods \ + --web-api-url https://api.yuzu-emu.org +``` + +**Please note, the token format has changed as of 11/1/2019.** + +**You can retrieve your token from https://profile.yuzu-emu.org/** + +Room name should follow the below format. +If multiple servers are stood up, `Server 1`, `Server 2` format should be used. +``` +USA East - Super Smash Bros. Ultimate - Server 1 +USA East - Super Smash Bros. Ultimate - Server 2 +USA East - Mario Kart 8 Deluxe - Server 1 +USA East - Mario Kart 8 Deluxe - Server 2 +USA East - Splatoon 2 - Server 1 +USA East - Splatoon 2 - Server 2 +USA East - Pokémon Sword and Shield - Server 1 +USA East - Pokémon Sword and Shield - Server 2 +USA East - Animal Crossing: New Horizons - Server 1 +USA East - Animal Crossing: New Horizons - Server 2 +USA East - Pokémon Legends: Arceus +USA East - Pokémon: Let’s Go +USA East - Puyo Puyo Tetris +USA East - Super Mario 3D World + Bowser's Fury +USA East - Super Mario Party +USA East - MONSTER HUNTER RISE +``` diff --git a/patches/.gitkeep b/patches/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/patches/0001-bypass-extra-deps.patch b/patches/0001-bypass-extra-deps.patch new file mode 100644 index 0000000..4c55649 --- /dev/null +++ b/patches/0001-bypass-extra-deps.patch @@ -0,0 +1,61 @@ +From 275b6282c3c9bd14cbaa7fe13c0be0c342a80c55 Mon Sep 17 00:00:00 2001 +From: liushuyu +Date: Mon, 15 Aug 2022 23:32:31 -0600 +Subject: [PATCH] build: bypass extra dependency checks + +--- + externals/CMakeLists.txt | 2 +- + src/video_core/CMakeLists.txt | 6 +++--- + src/video_core/host_shaders/CMakeLists.txt | 6 +++--- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt +index 9eebc7d65..a66f4373b 100644 +--- a/externals/CMakeLists.txt ++++ b/externals/CMakeLists.txt +@@ -139,7 +139,7 @@ endif() + + # FFMpeg + if (YUZU_USE_BUNDLED_FFMPEG) +- add_subdirectory(ffmpeg) ++ #add_subdirectory(ffmpeg) + set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE) + set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE) + set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE) +diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt +index cf9266d54..bef40788c 100644 +--- a/src/video_core/CMakeLists.txt ++++ b/src/video_core/CMakeLists.txt +@@ -290,9 +290,9 @@ create_target_directory_groups(video_core) + target_link_libraries(video_core PUBLIC common core) + target_link_libraries(video_core PUBLIC glad shader_recompiler stb bc_decoder) + +-if (YUZU_USE_BUNDLED_FFMPEG AND NOT (WIN32 OR ANDROID)) +- add_dependencies(video_core ffmpeg-build) +-endif() ++#if (YUZU_USE_BUNDLED_FFMPEG AND NOT (WIN32 OR ANDROID)) ++# add_dependencies(video_core ffmpeg-build) ++#endif() + + target_include_directories(video_core PRIVATE ${FFmpeg_INCLUDE_DIR}) + target_link_libraries(video_core PRIVATE ${FFmpeg_LIBRARIES}) +diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt +index 6b912027f..a65022962 100644 +--- a/src/video_core/host_shaders/CMakeLists.txt ++++ b/src/video_core/host_shaders/CMakeLists.txt +@@ -68,9 +68,9 @@ set(SHADER_FILES + ) + + find_program(GLSLANGVALIDATOR "glslangValidator") +-if ("${GLSLANGVALIDATOR}" STREQUAL "GLSLANGVALIDATOR-NOTFOUND") +- message(FATAL_ERROR "Required program `glslangValidator` not found.") +-endif() ++#if ("${GLSLANGVALIDATOR}" STREQUAL "GLSLANGVALIDATOR-NOTFOUND") ++# message(FATAL_ERROR "Required program `glslangValidator` not found.") ++#endif() + + set(GLSL_FLAGS "") + set(SPIR_V_VERSION "spirv1.3") +-- +2.42.0 +