You are not logged in.

#1 2020-06-28 19:02:28

bmwalters1
Member
Registered: 2020-06-28
Posts: 1

PKGBUILD review request: Moonscraper Chart Editor (Unity3d game)

Hello, I am working on porting this open source software to Linux:
https://github.com/FireFox2000000/Moons … rt-Editor/
and as part of that effort I have written a PKGBUILD file for Arch.

To my knowledge this is the first time a Unity engine game has been packaged from source, and there are a few complications.

Details

This is a game/tool built with the Unity game engine. As such, it is traditionally "compiled" by launching the Unity editor (installed via unityhub) and pressing the "Build Standalone" button.

Thankfully, the build process can be automated by launching the Unity editor in command-line mode (-batchmode).

One major headache is that after launching the Unity editor for the first time, the user has to provision a free license for the Unity editor from Unity's servers. This process involves signing to the Unity website with username/password, completing captcha and email verification, and downloading the license file. The end result is the file $HOME/.local/share/unity3d/Unity/Unity_lic.ulf.

This PKGBUILD assumes that the user will bring their own already-provisioned license file and place it next to the PKGBUILD (following a hint from the Arch Wiki).

One complication is that the user needs to exfiltrate a "license request" file from the editor to kick off the license provisioning flow on the Unity website.
The PKGBUILD file helps with this - if the user places a license file consisting of only the string "request" next to the PKGBUILD, then the PKGBUILD dumps the license request file to $srcdir.

So the user can invoke the PKGBUILD once to obtain a license request, complete the license provisioning on their own, and then run the PKGBUILD again once they have a license file.

The last complication is that Unity always uses the aforementioned location to store the license file. I assume the PKGBUILD user may already have a Unity installation and license that we don't want to clobber, so the entire build process is run inside of a firejail.

Summary

To summarize, here is what goes on when the user builds this software using this PKGBUILD:

1. echo "request" >> Unity_lic.ulf
2. makepkg
3. In Firejail: The PKGBUILD file downloads the appropriate Unity editor version into $srcdir using unityhub. This is around 3 gigabytes.
4. In Firejail: The Unity editor is invoked and a license request file is placed in $srcdir.
5. The user logs in to the Unity website, uploads the license request from $srcdir, and completes the license provisioning flow.
6. mv downloaded-license-file Unity_lic.ulf
7. makepkg
8. If it still exists, the downloaded Unity editor in $srcdir is reused (not downloaded again).
9. In Firejail: The Unity editor is invoked to activate the provisioned license.
10. In Firejail: The Unity editor is invoked to compile the application.
11. makepkg -si

Files

PKGBUILD

# Maintainer: bmwalters <oss at walters dot app>

# NOTE:
# This package requires a Unity engine license file to build.
# Copy an existing activated license file to Unity_lic.ulf next to PKGBUILD,
# or `echo "request" > Unity_lic.ulf` to begin the license activation process.

pkgname=moonscraper-chart-editor-git
_pkgname=moonscraper-chart-editor
pkgver=1.3.1.r361.g6b2a58e9
_curpkgver=1.3.4.1
pkgrel=1
pkgdesc="A song editor for Guitar Hero style rhythm games made in Unity"
url='https://github.com/FireFox2000000/moonscraper-chart-editor'
license=(BSD)
arch=(x86_64 i686)
depends=('mono' 'sdl2' 'ffmpeg' 'libx11' 'gtk3' 'libbass' 'libbass_fx')
makedepends=('git' 'unityhub' 'cmake'
  # runtime dependencies for Unity3d
  'desktop-file-utils' 'xdg-utils' 'gcc-libs' 'lib32-gcc-libs' 'gconf' 'nss'
  'libgl' 'glu' 'libpng12' 'libxtst' 'libpqxx' 'npm' 'intel-tbb'
  # used to isolate home directory files modified by Unity3d
  'firejail')
provides=(moonscraper-chart-editor)
backup=("opt/$pkgname/local_events.txt"
        "opt/$pkgname/global_events.txt"
        "opt/$pkgname/Custom Resources/settings.ini")
