Compare commits
364 Commits
v0.3.7
...
core-compare
| Author | SHA1 | Date | |
|---|---|---|---|
| e4868018f1 | |||
| f2af4a69d5 | |||
| b5b97b187a | |||
| c6ec9c0686 | |||
| eb6dd8068e | |||
| 30993dd73a | |||
| 363131c175 | |||
| 41b510e7c5 | |||
| a6da96cf82 | |||
| dcfcf8bc27 | |||
| 86c240f669 | |||
| 56b14ab54c | |||
| 7dee6c3989 | |||
| b86f520ee7 | |||
| 31ae8cbc57 | |||
| e8f10693c7 | |||
| cb07131fbb | |||
| 3392fe8d62 | |||
| bc7efed0ba | |||
| e80e202f7b | |||
| db9bd5d9ca | |||
| 685aa597c7 | |||
| ed9d9cbc0d | |||
| 3044f406c4 | |||
| 7e596c1509 | |||
| 7e239ae2ae | |||
| 84681fdd0d | |||
| 2d3514de7f | |||
| 768064a2e1 | |||
| df426f12cf | |||
| a0608384d9 | |||
| d94d6ce0a9 | |||
| a6d5a8cfab | |||
| d65b23f49f | |||
| 932b6b6aa2 | |||
| 8dccc6d72e | |||
| b5b596ca5d | |||
| a075ed734b | |||
| 48baa1bed0 | |||
| 4e46452d9b | |||
| 4ff1272403 | |||
| 7c6b2392bc | |||
| ccbd6bc772 | |||
| 0afc565bda | |||
| 81b26274c2 | |||
| 895438d83d | |||
| e943e86447 | |||
| 15014408c1 | |||
| c6b9f5b2a1 | |||
| 3a58264bf6 | |||
| 559cb6ba37 | |||
| 73f97dec3e | |||
| 3c8adb3898 | |||
| 1111e94e17 | |||
| 3158404408 | |||
| 4fc3177c1b | |||
| 3c95a91edb | |||
| 9c5b6f1ec6 | |||
| fdd46b04eb | |||
| a052239ffa | |||
| 7c8f53eced | |||
| 7f55b61721 | |||
| 8d3f2d4d88 | |||
| 5cfe3489a7 | |||
| 5035c53784 | |||
| e68f2b91cd | |||
| dbca21883b | |||
| bbad41b1a9 | |||
| a52073487f | |||
| bd0fe08545 | |||
| b36e8223f9 | |||
| 8af850ba29 | |||
| 51e044e68c | |||
| e6e67058c7 | |||
| ea8e9d6227 | |||
| 23a0e517fb | |||
| 994a87e871 | |||
| 2aa1a5fe80 | |||
| 6fb6fa59ad | |||
| 7713a9ec86 | |||
| 0f7e89dd57 | |||
| b4ad3f89f6 | |||
| 53d6dcbefc | |||
| 671eba964b | |||
| d21e6bb532 | |||
| b6e1737007 | |||
| 30586fa637 | |||
| a0ec85c7af | |||
| 7581316162 | |||
| f0aa87d0bb | |||
| b4c33ceae8 | |||
| 2c146d7f15 | |||
| 005db96f02 | |||
| 4cbecea0c3 | |||
| c70f59d7b6 | |||
| edbce2e415 | |||
| edc92b7b15 | |||
| b994902ed9 | |||
| 79c9ea193c | |||
| a45c3ba7f3 | |||
| 7873de64e0 | |||
| bfb7953c91 | |||
| b0acaaa681 | |||
| 92e26d6980 | |||
| 6624708348 | |||
| a327923ecf | |||
| dd521eac70 | |||
| 180877a518 | |||
| 9039a96fef | |||
| f3f8085d70 | |||
| 4b99d9de67 | |||
| d0928b5124 | |||
| 697b35808c | |||
| 5f2d8ed804 | |||
| 2c92dbeb8e | |||
| 251755a4ba | |||
| ece590e760 | |||
| 9e827f97f2 | |||
| 0e2a1ba3d9 | |||
| e00cfb4226 | |||
| 2d64acdcfe | |||
| 010035d697 | |||
| 37754e5cba | |||
| 4ab78b79c3 | |||
| 6c4ce4fb63 | |||
| c3c4dedebb | |||
| fb640cad8e | |||
| 45cb32b429 | |||
| 6c66268002 | |||
| 1e03d59592 | |||
| 8fbcf92e2d | |||
| 422f7d0801 | |||
| 38b946926a | |||
| 01dbc476b3 | |||
| 558a48f64d | |||
| 79ad4a9b29 | |||
| cc9975bf02 | |||
| 4cfa8fdd29 | |||
| 3a3b17001e | |||
| 295040ed56 | |||
| 54f6723d96 | |||
| 44e5395ed3 | |||
| d499c1a2d4 | |||
| d4a29dd609 | |||
| bc68f99693 | |||
| aa7cfc3969 | |||
| 9f4dfbb146 | |||
| ee76297fc0 | |||
| 0546ea3255 | |||
| df6870c990 | |||
| 07158dadf6 | |||
| 9bbe27e169 | |||
| aa72d3defc | |||
| 5d12991e6e | |||
| 1c5f22c18a | |||
| 7ed0245969 | |||
| ea3830f784 | |||
| 5fdfbf50d7 | |||
| 5d1f17fa0b | |||
| 70623111e7 | |||
| 148eeb7f07 | |||
| a688644a14 | |||
| 76c76b2661 | |||
| 696977ee83 | |||
| 3d076cfacd | |||
| f3df6c4ceb | |||
| d691498642 | |||
| eb8c5469f3 | |||
| 829713066b | |||
| ec6fa2aa36 | |||
| c1643aff28 | |||
| ec4f65ffa0 | |||
| fdbcc928ee | |||
| 75e5e53589 | |||
| 4233d317ac | |||
| 7476c92298 | |||
| e0a5205db5 | |||
| d20d6c4069 | |||
| eecbe5753d | |||
| 8e6853d74e | |||
| c00534d739 | |||
| 2cd2098460 | |||
| edf8dbca70 | |||
| b9dfabf2e6 | |||
| 29bf915919 | |||
| 99036b797f | |||
| 3987f6c9df | |||
| efc8e08c02 | |||
| 369596490f | |||
| 8ad727b33f | |||
| a760cd5412 | |||
| 409a42ec3d | |||
| be21461312 | |||
| 1cf1111a62 | |||
| f2246e3293 | |||
| 2283bd1bb2 | |||
| e69e251c5c | |||
| 16276852b2 | |||
| f4cf856ef5 | |||
| 45cf5a8663 | |||
| 77187d4bde | |||
| 662023c24d | |||
| df68694645 | |||
| c1e0a04dd1 | |||
| 87587426ca | |||
| 4065d12158 | |||
| 7cf3437542 | |||
| 6aff463b10 | |||
| 04ae630418 | |||
| 4bd2af5cc8 | |||
| 1c9dca25f9 | |||
| 86dfb96937 | |||
| 34915876e5 | |||
| ad06ffeeca | |||
| 7ac7bed45a | |||
| af31b8f8ba | |||
| c3528f99cd | |||
| 63906086b4 | |||
| 63441c34aa | |||
| 6a50c09517 | |||
| 7c46d9ef41 | |||
| fd2f0ea18e | |||
| 72574046ed | |||
| e8f0850eb2 | |||
| 44f8db26c7 | |||
| b3664ea00e | |||
| ed9f89a14d | |||
| 427341977c | |||
| a8b4230368 | |||
| 18a42f2363 | |||
| 938f457fea | |||
| d005e24f51 | |||
| 63c8dfd530 | |||
| 6d1da7514c | |||
| 06164d41b1 | |||
| cd54058e1a | |||
| 850ad78d3a | |||
| bf0d24d967 | |||
| 3db473f0df | |||
| d842baa2c5 | |||
| 86db43aab4 | |||
| 4397a0c614 | |||
| 898e1596b3 | |||
| 66e08de2fe | |||
| 7b73254ad2 | |||
| 9bd77efbdb | |||
| aaf42ea8b9 | |||
| 57c5af0f30 | |||
| 43c3e55466 | |||
| ffbd84df82 | |||
| 25ee5f2ca1 | |||
| f223b88803 | |||
| cd56680e38 | |||
| b9e1e230f9 | |||
| eb8294363a | |||
| d9e2ed2b9a | |||
| 81015e086c | |||
| a0e31029d1 | |||
| 53f87d0793 | |||
| 1e6c906300 | |||
| b76023209c | |||
| b4c7821630 | |||
| e86261e2dc | |||
| 7534c5bb3c | |||
| 7d5eec2d41 | |||
| 69b8461a87 | |||
| 32d2a12331 | |||
| ce8de27fb5 | |||
| 9c64d647ad | |||
| 726861dfaa | |||
| 51dea638c9 | |||
| 298a717225 | |||
| 27b2bc8387 | |||
| 6f6310c776 | |||
| e45fcdfb3e | |||
| ea02f68abe | |||
| 65d7d149f1 | |||
| c5f23f8b71 | |||
| ba327ce1c6 | |||
| 583687cfe1 | |||
| 19eda69468 | |||
| 4b3f979a74 | |||
| d171d62609 | |||
| 5ba195d32e | |||
| 950aa60fca | |||
| 3547e9bf53 | |||
| 5dbf6cfb2e | |||
| fb12f6432b | |||
| 5b61f811da | |||
| fe0fa0b527 | |||
| ba371f1349 | |||
| 38ec62c238 | |||
| 942c2ee1b0 | |||
| 2a7d8aa4d2 | |||
| b166eac200 | |||
| c06316f4aa | |||
| 09d96d9e4d | |||
| 66703970b6 | |||
| 0d3314a39b | |||
| 748492cc68 | |||
| e18ad31c53 | |||
| 0dd297f0f8 | |||
| 0da4becd46 | |||
| d284911d4a | |||
| e772eb3906 | |||
| 577ee4c3e0 | |||
| c534df8303 | |||
| a36c8f7de8 | |||
| dfb5f1b687 | |||
| d8eea015fd | |||
| f17b7eb2c9 | |||
| 33146626a9 | |||
| 78e12f774d | |||
| 689d8debb1 | |||
| 8be1ed8af5 | |||
| 0fabdb3f3a | |||
| 7a64e7e479 | |||
| 8c1589d7cd | |||
| 5a74b137f2 | |||
| 52ba182610 | |||
| b07eb79609 | |||
| 4e3915f527 | |||
| 9f620f276d | |||
| e3787b5ccf | |||
| 3d81a052c6 | |||
| 6353be1599 | |||
| bc6ee4877b | |||
| 6b38cc3740 | |||
| 9285fb9fdf | |||
| f5c609413a | |||
| a304f11b1d | |||
| e10ac1086f | |||
| 4533ed61ac | |||
| 235e41653d | |||
| 433479b1c3 | |||
| 2b4736f224 | |||
| 41f1dcf9d2 | |||
| 45b97cf39b | |||
| 95b1225219 | |||
| 70f6c40b26 | |||
| 43bc54fca9 | |||
| a5ec31ffef | |||
| 81cbf82ddc | |||
| 6cea506c6f | |||
| d7d49f261d | |||
| 4692a5c0b7 | |||
| d32ea32f1e | |||
| f5f053cc4e | |||
| bb3c6dc9fc | |||
| 496d4de1de | |||
| 71f8437ecb | |||
| e7767105d6 | |||
| 9cfda8514e | |||
| e0c6700a4d | |||
| 12bf158398 | |||
| ea01c86821 | |||
| 96459432a6 | |||
| 089194c663 | |||
| 7a70227535 | |||
| 7adfb3123b | |||
| 1d28075601 | |||
| af7aa688bb | |||
| beb524f523 | |||
| 18c9c151a8 |
@@ -6,19 +6,16 @@ jobs:
|
||||
Linux:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: hendrikmuhs/ccache-action@v1.2.5
|
||||
- uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: Linux
|
||||
- name: Install Packages
|
||||
run: |
|
||||
sudo apt-get purge grub\* --yes --allow-remove-essential
|
||||
sudo add-apt-repository ppa:okirby/qt6-backports --yes
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get upgrade
|
||||
sudo apt-get -y install cmake ninja-build libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt6-base-dev libqt6svg6-dev build-essential nasm git zip appstream
|
||||
sudo apt-get -y install cmake ninja-build libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt6-base-dev libqt6svg6-dev libvulkan-dev build-essential nasm git zip appstream
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
echo "GIT_REVISION=$(git describe --tags --always)" >> $GITHUB_ENV
|
||||
@@ -26,18 +23,24 @@ jobs:
|
||||
run: |
|
||||
mkdir Build Build/AppImage Bin/ -p
|
||||
export src_dir="$(pwd)"
|
||||
export build_dir="$(pwd)/build"
|
||||
export build_dir="$(pwd)/Build/AppImage"
|
||||
export bin_dir="$(pwd)/Bin/AppImage"
|
||||
cmake -S "$src_dir" -B "$build_dir" -DCMAKE_BUILD_TYPE="Release" -DPORTABLE_INSTALL="OFF" -DUPDATER=ON -DAPPIMAGE_UPDATER=ON -DCMAKE_INSTALL_PREFIX="/usr" -G "Ninja"
|
||||
cmake -S "$src_dir" -B "$build_dir" -DCMAKE_BUILD_TYPE="Release" \
|
||||
-DUSE_ANGRYLION=ON \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DCMAKE_INSTALL_LIBDIR="lib" \
|
||||
-DPORTABLE_INSTALL="OFF" \
|
||||
-DUPDATER=ON -DAPPIMAGE_UPDATER=ON \
|
||||
-G "Ninja"
|
||||
cmake --build "$build_dir"
|
||||
cmake --install "$build_dir" --prefix="$bin_dir/usr"
|
||||
cmake --install "$build_dir" --strip --prefix="$bin_dir/usr"
|
||||
shell: bash
|
||||
- name: Create AppImage
|
||||
run: |
|
||||
./Package/AppImage/Create.sh
|
||||
shell: bash
|
||||
- name: Upload RMG (AppImage)
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: RMG-Portable-Linux64-${{ env.GIT_REVISION }}
|
||||
path: Bin/*.AppImage
|
||||
@@ -45,10 +48,10 @@ jobs:
|
||||
Windows:
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: hendrikmuhs/ccache-action@v1.2.5
|
||||
- uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: Windows
|
||||
- uses: msys2/setup-msys2@v2
|
||||
@@ -71,6 +74,7 @@ jobs:
|
||||
mingw-w64-x86_64-libsamplerate
|
||||
mingw-w64-x86_64-nasm
|
||||
mingw-w64-x86_64-minizip
|
||||
mingw-w64-x86_64-vulkan-headers
|
||||
git
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
@@ -82,13 +86,16 @@ jobs:
|
||||
shell: msys2 {0}
|
||||
- name: Create Installer
|
||||
run: .\Build\Release\Source\Installer\CreateInstaller.bat
|
||||
- name: Configure RMG (Portable)
|
||||
run: touch Bin/Release/portable.txt
|
||||
shell: msys2 {0}
|
||||
- name: Upload RMG (Portable)
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: RMG-Portable-Windows64-${{ env.GIT_REVISION }}
|
||||
path: Bin/Release/*
|
||||
- name: Upload RMG (Installer)
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: RMG-Setup-Windows64-${{ env.GIT_REVISION }}
|
||||
path: Bin/*.exe
|
||||
|
||||
@@ -8,8 +8,15 @@ Package/ArchLinux/pkg/
|
||||
Package/ArchLinux/rmg/
|
||||
Package/ArchLinux/src/
|
||||
Package/ArchLinux/*.pkg.*
|
||||
# Fedora Package
|
||||
Package/Fedora/*.rpm
|
||||
Package/Fedora/*.tar.gz
|
||||
Package/Fedora/results_*/
|
||||
# Clangd compile_commands.json
|
||||
compile_commands.json
|
||||
# AppImage
|
||||
squashfs-root
|
||||
*.AppImage
|
||||
*.AppImage
|
||||
# 3rdParty Build
|
||||
Source/3rdParty/mupen64plus-core/src/asm_defines/asm_defines_gas.h
|
||||
Source/3rdParty/mupen64plus-core/src/asm_defines/asm_defines_nasm.h
|
||||
@@ -4,23 +4,37 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
option(PORTABLE_INSTALL "Portable Installation" ON)
|
||||
option(NO_GIT_CLONE "Disables git clone usage for 3rdParty dependencies" OFF)
|
||||
option(UPDATER "Enables updater" ${PORTABLE_INSTALL})
|
||||
option(UPDATER "Enables updater" ${WIN32})
|
||||
option(APPIMAGE_UPDATER "Enables AppImage updater" OFF)
|
||||
option(DISCORD_RPC "Enables Discord Rich Presence" ON)
|
||||
option(DRAG_DROP "Enables drag and drop" ON)
|
||||
option(VRU "Enables VRU support in RMG-Input" ON)
|
||||
option(USE_CCACHE "Enables usage of ccache when ccache has been found" ON)
|
||||
option(FORCE_XCB "Forces Qt to use the xcb platform on linux" ${LINUX})
|
||||
option(USE_LTO "Enables building with LTO/IPO when compiler supports it" ON)
|
||||
option(NO_ASM "Disables the usage of assembly in the mupen64plus-core" OFF)
|
||||
option(NO_RUST "Disables the building of rust subprojects" OFF)
|
||||
option(USE_LIBFMT "Enables usage of libfmt instead of detecting whether std::format is supported" OFF)
|
||||
option(USE_ANGRYLION "Enables building angrylion-rdp-plus which uses a non-GPL compliant license" OFF)
|
||||
|
||||
project(RMG)
|
||||
|
||||
find_package(Git REQUIRED)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --tags --always
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE GIT_VERSION
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
find_package(Git)
|
||||
if (GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --tags --always
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
RESULT_VARIABLE GIT_RESULT
|
||||
OUTPUT_VARIABLE GIT_VERSION
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
endif(GIT_FOUND)
|
||||
if (NOT GIT_FOUND OR NOT ${GIT_RESULT} EQUAL 0)
|
||||
if (NOT ${GIT_RESULT} EQUAL 0)
|
||||
message(WARNING "git failed to retrieve the current revision, falling back to VERSION file!")
|
||||
endif()
|
||||
file(STRINGS "VERSION" GIT_VERSION)
|
||||
endif()
|
||||
|
||||
if (USE_CCACHE)
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
@@ -31,7 +45,40 @@ if (USE_CCACHE)
|
||||
endif(CCACHE_FOUND)
|
||||
endif(USE_CCACHE)
|
||||
|
||||
if (NOT PORTABLE_INSTALL AND (WIN32 OR MSYS))
|
||||
if (USE_LTO)
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT ENABLE_IPO)
|
||||
|
||||
# ensure we don't enable LTO on Debug builds
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
if(ENABLE_IPO)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
||||
endif(ENABLE_IPO)
|
||||
endif()
|
||||
endif(USE_LTO)
|
||||
|
||||
if (NOT USE_LIBFMT)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <format>
|
||||
int main(void)
|
||||
{
|
||||
std::string str = std::format(\"number: {}\", 10);
|
||||
return 0;
|
||||
}" HAVE_STDFORMAT)
|
||||
|
||||
# fallback to libfmt if std::format
|
||||
# isn't supported in the compiler
|
||||
if (NOT HAVE_STDFORMAT)
|
||||
set(USE_LIBFMT ON)
|
||||
endif(NOT HAVE_STDFORMAT)
|
||||
endif(NOT USE_LIBFMT)
|
||||
|
||||
if (NOT PORTABLE_INSTALL AND WIN32)
|
||||
message(WARNING "Not-Portable build not supported on windows, re-enabling PORTABLE_INSTALL!")
|
||||
set(PORTABLE_INSTALL ON)
|
||||
endif()
|
||||
@@ -41,17 +88,17 @@ if (NOT PORTABLE_INSTALL AND UPDATER AND NOT APPIMAGE_UPDATER)
|
||||
set(UPDATER OFF)
|
||||
endif()
|
||||
|
||||
if (APPIMAGE_UPDATER AND (WIN32 OR MSYS))
|
||||
if (APPIMAGE_UPDATER AND WIN32)
|
||||
message(WARNING "AppImage updater not supported on windows, disabling APPIMAGE_UPDATER!")
|
||||
set(APPIMAGE_UPDATER OFF)
|
||||
endif()
|
||||
|
||||
if (UPDATER AND NOT (WIN32 OR MSYS) AND NOT APPIMAGE_UPDATER)
|
||||
if (UPDATER AND NOT WIN32 AND NOT APPIMAGE_UPDATER)
|
||||
message(WARNING "Only AppImage updater is supported on linux, disabling UPDATER!")
|
||||
set(UPDATER OFF)
|
||||
endif()
|
||||
|
||||
if (FORCE_XCB AND (WIN32 OR MSYS))
|
||||
if (FORCE_XCB AND WIN32)
|
||||
message(WARNING "XCB Qt platform not supported on windows, disabling FORCE_XCB!")
|
||||
set(FORCE_XCB OFF)
|
||||
endif()
|
||||
@@ -60,27 +107,39 @@ if (PORTABLE_INSTALL)
|
||||
set(CMAKE_INSTALL_PREFIX "")
|
||||
set(INSTALL_PATH "Bin/${CMAKE_BUILD_TYPE}")
|
||||
set(RMG_INSTALL_PATH "${INSTALL_PATH}")
|
||||
set(SYSTEM_LIB_INSTALL_PATH "${INSTALL_PATH}")
|
||||
set(LIB_INSTALL_PATH "${INSTALL_PATH}")
|
||||
set(CORE_INSTALL_PATH "${INSTALL_PATH}/Core")
|
||||
set(PLUGIN_INSTALL_PATH "${INSTALL_PATH}/Plugin")
|
||||
set(DATA_INSTALL_PATH "${INSTALL_PATH}/Data")
|
||||
set(INSTALL_DESKTOP_FILE OFF)
|
||||
else()
|
||||
set(RMG_INSTALL_PATH "bin")
|
||||
set(CORE_INSTALL_PATH "lib/RMG/Core")
|
||||
set(PLUGIN_INSTALL_PATH "lib/RMG/Plugin")
|
||||
set(DATA_INSTALL_PATH "share/RMG")
|
||||
include(GNUInstallDirs)
|
||||
set(RMG_INSTALL_PATH "${CMAKE_INSTALL_BINDIR}")
|
||||
set(SYSTEM_LIB_INSTALL_PATH "${CMAKE_INSTALL_LIBDIR}")
|
||||
set(LIB_INSTALL_PATH "${SYSTEM_LIB_INSTALL_PATH}/RMG")
|
||||
set(CORE_INSTALL_PATH "${SYSTEM_LIB_INSTALL_PATH}/RMG/Core")
|
||||
set(PLUGIN_INSTALL_PATH "${SYSTEM_LIB_INSTALL_PATH}/RMG/Plugin")
|
||||
set(DATA_INSTALL_PATH "${CMAKE_INSTALL_DATADIR}/RMG")
|
||||
set(INSTALL_DESKTOP_FILE ON)
|
||||
set(APPDATA_INSTALL_PATH "share/metainfo/")
|
||||
set(DESKTOP_INSTALL_PATH "share/applications")
|
||||
set(ICON_INSTALL_PATH "share/icons/hicolor/scalable/apps/")
|
||||
set(APPDATA_INSTALL_PATH "${CMAKE_INSTALL_DATADIR}/metainfo/")
|
||||
set(DESKTOP_INSTALL_PATH "${CMAKE_INSTALL_DATADIR}/applications")
|
||||
set(ICON_INSTALL_PATH "${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps/")
|
||||
endif()
|
||||
|
||||
add_subdirectory(Source/3rdParty)
|
||||
add_subdirectory(Source/3rdParty/lzma)
|
||||
if (VRU)
|
||||
add_subdirectory(Source/3rdParty/vosk-api)
|
||||
endif(VRU)
|
||||
|
||||
add_subdirectory(Source/RMG-Core)
|
||||
add_subdirectory(Source/RMG)
|
||||
add_subdirectory(Source/RMG-Audio)
|
||||
add_subdirectory(Source/RMG-Input)
|
||||
install(TARGETS RMG-Core
|
||||
DESTINATION ${SYSTEM_LIB_INSTALL_PATH}
|
||||
)
|
||||
install(TARGETS RMG
|
||||
DESTINATION ${RMG_INSTALL_PATH}
|
||||
)
|
||||
@@ -93,7 +152,7 @@ install(TARGETS RMG-Input
|
||||
|
||||
if (WIN32)
|
||||
add_subdirectory(Source/Installer)
|
||||
|
||||
|
||||
add_custom_target(bundle_dependencies
|
||||
COMMAND bash "${CMAKE_SOURCE_DIR}/Source/Script/BundleDependencies.sh" "${CMAKE_SOURCE_DIR}/Bin/${CMAKE_BUILD_TYPE}/RMG.exe" "${CMAKE_SOURCE_DIR}/Bin/${CMAKE_BUILD_TYPE}" "/mingw64/bin"
|
||||
)
|
||||
@@ -105,6 +164,14 @@ install(FILES ${MUPEN64PLUSCORE_LIB}
|
||||
install(FILES ${MUPEN64PLUSCORE_INI} Data/font.ttf
|
||||
DESTINATION ${DATA_INSTALL_PATH}
|
||||
)
|
||||
if (VRU)
|
||||
install(FILES ${VOSK_API_LIBRARY}
|
||||
DESTINATION ${LIB_INSTALL_PATH}
|
||||
)
|
||||
install(FILES ${VOSK_API_MODEL}
|
||||
DESTINATION ${DATA_INSTALL_PATH}
|
||||
)
|
||||
endif(VRU)
|
||||
install(FILES ${SDL_GAMECONTROLLERDB}
|
||||
DESTINATION ${DATA_INSTALL_PATH}
|
||||
)
|
||||
@@ -128,9 +195,11 @@ install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_RAPHNET}
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_INPUT_GCA}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/Input
|
||||
)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_GFX_ANGRYLION}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/GFX
|
||||
)
|
||||
if (USE_ANGRYLION)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_GFX_ANGRYLION}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/GFX
|
||||
)
|
||||
endif(USE_ANGRYLION)
|
||||
install(FILES ${MUPEN64PLUS_PLUGIN_GFX_GLIDEN64}
|
||||
DESTINATION ${PLUGIN_INSTALL_PATH}/GFX
|
||||
)
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
[1FBAF161-2C1C54F1-C:41]
|
||||
Name=1080 Snowboarding (JU) (M2)
|
||||
|
||||
$Enable All Levels & Boarders
|
||||
80255089 00FF
|
||||
8025508B 0005
|
||||
81255096 FCFF
|
||||
80255098 0007
|
||||
|
||||
$Have All\Contest First Place Done
|
||||
80244098 0007
|
||||
|
||||
$Have All\Match Levels Completed
|
||||
8025508A 0005
|
||||
|
||||
$Have All\Trick Attacks Done
|
||||
81255096 FCFF
|
||||
|
||||
$Infinite Damage All Players & Levels
|
||||
803F4C3C 0024
|
||||
807F4C3C 0024
|
||||
|
||||
$Infinite Lives & Continues
|
||||
8026B1CB 0003
|
||||
|
||||
$Always First Place (Player 1)
|
||||
81267B88 2400
|
||||
Note=The game will still show you in 2nd when you are behind. But when you cross the finish line, you will win!
|
||||
|
||||
$Open Level Character Select
|
||||
Note=With these codes, you have to press the buttons listed below when you are viewing a certain boarders stats. Highlight Akari Hayami's stats, and then hold down the C-Left button and then press the A button to be the Crystal Boarder. Highlight Kensuke Kimachi's stats, and then hold down the C-Up button and then press the A button to be the Metal Boarder. Hightlight Rob Haywood's stats, and then hold down the C-Right button and then press the A button to be the Panda Boarder
|
||||
8125508A 00??
|
||||
01 Easy Level
|
||||
02 Easy & Normal Level
|
||||
03 Easy Normal & Hard Levels
|
||||
04 Easy Normal Hard Levels & Crystal Boarder
|
||||
05 Easy Normal Hard Levels & Crystal & Metal Boarders
|
||||
|
||||
$Play As
|
||||
800200E7 00??
|
||||
00 Dion Blaster
|
||||
01 Kensuke Kimachi
|
||||
02 Akari Hayami
|
||||
03 Ricky Winterborn
|
||||
04 Rob Haywood
|
||||
05 Silver Boarder
|
||||
06 Gold Boarder
|
||||
07 Panda Boarder
|
||||
|
||||
$Freeze Timer In\Match Race
|
||||
D1267B20 05E1
|
||||
81267B20 1000
|
||||
|
||||
$Freeze Timer In\Time Attack
|
||||
D12660CC 05E1
|
||||
812660CC 1000
|
||||
|
||||
$Freeze Timer In\Trick Attack
|
||||
D1266138 05E1
|
||||
81266138 1000
|
||||
|
||||
$Freeze Timer In\Contest
|
||||
D126628C 05E1
|
||||
8126628C 1000
|
||||
@@ -0,0 +1,55 @@
|
||||
[58FD3F25-D92EAA8D-C:50]
|
||||
Name=1080 Snowboarding (E) (M4)
|
||||
|
||||
$Enable All Levels & Boarders
|
||||
80250AB9 00FF
|
||||
80250ABB 0005
|
||||
81250AC6 FCFF
|
||||
80250AC8 0007
|
||||
|
||||
$Infinite Damage All Players and Levels
|
||||
803F4C00 0024
|
||||
807F4C00 0024
|
||||
|
||||
$Infinite Lives & Continues
|
||||
802648A4 0003
|
||||
|
||||
$Open Level Character Select
|
||||
Note=With these codes, you have to press the buttons listed below when you are viewing a certain boarders stats. Highlight Akari Hayami's stats, and then hold down the C-Left button and then press the A button to be the Crystal Boarder. Highlight Kensuke Kimachi's stats, and then hold down the C-Up button and then press the A button to be the Metal Boarder. Hightlight Rob Haywood's stats, and then hold down the C-Right button and then press the A button to be the Panda Boarder
|
||||
8125508A 00??
|
||||
01 Easy Level
|
||||
02 Easy & Normal Level
|
||||
03 Easy Normal & Hard Levels
|
||||
04 Easy Normal Hard Levels & Crystal Boarder
|
||||
05 Easy Normal Hard Levels & Crystal & Metal Boarders
|
||||
|
||||
$Play As
|
||||
8001A0E7 00??
|
||||
00 Dion Blaster
|
||||
01 Kensuke Kimachi
|
||||
02 Akari Hayami
|
||||
03 Ricky Winterborn
|
||||
04 Rob Haywood
|
||||
05 Silver Boarder
|
||||
06 Gold Boarder
|
||||
07 Panda Boarder
|
||||
|
||||
$Always First Place (Player 1)
|
||||
812679BC 2400
|
||||
Note=The game will still show you in 2nd when you are behind. But when you cross the finish line, you will win!
|
||||
|
||||
$Freeze Timer In\Match Race
|
||||
D1267954 05E1
|
||||
81267954 1000
|
||||
|
||||
$Freeze Timer In\Time Attack
|
||||
D1265D4C 05E1
|
||||
81265D4C 1000
|
||||
|
||||
$Freeze Timer In\Trick Attack
|
||||
D1265DB8 05E1
|
||||
81265DB8 1000
|
||||
|
||||
$Freeze Timer In\Contest
|
||||
D1265F48 05E1
|
||||
81265F48 1000
|
||||
@@ -4,6 +4,7 @@ set -e
|
||||
cur_dir="$(readlink -f "$(dirname "$0")")"
|
||||
|
||||
exec "$cur_dir/usr/bin/RMG" \
|
||||
--lib-path="$cur_dir/usr/lib/RMG" \
|
||||
--core-path="$cur_dir/usr/lib/RMG/Core" \
|
||||
--plugin-path="$cur_dir/usr/lib/RMG/Plugin" \
|
||||
--shared-data-path="$cur_dir/usr/share/RMG" \
|
||||
|
||||
@@ -8,7 +8,8 @@ bin_dir="$toplvl_dir/Bin/AppImage" # RMG should be installed here
|
||||
export QMAKE="$(which qmake6)"
|
||||
export EXTRA_QT_PLUGINS="imageformats;iconengines;"
|
||||
export VERSION="$(git describe --tags --always)"
|
||||
export OUTPUT="$bin_dir/../RMG-Portable-Linux64.AppImage"
|
||||
export OUTPUT="$bin_dir/../RMG-Portable-Linux64-$VERSION.AppImage"
|
||||
export LD_LIBRARY_PATH="$toplvl_dir/Build/AppImage/Source/RMG-Core" # hack
|
||||
|
||||
if [ ! -f "$script_dir/linuxdeploy-x86_64.AppImage" ]
|
||||
then
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# Maintainer: Rosalie Wanders <rosalie@mailbox.org>
|
||||
pkgname=rmg
|
||||
pkgver=0.3.7
|
||||
pkgver=0.5.8
|
||||
pkgrel=1
|
||||
pkgdesc="Rosalie's Mupen GUI"
|
||||
arch=('x86_64')
|
||||
arch=('x86_64' 'aarch64')
|
||||
url="https://github.com/Rosalie241/$pkgname"
|
||||
license=('GPL3')
|
||||
|
||||
depends=("hidapi" "libsamplerate" "minizip" "sdl2" "zlib" "freetype2" "qt6-base" "qt6-svg" "xdg-user-dirs")
|
||||
makedepends=("git" "nasm" "cmake" "cargo" "ninja")
|
||||
depends=("hidapi" "libsamplerate" "speexdsp" "minizip" "sdl2" "zlib" "freetype2" "qt6-base" "qt6-svg" "xdg-user-dirs")
|
||||
makedepends=("git" "nasm" "cmake" "ninja")
|
||||
|
||||
source=("git+https://github.com/Rosalie241/$pkgname.git#tag=v$pkgver")
|
||||
sha256sums=('SKIP')
|
||||
@@ -24,6 +24,7 @@ build()
|
||||
-DCMAKE_BUILD_TYPE="Release" \
|
||||
-DPORTABLE_INSTALL="OFF" \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DNO_RUST="ON" \
|
||||
-G "Ninja"
|
||||
|
||||
cmake --build "$srcdir/$pkgname/build"
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
Name: RMG
|
||||
Version: 0.5.8
|
||||
Release: %autorelease
|
||||
Summary: Rosalie's Mupen GUI
|
||||
|
||||
License: GPL-3.0-only
|
||||
URL: https://github.com/Rosalie241/RMG
|
||||
Source0: https://github.com/Rosalie241/RMG/archive/refs/tags/v%{version}.tar.gz
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: g++
|
||||
BuildRequires: nasm
|
||||
BuildRequires: cmake
|
||||
BuildRequires: hidapi-devel
|
||||
BuildRequires: libsamplerate-devel
|
||||
BuildRequires: minizip-compat-devel
|
||||
BuildRequires: SDL2-devel
|
||||
BuildRequires: freetype-devel
|
||||
BuildRequires: mesa-libGL-devel
|
||||
BuildRequires: mesa-libGLU-devel
|
||||
BuildRequires: zlib-ng-devel
|
||||
BuildRequires: binutils-devel
|
||||
BuildRequires: speexdsp-devel
|
||||
BuildRequires: qt6-qtbase-devel
|
||||
BuildRequires: qt6-qtsvg-devel
|
||||
BuildRequires: libxkbcommon-devel
|
||||
|
||||
Requires: hidapi
|
||||
Requires: SDL2
|
||||
Requires: zlib-ng
|
||||
Requires: libsamplerate
|
||||
Requires: speexdsp
|
||||
Requires: qt6-qtbase
|
||||
Requires: qt6-qtsvg
|
||||
|
||||
%description
|
||||
Rosalie's Mupen GUI is a free and open-source mupen64plus front-end written in C++
|
||||
|
||||
%prep
|
||||
%autosetup
|
||||
|
||||
%build
|
||||
%cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DPORTABLE_INSTALL=OFF -DDISCORD_RPC=OFF
|
||||
%cmake_build
|
||||
|
||||
%install
|
||||
%cmake_install
|
||||
chmod +x %{buildroot}/usr/lib64/RMG/*.so
|
||||
chmod +x %{buildroot}/usr/lib64/RMG/*/*.so
|
||||
chmod +x %{buildroot}/usr/lib64/RMG/*/*/*.so
|
||||
|
||||
%files
|
||||
/usr/bin/RMG
|
||||
/usr/lib64/libRMG-Core.so
|
||||
/usr/lib64/RMG/
|
||||
/usr/share/RMG/
|
||||
/usr/share/applications/com.github.Rosalie241.RMG.desktop
|
||||
/usr/share/icons/hicolor/scalable/apps/com.github.Rosalie241.RMG.svg
|
||||
/usr/share/metainfo/com.github.Rosalie241.RMG.appdata.xml
|
||||
|
||||
%changelog
|
||||
%autochangelog
|
||||
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 318 KiB After Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 55 KiB |
@@ -1,4 +1,5 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<!-- Copyright 2022 Rosalie Wanders -->
|
||||
<component type="desktop">
|
||||
<!--Created with jdAppdataEdit 2.1-->
|
||||
<id>com.github.Rosalie241.RMG</id>
|
||||
@@ -11,33 +12,301 @@
|
||||
<description><p>Rosalie's Mupen GUI is an easy to use yet customizable mupen64plus front-end, allowing you to easily play N64 games.</p></description>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>The Rom Browser</caption>
|
||||
<caption>01 - The Rom Browser</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/RomBrowser.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>During A Game</caption>
|
||||
<caption>02 - During A Game</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/InGame.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Cheats</caption>
|
||||
<caption>03 - Cheats</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/Cheats.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Settings</caption>
|
||||
<caption>04 - Settings</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/Settings.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Input Settings</caption>
|
||||
<caption>05 - Input Settings</caption>
|
||||
<image type="source">https://github.com/Rosalie241/RMG/raw/master/Package/Screenshots/InputSettings.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="v0.5.8" date="2024-03-25" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix incorrect usage of cmake's GNUInstallDirs (thank you OPNA2608)</li>
|
||||
<li>Fix opening zipped ROMs when compiling with minizip-ng instead of minizip</li>
|
||||
<li>Fix RMG with paraLLEl crashing in mesa when using musl libc (thank you orbea and nekopsykose)</li>
|
||||
<li>Update GLideN64, parallel-rsp and SDL_GameControllerDB</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.5.7" date="2024-01-26" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix backwards compatibility with older plugin setting format</li>
|
||||
<li>Add NO_ASM build option to build mupen64plus-core without asm (thank you orbea)</li>
|
||||
<li>Change default screenshot directory on Linux (thank you orbea)</li>
|
||||
<li>Update mupen64plus-core</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.5.6" date="2024-01-23" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix updater for portable installs on windows failing to extract the zip file</li>
|
||||
<li>Fix Load State and View Log having the same default shortcut</li>
|
||||
<li>Fix not being GPL compliant by disabling the building of angrylion-rdp-plus by default (thank you orbea and carmiker)</li>
|
||||
<li>Fix installation not respecting CMAKE_INSTALL_LIBDIR</li>
|
||||
<li>Fix third party projects not respecting CMAKE_C_FLAGS and CMAKE_CXX_FLAGS</li>
|
||||
<li>Fix not all third party projects respecting the RelWithDebInfo configuration properly</li>
|
||||
<li>Fix GLideN64 not installing correctly with the RelWithDebInfo configuration</li>
|
||||
<li>Fix mupen64plus callbacks during initialization not showing up in the log window</li>
|
||||
<li>Add a few GUI logging messages</li>
|
||||
<li>Improve view log dialog behavior with clearing the log</li>
|
||||
<li>Update copyright year in the about dialog (thank you JakobDev)</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.5.5" date="2024-01-14" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Add TryExec to desktop file (thank you JakobDev)</li>
|
||||
<li>Update mupen64plus-core, parallel-rsp, mupen64plus-rsp-hle, GLideN64 and SDL_GameControllerDB</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.5.4" date="2023-12-17" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix issue with vulkan video plugins</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.5.3" date="2023-12-17" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix some error messages not being shown when there are a lot of errors</li>
|
||||
<li>Fix cheat dialog not allowing empty lines</li>
|
||||
<li>Fix forward slashes being displayed in paths on windows</li>
|
||||
<li>Fix some timers starting before plugins are ready</li>
|
||||
<li>Improve video size behavior by ensuring the video size matches the window size</li>
|
||||
<li>Update mupen64plus-core, GLideN64 and SDL_GameControllerDB</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.5.2" date="2023-09-06" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix drag and drop not working in the loading screen of the ROM browser</li>
|
||||
<li>Fix ROM browser not refreshing when launching RMG with a ROM specified through the commandline, using drag and drop and then returning to the ROM browser</li>
|
||||
<li>Fix ROM browser refreshing with '--quit-after-emulation' specified through the commandline after a ROM has finished executing causing some extra debug callbacks to be displayed</li>
|
||||
<li>Fix ROMs which have a ROM header name with 20 characters without a 0 byte at the end (fixes a crash on windows)</li>
|
||||
<li>Improve build process by automatically detecting whether 'std::format' is supported or not (if not, use libfmt)</li>
|
||||
<li>Improve message box behavior when there are a lot of errors</li>
|
||||
<li>Improve default directories on windows (it'll now use '%APPDATA%\RMG' unless 'portable.txt' or 'Config\mupen64plus.cfg' exists)</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.5.1" date="2023-08-27" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix window title of the windows installer</li>
|
||||
<li>Fix video plugins which use vulkan not working on some Linux distributions</li>
|
||||
<li>Fix 'Edit Game Input Settings' not saving settings when changing certain settings</li>
|
||||
<li>Fix crash when having the RMG-Input configuration GUI open and closing RMG with control+c on Linux</li>
|
||||
<li>Fix 'open_rom(): not a valid ROM image' error showing up sometimes when launching RMG with a ROM specified on the commandline</li>
|
||||
<li>Update mupen64plus-core, GLideN64, paraLLEl and SDL_GameControllerDB</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.5.0" date="2023-08-12" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix AppImage not working on LTS distributions</li>
|
||||
<li>Fix audio issues by reverting the audio changes from v0.4.8</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.4.9" date="2023-08-12" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix crash when opening the per-game settings</li>
|
||||
<li>Add support for using libfmt when the compiler doesn't support std::format</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.4.8" date="2023-08-11" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix undo and redo stack not being cleared in the edit cheat dialog</li>
|
||||
<li>Add hotkeys to increase, decrease and mute the volume (see the new Audio tab in the Hotkeys tab of the settings dialog)</li>
|
||||
<li>Add support for drag and drop (the flatpak has it disabled due to Qt not supporting drag and drop in the file portal yet)</li>
|
||||
<li>Add an implementation selection in RMG-Audio (see the advanced audio settings, the simple implementation might solve some audio issues for some people)</li>
|
||||
<li>Improve loading time duration of the ROM browser (the ROM browser should load faster when ROM entries are in the ROM browser cache)</li>
|
||||
<li>Improve control stick behavior in RMG-Input (thank you kev4cards)</li>
|
||||
<li>Improve cheats and settings code in RMG-Core</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.4.7" date="2023-08-05" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix diagonals not working for joystick hats in RMG-Input</li>
|
||||
<li>Fix visualization of joystick hats in the configuration GUI of RMG-Input</li>
|
||||
<li>Fix "Hide Cursor During Fullscreen Emulation" not working when using a Vulkan video plugin</li>
|
||||
<li>Improve VRU initialization code in RMG-Input</li>
|
||||
<li>Update SDL_GameControllerDB</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.4.6" date="2023-08-04" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix copying a string out-of-bounds in RMG-Core</li>
|
||||
<li>Fix memory leak in GLideN64</li>
|
||||
<li>Add experimental support for wayland on linux (you can enable it by setting RMG_WAYLAND to 1)</li>
|
||||
<li>Add RMG, mupen64plus and n64 keywords to the desktop file (thank you loganmc10)</li>
|
||||
<li>Add joystick hat support to RMG-Input</li>
|
||||
<li>Add native vulkan support (video plugins can now use vulkan natively without having to use OpenGL for presentation)</li>
|
||||
<li>Add current render mode to the status bar (OpenGL or Vulkan)</li>
|
||||
<li>Add information regarding the On-Screen display to the OSD tab of the settings dialog (the OSD will only work with OpenGL video plugins)</li>
|
||||
<li>Improve build process by building with LTO and stripping release binaries</li>
|
||||
<li>Update mupen64plus-video-parallel</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.4.5" date="2023-07-19" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix "Change" buttons in the transfer pak tab of the options dialog of RMG-Input not working since v0.4.2</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.4.4" date="2023-07-17" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix memory leak when using a 64DD disk in an archive</li>
|
||||
<li>Fix fallback of mupen64plus-rsp-hle not working on first run</li>
|
||||
<li>Fix 'Screenshot Captured' OSD message not appearing when using controller hotkeys</li>
|
||||
<li>Fix dynamic recompiler crashing on ARM64 since v0.4.1</li>
|
||||
<li>Add support for joysticks/triggers for hotkeys in RMG-Input</li>
|
||||
<li>Add hotkeys for increasing and decreasing the save state slot in RMG-Input</li>
|
||||
<li>Add hotkeys for switching controller paks in RMG-Input</li>
|
||||
<li>Improve deadzone and sensitivity code in RMG-Input (thank you JaxonWasTaken)</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.4.3" date="2023-07-11" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix minor corruption issues when using GLideN64 in Wave Race 64 and Space Station Silicon Valley</li>
|
||||
<li>Fix some potential issues with out of bounds RDRAM reads (thank you loganmc10)</li>
|
||||
<li>Fix ROM browser not updating entries when they've changed in the ROM database</li>
|
||||
<li>Fix mupen64plus-rsp-hle not having a fallback configured (fixes Xeno Crisis not booting with mupen64plus-rsp-hle)</li>
|
||||
<li>Fix Xeno Crisis showing an error message</li>
|
||||
<li>Add Xeno Crisis to the ROM database</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.4.2" date="2023-07-07" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix window behavior issues when saving GLideN64 settings while in-game</li>
|
||||
<li>Add VRU support to RMG-Input</li>
|
||||
<li>Add controller hotkey support to RMG-Input</li>
|
||||
<li>Improve window title by using the ROM filename when the ROM isn't in the database</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.4.1" date="2023-06-19" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix debug callbacks not printing before GUI has been started</li>
|
||||
<li>Fix emulation error being incorrect in some cases</li>
|
||||
<li>Fix user cheat file location (new ones will be placed in the user config directory instead of the user data directory)</li>
|
||||
<li>Fix mupen64plus-input-gca crashing in v0.4.0 due to updating to a broken commit</li>
|
||||
<li>Fix Paper Mario crashing when using the hammer on a specific tree in-game by implementing RDRAM address range 0x0800000-0x03EFFFFF</li>
|
||||
<li>Improve accuracy of the pure and cached interpreter</li>
|
||||
<li>Add *.st* and *.pj* to the file filter when loading a save state from a file</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.4.0" date="2023-05-04" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix updater on windows always installing the desktop icon</li>
|
||||
<li>Fix updater on windows not re-launching RMG after installation</li>
|
||||
<li>Fix the speed limiter toggle and speed factor options not working on linux on some systems</li>
|
||||
<li>Fix the 1080 Snowboarding cheats (thank you Gent)</li>
|
||||
<li>Add support for moving the toolbar (changes to the docked position are persistent across application runs)</li>
|
||||
<li>Update GLideN64 and mupen64plus-input-gca</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.3.9" date="2023-04-06" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix "Don't check for updates again" checkbox appearing when requesting an update check through Help -> Check For Updates</li>
|
||||
<li>Add game format, file name, file extension, file size, game I.D. and game region columns to the list view of the ROM browser which can be toggled in the "Show/Hide Columns" menu of the context menu in the list view of the ROM browser (thank you RetraCarteR)</li>
|
||||
<li>Add "Reset Column Sizes" to context menu of the list view of the ROM browser (thank you RetraCarteR)</li>
|
||||
<li>Add "Analog Stick Sensitivity" setting to RMG-Input (thank you JaxonWasTaken)</li>
|
||||
<li>Add "Save Filename Format" setting to the Core tab of the settings dialog</li>
|
||||
<li>Add "Edit Game Input Settings" to the context menu of the ROM browser</li>
|
||||
<li>Add support for 7z files</li>
|
||||
<li>Add progress status to the loading screen in the ROM browser when loading takes more than 5 seconds</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.3.8" date="2023-02-24" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix RMG not having the correct video size in some cases (i.e on a WM where resizing is not allowed to be done by an application)</li>
|
||||
<li>Fix translations not working in GLideN64</li>
|
||||
<li>Add -n/--nogui commandline option</li>
|
||||
<li>Add -d/--debug-messages commandline option</li>
|
||||
<li>Add hotkeys for graphics, audio, RSP and input settings</li>
|
||||
<li>Add hotkey for viewing the log</li>
|
||||
<li>Add SIGINT and SIGTERM handling on linux</li>
|
||||
<li>Add "Check For Updates" to "View" in the toolbar</li>
|
||||
<li>Add information about LLE plugins in the settings dialog</li>
|
||||
<li>Add support for toggling visibility of columns in the ROM browser list view (thank you RetraCarteR)</li>
|
||||
<li>Add date and time to the save state slot items in "Current Save State" menu in the menubar</li>
|
||||
<li>Add date and time to the OSD when selecting a save state slot</li>
|
||||
<li>Add failure messages to the OSD when loading/saving a save state fails</li>
|
||||
<li>Improve updater behavior by checking for an update on startup with at least an hour in-between checks</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="v0.3.7" date="2023-02-19" type="stable">
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix icons not showing up in some cases when migrating from a version before v0.3.5</li>
|
||||
<li>Fix plugin settings not being loaded properly in the settings dialog when migrating from a version before v0.3.5</li>
|
||||
<li>Fix icons not showing up in some cases when migrating from a version before v0.3.6</li>
|
||||
<li>Fix plugin settings not being loaded properly in the settings dialog when migrating from a version before v0.3.6</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
@@ -45,7 +314,7 @@
|
||||
<description>
|
||||
<p>Changes:</p>
|
||||
<ul>
|
||||
<li>Fix RMG not using xwayland when using wayland (wayland has lots of issues, can be disabled by building with the `-DFORCE_XCB=OFF` option)</li>
|
||||
<li>Fix RMG not using xwayland when using wayland (wayland has lots of issues, can be disabled by building with the "-DFORCE_XCB=OFF" option)</li>
|
||||
<li>Fix some non-fatal mupen64plus errors showing a pop-up</li>
|
||||
<li>Fix window not returning to ROM browser when launching a game through the commandline and the plugins aren't ready</li>
|
||||
<li>Add support for Qt stylesheets (place them in the 'user data directory/Styles' directory with the '.qss' extension, they'll show up in "Themes")</li>
|
||||
|
||||
@@ -3,7 +3,9 @@ Type=Application
|
||||
Name=Rosalie's Mupen GUI
|
||||
Comment=An easy to use & cross-platform mupen64plus front-end written in C++ & Qt
|
||||
Exec=RMG %f
|
||||
TryExec=RMG
|
||||
Icon=com.github.Rosalie241.RMG
|
||||
Terminal=false
|
||||
Categories=Game;Emulator;Qt;
|
||||
MimeType=application/x-n64-rom;
|
||||
Keywords=emulator;mupen64plus;n64;RMG
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Rosalie's Mupen GUI
|
||||
|
||||
Rosalie's Mupen GUI is a free and open-source mupen64plus GUI written in C++.
|
||||
Rosalie's Mupen GUI is a free and open-source mupen64plus front-end written in C++.
|
||||
|
||||
It offers a simple-to-use user interface.
|
||||
|
||||
@@ -14,10 +14,13 @@ You can download Rosalie's Mupen GUI on
|
||||
* [Github Releases (AppImage)](https://github.com/Rosalie241/RMG/releases)
|
||||
* [Flathub (Flatpak)](https://flathub.org/apps/details/com.github.Rosalie241.RMG)
|
||||
* [Arch User Repository](https://aur.archlinux.org/packages/rmg)
|
||||
* [Fedora COPR](https://copr.fedorainfracloud.org/coprs/rosalie/RMG/)
|
||||
|
||||
## Support
|
||||
|
||||
Join the [Rosalie's Mupen GUI Discord Server](https://discord.gg/k9GuyJ2PpF) for support
|
||||
You can ask for help or report issues on
|
||||
* [Github](https://github.com/Rosalie241/RMG/issues/new)
|
||||
* [Discord](https://discord.gg/k9GuyJ2PpF)
|
||||
|
||||
## License
|
||||
|
||||
@@ -35,7 +38,7 @@ Rosalie's Mupen GUI is licensed under the [GNU General Public License v3.0](http
|
||||
* Portable Debian/Ubuntu
|
||||
|
||||
```bash
|
||||
sudo apt-get -y install cmake libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt6-base-dev libqt6svg6-dev build-essential nasm git zip ninja-build
|
||||
sudo apt-get -y install cmake libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt6-base-dev libqt6svg6-dev libvulkan-dev build-essential nasm git zip ninja-build
|
||||
./Source/Script/Build.sh Release
|
||||
```
|
||||
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
#
|
||||
include(ExternalProject)
|
||||
|
||||
set(THIRDPARTY_DIR ${CMAKE_BINARY_DIR}/Source/3rdParty)
|
||||
|
||||
find_program(RUST_CARGO cargo)
|
||||
if(${RUST_CARGO} STREQUAL "RUST_CARGO-NOTFOUND")
|
||||
if(NO_RUST)
|
||||
set(BUILD_INPUT_GCA OFF)
|
||||
elseif(${RUST_CARGO} STREQUAL "RUST_CARGO-NOTFOUND")
|
||||
message(WARNING "mupen64plus-input-gca will not be built due to not having cargo installed")
|
||||
set(BUILD_INPUT_GCA OFF)
|
||||
else()
|
||||
set(BUILD_INPUT_GCA ON)
|
||||
endif()
|
||||
|
||||
set(M64P_CORE_DIR ${THIRDPARTY_DIR}/mupen64plus-core)
|
||||
set(M64P_CORE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-core)
|
||||
if(WIN32)
|
||||
set(SO_EXT "dll")
|
||||
set(GCA_LIB "mupen64plus_input_gca.${SO_EXT}")
|
||||
@@ -24,7 +24,9 @@ else(WIN32)
|
||||
set(CORE_FILE "libmupen64plus.so")
|
||||
endif(WIN32)
|
||||
|
||||
set(BASE_CMAKE_CONFIGURE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})
|
||||
set(BASE_CMAKE_CONFIGURE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS})
|
||||
if (USE_CCACHE)
|
||||
set(CMAKE_CONFIGURE_ARGS ${BASE_CMAKE_CONFIGURE_ARGS} -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache)
|
||||
set(MAKE_CC_COMPILER "ccache ${CMAKE_C_COMPILER}")
|
||||
@@ -35,157 +37,149 @@ else(USE_CCACHE)
|
||||
set(MAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}")
|
||||
endif(USE_CCACHE)
|
||||
|
||||
if(NOT NO_GIT_CLONE)
|
||||
set(MUPEN64PLUSCORE_URL "https://github.com/mupen64plus/mupen64plus-core")
|
||||
set(MUPEN64PLUSCORE_TAG "7ee312cb282a7794c62d5d284bf93151c585dd1f")
|
||||
# use sub-make when available
|
||||
if ("${CMAKE_GENERATOR}" STREQUAL "Unix Makefiles" OR
|
||||
"${CMAKE_GENERATOR}" STREQUAL "MSYS Makefiles")
|
||||
set(MAKE_CMD "$(MAKE)")
|
||||
else()
|
||||
set(MAKE_CMD "make")
|
||||
endif()
|
||||
|
||||
set(MUPEN64PLUS_RSP_CXD4_URL "https://github.com/mupen64plus/mupen64plus-rsp-cxd4")
|
||||
set(MUPEN64PLUS_RSP_CXD4_TAG "39f79201baa15890c4cbae92f2215a634cc3ee6d")
|
||||
if ("${CMAKE_C_FLAGS}" STREQUAL "")
|
||||
if (USE_LTO)
|
||||
set(MAKE_OPTFLAGS "-O3 -flto")
|
||||
else(USE_LTO)
|
||||
set(MAKE_OPTFLAGS "-O3")
|
||||
endif(USE_LTO)
|
||||
else()
|
||||
set(MAKE_OPTFLAGS "${CMAKE_C_FLAGS}")
|
||||
endif()
|
||||
|
||||
set(MUPEN64PLUS_RSP_HLE_URL "https://github.com/mupen64plus/mupen64plus-rsp-hle")
|
||||
set(MUPEN64PLUS_RSP_HLE_TAG "88093cb43499eff53d343653cddcae2132af17ef")
|
||||
|
||||
set(MUPEN64PLUS_RSP_PARALLEL_URL "https://github.com/Rosalie241/parallel-rsp")
|
||||
set(MUPEN64PLUS_RSP_PARALLEL_TAG "cfeea3a0f89ba5bc4265acb75778e1267ed1e424")
|
||||
|
||||
set(MUPEN64PLUS_INPUT_RAPHNET_URL "https://github.com/raphnet/mupen64plus-input-raphnetraw")
|
||||
set(MUPEN64PLUS_INPUT_RAPHNET_TAG "86112413e98a8648edb11d199673cc24d5799af8")
|
||||
|
||||
set(MUPEN64PLUS_INPUT_GCA_URL "https://github.com/amatho/mupen64plus-input-gca")
|
||||
set(MUPEN64PLUS_INPUT_GCA_TAG "21639fb13dfa797a7c0949ffd9bbda9a3456fc69")
|
||||
|
||||
set(MUPEN64PLUS_GFX_ANGRYLION_URL "https://github.com/Rosalie241/angrylion-rdp-plus")
|
||||
set(MUPEN64PLUS_GFX_ANGRYLION_TAG "158e74d4ec1c818289cd19c3a05e498c3ceff758")
|
||||
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_URL "https://github.com/Rosalie241/GLideN64")
|
||||
set(MUPEN64PLUS_GFX_GLIDEN64_TAG "71dcb55a398a5c4d2bdbfa9fc15b90f301f77a6b")
|
||||
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_URL "https://github.com/Rosalie241/parallel-rdp-standalone")
|
||||
set(MUPEN64PLUS_GFX_PARALLEL_TAG "2c2226517c4c8929e08ec944654867e26efe0cf5")
|
||||
|
||||
set(DISCORD_RPC_URL "https://github.com/discord/discord-rpc")
|
||||
set(DISCORD_RPC_TAG "963aa9f3e5ce81a4682c6ca3d136cddda614db33")
|
||||
|
||||
set(IMGUI_URL "https://github.com/ocornut/imgui")
|
||||
set(IMGUI_TAG "d7c8516a4b848c0291e3d75b627c0843f515f591")
|
||||
|
||||
set(SDL_GAMECONTROLLERDB_URL "https://github.com/gabomdq/SDL_GameControllerDB")
|
||||
set(SDL_GAMECONTROLLERDB_TAG "0562b00eaf5c0308c49d329b79263d2dae1c3a85")
|
||||
endif(NOT NO_GIT_CLONE)
|
||||
if ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo" OR
|
||||
"${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
set(MAKE_DEBUG "1")
|
||||
else()
|
||||
set(MAKE_DEBUG "0")
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(mupen64plus-core
|
||||
SOURCE_DIR mupen64plus-core/
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-core/
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUSCORE_URL}
|
||||
GIT_TAG ${MUPEN64PLUSCORE_TAG}
|
||||
|
||||
BUILD_COMMAND make all OSD=0 NEW_DYNAREC=1 TARGET=${CORE_FILE} DEBUG=$<CONFIG:Debug> KEYBINDINGS=0 CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
BUILD_COMMAND ${MAKE_CMD} all -f ${M64P_CORE_DIR}/projects/unix/Makefile
|
||||
SRCDIR=${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-core/src
|
||||
SUBDIR=${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-core/subprojects
|
||||
OSD=0 NEW_DYNAREC=1 NO_ASM=$<BOOL:${NO_ASM}> KEYBINDINGS=0 ACCURATE_FPU=1
|
||||
TARGET=${CORE_FILE} DEBUG=${MAKE_DEBUG} DBG_COMPARE=1
|
||||
CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
OPTFLAGS=${MAKE_OPTFLAGS}
|
||||
BUILD_IN_SOURCE False
|
||||
BUILD_ALWAYS True
|
||||
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-core
|
||||
|
||||
BINARY_DIR ${M64P_CORE_DIR}/projects/unix
|
||||
|
||||
BUILD_BYPRODUCTS ${M64P_CORE_DIR}/projects/unix/${CORE_FILE}
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-core/${CORE_FILE}
|
||||
)
|
||||
|
||||
set(APIDIR "${CMAKE_BINARY_DIR}/Source/3rdParty/mupen64plus-core/src/api")
|
||||
set(APIDIR "${CMAKE_SOURCE_DIR}/Source/3rdParty/mupen64plus-core/src/api")
|
||||
|
||||
ExternalProject_Add(mupen64plus-rsp-cxd4
|
||||
SOURCE_DIR mupen64plus-rsp-cxd4/
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-rsp-cxd4/
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_RSP_CXD4_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_RSP_CXD4_TAG}
|
||||
|
||||
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> POSTFIX= CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
BUILD_COMMAND ${MAKE_CMD} all -f ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-rsp-cxd4/projects/unix/Makefile
|
||||
SRCDIR=${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-rsp-cxd4
|
||||
APIDIR=${APIDIR} DEBUG=${MAKE_DEBUG} POSTFIX=
|
||||
CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
OPTFLAGS=${MAKE_OPTFLAGS}
|
||||
BUILD_IN_SOURCE False
|
||||
BUILD_ALWAYS True
|
||||
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-rsp-cxd4
|
||||
|
||||
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-rsp-cxd4/projects/unix
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-rsp-cxd4/projects/unix/mupen64plus-rsp-cxd4.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-rsp-cxd4/mupen64plus-rsp-cxd4.${SO_EXT}
|
||||
)
|
||||
|
||||
ExternalProject_Add(mupen64plus-rsp-hle
|
||||
SOURCE_DIR mupen64plus-rsp-hle/
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-rsp-hle/
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_RSP_HLE_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_RSP_HLE_TAG}
|
||||
|
||||
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
BUILD_COMMAND ${MAKE_CMD} all -f ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-rsp-hle/projects/unix/Makefile
|
||||
SRCDIR=${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-rsp-hle/src
|
||||
APIDIR=${APIDIR} DEBUG=${MAKE_DEBUG}
|
||||
CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
OPTFLAGS=${MAKE_OPTFLAGS}
|
||||
BUILD_IN_SOURCE False
|
||||
BUILD_ALWAYS True
|
||||
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-rsp-hle
|
||||
|
||||
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-rsp-hle/projects/unix
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-rsp-hle/projects/unix/mupen64plus-rsp-hle.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-rsp-hle/mupen64plus-rsp-hle.${SO_EXT}
|
||||
)
|
||||
|
||||
ExternalProject_Add(mupen64plus-rsp-parallel
|
||||
SOURCE_DIR mupen64plus-rsp-parallel
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_RSP_PARALLEL_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_RSP_PARALLEL_TAG}
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-rsp-parallel/
|
||||
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE True
|
||||
BUILD_IN_SOURCE False
|
||||
BUILD_ALWAYS True
|
||||
CMAKE_ARGS ${CMAKE_CONFIGURE_ARGS}
|
||||
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-rsp-parallel
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-rsp-parallel/mupen64plus-rsp-parallel.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-rsp-parallel/mupen64plus-rsp-parallel.${SO_EXT}
|
||||
)
|
||||
|
||||
ExternalProject_Add(mupen64plus-input-raphnetraw
|
||||
SOURCE_DIR mupen64plus-input-raphnetraw/
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-input-raphnetraw/
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_RAPHNET_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_INPUT_RAPHNET_TAG}
|
||||
|
||||
BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$<CONFIG:Debug> CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
BUILD_COMMAND ${MAKE_CMD} all -f ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-input-raphnetraw/projects/unix/Makefile
|
||||
SRCDIR=${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-input-raphnetraw/src
|
||||
APIDIR=${APIDIR} DEBUG=${MAKE_DEBUG}
|
||||
CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
|
||||
OPTFLAGS=${MAKE_OPTFLAGS}
|
||||
BUILD_IN_SOURCE False
|
||||
BUILD_ALWAYS True
|
||||
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-input-raphnetraw
|
||||
|
||||
BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-input-raphnetraw/projects/unix
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-input-raphnetraw/projects/unix/mupen64plus-input-raphnetraw.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-input-raphnetraw/mupen64plus-input-raphnetraw.${SO_EXT}
|
||||
)
|
||||
|
||||
if (BUILD_INPUT_GCA)
|
||||
ExternalProject_Add(mupen64plus-input-gca
|
||||
SOURCE_DIR mupen64plus-input-gca/
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-input-gca/
|
||||
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_INPUT_GCA_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_INPUT_GCA_TAG}
|
||||
|
||||
BUILD_COMMAND cargo build --release --features "m64p_compat"
|
||||
BUILD_IN_SOURCE True
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-input-gca/target/release/${GCA_LIB}
|
||||
DEPENDS mupen64plus-core
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-input-gca/target/release/${GCA_LIB}
|
||||
)
|
||||
endif(BUILD_INPUT_GCA)
|
||||
|
||||
set(GLIDEN64_DIR "${THIRDPARTY_DIR}/mupen64plus-video-GLideN64")
|
||||
set(GLIDEN64_BUILD_DIR "${GLIDEN64_DIR}/projects/cmake")
|
||||
set(GLIDEN64_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-video-GLideN64")
|
||||
set(GLIDEN64_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-video-GLideN64")
|
||||
set(GLIDEN64_CUSTOM_INI "${GLIDEN64_DIR}/ini/GLideN64.custom.ini")
|
||||
if (WIN32)
|
||||
set(GLIDEN64_LIB "${GLIDEN64_BUILD_DIR}/mupen64plus-video-GLideN64.${SO_EXT}")
|
||||
set(GLIDEN64_LIB "${GLIDEN64_BUILD_DIR}/mupen64plus-video-GLideN64.${SO_EXT}")
|
||||
else(WIN32)
|
||||
set(GLIDEN64_LIB "${GLIDEN64_BUILD_DIR}/plugin/${CMAKE_BUILD_TYPE}/mupen64plus-video-GLideN64.${SO_EXT}")
|
||||
# taken from GLideN64's CMakeLists.txt
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" OR
|
||||
"${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel" OR
|
||||
"${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
|
||||
set(GLIDEN64_BUILD_TYPE Release)
|
||||
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
set(GLIDEN64_BUILD_TYPE Debug)
|
||||
endif()
|
||||
set(GLIDEN64_LIB "${GLIDEN64_BUILD_DIR}/plugin/${GLIDEN64_BUILD_TYPE}/mupen64plus-video-GLideN64.${SO_EXT}")
|
||||
endif(WIN32)
|
||||
|
||||
set(GLIDENUI_TRANSLATIONS_LANGS "de;es;fr;it;ja;pl;pt_BR")
|
||||
@@ -193,71 +187,66 @@ foreach(LANG ${GLIDENUI_TRANSLATIONS_LANGS})
|
||||
list(APPEND GLIDENUI_TRANSLATIONS "${GLIDEN64_DIR}/translations/release/gliden64_${LANG}.qm")
|
||||
endforeach()
|
||||
|
||||
ExternalProject_Add(mupen64plus-video-angrylion-plus
|
||||
SOURCE_DIR mupen64plus-video-angrylion-plus
|
||||
if (USE_ANGRYLION)
|
||||
ExternalProject_Add(mupen64plus-video-angrylion-plus
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-video-angrylion-plus
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_GFX_ANGRYLION_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_GFX_ANGRYLION_TAG}
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_IN_SOURCE False
|
||||
BUILD_ALWAYS True
|
||||
CMAKE_ARGS -DBUILD_MUPEN64PLUS=ON -DBUILD_PROJECT64=OFF -DUSE_QT5=OFF ${CMAKE_CONFIGURE_ARGS}
|
||||
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-video-angrylion-plus
|
||||
|
||||
BUILD_IN_SOURCE True
|
||||
CMAKE_ARGS -DBUILD_MUPEN64PLUS=ON -DBUILD_PROJECT64=OFF -DUSE_QT5=OFF ${CMAKE_CONFIGURE_ARGS}
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-video-angrylion-plus/mupen64plus-video-angrylion-plus.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
)
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-video-angrylion-plus/mupen64plus-video-angrylion-plus.${SO_EXT}
|
||||
)
|
||||
endif(USE_ANGRYLION)
|
||||
|
||||
ExternalProject_Add(mupen64plus-video-GLideN64
|
||||
SOURCE_DIR mupen64plus-video-GLideN64
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_GFX_GLIDEN64_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_GFX_GLIDEN64_TAG}
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-video-GLideN64
|
||||
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE False
|
||||
BUILD_ALWAYS True
|
||||
CMAKE_ARGS -DMUPENPLUSAPI=ON -DMUPENPLUSAPI_GLIDENUI=ON -DGLIDENUI_QT6=ON -DUSE_SYSTEM_LIBS=ON ${CMAKE_CONFIGURE_ARGS}
|
||||
|
||||
SOURCE_SUBDIR ./src/
|
||||
BINARY_DIR ${GLIDEN64_BUILD_DIR}
|
||||
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-video-GLideN64
|
||||
|
||||
BUILD_BYPRODUCTS ${GLIDEN64_LIB}
|
||||
)
|
||||
|
||||
ExternalProject_Add(mupen64plus-video-parallel
|
||||
SOURCE_DIR mupen64plus-video-parallel
|
||||
|
||||
GIT_REPOSITORY ${MUPEN64PLUS_GFX_PARALLEL_URL}
|
||||
GIT_TAG ${MUPEN64PLUS_GFX_PARALLEL_TAG}
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-video-parallel
|
||||
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE True
|
||||
CMAKE_ARGS -DUSE_QT5=OFF ${CMAKE_CONFIGURE_ARGS}
|
||||
BUILD_IN_SOURCE False
|
||||
BUILD_ALWAYS True
|
||||
CMAKE_ARGS -DCONFIG_GUI=ON ${CMAKE_CONFIGURE_ARGS}
|
||||
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-video-parallel
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-video-parallel/mupen64plus-video-parallel.${SO_EXT}
|
||||
DEPENDS mupen64plus-core
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/mupen64plus-video-parallel/mupen64plus-video-parallel.${SO_EXT}
|
||||
)
|
||||
|
||||
if (DISCORD_RPC)
|
||||
ExternalProject_Add(discord-rpc
|
||||
SOURCE_DIR discord-rpc
|
||||
|
||||
GIT_REPOSITORY ${DISCORD_RPC_URL}
|
||||
GIT_TAG ${DISCORD_RPC_TAG}
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/discord-rpc
|
||||
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
BUILD_IN_SOURCE True
|
||||
BUILD_IN_SOURCE False
|
||||
BUILD_ALWAYS True
|
||||
CMAKE_ARGS -DBUILD_EXAMPLES=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON ${CMAKE_CONFIGURE_ARGS}
|
||||
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/discord-rpc
|
||||
|
||||
BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/discord-rpc/src/libdiscord-rpc.a
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/discord-rpc/src/libdiscord-rpc.a
|
||||
)
|
||||
endif(DISCORD_RPC)
|
||||
|
||||
set(IMGUI_DIR ${THIRDPARTY_DIR}/imgui)
|
||||
set(IMGUI_BUILD_DIR ${IMGUI_DIR}/build)
|
||||
set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui)
|
||||
set(IMGUI_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/imgui/)
|
||||
set(IMGUI_SOURCES_IN
|
||||
${IMGUI_DIR}/imgui_draw.cpp
|
||||
${IMGUI_DIR}/imgui_tables.cpp
|
||||
@@ -277,10 +266,7 @@ set(IMGUI_SOURCES_OUT
|
||||
${IMGUI_BUILD_DIR}/imgui_impl_opengl3_loader.h
|
||||
)
|
||||
ExternalProject_Add(imgui
|
||||
SOURCE_DIR imgui
|
||||
|
||||
GIT_REPOSITORY ${IMGUI_URL}
|
||||
GIT_TAG ${IMGUI_TAG}
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui
|
||||
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory ${IMGUI_BUILD_DIR}
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} -E copy ${IMGUI_SOURCES_IN} ${IMGUI_BUILD_DIR}
|
||||
@@ -289,8 +275,8 @@ ExternalProject_Add(imgui
|
||||
BUILD_BYPRODUCTS ${IMGUI_SOURCES_OUT}
|
||||
)
|
||||
|
||||
set(SDL_GAMECONTROLLERDB_DIR ${THIRDPARTY_DIR}/SDL_GameControllerDB)
|
||||
set(SDL_GAMECONTROLLERDB_BUILD_DIR ${SDL_GAMECONTROLLERDB_DIR}/build)
|
||||
set(SDL_GAMECONTROLLERDB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/SDL_GameControllerDB)
|
||||
set(SDL_GAMECONTROLLERDB_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/SDL_GameControllerDB)
|
||||
set(SDL_GAMECONTROLLERDB_SOURCES_IN
|
||||
${SDL_GAMECONTROLLERDB_DIR}/gamecontrollerdb.txt
|
||||
)
|
||||
@@ -298,10 +284,7 @@ set(SDL_GAMECONTROLLERDB_SOURCES_OUT
|
||||
${SDL_GAMECONTROLLERDB_BUILD_DIR}/gamecontrollerdb.txt
|
||||
)
|
||||
ExternalProject_Add(SDL_GameControllerDB
|
||||
SOURCE_DIR SDL_GameControllerDB
|
||||
|
||||
GIT_REPOSITORY ${SDL_GAMECONTROLLERDB_URL}
|
||||
GIT_TAG ${SDL_GAMECONTROLLERDB_TAG}
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/SDL_GameControllerDB
|
||||
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E make_directory ${SDL_GAMECONTROLLERDB_BUILD_DIR}
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} -E copy ${SDL_GAMECONTROLLERDB_SOURCES_IN} ${SDL_GAMECONTROLLERDB_SOURCES_OUT}
|
||||
@@ -331,8 +314,10 @@ if (BUILD_INPUT_GCA)
|
||||
set(MUPEN64PLUS_PLUGIN_INPUT_GCA ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
endif(BUILD_INPUT_GCA)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-video-angrylion-plus BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_GFX_ANGRYLION ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
if (USE_ANGRYLION)
|
||||
ExternalProject_Get_property(mupen64plus-video-angrylion-plus BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_GFX_ANGRYLION ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
endif(USE_ANGRYLION)
|
||||
|
||||
ExternalProject_Get_property(mupen64plus-video-GLideN64 BUILD_BYPRODUCTS)
|
||||
set(MUPEN64PLUS_PLUGIN_GFX_GLIDEN64 ${BUILD_BYPRODUCTS} ${GLIDENUI_TRANSLATIONS} ${GLIDEN64_CUSTOM_INI} PARENT_SCOPE)
|
||||
@@ -347,7 +332,7 @@ endif(DISCORD_RPC)
|
||||
|
||||
ExternalProject_Get_property(imgui BUILD_BYPRODUCTS)
|
||||
set(IMGUI_SOURCES ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
set(IMGUI_DIR ${THIRDPARTY_DIR}/imgui PARENT_SCOPE)
|
||||
set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui PARENT_SCOPE)
|
||||
|
||||
ExternalProject_Get_property(SDL_GameControllerDB BUILD_BYPRODUCTS)
|
||||
set(SDL_GAMECONTROLLERDB ${BUILD_BYPRODUCTS} PARENT_SCOPE)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
name: Data check
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
jobs:
|
||||
duplicates:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: |
|
||||
python duplicates.py
|
||||
@@ -0,0 +1,12 @@
|
||||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/ingydotnet/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = git@github.com:/gabomdq/SDL_GameControllerDB.git
|
||||
branch = master
|
||||
commit = e5a5fa2ac6e645d72c619ea99520a3a4586ee005
|
||||
parent = cb07131fbbf9cf9f139ef4281799613a71580182
|
||||
method = merge
|
||||
cmdver = 0.4.6
|
||||
@@ -0,0 +1,17 @@
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
@@ -0,0 +1,57 @@
|
||||
# SDL_GameControllerDB
|
||||
|
||||
A community sourced database of game controller mappings to be used with SDL2 Game Controller functionality.
|
||||
|
||||
# Usage
|
||||
Download gamecontrollerdb.txt, place it in your app's directory and load it.
|
||||
|
||||
SDL2:
|
||||
```c
|
||||
SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt");
|
||||
```
|
||||
|
||||
SDL3:
|
||||
```c
|
||||
SDL_AddGamepadMappingsFromFile("gamecontrollerdb.txt");
|
||||
```
|
||||
|
||||
The database is compatible with SDL v2.0.10 and newer.
|
||||
|
||||
## Create New Mappings
|
||||
A mapping looks like this:
|
||||
```
|
||||
030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
|
||||
```
|
||||
It includes controller GUID (`030000004c050000c405000000010000`), a name (`PS4 Controller`), button / axis mappings (`leftshoulder:b4`) and a platform (`platform:Mac OS X`).
|
||||
|
||||
Please make sure to check that the name is a good description of the controller. If relevant, include the controller's name and model number.
|
||||
|
||||
## Mapping Guide
|
||||
|
||||

|
||||
|
||||
## Mapping Tools
|
||||
There are a few different tools that let you create mappings.
|
||||
|
||||
### [SDL2 Gamepad Tool](http://www.generalarcade.com/gamepadtool/)
|
||||
Third party cross-platform tool with GUI (Windows, macOS and Linux)
|
||||
|
||||
#### Note: While convenient, this tool has fallen out of date as SDL has amended and added new features for gamepad support (see issue [#478](https://github.com/gabomdq/SDL_GameControllerDB/issues/476)). As such, maps authored with this tool require greater scrutiny to ensure they will not break support for explicit mappings the SDL project provides.
|
||||
|
||||
### [SDL2 Gamepad Mapper](https://gitlab.com/ryochan7/sdl2-gamepad-mapper/-/releases)
|
||||
Open source GUI app for authoring mappings. Builds available for Windows and Linux.
|
||||
|
||||
### [SDL](https://github.com/libsdl-org/SDL/releases/latest)
|
||||
[testcontroller (SDL3)](https://github.com/libsdl-org/SDL/blob/main/test/testcontroller.c) and [controllermap (SDL2)](https://github.com/libsdl-org/SDL/blob/SDL2/test/controllermap.c) utilities are the official tools to create these mappings on all SDL supported platforms (Windows, Mac, Linux, iOS, Android, etc).
|
||||
|
||||
### [Steam](http://store.steampowered.com)
|
||||
In Steam's Big Picture mode, configure your gamepad. Then look in `[steam_installation_directory]/config/config.vdf` in your Steam installation directory for the `SDL_GamepadBind` entry. It is one of the last entries, it will look something like this:
|
||||
|
||||
```
|
||||
"SDL_GamepadBind" "030000004c050000c405000000010000,PS4 Controller,platform:Windows,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,"
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
* [SDL2](http://www.libsdl.org)
|
||||
* [SDL_GameControllerAddMappingsFromFile](http://wiki.libsdl.org/SDL_GameControllerAddMappingsFromFile)
|
||||
@@ -0,0 +1,26 @@
|
||||
# SPDX-License-Identifier: Zlib
|
||||
|
||||
import difflib
|
||||
import sys
|
||||
|
||||
CROSS_PLATFORM=False
|
||||
|
||||
cdict = {}
|
||||
for i, l in enumerate(open("gamecontrollerdb.txt")):
|
||||
l = l.strip()
|
||||
if l.startswith("#") or not l:
|
||||
continue
|
||||
|
||||
c = l.split(",")
|
||||
key = tuple([c[0]]+[ce for ce in c[1:] if "platform:" in ce])
|
||||
if CROSS_PLATFORM:
|
||||
key = c[0]
|
||||
|
||||
if key in cdict:
|
||||
print("Duplicate:", c[1], "at line", i + 1)
|
||||
out = list(difflib.unified_diff(cdict[key], sorted(c), n=0))[3:]
|
||||
out = [o for o in out if not o.startswith("@@")]
|
||||
print("\t", " ".join(out))
|
||||
if not CROSS_PLATFORM:
|
||||
sys.exit(1)
|
||||
cdict[key] = sorted(c)
|
||||
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1,92 @@
|
||||
---
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: true
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: false
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: InlineOnly
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Stroustrup
|
||||
BreakBeforeInheritanceComma: true
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: ''
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 2
|
||||
ContinuationIndentWidth: 2
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros: []
|
||||
IndentCaseLabels: false
|
||||
IncludeCategories:
|
||||
- Regex: '^("|<)stdafx\.h(pp)?("|>)'
|
||||
Priority: -1
|
||||
- Regex: '^<(W|w)indows.h>'
|
||||
Priority: 1
|
||||
- Regex: '^<'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: '(_test|_win|_linux|_mac|_ios|_osx|_null)?$'
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
PenaltyBreakAssignment: 0
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 9999999
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
---
|
||||
Language: Cpp
|
||||
---
|
||||
Language: ObjC
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
---
|
||||
Language: Java
|
||||
BasedOnStyle: Google
|
||||
BreakAfterJavaFieldAnnotations: true
|
||||
...
|
||||
@@ -0,0 +1,5 @@
|
||||
/build*/
|
||||
/.vscode/
|
||||
/thirdparty/
|
||||
.vs/
|
||||
.DS_Store
|
||||
@@ -0,0 +1,12 @@
|
||||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/ingydotnet/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = git@github.com:/discord/discord-rpc.git
|
||||
branch = 963aa9f3e5ce81a4682c6ca3d136cddda614db33
|
||||
commit = 963aa9f3e5ce81a4682c6ca3d136cddda614db33
|
||||
parent = d28c28e9d34337b80c906572e2046a77ab3cb9dd
|
||||
method = merge
|
||||
cmdver = 0.4.6
|
||||
@@ -0,0 +1,47 @@
|
||||
language: cpp
|
||||
|
||||
env:
|
||||
global:
|
||||
- CLANG_FORMAT_SUFFIX="-dummy" # don't use formatting on Travis, this is
|
||||
# needed not to use default 3.5 version
|
||||
# which is too old.
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
env: MATRIX_EVAL="CC=gcc-5 && CXX=g++-5"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-5
|
||||
- os: linux
|
||||
env: MATRIX_EVAL="CC=clang-4.0 && CXX=clang++-4.0"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-trusty-4.0
|
||||
packages:
|
||||
- clang-4.0
|
||||
- os: linux
|
||||
env: MATRIX_EVAL="CC=clang-5.0 && CXX=clang++-5.0"
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-trusty-5.0
|
||||
packages:
|
||||
- clang-5.0
|
||||
- os: osx
|
||||
osx_image: xcode9
|
||||
|
||||
# prevent Travis from overwriting our CXX variables
|
||||
before_install:
|
||||
- eval "${MATRIX_EVAL}"
|
||||
- echo $CXX
|
||||
|
||||
script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCLANG_FORMAT_SUFFIX=$CLANG_FORMAT_SUFFIX -DWARNINGS_AS_ERRORS=On --config Release ..
|
||||
- cmake --build . -- -j2
|
||||
@@ -0,0 +1,56 @@
|
||||
cmake_minimum_required (VERSION 3.2.0)
|
||||
project (DiscordRPC)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
option(BUILD_EXAMPLES "Build example apps" ON)
|
||||
|
||||
# format
|
||||
file(GLOB_RECURSE ALL_SOURCE_FILES
|
||||
examples/*.cpp examples/*.h examples/*.c
|
||||
include/*.h
|
||||
src/*.cpp src/*.h src/*.c
|
||||
)
|
||||
|
||||
# Set CLANG_FORMAT_SUFFIX if you are using custom clang-format, e.g. clang-format-5.0
|
||||
#find_program(CLANG_FORMAT_CMD clang-format${CLANG_FORMAT_SUFFIX})
|
||||
set(CLANG_FORMAT_CMD OFF)
|
||||
if (CLANG_FORMAT_CMD)
|
||||
add_custom_target(
|
||||
clangformat
|
||||
COMMAND ${CLANG_FORMAT_CMD}
|
||||
-i -style=file -fallback-style=none
|
||||
${ALL_SOURCE_FILES}
|
||||
DEPENDS
|
||||
${ALL_SOURCE_FILES}
|
||||
)
|
||||
endif(CLANG_FORMAT_CMD)
|
||||
|
||||
# thirdparty stuff
|
||||
execute_process(
|
||||
COMMAND mkdir ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty
|
||||
ERROR_QUIET
|
||||
)
|
||||
|
||||
find_file(RAPIDJSONTEST NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH)
|
||||
if (NOT RAPIDJSONTEST)
|
||||
message("no rapidjson, download")
|
||||
set(RJ_TAR_FILE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/v1.1.0.tar.gz)
|
||||
file(DOWNLOAD https://github.com/miloyip/rapidjson/archive/v1.1.0.tar.gz ${RJ_TAR_FILE})
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${RJ_TAR_FILE}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty
|
||||
)
|
||||
file(REMOVE ${RJ_TAR_FILE})
|
||||
endif(NOT RAPIDJSONTEST)
|
||||
|
||||
find_file(RAPIDJSON NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH)
|
||||
|
||||
add_library(rapidjson STATIC IMPORTED ${RAPIDJSON})
|
||||
|
||||
# add subdirs
|
||||
|
||||
add_subdirectory(src)
|
||||
if (BUILD_EXAMPLES)
|
||||
add_subdirectory(examples/send-presence)
|
||||
endif(BUILD_EXAMPLES)
|
||||
@@ -0,0 +1,19 @@
|
||||
Copyright 2017 Discord, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,158 @@
|
||||
# Discord RPC
|
||||
|
||||
## Deprecation Notice
|
||||
|
||||
This library has been deprecated in favor of Discord's GameSDK. [Learn more here](https://discordapp.com/developers/docs/game-sdk/sdk-starter-guide)
|
||||
|
||||
---
|
||||
|
||||
This is a library for interfacing your game with a locally running Discord desktop client. It's known to work on Windows, macOS, and Linux. You can use the lib directly if you like, or use it as a guide to writing your own if it doesn't suit your game as is. PRs/feedback welcome if you have an improvement everyone might want, or can describe how this doesn't meet your needs.
|
||||
|
||||
Included here are some quick demos that implement the very minimal subset to show current status, and
|
||||
have callbacks for where a more complete game would do more things (joining, spectating, etc).
|
||||
|
||||
## Documentation
|
||||
|
||||
The most up to date documentation for Rich Presence can always be found on our [developer site](https://discordapp.com/developers/docs/rich-presence/how-to)! If you're interested in rolling your own native implementation of Rich Presence via IPC sockets instead of using our SDK—hey, you've got free time, right?—check out the ["Hard Mode" documentation](https://github.com/discordapp/discord-rpc/blob/master/documentation/hard-mode.md).
|
||||
|
||||
## Basic Usage
|
||||
|
||||
Zeroith, you should be set up to build things because you are a game developer, right?
|
||||
|
||||
First, head on over to the [Discord developers site](https://discordapp.com/developers/applications/me) and make yourself an app. Keep track of `Client ID` -- you'll need it here to pass to the init function.
|
||||
|
||||
### Unreal Engine 4 Setup
|
||||
|
||||
To use the Rich Presense plugin with Unreal Engine Projects:
|
||||
|
||||
1. Download the latest [release](https://github.com/discordapp/discord-rpc/releases) for each operating system you are targeting and the zipped source code
|
||||
2. In the source code zip, copy the UE plugin—`examples/unrealstatus/Plugins/discordrpc`—to your project's plugin directory
|
||||
3. At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create an `Include` folder and copy `discord_rpc.h` and `discord_register.h` to it from the zip
|
||||
4. Follow the steps below for each OS
|
||||
5. Build your UE4 project
|
||||
6. Launch the editor, and enable the Discord plugin.
|
||||
|
||||
#### Windows
|
||||
|
||||
- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Win64` folder
|
||||
- Copy `lib/discord-rpc.lib` and `bin/discord-rpc.dll` from `[RELEASE_ZIP]/win64-dynamic` to the `Win64` folder
|
||||
|
||||
#### Mac
|
||||
|
||||
- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Mac` folder
|
||||
- Copy `libdiscord-rpc.dylib` from `[RELEASE_ZIP]/osx-dynamic/lib` to the `Mac` folder
|
||||
|
||||
#### Linux
|
||||
|
||||
- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Linux` folder
|
||||
- Inside, create another folder `x86_64-unknown-linux-gnu`
|
||||
- Copy `libdiscord-rpc.so` from `[RELEASE_ZIP]/linux-dynamic/lib` to `Linux/x86_64-unknown-linux-gnu`
|
||||
|
||||
### Unity Setup
|
||||
|
||||
If you're a Unity developer looking to integrate Rich Presence into your game, follow this simple guide to get started towards success:
|
||||
|
||||
1. Download the DLLs for any platform that you need from [our releases](https://github.com/discordapp/discord-rpc/releases)
|
||||
2. In your Unity project, create a `Plugins` folder inside your `Assets` folder if you don't already have one
|
||||
3. Copy the file `DiscordRpc.cs` from [here](https://github.com/discordapp/discord-rpc/blob/master/examples/button-clicker/Assets/DiscordRpc.cs) into your `Assets` folder. This is basically your header file for the SDK
|
||||
|
||||
We've got our `Plugins` folder ready, so let's get platform-specific!
|
||||
|
||||
#### Windows
|
||||
|
||||
4. Create `x86` and `x86_64` folders inside `Assets/Plugins/`
|
||||
5. Copy `discord-rpc-win/win64-dynamic/bin/discord-rpc.dll` to `Assets/Plugins/x86_64/`
|
||||
6. Copy `discord-rpc-win/win32-dynamic/bin/discord-rpc.dll` to `Assets/Plugins/x86/`
|
||||
7. Click on both DLLs and make sure they are targetting the correct architectures in the Unity editor properties pane
|
||||
8. Done!
|
||||
|
||||
#### MacOS
|
||||
|
||||
4. Copy `discord-rpc-osx/osx-dynamic/lib/libdiscord-rpc.dylib` to `Assets/Plugins/`
|
||||
5. Rename `libdiscord-rpc.dylib` to `discord-rpc.bundle`
|
||||
6. Done!
|
||||
|
||||
#### Linux
|
||||
|
||||
4. Copy `discord-rpc-linux/linux-dynamic-lib/libdiscord-rpc.so` to `Assets/Plugins/`
|
||||
5. Done!
|
||||
|
||||
You're ready to roll! For code examples on how to interact with the SDK using the `DiscordRpc.cs` header file, check out [our example](https://github.com/discordapp/discord-rpc/blob/master/examples/button-clicker/Assets/DiscordController.cs)
|
||||
|
||||
### From package
|
||||
|
||||
Download a release package for your platform(s) -- they have subdirs with various prebuilt options, select the one you need add `/include` to your compile includes, `/lib` to your linker paths, and link with `discord-rpc`. For the dynamically linked builds, you'll need to ship the associated file along with your game.
|
||||
|
||||
### From repo
|
||||
|
||||
First-eth, you'll want `CMake`. There's a few different ways to install it on your system, and you should refer to [their website](https://cmake.org/install/). Many package managers provide ways of installing CMake as well.
|
||||
|
||||
To make sure it's installed correctly, type `cmake --version` into your flavor of terminal/cmd. If you get a response with a version number, you're good to go!
|
||||
|
||||
There's a [CMake](https://cmake.org/download/) file that should be able to generate the lib for you; Sometimes I use it like this:
|
||||
|
||||
```sh
|
||||
cd <path to discord-rpc>
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=<path to install discord-rpc to>
|
||||
cmake --build . --config Release --target install
|
||||
```
|
||||
|
||||
There is a wrapper build script `build.py` that runs `cmake` with a few different options.
|
||||
|
||||
Usually, I run `build.py` to get things started, then use the generated project files as I work on things. It does depend on `click` library, so do a quick `pip install click` to make sure you have it if you want to run `build.py`.
|
||||
|
||||
There are some CMake options you might care about:
|
||||
|
||||
| flag | default | does |
|
||||
| ---------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ENABLE_IO_THREAD` | `ON` | When enabled, we start up a thread to do io processing, if disabled you should call `Discord_UpdateConnection` yourself. |
|
||||
| `USE_STATIC_CRT` | `OFF` | (Windows) Enable to statically link the CRT, avoiding requiring users install the redistributable package. (The prebuilt binaries enable this option) |
|
||||
| [`BUILD_SHARED_LIBS`](https://cmake.org/cmake/help/v3.7/variable/BUILD_SHARED_LIBS.html) | `OFF` | Build library as a DLL |
|
||||
| `WARNINGS_AS_ERRORS` | `OFF` | When enabled, compiles with `-Werror` (on \*nix platforms). |
|
||||
|
||||
## Continuous Builds
|
||||
|
||||
Why do we have three of these? Three times the fun!
|
||||
|
||||
| CI | badge |
|
||||
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| TravisCI | [](https://travis-ci.org/discordapp/discord-rpc) |
|
||||
| AppVeyor | [](https://ci.appveyor.com/project/crmarsh/discord-rpc) |
|
||||
| Buildkite (internal) | [](https://buildkite.com/discord/discord-rpc) |
|
||||
|
||||
## Sample: send-presence
|
||||
|
||||
This is a text adventure "game" that inits/deinits the connection to Discord, and sends a presence update on each command.
|
||||
|
||||
## Sample: button-clicker
|
||||
|
||||
This is a sample [Unity](https://unity3d.com/) project that wraps a DLL version of the library, and sends presence updates when you click on a button. Run `python build.py unity` in the root directory to build the correct library files and place them in their respective folders.
|
||||
|
||||
## Sample: unrealstatus
|
||||
|
||||
This is a sample [Unreal](https://www.unrealengine.com) project that wraps the DLL version of the library with an Unreal plugin, exposes a blueprint class for interacting with it, and uses that to make a very simple UI. Run `python build.py unreal` in the root directory to build the correct library files and place them in their respective folders.
|
||||
|
||||
## Wrappers and Implementations
|
||||
|
||||
Below is a table of unofficial, community-developed wrappers for and implementations of Rich Presence in various languages. If you would like to have yours added, please make a pull request adding your repository to the table. The repository should include:
|
||||
|
||||
- The code
|
||||
- A brief ReadMe of how to use it
|
||||
- A working example
|
||||
|
||||
###### Rich Presence Wrappers and Implementations
|
||||
|
||||
| Name | Language |
|
||||
| ------------------------------------------------------------------------- | --------------------------------- |
|
||||
| [Discord RPC C#](https://github.com/Lachee/discord-rpc-csharp) | C# |
|
||||
| [Discord RPC D](https://github.com/voidblaster/discord-rpc-d) | [D](https://dlang.org/) |
|
||||
| [discord-rpc.jar](https://github.com/Vatuu/discord-rpc 'Discord-RPC.jar') | Java |
|
||||
| [java-discord-rpc](https://github.com/MinnDevelopment/java-discord-rpc) | Java |
|
||||
| [Discord-IPC](https://github.com/jagrosh/DiscordIPC) | Java |
|
||||
| [Discord Rich Presence](https://npmjs.org/discord-rich-presence) | JavaScript |
|
||||
| [drpc4k](https://github.com/Bluexin/drpc4k) | [Kotlin](https://kotlinlang.org/) |
|
||||
| [lua-discordRPC](https://github.com/pfirsich/lua-discordRPC) | LuaJIT (FFI) |
|
||||
| [pypresence](https://github.com/qwertyquerty/pypresence) | [Python](https://python.org/) |
|
||||
| [SwordRPC](https://github.com/Azoy/SwordRPC) | [Swift](https://swift.org) |
|
||||
@@ -0,0 +1,17 @@
|
||||
version: '{build}'
|
||||
install:
|
||||
- python -m pip install click
|
||||
|
||||
build_script:
|
||||
- mkdir examples\unrealstatus\Plugins\discordrpc\Binaries\ThirdParty\discordrpcLibrary\Win64
|
||||
- python build.py
|
||||
|
||||
artifacts:
|
||||
- path: builds\install\win32-dynamic
|
||||
name: win32-dynamic
|
||||
- path: builds\install\win32-static
|
||||
name: win32-static
|
||||
- path: builds\install\win64-dynamic
|
||||
name: win64-dynamic
|
||||
- path: builds\install\win64-static
|
||||
name: win64-static
|
||||
@@ -0,0 +1,304 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import shutil
|
||||
import zipfile
|
||||
from contextlib import contextmanager
|
||||
import click
|
||||
|
||||
|
||||
def get_platform():
|
||||
""" a name for the platform """
|
||||
if sys.platform.startswith('win'):
|
||||
return 'win'
|
||||
elif sys.platform == 'darwin':
|
||||
return 'osx'
|
||||
elif sys.platform.startswith('linux'):
|
||||
return 'linux'
|
||||
raise Exception('Unsupported platform ' + sys.platform)
|
||||
|
||||
|
||||
SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
# we use Buildkite which sets this env variable by default
|
||||
IS_BUILD_MACHINE = os.environ.get('CI', '') == 'true'
|
||||
PLATFORM = get_platform()
|
||||
INSTALL_ROOT = os.path.join(SCRIPT_PATH, 'builds', 'install')
|
||||
|
||||
|
||||
def get_signtool():
|
||||
""" get path to code signing tool """
|
||||
if PLATFORM == 'win':
|
||||
sdk_dir = 'c:\\Program Files (x86)\\Windows Kits\\10' # os.environ['WindowsSdkDir']
|
||||
return os.path.join(sdk_dir, 'bin', 'x86', 'signtool.exe')
|
||||
elif PLATFORM == 'osx':
|
||||
return '/usr/bin/codesign'
|
||||
|
||||
|
||||
@contextmanager
|
||||
def cd(new_dir):
|
||||
""" Temporarily change current directory """
|
||||
if new_dir:
|
||||
old_dir = os.getcwd()
|
||||
os.chdir(new_dir)
|
||||
yield
|
||||
if new_dir:
|
||||
os.chdir(old_dir)
|
||||
|
||||
|
||||
def mkdir_p(path):
|
||||
""" mkdir -p """
|
||||
if not os.path.isdir(path):
|
||||
click.secho('Making ' + path, fg='yellow')
|
||||
os.makedirs(path)
|
||||
|
||||
|
||||
@click.group(invoke_without_command=True)
|
||||
@click.pass_context
|
||||
@click.option('--clean', is_flag=True)
|
||||
def cli(ctx, clean):
|
||||
""" click wrapper for command line stuff """
|
||||
if ctx.invoked_subcommand is None:
|
||||
ctx.invoke(libs, clean=clean)
|
||||
if IS_BUILD_MACHINE:
|
||||
ctx.invoke(sign)
|
||||
ctx.invoke(archive)
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.pass_context
|
||||
def unity(ctx):
|
||||
""" build just dynamic libs for use in unity project """
|
||||
ctx.invoke(libs, clean=False, static=False, shared=True, skip_formatter=True, just_release=True)
|
||||
BUILDS = []
|
||||
|
||||
click.echo('--- Copying libs and header into unity example')
|
||||
UNITY_PROJECT_PATH = os.path.join(SCRIPT_PATH, 'examples', 'button-clicker', 'Assets', 'Plugins')
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
LIBRARY_NAME = 'discord-rpc.dll'
|
||||
BUILD_64_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'win64-dynamic', 'src', 'Release')
|
||||
UNITY_64_DLL_PATH = os.path.join(UNITY_PROJECT_PATH, 'x86_64')
|
||||
BUILDS.append({BUILD_64_BASE_PATH: UNITY_64_DLL_PATH})
|
||||
|
||||
BUILD_32_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'win32-dynamic', 'src', 'Release')
|
||||
UNITY_32_DLL_PATH = os.path.join(UNITY_PROJECT_PATH, 'x86')
|
||||
BUILDS.append({BUILD_32_BASE_PATH: UNITY_32_DLL_PATH})
|
||||
|
||||
elif sys.platform == 'darwin':
|
||||
LIBRARY_NAME = 'discord-rpc.bundle'
|
||||
BUILD_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'osx-dynamic', 'src')
|
||||
UNITY_DLL_PATH = UNITY_PROJECT_PATH
|
||||
os.rename(
|
||||
os.path.join(BUILD_BASE_PATH, 'libdiscord-rpc.dylib'), os.path.join(BUILD_BASE_PATH, 'discord-rpc.bundle'))
|
||||
|
||||
BUILDS.append({BUILD_BASE_PATH: UNITY_DLL_PATH})
|
||||
|
||||
elif sys.platform.startswith('linux'):
|
||||
LIBRARY_NAME = 'discord-rpc.so'
|
||||
BUILD_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'linux-dynamic', 'src')
|
||||
UNITY_DLL_PATH = os.path.join(UNITY_PROJECT_PATH, 'x86')
|
||||
os.rename(os.path.join(BUILD_BASE_PATH, 'libdiscord-rpc.so'), os.path.join(BUILD_BASE_PATH, 'discord-rpc.so'))
|
||||
|
||||
BUILDS.append({BUILD_BASE_PATH: UNITY_DLL_PATH})
|
||||
|
||||
else:
|
||||
raise Exception('Unsupported platform ' + sys.platform)
|
||||
|
||||
for build in BUILDS:
|
||||
for i in build:
|
||||
mkdir_p(build[i])
|
||||
shutil.copy(os.path.join(i, LIBRARY_NAME), build[i])
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.pass_context
|
||||
def unreal(ctx):
|
||||
""" build libs and copy them into the unreal project """
|
||||
ctx.invoke(libs, clean=False, static=False, shared=True, skip_formatter=True, just_release=True)
|
||||
BUILDS = []
|
||||
|
||||
click.echo('--- Copying libs and header into unreal example')
|
||||
UNREAL_PROJECT_PATH = os.path.join(SCRIPT_PATH, 'examples', 'unrealstatus', 'Plugins', 'discordrpc')
|
||||
UNREAL_INCLUDE_PATH = os.path.join(UNREAL_PROJECT_PATH, 'Source', 'ThirdParty', 'DiscordRpcLibrary', 'Include')
|
||||
mkdir_p(UNREAL_INCLUDE_PATH)
|
||||
shutil.copy(os.path.join(SCRIPT_PATH, 'include', 'discord_rpc.h'), UNREAL_INCLUDE_PATH)
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
LIBRARY_NAME = 'discord-rpc.lib'
|
||||
BUILD_64_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'win64-dynamic', 'src', 'Release')
|
||||
UNREAL_64_DLL_PATH = os.path.join(UNREAL_PROJECT_PATH, 'Source', 'ThirdParty', 'DiscordRpcLibrary', 'Win64')
|
||||
BUILDS.append({BUILD_64_BASE_PATH: UNREAL_64_DLL_PATH})
|
||||
|
||||
BUILD_32_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'win32-dynamic', 'src', 'Release')
|
||||
UNREAL_32_DLL_PATH = os.path.join(UNREAL_PROJECT_PATH, 'Source', 'ThirdParty', 'DiscordRpcLibrary', 'Win32')
|
||||
BUILDS.append({BUILD_32_BASE_PATH: UNREAL_32_DLL_PATH})
|
||||
|
||||
elif sys.platform == 'darwin':
|
||||
LIBRARY_NAME = 'libdiscord-rpc.dylib'
|
||||
BUILD_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'osx-dynamic', 'src')
|
||||
UNREAL_DLL_PATH = os.path.join(UNREAL_PROJECT_PATH, 'Source', 'ThirdParty', 'DiscordRpcLibrary', 'Mac')
|
||||
|
||||
BUILDS.append({BUILD_BASE_PATH: UNREAL_DLL_PATH})
|
||||
|
||||
elif sys.platform.startswith('linux'):
|
||||
LIBRARY_NAME = 'libdiscord-rpc.so'
|
||||
BUILD_BASE_PATH = os.path.join(SCRIPT_PATH, 'builds', 'linux-dynamic', 'src')
|
||||
UNREAL_DLL_PATH = os.path.join(UNREAL_PROJECT_PATH, 'Source', 'ThirdParty', 'DiscordRpcLibrary', 'Linux')
|
||||
|
||||
BUILDS.append({BUILD_BASE_PATH: UNREAL_DLL_PATH})
|
||||
|
||||
else:
|
||||
raise Exception('Unsupported platform ' + sys.platform)
|
||||
|
||||
for build in BUILDS:
|
||||
for i in build:
|
||||
mkdir_p(build[i])
|
||||
shutil.copy(os.path.join(i, LIBRARY_NAME), build[i])
|
||||
|
||||
|
||||
def build_lib(build_name, generator, options, just_release):
|
||||
""" Create a dir under builds, run build and install in it """
|
||||
build_path = os.path.join(SCRIPT_PATH, 'builds', build_name)
|
||||
install_path = os.path.join(INSTALL_ROOT, build_name)
|
||||
mkdir_p(build_path)
|
||||
mkdir_p(install_path)
|
||||
with cd(build_path):
|
||||
initial_cmake = ['cmake', SCRIPT_PATH, '-DCMAKE_INSTALL_PREFIX=%s' % os.path.join('..', 'install', build_name)]
|
||||
if generator:
|
||||
initial_cmake.extend(['-G', generator])
|
||||
for key in options:
|
||||
val = options[key]
|
||||
if type(val) is bool:
|
||||
val = 'ON' if val else 'OFF'
|
||||
initial_cmake.append('-D%s=%s' % (key, val))
|
||||
click.echo('--- Building ' + build_name)
|
||||
subprocess.check_call(initial_cmake)
|
||||
if not just_release:
|
||||
subprocess.check_call(['cmake', '--build', '.', '--config', 'Debug'])
|
||||
subprocess.check_call(['cmake', '--build', '.', '--config', 'Release', '--target', 'install'])
|
||||
|
||||
|
||||
@cli.command()
|
||||
def archive():
|
||||
""" create zip of install dir """
|
||||
click.echo('--- Archiving')
|
||||
archive_file_path = os.path.join(SCRIPT_PATH, 'builds', 'discord-rpc-%s.zip' % get_platform())
|
||||
archive_file = zipfile.ZipFile(archive_file_path, 'w', zipfile.ZIP_DEFLATED)
|
||||
archive_src_base_path = INSTALL_ROOT
|
||||
archive_dst_base_path = 'discord-rpc'
|
||||
with cd(archive_src_base_path):
|
||||
for path, _, filenames in os.walk('.'):
|
||||
for fname in filenames:
|
||||
fpath = os.path.join(path, fname)
|
||||
dst_path = os.path.normpath(os.path.join(archive_dst_base_path, fpath))
|
||||
click.echo('Adding ' + dst_path)
|
||||
archive_file.write(fpath, dst_path)
|
||||
|
||||
|
||||
@cli.command()
|
||||
def sign():
|
||||
""" Do code signing within install directory using our cert """
|
||||
tool = get_signtool()
|
||||
signable_extensions = set()
|
||||
if PLATFORM == 'win':
|
||||
signable_extensions.add('.dll')
|
||||
sign_command_base = [
|
||||
tool,
|
||||
'sign',
|
||||
'/n',
|
||||
'Discord Inc.',
|
||||
'/a',
|
||||
'/tr',
|
||||
'http://timestamp.digicert.com/rfc3161',
|
||||
'/as',
|
||||
'/td',
|
||||
'sha256',
|
||||
'/fd',
|
||||
'sha256',
|
||||
]
|
||||
elif PLATFORM == 'osx':
|
||||
signable_extensions.add('.dylib')
|
||||
sign_command_base = [
|
||||
tool,
|
||||
'--keychain',
|
||||
os.path.expanduser('~/Library/Keychains/login.keychain'),
|
||||
'-vvvv',
|
||||
'--deep',
|
||||
'--force',
|
||||
'--sign',
|
||||
'Developer ID Application: Hammer & Chisel Inc. (53Q6R32WPB)',
|
||||
]
|
||||
else:
|
||||
click.secho('Not signing things on this platform yet', fg='red')
|
||||
return
|
||||
|
||||
click.echo('--- Signing')
|
||||
for path, _, filenames in os.walk(INSTALL_ROOT):
|
||||
for fname in filenames:
|
||||
ext = os.path.splitext(fname)[1]
|
||||
if ext not in signable_extensions:
|
||||
continue
|
||||
fpath = os.path.join(path, fname)
|
||||
click.echo('Sign ' + fpath)
|
||||
sign_command = sign_command_base + [fpath]
|
||||
subprocess.check_call(sign_command)
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option('--clean', is_flag=True)
|
||||
@click.option('--static', is_flag=True)
|
||||
@click.option('--shared', is_flag=True)
|
||||
@click.option('--skip_formatter', is_flag=True)
|
||||
@click.option('--just_release', is_flag=True)
|
||||
def libs(clean, static, shared, skip_formatter, just_release):
|
||||
""" Do all the builds for this platform """
|
||||
if clean:
|
||||
shutil.rmtree('builds', ignore_errors=True)
|
||||
|
||||
mkdir_p('builds')
|
||||
|
||||
if not (static or shared):
|
||||
static = True
|
||||
shared = True
|
||||
|
||||
static_options = {}
|
||||
dynamic_options = {
|
||||
'BUILD_SHARED_LIBS': True,
|
||||
'USE_STATIC_CRT': True,
|
||||
}
|
||||
|
||||
if skip_formatter or IS_BUILD_MACHINE:
|
||||
static_options['CLANG_FORMAT_SUFFIX'] = 'none'
|
||||
dynamic_options['CLANG_FORMAT_SUFFIX'] = 'none'
|
||||
|
||||
if IS_BUILD_MACHINE:
|
||||
just_release = True
|
||||
static_options['WARNINGS_AS_ERRORS'] = True
|
||||
dynamic_options['WARNINGS_AS_ERRORS'] = True
|
||||
|
||||
if PLATFORM == 'win':
|
||||
generator32 = 'Visual Studio 14 2015'
|
||||
generator64 = 'Visual Studio 14 2015 Win64'
|
||||
if static:
|
||||
build_lib('win32-static', generator32, static_options, just_release)
|
||||
build_lib('win64-static', generator64, static_options, just_release)
|
||||
if shared:
|
||||
build_lib('win32-dynamic', generator32, dynamic_options, just_release)
|
||||
build_lib('win64-dynamic', generator64, dynamic_options, just_release)
|
||||
elif PLATFORM == 'osx':
|
||||
if static:
|
||||
build_lib('osx-static', None, static_options, just_release)
|
||||
if shared:
|
||||
build_lib('osx-dynamic', None, dynamic_options, just_release)
|
||||
elif PLATFORM == 'linux':
|
||||
if static:
|
||||
build_lib('linux-static', None, static_options, just_release)
|
||||
if shared:
|
||||
build_lib('linux-dynamic', None, dynamic_options, just_release)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.chdir(SCRIPT_PATH)
|
||||
sys.exit(cli())
|
||||
@@ -0,0 +1,164 @@
|
||||
# Hard Mode: Roll Your Own Client
|
||||
|
||||
Discord's Rich Presence feature is designed as an obfuscated addition to our existing [RPC infrastructure](https://discordapp.com/developers/docs/topics/rpc). The standalone library and header files make it easy for any dev to drop it into their game.
|
||||
|
||||
Our library communicates with Discord over the local Discord RPC socket. We've already done the work in connecting properly, handling disconnects and reconnects, and other RPC intracacies, but those who have done this implementation for our private alpha Voice and Chat SDK can simply make use of the new RPC commands and events to implement Rich Presence.
|
||||
|
||||
## Hark! A warning!
|
||||
|
||||
By committing to an RPC-only integration, you decide to forego the work our library and header file have done for you in the way of error handling, state storage, disconnecting and reconnecting, and other quality of life abstractions. While simply implementing the new RPC command and events will enable Rich Presence for your game, we highly suggest that you do your best to mimic the functionality of the SDK the most that you can. It ensure not only code quality on your part, but also an excellent experience on the part of your players.
|
||||
|
||||
## Application Protocol Registration
|
||||
|
||||
One thing that cannot be explicitly done over RPC is registering an application protocol for your game. If you choose to do an RPC-only implementation, you will have to register your application protocol yourself in the format of `discord-[your_app_id]://`. You can use `Discord_Register()` as a good(?) example of how to properly register an application protocol for use with Discord. For OSX and Linux it is probably simpler to handle the protocol registration as part of your install/packaging.
|
||||
|
||||
## New RPC Command
|
||||
|
||||
The new RPC command for Rich Presence is `SET_ACTIVITY`. The fields are similar to what is outlined in the SDK; we've combined similar fields into objects for the sake of less data on the wire.
|
||||
|
||||
The one major difference is the `party.size` field. It is an array with a size of two. The first element is the current party size, `partySize` from the main documentation. The second element is the maximum party size, `partyMax` from the main documentation.
|
||||
|
||||
Below is a full example of a `SET_ACTIVITY` command. Field restrictions like size are the same as outlined in the main documentation.
|
||||
|
||||
```
|
||||
{
|
||||
"cmd": "SET_ACTIVITY",
|
||||
"args": {
|
||||
"pid": 9999, // Your application's process id - required field
|
||||
"activity": {
|
||||
"state": "In a Group",
|
||||
"details": "Competitive | In a Match",
|
||||
"timestamps": {
|
||||
"start": time(nullptr),
|
||||
"end": time(nullptr) + ((60 * 5) + 23)
|
||||
},
|
||||
"assets": {
|
||||
"large_image": "numbani_map",
|
||||
"large_text": "Numbani",
|
||||
"small_image": "pharah_profile",
|
||||
"small_text": "Pharah"
|
||||
},
|
||||
"party": {
|
||||
"id": GameEngine.GetPartyId(),
|
||||
"size": [3, 6]
|
||||
},
|
||||
"secrets": {
|
||||
"join": "025ed05c71f639de8bfaa0d679d7c94b2fdce12f",
|
||||
"spectate": "e7eb30d2ee025ed05c71ea495f770b76454ee4e0",
|
||||
"match": "4b2fdce12f639de8bfa7e3591b71a0d679d7c93f"
|
||||
},
|
||||
"instance": true
|
||||
}
|
||||
},
|
||||
"nonce": "647d814a-4cf8-4fbb-948f-898abd24f55b"
|
||||
}
|
||||
```
|
||||
|
||||
## New RPC Events
|
||||
|
||||
The three new RPC events for Rich Presence power the ability to join and spectate your friends' games.
|
||||
|
||||
First is the `ACTIVITY_JOIN` event:
|
||||
|
||||
```json
|
||||
{
|
||||
"cmd": "DISPATCH",
|
||||
"data": {
|
||||
"secret": "025ed05c71f639de8bfaa0d679d7c94b2fdce12f"
|
||||
},
|
||||
"evt": "ACTIVITY_JOIN"
|
||||
}
|
||||
```
|
||||
|
||||
Second is the `ACTIVITY_SPECTATE` event:
|
||||
|
||||
```json
|
||||
{
|
||||
"cmd": "DISPATCH",
|
||||
"data": {
|
||||
"secret": "e7eb30d2ee025ed05c71ea495f770b76454ee4e0"
|
||||
},
|
||||
"evt": "ACTIVITY_SPECTATE"
|
||||
}
|
||||
```
|
||||
|
||||
And third is the `ACTIVITY_JOIN_REQUEST` event:
|
||||
|
||||
```json
|
||||
{
|
||||
"cmd": "DISPATCH",
|
||||
"data": {
|
||||
"user": {
|
||||
"id": "53908232506183680",
|
||||
"username": "Mason",
|
||||
"discriminator": "1337",
|
||||
"avatar": "a_bab14f271d565501444b2ca3be944b25"
|
||||
}
|
||||
},
|
||||
"evt": "ACTIVITY_JOIN_REQUEST"
|
||||
}
|
||||
```
|
||||
|
||||
In order to receive these events, you need to [subscribe](https://discordapp.com/developers/docs/topics/rpc#subscribe) to them like so:
|
||||
|
||||
```json
|
||||
{
|
||||
"nonce": "be9a6de3-31d0-4767-a8e9-4818c5690015",
|
||||
"evt": "ACTIVITY_JOIN",
|
||||
"cmd": "SUBSCRIBE"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"nonce": "ae9qdde3-31d0-8989-a8e9-dnakwy174he",
|
||||
"evt": "ACTIVITY_SPECTATE",
|
||||
"cmd": "SUBSCRIBE"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"nonce": "5dc0c062-98c6-47a0-8922-bbb52e9d6afa",
|
||||
"evt": "ACTIVITY_JOIN_REQUEST",
|
||||
"cmd": "SUBSCRIBE"
|
||||
}
|
||||
```
|
||||
|
||||
To unsubscribe from these events, resend with the command `UNSUBSCRIBE`
|
||||
|
||||
## Responding
|
||||
A discord user will request access to the game. If the ACTIVITY_JOIN_REQUEST has been subscribed too, the ACTIVITY_JOIN_REQUEST event will be sent to the host's game. Accept it with following model:
|
||||
```json
|
||||
{
|
||||
"nonce": "5dc0c062-98c6-47a0-8922-15aerg126",
|
||||
"cmd": "SEND_ACTIVITY_JOIN_INVITE",
|
||||
"args":
|
||||
{
|
||||
"user_id": "53908232506183680"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To reject the request, use `CLOSE_ACTIVITY_REQUEST`:
|
||||
```json
|
||||
{
|
||||
"nonce": "5dc0c062-98c6-47a0-8922-dasg256eafg",
|
||||
"cmd": "CLOSE_ACTIVITY_REQUEST",
|
||||
"args":
|
||||
{
|
||||
"user_id": "53908232506183680"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Notes
|
||||
Here are just some quick notes to help with some common troubleshooting problems.
|
||||
* IPC will echo back every command you send as a response. Use this as a lock-step feature to avoid flooding messages. Can be used to validate messages such as the Presence or Subscribes.
|
||||
* The pipe expects for frames to be written in a single byte array. You cannot do multiple `stream.Write(opcode);` `stream.Write(length);` as it will break the pipe. Instead create a buffer, write the data to the buffer, then send the entire buffer to the stream.
|
||||
* Discord can be on any pipe ranging from `discord-ipc-0` to `discord-ipc-9`. It is a good idea to try and connect to each one and keeping the first one you connect too. For multiple clients (eg Discord and Canary), you might want to add a feature to manually select the pipe so you can more easily debug the application.
|
||||
* All enums are `lower_snake_case`.
|
||||
* The opcode and length in the header are `Little Endian Unsigned Integers (32bits)`. In some languages, you must convert them as they can be architecture specific.
|
||||
* [Discord Rich Presence How-To](https://discordapp.com/developers/docs/rich-presence/how-to) contains a lot of the information this document doesn't. For example, it will tell you about the response payload.
|
||||
* In the documentation, DISCORD_REPLY_IGNORE is just implemented the same as DISCORD_REPLY_NO.
|
||||
* You can test the Join / Spectate feature by enabling them in your profile and whitelisting a test account. Use Canary to run 2 accounts on the same machine.
|
||||
|
After Width: | Height: | Size: 318 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,8 @@
|
||||
/Library/
|
||||
/Temp/
|
||||
/obj/
|
||||
/Assets/Plugins/
|
||||
/Assets/Plugins.meta
|
||||
*.sln
|
||||
*.csproj
|
||||
*.userprefs
|
||||
@@ -0,0 +1,125 @@
|
||||
using UnityEngine;
|
||||
|
||||
[System.Serializable]
|
||||
public class DiscordJoinEvent : UnityEngine.Events.UnityEvent<string> { }
|
||||
|
||||
[System.Serializable]
|
||||
public class DiscordSpectateEvent : UnityEngine.Events.UnityEvent<string> { }
|
||||
|
||||
[System.Serializable]
|
||||
public class DiscordJoinRequestEvent : UnityEngine.Events.UnityEvent<DiscordRpc.DiscordUser> { }
|
||||
|
||||
public class DiscordController : MonoBehaviour
|
||||
{
|
||||
public DiscordRpc.RichPresence presence = new DiscordRpc.RichPresence();
|
||||
public string applicationId;
|
||||
public string optionalSteamId;
|
||||
public int clickCounter;
|
||||
public DiscordRpc.DiscordUser joinRequest;
|
||||
public UnityEngine.Events.UnityEvent onConnect;
|
||||
public UnityEngine.Events.UnityEvent onDisconnect;
|
||||
public UnityEngine.Events.UnityEvent hasResponded;
|
||||
public DiscordJoinEvent onJoin;
|
||||
public DiscordJoinEvent onSpectate;
|
||||
public DiscordJoinRequestEvent onJoinRequest;
|
||||
|
||||
DiscordRpc.EventHandlers handlers;
|
||||
|
||||
public void OnClick()
|
||||
{
|
||||
Debug.Log("Discord: on click!");
|
||||
clickCounter++;
|
||||
|
||||
presence.details = string.Format("Button clicked {0} times", clickCounter);
|
||||
presence.joinSecret = "aSecret";
|
||||
presence.partyId = "aPartyId";
|
||||
presence.partySize = 1;
|
||||
presence.partyMax = 3;
|
||||
presence.partyPrivacy = DiscordRpc.PartyPrivacy.Public;
|
||||
|
||||
DiscordRpc.UpdatePresence(presence);
|
||||
}
|
||||
|
||||
public void RequestRespondYes()
|
||||
{
|
||||
Debug.Log("Discord: responding yes to Ask to Join request");
|
||||
DiscordRpc.Respond(joinRequest.userId, DiscordRpc.Reply.Yes);
|
||||
hasResponded.Invoke();
|
||||
}
|
||||
|
||||
public void RequestRespondNo()
|
||||
{
|
||||
Debug.Log("Discord: responding no to Ask to Join request");
|
||||
DiscordRpc.Respond(joinRequest.userId, DiscordRpc.Reply.No);
|
||||
hasResponded.Invoke();
|
||||
}
|
||||
|
||||
public void ReadyCallback(ref DiscordRpc.DiscordUser connectedUser)
|
||||
{
|
||||
Debug.Log(string.Format("Discord: connected to {0}#{1}: {2}", connectedUser.username, connectedUser.discriminator, connectedUser.userId));
|
||||
onConnect.Invoke();
|
||||
}
|
||||
|
||||
public void DisconnectedCallback(int errorCode, string message)
|
||||
{
|
||||
Debug.Log(string.Format("Discord: disconnect {0}: {1}", errorCode, message));
|
||||
onDisconnect.Invoke();
|
||||
}
|
||||
|
||||
public void ErrorCallback(int errorCode, string message)
|
||||
{
|
||||
Debug.Log(string.Format("Discord: error {0}: {1}", errorCode, message));
|
||||
}
|
||||
|
||||
public void JoinCallback(string secret)
|
||||
{
|
||||
Debug.Log(string.Format("Discord: join ({0})", secret));
|
||||
onJoin.Invoke(secret);
|
||||
}
|
||||
|
||||
public void SpectateCallback(string secret)
|
||||
{
|
||||
Debug.Log(string.Format("Discord: spectate ({0})", secret));
|
||||
onSpectate.Invoke(secret);
|
||||
}
|
||||
|
||||
public void RequestCallback(ref DiscordRpc.DiscordUser request)
|
||||
{
|
||||
Debug.Log(string.Format("Discord: join request {0}#{1}: {2}", request.username, request.discriminator, request.userId));
|
||||
joinRequest = request;
|
||||
onJoinRequest.Invoke(request);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
DiscordRpc.RunCallbacks();
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
Debug.Log("Discord: init");
|
||||
handlers = new DiscordRpc.EventHandlers();
|
||||
handlers.readyCallback += ReadyCallback;
|
||||
handlers.disconnectedCallback += DisconnectedCallback;
|
||||
handlers.errorCallback += ErrorCallback;
|
||||
handlers.joinCallback += JoinCallback;
|
||||
handlers.spectateCallback += SpectateCallback;
|
||||
handlers.requestCallback += RequestCallback;
|
||||
DiscordRpc.Initialize(applicationId, ref handlers, true, optionalSteamId);
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
Debug.Log("Discord: shutdown");
|
||||
DiscordRpc.Shutdown();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27f0a5f59ffffa84c86547736e2e730a
|
||||
timeCreated: 1501697692
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,231 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using AOT;
|
||||
|
||||
public class DiscordRpc
|
||||
{
|
||||
[MonoPInvokeCallback(typeof(OnReadyInfo))]
|
||||
public static void ReadyCallback(ref DiscordUser connectedUser) { Callbacks.readyCallback(ref connectedUser); }
|
||||
public delegate void OnReadyInfo(ref DiscordUser connectedUser);
|
||||
|
||||
[MonoPInvokeCallback(typeof(OnDisconnectedInfo))]
|
||||
public static void DisconnectedCallback(int errorCode, string message) { Callbacks.disconnectedCallback(errorCode, message); }
|
||||
public delegate void OnDisconnectedInfo(int errorCode, string message);
|
||||
|
||||
[MonoPInvokeCallback(typeof(OnErrorInfo))]
|
||||
public static void ErrorCallback(int errorCode, string message) { Callbacks.errorCallback(errorCode, message); }
|
||||
public delegate void OnErrorInfo(int errorCode, string message);
|
||||
|
||||
[MonoPInvokeCallback(typeof(OnJoinInfo))]
|
||||
public static void JoinCallback(string secret) { Callbacks.joinCallback(secret); }
|
||||
public delegate void OnJoinInfo(string secret);
|
||||
|
||||
[MonoPInvokeCallback(typeof(OnSpectateInfo))]
|
||||
public static void SpectateCallback(string secret) { Callbacks.spectateCallback(secret); }
|
||||
public delegate void OnSpectateInfo(string secret);
|
||||
|
||||
[MonoPInvokeCallback(typeof(OnRequestInfo))]
|
||||
public static void RequestCallback(ref DiscordUser request) { Callbacks.requestCallback(ref request); }
|
||||
public delegate void OnRequestInfo(ref DiscordUser request);
|
||||
|
||||
static EventHandlers Callbacks { get; set; }
|
||||
|
||||
public struct EventHandlers
|
||||
{
|
||||
public OnReadyInfo readyCallback;
|
||||
public OnDisconnectedInfo disconnectedCallback;
|
||||
public OnErrorInfo errorCallback;
|
||||
public OnJoinInfo joinCallback;
|
||||
public OnSpectateInfo spectateCallback;
|
||||
public OnRequestInfo requestCallback;
|
||||
}
|
||||
|
||||
[Serializable, StructLayout(LayoutKind.Sequential)]
|
||||
public struct RichPresenceStruct
|
||||
{
|
||||
public IntPtr state; /* max 128 bytes */
|
||||
public IntPtr details; /* max 128 bytes */
|
||||
public long startTimestamp;
|
||||
public long endTimestamp;
|
||||
public IntPtr largeImageKey; /* max 32 bytes */
|
||||
public IntPtr largeImageText; /* max 128 bytes */
|
||||
public IntPtr smallImageKey; /* max 32 bytes */
|
||||
public IntPtr smallImageText; /* max 128 bytes */
|
||||
public IntPtr partyId; /* max 128 bytes */
|
||||
public int partySize;
|
||||
public int partyMax;
|
||||
public int partyPrivacy;
|
||||
public IntPtr matchSecret; /* max 128 bytes */
|
||||
public IntPtr joinSecret; /* max 128 bytes */
|
||||
public IntPtr spectateSecret; /* max 128 bytes */
|
||||
public bool instance;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct DiscordUser
|
||||
{
|
||||
public string userId;
|
||||
public string username;
|
||||
public string discriminator;
|
||||
public string avatar;
|
||||
}
|
||||
|
||||
public enum Reply
|
||||
{
|
||||
No = 0,
|
||||
Yes = 1,
|
||||
Ignore = 2
|
||||
}
|
||||
|
||||
public enum PartyPrivacy
|
||||
{
|
||||
Private = 0,
|
||||
Public = 1
|
||||
}
|
||||
|
||||
public static void Initialize(string applicationId, ref EventHandlers handlers, bool autoRegister, string optionalSteamId)
|
||||
{
|
||||
Callbacks = handlers;
|
||||
|
||||
EventHandlers staticEventHandlers = new EventHandlers();
|
||||
staticEventHandlers.readyCallback += DiscordRpc.ReadyCallback;
|
||||
staticEventHandlers.disconnectedCallback += DiscordRpc.DisconnectedCallback;
|
||||
staticEventHandlers.errorCallback += DiscordRpc.ErrorCallback;
|
||||
staticEventHandlers.joinCallback += DiscordRpc.JoinCallback;
|
||||
staticEventHandlers.spectateCallback += DiscordRpc.SpectateCallback;
|
||||
staticEventHandlers.requestCallback += DiscordRpc.RequestCallback;
|
||||
|
||||
InitializeInternal(applicationId, ref staticEventHandlers, autoRegister, optionalSteamId);
|
||||
}
|
||||
|
||||
[DllImport("discord-rpc", EntryPoint = "Discord_Initialize", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void InitializeInternal(string applicationId, ref EventHandlers handlers, bool autoRegister, string optionalSteamId);
|
||||
|
||||
[DllImport("discord-rpc", EntryPoint = "Discord_Shutdown", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void Shutdown();
|
||||
|
||||
[DllImport("discord-rpc", EntryPoint = "Discord_RunCallbacks", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void RunCallbacks();
|
||||
|
||||
[DllImport("discord-rpc", EntryPoint = "Discord_UpdatePresence", CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void UpdatePresenceNative(ref RichPresenceStruct presence);
|
||||
|
||||
[DllImport("discord-rpc", EntryPoint = "Discord_ClearPresence", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void ClearPresence();
|
||||
|
||||
[DllImport("discord-rpc", EntryPoint = "Discord_Respond", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void Respond(string userId, Reply reply);
|
||||
|
||||
[DllImport("discord-rpc", EntryPoint = "Discord_UpdateHandlers", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void UpdateHandlers(ref EventHandlers handlers);
|
||||
|
||||
public static void UpdatePresence(RichPresence presence)
|
||||
{
|
||||
var presencestruct = presence.GetStruct();
|
||||
UpdatePresenceNative(ref presencestruct);
|
||||
presence.FreeMem();
|
||||
}
|
||||
|
||||
public class RichPresence
|
||||
{
|
||||
private RichPresenceStruct _presence;
|
||||
private readonly List<IntPtr> _buffers = new List<IntPtr>(10);
|
||||
|
||||
public string state; /* max 128 bytes */
|
||||
public string details; /* max 128 bytes */
|
||||
public long startTimestamp;
|
||||
public long endTimestamp;
|
||||
public string largeImageKey; /* max 32 bytes */
|
||||
public string largeImageText; /* max 128 bytes */
|
||||
public string smallImageKey; /* max 32 bytes */
|
||||
public string smallImageText; /* max 128 bytes */
|
||||
public string partyId; /* max 128 bytes */
|
||||
public int partySize;
|
||||
public int partyMax;
|
||||
public PartyPrivacy partyPrivacy;
|
||||
public string matchSecret; /* max 128 bytes */
|
||||
public string joinSecret; /* max 128 bytes */
|
||||
public string spectateSecret; /* max 128 bytes */
|
||||
public bool instance;
|
||||
|
||||
/// <summary>
|
||||
/// Get the <see cref="RichPresenceStruct"/> reprensentation of this instance
|
||||
/// </summary>
|
||||
/// <returns><see cref="RichPresenceStruct"/> reprensentation of this instance</returns>
|
||||
internal RichPresenceStruct GetStruct()
|
||||
{
|
||||
if (_buffers.Count > 0)
|
||||
{
|
||||
FreeMem();
|
||||
}
|
||||
|
||||
_presence.state = StrToPtr(state);
|
||||
_presence.details = StrToPtr(details);
|
||||
_presence.startTimestamp = startTimestamp;
|
||||
_presence.endTimestamp = endTimestamp;
|
||||
_presence.largeImageKey = StrToPtr(largeImageKey);
|
||||
_presence.largeImageText = StrToPtr(largeImageText);
|
||||
_presence.smallImageKey = StrToPtr(smallImageKey);
|
||||
_presence.smallImageText = StrToPtr(smallImageText);
|
||||
_presence.partyId = StrToPtr(partyId);
|
||||
_presence.partySize = partySize;
|
||||
_presence.partyMax = partyMax;
|
||||
_presence.partyPrivacy = (int)partyPrivacy;
|
||||
_presence.matchSecret = StrToPtr(matchSecret);
|
||||
_presence.joinSecret = StrToPtr(joinSecret);
|
||||
_presence.spectateSecret = StrToPtr(spectateSecret);
|
||||
_presence.instance = instance;
|
||||
|
||||
return _presence;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a pointer to a representation of the given string with a size of maxbytes
|
||||
/// </summary>
|
||||
/// <param name="input">String to convert</param>
|
||||
/// <returns>Pointer to the UTF-8 representation of <see cref="input"/></returns>
|
||||
private IntPtr StrToPtr(string input)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input)) return IntPtr.Zero;
|
||||
var convbytecnt = Encoding.UTF8.GetByteCount(input);
|
||||
var buffer = Marshal.AllocHGlobal(convbytecnt + 1);
|
||||
for (int i = 0; i < convbytecnt + 1; i++)
|
||||
{
|
||||
Marshal.WriteByte(buffer, i, 0);
|
||||
}
|
||||
_buffers.Add(buffer);
|
||||
Marshal.Copy(Encoding.UTF8.GetBytes(input), 0, buffer, convbytecnt);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert string to UTF-8 and add null termination
|
||||
/// </summary>
|
||||
/// <param name="toconv">string to convert</param>
|
||||
/// <returns>UTF-8 representation of <see cref="toconv"/> with added null termination</returns>
|
||||
private static string StrToUtf8NullTerm(string toconv)
|
||||
{
|
||||
var str = toconv.Trim();
|
||||
var bytes = Encoding.Default.GetBytes(str);
|
||||
if (bytes.Length > 0 && bytes[bytes.Length - 1] != 0)
|
||||
{
|
||||
str += "\0\0";
|
||||
}
|
||||
return Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(str));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Free the allocated memory for conversion to <see cref="RichPresenceStruct"/>
|
||||
/// </summary>
|
||||
internal void FreeMem()
|
||||
{
|
||||
for (var i = _buffers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
Marshal.FreeHGlobal(_buffers[i]);
|
||||
_buffers.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4474a677de9d80409e98c5393ec5b1e
|
||||
timeCreated: 1501697692
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,101 @@
|
||||
using UnityEditor;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public class ScriptBatch
|
||||
{
|
||||
static ScriptBatch()
|
||||
{
|
||||
EnsureDLL();
|
||||
}
|
||||
|
||||
public static bool FileExists(string filename)
|
||||
{
|
||||
return new FileInfo(filename).Exists;
|
||||
}
|
||||
|
||||
public static bool RunRpcBuildScript()
|
||||
{
|
||||
UnityEngine.Debug.Log("Try to run build script");
|
||||
|
||||
Process proc = new Process();
|
||||
#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
|
||||
proc.StartInfo.UseShellExecute = false;
|
||||
// brew installs cmake in /usr/local/bin, which Unity seems to strip from PATH?
|
||||
string newPath = proc.StartInfo.EnvironmentVariables["PATH"] + ":/usr/local/bin";
|
||||
proc.StartInfo.EnvironmentVariables["PATH"] = newPath;
|
||||
#endif
|
||||
proc.StartInfo.FileName = "python";
|
||||
proc.StartInfo.Arguments = "build.py unity";
|
||||
proc.StartInfo.WorkingDirectory = "../..";
|
||||
proc.Start();
|
||||
proc.WaitForExit();
|
||||
return proc.ExitCode == 0;
|
||||
}
|
||||
|
||||
public static void EnsureDLL()
|
||||
{
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
string[] dstDirs = { "Assets/Plugins", "Assets/Plugins/x86", "Assets/Plugins/x86_64" };
|
||||
string[] dstDlls = { "Assets/Plugins/x86/discord-rpc.dll", "Assets/Plugins/x86_64/discord-rpc.dll" };
|
||||
string[] srcDlls = { "../../builds/install/win64-dynamic/bin/discord-rpc.dll", "../../builds/install/win64-dynamic/bin/discord-rpc.dll" };
|
||||
#elif UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
|
||||
string[] dstDirs = { "Assets/Plugins" };
|
||||
string[] dstDlls = { "Assets/Plugins/discord-rpc.bundle" };
|
||||
string[] srcDlls = { "../../builds/install/osx-dynamic/lib/libdiscord-rpc.dylib" };
|
||||
#else
|
||||
string[] dstDirs = { "Assets/Plugins", "Assets/Plugins/x86", "Assets/Plugins/x86_64" };
|
||||
string[] dstDlls = { "Assets/Plugins/discord-rpc.so" };
|
||||
string[] srcDlls = { "../../builds/install/linux-dynamic/lib/libdiscord-rpc.so" };
|
||||
#endif
|
||||
|
||||
Debug.Assert(dstDlls.Length == srcDlls.Length);
|
||||
|
||||
bool exists = true;
|
||||
foreach (string fname in dstDlls)
|
||||
{
|
||||
if (!FileExists(fname))
|
||||
{
|
||||
exists = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
exists = true;
|
||||
foreach (string fname in srcDlls)
|
||||
{
|
||||
if (!FileExists(fname))
|
||||
{
|
||||
exists = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
if (!RunRpcBuildScript())
|
||||
{
|
||||
UnityEngine.Debug.LogError("Build failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the dirs exist
|
||||
foreach (string dirname in dstDirs)
|
||||
{
|
||||
Directory.CreateDirectory(dirname);
|
||||
}
|
||||
|
||||
// Copy dlls
|
||||
for (int i = 0; i < dstDlls.Length; ++i)
|
||||
{
|
||||
FileUtil.CopyFileOrDirectory(srcDlls[i], dstDlls[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5aecc4633e5f594b85eaa39f49bb402
|
||||
timeCreated: 1512071254
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b03d21bb25fa494e8694cd6e4b6d769
|
||||
timeCreated: 1501696924
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!11 &1
|
||||
AudioManager:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Volume: 1
|
||||
Rolloff Scale: 1
|
||||
Doppler Factor: 1
|
||||
Default Speaker Mode: 2
|
||||
m_SampleRate: 0
|
||||
m_DSPBufferSize: 0
|
||||
m_VirtualVoiceCount: 512
|
||||
m_RealVoiceCount: 32
|
||||
m_SpatializerPlugin:
|
||||
m_AmbisonicDecoderPlugin:
|
||||
m_DisableAudio: 0
|
||||
m_VirtualizeEffects: 1
|
||||
@@ -0,0 +1,6 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!236 &1
|
||||
ClusterInputManager:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Inputs: []
|
||||
@@ -0,0 +1,20 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!55 &1
|
||||
PhysicsManager:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 3
|
||||
m_Gravity: {x: 0, y: -9.81, z: 0}
|
||||
m_DefaultMaterial: {fileID: 0}
|
||||
m_BounceThreshold: 2
|
||||
m_SleepThreshold: 0.005
|
||||
m_DefaultContactOffset: 0.01
|
||||
m_DefaultSolverIterations: 6
|
||||
m_DefaultSolverVelocityIterations: 1
|
||||
m_QueriesHitBackfaces: 0
|
||||
m_QueriesHitTriggers: 1
|
||||
m_EnableAdaptiveForce: 0
|
||||
m_EnablePCM: 1
|
||||
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
m_AutoSimulation: 1
|
||||
m_AutoSyncTransforms: 1
|
||||
@@ -0,0 +1,10 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1045 &1
|
||||
EditorBuildSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Scenes:
|
||||
- enabled: 1
|
||||
path: Assets/main.unity
|
||||
guid: 3b03d21bb25fa494e8694cd6e4b6d769
|
||||
@@ -0,0 +1,16 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!159 &1
|
||||
EditorSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 4
|
||||
m_ExternalVersionControlSupport: Visible Meta Files
|
||||
m_SerializationMode: 2
|
||||
m_DefaultBehaviorMode: 1
|
||||
m_SpritePackerMode: 4
|
||||
m_SpritePackerPaddingPower: 1
|
||||
m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd
|
||||
m_ProjectGenerationRootNamespace:
|
||||
m_UserGeneratedProjectSuffix:
|
||||
m_CollabEditorSettings:
|
||||
inProgressEnabled: 1
|
||||
@@ -0,0 +1,61 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!30 &1
|
||||
GraphicsSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 12
|
||||
m_Deferred:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_DeferredReflections:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ScreenSpaceShadows:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_LegacyDeferred:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_DepthNormals:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_MotionVectors:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_LightHalo:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_LensFlare:
|
||||
m_Mode: 1
|
||||
m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_AlwaysIncludedShaders:
|
||||
- {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
|
||||
- {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_PreloadedShaders: []
|
||||
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
|
||||
type: 0}
|
||||
m_CustomRenderPipeline: {fileID: 0}
|
||||
m_TransparencySortMode: 0
|
||||
m_TransparencySortAxis: {x: 0, y: 0, z: 1}
|
||||
m_DefaultRenderingPath: 1
|
||||
m_DefaultMobileRenderingPath: 1
|
||||
m_TierSettings: []
|
||||
m_LightmapStripping: 0
|
||||
m_FogStripping: 0
|
||||
m_InstancingStripping: 0
|
||||
m_LightmapKeepPlain: 1
|
||||
m_LightmapKeepDirCombined: 1
|
||||
m_LightmapKeepDynamicPlain: 1
|
||||
m_LightmapKeepDynamicDirCombined: 1
|
||||
m_LightmapKeepShadowMask: 1
|
||||
m_LightmapKeepSubtractive: 1
|
||||
m_FogKeepLinear: 1
|
||||
m_FogKeepExp: 1
|
||||
m_FogKeepExp2: 1
|
||||
m_AlbedoSwatchInfos: []
|
||||
m_LightsUseLinearIntensity: 0
|
||||
m_LightsUseColorTemperature: 0
|
||||
@@ -0,0 +1,295 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!13 &1
|
||||
InputManager:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Axes:
|
||||
- serializedVersion: 3
|
||||
m_Name: Horizontal
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton: left
|
||||
positiveButton: right
|
||||
altNegativeButton: a
|
||||
altPositiveButton: d
|
||||
gravity: 3
|
||||
dead: 0.001
|
||||
sensitivity: 3
|
||||
snap: 1
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Vertical
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton: down
|
||||
positiveButton: up
|
||||
altNegativeButton: s
|
||||
altPositiveButton: w
|
||||
gravity: 3
|
||||
dead: 0.001
|
||||
sensitivity: 3
|
||||
snap: 1
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire1
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: left ctrl
|
||||
altNegativeButton:
|
||||
altPositiveButton: mouse 0
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire2
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: left alt
|
||||
altNegativeButton:
|
||||
altPositiveButton: mouse 1
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire3
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: left shift
|
||||
altNegativeButton:
|
||||
altPositiveButton: mouse 2
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Jump
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: space
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Mouse X
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton:
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0.1
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 1
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Mouse Y
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton:
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0.1
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 1
|
||||
axis: 1
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Mouse ScrollWheel
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton:
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 0
|
||||
dead: 0
|
||||
sensitivity: 0.1
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 1
|
||||
axis: 2
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Horizontal
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton:
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 0
|
||||
dead: 0.19
|
||||
sensitivity: 1
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 2
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Vertical
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton:
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 0
|
||||
dead: 0.19
|
||||
sensitivity: 1
|
||||
snap: 0
|
||||
invert: 1
|
||||
type: 2
|
||||
axis: 1
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire1
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: joystick button 0
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire2
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: joystick button 1
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Fire3
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: joystick button 2
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Jump
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: joystick button 3
|
||||
altNegativeButton:
|
||||
altPositiveButton:
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Submit
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: return
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 0
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Submit
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: enter
|
||||
altNegativeButton:
|
||||
altPositiveButton: space
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
- serializedVersion: 3
|
||||
m_Name: Cancel
|
||||
descriptiveName:
|
||||
descriptiveNegativeName:
|
||||
negativeButton:
|
||||
positiveButton: escape
|
||||
altNegativeButton:
|
||||
altPositiveButton: joystick button 1
|
||||
gravity: 1000
|
||||
dead: 0.001
|
||||
sensitivity: 1000
|
||||
snap: 0
|
||||
invert: 0
|
||||
type: 0
|
||||
axis: 0
|
||||
joyNum: 0
|
||||
@@ -0,0 +1,89 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!126 &1
|
||||
NavMeshProjectSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
areas:
|
||||
- name: Walkable
|
||||
cost: 1
|
||||
- name: Not Walkable
|
||||
cost: 1
|
||||
- name: Jump
|
||||
cost: 2
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
- name:
|
||||
cost: 1
|
||||
m_LastAgentTypeID: -887442657
|
||||
m_Settings:
|
||||
- serializedVersion: 2
|
||||
agentTypeID: 0
|
||||
agentRadius: 0.5
|
||||
agentHeight: 2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.75
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
minRegionArea: 2
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666667
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
accuratePlacement: 0
|
||||
m_SettingNames:
|
||||
- Humanoid
|
||||
@@ -0,0 +1,8 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!149 &1
|
||||
NetworkManager:
|
||||
m_ObjectHideFlags: 0
|
||||
m_DebugLevel: 0
|
||||
m_Sendrate: 15
|
||||
m_AssetToPrefab: {}
|
||||
@@ -0,0 +1,37 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!19 &1
|
||||
Physics2DSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 3
|
||||
m_Gravity: {x: 0, y: -9.81}
|
||||
m_DefaultMaterial: {fileID: 0}
|
||||
m_VelocityIterations: 8
|
||||
m_PositionIterations: 3
|
||||
m_VelocityThreshold: 1
|
||||
m_MaxLinearCorrection: 0.2
|
||||
m_MaxAngularCorrection: 8
|
||||
m_MaxTranslationSpeed: 100
|
||||
m_MaxRotationSpeed: 360
|
||||
m_BaumgarteScale: 0.2
|
||||
m_BaumgarteTimeOfImpactScale: 0.75
|
||||
m_TimeToSleep: 0.5
|
||||
m_LinearSleepTolerance: 0.01
|
||||
m_AngularSleepTolerance: 2
|
||||
m_DefaultContactOffset: 0.01
|
||||
m_AutoSimulation: 1
|
||||
m_QueriesHitTriggers: 1
|
||||
m_QueriesStartInColliders: 1
|
||||
m_ChangeStopsCallbacks: 0
|
||||
m_CallbacksOnDisable: 1
|
||||
m_AutoSyncTransforms: 1
|
||||
m_AlwaysShowColliders: 0
|
||||
m_ShowColliderSleep: 1
|
||||
m_ShowColliderContacts: 0
|
||||
m_ShowColliderAABB: 0
|
||||
m_ContactArrowScale: 0.2
|
||||
m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
|
||||
m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
|
||||
m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
|
||||
m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
|
||||
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
@@ -0,0 +1,610 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!129 &1
|
||||
PlayerSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 13
|
||||
productGUID: 5eccc60d3e382a346a65f512d6b81b84
|
||||
AndroidProfiler: 0
|
||||
AndroidFilterTouchesWhenObscured: 0
|
||||
defaultScreenOrientation: 4
|
||||
targetDevice: 2
|
||||
useOnDemandResources: 0
|
||||
accelerometerFrequency: 60
|
||||
companyName: Discord Inc.
|
||||
productName: button-clicker
|
||||
defaultCursor: {fileID: 0}
|
||||
cursorHotspot: {x: 0, y: 0}
|
||||
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
|
||||
m_ShowUnitySplashScreen: 1
|
||||
m_ShowUnitySplashLogo: 1
|
||||
m_SplashScreenOverlayOpacity: 1
|
||||
m_SplashScreenAnimation: 1
|
||||
m_SplashScreenLogoStyle: 1
|
||||
m_SplashScreenDrawMode: 0
|
||||
m_SplashScreenBackgroundAnimationZoom: 1
|
||||
m_SplashScreenLogoAnimationZoom: 1
|
||||
m_SplashScreenBackgroundLandscapeAspect: 1
|
||||
m_SplashScreenBackgroundPortraitAspect: 1
|
||||
m_SplashScreenBackgroundLandscapeUvs:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
m_SplashScreenBackgroundPortraitUvs:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
m_SplashScreenLogos: []
|
||||
m_VirtualRealitySplashScreen: {fileID: 0}
|
||||
m_HolographicTrackingLossScreen: {fileID: 0}
|
||||
defaultScreenWidth: 1024
|
||||
defaultScreenHeight: 768
|
||||
defaultScreenWidthWeb: 960
|
||||
defaultScreenHeightWeb: 600
|
||||
m_StereoRenderingPath: 0
|
||||
m_ActiveColorSpace: 0
|
||||
m_MTRendering: 1
|
||||
m_StackTraceTypes: 010000000100000001000000010000000100000001000000
|
||||
iosShowActivityIndicatorOnLoading: -1
|
||||
androidShowActivityIndicatorOnLoading: -1
|
||||
tizenShowActivityIndicatorOnLoading: -1
|
||||
iosAppInBackgroundBehavior: 0
|
||||
displayResolutionDialog: 1
|
||||
iosAllowHTTPDownload: 1
|
||||
allowedAutorotateToPortrait: 1
|
||||
allowedAutorotateToPortraitUpsideDown: 1
|
||||
allowedAutorotateToLandscapeRight: 1
|
||||
allowedAutorotateToLandscapeLeft: 1
|
||||
useOSAutorotation: 1
|
||||
use32BitDisplayBuffer: 1
|
||||
disableDepthAndStencilBuffers: 0
|
||||
androidBlitType: 0
|
||||
defaultIsFullScreen: 1
|
||||
defaultIsNativeResolution: 1
|
||||
macRetinaSupport: 1
|
||||
runInBackground: 0
|
||||
captureSingleScreen: 0
|
||||
muteOtherAudioSources: 0
|
||||
Prepare IOS For Recording: 0
|
||||
Force IOS Speakers When Recording: 0
|
||||
submitAnalytics: 1
|
||||
usePlayerLog: 1
|
||||
bakeCollisionMeshes: 0
|
||||
forceSingleInstance: 0
|
||||
resizableWindow: 0
|
||||
useMacAppStoreValidation: 0
|
||||
macAppStoreCategory: public.app-category.games
|
||||
gpuSkinning: 0
|
||||
graphicsJobs: 0
|
||||
xboxPIXTextureCapture: 0
|
||||
xboxEnableAvatar: 0
|
||||
xboxEnableKinect: 0
|
||||
xboxEnableKinectAutoTracking: 0
|
||||
xboxEnableFitness: 0
|
||||
visibleInBackground: 1
|
||||
allowFullscreenSwitch: 1
|
||||
graphicsJobMode: 0
|
||||
macFullscreenMode: 2
|
||||
d3d9FullscreenMode: 1
|
||||
d3d11FullscreenMode: 1
|
||||
xboxSpeechDB: 0
|
||||
xboxEnableHeadOrientation: 0
|
||||
xboxEnableGuest: 0
|
||||
xboxEnablePIXSampling: 0
|
||||
metalFramebufferOnly: 0
|
||||
n3dsDisableStereoscopicView: 0
|
||||
n3dsEnableSharedListOpt: 1
|
||||
n3dsEnableVSync: 0
|
||||
ignoreAlphaClear: 0
|
||||
xboxOneResolution: 0
|
||||
xboxOneMonoLoggingLevel: 0
|
||||
xboxOneLoggingLevel: 1
|
||||
xboxOneDisableEsram: 0
|
||||
xboxOnePresentImmediateThreshold: 0
|
||||
videoMemoryForVertexBuffers: 0
|
||||
psp2PowerMode: 0
|
||||
psp2AcquireBGM: 1
|
||||
wiiUTVResolution: 0
|
||||
wiiUGamePadMSAA: 1
|
||||
wiiUSupportsNunchuk: 0
|
||||
wiiUSupportsClassicController: 0
|
||||
wiiUSupportsBalanceBoard: 0
|
||||
wiiUSupportsMotionPlus: 0
|
||||
wiiUSupportsProController: 0
|
||||
wiiUAllowScreenCapture: 1
|
||||
wiiUControllerCount: 0
|
||||
m_SupportedAspectRatios:
|
||||
4:3: 1
|
||||
5:4: 1
|
||||
16:10: 1
|
||||
16:9: 1
|
||||
Others: 1
|
||||
bundleVersion: 1.0
|
||||
preloadedAssets: []
|
||||
metroInputSource: 0
|
||||
m_HolographicPauseOnTrackingLoss: 1
|
||||
xboxOneDisableKinectGpuReservation: 0
|
||||
xboxOneEnable7thCore: 0
|
||||
vrSettings:
|
||||
cardboard:
|
||||
depthFormat: 0
|
||||
enableTransitionView: 0
|
||||
daydream:
|
||||
depthFormat: 0
|
||||
useSustainedPerformanceMode: 0
|
||||
enableVideoLayer: 0
|
||||
useProtectedVideoMemory: 0
|
||||
hololens:
|
||||
depthFormat: 1
|
||||
protectGraphicsMemory: 0
|
||||
useHDRDisplay: 0
|
||||
m_ColorGamuts: 00000000
|
||||
targetPixelDensity: 0
|
||||
resolutionScalingMode: 0
|
||||
androidSupportedAspectRatio: 1
|
||||
androidMaxAspectRatio: 2.1
|
||||
applicationIdentifier: {}
|
||||
buildNumber: {}
|
||||
AndroidBundleVersionCode: 1
|
||||
AndroidMinSdkVersion: 16
|
||||
AndroidTargetSdkVersion: 0
|
||||
AndroidPreferredInstallLocation: 1
|
||||
aotOptions:
|
||||
stripEngineCode: 1
|
||||
iPhoneStrippingLevel: 0
|
||||
iPhoneScriptCallOptimization: 0
|
||||
ForceInternetPermission: 0
|
||||
ForceSDCardPermission: 0
|
||||
CreateWallpaper: 0
|
||||
APKExpansionFiles: 0
|
||||
keepLoadedShadersAlive: 0
|
||||
StripUnusedMeshComponents: 0
|
||||
VertexChannelCompressionMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 238
|
||||
iPhoneSdkVersion: 988
|
||||
iOSTargetOSVersionString: 7.0
|
||||
tvOSSdkVersion: 0
|
||||
tvOSRequireExtendedGameController: 0
|
||||
tvOSTargetOSVersionString: 9.0
|
||||
uIPrerenderedIcon: 0
|
||||
uIRequiresPersistentWiFi: 0
|
||||
uIRequiresFullScreen: 1
|
||||
uIStatusBarHidden: 1
|
||||
uIExitOnSuspend: 0
|
||||
uIStatusBarStyle: 0
|
||||
iPhoneSplashScreen: {fileID: 0}
|
||||
iPhoneHighResSplashScreen: {fileID: 0}
|
||||
iPhoneTallHighResSplashScreen: {fileID: 0}
|
||||
iPhone47inSplashScreen: {fileID: 0}
|
||||
iPhone55inPortraitSplashScreen: {fileID: 0}
|
||||
iPhone55inLandscapeSplashScreen: {fileID: 0}
|
||||
iPadPortraitSplashScreen: {fileID: 0}
|
||||
iPadHighResPortraitSplashScreen: {fileID: 0}
|
||||
iPadLandscapeSplashScreen: {fileID: 0}
|
||||
iPadHighResLandscapeSplashScreen: {fileID: 0}
|
||||
appleTVSplashScreen: {fileID: 0}
|
||||
tvOSSmallIconLayers: []
|
||||
tvOSLargeIconLayers: []
|
||||
tvOSTopShelfImageLayers: []
|
||||
tvOSTopShelfImageWideLayers: []
|
||||
iOSLaunchScreenType: 0
|
||||
iOSLaunchScreenPortrait: {fileID: 0}
|
||||
iOSLaunchScreenLandscape: {fileID: 0}
|
||||
iOSLaunchScreenBackgroundColor:
|
||||
serializedVersion: 2
|
||||
rgba: 0
|
||||
iOSLaunchScreenFillPct: 100
|
||||
iOSLaunchScreenSize: 100
|
||||
iOSLaunchScreenCustomXibPath:
|
||||
iOSLaunchScreeniPadType: 0
|
||||
iOSLaunchScreeniPadImage: {fileID: 0}
|
||||
iOSLaunchScreeniPadBackgroundColor:
|
||||
serializedVersion: 2
|
||||
rgba: 0
|
||||
iOSLaunchScreeniPadFillPct: 100
|
||||
iOSLaunchScreeniPadSize: 100
|
||||
iOSLaunchScreeniPadCustomXibPath:
|
||||
iOSDeviceRequirements: []
|
||||
iOSURLSchemes: []
|
||||
iOSBackgroundModes: 0
|
||||
iOSMetalForceHardShadows: 0
|
||||
metalEditorSupport: 1
|
||||
metalAPIValidation: 1
|
||||
iOSRenderExtraFrameOnPause: 0
|
||||
appleDeveloperTeamID:
|
||||
iOSManualSigningProvisioningProfileID:
|
||||
tvOSManualSigningProvisioningProfileID:
|
||||
appleEnableAutomaticSigning: 0
|
||||
AndroidTargetDevice: 0
|
||||
AndroidSplashScreenScale: 0
|
||||
androidSplashScreen: {fileID: 0}
|
||||
AndroidKeystoreName:
|
||||
AndroidKeyaliasName:
|
||||
AndroidTVCompatibility: 1
|
||||
AndroidIsGame: 1
|
||||
AndroidEnableTango: 0
|
||||
androidEnableBanner: 1
|
||||
androidUseLowAccuracyLocation: 0
|
||||
m_AndroidBanners:
|
||||
- width: 320
|
||||
height: 180
|
||||
banner: {fileID: 0}
|
||||
androidGamepadSupportLevel: 0
|
||||
resolutionDialogBanner: {fileID: 0}
|
||||
m_BuildTargetIcons: []
|
||||
m_BuildTargetBatching: []
|
||||
m_BuildTargetGraphicsAPIs: []
|
||||
m_BuildTargetVRSettings: []
|
||||
m_BuildTargetEnableVuforiaSettings: []
|
||||
openGLRequireES31: 0
|
||||
openGLRequireES31AEP: 0
|
||||
m_TemplateCustomTags: {}
|
||||
mobileMTRendering:
|
||||
Android: 1
|
||||
iPhone: 1
|
||||
tvOS: 1
|
||||
wiiUTitleID: 0005000011000000
|
||||
wiiUGroupID: 00010000
|
||||
wiiUCommonSaveSize: 4096
|
||||
wiiUAccountSaveSize: 2048
|
||||
wiiUOlvAccessKey: 0
|
||||
wiiUTinCode: 0
|
||||
wiiUJoinGameId: 0
|
||||
wiiUJoinGameModeMask: 0000000000000000
|
||||
wiiUCommonBossSize: 0
|
||||
wiiUAccountBossSize: 0
|
||||
wiiUAddOnUniqueIDs: []
|
||||
wiiUMainThreadStackSize: 3072
|
||||
wiiULoaderThreadStackSize: 1024
|
||||
wiiUSystemHeapSize: 128
|
||||
wiiUTVStartupScreen: {fileID: 0}
|
||||
wiiUGamePadStartupScreen: {fileID: 0}
|
||||
wiiUDrcBufferDisabled: 0
|
||||
wiiUProfilerLibPath:
|
||||
playModeTestRunnerEnabled: 0
|
||||
actionOnDotNetUnhandledException: 1
|
||||
enableInternalProfiler: 0
|
||||
logObjCUncaughtExceptions: 1
|
||||
enableCrashReportAPI: 0
|
||||
cameraUsageDescription:
|
||||
locationUsageDescription:
|
||||
microphoneUsageDescription:
|
||||
switchNetLibKey:
|
||||
switchSocketMemoryPoolSize: 6144
|
||||
switchSocketAllocatorPoolSize: 128
|
||||
switchSocketConcurrencyLimit: 14
|
||||
switchScreenResolutionBehavior: 2
|
||||
switchUseCPUProfiler: 0
|
||||
switchApplicationID: 0x01004b9000490000
|
||||
switchNSODependencies:
|
||||
switchTitleNames_0:
|
||||
switchTitleNames_1:
|
||||
switchTitleNames_2:
|
||||
switchTitleNames_3:
|
||||
switchTitleNames_4:
|
||||
switchTitleNames_5:
|
||||
switchTitleNames_6:
|
||||
switchTitleNames_7:
|
||||
switchTitleNames_8:
|
||||
switchTitleNames_9:
|
||||
switchTitleNames_10:
|
||||
switchTitleNames_11:
|
||||
switchPublisherNames_0:
|
||||
switchPublisherNames_1:
|
||||
switchPublisherNames_2:
|
||||
switchPublisherNames_3:
|
||||
switchPublisherNames_4:
|
||||
switchPublisherNames_5:
|
||||
switchPublisherNames_6:
|
||||
switchPublisherNames_7:
|
||||
switchPublisherNames_8:
|
||||
switchPublisherNames_9:
|
||||
switchPublisherNames_10:
|
||||
switchPublisherNames_11:
|
||||
switchIcons_0: {fileID: 0}
|
||||
switchIcons_1: {fileID: 0}
|
||||
switchIcons_2: {fileID: 0}
|
||||
switchIcons_3: {fileID: 0}
|
||||
switchIcons_4: {fileID: 0}
|
||||
switchIcons_5: {fileID: 0}
|
||||
switchIcons_6: {fileID: 0}
|
||||
switchIcons_7: {fileID: 0}
|
||||
switchIcons_8: {fileID: 0}
|
||||
switchIcons_9: {fileID: 0}
|
||||
switchIcons_10: {fileID: 0}
|
||||
switchIcons_11: {fileID: 0}
|
||||
switchSmallIcons_0: {fileID: 0}
|
||||
switchSmallIcons_1: {fileID: 0}
|
||||
switchSmallIcons_2: {fileID: 0}
|
||||
switchSmallIcons_3: {fileID: 0}
|
||||
switchSmallIcons_4: {fileID: 0}
|
||||
switchSmallIcons_5: {fileID: 0}
|
||||
switchSmallIcons_6: {fileID: 0}
|
||||
switchSmallIcons_7: {fileID: 0}
|
||||
switchSmallIcons_8: {fileID: 0}
|
||||
switchSmallIcons_9: {fileID: 0}
|
||||
switchSmallIcons_10: {fileID: 0}
|
||||
switchSmallIcons_11: {fileID: 0}
|
||||
switchManualHTML:
|
||||
switchAccessibleURLs:
|
||||
switchLegalInformation:
|
||||
switchMainThreadStackSize: 1048576
|
||||
switchPresenceGroupId: 0x01004b9000490000
|
||||
switchLogoHandling: 0
|
||||
switchReleaseVersion: 0
|
||||
switchDisplayVersion: 1.0.0
|
||||
switchStartupUserAccount: 0
|
||||
switchTouchScreenUsage: 0
|
||||
switchSupportedLanguagesMask: 0
|
||||
switchLogoType: 0
|
||||
switchApplicationErrorCodeCategory:
|
||||
switchUserAccountSaveDataSize: 0
|
||||
switchUserAccountSaveDataJournalSize: 0
|
||||
switchApplicationAttribute: 0
|
||||
switchCardSpecSize: 4
|
||||
switchCardSpecClock: 25
|
||||
switchRatingsMask: 0
|
||||
switchRatingsInt_0: 0
|
||||
switchRatingsInt_1: 0
|
||||
switchRatingsInt_2: 0
|
||||
switchRatingsInt_3: 0
|
||||
switchRatingsInt_4: 0
|
||||
switchRatingsInt_5: 0
|
||||
switchRatingsInt_6: 0
|
||||
switchRatingsInt_7: 0
|
||||
switchRatingsInt_8: 0
|
||||
switchRatingsInt_9: 0
|
||||
switchRatingsInt_10: 0
|
||||
switchRatingsInt_11: 0
|
||||
switchLocalCommunicationIds_0: 0x01004b9000490000
|
||||
switchLocalCommunicationIds_1:
|
||||
switchLocalCommunicationIds_2:
|
||||
switchLocalCommunicationIds_3:
|
||||
switchLocalCommunicationIds_4:
|
||||
switchLocalCommunicationIds_5:
|
||||
switchLocalCommunicationIds_6:
|
||||
switchLocalCommunicationIds_7:
|
||||
switchParentalControl: 0
|
||||
switchAllowsScreenshot: 1
|
||||
switchDataLossConfirmation: 0
|
||||
switchSupportedNpadStyles: 3
|
||||
switchSocketConfigEnabled: 0
|
||||
switchTcpInitialSendBufferSize: 32
|
||||
switchTcpInitialReceiveBufferSize: 64
|
||||
switchTcpAutoSendBufferSizeMax: 256
|
||||
switchTcpAutoReceiveBufferSizeMax: 256
|
||||
switchUdpSendBufferSize: 9
|
||||
switchUdpReceiveBufferSize: 42
|
||||
switchSocketBufferEfficiency: 4
|
||||
switchSocketInitializeEnabled: 1
|
||||
switchNetworkInterfaceManagerInitializeEnabled: 1
|
||||
switchPlayerConnectionEnabled: 1
|
||||
ps4NPAgeRating: 12
|
||||
ps4NPTitleSecret:
|
||||
ps4NPTrophyPackPath:
|
||||
ps4ParentalLevel: 11
|
||||
ps4ContentID: ED1633-NPXX51362_00-0000000000000000
|
||||
ps4Category: 0
|
||||
ps4MasterVersion: 01.00
|
||||
ps4AppVersion: 01.00
|
||||
ps4AppType: 0
|
||||
ps4ParamSfxPath:
|
||||
ps4VideoOutPixelFormat: 0
|
||||
ps4VideoOutInitialWidth: 1920
|
||||
ps4VideoOutBaseModeInitialWidth: 1920
|
||||
ps4VideoOutReprojectionRate: 120
|
||||
ps4PronunciationXMLPath:
|
||||
ps4PronunciationSIGPath:
|
||||
ps4BackgroundImagePath:
|
||||
ps4StartupImagePath:
|
||||
ps4SaveDataImagePath:
|
||||
ps4SdkOverride:
|
||||
ps4BGMPath:
|
||||
ps4ShareFilePath:
|
||||
ps4ShareOverlayImagePath:
|
||||
ps4PrivacyGuardImagePath:
|
||||
ps4NPtitleDatPath:
|
||||
ps4RemotePlayKeyAssignment: -1
|
||||
ps4RemotePlayKeyMappingDir:
|
||||
ps4PlayTogetherPlayerCount: 0
|
||||
ps4EnterButtonAssignment: 1
|
||||
ps4ApplicationParam1: 0
|
||||
ps4ApplicationParam2: 0
|
||||
ps4ApplicationParam3: 0
|
||||
ps4ApplicationParam4: 0
|
||||
ps4DownloadDataSize: 0
|
||||
ps4GarlicHeapSize: 2048
|
||||
ps4ProGarlicHeapSize: 2560
|
||||
ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ
|
||||
ps4pnSessions: 1
|
||||
ps4pnPresence: 1
|
||||
ps4pnFriends: 1
|
||||
ps4pnGameCustomData: 1
|
||||
playerPrefsSupport: 0
|
||||
restrictedAudioUsageRights: 0
|
||||
ps4UseResolutionFallback: 0
|
||||
ps4ReprojectionSupport: 0
|
||||
ps4UseAudio3dBackend: 0
|
||||
ps4SocialScreenEnabled: 0
|
||||
ps4ScriptOptimizationLevel: 0
|
||||
ps4Audio3dVirtualSpeakerCount: 14
|
||||
ps4attribCpuUsage: 0
|
||||
ps4PatchPkgPath:
|
||||
ps4PatchLatestPkgPath:
|
||||
ps4PatchChangeinfoPath:
|
||||
ps4PatchDayOne: 0
|
||||
ps4attribUserManagement: 0
|
||||
ps4attribMoveSupport: 0
|
||||
ps4attrib3DSupport: 0
|
||||
ps4attribShareSupport: 0
|
||||
ps4attribExclusiveVR: 0
|
||||
ps4disableAutoHideSplash: 0
|
||||
ps4videoRecordingFeaturesUsed: 0
|
||||
ps4contentSearchFeaturesUsed: 0
|
||||
ps4attribEyeToEyeDistanceSettingVR: 0
|
||||
ps4IncludedModules: []
|
||||
monoEnv:
|
||||
psp2Splashimage: {fileID: 0}
|
||||
psp2NPTrophyPackPath:
|
||||
psp2NPSupportGBMorGJP: 0
|
||||
psp2NPAgeRating: 12
|
||||
psp2NPTitleDatPath:
|
||||
psp2NPCommsID:
|
||||
psp2NPCommunicationsID:
|
||||
psp2NPCommsPassphrase:
|
||||
psp2NPCommsSig:
|
||||
psp2ParamSfxPath:
|
||||
psp2ManualPath:
|
||||
psp2LiveAreaGatePath:
|
||||
psp2LiveAreaBackroundPath:
|
||||
psp2LiveAreaPath:
|
||||
psp2LiveAreaTrialPath:
|
||||
psp2PatchChangeInfoPath:
|
||||
psp2PatchOriginalPackage:
|
||||
psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui
|
||||
psp2KeystoneFile:
|
||||
psp2MemoryExpansionMode: 0
|
||||
psp2DRMType: 0
|
||||
psp2StorageType: 0
|
||||
psp2MediaCapacity: 0
|
||||
psp2DLCConfigPath:
|
||||
psp2ThumbnailPath:
|
||||
psp2BackgroundPath:
|
||||
psp2SoundPath:
|
||||
psp2TrophyCommId:
|
||||
psp2TrophyPackagePath:
|
||||
psp2PackagedResourcesPath:
|
||||
psp2SaveDataQuota: 10240
|
||||
psp2ParentalLevel: 1
|
||||
psp2ShortTitle: Not Set
|
||||
psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF
|
||||
psp2Category: 0
|
||||
psp2MasterVersion: 01.00
|
||||
psp2AppVersion: 01.00
|
||||
psp2TVBootMode: 0
|
||||
psp2EnterButtonAssignment: 2
|
||||
psp2TVDisableEmu: 0
|
||||
psp2AllowTwitterDialog: 1
|
||||
psp2Upgradable: 0
|
||||
psp2HealthWarning: 0
|
||||
psp2UseLibLocation: 0
|
||||
psp2InfoBarOnStartup: 0
|
||||
psp2InfoBarColor: 0
|
||||
psp2ScriptOptimizationLevel: 0
|
||||
psmSplashimage: {fileID: 0}
|
||||
splashScreenBackgroundSourceLandscape: {fileID: 0}
|
||||
splashScreenBackgroundSourcePortrait: {fileID: 0}
|
||||
spritePackerPolicy:
|
||||
webGLMemorySize: 256
|
||||
webGLExceptionSupport: 1
|
||||
webGLNameFilesAsHashes: 0
|
||||
webGLDataCaching: 0
|
||||
webGLDebugSymbols: 0
|
||||
webGLEmscriptenArgs:
|
||||
webGLModulesDirectory:
|
||||
webGLTemplate: APPLICATION:Default
|
||||
webGLAnalyzeBuildSize: 0
|
||||
webGLUseEmbeddedResources: 0
|
||||
webGLUseWasm: 0
|
||||
webGLCompressionFormat: 1
|
||||
scriptingDefineSymbols: {}
|
||||
platformArchitecture: {}
|
||||
scriptingBackend: {}
|
||||
incrementalIl2cppBuild: {}
|
||||
additionalIl2CppArgs:
|
||||
scriptingRuntimeVersion: 0
|
||||
apiCompatibilityLevelPerPlatform: {}
|
||||
m_RenderingPath: 1
|
||||
m_MobileRenderingPath: 1
|
||||
metroPackageName: button-clicker
|
||||
metroPackageVersion:
|
||||
metroCertificatePath:
|
||||
metroCertificatePassword:
|
||||
metroCertificateSubject:
|
||||
metroCertificateIssuer:
|
||||
metroCertificateNotAfter: 0000000000000000
|
||||
metroApplicationDescription: button-clicker
|
||||
wsaImages: {}
|
||||
metroTileShortName:
|
||||
metroCommandLineArgsFile:
|
||||
metroTileShowName: 0
|
||||
metroMediumTileShowName: 0
|
||||
metroLargeTileShowName: 0
|
||||
metroWideTileShowName: 0
|
||||
metroDefaultTileSize: 1
|
||||
metroTileForegroundText: 2
|
||||
metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
|
||||
metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628,
|
||||
a: 1}
|
||||
metroSplashScreenUseBackgroundColor: 0
|
||||
platformCapabilities: {}
|
||||
metroFTAName:
|
||||
metroFTAFileTypes: []
|
||||
metroProtocolName:
|
||||
metroCompilationOverrides: 1
|
||||
tizenProductDescription:
|
||||
tizenProductURL:
|
||||
tizenSigningProfileName:
|
||||
tizenGPSPermissions: 0
|
||||
tizenMicrophonePermissions: 0
|
||||
tizenDeploymentTarget:
|
||||
tizenDeploymentTargetType: -1
|
||||
tizenMinOSVersion: 1
|
||||
n3dsUseExtSaveData: 0
|
||||
n3dsCompressStaticMem: 1
|
||||
n3dsExtSaveDataNumber: 0x12345
|
||||
n3dsStackSize: 131072
|
||||
n3dsTargetPlatform: 2
|
||||
n3dsRegion: 7
|
||||
n3dsMediaSize: 0
|
||||
n3dsLogoStyle: 3
|
||||
n3dsTitle: GameName
|
||||
n3dsProductCode:
|
||||
n3dsApplicationId: 0xFF3FF
|
||||
stvDeviceAddress:
|
||||
stvProductDescription:
|
||||
stvProductAuthor:
|
||||
stvProductAuthorEmail:
|
||||
stvProductLink:
|
||||
stvProductCategory: 0
|
||||
XboxOneProductId:
|
||||
XboxOneUpdateKey:
|
||||
XboxOneSandboxId:
|
||||
XboxOneContentId:
|
||||
XboxOneTitleId:
|
||||
XboxOneSCId:
|
||||
XboxOneGameOsOverridePath:
|
||||
XboxOnePackagingOverridePath:
|
||||
XboxOneAppManifestOverridePath:
|
||||
XboxOnePackageEncryption: 0
|
||||
XboxOnePackageUpdateGranularity: 2
|
||||
XboxOneDescription:
|
||||
XboxOneLanguage:
|
||||
- enus
|
||||
XboxOneCapability: []
|
||||
XboxOneGameRating: {}
|
||||
XboxOneIsContentPackage: 0
|
||||
XboxOneEnableGPUVariability: 0
|
||||
XboxOneSockets: {}
|
||||
XboxOneSplashScreen: {fileID: 0}
|
||||
XboxOneAllowedProductIds: []
|
||||
XboxOnePersistentLocalStorageSize: 0
|
||||
xboxOneScriptCompiler: 0
|
||||
vrEditorSettings:
|
||||
daydream:
|
||||
daydreamIconForeground: {fileID: 0}
|
||||
daydreamIconBackground: {fileID: 0}
|
||||
cloudServicesEnabled: {}
|
||||
facebookSdkVersion: 7.9.4
|
||||
apiCompatibilityLevel: 2
|
||||
cloudProjectId:
|
||||
projectName:
|
||||
organizationId:
|
||||
cloudEnabled: 0
|
||||
enableNativePlatformBackendsForNewInputSystem: 0
|
||||
disableOldInputManagerSupport: 0
|
||||
@@ -0,0 +1 @@
|
||||
m_EditorVersion: 2017.2.0f3
|
||||
@@ -0,0 +1,193 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!47 &1
|
||||
QualitySettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 5
|
||||
m_CurrentQuality: 5
|
||||
m_QualitySettings:
|
||||
- serializedVersion: 2
|
||||
name: Very Low
|
||||
pixelLightCount: 0
|
||||
shadows: 0
|
||||
shadowResolution: 0
|
||||
shadowProjection: 1
|
||||
shadowCascades: 1
|
||||
shadowDistance: 15
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
blendWeights: 1
|
||||
textureQuality: 1
|
||||
anisotropicTextures: 0
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
vSyncCount: 0
|
||||
lodBias: 0.3
|
||||
maximumLODLevel: 0
|
||||
particleRaycastBudget: 4
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 4
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
name: Low
|
||||
pixelLightCount: 0
|
||||
shadows: 0
|
||||
shadowResolution: 0
|
||||
shadowProjection: 1
|
||||
shadowCascades: 1
|
||||
shadowDistance: 20
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
blendWeights: 2
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 0
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
vSyncCount: 0
|
||||
lodBias: 0.4
|
||||
maximumLODLevel: 0
|
||||
particleRaycastBudget: 16
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 4
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
name: Medium
|
||||
pixelLightCount: 1
|
||||
shadows: 1
|
||||
shadowResolution: 0
|
||||
shadowProjection: 1
|
||||
shadowCascades: 1
|
||||
shadowDistance: 20
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 0
|
||||
blendWeights: 2
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 1
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 0
|
||||
realtimeReflectionProbes: 0
|
||||
billboardsFaceCameraPosition: 0
|
||||
vSyncCount: 1
|
||||
lodBias: 0.7
|
||||
maximumLODLevel: 0
|
||||
particleRaycastBudget: 64
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 4
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
name: High
|
||||
pixelLightCount: 2
|
||||
shadows: 2
|
||||
shadowResolution: 1
|
||||
shadowProjection: 1
|
||||
shadowCascades: 2
|
||||
shadowDistance: 40
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
blendWeights: 2
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 1
|
||||
antiAliasing: 0
|
||||
softParticles: 0
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
vSyncCount: 1
|
||||
lodBias: 1
|
||||
maximumLODLevel: 0
|
||||
particleRaycastBudget: 256
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 4
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
name: Very High
|
||||
pixelLightCount: 3
|
||||
shadows: 2
|
||||
shadowResolution: 2
|
||||
shadowProjection: 1
|
||||
shadowCascades: 2
|
||||
shadowDistance: 70
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
blendWeights: 4
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 2
|
||||
softParticles: 1
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
vSyncCount: 1
|
||||
lodBias: 1.5
|
||||
maximumLODLevel: 0
|
||||
particleRaycastBudget: 1024
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 4
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
excludedTargetPlatforms: []
|
||||
- serializedVersion: 2
|
||||
name: Ultra
|
||||
pixelLightCount: 4
|
||||
shadows: 2
|
||||
shadowResolution: 2
|
||||
shadowProjection: 1
|
||||
shadowCascades: 4
|
||||
shadowDistance: 150
|
||||
shadowNearPlaneOffset: 3
|
||||
shadowCascade2Split: 0.33333334
|
||||
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
|
||||
shadowmaskMode: 1
|
||||
blendWeights: 4
|
||||
textureQuality: 0
|
||||
anisotropicTextures: 2
|
||||
antiAliasing: 2
|
||||
softParticles: 1
|
||||
softVegetation: 1
|
||||
realtimeReflectionProbes: 1
|
||||
billboardsFaceCameraPosition: 1
|
||||
vSyncCount: 1
|
||||
lodBias: 2
|
||||
maximumLODLevel: 0
|
||||
particleRaycastBudget: 4096
|
||||
asyncUploadTimeSlice: 2
|
||||
asyncUploadBufferSize: 4
|
||||
resolutionScalingFixedDPIFactor: 1
|
||||
excludedTargetPlatforms: []
|
||||
m_PerPlatformDefaultQuality:
|
||||
Android: 2
|
||||
Nintendo 3DS: 5
|
||||
Nintendo Switch: 5
|
||||
PS4: 5
|
||||
PSM: 5
|
||||
PSP2: 2
|
||||
Samsung TV: 2
|
||||
Standalone: 5
|
||||
Tizen: 2
|
||||
Web: 5
|
||||
WebGL: 3
|
||||
WiiU: 5
|
||||
Windows Store Apps: 5
|
||||
XboxOne: 5
|
||||
iPhone: 2
|
||||
tvOS: 2
|
||||
@@ -0,0 +1,43 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!78 &1
|
||||
TagManager:
|
||||
serializedVersion: 2
|
||||
tags: []
|
||||
layers:
|
||||
- Default
|
||||
- TransparentFX
|
||||
- Ignore Raycast
|
||||
-
|
||||
- Water
|
||||
- UI
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
m_SortingLayers:
|
||||
- name: Default
|
||||
uniqueID: 0
|
||||
locked: 0
|
||||
@@ -0,0 +1,9 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!5 &1
|
||||
TimeManager:
|
||||
m_ObjectHideFlags: 0
|
||||
Fixed Timestep: 0.02
|
||||
Maximum Allowed Timestep: 0.33333334
|
||||
m_TimeScale: 1
|
||||
Maximum Particle Timestep: 0.03
|
||||
@@ -0,0 +1,34 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!310 &1
|
||||
UnityConnectSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Enabled: 0
|
||||
m_TestMode: 0
|
||||
m_TestEventUrl:
|
||||
m_TestConfigUrl:
|
||||
m_TestInitMode: 0
|
||||
CrashReportingSettings:
|
||||
m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes
|
||||
m_Enabled: 0
|
||||
m_CaptureEditorExceptions: 1
|
||||
UnityPurchasingSettings:
|
||||
m_Enabled: 0
|
||||
m_TestMode: 0
|
||||
UnityAnalyticsSettings:
|
||||
m_Enabled: 0
|
||||
m_InitializeOnStartup: 1
|
||||
m_TestMode: 0
|
||||
m_TestEventUrl:
|
||||
m_TestConfigUrl:
|
||||
UnityAdsSettings:
|
||||
m_Enabled: 0
|
||||
m_InitializeOnStartup: 1
|
||||
m_TestMode: 0
|
||||
m_EnabledPlatforms: 4294967295
|
||||
m_IosGameId:
|
||||
m_AndroidGameId:
|
||||
m_GameIds: {}
|
||||
m_GameId:
|
||||
PerformanceReportingSettings:
|
||||
m_Enabled: 0
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"dependencies": {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
add_executable(
|
||||
send-presence
|
||||
MACOSX_BUNDLE
|
||||
send-presence.c
|
||||
)
|
||||
set_target_properties(send-presence PROPERTIES
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "Send Presence"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "com.discordapp.examples.send-presence"
|
||||
)
|
||||
target_link_libraries(send-presence discord-rpc)
|
||||
|
||||
install(
|
||||
TARGETS send-presence
|
||||
RUNTIME
|
||||
DESTINATION "bin"
|
||||
CONFIGURATIONS Release
|
||||
BUNDLE
|
||||
DESTINATION "bin"
|
||||
CONFIGURATIONS Release
|
||||
)
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
This is a simple example in C of using the rich presence API asynchronously.
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS /* thanks Microsoft */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "discord_rpc.h"
|
||||
|
||||
static const char* APPLICATION_ID = "345229890980937739";
|
||||
static int FrustrationLevel = 0;
|
||||
static int64_t StartTime;
|
||||
static int SendPresence = 1;
|
||||
|
||||
static int prompt(char* line, size_t size)
|
||||
{
|
||||
int res;
|
||||
char* nl;
|
||||
printf("\n> ");
|
||||
fflush(stdout);
|
||||
res = fgets(line, (int)size, stdin) ? 1 : 0;
|
||||
line[size - 1] = 0;
|
||||
nl = strchr(line, '\n');
|
||||
if (nl) {
|
||||
*nl = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static void updateDiscordPresence()
|
||||
{
|
||||
if (SendPresence) {
|
||||
char buffer[256];
|
||||
DiscordRichPresence discordPresence;
|
||||
memset(&discordPresence, 0, sizeof(discordPresence));
|
||||
discordPresence.state = "West of House";
|
||||
sprintf(buffer, "Frustration level: %d", FrustrationLevel);
|
||||
discordPresence.details = buffer;
|
||||
discordPresence.startTimestamp = StartTime;
|
||||
discordPresence.endTimestamp = time(0) + 5 * 60;
|
||||
discordPresence.largeImageKey = "canary-large";
|
||||
discordPresence.smallImageKey = "ptb-small";
|
||||
discordPresence.partyId = "party1234";
|
||||
discordPresence.partySize = 1;
|
||||
discordPresence.partyMax = 6;
|
||||
discordPresence.partyPrivacy = DISCORD_PARTY_PUBLIC;
|
||||
discordPresence.matchSecret = "xyzzy";
|
||||
discordPresence.joinSecret = "join";
|
||||
discordPresence.spectateSecret = "look";
|
||||
discordPresence.instance = 0;
|
||||
Discord_UpdatePresence(&discordPresence);
|
||||
}
|
||||
else {
|
||||
Discord_ClearPresence();
|
||||
}
|
||||
}
|
||||
|
||||
static void handleDiscordReady(const DiscordUser* connectedUser)
|
||||
{
|
||||
printf("\nDiscord: connected to user %s#%s - %s\n",
|
||||
connectedUser->username,
|
||||
connectedUser->discriminator,
|
||||
connectedUser->userId);
|
||||
}
|
||||
|
||||
static void handleDiscordDisconnected(int errcode, const char* message)
|
||||
{
|
||||
printf("\nDiscord: disconnected (%d: %s)\n", errcode, message);
|
||||
}
|
||||
|
||||
static void handleDiscordError(int errcode, const char* message)
|
||||
{
|
||||
printf("\nDiscord: error (%d: %s)\n", errcode, message);
|
||||
}
|
||||
|
||||
static void handleDiscordJoin(const char* secret)
|
||||
{
|
||||
printf("\nDiscord: join (%s)\n", secret);
|
||||
}
|
||||
|
||||
static void handleDiscordSpectate(const char* secret)
|
||||
{
|
||||
printf("\nDiscord: spectate (%s)\n", secret);
|
||||
}
|
||||
|
||||
static void handleDiscordJoinRequest(const DiscordUser* request)
|
||||
{
|
||||
int response = -1;
|
||||
char yn[4];
|
||||
printf("\nDiscord: join request from %s#%s - %s\n",
|
||||
request->username,
|
||||
request->discriminator,
|
||||
request->userId);
|
||||
do {
|
||||
printf("Accept? (y/n)");
|
||||
if (!prompt(yn, sizeof(yn))) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!yn[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (yn[0] == 'y') {
|
||||
response = DISCORD_REPLY_YES;
|
||||
break;
|
||||
}
|
||||
|
||||
if (yn[0] == 'n') {
|
||||
response = DISCORD_REPLY_NO;
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
if (response != -1) {
|
||||
Discord_Respond(request->userId, response);
|
||||
}
|
||||
}
|
||||
|
||||
static void discordInit()
|
||||
{
|
||||
DiscordEventHandlers handlers;
|
||||
memset(&handlers, 0, sizeof(handlers));
|
||||
handlers.ready = handleDiscordReady;
|
||||
handlers.disconnected = handleDiscordDisconnected;
|
||||
handlers.errored = handleDiscordError;
|
||||
handlers.joinGame = handleDiscordJoin;
|
||||
handlers.spectateGame = handleDiscordSpectate;
|
||||
handlers.joinRequest = handleDiscordJoinRequest;
|
||||
Discord_Initialize(APPLICATION_ID, &handlers, 1, NULL);
|
||||
}
|
||||
|
||||
static void gameLoop()
|
||||
{
|
||||
char line[512];
|
||||
char* space;
|
||||
|
||||
StartTime = time(0);
|
||||
|
||||
printf("You are standing in an open field west of a white house.\n");
|
||||
while (prompt(line, sizeof(line))) {
|
||||
if (line[0]) {
|
||||
if (line[0] == 'q') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (line[0] == 't') {
|
||||
printf("Shutting off Discord.\n");
|
||||
Discord_Shutdown();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == 'c') {
|
||||
if (SendPresence) {
|
||||
printf("Clearing presence information.\n");
|
||||
SendPresence = 0;
|
||||
}
|
||||
else {
|
||||
printf("Restoring presence information.\n");
|
||||
SendPresence = 1;
|
||||
}
|
||||
updateDiscordPresence();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == 'y') {
|
||||
printf("Reinit Discord.\n");
|
||||
discordInit();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (time(NULL) & 1) {
|
||||
printf("I don't understand that.\n");
|
||||
}
|
||||
else {
|
||||
space = strchr(line, ' ');
|
||||
if (space) {
|
||||
*space = 0;
|
||||
}
|
||||
printf("I don't know the word \"%s\".\n", line);
|
||||
}
|
||||
|
||||
++FrustrationLevel;
|
||||
|
||||
updateDiscordPresence();
|
||||
}
|
||||
|
||||
#ifdef DISCORD_DISABLE_IO_THREAD
|
||||
Discord_UpdateConnection();
|
||||
#endif
|
||||
Discord_RunCallbacks();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
discordInit();
|
||||
|
||||
gameLoop();
|
||||
|
||||
Discord_Shutdown();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
# Visual Studio 2015 user specific files
|
||||
.vs/
|
||||
|
||||
# Visual Studio 2015 database file
|
||||
*.VC.db
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.ipa
|
||||
|
||||
# These project files can be generated by the engine
|
||||
*.xcodeproj
|
||||
*.xcworkspace
|
||||
*.sln
|
||||
*.suo
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.VC.db
|
||||
*.VC.opendb
|
||||
|
||||
# Precompiled Assets
|
||||
SourceArt/**/*.png
|
||||
SourceArt/**/*.tga
|
||||
|
||||
# Binary Files
|
||||
Binaries/
|
||||
|
||||
# Builds
|
||||
Build/*
|
||||
|
||||
# Whitelist PakBlacklist-<BuildConfiguration>.txt files
|
||||
!Build/*/
|
||||
Build/*/**
|
||||
!Build/*/PakBlacklist*.txt
|
||||
|
||||
# Don't ignore icon files in Build
|
||||
!Build/**/*.ico
|
||||
|
||||
# Built data for maps
|
||||
*_BuiltData.uasset
|
||||
|
||||
# Configuration files generated by the Editor
|
||||
Saved/*
|
||||
|
||||
# Compiled source files for the engine to use
|
||||
Intermediate/
|
||||
|
||||
# Cache files for the editor to use
|
||||
DerivedDataCache/
|
||||
|
||||
# Library headers must be copied automatically by the build script (build.py unreal)
|
||||
Plugins/DiscordRpc/Source/ThirdParty/DiscordRpcLibrary/Include
|
||||
@@ -0,0 +1,54 @@
|
||||
[URL]
|
||||
|
||||
[/Script/HardwareTargeting.HardwareTargetingSettings]
|
||||
TargetedHardwareClass=Desktop
|
||||
AppliedTargetedHardwareClass=Desktop
|
||||
DefaultGraphicsPerformance=Maximum
|
||||
AppliedDefaultGraphicsPerformance=Maximum
|
||||
|
||||
[/Script/Engine.EndUserSettings]
|
||||
bSendAnonymousUsageDataToEpic=False
|
||||
|
||||
[/Script/Engine.PhysicsSettings]
|
||||
DefaultGravityZ=-980.000000
|
||||
DefaultTerminalVelocity=4000.000000
|
||||
DefaultFluidFriction=0.300000
|
||||
SimulateScratchMemorySize=262144
|
||||
RagdollAggregateThreshold=4
|
||||
TriangleMeshTriangleMinAreaThreshold=5.000000
|
||||
bEnableAsyncScene=False
|
||||
bEnableShapeSharing=False
|
||||
bEnablePCM=False
|
||||
bEnableStabilization=False
|
||||
bWarnMissingLocks=True
|
||||
bEnable2DPhysics=False
|
||||
LockedAxis=Invalid
|
||||
DefaultDegreesOfFreedom=Full3D
|
||||
BounceThresholdVelocity=200.000000
|
||||
FrictionCombineMode=Average
|
||||
RestitutionCombineMode=Average
|
||||
MaxAngularVelocity=3600.000000
|
||||
MaxDepenetrationVelocity=0.000000
|
||||
ContactOffsetMultiplier=0.010000
|
||||
MinContactOffset=0.000100
|
||||
MaxContactOffset=1.000000
|
||||
bSimulateSkeletalMeshOnDedicatedServer=True
|
||||
DefaultShapeComplexity=CTF_UseSimpleAndComplex
|
||||
bDefaultHasComplexCollision=True
|
||||
bSuppressFaceRemapTable=False
|
||||
bSupportUVFromHitResults=False
|
||||
bDisableActiveActors=False
|
||||
bDisableCCD=False
|
||||
MaxPhysicsDeltaTime=0.033333
|
||||
bSubstepping=False
|
||||
bSubsteppingAsync=False
|
||||
MaxSubstepDeltaTime=0.016667
|
||||
MaxSubsteps=6
|
||||
SyncSceneSmoothingFactor=0.000000
|
||||
AsyncSceneSmoothingFactor=0.990000
|
||||
InitialAverageFrameRate=0.016667
|
||||
|
||||
[/Script/EngineSettings.GameMapsSettings]
|
||||
EditorStartupMap=/Game/ShowTheUILevel.ShowTheUILevel
|
||||
GameDefaultMap=/Game/ShowTheUILevel.ShowTheUILevel
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
[/Script/EngineSettings.GeneralProjectSettings]
|
||||
ProjectID=E5977A24492699DF20B8ADBF736AF6C6
|
||||
ProjectName=Discord RPC Example
|
||||
CompanyName=Discord Inc.
|
||||
Homepage="https://discordapp.com/"
|
||||
CopyrightNotice=
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "Discord RPC",
|
||||
"Description": "Wrap the Discord RPC library.",
|
||||
"Category": "Messaging",
|
||||
"CreatedBy": "Chris Marsh <chris@discordapp.com>",
|
||||
"CreatedByURL": "https://discordapp.com/",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "",
|
||||
"CanContainContent": true,
|
||||
"IsBetaVersion": true,
|
||||
"Installed": false,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "DiscordRpc",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "PreDefault",
|
||||
"WhitelistPlatforms" :
|
||||
[
|
||||
"Win64",
|
||||
"Linux",
|
||||
"Mac"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
@@ -0,0 +1,57 @@
|
||||
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
using System.IO;
|
||||
|
||||
public class DiscordRpc : ModuleRules
|
||||
{
|
||||
#if WITH_FORWARDED_MODULE_RULES_CTOR
|
||||
public DiscordRpc(ReadOnlyTargetRules Target) : base(Target)
|
||||
#else
|
||||
public DiscordRpc(TargetInfo Target)
|
||||
#endif
|
||||
{
|
||||
Definitions.Add("DISCORD_DYNAMIC_LIB=1");
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
"DiscordRpc/Public"
|
||||
}
|
||||
);
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
"DiscordRpc/Private"
|
||||
}
|
||||
);
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"DiscordRpcLibrary"
|
||||
}
|
||||
);
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"Projects"
|
||||
}
|
||||
);
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
|
||||
string BaseDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..", "Source", "ThirdParty", "DiscordRpcLibrary"));
|
||||
PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "DiscordRpcPrivatePCH.h"
|
||||
#include "IPluginManager.h"
|
||||
#include "ModuleManager.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FDiscordRpcModule"
|
||||
|
||||
void FDiscordRpcModule::StartupModule()
|
||||
{
|
||||
#if !PLATFORM_LINUX
|
||||
#if defined(DISCORD_DYNAMIC_LIB)
|
||||
// Get the base directory of this plugin
|
||||
FString BaseDir = IPluginManager::Get().FindPlugin("DiscordRpc")->GetBaseDir();
|
||||
const FString SDKDir =
|
||||
FPaths::Combine(*BaseDir, TEXT("Source"), TEXT("ThirdParty"), TEXT("DiscordRpcLibrary"));
|
||||
#if PLATFORM_WINDOWS
|
||||
const FString LibName = TEXT("discord-rpc");
|
||||
const FString LibDir = FPaths::Combine(*SDKDir, TEXT("Win64"));
|
||||
if (!LoadDependency(LibDir, LibName, DiscordRpcLibraryHandle)) {
|
||||
FMessageDialog::Open(
|
||||
EAppMsgType::Ok,
|
||||
LOCTEXT(LOCTEXT_NAMESPACE,
|
||||
"Failed to load DiscordRpc plugin. Plug-in will not be functional."));
|
||||
FreeDependency(DiscordRpcLibraryHandle);
|
||||
}
|
||||
#elif PLATFORM_MAC
|
||||
const FString LibName = TEXT("libdiscord-rpc");
|
||||
const FString LibDir = FPaths::Combine(*SDKDir, TEXT("Mac"));
|
||||
if (!LoadDependency(LibDir, LibName, DiscordRpcLibraryHandle)) {
|
||||
FMessageDialog::Open(
|
||||
EAppMsgType::Ok,
|
||||
LOCTEXT(LOCTEXT_NAMESPACE,
|
||||
"Failed to load DiscordRpc plugin. Plug-in will not be functional."));
|
||||
FreeDependency(DiscordRpcLibraryHandle);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void FDiscordRpcModule::ShutdownModule()
|
||||
{
|
||||
// Free the dll handle
|
||||
#if !PLATFORM_LINUX
|
||||
#if defined(DISCORD_DYNAMIC_LIB)
|
||||
FreeDependency(DiscordRpcLibraryHandle);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FDiscordRpcModule::LoadDependency(const FString& Dir, const FString& Name, void*& Handle)
|
||||
{
|
||||
FString Lib = Name + TEXT(".") + FPlatformProcess::GetModuleExtension();
|
||||
FString Path = Dir.IsEmpty() ? *Lib : FPaths::Combine(*Dir, *Lib);
|
||||
|
||||
Handle = FPlatformProcess::GetDllHandle(*Path);
|
||||
|
||||
if (Handle == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FDiscordRpcModule::FreeDependency(void*& Handle)
|
||||
{
|
||||
if (Handle != nullptr) {
|
||||
FPlatformProcess::FreeDllHandle(Handle);
|
||||
Handle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FDiscordRpcModule, DiscordRpc)
|
||||
@@ -0,0 +1,172 @@
|
||||
#include "DiscordRpcPrivatePCH.h"
|
||||
#include "DiscordRpcBlueprint.h"
|
||||
#include "discord_rpc.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY(Discord)
|
||||
|
||||
static UDiscordRpc* self = nullptr;
|
||||
|
||||
static void ReadyHandler(const DiscordUser* connectedUser)
|
||||
{
|
||||
FDiscordUserData ud;
|
||||
ud.userId = ANSI_TO_TCHAR(connectedUser->userId);
|
||||
ud.username = ANSI_TO_TCHAR(connectedUser->username);
|
||||
ud.discriminator = ANSI_TO_TCHAR(connectedUser->discriminator);
|
||||
ud.avatar = ANSI_TO_TCHAR(connectedUser->avatar);
|
||||
UE_LOG(Discord,
|
||||
Log,
|
||||
TEXT("Discord connected to %s - %s#%s"),
|
||||
*ud.userId,
|
||||
*ud.username,
|
||||
*ud.discriminator);
|
||||
if (self) {
|
||||
self->IsConnected = true;
|
||||
self->OnConnected.Broadcast(ud);
|
||||
}
|
||||
}
|
||||
|
||||
static void DisconnectHandler(int errorCode, const char* message)
|
||||
{
|
||||
auto msg = FString(message);
|
||||
UE_LOG(Discord, Log, TEXT("Discord disconnected (%d): %s"), errorCode, *msg);
|
||||
if (self) {
|
||||
self->IsConnected = false;
|
||||
self->OnDisconnected.Broadcast(errorCode, msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void ErroredHandler(int errorCode, const char* message)
|
||||
{
|
||||
auto msg = FString(message);
|
||||
UE_LOG(Discord, Log, TEXT("Discord error (%d): %s"), errorCode, *msg);
|
||||
if (self) {
|
||||
self->OnErrored.Broadcast(errorCode, msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void JoinGameHandler(const char* joinSecret)
|
||||
{
|
||||
auto secret = FString(joinSecret);
|
||||
UE_LOG(Discord, Log, TEXT("Discord join %s"), *secret);
|
||||
if (self) {
|
||||
self->OnJoin.Broadcast(secret);
|
||||
}
|
||||
}
|
||||
|
||||
static void SpectateGameHandler(const char* spectateSecret)
|
||||
{
|
||||
auto secret = FString(spectateSecret);
|
||||
UE_LOG(Discord, Log, TEXT("Discord spectate %s"), *secret);
|
||||
if (self) {
|
||||
self->OnSpectate.Broadcast(secret);
|
||||
}
|
||||
}
|
||||
|
||||
static void JoinRequestHandler(const DiscordUser* request)
|
||||
{
|
||||
FDiscordUserData ud;
|
||||
ud.userId = ANSI_TO_TCHAR(request->userId);
|
||||
ud.username = ANSI_TO_TCHAR(request->username);
|
||||
ud.discriminator = ANSI_TO_TCHAR(request->discriminator);
|
||||
ud.avatar = ANSI_TO_TCHAR(request->avatar);
|
||||
UE_LOG(Discord,
|
||||
Log,
|
||||
TEXT("Discord join request from %s - %s#%s"),
|
||||
*ud.userId,
|
||||
*ud.username,
|
||||
*ud.discriminator);
|
||||
if (self) {
|
||||
self->OnJoinRequest.Broadcast(ud);
|
||||
}
|
||||
}
|
||||
|
||||
void UDiscordRpc::Initialize(const FString& applicationId,
|
||||
bool autoRegister,
|
||||
const FString& optionalSteamId)
|
||||
{
|
||||
self = this;
|
||||
IsConnected = false;
|
||||
DiscordEventHandlers handlers{};
|
||||
handlers.ready = ReadyHandler;
|
||||
handlers.disconnected = DisconnectHandler;
|
||||
handlers.errored = ErroredHandler;
|
||||
if (OnJoin.IsBound()) {
|
||||
handlers.joinGame = JoinGameHandler;
|
||||
}
|
||||
if (OnSpectate.IsBound()) {
|
||||
handlers.spectateGame = SpectateGameHandler;
|
||||
}
|
||||
if (OnJoinRequest.IsBound()) {
|
||||
handlers.joinRequest = JoinRequestHandler;
|
||||
}
|
||||
auto appId = StringCast<ANSICHAR>(*applicationId);
|
||||
auto steamId = StringCast<ANSICHAR>(*optionalSteamId);
|
||||
Discord_Initialize(
|
||||
(const char*)appId.Get(), &handlers, autoRegister, (const char*)steamId.Get());
|
||||
}
|
||||
|
||||
void UDiscordRpc::Shutdown()
|
||||
{
|
||||
Discord_Shutdown();
|
||||
self = nullptr;
|
||||
}
|
||||
|
||||
void UDiscordRpc::RunCallbacks()
|
||||
{
|
||||
Discord_RunCallbacks();
|
||||
}
|
||||
|
||||
void UDiscordRpc::UpdatePresence()
|
||||
{
|
||||
DiscordRichPresence rp{};
|
||||
|
||||
auto state = StringCast<ANSICHAR>(*RichPresence.state);
|
||||
rp.state = state.Get();
|
||||
|
||||
auto details = StringCast<ANSICHAR>(*RichPresence.details);
|
||||
rp.details = details.Get();
|
||||
|
||||
auto largeImageKey = StringCast<ANSICHAR>(*RichPresence.largeImageKey);
|
||||
rp.largeImageKey = largeImageKey.Get();
|
||||
|
||||
auto largeImageText = StringCast<ANSICHAR>(*RichPresence.largeImageText);
|
||||
rp.largeImageText = largeImageText.Get();
|
||||
|
||||
auto smallImageKey = StringCast<ANSICHAR>(*RichPresence.smallImageKey);
|
||||
rp.smallImageKey = smallImageKey.Get();
|
||||
|
||||
auto smallImageText = StringCast<ANSICHAR>(*RichPresence.smallImageText);
|
||||
rp.smallImageText = smallImageText.Get();
|
||||
|
||||
auto partyId = StringCast<ANSICHAR>(*RichPresence.partyId);
|
||||
rp.partyId = partyId.Get();
|
||||
|
||||
auto matchSecret = StringCast<ANSICHAR>(*RichPresence.matchSecret);
|
||||
rp.matchSecret = matchSecret.Get();
|
||||
|
||||
auto joinSecret = StringCast<ANSICHAR>(*RichPresence.joinSecret);
|
||||
rp.joinSecret = joinSecret.Get();
|
||||
|
||||
auto spectateSecret = StringCast<ANSICHAR>(*RichPresence.spectateSecret);
|
||||
rp.spectateSecret = spectateSecret.Get();
|
||||
rp.startTimestamp = RichPresence.startTimestamp;
|
||||
rp.endTimestamp = RichPresence.endTimestamp;
|
||||
rp.partySize = RichPresence.partySize;
|
||||
rp.partyMax = RichPresence.partyMax;
|
||||
rp.partyPrivacy = (int)RichPresence.partyPrivacy;
|
||||
rp.instance = RichPresence.instance;
|
||||
|
||||
Discord_UpdatePresence(&rp);
|
||||
}
|
||||
|
||||
void UDiscordRpc::ClearPresence()
|
||||
{
|
||||
Discord_ClearPresence();
|
||||
}
|
||||
|
||||
void UDiscordRpc::Respond(const FString& userId, int reply)
|
||||
{
|
||||
UE_LOG(Discord, Log, TEXT("Responding %d to join request from %s"), reply, *userId);
|
||||
FTCHARToUTF8 utf8_userid(*userId);
|
||||
Discord_Respond(utf8_userid.Get(), reply);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#include "Core.h"
|
||||
#include "DiscordRpc.h"
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ModuleManager.h"
|
||||
|
||||
class FDiscordRpcModule : public IModuleInterface {
|
||||
public:
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
|
||||
private:
|
||||
/** Handle to the test dll we will load */
|
||||
void* DiscordRpcLibraryHandle;
|
||||
|
||||
/** StartupModule is covered with defines, these functions are the place to put breakpoints */
|
||||
static bool LoadDependency(const FString& Dir, const FString& Name, void*& Handle);
|
||||
static void FreeDependency(void*& Handle);
|
||||
};
|
||||
@@ -0,0 +1,181 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine.h"
|
||||
#include "DiscordRpcBlueprint.generated.h"
|
||||
|
||||
// unreal's header tool hates clang-format
|
||||
// clang-format off
|
||||
|
||||
/**
|
||||
* Ask to join callback data
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FDiscordUserData {
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
FString userId;
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
FString username;
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
FString discriminator;
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
FString avatar;
|
||||
};
|
||||
|
||||
/**
|
||||
* Valid response codes for Respond function
|
||||
*/
|
||||
UENUM(BlueprintType)
|
||||
enum class EDiscordJoinResponseCodes : uint8
|
||||
{
|
||||
DISCORD_REPLY_NO UMETA(DisplayName="No"),
|
||||
DISCORD_REPLY_YES UMETA(DisplayName="Yes"),
|
||||
DISCORD_REPLY_IGNORE UMETA(DisplayName="Ignore")
|
||||
};
|
||||
|
||||
/**
|
||||
* Valid party privacy values
|
||||
*/
|
||||
UENUM(BlueprintType)
|
||||
enum class EDiscordPartyPrivacy: uint8
|
||||
{
|
||||
DISCORD_PARTY_PRIVATE UMETA(DisplayName="Private"),
|
||||
DISCORD_PARTY_PUBLIC UMETA(DisplayName="Public")
|
||||
};
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(Discord, Log, All);
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordConnected, const FDiscordUserData&, joinRequest);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FDiscordDisconnected, int, errorCode, const FString&, errorMessage);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FDiscordErrored, int, errorCode, const FString&, errorMessage);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordJoin, const FString&, joinSecret);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordSpectate, const FString&, spectateSecret);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordJoinRequest, const FDiscordUserData&, joinRequest);
|
||||
|
||||
// clang-format on
|
||||
|
||||
/**
|
||||
* Rich presence data
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FDiscordRichPresence {
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString state;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString details;
|
||||
// todo, timestamps are 64bit, does that even matter?
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
int startTimestamp;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
int endTimestamp;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString largeImageKey;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString largeImageText;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString smallImageKey;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString smallImageText;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString partyId;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
int partySize;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
int partyMax;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
EDiscordPartyPrivacy partyPrivacy;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString matchSecret;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString joinSecret;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString spectateSecret;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
bool instance;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(BlueprintType, meta = (DisplayName = "Discord RPC"), Category = "Discord")
|
||||
class DISCORDRPC_API UDiscordRpc : public UObject {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable,
|
||||
meta = (DisplayName = "Initialize connection", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
void Initialize(const FString& applicationId,
|
||||
bool autoRegister,
|
||||
const FString& optionalSteamId);
|
||||
|
||||
UFUNCTION(BlueprintCallable,
|
||||
meta = (DisplayName = "Shut down connection", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
void Shutdown();
|
||||
|
||||
UFUNCTION(BlueprintCallable,
|
||||
meta = (DisplayName = "Check for callbacks", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
void RunCallbacks();
|
||||
|
||||
UFUNCTION(BlueprintCallable,
|
||||
meta = (DisplayName = "Send presence", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
void UpdatePresence();
|
||||
|
||||
UFUNCTION(BlueprintCallable,
|
||||
meta = (DisplayName = "Clear presence", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
void ClearPresence();
|
||||
|
||||
UFUNCTION(BlueprintCallable,
|
||||
meta = (DisplayName = "Respond to join request", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
void Respond(const FString& userId, int reply);
|
||||
|
||||
UPROPERTY(BlueprintReadOnly,
|
||||
meta = (DisplayName = "Is Discord connected", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
bool IsConnected;
|
||||
|
||||
UPROPERTY(BlueprintAssignable,
|
||||
meta = (DisplayName = "On connection", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
FDiscordConnected OnConnected;
|
||||
|
||||
UPROPERTY(BlueprintAssignable,
|
||||
meta = (DisplayName = "On disconnection", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
FDiscordDisconnected OnDisconnected;
|
||||
|
||||
UPROPERTY(BlueprintAssignable,
|
||||
meta = (DisplayName = "On error message", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
FDiscordErrored OnErrored;
|
||||
|
||||
UPROPERTY(BlueprintAssignable,
|
||||
meta = (DisplayName = "When Discord user presses join", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
FDiscordJoin OnJoin;
|
||||
|
||||
UPROPERTY(BlueprintAssignable,
|
||||
meta = (DisplayName = "When Discord user presses spectate", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
FDiscordSpectate OnSpectate;
|
||||
|
||||
UPROPERTY(BlueprintAssignable,
|
||||
meta = (DisplayName = "When Discord another user sends a join request",
|
||||
Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
FDiscordJoinRequest OnJoinRequest;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite,
|
||||
meta = (DisplayName = "Rich presence info", Keywords = "Discord rpc"),
|
||||
Category = "Discord")
|
||||
FDiscordRichPresence RichPresence;
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using System.IO;
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class DiscordRpcLibrary : ModuleRules
|
||||
{
|
||||
#if WITH_FORWARDED_MODULE_RULES_CTOR
|
||||
public DiscordRpcLibrary(ReadOnlyTargetRules Target) : base(Target)
|
||||
#else
|
||||
public DiscordRpcLibrary(TargetInfo Target)
|
||||
#endif
|
||||
{
|
||||
Type = ModuleType.External;
|
||||
Definitions.Add("DISCORD_DYNAMIC_LIB=1");
|
||||
|
||||
string BaseDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..", "ThirdParty", "DiscordRpcLibrary"));
|
||||
|
||||
if (Target.Platform == UnrealTargetPlatform.Win64)
|
||||
{
|
||||
string lib = Path.Combine(BaseDirectory, "Win64");
|
||||
|
||||
// Include headers
|
||||
PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include"));
|
||||
|
||||
// Add the import library
|
||||
PublicLibraryPaths.Add(lib);
|
||||
PublicAdditionalLibraries.Add(Path.Combine(lib, "discord-rpc.lib"));
|
||||
|
||||
// Dynamic
|
||||
RuntimeDependencies.Add(new RuntimeDependency(Path.Combine(lib, "discord-rpc.dll")));
|
||||
PublicDelayLoadDLLs.Add("discord-rpc.dll");
|
||||
}
|
||||
else if (Target.Platform == UnrealTargetPlatform.Linux)
|
||||
{
|
||||
string lib = Path.Combine(BaseDirectory, "Linux", "x86_64-unknown-linux-gnu");
|
||||
|
||||
// Include headers
|
||||
PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include"));
|
||||
|
||||
// Add the import library
|
||||
PublicLibraryPaths.Add(lib);
|
||||
PublicAdditionalLibraries.Add(Path.Combine(lib, "libdiscord-rpc.so"));
|
||||
RuntimeDependencies.Add(new RuntimeDependency(Path.Combine(lib, "libdiscord-rpc.so")));
|
||||
}
|
||||
else if (Target.Platform == UnrealTargetPlatform.Mac)
|
||||
{
|
||||
string lib = Path.Combine(BaseDirectory, "Mac");
|
||||
|
||||
// Include headers
|
||||
PublicIncludePaths.Add(Path.Combine(BaseDirectory, "Include"));
|
||||
|
||||
// Add the import library
|
||||
PublicLibraryPaths.Add(lib);
|
||||
PublicAdditionalLibraries.Add(Path.Combine(lib, "libdiscord-rpc.dylib"));
|
||||
RuntimeDependencies.Add(new RuntimeDependency(Path.Combine(lib, "libdiscord-rpc.dylib")));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using UnrealBuildTool;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class unrealstatusTarget : TargetRules
|
||||
{
|
||||
public unrealstatusTarget(TargetInfo Target) : base(Target)
|
||||
{
|
||||
Type = TargetType.Game;
|
||||
|
||||
ExtraModuleNames.AddRange( new string[] { "unrealstatus" } );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class unrealstatus : ModuleRules
|
||||
{
|
||||
public unrealstatus(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(new string[] { });
|
||||
|
||||
// Uncomment if you are using Slate UI
|
||||
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
|
||||
|
||||
// Uncomment if you are using online features
|
||||
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
|
||||
|
||||
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "unrealstatus.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
IMPLEMENT_PRIMARY_GAME_MODULE(FDefaultGameModuleImpl, unrealstatus, "unrealstatus");
|
||||
@@ -0,0 +1,5 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
@@ -0,0 +1,3 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "unrealstatusGameModeBase.h"
|
||||
@@ -0,0 +1,15 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/GameModeBase.h"
|
||||
#include "unrealstatusGameModeBase.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class UNREALSTATUS_API AunrealstatusGameModeBase : public AGameModeBase {
|
||||
GENERATED_BODY()
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using UnrealBuildTool;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class unrealstatusEditorTarget : TargetRules
|
||||
{
|
||||
public unrealstatusEditorTarget(TargetInfo Target) : base(Target)
|
||||
{
|
||||
Type = TargetType.Editor;
|
||||
|
||||
ExtraModuleNames.AddRange( new string[] { "unrealstatus" } );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"EngineAssociation": "4.18",
|
||||
"Category": "",
|
||||
"Description": "",
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "unrealstatus",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
],
|
||||
"TargetPlatforms": [
|
||||
"LinuxNoEditor",
|
||||
"MacNoEditor",
|
||||
"WindowsNoEditor",
|
||||
"AllDesktop"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(DISCORD_DYNAMIC_LIB)
|
||||
#if defined(_WIN32)
|
||||
#if defined(DISCORD_BUILDING_SDK)
|
||||
#define DISCORD_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DISCORD_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define DISCORD_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
#define DISCORD_EXPORT
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command);
|
||||
DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
// clang-format off
|
||||
|
||||
#if defined(DISCORD_DYNAMIC_LIB)
|
||||
# if defined(_WIN32)
|
||||
# if defined(DISCORD_BUILDING_SDK)
|
||||
# define DISCORD_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define DISCORD_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
# else
|
||||
# define DISCORD_EXPORT __attribute__((visibility("default")))
|
||||
# endif
|
||||
#else
|
||||
# define DISCORD_EXPORT
|
||||
#endif
|
||||
|
||||
// clang-format on
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct DiscordRichPresence {
|
||||
const char* state; /* max 128 bytes */
|
||||
const char* details; /* max 128 bytes */
|
||||
int64_t startTimestamp;
|
||||
int64_t endTimestamp;
|
||||
const char* largeImageKey; /* max 32 bytes */
|
||||
const char* largeImageText; /* max 128 bytes */
|
||||
const char* smallImageKey; /* max 32 bytes */
|
||||
const char* smallImageText; /* max 128 bytes */
|
||||
const char* partyId; /* max 128 bytes */
|
||||
int partySize;
|
||||
int partyMax;
|
||||
int partyPrivacy;
|
||||
const char* matchSecret; /* max 128 bytes */
|
||||
const char* joinSecret; /* max 128 bytes */
|
||||
const char* spectateSecret; /* max 128 bytes */
|
||||
int8_t instance;
|
||||
} DiscordRichPresence;
|
||||
|
||||
typedef struct DiscordUser {
|
||||
const char* userId;
|
||||
const char* username;
|
||||
const char* discriminator;
|
||||
const char* avatar;
|
||||
} DiscordUser;
|
||||
|
||||
typedef struct DiscordEventHandlers {
|
||||
void (*ready)(const DiscordUser* request);
|
||||
void (*disconnected)(int errorCode, const char* message);
|
||||
void (*errored)(int errorCode, const char* message);
|
||||
void (*joinGame)(const char* joinSecret);
|
||||
void (*spectateGame)(const char* spectateSecret);
|
||||
void (*joinRequest)(const DiscordUser* request);
|
||||
} DiscordEventHandlers;
|
||||
|
||||
#define DISCORD_REPLY_NO 0
|
||||
#define DISCORD_REPLY_YES 1
|
||||
#define DISCORD_REPLY_IGNORE 2
|
||||
#define DISCORD_PARTY_PRIVATE 0
|
||||
#define DISCORD_PARTY_PUBLIC 1
|
||||
|
||||
DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
||||
DiscordEventHandlers* handlers,
|
||||
int autoRegister,
|
||||
const char* optionalSteamId);
|
||||
DISCORD_EXPORT void Discord_Shutdown(void);
|
||||
|
||||
/* checks for incoming messages, dispatches callbacks */
|
||||
DISCORD_EXPORT void Discord_RunCallbacks(void);
|
||||
|
||||
/* If you disable the lib starting its own io thread, you'll need to call this from your own */
|
||||
#ifdef DISCORD_DISABLE_IO_THREAD
|
||||
DISCORD_EXPORT void Discord_UpdateConnection(void);
|
||||
#endif
|
||||
|
||||
DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence);
|
||||
DISCORD_EXPORT void Discord_ClearPresence(void);
|
||||
|
||||
DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply);
|
||||
|
||||
DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
@@ -0,0 +1,147 @@
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
option(ENABLE_IO_THREAD "Start up a separate I/O thread, otherwise I'd need to call an update function" ON)
|
||||
option(USE_STATIC_CRT "Use /MT[d] for dynamic library" OFF)
|
||||
option(WARNINGS_AS_ERRORS "When enabled, compiles with `-Werror` (on *nix platforms)." OFF)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
set(BASE_RPC_SRC
|
||||
${PROJECT_SOURCE_DIR}/include/discord_rpc.h
|
||||
discord_rpc.cpp
|
||||
${PROJECT_SOURCE_DIR}/include/discord_register.h
|
||||
rpc_connection.h
|
||||
rpc_connection.cpp
|
||||
serialization.h
|
||||
serialization.cpp
|
||||
connection.h
|
||||
backoff.h
|
||||
msg_queue.h
|
||||
)
|
||||
|
||||
if (${BUILD_SHARED_LIBS})
|
||||
if(WIN32)
|
||||
set(BASE_RPC_SRC ${BASE_RPC_SRC} dllmain.cpp)
|
||||
endif(WIN32)
|
||||
endif(${BUILD_SHARED_LIBS})
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DDISCORD_WINDOWS)
|
||||
set(BASE_RPC_SRC ${BASE_RPC_SRC} connection_win.cpp discord_register_win.cpp)
|
||||
add_library(discord-rpc ${BASE_RPC_SRC})
|
||||
if (MSVC)
|
||||
if(USE_STATIC_CRT)
|
||||
foreach(CompilerFlag
|
||||
CMAKE_CXX_FLAGS
|
||||
CMAKE_CXX_FLAGS_DEBUG
|
||||
CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_RELEASE)
|
||||
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
|
||||
endforeach()
|
||||
endif(USE_STATIC_CRT)
|
||||
target_compile_options(discord-rpc PRIVATE /EHsc
|
||||
/Wall
|
||||
/wd4100 # unreferenced formal parameter
|
||||
/wd4514 # unreferenced inline
|
||||
/wd4625 # copy constructor deleted
|
||||
/wd5026 # move constructor deleted
|
||||
/wd4626 # move assignment operator deleted
|
||||
/wd4668 # not defined preprocessor macro
|
||||
/wd4710 # function not inlined
|
||||
/wd4711 # function was inlined
|
||||
/wd4820 # structure padding
|
||||
/wd4946 # reinterpret_cast used between related classes
|
||||
/wd5027 # move assignment operator was implicitly defined as deleted
|
||||
)
|
||||
endif(MSVC)
|
||||
target_link_libraries(discord-rpc PRIVATE psapi advapi32)
|
||||
endif(WIN32)
|
||||
|
||||
if(UNIX)
|
||||
set(BASE_RPC_SRC ${BASE_RPC_SRC} connection_unix.cpp)
|
||||
|
||||
if (APPLE)
|
||||
add_definitions(-DDISCORD_OSX)
|
||||
set(BASE_RPC_SRC ${BASE_RPC_SRC} discord_register_osx.m)
|
||||
else (APPLE)
|
||||
add_definitions(-DDISCORD_LINUX)
|
||||
set(BASE_RPC_SRC ${BASE_RPC_SRC} discord_register_linux.cpp)
|
||||
endif(APPLE)
|
||||
|
||||
add_library(discord-rpc ${BASE_RPC_SRC})
|
||||
target_link_libraries(discord-rpc PUBLIC pthread)
|
||||
|
||||
if (APPLE)
|
||||
target_link_libraries(discord-rpc PRIVATE "-framework AppKit, -mmacosx-version-min=10.10")
|
||||
endif (APPLE)
|
||||
|
||||
target_compile_options(discord-rpc PRIVATE
|
||||
-g
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wpedantic
|
||||
)
|
||||
|
||||
if (${WARNINGS_AS_ERRORS})
|
||||
target_compile_options(discord-rpc PRIVATE -Werror)
|
||||
endif (${WARNINGS_AS_ERRORS})
|
||||
|
||||
target_compile_options(discord-rpc PRIVATE
|
||||
-Wno-unknown-pragmas # pragma push thing doesn't work on clang
|
||||
-Wno-old-style-cast # it's fine
|
||||
-Wno-c++98-compat # that was almost 2 decades ago
|
||||
-Wno-c++98-compat-pedantic
|
||||
-Wno-missing-noreturn
|
||||
-Wno-padded # structure padding
|
||||
-Wno-covered-switch-default
|
||||
-Wno-exit-time-destructors # not sure about these
|
||||
-Wno-global-constructors
|
||||
)
|
||||
|
||||
if (${BUILD_SHARED_LIBS})
|
||||
target_compile_options(discord-rpc PRIVATE -fPIC)
|
||||
endif (${BUILD_SHARED_LIBS})
|
||||
|
||||
if (APPLE)
|
||||
target_link_libraries(discord-rpc PRIVATE "-framework AppKit")
|
||||
endif (APPLE)
|
||||
endif(UNIX)
|
||||
|
||||
target_include_directories(discord-rpc PRIVATE ${RAPIDJSON}/include)
|
||||
|
||||
if (NOT ${ENABLE_IO_THREAD})
|
||||
target_compile_definitions(discord-rpc PUBLIC -DDISCORD_DISABLE_IO_THREAD)
|
||||
endif (NOT ${ENABLE_IO_THREAD})
|
||||
|
||||
if (${BUILD_SHARED_LIBS})
|
||||
target_compile_definitions(discord-rpc PUBLIC -DDISCORD_DYNAMIC_LIB)
|
||||
target_compile_definitions(discord-rpc PRIVATE -DDISCORD_BUILDING_SDK)
|
||||
endif(${BUILD_SHARED_LIBS})
|
||||
|
||||
if (CLANG_FORMAT_CMD)
|
||||
add_dependencies(discord-rpc clangformat)
|
||||
endif(CLANG_FORMAT_CMD)
|
||||
|
||||
# install
|
||||
|
||||
install(
|
||||
TARGETS discord-rpc
|
||||
EXPORT "discord-rpc"
|
||||
RUNTIME
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
LIBRARY
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
ARCHIVE
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
INCLUDES
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"../include/discord_rpc.h"
|
||||
"../include/discord_register.h"
|
||||
DESTINATION "include"
|
||||
)
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
struct Backoff {
|
||||
int64_t minAmount;
|
||||
int64_t maxAmount;
|
||||
int64_t current;
|
||||
int fails;
|
||||
std::mt19937_64 randGenerator;
|
||||
std::uniform_real_distribution<> randDistribution;
|
||||
|
||||
double rand01() { return randDistribution(randGenerator); }
|
||||
|
||||
Backoff(int64_t min, int64_t max)
|
||||
: minAmount(min)
|
||||
, maxAmount(max)
|
||||
, current(min)
|
||||
, fails(0)
|
||||
, randGenerator((uint64_t)time(0))
|
||||
{
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
fails = 0;
|
||||
current = minAmount;
|
||||
}
|
||||
|
||||
int64_t nextDelay()
|
||||
{
|
||||
++fails;
|
||||
int64_t delay = (int64_t)((double)current * 2.0 * rand01());
|
||||
current = std::min(current + delay, maxAmount);
|
||||
return current;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
// This is to wrap the platform specific kinds of connect/read/write.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// not really connectiony, but need per-platform
|
||||
int GetProcessId();
|
||||
|
||||
struct BaseConnection {
|
||||
static BaseConnection* Create();
|
||||
static void Destroy(BaseConnection*&);
|
||||
bool isOpen{false};
|
||||
bool Open();
|
||||
bool Close();
|
||||
bool Write(const void* data, size_t length);
|
||||
bool Read(void* data, size_t length);
|
||||
};
|
||||
@@ -0,0 +1,125 @@
|
||||
#include "connection.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int GetProcessId()
|
||||
{
|
||||
return ::getpid();
|
||||
}
|
||||
|
||||
struct BaseConnectionUnix : public BaseConnection {
|
||||
int sock{-1};
|
||||
};
|
||||
|
||||
static BaseConnectionUnix Connection;
|
||||
static sockaddr_un PipeAddr{};
|
||||
#ifdef MSG_NOSIGNAL
|
||||
static int MsgFlags = MSG_NOSIGNAL;
|
||||
#else
|
||||
static int MsgFlags = 0;
|
||||
#endif
|
||||
|
||||
static const char* GetTempPath()
|
||||
{
|
||||
const char* temp = getenv("XDG_RUNTIME_DIR");
|
||||
temp = temp ? temp : getenv("TMPDIR");
|
||||
temp = temp ? temp : getenv("TMP");
|
||||
temp = temp ? temp : getenv("TEMP");
|
||||
temp = temp ? temp : "/tmp";
|
||||
return temp;
|
||||
}
|
||||
|
||||
/*static*/ BaseConnection* BaseConnection::Create()
|
||||
{
|
||||
PipeAddr.sun_family = AF_UNIX;
|
||||
return &Connection;
|
||||
}
|
||||
|
||||
/*static*/ void BaseConnection::Destroy(BaseConnection*& c)
|
||||
{
|
||||
auto self = reinterpret_cast<BaseConnectionUnix*>(c);
|
||||
self->Close();
|
||||
c = nullptr;
|
||||
}
|
||||
|
||||
bool BaseConnection::Open()
|
||||
{
|
||||
const char* tempPath = GetTempPath();
|
||||
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
||||
self->sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (self->sock == -1) {
|
||||
return false;
|
||||
}
|
||||
fcntl(self->sock, F_SETFL, O_NONBLOCK);
|
||||
#ifdef SO_NOSIGPIPE
|
||||
int optval = 1;
|
||||
setsockopt(self->sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
|
||||
#endif
|
||||
|
||||
for (int pipeNum = 0; pipeNum < 10; ++pipeNum) {
|
||||
snprintf(
|
||||
PipeAddr.sun_path, sizeof(PipeAddr.sun_path), "%s/discord-ipc-%d", tempPath, pipeNum);
|
||||
int err = connect(self->sock, (const sockaddr*)&PipeAddr, sizeof(PipeAddr));
|
||||
if (err == 0) {
|
||||
self->isOpen = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
self->Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BaseConnection::Close()
|
||||
{
|
||||
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
||||
if (self->sock == -1) {
|
||||
return false;
|
||||
}
|
||||
close(self->sock);
|
||||
self->sock = -1;
|
||||
self->isOpen = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseConnection::Write(const void* data, size_t length)
|
||||
{
|
||||
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
||||
|
||||
if (self->sock == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t sentBytes = send(self->sock, data, length, MsgFlags);
|
||||
if (sentBytes < 0) {
|
||||
Close();
|
||||
}
|
||||
return sentBytes == (ssize_t)length;
|
||||
}
|
||||
|
||||
bool BaseConnection::Read(void* data, size_t length)
|
||||
{
|
||||
auto self = reinterpret_cast<BaseConnectionUnix*>(this);
|
||||
|
||||
if (self->sock == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int res = (int)recv(self->sock, data, length, MsgFlags);
|
||||
if (res < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
return false;
|
||||
}
|
||||
Close();
|
||||
}
|
||||
else if (res == 0) {
|
||||
Close();
|
||||
}
|
||||
return res == (int)length;
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
#include "connection.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMCX
|
||||
#define NOSERVICE
|
||||
#define NOIME
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
|
||||
int GetProcessId()
|
||||
{
|
||||
return (int)::GetCurrentProcessId();
|
||||
}
|
||||
|
||||
struct BaseConnectionWin : public BaseConnection {
|
||||
HANDLE pipe{INVALID_HANDLE_VALUE};
|
||||
};
|
||||
|
||||
static BaseConnectionWin Connection;
|
||||
|
||||
/*static*/ BaseConnection* BaseConnection::Create()
|
||||
{
|
||||
return &Connection;
|
||||
}
|
||||
|
||||
/*static*/ void BaseConnection::Destroy(BaseConnection*& c)
|
||||
{
|
||||
auto self = reinterpret_cast<BaseConnectionWin*>(c);
|
||||
self->Close();
|
||||
c = nullptr;
|
||||
}
|
||||
|
||||
bool BaseConnection::Open()
|
||||
{
|
||||
wchar_t pipeName[]{L"\\\\?\\pipe\\discord-ipc-0"};
|
||||
const size_t pipeDigit = sizeof(pipeName) / sizeof(wchar_t) - 2;
|
||||
pipeName[pipeDigit] = L'0';
|
||||
auto self = reinterpret_cast<BaseConnectionWin*>(this);
|
||||
for (;;) {
|
||||
self->pipe = ::CreateFileW(
|
||||
pipeName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
if (self->pipe != INVALID_HANDLE_VALUE) {
|
||||
self->isOpen = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto lastError = GetLastError();
|
||||
if (lastError == ERROR_FILE_NOT_FOUND) {
|
||||
if (pipeName[pipeDigit] < L'9') {
|
||||
pipeName[pipeDigit]++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (lastError == ERROR_PIPE_BUSY) {
|
||||
if (!WaitNamedPipeW(pipeName, 10000)) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseConnection::Close()
|
||||
{
|
||||
auto self = reinterpret_cast<BaseConnectionWin*>(this);
|
||||
::CloseHandle(self->pipe);
|
||||
self->pipe = INVALID_HANDLE_VALUE;
|
||||
self->isOpen = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseConnection::Write(const void* data, size_t length)
|
||||
{
|
||||
if (length == 0) {
|
||||
return true;
|
||||
}
|
||||
auto self = reinterpret_cast<BaseConnectionWin*>(this);
|
||||
assert(self);
|
||||
if (!self) {
|
||||
return false;
|
||||
}
|
||||
if (self->pipe == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
assert(data);
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
const DWORD bytesLength = (DWORD)length;
|
||||
DWORD bytesWritten = 0;
|
||||
return ::WriteFile(self->pipe, data, bytesLength, &bytesWritten, nullptr) == TRUE &&
|
||||
bytesWritten == bytesLength;
|
||||
}
|
||||
|
||||
bool BaseConnection::Read(void* data, size_t length)
|
||||
{
|
||||
assert(data);
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
auto self = reinterpret_cast<BaseConnectionWin*>(this);
|
||||
assert(self);
|
||||
if (!self) {
|
||||
return false;
|
||||
}
|
||||
if (self->pipe == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
DWORD bytesAvailable = 0;
|
||||
if (::PeekNamedPipe(self->pipe, nullptr, 0, nullptr, &bytesAvailable, nullptr)) {
|
||||
if (bytesAvailable >= length) {
|
||||
DWORD bytesToRead = (DWORD)length;
|
||||
DWORD bytesRead = 0;
|
||||
if (::ReadFile(self->pipe, data, bytesToRead, &bytesRead, nullptr) == TRUE) {
|
||||
assert(bytesToRead == bytesRead);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
#include "discord_rpc.h"
|
||||
#include "discord_register.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static bool Mkdir(const char* path)
|
||||
{
|
||||
int result = mkdir(path, 0755);
|
||||
if (result == 0) {
|
||||
return true;
|
||||
}
|
||||
if (errno == EEXIST) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// we want to register games so we can run them from Discord client as discord-<appid>://
|
||||
extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command)
|
||||
{
|
||||
// Add a desktop file and update some mime handlers so that xdg-open does the right thing.
|
||||
|
||||
const char* home = getenv("HOME");
|
||||
if (!home) {
|
||||
return;
|
||||
}
|
||||
|
||||
char exePath[1024];
|
||||
if (!command || !command[0]) {
|
||||
ssize_t size = readlink("/proc/self/exe", exePath, sizeof(exePath));
|
||||
if (size <= 0 || size >= (ssize_t)sizeof(exePath)) {
|
||||
return;
|
||||
}
|
||||
exePath[size] = '\0';
|
||||
command = exePath;
|
||||
}
|
||||
|
||||
const char* desktopFileFormat = "[Desktop Entry]\n"
|
||||
"Name=Game %s\n"
|
||||
"Exec=%s %%u\n" // note: it really wants that %u in there
|
||||
"Type=Application\n"
|
||||
"NoDisplay=true\n"
|
||||
"Categories=Discord;Games;\n"
|
||||
"MimeType=x-scheme-handler/discord-%s;\n";
|
||||
char desktopFile[2048];
|
||||
int fileLen = snprintf(
|
||||
desktopFile, sizeof(desktopFile), desktopFileFormat, applicationId, command, applicationId);
|
||||
if (fileLen <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
char desktopFilename[256];
|
||||
snprintf(desktopFilename, sizeof(desktopFilename), "/discord-%s.desktop", applicationId);
|
||||
|
||||
char desktopFilePath[1024];
|
||||
snprintf(desktopFilePath, sizeof(desktopFilePath), "%s/.local", home);
|
||||
if (!Mkdir(desktopFilePath)) {
|
||||
return;
|
||||
}
|
||||
strcat(desktopFilePath, "/share");
|
||||
if (!Mkdir(desktopFilePath)) {
|
||||
return;
|
||||
}
|
||||
strcat(desktopFilePath, "/applications");
|
||||
if (!Mkdir(desktopFilePath)) {
|
||||
return;
|
||||
}
|
||||
strcat(desktopFilePath, desktopFilename);
|
||||
|
||||
FILE* fp = fopen(desktopFilePath, "w");
|
||||
if (fp) {
|
||||
fwrite(desktopFile, 1, fileLen, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
char xdgMimeCommand[1024];
|
||||
snprintf(xdgMimeCommand,
|
||||
sizeof(xdgMimeCommand),
|
||||
"xdg-mime default discord-%s.desktop x-scheme-handler/discord-%s",
|
||||
applicationId,
|
||||
applicationId);
|
||||
if (system(xdgMimeCommand) < 0) {
|
||||
fprintf(stderr, "Failed to register mime handler\n");
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId,
|
||||
const char* steamId)
|
||||
{
|
||||
char command[256];
|
||||
sprintf(command, "xdg-open steam://rungameid/%s", steamId);
|
||||
Discord_Register(applicationId, command);
|
||||
}
|
||||