source=('git+https://github.com/bmwalters/moonscraper-chart-editor.git#branch=linux-new'
        "$_pkgname.desktop"
        'Unity_lic.ulf::local://Unity_lic.ulf')
sha256sums=('SKIP'
            '393ebe1ee7df6b667d2ff85b82eb1a58c2df7aa8728790cbb260bfa340746a54'
            'SKIP')
_unity3d_version=2018.4.23f1
_unity3d_changeset=c9cf1a90e812

pkgver() {
  cd "$_pkgname"

  printf "%s" "$(git describe --long --tags | sed 's/\([^-]*-g\)/r\1/;s/-/./g')"
}

prepare() {
  # Remove vendored libbass in favor of libbass dependency
  rm -rf "$_pkgname/Moonscraper Chart Editor/Assets/Plugins/Bass Audio/Linux/x64"
  rm -rf "$_pkgname/Moonscraper Chart Editor/Assets/Plugins/Bass Audio/Linux/x86"
  rm -f "$_pkgname/Moonscraper Chart Editor/Assets/Plugins/Bass Audio/Linux/x64.meta"
  rm -f "$_pkgname/Moonscraper Chart Editor/Assets/Plugins/Bass Audio/Linux/x86.meta"

  # We will build this library ourselves
  rm -f "$_pkgname/Moonscraper Chart Editor/Assets/Plugins/Native File Explorer/Linux/x64/libStandaloneFileBrowser.so"
  rm -f "$_pkgname/Moonscraper Chart Editor/Assets/Plugins/Native File Explorer/Linux/x86/libStandaloneFileBrowser.so"
}

build() {
  # Build libStandaloneFileBrowser helper library
  mkdir -p build-sfb && pushd build-sfb
  cmake "$srcdir/$_pkgname/Moonscraper Chart Editor/Assets/Plugins/Native File Explorer/Linux/Source~"
  make
  if [ "${CARCH}" = "i686" ]; then
    _FBARCH=x86
  else
    _FBARCH=x64
  fi
  popd
  cp build-sfb/libStandaloneFileBrowser.so "$_pkgname/Moonscraper Chart Editor/Assets/Plugins/Native File Explorer/Linux/$_FBARCH/libStandaloneFileBrowser.so"

  cp Unity_lic.ulf Unity_lic_physical.ulf

  # Install Unity via unityhub in firejail to avoid clobbering user's existing unityhub configuration.
  firejail --noprofile --whitelist="$(pwd)" sh <<EOF
  # Install appropriate unity3d version via unityhub
  if [ ! -d "$(pwd)"/unity3d/$_unity3d_version ]; then
    mkdir -p unity3d
    unityhub --no-sandbox --headless install-path --set "$(pwd)"/unity3d
    unityhub --no-sandbox --headless install --version $_unity3d_version --changeset $_unity3d_changeset
  fi

  # https://github.com/mono/mono/issues/6752#issuecomment-365212655
  export TERM=xterm

  # Request a manual activation file if the user has no license.
  if [ "$(cat Unity_lic_physical.ulf)" = "request" ]; then
    "$(pwd)"/unity3d/$_unity3d_version/Editor/Unity \
      -batchmode \
      -nographics \
      -silent-crashes \
      -createManualActivationFile \
      -logFile - \
      -quit
    echo Manual activation file written to "$srcdir"/Unity_v$_unity3d_version.alf.
    echo Activate license, save to Unity_lic.ulf, then rerun makepkg.
    echo https://docs.unity3d.com/2018.4/Documentation/Manual/ManualActivationGuide.html
    exit 1
  fi

  # Activate the license file.
  "$(pwd)"/unity3d/$_unity3d_version/Editor/Unity \
    -batchmode \
    -manualLicenseFile Unity_lic_physical.ulf \
    -nographics \
    -silent-crashes \
    -logFile - \
    -quit

  # Build the application using Unity in batch mode
  "$(pwd)"/unity3d/$_unity3d_version/Editor/Unity \
    -batchmode \
    -nographics \
    -silent-crashes \
    -logFile - \
    -projectPath "$_pkgname/Moonscraper Chart Editor" \
    -executeMethod BuildDocumentation.BuildLinux \
    -moonscraperBuildPath "$(pwd)"/build \
    -quit
EOF
}

package() {
  # Install application to /opt
  install -d "$pkgdir"/opt/$pkgname

  cp -a "build/Moonscraper Chart Editor v$_curpkgver Linux (Universal)/." "$pkgdir"/opt/$pkgname

  # Determine desired binary extension from arch
  if [ "${CARCH}" = "i686" ]; then
    _UNITY_ARCH=x86
  else
    _UNITY_ARCH=$CARCH
  fi

  # Install binary symlink and desktop files
  install -d "$pkgdir"/usr/{bin,share/{pixmaps,applications}}

  cat << EOF > "$pkgdir/usr/bin/$_pkgname"
#!/bin/sh
exec "/opt/$pkgname/Moonscraper Chart Editor.$_UNITY_ARCH" "\$@"
EOF
  chmod 755 "$pkgdir/usr/bin/$_pkgname"

  install $_pkgname.desktop "$pkgdir"/usr/share/applications
  ln -s "/opt/$pkgname/Moonscraper Chart Editor_Data/Resources/UnityPlayer.png" "$pkgdir"/usr/share/pixmaps/$_pkgname.png

  # Install licenses
  install -d "$pkgdir"/usr/share/licenses

  install -Dm 644 "$_pkgname/LICENSE" "$pkgdir"/usr/share/licenses/$pkgname/LICENSE
  install -Dm 644 "$_pkgname/Moonscraper Chart Editor/Assets/Documentation/attribution.txt" "$pkgdir"/usr/share/licenses/$pkgname/attribution.txt
}

moonscraper-chart-editor.desktop

[Desktop Entry]
Type=Application
Version=1.0
Name=Moonscraper Chart Editor
Comment=A song editor for Guitar Hero style rhythm games
Path=/opt/moonscraper-chart-editor-git
Exec=moonscraper-chart-editor
Icon=moonscraper-chart-editor
Terminal=false
Categories=Game;

Pedantic comments are welcome in addition to architectural suggestions smile

Thank you for your time.

Last edited by bmwalters1 (2020-06-28 19:05:43)

Offline

#2 2020-07-01 12:23:03

Lone_Wolf
Member
From: Netherlands, Europe
Registered: 2005-10-04
Posts: 11,911

Re: PKGBUILD review request: Moonscraper Chart Editor (Unity3d game)

Welcome to the forum.



PKGBUILDs are intended to be run without user interaction.
Instructions to get  a license should be in documentation like aur comments or a wiki page.

The Unity3D wiki page doesn't mention how to get a license. You clearly understand the process, maybe you could add something to that page.

Firejail in PKGBUILD
Trying to minimize risk of messing up a build system is good, but archlinux already has a great way to do that : build in a clean chroot


Having said those 2 things, your description suggests a different approach may be needed.

Scenario A

User has unity installed and a valid license in the correct location .

A1 build as normal user
This will use the existing unity install & license , I'm assuming unity will be able to build the standalone stuff sucessfull .

A2 build in a clean chroot
Technically the unity installation in the chroot is a new one.
If we use the classic way to setup a chroot we can copy the existing license to the corresponding location in the chroot before starting the build, but will this licensefile be accepted by unity in the chroot ?



Scenario B
User doesn't have unity installed or there's no valid license file present.
How do we get from this to scenario A and is this something the package should handle or the user ?


If the answer to A2 is yes, a package that complies with arch guidelines may be possible.
If the answer to A2 is no, a wiki page with instructions and an example script may be a better solution then  a package.

Last edited by Lone_Wolf (2020-07-01 12:24:18)


Disliking systemd intensely, but not satisfied with alternatives so focusing on taming systemd.


(A works at time B)  && (time C > time B ) ≠  (A works at time C)

Offline

Board footer

Powered by FluxBB